Merge branch 'dev'
commit
7c0c777ad3
|
@ -39,6 +39,7 @@
|
|||
"import/prefer-default-export": "off",
|
||||
"no-useless-constructor": "off",
|
||||
"@typescript-eslint/no-useless-constructor": 2,
|
||||
"import/extensions": "off"
|
||||
"import/extensions": "off",
|
||||
"no-param-reassign": "off"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
stages:
|
||||
- lint
|
||||
- build
|
||||
|
||||
lint:
|
||||
stage: lint
|
||||
script: |
|
||||
yarn install
|
||||
yarn lint
|
||||
only:
|
||||
- pushes
|
||||
- merge_requests
|
||||
- web
|
||||
|
||||
tsc:
|
||||
stage: build
|
||||
script: |
|
||||
yarn install
|
||||
tsc -p tsconfig.json -noEmit
|
||||
only:
|
||||
- pushes
|
||||
- merge_requests
|
||||
- web
|
2
Makefile
2
Makefile
|
@ -4,7 +4,7 @@ clean:
|
|||
@-rm -rf build
|
||||
|
||||
build:
|
||||
-tsc -p ./tsconfig.json
|
||||
-npx tsc -p ./tsconfig.json
|
||||
|
||||
run:
|
||||
cd build && node main
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import locsh from './loc.sh/main';
|
||||
|
||||
export default {
|
||||
'loc.sh': locsh,
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import { Server, ServerManagement } from '../../class';
|
||||
|
||||
export default function (management: ServerManagement) {
|
||||
export default (management: ServerManagement) => {
|
||||
const server = new Server(management, 3890, `${__dirname}/routes`);
|
||||
return server;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export { default as root } from './root';
|
|
@ -1,16 +1,18 @@
|
|||
import { Route, Server } from '../../../class';
|
||||
import { RedirectInterface } from '../../../models';
|
||||
import { RedirectRaw } from '../../../models';
|
||||
|
||||
export default class Root extends Route {
|
||||
constructor(server: Server) {
|
||||
super(server, { path: '/' });
|
||||
super(server);
|
||||
this.conf = {
|
||||
path: '/',
|
||||
};
|
||||
}
|
||||
|
||||
public bind() {
|
||||
this.router.get('/:key', async (req, res) => {
|
||||
try {
|
||||
// @ts-ignore
|
||||
const link: RedirectInterface = await this.server.client.db.redirect.findOne({ key: req.params.key }).lean().exec();
|
||||
const link: RedirectRaw = await this.server.client.db.Redirect.findOne({ key: req.params.key }).lean().exec();
|
||||
if (!link) return res.status(404).json({ code: this.constants.codes.NOT_FOUND, message: this.constants.messages.NOT_FOUND });
|
||||
return res.redirect(link.to);
|
||||
} catch (err) {
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import eris from 'eris';
|
||||
import mongoose from 'mongoose';
|
||||
import { promises as fs } from 'fs';
|
||||
import { Collection, Command, Util, ServerManagement } from '.';
|
||||
import { Collection, Command, Util, ServerManagement, Event } from '.';
|
||||
import { Member, MemberInterface, Moderation, ModerationInterface, Redirect, RedirectInterface } from '../models';
|
||||
|
||||
export default class Client extends eris.Client {
|
||||
|
@ -9,7 +9,7 @@ export default class Client extends eris.Client {
|
|||
|
||||
public commands: Collection<Command>;
|
||||
|
||||
public events: Collection<Function>;
|
||||
public events: Collection<Event>;
|
||||
|
||||
public intervals: Collection<NodeJS.Timeout>;
|
||||
|
||||
|
@ -17,15 +17,14 @@ export default class Client extends eris.Client {
|
|||
|
||||
public serverManagement: ServerManagement;
|
||||
|
||||
public db: { member: mongoose.Model<MemberInterface>, moderation: mongoose.Model<ModerationInterface>, redirect: mongoose.Model<RedirectInterface> };
|
||||
public db: { Member: mongoose.Model<MemberInterface>, Moderation: mongoose.Model<ModerationInterface>, Redirect: mongoose.Model<RedirectInterface> };
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
||||
constructor(token: string, options?: eris.ClientOptions) {
|
||||
super(token, options);
|
||||
this.commands = new Collection<Command>();
|
||||
this.events = new Collection<Function>();
|
||||
this.events = new Collection<Event>();
|
||||
this.intervals = new Collection<NodeJS.Timeout>();
|
||||
this.db = { member: Member, moderation: Moderation, redirect: Redirect };
|
||||
this.db = { Member, Moderation, Redirect };
|
||||
}
|
||||
|
||||
public async loadDatabase() {
|
||||
|
@ -48,27 +47,23 @@ export default class Client extends eris.Client {
|
|||
});
|
||||
}
|
||||
|
||||
public async loadEvents() {
|
||||
const evtFiles = await fs.readdir(`${__dirname}/../events`);
|
||||
evtFiles.forEach((file) => {
|
||||
const eventName = file.split('.')[0];
|
||||
if (file === 'index.js') return;
|
||||
// eslint-disable-next-line
|
||||
const event = new (require(`${__dirname}/../events/${file}`).default)(this);
|
||||
this.events.add(eventName, event);
|
||||
this.on(eventName, (...args) => event.run(...args));
|
||||
this.util.signale.success(`Successfully loaded event: ${eventName}`);
|
||||
delete require.cache[require.resolve(`${__dirname}/../events/${file}`)];
|
||||
});
|
||||
public async loadEvents(eventFiles: { [s: string]: typeof Event; } | ArrayLike<typeof Event>) {
|
||||
const evtFiles = Object.entries<typeof Event>(eventFiles);
|
||||
for (const [name, Ev] of evtFiles) {
|
||||
const event = new Ev(this);
|
||||
this.events.add(event.event, event);
|
||||
this.on(event.event, event.run);
|
||||
this.util.signale.success(`Successfully loaded event: ${name}`);
|
||||
delete require.cache[require.resolve(`${__dirname}/../events/${name}`)];
|
||||
}
|
||||
}
|
||||
|
||||
public async loadCommands() {
|
||||
const commandFiles = await fs.readdir(`${__dirname}/../commands`);
|
||||
commandFiles.forEach((file) => {
|
||||
// eslint-disable-next-line new-cap
|
||||
const command: Command = new (require(`${__dirname}/../commands/${file}`).default)(this);
|
||||
public async loadCommands(commandFiles: { [s: string]: typeof Command; } | ArrayLike<typeof Command>) {
|
||||
const cmdFiles = Object.values<typeof Command>(commandFiles);
|
||||
for (const Cmd of cmdFiles) {
|
||||
const command = new Cmd(this);
|
||||
this.commands.add(command.name, command);
|
||||
this.util.signale.success(`Successfully loaded command: ${command.name}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import { Client } from '.';
|
||||
|
||||
export default class Event {
|
||||
public client: Client
|
||||
|
||||
public event: string;
|
||||
|
||||
constructor(client: Client) {
|
||||
this.client = client;
|
||||
this.event = '';
|
||||
this.run = this.run.bind(this);
|
||||
}
|
||||
|
||||
public async run(...args: any[]): Promise<void> { return Promise.resolve(); }
|
||||
}
|
|
@ -111,7 +111,7 @@ export default class Moderation {
|
|||
return mod.save();
|
||||
}
|
||||
|
||||
public async kick(user: User, moderator: Member, reason?: string): Promise<ModerationInterface> {
|
||||
public async kick(user: Member|User, moderator: Member, reason?: string): Promise<ModerationInterface> {
|
||||
if (reason && reason.length > 512) throw new Error('Kick reason cannot be longer than 512 characters');
|
||||
await this.client.guilds.get(this.client.config.guildID).kickMember(user.id, reason);
|
||||
const logID = randomBytes(2).toString('hex');
|
||||
|
|
|
@ -1,20 +1,8 @@
|
|||
/* eslint-disable no-param-reassign */
|
||||
|
||||
export interface EmbedData {
|
||||
title?: string
|
||||
description?: string
|
||||
url?: string
|
||||
timestamp?: Date
|
||||
color?: number
|
||||
footer?: { text: string, icon_url?: string, proxy_icon_url?: string}
|
||||
image?: { url: string, proxy_url?: string, height?: number, width?: number }
|
||||
thumbnail?: { url: string, proxy_url?: string, height?: number, width?: number }
|
||||
video?: { url: string, height?: number, width?: number }
|
||||
author?: { name: string, url?: string, proxy_icon_url?: string, icon_url?: string}
|
||||
fields?: {name: string, value: string, inline?: boolean}[]
|
||||
}
|
||||
import { EmbedOptions } from 'eris';
|
||||
|
||||
export default class RichEmbed implements EmbedData {
|
||||
export default class RichEmbed implements EmbedOptions {
|
||||
title?: string
|
||||
|
||||
type?: string
|
||||
|
@ -23,15 +11,15 @@ export default class RichEmbed implements EmbedData {
|
|||
|
||||
url?: string
|
||||
|
||||
timestamp?: Date
|
||||
timestamp?: string | Date
|
||||
|
||||
color?: number
|
||||
|
||||
footer?: { text: string, icon_url?: string, proxy_icon_url?: string}
|
||||
|
||||
image?: { url: string, proxy_url?: string, height?: number, width?: number }
|
||||
image?: { url?: string, proxy_url?: string, height?: number, width?: number }
|
||||
|
||||
thumbnail?: { url: string, proxy_url?: string, height?: number, width?: number }
|
||||
thumbnail?: { url?: string, proxy_url?: string, height?: number, width?: number }
|
||||
|
||||
video?: { url: string, height?: number, width?: number }
|
||||
|
||||
|
@ -41,7 +29,7 @@ export default class RichEmbed implements EmbedData {
|
|||
|
||||
fields?: {name: string, value: string, inline?: boolean}[]
|
||||
|
||||
constructor(data: EmbedData = {}) {
|
||||
constructor(data: EmbedOptions = {}) {
|
||||
/*
|
||||
let types: {
|
||||
title?: string, type?: string, description?: string, url?: string, timestamp?: Date, color?: number, fields?: {name: string, value: string, inline?: boolean}[]
|
||||
|
@ -124,8 +112,7 @@ export default class RichEmbed implements EmbedData {
|
|||
* Sets the timestamp of this embed.
|
||||
*/
|
||||
setTimestamp(timestamp = new Date()) {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
if (isNaN(timestamp.getTime())) throw new TypeError('Expecting ISO8601 (Date constructor)');
|
||||
if (Number.isNaN(timestamp.getTime())) throw new TypeError('Expecting ISO8601 (Date constructor)');
|
||||
this.timestamp = timestamp;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,9 @@ export default class Route {
|
|||
|
||||
public router: Router;
|
||||
|
||||
constructor(server: Server, options: { path: string, deprecated?: boolean, maintenance?: boolean }) {
|
||||
constructor(server: Server) {
|
||||
this.server = server;
|
||||
this.conf = options;
|
||||
this.conf = { path: '' };
|
||||
this.router = Router();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,10 +31,9 @@ export default class Server {
|
|||
}
|
||||
|
||||
public async loadRoutes() {
|
||||
const routes = await fs.readdir(`${this.root}`);
|
||||
for (const routeFile of routes) {
|
||||
// eslint-disable-next-line new-cap
|
||||
const route: Route = new (require(`${this.root}/${routeFile}`).default)(this);
|
||||
const routes = Object.values<typeof Route>(require(this.root));
|
||||
for (const RouteFile of routes) {
|
||||
const route = new RouteFile(this);
|
||||
if (route.conf.deprecated) {
|
||||
route.deprecated();
|
||||
} else if (route.conf.maintenance) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import express from 'express';
|
||||
import { promises as fs } from 'fs';
|
||||
import { Client, Collection, Server } from '.';
|
||||
// import serverSetup from '../api/server';
|
||||
import serverSetup from '../api';
|
||||
|
||||
export default class ServerManagement {
|
||||
public client: Client;
|
||||
|
@ -15,12 +13,9 @@ export default class ServerManagement {
|
|||
}
|
||||
|
||||
public async loadServers() {
|
||||
const apiRoot = await fs.readdir(`${__dirname}/../api`);
|
||||
for (const api of apiRoot) {
|
||||
// eslint-disable-next-line no-continue
|
||||
if (api === 'server.js') continue;
|
||||
const server: Server = require(`${__dirname}/../api/${api}/main.js`).default(this);
|
||||
this.servers.add(api, server);
|
||||
const apiRoot = Object.entries<(management: ServerManagement) => Server>(serverSetup);
|
||||
for (const [api, server] of apiRoot) {
|
||||
this.servers.add(api, server(this));
|
||||
this.client.util.signale.success(`Successfully loaded server '${api}'.`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,6 @@ export default class Util {
|
|||
*/
|
||||
public resolveCommand(query: string | string[]): Promise<{cmd: Command, args: string[] }> {
|
||||
try {
|
||||
// let resolvedCommand: Command;
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
if (typeof query === 'string') query = query.split(' ');
|
||||
const commands = this.client.commands.toArray();
|
||||
const resolvedCommand = commands.find((c) => c.name === query[0].toLowerCase() || c.aliases.includes(query[0].toLowerCase()));
|
||||
|
@ -91,7 +89,6 @@ export default class Util {
|
|||
}
|
||||
await this.client.createMessage('595788220764127272', info);
|
||||
const msg = message ? message.content.slice(this.client.config.prefix.length).trim().split(/ +/g) : [];
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
if (command && disable) this.resolveCommand(msg).then((c) => { c.cmd.enabled = false; });
|
||||
if (message) message.channel.createMessage(`***${this.emojis.ERROR} An unexpected error has occured - please contact a Staff member.${command && disable ? ' This command has been disabled.' : ''}***`);
|
||||
} catch (err) {
|
||||
|
@ -101,7 +98,6 @@ export default class Util {
|
|||
|
||||
public splitString(string: string, length: number): string[] {
|
||||
if (!string) return [];
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
if (Array.isArray(string)) string = string.join('\n');
|
||||
if (string.length <= length) return [string];
|
||||
const arrayString: string[] = [];
|
||||
|
@ -111,7 +107,6 @@ export default class Util {
|
|||
pos = string.length > length ? string.lastIndexOf('\n', length) : string.length;
|
||||
if (pos > length) pos = length;
|
||||
str = string.substr(0, pos);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
string = string.substr(pos);
|
||||
arrayString.push(str);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
export { default as Client } from './Client';
|
||||
export { default as Collection } from './Collection';
|
||||
export { default as Command } from './Command';
|
||||
export { default as Event } from './Event';
|
||||
export { default as Moderation } from './Moderation';
|
||||
export { default as RichEmbed } from './RichEmbed';
|
||||
export { default as Route } from './Route';
|
||||
|
|
|
@ -23,10 +23,9 @@ export default class AddItem extends Command {
|
|||
return message.channel.createMessage({ embed });
|
||||
}
|
||||
if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) {
|
||||
const account = await this.client.db.member.findOne({ userID: message.member.id });
|
||||
const account = await this.client.db.Member.findOne({ userID: message.member.id });
|
||||
if (!account) {
|
||||
// eslint-disable-next-line new-cap
|
||||
const newAccount = new this.client.db.member({
|
||||
const newAccount = new this.client.db.Member({
|
||||
userID: message.member.id,
|
||||
additional: {
|
||||
operatingSystems: [args[0].split('-')[1]],
|
||||
|
@ -39,10 +38,9 @@ export default class AddItem extends Command {
|
|||
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Added OS code ${args[0]} to profile.***`);
|
||||
}
|
||||
if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) {
|
||||
const account = await this.client.db.member.findOne({ userID: message.member.id });
|
||||
const account = await this.client.db.Member.findOne({ userID: message.member.id });
|
||||
if (!account) {
|
||||
// eslint-disable-next-line new-cap
|
||||
const newAccount = new this.client.db.member({
|
||||
const newAccount = new this.client.db.Member({
|
||||
userID: message.member.id,
|
||||
additional: {
|
||||
langs: [args[0].split('-')[1]],
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class AddRedirect extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const check = await this.client.db.redirect.findOne({ key: args[1].toLowerCase() });
|
||||
const check = await this.client.db.Redirect.findOne({ key: args[1].toLowerCase() });
|
||||
if (check) return this.error(message.channel, `Redirect key ${args[1].toLowerCase()} already exists. Linked to: ${check.to}`);
|
||||
try {
|
||||
const test = new URL(args[0]);
|
||||
|
@ -24,8 +24,7 @@ export default class AddRedirect extends Command {
|
|||
return this.error(message.channel, 'This doesn\'t appear to be a valid URL.');
|
||||
}
|
||||
if ((/^[a-zA-Z0-9]+$/gi.test(args[1].toLowerCase().replace('-', '').trim()) === false) || args[1].toLowerCase().length > 15) return this.error(message.channel, 'Invalid key. The key must be alphanumeric and less than 16 characters.');
|
||||
// eslint-disable-next-line new-cap
|
||||
const redirect = new this.client.db.redirect({
|
||||
const redirect = new this.client.db.Redirect({
|
||||
key: args[1].toLowerCase(),
|
||||
to: args[0],
|
||||
});
|
||||
|
|
|
@ -23,16 +23,16 @@ export default class DelItem extends Command {
|
|||
return message.channel.createMessage({ embed });
|
||||
}
|
||||
if (args[0].split('-')[0] === 'os' && ['arch', 'deb', 'cent', 'fedora', 'manjaro', 'mdarwin', 'redhat', 'ubuntu', 'win'].includes(args[0].split('-')[1])) {
|
||||
const account = await this.client.db.member.findOne({ userID: message.member.id });
|
||||
if (!account || !account?.additional.operatingSystems || account?.additional.operatingSystems.length < 1) {
|
||||
const account = await this.client.db.Member.findOne({ userID: message.member.id });
|
||||
if (account?.additional.operatingSystems.length < 1) {
|
||||
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any operating systems to remove.***`);
|
||||
}
|
||||
await account.updateOne({ $pull: { 'additional.operatingSystems': args[0].split('-')[1] } });
|
||||
return message.channel.createMessage(`***${this.client.util.emojis.SUCCESS} Removed OS code ${args[0]} from profile.***`);
|
||||
}
|
||||
if (args[0].split('-')[0] === 'lang' && ['js', 'py', 'rb', 'ts', 'rs', 'go', 'cfam', 'csharp', 'swift', 'java', 'kt', 'asm'].includes(args[0].split('-')[1])) {
|
||||
const account = await this.client.db.member.findOne({ userID: message.member.id });
|
||||
if (!account || !account?.additional.langs || account?.additional.langs.length < 1) {
|
||||
const account = await this.client.db.Member.findOne({ userID: message.member.id });
|
||||
if (account?.additional.langs.length < 1) {
|
||||
return message.channel.createMessage(`***${this.client.util.emojis.ERROR} You don't have any languages to remove.***`);
|
||||
}
|
||||
await account.updateOne({ $pull: { 'additional.langs': args[0].split('-')[1] } });
|
||||
|
|
|
@ -15,9 +15,9 @@ export default class DelRedirect extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const check = await this.client.db.redirect.findOne({ key: args[0].toLowerCase() });
|
||||
const check = await this.client.db.Redirect.findOne({ key: args[0].toLowerCase() });
|
||||
if (!check) return this.error(message.channel, `Redirect key ${args[0].toLowerCase()} doesn't exist.`);
|
||||
await this.client.db.redirect.deleteOne({ key: args[0].toLowerCase() });
|
||||
await this.client.db.Redirect.deleteOne({ key: args[0].toLowerCase() });
|
||||
return this.success(message.channel, `Deleted redirect https://loc.sh/${args[0].toLowerCase()}.`);
|
||||
} catch (err) {
|
||||
return this.client.util.handleError(err, message, this);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Message } from 'eris';
|
||||
import axios from 'axios';
|
||||
import { Message, EmbedOptions } from 'eris';
|
||||
import axios, { AxiosResponse } from 'axios';
|
||||
import { Client, Command, RichEmbed } from '../class';
|
||||
|
||||
export default class DJS extends Command {
|
||||
|
@ -17,34 +17,10 @@ export default class DJS extends Command {
|
|||
try {
|
||||
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
|
||||
|
||||
let res;
|
||||
try {
|
||||
res = await axios.get(`https://djsdocs.sorta.moe/v2/embed?src=master&q=${args[0]}`);
|
||||
} catch (err) {
|
||||
this.error(message.channel, 'Please try again later, something unexpected happened.');
|
||||
return this.client.util.handleError(err, message, this);
|
||||
}
|
||||
const { data } = res;
|
||||
const { data }: AxiosResponse<EmbedOptions> = await axios.get(`https://djsdocs.sorta.moe/v2/embed?src=master&q=${args[0]}`);
|
||||
if (!data) return this.error(message.channel, 'Could not find information. Try something else.');
|
||||
|
||||
const name: string = data.author?.name || '';
|
||||
const icon_url: string = data.author?.icon_url || '';
|
||||
const author_url: string = data.author?.url || '';
|
||||
const description: string = data.description || 'None';
|
||||
const title: string = data.title || '';
|
||||
|
||||
const embed = new RichEmbed();
|
||||
embed.setAuthor(name, icon_url, author_url);
|
||||
embed.setColor(0x2296f3);
|
||||
embed.setTitle(title);
|
||||
embed.setDescription(description);
|
||||
if (data.fields !== undefined && data.fields.length > 0) {
|
||||
data.fields.forEach((field) => {
|
||||
embed.addField(field.name, field.value);
|
||||
});
|
||||
}
|
||||
embed.setFooter(this.client.user.username, this.client.user.avatarURL);
|
||||
embed.setTimestamp();
|
||||
const embed = new RichEmbed(data);
|
||||
return message.channel.createMessage({ embed });
|
||||
} catch (err) {
|
||||
return this.client.util.handleError(err, message, this);
|
||||
|
|
|
@ -47,13 +47,9 @@ export default class Game extends Command {
|
|||
embed.setColor('#1ed760');
|
||||
embed.addField('Song', mainStatus.details, true);
|
||||
embed.addField('Artist', mainStatus.state, true);
|
||||
// @ts-ignore
|
||||
embed.addField('Album', mainStatus.assets.large_text);
|
||||
// @ts-ignore
|
||||
embed.addField('Start', `${new Date(mainStatus.timestamps.start).toLocaleTimeString('en-us')} ET`, true);
|
||||
// @ts-ignore
|
||||
embed.addField('End', `${new Date(mainStatus.timestamps.end).toLocaleTimeString('en-us')} ET`, true);
|
||||
// @ts-ignore
|
||||
embed.setThumbnail(`https://i.scdn.co/image/${mainStatus.assets.large_image.split(':')[1]}`);
|
||||
embed.setFooter(`Listening to Spotify | ${this.client.user.username}`, 'https://media.discordapp.net/attachments/358674161566220288/496894273304920064/2000px-Spotify_logo_without_text.png');
|
||||
embed.setTimestamp();
|
||||
|
|
|
@ -12,7 +12,6 @@ export default class Help extends Command {
|
|||
this.enabled = true;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line consistent-return
|
||||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (args.length > 0) {
|
||||
|
@ -110,7 +109,7 @@ export default class Help extends Command {
|
|||
if (cmdPages.length === 1) return message.channel.createMessage({ embed: cmdPages[0] });
|
||||
return createPaginationEmbed(message, cmdPages);
|
||||
} catch (err) {
|
||||
this.client.util.handleError(err, message, this, false);
|
||||
return this.client.util.handleError(err, message, this, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
export { default as additem } from './additem';
|
||||
export { default as addredirect } from './addredirect';
|
||||
export { default as ban } from './ban';
|
||||
export { default as delitem } from './delitem';
|
||||
export { default as delredirect } from './delredirect';
|
||||
export { default as djs } from './djs';
|
||||
export { default as eval } from './eval';
|
||||
export { default as game } from './game';
|
||||
export { default as help } from './help';
|
||||
export { default as info } from './info';
|
||||
export { default as kick } from './kick';
|
||||
export { default as listredirects } from './listredirects';
|
||||
export { default as npm } from './npm';
|
||||
export { default as ping } from './ping';
|
||||
export { default as roleinfo } from './roleinfo';
|
||||
export { default as unban } from './unban';
|
||||
export { default as whois } from './whois';
|
|
@ -1,4 +1,4 @@
|
|||
import { Message, User } from 'eris';
|
||||
import { Message, User, Member } from 'eris';
|
||||
import { Client, Command } from '../class';
|
||||
|
||||
export default class Kick extends Command {
|
||||
|
@ -15,16 +15,15 @@ export default class Kick extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (!args[0]) return this.client.commands.get('help').run(message, [this.name]);
|
||||
const member = this.client.util.resolveMember(args[0], this.client.guilds.get(this.client.config.guildID));
|
||||
let user: User;
|
||||
if (!member) {
|
||||
let user: Member = this.client.util.resolveMember(args[0], this.client.guilds.get(this.client.config.guildID));
|
||||
if (!user) {
|
||||
try {
|
||||
user = await this.client.getRESTUser(args[0]);
|
||||
user = await this.client.getRESTGuildMember(this.client.config.guildID, args[0]);
|
||||
} catch {
|
||||
return this.error(message.channel, 'Cannot find user.');
|
||||
}
|
||||
}
|
||||
if (member && !this.client.util.moderation.checkPermissions(member, message.member)) return this.error(message.channel, 'Permission Denied.');
|
||||
if (user && !this.client.util.moderation.checkPermissions(user, message.member)) return this.error(message.channel, 'Permission Denied.');
|
||||
message.delete();
|
||||
|
||||
const reason: string = args[1];
|
||||
|
|
|
@ -16,7 +16,7 @@ export default class DelRedirect extends Command {
|
|||
public async run(message: Message, args: string[]) {
|
||||
try {
|
||||
if (args[0]) {
|
||||
const redirects = await this.client.db.redirect.find({ $or: [{ key: args[0].toLowerCase() }, { to: args[0].toLowerCase() }] });
|
||||
const redirects = await this.client.db.Redirect.find({ $or: [{ key: args[0].toLowerCase() }, { to: args[0].toLowerCase() }] });
|
||||
if (redirects.length <= 0) return this.error(message.channel, 'Could not find an entry matching that query.');
|
||||
const embed = new RichEmbed();
|
||||
embed.setTitle('Redirect Information');
|
||||
|
@ -27,7 +27,7 @@ export default class DelRedirect extends Command {
|
|||
embed.setTimestamp();
|
||||
return message.channel.createMessage({ embed });
|
||||
}
|
||||
const redirects = await this.client.db.redirect.find();
|
||||
const redirects = await this.client.db.Redirect.find();
|
||||
if (!redirects) return this.error(message.channel, 'No redirect links found.');
|
||||
const redirectArray: [{ name: string, value: string }?] = [];
|
||||
for (const redirect of redirects) {
|
||||
|
|
|
@ -34,8 +34,7 @@ export default class NPM extends Command {
|
|||
license = data.license;
|
||||
}
|
||||
let dependencies: string = 'None';
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (version !== 'Unknown' && data.versions[version].hasOwnProperty('dependencies') && Object.keys(data.versions[version].dependencies).length > 0) {
|
||||
if (version !== 'Unknown' && data.versions[version].dependencies !== undefined && Object.keys(data.versions[version].dependencies).length > 0) {
|
||||
dependencies = Object.keys(data.versions[version].dependencies).join(', ');
|
||||
}
|
||||
const name: string = data.name || 'None';
|
||||
|
|
|
@ -41,22 +41,20 @@ export default class Whois extends Command {
|
|||
embed.setThumbnail(member.avatarURL);
|
||||
const ackResolve = this.resolveStaffInformation(member.id);
|
||||
let description = '';
|
||||
if (ackResolve) {
|
||||
if (ackResolve?.title) {
|
||||
description += `${emotes.titleAndDepartment} __**${ackResolve.title}**__\n\n`;
|
||||
}
|
||||
if (ackResolve?.emailAddress) {
|
||||
description += `${emotes.email} ${ackResolve.emailAddress}\n`;
|
||||
}
|
||||
if (ackResolve?.gitlab) {
|
||||
description += `${emotes.gitlab} ${ackResolve.gitlab}\n`;
|
||||
}
|
||||
if (ackResolve?.github) {
|
||||
description += `${emotes.github} ${ackResolve.github}\n`;
|
||||
}
|
||||
if (ackResolve?.bio) {
|
||||
description += `${emotes.bio} *${ackResolve.bio}*\n`;
|
||||
}
|
||||
if (ackResolve?.title) {
|
||||
description += `${emotes.titleAndDepartment} __**${ackResolve.title}**__\n\n`;
|
||||
}
|
||||
if (ackResolve?.emailAddress) {
|
||||
description += `${emotes.email} ${ackResolve.emailAddress}\n`;
|
||||
}
|
||||
if (ackResolve?.gitlab) {
|
||||
description += `${emotes.gitlab} ${ackResolve.gitlab}\n`;
|
||||
}
|
||||
if (ackResolve?.github) {
|
||||
description += `${emotes.github} ${ackResolve.github}\n`;
|
||||
}
|
||||
if (ackResolve?.bio) {
|
||||
description += `${emotes.bio} *${ackResolve.bio}*\n`;
|
||||
}
|
||||
description += `\n<@${member.id}>`;
|
||||
embed.setDescription(description);
|
||||
|
@ -95,7 +93,7 @@ export default class Whois extends Command {
|
|||
if ((bit | 1073741824) === bit) permissions.push('Manage Emojis');
|
||||
if ((bit | 4) === bit) permissions.push('Ban Members');
|
||||
if ((bit | 2) === bit) permissions.push('Kick Members');
|
||||
const account = await this.client.db.member.findOne({ userID: member.id });
|
||||
const account = await this.client.db.Member.findOne({ userID: member.id });
|
||||
if (account?.additional?.langs.length > 0) {
|
||||
const langs: string[] = [];
|
||||
for (const lang of account.additional.langs.sort((a, b) => a.localeCompare(b))) {
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
{
|
||||
"name": "Midori",
|
||||
"id": "109122112643440640",
|
||||
"title": "Board of Directors",
|
||||
"title": "Board of Directors [ON LEAVE]",
|
||||
"emailAddress": "midori@staff.libraryofcode.org"
|
||||
},
|
||||
{
|
||||
|
@ -101,13 +101,6 @@
|
|||
"github": "https://github.com/Hector6704",
|
||||
"bio": "Hi there, I'm the developer of Delta, the Discord bot. I'm a free-time French JavaScript developer. I hope you'll enjoy LOC!"
|
||||
},
|
||||
{
|
||||
"name": "Realitus",
|
||||
"id": "156450671338586112",
|
||||
"title": "Associate",
|
||||
"github": "https://github.com/Realitus",
|
||||
"bio": "A hobbyist software developer with some rather strange ideas, and even stranger implementations."
|
||||
},
|
||||
{
|
||||
"name": "KhaaZ",
|
||||
"id": "179908288337412096",
|
||||
|
@ -133,6 +126,13 @@
|
|||
"github": "https://github.com/gavintjhxx",
|
||||
"bio": "Wake up. Eat. Code. Sleep. Loop()"
|
||||
},
|
||||
{
|
||||
"name": "PlayerVMachine",
|
||||
"id": "273999507174195203",
|
||||
"title": "Instructor & Associate",
|
||||
"emailAddress": "nicolas@staff.libraryofcode.org",
|
||||
"bio": "I write C++ to pay off my student loans"
|
||||
},
|
||||
{
|
||||
"name": "Null",
|
||||
"id": "323673862971588609",
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
/* eslint-disable no-useless-return */
|
||||
import { Message, TextChannel, NewsChannel } from 'eris';
|
||||
import { Client } from '../class';
|
||||
import { Client, Event } from '../class';
|
||||
|
||||
export default class {
|
||||
export default class CommandHandler extends Event {
|
||||
public client: Client;
|
||||
|
||||
constructor(client: Client) {
|
||||
this.client = client;
|
||||
super(client);
|
||||
this.event = 'messageCreate';
|
||||
}
|
||||
|
||||
public async run(message: Message) {
|
|
@ -0,0 +1,2 @@
|
|||
export { default as CommandHandler } from './CommandHandler';
|
||||
export { default as ready } from './ready';
|
|
@ -1,10 +1,11 @@
|
|||
import { Client } from '../class';
|
||||
import { Client, Event } from '../class';
|
||||
|
||||
export default class {
|
||||
export default class Ready extends Event {
|
||||
public client: Client;
|
||||
|
||||
constructor(client: Client) {
|
||||
this.client = client;
|
||||
super(client);
|
||||
this.event = 'ready';
|
||||
}
|
||||
|
||||
public async run() {
|
||||
|
|
|
@ -5,7 +5,7 @@ let interval: NodeJS.Timeout;
|
|||
export default function checkLock(client: Client): NodeJS.Timeout {
|
||||
interval = setInterval(async () => {
|
||||
try {
|
||||
const moderations = await client.db.moderation.find();
|
||||
const moderations = await client.db.Moderation.find();
|
||||
moderations.forEach(async (moderation) => {
|
||||
if (!moderation.expiration) return;
|
||||
if (moderation.expiration.processed) return;
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Client } from '../class';
|
|||
let interval: NodeJS.Timeout;
|
||||
|
||||
export default async function fetchMembers(client: Client): Promise<NodeJS.Timeout> {
|
||||
await client.guilds.get(client.config.guildID).fetchAllMembers();
|
||||
await client.guilds.get(client.config.guildID)?.fetchAllMembers();
|
||||
interval = setInterval(async () => {
|
||||
await client.guilds.get(client.config.guildID).fetchAllMembers();
|
||||
}, 1800000);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
import { parse } from 'yaml';
|
||||
import { promises as fs } from 'fs';
|
||||
import { Client } from './class';
|
||||
import * as eventFiles from './events';
|
||||
import * as commandFiles from './commands';
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const read = await fs.readFile('../config.yaml', 'utf8');
|
||||
|
@ -13,8 +15,8 @@ async function main(): Promise<void> {
|
|||
await client.loadDatabase();
|
||||
client.loadPlugins();
|
||||
await client.loadIntervals();
|
||||
await client.loadEvents();
|
||||
await client.loadCommands();
|
||||
await client.loadEvents(eventFiles);
|
||||
await client.loadCommands(commandFiles);
|
||||
client.connect();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,11 @@ export interface RedirectInterface extends Document {
|
|||
to: string,
|
||||
}
|
||||
|
||||
export interface RedirectRaw {
|
||||
key: string,
|
||||
to: string,
|
||||
}
|
||||
|
||||
const Redirect: Schema = new Schema({
|
||||
key: String,
|
||||
to: String,
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export { default as Member, MemberInterface } from './Member';
|
||||
export { default as Moderation, ModerationInterface } from './Moderation';
|
||||
export { default as Redirect, RedirectInterface } from './Redirect';
|
||||
export { default as Redirect, RedirectInterface, RedirectRaw } from './Redirect';
|
||||
|
|
Loading…
Reference in New Issue