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

guildElder command #2715

Draft
wants to merge 7 commits into
base: draftbot-v5
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions Core/src/commands/guild/GuildElderCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import Player, {Players} from "../../core/database/game/models/Player";
import {DraftBotPacket, makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPacket";
import {Guilds} from "../../core/database/game/models/Guild";
import {
CommandGuildElderAcceptPacketRes,
CommandGuildElderAlreadyElderPacketRes,
CommandGuildElderFoundPlayerPacketRes,
CommandGuildElderHimselfPacketRes,
CommandGuildElderPacketReq,
CommandGuildElderRefusePacketRes,
CommandGuildElderSameGuildPacketRes
} from "../../../../Lib/src/packets/commands/CommandGuildElderPacket";
import {draftBotInstance} from "../../index";
import {commandRequires, CommandUtils} from "../../core/utils/CommandUtils";
import {GuildConstants} from "../../../../Lib/src/constants/GuildConstants";
import {GuildRole} from "../../../../Lib/src/enums/GuildRole";
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";
import {ReactionCollectorGuildElder} from "../../../../Lib/src/packets/interaction/ReactionCollectorGuildElder";

/**
* Return true if promotedPlayer can be promoted
* @param player
* @param promotedPlayer
* @param response
*/
async function isEligible(player: Player, promotedPlayer: Player, response: DraftBotPacket[]): Promise<boolean> {
if (promotedPlayer === null) {
response.push(makePacket(CommandGuildElderFoundPlayerPacketRes, {foundPlayer: false}));
return false;
}
let promotedGuild;
try {
promotedGuild = await Guilds.getById(promotedPlayer.guildId);
}
catch (error) {
promotedGuild = null;
}

const guild = await Guilds.getById(player.guildId);
if (promotedGuild === null || promotedGuild.id !== player.guildId) {
response.push(makePacket(CommandGuildElderSameGuildPacketRes, {sameGuild: false}));
return false;
}

if (promotedPlayer.id === player.id) {
response.push(makePacket(CommandGuildElderHimselfPacketRes, {himself: true}));
return false;
}

if (promotedPlayer.id === guild.elderId) {
response.push(makePacket(CommandGuildElderAlreadyElderPacketRes, {alreadyElder: true}));
return false;
}
return true;
}

/**
* Promote promotedPlayer as elder of the guild
* @param player
* @param promotedPlayer
* @param response
*/
async function acceptGuildElder(player: Player, promotedPlayer: Player, response: DraftBotPacket[]): Promise<void> {
await player.reload();
await promotedPlayer.reload();
// Do all necessary checks again just in case something changed during the menu
if (!await isEligible(player, promotedPlayer, response)) {
return;
}
const guild = await Guilds.getById(player.guildId);
guild.elderId = promotedPlayer.id;

await Promise.all([
promotedPlayer.save(),
guild.save()
]);
draftBotInstance.logsDatabase.logGuildElderAdd(guild, promotedPlayer.keycloakId).then();

response.push(makePacket(CommandGuildElderAcceptPacketRes, {
promotedKeycloakId: promotedPlayer.keycloakId,
guildName: guild.name
}));
}

export default class GuildElderCommand {
@commandRequires(CommandGuildElderPacketReq, {
notBlocked: true,
disallowedEffects: CommandUtils.DISALLOWED_EFFECTS.NOT_STARTED_OR_DEAD,
level: GuildConstants.REQUIRED_LEVEL,
guildNeeded: true,
guildRoleNeeded: GuildRole.CHIEF
})
async execute(response: DraftBotPacket[], player: Player, packet: CommandGuildElderPacketReq, context: PacketContext): Promise<void> {
const promotedPlayer = await Players.getAskedPlayer({keycloakId: packet.askedPlayerKeycloakId}, player);

if (!await isEligible(player, promotedPlayer, response)) {
return;
}
const guildName = (await Guilds.getById(player.guildId)).name;

const collector = new ReactionCollectorGuildElder(
guildName,
promotedPlayer.keycloakId
);

const endCallback: EndCallback = async (collector: ReactionCollectorInstance, response: DraftBotPacket[]): Promise<void> => {
const reaction = collector.getFirstReaction();
if (reaction && reaction.reaction.type === ReactionCollectorAcceptReaction.name) {
await acceptGuildElder(player, promotedPlayer, response);
}
else {
response.push(makePacket(CommandGuildElderRefusePacketRes, {
promotedKeycloakId: promotedPlayer.keycloakId
}));
}
BlockingUtils.unblockPlayer(player.id, BlockingConstants.REASONS.GUILD_ELDER);
};

const collectorPacket = new ReactionCollectorInstance(
collector,
context,
{
allowedPlayerKeycloakIds: [player.keycloakId],
reactionLimit: 1
},
endCallback
)
.block(player.id, BlockingConstants.REASONS.GUILD_ELDER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Penser a bloquer / check le blocage / debloquer le joueur promu Aussi et pas seulement celui qui fait la commande

.build();

response.push(collectorPacket);
}
}
2 changes: 1 addition & 1 deletion Core/src/commands/guild/GuildKickCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ async function isNotEligible(player: Player, kickedPlayer: Player, response: Dra
}

if (kickedPlayer.id === player.id) {
// Different guild
// Same player
response.push(makePacket(CommandGuildKickPacketRes, {
foundPlayer: true,
sameGuild: true,
Expand Down
187 changes: 187 additions & 0 deletions Discord/src/commands/guild/GuildElderCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
import {ReactionCollectorCreationPacket} from "../../../../Lib/src/packets/interaction/ReactionCollectorPacket";
import {makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPacket";
import {DiscordCache} from "../../bot/DiscordCache";
import {KeycloakUtils} from "../../../../Lib/src/keycloak/KeycloakUtils";
import {keycloakConfig} from "../../bot/DraftBotShard";
import {DraftBotEmbed} from "../../messages/DraftBotEmbed";
import i18n from "../../translations/i18n";
import {DiscordCollectorUtils} from "../../utils/DiscordCollectorUtils";
import {ReactionCollectorGuildElderData} from "../../../../Lib/src/packets/interaction/ReactionCollectorGuildElder";
import {
CommandGuildElderAcceptPacketRes,
CommandGuildElderAlreadyElderPacketRes,
CommandGuildElderFoundPlayerPacketRes,
CommandGuildElderHimselfPacketRes,
CommandGuildElderPacketReq,
CommandGuildElderRefusePacketRes,
CommandGuildElderSameGuildPacketRes
} from "../../../../Lib/src/packets/commands/CommandGuildElderPacket";
import {sendErrorMessage, SendManner} from "../../utils/ErrorUtils";
import {ICommand} from "../ICommand";
import {SlashCommandBuilderGenerator} from "../SlashCommandBuilderGenerator";
import {DraftbotInteraction} from "../../messages/DraftbotInteraction";
import {KeycloakUser} from "../../../../Lib/src/keycloak/KeycloakUser";
import {PacketUtils} from "../../utils/PacketUtils";
import {SlashCommandBuilder} from "@discordjs/builders";

/**
* Create a collector to confirm the promotion
* @param packet
* @param context
*/
export async function createGuildElderCollector(packet: ReactionCollectorCreationPacket, context: PacketContext): Promise<void> {
const interaction = DiscordCache.getInteraction(context.discord!.interaction)!;
await interaction.deferReply();
const data = packet.data.data as ReactionCollectorGuildElderData;
const elderPlayer = (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, data.promotedKeycloakId))!;
const embed = new DraftBotEmbed().formatAuthor(i18n.t("commands:guildElder.title", {
lng: interaction.userLanguage,
pseudo: interaction.user.displayName
}), interaction.user)
.setDescription(
i18n.t("commands:guildElder.confirmDesc", {
lng: interaction.userLanguage,
elderPseudo: elderPlayer.attributes.gameUsername,
guildName: data.guildName
})
);

await DiscordCollectorUtils.createAcceptRefuseCollector(interaction, embed, packet, context);
}


export async function handleCommandGuildElderFoundPlayerPacketRes(packet: CommandGuildElderFoundPlayerPacketRes, context: PacketContext): Promise<void> {
const interaction = DiscordCache.getInteraction(context.discord!.interaction);
if (!interaction) {
return;
}
if (!packet.foundPlayer) {
await sendErrorMessage(
interaction.user,
interaction,
i18n.t("commands:guildElder.playerNotFound", {lng: interaction.userLanguage}),
{sendManner: SendManner.REPLY}
);
}
}

export async function handleCommandGuildElderSameGuildPacketRes(packet: CommandGuildElderSameGuildPacketRes, context: PacketContext): Promise<void> {
const interaction = DiscordCache.getInteraction(context.discord!.interaction);
if (!interaction) {
return;
}
if (!packet.sameGuild) {
await sendErrorMessage(
interaction.user,
interaction,
i18n.t("commands:guildElder.notSameGuild", {lng: interaction.userLanguage}),
{sendManner: SendManner.REPLY}
);
}
}

export async function handleCommandGuildElderHimselfPacketRes(packet: CommandGuildElderHimselfPacketRes, context: PacketContext): Promise<void> {
const interaction = DiscordCache.getInteraction(context.discord!.interaction);
if (!interaction) {
return;
}
if (packet.himself) {
await sendErrorMessage(
interaction.user,
interaction,
i18n.t("commands:guildElder.chiefError", {lng: interaction.userLanguage}),
{sendManner: SendManner.REPLY}
);
}
}

export async function handleCommandGuildElderAlreadyElderPacketRes(packet: CommandGuildElderAlreadyElderPacketRes, context: PacketContext): Promise<void> {
const interaction = DiscordCache.getInteraction(context.discord!.interaction);
if (!interaction) {
return;
}
if (packet.alreadyElder) {
await sendErrorMessage(
interaction.user,
interaction,
i18n.t("commands:guildElder.alreadyElder", {lng: interaction.userLanguage}),
{sendManner: SendManner.REPLY}
);
}
}

/**
* Handle the response of the server after a guild elder,
* this packet is only sent if the promotion is refused
* @param packet
* @param context
*/
export async function handleCommandGuildElderRefusePacketRes(packet: CommandGuildElderRefusePacketRes, context: PacketContext): Promise<void> {
const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!);
if (!originalInteraction) {
return;
}
const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!);
const promotedPlayer = (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, packet.promotedKeycloakId))!;
await buttonInteraction?.editReply({
embeds: [
new DraftBotEmbed().formatAuthor(i18n.t("commands:guildElder.canceledTitle", {
lng: originalInteraction.userLanguage,
pseudo: originalInteraction.user.displayName
}), originalInteraction.user)
.setDescription(
i18n.t("commands:guildElder.canceledDesc", {
lng: originalInteraction.userLanguage,
elderPseudo: promotedPlayer.attributes.gameUsername
})
)
.setErrorColor()
]
});
}

/**
* Handle the response of the server after a guild elder,
* this packet is only sent if the promotion is accepted
* @param packet
* @param context
*/
export async function handleCommandGuildElderAcceptPacketRes(packet: CommandGuildElderAcceptPacketRes, context: PacketContext): Promise<void> {
const originalInteraction = DiscordCache.getInteraction(context.discord!.interaction!);
const buttonInteraction = DiscordCache.getButtonInteraction(context.discord!.buttonInteraction!);
const promotedPlayer = (await KeycloakUtils.getUserByKeycloakId(keycloakConfig, packet.promotedKeycloakId!))!;
if (buttonInteraction && originalInteraction) {
await buttonInteraction.editReply({
embeds: [
new DraftBotEmbed().formatAuthor(i18n.t("commands:guildElder.successElderAddTitle", {
lng: originalInteraction.userLanguage,
elderPseudo: promotedPlayer.attributes.gameUsername,
guildName: packet.guildName
}), originalInteraction.user)
.setDescription(
i18n.t("commands:guildElder.acceptedDesc", {lng: originalInteraction.userLanguage})
)
]
});
}
}

/**
* Promote a player from a guild
*/
async function getPacket(interaction: DraftbotInteraction, user: KeycloakUser): Promise<CommandGuildElderPacketReq | null> {
const askedPlayer = await PacketUtils.prepareAskedPlayer(interaction, user);
if (!askedPlayer || !askedPlayer.keycloakId) {
return null;
}
return makePacket(CommandGuildElderPacketReq, {askedPlayerKeycloakId: askedPlayer.keycloakId});
}

export const commandInfo: ICommand = {
slashCommandBuilder: SlashCommandBuilderGenerator.generateBaseCommand("guildElder")
.addUserOption(option =>
SlashCommandBuilderGenerator.generateOption("guildElder", "user", option)
.setRequired(true)) as SlashCommandBuilder,
getPacket,
mainGuildCommand: false
};
10 changes: 7 additions & 3 deletions Discord/src/commands/guild/GuildKickCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,25 @@ import {SlashCommandBuilderGenerator} from "../SlashCommandBuilderGenerator";
import {SlashCommandBuilder} from "@discordjs/builders";
import {DiscordCache} from "../../bot/DiscordCache";
import {KeycloakUser} from "../../../../Lib/src/keycloak/KeycloakUser";
import {CommandGuildKickAcceptPacketRes, CommandGuildKickPacketReq, CommandGuildKickPacketRes, CommandGuildKickRefusePacketRes} from "../../../../Lib/src/packets/commands/CommandGuildKickPacket";
import {
CommandGuildKickAcceptPacketRes,
CommandGuildKickPacketReq,
CommandGuildKickPacketRes,
CommandGuildKickRefusePacketRes
} from "../../../../Lib/src/packets/commands/CommandGuildKickPacket";
import {ReactionCollectorCreationPacket} from "../../../../Lib/src/packets/interaction/ReactionCollectorPacket";
import {DraftBotEmbed} from "../../messages/DraftBotEmbed";
import {DiscordCollectorUtils} from "../../utils/DiscordCollectorUtils";
import {ReactionCollectorGuildKickData} from "../../../../Lib/src/packets/interaction/ReactionCollectorGuildKick";
import {PacketUtils} from "../../utils/PacketUtils";
import {CommandProfilePacketReq} from "../../../../Lib/src/packets/commands/CommandProfilePacket";
import {sendErrorMessage, SendManner} from "../../utils/ErrorUtils";
import {KeycloakUtils} from "../../../../Lib/src/keycloak/KeycloakUtils";
import {keycloakConfig} from "../../bot/DraftBotShard";

/**
* Kick a player from a guild
*/
async function getPacket(interaction: DraftbotInteraction, user: KeycloakUser): Promise<CommandProfilePacketReq | null> {
async function getPacket(interaction: DraftbotInteraction, user: KeycloakUser): Promise<CommandGuildKickPacketReq | null> {
const askedPlayer = await PacketUtils.prepareAskedPlayer(interaction, user);
if (!askedPlayer) {
return null;
Expand Down
Loading
Loading