Skip to content

Commit

Permalink
5e 3.0 verified
Browse files Browse the repository at this point in the history
  • Loading branch information
ChunkLightTuna committed Feb 2, 2024
1 parent 6511846 commit 8796dc4
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 66 deletions.
30 changes: 14 additions & 16 deletions .github/workflows/foundry_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
CHANGES = os.environ['CHANGES']


def push_release(module):
def push_release(module: dict) -> None:
conn = http.client.HTTPSConnection("api.foundryvtt.com")
conn.request(
"POST", "/_api/packages/release_version/",
Expand All @@ -44,14 +44,14 @@ def push_release(module):
raise Exception(pprint.pformat(response_json['errors']))


def get_readme_as_html():
def get_readme_as_html() -> str:
md = MarkdownIt('commonmark', {'html': True}).enable('table')
with open('./README.md', 'r') as readme_file:
readme = readme_file.read()
return md.render(readme)


def get_root():
def get_tokens() -> (str, str):
conn = http.client.HTTPSConnection('foundryvtt.com')
conn.request('GET', '/', headers={})
response = conn.getresponse()
Expand All @@ -62,7 +62,7 @@ def get_root():
return csrf_token, csrf_middleware_token


def post_auth_login(csrf_token, csrf_middleware_token):
def get_session_id(csrf_token: str, csrf_middleware_token: str) -> str:
body = urlencode({
'csrfmiddlewaretoken': csrf_middleware_token,
'username': FOUNDRY_USERNAME,
Expand All @@ -85,7 +85,7 @@ def post_auth_login(csrf_token, csrf_middleware_token):
return session_id


def extract_errorlist_text(html_string):
def extract_errorlist_text(html_string: str) -> str:
class ErrorListParser(HTMLParser):
in_errorlist = False
errorlist_content = []
Expand All @@ -109,7 +109,7 @@ def handle_data(self, data):
return parser.errorlist_content


def post_packages_oronder_edit(csrf_token, csrf_middleware_token, session_id, description, module):
def post_packages_oronder_edit(csrf_token, csrf_middleware_token, session_id, description, module) -> None:
conn = http.client.HTTPSConnection('foundryvtt.com')
headers = {
'Referer': 'https://foundryvtt.com/packages/oronder/edit',
Expand All @@ -132,11 +132,10 @@ def post_packages_oronder_edit(csrf_token, csrf_middleware_token, session_id, de
response = conn.getresponse()
if response.status != 302:
content = response.read().decode()
err_msg = f'Update Description Failed\n{extract_errorlist_text(content)}'
raise Exception(err_msg)
raise Exception(f'Update Description Failed\n{extract_errorlist_text(content)}')


def post_update(version):
def post_update(version) -> None:
conn = http.client.HTTPSConnection("api.oronder.com")
conn.request(
"POST", '/update_discord',
Expand All @@ -150,25 +149,24 @@ def post_update(version):
if response.status != 200:
content = response.read().decode()
headers = response.headers.as_string()
err_msg = f'Failed to send Update Message to Discord\n{content=}\n{headers=}'
raise Exception(err_msg)
raise Exception(f'Failed to send Update Message to Discord\n{content=}\n{headers=}')


def main():
with open('./module.json', 'r') as file:
module_json = json.load(file)

csrf_token, csrf_middleware_token = get_root()
session_id = post_auth_login(csrf_token, csrf_middleware_token)
csrf_token, csrf_middleware_token = get_tokens()
session_id = get_session_id(csrf_token, csrf_middleware_token)
readme = get_readme_as_html()
post_packages_oronder_edit(csrf_token, csrf_middleware_token, session_id, readme, module_json)
print('REPO DESCRIPTION UPDATED')
print('\n__REPO DESCRIPTION UPDATED__\n')

push_release(module_json)
print('MODULE POSTED TO REPO')
print('\n__MODULE POSTED TO REPO__\n')

post_update(module_json['version'])
print('DISCORD NOTIFIED OF NEW RELEASE')
print('\n__DISCORD NOTIFIED OF NEW RELEASE__\n')


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion module.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"manifest": "https://raw.githubusercontent.com/foundryvtt/dnd5e/master/system.json",
"compatibility": {
"minimum": "2.4.0",
"verified": "2.4.1"
"verified": "3.0.0"
}
}
]
Expand Down
2 changes: 1 addition & 1 deletion src/constants.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const MODULE_DEBUG_TAG = [
`%c${MODULE_NAME}`,
`color: #66023c; font-weight: bold;`,
`|`,
];
]

export const GUILD_NAME = "guild_name"
export const AUTH = "auth"
Expand Down
8 changes: 4 additions & 4 deletions src/module.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -78,20 +78,20 @@ export function open_socket_with_oronder(update = false) {
})

socket.on('connect_error', (error) => {
Logger.warn(`Oronder Websocket connection failed: ${error.message}`);
Logger.warn(`Oronder Websocket connection failed: ${error.message}`)
})

socket.on('connect', () => {
Logger.info('Oronder Websocket connection established.')
})
socket.on('xp', data => {
socket.on('xp', async data => {
for (const [actor_id, xp] of Object.entries(data)) {
const actor = game.actors.get(actor_id)
if (actor === undefined) {
Logger.warn(`Failed to update XP. No Actor with ID ${actor_id} found!`)
} else {
Logger.info(`${actor.name} xp: ${actor.system.details.xp.value} -> ${xp}`)
actor.update({"system.details.xp.value": xp})
await actor.update({"system.details.xp.value": xp})
}
}
})
Expand All @@ -106,7 +106,7 @@ game.socket.on(SOCKET_NAME, data => {
case 'session': {
set_session(data.session)
}
break;
break
}
})

Expand Down
24 changes: 12 additions & 12 deletions src/settings-form-application.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Logger} from "./util.mjs";
import {AUTH, GUILD_NAME, ID_MAP, MODULE_ID, ORONDER_BASE_URL, VALID_CONFIG} from "./constants.mjs";
import {full_sync} from "./sync.mjs";
import {open_socket_with_oronder} from "./module.mjs";
import {Logger} from "./util.mjs"
import {AUTH, GUILD_NAME, ID_MAP, MODULE_ID, ORONDER_BASE_URL, VALID_CONFIG} from "./constants.mjs"
import {full_sync} from "./sync.mjs"
import {open_socket_with_oronder} from "./module.mjs"

export class OronderSettingsFormApplication extends FormApplication {

Expand All @@ -22,8 +22,8 @@ export class OronderSettingsFormApplication extends FormApplication {
foundry_id: user.id,
discord_id: id_map[user.id] ?? ''
}))
});
super(object, options);
})
super(object, options)
}

static get defaultOptions() {
Expand All @@ -32,13 +32,13 @@ export class OronderSettingsFormApplication extends FormApplication {
template: `modules/${MODULE_ID}/templates/settings-form-application.hbs`,
width: 580,
resizable: true
});
})
}


/** @override */
get title() {
return game.i18n.localize("oronder.Oronder-Bot-Config");
return game.i18n.localize("oronder.Oronder-Bot-Config")
}

/** @override */
Expand All @@ -48,14 +48,14 @@ export class OronderSettingsFormApplication extends FormApplication {

/** @override */
activateListeners(html) {
super.activateListeners(html);
html.find(".control").on("click", this._onClickControl.bind(this));
super.activateListeners(html)
html.find(".control").on("click", this._onClickControl.bind(this))
}

_onClickControl(event) {
switch (event.currentTarget.dataset.action) {
case "fetch":
return this._fetch_discord_ids();
return this._fetch_discord_ids()
case "sync-all":
return this._full_sync()

Expand All @@ -71,7 +71,7 @@ export class OronderSettingsFormApplication extends FormApplication {
}),
redirect: 'follow'
}
};
}

/** @override */
async _updateObject(event, formData) {
Expand Down
8 changes: 4 additions & 4 deletions src/settings.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {AUTH, GUILD_NAME, ID_MAP, MODULE_ID, ORONDER_CONFIGURATION_FORM, VALID_CONFIG} from "./constants.mjs";
import {Logger} from "./util.mjs";
import {OronderSettingsFormApplication} from "./settings-form-application.mjs";
import {AUTH, GUILD_NAME, ID_MAP, MODULE_ID, ORONDER_CONFIGURATION_FORM, VALID_CONFIG} from "./constants.mjs"
import {Logger} from "./util.mjs"
import {OronderSettingsFormApplication} from "./settings-form-application.mjs"

export const registerSettings = async () => {
game.settings.register(MODULE_ID, GUILD_NAME, {
Expand Down Expand Up @@ -31,7 +31,7 @@ export const registerSettings = async () => {
config: true,
type: OronderSettingsFormApplication,
restricted: true
});
})

game.settings.register(MODULE_ID, VALID_CONFIG, {
scope: "world",
Expand Down
40 changes: 22 additions & 18 deletions src/sync.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ACTORS, AUTH, ID_MAP, MODULE_ID, ORONDER_BASE_URL} from "./constants.mjs";
import {hash, Logger} from "./util.mjs";
import {ACTORS, AUTH, ID_MAP, MODULE_ID, ORONDER_BASE_URL} from "./constants.mjs"
import {hash, Logger} from "./util.mjs"

function prune_roll_data(
{
Expand Down Expand Up @@ -116,7 +116,7 @@ export function enrich_actor(actor) {
let currency = actor.system['currency']
for (const key in currency) {
if (currency.hasOwnProperty(key) && !currency[key]) {
currency[key] = 0;
currency[key] = 0
}
}

Expand Down Expand Up @@ -166,7 +166,7 @@ async function upload(pc) {
headers: headers(),
body: JSON.stringify(pc),
redirect: 'follow'
};
}

return await fetch(`${ORONDER_BASE_URL}/actor`, requestOptions)
}
Expand All @@ -176,7 +176,7 @@ export async function del_actor(pc_id) {
method: 'DELETE',
headers: headers(),
redirect: 'follow'
};
}

return await fetch(`${ORONDER_BASE_URL}/actor/${pc_id}`, requestOptions)
}
Expand All @@ -192,21 +192,21 @@ const actor_to_discord_ids = actor =>
export async function full_sync() {
game.actors
.filter(_ => localStorage.getItem(`${ACTORS}.${_.id}`))
.forEach(_ => localStorage.removeItem(`${ACTORS}${_.id}`))
.forEach(_ => localStorage.removeItem(`${ACTORS}.${_.id}`))
return Promise.all(game.actors.map(sync_actor))
}

export async function sync_actor(actor) {
if (actor.type !== "character") {
Logger.info(
`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor.name}. ${game.i18n.localize("oronder.NPC")}`
);
)
return Promise.resolve()
}
if (!actor_to_discord_ids(actor).length) {
Logger.info(
`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor.name}. ${game.i18n.localize("oronder.No-Owner")}`
);
)
return Promise.resolve()
}

Expand All @@ -215,41 +215,45 @@ export async function sync_actor(actor) {
const new_hash = hash(actor_obj)

if (old_hash && old_hash === new_hash) {
Logger.info(`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor_obj.name}. ${game.i18n.localize("oronder.No-Change")}`);
Logger.info(`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor_obj.name}. ${game.i18n.localize("oronder.No-Change")}`)
return Promise.resolve()
}
if (!actor_obj.details.level) {
Logger.info(`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor_obj.name}. ${game.i18n.localize("oronder.No-Level")}`);
Logger.info(`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor_obj.name}. ${game.i18n.localize("oronder.No-Level")}`)
return Promise.resolve()
}
if (!actor_obj.details.race) {
Logger.info(`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor_obj.name}. ${game.i18n.localize("oronder.No-Race")}`);
Logger.info(`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor_obj.name}. ${game.i18n.localize("oronder.No-Race")}`)
return Promise.resolve()
}
if (!actor_obj.details.background) {
Logger.info(`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor_obj.name}. ${game.i18n.localize("oronder.No-Background")}`);
Logger.info(`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor_obj.name}. ${game.i18n.localize("oronder.No-Background")}`)
return Promise.resolve()
}
if (!Object.keys(actor_obj.classes).length) {
Logger.info(`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor_obj.name}. ${game.i18n.localize("oronder.No-Class")}`);
Logger.info(`${game.i18n.localize("oronder.Skipping-Sync-For")} ${actor_obj.name}. ${game.i18n.localize("oronder.No-Class")}`)
return Promise.resolve()
}

return upload(actor_obj).then(response => {
if (response.ok) {
localStorage.setItem(`${ACTORS}.${actor.id}`, new_hash)
Logger.info(`${game.i18n.localize("oronder.Synced")} ${actor_obj.name}`);
Logger.info(`${game.i18n.localize("oronder.Synced")} ${actor_obj.name}`)
} else if (response.status === 422) {
response
.json()
.then(({detail}) => Logger.error(
`${actor_obj.name} ${game.i18n.localize("oronder.Failed-To-Sync")}: ` +
`${actor_obj.name} ${game.i18n.localize("oronder.Failed-To-Sync")} ` +
detail.flat().map(({loc, input, msg}) =>
`${loc.filter(_ => _ !== 'body').join('->')}->${input} | ${msg}`
).join(' ')
`❌ ${loc.filter(_ => _ !== 'body').join('>')}>${input} ${msg}`
).join(' '),
{permanent: true}
))
} else {
Logger.error(`${actor_obj.name} ${game.i18n.localize("oronder.Failed-To-Sync")}: ${response.status} ${response.statusText}`);
Logger.error(
`${actor_obj.name} ${game.i18n.localize("oronder.Failed-To-Sync")}: ${response.status} ${response.statusText}`,
{permanent: true}
)
}
}).catch(Logger.error)
}
Loading

0 comments on commit 8796dc4

Please sign in to comment.