From 97b0fb0f1da777bc3f1f781056ca9e968aa38272 Mon Sep 17 00:00:00 2001 From: wancat Date: Fri, 1 Sep 2023 15:25:18 +0800 Subject: [PATCH] refactor: seperate SessionHandler from commandHandler --- server/src/api/socket.js | 8 ++--- server/src/game/commandHandler.js | 48 ++--------------------------- server/src/game/sessionHandler.js | 50 +++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 49 deletions(-) create mode 100644 server/src/game/sessionHandler.js diff --git a/server/src/api/socket.js b/server/src/api/socket.js index d3dd797..67b9d77 100644 --- a/server/src/api/socket.js +++ b/server/src/api/socket.js @@ -18,10 +18,10 @@ function removeFromSession(sessionId, event, callback) { ) } -export function pushToSession(sessionId, ...args) { +export function pushToSession(sessionId, event, ...args) { const callbacks = sessions.get(sessionId) if (callbacks) { - callbacks.forEach((callback) => callback(...args)) + callbacks.forEach((callback) => callback(event, ...args)) } } @@ -68,8 +68,8 @@ async function connectClient(socket) { stream.socket.write(message) }) - const socketCallback = (event, data) => { - socket.emit(event, data) + const socketCallback = (event, ...data) => { + socket.emit(event, ...data) } listenToSession(session.id, socketCallback) diff --git a/server/src/game/commandHandler.js b/server/src/game/commandHandler.js index a166d6f..01ea533 100644 --- a/server/src/game/commandHandler.js +++ b/server/src/game/commandHandler.js @@ -2,6 +2,7 @@ import minimist from 'minimist' import { FileGraph } from '@linux-odyssey/file-graph' import Quest from '../models/quest.js' import { pushToSession } from '../api/socket.js' +import SessionHandler from './sessionHandler.js' // 檢查 pattern 是否符合 input const checkMatch = (pattern, input) => { @@ -12,9 +13,9 @@ const checkMatch = (pattern, input) => { }) } -export default class CommandHandler { +export default class CommandHandler extends SessionHandler { constructor(session, commandInput, additionalData) { - this.session = session + super(session) this.commandInput = commandInput this.argv = minimist(this.commandInput.command.split(' ')) @@ -52,23 +53,6 @@ export default class CommandHandler { this.session.graph = graph } - getTask(stage) { - return this.session.tasks.find((t) => t.id === stage.id) - } - - isCompleted(stage) { - const task = this.getTask(stage) - return task ? task.completed : false - } - - getStages() { - return this.quest.stages.filter( - (stage) => - stage.requirements.every((r) => this.isCompleted({ id: r })) && - (stage.repeatable || !this.isCompleted(stage)) - ) - } - isMatch(stage) { const keys = ['command', 'output', 'error', 'pwd'] return keys.every((k) => @@ -76,32 +60,6 @@ export default class CommandHandler { ) } - execute(stage) { - this.session.tasks - .filter((t) => t.id === stage.id) - .forEach((t) => { - t.completed = true - }) - this.session.hints.push(...stage.hints) - if (stage.id === 'END') { - this.session.status = 'finished' - this.session.finishedAt = new Date() - } - const stages = this.getStages() - console.debug(stages) - const newTasks = stages - .filter((s) => s.task) - .map((s) => ({ id: s.id, name: s.task, completed: false })) - - this.session.tasks.push(...newTasks) - pushToSession(this.session.id, 'tasks', this.session.tasks) - return { - responses: stage.responses, - hints: stage.hints, - tasks: newTasks, - } - } - async run() { this.quest = await Quest.findById(this.session.quest) const stages = this.getStages() diff --git a/server/src/game/sessionHandler.js b/server/src/game/sessionHandler.js new file mode 100644 index 0000000..de9208e --- /dev/null +++ b/server/src/game/sessionHandler.js @@ -0,0 +1,50 @@ +import { pushToSession } from '../api/socket.js' + +export default class SessionWrapper { + constructor(session) { + this.session = session + } + + getTask(stage) { + return this.session.tasks.find((t) => t.id === stage.id) + } + + isCompleted(stage) { + const task = this.getTask(stage) + return task ? task.completed : false + } + + getStages() { + return this.quest.stages.filter( + (stage) => + stage.requirements.every((r) => this.isCompleted({ id: r })) && + (stage.repeatable || !this.isCompleted(stage)) + ) + } + + execute(stage) { + this.session.tasks + .filter((t) => t.id === stage.id) + .forEach((t) => { + t.completed = true + }) + this.session.hints.push(...stage.hints) + if (stage.id === 'END') { + this.session.status = 'finished' + this.session.finishedAt = new Date() + } + const stages = this.getStages() + console.debug(stages) + const newTasks = stages + .filter((s) => s.task) + .map((s) => ({ id: s.id, name: s.task, completed: false })) + + this.session.tasks.push(...newTasks) + pushToSession(this.session.id, 'tasks', this.session.tasks) + return { + responses: stage.responses, + hints: stage.hints, + tasks: newTasks, + } + } +}