diff --git a/config.example.json b/config.example.json index 9e87fc8..cd049c2 100644 --- a/config.example.json +++ b/config.example.json @@ -1,4 +1,5 @@ { "token": "", - "clientId": "" + "clientId": "", + "resolvedTag": "" } diff --git a/main.ts b/main.ts index 66bb5e4..168d35a 100644 --- a/main.ts +++ b/main.ts @@ -1,6 +1,6 @@ import { Client, GatewayIntentBits, ActivityType } from 'discord.js' -import config from './config.json' +import config from 'config.json' import fs from 'fs' @@ -26,7 +26,7 @@ const client = new Client({ }) client.on('ready', () => { - console.log(`Logged in as ${client.user?.tag}!`) + console.log(`Logged in as ${client.user?.tag ?? 'unknown'}!`) }) fs.readdirSync('modules') diff --git a/modules/autoupload.ts b/modules/autoupload.ts index c99b956..0275103 100644 --- a/modules/autoupload.ts +++ b/modules/autoupload.ts @@ -6,7 +6,7 @@ const website = 'https://pastes.dev' const api = 'https://api.pastes.dev' // noinspection JSUnusedGlobalSymbols -export default (client: Client) => { +export default (client: Client): void => { client.on('messageCreate', async message => { if (!message.channel.isTextBased() || message.channel.isDMBased()) return diff --git a/modules/checks/checks.config.ts b/modules/checks/checks.config.ts index c232d1b..f609b7a 100644 --- a/modules/checks/checks.config.ts +++ b/modules/checks/checks.config.ts @@ -35,7 +35,7 @@ const checksConfig: ChecksConfig = { title: 'SkinsRestorerAPI is not initialized yet', content: 'This error occurs when a third-party plugin tries to access SkinsRestorerAPI before SkinsRestorer is fully loaded. This is a bug in the third-party plugin, and should be reported to the plugin developer.', tips: [ - "Make sure SkinsRestorer is installed and enabled. There may have been a startup error that prevented SkinsRestorer from loading.", + 'Make sure SkinsRestorer is installed and enabled. There may have been a startup error that prevented SkinsRestorer from loading.', 'Your plugin may be loading before SkinsRestorer. To load your plugin after SkinsRestorer, add `softdepend: [ "SkinsRestorer" ]` to your plugin.yml file.' ], link: 'https://skinsrestorer.net/docs/development/api#add-skinsrestorer-as-a-dependency' @@ -45,9 +45,9 @@ const checksConfig: ChecksConfig = { title: 'Missing mapping in SkinsRestorer', content: 'This error occurs when the current build does not support the current Minecraft version. Every new version of Minecraft requires a new mapping to be added to SkinsRestorer because of Spigot\'s obfuscation.', tips: [ - "Check announcements for updates for new versions of SkinsRestorer. If there is no update, please be patient.", + 'Check announcements for updates for new versions of SkinsRestorer. If there is no update, please be patient.', 'If PaperMC has released a new version, try switching from Spigot to Paper. We recommend PaperMC over Spigot because we don\'t use mappings for Paper.' - ], + ] } ] } diff --git a/modules/checks/index.ts b/modules/checks/index.ts index 3e57358..11f76b0 100644 --- a/modules/checks/index.ts +++ b/modules/checks/index.ts @@ -30,7 +30,7 @@ export default (client: Client): void => { let response = '' try { - console.log(`Getting upload bin ${getLink}`); + console.log(`Getting upload bin ${getLink}`) response = (await (await fetch(getLink)).text()) } catch (e: any) { if (e.response) { @@ -96,7 +96,7 @@ function checkMatch (text: string, checks: RegExp[]) { async function respondToText (message: Message, text: string, footer: string) { for (const test of config.tests) { - let cause = checkMatch(text, test.checks) + const cause = checkMatch(text, test.checks) if (cause == null) { continue } @@ -104,12 +104,12 @@ async function respondToText (message: Message, text: string, footer: string) { const embed = new EmbedBuilder() embed.setTitle(test.title) embed.setDescription(test.content) - if (test.tips) { + if (test.tips != null) { embed.addFields(test.tips.map((tip, i) => ({ name: `Tip #${i + 1}`, value: tip }))) } if (test.link) { - embed.addFields({ name: 'Read More', value: test.link },) + embed.addFields({ name: 'Read More', value: test.link }) } embed.addFields({ name: 'Caused By', value: `\`\`\`${cause}\`\`\`` }) diff --git a/modules/commands/commands.config.ts b/modules/commands/commands.config.ts index 84fdce7..a54e1cb 100644 --- a/modules/commands/commands.config.ts +++ b/modules/commands/commands.config.ts @@ -15,264 +15,264 @@ export interface CommandField { export const configCommands: ConfigCommand[] = [ { - name: "wrong-channel", - cmdDescription: "Send a message that the channel is wrong", - title: "This channel is not for support!", - url: "https://discord.com/channels/186794372468178944/1058044481246605383", - description: "This channel is not for support for the **SkinsRestorer Minecraft plugin**. Please use the <#1058044481246605383> channel for support, you need to create a post in that channel. You will not receive support in this specific Discord channel." + name: 'wrong-channel', + cmdDescription: 'Send a message that the channel is wrong', + title: 'This channel is not for support!', + url: 'https://discord.com/channels/186794372468178944/1058044481246605383', + description: 'This channel is not for support for the **SkinsRestorer Minecraft plugin**. Please use the <#1058044481246605383> channel for support, you need to create a post in that channel. You will not receive support in this specific Discord channel.' }, { - name: "docs", - cmdDescription: "Send a link to the docs", - title: "SkinsRestorer Documentation", - url: "https://skinsrestorer.net/docs", - description: "Learn how to use SkinsRestorer and all of its features by reading the wiki.", + name: 'docs', + cmdDescription: 'Send a link to the docs', + title: 'SkinsRestorer Documentation', + url: 'https://skinsrestorer.net/docs', + description: 'Learn how to use SkinsRestorer and all of its features by reading the wiki.', docs: true }, { - name: "install", - cmdDescription: "Send a message with a link to the installation guide", - title: "Installing SkinsRestorer", - url: "https://skinsrestorer.net/docs/installation", - description: "You can install SkinsRestorer on Bukkit/Spigot/Paper, BungeeCord, Sponge and Velocity servers. Check the installation guide for more info on setting up SkinsRestorer.", + name: 'install', + cmdDescription: 'Send a message with a link to the installation guide', + title: 'Installing SkinsRestorer', + url: 'https://skinsrestorer.net/docs/installation', + description: 'You can install SkinsRestorer on Bukkit/Spigot/Paper, BungeeCord, Sponge and Velocity servers. Check the installation guide for more info on setting up SkinsRestorer.', docs: true }, { - name: "proxy-install", - cmdDescription: "Send a link to the proxy installation guide", - title: "Network Installation", - url: "https://skinsrestorer.net/docs/installation", - description: "If you run a BungeeCord/Velocity network, learn how to correctly setup SkinsRestorer on all server instances (including BungeeCord/Velocity).", + name: 'proxy-install', + cmdDescription: 'Send a link to the proxy installation guide', + title: 'Network Installation', + url: 'https://skinsrestorer.net/docs/installation', + description: 'If you run a BungeeCord/Velocity network, learn how to correctly setup SkinsRestorer on all server instances (including BungeeCord/Velocity).', fields: [ { - key: "BungeeCord Installation:", - value: "https://skinsrestorer.net/docs/installation/bungeecord" + key: 'BungeeCord Installation:', + value: 'https://skinsrestorer.net/docs/installation/bungeecord' }, { - key: "Velocity Installation:", - value: "https://skinsrestorer.net/docs/installation/velocity" + key: 'Velocity Installation:', + value: 'https://skinsrestorer.net/docs/installation/velocity' } ], docs: true }, { - name: "troubleshooting", - cmdDescription: "Send a link to the troubleshooting guide", - title: "Troubleshooting", - url: "https://skinsrestorer.net/docs/troubleshooting", + name: 'troubleshooting', + cmdDescription: 'Send a link to the troubleshooting guide', + title: 'Troubleshooting', + url: 'https://skinsrestorer.net/docs/troubleshooting', description: "Here's a page with some common errors.", docs: true }, { - name: "command-help", - cmdDescription: "Send a link to the command help page", - title: "Command/Permissions Usage", - url: "https://skinsrestorer.net/docs/configuration/commands-permissions", - description: "Find all of the available SkinsRestorer commands and permissions on the wiki.", + name: 'command-help', + cmdDescription: 'Send a link to the command help page', + title: 'Command/Permissions Usage', + url: 'https://skinsrestorer.net/docs/configuration/commands-permissions', + description: 'Find all of the available SkinsRestorer commands and permissions on the wiki.', docs: true }, { - name: "api", - cmdDescription: "Send a link to the API page", - title: "Developer API", - url: "https://github.com/SkinsRestorer/SkinsRestorerX/wiki/SkinsRestorerAPI", - description: "Learn how to use the SkinsRestorer API in your project.", + name: 'api', + cmdDescription: 'Send a link to the API page', + title: 'Developer API', + url: 'https://github.com/SkinsRestorer/SkinsRestorerX/wiki/SkinsRestorerAPI', + description: 'Learn how to use the SkinsRestorer API in your project.', fields: [ { - key: "Example usages", - value: "https://github.com/SkinsRestorer/SkinsRestorerAPIExample" + key: 'Example usages', + value: 'https://github.com/SkinsRestorer/SkinsRestorerAPIExample' }, { - key: "Plugin messaging channel", - value: "https://github.com/SkinsRestorer/SRPluginMessagingChannelExample" + key: 'Plugin messaging channel', + value: 'https://github.com/SkinsRestorer/SRPluginMessagingChannelExample' }, { - key: "Javadocs", - value: "https://docs.skinsrestorer.net" + key: 'Javadocs', + value: 'https://docs.skinsrestorer.net' } ], docs: true }, { - name: "config", - cmdDescription: "Send a link to the config page", - title: "SkinsRestorer Configuration", - url: "https://skinsrestorer.net/docs/configuration", - description: "Learn what each of the config options are for.", + name: 'config', + cmdDescription: 'Send a link to the config page', + title: 'SkinsRestorer Configuration', + url: 'https://skinsrestorer.net/docs/configuration', + description: 'Learn what each of the config options are for.', docs: true }, { - name: "storage", - cmdDescription: "Send a link to the storage page", - title: "SkinsRestorer Data Storage", - url: "https://skinsrestorer.net/docs/development/storage", - description: "Here is how data storage works in SkinsRestorer.", + name: 'storage', + cmdDescription: 'Send a link to the storage page', + title: 'SkinsRestorer Data Storage', + url: 'https://skinsrestorer.net/docs/development/storage', + description: 'Here is how data storage works in SkinsRestorer.', docs: true }, { - name: "launcher-issues", - cmdDescription: "Send a link to the launcher issues page", - title: "Launcher skin issues", - url: "https://skinsrestorer.net/docs/troubleshooting/launcher-issues", - description: "Here is how to fix skin issues with some launchers.", + name: 'launcher-issues', + cmdDescription: 'Send a link to the launcher issues page', + title: 'Launcher skin issues', + url: 'https://skinsrestorer.net/docs/troubleshooting/launcher-issues', + description: 'Here is how to fix skin issues with some launchers.', docs: true }, { - name: "tlauncher", - cmdDescription: "Explain how to fix TLauncher issues", - title: "TLauncher skin issues", - description: "TLauncher is malware. If you still want to use it, you have to know that its own skin system breaks SkinsRestorer. It simply ignores the skin set by SkinsRestorer in favor of its own skin system. You have to disable it in the TLauncher settings. A link to the documentation is below.", - url: "https://skinsrestorer.net/docs/troubleshooting/launcher-issues#tlauncher", + name: 'tlauncher', + cmdDescription: 'Explain how to fix TLauncher issues', + title: 'TLauncher skin issues', + description: 'TLauncher is malware. If you still want to use it, you have to know that its own skin system breaks SkinsRestorer. It simply ignores the skin set by SkinsRestorer in favor of its own skin system. You have to disable it in the TLauncher settings. A link to the documentation is below.', + url: 'https://skinsrestorer.net/docs/troubleshooting/launcher-issues#tlauncher', docs: true }, { - name: "downloads", - cmdDescription: "Send a link to the downloads page", - title: "Downloads", - url: "https://www.spigotmc.org/resources/skinsrestorer.2124/", - description: "You can download SkinsRestorer for Bukkit/Spigot/Paper, BungeeCord, Sponge and Velocity.", + name: 'downloads', + cmdDescription: 'Send a link to the downloads page', + title: 'Downloads', + url: 'https://www.spigotmc.org/resources/skinsrestorer.2124/', + description: 'You can download SkinsRestorer for Bukkit/Spigot/Paper, BungeeCord, Sponge and Velocity.', fields: [ { - key: "Dev downloads", - value: "https://ci.codemc.io/job/SkinsRestorer/job/SkinsRestorerX-DEV/" + key: 'Dev downloads', + value: 'https://ci.codemc.io/job/SkinsRestorer/job/SkinsRestorerX-DEV/' } ] }, { - name: "crowdin", - cmdDescription: "Send a link to the Crowdin page", - title: "Translating SkinsRestorer", - url: "https://translate.skinsrestorer.net", - description: "Translations for SkinsRestorer are managed on Crowdin. Any contributions are very welcome!" + name: 'crowdin', + cmdDescription: 'Send a link to the Crowdin page', + title: 'Translating SkinsRestorer', + url: 'https://translate.skinsrestorer.net', + description: 'Translations for SkinsRestorer are managed on Crowdin. Any contributions are very welcome!' }, { - name: "forge", - cmdDescription: "Send a message that Forge is not supported", - title: "Cauldron, Thermos, Forge + Bukkit Hacks, SpongeForge", + name: 'forge', + cmdDescription: 'Send a message that Forge is not supported', + title: 'Cauldron, Thermos, Forge + Bukkit Hacks, SpongeForge', description: "We don't support those! They are hacky and do not work with our plugin most of the time! Try Skinport or Offlineskin", docs: true }, { - name: "color-codes", - cmdDescription: "Send a link to a page with color codes", - title: "Colour Codes", - description: "A helpful list of all colour codes that you can use.", + name: 'color-codes', + cmdDescription: 'Send a link to a page with color codes', + title: 'Colour Codes', + description: 'A helpful list of all colour codes that you can use.', fields: [ { - key: "Colours", - value: "https://wiki.ess3.net/mc/" + key: 'Colours', + value: 'https://wiki.ess3.net/mc/' } ] }, { - name: "not-working", - cmdDescription: "Send a message that the plugin is not working", + name: 'not-working', + cmdDescription: 'Send a message that the plugin is not working', title: "Please tell us what's going on!", description: "We really would absolutely love to help you out! However, telling us that it isn't working wastes everyone's time. Please, just **describe the issue you're having clearly** and with as much detail as possible, and **send any relevant screenshots** of whatever problems you're having.", fields: [ { - key: "For sending us Console Errors:", - value: "https://pastes.dev/" + key: 'For sending us Console Errors:', + value: 'https://pastes.dev/' } ] }, { - name: "issue-tracker", - cmdDescription: "Send a link to the issue tracker", - title: "Suggestions and Bug Reports", - description: "If you would like to request a feature for SkinsRestorer, or report a bug, feel free to open an issue on GitHub!", + name: 'issue-tracker', + cmdDescription: 'Send a link to the issue tracker', + title: 'Suggestions and Bug Reports', + description: 'If you would like to request a feature for SkinsRestorer, or report a bug, feel free to open an issue on GitHub!', fields: [ { - key: "Issue Tracker:", - value: "https://github.com/SkinsRestorer/SkinsRestorerX/issues" + key: 'Issue Tracker:', + value: 'https://github.com/SkinsRestorer/SkinsRestorerX/issues' } ] }, { - name: "server-info", - cmdDescription: "Send a message with server info", - title: "Please take a screenshot!", - description: "Seeing a screenshot makes everything so much easier!", + name: 'server-info', + cmdDescription: 'Send a message with server info', + title: 'Please take a screenshot!', + description: 'Seeing a screenshot makes everything so much easier!', fields: [ { - key: "For SkinsRestorer info:", - value: "`/sr status`" + key: 'For SkinsRestorer info:', + value: '`/sr status`' }, { - key: "For server info:", - value: "`/version`" + key: 'For server info:', + value: '`/version`' } ] }, { - name: "paste-it", - cmdDescription: "Send a message with a link to a paste service", - title: "Please use a paste service!", - description: "Seeing a paste of the problem makes everything so much easier! Use https://pastes.dev/ for easy pasting!", + name: 'paste-it', + cmdDescription: 'Send a message with a link to a paste service', + title: 'Please use a paste service!', + description: 'Seeing a paste of the problem makes everything so much easier! Use https://pastes.dev/ for easy pasting!', fields: [ { - key: "For console errors:", + key: 'For console errors:', value: "Paste any relevant segments of the console log. If it's a startup error, this includes the entire startup log!" }, { - key: "Other errors:", - value: "Paste the entire SkinsRestorer config file (passwords removed) as well as any other relevant files!" + key: 'Other errors:', + value: 'Paste the entire SkinsRestorer config file (passwords removed) as well as any other relevant files!' } ] }, { - name: "just-ask", - cmdDescription: "Send a message that the user should just ask their question", - title: "Please ask your question!", + name: 'just-ask', + cmdDescription: 'Send a message that the user should just ask their question', + title: 'Please ask your question!', description: "Please ask the question you have. Don't ask to ask, or ask to DM someone. There are people here to help you, but we need to know what to help you with, so please just ask the question you want to in as much detail as possible!", fields: [ { - key: "Or, try here first:", - value: "https://skinsrestorer.net/docs" + key: 'Or, try here first:', + value: 'https://skinsrestorer.net/docs' }, { key: "Why shouldn't I ask to ask?", - value: "https://sol.gfxile.net/dontask.html" + value: 'https://sol.gfxile.net/dontask.html' } ] }, { - name: "no-wildcard", - cmdDescription: "Send a message that the user should not use the wildcard", - title: "Wildcard issues", + name: 'no-wildcard', + cmdDescription: 'Send a message that the user should not use the wildcard', + title: 'Wildcard issues', description: "Some plugins are created in a way which results in odd behaviour when the root '*' wildcard is used.", fields: [ { - key: "More information:", - value: "https://nucleuspowered.org/docs/nowildcard.html" + key: 'More information:', + value: 'https://nucleuspowered.org/docs/nowildcard.html' } ] }, { - name: "proxy-mode", - cmdDescription: "Send a message that explains Proxy Mode", - title: "SkinsRestorer Proxy Mode", - description: "SkinsRestorer Proxy Mode is one of the modes that SkinsRestorer can run in. It is used for servers in BungeeCord/Velocity networks.", + name: 'proxy-mode', + cmdDescription: 'Send a message that explains Proxy Mode', + title: 'SkinsRestorer Proxy Mode', + description: 'SkinsRestorer Proxy Mode is one of the modes that SkinsRestorer can run in. It is used for servers in BungeeCord/Velocity networks.', fields: [ { - key: "What does it do?", - value: "In this mode SkinsRestorer acts as a receiver of skin data from the proxy. By itself the plugin does not store any data on the server and only acts as a middleman between the proxy and the player.", + key: 'What does it do?', + value: 'In this mode SkinsRestorer acts as a receiver of skin data from the proxy. By itself the plugin does not store any data on the server and only acts as a middleman between the proxy and the player.' }, { - key: "What does it differently?", - value: "SkinsRestorer no longer stores data, does not have a API, and does not register commands. It will listen for messages for applying a skin and opening the skin GUI on a plugin messaging channel.", + key: 'What does it differently?', + value: 'SkinsRestorer no longer stores data, does not have a API, and does not register commands. It will listen for messages for applying a skin and opening the skin GUI on a plugin messaging channel.' }, { - key: "How do I use it?", - value: "SkinsRestorer Proxy Mode is automatically detected when the server is configured to only accept connections from proxies. Usually this is configured in `spigot.yml`, `paper.yml`, or `config/paper-global.yml`.", + key: 'How do I use it?', + value: 'SkinsRestorer Proxy Mode is automatically detected when the server is configured to only accept connections from proxies. Usually this is configured in `spigot.yml`, `paper.yml`, or `config/paper-global.yml`.' }, { key: "What if I don't want to use it?", - value: "If you don't put SkinsRestorer on your backend servers, your proxy will no longer be able to refresh your players skin without rejoining and the skin GUI will not work.", + value: "If you don't put SkinsRestorer on your backend servers, your proxy will no longer be able to refresh your players skin without rejoining and the skin GUI will not work." }, { - key: "What other options do I have?", - value: "You can use SkinsRestorer in standalone mode, which is the default mode, in that case you should not put the plugin on your proxy and you need to manually link your backend servers via MySQL.", + key: 'What other options do I have?', + value: 'You can use SkinsRestorer in standalone mode, which is the default mode, in that case you should not put the plugin on your proxy and you need to manually link your backend servers via MySQL.' } ] } diff --git a/modules/commands/index.ts b/modules/commands/index.ts index 4d78753..235db9c 100644 --- a/modules/commands/index.ts +++ b/modules/commands/index.ts @@ -1,8 +1,9 @@ -import {Client, ColorResolvable, EmbedBuilder, REST, Routes, SlashCommandBuilder} from 'discord.js' +import { Client, ColorResolvable, EmbedBuilder, PermissionFlagsBits, REST, Routes, SlashCommandBuilder } from 'discord.js' -import config from '../../config.json' +import config from 'config.json' import data from 'data.json' -import {ConfigCommand, configCommands} from "./commands.config"; +import { ConfigCommand, configCommands } from './commands.config' +import { getMetadata } from './metadata' const commands: ConfigCommand[] = configCommands.sort((a, b) => { if (a.name < b.name) return -1 @@ -10,29 +11,25 @@ const commands: ConfigCommand[] = configCommands.sort((a, b) => { return 0 }) -let metaData: { name?: string } = {} - -const fetchData = async (): Promise => { - try { - metaData = {...await (await fetch('https://api.spiget.org/v2/resources/2124/versions/latest')).json()} - } catch (e) { - console.error(e) - } -} - -await fetchData() -setInterval(fetchData, 60000) - const slashApiCommands: any[] = [ new SlashCommandBuilder() - .setName("help") - .setDescription("Show Steward help") + .setName('help') + .setDescription('Show Steward help') .addUserOption(option => option.setName('user').setDescription('Mention a specific user with the command')) .toJSON(), new SlashCommandBuilder() - .setName("latest") - .setDescription("Show latest version on SpigotMC") - .addUserOption(option => option.setName('user').setDescription('Mention a specific user with the command')) + .setName('latest') + .setDescription('Show latest version on SpigotMC') + .addUserOption(option => option + .setName('user') + .setDescription('Mention a specific user with the command') + ) + .toJSON(), + new SlashCommandBuilder() + .setName('resolved') + .setDescription('Moderator command to mark a forum post as resolved') + .setDefaultMemberPermissions(PermissionFlagsBits.ManageThreads) + .setDMPermission(false) .toJSON() ] @@ -40,7 +37,10 @@ for (const command of commands) { const slashCommand = new SlashCommandBuilder() .setName(command.name) .setDescription(command.cmdDescription) - .addUserOption(option => option.setName('user').setDescription('Mention a specific user with the command')) + .addUserOption(option => option + .setName('user') + .setDescription('Mention a specific user with the command') + ) slashApiCommands.push(slashCommand.toJSON()) } @@ -54,7 +54,7 @@ export default async (client: Client): Promise => { // The put method is used to fully refresh all commands in the guild with the current set const responseData = await rest.put( Routes.applicationCommands(config.clientId), - {body: slashApiCommands} + { body: slashApiCommands } ) as any console.log(`Successfully reloaded ${responseData.length} application (/) commands.`) @@ -68,6 +68,27 @@ export default async (client: Client): Promise => { // Ignore if trigger is blank if (trigger === '') return + if (trigger === 'resolved') { + const channel = interaction.channel + if (channel == null || !channel.isThread()) { + await interaction.reply('This command can only be used in threads.') + return + } + + if (channel.appliedTags.includes(config.resolvedTag)) { + await interaction.reply('This thread is already marked as resolved.') + return + } + + // Send a message before locking the thread, so we can still reply to it + await interaction.reply('This thread has been marked as resolved, locked and archived. Thank you for using SkinRestorer! For any future issues, please create a new post.') + await channel.setAppliedTags([...channel.appliedTags, config.resolvedTag]) + await channel.setLocked(true) + await channel.setArchived(true, 'resolved') + + return + } + const targetUser = interaction.options.getUser('user') // Initiate the embed @@ -77,9 +98,9 @@ export default async (client: Client): Promise => { embed .setColor(data.accent_color as ColorResolvable) .setTitle('Steward help') - .setDescription("Hi! :wave: I am Steward. Here to help out at SkinsRestorer. The code for commands can be [found on GitHub](https://github.com/SkinsRestorer/steward/tree/main/modules/commands)") + .setDescription('Hi! :wave: I am Steward. Here to help out at SkinsRestorer. The code for commands can be [found on GitHub](https://github.com/SkinsRestorer/steward/tree/main/modules/commands)') - await interaction.reply({embeds: [embed], ephemeral: true}) + await interaction.reply({ embeds: [embed], ephemeral: true }) return } @@ -87,9 +108,9 @@ export default async (client: Client): Promise => { embed .setColor(data.accent_color as ColorResolvable) .setTitle('Latest version') - .setDescription(`\`${metaData.name ?? 'Unknown'}\``) + .setDescription(`\`${getMetadata().name ?? 'Unknown'}\``) - await interaction.reply({embeds: [embed]}) + await interaction.reply({ embeds: [embed] }) return } @@ -122,19 +143,19 @@ export default async (client: Client): Promise => { }) if (item.url != null) { - embed.addFields([{name: 'Read more', value: item.url}]) + embed.addFields([{ name: 'Read more', value: item.url }]) } } else { embed.setTitle(`${item.title}`) if (item.url != null) { - embed.addFields([{name: 'Link', value: item.url}]) + embed.addFields([{ name: 'Link', value: item.url }]) } } if (item.fields != null) { item.fields.forEach(field => { - embed.addFields([{name: field.key, value: field.value, inline: false}]) + embed.addFields([{ name: field.key, value: field.value, inline: false }]) }) } @@ -143,6 +164,6 @@ export default async (client: Client): Promise => { message = `<@${targetUser.id}>` } - await interaction.reply({content: message, embeds: [embed]}) + await interaction.reply({ content: message, embeds: [embed] }) }) } diff --git a/modules/commands/metadata.ts b/modules/commands/metadata.ts new file mode 100644 index 0000000..99e55db --- /dev/null +++ b/modules/commands/metadata.ts @@ -0,0 +1,16 @@ +let metadata: { name?: string } = {} + +const fetchData = async (): Promise => { + try { + metadata = { ...await (await fetch('https://api.spiget.org/v2/resources/2124/versions/latest')).json() } + } catch (e) { + console.error(e) + } +} + +await fetchData() +setInterval(fetchData, 1_000 * 60) // 60 requests per hour + +export function getMetadata () { + return metadata +} diff --git a/modules/log.ts b/modules/log.ts index e44a427..465ab01 100644 --- a/modules/log.ts +++ b/modules/log.ts @@ -2,8 +2,8 @@ import { Client } from 'discord.js' import dateFormat from 'dateformat' import fs from 'fs' -const getLogFileName = (date: number) => 'logs/' + dateFormat(date, 'yyyy-mm-dd') + '.log' -const getLogFileTime = (date: number) => dateFormat(date, 'hh-MM-ss TT') +const getLogFileName = (date: number): string => 'logs/' + dateFormat(date, 'yyyy-mm-dd') + '.log' +const getLogFileTime = (date: number): string => dateFormat(date, 'hh-MM-ss TT') // noinspection JSUnusedGlobalSymbols export default (client: Client): void => { diff --git a/modules/post-help.ts b/modules/post-help.ts index 69df448..1c91289 100644 --- a/modules/post-help.ts +++ b/modules/post-help.ts @@ -1,7 +1,7 @@ -import {ChannelType, Client, EmbedBuilder} from 'discord.js' +import { ChannelType, Client, EmbedBuilder } from 'discord.js' // noinspection JSUnusedGlobalSymbols -export default (client: Client) => { +export default (client: Client): void => { client.on('threadCreate', async thread => { if (thread.parent?.type !== ChannelType.GuildForum) return @@ -47,8 +47,8 @@ export default (client: Client) => { value: 'We are a small team and cannot always respond immediately. If we do not respond within a few days, feel free to ping us. While you\'re waiting, you can chat with other users in <#199827109458214913>. :D' } ]) - embed.setFooter({text: 'If you have any questions, feel free to ask them here.'}) + embed.setFooter({ text: 'If you have any questions, feel free to ask them here.' }) - await thread.send({embeds: [embed]}) + await thread.send({ embeds: [embed] }) }) }