refactor: refactor commandHandler to class

This commit is contained in:
wancat committed 2023-08-29 12:08:36 +08:00
1 parent c3683ddaea
commit 3b8264e39e
2 files changed
+79 -70

No files matched your search

@@ -2,7 +2,7 @@
import Command from '../../models/command.js' import Command from '../../models/command.js'
import Session from '../../models/session.js' import Session from '../../models/session.js'
import { verifySessionJWT } from '../../utils/auth.js' import { verifySessionJWT } from '../../utils/auth.js'
import commandHandler from '../../game/commandHandler.js' import CommandHandler from '../../game/commandHandler.js'
export async function newCommand(req, res) { export async function newCommand(req, res) {
console.log('new command:', req.body) console.log('new command:', req.body)
@@ -48,7 +48,9 @@ export async function newCommand(req, res) {
await c.save() await c.save()
const response = await commandHandler(session, c, additionalData) const commandHandler = new CommandHandler(session, c, additionalData)
const response = await commandHandler.run()
console.log(response) console.log(response)
res.status(201).json(response) res.status(201).json(response)
+75 -68
View File
@@ -3,8 +3,6 @@ import { FileGraph } from '@linux-odyssey/file-graph'
import Quest from '../models/quest.js' import Quest from '../models/quest.js'
import { pushToSession } from '../api/socket.js' import { pushToSession } from '../api/socket.js'
console.log(typeof FileGraph)
// 檢查 pattern 是否符合 input // 檢查 pattern 是否符合 input
const checkMatch = (pattern, input) => { const checkMatch = (pattern, input) => {
if (pattern.length === 0) return true if (pattern.length === 0) return true
@@ -14,78 +12,87 @@ const checkMatch = (pattern, input) => {
}) })
} }
async function discoverHandler(session, commandInput, additionalData) { export default class CommandHandler {
const graph = new FileGraph(session.graph) constructor(session, commandInput, additionalData) {
graph.discover(additionalData.discover) this.session = session
console.log('graph:', graph.toString()) this.commandInput = commandInput
session.graph = graph.toJSON() this.additionalData = additionalData
await session.save() this.eventListenr = {
} discover: [this.discoverHandler, this.pushGraph],
const pushGraph = (session, commandInput, additionalData) => {
pushToSession(session.id, 'graph', {
pwd: commandInput.pwd,
discover: additionalData.discover,
})
}
const eventListenr = {
add: [],
remove: [],
discover: [discoverHandler, pushGraph],
pwd: [],
}
function handleEvent(session, commandInput, additionalData) {
const events = Object.keys(additionalData)
events.forEach((event) => {
const handlers = eventListenr[event]
if (handlers) {
handlers.forEach((handler) =>
handler(session, commandInput, additionalData)
)
} }
})
}
async function commandHandler(session, commandInput, additionalData) {
const quest = await Quest.findById(session.quest)
const stage = quest.stages.find((s) => s.id === session.progress)
if (!stage) {
console.error('stage not found', session.progress)
return {}
} }
const argv = minimist(commandInput.command.split(' ')) handleEvent() {
const events = Object.keys(this.additionalData)
handleEvent(session, commandInput, additionalData) events.forEach((event) => {
if (argv._[0] === 'cd') { const handlers = this.eventListeners[event]
pushToSession(session.id, 'graph', { pwd: commandInput.pwd }) if (handlers) {
handlers.forEach((handler) => handler())
}
})
} }
const commandMatch = checkMatch(stage.condition.command, commandInput.command) async discoverHandler() {
const outputMatch = checkMatch(stage.condition.output, commandInput.output) const graph = new FileGraph(this.session.graph)
const errorMatch = checkMatch(stage.condition.error, commandInput.output) graph.discover(this.additionalData.discover)
console.log('graph:', graph.toString())
if (!commandMatch || !outputMatch || !errorMatch) return {} this.session.graph = graph.toJSON()
await this.session.save()
session.completion.push(session.progress)
session.hints.push(...stage.hints)
session.progress = stage.next
await session.save()
if (stage.next === 'END') {
session.status = 'finished'
session.finishedAt = new Date()
await session.save()
} }
return { pushGraph() {
responses: stage.responses, pushToSession(this.session.id, 'graph', {
hints: stage.hints, pwd: this.commandInput.pwd,
end: stage.next === 'END', discover: this.additionalData.discover,
})
}
async run() {
const quest = await Quest.findById(this.session.quest)
const stage = quest.stages.find((s) => s.id === this.session.progress)
if (!stage) {
console.error('stage not found', this.session.progress)
return {}
}
const argv = minimist(this.commandInput.command.split(' '))
this.handleEvent()
if (argv._[0] === 'cd') {
pushToSession(this.session.id, 'graph', { pwd: this.commandInput.pwd })
}
const commandMatch = checkMatch(
stage.condition.command,
this.commandInput.command
)
const outputMatch = checkMatch(
stage.condition.output,
this.commandInput.output
)
const errorMatch = checkMatch(
stage.condition.error,
this.commandInput.output
)
if (!commandMatch || !outputMatch || !errorMatch) return {}
this.session.completion.push(this.session.progress)
this.session.hints.push(...stage.hints)
this.session.progress = stage.next
await this.session.save()
if (stage.next === 'END') {
this.session.status = 'finished'
this.session.finishedAt = new Date()
await this.session.save()
}
return {
responses: stage.responses,
hints: stage.hints,
end: stage.next === 'END',
}
} }
} }
export default commandHandler