diff --git a/.github/workflows/CodeQL.yml b/.github/workflows/CodeQL.yml new file mode 100644 index 000000000..ae3edea79 --- /dev/null +++ b/.github/workflows/CodeQL.yml @@ -0,0 +1,31 @@ +name: CodeQL + +on: + push: + branches: + - dev + pull_request: + branches: + - dev + +jobs: + run: + runs-on: ubuntu-latest + strategy: + fail-fast: true + matrix: + languange: ['javascript'] + steps: + - name: Checkout repository + uses: actions/checkout@v2.3.4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + + - name: Autobuild (Attempts to build any compiled languages) + uses: github/codeql-action/autobuild@v1 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 \ No newline at end of file diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index cce754dae..018f9ad5f 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -12,25 +12,16 @@ jobs: - name: Checkout uses: actions/checkout@v2 - - name: Create Folder - run: mkdir docs - - name: Download - run: npm i jsdoc-to-markdown + run: npm i @discordjs/docgen - name: Build run: npm run docs:build - - name: Copy File - uses: canastro/copy-file-action@master - with: - source: "docs.md" - target: "docs/index.md" - - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.ACCESS_TOKEN }} publish_dir: ./docs publish_branch: docs - destination_dir: ./docs/docs/ \ No newline at end of file + destination_dir: ./docs/ \ No newline at end of file diff --git a/.github/workflows/lint_node12.yml b/.github/workflows/lint_node12.yml new file mode 100644 index 000000000..cb03d3b7e --- /dev/null +++ b/.github/workflows/lint_node12.yml @@ -0,0 +1,26 @@ +name: Lint (Node 12.x) + +on: + push: + branches: [ dev ] + pull_request: + branches: [ dev ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js 12.x + uses: actions/setup-node@v1 + with: + node-version: 12.x + - name: Lint + uses: github/super-linter@v3 + env: + VALIDATE_ALL_CODEBASE: true + VALIDATE_JAVASCRIPT_ES: true + DEFAULT_BRANCH: master + GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/lint_node14.yml b/.github/workflows/lint_node14.yml new file mode 100644 index 000000000..d0bf60903 --- /dev/null +++ b/.github/workflows/lint_node14.yml @@ -0,0 +1,26 @@ +name: Lint (Node 14.x) + +on: + push: + branches: [ dev ] + pull_request: + branches: [ dev ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js 14.x + uses: actions/setup-node@v1 + with: + node-version: 14.x + - name: Lint + uses: github/super-linter@v3 + env: + VALIDATE_ALL_CODEBASE: true + VALIDATE_JAVASCRIPT_ES: true + DEFAULT_BRANCH: master + GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/lint_node16.yml b/.github/workflows/lint_node16.yml new file mode 100644 index 000000000..e4ae6a6ab --- /dev/null +++ b/.github/workflows/lint_node16.yml @@ -0,0 +1,26 @@ +name: Lint (Node 16.x) + +on: + push: + branches: [ dev ] + pull_request: + branches: [ dev ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js 16.x + uses: actions/setup-node@v1 + with: + node-version: 16.x + - name: Lint + uses: github/super-linter@v3 + env: + VALIDATE_ALL_CODEBASE: true + VALIDATE_JAVASCRIPT_ES: true + DEFAULT_BRANCH: master + GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/vuebuild.yml b/.github/workflows/vuebuild.yml deleted file mode 100644 index 35afe3eef..000000000 --- a/.github/workflows/vuebuild.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: "vue build | gcommands.js.org Build" - -on: - push: - branches: - - docs - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@main - - - name: Build and Deploy - uses: jenkey2011/vuepress-deploy@1.6.1 - env: - ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} - TARGET_REPO: Garlic-Team/GCommands - TARGET_BRANCH: master - BUILD_SCRIPT: yarn && yarn build - BUILD_DIR: docs/.vuepress/dist/ - CNAME: gcommands.js.org - COMMIT_MESSAGE: Deploy Docs diff --git a/.npmignore b/.npmignore new file mode 100644 index 000000000..b5962a597 --- /dev/null +++ b/.npmignore @@ -0,0 +1,18 @@ +# Packages +node_modules/ +yarn.lock + +# Log files +logs/ +*.log + +# Authentication +deploy/ + +# Miscellaneous +.tmp/ +.vscode/ +docs/ + +# NPM ignore +jsdoc.json \ No newline at end of file diff --git a/README.md b/README.md index 14a581bfd..0d0a0b311 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@
@@ -16,10 +17,12 @@
npm install gcommands
yarn install gcommands
-npm install github:Garlic-Team/GCommands#dev #dev build
+# Dev Build
+npm install Garlic-Team/GCommands#dev
+yarn install Garlic-Team/GCommands#dev
```
-If you're updating from 3.x to 4.x, check https://gcommands.js.org/guide/additional/fromv3tov4.html
+If you're updating from 4.x to 5.x, check https://gcommands.js.org/guide/additional/fromv4tov5.html
### 📜 | Setup
```js
@@ -55,7 +58,7 @@ client.login("bot token")
```
### ✍ | Examples
-You can find everything in the [guide](https://gcommands.js.org).
+You can find everything in the [guide](https://gcommands.js.org/guide/) and [docs](https://gcommands.js.org/docs/).
Join our [discord server](https://discord.gg/AjKJSBbGm2), if you need help or have any questions.
### 👥 | Contact
diff --git a/docs/index.yml b/docs/index.yml
new file mode 100644
index 000000000..0aea5a7e4
--- /dev/null
+++ b/docs/index.yml
@@ -0,0 +1,5 @@
+- name: General
+ files:
+ - name: Welcome
+ id: welcome
+ path: ../../README.md
\ No newline at end of file
diff --git a/jsdoc.json b/jsdoc.json
new file mode 100644
index 000000000..3929bca27
--- /dev/null
+++ b/jsdoc.json
@@ -0,0 +1,3 @@
+{
+ "plugins": ["node_modules/jsdoc-strip-async-await"]
+}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 75c93718d..db8efb54a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "gcommands",
- "version": "4.3.0",
+ "version": "5.2.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "gcommands",
- "version": "4.3.0",
+ "version": "5.2.3",
"license": "MIT",
"dependencies": {
"axios": "^0.21.1",
diff --git a/package.json b/package.json
index 45f2db27a..f4013f782 100644
--- a/package.json
+++ b/package.json
@@ -1,14 +1,16 @@
{
"name": "gcommands",
- "version": "4.3.0",
- "description": "Open-source slash/normal command handler",
+ "version": "5.2.3",
+ "description": "Powerful and flexible command handler that can do everything!",
"main": "src/index.js",
"types": "./typings/index.d.ts",
"dependencies": {
+ "@gcommands/events": "^1.0.3",
"axios": "^0.21.1",
"ms": "^2.1.3"
},
"devDependencies": {
+ "@discordjs/docgen": "^0.10.0",
"@types/node": "^12.7.3"
},
"repository": {
@@ -17,13 +19,10 @@
},
"keywords": [
"gcommands",
- "cmdhandler",
- "slashcommandhandler",
- "slashcmds",
- "slash commands",
- "handler slash commands",
- "command handler",
- "discord js slash"
+ "command",
+ "discord bot",
+ "handler",
+ "slash command handler"
],
"author": "Garlic-Team",
"license": "MIT",
@@ -31,7 +30,11 @@
"url": "https://github.com/Garlic-Team/GCommands/issues"
},
"scripts": {
- "docs:build": "jsdoc2md ./src/**/** > docs.md"
+ "docs:build": "docgen --source src --custom docs/index.yml --output docs/main.json",
+ "docs:test": "docgen --source src"
+ },
+ "engines": {
+ "node": ">=12.0.0"
},
"homepage": "https://gcommands.js.org"
}
diff --git a/src/base/GCommands.js b/src/base/GCommands.js
index 60ca18db2..82b7f178d 100644
--- a/src/base/GCommands.js
+++ b/src/base/GCommands.js
@@ -1,8 +1,7 @@
-const GCommandLoader = require("../managers/GCommandLoader"), Color = require("../structures/Color"), GCommandsBase = require("./GCommandsBase"), GCommandsDispatcher = require("./GCommandsDispatcher"), GEvents = require("./GEvents"), GEventLoader = require("../managers/GEventLoader"), GDatabaseLoader = require("../managers/GDatabaseLoader"), { Events } = require("../util/Constants"), GUpdater = require("../util/updater"), {msToSeconds} = require("../util/util");
-const { Collection, version, Client } = require('discord.js');
-const axios = require("axios");
-const fs = require("fs");
-const ms = require("ms");
+const GCommandLoader = require('../managers/GCommandLoader'), Color = require('../structures/Color'), GCommandsBase = require('./GCommandsBase'), GCommandsDispatcher = require('./GCommandsDispatcher'), { GEvents: GEventLoader } = require('@gcommands/events'), GEventHandling = require('../managers/GEventHandling'), GDatabaseLoader = require('../managers/GDatabaseLoader'), { Events } = require('../util/Constants'), GUpdater = require('../util/updater'), {msToSeconds} = require('../util/util');
+const { Collection, version } = require('discord.js');
+const fs = require('fs');
+const ms = require('ms');
/**
* The main GCommands class
@@ -10,112 +9,156 @@ const ms = require("ms");
class GCommands extends GCommandsBase {
/**
* The GCommands class
- * @param {Object} client - Discord.js Client
+ * @param {Client} client - Discord.js Client
* @param {Object} options - Options (cmdDir, eventDir etc)
*/
constructor(client, options = {}) {
super(client, options)
- if (typeof client != "object") return console.log(new Color("&d[GCommands] &cNo discord.js client provided!",{json:false}).getText());
- if (!Object.keys(options).length) return console.log(new Color("&d[GCommands] &cNo default options provided!",{json:false}).getText());
- if(!options.cmdDir) return console.log(new Color("&d[GCommands] &cNo default options provided! (cmdDir)",{json:false}).getText());
- if(!options.language) return console.log(new Color("&d[GCommands] &cNo default options provided! (language (english, spanish, portuguese, russian, german, czech, slovak, turkish))",{json:false}).getText());
+ if (typeof client !== 'object') return console.log(new Color('&d[GCommands] &cNo discord.js client provided!',{json:false}).getText());
+ if (!Object.keys(options).length) return console.log(new Color('&d[GCommands] &cNo default options provided!',{json:false}).getText());
+ if(!options.cmdDir) return console.log(new Color('&d[GCommands] &cNo default options provided! (cmdDir)',{json:false}).getText());
+ if(!options.language) return console.log(new Color('&d[GCommands] &cNo default options provided! (language (english, spanish, portuguese, russian, german, czech, slovak, turkish))',{json:false}).getText());
+ /**
+ * GCommandsClient
+ * @type {GCommands}
+ */
this.GCommandsClient = this;
+
+ /**
+ * client
+ * @type {Client}
+ */
this.client = client;
+ /**
+ * caseSensitiveCommands
+ * @type {Boolean}
+ * @default true
+ */
+ this.caseSensitiveCommands = Boolean(options.caseSensitiveCommands) || true
+
+ /**
+ * caseSensitivePrefixes
+ * @type {Boolean}
+ * @default true
+ */
+ this.caseSensitivePrefixes = Boolean(options.caseSensitivePrefixes) || true
+
/**
* CmdDir
- * @property {String} cmdDir
+ * @type {String}
*/
this.cmdDir = options.cmdDir;
/**
* EventDir
- * @property {String} eventDir
+ * @type {String}
+ * @default undefined
*/
this.eventDir = options.eventDir;
this.client.discordjsversion = version;
/**
* unkownCommandMessage
- * @property {String} unkownCommandMessage
+ * @type {Boolean}
+ * @default false
*/
this.unkownCommandMessage = options.unkownCommandMessage;
/**
* AutoTyping
- * @property {Boolean} autoTyping
+ * @type {Boolean}
+ * @default false
*/
this.autoTyping = options.autoTyping;
/**
* ownLanguageFile
- * @property {Object} ownLanguageFile
+ * @type {Object}
*/
- if(!options.ownLanguageFile) this.languageFile = require("../util/message.json");
+ if(!options.ownLanguageFile) this.languageFile = require('../util/message.json');
else this.languageFile = options.ownLanguageFile;
- this.language = options.language;
- if(this.eventDir) {
- new GEvents(this.GCommandsClient, {
- eventDir: this.eventDir
- })
- }
+ /**
+ * language
+ * @type {Object} language
+ */
+ this.language = options.language;
/**
* database
- * @property {Object} database
+ * @type {Object} database
+ * @default undefined
*/
- this.database = options.database || undefined;
+ this.database = options.database;
+
+ /**
+ * gcategories
+ * @type {Array}
+ */
+ this.client.gcategories = fs.readdirSync(`./${this.cmdDir}`)
- this.client.categories = fs.readdirSync("./" + this.cmdDir );
+ /**
+ * gcommands
+ * @type {Collection}
+ */
this.client.gcommands = new Collection();
+
+ /**
+ * galiases
+ * @type {Collection}
+ */
this.client.galiases = new Collection();
/**
* Prefix
- * @property {String} prefix
+ * @type {String}
+ * @default undefined
*/
- this.prefix = options.slash.prefix ? options.slash.prefix : undefined;
+ this.prefix = !Array.isArray(options.slash.prefix) ? [options.slash.prefix] : options.slash.prefix;
/**
* Slash
- * @property {String} slash
+ * @type {String}
+ * @default false
*/
this.slash = options.slash.slash ? options.slash.slash : false;
/**
- * cooldownDefault
- * @property {Number} cooldownDefault
+ * defaultCooldown
+ * @type {Number}
+ * @default 0
*/
- this.cooldownDefault = options.defaultCooldown ? options.defaultCooldown : 0;
+ this.defaultCooldown = options.defaultCooldown ? options.defaultCooldown : 0;
- this.GCommandsClient.unkownCommandMessage = this.unkownCommandMessage;
- this.GCommandsClient.database = this.database;
this.client.language = this.language;
this.client.languageFile = this.languageFile;
this.client.database = this.database
- this.client.prefix = this.prefix;
+ this.client.prefixes = this.prefix;
this.client.slash = this.slash;
- this.client.cooldownDefault = this.cooldownDefault;
+ this.client.defaultCooldown = this.defaultCooldown;
this.client.autoTyping = this.autoTyping ? msToSeconds(ms(this.autoTyping)) : null;
- process.setMaxListeners(50);
process.on('uncaughtException', (error) => {
- this.emit(Events.LOG, new Color("&d[GCommands Errors] &eHandled: &a" + error + ` ${error.response ? error.response.data.message : ""} ${error.response ? error.response.data.code : ""} | use debug for full error`).getText());
+ this.emit(Events.LOG, new Color('&d[GCommands Errors] &eHandled: &a' + error + ` ${error.response ? error.response.data.message : ''} ${error.response ? error.response.data.code : ''} | use debug for full error`).getText());
setTimeout(() => {this.emit(Events.DEBUG, error)}, 1000)
});
this.client.dispatcher = new GCommandsDispatcher(this.client);
- setTimeout(() => {
- new GDatabaseLoader(this.GCommandsClient);
- new GEventLoader(this.GCommandsClient);
- new GCommandLoader(this.GCommandsClient);
- }, 1000)
+ setTimeout(() => { this.loadSys() }, 1000)
GUpdater.__updater();
}
+
+ async loadSys() {
+ require('../structures/GMessage'); require('../structures/GGuild'); require('../structures/DMChannel'); require('../structures/NewsChannel'); require('../structures/TextChannel');
+ new GDatabaseLoader(this.GCommandsClient)
+ new GEventHandling(this.GCommandsClient)
+ new GEventLoader(this.GCommandsClient)
+ new GCommandLoader(this.GCommandsClient)
+ };
}
module.exports = GCommands;
\ No newline at end of file
diff --git a/src/base/GCommandsBase.js b/src/base/GCommandsBase.js
index 95f4a69be..821cee153 100644
--- a/src/base/GCommandsBase.js
+++ b/src/base/GCommandsBase.js
@@ -1,4 +1,4 @@
-const EventEmitter = require("events");
+const EventEmitter = require('events');
/**
* The GCommandsBase class
diff --git a/src/base/GCommandsDispatcher.js b/src/base/GCommandsDispatcher.js
index 8e5bd441c..0d1f5c5d4 100644
--- a/src/base/GCommandsDispatcher.js
+++ b/src/base/GCommandsDispatcher.js
@@ -1,21 +1,37 @@
-const { Collector, Collection } = require('discord.js');
-const ButtonCollectorV12 = require('../structures/v12/ButtonCollector'), ButtonCollectorV13 = require('../structures/v13/ButtonCollector'), SelectMenuCollectorV12 = require('../structures/v12/SelectMenuCollector'), SelectMenuCollectorV13 = require('../structures/v13/SelectMenuCollector'), Color = require("../structures/Color")
-const updater = require("../util/updater");
-const ms = require("ms");
+const { Collector, Collection, User, Team } = require('discord.js');
+const ButtonCollectorV12 = require('../structures/v12/ButtonCollector'), ButtonCollectorV13 = require('../structures/v13/ButtonCollector'), SelectMenuCollectorV12 = require('../structures/v12/SelectMenuCollector'), SelectMenuCollectorV13 = require('../structures/v13/SelectMenuCollector'), Color = require('../structures/Color')
+const ifDjsV13 = require('../util/updater').checkDjsVersion('13');
+const ms = require('ms');
/**
* The GCommansDispatcher class
*/
class GCommandsDispatcher {
+ /**
+ * The GCommansDispatcher class
+ * @param {Client} client - Discord.js Client
+ */
constructor(client) {
/**
- * GCommandsDispatcher options
- * @property {Object} client
+ * client
+ * @type {Client} client
*/
this.client = client;
+
+ /**
+ * Inhibitors
+ * @type {Set}
+ */
this.client.inhibitors = new Set();
+
+ /**
+ * Cooldowns
+ * @type {Collection}
+ */
this.client.cooldowns = new Collection();
+
+ this.fetchClientApplication();
}
/**
@@ -39,24 +55,24 @@ class GCommandsDispatcher {
* @returns {String}
*/
async getGuildPrefix(guildId, cache = true) {
- if(!this.client.database) return this.client.prefix;
- if(cache) return this.client.guilds.cache.get(guildId).prefix ? this.client.guilds.cache.get(guildId).prefix : this.client.prefix;
+ if(!this.client.database) return this.client.prefixes;
+ if(cache) return this.client.guilds.cache.get(guildId).prefix ? this.client.guilds.cache.get(guildId).prefix : this.client.prefixes;
let guildData = await this.client.database.get(`guild_${guildId}`)
- return guildData ? guildData.prefix : this.client.prefix
+ return guildData ? guildData.prefix : this.client.prefixes
}
/**
* Internal method to getCooldown
* @returns {String}
*/
- async getCooldown(guildId, userId, command) {
- if(!command.cooldown) return { cooldown: false } ;
+ async getCooldown(guildId, userId, command) {
+ if(this.client.application.owners.some(user => user.id == userId)) return { cooldown: false };
let now = Date.now();
let cooldown;
- if(typeof command.cooldown == "object") cooldown = command.cooldown ? ms(command.cooldown.cooldown) : 0;
- else cooldown = command.cooldown ? ms(command.cooldown) : 0;
+ if(typeof command.cooldown == 'object') cooldown = command.cooldown ? ms(command.cooldown.cooldown) : ms(this.client.defaultCooldown);
+ else cooldown = command.cooldown ? ms(command.cooldown) : ms(this.client.defaultCooldown);
if(cooldown < 1800000 || !this.client.database) {
if (!this.client.cooldowns.has(command.name)) {
@@ -64,14 +80,13 @@ class GCommandsDispatcher {
}
const timestamps = this.client.cooldowns.get(command.name);
- const cooldownAmount = cooldown ? cooldown : ms(this.client.defaultCooldown);
if (timestamps.has(userId)) {
if (timestamps.has(userId)) {
- const expirationTime = timestamps.get(userId) + cooldownAmount;
+ const expirationTime = timestamps.get(userId) + cooldown;
if (now < expirationTime) {
- if(typeof command.cooldown == "object" && command.cooldown.agressive) {
+ if(typeof command.cooldown == 'object' && command.cooldown.agressive) {
this.client.cooldowns.set(command.name, new Collection());
return { cooldown: true, wait: ms(cooldown) }
}
@@ -84,10 +99,11 @@ class GCommandsDispatcher {
}
timestamps.set(userId, now);
- setTimeout(() => timestamps.delete(userId), cooldownAmount);
+ setTimeout(() => timestamps.delete(userId), cooldown);
+ return { cooldown:false }
}
- if(!this.client.database) return 0;
+ if(!this.client.database || !command.cooldown) return { cooldown: false };
let guildData = await this.client.database.get(`guild_${guildId}`) || {}
if(!guildData.users) guildData.users = {}
@@ -103,7 +119,7 @@ class GCommandsDispatcher {
}
if(now < userInfo) {
- if(typeof command.cooldown == "object" && command.cooldown.agressive) {
+ if(typeof command.cooldown == 'object' && command.cooldown.agressive) {
guildData.users[userId][command.name] = ms(command.cooldown) + now
userInfo = guildData.users[userId][command.name]
@@ -149,7 +165,7 @@ class GCommandsDispatcher {
* @param {Object} command
* @returns {boolean}
*/
- async getGuildLanguage(guildId, cache = true) {
+ async getGuildLanguage(guildId, cache = true) {
if(!this.client.database) return this.client.language;
if(cache) return this.client.guilds.cache.get(guildId).language ? this.client.guilds.cache.get(guildId).language : this.client.language;
@@ -157,6 +173,22 @@ class GCommandsDispatcher {
return guildData ? guildData.language : this.client.language
}
+ /**
+ * Internal method to fetchClientApplication
+ * @private
+ * @returns {Array}
+ */
+ async fetchClientApplication() {
+ if(!ifDjsV13) this.client.application = await this.client.fetchApplication()
+ if(this.client.application.owner == null) return this.client.application.owners = [];
+
+ if(this.client.application.owner instanceof Team) {
+ this.client.application.owners = this.client.application.owner.members.array().map(teamMember => teamMember.user)
+ } else this.client.application.owners = [this.client.application.owner]
+
+ return this.client.application.owners;
+ }
+
/**
* Internal method to addInhibitor
* @param {Function} inhibitor
@@ -185,7 +217,7 @@ class GCommandsDispatcher {
* @returns {Collector}
*/
createButtonCollector(msg, filter, options = {}) {
- if(updater.checkDjsVersion("13")) return new ButtonCollectorV13(msg, filter, options);
+ if(ifDjsV13) return new ButtonCollectorV13(msg, filter, options);
else return new ButtonCollectorV12(msg, filter, options);
}
@@ -215,7 +247,7 @@ class GCommandsDispatcher {
* @returns {Collector}
*/
createSelectMenuCollector(msg, filter, options = {}) {
- if(updater.checkDjsVersion("13")) return new SelectMenuCollectorV13(msg, filter, options);
+ if(ifDjsV13) return new SelectMenuCollectorV13(msg, filter, options);
else return new SelectMenuCollectorV12(msg, filter, options);
}
diff --git a/src/base/GEvents.js b/src/base/GEvents.js
deleted file mode 100644
index 854c591d7..000000000
--- a/src/base/GEvents.js
+++ /dev/null
@@ -1,95 +0,0 @@
-const { Collection } = require("discord.js");
-const Color = require("../structures/Color"), { Events } = require("../util/Constants");
-const path = require('path');
-const fs = require('fs');
-
-/**
- * The GEvents class
- */
-class GEvents {
-
- /**
- * Creates new GEvents instance
- * @param {DiscordClient} client
- * @param {GEventsOptions} options
- */
- constructor(GCommandsClient, options = {}) {
- if(!GCommandsClient.client) GCommandsClient = { client: GCommandsClient }
- if (typeof GCommandsClient.client !== 'object') return console.log(new Color("&d[GCommands EVENTS] &cNo discord.js client provided!",{json:false}).getText());
- if (!Object.keys(options).length) return console.log(new Color("&d[GCommands EVENTS] &cNo default options provided!",{json:false}).getText());
- if(!options.eventDir) return console.log(new Color("&d[GCommands EVENTS] &cNo default options provided! (eventDir)",{json:false}).getText());
-
- /**
- * GEventsOptions options
- * @type {GEventsOptions}
- * @property {String} eventDir
- */
-
- this.eventDir = options.eventDir;
-
- this.GCommandsClient = GCommandsClient;
- this.client = GCommandsClient.client;
- this.client.events = new Collection();
-
- this.__loadEventFiles();
- }
-
- /**
- * Internal method to loadEventsFiles
- * @returns {void}
- * @private
- */
- async __loadEventFiles() {
- await fs.readdirSync(`${__dirname}/../../../../${this.eventDir}`).forEach(async(dir) => {
- var file;
- var fileName = dir.split(".").reverse()[1]
- var fileType = dir.split(".").reverse()[0]
- if(fileType == "js" || fileType == "ts") {
- try {
- file = await require(`../../../../${this.eventDir}${dir}`);
-
- this.client.events.set(file.name, file);
- this.GCommandsClient.emit(Events.LOG, new Color("&d[GEvents] &aLoaded (File): &e➜ &3" + fileName, {json:false}).getText());
- } catch(e) {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GEvents Debug] "+e).getText());
- console.log(new Color("&d[GEvents] &cCan't load " + fileName).getText());
- }
- } else {
- fs.readdirSync(`${this.eventDir}${dir}`).forEach(async(eventFile) => {
- var file2;
- var fileName2 = eventFile.split(".").reverse()[1];
- try {
- file2 = await require(`../../../../${this.eventDir}${dir}/${eventFile}`);
-
- this.client.events.set(file2.name, file2);
- this.GCommandsClient.emit(Events.LOG, new Color("&d[GEvents] &aLoaded (File): &e➜ &3" + fileName2, {json:false}).getText());
- } catch(e) {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GEvents Debug] "+e).getText());
- console.log(new Color("&d[GEvents] &cCan't load " + fileName2).getText());
- }
- })
- }
- })
-
- await this.__loadEvents()
- }
-
- /**
- * Internal method to loadEvents
- * @returns {void}
- * @private
- */
- async __loadEvents() {
- this.client.events.forEach(event => {
- if(event.name == "ready") return event.run(this.client);
-
- if (event.once) {
- this.client.once(event.name, (...args) => event.run(this.client, ...args));
- } else {
- this.client.on(event.name, (...args) => event.run(this.client, ...args));
- }
- })
- }
-}
-
-module.exports = GEvents;
\ No newline at end of file
diff --git a/src/base/actions/channel.js b/src/base/actions/channel.js
index a4d844781..f91d4347f 100644
--- a/src/base/actions/channel.js
+++ b/src/base/actions/channel.js
@@ -1,47 +1,47 @@
module.exports = (client) => {
- client.on("channelUpdate", async(oldChannel, newChannel) => {
- if(oldChannel.permissionOverwrites != newChannel.permissionOverwrites) {
- client.emit("guildChannelPermissionsUpdate",
+ client.on('channelUpdate', async(oldChannel, newChannel) => {
+ if(oldChannel.permissionOverwrites !== newChannel.permissionOverwrites) {
+ client.emit('guildChannelPermissionsUpdate',
newChannel,
oldChannel.permissionOverwrites,
newChannel.permissionOverwrites,
);
}
- if(oldChannel.type == "text" && oldChannel.topic !== newChannel.topic) {
- client.emit("guildChannelTopicUpdate",
+ if(oldChannel.type == 'text' && oldChannel.topic !== newChannel.topic) {
+ client.emit('guildChannelTopicUpdate',
newChannel,
oldChannel.topic,
newChannel.topic
)
}
- if(oldChannel.type == "text" && oldChannel.nsfw !== newChannel.nsfw) {
- client.emit("guildChannelNSFWUpdate",
+ if(oldChannel.type == 'text' && oldChannel.nsfw !== newChannel.nsfw) {
+ client.emit('guildChannelNSFWUpdate',
newChannel,
oldChannel.nsfw,
newChannel.nsfw
)
}
- if(oldChannel.type != newChannel.type) {
- client.emit("guildChannelTypeUpdate",
+ if(oldChannel.type !== newChannel.type) {
+ client.emit('guildChannelTypeUpdate',
newChannel,
oldChannel.type,
newChannel.type
)
}
- if(oldChannel.type == "voice" && oldChannel.userLimit != newChannel.userLimit) {
- client.emit("guildChannelUserLimitUpdate",
+ if(oldChannel.type == 'voice' && oldChannel.userLimit !== newChannel.userLimit) {
+ client.emit('guildChannelUserLimitUpdate',
newChannel,
oldChannel.userLimit,
newChannel.userLimit
)
}
- if(oldChannel.type == "voice" && oldChannel.bitrate != newChannel.bitrate) {
- client.emit("guildChannelBitrateUpdate",
+ if(oldChannel.type == 'voice' && oldChannel.bitrate !== newChannel.bitrate) {
+ client.emit('guildChannelBitrateUpdate',
newChannel,
oldChannel.bitrate,
newChannel.bitrate
diff --git a/src/base/actions/guild.js b/src/base/actions/guild.js
index ee294e394..d1348ddff 100644
--- a/src/base/actions/guild.js
+++ b/src/base/actions/guild.js
@@ -1,7 +1,7 @@
module.exports = (client) => {
- client.on("guildUpdate", async(oldGuild, newGuild) => {
+ client.on('guildUpdate', async(oldGuild, newGuild) => {
if(oldGuild.premiumTier < newGuild.premiumTier) {
- client.emit("guildBoostLevelUp",
+ client.emit('guildBoostLevelUp',
newGuild,
oldGuild.premiumTier,
newGuild.premiumTier
@@ -9,87 +9,87 @@ module.exports = (client) => {
}
if(oldGuild.premiumTier > newGuild.premiumTier) {
- client.emit("guildBoostLevelDown",
+ client.emit('guildBoostLevelDown',
newGuild,
oldGuild.premiumTier,
newGuild.premiumTier
)
}
- if(oldGuild.region != newGuild.region) {
- client.emit("guildRegionUpdate",
+ if(oldGuild.region !== newGuild.region) {
+ client.emit('guildRegionUpdate',
newGuild,
oldGuild.region,
newGuild.region
)
}
- if(oldGuild.banner != newGuild.banner) {
- client.emit("guildBannerUpdate",
+ if(oldGuild.banner !== newGuild.banner) {
+ client.emit('guildBannerUpdate',
newGuild,
oldGuild.banner,
newGuild.banner
)
}
- if(oldGuild.afkChannel != newGuild.afkChannel) {
- client.emit("guildAfkChannelUpdate",
+ if(oldGuild.afkChannel !== newGuild.afkChannel) {
+ client.emit('guildAfkChannelUpdate',
newGuild,
oldGuild.afkChannel,
newGuild.afkChannel
)
}
- if(oldGuild.vanityURLCode != newGuild.vanityURLCode) {
- client.emit("guildVanityURLUpdate",
+ if(oldGuild.vanityURLCode !== newGuild.vanityURLCode) {
+ client.emit('guildVanityURLUpdate',
newGuild,
oldGuild.vanityURLCode,
newGuild.vanityURLCode
)
}
- if(oldGuild.features.length != newGuild.features.length) {
- client.emit("guildFeaturesUpdate",
+ if(oldGuild.features.length !== newGuild.features.length) {
+ client.emit('guildFeaturesUpdate',
newGuild,
oldGuild.features,
newGuild.features
)
}
- if(oldGuild.nameAcronym != newGuild.nameAcronym) {
- client.emit("guildAcronymUpdate",
+ if(oldGuild.nameAcronym !== newGuild.nameAcronym) {
+ client.emit('guildAcronymUpdate',
newGuild,
oldGuild.nameAcronym,
newGuild.nameAcronym
)
}
- if(oldGuild.ownerID != newGuild.ownerID) {
- client.emit("guildOwnerUpdate",
+ if(oldGuild.ownerID !== newGuild.ownerID) {
+ client.emit('guildOwnerUpdate',
newGuild,
oldGuild.ownerID,
newGuild.ownerID
)
}
- if(oldGuild.maximumMembers != newGuild.maximumMembers ) {
- client.emit("guildMaximumMembersUpdate",
+ if(oldGuild.maximumMembers !== newGuild.maximumMembers ) {
+ client.emit('guildMaximumMembersUpdate',
newGuild,
oldGuild.maximumMembers,
newGuild.maximumMembers
)
}
- if(oldGuild.partnered != newGuild.partnered ) {
- client.emit("guildPartnerUpdate",
+ if(oldGuild.partnered !== newGuild.partnered ) {
+ client.emit('guildPartnerUpdate',
newGuild,
oldGuild.partnered,
newGuild.partnered
)
}
- if(oldGuild.verified != newGuild.verified ) {
- client.emit("guildVerifyUpdate",
+ if(oldGuild.verified !== newGuild.verified ) {
+ client.emit('guildVerifyUpdate',
newGuild,
oldGuild.verified,
newGuild.verified
diff --git a/src/base/actions/guildmember.js b/src/base/actions/guildmember.js
index f26eba6b0..7c265912c 100644
--- a/src/base/actions/guildmember.js
+++ b/src/base/actions/guildmember.js
@@ -1,9 +1,9 @@
-const { default: axios } = require("axios");
+const { default: axios } = require('axios');
module.exports = (client) => {
- client.on("guildMemberUpdate", async(oldMember, newMember) => {
+ client.on('guildMemberUpdate', async(oldMember, newMember) => {
if(oldMember.premiumSince && newMember.premiumSince) {
- client.emit("guildMemberBoost",
+ client.emit('guildMemberBoost',
newMember,
oldMember.premiumSince,
newMember.premiumSince
@@ -11,14 +11,14 @@ module.exports = (client) => {
}
if(oldMember.premiumSince && !newMember.premiumSince) {
- client.emit("guildMemberUnboost",
+ client.emit('guildMemberUnboost',
newMember,
oldMember.premiumSince,
newMember.premiumSince
)
}
- if (oldMember.nickname != newMember.nickname) {
+ if (oldMember.nickname !== newMember.nickname) {
client.emit('guildMemberNicknameUpdate',
newMember,
oldMember.nickname,
@@ -30,10 +30,10 @@ module.exports = (client) => {
let url = `https://discord.com/api/v9/guilds/${newMember.guild.id}/members/${newMember.user.id}`
let config = {
- method: "GET",
+ method: 'GET',
headers: {
Authorization: `Bot ${client.token}`,
- "Content-Type": "application/json"
+ 'Content-Type': 'application/json'
},
url,
}
diff --git a/src/base/actions/interactions.js b/src/base/actions/interactions.js
index 8a160401b..a9bd4a8d2 100644
--- a/src/base/actions/interactions.js
+++ b/src/base/actions/interactions.js
@@ -1,14 +1,29 @@
-const InteractionEvent = require("../../structures/InteractionEvent");
+const InteractionEvent = require('../../structures/InteractionEvent');
+const { inhibit, interactionRefactor } = require('../../util/util')
module.exports = (client) => {
- client.ws.on('INTERACTION_CREATE', data => {
+ client.ws.on('INTERACTION_CREATE', async(data) => {
if (!data.message) return;
if(data.data.component_type) {
const interaction = new InteractionEvent(client, data)
+ let member = interaction.clicker.member, guild = interaction.guild, channel = interaction.channel
+ let inhibitReturn = await inhibit(client, interactionRefactor(client, interaction), {
+ interaction, member,
+ guild: guild,
+ channel: channel,
+ respond: async(result) => {
+ return interaction.slashRespond(result)
+ },
+ edit: async(result, update = false) => {
+ return interaction.slashEdit(result, update);
+ }
+ })
+ if(inhibitReturn == false) return;
+
client.emit(data.data.component_type == 3 ? `selectMenu` : `clickButton`, interaction)
- client.emit("interaction", interaction)
+ client.emit('interaction', interaction)
}
});
}
\ No newline at end of file
diff --git a/src/base/actions/role.js b/src/base/actions/role.js
index bb70ca5a6..b2cb1eef7 100644
--- a/src/base/actions/role.js
+++ b/src/base/actions/role.js
@@ -1,5 +1,5 @@
module.exports = (client) => {
- client.on("roleUpdate", async(oldRole, newRole) => {
+ client.on('roleUpdate', async(oldRole, newRole) => {
if (oldRole.rawPosition !== newRole.rawPosition) {
client.emit('rolePositionUpdate',
newRole,
diff --git a/src/base/actions/user.js b/src/base/actions/user.js
index 046f95caa..c338fbe4a 100644
--- a/src/base/actions/user.js
+++ b/src/base/actions/user.js
@@ -1,23 +1,23 @@
module.exports = (client) => {
- client.on("userUpdate", async(oldUser, newUser) => {
- if(oldUser.displayAvatarURL() != newUser.displayAvatarURL()) {
- client.emit("userAvatarUpdate",
+ client.on('userUpdate', async(oldUser, newUser) => {
+ if(oldUser.displayAvatarURL() !== newUser.displayAvatarURL()) {
+ client.emit('userAvatarUpdate',
newUser,
oldUser.displayAvatarURL(),
newUser.displayAvatarURL()
)
}
- if(oldUser.username != newUser.username) {
- client.emit("userUsernameUpdate",
+ if(oldUser.username !== newUser.username) {
+ client.emit('userUsernameUpdate',
newUser,
oldUser.username,
newUser.username
)
}
- if(oldUser.discriminator != newUser.discriminator) {
- client.emit("userDiscriminatorUpdate",
+ if(oldUser.discriminator !== newUser.discriminator) {
+ client.emit('userDiscriminatorUpdate',
newUser,
oldUser.discriminator,
newUser.discriminator
@@ -25,8 +25,8 @@ module.exports = (client) => {
}
- if(oldUser.flags != newUser.flags) {
- client.emit("userFlagsUpdate",
+ if(oldUser.flags !== newUser.flags) {
+ client.emit('userFlagsUpdate',
newUser,
oldUser.flags,
newUser.flags
diff --git a/src/base/actions/voiceupdate.js b/src/base/actions/voiceupdate.js
index bb59b4b13..3eedafad8 100644
--- a/src/base/actions/voiceupdate.js
+++ b/src/base/actions/voiceupdate.js
@@ -1,5 +1,5 @@
module.exports = (client) => {
- client.on("voiceStateUpdate", async(oldState, newState) => {
+ client.on('voiceStateUpdate', async(oldState, newState) => {
const oldMember = oldState.member;
const newMember = newState.member;
@@ -26,7 +26,7 @@ module.exports = (client) => {
}
if (!oldState.mute && newState.mute) {
- var muteType = newState.selfMute ? 'self-muted' : 'server-muted';
+ let muteType = newState.selfMute ? 'self-muted' : 'server-muted';
client.emit('voiceChannelMute',
newMember,
muteType
@@ -34,7 +34,7 @@ module.exports = (client) => {
}
if (oldState.mute && !newState.mute) {
- var muteType = oldState.selfMute ? 'self-muted' : 'server-muted';
+ let muteType = oldState.selfMute ? 'self-muted' : 'server-muted';
client.emit('voiceChannelUnmute',
newMember,
muteType
@@ -42,7 +42,7 @@ module.exports = (client) => {
}
if (!oldState.deaf && newState.deaf) {
- var deafType = newState.selfDeaf ? 'self-deafed' : 'server-v';
+ let deafType = newState.selfDeaf ? 'self-deafed' : 'server-v';
client.emit('voiceChannelDeaf',
newMember,
deafType
@@ -50,7 +50,7 @@ module.exports = (client) => {
}
if (oldState.deaf && !newState.deaf) {
- var deafType = oldState.selfDeaf ? 'self-deafed' : 'server-v';
+ let deafType = oldState.selfDeaf ? 'self-deafed' : 'server-v';
client.emit('voiceChannelUndeaf',
newMember,
deafType
diff --git a/src/commands/argument.js b/src/commands/argument.js
new file mode 100644
index 000000000..1615034fd
--- /dev/null
+++ b/src/commands/argument.js
@@ -0,0 +1,108 @@
+const ms = require('ms');
+const StringArgumentType = require('./types/string');
+const IntegerArgumentType = require('./types/integer');
+const BooleanArgumentType = require('./types/boolean');
+const ChannelArgumentType = require('./types/channel');
+const UserArgumentType = require('./types/user');
+const RoleArgumentType = require('./types/role');
+
+/**
+ * The Argument class
+ */
+class Argument {
+ /**
+ * The Argument class
+ * @param {Client}
+ * @param {Object} argument
+ */
+ constructor(client, argument) {
+ /**
+ * client
+ * @type {Client}
+ */
+ this.client = client;
+
+ /**
+ * name
+ * @type {String}
+ */
+ this.name = argument.name;
+
+ /**
+ * argument
+ * @type {Argument}
+ */
+ this.argument = this.determineArgument(client, argument);
+
+ /**
+ * type
+ * @type {String}
+ */
+ this.type = this.determineArgument(client, argument).type;
+
+ /**
+ * prompt
+ * @type {String}
+ */
+ this.prompt = argument.prompt || `Please define argument ${argument.name}`;
+
+ /**
+ * choices
+ * @type {Object}
+ */
+ this.choices = argument.choices;
+
+ return this;
+ }
+
+ /**
+ * Method to obtain
+ * @param {Message|Object}
+ * @param {String}
+ */
+ async obtain(message, prompt = this.prompt) {
+ if(message.author.bot) return;
+
+ const wait = 30000;
+
+ message.reply(prompt)
+ const responses = await message.channel.awaitMessages(msg => msg.author.id === message.author.id, {
+ max: 1,
+ time: wait
+ });
+ if(responses.size == 0) return {
+ valid: true,
+ timeLimit: true
+ }
+
+ let valid = await this.argument.validate(this, responses.first())
+ if(valid) {
+ return {
+ valid: false,
+ prompt: valid
+ };
+ }
+
+ return {
+ valid: true,
+ content: responses.first().content
+ };
+ }
+
+ /**
+ * Method to determineArgument
+ * @param {Client}
+ * @param {Argument}
+ */
+ determineArgument(client, argument) {
+ if(argument.type == 3) return new StringArgumentType(client, argument);
+ if(argument.type == 4) return new IntegerArgumentType(client, argument);
+ if(argument.type == 5) return new BooleanArgumentType(client, argument);
+ if(argument.type == 6) return new UserArgumentType(client, argument);
+ if(argument.type == 7) return new ChannelArgumentType(client, argument);
+ if(argument.type == 8) return new RoleArgumentType(client, argument);
+ else return new StringArgumentType(client, argument);
+ }
+}
+
+module.exports = Argument;
\ No newline at end of file
diff --git a/src/commands/base.js b/src/commands/base.js
new file mode 100644
index 000000000..0568c3f04
--- /dev/null
+++ b/src/commands/base.js
@@ -0,0 +1,137 @@
+const { Snowflake } = require('discord.js');
+const { resolveString } = require('../util/util');
+const Color = require('../structures/Color');
+
+/**
+ * The Command class
+ */
+class Command {
+
+ /**
+ * Creates new Command instance
+ * @param {Client} client
+ * @param {Object} options
+ */
+ constructor(client, options = {}) {
+ /**
+ * Name
+ * @type {String}
+ */
+ this.name = resolveString(options.name);
+
+ /**
+ * Description
+ * @type {String}
+ */
+ this.description = resolveString(options.description);
+
+ /**
+ * Cooldown
+ * @type {String}
+ */
+ this.cooldown = resolveString(options.cooldown);
+
+ /**
+ * expectedArgs
+ * @type {String | Array}
+ * @deprecated
+ */
+ this.expectedArgs = options.expectedArgs;
+
+ /**
+ * args
+ * @type {String | Array}
+ */
+ this.args = options.args;
+
+ /**
+ * minArgs
+ * @type {Number}
+ */
+ this.minArgs = Number(options.minArgs);
+
+ /**
+ * userRequiredPermissions
+ * @type {String | Array}
+ */
+ this.userRequiredPermissions = options.userRequiredPermissions;
+
+ /**
+ * userRequiredRoles
+ * @type {String | Array}
+ */
+ this.userRequiredRoles = options.userRequiredRoles;
+
+ /**
+ * clientRequiredPermissions
+ * @type {String | Array}
+ */
+ this.clientRequiredPermissions = options.clientRequiredPermissions;
+
+ /**
+ * userOnly
+ * @type {Snowflake | Array}
+ */
+ this.userOnly = options.userOnly;
+
+ /**
+ * channelOnly
+ * @type {Snowflake | Array}
+ */
+ this.channelOnly = options.channelOnly;
+
+ /**
+ * channelTextOnly
+ * @type {Boolean}
+ */
+ this.channelTextOnly = Boolean(options.channelTextOnly) || undefined;
+
+ /**
+ * channelNewsOnly
+ * @type {Boolean}
+ */
+ this.channelNewsOnly = Boolean(options.channelNewsOnly) || undefined;
+
+ /**
+ * guildOnly
+ * @type {Snowflake}
+ */
+ this.guildOnly = options.guildOnly;
+
+ /**
+ * nsfw
+ * @type {Boolean}
+ */
+ this.nsfw = Boolean(options.nfsw) || false;
+
+ /**
+ * slash
+ * @type {Boolean}
+ */
+ this.slash = Boolean(options.slash) || null;
+
+ /**
+ * aliases
+ * @type {Array}
+ */
+ this.aliases = Array(options.aliases);
+
+ /**
+ * category
+ * @type {String}
+ */
+ this.category = resolveString(options.category);
+ }
+
+ /**
+ * run function
+ * @param {Object} options
+ * @param {Array} arrayArgs
+ * @param {Array | Object} objectArgs
+ */
+ async run({client, interaction, member, message, guild, channel, respond, edit}, arrayArgs, objectArgs) {
+ return console.log(new Color(`&d[GCommands] &cCommand ${this.name} doesn't provide a run method!`).getText())
+ }
+}
+
+module.exports = Command;
\ No newline at end of file
diff --git a/src/commands/types/base.js b/src/commands/types/base.js
new file mode 100644
index 000000000..051d775f5
--- /dev/null
+++ b/src/commands/types/base.js
@@ -0,0 +1,35 @@
+const Color = require('../../structures/Color');
+
+/**
+ * The ArgumentType class
+ */
+class ArgumentType {
+ /**
+ * The ArgumentType class
+ * @param {Client}
+ * @param {String} type
+ */
+ constructor(client, type) {
+ if(!client) return console.log(new Color('&d[GCommands Args] &cNo discord.js client provided!').getText());
+ if(!type) return console.log(new Color('&d[GCommands Args] &cNo argument provided!').getText());
+
+ /**
+ * type
+ * @type {String}
+ */
+ this.type = type;
+
+ return this;
+ }
+
+ /**
+ * Method to validate
+ * @param {Argument}
+ * @param {Message|Object}
+ */
+ validate() {
+ return console.log(new Color('&d[GCommands Args] &cArgument doesnt have provided validate() method'))
+ }
+}
+
+module.exports = ArgumentType;
\ No newline at end of file
diff --git a/src/commands/types/boolean.js b/src/commands/types/boolean.js
new file mode 100644
index 000000000..735559737
--- /dev/null
+++ b/src/commands/types/boolean.js
@@ -0,0 +1,38 @@
+const ArgumentType = require('./base');
+
+/**
+ * The BooleanArgumentType class
+ * @extends ArgumentType
+ */
+class BooleanArgumentType extends ArgumentType {
+ /**
+ * The BooleanArgumentType class
+ * @param {Client}
+ */
+ constructor(client) {
+ super(client, 'boolean')
+
+ /**
+ * client
+ * @type {Client}
+ */
+ this.client = client;
+
+ /**
+ * answerSet
+ * @type {Set}
+ */
+ this.answerSet = new Set(['true', 't', 'yes', 'y', 'on', 'enable', 'enabled', 'false', 'f', 'no', 'n', 'off', 'disable', 'disabled']);
+ }
+
+ async validate(argument, message) {
+ const b = message.content.toLowerCase();
+ const guildLanguage = await message.guild.getLanguage();
+
+ if(!this.answerSet.has(b)) {
+ return this.client.languageFile.ARGS_MUST_CONTAIN[guildLanguage].replace('{argument}', argument.name).replace('{type}', 'boolean')
+ }
+ }
+}
+
+module.exports = BooleanArgumentType;
\ No newline at end of file
diff --git a/src/commands/types/channel.js b/src/commands/types/channel.js
new file mode 100644
index 000000000..e5b7e216d
--- /dev/null
+++ b/src/commands/types/channel.js
@@ -0,0 +1,33 @@
+const ArgumentType = require('./base');
+
+/**
+ * The ChannelArgumentType class
+ * @extends ArgumentType
+ */
+class ChannelArgumentType extends ArgumentType {
+ /**
+ * The ChannelArgumentType class
+ * @param {Client}
+ */
+ constructor(client) {
+ super(client, 'channel')
+
+ /**
+ * client
+ * @type {Client}
+ */
+ this.client = client;
+ }
+
+ async validate(argument, message) {
+ const matches = message.content.match(/([0-9]+)/);
+ const guildLanguage = await message.guild.getLanguage();
+
+ if(!matches) return this.client.languageFile.ARGS_MUST_CONTAIN[guildLanguage].replace('{argument}', argument.name).replace('{type}', 'channel')
+
+ let channel = this.client.channels.cache.get(matches[1]);
+ if(!channel) return this.client.languageFile.ARGS_MUST_CONTAIN[guildLanguage].replace('{argument}', argument.name).replace('{type}', 'channel')
+ }
+}
+
+module.exports = ChannelArgumentType;
\ No newline at end of file
diff --git a/src/commands/types/integer.js b/src/commands/types/integer.js
new file mode 100644
index 000000000..a3f535cce
--- /dev/null
+++ b/src/commands/types/integer.js
@@ -0,0 +1,31 @@
+const ArgumentType = require('./base');
+
+/**
+ * The IntegerArgumentType class
+ * @extends ArgumentType
+ */
+class IntegerArgumentType extends ArgumentType {
+ /**
+ * The IntegerArgumentType class
+ * @param {Client}
+ */
+ constructor(client) {
+ super(client, 'integer')
+
+ /**
+ * client
+ * @type {Client}
+ */
+ this.client = client;
+ }
+
+ async validate(argument, message) {
+ const guildLanguage = await message.guild.getLanguage();
+
+ if(!parseInt(message.content)) return this.client.languageFile.ARGS_MUST_CONTAIN[guildLanguage].replace('{argument}', argument.name).replace('{type}', 'integer')
+
+ if(argument.oneOf && !argument.oneOf.includes(message.content.toLowerCase())) return `Please enter one of the following options: ${argument.oneOf.map(opt => `\`${opt}\``).join(', ')}`;
+ }
+}
+
+module.exports = IntegerArgumentType;
\ No newline at end of file
diff --git a/src/commands/types/role.js b/src/commands/types/role.js
new file mode 100644
index 000000000..89001447d
--- /dev/null
+++ b/src/commands/types/role.js
@@ -0,0 +1,33 @@
+const ArgumentType = require('./base');
+
+/**
+ * The RoleArgumentType class
+ * @param {Client}
+ */
+class RoleArgumentType extends ArgumentType {
+ /**
+ * The RoleArgumentType class
+ * @param {Client}
+ */
+ constructor(client) {
+ super(client, 'role')
+
+ /**
+ * client
+ * @type {Client}
+ */
+ this.client = client;
+ }
+
+ async validate(argument, message) {
+ const matches = message.content.match(/([0-9]+)/);
+ const guildLanguage = await message.guild.getLanguage();
+
+ if(!matches) return this.client.languageFile.ARGS_MUST_CONTAIN[guildLanguage].replace('{argument}', argument.name).replace('{type}', 'role')
+
+ let user = message.guild.roles.cache.get(matches[1]);
+ if(!user) return this.client.languageFile.ARGS_MUST_CONTAIN[guildLanguage].replace('{argument}', argument.name).replace('{type}', 'role')
+ }
+}
+
+module.exports = RoleArgumentType;
\ No newline at end of file
diff --git a/src/commands/types/string.js b/src/commands/types/string.js
new file mode 100644
index 000000000..0f46b24f6
--- /dev/null
+++ b/src/commands/types/string.js
@@ -0,0 +1,22 @@
+const ArgumentType = require('./base');
+
+/**
+ * The StringArgumentType class
+ * @param {Client}
+ */
+class StringArgumentType extends ArgumentType {
+ /**
+ * The StringArgumentType class
+ */
+ constructor(client) {
+ super(client, 'string')
+ }
+
+ async validate(argument, message) {
+ const guildLanguage = await message.guild.getLanguage();
+
+ if(argument.choices && !argument.choices.some(ch => ch.value == message.content.toLowerCase())) return this.client.languageFile.ARGS_CHOICES[guildLanguage].replace('{choices}', argument.choices.map(opt => `\`${opt.name}\``).join(', '))
+ }
+}
+
+module.exports = StringArgumentType;
\ No newline at end of file
diff --git a/src/commands/types/user.js b/src/commands/types/user.js
new file mode 100644
index 000000000..6372526f2
--- /dev/null
+++ b/src/commands/types/user.js
@@ -0,0 +1,33 @@
+const ArgumentType = require('./base');
+
+/**
+ * The UserArgumentType class
+ * @param {Client}
+ */
+class UserArgumentType extends ArgumentType {
+ /**
+ * The UserArgumentType class
+ * @param {Client}
+ */
+ constructor(client) {
+ super(client, 'user')
+
+ /**
+ * client
+ * @type {Client}
+ */
+ this.client = client;
+ }
+
+ async validate(argument, message) {
+ const matches = message.content.match(/([0-9]+)/);
+ const guildLanguage = await message.guild.getLanguage();
+
+ if(!matches) return this.client.languageFile.ARGS_MUST_CONTAIN[guildLanguage].replace('{argument}', argument.name).replace('{type}', 'user')
+
+ let user = this.client.users.cache.get(matches[1]);
+ if(!user) return this.client.languageFile.ARGS_MUST_CONTAIN[guildLanguage].replace('{argument}', argument.name).replace('{type}', 'user')
+ }
+}
+
+module.exports = UserArgumentType;
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index c38b04268..8b116a280 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,37 +2,37 @@
module.exports = {
// Root classes
- GCommandsBase: require("./base/GCommandsBase"),
- GCommands: require("./base/GCommands.js"),
- GEvents: require("./base/GEvents"),
- GCommandsDispatcher: require("./base/GCommandsDispatcher"),
+ GCommandsBase: require('./base/GCommandsBase'),
+ GCommands: require('./base/GCommands.js'),
+ GEventLoader: require('@gcommands/events').GEventLoader,
+ GCommandsDispatcher: require('./base/GCommandsDispatcher'),
// Loaders
- GEventLoader: require("./managers/GEventLoader"),
- GCommandLoader: require("./managers/GCommandLoader"),
- GDatabaseLoader: require("./managers/GDatabaseLoader"),
+ GEventHandling: require('./managers/GEventHandling'),
+ GCommandLoader: require('./managers/GCommandLoader'),
+ GDatabaseLoader: require('./managers/GDatabaseLoader'),
// Structures
- GCommandsGuild: require("./structures/GGuild"),
- GCommandsMessage: require("./structures/GMessage"),
- GNewsChannel: require("./structures/NewsChannel"),
- GTextChannel: require("./structures/TextChannel"),
- GDMChannel: require("./structures/DMChannel"),
- MessageButton: require("./structures/MessageButton"),
- MessageActionRow: require("./structures/MessageActionRow"),
- MessageSelectMenu: require("./structures/MessageSelectMenu"),
- MessageSelectMenuOption: require("./structures/MessageSelectMenuOption"),
-
- ButtonCollectorV12: require("./structures/v13/ButtonCollector"),
- ButtonCollectorV13: require("./structures/v12/ButtonCollector"),
-
- SelectMenuCollectorV12: require("./structures/v13/SelectMenuCollector"),
- SelectMenuCollectorV13: require("./structures/v12/SelectMenuCollector"),
+ GMessage: require('./structures/GMessage'),
+ GNewsChannel: require('./structures/NewsChannel'),
+ GTextChannel: require('./structures/TextChannel'),
+ GDMChannel: require('./structures/DMChannel'),
+ MessageButton: require('./structures/MessageButton'),
+ MessageActionRow: require('./structures/MessageActionRow'),
+ MessageSelectMenu: require('./structures/MessageSelectMenu'),
+ MessageSelectMenuOption: require('./structures/MessageSelectMenuOption'),
+ Command: require('./commands/base'),
+ Event: require('@gcommands/events').Event,
+ GPayload: require('./structures/GPayload'),
+ ButtonCollectorV12: require('./structures/v13/ButtonCollector'),
+ ButtonCollectorV13: require('./structures/v12/ButtonCollector'),
+ SelectMenuCollectorV12: require('./structures/v13/SelectMenuCollector'),
+ SelectMenuCollectorV13: require('./structures/v12/SelectMenuCollector'),
// Other
- Color: require("./structures/Color"),
- Util: require("./util/util"),
- SlashCommand: {
+ Color: require('./structures/Color'),
+ Util: require('./util/util'),
+ ArgumentType: {
SUB_COMMAND: 1,
SUB_COMMAND_GROUP: 2,
STRING: 3,
@@ -44,13 +44,13 @@ module.exports = {
MENTIONABLE: 9
},
ButtonTypes: {
- blurple: "blurple",
- gray: "gray",
- grey: "gray",
- green: "green",
- red: "red",
- url: "url"
+ blurple: 'blurple',
+ gray: 'gray',
+ grey: 'gray',
+ green: 'green',
+ red: 'red',
+ url: 'url'
},
- version: require("../package.json").version
+ version: require('../package.json').version
}
\ No newline at end of file
diff --git a/src/managers/GCommandLoader.js b/src/managers/GCommandLoader.js
index c5929a350..3977bf52e 100644
--- a/src/managers/GCommandLoader.js
+++ b/src/managers/GCommandLoader.js
@@ -1,13 +1,35 @@
-const cmdUtils = require('../util/cmdUtils'), Color = require("../structures/Color"), { Events } = require("../util/Constants")
-const axios = require("axios");
-const fs = require("fs");
-const ms = require("ms")
-
+const cmdUtils = require('../util/cmdUtils'), Color = require('../structures/Color'), { Events } = require('../util/Constants')
+const axios = require('axios');
+const fs = require('fs');
+const ms = require('ms');
+const { isClass } = require('../util/util');
+const Command = require('../commands/base');
+
+/**
+ * The GCommandLoader class
+ */
class GCommandLoader {
+ /**
+ * The GCommandLoader class
+ * @param {GCommands} GCommandsClient
+ */
constructor(GCommandsClient) {
+ /**
+ * GCommandsClient
+ * @type {GCommands}
+ */
this.GCommandsClient = GCommandsClient;
+
+ /**
+ * client
+ * @type {Client}
+ */
this.client = this.GCommandsClient.client;
+ /**
+ * cmdDir
+ * @type {String}
+ */
this.cmdDir = this.GCommandsClient.cmdDir;
this.__loadCommands()
@@ -20,33 +42,45 @@ class GCommandLoader {
*/
async __loadCommands() {
await fs.readdirSync(`${__dirname}/../../../../${this.cmdDir}`).forEach(async(dir) => {
- var file;
- var fileName = dir.split(".").reverse()[1]
- var fileType = dir.split(".").reverse()[0]
- if(fileType == "js" || fileType == "ts") {
+ let file;
+ let fileName = dir.split('.').reverse()[1]
+ let fileType = dir.split('.').reverse()[0]
+ if(fileType == 'js' || fileType == 'ts') {
try {
- file = await require(`../../../../${this.cmdDir}${dir}`);
+ let finalFile;
- if (file && file.aliases && Array.isArray(file.aliases)) file.aliases.forEach(alias => this.client.galiases.set(alias, file.name));
- this.client.gcommands.set(file.name, file);
- this.GCommandsClient.emit(Events.LOG, new Color("&d[GCommands] &aLoaded (File): &e➜ &3" + fileName, {json:false}).getText());
+ file = await require(`../../../../${this.cmdDir}${dir}`);
+ if (isClass(file)) {
+ finalFile = new file(this.client)
+ if(!(finalFile instanceof Command)) return console.log(new Color(`&d[GCommands] &cComamnd ${fileName} doesnt belong in Commands.`).getText())
+ } else finalFile = file;
+
+ if (finalFile && finalFile.aliases && Array.isArray(finalFile.aliases)) finalFile.aliases.forEach(alias => this.client.galiases.set(alias, finalFile.name));
+ this.client.gcommands.set(finalFile.name, finalFile);
+ this.GCommandsClient.emit(Events.LOG, new Color('&d[GCommands] &aLoaded (File): &e➜ &3' + fileName, {json:false}).getText());
} catch(e) {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands Debug] &e("+fileName+") &3"+e).getText());
- this.GCommandsClient.emit(Events.LOG, new Color("&d[GCommands] &cCan't load " + fileName).getText());
+ this.GCommandsClient.emit(Events.DEBUG, new Color('&d[GCommands Debug] &e('+fileName+') &3'+e).getText());
+ this.GCommandsClient.emit(Events.LOG, new Color('&d[GCommands] &cCan\'t load ' + fileName).getText());
}
} else {
fs.readdirSync(`${this.cmdDir}${dir}`).forEach(async(cmdFile) => {
- var file2;
- var fileName2 = cmdFile.split(".").reverse()[1]
+ let file2;
+ let fileName2 = cmdFile.split('.').reverse()[1]
try {
+ let finalFile2;
+
file2 = await require(`../../../../${this.cmdDir}${dir}/${cmdFile}`);
-
- if (file2.aliases && Array.isArray(file2.aliases)) file2.aliases.forEach(alias => this.client.galiases.set(alias, file2.name));
- this.client.gcommands.set(file2.name, file2);
- this.GCommandsClient.emit(Events.LOG, new Color("&d[GCommands] &aLoaded (File): &e➜ &3" + fileName2, {json:false}).getText());
+ if (isClass(file2)) {
+ finalFile2 = new file2(this.client)
+ if(!(finalFile2 instanceof Command)) return console.log(new Color(`&d[GCommands] &cComamnd ${finalFile2} doesnt belong in Commands.`).getText())
+ } else finalFile2 = file2;
+
+ if (finalFile2.aliases && Array.isArray(finalFile2.aliases)) finalFile2.aliases.forEach(alias => this.client.galiases.set(alias, finalFile2.name));
+ this.client.gcommands.set(finalFile2.name, finalFile2);
+ this.GCommandsClient.emit(Events.LOG, new Color('&d[GCommands] &aLoaded (File): &e➜ &3' + fileName2, {json:false}).getText());
} catch(e) {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands Debug] &e("+fileName2+") &3"+e).getText());
- this.GCommandsClient.emit(Events.LOG, new Color("&d[GCommands] &cCan't load " + fileName2).getText());
+ this.GCommandsClient.emit(Events.DEBUG, new Color('&d[GCommands Debug] &e('+fileName2+') &3'+e).getText());
+ this.GCommandsClient.emit(Events.LOG, new Color('&d[GCommands] &cCan\'t load ' + fileName2).getText());
}
})
}
@@ -61,33 +95,22 @@ class GCommandLoader {
* @private
*/
async __createCommands() {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands] &3Creating slash commands...").getText())
+ this.GCommandsClient.emit(Events.DEBUG, new Color('&d[GCommands] &3Creating slash commands...').getText())
let keys = Array.from(this.client.gcommands.keys());
keys.forEach(async (cmdname) => {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands] &3Creating slash command (&e"+cmdname+"&3)").getText());
- var options = [];
- var subCommandGroup = {};
- var subCommand = [];
+ this.GCommandsClient.emit(Events.DEBUG, new Color('&d[GCommands] &3Creating slash command (&e'+cmdname+'&3)').getText());
+ let options = [];
const cmd = this.client.gcommands.get(cmdname)
- if(cmd.slash == false || cmd.slash == "false") return;
+ if(String(cmd.slash) == 'false') return;
- if(!cmd.name) return console.log(new Color("&d[GCommands] &cParameter name is required! ("+cmdname+")",{json:false}).getText());
- if(!cmd.description) return console.log(new Color("&d[GCommands] &cParameter description is required! ("+cmdname+")",{json:false}).getText());
+ if(!cmd.name) return console.log(new Color('&d[GCommands] &cParameter name is required! ('+cmdname+')',{json:false}).getText());
+ if(!cmd.description) return console.log(new Color('&d[GCommands] &cParameter description is required! ('+cmdname+')',{json:false}).getText());
- if(cmd.subCommandGroup) {
- subCommandGroup = [
- {
- name: cmd.subCommandGroup,
- description: cmd.subCommandGroup,
- type: 2
- }
- ]
- }
-
- if (cmd.expectedArgs) {
- if(typeof cmd.expectedArgs == "object") {
- cmd.expectedArgs.forEach(option => {
+ if(cmd.expectedArgs) cmd.args = cmd.expectedArgs
+ if (cmd.args) {
+ if(typeof cmd.args == 'object') {
+ cmd.args.forEach(option => {
options.push({
name: option.name,
description: option.description,
@@ -98,154 +121,84 @@ class GCommandLoader {
})
})
} else {
- var split = cmd.expectedArgs
- .substring(1, cmd.expectedArgs.length - 1)
+ let split = cmd.args
+ .substring(1, cmd.args.length - 1)
.split(/[>\]] [<\[]/)
for (let a = 0; a < split.length; ++a) {
- var item = split[a];
- var option = item.replace(/ /g, '-').split(":")[0] ? item.replace(/ /g, '-').split(":")[0] : item.replace(/ /g, '-');
- var optionType = item.replace(/ /g, '-').split(":")[1] ? item.replace(/ /g, '-').split(":")[1] : 3;
- var optionDescription = item.replace(/ /g, '-').split(":")[2] ? item.replace(/ /g, '-').split(":")[2] : item;
+ let item = split[a];
+ let option = item.replace(/ /g, '-').split(':')[0] ? item.replace(/ /g, '-').split(':')[0] : item.replace(/ /g, '-');
+ let optionType = item.replace(/ /g, '-').split(':')[1] ? item.replace(/ /g, '-').split(':')[1] : 3;
+ let optionDescription = item.replace(/ /g, '-').split(':')[2] ? item.replace(/ /g, '-').split(':')[2] : item;
if(optionType == 1 || optionType == 2) optionType = 3
options.push({
name: option,
- description: optionDescription,
- type: parseInt(optionType),
- required: a < cmd.minArgs ? cmd.minArgs : 0,
+ description: optionDescription || option,
+ type: parseInt(optionType) || 3,
+ required: a < cmd.minArgs,
})
}
}
}
-
- if(cmd.subCommand) {
- cmd.subCommand.forEach(sc => {
- try {
- var opt = []
- var optionsSplit = sc.split(";")[1]
-
- if(optionsSplit) {
- var split = optionsSplit
- .substring(1, optionsSplit.length - 1)
- .split(/[>\]] [<\[]/)
-
- for (let a = 0; a < split.length; ++a) {
- var item = split[a]
- var option = item.replace(/ /g, '-').split(":")[0] ? item.replace(/ /g, '-').split(":")[0] : item.replace(/ /g, '-');
- var optionType = item.replace(/ /g, '-').split(":")[1] ? item.replace(/ /g, '-').split(":")[1] : 3;
- var optionDescription = item.replace(/ /g, '-').split(":")[2] ? item.replace(/ /g, '-').split(":")[2] : item;
- if(optionType == 1 || optionType == 2) optionType = 3
-
- opt.push({
- name: option,
- description: optionDescription,
- type: parseInt(optionType),
- required: a < cmd.minArgs,
- })
- }
- }
-
- subCommand.push({
- name: sc.split(";")[0],
- description: sc.split(";")[0],
- type: 1,
- options: opt || []
- })
- } catch(e) {
- subCommand.push({
- name: sc.name,
- description: sc.description,
- type: 1,
- options: sc.options || []
- })
- }
- })
- }
-
- if(cmd.subCommandGroup) {
- subCommandGroup = [
- {
- name: subCommandGroup[0].name,
- description: subCommandGroup[0].name,
- type: subCommandGroup[0].type,
- options: subCommand
- }
- ]
- }
-
try {
- var url = `https://discord.com/api/v8/applications/${this.client.user.id}/commands`;
+ let url = `https://discord.com/api/v8/applications/${this.client.user.id}/commands`;
if(cmd.guildOnly) url = `https://discord.com/api/v8/applications/${this.client.user.id}/guilds/${cmd.guildOnly}/commands`;
- var cmdd = {
+ let cmdd = {
name: cmd.name.toLowerCase(),
description: cmd.description,
options: options || []
}
- if(cmd.subCommandGroup && cmd.subCommand) {
- cmdd = {
- name: cmd.name.toLowerCase(),
- description: cmd.description,
- options: subCommandGroup || []
- };
- } else {
- cmdd = {
- name: cmd.name.toLowerCase(),
- description: cmd.description,
- options: options || []
- };
- }
-
- var config = {
- method: "POST",
+ let config = {
+ method: 'POST',
headers: {
Authorization: `Bot ${this.client.token}`,
- "Content-Type": "application/json"
+ 'Content-Type': 'application/json'
},
data: JSON.stringify(cmdd),
url,
}
axios(config).then((response) => {
- this.GCommandsClient.emit(Events.LOG, new Color("&d[GCommands] &aLoaded: &e➜ &3" + cmd.name, {json:false}).getText());
+ this.GCommandsClient.emit(Events.LOG, new Color('&d[GCommands] &aLoaded: &e➜ &3' + cmd.name, {json:false}).getText());
})
.catch((error) => {
- console.log(new Color(`&d[GCommands] ${error.response.status == 429 ? "&aWait &e" + ms(error.response.data["retry_after"] * 1000) : ""} &c${error} &e(${cmd.name})`, {json:false}).getText());
+ this.GCommandsClient.emit(Events.LOG, new Color(`&d[GCommands] ${error.response.status == 429 ? '&aWait &e' + ms(error.response.data['retry_after'] * 1000) : ''} &c${error} &e(${cmd.name})`, {json:false}).getText());
if(error.response) {
if(error.response.status == 429) {
setTimeout(() => {
this.__tryAgain(cmd, config)
- }, (error.response.data["retry_after"]) * 1000)
+ }, (error.response.data['retry_after']) * 1000)
} else {
try {
this.GCommandsClient.emit(Events.DEBUG, new Color([
- "&a----------------------",
- " &d[GCommands Debug] &3",
- "&aCode: &b" + error.response.data.code,
- "&aMessage: &b" + error.response.data.message,
- " ",
- "&b" + error.response.data.errors.guild_id._errors[0].code,
- "&b" + rror.response.data.errors.guild_id._errors[0].message,
- "&a----------------------"
+ '&a----------------------',
+ ' &d[GCommands Debug] &3',
+ '&aCode: &b' + error.response.data.code,
+ '&aMessage: &b' + error.response.data.message,
+ ' ',
+ '&b' + error.response.data.errors.guild_id._errors[0].code,
+ '&b' + rror.response.data.errors.guild_id._errors[0].message,
+ '&a----------------------'
]).getText())
} catch(e) {
this.GCommandsClient.emit(Events.DEBUG, new Color([
- "&a----------------------",
- " &d[GCommands Debug] &3",
- "&aCode: &b" + error.response.data.code,
- "&aMessage: &b" + error.response.data.message,
- "&a----------------------"
+ '&a----------------------',
+ ' &d[GCommands Debug] &3',
+ '&aCode: &b' + error.response.data.code,
+ '&aMessage: &b' + error.response.data.message,
+ '&a----------------------'
]).getText())
}
}
}
})
- }catch(e) {
- console.log(e)
+ } catch(e) {
+ this.GCommandsClient.emit(Events.DEBUG, e)
}
})
}
@@ -257,16 +210,16 @@ class GCommandLoader {
*/
async __tryAgain(cmd, config) {
axios(config).then((response) => {
- this.GCommandsClient.emit(Events.LOG, new Color("&d[GCommands] &aLoaded: &e➜ &3" + cmd.name, {json:false}).getText());
+ this.GCommandsClient.emit(Events.LOG, new Color('&d[GCommands] &aLoaded: &e➜ &3' + cmd.name, {json:false}).getText());
})
.catch((error) => {
- console.log(new Color(`&d[GCommands] ${error.response.status == 429 ? "&aWait &e" + ms(error.response.data["retry_after"] * 1000) : ""} &c${error} &e(${cmd.name})`, {json:false}).getText());
+ this.GCommandsClient.emit(Events.LOG, new Color(`&d[GCommands] ${error.response.status == 429 ? '&aWait &e' + ms(error.response.data['retry_after'] * 1000) : ''} &c${error} &e(${cmd.name})`, {json:false}).getText());
if(error.response) {
if(error.response.status == 429) {
setTimeout(() => {
this.__tryAgain(cmd, config)
- }, (error.response.data["retry_after"]) * 1000)
+ }, (error.response.data['retry_after']) * 1000)
}
}
})
@@ -279,20 +232,20 @@ class GCommandLoader {
*/
async __deleteAllGlobalCmds() {
try {
- var allcmds = await cmdUtils.__getAllCommands(this.client);
- if(!this.client.slash) {
+ let allcmds = await cmdUtils.__getAllCommands(this.client);
+ if(String(this.client.slash) == 'false') {
allcmds.forEach(cmd => {
cmdUtils.__deleteCmd(this.client, cmd.id)
})
}
- var nowCMDS = [];
+ let nowCMDS = [];
- var keys = Array.from(this.client.gcommands.keys());
+ let keys = Array.from(this.client.gcommands.keys());
keys.forEach(cmdname => {
nowCMDS.push(cmdname)
- if(this.client.gcommands.get(cmdname).slash == false || this.client.gcommands.get(cmdname).slash == "false") {
+ if(this.client.gcommands.get(cmdname).slash == false || this.client.gcommands.get(cmdname).slash == 'false') {
allcmds.forEach(cmd => {
if(cmd.name == cmdname) {
cmdUtils.__deleteCmd(this.client, cmd.id)
@@ -302,14 +255,14 @@ class GCommandLoader {
})
allcmds.forEach(cmd => {
- var f = nowCMDS.some(v => cmd.name.toLowerCase().includes(v.toLowerCase()))
+ let f = nowCMDS.some(v => cmd.name.toLowerCase().includes(v.toLowerCase()))
if(!f) {
cmdUtils.__deleteCmd(this.client, cmd.id)
}
})
} catch(e) {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands Debug] &3Can't remove global commands!").getText())
+ return;
}
this.__deleteAllGuildCmds()
@@ -323,7 +276,7 @@ class GCommandLoader {
async __deleteAllGuildCmds() {
try {
this.client.guilds.cache.forEach(async(guild) => {
- var allcmds = await cmdUtils.__getAllCommands(this.client, guild.id);
+ let allcmds = await cmdUtils.__getAllCommands(this.client, guild.id);
if(!allcmds) return;
if(!this.client.slash) {
@@ -332,12 +285,13 @@ class GCommandLoader {
})
}
- var nowCMDS = [];
- var keys = Array.from(this.client.gcommands.keys());
+ let nowCMDS = [];
+ let keys = Array.from(this.client.gcommands.keys());
keys.forEach(cmdname => {
nowCMDS.push(cmdname)
+ let command = this.client.gcommands.get(cmdname);
- if(this.client.gcommands.get(cmdname).slash == false || this.client.gcommands.get(cmdname).slash == "false") {
+ if(command.slash == false || command.slash == 'false') {
allcmds.forEach(cmd => {
if(cmd.name == cmdname) {
cmdUtils.__deleteCmd(this.client, cmd.id, guild.id)
@@ -347,7 +301,7 @@ class GCommandLoader {
})
allcmds.forEach(cmd => {
- var f = nowCMDS.some(v => cmd.name.toLowerCase().includes(v.toLowerCase()))
+ let f = nowCMDS.some(v => cmd.name.toLowerCase().includes(v.toLowerCase()))
if(!f) {
cmdUtils.__deleteCmd(this.client, cmd.id, guild.id)
@@ -355,14 +309,12 @@ class GCommandLoader {
})
})
- console.log(new Color("&d[GCommands TIP] &3Are guild commands not deleted when you delete them? Use this site for remove &ehttps://gcommands-slash-gui.netlify.app/").getText())
- if((this.client.slash) || (this.client.slash == "both")) {
+ console.log(new Color('&d[GCommands TIP] &3Are guild commands not deleted when you delete them? Use this site for remove &ehttps://gcommands-slash-gui.netlify.app/').getText())
+ if((this.client.slash) || (this.client.slash == 'both')) {
this.__createCommands();
}
} catch(e) {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands Debug] &3Can't remove guild commands!").getText())
-
- if((this.client.slash) || (this.client.slash == "both")) {
+ if((this.client.slash) || (this.client.slash == 'both')) {
this.__createCommands();
}
}
diff --git a/src/managers/GDatabaseLoader.js b/src/managers/GDatabaseLoader.js
index cb246d546..fffb602af 100644
--- a/src/managers/GDatabaseLoader.js
+++ b/src/managers/GDatabaseLoader.js
@@ -1,10 +1,25 @@
-const Color = require("../structures/Color")
-
+/**
+ * The GDatabaseLoader class
+ */
class GDatabaseLoader {
+ /**
+ * The GDatabaseLoader class
+ * @param {GCommands} GCommandsClient
+ */
constructor(GCommandsClient) {
+
+ /**
+ * GCommandsClient
+ * @type {GCommands}
+ */
this.GCommandsClient = GCommandsClient;
- this.client = this.GCommandsClient.client;
+ /**
+ * client
+ * @type {Client}
+ */
+ this.client = this.GCommandsClient.client;
+
this.__loadDB()
}
@@ -13,32 +28,13 @@ class GDatabaseLoader {
* @returns {boolean}
* @private
*/
- async __loadDB() {
+ __loadDB() {
let dbType = this.GCommandsClient.database;
if(!dbType) this.client.database = undefined;
else {
const Keyv = require('keyv');
this.client.database = new Keyv(dbType)
}
-
- this.__guildConfig()
- }
-
- async __guildConfig() {
- this.client.guilds.cache.forEach(async (guild) => {
- let prefix = await this.client.dispatcher.getGuildPrefix(guild.id, false)
- guild.prefix = prefix;
- })
-
- this.client.guilds.cache.forEach(async (guild) => {
- let language = await this.client.dispatcher.getGuildLanguage(guild.id, false)
- guild.language = language;
- })
-
- this.client.on("guildCreate", (guild) => {
- guild.prefix = this.client.dispatcher.getGuildPrefix(guild.id, false)
- guild.language = this.client.dispatcher.getGuildLanguage(guild.id, false)
- })
}
}
diff --git a/src/managers/GEventHandling.js b/src/managers/GEventHandling.js
new file mode 100644
index 000000000..33bfed736
--- /dev/null
+++ b/src/managers/GEventHandling.js
@@ -0,0 +1,429 @@
+const {Collection} = require('discord.js');
+const { readdirSync } = require('fs');
+const Argument = require('../commands/argument');
+const Color = require('../structures/Color'), { Events } = require('../util/Constants');
+const GInteraction = require('../structures/GInteraction');
+const ifDjsV13 = require('../util/updater').checkDjsVersion('13'), { inhibit, interactionRefactor } = require('../util/util')
+
+/**
+ * The GEventHandling class
+*/
+class GEventHandling {
+
+ /**
+ * Creates new GEventHandling instance
+ * @param {GCommandsClient} GCommandsClient
+ */
+ constructor(GCommandsClient) {
+ /**
+ * GCommandsClient
+ * @type {GCommands}
+ */
+ this.GCommandsClient = GCommandsClient;
+
+ /**
+ * client
+ * @type {Client}
+ */
+ this.client = GCommandsClient.client;
+
+ this.messageEvent()
+ this.slashEvent()
+ this.loadMoreEvents()
+ }
+
+ /**
+ * Internal method to messageEvent
+ * @returns {void}
+ * @private
+ */
+ async messageEvent() {
+ if((this.client.slash == false) || (this.client.slash == 'both')) {
+ this.client.on('message', async(message) => {
+ messageEventUse(message)
+ })
+
+ this.client.on('messageUpdate', async(oldMessage, newMessage) => {
+ if(oldMessage.content == newMessage.content || oldMessage.embeds == newMessage.embeds) return;
+ messageEventUse(newMessage)
+ })
+ }
+
+ let messageEventUse = async(message) => {
+ if (!message || !message.author || message.author.bot || !message.guild) return;
+
+ let mentionRegex = new RegExp(`^<@!?(${this.client.user.id})> `)
+
+ let prefix = message.content.match(mentionRegex) ? message.content.match(mentionRegex) : (await message.guild.getCommandPrefix()).filter(p => message.content.startsWith(p))
+ if(prefix.length === 0) return;
+
+
+ if (this.GCommandsClient.caseSensitivePrefixes && !message.content.toLowerCase().startsWith(prefix[0].toLowerCase())) return;
+ else if (!message.content.startsWith(prefix[0])) return;
+
+ const [cmd, ...args] = message.content.slice(prefix.length).trim().split(/ +/g);
+
+ if (cmd.length === 0) return;
+
+ try {
+ let commandos = this.client.gcommands.get(this.GCommandsClient.caseSensitiveCommands ? cmd.toLowerCase() : cmd);
+ if(!commandos) commandos = this.client.gcommands.get(this.client.galiases.get(this.GCommandsClient.caseSensitiveCommands ? cmd.toLowerCase() : cmd));
+ if(!commandos || String(commandos.slash) == 'true') return;
+
+ let member = message.member, guild = message.guild, channel = message.channel
+ let botMessageInhibit;
+ let inhibitReturn = await inhibit(this.client, interactionRefactor(this.client, commandos), {
+ message, member, guild, channel,
+ /**
+ * Respond
+ * @type {Interface}
+ * @param {RespondOptions} result
+ * @returns {Object}
+ */
+ respond: async(options = undefined) => {
+ if(this.client.autoTyping) channel.startTyping(this.client.autoTyping);
+
+ let msg = await message.send(options);
+ botMessageInhibit = msg;
+
+ if(this.client.autoTyping) channel.stopTyping(true);
+ return msg;
+ },
+ edit: async(options = undefined) => {
+ if(!botMessageInhibit) return console.log(new Color('&d[GCommands Errors] &cFirst you need to send a respond.'))
+ return await botMessageInhibit.edit(options);
+ }
+ }, args, args)
+ if(inhibitReturn == false) return;
+
+ let guildLanguage = await this.client.dispatcher.getGuildLanguage(message.guild.id);
+ let cooldown = await this.client.dispatcher.getCooldown(message.guild.id, message.author.id, commandos)
+ if(cooldown.cooldown) return message.inlineReply(this.client.languageFile.COOLDOWN[guildLanguage].replace(/{COOLDOWN}/g, cooldown.wait).replace(/{CMDNAME}/g, commandos.name))
+
+ if(commandos.nsfw) {
+ if(!message.channel.nsfw) {
+ return ifDjsV13 ? message.inlineReply(this.client.languageFile.NSFW[guildLanguage]) : message.reply(this.client.languageFile.NSFW[guildLanguage]);
+ }
+ }
+
+ if(commandos.guildOnly) {
+ if(message.guild.id !== commandos.guildOnly) return;
+ }
+
+ if(commandos.userOnly) {
+ if(typeof commandos.userOnly == 'object') {
+ let users = commandos.userOnly.some(v => message.author.id == v)
+ if(!users) return;
+ } else {
+ if(message.author.id !== commandos.userOnly) return;
+ }
+ }
+
+ if(commandos.channelOnly) {
+ if(typeof commandos.channelOnly == 'object') {
+ let channels = commandos.channelOnly.some(v => message.channel.id == v)
+ if(!channels) return;
+ } else {
+ if(message.channel.id !== commandos.channelOnly) return;
+ }
+ }
+
+ if(commandos.channelTextOnly && message.channel.type != 'text') return message.send(this.client.languageFile.CHANNEL_TEXT_ONLY[guildLanguage])
+ if(commandos.channelNewsOnly && message.channel.type != 'news') return message.send(this.client.languageFile.CHANNEL_NEWS_ONLY[guildLanguage])
+
+ if(commandos.clientRequiredPermissions) {
+ if(!Array.isArray(commandos.clientRequiredPermissions)) commandos.clientRequiredPermissions = [commandos.clientRequiredPermissions];
+
+ if(message.channel.permissionsFor(message.guild.me).missing(commandos.clientRequiredPermissions).length > 0) {
+ let permsNeed = this.client.languageFile.MISSING_CLIENT_PERMISSIONS[guildLanguage].replace('{PERMISSION}',commandos.clientRequiredPermissions.map(v => v.split(' ').map(vv => vv[0].toUpperCase() + vv.slice(1).toLowerCase()).join(' ')).join(', '));
+ return ifDjsV13 ? message.inlineReply(permsNeed) : message.reply(permsNeed);
+ }
+ }
+
+ if(commandos.userRequiredPermissions) {
+ if(!Array.isArray(commandos.userRequiredPermissions)) commandos.userRequiredPermissions = [commandos.userRequiredPermissions];
+
+ if(!member.permissions.has(commandos.userRequiredPermissions)) {
+ let permsNeed = this.client.languageFile.MISSING_PERMISSIONS[guildLanguage].replace('{PERMISSION}',commandos.userRequiredPermissions.map(v => v.split(' ').map(vv => vv[0].toUpperCase() + vv.slice(1).toLowerCase()).join(' ')).join(', '));
+ return ifDjsV13 ? message.inlineReply(permsNeed) : message.reply(permsNeed);
+ }
+ }
+
+ if(commandos.userRequiredRoles) {
+ if(!Array.isArray(commandos.userRequiredRoles)) commandos.userRequiredRoles = [commandos.userRequiredRoles];
+
+ let roles = commandos.userRequiredRoles.some(v => member._roles.includes(v))
+ if(!roles) {
+ let permsNeed = this.client.languageFile.MISSING_ROLES[guildLanguage].replace('{ROLES}', `\`${commandos.userRequiredRoles.map(r => message.guild.roles.cache.get(r).name).join(', ')}\``);
+ return ifDjsV13 ? message.inlineReply(permsNeed) : message.reply(permsNeed);
+ }
+ }
+
+ if(commandos.userRequiredRole) {
+ if(!Array.isArray(commandos.userRequiredRole)) commandos.userRequiredRole = [commandos.userRequiredRole];
+
+ let roles = commandos.userRequiredRole.some(v => member._roles.includes(v))
+ if(!roles) {
+ let permsNeed = this.client.languageFile.MISSING_ROLES[guildLanguage].replace('{ROLES}', `\`${commandos.userRequiredRoles.map(r => message.guild.roles.cache.get(r).name).join(', ')}\``);
+ return ifDjsV13 ? message.inlineReply(permsNeed) : message.reply(permsNeed);
+ }
+ }
+
+ for(let i in commandos.args) {
+ let arg = new Argument(this.client, commandos.args[i]);
+
+ if(args[i]) {
+ let argInvalid = await arg.argument.validate(arg, {content: args[i], guild: message.guild})
+ if(argInvalid) {
+ let argInput = await arg.obtain(message, argInvalid)
+ if(!argInput.valid) argInput = await arg.obtain(message, argInput.prompt);
+
+ if(argInput.timeLimit) return message.reply(this.client.languageFile.ARGS_TIME_LIMIT[guildLanguage]);
+ args[i] = argInput.content;
+ }
+
+ continue;
+ }
+
+ let argInput = await arg.obtain(message)
+ if(!argInput.valid) argInput = await arg.obtain(message, argInput.prompt);
+
+ if(argInput.timeLimit) return message.reply(this.client.languageFile.ARGS_TIME_LIMIT[guildLanguage]);
+ args[i] = argInput.content;
+ }
+
+ this.GCommandsClient.emit(Events.DEBUG, new Color('&d[GCommands Debug] &3User &a' + message.author.id + '&3 used &a' + cmd).getText())
+
+ const client = this.client, bot = this.client
+ let botMessage;
+ commandos.run({
+ client, bot, message, member, guild, channel,
+ /**
+ * Respond
+ * @type {Interface}
+ * @param {RespondOptions} result
+ * @returns {Object}
+ */
+ respond: async(options = undefined) => {
+ if(this.client.autoTyping) channel.startTyping(this.client.autoTyping);
+
+ let msg = await message.send(options);
+ botMessage = msg;
+
+ if(this.client.autoTyping) channel.stopTyping(true);
+ return msg;
+ },
+ edit: async(options = undefined) => {
+ if(!botMessage) return console.log(new Color('&d[GCommands Errors] &cFirst you need to send a respond.'))
+ return await botMessage.edit(options);
+ }
+ }, args, args)
+ } catch(e) {
+ this.GCommandsClient.emit(Events.DEBUG, e);
+
+ if(!this.GCommandsClient.unkownCommandMessage) return;
+ if(this.client.languageFile.UNKNOWN_COMMAND[this.client.language]) {
+ message.channel.send(this.client.languageFile.UNKNOWN_COMMAND[guildLanguage].replace('{COMMAND}',cmd));
+ }
+ }
+ }
+ }
+
+ /**
+ * Internal method to slashEvent
+ * @returns {void}
+ * @private
+ */
+ async slashEvent() {
+ if((this.client.slash) || (this.client.slash == 'both')) {
+ this.client.ws.on('INTERACTION_CREATE', async (int) => {
+ let interaction = new GInteraction(this.client, int)
+ if(interaction.type !== 2) return;
+
+ try {
+ let commandos = this.client.gcommands.get(this.GCommandsClient.caseSensitiveCommands ? interaction.interaction.name.toLowerCase() : interaction.interaction.name);
+ if(!commandos || String(commandos.slash) == 'false') return;
+
+ let inhibitReturn = await inhibit(this.client, interactionRefactor(this.client, commandos), {
+ interaction,
+ member: interaction.member,
+ author: interaction.user,
+ guild: interaction.guild,
+ channel: interaction.channel,
+ respond: async(result) => {
+ return interaction.reply.send(result);
+ },
+ edit: async(result) => {
+ return interaction.reply.edit(result);
+ }
+ }, await this.getSlashArgs(interaction.interaction.options || []), await this.getSlashArgsObject(interaction.interaction.options || []))
+ if(inhibitReturn == false) return;
+
+ let guildLanguage = await this.client.dispatcher.getGuildLanguage(interaction.guild.id);
+ let cooldown = await this.client.dispatcher.getCooldown(interaction.guild.id, interaction.author.id, commandos)
+ if(cooldown.cooldown) return interaction.reply.send(this.client.languageFile.COOLDOWN[guildLanguage].replace(/{COOLDOWN}/g, cooldown.wait).replace(/{CMDNAME}/g, commandos.name))
+
+ if(commandos.nsfw && !interaction.channel.nsfw) return interaction.reply.send(this.client.languageFile.NSFW[guildLanguage])
+
+ if(commandos.userOnly) {
+ if(typeof commandos.userOnly == 'object') {
+ let users = commandos.userOnly.some(v => interaction.user.id == v)
+ if(!users) return;
+ } else {
+ if(interaction.author.id !== commandos.userOnly) return;
+ }
+ }
+
+ if(commandos.channelOnly) {
+ if(typeof commandos.channelOnly == 'object') {
+ let channels = commandos.channelOnly.some(v => interaction.channel.id == v);
+ if(!channels) return;
+ } else {
+ if(interaction.channel.id !== commandos.channelOnly) return;
+ }
+ }
+
+ if(commandos.channelTextOnly && interaction.channel.type != 'text') return interaction.reply.send({content: this.client.languageFile.CHANNEL_TEXT_ONLY[guildLanguage], ephemeral: true})
+ if(commandos.channelNewsOnly && interaction.channel.type != 'news') return interaction.reply.send({content: this.client.languageFile.CHANNEL_NEWS_ONLY[guildLanguage], ephemeral: true})
+
+ if(commandos.clientRequiredPermissions) {
+ if(!Array.isArray(commandos.clientRequiredPermissions)) commandos.clientRequiredPermissions = [commandos.clientRequiredPermissions];
+
+ if(interaction.guild.channels.cache.get(interaction.channel.id).permissionsFor(interaction.guild.me).missing(commandos.clientRequiredPermissions).length > 0) return interaction.reply.send({content: this.client.languageFile.MISSING_CLIENT_PERMISSIONS[guildLanguage].replace('{PERMISSION}',commandos.clientRequiredPermissions.map(v => v.split(' ').map(vv => vv[0].toUpperCase() + vv.slice(1).toLowerCase()).join(' ')).join(', ')), ephemeral: true})
+ }
+
+ if(commandos.userRequiredPermissions) {
+ if(!Array.isArray(commandos.userRequiredPermissions)) commandos.userRequiredPermissions = [commandos.userRequiredPermissions];
+
+ if(!interaction.member.permissions.has(commandos.userRequiredPermissions)) return interaction.reply.send({content:this.client.languageFile.MISSING_PERMISSIONS[guildLanguage].replace('{PERMISSION}',commandos.userRequiredPermissions.map(v => v.split(' ').map(vv => vv[0].toUpperCase() + vv.slice(1).toLowerCase()).join(' ')).join(', ')), ephemeral: true})
+ }
+
+ if((commandos.userRequiredRoles) || (commandos.userRequiredRole)) {
+ if(commandos.userRequiredRole) commandos.userRequiredRoles = commandos.userRequiredRole;
+ if(!Array.isArray(commandos.userRequiredRoles)) commandos.userRequiredRoles = [commandos.userRequiredRoles];
+
+ let roles = commandos.userRequiredRoles.some(v => interaction.member.roles.includes(v))
+ if(!roles) return interaction.reply.send({content: this.client.languageFile.MISSING_ROLES[guildLanguage].replace('{ROLES}', `\`${commandos.userRequiredRoles.map(r => interaction.guild.roles.cache.get(r).name).join(', ')}\``), ephemeral: true})
+ }
+
+ try {
+ /**
+ * Return system for slash
+ * @name ReturnSystem
+ * @param {DiscordClient} client
+ * @param {Object} interaction
+ * @example
+ * return {
+ * content: 'hi',
+ * ephemeral: true,
+ * allowedMentions: { parse: [], repliedUser: true }
+ * }
+ */
+
+ const client = this.client, bot = this.client
+ commandos.run({
+ client, bot, interaction,
+ member: interaction.member,
+ author: interaction.user,
+ guild: interaction.guild,
+ channel: interaction.channel,
+ /**
+ * Respond
+ * @type {Interface}
+ * @param {RespondOptions} result
+ * @returns {Object}
+ */
+ respond: async(result) => {
+ return interaction.reply.send(result);
+ },
+ edit: async(result) => {
+ return interaction.reply.edit(result);
+ }
+ }, await this.getSlashArgs(interaction.interaction.options || []), await this.getSlashArgsObject(interaction.interaction.options || []))
+ } catch(e) {
+ this.GCommandsClient.emit(Events.DEBUG, new Color('&d[GCommands Debug] &3' + e).getText())
+ }
+
+ this.GCommandsClient.emit(Events.DEBUG, new Color('&d[GCommands Debug] &3User &a' + interaction.member.user.id + '&3 used &a' + interaction.interaction.name).getText())
+ }catch(e) {
+ this.GCommandsClient.emit(Events.DEBUG, e);
+
+ if(!this.unkownCommandMessage) return;
+ if(this.client.languageFile.UNKNOWN_COMMAND[guildLanguage]) {
+ this.client.api.interactions(interaction.id, interaction.token).callback.post({
+ data: {
+ type: 4,
+ data: {
+ content: this.client.languageFile.UNKNOWN_COMMAND[guildLanguage].replace('{COMMAND}',interaction.data.name)
+ }
+ }
+ });
+ }
+ }
+ })
+ }
+ }
+
+ /**
+ * Internal method to loadMoreEvents
+ * @returns {void}
+ * @private
+ */
+ async loadMoreEvents() {
+ await readdirSync(`${__dirname}/../base/actions/`).forEach(file => {
+ require(`../base/actions/${file}`)(this.client)
+ })
+ }
+
+ /**
+ * Internal method to getSlashArgs
+ * @returns {Array}
+ * @private
+ */
+ getSlashArgs(options) {
+ let args = [];
+
+ let check = (option) => {
+ if (!option) return;
+ if (option.value) args.push(option.value);
+ else args.push(option.name);
+
+ if (option.options) {
+ for (let o = 0; o < option.options.length; o++) {
+ check(option.options[o]);
+ }
+ }
+ }
+
+ if (Array.isArray(options)) {
+ for (let o = 0; o < options.length; o++) {
+ check(options[o]);
+ }
+ } else {
+ check(options);
+ }
+
+ return args;
+ }
+
+ /**
+ * Internal method to getSlashArgsObject
+ * @returns {object}
+ * @private
+ */
+ getSlashArgsObject(options) {
+ let args = {};
+
+ for (let o of options) {
+ if (o.type == 1) args[o.name] = this.getSlashArgsObject(o.options || []);
+ else if (o.type == 2) args[o.name] = this.getSlashArgsObject(o.options || []);
+ else {
+ args[o.name] = o.value;
+ }
+ }
+
+ return args;
+ }
+}
+
+module.exports = GEventHandling;
\ No newline at end of file
diff --git a/src/managers/GEventLoader.js b/src/managers/GEventLoader.js
index ddffc9c31..4fe3011ba 100644
--- a/src/managers/GEventLoader.js
+++ b/src/managers/GEventLoader.js
@@ -1,720 +1,48 @@
-const { default: axios } = require("axios");
-const {Collection,MessageEmbed, Message} = require("discord.js");
-const Color = require("../structures/Color"), { Events } = require("../util/Constants")
-const GMessage = require("../structures/GMessage");
-const ifDjsV13 = require("../util/updater").checkDjsVersion("13")
+// ONLY FOR DOCS
+const GEvents = require('@gcommands/events')
/**
- * The GCommandsEventLoader class
-*/
-class GEventLoader {
-
- /**
- * Creates new GCommandsEventLoader instance
- * @param {GCommandsClient} GCommandsClient
- */
- constructor(GCommandsClient) {
- /**
- * GCommandsEventLoader options
- * @property {Object} GCommandsClient
- */
- this.GCommandsClient = GCommandsClient;
-
- this.client = GCommandsClient.client;
-
- this.messageEvent()
- this.slashEvent()
- this.loadMoreEvents()
- }
-
- /**
- * Internal method to messageEvent
- * @returns {void}
- * @private
- */
- async messageEvent() {
- if(this.client == undefined) return;
- if((this.client.slash == false) || (this.client.slash == "both")) {
- this.client.on('message', async(message) => {
- messageEventUse(message)
- })
-
- this.client.on('messageUpdate', async(oldMessage, newMessage) => {
- if(oldMessage.content == newMessage.content || oldMessage.embeds == newMessage.embeds) return;
- messageEventUse(newMessage)
- })
- }
-
- let messageEventUse = async(message) => {
- if(!message) return;
- if (!message.author || message.author.bot) return;
- if (!message.guild) return;
-
- let mentionRegex = new RegExp(`^<@!?(${this.client.user.id})> `)
-
- let clientDefaultPrefix;
- if(Array.isArray(this.client.prefix)) {
- this.client.prefix.some(pf => {
- if(message.content.startsWith(pf)) {
- clientDefaultPrefix = pf;
- }
- })
- } else clientDefaultPrefix = this.client.prefix
-
- let prefix = message.content.match(mentionRegex) ? message.content.match(mentionRegex)[0] : clientDefaultPrefix
-
- if(this.client.database) {
- let guildDefaultPrefix;
- if(Array.isArray(message.guild.prefix)) {
- message.guild.prefix.some(pf => {
- if(message.content.startsWith(pf)) {
- guildDefaultPrefix = pf;
- }
- })
- } else guildDefaultPrefix = message.guild.prefix
-
- let guildSettings = guildDefaultPrefix || clientDefaultPrefix;
- prefix = message.content.match(mentionRegex) ? message.content.match(mentionRegex)[0] : guildSettings
- }
-
- if (!message.content.startsWith(prefix)) return;
-
- const args = message.content.slice(prefix.length).trim().split(/ +/g);
- const cmd = args.shift().toLowerCase();
-
- if (cmd.length === 0) return;
-
- try {
- let commandos = this.client.gcommands.get(cmd);
- if(!commandos) commandos = this.client.gcommands.get(this.client.galiases.get(cmd));
- if(!commandos) return;
- if(commandos.slash == true || commandos.slash == "true") return;
-
- let member = message.member, guild = message.guild, channel = message.channel
- let inhibit = await this.inhibit(commandos, {
- message, member, guild, channel,
- /**
- * Respond
- * @type {Interface}
- * @param {RespondOptions} result
- * @returns {Object}
- */
- respond: async(options = undefined) => {
- if(this.client.autoTyping) channel.startTyping(this.client.autoTyping);
-
- if(ifDjsV13) options.client = this.client, options.channel = message.channel
- if(typeof options == "object" && options.content) {
- msg = await ifDjsV13 ? GMessage.buttons(options.content, options) : message.buttons(options.content, options)
- } else if(typeof options == "object" && !options.content) {
- if(ifDjsV13) options.client = this.client, options.channel = message.channel
- if(options.inlineReply) msg = await ifDjsV13 ? GMessage.inlineReply(options) : message.inlineReply(options)
- else msg = await message.channel.send(options)
- } else {
- if(options.inlineReply) msg = await ifDjsV13 ? GMessage.inlineReply({content:options}) : message.inlineReply({content:options});
- else msg = await message.channel.send(options)
- }
-
- msg = msg.toJSON()
- msg.client = this.client;
- msg.createButtonCollector = function createButtonCollector(filter, options) {return client.dispatcher.createButtonCollector(msg, filter, options)}
- msg.awaitButtons = function awaitButtons(filter, options) {return client.dispatcher.awaitButtons(msg, filter, options)}
- msg.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return client.dispatcher.createSelectMenuCollector(msg, filter, options)};
- msg.awaitSelectMenus = function awaitSelectMenus(filter, options) {return client.dispatcher.awaitSelectMenus(msg, filter, options)};
-
- if(this.client.autoTyping) channel.stopTyping(true);
- return msg;
- },
- edit: async(options = undefined) => {
- if(ifDjsV13) options.client = this.client, options.channel = message.channel
- if(typeof options == "object" && options.content) {
- msg = await ifDjsV13 ? GMessage.buttonsEdit(msg.id, options.content, options) : message.buttonsEdit(msg.id, options.content, options)
- } else {
- msg = ifDjsV13 ? GMessage.buttonsEdit(msg.id, options, []) : message.buttonsEdit(msg.id, options, [])
- }
-
- msg = await msg;
- msg = msg.toJSON()
- msg.client = this.client;
- msg.createButtonCollector = function createButtonCollector(filter, options) {return client.dispatcher.createButtonCollector(msg, filter, options)}
- msg.awaitButtons = function awaitButtons(filter, options) {return client.dispatcher.awaitButtons(msg, filter, options)}
- msg.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return client.dispatcher.createSelectMenuCollector(msg, filter, options)};
- msg.awaitSelectMenus = function awaitSelectMenus(filter, options) {return client.dispatcher.awaitSelectMenus(msg, filter, options)};
-
- return msg;
- }
- })
- if(inhibit == false) return;
-
- let guildLanguage = await this.client.dispatcher.getGuildLanguage(message.guild.id);
- let cooldown = await this.client.dispatcher.getCooldown(message.guild.id, message.author.id, commandos)
- if(cooldown.cooldown) return message.inlineReply(this.client.languageFile.COOLDOWN[guildLanguage].replace(/{COOLDOWN}/g, cooldown.wait).replace(/{CMDNAME}/g, commandos.name))
-
- if(commandos.nsfw) {
- if(!message.channel.nsfw) {
- return message.inlineReply(this.client.languageFile.NSFW[guildLanguage])
- }
- }
-
- if(commandos.guildOnly) {
- if(message.guild.id != commandos.guildOnly) {
- return;
- }
- }
-
- if(commandos.userOnly) {
- if(typeof commandos.userOnly == "object") {
- let users = commandos.userOnly.some(v => message.author.id == v)
- if(!users) {
- return
- }
- } else {
- if(message.author.id != commandos.userOnly) {
- return;
- }
- }
- }
-
- if(commandos.channelOnly) {
- if(typeof commandos.channelOnly == "object") {
- let channels = commandos.channelOnly.some(v => message.channel.id == v)
- if(!channels) {
- return
- }
- } else {
- if(message.channel.id != commandos.channelOnly) {
- return;
- }
- }
- }
-
- if(commandos.clientRequiredPermissions) {
- if(!Array.isArray(commandos.clientRequiredPermissions)) commandos.clientRequiredPermissions = [commandos.clientRequiredPermissions]
- if(message.channel.permissionsFor(message.guild.me).missing(commandos.clientRequiredPermissions).length > 0) {
- message.channel.send(this.client.languageFile.MISSING_CLIENT_PERMISSIONS[guildLanguage].replace("{PERMISSION}",commandos.clientRequiredPermissions.map(v => v.split(" ").map(vv => vv[0].toUpperCase() + vv.slice(1).toLowerCase()).join(" ")).join(", ")))
- return;
- }
- }
-
- if(commandos.userRequiredPermissions) {
- if(!Array.isArray(commandos.userRequiredPermissions)) commandos.userRequiredPermissions = [commandos.userRequiredPermissions]
- if(this.client.discordjsversion.includes("12.")) {
- if(!message.member.hasPermission(commandos.userRequiredPermissions)) {
- message.channel.send(this.client.languageFile.MISSING_PERMISSIONS[guildLanguage].replace("{PERMISSION}",commandos.userRequiredPermissions.map(v => v.split(" ").map(vv => vv[0].toUpperCase() + vv.slice(1).toLowerCase()).join(" ")).join(", ")))
- return;
- }
- } else {
- if(!message.member.permissions.has(commandos.userRequiredPermissions)) {
- message.channel.send(this.client.languageFile.MISSING_PERMISSIONS[guildLanguage].replace("{PERMISSION}",commandos.userRequiredPermissions.map(v => v.split(" ").map(vv => vv[0].toUpperCase() + vv.slice(1).toLowerCase()).join(" ")).join(", ")))
- return;
- }
- }
- }
-
- if(commandos.userRequiredRoles) {
- if(!Array.isArray(commandos.userRequiredRoles)) commandos.userRequiredRoles = [commandos.userRequiredRoles]
-
- let roles = commandos.userRequiredRoles.some(v => message.member._roles.includes(v))
- if(!roles) {
- message.channel.send(this.client.languageFile.MISSING_ROLES[guildLanguage].replace("{ROLES}", `\`${commandos.userRequiredRoles.map(r => message.guild.roles.cache.get(r).name).join(", ")}\``))
- return;
- }
- }
-
- if(commandos.userRequiredRole) {
- if(!Array.isArray(commandos.userRequiredRole)) commandos.userRequiredRole = [commandos.userRequiredRole]
-
- let roles = commandos.userRequiredRole.some(v => message.member._roles.includes(v))
- if(!roles) {
- message.channel.send(this.client.languageFile.MISSING_ROLES[guildLanguage].replace("{ROLES}", `\`${commandos.userRequiredRoles.map(r => message.guild.roles.cache.get(r).name).join(", ")}\``))
- return;
- }
- }
-
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands Debug] &3User &a" + message.author.id + "&3 used &a" + cmd).getText())
-
- const client = this.client, bot = this.client
- var msg = "";
- commandos.run({
- client, bot, message, member, guild, channel,
- /**
- * Respond
- * @type {Interface}
- * @param {RespondOptions} result
- * @returns {Object}
- */
- respond: async(options = undefined) => {
- if(this.client.autoTyping) channel.startTyping(this.client.autoTyping);
-
- if(ifDjsV13) options.client = this.client, options.channel = message.channel
- if(typeof options == "object" && options.content) {
- msg = await ifDjsV13 ? GMessage.buttons(options.content, options) : message.buttons(options.content, options)
- } else if(typeof options == "object" && !options.content) {
- if(ifDjsV13) options.client = this.client, options.channel = message.channel
- if(options.inlineReply) msg = await ifDjsV13 ? GMessage.inlineReply(options) : message.inlineReply(options)
- else msg = await message.channel.send(options)
- } else {
- if(options.inlineReply) msg = await ifDjsV13 ? GMessage.inlineReply({content:options}) : message.inlineReply({content:options});
- else msg = await message.channel.send(options)
- }
-
- msg = await msg;
- msg = msg.toJSON()
- msg.client = this.client;
- msg.createButtonCollector = function createButtonCollector(filter, options) {return client.dispatcher.createButtonCollector(msg, filter, options)}
- msg.awaitButtons = function awaitButtons(filter, options) {return client.dispatcher.awaitButtons(msg, filter, options)}
- msg.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return client.dispatcher.createSelectMenuCollector(msg, filter, options)};
- msg.awaitSelectMenus = function awaitSelectMenus(filter, options) {return client.dispatcher.awaitSelectMenus(msg, filter, options)};
-
- if(this.client.autoTyping) channel.stopTyping(true);
- return msg;
- },
- edit: async(options = undefined) => {
- if(ifDjsV13) options.client = this.client, options.channel = message.channel
- if(typeof options == "object" && options.content) {
- msg = await ifDjsV13 ? GMessage.buttonsEdit(msg.id, options.content, options) : message.buttonsEdit(msg.id, options.content, options)
- } else {
- msg = ifDjsV13 ? GMessage.buttonsEdit(msg.id, options, []) : message.buttonsEdit(msg.id, options, [])
- }
-
- msg = await msg;
- msg = msg.toJSON()
- msg.client = this.client;
- msg.createButtonCollector = function createButtonCollector(filter, options) {return client.dispatcher.createButtonCollector(msg, filter, options)}
- msg.awaitButtons = function awaitButtons(filter, options) {return client.dispatcher.awaitButtons(msg, filter, options)}
- msg.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return client.dispatcher.createSelectMenuCollector(msg, filter, options)};
- msg.awaitSelectMenus = function awaitSelectMenus(filter, options) {return client.dispatcher.awaitSelectMenus(msg, filter, options)};
-
- return msg;
- }
- }, args, args)
- } catch(e) {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands Debug] &3" + e).getText())
- if(!this.GCommandsClient.unkownCommandMessage) return;
- if(this.client.languageFile.UNKNOWN_COMMAND[this.client.language]) {
- message.channel.send(this.client.languageFile.UNKNOWN_COMMAND[guildLanguage].replace("{COMMAND}",cmd));
- }
- }
- }
- }
+ * The GEventLoader class
+ */
+class GEventLoader extends null {}
- /**
- * Internal method to slashEvent
- * @returns {void}
- * @private
- */
- async slashEvent() {
- if(this.client == undefined) return;
- if((this.client.slash) || (this.client.slash == "both")) {
- this.client.ws.on('INTERACTION_CREATE', async (interaction) => {
- if(interaction.type != 2) return;
-
- if(this.client == undefined) return;
- try {
- let commandos = this.client.gcommands.get(interaction.data.name);
- if(!commandos) return;
- if(commandos.slash == false || commandos.slash == "false") return;
- if (!this.client.cooldowns.has(commandos.name)) {
- this.client.cooldowns.set(commandos.name, new Collection());
- }
-
- let guild = await this.client.guilds.cache.get(interaction.guild_id)
- let member = guild.members.cache.get(interaction.member.user.id);
-
- let inhibit = await this.inhibit(commandos, {
- interaction, member,
- guild: guild,
- channel: guild.channels.cache.get(interaction.channel_id),
- respond: async(result) => {
- return this.slashRespond(guild.channels.cache.get(interaction.channel_id), interaction, result);
- },
- edit: async(result) => {
- return this.slashEdit(interaction, result);
- }
- })
- if(inhibit == false) return;
-
- let guildLanguage = await this.client.dispatcher.getGuildLanguage(member.guild.id);
- let cooldown = await this.client.dispatcher.getCooldown(member.guild.id, member.user.id, commandos)
- if(cooldown.cooldown) {
- return this.client.api.interactions(interaction.id, interaction.token).callback.post({
- data: {
- type: 4,
- data: {
- flags: 64,
- content: this.client.languageFile.COOLDOWN[guildLanguage].replace(/{COOLDOWN}/g, cooldown.wait).replace(/{CMDNAME}/g, commandos.name)
- }
- }
- });
- }
-
- if(commandos.nsfw) {
- if(!member.guild.channels.cache.get(interaction.channel_id).nsfw) {
- return this.client.api.interactions(interaction.id, interaction.token).callback.post({
- data: {
- type: 4,
- data: {
- flags: 64,
- content: this.client.languageFile.NSFW[guildLanguage]
- }
- }
- });
- }
- }
-
- if(commandos.userOnly) {
- if(typeof commandos.userOnly == "object") {
- let users = commandos.userOnly.some(v => interaction.member.user.id == v)
- if(!users) {
- return;
- }
- } else {
- if(interaction.member.user.id != commandos.userOnly) {
- return;
- }
- }
- }
-
- if(commandos.channelOnly) {
- if(typeof commandos.channelOnly == "object") {
- let users = commandos.channelOnly.some(v => interaction.channel_id == v)
- if(!users) {
- return;
- }
- } else {
- if(interaction.channel_id != commandos.channelOnly) {
- return;
- }
- }
- }
-
- if(commandos.clientRequiredPermissions) {
- if(!Array.isArray(commandos.clientRequiredPermissions)) commandos.clientRequiredPermissions = [commandos.clientRequiredPermissions]
- if(member.guild.channels.cache.get(interaction.channel_id).permissionsFor(member.guild.me).missing(commandos.clientRequiredPermissions).length > 0) {
- this.client.api.interactions(interaction.id, interaction.token).callback.post({
- data: {
- type: 4,
- data: {
- flags: 64,
- content: this.client.languageFile.MISSING_CLIENT_PERMISSIONS[guildLanguage].replace("{PERMISSION}",commandos.clientRequiredPermissions.map(v => v.split(" ").map(vv => vv[0].toUpperCase() + vv.slice(1).toLowerCase()).join(" ")).join(", "))
- }
- }
- });
- return;
- }
- }
-
- if(commandos.userRequiredPermissions) {
- if(!Array.isArray(commandos.userRequiredPermissions)) commandos.userRequiredPermissions = [commandos.userRequiredPermissions]
- if(this.client.discordjsversion.includes("12.")) {
- if(!this.client.guilds.cache.get(interaction.guild_id).members.cache.get(interaction.member.user.id).hasPermission(commandos.userRequiredPermissions)) {
- this.client.api.interactions(interaction.id, interaction.token).callback.post({
- data: {
- type: 4,
- data: {
- flags: 64,
- content: this.client.languageFile.MISSING_PERMISSIONS[guildLanguage].replace("{PERMISSION}",commandos.userRequiredPermissions.map(v => v.split(" ").map(vv => vv[0].toUpperCase() + vv.slice(1).toLowerCase()).join(" ")).join(", "))
- }
- }
- });
- return;
- }
- } else {
- if(!this.client.guilds.cache.get(interaction.guild_id).members.cache.get(interaction.member.user.id).permissions.has(commandos.userRequiredPermissions)) {
- this.client.api.interactions(interaction.id, interaction.token).callback.post({
- data: {
- type: 4,
- data: {
- flags: 64,
- content: this.client.languageFile.MISSING_PERMISSIONS[guildLanguage].replace("{PERMISSION}",commandos.userRequiredPermissions.map(v => v.split(" ").map(vv => vv[0].toUpperCase() + vv.slice(1).toLowerCase()).join(" ")).join(", "))
- }
- }
- });
- return;
- }
- }
- }
-
- if(commandos.userRequiredRoles) {
- if(!Array.isArray(commandos.userRequiredRoles)) commandos.userRequiredRoles = [commandos.userRequiredRoles]
-
- let roles = commandos.userRequiredRoles.some(v => interaction.member.roles.includes(v))
- if(!roles) {
- this.client.api.interactions(interaction.id, interaction.token).callback.post({
- data: {
- type: 4,
- data: {
- flags: 64,
- content: this.client.languageFile.MISSING_ROLES[guildLanguage].replace("{ROLES}", `\`${commandos.userRequiredRoles.map(r => member.guild.roles.cache.get(r).name).join(", ")}\``),
- }
- }
- });
- return;
- }
- }
-
- if(commandos.userRequiredRole) {
- if(!Array.isArray(commandos.userRequiredRole)) commandos.userRequiredRole = [commandos.userRequiredRole]
-
- let roles = commandos.userRequiredRole.some(v => interaction.member.roles.includes(v))
- if(!roles) {
- this.client.api.interactions(interaction.id, interaction.token).callback.post({
- data: {
- type: 4,
- data: {
- flags: 64,
- content: this.client.languageFile.MISSING_ROLES[guildLanguage].replace("{ROLES}", `\`${commandos.userRequiredRoles.map(r => member.guild.roles.cache.get(r).name).join(", ")}\``),
- }
- }
- });
- return;
- }
- }
-
- try {
-
- /**
- * Return system for slash
- * @name ReturnSystem
- * @param {DiscordClient} client
- * @param {Object} interaction
- * @example
- * return {
- * content: "hi",
- * ephemeral: true,
- * allowedMentions: { parse: [], repliedUser: true }
- * }
- */
-
- const client = this.client, bot = this.client, channel = member.guild.channels.cache.get(interaction.channel_id)
- commandos.run({
- client, bot, interaction, member, channel,
- guild: member.guild,
- /**
- * Respond
- * @type {Interface}
- * @param {RespondOptions} result
- * @returns {Object}
- */
- respond: async(result) => {
- return this.slashRespond(channel, interaction, result);
- },
- edit: async(result) => {
- return this.slashEdit(interaction, result);
- }
- }, await this.getSlashArgs(interaction.data.options || []), await this.getSlashArgs2(interaction.data.options || []))
- } catch(e) {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands Debug] &3" + e).getText())
- }
-
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands Debug] &3User &a" + interaction.member.user.id + "&3 used &a" + interaction.data.name).getText())
- }catch(e) {
- this.GCommandsClient.emit(Events.DEBUG, new Color("&d[GCommands Debug] &3" + e).getText())
- if(!this.unkownCommandMessage) return;
- if(this.client.languageFile.UNKNOWN_COMMAND[guildLanguage]) {
- this.client.api.interactions(interaction.id, interaction.token).callback.post({
- data: {
- type: 4,
- data: {
- content: this.client.languageFile.UNKNOWN_COMMAND[guildLanguage].replace("{COMMAND}",interaction.data.name)
- }
- }
- });
- }
- }
- })
- }
- }
-
- /**
- * Internal method to loadMoreEvents
- * @returns {void}
- * @private
- */
- async loadMoreEvents() {
- require("../base/actions/channel")(this.client)
- require("../base/actions/guild")(this.client)
- require("../base/actions/guildmember")(this.client)
- require("../base/actions/role")(this.client)
- require("../base/actions/user")(this.client)
- require("../base/actions/voiceupdate")(this.client)
- require("../base/actions/interactions")(this.client)
- }
-
- async slashRespond(channel, interaction, result) {
- if(!result.ephemeral && this.client.autoTyping) channel.startTyping(this.client.autoTyping);
-
- var data = {}
-
- if(typeof result != "object") data.content = result;
- if(typeof result == "object" && !result.content) data.embeds = [result];
- if(typeof result == "object" && typeof result.content != "object") data.content = result.content;
- if(typeof result == "object" && typeof result.content == "object") data.embeds = [result.content];
- if(typeof result == "object" && result.allowedMentions) { data.allowedMentions = result.allowedMentions } else data.allowedMentions = { parse: [], repliedUser: true }
- if(typeof result == "object" && result.ephemeral) { data.flags = 64 }
- if(typeof result == "object" && result.components) {
- if(!Array.isArray(result.components)) result.components = [result.components];
- data.components = result.components;
- }
- if(typeof result == "object" && result.embeds) {
- if(!Array.isArray(result.embeds)) result.embeds = [result.embeds]
- data.embeds = result.embeds;
- }
- if(result.embeds && !result.content) result.content = "\u200B"
-
- let finalFiles = [];
- if(typeof result == "object" && result.attachments) {
- if(!Array.isArray(result.attachments)) result.attachments = [result.attachments]
- result.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
- })
- }
-
- let apiMessage = (await this.client.api.interactions(interaction.id, interaction.token).callback.post({
- data: {
- type: result.thinking ? 5 : 4,
- data
- },
- files: finalFiles
- }))
-
- let apiMessageMsg = {};
- try {
- apiMessageMsg = (await axios.get(`https://discord.com/api/v8/webhooks/${this.client.user.id}/${interaction.token}/messages/@original`)).data;
- } catch(e) {
- apiMessage = {
- id: undefined
- }
- }
-
- if(typeof apiMessage != "object") apiMessage = apiMessage.toJSON();
- if(apiMessage) {
- apiMessage = apiMessageMsg;
- apiMessage.client = this.client ? this.client : client;
- apiMessage.createButtonCollector = function createButtonCollector(filter, options) {return this.client.dispatcher.createButtonCollector(apiMessage, filter, options)};
- apiMessage.awaitButtons = function awaitButtons(filter, options) {return this.client.dispatcher.awaitButtons(apiMessage, filter, options)};
- apiMessage.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return this.client.dispatcher.createSelectMenuCollector(apiMessage, filter, options)};
- apiMessage.awaitSelectMenus = function awaitSelectMenus(filter, options) {return this.client.dispatcher.awaitSelectMenus(apiMessage, filter, options)};
- apiMessage.delete = function deleteMsg() {return this.client.api.webhooks(this.client.user.id, interaction.token).messages[apiMessageMsg.id].delete()};
- }
-
- if(!result.ephemeral && this.client.autoTyping) channel.stopTyping(true)
-
- if(ifDjsV13) return apiMessage.id ? new Message(this.client, apiMessage, channel) : apiMessage;
- else return apiMessage.id ? new GMessage(this.client, apiMessage, channel) : apiMessage;
- }
-
- async slashEdit(interaction, result) {
- if (typeof result == "object") {
- if(result.components) {
- if(!Array.isArray(result.components)) result.components = [result.components];
-
- result.components = result.components;
- } else result.components = [];
-
- if(typeof result.content == "object") {
- result.embeds = [result.content]
- result.content = "\u200B"
- }
- if(typeof result == "object" && result.embeds) {
- if(!Array.isArray(result.embeds)) result.embeds = [result.embeds];
- result.embeds = result.embeds;
- } else result.embeds = []
- if(result.embeds && !result.content) result.content = "\u200B"
-
- let finalFiles = [];
- if(typeof result == "object" && result.attachments) {
- if(!Array.isArray(result.attachments)) result.attachments = [result.attachments]
- result.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
- })
- }
-
- let apiMessage = (await this.client.api.webhooks(this.client.user.id, interaction.token).messages[result.messageId ? result.messageId : "@original"].patch({
- data: {
- content: result.content,
- components: result.components,
- embeds: result.embeds || []
- },
- files: finalFiles
- }))
+/**
+ * GCommandsClient
+ * @type {GCommands}
+*/
+GEventLoader.GCommandsClient = GEvents.GEvents.GCommandsClient;
- if(apiMessage) {
- apiMessage.client = this.client;
- apiMessage.createButtonCollector = function createButtonCollector(filter, options) {return this.client.dispatcher.createButtonCollector(apiMessage, filter, options)};
- apiMessage.awaitButtons = function awaitButtons(filter, options) {return this.client.dispatcher.awaitButtons(apiMessage, filter, options)};
- apiMessage.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return this.client.dispatcher.createSelectMenuCollector(apiMessage, filter, options)};
- apiMessage.awaitSelectMenus = function awaitSelectMenus(filter, options) {return this.client.dispatcher.awaitSelectMenus(apiMessage, filter, options)};
- apiMessage.delete = function deleteMsg() {return this.client.api.webhooks(this.client.user.id, interaction.token).messages[apiMessage.id].delete()};
- }
+/**
+ * eventDir
+ * @type {String}
+ */
+GEventLoader.eventDir = GEvents.GEvents.eventDir;
- if(ifDjsV13) return apiMessage.id ? new Message(this.client, apiMessage, channel) : apiMessage;
- else return apiMessage.id ? new GMessage(this.client, apiMessage, channel) : apiMessage;
- }
+/**
+ * client
+ * @type {Client}
+ */
+GEventLoader.client = GEvents.GEvents.client;
- return this.client.api.webhooks(this.client.user.id, interaction.token).messages["@original"].patch({ data: { content: result }})
- }
+/**
+ * gevents
+ * @type {Collection}
+ */
+GEventLoader.client.gevents = GEvents.GEvents.gevents;
- /**
- * Internal method to getSlashArgs
- * @returns {object}
- */
- getSlashArgs(options) {
- var args = [];
-
- let check = (option) => {
- if (!option) return;
- if (option.value) args.push(option.value);
- else args.push(option.name);
-
- if (option.options) {
- for (let o = 0; o < option.options.length; o++) {
- check(option.options[o]);
- }
- }
- }
-
- if (Array.isArray(options)) {
- for (let o = 0; o < options.length; o++) {
- check(options[o]);
- }
- } else {
- check(options);
- }
-
- return args;
- }
- getSlashArgs2(options) {
- var args = {};
- for (let o of options) {
- if (o.type == 1) args[o.name] = this.getSlashArgs2(o.options || []);
- else if (o.type == 2) args[o.name] = this.getSlashArgs2(o.options || []);
- else {
- args[o.name] = o.value;
- }
- }
- return args;
- }
+/**
+ * Internal method to loadEventsFiles
+ * @returns {void}
+ * @private
+*/
+GEventLoader.__loadEventFiles = () => GEvents.GEvents.__loadEventFiles;
- /**
- * Internal method to inhivit
- * @returns {object}
- */
- async inhibit(cmd, data) {
- for(const inhibitor of this.client.inhibitors) {
- let inhibit = inhibitor(cmd, data);
- return inhibit;
- }
- return null;
- }
-}
+/**
+ * Internal method to loadEvents
+ * @returns {void}
+ * @private
+*/
+GEventLoader.__loadEvents = () => GEvents.GEvents.__loadEvents;
module.exports = GEventLoader;
\ No newline at end of file
diff --git a/src/structures/Color.js b/src/structures/Color.js
index 56e7bfe76..306062852 100644
--- a/src/structures/Color.js
+++ b/src/structures/Color.js
@@ -1,3 +1,5 @@
+const { resolveString } = require('../util/util');
+
/**
* The Color class
*/
@@ -8,43 +10,34 @@ class Color {
* @param {string} text
* @param {ColorOptions} options
*/
- constructor(text = "", options = {}) {
+ constructor(text = '', options = {}) {
/**
- * Color options
- * @param {string} text
- * @param {ColorOptions} json
- * @type {ColorOptions}
+ * text
+ * @type {String}
*/
- this.text = text;
+ this.text = resolveString(text);
+ /**
+ * json
+ * @type {Object}
+ */
this.json = options.json;
- if(typeof this.text == "object") {
- this.text2 = "";
- var i;
- for (i = 0; i < this.text.length; i++) {
- this.text2 += text[i] + "\n"
- }
- }
-
- if(this.text2) {
- this.text = this.text2
- }
this.text = this.text
// COLORS
- .replace(/&c/g, "\x1b[31m")
- .replace(/&a/g, "\x1b[32m")
- .replace(/&e/g, "\x1b[33m")
- .replace(/&b/g, "\x1b[34m")
- .replace(/&d/g, "\x1b[35m")
- .replace(/&3/g, "\x1b[36m")
- .replace(/&f/g, "\x1b[37m")
+ .replace(/&c/g, '\x1b[31m')
+ .replace(/&a/g, '\x1b[32m')
+ .replace(/&e/g, '\x1b[33m')
+ .replace(/&b/g, '\x1b[34m')
+ .replace(/&d/g, '\x1b[35m')
+ .replace(/&3/g, '\x1b[36m')
+ .replace(/&f/g, '\x1b[37m')
// OTHER
- .replace(/&r/g, "\x1b[0m")
- .replace(/&n/g, "\x1b[4m")
- .replace(/&p/g, "\x1b[7m")
+ .replace(/&r/g, '\x1b[0m')
+ .replace(/&n/g, '\x1b[4m')
+ .replace(/&p/g, '\x1b[7m')
}
@@ -55,9 +48,9 @@ class Color {
*/
getText() {
if(this.json) {
- return {text:this.text + "\x1b[0m"}
+ return {text:this.text + '\x1b[0m'}
}
- return this.text + "\x1b[0m";
+ return this.text + '\x1b[0m';
}
/**
@@ -66,7 +59,7 @@ class Color {
* @returns {string}
*/
getRGB() {
- var get = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(this.text);
+ let get = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(this.text);
if(this.json) {
return {
@@ -78,6 +71,6 @@ class Color {
return `r: ${parseInt(get[1], 16)}, g: ${parseInt(get[2], 16)}, b: ${parseInt(get[3], 16)}`
}
-};
+}
module.exports = Color;
\ No newline at end of file
diff --git a/src/structures/DMChannel.js b/src/structures/DMChannel.js
index db156dcae..dec1b19c4 100644
--- a/src/structures/DMChannel.js
+++ b/src/structures/DMChannel.js
@@ -1,89 +1,64 @@
-const { Structures, MessageEmbed, DMChannel } = require("discord.js");
+const { DMChannel } = require('discord.js');
const ButtonCollectorV12 = require('../structures/v12/ButtonCollector'), ButtonCollectorV13 = require('../structures/v13/ButtonCollector'), SelectMenuCollectorV12 = require('../structures/v12/SelectMenuCollector'), SelectMenuCollectorV13 = require('../structures/v13/SelectMenuCollector')
-const updater = require("../util/updater")
+const GPayload = require('./GPayload');
+const ifDjsV13 = (require('../util/updater')).checkDjsVersion('13');
-if(!updater.checkDjsVersion("13")) {
- module.exports = Structures.extend("DMChannel", DMChannel => {
- class GDMChannel extends DMChannel {
- constructor(...args) {
- super(...args)
- }
+module.exports = Object.defineProperties(DMChannel.prototype, {
+ send: {
+ value: async function(result) {
+ let GPayloadResult = await GPayload.create(this, result)
+ .resolveData()
+ .resolveFiles();
- async send(result) {
- var data = {}
-
- if(typeof result != "object") data.content = result;
- if(typeof result == "object" && !result.content) data.embeds = [result];
- if(typeof result == "object" && typeof result.content != "object") data.content = result.content;
- if(typeof result == "object" && typeof result.content == "object") data.embeds = [result.content];
- if(typeof result == "object" && result.allowedMentions) { data.allowedMentions = result.allowedMentions } else data.allowedMentions = { parse: [], repliedUser: true }
- if(typeof result == "object" && result.ephemeral) { data.flags = 64 }
- if(typeof result == "object" && result.components) {
- if(!Array.isArray(result.components)) result.components = [result.components];
- data.components = result.components;
- }
- if(typeof result == "object" && result.embeds) {
- if(!Array.isArray(result.embeds)) result.embeds = [result.embeds]
- data.embeds = result.embeds;
- }
- if(result.embeds && !result.content) result.content = "\u200B"
-
- let finalFiles = [];
- if(typeof result == "object" && result.attachments) {
- if(!Array.isArray(result.attachments)) result.attachments = [result.attachments]
- result.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
- })
- }
+ return this.client.api.channels[this.id].messages.post({
+ data: GPayloadResult.data,
+ files: GPayloadResult.files
+ })
+ .then(d => this.client.actions.MessageCreate.handle(d).message);
+ }
+ },
- return this.client.api.channels[this.id].messages.post({
- data,
- files: finalFiles
- })
- .then(d => this.client.actions.MessageCreate.handle(d).message);
- }
+ createButtonCollector: {
+ value: async function (msg, filter, options = {}) {
+ if(ifDjsV13) return new ButtonCollectorV13(msg, filter, options);
+ else return new ButtonCollectorV12(msg, filter, options);
+ }
+ },
- createButtonCollector(msg, filter, options = {}) {
- if(updater.checkDjsVersion("13")) return new ButtonCollectorV13(msg, filter, options);
- else return new ButtonCollectorV12(msg, filter, options);
- }
-
- awaitButtons(msg, filter, options = {}) {
- return new Promise((resolve, reject) => {
- const collector = this.createButtonCollector(msg, filter, options);
- collector.once('end', (buttons, reason) => {
- if (options.errors && options.errors.includes(reason)) {
- reject(buttons);
- } else {
- resolve(buttons);
- }
- });
- })
- }
+ awaitButtons: {
+ value: async function(msg, filter, options = {}) {
+ return new Promise((resolve, reject) => {
+ const collector = this.createButtonCollector(msg, filter, options);
+ collector.once('end', (buttons, reason) => {
+ if (options.errors && options.errors.includes(reason)) {
+ reject(buttons);
+ } else {
+ resolve(buttons);
+ }
+ });
+ })
+ }
+ },
- createSelectMenuCollector(msg, filter, options = {}) {
- if(updater.checkDjsVersion("13")) return new SelectMenuCollectorV13(msg, filter, options);
- else return new SelectMenuCollectorV12(msg, filter, options);
- }
-
- awaitSelectMenus(msg, filter, options = {}) {
- return new Promise((resolve, reject) => {
- const collector = this.createSelectMenuCollector(msg, filter, options);
- collector.once('end', (buttons, reason) => {
- if (options.errors && options.errors.includes(reason)) {
- reject(buttons);
- } else {
- resolve(buttons);
- }
- });
- })
- }
+ createSelectMenuCollector: {
+ value: async function(msg, filter, options = {}) {
+ if(ifDjsV13) return new SelectMenuCollectorV13(msg, filter, options);
+ else return new SelectMenuCollectorV12(msg, filter, options);
}
+ },
- return GDMChannel;
- })
-} else module.exports = DMChannel;
\ No newline at end of file
+ awaitSelectMenus: {
+ value: async function(msg, filter, options = {}) {
+ return new Promise((resolve, reject) => {
+ const collector = this.createSelectMenuCollector(msg, filter, options);
+ collector.once('end', (buttons, reason) => {
+ if (options.errors && options.errors.includes(reason)) {
+ reject(buttons);
+ } else {
+ resolve(buttons);
+ }
+ });
+ })
+ }
+ }
+});
\ No newline at end of file
diff --git a/src/structures/Event.js b/src/structures/Event.js
new file mode 100644
index 000000000..f1b54ced8
--- /dev/null
+++ b/src/structures/Event.js
@@ -0,0 +1,34 @@
+// ONLY FOR DOCS
+const GEvents = require('@gcommands/events')
+
+/**
+ * The Event class
+ */
+class Event extends null {}
+
+/**
+ * Name
+ * @type {String}
+ */
+Event.name = GEvents.Event.name;
+
+/**
+ * once
+ * @type {Boolean}
+ */
+Event.once = GEvents.Event.once;
+
+/**
+ * ws
+ * @type {Boolean}
+ */
+Event.ws = GEvents.Event.ws;
+
+/**
+ * run function
+ * @param {Client}
+ * @param {String}
+ */
+Event.run = () => GEvents.Event.run;
+
+module.exports = Event;
\ No newline at end of file
diff --git a/src/structures/GGuild.js b/src/structures/GGuild.js
index 5205c4936..d856f94e3 100644
--- a/src/structures/GGuild.js
+++ b/src/structures/GGuild.js
@@ -1,53 +1,25 @@
-const { Structures, Guild } = require("discord.js")
-const updater = require("../util/updater")
+const { Guild } = require('discord.js');
-if(!updater.checkDjsVersion("13")) {
- module.exports = Structures.extend('Guild', Guild => {
- /**
- * The GuildStructure structure
- * @extends Guild
- */
-
- class GCommandsGuild extends Guild {
- constructor(...args) {
- super(...args)
- }
-
- /**
- * Method to getCommandPrefix
- * @returns {Promise}
- */
- async getCommandPrefix(cache = true) {
- return this.client.dispatcher.getGuildPrefix(this.id, cache);
- }
-
- /**
- * Method to setCommandPrefix
- * @returns {void}
- */
- async setCommandPrefix(prefix) {
- this.client.dispatcher.setGuildPrefix(this.id, prefix);
- this.client.emit('commandPrefixChange', this, this.prefix);
- }
-
- /**
- * Method to getLanguage
- * @returns {Promise}
- */
- async getLanguage(cache = true) {
- return this.client.dispatcher.getGuildLanguage(this.id, cache);
- }
-
- /**
- * Method to setLanguage
- * @returns {void}
- */
- async setLanguage(lang) {
- this.client.dispatcher.setGuildLanguage(this.id, lang);
- this.client.emit('guildLanguageChange', this, this.language);
- }
+module.exports = Object.defineProperties(Guild.prototype, {
+ getCommandPrefix: {
+ value: async function(cache = true) {
+ return this.client.dispatcher.getGuildPrefix(this.id, cache)
+ }
+ },
+ setCommandPrefix: {
+ value: async function(prefix) {
+ this.client.dispatcher.setGuildPrefix(this.id, prefix);
+ this.client.emit('commandPrefixChange', this, prefix);
}
+ },
- return GCommandsGuild;
- })
-} else module.exports = Guild;
\ No newline at end of file
+ getLanguage: {
+ value: async function(cache = true) { return this.client.dispatcher.getGuildLanguage(this.id, cache) }
+ },
+ setLanguage: {
+ value: async function(lang) {
+ this.client.dispatcher.setGuildLanguage(this.id, lang);
+ this.client.emit('guildLanguageChange', this, lang);
+ }
+ }
+});
\ No newline at end of file
diff --git a/src/structures/GInteraction.js b/src/structures/GInteraction.js
new file mode 100644
index 000000000..5424e4bf3
--- /dev/null
+++ b/src/structures/GInteraction.js
@@ -0,0 +1,303 @@
+const { Message } = require('discord.js');
+const Color = require('../structures/Color');
+const GPayload = require('./GPayload');
+const axios = require('axios');
+
+/**
+ * The GInteraction class
+ */
+class GInteraction {
+
+ /**
+ * Creates new GInteraction instance
+ * @param {Client} client
+ * @param {Object} data
+ */
+ constructor(client, data) {
+
+ /**
+ * client
+ * @type {Client}
+ */
+ this.client = client;
+
+ /**
+ * type
+ * @type {number}
+ */
+ this.type = data.type;
+
+ /**
+ * token
+ * @type {string}
+ */
+ this.token = data.token;
+
+ /**
+ * discordId
+ * @type {number}
+ */
+ this.discordId = data.id;
+
+ /**
+ * version
+ * @type {number}
+ */
+ this.version = data.version;
+
+ /**
+ * applicationId
+ * @type {number}
+ */
+ this.applicationId = data.application_id;
+
+ /**
+ * guild
+ * @type {Guild}
+ */
+ this.guild = data.guild_id ? this.client.guilds.cache.get(data.guild_id) : null;
+
+ /**
+ * channel
+ * @type {TextChannel | NewsChannel | DMChannel}
+ */
+ this.channel = data.guild_id ? this.guild.channels.cache.get(data.channel_id) : client.channels.cache.get(data.channel_id)
+
+ /**
+ * createdTimestamp
+ * @type {Number}
+ */
+ this.createdTimestamp = Date.now();
+
+ /**
+ * author
+ * @type {User}
+ */
+ this.author = this.client.users.cache.get(data.guild_id ? data.member.user.id : data.user.id);
+
+ /**
+ * member
+ * @type {GuildMember | null}
+ */
+ this.member = data.guild_id ? this.guild.members.cache.get(data.member.user.id) : null;
+
+ /**
+ * interaction
+ * @type {Object}
+ */
+ this.interaction = {
+ name: data.data.name,
+ options: data.data.options,
+ id: data.data.id
+ }
+
+ /**
+ * replied
+ * @type {boolean}
+ */
+ this.replied = false;
+
+ /**
+ * deferred
+ * @type {boolean}
+ */
+ this.deferred = false;
+
+ return this;
+ }
+
+ /**
+ * Method to defer
+ * @param {Boolean} ephemeral
+ */
+ async defer(ephemeral) {
+ if (this.deferred || this.replied) return console.log(new Color('&d[GCommands] &cThis button already has a reply').getText());
+ await this.client.api.interactions(this.discordId, this.token).callback.post({
+ data: {
+ type: 6,
+ data: {
+ flags: ephemeral ? 1 << 6 : null,
+ },
+ },
+ });
+ this.deferred = true;
+ }
+
+ /**
+ * Method to think
+ * @param {Boolean} ephemeral
+ */
+ async think(ephemeral) {
+ if (this.deferred || this.replied) return console.log(new Color('&d[GCommands] &cThis button already has a reply').getText());
+ await this.client.api.interactions(this.discordId, this.token).callback.post({
+ data: {
+ type: 5,
+ data: {
+ flags: ephemeral ? 1 << 6 : null,
+ },
+ },
+ });
+ this.deferred = true;
+ }
+
+ /**
+ * Method to edit
+ * @param {Object} options
+ */
+ async edit(result) {
+ if(result.autoDefer == true) {
+ await this.client.api.interactions(this.discordId, this.token).callback.post({
+ data: {
+ type: 6,
+ },
+ });
+ }
+
+ this.slashEdit(result)
+ }
+
+ /**
+ * Method to update
+ * @param {Object} options
+ */
+ async update(result) {
+ if(result.autoDefer == true) {
+ await this.client.api.interactions(this.discordId, this.token).callback.post({
+ data: {
+ type: 6,
+ },
+ });
+ }
+
+ this.slashEdit(result, true)
+ }
+
+ /**
+ * Method to reply
+ * @type {get}
+ */
+ get reply() {
+ /**
+ * Method to replySend
+ * @param {Object} options
+ */
+ let _send = async(result) => {
+ this.replied = true;
+ return this.slashRespond(result)
+ }
+
+ /**
+ * Method to replyEdit
+ * @param {Object} options
+ */
+ let _edit = async(result) => {
+ if(!this.replied) return console.log(new Color('&d[GCommands] &cThis button has no reply.').getText())
+ return this.slashEdit(result)
+ }
+
+ /**
+ * Method to replyUpdate
+ * @param {Object} options
+ */
+ let _update = async(result) => {
+ if(!this.replied) return console.log(new Color('&d[GCommands] &cThis button has no reply.').getText())
+ return this.slashEdit(result, true)
+ }
+
+ /**
+ * Method to replyFetch
+ * @param {Object} options
+ */
+ let _fetch = async() => {
+ if(!this.replied) return console.log(new Color('&d[GCommands] &cThis button has no reply.').getText())
+ let apiMessage = (await this.client.api.webhooks(this.client.user.id, this.token).messages['@original'].get());
+
+ if(apiMessage) {
+ apiMessage.client = this.client;
+ apiMessage.createButtonCollector = function createButtonCollector(filter, options) {return this.client.dispatcher.createButtonCollector(apiMessage, filter, options)};
+ apiMessage.awaitButtons = function awaitButtons(filter, options) {return this.client.dispatcher.awaitButtons(apiMessage, filter, options)};
+ apiMessage.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return this.client.dispatcher.createSelectMenuCollector(apiMessage, filter, options)};
+ apiMessage.awaitSelectMenus = function awaitSelectMenus(filter, options) {return this.client.dispatcher.awaitSelectMenus(apiMessage, filter, options)};
+ apiMessage.delete = function deleteMsg() {return this.client.api.webhooks(this.client.user.id, interaction.token).messages[apiMessage.id].delete()};
+ }
+
+ return new Message(this.client, data.message, this.channel)
+ }
+
+ return {
+ send: _send,
+ edit: _edit,
+ update: _update,
+ fetch: _fetch
+ }
+ }
+
+ async slashRespond(result) {
+ let GPayloadResult = await GPayload.create(this.channel, result)
+ .resolveData()
+ .resolveFiles();
+
+ let apiMessage = (await this.client.api.interactions(this.discordId, this.token).callback.post({
+ data: {
+ type: result.thinking ? 5 : 4,
+ data: GPayloadResult.data
+ },
+ files: GPayloadResult.files
+ }))
+
+ let apiMessageMsg = {};
+ try {
+ apiMessageMsg = (await axios.get(`https://discord.com/api/v8/webhooks/${this.client.user.id}/${this.token}/messages/@original`)).data;
+ } catch(e) {
+ apiMessageMsg = {
+ id: undefined
+ }
+ }
+
+ if(typeof apiMessage !== 'object') apiMessage = apiMessage.toJSON();
+ if(apiMessage) {
+ apiMessage = apiMessageMsg;
+ apiMessage.client = this.client ? this.client : client;
+ apiMessage.createButtonCollector = function createButtonCollector(filter, options) {return this.client.dispatcher.createButtonCollector(apiMessage, filter, options)};
+ apiMessage.awaitButtons = function awaitButtons(filter, options) {return this.client.dispatcher.awaitButtons(apiMessage, filter, options)};
+ apiMessage.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return this.client.dispatcher.createSelectMenuCollector(apiMessage, filter, options)};
+ apiMessage.awaitSelectMenus = function awaitSelectMenus(filter, options) {return this.client.dispatcher.awaitSelectMenus(apiMessage, filter, options)};
+ apiMessage.delete = function deleteMsg() {return this.client.api.webhooks(this.client.user.id, interaction.token).messages[apiMessageMsg.id].delete()};
+ }
+
+ return apiMessage.id ? new Message(this.client, apiMessage, this.channel) : apiMessage;
+ }
+
+ async slashEdit(result, update) {
+ let GPayloadResult = await GPayload.create(this.channel, result)
+ .resolveData();
+
+ let apiMessage = {}
+ if(update) {
+ apiMessage = this.client.api.interactions(this.discordId, this.token).callback.post({
+ data: {
+ type: 7,
+ data: GPayloadResult.data
+ },
+ })
+ } else {
+ apiMessage = (await this.client.api.webhooks(this.client.user.id, this.token).messages[result.messageId ? result.messageId : '@original'].patch({
+ data: GPayloadResult.data
+ }))
+ }
+
+ if(typeof apiMessage !== 'object') apiMessage = apiMessage.toJSON();
+ if(apiMessage) {
+ apiMessage.client = this.client ? this.client : client;
+ apiMessage.createButtonCollector = function createButtonCollector(filter, options) {return this.client.dispatcher.createButtonCollector(apiMessage, filter, options)};
+ apiMessage.awaitButtons = function awaitButtons(filter, options) {return this.client.dispatcher.awaitButtons(apiMessage, filter, options)};
+ apiMessage.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return this.client.dispatcher.createSelectMenuCollector(apiMessage, filter, options)};
+ apiMessage.awaitSelectMenus = function awaitSelectMenus(filter, options) {return this.client.dispatcher.awaitSelectMenus(apiMessage, filter, options)};
+ apiMessage.delete = function deleteMsg() {return this.client.api.webhooks(this.client.user.id, interaction.token).messages[apiMessageMsg.id].delete()};
+ }
+
+ return apiMessage.id ? new Message(this.client, apiMessage, this.channel) : apiMessage;
+ }
+}
+
+module.exports = GInteraction;
\ No newline at end of file
diff --git a/src/structures/GMessage.js b/src/structures/GMessage.js
index 2c5261b22..af3926e70 100644
--- a/src/structures/GMessage.js
+++ b/src/structures/GMessage.js
@@ -1,434 +1,123 @@
-const { APIMessage, Structures, Message } = require('discord.js');
-const ButtonCollectorV12 = require('../structures/v12/ButtonCollector'), ButtonCollectorV13 = require('../structures/v13/ButtonCollector'), SelectMenuCollectorV12 = require('../structures/v12/SelectMenuCollector'), SelectMenuCollectorV13 = require('../structures/v13/SelectMenuCollector')
-const updater = require("../util/updater")
+const { Message } = require('discord.js');
+const ButtonCollectorV12 = require('../structures/v12/ButtonCollector'), ButtonCollectorV13 = require('../structures/v13/ButtonCollector'), SelectMenuCollectorV12 = require('../structures/v12/SelectMenuCollector'), SelectMenuCollectorV13 = require('../structures/v13/SelectMenuCollector');
+const GPayload = require('./GPayload');
+const ifDjsV13 = (require('../util/updater')).checkDjsVersion('13');
-if(!updater.checkDjsVersion("13")) {
- module.exports = Structures.extend("Message", Message => {
- /**
- * The MessageStructure structure
- * @extends Message
- */
- class GCommandsMessage extends Message {
- constructor(...args) {
- super(...args)
- }
-
- /**
- * Method to make buttons
- * @param {String} content
- * @param {Object} options
- * @returns {Promise}
- */
- async buttons(content, options) {
- var embed = null;
- if(typeof content == "object") {
- embed = content;
- content = "\u200B"
- }
-
-
- if(!options.allowedMentions) {
- options.allowedMentions = { parse: [] };
- }
-
- if(options.components) {
- if(!Array.isArray(options.components)) options.components = [options.components];
- options.components = options.components;
- }
- if(options.embeds) {
- if(!Array.isArray(options.embeds)) options.embeds = [options.embeds];
- options.embeds = options.embeds;
- }
-
- let finalFiles = [];
- if(options.attachments) {
- if(!Array.isArray(options.attachments)) options.attachments = [options.attachments]
- options.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
- })
- }
-
- if(options.inlineReply) {
- options.message_reference = {
- message_id: this.channel.lastMessageID
- }
- }
+module.exports = Object.defineProperties(Message.prototype, {
+ /**
+ * Method to edit message
+ * @param {Object} options
+ */
+ edit: {
+ value: async function(result) {
+ let GPayloadResult = await GPayload.create(this.channel, result)
+ .resolveData();
- return this.client.api.channels[this.channel.id].messages.post({
- data: {
- allowed_mentions: options.allowedMentions,
- content: content,
- components: options.components,
- options,
- embed: embed || null
- },
- files: finalFiles
- })
- .then(d => this.client.actions.MessageCreate.handle(d).message);
- }
-
- /**
- * Method to buttonsEdit
- * @param {String} content
- * @param {Object} options
- * @returns {Promise}
- */
- async buttonsEdit(msgID, content, options) {
- var embed = null;
- if(typeof content == "object") {
- embed = content;
- content = "\u200B"
- }
-
- if(!options.allowedMentions) {
- options.allowedMentions = { parse: [] };
- }
-
- if(options.components) {
- if(!Array.isArray(options.components)) options.components = [options.components];
- options.components = options.components;
- }
- if(options.embeds) {
- if(!Array.isArray(options.embeds)) options.embeds = [options.embeds];
- options.embeds = options.embeds;
- }
-
- let finalFiles = [];
- if(options.attachments) {
- if(!Array.isArray(options.attachments)) options.attachments = [options.attachments]
- options.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
- })
- }
-
- return this.client.api.channels[this.channel.id].messages[msgID].patch({
+ if(result.edited == false) {
+ return this.client.api.channels(this.channel.id).messages[this.id].patch({
data: {
- allowed_mentions: options.allowedMentions,
- content: content,
- components: options.components,
- options,
- embed: embed || null
+ type: 7,
+ data: GPayloadResult.data
},
- files: finalFiles
- })
- .then(d => this.client.actions.MessageCreate.handle(d).message);
- }
-
- /**
- * Method to edit message
- * @param {Object} options
- */
- async edit(result) {
- if (typeof result == "object") {
- var finalData = [];
-
- if(result.components && !Array.isArray(result.components)) result.components = [result.components];
- if(result.embeds && !Array.isArray(result.embeds)) result.embeds = [result.embeds]
-
- if(typeof result == "object" && !result.content) result.embeds = [result]
- if(typeof result.content == "object") {
- result.embeds = [result.content]
- result.content = "\u200B"
- }
-
- if(result.edited == false) {
- return this.client.api.channels(this.channel.id).messages[this.id].patch({
- data: {
- type: 7,
- data: {
- content: result.content,
- components: result.components,
- embeds: result.embeds
- },
- },
- }).then(d => this.client.actions.MessageCreate.handle(d).message);
- }
-
- let finalFiles = [];
- if(typeof result == "object" && result.attachments) {
- if(!Array.isArray(result.attachments)) result.attachments = [result.attachments]
- result.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
- })
- }
-
- return this.client.api.channels(this.channel.id).messages[result.messageId ? result.messageId : this.id].patch({
- data: {
- content: result.content,
- components: result.components || [],
- embeds: result.embeds || []
- },
- files: finalFiles
- })
- } else {
- return this.client.api.channels(this.channel.id).messages[this.id].patch({ data: {
- content: result,
- }})
- }
- }
-
- /**
- * Method to update message
- * @param {Object} options
- */
- async update(result) {
- if (typeof result == "object") {
- var finalData = [];
-
- if(result.components && !Array.isArray(result.components)) result.components = [result.components];
- if(result.embeds && !Array.isArray(result.embeds)) result.embeds = [result.embeds]
-
- if(typeof result == "object" && !result.content) result.embeds = [result]
- if(typeof result.content == "object") {
- result.embeds = [result.content]
- result.content = "\u200B"
- }
-
- return this.client.api.channels(this.channel.id).messages[this.id].patch({
- data: {
- type: 7,
- data: {
- content: result.content,
- components: result.components,
- embeds: result.embeds
- },
- },
- }).then(d => this.client.actions.MessageCreate.handle(d).message);
- } else {
- return this.client.api.channels(this.channel.id).messages[this.id].patch({
- data: {
- type: 7,
- data: {
- content: result,
- }
- }
- })
- }
- }
-
- /**
- * Method to inlineReply
- * @param {String} content
- * @param {Object} options
- * @returns {Promise}
- */
- async inlineReply(content, options) {
- const mentionRepliedUser = typeof ((options || content || {}).allowedMentions || {}).repliedUser === "undefined" ? true : ((options || content).allowedMentions).repliedUser;
- delete ((options || content || {}).allowedMentions || {}).repliedUser;
-
- const apiMessage = content instanceof APIMessage ? content.resolveData() : APIMessage.create(this.channel, content, options).resolveData();
- Object.assign(apiMessage.data, { message_reference: { message_id: this.id } });
-
- if (!apiMessage.data.allowed_mentions || Object.keys(apiMessage.data.allowed_mentions).length === 0)
- apiMessage.data.allowed_mentions = { parse: ["users", "roles", "everyone"] };
- if (typeof apiMessage.data.allowed_mentions.replied_user === "undefined")
- Object.assign(apiMessage.data.allowed_mentions, { replied_user: mentionRepliedUser });
-
- if (Array.isArray(apiMessage.data.content)) {
- return Promise.all(apiMessage.split().map(x => {
- x.data.allowed_mentions = apiMessage.data.allowed_mentions;
- return x;
- }).map(this.inlineReply.bind(this)));
- }
-
- const { data, files } = await apiMessage.resolveFiles();
- return this.client.api.channels[this.channel.id].messages
- .post({ data, files })
- .then(d => this.client.actions.MessageCreate.handle(d).message);
+ }).then(d => this.client.actions.MessageCreate.handle(d).message);
}
-
- createButtonCollector(filter, options = {}) {
- if(updater.checkDjsVersion("13")) return new ButtonCollectorV13(this, filter, options);
- else return new ButtonCollectorV12(this, filter, options);
- }
-
- awaitButtons(filter, options = {}) {
- return new Promise((resolve, reject) => {
- const collector = this.createButtonCollector(this, filter, options);
- collector.once('end', (buttons, reason) => {
- if (options.errors && options.errors.includes(reason)) {
- reject(buttons);
- } else {
- resolve(buttons);
- }
- });
- })
- }
-
- createSelectMenuCollector(filter, options = {}) {
- if(updater.checkDjsVersion("13")) return new SelectMenuCollectorV13(this, filter, options);
- else return new SelectMenuCollectorV12(this, filter, options);
- }
-
- awaitSelectMenus(filter, options = {}) {
- return new Promise((resolve, reject) => {
- const collector = this.createSelectMenuCollector(this, filter, options);
- collector.once('end', (buttons, reason) => {
- if (options.errors && options.errors.includes(reason)) {
- reject(buttons);
- } else {
- resolve(buttons);
- }
- });
- })
- }
- }
-
- return GCommandsMessage;
- })
-} else module.exports = {
- /**
- * Method to make buttons
- * @param {String} content
- * @param {Object} options
- * @returns {Promise}
- */
- buttons: async function(content, options) {
- this.client = options.client, this.channel = options.channel
- var embed = null;
- if(typeof content == "object") {
- embed = content;
- content = "\u200B"
- }
+ let apiMessage = (await this.client.api.channels(this.channel.id).messages[result.messageId ? result.messageId : this.id].patch({
+ data: GPayloadResult.data
+ }))
+
+ if(typeof apiMessage !== 'object') apiMessage = apiMessage.toJSON();
+ if(apiMessage) {
+ apiMessage.client = this.client ? this.client : client;
+ apiMessage.createButtonCollector = function createButtonCollector(filter, options) {return this.client.dispatcher.createButtonCollector(apiMessage, filter, options)};
+ apiMessage.awaitButtons = function awaitButtons(filter, options) {return this.client.dispatcher.awaitButtons(apiMessage, filter, options)};
+ apiMessage.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return this.client.dispatcher.createSelectMenuCollector(apiMessage, filter, options)};
+ apiMessage.awaitSelectMenus = function awaitSelectMenus(filter, options) {return this.client.dispatcher.awaitSelectMenus(apiMessage, filter, options)};
+ apiMessage.delete = function deleteMsg() {return this.client.api.webhooks(this.client.user.id, interaction.token).messages[apiMessageMsg.id].delete()};
+ }
- if(!options.allowedMentions) {
- options.allowedMentions = { parse: [] };
- }
-
- if(options.components) {
- if(!Array.isArray(options.components)) options.components = [options.components];
- options.components = options.components;
- }
- if(options.embeds) {
- if(!Array.isArray(options.embeds)) options.embeds = [options.embeds];
- options.embeds = options.embeds;
- }
-
- let finalFiles = [];
- if(options.attachments) {
- if(!Array.isArray(options.attachments)) options.attachments = [options.attachments]
- options.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
- })
+ return apiMessage.id ? new Message(this.client, apiMessage, this.channel) : apiMessage;
}
+ },
- if(options.inlineReply) {
- options.message_reference = {
- message_id: this.channel.lastMessageID
- }
+ /**
+ * Method to update message
+ * @param {Object} options
+ */
+ update: {
+ value: async function(result) {
+ let GPayloadResult = await GPayload.create(this.channel, result)
+ .resolveData();
+
+ return this.client.api.channels(this.channel.id).messages[this.id].patch({
+ data: {
+ type: 7,
+ data: GPayloadResult.data
+ },
+ }).then(d => this.client.actions.MessageCreate.handle(d).message);
}
-
- return this.client.api.channels[this.channel.id].messages.post({
- data: {
- allowed_mentions: options.allowedMentions,
- content: content,
- components: options.components,
- options,
- embed: embed || null
- },
- files: finalFiles
- })
- .then(d => this.client.actions.MessageCreate.handle(d).message);
},
/**
- * Method to buttonsEdit
- * @param {String} content
- * @param {Object} options
+ * Method to send
+ * @param {Object} result
* @returns {Promise}
*/
- buttonsEdit: async function(msgID, content, options) {
- this.client = options.client, this.channel = options.channel
- var embed = null;
- if(typeof content == "object") {
- embed = content;
- content = "\u200B"
- }
-
- if(!options.allowedMentions) {
- options.allowedMentions = { parse: [] };
+ send: {
+ value: async function(result) {
+ let GPayloadResult = await GPayload.create(this.channel, result)
+ .resolveData()
+ .resolveFiles();
+
+ return this.client.api.channels[this.channel.id].messages.post({
+ data: GPayloadResult.data,
+ files: GPayloadResult.files
+ })
+ .then(d => this.client.actions.MessageCreate.handle(d).message);
}
+ },
- if(options.components) {
- if(!Array.isArray(options.components)) options.components = [options.components];
- options.components = options.components;
- }
- if(options.embeds) {
- if(!Array.isArray(options.embeds)) options.embeds = [options.embeds];
- options.embeds = options.embeds;
+ createButtonCollector: {
+ value: function(filter, options = {}) {
+ if(ifDjsV13) return new ButtonCollectorV13(this, filter, options);
+ else return new ButtonCollectorV12(this, filter, options);
}
+ },
- let finalFiles = [];
- if(options.attachments) {
- if(!Array.isArray(options.attachments)) options.attachments = [options.attachments]
- options.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
+ awaitButtons: {
+ value: async function(filter, options = {}) {
+ return new Promise((resolve, reject) => {
+ const collector = this.client.dispatcher.createButtonCollector(this, filter, options);
+ collector.once('end', (buttons, reason) => {
+ if (options.errors && options.errors.includes(reason)) {
+ reject(buttons);
+ } else {
+ resolve(buttons);
+ }
+ });
})
}
-
- return this.client.api.channels[this.channel.id].messages[msgID].patch({
- data: {
- allowed_mentions: options.allowedMentions,
- content: content,
- components: options.components,
- options,
- embed: embed || null
- },
- files: finalFiles
- })
- .then(d => this.client.actions.MessageCreate.handle(d).message);
},
- /**
- * Method to inlineReply
- * @param {String} content
- * @param {Object} options
- * @returns {Promise}
- */
- inlineReply: async function(content, options) {
- this.client = options.client, this.channel = options.channel
- const mentionRepliedUser = typeof ((options || content || {}).allowedMentions || {}).repliedUser === "undefined" ? true : ((options || content).allowedMentions).repliedUser;
- delete ((options || content || {}).allowedMentions || {}).repliedUser;
-
- const apiMessage = content instanceof APIMessage ? content.resolveData() : APIMessage.create(this.channel, content, options).resolveData();
- Object.assign(apiMessage.data, { message_reference: { message_id: this.id } });
-
- if (!apiMessage.data.allowed_mentions || Object.keys(apiMessage.data.allowed_mentions).length === 0)
- apiMessage.data.allowed_mentions = { parse: ["users", "roles", "everyone"] };
- if (typeof apiMessage.data.allowed_mentions.replied_user === "undefined")
- Object.assign(apiMessage.data.allowed_mentions, { replied_user: mentionRepliedUser });
-
- if (Array.isArray(apiMessage.data.content)) {
- return Promise.all(apiMessage.split().map(x => {
- x.data.allowed_mentions = apiMessage.data.allowed_mentions;
- return x;
- }).map(this.inlineReply.bind(this)));
+ createSelectMenuCollector: {
+ value: function(filter, options = {}) {
+ if(ifDjsV13) return new SelectMenuCollectorV13(this, filter, options);
+ else return new SelectMenuCollectorV12(this, filter, options);
}
+ },
- const { data, files } = await apiMessage.resolveFiles();
- return this.client.api.channels[this.channel.id].messages
- .post({ data, files })
- .then(d => this.client.actions.MessageCreate.handle(d).message);
+ awaitSelectMenus: {
+ value: async function(filter, options = {}) {
+ return new Promise((resolve, reject) => {
+ const collector = this.client.dispatcher.createSelectMenuCollector(this, filter, options);
+ collector.once('end', (buttons, reason) => {
+ if (options.errors && options.errors.includes(reason)) {
+ reject(buttons);
+ } else {
+ resolve(buttons);
+ }
+ });
+ })
+ }
}
-};
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/src/structures/GPayload.js b/src/structures/GPayload.js
new file mode 100644
index 000000000..ca53d4636
--- /dev/null
+++ b/src/structures/GPayload.js
@@ -0,0 +1,146 @@
+const { MessageEmbed, MessageAttachment, DataResolver, Util } = require('discord.js');
+const { browser } = require('discord.js').Constants;
+
+/**
+ * The GPayload class
+ */
+class GPayload {
+
+ /**
+ * Creates new GPayload instance
+ * @param {TextChannel | NewsChannel | DMChannel} channel
+ * @param {options} data
+ */
+ constructor(channel, options) {
+ /**
+ * Channel
+ * @type {TextChannel | NewsChannel | DMChannel}
+ */
+
+ this.channel = channel;
+
+ /**
+ * Options
+ * @type {string|GPayloadOptions}
+ */
+ this.options = options;
+
+ /**
+ * Data sendable to the API
+ * @type {GPayloadOptions}
+ */
+ this.data = null;
+
+ /**
+ * Files sendable to the API
+ * @type {?MessageFile[]}
+ */
+ this.files = null;
+ }
+
+ /**
+ * Resolves data.
+ * @returns {GPayload}
+ */
+ resolveData() {
+ if(this.data) return this;
+ else this.data = {};
+
+ let type = typeof this.options;
+ if(type !== 'object' || this.options instanceof MessageEmbed || this.options instanceof MessageAttachment) this.options = { content: this.options }
+
+ this.options.inlineReply = this.options.inlineReply == undefined ? true : this.options.inlineReply;
+
+ if(this.options.content && typeof this.options.content == 'object') {
+ this.options.embeds = this.options.content instanceof MessageEmbed ? this.options.content : [];
+ this.options.attachments = this.options.content instanceof MessageAttachment ? this.options.content : [];
+ } else this.data.content = this.options.content || null
+
+ this.data.allowed_mentions = this.options.allowedMentions ? this.options.allowedMentions : { parse: [], repliedUser: true }
+ this.data.flags = this.options.ephemeral ? 64 : null
+
+ if(this.options.components) this.data.components =!Array.isArray(this.options.components) ? [this.options.components] : this.options.components
+ if(this.options.embeds) this.data.embeds = !Array.isArray(this.options.embeds) ? [this.options.embeds] : this.options.embeds
+ if(this.options.attachments) this.options.attachments = !Array.isArray(this.options.attachments) ? [this.options.attachments] : this.options.attachments
+ if(this.options.files) this.options.files = !Array.isArray(this.options.files) ? [this.options.files] : this.options.files
+
+ if(this.options.inlineReply && this.channel.lastMessageID) this.data.message_reference = { message_id: this.channel.lastMessageID }
+
+ return this;
+ }
+
+ /**
+ * Resolves files.
+ * @returns {GPayload}
+ */
+ async resolveFiles() {
+ if (this.files) return this;
+
+ const finalFiles = [];
+ if(this.options.files) this.options.attachments = this.options.files;
+ if (this.options.attachments) {
+ finalFiles.push(...this.options.attachments);
+ }
+
+ if(this.data.embeds) {
+ for (const embed of this.data.embeds) {
+ if (embed.files) {
+ finalFiles.push(...embed.files);
+ }
+ }
+ }
+
+ this.files = await Promise.all(finalFiles.map(f => this.constructor.resolveFile(f)));
+ return this;
+ }
+
+ /**
+ * Resolves a single file into an object sendable to the API.
+ * from djs
+ * @param {BufferResolvable|Stream|FileOptions|MessageAttachment} fileLike Something that could be resolved to a file
+ * @returns {Object}
+ */
+ static async resolveFile(fileLike) {
+ let attachment;
+ let name;
+
+ const findName = thing => {
+ if (typeof thing === 'string') {
+ return Util.basename(thing);
+ }
+
+ if (thing.path) {
+ return Util.basename(thing.path);
+ }
+
+ return 'file.jpg';
+ };
+
+ const ownAttachment =
+ typeof fileLike === 'string' ||
+ fileLike instanceof (browser ? ArrayBuffer : Buffer) ||
+ typeof fileLike.pipe === 'function';
+ if (ownAttachment) {
+ attachment = fileLike;
+ name = findName(attachment);
+ } else {
+ attachment = fileLike.attachment;
+ name = fileLike.name || findName(attachment);
+ }
+
+ const resource = await DataResolver.resolveFile(attachment);
+ return { attachment, name, file: resource };
+ }
+
+ /**
+ * Creates a `GPayload` from user-level arguments.
+ * @param {TextChannel | NewsChannel | DMChannel} channel
+ * @param {string|GPayloadOptions} options
+ * @returns {GPayload}
+ */
+ static create(channel, options) {
+ return new this(channel, options);
+ }
+}
+
+module.exports = GPayload;
\ No newline at end of file
diff --git a/src/structures/InteractionEvent.js b/src/structures/InteractionEvent.js
index c9b23b50e..c7633a814 100644
--- a/src/structures/InteractionEvent.js
+++ b/src/structures/InteractionEvent.js
@@ -1,14 +1,11 @@
-/* From discord-buttons edited */
-const { default: axios } = require("axios");
-const {Client, MessageEmbed, Guild, NewsChannel, GuildMember, User, Message} = require("discord.js")
-const Color = require("../structures/Color");
-const GMessage = require("./GMessage");
-const ifDjsV13 = require("../util/updater").checkDjsVersion("13")
+const { interactionRefactor } = require('../util/util');
+const { Message } = require('discord.js')
+const GInteraction = require('./GInteraction');
/**
* The InteractionEvent class
*/
-class InteractionEvent {
+class InteractionEvent extends GInteraction {
/**
* Creates new InteractionEvent instance
@@ -16,16 +13,25 @@ class InteractionEvent {
* @param {Object} data
*/
constructor(client, data) {
- this.client = client;
+ super(client, data)
+ this.functions = interactionRefactor(client, data);
+
+ /**
+ * componentType
+ * @type {Number}
+ */
+ this.componentType = data.data.component_type
/**
* selectMenuId
+ * @type {String}
* @deprecated
*/
this.selectMenuId = data.data.values ? data.data.custom_id : undefined;
/**
- * selectMenuId
+ * valueId
+ * @type {Array}
* @deprecated
*/
this.valueId = data.data.values ? data.data.values : undefined;
@@ -42,49 +48,13 @@ class InteractionEvent {
*/
this.values = data.data.values ? data.data.values : undefined
- /**
- * version
- * @type {Number}
- */
- this.version = data.version;
-
- /**
- * token
- * @type {String}
- */
- this.token = data.token;
-
- /**
- * discordID
- * @type {Number}
- */
- this.discordID = data.id;
-
- /**
- * applicationID
- * @type {Number}
- */
- this.applicationID = data.application_id;
-
- /**
- * guild
- * @type {Guild}
- */
- this.guild = data.guild_id ? client.guilds.cache.get(data.guild_id) : undefined;
-
- /**
- * channel
- * @type {TextChannel | NewsChannel | DMChannel}
- */
- this.channel = client.channels.cache.get(data.channel_id);
-
/**
* clicker
* @type {GuildMember | User | Number}
*/
this.clicker = {
- member: this.guild ? this.guild.members.cache.get(data.member.user.id) : undefined,
- user: this.client.users.cache.get(data.guild_id ? data.member.user.id : data.user.id),
+ member: this.member,
+ user: this.author,
id: data.guild_id ? data.member.user.id : data.member.user.id,
};
@@ -92,302 +62,7 @@ class InteractionEvent {
* message
* @type {GMessage}
*/
- this.message = ifDjsV13 ? new Message(this.client, data.message, this.channel) : new GMessage(this.client, data.message, this.channel);
-
- /**
- * replied
- * @type {boolean}
- */
- this.replied = false;
-
- /**
- * deferred
- * @type {boolean}
- */
- this.deferred = false;
- }
-
- /**
- * Method to defer
- * @param {Boolean} ephemeral
- */
- async defer(ephemeral) {
- if (this.deferred || this.replied) return console.log(new Color('&d[GCommands] &cThis button already has a reply').getText());
- await this.client.api.interactions(this.discordID, this.token).callback.post({
- data: {
- type: 6,
- data: {
- flags: ephemeral ? 1 << 6 : null,
- },
- },
- });
- this.deferred = true;
- }
-
- /**
- * Method to think
- * @param {Boolean} ephemeral
- */
- async think(ephemeral) {
- if (this.deferred || this.replied) return console.log(new Color('&d[GCommands] &cThis button already has a reply').getText());
- await this.client.api.interactions(this.discordID, this.token).callback.post({
- data: {
- type: 5,
- data: {
- flags: ephemeral ? 1 << 6 : null,
- },
- },
- });
- this.deferred = true;
- }
-
- /**
- * Method to edit
- * @param {Object} options
- */
- async edit(result) {
- if(result.autoDefer == true) {
- await this.client.api.interactions(this.discordID, this.token).callback.post({
- data: {
- type: 6,
- },
- });
- }
-
- this.slashEdit(result)
- }
-
- /**
- * Method to update
- * @param {Object} options
- */
- async update(result) {
- if(result.autoDefer == true) {
- await this.client.api.interactions(this.discordID, this.token).callback.post({
- data: {
- type: 6,
- },
- });
- }
-
- this.slashEdit(result, true)
- }
-
- /**
- * Method to reply
- */
- get reply() {
- /**
- * Method to replySend
- * @param {Object} options
- */
- let _send = async(result) => {
- this.replied = true;
- this.slashRespond(result)
- }
-
- /**
- * Method to replyEdit
- * @param {Object} options
- */
- let _edit = async(result) => {
- if(!this.replied) return console.log(new Color("&d[GCommands] &cThis button has no reply.").getText())
- this.slashEdit(result)
- }
-
- /**
- * Method to replyUpdate
- * @param {Object} options
- */
- let _update = async(result) => {
- if(!this.replied) return console.log(new Color("&d[GCommands] &cThis button has no reply.").getText())
- this.slashEdit(result, true)
- }
-
- /**
- * Method to replyFetch
- * @param {Object} options
- */
- let _fetch = async() => {
- if(!this.replied) return console.log(new Color("&d[GCommands] &cThis button has no reply.").getText())
- let apiMessage = (await this.client.api.webhooks(this.client.user.id, this.token).messages["@original"].get());
-
- if(apiMessage) {
- apiMessage.client = this.client;
- apiMessage.createButtonCollector = function createButtonCollector(filter, options) {return this.client.dispatcher.createButtonCollector(apiMessage, filter, options)};
- apiMessage.awaitButtons = function awaitButtons(filter, options) {return this.client.dispatcher.awaitButtons(apiMessage, filter, options)};
- apiMessage.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return this.client.dispatcher.createSelectMenuCollector(apiMessage, filter, options)};
- apiMessage.awaitSelectMenus = function awaitSelectMenus(filter, options) {return this.client.dispatcher.awaitSelectMenus(apiMessage, filter, options)};
- apiMessage.delete = function deleteMsg() {return this.client.api.webhooks(this.client.user.id, interaction.token).messages[apiMessage.id].delete()};
- }
-
- return ifDjsV13 ? new Message(this.client, data.message, this.channel) : new GMessage(this.client, data.message, this.channel);
- }
-
- return {
- send: _send,
- edit: _edit,
- update: _update,
- fetch: _fetch
- }
- }
-
- async slashRespond(result) {
- var data = {}
-
- if(typeof result != "object") data.content = result;
- if(typeof result == "object" && !result.content) data.embeds = [result];
- if(typeof result == "object" && typeof result.content != "object") data.content = result.content;
- if(typeof result == "object" && typeof result.content == "object") data.embeds = [result.content];
- if(typeof result == "object" && result.allowedMentions) { data.allowedMentions = result.allowedMentions } else data.allowedMentions = { parse: [], repliedUser: true }
- if(typeof result == "object" && result.ephemeral) { data.flags = 64 }
- if(typeof result == "object" && result.components) {
- if(!Array.isArray(result.components)) result.components = [result.components];
- data.components = result.components;
- }
- if(typeof result == "object" && result.embeds) {
- if(!Array.isArray(result.embeds)) result.embeds = [result.embeds]
- data.embeds = result.embeds;
- }
-
- let finalFiles = [];
- if(typeof result == "object" && result.attachments) {
- if(!Array.isArray(result.attachments)) result.attachments = [result.attachments]
- result.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
- })
- }
-
- let apiMessage = (await this.client.api.interactions(this.discordID, this.token).callback.post({
- data: {
- type: result.thinking ? 5 : 4,
- data
- },
- files: finalFiles
- }))
-
- let apiMessageMsg = {};
- try {
- apiMessageMsg = (await axios.get(`https://discord.com/api/v8/webhooks/${this.client.user.id}/${interaction.token}/messages/@original`)).data;
- } catch(e) {
- apiMessage = {
- id: undefined
- }
- }
-
- if(typeof apiMessage != "object") apiMessage = apiMessage.toJSON();
- if(apiMessage) {
- apiMessage = apiMessageMsg;
- apiMessage.client = this.client ? this.client : client;
- apiMessage.createButtonCollector = function createButtonCollector(filter, options) {return this.client.dispatcher.createButtonCollector(apiMessage, filter, options)};
- apiMessage.awaitButtons = function awaitButtons(filter, options) {return this.client.dispatcher.awaitButtons(apiMessage, filter, options)};
- apiMessage.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return this.client.dispatcher.createSelectMenuCollector(apiMessage, filter, options)};
- apiMessage.awaitSelectMenus = function awaitSelectMenus(filter, options) {return this.client.dispatcher.awaitSelectMenus(apiMessage, filter, options)};
- apiMessage.delete = function deleteMsg() {return this.client.api.webhooks(this.client.user.id, interaction.token).messages[apiMessageMsg.id].delete()};
- }
-
- return apiMessage
- }
-
- async slashEdit(result, update) {
- if (typeof result == "object") {
- if(result.components) {
- if(!Array.isArray(result.components)) result.components = [result.components];
-
- result.components = result.components;
- } else result.components = [];
-
- if(typeof result.content == "object") {
- result.embeds = [result.content]
- result.content = "\u200B"
- }
- if(typeof result == "object" && result.embeds) {
- if(!Array.isArray(result.embeds)) result.embeds = [result.embeds];
- result.embeds = result.embeds;
- } else result.embeds = []
- if(result.embeds && !result.content) result.content = "\u200B"
-
- let apiMessage = {};
- if(update) {
- apiMessage = (await this.client.api.interactions(this.discordID, this.token).callback.post({
- data: {
- type: 7,
- data: {
- content: result.content,
- components: result.components,
- embeds: result.embeds || []
- }
- }
- }))
- } else {
- apiMessage = (await this.client.api.webhooks(this.client.user.id, this.token).messages[result.messageId ? result.messageId : "@original"].patch({
- data: {
- content: result.content,
- components: result.components,
- embeds: result.embeds || []
- }
- }))
- }
-
- if(typeof apiMessage != "object") apiMessage = apiMessage.toJSON();
- if(apiMessage) {
- apiMessage.client = this.client;
- apiMessage.createButtonCollector = function createButtonCollector(filter, options) {return this.client.dispatcher.createButtonCollector(apiMessage, filter, options)};
- apiMessage.awaitButtons = function awaitButtons(filter, options) {return this.client.dispatcher.awaitButtons(apiMessage, filter, options)};
- apiMessage.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return this.client.dispatcher.createSelectMenuCollector(apiMessage, filter, options)};
- apiMessage.awaitSelectMenus = function awaitSelectMenus(filter, options) {return this.client.dispatcher.awaitSelectMenus(apiMessage, filter, options)};
- apiMessage.delete = function deleteMsg() {return this.client.api.webhooks(this.client.user.id, interaction.token).messages[apiMessage.id].delete()};
- }
- return apiMessage;
- }
-
- let apiMessage;
- if(update) {
- apiMessage = (await this.client.api.interactions(this.discordID, this.token).callback.post({
- data: {
- data: {
- content: result,
- },
- type: 7
- },
- }))
- } else {
- apiMessage = (await this.client.api.webhooks(this.client.user.id, this.token).messages[result.messageId ? result.messageId : "@original"].patch({
- data: {
- content: result,
- }
- }))
- }
-
- if(typeof apiMessage != "object") apiMessage = apiMessage.toJSON();
- if(apiMessage) {
- apiMessage.client = this.client;
- apiMessage.createButtonCollector = function createButtonCollector(filter, options) {return this.client.dispatcher.createButtonCollector(apiMessage, filter, options)};
- apiMessage.awaitButtons = function awaitButtons(filter, options) {return this.client.dispatcher.awaitButtons(apiMessage, filter, options)};
- apiMessage.createSelectMenuCollector = function createSelectMenuCollector(filter, options) {return this.client.dispatcher.createSelectMenuCollector(apiMessage, filter, options)};
- apiMessage.awaitSelectMenus = function awaitSelectMenus(filter, options) {return this.client.dispatcher.awaitSelectMenus(apiMessage, filter, options)};
- apiMessage.delete = function deleteMsg() {return this.client.api.webhooks(this.client.user.id, interaction.token).messages[apiMessage.id].delete()};
- }
-
- return apiMessage;
- }
-
- /**
- * Method to isSelectMenu
- */
- async isSelectMenu() {
- return data.data.values ? true : false;
- }
-
- /**
- * Method to isButton
- */
- async isButton() {
- return data.data.values ? false : true;
+ this.message = new Message(this.client, data.message, this.channel)
}
}
diff --git a/src/structures/MessageActionRow.js b/src/structures/MessageActionRow.js
index 8fc45d949..f44ff6b5f 100644
--- a/src/structures/MessageActionRow.js
+++ b/src/structures/MessageActionRow.js
@@ -1,4 +1,4 @@
-const Color = require("../structures/Color");
+const Color = require('../structures/Color');
/**
* The MessageActionRow class
@@ -7,15 +7,33 @@ class MessageActionRow {
/**
* Creates new MessageActionRow instance
- * @param {Object} data
+ * @param {Array} data
*/
constructor(data = {}) {
+
+ /**
+ * type
+ * @type {Number}
+ */
+ this.type = 1;
+
+ /**
+ * components
+ * @type {Array}
+ */
+ this.components = [];
+
this.setup(data);
}
+ /**
+ * Setup
+ * @param {Array} data
+ * @returns {MessageActionRow}
+ * @private
+ */
setup(data) {
- this.type = 1;
- this.components = [];
+ this.components = 'components' in data ? Array(data.components) : [];
return this.toJSON();
}
@@ -25,7 +43,7 @@ class MessageActionRow {
* @param {MessageButton | MessageSelectMenu} cmponent
*/
addComponent(component) {
- if(typeof component != "object") return console.log(new Color("&d[GCommands] &cNeed provide MessageButton!").getText())
+ if(typeof component !== 'object') return console.log(new Color('&d[GCommands] &cNeed provide MessageButton!').getText())
this.components.push(component)
return this;
}
@@ -35,7 +53,7 @@ class MessageActionRow {
* @param {MessageButton[] | MessageSelectMenu[]} components
*/
addComponents(components) {
- if(typeof components != "object") return console.log(new Color("&d[GCommands] &cNeed provide MessageButton!").getText())
+ if(typeof components !== 'object') return console.log(new Color('&d[GCommands] &cNeed provide MessageButton!').getText())
this.components.push(...components.flat(Infinity).map((c) => c));
return this;
}
@@ -47,7 +65,7 @@ class MessageActionRow {
* @param {MessageButton[] | MessageSelectMenu[]} components
*/
removeComponents(index, deleteCount, ...components) {
- if(typeof components != "object") return console.log(new Color("&d[GCommands] &cNeed provide MessageSelectOption!").getText())
+ if(typeof components !== 'object') return console.log(new Color('&d[GCommands] &cNeed provide MessageSelectOption!').getText())
this.components.splice(index, deleteCount, ...components.flat(Infinity).map((c) => c));
return this;
}
diff --git a/src/structures/MessageButton.js b/src/structures/MessageButton.js
index cbe368397..1fb3884fa 100644
--- a/src/structures/MessageButton.js
+++ b/src/structures/MessageButton.js
@@ -1,6 +1,6 @@
/* From discord-buttons edited */
-const { resolveString } = require("../util/util");
-const Color = require("../structures/Color")
+const { resolveString, parseEmoji } = require('../util/util');
+const Color = require('./Color')
const styles = {
'blurple': 1,
'gray': 2,
@@ -28,17 +28,50 @@ class MessageButton {
this.setup(data);
}
+ /**
+ * Setup
+ * @param {Object} data
+ * @returns {MessageButton}
+ * @private
+ */
setup(data) {
+
+ /**
+ * style
+ * @type {String}
+ */
this.style = 'style' in data ? this.resolveStyle(resolveString(data.style)) : null;
+
+ /**
+ * label
+ * @type {String}
+ */
this.label = 'label' in data ? resolveString(data.label) : null;
+
+ /**
+ * disabled
+ * @type {Boolean}
+ */
this.disabled = 'disabled' in data ? Boolean(data.disabled) : false;
if (this.style === 5) {
+ /**
+ * url
+ * @type {String}
+ */
this.url = 'url' in data ? resolveString(data.url) : null;
} else {
+ /**
+ * customId
+ * @type {String}
+ */
this.custom_id = 'id' in data ? resolveString(data.id): null;
}
+ /**
+ * type
+ * @type {Number}
+ */
this.type = 2;
return this.toJSON();
@@ -67,7 +100,7 @@ class MessageButton {
* @param {String} emoji
*/
setEmoji(emoji) {
- this.emoji = this.parseEmoji(`${emoji}`);
+ this.emoji = parseEmoji(`${emoji}`);
return this;
}
@@ -115,24 +148,22 @@ class MessageButton {
}
resolveStyle(style) {
-
- if (!style || style === undefined || style === null) return console.log(new Color("&d[GCommands] &cAn invalid button styles was provided").getText())
+ if (!style || style === undefined || style === null) return console.log(new Color('&d[GCommands] &cAn invalid button styles was provided').getText())
- if (!styles[style] || styles[style] === undefined || styles[style] === null) return console.log(new Color("&d[GCommands] &cAn invalid button styles was provided").getText())
+ if (!styles[style] || styles[style] === undefined || styles[style] === null) return console.log(new Color('&d[GCommands] &cAn invalid button styles was provided').getText())
return styles[style] || style;
}
resolveButton(data) {
+ if (!data.style) return console.log(new Color('&d[GCommands] &cPlease provide button style').getText())
- if (!data.style) return console.log(new Color("&d[GCommands] &cPlease provide button style").getText())
-
- if (!data.label) return console.log(new Color("&d[GCommands] &cPlease provide button label").getText())
+ if (!data.label) return console.log(new Color('&d[GCommands] &cPlease provide button label').getText())
if (data.style === 5) {
- if (!data.url) return console.log(new Color("&d[GCommands] &cYou provided url style, you must provide an URL").getText())
+ if (!data.url) return console.log(new Color('&d[GCommands] &cYou provided url style, you must provide an URL').getText())
} else {
- if (!data.custom_id) return console.log(new Color("&d[GCommands] &cPlease provide button id").getText())
+ if (!data.custom_id) return console.log(new Color('&d[GCommands] &cPlease provide button id').getText())
}
return {
@@ -144,14 +175,6 @@ class MessageButton {
type: 2
}
}
-
- parseEmoji(text) {
- if (text.includes('%')) text = decodeURIComponent(text);
- if (!text.includes(':')) return { animated: false, name: text, id: null };
- const m = text.match(/(?:(a):)?(\w{2,32}):(\d{17,19})?>?/);
- if (!m) return null;
- return { animated: Boolean(m[1]), name: m[2], id: m[3] || null };
- }
}
module.exports = MessageButton;
\ No newline at end of file
diff --git a/src/structures/MessageSelectMenu.js b/src/structures/MessageSelectMenu.js
index baab35951..24eed37d6 100644
--- a/src/structures/MessageSelectMenu.js
+++ b/src/structures/MessageSelectMenu.js
@@ -1,5 +1,5 @@
-const { resolveString } = require("../util/util");
-const Color = require("../structures/Color")
+const { resolveString } = require('../util/util');
+const Color = require('./Color')
/**
* The MessageSelectMenu class
@@ -10,14 +10,61 @@ class MessageSelectMenu {
* Creates new MessageSelectMenu instance
* @param {Object} data
*/
- constructor(data = {}) {
+ constructor(data = {}) {
+
+ /**
+ * type
+ * @type {Number}
+ */
+ this.type = 3;
+
+ /**
+ * options
+ * @type {Array}
+ */
this.options = [];
this.setup(data);
}
- setup(data) {
- this.type = 3;
+ /**
+ * Setup
+ * @param {Object} data
+ * @returns {MessageSelectMenu}
+ * @private
+ */
+ setup(data) {
+ /**
+ * placeholder
+ * @type {String}
+ */
+ this.placeholder = 'placeholder' in data ? resolveString(data.placeholder) : null;
+
+ /**
+ * maxValues
+ * @type {number}
+ */
+ this.max_values = 'max_values' in data ? Number(data.max_values) : 1;
+
+ /**
+ * minValues
+ * @type {number}
+ */
+ this.min_values = 'min_values' in data ? Number(data.min_values) : 1;
+
+ /**
+ * id
+ * @type {String}
+ */
+ this.id = 'id' in data ? resolveString(data.id) : null;
+
+ this.options = 'options' in data ? Array(data.options) : [];
+
+ /**
+ * disabled
+ * @type {Boolean}
+ */
+ this.disabled = 'disabled' in data ? Boolean(data.disabled) : false;
return this.toJSON();
}
@@ -58,22 +105,31 @@ class MessageSelectMenu {
return this;
}
+ /**
+ * Method to setDisabled
+ * @param {String} boolean
+ */
+ setDisabled(boolean = true) {
+ this.disabled = Boolean(boolean);
+ return this;
+ }
+
/**
* Method to addOption
- * @param {MessageSelectOption} MessageSelectOption
+ * @param {MessageSelectMenuOption} MessageSelectMenuOption
*/
addOption(option) {
- if(typeof option != "object") return console.log(new Color("&d[GCommands] &cNeed provide MessageSelectOption!").getText())
+ if(typeof option !== 'object') return console.log(new Color('&d[GCommands] &cNeed provide MessageSelectOption!').getText())
this.options.push(option)
return this;
}
/**
* Method to addOptions
- * @param {MessageSelectOption[]} MessageSelectOptions
+ * @param {MessageSelectMenuOption[]} MessageSelectMenuOption
*/
addOptions(...options) {
- if(typeof options != "object") return console.log(new Color("&d[GCommands] &cNeed provide MessageSelectOption!").getText())
+ if(typeof options !== 'object') return console.log(new Color('&d[GCommands] &cNeed provide MessageSelectOption!').getText())
this.options.push(...options.flat(Infinity).map((o) => o));
return this;
}
@@ -82,10 +138,10 @@ class MessageSelectMenu {
* Method to removeOptions
* @param {Number} index
* @param {Number} deleteCount
- * @param {MessageSelectOption[]} MessageSelectOptions
+ * @param {MessageSelectMenuOption[]} MessageSelectMenuOption[]
*/
removeOptions(index, deleteCount, ...options) {
- if(typeof options != "object") return console.log(new Color("&d[GCommands] &cNeed provide MessageSelectOption!").getText())
+ if(typeof options !== 'object') return console.log(new Color('&d[GCommands] &cNeed provide MessageSelectOption!').getText())
this.components.splice(index, deleteCount, ...options.flat(Infinity).map((o) => o));
return this;
}
@@ -99,8 +155,9 @@ class MessageSelectMenu {
type: 3,
min_values: this.min_values,
max_values: this.max_values || this.options.length,
- placeholder: this.placeholder || "",
+ placeholder: this.placeholder || '',
custom_id: this.custom_id,
+ disabled: this.disabled,
options: this.options
}
}
diff --git a/src/structures/MessageSelectMenuOption.js b/src/structures/MessageSelectMenuOption.js
index f1a61e927..b7e899e15 100644
--- a/src/structures/MessageSelectMenuOption.js
+++ b/src/structures/MessageSelectMenuOption.js
@@ -1,4 +1,4 @@
-const { resolveString } = require("../util/util");
+const { resolveString, parseEmoji } = require('../util/util');
/**
* The MessageSelectMenuOption class
@@ -13,9 +13,43 @@ class MessageSelectMenuOption {
this.setup(data);
}
+ /**
+ * Setup
+ * @param {Object} data
+ * @returns {MessageButton}
+ * @private
+ */
setup(data) {
+ /**
+ * label
+ * @type {String}
+ */
this.label = 'label' in data ? resolveString(data.label) : null;
+ /**
+ * value
+ * @type {String}
+ */
+ this.value = 'value' in data ? resolveString(data.value) : null;
+
+ /**
+ * description
+ * @type {String}
+ */
+ this.description = 'description' in data ? resolveString(data.description) : null;
+
+ /**
+ * emoji
+ * @type {String}
+ */
+ this.emoji = 'emoji' in data ? parseEmoji(data.emoji) : null;
+
+ /**
+ * default
+ * @type {Boolean}
+ */
+ this.default = 'default' in data ? Boolean(data.default) : false;
+
return this.toJSON();
}
@@ -51,7 +85,7 @@ class MessageSelectMenuOption {
* @param {String} emoji
*/
setEmoji(emoji) {
- this.emoji = this.parseEmoji(`${emoji}`);
+ this.emoji = parseEmoji(`${emoji}`);
return this;
}
@@ -77,14 +111,6 @@ class MessageSelectMenuOption {
default: this.default
}
}
-
- parseEmoji(text) {
- if (text.includes('%')) text = decodeURIComponent(text);
- if (!text.includes(':')) return { animated: false, name: text, id: null };
- const m = text.match(/(?:(a):)?(\w{2,32}):(\d{17,19})?>?/);
- if (!m) return null;
- return { animated: Boolean(m[1]), name: m[2], id: m[3] || null };
- }
}
module.exports = MessageSelectMenuOption;
\ No newline at end of file
diff --git a/src/structures/NewsChannel.js b/src/structures/NewsChannel.js
index 13a2bad67..5b7a297b4 100644
--- a/src/structures/NewsChannel.js
+++ b/src/structures/NewsChannel.js
@@ -1,89 +1,64 @@
-const { Structures, MessageEmbed, NewsChannel } = require("discord.js");
+const { NewsChannel } = require('discord.js');
const ButtonCollectorV12 = require('../structures/v12/ButtonCollector'), ButtonCollectorV13 = require('../structures/v13/ButtonCollector'), SelectMenuCollectorV12 = require('../structures/v12/SelectMenuCollector'), SelectMenuCollectorV13 = require('../structures/v13/SelectMenuCollector')
-const updater = require("../util/updater")
+const GPayload = require('./GPayload');
+const ifDjsV13 = (require('../util/updater')).checkDjsVersion('13');
-if(!updater.checkDjsVersion("13")) {
- module.exports = Structures.extend("NewsChannel", NewsChannel => {
- class GNewsChannel extends NewsChannel {
- constructor(...args) {
- super(...args)
- }
+module.exports = Object.defineProperties(NewsChannel.prototype, {
+ send: {
+ value: async function(result) {
+ let GPayloadResult = await GPayload.create(this, result)
+ .resolveData()
+ .resolveFiles();
- async send(result) {
- var data = {}
-
- if(typeof result != "object") data.content = result;
- if(typeof result == "object" && !result.content) data.embeds = [result];
- if(typeof result == "object" && typeof result.content != "object") data.content = result.content;
- if(typeof result == "object" && typeof result.content == "object") data.embeds = [result.content];
- if(typeof result == "object" && result.allowedMentions) { data.allowedMentions = result.allowedMentions } else data.allowedMentions = { parse: [], repliedUser: true }
- if(typeof result == "object" && result.ephemeral) { data.flags = 64 }
- if(typeof result == "object" && result.components) {
- if(!Array.isArray(result.components)) result.components = [result.components];
- data.components = result.components;
- }
- if(typeof result == "object" && result.embeds) {
- if(!Array.isArray(result.embeds)) result.embeds = [result.embeds]
- data.embeds = result.embeds;
- }
- if(result.embeds && !result.content) result.content = "\u200B"
-
- let finalFiles = [];
- if(typeof result == "object" && result.attachments) {
- if(!Array.isArray(result.attachments)) result.attachments = [result.attachments]
- result.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
- })
- }
+ return this.client.api.channels[this.id].messages.post({
+ data: GPayloadResult.data,
+ files: GPayloadResult.files
+ })
+ .then(d => this.client.actions.MessageCreate.handle(d).message);
+ }
+ },
- return this.client.api.channels[this.id].messages.post({
- data,
- files: finalFiles
- })
- .then(d => this.client.actions.MessageCreate.handle(d).message);
- }
+ createButtonCollector: {
+ value: async function (msg, filter, options = {}) {
+ if(ifDjsV13) return new ButtonCollectorV13(msg, filter, options);
+ else return new ButtonCollectorV12(msg, filter, options);
+ }
+ },
- createButtonCollector(msg, filter, options = {}) {
- if(updater.checkDjsVersion("13")) return new ButtonCollectorV13(msg, filter, options);
- else return new ButtonCollectorV12(msg, filter, options);
- }
-
- awaitButtons(msg, filter, options = {}) {
- return new Promise((resolve, reject) => {
- const collector = this.createButtonCollector(msg, filter, options);
- collector.once('end', (buttons, reason) => {
- if (options.errors && options.errors.includes(reason)) {
- reject(buttons);
- } else {
- resolve(buttons);
- }
- });
- })
- }
+ awaitButtons: {
+ value: async function(msg, filter, options = {}) {
+ return new Promise((resolve, reject) => {
+ const collector = this.createButtonCollector(msg, filter, options);
+ collector.once('end', (buttons, reason) => {
+ if (options.errors && options.errors.includes(reason)) {
+ reject(buttons);
+ } else {
+ resolve(buttons);
+ }
+ });
+ })
+ }
+ },
- createSelectMenuCollector(msg, filter, options = {}) {
- if(updater.checkDjsVersion("13")) return new SelectMenuCollectorV13(msg, filter, options);
- else return new SelectMenuCollectorV12(msg, filter, options);
- }
-
- awaitSelectMenus(msg, filter, options = {}) {
- return new Promise((resolve, reject) => {
- const collector = this.createSelectMenuCollector(msg, filter, options);
- collector.once('end', (buttons, reason) => {
- if (options.errors && options.errors.includes(reason)) {
- reject(buttons);
- } else {
- resolve(buttons);
- }
- });
- })
- }
+ createSelectMenuCollector: {
+ value: async function(msg, filter, options = {}) {
+ if(ifDjsV13) return new SelectMenuCollectorV13(msg, filter, options);
+ else return new SelectMenuCollectorV12(msg, filter, options);
}
+ },
- return GNewsChannel;
- })
-} else module.exports = NewsChannel;
\ No newline at end of file
+ awaitSelectMenus: {
+ value: async function(msg, filter, options = {}) {
+ return new Promise((resolve, reject) => {
+ const collector = this.createSelectMenuCollector(msg, filter, options);
+ collector.once('end', (buttons, reason) => {
+ if (options.errors && options.errors.includes(reason)) {
+ reject(buttons);
+ } else {
+ resolve(buttons);
+ }
+ });
+ })
+ }
+ }
+});
\ No newline at end of file
diff --git a/src/structures/TextChannel.js b/src/structures/TextChannel.js
index a313ffc1b..d546e439e 100644
--- a/src/structures/TextChannel.js
+++ b/src/structures/TextChannel.js
@@ -1,89 +1,64 @@
-const { Structures, MessageEmbed, TextChannel } = require("discord.js");
+const { TextChannel } = require('discord.js');
const ButtonCollectorV12 = require('../structures/v12/ButtonCollector'), ButtonCollectorV13 = require('../structures/v13/ButtonCollector'), SelectMenuCollectorV12 = require('../structures/v12/SelectMenuCollector'), SelectMenuCollectorV13 = require('../structures/v13/SelectMenuCollector')
-const updater = require("../util/updater");
+const GPayload = require('./GPayload');
+const ifDjsV13 = (require('../util/updater')).checkDjsVersion('13');
-if(!updater.checkDjsVersion("13")) {
- module.exports = Structures.extend("TextChannel", TextChannel => {
- class GTextChannel extends TextChannel {
- constructor(...args) {
- super(...args)
- }
+module.exports = Object.defineProperties(TextChannel.prototype, {
+ send: {
+ value: async function(result) {
+ let GPayloadResult = await GPayload.create(this, result)
+ .resolveData()
+ .resolveFiles();
- async send(result) {
- var data = {}
-
- if(typeof result != "object") data.content = result;
- if(typeof result == "object" && !result.content) data.embeds = [result];
- if(typeof result == "object" && typeof result.content != "object") data.content = result.content;
- if(typeof result == "object" && typeof result.content == "object") data.embeds = [result.content];
- if(typeof result == "object" && result.allowedMentions) { data.allowedMentions = result.allowedMentions } else data.allowedMentions = { parse: [], repliedUser: true }
- if(typeof result == "object" && result.ephemeral) { data.flags = 64 }
- if(typeof result == "object" && result.components) {
- if(!Array.isArray(result.components)) result.components = [result.components];
- data.components = result.components;
- }
- if(typeof result == "object" && result.embeds) {
- if(!Array.isArray(result.embeds)) result.embeds = [result.embeds]
- data.embeds = result.embeds;
- }
- if(result.embeds && !result.content) result.content = "\u200B"
-
- let finalFiles = [];
- if(typeof result == "object" && result.attachments) {
- if(!Array.isArray(result.attachments)) result.attachments = [result.attachments]
- result.attachments.forEach(file => {
- finalFiles.push({
- attachment: file.attachment,
- name: file.name,
- file: file.attachment
- })
- })
- }
+ return this.client.api.channels[this.id].messages.post({
+ data: GPayloadResult.data,
+ files: GPayloadResult.files
+ })
+ .then(d => this.client.actions.MessageCreate.handle(d).message);
+ }
+ },
- return this.client.api.channels[this.id].messages.post({
- data,
- files: finalFiles
- })
- .then(d => this.client.actions.MessageCreate.handle(d).message);
- }
+ createButtonCollector: {
+ value: async function (msg, filter, options = {}) {
+ if(ifDjsV13) return new ButtonCollectorV13(msg, filter, options);
+ else return new ButtonCollectorV12(msg, filter, options);
+ }
+ },
- createButtonCollector(msg, filter, options = {}) {
- if(updater.checkDjsVersion("13")) return new ButtonCollectorV13(msg, filter, options);
- else return new ButtonCollectorV12(msg, filter, options);
- }
-
- awaitButtons(msg, filter, options = {}) {
- return new Promise((resolve, reject) => {
- const collector = this.createButtonCollector(msg, filter, options);
- collector.once('end', (buttons, reason) => {
- if (options.errors && options.errors.includes(reason)) {
- reject(buttons);
- } else {
- resolve(buttons);
- }
- });
- })
- }
+ awaitButtons: {
+ value: async function(msg, filter, options = {}) {
+ return new Promise((resolve, reject) => {
+ const collector = this.createButtonCollector(msg, filter, options);
+ collector.once('end', (buttons, reason) => {
+ if (options.errors && options.errors.includes(reason)) {
+ reject(buttons);
+ } else {
+ resolve(buttons);
+ }
+ });
+ })
+ }
+ },
- createSelectMenuCollector(msg, filter, options = {}) {
- if(updater.checkDjsVersion("13")) return new SelectMenuCollectorV13(msg, filter, options);
- else return new SelectMenuCollectorV12(msg, filter, options);
- }
-
- awaitSelectMenus(msg, filter, options = {}) {
- return new Promise((resolve, reject) => {
- const collector = this.createSelectMenuCollector(msg, filter, options);
- collector.once('end', (buttons, reason) => {
- if (options.errors && options.errors.includes(reason)) {
- reject(buttons);
- } else {
- resolve(buttons);
- }
- });
- })
- }
+ createSelectMenuCollector: {
+ value: async function(msg, filter, options = {}) {
+ if(ifDjsV13) return new SelectMenuCollectorV13(msg, filter, options);
+ else return new SelectMenuCollectorV12(msg, filter, options);
}
+ },
- return GTextChannel;
- })
-} else module.exports = TextChannel;
\ No newline at end of file
+ awaitSelectMenus: {
+ value: async function(msg, filter, options = {}) {
+ return new Promise((resolve, reject) => {
+ const collector = this.createSelectMenuCollector(msg, filter, options);
+ collector.once('end', (buttons, reason) => {
+ if (options.errors && options.errors.includes(reason)) {
+ reject(buttons);
+ } else {
+ resolve(buttons);
+ }
+ });
+ })
+ }
+ }
+});
\ No newline at end of file
diff --git a/src/structures/v12/ButtonCollector.js b/src/structures/v12/ButtonCollector.js
index c02ff60e8..4f129a17c 100644
--- a/src/structures/v12/ButtonCollector.js
+++ b/src/structures/v12/ButtonCollector.js
@@ -1,14 +1,32 @@
-const { Collector } = require("discord.js");
+const { Collector } = require('discord.js');
const Collection = require('discord.js').Collection;
const { Events } = require('discord.js').Constants;
+/**
+ * Collects buttons on a message.
+ * Will automatically stop if the channel (`'channelDelete'`), guild (`'guildDelete'`) or (`'messageDelete'`) are deleted.
+ * @extends {Collector}
+ */
class ButtonCollector extends Collector {
+ /**
+ * @param {Message} message
+ * @param {CollectorOptions} options The options to be applied to this collector
+ * @emits ButtonCollector#clickButton
+ */
constructor(message, filter, options = {}) {
super(message.client, filter, options);
this.message = message;
+ /**
+ * users
+ * @type {Collection}
+ */
this.users = new Collection();
+ /**
+ * total
+ * @type {Number}
+ */
this.total = 0;
this.empty = this.empty.bind(this);
@@ -36,16 +54,28 @@ class ButtonCollector extends Collector {
});
}
+ /**
+ * Handles a button for possible collection.
+ * @param {GInteraction} button
+ * @returns {GInteraction}
+ * @private
+ */
collect(button) {
if(this.message.unstable) return ButtonCollector.key(button)
if (button.message.id !== this.message.id) return null;
return ButtonCollector.key(button);
}
+ /**
+ * @returns {null}
+ */
dispose() {
return null;
}
+ /**
+ * Empties this button collector.
+ */
empty() {
this.total = 0;
this.collected.clear();
@@ -53,6 +83,11 @@ class ButtonCollector extends Collector {
this.checkEnd();
}
+ /**
+ * The reason this collector has ended with, or null if it hasn't ended yet
+ * @type {?string}
+ * @readonly
+ */
endReason() {
if (this.options.max && this.total >= this.options.max) return 'limit';
if (this.options.maxEmojis && this.collected.size >= this.options.maxEmojis) return 'emojiLimit';
@@ -60,24 +95,47 @@ class ButtonCollector extends Collector {
return null;
}
+ /**
+ * Handles checking if the message has been deleted, and if so, stops the collector with the reason 'messageDelete'.
+ * @private
+ * @param {Guild} message The message that was deleted
+ * @returns {void}
+ */
_handleMessageDeletion(message) {
if (message.id === this.message.id) {
this.stop('messageDelete');
}
}
+ /**
+ * Handles checking if the channel has been deleted, and if so, stops the collector with the reason 'channelDelete'.
+ * @private
+ * @param {Guild} channel The channel that was deleted
+ * @returns {void}
+ */
_handleChannelDeletion(channel) {
if (channel.id === this.message.channel.id) {
this.stop('channelDelete');
}
}
+ /**
+ * Handles checking if the guild has been deleted, and if so, stops the collector with the reason 'guildDelete'.
+ * @private
+ * @param {Guild} guild The guild that was deleted
+ * @returns {void}
+ */
_handleGuildDeletion(guild) {
if (this.message.guild && guild.id === this.message.guild.id) {
this.stop('guildDelete');
}
}
+ /**
+ * Gets the collector key for a button.
+ * @param {MessageButton} button The button to get the key for
+ * @returns {Snowflake|string}
+ */
static key(button) {
return button.id;
}
diff --git a/src/structures/v12/SelectMenuCollector.js b/src/structures/v12/SelectMenuCollector.js
index af06028c0..45ac3be9d 100644
--- a/src/structures/v12/SelectMenuCollector.js
+++ b/src/structures/v12/SelectMenuCollector.js
@@ -1,14 +1,32 @@
-const { Collector } = require("discord.js");
+const { Collector } = require('discord.js');
const Collection = require('discord.js').Collection;
const { Events } = require('discord.js').Constants;
-class SelectMenuCollector extends Collector {
+/**
+ * Collects menus on a message.
+ * Will automatically stop if the channel (`'channelDelete'`), guild (`'guildDelete'`) or (`'messageDelete'`) are deleted.
+ * @extends {Collector}
+ */
+ class SelectMenuCollector extends Collector {
+ /**
+ * @param {Message} message
+ * @param {CollectorOptions} options The options to be applied to this collector
+ * @emits SelectMenuCollector#selectMenu
+ */
constructor(message, filter, options = {}) {
super(message.client, filter, options);
this.message = message;
+ /**
+ * users
+ * @type {Collection}
+ */
this.users = new Collection();
+ /**
+ * total
+ * @type {Number}
+ */
this.total = 0;
this.empty = this.empty.bind(this);
@@ -36,16 +54,28 @@ class SelectMenuCollector extends Collector {
});
}
+ /**
+ * Handles a menu for possible collection.
+ * @param {GInteraction} menu
+ * @returns {GInteraction}
+ * @private
+ */
collect(menu) {
if(this.message.unstable) return SelectMenuCollector.key(menu)
if (menu.message.id !== this.message.id) return null;
return SelectMenuCollector.key(menu);
}
+ /**
+ * @returns {null}
+ */
dispose() {
return null;
}
+ /**
+ * Empties this menu collector.
+ */
empty() {
this.total = 0;
this.collected.clear();
@@ -53,6 +83,11 @@ class SelectMenuCollector extends Collector {
this.checkEnd();
}
+ /**
+ * The reason this collector has ended with, or null if it hasn't ended yet
+ * @type {?string}
+ * @readonly
+ */
endReason() {
if (this.options.max && this.total >= this.options.max) return 'limit';
if (this.options.maxEmojis && this.collected.size >= this.options.maxEmojis) return 'emojiLimit';
@@ -60,26 +95,49 @@ class SelectMenuCollector extends Collector {
return null;
}
- _handleMessageDeletion(message) {
+ /**
+ * Handles checking if the message has been deleted, and if so, stops the collector with the reason 'messageDelete'.
+ * @private
+ * @param {Guild} message The message that was deleted
+ * @returns {void}
+ */
+ _handleMessageDeletion(message) {
if (message.id === this.message.id) {
this.stop('messageDelete');
}
}
+ /**
+ * Handles checking if the channel has been deleted, and if so, stops the collector with the reason 'channelDelete'.
+ * @private
+ * @param {Guild} channel The channel that was deleted
+ * @returns {void}
+ */
_handleChannelDeletion(channel) {
if (channel.id === this.message.channel.id) {
this.stop('channelDelete');
}
}
+ /**
+ * Handles checking if the guild has been deleted, and if so, stops the collector with the reason 'guildDelete'.
+ * @private
+ * @param {Guild} guild The guild that was deleted
+ * @returns {void}
+ */
_handleGuildDeletion(guild) {
if (this.message.guild && guild.id === this.message.guild.id) {
this.stop('guildDelete');
}
}
+ /**
+ * Gets the collector key for a menu.
+ * @param {MessageSelectMenu} menu The menu to get the key for
+ * @returns {Snowflake|string}
+ */
static key(menu) {
- return menu.selectMenuId;
+ return menu.id;
}
}
diff --git a/src/structures/v13/ButtonCollector.js b/src/structures/v13/ButtonCollector.js
index 27a5a8af6..f105a68ca 100644
--- a/src/structures/v13/ButtonCollector.js
+++ b/src/structures/v13/ButtonCollector.js
@@ -1,4 +1,4 @@
-const { Collector } = require("discord.js");
+const { Collector } = require('discord.js');
const Collection = require('discord.js').Collection;
const { Events } = require('discord.js').Constants;
diff --git a/src/structures/v13/SelectMenuCollector.js b/src/structures/v13/SelectMenuCollector.js
index 9ea1decce..043258d19 100644
--- a/src/structures/v13/SelectMenuCollector.js
+++ b/src/structures/v13/SelectMenuCollector.js
@@ -1,4 +1,4 @@
-const { Collector } = require("discord.js");
+const { Collector } = require('discord.js');
const Collection = require('discord.js').Collection;
const { Events } = require('discord.js').Constants;
@@ -79,7 +79,7 @@ class SelectMenuCollector extends Collector {
}
static key(menu) {
- return menu.selectMenuId;
+ return menu.id;
}
}
diff --git a/src/util/Constants.js b/src/util/Constants.js
index eb7ae4aec..5a7f2c504 100644
--- a/src/util/Constants.js
+++ b/src/util/Constants.js
@@ -11,6 +11,6 @@
*/
exports.Events = {
- DEBUG: "debug",
- LOG: "log"
+ DEBUG: 'debug',
+ LOG: 'log'
}
\ No newline at end of file
diff --git a/src/util/cmdUtils.js b/src/util/cmdUtils.js
index fa55316d1..ffdf414a4 100644
--- a/src/util/cmdUtils.js
+++ b/src/util/cmdUtils.js
@@ -1,8 +1,9 @@
-const {Collection,MessageEmbed,APIMessage} = require("discord.js")
-
module.exports = {
/**
* Internal method to deleteCmd
+ * @param {Client} client
+ * @param {Number} commandId
+ * @param {?Number} guildId
* @private
*/
__deleteCmd: async function(client, commandId, guildId = undefined) {
@@ -18,7 +19,9 @@ module.exports = {
/**
* Internal method to getAllCmds
- * @returns {object}
+ * @param {Client} client
+ * @param {Number} guildId
+ * @private
*/
__getAllCommands: async function(client, guildId = undefined) {
try {
diff --git a/src/util/message.json b/src/util/message.json
index 25f1d0b60..1d90aeb70 100644
--- a/src/util/message.json
+++ b/src/util/message.json
@@ -54,6 +54,28 @@
"turkish": "{COMMAND} adındaki komutu bulamadım!",
"polish": "Nie mogę znaleźć komendy {COMMAND}!"
},
+ "CHANNEL_TEXT_ONLY": {
+ "english": "You can only run this command in text channels.",
+ "spanish": "Sólo puede ejecutar este comando en los canales de texto.",
+ "portuguese": "Só se pode executar este comando em canais de texto.",
+ "russian": "Эту команду можно выполнить только в текстовых каналах.",
+ "german": "Sie können diesen Befehl nur in Textkanälen ausführen.",
+ "czech": "Tento příkaz lze spustit pouze v textových kanálech.",
+ "slovak": "Tento príkaz môžete spustiť len v textových kanáloch.",
+ "turkish": "Bu komutu yalnızca metin kanallarında çalıştırabilirsiniz.",
+ "polish": "Możesz uruchomić to polecenie tylko w kanałach tekstowych."
+ },
+ "CHANNEL_NEWS_ONLY": {
+ "english": "You can only run this command in news channels.",
+ "spanish": "Sólo puede ejecutar este comando en los canales de noticias.",
+ "portuguese": "Só se pode executar este comando em canais de notícias.",
+ "russian": "Эту команду можно выполнять только в новостных каналах.",
+ "german": "Sie können diesen Befehl nur in Nachrichtenkanälen ausführen.",
+ "czech": "Tento příkaz lze spustit pouze ve zpravodajských kanálech.",
+ "slovak": "Tento príkaz môžete spustiť len v spravodajských kanáloch.",
+ "turkish": "Bu komutu sadece haber kanallarında çalıştırabilirsiniz.",
+ "polish": "To polecenie można uruchomić tylko w kanałach informacyjnych."
+ },
"NSFW": {
"english": "You can only use this command in nsfw channel.",
"spanish": "Sólo puede utilizar este comando en el canal nsfw.",
@@ -64,5 +86,38 @@
"slovak": "Príkaz môžete využiť iba v nsfw room.",
"turkish": "Bu komutu sadece nsfw kanalında kullanabilirsiniz.",
"polish": "Tej komendy możesz użyć tylko na kanale NSFW."
+ },
+ "ARGS_TIME_LIMIT": {
+ "english": "You have no time left to answer. You must run the command again.",
+ "spanish": "No te queda tiempo para responder. Debe ejecutar el comando de nuevo.",
+ "portuguese": "Não lhe resta tempo para responder. Deve executar o comando de novo.",
+ "russian": "У вас не осталось времени на ответ. Вы должны выполнить команду еще раз.",
+ "german": "Sie haben keine Zeit mehr zu antworten. Sie müssen den Befehl erneut ausführen.",
+ "czech": "Na odpověď vám nezbývá čas. Příkaz musíte spustit znovu.",
+ "slovak": "Na odpoveď vám už nezostáva čas. Príkaz musíte spustiť znova.",
+ "turkish": "Cevaplamak için zamanınız kalmadı. Komutu tekrar çalıştırmanız gerekir.",
+ "polish": "Nie masz już czasu na odpowiedź. Musisz ponownie uruchomić polecenie."
+ },
+ "ARGS_MUST_CONTAIN": {
+ "english": "The argument `{argument}` must contain a {type}.",
+ "spanish": "El argumento `{argument}` debe contener un {type}.",
+ "portuguese": "O argumento ``{argument}` deve conter um {type}.",
+ "russian": "Аргумент `{argument}` должен содержать {type}.",
+ "german": "Das Argument `{argument}` muss einen {type} enthalten.",
+ "czech": "Argument `{argument}` musí obsahovat {type}.",
+ "slovak": "Argument `{argument}` musí obsahovať {type}.",
+ "turkish": "`{argument}` bağımsız değişkeni bir {type} içermelidir.",
+ "polish": "Argument `{argument}` musi zawierać {type}."
+ },
+ "ARGS_CHOICES": {
+ "english": "Please enter one of the following options: {choices}.",
+ "spanish": "Por favor, introduzca una de las siguientes opciones: {choices}.",
+ "portuguese": "Por favor, introduza uma das seguintes opções: {choices}.",
+ "russian": "Пожалуйста, введите один из следующих вариантов: {choices}.",
+ "german": "Bitte geben Sie eine der folgenden Optionen ein: {choices}.",
+ "czech": "Zadejte jednu z následujících možností: {choices}.",
+ "slovak": "Zadajte jednu z nasledujúcich možností: {choices}.",
+ "turkish": "Lütfen aşağıdaki seçeneklerden birini girin: {choices}.",
+ "polish": "Proszę wprowadzić jedną z poniższych opcji: {choices}."
}
}
\ No newline at end of file
diff --git a/src/util/updater.js b/src/util/updater.js
index 505a79ea8..73b050df2 100644
--- a/src/util/updater.js
+++ b/src/util/updater.js
@@ -1,5 +1,5 @@
-const axios = require("axios")
-const { writeFileSync, readFileSync } = require("fs")
+const axios = require('axios')
+const { writeFileSync, readFileSync } = require('fs')
const { version } = require('discord.js');
module.exports = {
@@ -9,21 +9,26 @@ module.exports = {
* @private
*/
__updater: async function() {
- var { Color } = require("../index")
- var version = require("../index").version
+ let { Color } = require('../index')
+ let version = require('../index').version
- var GCommandsUpdater = await axios.get("https://registry.npmjs.org/gcommands")
- var stableVersion = GCommandsUpdater.data["dist-tags"].latest
+ let GCommandsUpdater = await axios.get('https://registry.npmjs.org/gcommands')
+ let stableVersion = GCommandsUpdater.data['dist-tags'].latest
- if(stableVersion != version && !version.includes("dev")) {
- console.log(new Color("&d[GCommands Updater] &cPlease update GCommands &ehttps://npmjs.org/package/gcommands").getText())
- } else if(version.includes("dev")) {
- console.log(new Color("&d[GCommands Updater] &cYou have &eDEV &cversion of GCommands &ehttps://gcommands.js.org&c and select dev version.").getText())
+ if(stableVersion !== version && !version.includes('dev')) {
+ console.log(new Color('&d[GCommands Updater] &cPlease update GCommands &ehttps://npmjs.org/package/gcommands').getText())
+ } else if(version.includes('dev')) {
+ console.log(new Color('&d[GCommands Updater] &cYou have &eDEV &cversion of GCommands &ehttps://gcommands.js.org&c and select dev version.').getText())
}
},
+ /**
+ * Internal method to checkDjsVersion
+ * @returns {Boolean}
+ * @private
+ */
checkDjsVersion: function(needVer) {
- var ver = parseInt(version.split("")[0] + version.split("")[1]);
+ let ver = parseInt(version.split('')[0] + version.split('')[1]);
if(ver == parseInt(needVer)) {
return true;
} else {
diff --git a/src/util/util.js b/src/util/util.js
index dae79ed89..ba19d7b77 100644
--- a/src/util/util.js
+++ b/src/util/util.js
@@ -1,12 +1,91 @@
module.exports = {
+ /**
+ * Internal method to resolveString
+ * @param {String | Array} data
+ * @returns {String}
+ */
resolveString(data) {
if (typeof data === 'string') return data;
if (Array.isArray(data)) return data.join('\n');
return String(data);
},
+ /**
+ * Internal method to msToSeconds
+ * @param {Number} ms
+ * @returns {number}
+ */
msToSeconds(ms) {
let seconds = ms / 1000;
return seconds;
- }
+ },
+
+ /**
+ * Internal method to parseEmoji
+ * @param {String} text
+ * @returns {Object}
+ */
+ parseEmoji(text) {
+ if (text.includes('%')) text = decodeURIComponent(text);
+ if (!text.includes(':')) return { animated: false, name: text, id: null };
+ const match = text.match(/(?:(a):)?(\w{2,32}):(\d{17,19})?>?/);
+ return match && { animated: Boolean(match[1]), name: match[2], id: match[3] || null };
+ },
+
+ /**
+ * Internal method to interactionRefactor
+ * @param {Client} djsclient
+ * @param {GInteraction} interaction
+ * @returns {Object}
+ */
+ interactionRefactor(client, interaction) {
+ let is = {
+ button: false,
+ menu: false,
+ command: false,
+ }
+
+ if(interaction.name && client.gcommands.get(interaction.name)) {
+ is.command = true;
+ }
+
+ if(interaction.componentType == 2) {
+ is.button = true;
+ }
+
+ if(interaction.componentType == 3) {
+ is.menu = true;
+ }
+
+ interaction.isCommand = async() => is.command;
+ interaction.isButton = async() => is.button;
+ interaction.isSelectMenu = async() => is.menu;
+ return interaction;
+ },
+
+ /**
+ * Internal method to inhivit
+ * @param {Client} client
+ * @param {GInteraction} interaction
+ * @param {Function} data
+ * @returns {object}
+ */
+ inhibit(client, interaction, data) {
+ for(const inhibitor of client.inhibitors) {
+ let inhibit = inhibitor(interaction, data);
+ return inhibit;
+ }
+ return null;
+ },
+
+ /**
+ * Internal method to isClass
+ * @param {File} input
+ * @returns {boolean}
+ */
+ isClass(input) {
+ return typeof input === 'function' &&
+ typeof input.prototype === 'object' &&
+ input.toString().substring(0, 5) === 'class';
+ }
}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
deleted file mode 100644
index fda50cc42..000000000
--- a/tsconfig.json
+++ /dev/null
@@ -1,72 +0,0 @@
-{
- "compilerOptions": {
- /* Visit https://aka.ms/tsconfig.json to read more about this file */
-
- /* Basic Options */
- // "incremental": true, /* Enable incremental compilation */
- "target": "es2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */
- "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
- // "lib": [], /* Specify library files to be included in the compilation. */
- // "allowJs": true, /* Allow javascript files to be compiled. */
- // "checkJs": true, /* Report errors in .js files. */
- // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
- // "declaration": true, /* Generates corresponding '.d.ts' file. */
- // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
- // "sourceMap": true, /* Generates corresponding '.map' file. */
- // "outFile": "./", /* Concatenate and emit output to single file. */
- // "outDir": "./", /* Redirect output structure to the directory. */
- // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
- // "composite": true, /* Enable project compilation */
- // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
- // "removeComments": true, /* Do not emit comments to output. */
- // "noEmit": true, /* Do not emit outputs. */
- // "importHelpers": true, /* Import emit helpers from 'tslib'. */
- // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
- // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
-
- /* Strict Type-Checking Options */
- "strict": true, /* Enable all strict type-checking options. */
- // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
- // "strictNullChecks": true, /* Enable strict null checks. */
- // "strictFunctionTypes": true, /* Enable strict checking of function types. */
- // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
- // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
- // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
- // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
-
- /* Additional Checks */
- // "noUnusedLocals": true, /* Report errors on unused locals. */
- // "noUnusedParameters": true, /* Report errors on unused parameters. */
- // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
- // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
- // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
- // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */
- // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */
-
- /* Module Resolution Options */
- // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
- // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
- // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
- // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
- // "typeRoots": [], /* List of folders to include type definitions from. */
- // "types": [], /* Type declaration files to be included in compilation. */
- // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
- "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
- // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
- // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
-
- /* Source Map Options */
- // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
- // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
- // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
- // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
-
- /* Experimental Options */
- // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
- // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
-
- /* Advanced Options */
- "skipLibCheck": true, /* Skip type checking of declaration files. */
- "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
- }
-}
\ No newline at end of file
diff --git a/typings/index.d.ts b/typings/index.d.ts
index b4e53bc9c..17c7f3546 100644
--- a/typings/index.d.ts
+++ b/typings/index.d.ts
@@ -1,4 +1,4 @@
-import discord, { Channel, Client, Collector, Collection, Guild, GuildChannel, GuildMember, Message, MessageAttachment, MessageCollectorOptions, CollectorOptions, MessageEmbed, Snowflake, User } from 'discord.js';
+import discord, { Channel, Client, Collector, Collection, Guild, GuildChannel, GuildMember, Message, MessageAttachment, MessageCollectorOptions, CollectorOptions, MessageEmbed, Snowflake, User, NewsChannel, TextChannel, DMChannel, MembershipStates } from 'discord.js';
import InteractionEvent = require('../src/structures/InteractionEvent');
import { EventEmitter } from 'events';
type GuildLanguageTypes = 'english' | 'spanish' | 'portuguese' | 'russian' | 'german' | 'czech' | 'slovak' | 'turkish' | 'polish';
@@ -104,34 +104,21 @@ declare module 'discord.js' {
}
declare module 'gcommands' {
- export class GCommandsGuild extends Guild {
- public prefix: string;
- public language: string;
-
- public getCommandPrefix(cache?: boolean): string;
- public getLanguage(cache?: boolean): string;
-
- public setCommandPrefix(prefix: string): void;
- public setLanguage(language: GuildLanguageTypes): void;
- }
-
- export class InteractionEvent {
- constructor(client: Client, data: object)
- public selectMenuId: string;
- public valueId: string;
- public values: array;
- public id: string;
- public version: number;
+ export class GInteraction {
+ public type: number;
public token: number;
- public discordID: number;
- public applicationID: number;
+ public discordId: number;
+ public version: number;
+ public applicationId: number;
public guild: Guild;
- public channel: Channel;
- public clicker: {
- member: GuildMember;
- user: User;
+ public channel: TextChannel | NewsChannel | DMChannel;
+ public author: User;
+ public member: GuildMember;
+ public interaction: {
+ name: string;
+ id: number;
+ options: Array;
}
- public message: Message;
public replied: boolean;
public deffered: boolean;
@@ -145,6 +132,19 @@ declare module 'gcommands' {
}
}
+ export class InteractionEvent extends GInteraction {
+ constructor(client: Client, data: object)
+
+ public values: array;
+ public id: string;
+ public clicker: {
+ member: GuildMember;
+ user: User;
+ }
+
+ public message: Message;
+ }
+
export class Color {
constructor(text: string, options: object)
public text: string;
@@ -203,13 +203,13 @@ declare module 'gcommands' {
public type: number;
public disabled: boolean;
- public setStyle(style: MessageButtonStyle): this;
- public setLabel(label: string): this;
- public setEmoji(emoji: string): this;
- public setURL(url: string): this;
- public setDisabled(disabled: boolean): this;
- public setID(id: number): this;
- public toJSON(): this;
+ public setStyle(style: MessageButtonStyle): MessageButton;
+ public setLabel(label: string): MessageButton;
+ public setEmoji(emoji: string): MessageButton;
+ public setURL(url: string): MessageButton;
+ public setDisabled(disabled: boolean): MessageButton;
+ public setID(id: number): MessageButton;
+ public toJSON(): MessageButton;
}
export class MessageSelectMenu {
@@ -220,14 +220,15 @@ declare module 'gcommands' {
public custom_id: string;
public options: object;
- public setPlaceholder(placeholder: string): this;
- public setMaxValues(max: number): this;
- public setMinValues(min: number): this;
- public setID(id: number): this;
+ public setPlaceholder(placeholder: string): tMessageSelectMenuhis;
+ public setMaxValues(max: number): MessageSelectMenu;
+ public setMinValues(min: number): MessageSelectMenu;
+ public setID(id: number): MessageSelectMenu;
+ public setDisabled(disabled: boolean): MessageSelectMenu;
public addOption(option: MessageSelectMenuOption)
public addOptions(...options: MessageSelectMenuOption[])
public removeOptions(index: number, deleteCount: number, ...options: MessageSelectMenuOption[])
- public toJSON(): this;
+ public toJSON(): MessageSelectMenu;
}
export class MessageSelectMenuOption {
@@ -239,12 +240,12 @@ declare module 'gcommands' {
public emoji: object;
public default: boolean;
- public setLabel(label: string): this;
- public setValue(value: string): this;
- public setDescription(value: string): this;
- public setEmoji(emoji: string): this;
- public setDefault(disabled: boolean): this;
- public toJSON(): this;
+ public setLabel(label: string): MessageSelectMenuOption;
+ public setValue(value: string): MessageSelectMenuOption;
+ public setDescription(value: string): MessageSelectMenuOption;
+ public setEmoji(emoji: string): MessageSelectMenuOption;
+ public setDefault(disabled: boolean): MessageSelectMenuOption;
+ public toJSON(): MessageSelectMenuOption;
}
export class GCommandsDispatcher {
@@ -281,6 +282,53 @@ declare module 'gcommands' {
): this;
}
+ export class Command {
+ constructor(client: Client, options: CommandOptions)
+
+ public name: string;
+ public description: string;
+ public cooldown: string;
+ public expectedArgs: String | Array;
+ public args: Array;
+ public minArgs: number;
+ public clientRequiredPermissions: String | Array;
+ public userRequiredPermissions: String | Array;
+ public userRequiredRoles: String | Array;
+ public userOnly: Snowflake | Array;
+ public channelOnly: Snowflake | Array;
+ public channelTextOnly: Boolean;
+ public channelNewsOnly: Boolean;
+ public guildOnly: Snowflake | String;
+ public nsfw: boolean;
+ public aliases: Array;
+ public category: string;
+
+ public run(options: CommandRunOptions, args: Array, args2: Object | Array): void;
+ }
+
+ export class Event {
+ constructor(client: Client, options: EventOptions)
+
+ public name: string;
+ public once: boolean;
+ public ws: boolean;
+
+ public run(client: Client, ...args): void;
+ }
+
+ export class GPayload {
+ constructor(channel: TextChannel | NewsChannel | DMChannel, options: String | GPayloadOptions)
+
+ public channel: TextChannel | NewsChannel | DMChannel;
+ public options: GPayloadOptions;
+ public data: GPayloadOptions;
+ public files: GPayloadFiles;
+
+ public create(channel: TextChannel | NewsChannel | DMChannel, options: String | GPayloadOptions): GPayload;
+ public resolveData(): GPayload;
+ public resolveFiles(): GPayload;
+ }
+
interface GEvents {
debug: [string];
log: [string];
@@ -292,14 +340,28 @@ declare module 'gcommands' {
language: GuildLanguageTypes;
unkownCommandMessage?: boolean;
slash: {
- slash: string | boolean;
- prefix: string;
- }
+ slash: string | boolean;
+ prefix?: string;
+ },
+ caseSensitiveCommands?: boolean;
+ caseSensitivePrefixes?: boolean;
defaultCooldown?: string;
database?: string;
}
- interface RespondOptions {
+ interface CommandRunOptions {
+ client: Client;
+ interaction: Object;
+ member: GuildMember;
+ message: Message;
+ guild: Guild;
+ channel: TextChannel | NewsChannel;
+
+ respond(options: string | GPayloadOptions): void;
+ edit(options: string | GPayloadOptions): void;
+ }
+
+ interface GPayloadOptions {
content: [string | MessageEmbed];
embeds?: [MessageEmbed];
components?: [MessageActionRow];
@@ -308,6 +370,11 @@ declare module 'gcommands' {
allowedMentions?: [object];
}
+ interface GPayloadFiles {
+ files?: [MessageAttachment | MessageAttachment[]];
+ attachments?: [MessageAttachment | MessageAttachment[]];
+ }
+
interface MessageEditAndUpdateOptions {
content: string,
embeds?: MessageEmbed,
@@ -316,4 +383,25 @@ declare module 'gcommands' {
attachments?: MessageAttachment | MessageAttachment[],
allowedMentions?: object
}
+
+ interface CommandOptions {
+ name: string;
+ description: string;
+ cooldown?: string;
+ expectedArgs?: string;
+ minArgs?: number;
+ userRequiredPermissions?: Array | String;
+ userRequiredRoles?: Array | String;
+ clientRequiredPermissions?: Array | String;
+ userOnly?: Array | Snowflake;
+ channelOnly?: Array | Snowflake;
+ guildOnly?: Array | Snowflake;
+ nsfw?: boolean;
+ aliases?: Array;
+ }
+
+ interface EventOptions {
+ name: string;
+ once: boolean;
+ }
}
\ No newline at end of file