diff --git a/.eslintrc.json b/.eslintrc.json index 6ab0201..672f44a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,15 +1,16 @@ { "env": { + "commonjs": true, "es6": true, "node": true }, "extends": "eslint:recommended", + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, "parserOptions": { - "sourceType": "module", - "ecmaVersion": 2018, - "ecmaFeatures": { - "experimentalObjectRestSpread": true - } + "ecmaVersion": 2018 }, "rules": { "indent": [ @@ -21,7 +22,7 @@ "unix" ], "semi": [ - "warn", + "error", "always" ] } diff --git a/Manager.js b/Manager.js index 5c5f206..c0257b4 100644 --- a/Manager.js +++ b/Manager.js @@ -2,9 +2,7 @@ const { EventEmitter } = require('events'); const ShardManager = require('./middleware/ShardManager.js'); const StorageManager = require('./storage/StorageManager.js'); -const Logger = require('./Logger.js'); - -const { Command, Setting, Inhibitor } = require('./structure/interfaces/'); +const Logger = require('./middleware/logger/Logger.js'); class Manager extends EventEmitter { diff --git a/logs/what.log b/logs/what.log new file mode 100644 index 0000000..b5ae471 --- /dev/null +++ b/logs/what.log @@ -0,0 +1,37 @@ +info: Why tf isnt this working... +info: Component module:utility was loaded. +info: Component command:ping was loaded. +info: Component observer:commandHandler was loaded. +info: Client connected to asfasf#1551 with undefined guilds. +info: Why tf isnt this working... +error: THERES A FUCKIN ERROR +info: Component module:utility was loaded. +info: Component command:ping was loaded. +info: Component observer:commandHandler was loaded. +info: Client connected to asfasf#1551 with undefined guilds. +info: Why tf isnt this working... +error: THERES A FUCKIN ERROR +info: Why tf isnt this working... +error: THERES A FUCKIN ERROR +info: [04-12-2020 08:38:18][shard-00] Component module:utility was loaded. +info: [04-12-2020 08:38:18][shard-00] Component command:ping was loaded. +info: [04-12-2020 08:38:18][shard-00] Component observer:commandHandler was loaded. +info: [04-12-2020 08:38:18][shard-00] Client connected to asfasf#1551 with undefined guilds. +info: Why tf isnt this working... +error: THERES A FUCKIN ERROR +info: [04-12-2020 08:39:00][shard-00] Component module:utility was loaded. +info: [04-12-2020 08:39:00][shard-00] Component command:ping was loaded. +info: [04-12-2020 08:39:00][shard-00] Component observer:commandHandler was loaded. +info: [04-12-2020 08:39:00][shard-00] Client connected to asfasf#1551 with undefined guilds. +info: Why tf isnt this working... +error: THERES A FUCKIN ERROR +info: [04-12-2020 08:39:24][shard-00] Component module:utility was loaded. +info: [04-12-2020 08:39:24][shard-00] Component command:ping was loaded. +info: [04-12-2020 08:39:24][shard-00] Component observer:commandHandler was loaded. +info: [04-12-2020 08:39:24][shard-00] Client connected to asfasf#1551 with undefined guilds. +info: Why tf isnt this working... +error: THERES A FUCKIN ERROR +info: [04-12-2020 08:41:07][shard-00] Component module:utility was loaded. +info: [04-12-2020 08:41:07][shard-00] Component command:ping was loaded. +info: [04-12-2020 08:41:07][shard-00] Component observer:commandHandler was loaded. +info: [04-12-2020 08:41:07][shard-00] Client connected to asfasf#1551 with undefined guilds. diff --git a/Logger.js b/middleware/logger/Logger.js similarity index 52% rename from Logger.js rename to middleware/logger/Logger.js index 990de5b..cbedac7 100644 --- a/Logger.js +++ b/middleware/logger/Logger.js @@ -3,23 +3,37 @@ const { combine, label, printf } = format; const moment = require('moment'); const chalk = require('chalk'); +const { DiscordWebhook } = require('./transports/'); + +const regex = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g //removes chalk formatting, will be used for the log FILES. + class Logger { constructor(manager) { this.manager = manager; + this.shardManager = manager.shardManager; + this.logger = createLogger({ + format: ( + format.simple() + ), transports: [ new transports.Console(), - new transports.File({ filename: `logs/${this.date.replace(/ /g, '-')}.log` }), - new transports.File({ filename: `logs/${this.date.replace(/ /g, '-')}-error.log`, level: 'error' }) + new transports.File({ filename: `logs/what.log` }), + new transports.File({ filename: `logs/${this.date.replace(/ /g, '-')}-error.log`, level: 'error' }), + new DiscordWebhook({ level: 'error' }) //Broadcast errors to a discord webhook. ] }); - this.client - .on('shardCreate', (shard) => this.write(shard, "Shard created.", 'DEBUG')) + this.shardManager + .on('shardCreate', (shard) => this.write(shard, "Shard created.", 'debug')) .on('message', (shard, message) => this._handleMessage(shard, message)); + console.log("FUCK"); + this.logger.log('info', "Why tf isnt this working..."); + this.logger.log('error', "THERES A FUCKIN ERROR"); + } //Messages coming from the shards process.send functions. @@ -31,7 +45,7 @@ class Logger { || message._sEval || message._sRespawnAll) return undefined; //Properties used for discord.js internal sharding, must filter for. - + await this.write(shard, message.message, message.type); } @@ -39,10 +53,11 @@ class Logger { async write(shard, string = '', type = 'silly') { if(!config.npm.levels[type]) return undefined; - const header = `[${this.date}][shard-${this._shardId(shard)}]`; + const color = Constants.Colors[type]; + const header = `${chalk[color](`[${this.date}][shard-${this._shardId(shard)}]`)}`; //[04/02/2020 12:52:20][shard-00] - this.logger.log(type, string) + this.logger.log(type, `${header} ${string}`) } @@ -57,4 +72,26 @@ class Logger { } -module.exports = Logger; \ No newline at end of file +module.exports = Logger; + +const Constants = { + Colors: { + error: 'red', + warn: 'yellow', + info: 'blue', + verbose: 'cyan', + debug: 'magenta', + silly: 'magentaBright' + } +}; + +/* +const levels = { + error: 0, + warn: 1, + info: 2, + http: 3, + verbose: 4, + debug: 5, + silly: 6 +};*/ \ No newline at end of file diff --git a/middleware/logger/transports/DiscordWebhook.js b/middleware/logger/transports/DiscordWebhook.js new file mode 100644 index 0000000..08a51d2 --- /dev/null +++ b/middleware/logger/transports/DiscordWebhook.js @@ -0,0 +1,24 @@ +const Transport = require('winston-transport'); + +class DiscordWebhook extends Transport { + constructor(opts) { + super(opts); + // + // Consume any custom options here. e.g.: + // - Connection information for databases + // - Authentication information for APIs (e.g. loggly, papertrail, + // logentries, etc.). + // + } + + log(info, callback) { + setImmediate(() => { + this.emit('logged', info); + }); + + // Perform the writing to the remote service + callback(); + } +}; + +module.exports = DiscordWebhook; \ No newline at end of file diff --git a/middleware/logger/transports/index.js b/middleware/logger/transports/index.js new file mode 100644 index 0000000..d1bb9a6 --- /dev/null +++ b/middleware/logger/transports/index.js @@ -0,0 +1,3 @@ +module.exports = { + DiscordWebhook: require('./DiscordWebhook.js') +} \ No newline at end of file diff --git a/package.json b/package.json index 821996b..b475cc1 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "mongodb": "^3.5.5", "mysql": "^2.18.1", "node-fetch": "^2.6.0", - "winston": "^3.2.1" + "winston": "^3.2.1", + "winston-transport": "^4.3.0" } } diff --git a/structure/client/DiscordClient.js b/structure/client/DiscordClient.js index 4070f4c..8a99de0 100644 --- a/structure/client/DiscordClient.js +++ b/structure/client/DiscordClient.js @@ -6,7 +6,7 @@ const Registry = require('./Registry.js') const EventHooker = require('./EventHooker.js'); const Dispatcher = require('./Dispatcher.js') const Resolver = require('./Resolver.js'); -const Transporter = require('./Transporter.js'); +const Logger = require('./Logger.js'); const { Guild, User, Message } = require('../../structure/extensions/'); const { Command, Observer, Inhibitor, Setting } = require('../../structure/interfaces/'); @@ -21,7 +21,7 @@ class DiscordClient extends Client { this.eventHooker = new EventHooker(this); this.dispatcher = new Dispatcher(this); this.resolver = new Resolver(this); - this.transporter = new Transporter(this); + this.logger = new Logger(this); this._options = options; this._built = false; @@ -47,10 +47,6 @@ class DiscordClient extends Client { console.log('Client websocket is ready.'); }); - this.registry.on('componentUpdate', (comp, type) => { - console.log(`[registry][${type}] ${comp.resolveable}`) - }); - console.log('Client built'); } diff --git a/structure/client/Logger.js b/structure/client/Logger.js index 0c67f41..d1fca62 100644 --- a/structure/client/Logger.js +++ b/structure/client/Logger.js @@ -6,16 +6,16 @@ class Logger { this.client = client; - this.client.hooker.hook('ready', () => { - this.transport(`Client connected to ${chalk.bold(this.client.user.tag)} with ${chalk.bold(`${this.client.guilds.size} guild${this.client.guilds.size === 1 ? '' : 's'}`)}.`, { embed: true, type: 'SUCCESS' }); + this.client.eventHooker.hook('ready', () => { + this.info(`Client connected to ${chalk.bold(this.client.user.tag)} with ${chalk.bold(`${this.client.guilds.size} guild${this.client.guilds.size === 1 ? '' : 's'}`)}.`); }); - this.client.hooker.hook('componentUpdate', ({ component, type }) => { + this.client.eventHooker.hook('componentUpdate', ({ component, type }) => { this.info(`Component ${chalk.bold(component.resolveable)} was ${chalk.bold(Constants.ComponentTypes[type])}.`); }); - this.client.hooker.hook('reconnect', () => { - this.warn(`Shard is reconnecting.`, { embed: true }); + this.client.eventHooker.hook('reconnect', () => { + this.warn(`Shard is reconnecting.`); }); } @@ -26,24 +26,28 @@ class Logger { /* Quick & Dirty Functions */ - log(message, opts = {}) { - this.transport(message, { ...opts, type: 'LOG' }); - } - - info(message, opts = {}) { - this.transport(message, { ...opts, type: 'INFO' }); - } - - warn(message, opts = {}) { - this.transport(message, { ...opts, type: 'WARN' }); + silly(message, opts = {}) { + this.transport(message, { ...opts, type: 'silly' }); } debug(message, opts = {}) { - this.transport(message, { ...opts, type: 'DEBUG' }); + this.transport(message, { ...opts, type: 'debug' }); + } + + verbose(message, opts = {}) { + this.transport(message, { ...opts, type: 'verbose' }); + } + + info(message, opts = {}) { + this.transport(message, { ...opts, type: 'info' }); + } + + warn(message, opts = {}) { + this.transport(message, { ...opts, type: 'warn' }); } error(message, opts = {}) { - this.transport(message, { ...opts, type: 'ERROR' }); + this.transport(message, { ...opts, type: 'error' }); } diff --git a/structure/client/Registry.js b/structure/client/Registry.js index a86e3db..4fe713c 100644 --- a/structure/client/Registry.js +++ b/structure/client/Registry.js @@ -1,16 +1,13 @@ const path = require('path'); -const { EventEmitter } = require('events'); const { Collection, Util } = require('../../util/'); const { Component, Module } = require('../../structure/interfaces'); -class Registry extends EventEmitter { +class Registry { constructor(client) { - super(); - this.client = client; this.components = new Collection(); @@ -67,7 +64,7 @@ class Registry extends EventEmitter { } this.components.set(component.resolveable, component); - this.emit('componentUpdate', { component, type: 'LOAD' }); + this.client.emit('componentUpdate', { component, type: 'LOAD' }); return component; } diff --git a/structure/client/components/commands/utility/Ping.js b/structure/client/components/commands/utility/Ping.js index fdf1039..e95436c 100644 --- a/structure/client/components/commands/utility/Ping.js +++ b/structure/client/components/commands/utility/Ping.js @@ -12,7 +12,8 @@ class PingCommand extends Command { new Argument(client, { name: 'apple', type: 'BOOLEAN', - types: ['VERBAL'] + types: ['VERBAL', 'FLAG'], + default: true }), new Argument(client, { name: 'banana', diff --git a/structure/interfaces/Component.js b/structure/interfaces/Component.js index f336305..f4c2bb8 100644 --- a/structure/interfaces/Component.js +++ b/structure/interfaces/Component.js @@ -20,14 +20,14 @@ class Component { enable() { if(this.guarded) return { error: true, code: 'GUARDED' }; this.disabled = false; - this.registry.emit('componentUpdate', { component: this, type: 'ENABLE' }); + this.client.emit('componentUpdate', { component: this, type: 'ENABLE' }); return { error: false }; } disable() { if(this.guarded) return { error: true, code: 'GUARDED' }; this.disabled = true; - this.registry.emit('componentUpdate', { component: this, type: 'DISABLE' }); + this.client.emit('componentUpdate', { component: this, type: 'DISABLE' }); return { error: false }; } @@ -38,7 +38,7 @@ class Component { this.registry.unloadComponent(this); delete require.cache[this.filePath]; - this.registry.emit('componentUpdate', { component: this, type: 'UNLOAD' }); + this.client.emit('componentUpdate', { component: this, type: 'UNLOAD' }); return { error: false }; } @@ -59,7 +59,7 @@ class Component { } this.registry.unloadComponent(this); - this.registry.emit('componentUpdate', { component: this, type: 'UNLOAD' }); + this.client.emit('componentUpdate', { component: this, type: 'UNLOAD' }); this.registry.loadComponent(newModule, this.directory); } catch(error) { if(cached) require.cache[this.directory] = cached;