-
-
Notifications
You must be signed in to change notification settings - Fork 61
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'draftbot-v5' into top-command
# Conflicts: # Discord/src/packetHandlers/handlers/CommandHandlers.ts
- Loading branch information
Showing
11 changed files
with
418 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, {})); | ||
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, {})); | ||
return false; | ||
} | ||
|
||
if (promotedPlayer.id === player.id) { | ||
response.push(makePacket(CommandGuildElderHimselfPacketRes, {})); | ||
return false; | ||
} | ||
|
||
if (promotedPlayer.id === guild.elderId) { | ||
response.push(makePacket(CommandGuildElderAlreadyElderPacketRes, {})); | ||
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) | ||
.build(); | ||
|
||
response.push(collectorPacket); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
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, | ||
CommandGuildElderPacketReq, | ||
CommandGuildElderRefusePacketRes | ||
} from "../../../../Lib/src/packets/commands/CommandGuildElderPacket"; | ||
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); | ||
} | ||
|
||
/** | ||
* 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 | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.