From 5684c5da212a04ff23ce93170e37e4cc17075fd7 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Wed, 15 Jan 2025 17:56:35 +0100 Subject: [PATCH 01/18] first version core guildleave #2273 --- Core/src/commands/guild/GuildLeaveCommand.ts | 91 +++++++++++++++++++ .../src/commands/guild/GuildLeaveCommand.ts | 0 .../commands/CommandGuildLeavePacket.ts | 16 ++++ .../ReactionCollectorGuildLeave.ts | 40 ++++++++ 4 files changed, 147 insertions(+) create mode 100644 Core/src/commands/guild/GuildLeaveCommand.ts create mode 100644 Discord/src/commands/guild/GuildLeaveCommand.ts create mode 100644 Lib/src/packets/commands/CommandGuildLeavePacket.ts create mode 100644 Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts diff --git a/Core/src/commands/guild/GuildLeaveCommand.ts b/Core/src/commands/guild/GuildLeaveCommand.ts new file mode 100644 index 000000000..0a525cfb8 --- /dev/null +++ b/Core/src/commands/guild/GuildLeaveCommand.ts @@ -0,0 +1,91 @@ +import {commandRequires, CommandUtils} from "../../core/utils/CommandUtils"; +import {GuildConstants} from "../../../../Lib/src/constants/GuildConstants"; +import {DraftBotPacket, makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPacket"; +import Player, {Players} from "../../core/database/game/models/Player"; +import { + CommandGuildLeaveAcceptPacketRes, + CommandGuildLeavePacketReq, CommandGuildLeaveRefusePacketRes +} from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; +import {Guilds} from "../../core/database/game/models/Guild"; +import {ReactionCollectorGuildLeave} from "../../../../Lib/src/packets/interaction/ReactionCollectorGuildLeave"; +import {EndCallback, ReactionCollectorInstance} from "../../core/utils/ReactionsCollector"; +import {ReactionCollectorAcceptReaction} from "../../../../Lib/src/packets/interaction/ReactionCollectorPacket"; +import {BlockingUtils} from "../../core/utils/BlockingUtils"; +import {BlockingConstants} from "../../../../Lib/src/constants/BlockingConstants"; + +async function acceptGuildleave(player: Player, response: DraftBotPacket[]): Promise { + await player.reload(); + if (player.guildId === null) { + return; + } + const guild = await Guilds.getById(player.guildId); + if (player.id === guild.chiefId) { + if (guild.elderId !== null) { + const elder = await Players.getById(guild.elderId); + guild.elderId = null; + guild.chiefId = elder.id; + response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { + newChiefKeycloakId: elder.keycloakId, + guildName: guild.name + })); + return; + } + // TODO : détruire la guilde ici + response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { + guildName: guild.name + })); + return; + } + if (guild.elderId === player.id) { + guild.elderId = null; + } + player.guildId = null; + response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { + guildName: guild.name + })); +} + +export default class GuildElderCommand { + @commandRequires(CommandGuildLeavePacketReq, { + notBlocked: true, + disallowedEffects: CommandUtils.DISALLOWED_EFFECTS.NOT_STARTED_OR_DEAD, + level: GuildConstants.REQUIRED_LEVEL, + guildNeeded: true + }) + async execute(response: DraftBotPacket[], player: Player, packet: CommandGuildLeavePacketReq, context: PacketContext): Promise { + if (player.guildId === null) { + return; + } + const guild = await Guilds.getById(player.guildId); + const elder = await Players.getById(guild.elderId); + + const collector = new ReactionCollectorGuildLeave( + guild.name, + elder.keycloakId + ); + const endCallback: EndCallback = async (collector: ReactionCollectorInstance, response: DraftBotPacket[]): Promise => { + const reaction = collector.getFirstReaction(); + if (reaction && reaction.reaction.type === ReactionCollectorAcceptReaction.name) { + await acceptGuildleave(player, response); + } + else { + response.push(makePacket(CommandGuildLeaveRefusePacketRes, {})); + } + BlockingUtils.unblockPlayer(player.id, BlockingConstants.REASONS.GUILD_LEAVE); + }; + + const collectorPacket = new ReactionCollectorInstance( + collector, + context, + { + allowedPlayerKeycloakIds: [player.keycloakId], + reactionLimit: 1 + }, + endCallback + ) + .block(player.id, BlockingConstants.REASONS.GUILD_LEAVE) + .build(); + + response.push(collectorPacket); + } +} \ No newline at end of file diff --git a/Discord/src/commands/guild/GuildLeaveCommand.ts b/Discord/src/commands/guild/GuildLeaveCommand.ts new file mode 100644 index 000000000..e69de29bb diff --git a/Lib/src/packets/commands/CommandGuildLeavePacket.ts b/Lib/src/packets/commands/CommandGuildLeavePacket.ts new file mode 100644 index 000000000..0c33dbb40 --- /dev/null +++ b/Lib/src/packets/commands/CommandGuildLeavePacket.ts @@ -0,0 +1,16 @@ +import {DraftBotPacket, PacketDirection, sendablePacket} from "../DraftBotPacket"; + +@sendablePacket(PacketDirection.FRONT_TO_BACK) +export class CommandGuildLeavePacketReq extends DraftBotPacket { +} + +@sendablePacket(PacketDirection.BACK_TO_FRONT) +export class CommandGuildLeaveRefusePacketRes extends DraftBotPacket { +} + +@sendablePacket(PacketDirection.BACK_TO_FRONT) +export class CommandGuildLeaveAcceptPacketRes extends DraftBotPacket { + newChiefKeycloakId?: string; + + guildName!: string; +} \ No newline at end of file diff --git a/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts b/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts new file mode 100644 index 000000000..aeda15b14 --- /dev/null +++ b/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts @@ -0,0 +1,40 @@ +import { + ReactionCollector, + ReactionCollectorAcceptReaction, + ReactionCollectorCreationPacket, + ReactionCollectorData, + ReactionCollectorRefuseReaction +} from "./ReactionCollectorPacket"; + +export class ReactionCollectorGuildLeaveData extends ReactionCollectorData { + guildName!: string; + + newChiefKeycloakId!: string | null; +} + +export class ReactionCollectorGuildLeave extends ReactionCollector { + private readonly guildName: string; + + private readonly newChiefKeycloakId: string; + + constructor(guildName: string, newChiefKeycloakId: string) { + super(); + this.guildName = guildName; + this.newChiefKeycloakId = newChiefKeycloakId; + } + + creationPacket(id: string, endTime: number): ReactionCollectorCreationPacket { + return { + id, + endTime, + reactions: [ + this.buildReaction(ReactionCollectorAcceptReaction, {}), + this.buildReaction(ReactionCollectorRefuseReaction, {}) + ], + data: this.buildData(ReactionCollectorGuildLeaveData, { + guildName: this.guildName, + newChiefKeycloakId: this.newChiefKeycloakId + }) + }; + } +} \ No newline at end of file From 282d8b3ebe58db11265186dbab5ab2e382e399c0 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Fri, 17 Jan 2025 19:38:43 +0100 Subject: [PATCH 02/18] End of core guildLeave #2273 --- Core/src/commands/guild/GuildLeaveCommand.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Core/src/commands/guild/GuildLeaveCommand.ts b/Core/src/commands/guild/GuildLeaveCommand.ts index 0a525cfb8..36f66c229 100644 --- a/Core/src/commands/guild/GuildLeaveCommand.ts +++ b/Core/src/commands/guild/GuildLeaveCommand.ts @@ -13,14 +13,23 @@ import {ReactionCollectorAcceptReaction} from "../../../../Lib/src/packets/inter import {BlockingUtils} from "../../core/utils/BlockingUtils"; import {BlockingConstants} from "../../../../Lib/src/constants/BlockingConstants"; -async function acceptGuildleave(player: Player, response: DraftBotPacket[]): Promise { + +/** + * Allow the player to leave its guild + * @param player + * @param response + */ +async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Promise { await player.reload(); + // The player is no longer in a guild since the menu if (player.guildId === null) { return; } const guild = await Guilds.getById(player.guildId); if (player.id === guild.chiefId) { + // The guild's chief is leaving if (guild.elderId !== null) { + // An elder can recover the guild const elder = await Players.getById(guild.elderId); guild.elderId = null; guild.chiefId = elder.id; @@ -30,13 +39,15 @@ async function acceptGuildleave(player: Player, response: DraftBotPacket[]): Pro })); return; } - // TODO : détruire la guilde ici + // No elder => the guild will be destroyed + await guild.completelyDestroyAndDeleteFromTheDatabase(); response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { guildName: guild.name })); return; } if (guild.elderId === player.id) { + // The guild's elder is leaving guild.elderId = null; } player.guildId = null; @@ -66,7 +77,7 @@ export default class GuildElderCommand { const endCallback: EndCallback = async (collector: ReactionCollectorInstance, response: DraftBotPacket[]): Promise => { const reaction = collector.getFirstReaction(); if (reaction && reaction.reaction.type === ReactionCollectorAcceptReaction.name) { - await acceptGuildleave(player, response); + await acceptGuildLeave(player, response); } else { response.push(makePacket(CommandGuildLeaveRefusePacketRes, {})); From 6219dd6b483d7fa522a17df9f25b34e1962e2432 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Fri, 17 Jan 2025 20:34:20 +0100 Subject: [PATCH 03/18] WIP on guildLeave #2273 --- Core/src/commands/guild/GuildLeaveCommand.ts | 5 +- .../src/commands/guild/GuildLeaveCommand.ts | 51 +++++++++++++++++++ .../handlers/CommandHandlers.ts | 18 +++++++ .../handlers/ReactionCollectorHandlers.ts | 3 ++ Lang/en/discordBuilder.json | 14 +++++ Lang/fr/commands.json | 12 +++++ .../commands/CommandGuildLeavePacket.ts | 1 + .../ReactionCollectorGuildLeave.ts | 12 +++-- 8 files changed, 111 insertions(+), 5 deletions(-) diff --git a/Core/src/commands/guild/GuildLeaveCommand.ts b/Core/src/commands/guild/GuildLeaveCommand.ts index 36f66c229..d0a3e07a9 100644 --- a/Core/src/commands/guild/GuildLeaveCommand.ts +++ b/Core/src/commands/guild/GuildLeaveCommand.ts @@ -56,7 +56,7 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro })); } -export default class GuildElderCommand { +export default class GuildLeaveCommand { @commandRequires(CommandGuildLeavePacketReq, { notBlocked: true, disallowedEffects: CommandUtils.DISALLOWED_EFFECTS.NOT_STARTED_OR_DEAD, @@ -72,7 +72,8 @@ export default class GuildElderCommand { const collector = new ReactionCollectorGuildLeave( guild.name, - elder.keycloakId + elder.keycloakId, + guild.chiefId === player.id && guild.elderId === null ); const endCallback: EndCallback = async (collector: ReactionCollectorInstance, response: DraftBotPacket[]): Promise => { const reaction = collector.getFirstReaction(); diff --git a/Discord/src/commands/guild/GuildLeaveCommand.ts b/Discord/src/commands/guild/GuildLeaveCommand.ts index e69de29bb..9ac08ee15 100644 --- a/Discord/src/commands/guild/GuildLeaveCommand.ts +++ b/Discord/src/commands/guild/GuildLeaveCommand.ts @@ -0,0 +1,51 @@ +import {DraftbotInteraction} from "../../messages/DraftbotInteraction"; +import {KeycloakUser} from "../../../../Lib/src/keycloak/KeycloakUser"; +import {PacketUtils} from "../../utils/PacketUtils"; +import {makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPacket"; +import {ICommand} from "../ICommand"; +import {SlashCommandBuilderGenerator} from "../SlashCommandBuilderGenerator"; +import {CommandGuildLeavePacketReq} from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; +import {ReactionCollectorCreationPacket} from "../../../../Lib/src/packets/interaction/ReactionCollectorPacket"; +import {DiscordCache} from "../../bot/DiscordCache"; +import {DraftBotEmbed} from "../../messages/DraftBotEmbed"; +import i18n from "../../translations/i18n"; +import {DiscordCollectorUtils} from "../../utils/DiscordCollectorUtils"; +import {ReactionCollectorGuildLeaveData} from "../../../../Lib/src/packets/interaction/ReactionCollectorGuildLeave"; +import {KeycloakUtils} from "../../../../Lib/src/keycloak/KeycloakUtils"; +import {keycloakConfig} from "../../bot/DraftBotShard"; + + +export async function createGuildLeaveCollector(packet: ReactionCollectorCreationPacket, context: PacketContext): Promise { + const interaction = DiscordCache.getInteraction(context.discord!.interaction)!; + await interaction.deferReply(); + const data = packet.data.data as ReactionCollectorGuildLeaveData; + const elderPlayer = (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, data.newChiefKeycloakId))!; + const keyDesc = data.guildIsDestroyed ? data.newChiefKeycloakId !== null ? "confirmChiefDescWithElder" : "confirmChiefDesc" : "confirmDesc"; + const embed = new DraftBotEmbed().formatAuthor(i18n.t("commands:guildLeave.title", { + lng: interaction.userLanguage, + pseudo: interaction.user.displayName + }), interaction.user) + .setDescription( + i18n.t(`commands:guildLeave.${keyDesc}`, { + lng: interaction.userLanguage, + elderPseudo: elderPlayer.attributes.gameUsername, + guildName: data.guildName + }) + ); + + await DiscordCollectorUtils.createAcceptRefuseCollector(interaction, embed, packet, context); +} + +async function getPacket(interaction: DraftbotInteraction, user: KeycloakUser): Promise { + const askedPlayer = await PacketUtils.prepareAskedPlayer(interaction, user); + if (!askedPlayer || !askedPlayer.keycloakId) { + return null; + } + return makePacket(CommandGuildLeavePacketReq, {askedPlayerKeycloakId: askedPlayer.keycloakId}); +} + +export const commandInfo: ICommand = { + slashCommandBuilder: SlashCommandBuilderGenerator.generateBaseCommand("guildLeave"), + getPacket, + mainGuildCommand: false +}; \ No newline at end of file diff --git a/Discord/src/packetHandlers/handlers/CommandHandlers.ts b/Discord/src/packetHandlers/handlers/CommandHandlers.ts index 1c24c439f..694816e43 100644 --- a/Discord/src/packetHandlers/handlers/CommandHandlers.ts +++ b/Discord/src/packetHandlers/handlers/CommandHandlers.ts @@ -139,6 +139,14 @@ import { CommandGuildElderRefusePacketRes, CommandGuildElderSameGuildPacketRes } from "../../../../Lib/src/packets/commands/CommandGuildElderPacket"; +import { + handleCommandGuildElderAcceptPacketRes, + handleCommandGuildElderRefusePacketRes +} from "../../commands/guild/GuildElderCommand"; +import { + CommandGuildLeaveAcceptPacketRes, + CommandGuildLeaveRefusePacketRes +} from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; import {handleCommandGuildElderAcceptPacketRes, handleCommandGuildElderRefusePacketRes} from "../../commands/guild/GuildElderCommand"; import {CommandSwitchCancelled, CommandSwitchErrorNoItemToSwitch, CommandSwitchSuccess} from "../../../../Lib/src/packets/commands/CommandSwitchPacket"; import {handleItemSwitch} from "../../commands/player/SwitchCommand"; @@ -303,6 +311,16 @@ export default class CommandHandlers { await handleCommandGuildElderAcceptPacketRes(packet, context); } + @packetHandler(CommandGuildLeaveRefusePacketRes) + async guildLeaveRefuseRes(packet: CommandGuildLeaveRefusePacketRes, context: PacketContext): Promise { + // TODO + } + + @packetHandler(CommandGuildLeaveAcceptPacketRes) + async guildLeaveAcceptRes(packet: CommandGuildLeaveAcceptPacketRes, context: PacketContext): Promise { + // TODO + } + @packetHandler(CommandInventoryPacketRes) async inventoryRes(packet: CommandInventoryPacketRes, context: PacketContext): Promise { diff --git a/Discord/src/packetHandlers/handlers/ReactionCollectorHandlers.ts b/Discord/src/packetHandlers/handlers/ReactionCollectorHandlers.ts index c6aee577a..94f1e7ff6 100644 --- a/Discord/src/packetHandlers/handlers/ReactionCollectorHandlers.ts +++ b/Discord/src/packetHandlers/handlers/ReactionCollectorHandlers.ts @@ -43,6 +43,8 @@ import {ReactionCollectorSkipMissionShopItemData} from "../../../../Lib/src/pack import {skipMissionShopItemCollector} from "../../commands/mission/MissionShop"; import {createGuildElderCollector} from "../../commands/guild/GuildElderCommand"; import {ReactionCollectorGuildElderData} from "../../../../Lib/src/packets/interaction/ReactionCollectorGuildElder"; +import {ReactionCollectorGuildLeaveData} from "../../../../Lib/src/packets/interaction/ReactionCollectorGuildLeave"; +import {createGuildLeaveCollector} from "../../commands/guild/GuildLeaveCommand"; import {ReactionCollectorSwitchItemData} from "../../../../Lib/src/packets/interaction/ReactionCollectorSwitchItem"; import {switchItemCollector} from "../../commands/player/SwitchCommand"; @@ -59,6 +61,7 @@ export default class ReactionCollectorHandler { ReactionCollectorHandler.collectorMap.set(ReactionCollectorGuildCreateData.name, createGuildCreateCollector); ReactionCollectorHandler.collectorMap.set(ReactionCollectorGuildKickData.name, createGuildKickCollector); ReactionCollectorHandler.collectorMap.set(ReactionCollectorGuildElderData.name, createGuildElderCollector); + ReactionCollectorHandler.collectorMap.set(ReactionCollectorGuildLeaveData.name, createGuildLeaveCollector); ReactionCollectorHandler.collectorMap.set(ReactionCollectorLotteryData.name, lotteryCollector); ReactionCollectorHandler.collectorMap.set(ReactionCollectorInteractOtherPlayersPoorData.name, interactOtherPlayersCollector); ReactionCollectorHandler.collectorMap.set(ReactionCollectorWitchData.name, witchCollector); diff --git a/Lang/en/discordBuilder.json b/Lang/en/discordBuilder.json index cd7668282..ace47ec53 100644 --- a/Lang/en/discordBuilder.json +++ b/Lang/en/discordBuilder.json @@ -109,6 +109,20 @@ } } }, + "guildElder": { + "description": "Promote a guild member to elder.", + "name": "guildelder", + "options": { + "user": { + "description": "The user who will be promoted as an elder.", + "name": "user" + } + } + }, + "guildLeave": { + "description": "Leave your guild", + "name": "guildleave" + }, "profile": { "description": "Displays the profile of a player.", "name": "profile", diff --git a/Lang/fr/commands.json b/Lang/fr/commands.json index 8af59226e..a71ecd17f 100644 --- a/Lang/fr/commands.json +++ b/Lang/fr/commands.json @@ -96,6 +96,18 @@ "canceledTitle": "Annulation prise en compte.", "problemWhilePromoting": "Une erreur est survenue lors de la promotion du joueur." }, + "guildLeave": { + "title": "{pseudo}, confirmation :", + "confirmDesc": ":question: Souhaitez vous vraiment quitter la guilde `{{guildName}}` ?", + "confirmChiefDesc": ":question: Souhaitez vous vraiment **détruire définitivement** la guilde `{guildName}` ?", + "confirmChiefDescWithElder": ":question: Souhaitez vous vraiment quitter la guilde `{guildName}` ? {elderName} en deviendra le chef.", + "leavingCancelled": "Votre départ a été annulé.", + "successTitle": "{pseudo} a quitté la guilde {guildName} !", + "leavingSuccess": "You're a poor lonesome cowboy and a long long way from home...", + "newChiefTitle": ":crown: | La guilde **{guild}** a un nouveau chef !", + "leaveGuildTitle": "Quitter la guilde", + "guildDestroy": "Il semblerait que vous ayez déjà quitté la guilde." + }, "help": { "aliasFieldTitle": "Alias", "aliasesFieldTitle": "Alias", diff --git a/Lib/src/packets/commands/CommandGuildLeavePacket.ts b/Lib/src/packets/commands/CommandGuildLeavePacket.ts index 0c33dbb40..b408909b4 100644 --- a/Lib/src/packets/commands/CommandGuildLeavePacket.ts +++ b/Lib/src/packets/commands/CommandGuildLeavePacket.ts @@ -2,6 +2,7 @@ import {DraftBotPacket, PacketDirection, sendablePacket} from "../DraftBotPacket @sendablePacket(PacketDirection.FRONT_TO_BACK) export class CommandGuildLeavePacketReq extends DraftBotPacket { + askedPlayerKeycloakId!: string; } @sendablePacket(PacketDirection.BACK_TO_FRONT) diff --git a/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts b/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts index aeda15b14..212ebea93 100644 --- a/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts +++ b/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts @@ -9,7 +9,9 @@ import { export class ReactionCollectorGuildLeaveData extends ReactionCollectorData { guildName!: string; - newChiefKeycloakId!: string | null; + newChiefKeycloakId!: string; + + guildIsDestroyed!: boolean; } export class ReactionCollectorGuildLeave extends ReactionCollector { @@ -17,10 +19,13 @@ export class ReactionCollectorGuildLeave extends ReactionCollector { private readonly newChiefKeycloakId: string; - constructor(guildName: string, newChiefKeycloakId: string) { + private readonly guildIsDestroyed: boolean; + + constructor(guildName: string, newChiefKeycloakId: string, guildIsDestroyed: boolean) { super(); this.guildName = guildName; this.newChiefKeycloakId = newChiefKeycloakId; + this.guildIsDestroyed = guildIsDestroyed; } creationPacket(id: string, endTime: number): ReactionCollectorCreationPacket { @@ -33,7 +38,8 @@ export class ReactionCollectorGuildLeave extends ReactionCollector { ], data: this.buildData(ReactionCollectorGuildLeaveData, { guildName: this.guildName, - newChiefKeycloakId: this.newChiefKeycloakId + newChiefKeycloakId: this.newChiefKeycloakId, + guildIsDestroyed: this.guildIsDestroyed }) }; } From 4e35bf779ab860960368633da9896235e061f70d Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Fri, 17 Jan 2025 21:35:35 +0100 Subject: [PATCH 04/18] WIP on guildLeave #2273 --- Core/src/commands/guild/GuildLeaveCommand.ts | 14 +++++++- .../src/commands/guild/GuildLeaveCommand.ts | 35 ++++++++++++++++--- .../handlers/CommandHandlers.ts | 3 +- Lang/fr/commands.json | 12 +++---- .../commands/CommandGuildLeavePacket.ts | 4 ++- 5 files changed, 54 insertions(+), 14 deletions(-) diff --git a/Core/src/commands/guild/GuildLeaveCommand.ts b/Core/src/commands/guild/GuildLeaveCommand.ts index d0a3e07a9..09c516e0a 100644 --- a/Core/src/commands/guild/GuildLeaveCommand.ts +++ b/Core/src/commands/guild/GuildLeaveCommand.ts @@ -30,6 +30,7 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro // The guild's chief is leaving if (guild.elderId !== null) { // An elder can recover the guild + player.guildId = null; const elder = await Players.getById(guild.elderId); guild.elderId = null; guild.chiefId = elder.id; @@ -37,12 +38,19 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro newChiefKeycloakId: elder.keycloakId, guildName: guild.name })); + + await Promise.all([ + elder.save(), + guild.save(), + player.save() + ]); return; } // No elder => the guild will be destroyed await guild.completelyDestroyAndDeleteFromTheDatabase(); response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { - guildName: guild.name + guildName: guild.name, + isGuildDestroyed: true })); return; } @@ -54,6 +62,10 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { guildName: guild.name })); + await Promise.all([ + player.save(), + guild.save() + ]); } export default class GuildLeaveCommand { diff --git a/Discord/src/commands/guild/GuildLeaveCommand.ts b/Discord/src/commands/guild/GuildLeaveCommand.ts index 9ac08ee15..351413b81 100644 --- a/Discord/src/commands/guild/GuildLeaveCommand.ts +++ b/Discord/src/commands/guild/GuildLeaveCommand.ts @@ -4,7 +4,10 @@ import {PacketUtils} from "../../utils/PacketUtils"; import {makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPacket"; import {ICommand} from "../ICommand"; import {SlashCommandBuilderGenerator} from "../SlashCommandBuilderGenerator"; -import {CommandGuildLeavePacketReq} from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; +import { + CommandGuildLeaveAcceptPacketRes, + CommandGuildLeavePacketReq +} from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; import {ReactionCollectorCreationPacket} from "../../../../Lib/src/packets/interaction/ReactionCollectorPacket"; import {DiscordCache} from "../../bot/DiscordCache"; import {DraftBotEmbed} from "../../messages/DraftBotEmbed"; @@ -20,7 +23,7 @@ export async function createGuildLeaveCollector(packet: ReactionCollectorCreatio await interaction.deferReply(); const data = packet.data.data as ReactionCollectorGuildLeaveData; const elderPlayer = (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, data.newChiefKeycloakId))!; - const keyDesc = data.guildIsDestroyed ? data.newChiefKeycloakId !== null ? "confirmChiefDescWithElder" : "confirmChiefDesc" : "confirmDesc"; + const keyDesc = data.guildIsDestroyed ? "confirmChiefDesc" : data.newChiefKeycloakId !== null ? "confirmChiefDescWithElder" : "confirmDesc"; const embed = new DraftBotEmbed().formatAuthor(i18n.t("commands:guildLeave.title", { lng: interaction.userLanguage, pseudo: interaction.user.displayName @@ -36,12 +39,34 @@ export async function createGuildLeaveCollector(packet: ReactionCollectorCreatio await DiscordCollectorUtils.createAcceptRefuseCollector(interaction, embed, packet, context); } +export async function handleCommandGuildLeaveAcceptPacketRes(packet: CommandGuildLeaveAcceptPacketRes, context: PacketContext): Promise { + const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!); + const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!); + const keyTitle = packet.newChiefKeycloakId ? "newChiefTitle" : "successTitle"; + const keyDesc = packet.isGuildDestroyed ? "destroySuccess" : "leavingSuccess"; + const elder = (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, packet.newChiefKeycloakId!))!; + if (buttonInteraction && originalInteraction) { + await buttonInteraction.editReply({ + embeds: [ + new DraftBotEmbed().formatAuthor(i18n.t(`commands:guildLeave.${keyTitle}`, { + lng: originalInteraction.userLanguage, + elderPseudo: elder.attributes.gameUsername, + guildName: packet.guildName + }), originalInteraction.user) + .setDescription( + i18n.t(`commands:guildLeave.${keyDesc}`, {lng: originalInteraction.userLanguage, guildName: packet.guildName}) + ) + ] + }); + } +} + async function getPacket(interaction: DraftbotInteraction, user: KeycloakUser): Promise { - const askedPlayer = await PacketUtils.prepareAskedPlayer(interaction, user); - if (!askedPlayer || !askedPlayer.keycloakId) { + const player = await PacketUtils.prepareAskedPlayer(interaction, user); + if (!player || !player.keycloakId) { return null; } - return makePacket(CommandGuildLeavePacketReq, {askedPlayerKeycloakId: askedPlayer.keycloakId}); + return makePacket(CommandGuildLeavePacketReq, {playerKeycloakId: player.keycloakId}); } export const commandInfo: ICommand = { diff --git a/Discord/src/packetHandlers/handlers/CommandHandlers.ts b/Discord/src/packetHandlers/handlers/CommandHandlers.ts index 694816e43..1cbbdfda3 100644 --- a/Discord/src/packetHandlers/handlers/CommandHandlers.ts +++ b/Discord/src/packetHandlers/handlers/CommandHandlers.ts @@ -147,6 +147,7 @@ import { CommandGuildLeaveAcceptPacketRes, CommandGuildLeaveRefusePacketRes } from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; +import {handleCommandGuildLeaveAcceptPacketRes} from "../../commands/guild/GuildLeaveCommand"; import {handleCommandGuildElderAcceptPacketRes, handleCommandGuildElderRefusePacketRes} from "../../commands/guild/GuildElderCommand"; import {CommandSwitchCancelled, CommandSwitchErrorNoItemToSwitch, CommandSwitchSuccess} from "../../../../Lib/src/packets/commands/CommandSwitchPacket"; import {handleItemSwitch} from "../../commands/player/SwitchCommand"; @@ -318,7 +319,7 @@ export default class CommandHandlers { @packetHandler(CommandGuildLeaveAcceptPacketRes) async guildLeaveAcceptRes(packet: CommandGuildLeaveAcceptPacketRes, context: PacketContext): Promise { - // TODO + await handleCommandGuildLeaveAcceptPacketRes(packet,context); } diff --git a/Lang/fr/commands.json b/Lang/fr/commands.json index a71ecd17f..6874d3319 100644 --- a/Lang/fr/commands.json +++ b/Lang/fr/commands.json @@ -97,15 +97,15 @@ "problemWhilePromoting": "Une erreur est survenue lors de la promotion du joueur." }, "guildLeave": { - "title": "{pseudo}, confirmation :", + "title": "{{pseudo}}, confirmation :", "confirmDesc": ":question: Souhaitez vous vraiment quitter la guilde `{{guildName}}` ?", "confirmChiefDesc": ":question: Souhaitez vous vraiment **détruire définitivement** la guilde `{guildName}` ?", - "confirmChiefDescWithElder": ":question: Souhaitez vous vraiment quitter la guilde `{guildName}` ? {elderName} en deviendra le chef.", + "confirmChiefDescWithElder": ":question: Souhaitez vous vraiment quitter la guilde `{{guildName}}` ? {{elderPseudo}} en deviendra le chef.", "leavingCancelled": "Votre départ a été annulé.", - "successTitle": "{pseudo} a quitté la guilde {guildName} !", - "leavingSuccess": "You're a poor lonesome cowboy and a long long way from home...", - "newChiefTitle": ":crown: | La guilde **{guild}** a un nouveau chef !", - "leaveGuildTitle": "Quitter la guilde", + "successTitle": "{{pseudo}} a quitté la guilde {{guildName}} !", + "leavingSuccess": "Vous êtes un pauvre cow-boy solitaire et vous êtes très loin de chez vous...", + "destroySuccess": "La guilde {{guildName}} a correctement été dissoute.", + "newChiefTitle": ":crown: | {{elderPseudo}} est le nouveau chef de la guilde **{{guildName}}** !", "guildDestroy": "Il semblerait que vous ayez déjà quitté la guilde." }, "help": { diff --git a/Lib/src/packets/commands/CommandGuildLeavePacket.ts b/Lib/src/packets/commands/CommandGuildLeavePacket.ts index b408909b4..032179289 100644 --- a/Lib/src/packets/commands/CommandGuildLeavePacket.ts +++ b/Lib/src/packets/commands/CommandGuildLeavePacket.ts @@ -2,7 +2,7 @@ import {DraftBotPacket, PacketDirection, sendablePacket} from "../DraftBotPacket @sendablePacket(PacketDirection.FRONT_TO_BACK) export class CommandGuildLeavePacketReq extends DraftBotPacket { - askedPlayerKeycloakId!: string; + playerKeycloakId!: string; } @sendablePacket(PacketDirection.BACK_TO_FRONT) @@ -14,4 +14,6 @@ export class CommandGuildLeaveAcceptPacketRes extends DraftBotPacket { newChiefKeycloakId?: string; guildName!: string; + + isGuildDestroyed?: boolean; } \ No newline at end of file From ca15c90f1d63692a6f329ce147bfe0cc303c5984 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Fri, 17 Jan 2025 23:01:24 +0100 Subject: [PATCH 05/18] WIP on guildLeave #2273 --- Core/src/commands/guild/GuildLeaveCommand.ts | 6 ++++-- .../src/commands/guild/GuildLeaveCommand.ts | 19 ++++++------------- Lang/fr/commands.json | 4 ++-- .../commands/CommandGuildLeavePacket.ts | 3 +-- .../ReactionCollectorGuildLeave.ts | 6 +++--- 5 files changed, 16 insertions(+), 22 deletions(-) diff --git a/Core/src/commands/guild/GuildLeaveCommand.ts b/Core/src/commands/guild/GuildLeaveCommand.ts index 09c516e0a..5cf6b8a1a 100644 --- a/Core/src/commands/guild/GuildLeaveCommand.ts +++ b/Core/src/commands/guild/GuildLeaveCommand.ts @@ -49,6 +49,7 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro // No elder => the guild will be destroyed await guild.completelyDestroyAndDeleteFromTheDatabase(); response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { + newChiefKeycloakId: null, guildName: guild.name, isGuildDestroyed: true })); @@ -60,6 +61,7 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro } player.guildId = null; response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { + newChiefKeycloakId: null, guildName: guild.name })); await Promise.all([ @@ -80,11 +82,11 @@ export default class GuildLeaveCommand { return; } const guild = await Guilds.getById(player.guildId); - const elder = await Players.getById(guild.elderId); + const newChief = guild.chiefId === player.id && guild.elderId ? await Players.getById(guild.elderId) : null; const collector = new ReactionCollectorGuildLeave( guild.name, - elder.keycloakId, + newChief ? newChief.keycloakId : null, guild.chiefId === player.id && guild.elderId === null ); const endCallback: EndCallback = async (collector: ReactionCollectorInstance, response: DraftBotPacket[]): Promise => { diff --git a/Discord/src/commands/guild/GuildLeaveCommand.ts b/Discord/src/commands/guild/GuildLeaveCommand.ts index 351413b81..02858c933 100644 --- a/Discord/src/commands/guild/GuildLeaveCommand.ts +++ b/Discord/src/commands/guild/GuildLeaveCommand.ts @@ -1,6 +1,3 @@ -import {DraftbotInteraction} from "../../messages/DraftbotInteraction"; -import {KeycloakUser} from "../../../../Lib/src/keycloak/KeycloakUser"; -import {PacketUtils} from "../../utils/PacketUtils"; import {makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPacket"; import {ICommand} from "../ICommand"; import {SlashCommandBuilderGenerator} from "../SlashCommandBuilderGenerator"; @@ -22,7 +19,7 @@ export async function createGuildLeaveCollector(packet: ReactionCollectorCreatio const interaction = DiscordCache.getInteraction(context.discord!.interaction)!; await interaction.deferReply(); const data = packet.data.data as ReactionCollectorGuildLeaveData; - const elderPlayer = (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, data.newChiefKeycloakId))!; + const newChiefPseudo = data.newChiefKeycloakId !== null ? (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, data.newChiefKeycloakId))!.attributes.gameUsername : ""; const keyDesc = data.guildIsDestroyed ? "confirmChiefDesc" : data.newChiefKeycloakId !== null ? "confirmChiefDescWithElder" : "confirmDesc"; const embed = new DraftBotEmbed().formatAuthor(i18n.t("commands:guildLeave.title", { lng: interaction.userLanguage, @@ -31,7 +28,7 @@ export async function createGuildLeaveCollector(packet: ReactionCollectorCreatio .setDescription( i18n.t(`commands:guildLeave.${keyDesc}`, { lng: interaction.userLanguage, - elderPseudo: elderPlayer.attributes.gameUsername, + newChiefPseudo, guildName: data.guildName }) ); @@ -44,13 +41,13 @@ export async function handleCommandGuildLeaveAcceptPacketRes(packet: CommandGuil const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!); const keyTitle = packet.newChiefKeycloakId ? "newChiefTitle" : "successTitle"; const keyDesc = packet.isGuildDestroyed ? "destroySuccess" : "leavingSuccess"; - const elder = (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, packet.newChiefKeycloakId!))!; + const newChiefPseudo = packet.newChiefKeycloakId !== null ? (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, packet.newChiefKeycloakId))!.attributes.gameUsername : ""; if (buttonInteraction && originalInteraction) { await buttonInteraction.editReply({ embeds: [ new DraftBotEmbed().formatAuthor(i18n.t(`commands:guildLeave.${keyTitle}`, { lng: originalInteraction.userLanguage, - elderPseudo: elder.attributes.gameUsername, + newChiefPseudo, guildName: packet.guildName }), originalInteraction.user) .setDescription( @@ -61,12 +58,8 @@ export async function handleCommandGuildLeaveAcceptPacketRes(packet: CommandGuil } } -async function getPacket(interaction: DraftbotInteraction, user: KeycloakUser): Promise { - const player = await PacketUtils.prepareAskedPlayer(interaction, user); - if (!player || !player.keycloakId) { - return null; - } - return makePacket(CommandGuildLeavePacketReq, {playerKeycloakId: player.keycloakId}); +function getPacket(): CommandGuildLeavePacketReq { + return makePacket(CommandGuildLeavePacketReq, {}); } export const commandInfo: ICommand = { diff --git a/Lang/fr/commands.json b/Lang/fr/commands.json index 6874d3319..c92886177 100644 --- a/Lang/fr/commands.json +++ b/Lang/fr/commands.json @@ -100,12 +100,12 @@ "title": "{{pseudo}}, confirmation :", "confirmDesc": ":question: Souhaitez vous vraiment quitter la guilde `{{guildName}}` ?", "confirmChiefDesc": ":question: Souhaitez vous vraiment **détruire définitivement** la guilde `{guildName}` ?", - "confirmChiefDescWithElder": ":question: Souhaitez vous vraiment quitter la guilde `{{guildName}}` ? {{elderPseudo}} en deviendra le chef.", + "confirmChiefDescWithElder": ":question: Souhaitez vous vraiment quitter la guilde `{{newChiefPseudo}}` ? {{newChief}} en deviendra le chef.", "leavingCancelled": "Votre départ a été annulé.", "successTitle": "{{pseudo}} a quitté la guilde {{guildName}} !", "leavingSuccess": "Vous êtes un pauvre cow-boy solitaire et vous êtes très loin de chez vous...", "destroySuccess": "La guilde {{guildName}} a correctement été dissoute.", - "newChiefTitle": ":crown: | {{elderPseudo}} est le nouveau chef de la guilde **{{guildName}}** !", + "newChiefTitle": ":crown: | {{newChiefPseudo}} est le nouveau chef de la guilde **{{guildName}}** !", "guildDestroy": "Il semblerait que vous ayez déjà quitté la guilde." }, "help": { diff --git a/Lib/src/packets/commands/CommandGuildLeavePacket.ts b/Lib/src/packets/commands/CommandGuildLeavePacket.ts index 032179289..eeef9337c 100644 --- a/Lib/src/packets/commands/CommandGuildLeavePacket.ts +++ b/Lib/src/packets/commands/CommandGuildLeavePacket.ts @@ -2,7 +2,6 @@ import {DraftBotPacket, PacketDirection, sendablePacket} from "../DraftBotPacket @sendablePacket(PacketDirection.FRONT_TO_BACK) export class CommandGuildLeavePacketReq extends DraftBotPacket { - playerKeycloakId!: string; } @sendablePacket(PacketDirection.BACK_TO_FRONT) @@ -11,7 +10,7 @@ export class CommandGuildLeaveRefusePacketRes extends DraftBotPacket { @sendablePacket(PacketDirection.BACK_TO_FRONT) export class CommandGuildLeaveAcceptPacketRes extends DraftBotPacket { - newChiefKeycloakId?: string; + newChiefKeycloakId!: string | null; guildName!: string; diff --git a/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts b/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts index 212ebea93..59687fe5c 100644 --- a/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts +++ b/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts @@ -9,7 +9,7 @@ import { export class ReactionCollectorGuildLeaveData extends ReactionCollectorData { guildName!: string; - newChiefKeycloakId!: string; + newChiefKeycloakId!: string | null; guildIsDestroyed!: boolean; } @@ -17,11 +17,11 @@ export class ReactionCollectorGuildLeaveData extends ReactionCollectorData { export class ReactionCollectorGuildLeave extends ReactionCollector { private readonly guildName: string; - private readonly newChiefKeycloakId: string; + private readonly newChiefKeycloakId: string | null; private readonly guildIsDestroyed: boolean; - constructor(guildName: string, newChiefKeycloakId: string, guildIsDestroyed: boolean) { + constructor(guildName: string, newChiefKeycloakId: string | null, guildIsDestroyed: boolean) { super(); this.guildName = guildName; this.newChiefKeycloakId = newChiefKeycloakId; From ffb0d1d457f9e8dbc9ce5735779ad2d3c0991856 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Fri, 17 Jan 2025 23:03:28 +0100 Subject: [PATCH 06/18] small fix #2273 --- Discord/src/commands/guild/GuildLeaveCommand.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/Discord/src/commands/guild/GuildLeaveCommand.ts b/Discord/src/commands/guild/GuildLeaveCommand.ts index 02858c933..4b5ae6811 100644 --- a/Discord/src/commands/guild/GuildLeaveCommand.ts +++ b/Discord/src/commands/guild/GuildLeaveCommand.ts @@ -47,6 +47,7 @@ export async function handleCommandGuildLeaveAcceptPacketRes(packet: CommandGuil embeds: [ new DraftBotEmbed().formatAuthor(i18n.t(`commands:guildLeave.${keyTitle}`, { lng: originalInteraction.userLanguage, + pseudo: originalInteraction.user.displayName, newChiefPseudo, guildName: packet.guildName }), originalInteraction.user) From f68cdd1370451ecba7d098b150d377ac540a195d Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Sat, 18 Jan 2025 11:32:52 +0100 Subject: [PATCH 07/18] WIP on guildLeave #2273 --- Core/src/commands/guild/GuildLeaveCommand.ts | 4 +- .../src/commands/guild/GuildLeaveCommand.ts | 48 ++++++++++++++++++- .../handlers/CommandHandlers.ts | 21 +++++--- Lang/fr/commands.json | 11 +++-- .../commands/CommandGuildLeavePacket.ts | 4 ++ 5 files changed, 74 insertions(+), 14 deletions(-) diff --git a/Core/src/commands/guild/GuildLeaveCommand.ts b/Core/src/commands/guild/GuildLeaveCommand.ts index 5cf6b8a1a..a252887bf 100644 --- a/Core/src/commands/guild/GuildLeaveCommand.ts +++ b/Core/src/commands/guild/GuildLeaveCommand.ts @@ -3,7 +3,7 @@ import {GuildConstants} from "../../../../Lib/src/constants/GuildConstants"; import {DraftBotPacket, makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPacket"; import Player, {Players} from "../../core/database/game/models/Player"; import { - CommandGuildLeaveAcceptPacketRes, + CommandGuildLeaveAcceptPacketRes, CommandGuildLeaveNotInAGuildPacketRes, CommandGuildLeavePacketReq, CommandGuildLeaveRefusePacketRes } from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; import {Guilds} from "../../core/database/game/models/Guild"; @@ -23,6 +23,7 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro await player.reload(); // The player is no longer in a guild since the menu if (player.guildId === null) { + response.push(makePacket(CommandGuildLeaveNotInAGuildPacketRes, {})); return; } const guild = await Guilds.getById(player.guildId); @@ -79,6 +80,7 @@ export default class GuildLeaveCommand { }) async execute(response: DraftBotPacket[], player: Player, packet: CommandGuildLeavePacketReq, context: PacketContext): Promise { if (player.guildId === null) { + response.push(makePacket(CommandGuildLeaveNotInAGuildPacketRes, {})); return; } const guild = await Guilds.getById(player.guildId); diff --git a/Discord/src/commands/guild/GuildLeaveCommand.ts b/Discord/src/commands/guild/GuildLeaveCommand.ts index 4b5ae6811..cc9cc70b6 100644 --- a/Discord/src/commands/guild/GuildLeaveCommand.ts +++ b/Discord/src/commands/guild/GuildLeaveCommand.ts @@ -2,8 +2,8 @@ import {makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPac import {ICommand} from "../ICommand"; import {SlashCommandBuilderGenerator} from "../SlashCommandBuilderGenerator"; import { - CommandGuildLeaveAcceptPacketRes, - CommandGuildLeavePacketReq + CommandGuildLeaveAcceptPacketRes, CommandGuildLeaveNotInAGuildPacketRes, + CommandGuildLeavePacketReq, CommandGuildLeaveRefusePacketRes } from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; import {ReactionCollectorCreationPacket} from "../../../../Lib/src/packets/interaction/ReactionCollectorPacket"; import {DiscordCache} from "../../bot/DiscordCache"; @@ -59,6 +59,50 @@ export async function handleCommandGuildLeaveAcceptPacketRes(packet: CommandGuil } } +export async function handleCommandGuildLeaveRefusePacketRes(packet: CommandGuildLeaveRefusePacketRes, context: PacketContext): Promise { + const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!); + if (!originalInteraction) { + return; + } + const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!); + await buttonInteraction?.editReply({ + embeds: [ + new DraftBotEmbed().formatAuthor(i18n.t("commands:guildLeave.canceledTitle", { + lng: originalInteraction.userLanguage, + pseudo: originalInteraction.user.displayName + }), originalInteraction.user) + .setDescription( + i18n.t("commands:guildLeave.canceledDesc", { + lng: originalInteraction.userLanguage + }) + ) + .setErrorColor() + ] + }); +} + +export async function handleCommandGuildLeaveNotInAGuildRes(packet: CommandGuildLeaveNotInAGuildPacketRes, context: PacketContext): Promise { + const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!); + if (!originalInteraction) { + return; + } + const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!); + await buttonInteraction?.editReply({ + embeds: [ + new DraftBotEmbed().formatAuthor(i18n.t("error:titleDidntWork", { + lng: originalInteraction.userLanguage, + pseudo: originalInteraction.user.displayName + }), originalInteraction.user) + .setDescription( + i18n.t("commands:guildLeave.notInAGuild", { + lng: originalInteraction.userLanguage + }) + ) + .setErrorColor() + ] + }); +} + function getPacket(): CommandGuildLeavePacketReq { return makePacket(CommandGuildLeavePacketReq, {}); } diff --git a/Discord/src/packetHandlers/handlers/CommandHandlers.ts b/Discord/src/packetHandlers/handlers/CommandHandlers.ts index 1cbbdfda3..d9db4798b 100644 --- a/Discord/src/packetHandlers/handlers/CommandHandlers.ts +++ b/Discord/src/packetHandlers/handlers/CommandHandlers.ts @@ -144,9 +144,13 @@ import { handleCommandGuildElderRefusePacketRes } from "../../commands/guild/GuildElderCommand"; import { - CommandGuildLeaveAcceptPacketRes, + CommandGuildLeaveAcceptPacketRes, CommandGuildLeaveNotInAGuildPacketRes, CommandGuildLeaveRefusePacketRes } from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; +import { + handleCommandGuildLeaveAcceptPacketRes, handleCommandGuildLeaveNotInAGuildRes, + handleCommandGuildLeaveRefusePacketRes +} from "../../commands/guild/GuildLeaveCommand"; import {handleCommandGuildLeaveAcceptPacketRes} from "../../commands/guild/GuildLeaveCommand"; import {handleCommandGuildElderAcceptPacketRes, handleCommandGuildElderRefusePacketRes} from "../../commands/guild/GuildElderCommand"; import {CommandSwitchCancelled, CommandSwitchErrorNoItemToSwitch, CommandSwitchSuccess} from "../../../../Lib/src/packets/commands/CommandSwitchPacket"; @@ -283,22 +287,22 @@ export default class CommandHandlers { } @packetHandler(CommandGuildElderSameGuildPacketRes) - async guildElderSameGuildRes(packet: CommandGuildElderSameGuildPacketRes, context: PacketContext): Promise { + async guildElderSameGuildRes(_packet: CommandGuildElderSameGuildPacketRes, context: PacketContext): Promise { await handleClassicError(context, "commands:guildElder.notSameGuild"); } @packetHandler(CommandGuildElderHimselfPacketRes) - async guildElderHimselfRes(packet: CommandGuildElderHimselfPacketRes, context: PacketContext): Promise { + async guildElderHimselfRes(_packet: CommandGuildElderHimselfPacketRes, context: PacketContext): Promise { await handleClassicError(context, "commands:guildElder.chiefError"); } @packetHandler(CommandGuildElderAlreadyElderPacketRes) - async guildElderAlreadyElderRes(packet: CommandGuildElderAlreadyElderPacketRes, context: PacketContext): Promise { + async guildElderAlreadyElderRes(_packet: CommandGuildElderAlreadyElderPacketRes, context: PacketContext): Promise { await handleClassicError(context, "commands:guildElder.alreadyElder"); } @packetHandler(CommandGuildElderFoundPlayerPacketRes) - async guildElderFoundPlayerRes(packet: CommandGuildElderFoundPlayerPacketRes, context: PacketContext): Promise { + async guildElderFoundPlayerRes(_packet: CommandGuildElderFoundPlayerPacketRes, context: PacketContext): Promise { await handleClassicError(context, "commands:guildElder.playerNotFound"); } @@ -312,9 +316,14 @@ export default class CommandHandlers { await handleCommandGuildElderAcceptPacketRes(packet, context); } + @packetHandler(CommandGuildLeaveNotInAGuildPacketRes) + async guildLeaveNotInAGuildRes(packet: CommandGuildLeaveNotInAGuildPacketRes, context: PacketContext): Promise { + await handleCommandGuildLeaveNotInAGuildRes(packet, context); + } + @packetHandler(CommandGuildLeaveRefusePacketRes) async guildLeaveRefuseRes(packet: CommandGuildLeaveRefusePacketRes, context: PacketContext): Promise { - // TODO + await handleCommandGuildLeaveRefusePacketRes(packet, context); } @packetHandler(CommandGuildLeaveAcceptPacketRes) diff --git a/Lang/fr/commands.json b/Lang/fr/commands.json index c92886177..52461aeb5 100644 --- a/Lang/fr/commands.json +++ b/Lang/fr/commands.json @@ -99,14 +99,15 @@ "guildLeave": { "title": "{{pseudo}}, confirmation :", "confirmDesc": ":question: Souhaitez vous vraiment quitter la guilde `{{guildName}}` ?", - "confirmChiefDesc": ":question: Souhaitez vous vraiment **détruire définitivement** la guilde `{guildName}` ?", - "confirmChiefDescWithElder": ":question: Souhaitez vous vraiment quitter la guilde `{{newChiefPseudo}}` ? {{newChief}} en deviendra le chef.", - "leavingCancelled": "Votre départ a été annulé.", + "confirmChiefDesc": ":question: Souhaitez vous vraiment **détruire définitivement** la guilde `{{guildName}}` ?", + "confirmChiefDescWithElder": ":question: Souhaitez vous vraiment quitter la guilde `{{guildName}}` ? {{newChiefPseudo}} en deviendra le chef.", + "canceledDesc": "Votre départ a été annulé.", "successTitle": "{{pseudo}} a quitté la guilde {{guildName}} !", "leavingSuccess": "Vous êtes un pauvre cow-boy solitaire et vous êtes très loin de chez vous...", "destroySuccess": "La guilde {{guildName}} a correctement été dissoute.", - "newChiefTitle": ":crown: | {{newChiefPseudo}} est le nouveau chef de la guilde **{{guildName}}** !", - "guildDestroy": "Il semblerait que vous ayez déjà quitté la guilde." + "newChiefTitle": "{{newChiefPseudo}} est le nouveau chef de la guilde {{guildName}} !", + "notInAGuild": "Il semblerait que vous ne fassiez déjà plus parti d'une guilde.", + "canceledTitle": "Annulation prise en compte" }, "help": { "aliasFieldTitle": "Alias", diff --git a/Lib/src/packets/commands/CommandGuildLeavePacket.ts b/Lib/src/packets/commands/CommandGuildLeavePacket.ts index eeef9337c..6cff1cb10 100644 --- a/Lib/src/packets/commands/CommandGuildLeavePacket.ts +++ b/Lib/src/packets/commands/CommandGuildLeavePacket.ts @@ -15,4 +15,8 @@ export class CommandGuildLeaveAcceptPacketRes extends DraftBotPacket { guildName!: string; isGuildDestroyed?: boolean; +} + +@sendablePacket(PacketDirection.BACK_TO_FRONT) +export class CommandGuildLeaveNotInAGuildPacketRes extends DraftBotPacket { } \ No newline at end of file From bee4765b1b3b94c8c174ef0a430ef2b3f86dd387 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Sat, 18 Jan 2025 11:45:37 +0100 Subject: [PATCH 08/18] fix on guildElder #2273 --- .../src/commands/guild/GuildElderCommand.ts | 24 ++++++++++++++++++- .../handlers/CommandHandlers.ts | 6 ++--- Lang/fr/commands.json | 3 +-- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Discord/src/commands/guild/GuildElderCommand.ts b/Discord/src/commands/guild/GuildElderCommand.ts index 78a60a25f..9b406555d 100644 --- a/Discord/src/commands/guild/GuildElderCommand.ts +++ b/Discord/src/commands/guild/GuildElderCommand.ts @@ -10,7 +10,7 @@ import {ReactionCollectorGuildElderData} from "../../../../Lib/src/packets/inter import { CommandGuildElderAcceptPacketRes, CommandGuildElderPacketReq, - CommandGuildElderRefusePacketRes + CommandGuildElderRefusePacketRes, CommandGuildElderSameGuildPacketRes } from "../../../../Lib/src/packets/commands/CommandGuildElderPacket"; import {ICommand} from "../ICommand"; import {SlashCommandBuilderGenerator} from "../SlashCommandBuilderGenerator"; @@ -73,6 +73,28 @@ export async function handleCommandGuildElderRefusePacketRes(packet: CommandGuil ] }); } +export async function handleCommandGuildElderNotSameGuildPacketRes(packet: CommandGuildElderSameGuildPacketRes, context: PacketContext): Promise { + const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!); + if (!originalInteraction) { + return; + } + const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!); + await buttonInteraction?.editReply({ + embeds: [ + new DraftBotEmbed().formatAuthor(i18n.t("error:titleDidntWork", { + lng: originalInteraction.userLanguage, + pseudo: originalInteraction.user.displayName + }), originalInteraction.user) + .setDescription( + i18n.t("commands:guildElder.notSameGuild", { + lng: originalInteraction.userLanguage + }) + ) + .setErrorColor() + ] + }); +} + /** * Handle the response of the server after a guild elder, diff --git a/Discord/src/packetHandlers/handlers/CommandHandlers.ts b/Discord/src/packetHandlers/handlers/CommandHandlers.ts index d9db4798b..159655b47 100644 --- a/Discord/src/packetHandlers/handlers/CommandHandlers.ts +++ b/Discord/src/packetHandlers/handlers/CommandHandlers.ts @@ -140,7 +140,7 @@ import { CommandGuildElderSameGuildPacketRes } from "../../../../Lib/src/packets/commands/CommandGuildElderPacket"; import { - handleCommandGuildElderAcceptPacketRes, + handleCommandGuildElderAcceptPacketRes, handleCommandGuildElderNotSameGuildPacketRes, handleCommandGuildElderRefusePacketRes } from "../../commands/guild/GuildElderCommand"; import { @@ -287,8 +287,8 @@ export default class CommandHandlers { } @packetHandler(CommandGuildElderSameGuildPacketRes) - async guildElderSameGuildRes(_packet: CommandGuildElderSameGuildPacketRes, context: PacketContext): Promise { - await handleClassicError(context, "commands:guildElder.notSameGuild"); + async guildElderSameGuildRes(packet: CommandGuildElderSameGuildPacketRes, context: PacketContext): Promise { + await handleCommandGuildElderNotSameGuildPacketRes(packet, context); } @packetHandler(CommandGuildElderHimselfPacketRes) diff --git a/Lang/fr/commands.json b/Lang/fr/commands.json index 52461aeb5..0cbb6091c 100644 --- a/Lang/fr/commands.json +++ b/Lang/fr/commands.json @@ -93,8 +93,7 @@ "successElderAddTitle": "{{elderPseudo}} est le nouvel aîné de la guilde {{guildName}} !", "acceptedDesc": "L'aîné sert à aider le chef dans la gestion de la guilde. Il faut donc le choisir avec prudence ! Mais rassurez-vous, si vous n'êtes pas satisfait de votre aîné, vous pouvez le remplacer avec la commande {command:guildelder}, ou si vous avez une âme de dictateur, vous pouvez définitivement le supprimer avec {command:guildelderremove}.", "canceledDesc": "L'aîné n'a pas été promu.", - "canceledTitle": "Annulation prise en compte.", - "problemWhilePromoting": "Une erreur est survenue lors de la promotion du joueur." + "canceledTitle": "Annulation prise en compte." }, "guildLeave": { "title": "{{pseudo}}, confirmation :", From e804f3b336f873181fd9cdf92c6f247ff33f834d Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Sat, 18 Jan 2025 11:53:56 +0100 Subject: [PATCH 09/18] add logs #2273 --- Core/src/commands/guild/GuildKickCommand.ts | 1 + Core/src/commands/guild/GuildLeaveCommand.ts | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Core/src/commands/guild/GuildKickCommand.ts b/Core/src/commands/guild/GuildKickCommand.ts index 53ad51bc2..7993c9554 100644 --- a/Core/src/commands/guild/GuildKickCommand.ts +++ b/Core/src/commands/guild/GuildKickCommand.ts @@ -28,6 +28,7 @@ async function acceptGuildKick(player: Player, kickedPlayer: Player, response: D kickedPlayer.guildId = null; if (guild.elderId === kickedPlayer.id) { + await draftBotInstance.logsDatabase.logGuildElderRemove(guild, guild.elderId); guild.elderId = null; } await Promise.all([ diff --git a/Core/src/commands/guild/GuildLeaveCommand.ts b/Core/src/commands/guild/GuildLeaveCommand.ts index a252887bf..d92a1340b 100644 --- a/Core/src/commands/guild/GuildLeaveCommand.ts +++ b/Core/src/commands/guild/GuildLeaveCommand.ts @@ -12,6 +12,8 @@ import {EndCallback, ReactionCollectorInstance} from "../../core/utils/Reactions import {ReactionCollectorAcceptReaction} from "../../../../Lib/src/packets/interaction/ReactionCollectorPacket"; import {BlockingUtils} from "../../core/utils/BlockingUtils"; import {BlockingConstants} from "../../../../Lib/src/constants/BlockingConstants"; +import {draftBotInstance} from "../../index"; +import {LogsDatabase} from "../../core/database/logs/LogsDatabase"; /** @@ -30,6 +32,8 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro if (player.id === guild.chiefId) { // The guild's chief is leaving if (guild.elderId !== null) { + await draftBotInstance.logsDatabase.logGuildElderRemove(guild, guild.elderId); + await draftBotInstance.logsDatabase.logGuildChiefChange(guild, guild.elderId); // An elder can recover the guild player.guildId = null; const elder = await Players.getById(guild.elderId); @@ -58,8 +62,10 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro } if (guild.elderId === player.id) { // The guild's elder is leaving + await draftBotInstance.logsDatabase.logGuildElderRemove(guild, guild.elderId); guild.elderId = null; } + LogsDatabase.logGuildLeave(guild, player.keycloakId).then(); player.guildId = null; response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { newChiefKeycloakId: null, From ece98f8ecea86212986fab18f9eb4616b69f4692 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Sat, 18 Jan 2025 11:59:31 +0100 Subject: [PATCH 10/18] add docstrings #2273 --- .../src/commands/guild/GuildElderCommand.ts | 6 +++++ .../src/commands/guild/GuildLeaveCommand.ts | 24 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Discord/src/commands/guild/GuildElderCommand.ts b/Discord/src/commands/guild/GuildElderCommand.ts index 9b406555d..8b0879e00 100644 --- a/Discord/src/commands/guild/GuildElderCommand.ts +++ b/Discord/src/commands/guild/GuildElderCommand.ts @@ -73,6 +73,12 @@ export async function handleCommandGuildElderRefusePacketRes(packet: CommandGuil ] }); } + +/** + * Handle the response when the user is not in the guild + * @param packet + * @param context + */ export async function handleCommandGuildElderNotSameGuildPacketRes(packet: CommandGuildElderSameGuildPacketRes, context: PacketContext): Promise { const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!); if (!originalInteraction) { diff --git a/Discord/src/commands/guild/GuildLeaveCommand.ts b/Discord/src/commands/guild/GuildLeaveCommand.ts index cc9cc70b6..e4f40e8af 100644 --- a/Discord/src/commands/guild/GuildLeaveCommand.ts +++ b/Discord/src/commands/guild/GuildLeaveCommand.ts @@ -14,7 +14,11 @@ import {ReactionCollectorGuildLeaveData} from "../../../../Lib/src/packets/inter import {KeycloakUtils} from "../../../../Lib/src/keycloak/KeycloakUtils"; import {keycloakConfig} from "../../bot/DraftBotShard"; - +/** + * Create a collector to accept/refuse to leave the guild + * @param packet + * @param context + */ export async function createGuildLeaveCollector(packet: ReactionCollectorCreationPacket, context: PacketContext): Promise { const interaction = DiscordCache.getInteraction(context.discord!.interaction)!; await interaction.deferReply(); @@ -36,6 +40,11 @@ export async function createGuildLeaveCollector(packet: ReactionCollectorCreatio await DiscordCollectorUtils.createAcceptRefuseCollector(interaction, embed, packet, context); } +/** + * Handle the response when the player leave its guild + * @param packet + * @param context + */ export async function handleCommandGuildLeaveAcceptPacketRes(packet: CommandGuildLeaveAcceptPacketRes, context: PacketContext): Promise { const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!); const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!); @@ -59,6 +68,11 @@ export async function handleCommandGuildLeaveAcceptPacketRes(packet: CommandGuil } } +/** + * Handle the response when the player don't leave its guild + * @param packet + * @param context + */ export async function handleCommandGuildLeaveRefusePacketRes(packet: CommandGuildLeaveRefusePacketRes, context: PacketContext): Promise { const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!); if (!originalInteraction) { @@ -81,6 +95,11 @@ export async function handleCommandGuildLeaveRefusePacketRes(packet: CommandGuil }); } +/** + * Handle the response when the user is not in the guild + * @param packet + * @param context + */ export async function handleCommandGuildLeaveNotInAGuildRes(packet: CommandGuildLeaveNotInAGuildPacketRes, context: PacketContext): Promise { const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!); if (!originalInteraction) { @@ -103,6 +122,9 @@ export async function handleCommandGuildLeaveNotInAGuildRes(packet: CommandGuild }); } +/** + * Allow the player to leave its guild + */ function getPacket(): CommandGuildLeavePacketReq { return makePacket(CommandGuildLeavePacketReq, {}); } From bc939ce975791ad37a1e2970032b582bdad3fef2 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Sun, 19 Jan 2025 14:39:07 +0100 Subject: [PATCH 11/18] fixes from review #2273 --- Core/src/commands/guild/GuildLeaveCommand.ts | 10 ++-------- Discord/src/commands/guild/GuildLeaveCommand.ts | 6 +++--- .../packets/commands/CommandGuildLeavePacket.ts | 2 +- .../interaction/ReactionCollectorGuildLeave.ts | 14 +++++++------- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/Core/src/commands/guild/GuildLeaveCommand.ts b/Core/src/commands/guild/GuildLeaveCommand.ts index d92a1340b..aa8397d5f 100644 --- a/Core/src/commands/guild/GuildLeaveCommand.ts +++ b/Core/src/commands/guild/GuildLeaveCommand.ts @@ -54,7 +54,6 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro // No elder => the guild will be destroyed await guild.completelyDestroyAndDeleteFromTheDatabase(); response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { - newChiefKeycloakId: null, guildName: guild.name, isGuildDestroyed: true })); @@ -68,7 +67,6 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro LogsDatabase.logGuildLeave(guild, player.keycloakId).then(); player.guildId = null; response.push(makePacket(CommandGuildLeaveAcceptPacketRes, { - newChiefKeycloakId: null, guildName: guild.name })); await Promise.all([ @@ -85,17 +83,13 @@ export default class GuildLeaveCommand { guildNeeded: true }) async execute(response: DraftBotPacket[], player: Player, packet: CommandGuildLeavePacketReq, context: PacketContext): Promise { - if (player.guildId === null) { - response.push(makePacket(CommandGuildLeaveNotInAGuildPacketRes, {})); - return; - } const guild = await Guilds.getById(player.guildId); const newChief = guild.chiefId === player.id && guild.elderId ? await Players.getById(guild.elderId) : null; const collector = new ReactionCollectorGuildLeave( guild.name, - newChief ? newChief.keycloakId : null, - guild.chiefId === player.id && guild.elderId === null + guild.chiefId === player.id && guild.elderId === null, + newChief?.keycloakId ); const endCallback: EndCallback = async (collector: ReactionCollectorInstance, response: DraftBotPacket[]): Promise => { const reaction = collector.getFirstReaction(); diff --git a/Discord/src/commands/guild/GuildLeaveCommand.ts b/Discord/src/commands/guild/GuildLeaveCommand.ts index e4f40e8af..4c511e369 100644 --- a/Discord/src/commands/guild/GuildLeaveCommand.ts +++ b/Discord/src/commands/guild/GuildLeaveCommand.ts @@ -23,8 +23,8 @@ export async function createGuildLeaveCollector(packet: ReactionCollectorCreatio const interaction = DiscordCache.getInteraction(context.discord!.interaction)!; await interaction.deferReply(); const data = packet.data.data as ReactionCollectorGuildLeaveData; - const newChiefPseudo = data.newChiefKeycloakId !== null ? (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, data.newChiefKeycloakId))!.attributes.gameUsername : ""; - const keyDesc = data.guildIsDestroyed ? "confirmChiefDesc" : data.newChiefKeycloakId !== null ? "confirmChiefDescWithElder" : "confirmDesc"; + const newChiefPseudo = data.newChiefKeycloakId ? (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, data.newChiefKeycloakId))!.attributes.gameUsername : ""; + const keyDesc = data.isGuildDestroyed ? "confirmChiefDesc" : data.newChiefKeycloakId !== null ? "confirmChiefDescWithElder" : "confirmDesc"; const embed = new DraftBotEmbed().formatAuthor(i18n.t("commands:guildLeave.title", { lng: interaction.userLanguage, pseudo: interaction.user.displayName @@ -50,7 +50,7 @@ export async function handleCommandGuildLeaveAcceptPacketRes(packet: CommandGuil const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!); const keyTitle = packet.newChiefKeycloakId ? "newChiefTitle" : "successTitle"; const keyDesc = packet.isGuildDestroyed ? "destroySuccess" : "leavingSuccess"; - const newChiefPseudo = packet.newChiefKeycloakId !== null ? (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, packet.newChiefKeycloakId))!.attributes.gameUsername : ""; + const newChiefPseudo = packet.newChiefKeycloakId ? (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, packet.newChiefKeycloakId))!.attributes.gameUsername : ""; if (buttonInteraction && originalInteraction) { await buttonInteraction.editReply({ embeds: [ diff --git a/Lib/src/packets/commands/CommandGuildLeavePacket.ts b/Lib/src/packets/commands/CommandGuildLeavePacket.ts index 6cff1cb10..3f9c0b2aa 100644 --- a/Lib/src/packets/commands/CommandGuildLeavePacket.ts +++ b/Lib/src/packets/commands/CommandGuildLeavePacket.ts @@ -10,7 +10,7 @@ export class CommandGuildLeaveRefusePacketRes extends DraftBotPacket { @sendablePacket(PacketDirection.BACK_TO_FRONT) export class CommandGuildLeaveAcceptPacketRes extends DraftBotPacket { - newChiefKeycloakId!: string | null; + newChiefKeycloakId?: string; guildName!: string; diff --git a/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts b/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts index 59687fe5c..f58d2f5e2 100644 --- a/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts +++ b/Lib/src/packets/interaction/ReactionCollectorGuildLeave.ts @@ -9,23 +9,23 @@ import { export class ReactionCollectorGuildLeaveData extends ReactionCollectorData { guildName!: string; - newChiefKeycloakId!: string | null; + isGuildDestroyed!: boolean; - guildIsDestroyed!: boolean; + newChiefKeycloakId!: string; } export class ReactionCollectorGuildLeave extends ReactionCollector { private readonly guildName: string; - private readonly newChiefKeycloakId: string | null; + private readonly newChiefKeycloakId: string; - private readonly guildIsDestroyed: boolean; + private readonly isGuildDestroyed: boolean; - constructor(guildName: string, newChiefKeycloakId: string | null, guildIsDestroyed: boolean) { + constructor(guildName: string, isGuildDestroyed: boolean, newChiefKeycloakId: string) { super(); this.guildName = guildName; this.newChiefKeycloakId = newChiefKeycloakId; - this.guildIsDestroyed = guildIsDestroyed; + this.isGuildDestroyed = isGuildDestroyed; } creationPacket(id: string, endTime: number): ReactionCollectorCreationPacket { @@ -39,7 +39,7 @@ export class ReactionCollectorGuildLeave extends ReactionCollector { data: this.buildData(ReactionCollectorGuildLeaveData, { guildName: this.guildName, newChiefKeycloakId: this.newChiefKeycloakId, - guildIsDestroyed: this.guildIsDestroyed + isGuildDestroyed: this.isGuildDestroyed }) }; } From 6bed7cae560d3946646adcef60b04d7c226eee4a Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Sun, 19 Jan 2025 14:43:33 +0100 Subject: [PATCH 12/18] fix emotes #2273 --- Lang/fr/commands.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lang/fr/commands.json b/Lang/fr/commands.json index 0cbb6091c..227eb4293 100644 --- a/Lang/fr/commands.json +++ b/Lang/fr/commands.json @@ -89,7 +89,7 @@ "chiefError": "En tant que chef de la guilde, vous ne pouvez pas être l'aîné.", "alreadyElder": "Le joueur est déjà aîné de votre guilde.", "title": "{{pseudo}}, confirmez-vous votre choix ?", - "confirmDesc": ":question: {{elderPseudo}} deviendra l'aîné de la guilde `{{guildName}}`.", + "confirmDesc": "{emote:collectors.question} {{elderPseudo}} deviendra l'aîné de la guilde `{{guildName}}`.", "successElderAddTitle": "{{elderPseudo}} est le nouvel aîné de la guilde {{guildName}} !", "acceptedDesc": "L'aîné sert à aider le chef dans la gestion de la guilde. Il faut donc le choisir avec prudence ! Mais rassurez-vous, si vous n'êtes pas satisfait de votre aîné, vous pouvez le remplacer avec la commande {command:guildelder}, ou si vous avez une âme de dictateur, vous pouvez définitivement le supprimer avec {command:guildelderremove}.", "canceledDesc": "L'aîné n'a pas été promu.", @@ -97,9 +97,9 @@ }, "guildLeave": { "title": "{{pseudo}}, confirmation :", - "confirmDesc": ":question: Souhaitez vous vraiment quitter la guilde `{{guildName}}` ?", - "confirmChiefDesc": ":question: Souhaitez vous vraiment **détruire définitivement** la guilde `{{guildName}}` ?", - "confirmChiefDescWithElder": ":question: Souhaitez vous vraiment quitter la guilde `{{guildName}}` ? {{newChiefPseudo}} en deviendra le chef.", + "confirmDesc": "{emote:collectors.question} Souhaitez vous vraiment quitter la guilde `{{guildName}}` ?", + "confirmChiefDesc": "{emote:collectors.question} Souhaitez vous vraiment **détruire définitivement** la guilde `{{guildName}}` ?", + "confirmChiefDescWithElder": "{emote:collectors.question} Souhaitez vous vraiment quitter la guilde `{{guildName}}` ? {{newChiefPseudo}} en deviendra le chef.", "canceledDesc": "Votre départ a été annulé.", "successTitle": "{{pseudo}} a quitté la guilde {{guildName}} !", "leavingSuccess": "Vous êtes un pauvre cow-boy solitaire et vous êtes très loin de chez vous...", From 398aa9c90c5c99a924c491fe1efe1af8005aa30b Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Thu, 23 Jan 2025 02:12:30 +0100 Subject: [PATCH 13/18] handleClassicError on notSameGuild for guildElder --- Discord/src/packetHandlers/handlers/CommandHandlers.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Discord/src/packetHandlers/handlers/CommandHandlers.ts b/Discord/src/packetHandlers/handlers/CommandHandlers.ts index 159655b47..8cb2731a7 100644 --- a/Discord/src/packetHandlers/handlers/CommandHandlers.ts +++ b/Discord/src/packetHandlers/handlers/CommandHandlers.ts @@ -287,8 +287,8 @@ export default class CommandHandlers { } @packetHandler(CommandGuildElderSameGuildPacketRes) - async guildElderSameGuildRes(packet: CommandGuildElderSameGuildPacketRes, context: PacketContext): Promise { - await handleCommandGuildElderNotSameGuildPacketRes(packet, context); + async guildElderSameGuildRes(_packet: CommandGuildElderSameGuildPacketRes, context: PacketContext): Promise { + await handleClassicError(context, "commands:guildElder.notSameGuild"); } @packetHandler(CommandGuildElderHimselfPacketRes) From ffb722f1a46a7ac759ece282b7edea9744289142 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Thu, 23 Jan 2025 02:12:49 +0100 Subject: [PATCH 14/18] handleClassicError on notSameGuild for guildElder --- Discord/src/packetHandlers/handlers/CommandHandlers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Discord/src/packetHandlers/handlers/CommandHandlers.ts b/Discord/src/packetHandlers/handlers/CommandHandlers.ts index 8cb2731a7..5c82732e9 100644 --- a/Discord/src/packetHandlers/handlers/CommandHandlers.ts +++ b/Discord/src/packetHandlers/handlers/CommandHandlers.ts @@ -140,7 +140,7 @@ import { CommandGuildElderSameGuildPacketRes } from "../../../../Lib/src/packets/commands/CommandGuildElderPacket"; import { - handleCommandGuildElderAcceptPacketRes, handleCommandGuildElderNotSameGuildPacketRes, + handleCommandGuildElderAcceptPacketRes, handleCommandGuildElderRefusePacketRes } from "../../commands/guild/GuildElderCommand"; import { From 25f6702b8489ef1fb361f1d6382285b338ed0b1c Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Thu, 23 Jan 2025 02:26:20 +0100 Subject: [PATCH 15/18] endCallback function guildLeave #2723 --- Core/src/commands/guild/GuildLeaveCommand.ts | 24 ++++++++------- .../src/commands/guild/GuildElderCommand.ts | 29 +------------------ 2 files changed, 14 insertions(+), 39 deletions(-) diff --git a/Core/src/commands/guild/GuildLeaveCommand.ts b/Core/src/commands/guild/GuildLeaveCommand.ts index aa8397d5f..b930e7021 100644 --- a/Core/src/commands/guild/GuildLeaveCommand.ts +++ b/Core/src/commands/guild/GuildLeaveCommand.ts @@ -75,6 +75,18 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro ]); } +function endCallback(player: Player): EndCallback { + return async (collector, response): Promise => { + const reaction = collector.getFirstReaction(); + if (reaction && reaction.reaction.type === ReactionCollectorAcceptReaction.name) { + await acceptGuildLeave(player, response); + } + else { + response.push(makePacket(CommandGuildLeaveRefusePacketRes, {})); + } + BlockingUtils.unblockPlayer(player.id, BlockingConstants.REASONS.GUILD_LEAVE); + }; +} export default class GuildLeaveCommand { @commandRequires(CommandGuildLeavePacketReq, { notBlocked: true, @@ -91,16 +103,6 @@ export default class GuildLeaveCommand { guild.chiefId === player.id && guild.elderId === null, newChief?.keycloakId ); - const endCallback: EndCallback = async (collector: ReactionCollectorInstance, response: DraftBotPacket[]): Promise => { - const reaction = collector.getFirstReaction(); - if (reaction && reaction.reaction.type === ReactionCollectorAcceptReaction.name) { - await acceptGuildLeave(player, response); - } - else { - response.push(makePacket(CommandGuildLeaveRefusePacketRes, {})); - } - BlockingUtils.unblockPlayer(player.id, BlockingConstants.REASONS.GUILD_LEAVE); - }; const collectorPacket = new ReactionCollectorInstance( collector, @@ -109,7 +111,7 @@ export default class GuildLeaveCommand { allowedPlayerKeycloakIds: [player.keycloakId], reactionLimit: 1 }, - endCallback + endCallback(player) ) .block(player.id, BlockingConstants.REASONS.GUILD_LEAVE) .build(); diff --git a/Discord/src/commands/guild/GuildElderCommand.ts b/Discord/src/commands/guild/GuildElderCommand.ts index 8b0879e00..8b173b7f4 100644 --- a/Discord/src/commands/guild/GuildElderCommand.ts +++ b/Discord/src/commands/guild/GuildElderCommand.ts @@ -10,7 +10,7 @@ import {ReactionCollectorGuildElderData} from "../../../../Lib/src/packets/inter import { CommandGuildElderAcceptPacketRes, CommandGuildElderPacketReq, - CommandGuildElderRefusePacketRes, CommandGuildElderSameGuildPacketRes + CommandGuildElderRefusePacketRes } from "../../../../Lib/src/packets/commands/CommandGuildElderPacket"; import {ICommand} from "../ICommand"; import {SlashCommandBuilderGenerator} from "../SlashCommandBuilderGenerator"; @@ -74,33 +74,6 @@ export async function handleCommandGuildElderRefusePacketRes(packet: CommandGuil }); } -/** - * Handle the response when the user is not in the guild - * @param packet - * @param context - */ -export async function handleCommandGuildElderNotSameGuildPacketRes(packet: CommandGuildElderSameGuildPacketRes, context: PacketContext): Promise { - const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!); - if (!originalInteraction) { - return; - } - const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!); - await buttonInteraction?.editReply({ - embeds: [ - new DraftBotEmbed().formatAuthor(i18n.t("error:titleDidntWork", { - lng: originalInteraction.userLanguage, - pseudo: originalInteraction.user.displayName - }), originalInteraction.user) - .setDescription( - i18n.t("commands:guildElder.notSameGuild", { - lng: originalInteraction.userLanguage - }) - ) - .setErrorColor() - ] - }); -} - /** * Handle the response of the server after a guild elder, From 323ca8543df4a3d5296b698c400aceec95386396 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Thu, 23 Jan 2025 02:30:29 +0100 Subject: [PATCH 16/18] #2723 --- .../src/commands/guild/GuildLeaveCommand.ts | 29 +------------------ .../handlers/CommandHandlers.ts | 8 ++--- 2 files changed, 5 insertions(+), 32 deletions(-) diff --git a/Discord/src/commands/guild/GuildLeaveCommand.ts b/Discord/src/commands/guild/GuildLeaveCommand.ts index 4c511e369..5d0d5076c 100644 --- a/Discord/src/commands/guild/GuildLeaveCommand.ts +++ b/Discord/src/commands/guild/GuildLeaveCommand.ts @@ -2,7 +2,7 @@ import {makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPac import {ICommand} from "../ICommand"; import {SlashCommandBuilderGenerator} from "../SlashCommandBuilderGenerator"; import { - CommandGuildLeaveAcceptPacketRes, CommandGuildLeaveNotInAGuildPacketRes, + CommandGuildLeaveAcceptPacketRes, CommandGuildLeavePacketReq, CommandGuildLeaveRefusePacketRes } from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; import {ReactionCollectorCreationPacket} from "../../../../Lib/src/packets/interaction/ReactionCollectorPacket"; @@ -95,33 +95,6 @@ export async function handleCommandGuildLeaveRefusePacketRes(packet: CommandGuil }); } -/** - * Handle the response when the user is not in the guild - * @param packet - * @param context - */ -export async function handleCommandGuildLeaveNotInAGuildRes(packet: CommandGuildLeaveNotInAGuildPacketRes, context: PacketContext): Promise { - const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!); - if (!originalInteraction) { - return; - } - const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!); - await buttonInteraction?.editReply({ - embeds: [ - new DraftBotEmbed().formatAuthor(i18n.t("error:titleDidntWork", { - lng: originalInteraction.userLanguage, - pseudo: originalInteraction.user.displayName - }), originalInteraction.user) - .setDescription( - i18n.t("commands:guildLeave.notInAGuild", { - lng: originalInteraction.userLanguage - }) - ) - .setErrorColor() - ] - }); -} - /** * Allow the player to leave its guild */ diff --git a/Discord/src/packetHandlers/handlers/CommandHandlers.ts b/Discord/src/packetHandlers/handlers/CommandHandlers.ts index 5c82732e9..8c5db8bf0 100644 --- a/Discord/src/packetHandlers/handlers/CommandHandlers.ts +++ b/Discord/src/packetHandlers/handlers/CommandHandlers.ts @@ -140,7 +140,7 @@ import { CommandGuildElderSameGuildPacketRes } from "../../../../Lib/src/packets/commands/CommandGuildElderPacket"; import { - handleCommandGuildElderAcceptPacketRes, + handleCommandGuildElderAcceptPacketRes, handleCommandGuildElderRefusePacketRes } from "../../commands/guild/GuildElderCommand"; import { @@ -148,7 +148,7 @@ import { CommandGuildLeaveRefusePacketRes } from "../../../../Lib/src/packets/commands/CommandGuildLeavePacket"; import { - handleCommandGuildLeaveAcceptPacketRes, handleCommandGuildLeaveNotInAGuildRes, + handleCommandGuildLeaveAcceptPacketRes, handleCommandGuildLeaveRefusePacketRes } from "../../commands/guild/GuildLeaveCommand"; import {handleCommandGuildLeaveAcceptPacketRes} from "../../commands/guild/GuildLeaveCommand"; @@ -317,8 +317,8 @@ export default class CommandHandlers { } @packetHandler(CommandGuildLeaveNotInAGuildPacketRes) - async guildLeaveNotInAGuildRes(packet: CommandGuildLeaveNotInAGuildPacketRes, context: PacketContext): Promise { - await handleCommandGuildLeaveNotInAGuildRes(packet, context); + async guildLeaveNotInAGuildRes(_packet: CommandGuildLeaveNotInAGuildPacketRes, context: PacketContext): Promise { + await handleClassicError(context, "commands:guildLeave.notInAGuild"); } @packetHandler(CommandGuildLeaveRefusePacketRes) From 9a06f93e071deecbd115254d806b909916af0514 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Sat, 25 Jan 2025 20:20:47 +0100 Subject: [PATCH 17/18] fix #2723 --- Discord/src/commands/guild/GuildLeaveCommand.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Discord/src/commands/guild/GuildLeaveCommand.ts b/Discord/src/commands/guild/GuildLeaveCommand.ts index 5d0d5076c..9c5585138 100644 --- a/Discord/src/commands/guild/GuildLeaveCommand.ts +++ b/Discord/src/commands/guild/GuildLeaveCommand.ts @@ -24,7 +24,7 @@ export async function createGuildLeaveCollector(packet: ReactionCollectorCreatio await interaction.deferReply(); const data = packet.data.data as ReactionCollectorGuildLeaveData; const newChiefPseudo = data.newChiefKeycloakId ? (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, data.newChiefKeycloakId))!.attributes.gameUsername : ""; - const keyDesc = data.isGuildDestroyed ? "confirmChiefDesc" : data.newChiefKeycloakId !== null ? "confirmChiefDescWithElder" : "confirmDesc"; + const keyDesc = data.isGuildDestroyed ? "confirmChiefDesc" : data.newChiefKeycloakId ? "confirmChiefDescWithElder" : "confirmDesc"; const embed = new DraftBotEmbed().formatAuthor(i18n.t("commands:guildLeave.title", { lng: interaction.userLanguage, pseudo: interaction.user.displayName From 973c00996d4a06c078fadcfa91a70981c1923382 Mon Sep 17 00:00:00 2001 From: Ntalcme Date: Sat, 25 Jan 2025 20:41:45 +0100 Subject: [PATCH 18/18] fixes import & logs #2723 --- Core/src/commands/guild/GuildKickCommand.ts | 2 +- Core/src/commands/guild/GuildLeaveCommand.ts | 6 +++--- Discord/src/packetHandlers/handlers/CommandHandlers.ts | 5 ----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Core/src/commands/guild/GuildKickCommand.ts b/Core/src/commands/guild/GuildKickCommand.ts index 7993c9554..2cd3ff78b 100644 --- a/Core/src/commands/guild/GuildKickCommand.ts +++ b/Core/src/commands/guild/GuildKickCommand.ts @@ -28,7 +28,7 @@ async function acceptGuildKick(player: Player, kickedPlayer: Player, response: D kickedPlayer.guildId = null; if (guild.elderId === kickedPlayer.id) { - await draftBotInstance.logsDatabase.logGuildElderRemove(guild, guild.elderId); + draftBotInstance.logsDatabase.logGuildElderRemove(guild, guild.elderId).then(); guild.elderId = null; } await Promise.all([ diff --git a/Core/src/commands/guild/GuildLeaveCommand.ts b/Core/src/commands/guild/GuildLeaveCommand.ts index b930e7021..5db564210 100644 --- a/Core/src/commands/guild/GuildLeaveCommand.ts +++ b/Core/src/commands/guild/GuildLeaveCommand.ts @@ -32,8 +32,8 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro if (player.id === guild.chiefId) { // The guild's chief is leaving if (guild.elderId !== null) { - await draftBotInstance.logsDatabase.logGuildElderRemove(guild, guild.elderId); - await draftBotInstance.logsDatabase.logGuildChiefChange(guild, guild.elderId); + draftBotInstance.logsDatabase.logGuildElderRemove(guild, guild.elderId).then(); + draftBotInstance.logsDatabase.logGuildChiefChange(guild, guild.elderId).then(); // An elder can recover the guild player.guildId = null; const elder = await Players.getById(guild.elderId); @@ -61,7 +61,7 @@ async function acceptGuildLeave(player: Player, response: DraftBotPacket[]): Pro } if (guild.elderId === player.id) { // The guild's elder is leaving - await draftBotInstance.logsDatabase.logGuildElderRemove(guild, guild.elderId); + draftBotInstance.logsDatabase.logGuildElderRemove(guild, guild.elderId).then(); guild.elderId = null; } LogsDatabase.logGuildLeave(guild, player.keycloakId).then(); diff --git a/Discord/src/packetHandlers/handlers/CommandHandlers.ts b/Discord/src/packetHandlers/handlers/CommandHandlers.ts index 8c5db8bf0..d3244d433 100644 --- a/Discord/src/packetHandlers/handlers/CommandHandlers.ts +++ b/Discord/src/packetHandlers/handlers/CommandHandlers.ts @@ -139,10 +139,6 @@ import { CommandGuildElderRefusePacketRes, CommandGuildElderSameGuildPacketRes } from "../../../../Lib/src/packets/commands/CommandGuildElderPacket"; -import { - handleCommandGuildElderAcceptPacketRes, - handleCommandGuildElderRefusePacketRes -} from "../../commands/guild/GuildElderCommand"; import { CommandGuildLeaveAcceptPacketRes, CommandGuildLeaveNotInAGuildPacketRes, CommandGuildLeaveRefusePacketRes @@ -151,7 +147,6 @@ import { handleCommandGuildLeaveAcceptPacketRes, handleCommandGuildLeaveRefusePacketRes } from "../../commands/guild/GuildLeaveCommand"; -import {handleCommandGuildLeaveAcceptPacketRes} from "../../commands/guild/GuildLeaveCommand"; import {handleCommandGuildElderAcceptPacketRes, handleCommandGuildElderRefusePacketRes} from "../../commands/guild/GuildElderCommand"; import {CommandSwitchCancelled, CommandSwitchErrorNoItemToSwitch, CommandSwitchSuccess} from "../../../../Lib/src/packets/commands/CommandSwitchPacket"; import {handleItemSwitch} from "../../commands/player/SwitchCommand";