diff --git a/.env.example b/.env.example deleted file mode 100644 index dd4af59..0000000 --- a/.env.example +++ /dev/null @@ -1,3 +0,0 @@ -TOKEN= -GUILD= -CLIENT= \ No newline at end of file diff --git a/events/onReady.js b/events/onReady.js index 6472e58..815cd93 100644 --- a/events/onReady.js +++ b/events/onReady.js @@ -1,35 +1,46 @@ -const { ActivityType } = require('discord.js'); +const { ActivityType } = require("discord.js"); module.exports = { - name: 'ready', - once: true, - execute(client) { - console.log(`[CLIENT] Logged in as ${client.user.tag}!`); - status(client); + name: "ready", + once: true, + execute(client) { + console.log(`[CLIENT] Logged in as ${client.user.tag}!`); + status(client); - client.guilds.fetch(process.env.GUILD).then(guild => { - guild.channels - .fetch('1006080822215966741') - .then(channel => { - channel.setName(`User Count: ${guild.memberCount - guild.members.cache.filter(m => m.user.bot).size}`).catch(e => console.error(`[ERROR]: ${e}`)); - }) - .catch(e => console.error(`[ERROR]: ${e}`)); - }); - } + client.guilds.fetch(process.env.GUILD).then((guild) => { + guild.channels + .fetch("1006080822215966741") + .then((channel) => { + channel + .setName( + `User Count: ${guild.memberCount - guild.members.cache.filter((m) => m.user.bot).size}`, + ) + .catch((e) => console.error(`[ERROR]: ${e}`)); + }) + .catch((e) => console.error(`[ERROR]: ${e}`)); + }); + }, }; function status(client) { - setInterval(() => { - let key = [ - { type: ActivityType.Watching, data: 'people not read FAQ' }, - { type: ActivityType.Watching, data: 'devs push back releases' }, - { type: ActivityType.Playing, data: 'PlayCover' }, - { type: ActivityType.Playing, data: 'with roeegh' }, - { type: ActivityType.Playing, data: 'with depression' } - ]; - let rand = key[Math.floor(Math.random() * key.length)]; + setInterval(() => { + let key = [ + { type: ActivityType.Watching, data: "people not read FAQ" }, + { type: ActivityType.Watching, data: "devs push back releases" }, + { type: ActivityType.Playing, data: "PlayCover" }, + { type: ActivityType.Playing, data: "gacha games" }, + ]; + let rand = key[Math.floor(Math.random() * key.length)]; - client.user.setPresence({ activities: [{ name: rand.data, type: rand.type }] }); - }, 5 * 60000); - setTimeout(() => client.user.setPresence({ activities: [{ name: '/help', type: ActivityType.Watching }] }), 60000); + client.user.setPresence({ + activities: [{ name: rand.data, type: rand.type }], + }); + }, 5 * 60000); + setTimeout( + () => + client.user.setPresence({ + activities: [{ name: "/help", type: ActivityType.Watching }], + }), + 60000, + ); } diff --git a/events/threadCreate.js b/events/threadCreate.js index 4021492..c98cbc4 100644 --- a/events/threadCreate.js +++ b/events/threadCreate.js @@ -1,17 +1,43 @@ +const { EmbedBuilder } = require("discord.js"); + module.exports = { - name: 'threadCreate', - async execute(channel) { - if (channel.parentId != '1019859452352020540') return; + name: "threadCreate", + async execute(channel) { + if (channel.parentId != "1019859452352020540") return; + + try { + const templateCheckFalse = new EmbedBuilder() + .setDescription( + `You have created a post without using the required template. Support to your issue might be delayed.`, + ) + .setTimestamp() + .setFooter({ + text: `Post template not used.`, + iconURL: `https://i.imgur.com/ZdGKYWh.png`, + }) + .setColor("#e6ce1c"); + + const useSolveCommand = new EmbedBuilder() + .setDescription( + `Please use \`/solved\` to delete this post when your issue has been resolved.`, + ) + .setTimestamp() + .setColor("#78D7A3"); - try { - let templateCheck = await channel.messages - .fetch() - .then(messages => messages.filter(message => message.author.id === channel.ownerId)) - .then(msg => { - return msg.first().content; - }); - !templateCheck.includes('I have read the documentation and searched for previously created posts about this') ? channel.send('You have created a post without using the required template.') : null; - channel.send("Please use `/solved` to delete this post when you're done."); - } catch (e) {} - } + let templateCheck = await channel.messages + .fetch() + .then((messages) => + messages.filter((message) => message.author.id === channel.ownerId), + ) + .then((msg) => { + return msg.first().content; + }); + !templateCheck.includes( + "I have read the documentation and searched for previously created posts about this", + ) + ? channel.send({ embeds: [templateCheckFalse] }) + : null; + channel.send({ embeds: [useSolveCommand] }); + } catch (e) {} + }, }; diff --git a/interactions/slash/users/clt.js b/interactions/slash/users/clt.js deleted file mode 100644 index 7d24343..0000000 --- a/interactions/slash/users/clt.js +++ /dev/null @@ -1,39 +0,0 @@ -const { EmbedBuilder, SlashCommandBuilder } = require('discord.js'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('clt') - .setDescription('How to install Xcode Command Line Tools') - .addUserOption(option => option.setName('user').setDescription('User to ping in reply')), - - async execute(interaction) { - let user = interaction.options.getUser('user'); - - return interaction - .reply({ - content: user ? `${user.toString()}, ${interaction.member.toString()} wanted you to see this command` : null, - allowedMentions: { users: [user ? user.id : null] }, - embeds: [ - new EmbedBuilder() - .setAuthor({ name: `Requested by: ${interaction.member.nickname}`, iconURL: interaction.user.avatarURL() }) - .setTitle('How to install Xcode Command Line Tools') - .setDescription( - ` - ➤ **Command + Space** on your keyboard - ➤ Type **Terminal** - ➤ Type or copy+paste the following command: - \`\`\`xcode-select --install\`\`\` - ➤ Input your password - ➤ Press \`install\` and agree to the terms and conditions - ➤ The install time you will see is very misleading, it should take from 10 to 60 minutes depending on your internet connection. - ➤ **Enjoy!** - ➤ *If you are having issues or just want to ask questions, you can always go to <#1019859452352020540> for help!* - ` - ) - .setColor('Random') - ], - ephemeral: user ? false : true - }) - .catch(error => console.error(`[ERROR]: ${error}`)); - } -}; diff --git a/interactions/slash/users/docs.js b/interactions/slash/users/docs.js index 1f1b9d2..b58b72d 100644 --- a/interactions/slash/users/docs.js +++ b/interactions/slash/users/docs.js @@ -1,34 +1,50 @@ -const { EmbedBuilder, SlashCommandBuilder } = require('discord.js'); +const { EmbedBuilder, SlashCommandBuilder } = require("discord.js"); module.exports = { - data: new SlashCommandBuilder() - .setName('docs') - .setDescription('Get the link to the PlayCover Documentation (PlayBook)') - .addStringOption(option => option.setName('page').setDescription('Specify a Doc page').setAutocomplete(true)) - .addUserOption(option => option.setName('user').setDescription('User to ping in reply')), + data: new SlashCommandBuilder() + .setName("docs") + .setDescription("Get the link to the PlayCover Documentation (PlayBook)") + .addStringOption((option) => + option + .setName("page") + .setDescription("Specify a Doc page") + .setAutocomplete(true), + ) + .addUserOption((option) => + option.setName("user").setDescription("User to ping in reply"), + ), - async execute(interaction) { - let specified = interaction.options.getString('page'); - let user = interaction.options.getUser('user'); - let embed = new EmbedBuilder(); + async execute(interaction) { + let specified = interaction.options.getString("page"); + let user = interaction.options.getUser("user"); + let embed = new EmbedBuilder(); - if (specified) { - embed - .setTitle(`${specified}`) - .setDescription(`[Click here to open this page on PlayBook](https://${require('../../../resources/pages.json').find(page => page.name == specified).url})`) - .setAuthor({ name: 'PlayCover Documentation' }) - .setThumbnail(interaction.guild.iconURL()); - } else { - embed.setTitle('Click here to open PlayBook').setURL('https://docs.playcover.io/').setAuthor({ name: 'PlayCover Documentation' }).setThumbnail(interaction.guild.iconURL()).setColor('Random'); - } + if (specified) { + embed + .setTitle(`${specified}`) + .setDescription( + `[Click here to open this page on PlayBook](https://${require("../../../resources/pages.json").find((page) => page.name == specified).url})`, + ) + .setAuthor({ name: "PlayCover Documentation" }) + .setThumbnail(interaction.guild.iconURL()); + } else { + embed + .setTitle("Click here to open PlayBook") + .setURL("https://docs.playcover.io/") + .setAuthor({ name: "PlayCover Documentation" }) + .setThumbnail(interaction.guild.iconURL()) + .setColor("Random"); + } - return interaction - .reply({ - content: user ? `${user.toString()}, ${interaction.member.toString()} wanted you to see this command` : null, - allowedMentions: { users: [user ? user.id : null] }, - embeds: [embed], - ephemeral: user ? false : true - }) - .catch(error => console.error(`[ERROR]: ${error}`)); - } + return interaction + .reply({ + content: user + ? `${user.toString()}, ${interaction.member.toString()} wanted you to see the documentation` + : null, + allowedMentions: { users: [user ? user.id : null] }, + embeds: [embed], + ephemeral: user ? false : true, + }) + .catch((error) => console.error(`[ERROR]: ${error}`)); + }, }; diff --git a/interactions/slash/users/download.js b/interactions/slash/users/download.js index 77e721b..8fcf9de 100644 --- a/interactions/slash/users/download.js +++ b/interactions/slash/users/download.js @@ -1,49 +1,96 @@ -const { EmbedBuilder, SlashCommandBuilder, AttachmentBuilder } = require('discord.js'); -const stableAndPre = new AttachmentBuilder('./resources/stable.png'); -const nightly = new AttachmentBuilder('./resources/nightly.png'); +const { + EmbedBuilder, + SlashCommandBuilder, + AttachmentBuilder, +} = require("discord.js"); module.exports = { - data: new SlashCommandBuilder() - .setName('download') - .setDescription('Get the download link for PlayCover') - .addStringOption(option => option.setName('release').setDescription('The release of PlayCover you want to download').setRequired(true).addChoices({ name: 'Stable', value: 'stable' }, { name: 'Pre-Release', value: 'pre-release' }, { name: 'Nightly', value: 'nightly' })) - .addUserOption(option => option.setName('user').setDescription('User to ping in reply')), + data: new SlashCommandBuilder() + .setName("download") + .setDescription("Get the download link for PlayCover") + .addStringOption((option) => + option + .setName("release") + .setDescription("The release of PlayCover you want to download") + .setRequired(true) + .addChoices( + { name: "Stable", value: "stable" }, + { name: "Nightly", value: "nightly" }, + ), + ) + .addUserOption((option) => + option.setName("user").setDescription("User to ping in reply"), + ), - async execute(interaction) { - var title, description, thumbnail, file; - const release = interaction.options.getString('release'); - const user = interaction.options.getUser('user'); - const releaseData = await fetch('https://api.github.com/repos/playcover/playcover/releases').then(res => res.json()); + async execute(interaction) { + var title, url, author, color, description, icon; + const release = interaction.options.getString("release"); + const user = interaction.options.getUser("user"); + const releaseData = await fetch( + "https://api.github.com/repos/playcover/playcover/releases", + ).then((res) => res.json()); - switch (release) { - case 'stable': - title = 'Stable'; - description = `[Click here to download](${releaseData.filter(release => release.prerelease === false)[0].assets[0].browser_download_url})`; - thumbnail = 'attachment://stable.png'; - file = stableAndPre; - break; - case 'pre-release': - title = 'Pre-Release'; - description = `[Click here to download](${releaseData.filter(release => release.prerelease === true)[0].assets[0].browser_download_url})`; - thumbnail = 'attachment://stable.png'; - file = stableAndPre; - break; - case 'nightly': - title = 'Nightly'; - description = `[Click here to download](https://nightly.link/playcover/playcover/workflows/2.nightly_release/develop)`; - thumbnail = 'attachment://nightly.png'; - file = nightly; - break; - } + switch (release) { + case "stable": + title = `**Click here to download**`; + url = `${releaseData.filter((release) => release.prerelease === false)[0].assets[0].browser_download_url}`; + author = `PlayCover - Stable`; + description = `**Common errors:**`; + color = `#78D7A3`; + icon = `https://i.imgur.com/yaDJci8.png`; + break; - return interaction - .reply({ - content: user ? `${user.toString()}, ${interaction.member.toString()} wanted you to see this command` : null, - allowedMentions: { users: [user ? user.id : null] }, - embeds: [new EmbedBuilder().setTitle(title).setDescription(description).setThumbnail(thumbnail).setColor('Random')], - ephemeral: user ? false : true, - files: [file] - }) - .catch(error => console.error(`[ERROR]: ${error}`)); - } + case "nightly": + title = `**Click here to download**`; + url = `https://nightly.link/playcover/playcover/workflows/2.nightly_release/develop`; + author = `PlayCover - Nightly`; + description = `**What is nightly build?**\nA build of PlayCover created every night(hence the word nightly). It is the most up-to-date version of PlayCover with the latest features, however it may have severe game-breaking bugs. It is recommended that you use nightly builds only if you know what you are doing.\n\n**Common errors:**`; + color = `#F0C44B`; + icon = `https://i.imgur.com/V7lY78f.png`; + break; + } + + return interaction + .reply({ + content: user + ? `${user.toString()}, ${interaction.member.toString()} wanted you to see this command` + : null, + allowedMentions: { users: [user ? user.id : null] }, + embeds: [ + new EmbedBuilder() + .setTitle(title) + .setURL(url) + .setAuthor({ + name: author, + iconURL: icon, + }) + .setDescription(description) + .addFields( + { + name: "Apple can't check app for malicious software", + value: ` + This error occours because PlayCover is not signed. + To override this warning: + 1. Open \`System Settings\` on your Mac\n2. Open \`Privacy & Security\` tab in System Settings\n3. Scroll down and click \`Open Anyway\``, + inline: true, + }, + { + name: "PlayCover Damaged and Can\’t Be Opened", + value: ` + To fix this error: + 1. Press \`Command + Space\` on your keyboard\n2. Type \`Terminal\` and press return\n3. Enter the following command: \`xattr -c /Applications/PlayCover.app\``, + inline: true, + }, + ) + .setTimestamp() + .setFooter({ + text: "macOS Beta builds are not supported by PlayCover", + iconURL: "https://i.imgur.com/ZdGKYWh.png", + }) + .setColor(color), + ], + ephemeral: user ? false : true, + }) + .catch((error) => console.error(`[ERROR]: ${error}`)); + }, }; diff --git a/interactions/slash/users/keymap.js b/interactions/slash/users/keymap.js index 24fcfe1..f24945b 100644 --- a/interactions/slash/users/keymap.js +++ b/interactions/slash/users/keymap.js @@ -1,21 +1,60 @@ -const { EmbedBuilder, SlashCommandBuilder } = require('discord.js'); +const { EmbedBuilder, SlashCommandBuilder } = require("discord.js"); module.exports = { - data: new SlashCommandBuilder() - .setName('keymap') - .setDescription('Information about the keymapping system') - .addStringOption(option => option.setName('keymap').setDescription('Premade keymaps').setAutocomplete(true)) - .addUserOption(option => option.setName('user').setDescription('User to ping in reply')), + data: new SlashCommandBuilder() + .setName("keymap") + .setDescription("Information about the keymapping system") + .addStringOption((option) => + option + .setName("keymap") + .setDescription("Premade keymaps") + .setAutocomplete(true), + ) + .addUserOption((option) => + option.setName("user").setDescription("User to ping in reply"), + ), - async execute(interaction) { - let game = interaction.options.getString('keymap'); - let user = interaction.options.getUser('user'); - let embed = new EmbedBuilder(); + async execute(interaction) { + let game = interaction.options.getString("keymap"); + let user = interaction.options.getUser("user"); + let embed = new EmbedBuilder(); - if (game) { - embed.setTitle(`${game} Keymap`).setDescription(`[Download Here](https://${require('../../../resources/keymaps.json').find(keymap => keymap.name == game).url})`); - } else { - embed.setTitle('Keymapping FAQ').setDescription(` + if (game) { + embed + .setThumbnail("https://playcover.io/PlayCover-Square.png") + .setDescription( + `## [Click here to download keymapping for ${game}](https://${ + require("../../../resources/keymaps.json").find( + (keymap) => keymap.name == game, + ).url + })`, + ) + .addFields( + { + name: "Encountering a problem?", + value: + "If you are facing keymapping issues, please make sure you are on macOS 13.1 or above. If so, please make a support post in <#1019859452352020540>", + inline: true, + }, + { + name: "How to import keymapping", + value: `1. In PlayCover, \`right click/control click\` ${game} \n2. Select \`Import Keymapping\` from the drop down menu\n3. Navigate the keymap you just downloaded and press \`Open\`.\nFor further information, please read the [docs](https://docs.playcover.io/keymapping/using_making_keymaps).`, + inline: true, + }, + ) + .addFields({ + name: "\u200B", + value: "# Here's how to download the keymaps:", + }) + .setImage("https://i.imgur.com/QsOX6gl.gif") + .setFooter({ + text: `Keymap for ${game}`, + iconURL: `https://i.imgur.com/TS5tXcv.png`, + }) + .setTimestamp() + .setColor(`#78D7A3`); + } else { + embed.setTitle("Keymapping FAQ").setDescription(` ➤ \`Command (CMD) + K\` — Toggle keymapping mode **Button Events:** @@ -34,15 +73,17 @@ module.exports = { ➤ \`Command (CMD) + Delete (Backspace)\` — Delete the selected keymapping ➤ \`Press option (⌥)\` — Toggle between show/hide cursor `); - } + } - return interaction - .reply({ - content: user ? `${user.toString()}, ${interaction.member.toString()} wanted you to see this command` : null, - allowedMentions: { users: [user ? user.id : null] }, - embeds: [embed], - ephemeral: user ? false : true - }) - .catch(error => console.error(`[ERROR]: ${error}`)); - } + return interaction + .reply({ + content: user + ? `${user.toString()}, ${interaction.member.toString()} wanted you to check out this keymap:` + : null, + allowedMentions: { users: [user ? user.id : null] }, + embeds: [embed], + ephemeral: user ? false : true, + }) + .catch((error) => console.error(`[ERROR]: ${error}`)); + }, }; diff --git a/interactions/slash/users/nvram.js b/interactions/slash/users/nvram.js deleted file mode 100644 index 308fca7..0000000 --- a/interactions/slash/users/nvram.js +++ /dev/null @@ -1,39 +0,0 @@ -const { EmbedBuilder, SlashCommandBuilder } = require('discord.js'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('nvram') - .setDescription('Setup Boot Arguments') - .addUserOption(option => option.setName('user').setDescription('User to ping in reply')), - - async execute(interaction) { - let user = interaction.options.getUser('user'); - - return interaction - .reply({ - content: user ? `${user.toString()}, ${interaction.member.toString()} wanted you to see this command` : null, - allowedMentions: { users: [user ? user.id : null] }, - embeds: [ - new EmbedBuilder() - .setAuthor({ name: `Requested by: ${interaction.member.nickname}`, iconURL: interaction.user.avatarURL() }) - .setTitle('How to input the recommended nvram boot-args:') - .setDescription( - ` - ➤ **Command + Space** on your keyboard - ➤ Type **Terminal** - ➤ Type or copy+paste the following command: - \`\`\`sudo nvram boot-args="amfi_get_out_of_my_way=0x1 ipc_control_port_options=0"\`\`\` - ➤ Input your password - ➤ If it seems like nothing happened, **that's expected** and correct - ➤ Restart your mac - ➤ **Enjoy!** - ➤ *If you are having issues or just want to ask questions, you can always go to <#1019859452352020540> for help!* - ` - ) - .setColor('Random') - ], - ephemeral: user ? false : true - }) - .catch(error => console.error(`[ERROR]: ${error}`)); - } -}; diff --git a/interactions/slash/users/setup.js b/interactions/slash/users/setup.js deleted file mode 100644 index e9606f6..0000000 --- a/interactions/slash/users/setup.js +++ /dev/null @@ -1,64 +0,0 @@ -const { EmbedBuilder, SlashCommandBuilder } = require('discord.js'); - -module.exports = { - data: new SlashCommandBuilder() - .setName('setup') - .setDescription('How to setup Genshin Impact in PlayCover') - .addUserOption(option => option.setName('user').setDescription('User to ping in reply')), - - async execute(interaction) { - let user = interaction.options.getUser('user'); - - return interaction - .reply({ - content: user ? `${user.toString()}, ${interaction.member.toString()} wanted you to see this command` : null, - allowedMentions: { users: [user ? user.id : null] }, - embeds: [ - new EmbedBuilder() - .setAuthor({ name: `Requested by: ${interaction.member.nickname}`, iconURL: interaction.user.avatarURL() }) - .setTitle('How to setup Genshin Impact in PlayCover') - .setDescription( - ` - **1. Disable SIP** - ➤ This can be done by shutting down your mac, holding down power button - ➤ After this, click on your username/ssd, then keep going until you can see \`Utilities\` at the top - ➤ When you see this, click on it and click on \`Terminal\` - ➤ After this, you should be in a terminal window - ➤ Type \`csrutil disable\` in that terminal window - ➤ It will ask for your mac username, type it and press return - ➤ Then if will ask for that user's password, type it and press return - ➤ Your password will not be shown on screen, so don't panic! - ➤ Click on Apple logo on the top and Restart your mac - **2. Allow the nvram boot-args** - ➤ When you have SIP Disabled (this command only works with SIP disabled), do the following steps: - ➤ *Command + Space*; type "Terminal" in the search box - ➤ It should open a normal terminal window - ➤ Type the following in this window (or copy paste it) - \`\`\`sudo nvram boot-args="amfi_get_out_of_my_way=0x1 ipc_control_port_options=0"\`\`\` - ➤ If it appears that nothing has happened, this is correct. - ➤ **Now restart your Mac once again** - **3. Login to Genshin** - ➤ Open Genshin Impact with PlayCover, and you should be greeted with a **Login** button - ➤ Login to your account, then wait until the door appears and quit the game with **Command + Q** - ➤ Thats all which is required in Genshin for now - **4. Enable SIP Again** - ➤ Shut down your Mac again - ➤ Hold down the power button until you get to recovery options - ➤ Click on your username and your storage disk respectively like you did for step 1. - ➤ You should see \`Utilities\` at the top - ➤ Click on it, and Click on \`Terminal\` - ➤ In terminal, type the following: \`csrutil enable\` - ➤ \`csrutil clear\` should also work - ➤ Reboot your Mac by going to Apple Logo>Restart - **5. Open Genshin** - ➤ You're done! Enjoy playing genshin! - ➤ *If you are having issues or just want to ask questions, you can always go to <#1019859452352020540> for help!* - ` - ) - .setColor('Random') - ], - ephemeral: user ? false : true - }) - .catch(error => console.error(`[ERROR]: ${error}`)); - } -}; diff --git a/interactions/slash/users/solved.js b/interactions/slash/users/solved.js index a85e210..80d6055 100644 --- a/interactions/slash/users/solved.js +++ b/interactions/slash/users/solved.js @@ -1,8 +1,22 @@ -const { SlashCommandBuilder } = require('discord.js'); +const { SlashCommandBuilder, EmbedBuilder } = require("discord.js"); module.exports = { - data: new SlashCommandBuilder().setName('solved').setDescription('Close a post once it has been solved'), - async execute(interaction) { - interaction.channel.ownerId === interaction.user.id ? interaction.channel.delete() : interaction.reply({ content: 'You can only delete your own posts.', ephemeral: true }); - } + data: new SlashCommandBuilder() + .setName("solved") + .setDescription("Close a post once it has been solved"), + + async execute(interaction) { + const errorEmbed = new EmbedBuilder() + .setColor("#cf3838") + .setDescription("You can only delete your own posts.") + .setFooter({ + text: "An error occurred", + iconURL: "https://i.imgur.com/fdzF9QP.png", + }) + .setTimestamp(); + + interaction.channel.ownerId === interaction.user.id + ? interaction.channel.delete() + : interaction.reply(errorEmbed); + }, }; diff --git a/package.json b/package.json index 91fe07c..11d107b 100644 --- a/package.json +++ b/package.json @@ -1,36 +1,36 @@ { - "name": "puck", - "version": "1.1.0", - "description": "an Artificial Spirit", - "types": "./typings.d.ts", - "main": "puck.js", - "scripts": { - "start": "node puck.js", - "dev": "nodemon puck.js", - "u": "taze major -IR" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/PlayCover/Puck.git" - }, - "keywords": [ - "PlayCover", - "Puck" - ], - "author": { - "name": "Roeegh", - "url": "https://github.com/roeegh", - "email": "admin@roeegh.dev" - }, - "license": "GPL-3.0", - "dependencies": { - "@discordjs/rest": "^1.7.0", - "discord-api-types": "^0.37.39", - "discord.js": "^14.9.0", - "dotenv": "^16.0.3" - }, - "devDependencies": { - "nodemon": "^2.0.22", - "taze": "^0.9.1" - } + "name": "puck", + "version": "1.1.0", + "description": "an Artificial Spirit", + "types": "./typings.d.ts", + "main": "puck.js", + "scripts": { + "start": "node puck.js", + "dev": "nodemon puck.js", + "u": "taze major -IR" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/PlayCover/Puck.git" + }, + "keywords": [ + "PlayCover", + "Puck" + ], + "author": "PlayCover", + "license": "GPL-3.0", + "dependencies": { + "@discordjs/rest": "^1.7.0", + "discord-api-types": "^0.37.39", + "discord.js": "^14.10.2", + "dotenv": "^16.0.3" + }, + "devDependencies": { + "nodemon": "^2.0.22", + "taze": "^0.9.1" + }, + "bugs": { + "url": "https://github.com/PlayCover/Puck/issues" + }, + "homepage": "https://github.com/PlayCover/Puck#readme" } diff --git a/puck.js b/puck.js index db866c7..711b0b6 100644 --- a/puck.js +++ b/puck.js @@ -1,13 +1,29 @@ -require('dotenv').config(); -const fs = require('fs'); -const { Client, Collection, GatewayIntentBits, Partials, Options } = require('discord.js'); -const { REST } = require('@discordjs/rest'); -const { Routes } = require('discord-api-types/v9'); +require("dotenv").config(); +const fs = require("fs"); +const { + Client, + Collection, + GatewayIntentBits, + Partials, + Options, + EmbedBuilder, + AttachmentBuilder, +} = require("discord.js"); +const { REST } = require("@discordjs/rest"); +const { Routes } = require("discord-api-types/v9"); +const usecommand = new AttachmentBuilder("./resources/usecommands.gif"); const client = new Client({ - intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessages, GatewayIntentBits.GuildMessageReactions, GatewayIntentBits.GuildPresences, GatewayIntentBits.MessageContent], - partials: [Partials.Reaction, Partials.Message, Partials.User], - makeCache: Options.cacheEverything() + intents: [ + GatewayIntentBits.Guilds, + GatewayIntentBits.GuildMembers, + GatewayIntentBits.GuildMessages, + GatewayIntentBits.GuildMessageReactions, + GatewayIntentBits.GuildPresences, + GatewayIntentBits.MessageContent, + ], + partials: [Partials.Reaction, Partials.Message, Partials.User], + makeCache: Options.cacheEverything(), }); client.slashCommands = new Collection(); @@ -17,112 +33,186 @@ client.modalCommands = new Collection(); client.autocompleteInteractions = new Collection(); try { - const eventFiles = fs.readdirSync('./events').filter(file => file.endsWith('.js')); - - for (const file of eventFiles) { - const event = require(`./events/${file}`); - if (event.once) { - client.once(event.name, (...args) => event.execute(...args, client)); - } else { - client.on(event.name, async (...args) => await event.execute(...args, client)); - } - } - console.log('[CLIENT] All Events Loaded.'); + const eventFiles = fs + .readdirSync("./events") + .filter((file) => file.endsWith(".js")); + + for (const file of eventFiles) { + const event = require(`./events/${file}`); + if (event.once) { + client.once(event.name, (...args) => event.execute(...args, client)); + } else { + client.on( + event.name, + async (...args) => await event.execute(...args, client), + ); + } + } + console.log("[CLIENT] All Events Loaded."); } catch (error) { - console.log(`[ERROR] Failed to Load Events: ${error.toString().substring(7)}`); + console.log( + `[ERROR] Failed to Load Events: ${error.toString().substring(7)}`, + ); } try { - const slashCommands = fs.readdirSync('./interactions/slash'); - - for (const module of slashCommands) { - const commandFiles = fs.readdirSync(`./interactions/slash/${module}`).filter(file => file.endsWith('.js')); - - for (const commandFile of commandFiles) { - const command = require(`./interactions/slash/${module}/${commandFile}`); - client.slashCommands.set(command.data.name, command); - } - } - console.log('[CLIENT] All Slash Commands Loaded.'); + const slashCommands = fs.readdirSync("./interactions/slash"); + + for (const module of slashCommands) { + const commandFiles = fs + .readdirSync(`./interactions/slash/${module}`) + .filter((file) => file.endsWith(".js")); + + for (const commandFile of commandFiles) { + const command = require(`./interactions/slash/${module}/${commandFile}`); + client.slashCommands.set(command.data.name, command); + } + } + console.log("[CLIENT] All Slash Commands Loaded."); } catch (error) { - console.log(`[ERROR] Failed to Load Slash Commands: ${error.toString().substring(7)}`); + console.log( + `[ERROR] Failed to Load Slash Commands: ${error.toString().substring(7)}`, + ); } try { - const autocompleteInteractions = fs.readdirSync('./interactions/autocomplete'); - - for (const module of autocompleteInteractions) { - const files = fs.readdirSync(`./interactions/autocomplete/${module}`).filter(file => file.endsWith('.js')); - - for (const interactionFile of files) { - const interaction = require(`./interactions/autocomplete/${module}/${interactionFile}`); - client.autocompleteInteractions.set(interaction.name, interaction); - } - } - console.log('[CLIENT] All Autocomplete Interactions Loaded.'); + const autocompleteInteractions = fs.readdirSync( + "./interactions/autocomplete", + ); + + for (const module of autocompleteInteractions) { + const files = fs + .readdirSync(`./interactions/autocomplete/${module}`) + .filter((file) => file.endsWith(".js")); + + for (const interactionFile of files) { + const interaction = require( + `./interactions/autocomplete/${module}/${interactionFile}`, + ); + client.autocompleteInteractions.set(interaction.name, interaction); + } + } + console.log("[CLIENT] All Autocomplete Interactions Loaded."); } catch (error) { - console.log(`[ERROR] Failed to Load Autocomplete Interactions: ${error.toString().substring(7)}`); + console.log( + `[ERROR] Failed to Load Autocomplete Interactions: ${error.toString().substring(7)}`, + ); } try { - const buttonCommands = fs.readdirSync('./interactions/buttons'); - - for (const module of buttonCommands) { - const commandFiles = fs.readdirSync(`./interactions/buttons/${module}`).filter(file => file.endsWith('.js')); - - for (const commandFile of commandFiles) { - const command = require(`./interactions/buttons/${module}/${commandFile}`); - client.buttonCommands.set(command.id, command); - } - } - - console.log('[CLIENT] All Button Interactions Loaded.'); + const buttonCommands = fs.readdirSync("./interactions/buttons"); + + for (const module of buttonCommands) { + const commandFiles = fs + .readdirSync(`./interactions/buttons/${module}`) + .filter((file) => file.endsWith(".js")); + + for (const commandFile of commandFiles) { + const command = require( + `./interactions/buttons/${module}/${commandFile}`, + ); + client.buttonCommands.set(command.id, command); + } + } + + console.log("[CLIENT] All Button Interactions Loaded."); } catch (error) { - console.log(`[ERROR] Failed to Load Button Interactions: ${error.toString().substring(7)}`); + console.log( + `[ERROR] Failed to Load Button Interactions: ${error.toString().substring(7)}`, + ); } try { - const modalCommands = fs.readdirSync('./interactions/modals'); - - for (const module of modalCommands) { - const commandFiles = fs.readdirSync(`./interactions/modals/${module}`).filter(file => file.endsWith('.js')); - - for (const commandFile of commandFiles) { - const command = require(`./interactions/modals/${module}/${commandFile}`); - client.modalCommands.set(command.id, command); - } - } - console.log('[CLIENT] All Modal Interactions Loaded.'); + const modalCommands = fs.readdirSync("./interactions/modals"); + + for (const module of modalCommands) { + const commandFiles = fs + .readdirSync(`./interactions/modals/${module}`) + .filter((file) => file.endsWith(".js")); + + for (const commandFile of commandFiles) { + const command = require(`./interactions/modals/${module}/${commandFile}`); + client.modalCommands.set(command.id, command); + } + } + console.log("[CLIENT] All Modal Interactions Loaded."); } catch (error) { - console.log(`[ERROR] Failed to Load Modal Interactions: ${error.toString().substring(7)}`); + console.log( + `[ERROR] Failed to Load Modal Interactions: ${error.toString().substring(7)}`, + ); } try { - const selectMenus = fs.readdirSync('./interactions/select-menus'); - - for (const module of selectMenus) { - const commandFiles = fs.readdirSync(`./interactions/select-menus/${module}`).filter(file => file.endsWith('.js')); - for (const commandFile of commandFiles) { - const command = require(`./interactions/select-menus/${module}/${commandFile}`); - client.selectCommands.set(command.id, command); - } - } - console.log('[CLIENT] All Select Menus Loaded.'); + const selectMenus = fs.readdirSync("./interactions/select-menus"); + + for (const module of selectMenus) { + const commandFiles = fs + .readdirSync(`./interactions/select-menus/${module}`) + .filter((file) => file.endsWith(".js")); + for (const commandFile of commandFiles) { + const command = require( + `./interactions/select-menus/${module}/${commandFile}`, + ); + client.selectCommands.set(command.id, command); + } + } + console.log("[CLIENT] All Select Menus Loaded."); } catch (error) { - console.log(`[ERROR] Failed to Load Select Menus Interactions: ${error.toString().substring(7)}`); + console.log( + `[ERROR] Failed to Load Select Menus Interactions: ${error.toString().substring(7)}`, + ); } -const rest = new REST({ version: '9' }).setToken(process.env.TOKEN); +const rest = new REST({ version: "9" }).setToken(process.env.TOKEN); (async () => { - try { - // await rest.put(Routes.applicationGuildCommands(process.env.CLIENT, process.env.GUILD), { body: [...Array.from(client.slashCommands.values()).map(c => c.data.toJSON())] }); - await rest.put(Routes.applicationCommands(process.env.CLIENT), { body: [...Array.from(client.slashCommands.values()).map(c => c.data.toJSON())] }); - - console.log('[CLIENT] All Slash Commands Registered.'); - } catch (error) { - console.log(`[ERROR] Registering Slash Commands: ${error.toString().substring(7)}`); - } + try { + // await rest.put(Routes.applicationGuildCommands(process.env.CLIENT, process.env.GUILD), { body: [...Array.from(client.slashCommands.values()).map(c => c.data.toJSON())] }); + await rest.put(Routes.applicationCommands(process.env.CLIENT), { + body: [ + ...Array.from(client.slashCommands.values()).map((c) => + c.data.toJSON(), + ), + ], + }); + + console.log("[CLIENT] All Slash Commands Registered."); + } catch (error) { + console.log( + `[ERROR] Registering Slash Commands: ${error.toString().substring(7)}`, + ); + } })(); +const prefix = "."; + +client.on("messageCreate", (message) => { + const args = message.content.trim().split(/ +/g); + const cmd = args[0].slice(prefix.length).toLowerCase(); + + if (cmd === "keymap" || cmd === "keymapping") { + if (args[0]) { + message.reply({ + embeds: [ + new EmbedBuilder() + .setAuthor({ name: "Invalid Command" }) + .setDescription( + `The \`.keymap\` command has been deprecated in favour of slash commands! Please use \`/keymap\` command.`, + ) + .setImage( + "https://cdn.discordapp.com/attachments/818783506716557316/1213510301253767250/useKeymap.gif?ex=65f5bc89&is=65e34789&hm=3ecf97bf13691b0c554309e45f17c034b1999fd629e4db0991f2499cc99bd83e&", + ) + .setTimestamp() + .setColor("#cf3838") + .setFooter({ + text: "An error occurred", + iconURL: "https://i.imgur.com/fdzF9QP.png", + }), + ], + }); + } + + // command code + } +}); client.login(process.env.TOKEN); diff --git a/resources/keymaps.json b/resources/keymaps.json index e0ca773..4210d2c 100644 --- a/resources/keymaps.json +++ b/resources/keymaps.json @@ -1,30 +1,38 @@ [ - { - "name": "Genshin Impact", - "url": "cdn.discordapp.com/attachments/922068254569160745/1073239279855214592/Genshin_Impact.playmap" - }, - { - "name": "Honkai: Star Rail", - "url": "cdn.discordapp.com/attachments/922068254569160745/1156292437791219744/Honkai_Star_Rail.playmap" - }, - { - "name": "Honkai Impact 3", - "url": "cdn.discordapp.com/attachments/922068254569160745/1073226927541862470/Honkai_Impact_3rd.playmap" - }, - { - "name": "Honkai Impact 3rd (Global)", - "url": "cdn.discordapp.com/attachments/922068254569160745/1073226927541862470/Honkai_Impact_3rd.playmap" - }, - { - "name": "Diablo Immortal", - "url": "cdn.discordapp.com/attachments/922068254569160745/1073247320637980672/Diablo_Immortal.playmap" - }, - { - "name": "League of Legends: Wild Rift", - "url": "cdn.discordapp.com/attachments/922068254569160745/1073247320226922527/LoL_Wild_Rift.playmap" - }, - { - "name": "Punishing: Gray Raven", - "url": "cdn.discordapp.com/attachments/922068254569160745/1073247319790727188/Punishing_Gray_Raven.playmap" - } -] \ No newline at end of file + { + "name": "Genshin Impact", + "url": "github.com/PlayCover/keymaps/tree/master/keymapping/com.miHoYo.GenshinImpact" + }, + { + "name": "Honkai: Star Rail", + "url": "github.com/PlayCover/keymaps/tree/master/keymapping/com.HoYoverse.hkrpgoversea" + }, + { + "name": "Zenless Zone Zero", + "url": "/github.com/PlayCover/keymaps/tree/master/keymapping/com.HoYoverse.Nap" + }, + { + "name": "Wuthering Waves", + "url": "github.com/PlayCover/keymaps/tree/master/keymapping/com.kurogame.wutheringwaves.global" + }, + { + "name": "Punishing: Gray Raven", + "url": "github.com/PlayCover/keymaps/tree/master/keymapping/com.kurogame.punishing.grayraven.en" + }, + { + "name": "Diablo Immortal", + "url": "github.com/PlayCover/keymaps/tree/master/keymapping/com.blizzard.diablo.immortal" + }, + { + "name": "League of Legends: Wild Rift", + "url": "github.com/PlayCover/keymaps/tree/master/keymapping/com.riotgames.league.wildrift" + }, + { + "name": "Rocket League: Side Swipe", + "url": "github.com/PlayCover/keymaps/tree/master/keymapping/com.psyonixllc.mesa" + }, + { + "name": "Umamusume: Pretty Derby", + "url": "github.com/PlayCover/keymaps/tree/master/keymapping/jp.co.cygames.umamusume" + } +] diff --git a/resources/usecommands.gif b/resources/usecommands.gif new file mode 100644 index 0000000..89d1c8c Binary files /dev/null and b/resources/usecommands.gif differ