diff --git a/src/events.js b/src/events.js index 564171b..c00da4c 100644 --- a/src/events.js +++ b/src/events.js @@ -1,29 +1,36 @@ import {Logger} from './logger'; import {Config} from './config'; -import { resolve } from 'path'; -import { rejects } from 'assert'; +import {RateLimits} from './ratelimits' + +export class Events extends RateLimits { // extends rate limits + constructor() { + super() + } -export class Events { // extends rate limits async init(client) { this.client = client; this.client.login(Config.Token); } + get Client() {return this.client;} + async handleEvents() { this.client.on('ready', async () => { this.handle(undefined, - [this.handleReady] + [this.handleReady], + this.client ); }); this.client.on('message', async (message) => { this.handle(message, - [this.handleMessage] + [super.request, this.handleMessage], + this.client ); }); } - async handle(obj = [null], callbacks = [undefined]) { + async handle(obj = [null], callbacks = [undefined], client) { let doNext = false; if (callbacks.length == 0) { return; @@ -33,29 +40,25 @@ export class Events { // extends rate limits doNext = true; } - await callbacks[0](obj, next); + await callbacks[0](obj, client, next); callbacks.splice(0, 1); if (doNext) { - this.handle(obj, callbacks); + this.handle(obj, callbacks, client); } } - async handleReady(obj, next) { - this.client.user.setPresence('online'); - this.client.user.setActivity(Config.NowPlaying); - Logger.info(`Discord client logged in as ${this.client.user.tag}`); + async handleReady(obj, client, next) { + client.user.setPresence('online'); + client.user.setActivity(Config.NowPlaying); + Logger.info(`Discord client logged in as ${client.user.tag}`); Logger.ready(); - - await new Promise((resolve, reject) => { - setTimeout(resolve, 1000); - }); - next(); } - async handleMessage(...args) { - Logger.info(args[0]); - args[0].channel.send('lol u homo') + async handleMessage(obj, client, next) { + if (client.user.id == obj.author.id) return; + if (obj.limiting) obj.channel.send(`${obj.author} You are being rate limited`); + next(); } } diff --git a/src/logger.js b/src/logger.js index ac6b62f..4691f83 100644 --- a/src/logger.js +++ b/src/logger.js @@ -56,9 +56,9 @@ export class Logger { static middleware(message) { if (LogLevel > 0) return; let d = moment().format(dateFormat); - fs.appendFileSync(logPath, `[${d.toLocaleString()}] [HTTP-MIDDLEWARE] ${message} \n`); + fs.appendFileSync(logPath, `[${d.toLocaleString()}] [MIDDLEWARE] ${message} \n`); console.log('[' + d.toLocaleString() + '] [' - + colours.blue('HTTP-MIDDLEWARE') + '] ' + message); + + colours.blue('MIDDLEWARE') + '] ' + message); } static debug(message) { diff --git a/src/ratelimits.js b/src/ratelimits.js index e69de29..505e10b 100644 --- a/src/ratelimits.js +++ b/src/ratelimits.js @@ -0,0 +1,50 @@ +import {Logger} from './logger'; + +let buckets = { }; + +export class RateLimits { + constructor() { + Logger.info('Initialized ratelimiting middleware'); + this.requestsPerSecond = 1; + setInterval(this.tick, 1000 / this.requestsPerSecond); + } + + async request(obj, client, next) { + let id = obj.author.id; + + if (!buckets[id]) { + Logger.debug(`New rate limiting bucket`); + + buckets[id] = {id: id, tokens: [], lastUsed: new Date().getTime()}; + for (let i = 0; i < this.requestsPerSecond; i++) { + buckets[id].tokens.push(1); + } + + next(); + return; + } + + buckets[id].lastUsed = new Date().getTime(); + + if (buckets[id].tokens.length <= 0) { + Logger.middleware(`${id} is being rate limited`); + obj.limiting = true; + next(); + return; + } + + buckets[id].tokens.pop(); + next(); + } + + tick() { + for (let bucket in buckets) { + // if (buckets[bucket].lastUsed += disposeTime >= new Date().getTime()) { + // delete buckets[bucket]; // remove element here, don't redefine + // continue; + // } + if (buckets[bucket].tokens.length > this.requestsPerSecond) continue; + buckets[bucket].tokens.push(1); + } + } +}