Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Language command #2430

Merged
merged 12 commits into from
Mar 1, 2024
13 changes: 13 additions & 0 deletions Core/src/commands/admin/LanguageCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {packetHandler} from "../../core/packetHandlers/PacketHandler";
import {CommandUpdatePacketReq, CommandUpdatePacketRes} from "../../../../Lib/src/packets/commands/CommandUpdatePacket";
import {WebsocketClient} from "../../../../Lib/src/instances/WebsocketClient";
import {DraftBotPacket, makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPacket";

export default class LanguageCommand {
@packetHandler(CommandUpdatePacketReq)
execute(client: WebsocketClient, packet: CommandUpdatePacketReq, context: PacketContext, response: DraftBotPacket[]): void {
response.push(makePacket(CommandUpdatePacketRes, {
coreVersion: process.env.npm_package_version
}));
}
}
39 changes: 0 additions & 39 deletions Core/src/core/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,6 @@ export abstract class Constants {
ROLE_DURATION: 24
};

static readonly COMMAND_CATEGORY = {
SERVER: "server",
UTIL: "util",
PLAYER: "player",
MISSION: "mission",
GUILD: "guild",
PET: "pet"
};

static readonly XP = {
BASE_VALUE: 325,
COEFFICIENT: 1.041,
Expand Down Expand Up @@ -235,11 +226,6 @@ export abstract class Constants {
]
};

static readonly LANGUAGE = {
FRENCH: "fr",
ENGLISH: "en"
};

static readonly PET_FOOD = {
COMMON_FOOD: "commonFood",
CARNIVOROUS_FOOD: "carnivorousFood",
Expand Down Expand Up @@ -274,33 +260,8 @@ export abstract class Constants {
]
};

static readonly ROLES = {
GUILD: {
NONE: "none",
MEMBER: "member",
ELDER: "elder",
CHIEF: "chief"
},
USER: {
ADMINISTRATOR: "administrator",
BADGE_MANAGER: "manager",
CONTRIBUTORS: "contributors",
BOT_OWNER: "owner"
}
};

static readonly MINIMAL_PLAYER_SCORE = 100;

static readonly PERMISSION = {
ROLE: {
BOT_OWNER: "owner", // Is the owner of the bot
BADGE_MANAGER: "manager", // Has the badge manager role
SUPPORT: "support", // Has the support role
ADMINISTRATOR: "administrator", // Has the admin permission in a server where the bot is.
CONTRIBUTORS: "contributors",
ALL: "all"
}
};

static readonly MAX_DAILY_POTION_BUYOUTS: number = 5;

Expand Down
4 changes: 2 additions & 2 deletions Core/src/core/constants/ServersConstants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Constants} from "../Constants";
import {StringConstants} from "../../../../Lib/src/constants/StringConstants";

export abstract class ServersConstants {
static readonly DEFAULT_LANGUAGE = Constants.LANGUAGE.ENGLISH;
static readonly DEFAULT_LANGUAGE = StringConstants.LANGUAGE.ENGLISH;
}
4 changes: 2 additions & 2 deletions Core/src/core/database/game/migrations/019-v5.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {parse} from "toml";
import {readFileSync} from "fs";
import {KeycloakUtils} from "../../../../../../Lib/src/keycloak/KeycloakUtils";
import {KeycloakConfig} from "../../../../../../Lib/src/keycloak/KeycloakConfig";
import {Constants} from "../../../Constants";
import {logsV5NewIds} from "../../logs/migrations/006-v5";
import {StringConstants} from "../../../../../../Lib/src/constants/StringConstants";

export async function up({context}: { context: QueryInterface }): Promise<void> {
const configPath = `${process.cwd()}/config/keycloak.toml`;
Expand All @@ -29,7 +29,7 @@ clientSecret = "secret"

for (let i = 0; i < players.length; ++i) {
const player = players[i];
const user = await KeycloakUtils.getOrRegisterDiscordUser(config.keycloak, player.discordUserId as string, player.discordUserId as string, Constants.LANGUAGE.ENGLISH);
const user = await KeycloakUtils.getOrRegisterDiscordUser(config.keycloak, player.discordUserId as string, player.discordUserId as string, StringConstants.LANGUAGE.ENGLISH);
await context.sequelize.query(`UPDATE players SET discordUserId = "${user.id}" WHERE discordUserId = "${player.discordUserId}"`);
logsV5NewIds.set(player.discordUserId as string, user.id);
}
Expand Down
1 change: 0 additions & 1 deletion Core/src/core/fights/fighter/MonsterFighter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export class MonsterFighter extends Fighter {
this.stats.breath = monster.breath;
this.stats.maxBreath = monster.maxBreath;
this.stats.breathRegen = monster.breathRegen;
this.emoji = monster.emoji;
this.monster = monster;
this.status = FighterStatus.NOT_STARTED;
}
Expand Down
7 changes: 0 additions & 7 deletions Discord/src/Constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import {Language} from "../../Lib/src/Language";

export class Constants {
static readonly VERSION = import("../package.json").then(json => json.version);

Expand Down Expand Up @@ -54,11 +52,6 @@ export class Constants {
]
};

static readonly LANGUAGE: { FRENCH: Language, ENGLISH: Language } = {
FRENCH: "fr",
ENGLISH: "en"
};

static readonly MESSAGES = {
COLLECTOR_TIME: 120000,
COLORS: {
Expand Down
22 changes: 11 additions & 11 deletions Discord/src/commands/CommandsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {DiscordWebSocket} from "../bot/Websocket";
import {PacketContext} from "../../../Lib/src/packets/DraftBotPacket";
import {DiscordCache} from "../bot/DiscordCache";
import {BotUtils} from "../utils/BotUtils";
import { StringConstants } from "../../../Lib/src/constants/StringConstants";

export class CommandsManager {
static commands = new Map<string, ICommand>();
Expand Down Expand Up @@ -216,13 +217,13 @@ export class CommandsManager {
message.channel.send({
content: `
${i18n.t("bot:mentionHelp", {
lang: Constants.LANGUAGE.ENGLISH,
lang: StringConstants.LANGUAGE.ENGLISH,
commandHelp: BotUtils.commandsMentions.get("help"),
commandLanguage: BotUtils.commandsMentions.get("language")
})}

${i18n.t("bot:mentionHelp", {
lang: Constants.LANGUAGE.FRENCH,
lang: StringConstants.LANGUAGE.FRENCH,
commandHelp: BotUtils.commandsMentions.get("help"),
commandLanguage: BotUtils.commandsMentions.get("language")
})}`
Expand Down Expand Up @@ -270,17 +271,16 @@ ${i18n.t("bot:mentionHelp", {
}
const user = await KeycloakUtils.getOrRegisterDiscordUser(keycloakConfig, discordInteraction.user.id, discordInteraction.user.displayName, discordInteraction.locale.substring(0, 2));
const interaction: DraftbotInteraction = DraftbotInteraction.cast(discordInteraction);
interaction.userLanguage = KeycloakUtils.getUserLanguage(user);
if (!interaction.channel) {
replyErrorMessage(
interaction,
user.attributes.language,
i18n.t("bot:noChannelAccess", {lang: user.attributes.language})
)
.finally(() => null);
return;
}
if (!interaction.member) { // If in DM, shouldn't happen
interaction.channel.language = user.attributes.language;
CommandsManager.handlePrivateMessage(interaction)
.finally(() => null);
return;
Expand All @@ -302,7 +302,7 @@ ${i18n.t("bot:mentionHelp", {
attachmentList.push(new AttachmentBuilder(Buffer.from(message.content)).setName(`userMessage-${message.author.id}-${message.id}.txt`));
}
const supportAlert = i18n.t("bot:supportAlert", {
lang: Constants.LANGUAGE.FRENCH,
lang: StringConstants.LANGUAGE.FRENCH,
username: escapeUsername(message.author.username),
id: message.author.id
}) + (message.content.length > Constants.DM.MAX_MESSAGE_LENGTH_ALLOWED
Expand Down Expand Up @@ -336,7 +336,7 @@ ${i18n.t("bot:mentionHelp", {
if (!msg!.getFirstReaction()) {
return;
}
const language = msg!.getFirstReaction()!.emoji.name === Constants.REACTIONS.ENGLISH_FLAG ? Constants.LANGUAGE.ENGLISH : Constants.LANGUAGE.FRENCH;
const language = msg!.getFirstReaction()!.emoji.name === Constants.REACTIONS.ENGLISH_FLAG ? StringConstants.LANGUAGE.ENGLISH : StringConstants.LANGUAGE.FRENCH;
message.channel.send({
embeds: [new DraftBotEmbed()
.formatAuthor(i18n.t("bot:dmHelpMessageTitle", {
Expand All @@ -354,7 +354,7 @@ ${i18n.t("bot:mentionHelp", {
.formatAuthor(Constants.DM.TITLE_SUPPORT, author)
.setDescription(message instanceof DraftbotInteraction ? Constants.DM.INTERACTION_SUPPORT : Constants.DM.MESSAGE_SUPPORT);
const draftbotChannel = message.channel as unknown as DraftbotChannel;
draftbotChannel.language = Constants.LANGUAGE.ENGLISH;
draftbotChannel.language = StringConstants.LANGUAGE.ENGLISH;
message instanceof Message ? await helpMessage.send(draftbotChannel) : await helpMessage.reply(message);
}

Expand All @@ -365,19 +365,19 @@ ${i18n.t("bot:mentionHelp", {
* @private
*/
private static async handleCommand(interaction: DraftbotInteraction, user: KeycloakUser): Promise<void> {
const language = user.attributes.language;
const language = interaction.userLanguage;

const commandInfo = this.commands.get(interaction.commandName);

if (!commandInfo) {
await replyErrorMessage(interaction, Constants.LANGUAGE.ENGLISH, i18n.t("bot:command404", {lang: language}));
await replyErrorMessage(interaction, i18n.t("bot:command404", {lang: language}));
console.error(`Command "${interaction.commandName}" is not registered`);
return;
}

const channelAccess = this.hasChannelPermission(interaction.channel);
if (!channelAccess[0]) {
await replyErrorMessage(interaction, Constants.LANGUAGE.ENGLISH, i18n.t(channelAccess[1], {lang: language}));
await replyErrorMessage(interaction, i18n.t(channelAccess[1], {lang: language}));
return;
}

Expand All @@ -390,7 +390,7 @@ ${i18n.t("bot:mentionHelp", {
user: interaction.user.id,
channel: interaction.channel.id,
interaction: interaction.id,
language: interaction.channel.language
language: interaction.userLanguage
}
};
DiscordWebSocket.socket!.send(JSON.stringify({
Expand Down
25 changes: 13 additions & 12 deletions Discord/src/commands/SlashCommandBuilderGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
*/
import {ApplicationCommandOptionBase, SlashCommandBuilder} from "@discordjs/builders";
import i18n from "../translations/i18n";
import {Constants} from "../Constants";

Check failure on line 6 in Discord/src/commands/SlashCommandBuilderGenerator.ts

View workflow job for this annotation

GitHub Actions / eslint-discord-module

'Constants' is defined but never used
import {SlashCommandStringOption} from "discord.js";
import {TopConstants} from "../../../Lib/src/constants/TopConstants";
import { StringConstants } from "../../../Lib/src/constants/StringConstants";


export class SlashCommandBuilderGenerator {
Expand All @@ -16,13 +17,13 @@
*/
static generateBaseCommand(commandSectionName: string): SlashCommandBuilder {
return new SlashCommandBuilder()
.setName(i18n.t(`discordBuilder:${commandSectionName}.name`, { lng: Constants.LANGUAGE.ENGLISH }))
.setName(i18n.t(`discordBuilder:${commandSectionName}.name`, { lng: StringConstants.LANGUAGE.ENGLISH }))
.setNameLocalizations({
fr: i18n.t(`discordBuilder:${commandSectionName}.name`, { lng: Constants.LANGUAGE.FRENCH })
fr: i18n.t(`discordBuilder:${commandSectionName}.name`, { lng: StringConstants.LANGUAGE.FRENCH })
})
.setDescription(i18n.t(`discordBuilder:${commandSectionName}.description`, { lng: Constants.LANGUAGE.ENGLISH }))
.setDescription(i18n.t(`discordBuilder:${commandSectionName}.description`, { lng: StringConstants.LANGUAGE.ENGLISH }))
.setDescriptionLocalizations({
fr: i18n.t(`discordBuilder:${commandSectionName}.description`, { lng: Constants.LANGUAGE.FRENCH })
fr: i18n.t(`discordBuilder:${commandSectionName}.description`, { lng: StringConstants.LANGUAGE.FRENCH })
});
}

Expand All @@ -33,13 +34,13 @@
* @param option Option to populate
*/
static generateOption<T extends ApplicationCommandOptionBase>(commandSectionName: string, optionSectionName: string, option: T): T {
return option.setName(i18n.t(`discordBuilder:${commandSectionName}.options.${optionSectionName}.name`, { lng: Constants.LANGUAGE.ENGLISH }))
return option.setName(i18n.t(`discordBuilder:${commandSectionName}.options.${optionSectionName}.name`, { lng: StringConstants.LANGUAGE.ENGLISH }))
.setNameLocalizations({
fr: i18n.t(`discordBuilder:${commandSectionName}.options.${optionSectionName}.name`, { lng: Constants.LANGUAGE.FRENCH })
fr: i18n.t(`discordBuilder:${commandSectionName}.options.${optionSectionName}.name`, { lng: StringConstants.LANGUAGE.FRENCH })
})
.setDescription(i18n.t(`discordBuilder:${commandSectionName}.options.${optionSectionName}.description`, { lng: Constants.LANGUAGE.ENGLISH }))
.setDescription(i18n.t(`discordBuilder:${commandSectionName}.options.${optionSectionName}.description`, { lng: StringConstants.LANGUAGE.ENGLISH }))
.setDescriptionLocalizations({
fr: i18n.t(`discordBuilder:${commandSectionName}.options.${optionSectionName}.description`, { lng: Constants.LANGUAGE.FRENCH })
fr: i18n.t(`discordBuilder:${commandSectionName}.options.${optionSectionName}.description`, { lng: StringConstants.LANGUAGE.FRENCH })
});
}

Expand All @@ -57,16 +58,16 @@
return SlashCommandBuilderGenerator.generateOption(commandSectionName, optionSectionName, option)
.addChoices(
{
name: i18n.t("discordBuilder:scopes.global", { lng: Constants.LANGUAGE.ENGLISH }),
name: i18n.t("discordBuilder:scopes.global", { lng: StringConstants.LANGUAGE.ENGLISH }),
"name_localizations": {
fr: i18n.t("discordBuilder:scopes.global", { lng: Constants.LANGUAGE.FRENCH })
fr: i18n.t("discordBuilder:scopes.global", { lng: StringConstants.LANGUAGE.FRENCH })
}, value: TopConstants.GLOBAL_SCOPE
},
{
name: i18n.t("discordBuilder:scopes.server", { lng: Constants.LANGUAGE.ENGLISH }),
name: i18n.t("discordBuilder:scopes.server", { lng: StringConstants.LANGUAGE.ENGLISH }),
"name_localizations":
{
fr: i18n.t("discordBuilder:scopes.server", { lng: Constants.LANGUAGE.FRENCH })
fr: i18n.t("discordBuilder:scopes.server", { lng: StringConstants.LANGUAGE.FRENCH })
}
,
value: TopConstants.SERVER_SCOPE
Expand Down
82 changes: 82 additions & 0 deletions Discord/src/commands/admin/LanguageCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {ICommand} from "../ICommand";
import {SlashCommandBuilderGenerator} from "../SlashCommandBuilderGenerator";
import {
ActionRowBuilder,
StringSelectMenuBuilder,
StringSelectMenuInteraction,
StringSelectMenuOptionBuilder
} from "discord.js";
import {DraftbotInteraction} from "../../messages/DraftbotInteraction";
import i18n from "../../translations/i18n";
import {DraftBotEmbed} from "../../messages/DraftBotEmbed";
import {StringConstants} from "../../../../Lib/src/constants/StringConstants";
import {PermissionsConstants} from "../../constants/PermissionsConstants";
import {KeycloakUser} from "../../../../Lib/src/keycloak/KeycloakUser";
import {KeycloakUtils} from "../../../../Lib/src/keycloak/KeycloakUtils";
import {keycloakConfig} from "../../bot/DraftBotShard";
import {Constants} from "../../Constants";
import {sendInteractionNotForYou} from "../../utils/ErrorUtils";
import {Language} from "../../../../Lib/src/Language";

/**
* Allow an admin to change the prefix the bot uses in a specific server
*/
async function getPacket(interaction: DraftbotInteraction, keycloakUser: KeycloakUser): Promise<null> {
const selectLanguageMenuId = "languageSelectionMenu";
const selectLanguageMenuOptions = Object.keys(StringConstants.LANGUAGE)
.map((key) => {
const languageCode = StringConstants.LANGUAGE[key as keyof typeof StringConstants.LANGUAGE];
return new StringSelectMenuOptionBuilder()
.setLabel(i18n.t(`commands:language.languages.${languageCode}.name`, {lng: interaction.userLanguage}))
.setEmoji(i18n.t(`commands:language.languages.${languageCode}.emoji`, {lng: interaction.userLanguage}))
.setValue(languageCode);
});
const languageSelectionMenu = new StringSelectMenuBuilder()
.setCustomId(selectLanguageMenuId)
.setPlaceholder(i18n.t("commands:language.selectLanguage", {lng: interaction.userLanguage}))
.addOptions(selectLanguageMenuOptions);
const row = new ActionRowBuilder<StringSelectMenuBuilder>()
.addComponents(languageSelectionMenu);
const msg = await interaction.reply({
embeds: [new DraftBotEmbed()
.setTitle(i18n.t("commands:language.title", {
lng: interaction.userLanguage
}))
.setDescription(i18n.t("commands:language.description", {
lng: interaction.userLanguage
}))],
components: [row]
});

const collector = msg.createMessageComponentCollector({
filter: menuInteraction => menuInteraction.customId === selectLanguageMenuId,
time: Constants.MESSAGES.COLLECTOR_TIME
});

collector.on("collect", async (menuInteraction: StringSelectMenuInteraction) => {
if (menuInteraction.user.id !== interaction.user.id) {
await sendInteractionNotForYou(menuInteraction.user, menuInteraction, interaction.userLanguage);
return;
}
await KeycloakUtils.updateUserLanguage(keycloakConfig, keycloakUser, menuInteraction.values[0] as Language);
await menuInteraction.reply({
embeds: [new DraftBotEmbed()
.setTitle(i18n.t("commands:language.newLanguageSetTitle", {
lng: menuInteraction.values[0] as Language

Check warning on line 65 in Discord/src/commands/admin/LanguageCommand.ts

View workflow job for this annotation

GitHub Actions / eslint-discord-module

Extra space before value for key 'lng'
}))
.setDescription(i18n.t("commands:language.newLanguageSetDescription", {
lng: menuInteraction.values[0] as Language

Check warning on line 68 in Discord/src/commands/admin/LanguageCommand.ts

View workflow job for this annotation

GitHub Actions / eslint-discord-module

Extra space before value for key 'lng'
}))]
})

Check failure on line 70 in Discord/src/commands/admin/LanguageCommand.ts

View workflow job for this annotation

GitHub Actions / eslint-discord-module

Missing semicolon
});
return null;
}

export const commandInfo: ICommand = {
slashCommandBuilder: SlashCommandBuilderGenerator.generateBaseCommand("language"),
getPacket,
requirements: {
userPermission: PermissionsConstants.ROLES.USER.ADMINISTRATOR
},
mainGuildCommand: false
};
4 changes: 2 additions & 2 deletions Discord/src/commands/player/BadgesCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ async function getPacket(interaction: DraftbotInteraction): Promise<null> {
await interaction.reply({
embeds: [new DraftBotEmbed()
.setTitle(i18n.t("commands:badges.title", {
lng: interaction.channel.language
lng: interaction.userLanguage
}))
.setDescription(i18n.t("commands:badges.description", {
lng: interaction.channel.language
lng: interaction.userLanguage
}))]
});
return null;
Expand Down
Loading
Loading