Skip to content

Commit

Permalink
Adding admin ability to overwrite user's experience data (#864)
Browse files Browse the repository at this point in the history
Add XP overwrite functionality to /admin with /admin overwriteuserdata
  • Loading branch information
Hipperooni authored Oct 30, 2024
1 parent 1a5ea8a commit 8c464e4
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 5 deletions.
103 changes: 101 additions & 2 deletions src/discord/commands/guild/d.admin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import {
} from 'discord.js';
import axios from 'axios';
import { stripIndents } from 'common-tags';
import {
experience_category, experience_type,
} from '@prisma/client';
import { findXPfromLevel } from '../../../global/utils/experience';
import { SlashCommand } from '../../@types/commandDef';
import commandContext from '../../utils/context';
import deployCommands from '../../utils/commandDeploy';
Expand Down Expand Up @@ -144,6 +148,72 @@ async function setStatus(
await interaction.editReply(`Status set to ${statusType} ${status}`);
}

async function overwriteUserData(
interaction: ChatInputCommandInteraction,
): Promise<void> {
const member = interaction.options.getUser('user');
if (!member) {
await interaction.editReply('Error: User not found.');
return;
}

const category = interaction.options.getString('category') as experience_category;
const type = interaction.options.getString('type') as experience_type;
const level = interaction.options.getInteger('level');

if (!category || !type || level === null) {
await interaction.editReply('Error: Missing category, type, or level.');
return;
}

const userData = await db.users.upsert({
where: {
discord_id: member.id,
},
create: {
discord_id: member.id,
},
update: {},
});

const experienceData = await db.user_experience.findFirst({
where: {
user_id: userData.id,
category,
type,
},
});

if (!experienceData) {
log.debug(F, `No experience data found for user ${userData.id} in category ${category} type ${type}.`);
await interaction.editReply('Error: No experience data found for the user.');
return;
}

const levelPoints = await findXPfromLevel(level);
log.debug(F, `Overwriting user data for user ${userData.id} in category ${category} type ${type} to level ${level} with ${levelPoints} XP points.`);

Check warning on line 194 in src/discord/commands/guild/d.admin.ts

View workflow job for this annotation

GitHub Actions / Lint

This line has a length of 150. Maximum allowed is 120

try {
const result = await db.user_experience.updateMany({
where: {
user_id: userData.id,
category,
type,
},
data: {
level,
level_points: levelPoints,
total_points: levelPoints,
},
});
console.log(`Update result: ${JSON.stringify(result)}`);
} catch (error) {
console.error(`Error updating database: ${(error as Error).message}`);
}

await interaction.editReply(`User level and points updated for category ${category} to level ${level} with ${levelPoints} points.`);
}

export const dAdmin: SlashCommand = {
data: new SlashCommandBuilder()
.setName('admin')
Expand Down Expand Up @@ -187,12 +257,37 @@ export const dAdmin: SlashCommand = {
.addStringOption(option => option
.setName('url')
.setDescription('The URL of the banner')
.setRequired(true))),
.setRequired(true)))
.addSubcommand(subcommand => subcommand
.setName('overwriteuserdata')
.setDescription('Overwrite user data')
.addUserOption(option => option.setName('user').setDescription('The user to update').setRequired(true))
.addStringOption(option => option.setName('category')
.setDescription('The category to update')
.setRequired(true)
.addChoices(
{ name: 'General', value: 'GENERAL' },
{ name: 'Tripsitter', value: 'TRIPSITTER' },
{ name: 'Developer', value: 'DEVELOPER' },
{ name: 'Team', value: 'TEAM' },
{ name: 'Ignored', value: 'IGNORED' },
// Add more categories as needed
))
.addStringOption(option => option.setName('type')
.setDescription('The type to update')
.setRequired(true)
.addChoices(
{ name: 'Text', value: 'TEXT' },
{ name: 'Voice', value: 'VOICE' },
// Add more types as needed
))
.addIntegerOption(option => option.setName('level').setDescription('The level to set').setRequired(true))),

async execute(interaction) {
if (!interaction.channel) return false;
if (!interaction.guild) return false;
log.info(F, await commandContext(interaction));
const command = interaction.options.getSubcommand() as 'restart' | 'rebuild' | 'deploy' | 'setstatus' | 'setavatar' | 'setbanner';
const command = interaction.options.getSubcommand() as 'restart' | 'rebuild' | 'deploy' | 'setstatus' | 'setavatar' | 'setbanner' | 'overwriteuserdata';
// By default we want to make the reply private
await interaction.deferReply({ ephemeral: true });
// eslint-disable-next-line sonarjs/no-small-switch
Expand Down Expand Up @@ -221,6 +316,10 @@ export const dAdmin: SlashCommand = {
await setStatus(interaction, interaction.options.getString('prefix') as string, interaction.options.getString('status') as string);
break;
}
case 'overwriteuserdata': {
await overwriteUserData(interaction);
break;
}
default: {
log.debug(F, `default ${command}`);
await interaction.editReply('Command not found');
Expand Down
17 changes: 14 additions & 3 deletions src/global/utils/experience.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,24 @@ const announcementEmojis = [
'🎇',
];

export async function expForNextLevel(
level:number,
):Promise<number> {
export async function expForNextLevel(level: number): Promise<number> {
// This is a simple formula, making sure it's standardized across the system
return 5 * (level ** 2) + (50 * level) + 100;
}

export async function findXPfromLevel(level: number): Promise<number> {
let totalXP = 0;

const xpPromises = [];
for (let currentLevel = 1; currentLevel < level; currentLevel += 1) {
xpPromises.push(expForNextLevel(currentLevel));
}
const xpResults = await Promise.all(xpPromises);
totalXP = xpResults.reduce((acc, xp) => acc + xp, 0);

return totalXP;
}

export async function getTotalLevel(
totalExp:number,
):Promise<{ level: number, level_points: number }> {
Expand Down

0 comments on commit 8c464e4

Please sign in to comment.