Merge branch 'dev'

pull/29/head
Matthew 2020-07-21 04:18:49 -04:00
commit da18fb2481
No known key found for this signature in database
GPG Key ID: 210AF32ADE3B5C4B
9 changed files with 79 additions and 3 deletions

View File

@ -2,7 +2,7 @@ import eris from 'eris';
import mongoose from 'mongoose'; import mongoose from 'mongoose';
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
import { Collection, Command, LocalStorage, Util, ServerManagement, Event } from '.'; import { Collection, Command, LocalStorage, Util, ServerManagement, Event } from '.';
import { File, FileInterface, Member, MemberInterface, Moderation, ModerationInterface, PagerNumber, PagerNumberInterface, Rank, RankInterface, Redirect, RedirectInterface } from '../models'; import { File, FileInterface, Member, MemberInterface, Moderation, ModerationInterface, PagerNumber, PagerNumberInterface, Rank, RankInterface, Redirect, RedirectInterface, Stat, StatInterface } from '../models';
import { Config } from '../../types'; // eslint-disable-line import { Config } from '../../types'; // eslint-disable-line
export default class Client extends eris.Client { export default class Client extends eris.Client {
@ -18,18 +18,36 @@ export default class Client extends eris.Client {
public serverManagement: ServerManagement; public serverManagement: ServerManagement;
public db: { File: mongoose.Model<FileInterface>, Member: mongoose.Model<MemberInterface>, Moderation: mongoose.Model<ModerationInterface>, PagerNumber: mongoose.Model<PagerNumberInterface>, Rank: mongoose.Model<RankInterface>, Redirect: mongoose.Model<RedirectInterface>, local: { muted: LocalStorage } }; public db: { File: mongoose.Model<FileInterface>, Member: mongoose.Model<MemberInterface>, Moderation: mongoose.Model<ModerationInterface>, PagerNumber: mongoose.Model<PagerNumberInterface>, Rank: mongoose.Model<RankInterface>, Redirect: mongoose.Model<RedirectInterface>, Stat: mongoose.Model<StatInterface>, local: { muted: LocalStorage } };
constructor(token: string, options?: eris.ClientOptions) { constructor(token: string, options?: eris.ClientOptions) {
super(token, options); super(token, options);
this.commands = new Collection<Command>(); this.commands = new Collection<Command>();
this.events = new Collection<Event>(); this.events = new Collection<Event>();
this.intervals = new Collection<NodeJS.Timeout>(); this.intervals = new Collection<NodeJS.Timeout>();
this.db = { File, Member, Moderation, PagerNumber, Rank, Redirect, local: { muted: new LocalStorage('muted') } }; this.db = { File, Member, Moderation, PagerNumber, Rank, Redirect, Stat, local: { muted: new LocalStorage('muted') } };
} }
public async loadDatabase() { public async loadDatabase() {
await mongoose.connect(this.config.mongoDB, { useNewUrlParser: true, useUnifiedTopology: true, poolSize: 50 }); await mongoose.connect(this.config.mongoDB, { useNewUrlParser: true, useUnifiedTopology: true, poolSize: 50 });
const statMessages = await this.db.Stat.findOne({ name: 'messages' });
const statCommands = await this.db.Stat.findOne({ name: 'commands' });
const statPages = await this.db.Stat.findOne({ name: 'pages' });
const statRequests = await this.db.Stat.findOne({ name: 'requests' });
if (!statMessages) {
await (new this.db.Stat({ name: 'messages', value: 0 }).save());
}
if (!statCommands) {
await (new this.db.Stat({ name: 'commands', value: 0 }).save());
}
if (!statPages) {
await (new this.db.Stat({ name: 'pages', value: 0 }).save());
}
if (!statRequests) {
await (new this.db.Stat({ name: 'requests', value: 0 }).save());
}
} }
public loadPlugins() { public loadPlugins() {

View File

@ -20,6 +20,7 @@ export default class Route {
public init() { public init() {
this.router.all('*', (req, res, next) => { this.router.all('*', (req, res, next) => {
this.server.client.util.signale.log(`'${req.method}' request from '${req.ip}' to '${req.hostname}${req.path}'.`); this.server.client.util.signale.log(`'${req.method}' request from '${req.ip}' to '${req.hostname}${req.path}'.`);
this.server.client.db.Stat.updateOne({ name: 'requests' }, { $inc: { value: 1 } }).exec();
if (this.conf.maintenance === true) res.status(503).json({ code: this.constants.codes.MAINTENANCE_OR_UNAVAILABLE, message: this.constants.messages.MAINTENANCE_OR_UNAVAILABLE }); if (this.conf.maintenance === true) res.status(503).json({ code: this.constants.codes.MAINTENANCE_OR_UNAVAILABLE, message: this.constants.messages.MAINTENANCE_OR_UNAVAILABLE });
else if (this.conf.deprecated === true) res.status(501).json({ code: this.constants.codes.DEPRECATED, message: this.constants.messages.DEPRECATED }); else if (this.conf.deprecated === true) res.status(501).json({ code: this.constants.codes.DEPRECATED, message: this.constants.messages.DEPRECATED });
else next(); else next();

View File

@ -19,6 +19,7 @@ export { default as page } from './page';
export { default as ping } from './ping'; export { default as ping } from './ping';
export { default as rank } from './rank'; export { default as rank } from './rank';
export { default as roleinfo } from './roleinfo'; export { default as roleinfo } from './roleinfo';
export { default as stats } from './stats';
export { default as storemessages } from './storemessages'; export { default as storemessages } from './storemessages';
export { default as unban } from './unban'; export { default as unban } from './unban';
export { default as unmute } from './unmute'; export { default as unmute } from './unmute';

View File

@ -4,6 +4,7 @@ import { Client, Command, RichEmbed } from '../class';
import { version as erisVersion } from '../../node_modules/eris/package.json'; import { version as erisVersion } from '../../node_modules/eris/package.json';
import { version as expressVersion } from '../../node_modules/express/package.json'; import { version as expressVersion } from '../../node_modules/express/package.json';
import { version as mongooseVersion } from '../../node_modules/mongoose/package.json'; import { version as mongooseVersion } from '../../node_modules/mongoose/package.json';
import { version as tsVersion } from '../../node_modules/typescript/package.json';
export default class Info extends Command { export default class Info extends Command {
constructor(client: Client) { constructor(client: Client) {
@ -21,6 +22,8 @@ export default class Info extends Command {
embed.setTitle('Information'); embed.setTitle('Information');
embed.setThumbnail(this.client.user.avatarURL); embed.setThumbnail(this.client.user.avatarURL);
embed.addField('Language(s)', '<:TypeScript:703451285789343774> TypeScript', true); embed.addField('Language(s)', '<:TypeScript:703451285789343774> TypeScript', true);
embed.addField('Runtime', `Node (${process.version})`, true);
embed.addField('Compilers/Transpilers', `TypeScript [tsc] (${tsVersion})`, true);
embed.addField('Discord Library', `Eris (${erisVersion})`, true); embed.addField('Discord Library', `Eris (${erisVersion})`, true);
embed.addField('HTTP Server Library', `Express (${expressVersion})`, true); embed.addField('HTTP Server Library', `Express (${expressVersion})`, true);
embed.addField('Database Library', `MongoDB w/ Mongoose ODM (${mongooseVersion})`, true); embed.addField('Database Library', `MongoDB w/ Mongoose ODM (${mongooseVersion})`, true);

View File

@ -146,6 +146,7 @@ export default class Page extends Command {
html: `<h1>Page</h1>${options?.emergencyNumber ? `<h2>[SEN#${options.emergencyNumber}]` : ''}<strong>Recipient PN:</strong> ${recipientNumber}<br><strong>Sender PN:</strong> ${senderNumber} (${sender ? `${sender.username}#${sender.discriminator}` : ''})<br><strong>Initial Command:</strong> https://discordapp.com/channels/${message.guild.id}/${message.channel.id}/${message.id} (<#${message.channel.id}>)<br><br><strong>Pager Code:</strong> ${code} (${this.local.codeDict.get(code)})${txt ? `<br><strong>Message:</strong> ${txt}` : ''}`, html: `<h1>Page</h1>${options?.emergencyNumber ? `<h2>[SEN#${options.emergencyNumber}]` : ''}<strong>Recipient PN:</strong> ${recipientNumber}<br><strong>Sender PN:</strong> ${senderNumber} (${sender ? `${sender.username}#${sender.discriminator}` : ''})<br><strong>Initial Command:</strong> https://discordapp.com/channels/${message.guild.id}/${message.channel.id}/${message.id} (<#${message.channel.id}>)<br><br><strong>Pager Code:</strong> ${code} (${this.local.codeDict.get(code)})${txt ? `<br><strong>Message:</strong> ${txt}` : ''}`,
}); });
} }
this.client.db.Stat.updateOne({ name: 'pages' }, { $inc: { value: 1 } }).exec();
return { status: true, message: `Page to \`${recipientNumber}\` sent.` }; return { status: true, message: `Page to \`${recipientNumber}\` sent.` };
} catch (err) { } catch (err) {
this.client.util.signale.error(err); this.client.util.signale.error(err);

36
src/commands/stats.ts Normal file
View File

@ -0,0 +1,36 @@
import { Message } from 'eris';
import { Client, Command, RichEmbed } from '../class';
export default class Stats extends Command {
constructor(client: Client) {
super(client);
this.name = 'stats';
this.description = 'Provides system statistics.';
this.usage = `${this.client.config.prefix}stats`;
this.permissions = 0;
this.guildOnly = false;
this.enabled = true;
}
public async run(message: Message) {
try {
const messages = await this.client.db.Stat.findOne({ name: 'messages' });
const commands = await this.client.db.Stat.findOne({ name: 'commands' });
const pages = await this.client.db.Stat.findOne({ name: 'pages' });
const requests = await this.client.db.Stat.findOne({ name: 'requests' });
const embed = new RichEmbed();
embed.setTitle('Statistics');
embed.setThumbnail(this.client.user.avatarURL);
embed.addField('Messages Seen', `${messages.value}`, true);
embed.addField('Commands Executed', `${commands.value}`, true);
embed.addField('HTTP Requests Served', `${requests.value}`, true);
embed.addField('Pages Sent', `${pages.value}`, true);
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
embed.setTimestamp();
return message.channel.createMessage({ embed });
} catch (err) {
return this.client.util.handleError(err, message, this);
}
}
}

View File

@ -12,6 +12,7 @@ export default class CommandHandler extends Event {
public async run(message: Message) { public async run(message: Message) {
try { try {
this.client.db.Stat.updateOne({ name: 'messages' }, { $inc: { value: 1 } }).exec();
if (message.author.bot) return; if (message.author.bot) return;
if (message.content.indexOf(this.client.config.prefix) !== 0) return; if (message.content.indexOf(this.client.config.prefix) !== 0) return;
const noPrefix: string[] = message.content.slice(this.client.config.prefix.length).trim().split(/ +/g); const noPrefix: string[] = message.content.slice(this.client.config.prefix.length).trim().split(/ +/g);
@ -25,6 +26,7 @@ export default class CommandHandler extends Event {
} }
this.client.util.signale.log(`User '${message.author.username}#${message.author.discriminator}' ran command '${resolved.cmd.name}' in '${message.channel.id}'.`); this.client.util.signale.log(`User '${message.author.username}#${message.author.discriminator}' ran command '${resolved.cmd.name}' in '${message.channel.id}'.`);
await resolved.cmd.run(message, resolved.args); await resolved.cmd.run(message, resolved.args);
this.client.db.Stat.updateOne({ name: 'commands' }, { $inc: { value: 1 } }).exec();
} catch (err) { } catch (err) {
this.client.util.handleError(err, message); this.client.util.handleError(err, message);
} }

13
src/models/Stat.ts Normal file
View File

@ -0,0 +1,13 @@
import { Document, Schema, model } from 'mongoose';
export interface StatInterface extends Document {
name: 'messages' | 'commands' | 'pages' | 'requests',
value: number,
}
const Stat: Schema = new Schema({
name: String,
value: Number,
});
export default model<StatInterface>('Stat', Stat);

View File

@ -4,3 +4,4 @@ export { default as Moderation, ModerationInterface } from './Moderation';
export { default as PagerNumber, PagerNumberInterface, PagerNumberRaw } from './PagerNumber'; export { default as PagerNumber, PagerNumberInterface, PagerNumberRaw } from './PagerNumber';
export { default as Rank, RankInterface } from './Rank'; export { default as Rank, RankInterface } from './Rank';
export { default as Redirect, RedirectInterface, RedirectRaw } from './Redirect'; export { default as Redirect, RedirectInterface, RedirectRaw } from './Redirect';
export { default as Stat, StatInterface } from './Stat';