import Config from './util/config.js'; import {MessageActionRow, MessageButton, MessageEmbed} from 'discord.js'; import db from './database.js'; import {capture_sentry_exception, gen_url, escape_markdown, recover_sql_query_data, stars_to_color} from './util/helpers.js'; let guild = null; async function init(discord_client) { guild = await discord_client.guilds.fetch(Config.discord_guild_id); } // Adds the 'Linked account' role and sets the user's nickname to their in-game username async function sync_discord_info(user, sync_reason) { if (!guild) return; if (!user.discord_user_id) return; let member; try { member = await guild.members.fetch(user.discord_user_id); } catch (err) { // User left the server; we don't remove them from the database as they could re-join anytime if (err.message == 'Unknown Member') { return; } console.error(`[Discord] Failed to fetch '${user.username}' <@${user.discord_user_id}>: ${err}`); capture_sentry_exception(err); return; } try { await member.roles.add(Config.discord_linked_account_role_id); } catch (err) { console.error(`[Discord] Failed to add role to '${user.username}' <@${user.discord_user_id}>: ${err}`); capture_sentry_exception(err); } try { await member.setNickname(user.username, sync_reason); } catch (err) { console.error(`[Discord] Failed to update nickname for '${user.username}' <@${user.discord_user_id}>: ${err}`); capture_sentry_exception(err); } } async function announce_new_room(lobby) { if (!guild) return; let map_pool_info = 'All maps'; if (lobby.data.map_pool == 'collection') { const name = escape_markdown(lobby.data.collection?.name || 'Untitled collection'); map_pool_info = `[${name}](https://osucollector.com/collections/${lobby.data.collection_id})`; } let map_selection_info = 'Random'; if (lobby.data.map_selection_algo == 'pp') { map_selection_info = 'Average player pp'; } else if (lobby.data.map_selection_algo == 'elo') { map_selection_info = 'Average player elo'; } let description = ''; const filters = {...recover_sql_query_data(lobby.data.filter_query)}; // XXX: Cache this for (const filter of filters.filters) { const filter_name = filter.name[0].toUpperCase() + filter.name.slice(1); description += `- ${filter_name} between ${filter.min} and ${filter.max}\n`; } if (description != '') { description = 'Filters:\n' + description; } let mods_info = 'None'; if (lobby.data.mod_list.length > 0) { mods_info = lobby.data.mod_list.join(', '); } if (lobby.data.freemod) { mods_info += ' (freemod)'; } const fields = [ {name: 'Ruleset', value: ['Standard', 'Taiko', 'Catch', 'Mania'][lobby.data.ruleset], inline: true}, ]; if (lobby.data.ruleset == 3) { fields.push({name: 'Keys', value: filters.key_counts.join(', '), inline: true}); } fields.push({name: 'Map pool', value: map_pool_info}); fields.push({name: 'Map selection', value: map_selection_info}); fields.push({name: 'Mods', value: mods_info}); const ann = new MessageEmbed() .setColor(stars_to_color((lobby.data.min_stars + lobby.data.max_stars) / 2)) .setTitle(escape_markdown(lobby.name)) .setURL(gen_url(lobby.data.ruleset, '/lobbies/')) .setAuthor({ name: lobby.data.creator, iconURL: `https://a.ppy.sh/${lobby.data.creator_id}`, url: gen_url(lobby.data.ruleset, `/u/${lobby.data.creator_id}`), }) .setDescription(description) .addFields(fields) .setTimestamp(); const announce_channel = guild.channels.cache.get(Config.discord_room_announce_channel_id); await announce_channel.send({ content: 'New lobby created:', embeds: [ann], components: [ new MessageActionRow().addComponents([ new MessageButton({ custom_id: 'orl_get_lobby_invite_' + lobby.id, label: 'Get invite', style: 'PRIMARY', }), ]), ], }); } async function update_the_one_discord_role(user_id, is_the_one) { if (!guild) return; const user = db.prepare('SELECT * FROM user WHERE user_id = ?').get(user_id); if (!user) return; if (!user.discord_user_id) return; let member; try { member = await guild.members.fetch(user.discord_user_id); } catch (err) { // User left the server; we don't remove them from the database as they could re-join anytime if (err.message == 'Unknown Member') { return; } console.error(`[Discord] Failed to fetch '${user.username}' <@${user.discord_user_id}>: ${err}`); capture_sentry_exception(err); return; } if (is_the_one) { try { await member.roles.add(Config.discord_the_one_role_id); } catch (err) { console.error(`[Discord] Failed to add The One role to '${user.username}' <@${user.discord_user_id}>: ${err}`); capture_sentry_exception(err); } } else { try { await member.roles.remove(Config.discord_the_one_role_id); } catch (err) { console.error(`[Discord] Failed to remove The One role from '${user.username}' <@${user.discord_user_id}>: ${err}`); capture_sentry_exception(err); } } } export { init, sync_discord_info, update_the_one_discord_role, announce_new_room, };