This commit is contained in:
76
commands/contests/ac.ts
Normal file
76
commands/contests/ac.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import {
|
||||
CommandInteraction,
|
||||
CommandInteractionOptionResolver,
|
||||
TextChannel,
|
||||
SlashCommandBuilder,
|
||||
SlashCommandStringOption,
|
||||
PermissionFlagsBits,
|
||||
} from 'discord.js';
|
||||
import {Command} from '../../classes/command';
|
||||
import {logger} from '../../logger'
|
||||
import {getContest, updateProblem} from '../../functions/database';
|
||||
|
||||
function isTextChannel(data: unknown): data is TextChannel{
|
||||
return (data as TextChannel).name !== undefined;
|
||||
}
|
||||
|
||||
type CIOR = CommandInteractionOptionResolver;
|
||||
|
||||
class Ac extends Command{
|
||||
get name(){return "ac";}
|
||||
get description(){return "Add timestamp when you get ac";}
|
||||
async execute(interaction: CommandInteraction): Promise<void>{
|
||||
if(!isTextChannel(interaction.channel)){
|
||||
await interaction.reply({
|
||||
content: `Channel name doesn't exist!`
|
||||
});
|
||||
logger.error(`Channel name doesn't exist`);
|
||||
return;
|
||||
}
|
||||
try{
|
||||
// parse
|
||||
const user = interaction.user;
|
||||
let problemId = (interaction.options as CIOR).getString('problem');
|
||||
const contestName = interaction.channel.name;
|
||||
const channelId = interaction.channel.id;
|
||||
const contest = await getContest(channelId);
|
||||
const time = new Date();
|
||||
if(problemId === null){
|
||||
logger.error('option error');
|
||||
return;
|
||||
}
|
||||
problemId = problemId.toUpperCase();
|
||||
if(contest === null){
|
||||
await interaction.reply({
|
||||
content: `The contest in this channel didn't start!`
|
||||
});
|
||||
logger.error(`Contest ${contestName} didn't start`);
|
||||
return;
|
||||
}
|
||||
// update
|
||||
await updateProblem(user, problemId, channelId, 'ac', time.valueOf());
|
||||
await interaction.reply({
|
||||
content: `Problem ${problemId} has ac-ed.`
|
||||
});
|
||||
logger.log(`Problem ${problemId} has ac-ed.`);
|
||||
}catch(error: unknown){
|
||||
logger.error(`Error occur while ac-ing problem`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
override build(): SlashCommandBuilder |
|
||||
Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">{
|
||||
return new SlashCommandBuilder()
|
||||
.setName(this.name)
|
||||
.setDescription(this.description)
|
||||
.addStringOption((option: SlashCommandStringOption) =>
|
||||
option
|
||||
.setName('problem')
|
||||
.setDescription('The id of the problem.')
|
||||
.setMinLength(1).setMaxLength(1)
|
||||
.setRequired(true))
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.SendMessages);
|
||||
}
|
||||
};
|
||||
|
||||
export const command = new Ac();
|
||||
40
commands/contests/clear.ts
Normal file
40
commands/contests/clear.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
CommandInteraction,
|
||||
TextChannel,
|
||||
} from 'discord.js';
|
||||
import {Command} from '../../classes/command';
|
||||
import {logger} from '../../logger'
|
||||
import {getContest, clearContest} from '../../functions/database';
|
||||
|
||||
function isTextChannel(data: unknown): data is TextChannel{
|
||||
return (data as TextChannel).name !== undefined;
|
||||
}
|
||||
|
||||
class Clear extends Command{
|
||||
get name(){return "clear";}
|
||||
get description(){return "clear contest.";}
|
||||
async execute(interaction: CommandInteraction): Promise<void>{
|
||||
if(!isTextChannel(interaction.channel)){
|
||||
await interaction.reply({
|
||||
content: `Channel name doesn't exist!`
|
||||
});
|
||||
logger.error(`Channel name doesn't exist`);
|
||||
return;
|
||||
}
|
||||
const contestName = interaction.channel.name;
|
||||
const channelId = interaction.channel.id;
|
||||
const contest = await getContest(contestName);
|
||||
if(contest === null){
|
||||
await interaction.reply({
|
||||
content: `The contest in this channel didn't start!`
|
||||
});
|
||||
logger.error(`Contest ${contestName} didn't start`);
|
||||
return;
|
||||
}
|
||||
await clearContest(channelId);
|
||||
await interaction.reply({content: `Clear ${contestName} complete.`});
|
||||
logger.log(`Command: clear ${contestName}/${channelId}`);
|
||||
}
|
||||
};
|
||||
|
||||
export const command = new Clear();
|
||||
87
commands/contests/code.ts
Normal file
87
commands/contests/code.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
import {
|
||||
CommandInteraction,
|
||||
CommandInteractionOptionResolver,
|
||||
TextChannel,
|
||||
SlashCommandBuilder,
|
||||
SlashCommandStringOption,
|
||||
SlashCommandUserOption,
|
||||
SlashCommandIntegerOption,
|
||||
PermissionFlagsBits,
|
||||
} from 'discord.js';
|
||||
import {Command} from '../../classes/command';
|
||||
import {logger} from '../../logger'
|
||||
import {getContest, putCode} from '../../functions/database';
|
||||
|
||||
function isTextChannel(data: unknown): data is TextChannel{
|
||||
return (data as TextChannel).name !== undefined;
|
||||
}
|
||||
|
||||
type CIOR = CommandInteractionOptionResolver;
|
||||
|
||||
class Code extends Command{
|
||||
get name(){return "code";}
|
||||
get description(){return "Add timestamp to code a problem";}
|
||||
async execute(interaction: CommandInteraction): Promise<void>{
|
||||
if(!isTextChannel(interaction.channel)){
|
||||
await interaction.reply({
|
||||
content: `Channel name doesn't exist!`
|
||||
});
|
||||
logger.error(`Channel name doesn't exist`);
|
||||
return;
|
||||
}
|
||||
try{
|
||||
let problemId = (interaction.options as CIOR).getString('problem');
|
||||
const estimate = (interaction.options as CIOR).getInteger('estimate') ?? -1;
|
||||
const specifiedUser = (interaction.options as CIOR).getUser('user');
|
||||
const contestName = interaction.channel.name;
|
||||
const channelId = interaction.channel.id;
|
||||
const contest = await getContest(channelId);
|
||||
const time = new Date();
|
||||
if(problemId === null){
|
||||
logger.error('option error');
|
||||
return;
|
||||
}
|
||||
problemId = problemId.toUpperCase();
|
||||
if(contest === null){
|
||||
await interaction.reply({
|
||||
content: `The contest in this channel didn't start!`
|
||||
});
|
||||
logger.error(`Contest ${contestName} didn't start`);
|
||||
return;
|
||||
}
|
||||
const user = specifiedUser ?? interaction.user;
|
||||
const sessionId: string = await putCode(
|
||||
user, problemId, channelId, time.valueOf(), estimate*1000*60 + contest.startTime
|
||||
);
|
||||
const content = `Problem ${problemId} code by ${user.username}, estimate in ${estimate} min. (session id: ${sessionId})`;
|
||||
await interaction.reply({content: logger.log(content)});
|
||||
}catch(error: unknown){
|
||||
logger.error(`Error occur while coding problem`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
override build(): SlashCommandBuilder |
|
||||
Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">{
|
||||
return new SlashCommandBuilder()
|
||||
.setName(this.name)
|
||||
.setDescription(this.description)
|
||||
.addStringOption((option: SlashCommandStringOption) =>
|
||||
option
|
||||
.setName('problem')
|
||||
.setDescription('The id of the problem.')
|
||||
.setMinLength(1).setMaxLength(1)
|
||||
.setRequired(true))
|
||||
.addIntegerOption((option: SlashCommandIntegerOption) =>
|
||||
option
|
||||
.setName('estimate')
|
||||
.setDescription('The estimate coding time of the problem.')
|
||||
.setRequired(true))
|
||||
.addUserOption((option: SlashCommandUserOption) =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('Who read the problem, default is yourself'))
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.SendMessages);
|
||||
}
|
||||
};
|
||||
|
||||
export const command = new Code();
|
||||
90
commands/contests/modify.ts
Normal file
90
commands/contests/modify.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import {
|
||||
CommandInteraction,
|
||||
CommandInteractionOptionResolver,
|
||||
TextChannel,
|
||||
SlashCommandBuilder,
|
||||
SlashCommandStringOption,
|
||||
SlashCommandIntegerOption,
|
||||
} from 'discord.js';
|
||||
import {Command} from '../../classes/command';
|
||||
import {logger} from '../../logger'
|
||||
import {getContest, updateSession} from '../../functions/database';
|
||||
|
||||
function isTextChannel(data: unknown): data is TextChannel{
|
||||
return (data as TextChannel).name !== undefined;
|
||||
}
|
||||
|
||||
type CIOR = CommandInteractionOptionResolver;
|
||||
|
||||
class Code extends Command{
|
||||
get name(){return "modify";}
|
||||
get description(){return "Modify a session timestamp.";}
|
||||
async execute(interaction: CommandInteraction): Promise<void>{
|
||||
if(!isTextChannel(interaction.channel)){
|
||||
await interaction.reply({
|
||||
content: `Channel name doesn't exist!`
|
||||
});
|
||||
logger.error(`Channel name doesn't exist`);
|
||||
return;
|
||||
}
|
||||
try{
|
||||
// parse
|
||||
const sessionId = (interaction.options as CIOR).getString('session');
|
||||
const key = (interaction.options as CIOR).getString('key');
|
||||
const channelId = interaction.channel.id;
|
||||
const contest = await getContest(channelId);
|
||||
let time = (interaction.options as CIOR).getInteger('time');
|
||||
if(sessionId === null || key === null || contest === null){
|
||||
logger.error(`Can't parse parameters in "modify"`);
|
||||
throw Error();
|
||||
}
|
||||
if(time === null)
|
||||
time = new Date().getTime();
|
||||
else
|
||||
time = time*1000*60 + contest.startTime;
|
||||
// update
|
||||
if (! await updateSession(sessionId, key, time)){
|
||||
await interaction.reply({
|
||||
content: `Session ${sessionId} doesn't exist`
|
||||
});
|
||||
return;
|
||||
}
|
||||
await interaction.reply({
|
||||
content: `The value of key ${key} in session ${sessionId} has been updated.`
|
||||
});
|
||||
logger.log(`The value of key ${key} in session ${sessionId} has been updated.`);
|
||||
}catch(error: unknown){
|
||||
logger.error(`Error occur while coding problem`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
override build(): SlashCommandBuilder |
|
||||
Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">{
|
||||
return new SlashCommandBuilder()
|
||||
.setName(this.name)
|
||||
.setDescription(this.description)
|
||||
.addStringOption((option: SlashCommandStringOption) =>
|
||||
option
|
||||
.setName('session')
|
||||
.setDescription('The id of the session.')
|
||||
.setRequired(true)
|
||||
)
|
||||
.addStringOption((option: SlashCommandStringOption) =>
|
||||
option
|
||||
.setName('key')
|
||||
.setDescription('Which value should be modified.')
|
||||
.setRequired(true)
|
||||
.addChoices(
|
||||
{name: 'start', value: 'start'},
|
||||
{name: 'end', value: 'end'},
|
||||
)
|
||||
)
|
||||
.addIntegerOption((option: SlashCommandIntegerOption) =>
|
||||
option
|
||||
.setName('time')
|
||||
.setDescription('The time which being updated, default is now.')
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
export const command = new Code();
|
||||
89
commands/contests/read.ts
Normal file
89
commands/contests/read.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import {
|
||||
CommandInteraction,
|
||||
CommandInteractionOptionResolver,
|
||||
TextChannel,
|
||||
SlashCommandBuilder,
|
||||
SlashCommandStringOption,
|
||||
SlashCommandUserOption,
|
||||
SlashCommandIntegerOption,
|
||||
} from 'discord.js';
|
||||
import {Command} from '../../classes/command';
|
||||
import {logger} from '../../logger'
|
||||
import {getContest, putRead} from '../../functions/database';
|
||||
|
||||
function isTextChannel(data: unknown): data is TextChannel{
|
||||
return (data as TextChannel).name !== undefined;
|
||||
}
|
||||
|
||||
type CIOR = CommandInteractionOptionResolver;
|
||||
|
||||
class Read extends Command{
|
||||
get name(){return "read";}
|
||||
get description(){return "Add timestamp to read a problem";}
|
||||
async execute(interaction: CommandInteraction): Promise<void>{
|
||||
if(!isTextChannel(interaction.channel)){
|
||||
await interaction.reply({
|
||||
content: `Channel name doesn't exist!`
|
||||
});
|
||||
logger.error(`Channel name doesn't exist`);
|
||||
return;
|
||||
}
|
||||
try{
|
||||
let problemId = (interaction.options as CIOR).getString('problem');
|
||||
const estimate = (interaction.options as CIOR).getInteger('estimate') ?? -1;
|
||||
const specifiedUser = (interaction.options as CIOR).getUser('user');
|
||||
const contestName = interaction.channel.name;
|
||||
const channelId = interaction.channel.id;
|
||||
const contest = await getContest(channelId);
|
||||
const time = new Date();
|
||||
if(problemId === null){
|
||||
logger.error('Options error in "read".');
|
||||
return;
|
||||
}
|
||||
const user = specifiedUser ?? interaction.user;
|
||||
problemId = problemId.toUpperCase();
|
||||
if(contest === null){
|
||||
await interaction.reply({
|
||||
content: `The contest in this channel didn't start!`
|
||||
});
|
||||
logger.error(`Contest ${contestName} didn't start`);
|
||||
return;
|
||||
}
|
||||
const sessionId: string = await putRead(
|
||||
user, problemId, channelId, time.valueOf(), estimate*1000*60 + contest.startTime
|
||||
);
|
||||
let content = `Problem ${problemId} read by ${user.username}`;
|
||||
if(estimate !== -1) content += `, estimate in ${estimate} min`;
|
||||
content += `. (session id: ${sessionId})`;
|
||||
await interaction.reply({content: logger.log(content)});
|
||||
}catch(error: unknown){
|
||||
logger.error(`Error occur while reading problem`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
override build(): SlashCommandBuilder |
|
||||
Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">{
|
||||
return new SlashCommandBuilder()
|
||||
.setName(this.name)
|
||||
.setDescription(this.description)
|
||||
.addStringOption((option: SlashCommandStringOption) =>
|
||||
option
|
||||
.setName('problem')
|
||||
.setDescription('The id of the problem.')
|
||||
.setMinLength(1).setMaxLength(1)
|
||||
.setRequired(true)
|
||||
)
|
||||
.addIntegerOption((option: SlashCommandIntegerOption) =>
|
||||
option
|
||||
.setName('estimate')
|
||||
.setDescription('The estimate coding time of the problem.')
|
||||
)
|
||||
.addUserOption((option: SlashCommandUserOption) =>
|
||||
option
|
||||
.setName('user')
|
||||
.setDescription('Who read the problem, default is yourself')
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
export const command = new Read();
|
||||
21
commands/contests/reset.ts
Normal file
21
commands/contests/reset.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/* DEPRECATED
|
||||
|
||||
import {CommandInteraction} from 'discord.js';
|
||||
import {Command} from '../../classes/command';
|
||||
import {logger} from '../../logger'
|
||||
import {clearContests, clearProblems, clearSessions} from '../../functions/database';
|
||||
|
||||
class Reset extends Command{
|
||||
get name(){return "reset";}
|
||||
get description(){return "Reset database.";}
|
||||
async execute(interaction: CommandInteraction): Promise<void>{
|
||||
await clearContests();
|
||||
await clearProblems();
|
||||
await clearSessions();
|
||||
await interaction.reply({content: `Reset complete.`});
|
||||
logger.log(`Command: reset database.`);
|
||||
}
|
||||
};
|
||||
|
||||
export const command = new Reset();
|
||||
*/
|
||||
124
commands/contests/result.ts
Normal file
124
commands/contests/result.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import {
|
||||
CommandInteraction,
|
||||
TextChannel,
|
||||
SlashCommandBuilder,
|
||||
SlashCommandBooleanOption,
|
||||
CommandInteractionOptionResolver,
|
||||
} from 'discord.js';
|
||||
import {writeFileSync} from 'fs';
|
||||
|
||||
import {Command} from '../../classes/command';
|
||||
import {logger} from '../../logger';
|
||||
import {config} from '../../config';
|
||||
import {getContest, getProblem, getSession} from '../../functions/database';
|
||||
|
||||
function isTextChannel(data: unknown): data is TextChannel{
|
||||
return (data as TextChannel).name !== undefined;
|
||||
}
|
||||
|
||||
type CIOR = CommandInteractionOptionResolver;
|
||||
|
||||
class Result extends Command{
|
||||
get name(){return "result";}
|
||||
get description(){return "See the result of a contest.";}
|
||||
async execute(interaction: CommandInteraction): Promise<void>{
|
||||
if(!isTextChannel(interaction.channel)){
|
||||
await interaction.reply({
|
||||
content: `Channel name doesn't exist!`
|
||||
});
|
||||
logger.error(`Channel name doesn't exist`);
|
||||
return;
|
||||
}
|
||||
const contestName = interaction.channel.name;
|
||||
const channelId = interaction.channel.id;
|
||||
const markdown = (interaction.options as CIOR).getBoolean('markdown') ?? false;
|
||||
const contest = await getContest(channelId);
|
||||
if(contest === null){
|
||||
await interaction.reply({
|
||||
content: `The contest in this channel didn't start!`
|
||||
});
|
||||
logger.error(`Contest ${contestName} didn't start`);
|
||||
return;
|
||||
}
|
||||
let content: string = '';
|
||||
content += `# ${contestName}\n\n`
|
||||
contest.problems.sort(
|
||||
(a, b) => {
|
||||
if(a.problemId > b.problemId)
|
||||
return 1;
|
||||
if(a.problemId < b.problemId)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
const getTime = (time: number) => {
|
||||
if(time === -1) return -1;
|
||||
return Math.floor((time-contest.startTime)/(1000*60));
|
||||
};
|
||||
for(const problem of contest.problems){
|
||||
const p = await getProblem(problem._id);
|
||||
if(p === null) continue;
|
||||
content += `## p${p.problemId}\n`;
|
||||
if(getTime(p.ac) === -1)
|
||||
content += "*Problem unsolved!*\n";
|
||||
else
|
||||
content += `**AC** at ${getTime(p.ac)} min\n`;
|
||||
if(p.wa.length !== 0){
|
||||
content += `**WA** at`;
|
||||
let isFirst: boolean = true;
|
||||
for(const wa of p.wa.sort()){
|
||||
if(isFirst) isFirst = false;
|
||||
else content += ',';
|
||||
content += ` ${getTime(wa)}`;
|
||||
}
|
||||
content += ' min\n';
|
||||
}
|
||||
if(p.read.length === 0)
|
||||
content += "*Problem unread!*\n";
|
||||
else{
|
||||
content += `**Read**:\n`;
|
||||
for(const session of p.read){
|
||||
const s = await getSession(session._id);
|
||||
if(s === null) continue;
|
||||
content += `- \`${s.name}\` at ${getTime(s.start)} min`;
|
||||
if(getTime(s.end) !== -1)
|
||||
content += ` (estimate: ${getTime(s.end)} min)`;
|
||||
content += '\n';
|
||||
}
|
||||
}
|
||||
if(p.code.length === 0)
|
||||
content += "*No one have attempted*\n";
|
||||
else{
|
||||
content += `**Code**:\n`;
|
||||
for(const session of p.code){
|
||||
const s = await getSession(session._id);
|
||||
if(s === null) continue;
|
||||
content += `- \`${s.name}\` at ${getTime(s.start)} min`
|
||||
content += ` (estimate: ${getTime(s.end)} min)\n`;
|
||||
}
|
||||
}
|
||||
content += '\n';
|
||||
}
|
||||
if(markdown){
|
||||
const file = `${config.mdBaseDir}/${channelId}.md`;
|
||||
logger.log(`Output to ${file}`);
|
||||
await writeFileSync(file, content, {encoding: 'utf8'});
|
||||
await interaction.reply({files:[file]});
|
||||
}else
|
||||
await interaction.reply({content: content});
|
||||
logger.log(`Command: result of ${contestName}/${channelId}`);
|
||||
}
|
||||
override build(): SlashCommandBuilder |
|
||||
Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">{
|
||||
return new SlashCommandBuilder()
|
||||
.setName(this.name)
|
||||
.setDescription(this.description)
|
||||
.addBooleanOption((option: SlashCommandBooleanOption) =>
|
||||
option
|
||||
.setName('markdown')
|
||||
.setDescription('If true then upload markdown file instead.')
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
export const command = new Result();
|
||||
37
commands/contests/virtual.ts
Normal file
37
commands/contests/virtual.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import {CommandInteraction, TextChannel} from 'discord.js';
|
||||
import {Command} from '../../classes/command';
|
||||
import {logger} from '../../logger'
|
||||
import {createContest} from '../../functions/database';
|
||||
|
||||
function isTextChannel(data: unknown): data is TextChannel{
|
||||
return (data as TextChannel).name !== undefined;
|
||||
}
|
||||
|
||||
class Virtual extends Command{
|
||||
get name(){return "virtual";}
|
||||
get description(){return "Start a virtual contest.";}
|
||||
async execute(interaction: CommandInteraction): Promise<void>{
|
||||
if(!isTextChannel(interaction.channel)){
|
||||
await interaction.reply({
|
||||
content: `Channel name doesn't exist!`
|
||||
});
|
||||
logger.error(`Channel name doesn't exist`);
|
||||
return;
|
||||
}
|
||||
try{
|
||||
const contestName = interaction.channel.name;
|
||||
const channelId = interaction.channel.id;
|
||||
const startTime = new Date();
|
||||
await createContest(channelId, startTime.valueOf());
|
||||
await interaction.reply({
|
||||
content: `Contest archive ${contestName} created on ${startTime.toString()}.`
|
||||
});
|
||||
logger.log(`Contest archive ${contestName} created.`);
|
||||
}catch(error: unknown){
|
||||
logger.error(`Error occur while initializing contest`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const command = new Virtual();
|
||||
76
commands/contests/wa.ts
Normal file
76
commands/contests/wa.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import {
|
||||
CommandInteraction,
|
||||
CommandInteractionOptionResolver,
|
||||
TextChannel,
|
||||
SlashCommandBuilder,
|
||||
SlashCommandStringOption,
|
||||
PermissionFlagsBits,
|
||||
} from 'discord.js';
|
||||
import {Command} from '../../classes/command';
|
||||
import {logger} from '../../logger'
|
||||
import {getContest, updateProblem} from '../../functions/database';
|
||||
|
||||
function isTextChannel(data: unknown): data is TextChannel{
|
||||
return (data as TextChannel).name !== undefined;
|
||||
}
|
||||
|
||||
type CIOR = CommandInteractionOptionResolver;
|
||||
|
||||
class Wa extends Command{
|
||||
get name(){return "wa";}
|
||||
get description(){return "Add timestamp when you get wa";}
|
||||
async execute(interaction: CommandInteraction): Promise<void>{
|
||||
if(!isTextChannel(interaction.channel)){
|
||||
await interaction.reply({
|
||||
content: `Channel name doesn't exist!`
|
||||
});
|
||||
logger.error(`Channel name doesn't exist`);
|
||||
return;
|
||||
}
|
||||
try{
|
||||
// parse
|
||||
const user = interaction.user;
|
||||
let problemId = (interaction.options as CIOR).getString('problem');
|
||||
const contestName = interaction.channel.name;
|
||||
const channelId = interaction.channel.id;
|
||||
const contest = await getContest(channelId);
|
||||
const time = new Date();
|
||||
if(problemId === null){
|
||||
logger.error('option error');
|
||||
return;
|
||||
}
|
||||
problemId = problemId.toUpperCase();
|
||||
if(contest === null){
|
||||
await interaction.reply({
|
||||
content: `The contest in this channel didn't start!`
|
||||
});
|
||||
logger.error(`Contest ${contestName} didn't start`);
|
||||
return;
|
||||
}
|
||||
// update
|
||||
await updateProblem(user, problemId, channelId, 'wa', time.valueOf());
|
||||
await interaction.reply({
|
||||
content: `Problem ${problemId} has wa-ed.`
|
||||
});
|
||||
logger.log(`Problem ${problemId} has wa-ed.`);
|
||||
}catch(error: unknown){
|
||||
logger.error(`Error occur while wa-ing problem`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
override build(): SlashCommandBuilder |
|
||||
Omit<SlashCommandBuilder, "addSubcommand" | "addSubcommandGroup">{
|
||||
return new SlashCommandBuilder()
|
||||
.setName(this.name)
|
||||
.setDescription(this.description)
|
||||
.addStringOption((option: SlashCommandStringOption) =>
|
||||
option
|
||||
.setName('problem')
|
||||
.setDescription('The id of the problem.')
|
||||
.setMinLength(1).setMaxLength(1)
|
||||
.setRequired(true))
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.SendMessages);
|
||||
}
|
||||
};
|
||||
|
||||
export const command = new Wa();
|
||||
Reference in New Issue
Block a user