From 26dbaa45a730c18be3d535e767ed38faf0b061fb Mon Sep 17 00:00:00 2001 From: Dennis Postma Date: Tue, 5 Nov 2024 23:07:23 +0100 Subject: [PATCH] #184: Allow GMs to set time --- src/managers/dateManager.ts | 26 ++++++-- .../chat/gameMaster/setTimeCommand.ts | 66 +++++++++++++++++++ 2 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 src/socketEvents/chat/gameMaster/setTimeCommand.ts diff --git a/src/managers/dateManager.ts b/src/managers/dateManager.ts index 36836bd..9b7d6f7 100644 --- a/src/managers/dateManager.ts +++ b/src/managers/dateManager.ts @@ -18,10 +18,28 @@ class DateManager { appLogger.info('Date manager loaded') } - public stop(): void { - if (this.intervalId) { - clearInterval(this.intervalId) - this.intervalId = null + // When a GM sets the time, update the current date and update the world file + public async setTime(time: string): Promise { + try { + let newDate: Date; + + // Check if it's just a time (HH:mm or HH:mm:ss format) + if (/^\d{1,2}:\d{2}(:\d{2})?$/.test(time)) { + const [hours, minutes] = time.split(':').map(Number); + newDate = new Date(this.currentDate); // Clone current date + newDate.setHours(hours, minutes); + } else { + // Treat as full datetime string + newDate = new Date(time); + if (isNaN(newDate.getTime())) return; + } + + this.currentDate = newDate; + this.emitDate(); + await this.saveDate(); + } catch (error) { + appLogger.error(`Failed to set time: ${error instanceof Error ? error.message : String(error)}`); + throw error; } } diff --git a/src/socketEvents/chat/gameMaster/setTimeCommand.ts b/src/socketEvents/chat/gameMaster/setTimeCommand.ts new file mode 100644 index 0000000..8a34eae --- /dev/null +++ b/src/socketEvents/chat/gameMaster/setTimeCommand.ts @@ -0,0 +1,66 @@ +import { Server } from 'socket.io' +import { TSocket } from '../../../utilities/types' +import { getArgs, isCommand } from '../../../utilities/chat' +import CharacterRepository from '../../../repositories/characterRepository' +import { gameLogger } from '../../../utilities/logger' +import DateManager from '../../../managers/dateManager' + +type TypePayload = { + message: string +} + +export default class SetTimeCommand { + constructor( + private readonly io: Server, + private readonly socket: TSocket + ) {} + + public listen(): void { + this.socket.on('chat:send_message', this.handleAlertCommand.bind(this)) + } + + private async handleAlertCommand(data: TypePayload, callback: (response: boolean) => void): Promise { + try { + if (!isCommand(data.message, 'time')) { + return + } + + // Check if character exists + const character = await CharacterRepository.getByUserAndId(this.socket.user?.id as number, this.socket.characterId as number) + if (!character) { + gameLogger.error('chat:alert_command error', 'Character not found') + callback(false) + return + } + + // Check if the user is the GM + if (character.role !== 'gm') { + gameLogger.info(`User ${character.id} tried to set time but is not a game master.`) + callback(false) + return + } + + // Get arguments + const args = getArgs('time', data.message) + + if (!args) { + callback(false) + return + } + + const time = args[0] // 24h time, e.g. 17:34 + + if (!time) { + callback(false) + return + } + + await DateManager.setTime(time) + + callback(true) + } catch (error: any) { + gameLogger.error('command error', error.message) + callback(false) + } + } +}