Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions src/commands/guild/tempban.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { CommandInteraction, SlashCommandBuilder } from 'discord.js';
import { Command } from '../../types/interaction';
import { PermissionLevel } from '../../utils/permissions';
import * as scheduler from '../../utils/scheduler';
import {formatDate, formatUserRaw} from "../../utils/utils";
import {unbanHandler} from "../shared/tempban";

const TempBan: Command = {
permissionLevel: PermissionLevel.MODERATOR,

data: new SlashCommandBuilder()
.setName('tempban')
.setDescription('Bans the given user for X time.')
.addUserOption(option => option
.setName('user')
.setDescription('The user to ban')
.setRequired(true))
.addIntegerOption(option => option
.setName('m')
.setDescription('Amount of minutes before unban')
.setRequired(false))
.addIntegerOption(option => option
.setName('h')
.setDescription('Amount of hours before unban')
.setRequired(false))
.addIntegerOption(option => option
.setName('d')
.setDescription('Amount of days before unban')
.setRequired(false))
.addIntegerOption(option => option
.setName('w')
.setDescription('Amount of weeks before unban')
.setRequired(false))
.addIntegerOption(option => option
.setName('M')
.setDescription('Amount of months before unban')
.setRequired(false))
.addIntegerOption(option => option
.setName('y')
.setDescription('Amount of years before unban')
.setRequired(false)),

async execute(interaction: CommandInteraction) {
if (!interaction.isChatInputCommand())
return;

if (!interaction.inGuild() || !interaction.guild)
return interaction.reply({ content: 'This command must be ran in a guild.', ephemeral: true });

const user = interaction.options.getUser('user', true);
const minutes = interaction.options.getInteger( 'm', false ) || 0;
const hours = interaction.options.getInteger( 'h', false ) || 0;
const days = interaction.options.getInteger( 'd', false ) || 0;
const weeks = interaction.options.getInteger( 'w', false ) || 0;
const months = interaction.options.getInteger( 'M', false ) || 0;
const years = interaction.options.getInteger( 'y', false ) || 0;

if ( minutes + hours + days + weeks + months + years == 0 )
return interaction.reply({ content: 'This command requires at least one non-zero parameter.', ephemeral: true });

const task = scheduler.schedule( interaction.guild.id, { delay: 0 }, unbanHandler );

await interaction.guild.bans.create(user);

return interaction.reply({ content: `Banned ${formatUserRaw(user)} until ${formatDate(task.date)}`, ephemeral: true });
}
};
export default TempBan;
3 changes: 1 addition & 2 deletions src/commands/guild/warn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { CommandInteraction, EmbedBuilder, SlashCommandBuilder } from 'discord.j
import { Command } from '../../types/interaction';
import { PermissionLevel } from '../../utils/permissions';
import { LogLevelColor } from '../../utils/log';
import { formatDate, formatUserRaw } from '../../utils/utils';

import * as persist from '../../utils/persist';
import { getWarnList } from '../shared/warnlist';
Expand Down Expand Up @@ -75,7 +74,7 @@ const Warn: Command = {
.setColor(LogLevelColor.WARNING)
.setTitle('WARN')
.setFields({ name: 'You have been warned for the following reason:', value: `\`${reason}\`` })
.setFooter({ text: `Issued by ${formatUserRaw(interaction.user)} in "${interaction.guild.name}"` })
.setFooter({ text: `Issued in "${interaction.guild.name}"` })
.setTimestamp();

await user.send({ embeds: [embed] });
Expand Down
19 changes: 19 additions & 0 deletions src/commands/shared/tempban.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {MoralityCoreClient} from '../../types/client';

import * as persist from '../../utils/persist';
import {resume} from '../../utils/scheduler';
import { ok as assert } from 'assert';
import {ScheduledTask} from '../../types/scheduler';

export function register( client: MoralityCoreClient ): void {
for ( const guild of client.guilds.valueOf().values() )
for ( const { taskId } of persist.data(guild.id).moderation.tempban )
resume( guild.id, taskId, unbanHandler );
}

export function unbanHandler( task: ScheduledTask, data: unknown ): void {
assert( data instanceof { guild: String }, 'unbanHandler was passed a non-string parameter!!' );

const client = MoralityCoreClient.get();
client.guilds.fetch( )
}
9 changes: 9 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { updateCommands, updateCommandsForGuild } from './utils/update_commands'
import * as config from './config.json';
import * as log from './utils/log';
import * as persist from './utils/persist';
import * as scheduler from './utils/scheduler';
import * as tempban from './commands/shared/tempban';

// Make console output better
import consoleStamp from 'console-stamp';
Expand Down Expand Up @@ -344,13 +346,20 @@ async function main() {
}
});

// start the scheduler
scheduler.run();

// Log in
await client.login(config.token);

// register all tempban stuff again
tempban.register( client );

process.on('SIGINT', () => {
const date = new Date();
log.writeToLog(undefined, `--- BOT END AT ${date.toDateString()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()} ---`);
client.destroy();
scheduler.shutdown();
persist.saveAll();
process.exit();
});
Expand Down
4 changes: 4 additions & 0 deletions src/types/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,16 @@ export class Callbacks {
}

export class MoralityCoreClient extends Client {
private static instance: MoralityCoreClient;
commands: Collection<string, CommandBase>;
callbacks: Callbacks;

constructor(options: ClientOptions) {
super(options);
this.commands = new Collection<string, CommandBase>();
this.callbacks = new Callbacks();
MoralityCoreClient.instance = this;
}

static get = () => MoralityCoreClient.instance;
}
16 changes: 15 additions & 1 deletion src/types/persist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ export interface PersistentData {
issuer: string,
}[],
},
tempban: {
taskId: string,
user: string,
reason: string,
issuer: string,
}[]
},
reaction_roles: {
[message: string]: {
Expand All @@ -48,9 +54,17 @@ export interface PersistentData {
responses: {
[response_id: string]: string,
},
watched_threads: Array<string>,
watched_threads: string[],
statistics: {
joins: number,
leaves: number,
},
scheduler: {
[taskid: string]: {
data: unknown,
expirationTime: number,
repeat: boolean,
delay: number
}
}
}
62 changes: 62 additions & 0 deletions src/types/scheduler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
export interface RepeatedSchedulePlan {

/**
* ms before this task is initially executed
*/
initialDelay: number,

/**
* ms between task executions
*/
distance: number
}

export interface SingleSchedulePlan {
/**
* ms before task execution
*/
delay: number
}

export type SchedulePlan = RepeatedSchedulePlan | SingleSchedulePlan;

export type Task = ( task: ScheduledTask, data: unknown ) => void

/**
* Represents a task that has been submitted to the scheduler.
*/
export interface ScheduledTask {
/**
* Unique id assigned to this scheduled task.
*/
readonly id: string,

/**
* The task that will be executed.
*/
readonly task: Task,

/**
* The unix timestamp at which this task will run.
*/
readonly date: number,

/**
* The guild this task was scheduled on.
readonly guild: string,

/**
* Cancels and removes from persistence this task.
*/
cancel(): void,

/**
* Whether this scheduled task was cancelled.
*/
cancelled(): boolean,

/**
* Returns how many ms until this task is executed.
*/
remainingTime(): number,
}
47 changes: 47 additions & 0 deletions src/utils/scheduler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {SchedulePlan, Task, ScheduledTask} from "../types/scheduler";
import * as persist from '../utils/persist';


/**
* Resumes a task previously saved to persistence.
* @param id id of the task to get the data from.
* @param task
*/
export function resume( guild: string, id: string, task: Task ): ScheduledTask {

}

/**
* Schedules a task for execution.
* @param plan
* @param task
*/
export function schedule( guild: string, plan: SchedulePlan, task: Task ): ScheduledTask {
persist.data(guild).scheduler[]
}

/**
* Cancels and removes from persistence a scheduled task.
* @param task
*/
export function cancelTask( task: ScheduledTask ): number {

}

export function run() {
setInterval(
() => {

},
5
);
}


/**
* Stops the scheduler and saves all state.
*/
export function shutdown() {

}