Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/shopSmallEvent' into shopSmallEvent
Browse files Browse the repository at this point in the history
# Conflicts:
#	Discord/src/packetHandlers/handlers/ReactionCollectorHandlers.ts
#	Discord/src/smallEvents/shop.ts
#	Lang/fr/smallEvents.json
  • Loading branch information
Ntalcme committed Dec 12, 2024
2 parents 5001159 + d1bed01 commit 3bb1cc8
Show file tree
Hide file tree
Showing 80 changed files with 1,040 additions and 496 deletions.
6 changes: 3 additions & 3 deletions Core/resources/mapLinks/29.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"startMap": 23,
"endMap": 21,
"tripDuration": 420
"startMap": 23,
"endMap": 21,
"tripDuration": 240
}
6 changes: 3 additions & 3 deletions Core/resources/mapLinks/35.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"startMap": 21,
"endMap": 23,
"tripDuration": 420
"startMap": 21,
"endMap": 23,
"tripDuration": 240
}
10 changes: 8 additions & 2 deletions Core/src/commands/admin/testCommands/Infos/HelpTestCommand.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import {CommandsTest, ExecuteTestCommandLike, ITestCommand, TypeKey} from "../../../../core/CommandsTest";
import {
CommandsTest,
ExecuteTestCommandLike,
formatTypeWaited,
ITestCommand,
TypeKey
} from "../../../../core/CommandsTest";

export const commandInfo: ITestCommand = {
name: "help",
Expand Down Expand Up @@ -29,7 +35,7 @@ ${helpOnCommand.description}
**Utilisation :** \`test ${helpOnCommand.name}${helpOnCommand.commandFormat === "" ? "" : ` ${helpOnCommand.commandFormat}`}\`
${hasArguments ? `**Argument${argsAmount === 1 ? "" : "s"} attendu${argsAmount === 1 ? "" : "s"} :**` : ""}
${hasArguments ? Object.keys(helpOnCommand.typeWaited)
.map((arg) => `- \`<${arg}>\` : ${helpOnCommand.typeWaited[arg]}`)
.map((arg) => `- \`<${arg}>\` : ${formatTypeWaited(helpOnCommand.typeWaited[arg])}`)
.join("\n") : ""}
${hasAliases ? `**Alias :** \`${helpOnCommand.aliases.join("`, `")}\`` : ""}`;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ export const commandInfo: ITestCommand = {
/**
* Show your player's ID
*/
const myIDTestCommand: ExecuteTestCommandLike = (player) => `Player id: ${player.id}`;
const myIDTestCommand: ExecuteTestCommandLike = (player) => `Player id: ${player.id}\nKeycloak id: ${player.keycloakId}`;

commandInfo.execute = myIDTestCommand;
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ smallEventsKeys

export const commandInfo: ITestCommand = {
name: "smallEvent",
aliases: ["se"],
commandFormat: "<seName>",
typeWaited: {
seName: TypeKey.STRING
Expand Down
20 changes: 20 additions & 0 deletions Core/src/commands/admin/testCommands/Player/UnblockTestCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {ExecuteTestCommandLike, ITestCommand} from "../../../../core/CommandsTest";
import {BlockingUtils} from "../../../../core/utils/BlockingUtils";

export const commandInfo: ITestCommand = {
name: "unblock",
description: "Vous permet de vous débloquer lorsqu'une commande vous bloque (ATTENTION: si vous obtenez un exploit avec cette commande, ce n'en est pas un)"
};

/**
* Unblock the player
*/
const unblockTestCommand: ExecuteTestCommandLike = (player) => {
const reasons = BlockingUtils.getPlayerBlockingReason(player.id).map(r => {
BlockingUtils.unblockPlayer(player.id, r);
return r;
});
return `Vous vous êtes débloqué des raisons suivantes : ${reasons.join(", ")}`;
};

commandInfo.execute = unblockTestCommand;
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export const commandInfo: ITestCommand = {
*/
const jailPlayerTestCommand: ExecuteTestCommandLike = async (player, args) => {
const jailPlayer = await Players.getByKeycloakId(player.keycloakId);
if (jailPlayer.effectId === Effect.NOT_STARTED.id) {
// Prevent the non initialized player to mess with the game's travel logic
throw new Error("Ce joueur n'a pas encore démarré l'aventure, laissez lui le temps de commencer !");
}
await TravelTime.applyEffect(jailPlayer, Effect.JAILED, 0, new Date(), NumberChangeReason.TEST);
await jailPlayer.save();
return `Vous avez enfermé ${args[0]} !`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ const playerEffectTestCommand: ExecuteTestCommandLike = async (player, args) =>
if (!effect) {
throw new Error("Effet inconnu !");
}
if ([Effect.NOT_STARTED, Effect.NO_EFFECT, Effect.DEAD, Effect.OCCUPIED].includes(effect)) {
throw new Error("Cet effet ne peut pas être appliqué !");
}
if (player.effectId === Effect.NOT_STARTED.id) {
// Prevent the non initialized player to mess with the game's travel logic
throw new Error("Vous n'avez pas encore démarré l'aventure, laisse toi le temps de commencer (`/test command:init`) !");
}
await TravelTime.applyEffect(player, effect, 0, new Date(), NumberChangeReason.TEST);
await player.save();
return `Vous avez maintenant l'effet ${effect.id} !`;
Expand Down
17 changes: 8 additions & 9 deletions Core/src/commands/player/ProfileCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import {FightConstants} from "../../../../Lib/src/constants/FightConstants";
import {DraftBotPacket, makePacket} from "../../../../Lib/src/packets/DraftBotPacket";
import {
CommandProfilePacketReq,
CommandProfilePacketRes
CommandProfilePacketRes,
CommandProfilePlayerNotFound
} from "../../../../Lib/src/packets/commands/CommandProfilePacket";
import {Campaign} from "../../core/missions/Campaign";
import {Player, Players} from "../../core/database/game/models/Player";
Expand All @@ -32,9 +33,7 @@ export default class ProfileCommand {
const toCheckPlayer = await Players.getAskedPlayer(packet.askedPlayer, player);

if (!toCheckPlayer) {
response.push(makePacket(CommandProfilePacketRes, {
foundPlayer: false
}));
response.push(makePacket(CommandProfilePlayerNotFound, {}));
return;
}
const guild = toCheckPlayer.guildId ? await Guilds.getById(toCheckPlayer.guildId) : null;
Expand All @@ -49,9 +48,8 @@ export default class ProfileCommand {
const destinationId = toCheckPlayer.getDestinationId();

response.push(makePacket(CommandProfilePacketRes, {
foundPlayer: true,
keycloakId: toCheckPlayer.keycloakId,
data: {
playerData: {
badges,
guild: guild?.name,
level: toCheckPlayer.level,
Expand All @@ -71,11 +69,12 @@ export default class ProfileCommand {
} : null,
destinationId,
mapTypeId: destinationId ? MapLocationDataController.instance.getById(destinationId).type : null,
effect: toCheckPlayer.checkEffect() ? {
effect: {
effect: toCheckPlayer.effectId,
timeLeft: toCheckPlayer.effectEndDate.valueOf() - Date.now(),
healed: new Date() >= toCheckPlayer.effectEndDate
} : null,
healed: new Date() >= toCheckPlayer.effectEndDate,
hasTimeDisplay: toCheckPlayer.isUnderEffect()
},
fightRanking: toCheckPlayer.level >= FightConstants.REQUIRED_LEVEL ? {
glory: toCheckPlayer.gloryPoints,
league: toCheckPlayer.getLeague().id
Expand Down
2 changes: 1 addition & 1 deletion Core/src/commands/player/ReportCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ async function doEvent(event: BigEvent, player: Player, time: number, context: P
async function doRandomBigEvent(
context: PacketContext,
response: DraftBotPacket[],
player: Player,
player: Player
): Promise<void> {
await completeMissionsBigEvent(player, response);
const travelData = TravelTime.getTravelDataSimplified(player, new Date());
Expand Down
126 changes: 126 additions & 0 deletions Core/src/commands/player/UnlockCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import {DraftBotPacket, makePacket, PacketContext} from "../../../../Lib/src/packets/DraftBotPacket";
import {Player, Players} from "../../core/database/game/models/Player";
import {
CommandUnlockAcceptPacketRes,
CommandUnlockHimself,
CommandUnlockNoPlayerFound,
CommandUnlockNotEnoughMoney,
CommandUnlockNotInJail,
CommandUnlockPacketReq,
CommandUnlockRefusePacketRes
} from "../../../../Lib/src/packets/commands/CommandUnlockPacket";
import {EndCallback, ReactionCollectorInstance} from "../../core/utils/ReactionsCollector";
import {ReactionCollectorAcceptReaction} from "../../../../Lib/src/packets/interaction/ReactionCollectorPacket";
import {BlockingConstants} from "../../../../Lib/src/constants/BlockingConstants";
import {BlockingUtils} from "../../core/utils/BlockingUtils";
import {commandRequires, CommandUtils} from "../../core/utils/CommandUtils";
import {ReactionCollectorUnlock} from "../../../../Lib/src/packets/interaction/ReactionCollectorUnlock";
import {draftBotInstance} from "../../index";
import {UnlockConstants} from "../../../../Lib/src/constants/UnlockConstants";
import {TravelTime} from "../../core/maps/TravelTime";
import {NumberChangeReason} from "../../../../Lib/src/constants/LogsConstants";
import {Effect} from "../../../../Lib/src/enums/Effect";

/**
* Accept the unlock of a player
* @param player
* @param freedPlayer
* @param response
*/
async function acceptUnlock(player: Player, freedPlayer: Player, response: DraftBotPacket[]): Promise<void> {
await player.reload();
// Do all necessary checks again just in case something changed during the menu
if (unlockCannotBeDone(player, freedPlayer, response)) {
return;
}

await TravelTime.removeEffect(freedPlayer, NumberChangeReason.UNLOCK);
await player.spendMoney({
amount: UnlockConstants.PRICE_FOR_UNLOCK,
response,
reason: NumberChangeReason.UNLOCK
});

await Promise.all([
player.save(),
freedPlayer.save()
]);

draftBotInstance.logsDatabase.logUnlock(player.keycloakId, freedPlayer.keycloakId).then();

response.push(makePacket(CommandUnlockAcceptPacketRes, {
unlockedKeycloakId: freedPlayer.keycloakId
}));
}

/**
* Check if the player can unlock another player
* @param player The player who wants to kick a member
* @param freedPlayer The player who will be freed from the prison
* @param response The response to send
*/
function unlockCannotBeDone(player: Player, freedPlayer: Player, response: DraftBotPacket[]): boolean {
if (freedPlayer === null) {
response.push(makePacket(CommandUnlockNoPlayerFound, {}));
return true;
}
if (player.money < UnlockConstants.PRICE_FOR_UNLOCK) {
response.push(makePacket(CommandUnlockNotEnoughMoney, {
money: player.money
}));
return true;
}
if (player.id === freedPlayer.id) {
response.push(makePacket(CommandUnlockHimself, {}));
return true;
}
if (freedPlayer.effectId !== Effect.JAILED.id) {
response.push(makePacket(CommandUnlockNotInJail, {}));
return true;
}
return false;
}

export default class UnlockCommand {
@commandRequires(CommandUnlockPacketReq, {
notBlocked: true,
allowedEffects: CommandUtils.ALLOWED_EFFECTS.NO_EFFECT
})
async execute(response: DraftBotPacket[], player: Player, packet: CommandUnlockPacketReq, context: PacketContext): Promise<void> {
const freedPlayer = await Players.getAskedPlayer(packet.askedPlayer, player);

if (unlockCannotBeDone(player, freedPlayer, response)) {
return;
}

// Send collector
const collector = new ReactionCollectorUnlock(
freedPlayer.keycloakId
);

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

const collectorPacket = new ReactionCollectorInstance(
collector,
context,
{
allowedPlayerKeycloakIds: [player.keycloakId],
reactionLimit: 1
},
endCallback
)
.block(player.id, BlockingConstants.REASONS.UNLOCK)
.build();

response.push(collectorPacket);
}
}
23 changes: 19 additions & 4 deletions Core/src/core/CommandsTest.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {readdir} from "fs/promises";
import {readdirSync} from "fs";
import {isAnId, isAnEmoji} from "../../../Lib/src/utils/StringUtils";
import {isAnEmoji, isAnId} from "../../../Lib/src/utils/StringUtils";
import {DraftBotPacket, PacketContext} from "../../../Lib/src/packets/DraftBotPacket";
import Player from "./database/game/models/Player";

Expand All @@ -14,12 +14,27 @@ export enum TypeKey {
}

const typeVariableChecks: Map<TypeKey, Checker> = new Map<TypeKey, Checker>([
[TypeKey.INTEGER, (v: string): boolean => !isNaN(parseInt(v, 10))],
[TypeKey.ID, (v: string): boolean => isAnId(v)],
[TypeKey.INTEGER, (v: string): boolean => !isNaN(parseInt(v, 10))],
[TypeKey.EMOJI, (v: string): boolean => isAnEmoji(v)],
[TypeKey.STRING, (): boolean => false]
]);

const typeVariableFormatLike: Map<TypeKey, string> = new Map<TypeKey, string>([
[TypeKey.ID, "0a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c (voir `/test command:myids`)"],
[TypeKey.INTEGER, "###"],
[TypeKey.EMOJI, "<:emoteName:123456789012345678>"],
[TypeKey.STRING, "texte"]
]);

/**
* Format the type waited for the command
* @param typeWaited
*/
export function formatTypeWaited(typeWaited: TypeKey): string {
return `\`${typeWaited}\`(${typeVariableFormatLike.get(typeWaited)})`;
}

export interface ITestCommand {
name: string,
aliases?: string[],
Expand Down Expand Up @@ -88,8 +103,8 @@ export class CommandsTest {
description: `❌ Mauvais argument pour la commande test ${commandTest.name}
**Format attendu** : \`test ${commandTest.name} ${commandTest.commandFormat}\`
**Format de l'argument** \`<${commandTypeKeys[i]}>\` : ${commandTest.typeWaited[commandTypeKeys[i]]}
**Format reçu** : ${CommandsTest.getTypeOf(args[i])}`
**Format de l'argument** \`<${commandTypeKeys[i]}>\` : ${formatTypeWaited(commandTest.typeWaited[commandTypeKeys[i]])}
**Format reçu** : ${formatTypeWaited(CommandsTest.getTypeOf(args[i]))}`
};
}
}
Expand Down
11 changes: 4 additions & 7 deletions Core/src/core/database/game/models/Player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {BlockingConstants} from "../../../../../../Lib/src/constants/BlockingCon
import {Effect} from "../../../../../../Lib/src/enums/Effect";
import {ScheduledReportNotifications} from "./ScheduledReportNotification";
import {PacketUtils} from "../../../utils/PacketUtils";
import {StatValues} from "../../../../../../Lib/src/types/StatValues";
import moment = require("moment");

export type PlayerEditValueParameters = {
Expand Down Expand Up @@ -415,8 +416,8 @@ export class Player extends Model {
/**
* Check if the player is under some effect (except dead or baby)
*/
public checkEffect(): boolean {
return [Effect.NOT_STARTED.id, Effect.NO_EFFECT.id, Effect.DEAD.id].indexOf(this.effectId) !== -1;
public isUnderEffect(): boolean {
return [Effect.NOT_STARTED.id, Effect.NO_EFFECT.id, Effect.DEAD.id].indexOf(this.effectId) === -1;
}

/**
Expand Down Expand Up @@ -539,11 +540,7 @@ export class Player extends Model {
);
}

public getMaxStatsValue(): {
attack: number,
defense: number,
speed: number
} {
public getMaxStatsValue(): StatValues {
const playerClass = ClassDataController.instance.getById(this.class);
return {
attack: playerClass.getAttackValue(this.level),
Expand Down
2 changes: 1 addition & 1 deletion Core/src/core/database/logs/LogsDatabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ export class LogsDatabase extends Database {
* @param buyerKeycloakId
* @param releasedKeycloakId
*/
public async logUnlocks(buyerKeycloakId: string, releasedKeycloakId: string): Promise<void> {
public async logUnlock(buyerKeycloakId: string, releasedKeycloakId: string): Promise<void> {
const [buyer] = await LogsPlayers.findOrCreate({
where: {
keycloakId: buyerKeycloakId
Expand Down
2 changes: 1 addition & 1 deletion Core/src/core/smallEvents/interactOtherPlayers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ async function checkGuildResponsibilities(otherPlayer: Player, guild: Guild, int
* @param interactionsList
*/
function checkEffects(otherPlayer: Player, interactionsList: InteractOtherPlayerInteraction[]): void {
if (!otherPlayer.checkEffect()) {
if (otherPlayer.isUnderEffect()) {
interactionsList.push(InteractOtherPlayerInteraction.EFFECT);
}
}
Expand Down
4 changes: 2 additions & 2 deletions Core/src/core/utils/BlockingUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ export class BlockingUtils {
* Gets why this player is blocked (empty list means it isn't blocked)
* @param playerId
*/
static getPlayerBlockingReason(playerId: number): string[] {
static getPlayerBlockingReason(playerId: number): BlockingReason[] {
const blockedPlayer = BlockingUtils.blockedPlayers.get(playerId);
const response = [];
const response: BlockingReason[] = [];
if (blockedPlayer) {
for (const block of blockedPlayer) {
if (block.limitTimestamp !== 0 && block.limitTimestamp < Date.now()) {
Expand Down
Loading

0 comments on commit 3bb1cc8

Please sign in to comment.