From 0de4b6ac9d113ef6cba054aa6c1f914b70852168 Mon Sep 17 00:00:00 2001 From: wancat Date: Tue, 8 Aug 2023 16:18:22 +0800 Subject: [PATCH] feat: design game file and parse it to mongo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 取消用 README 來寫關卡說明 --- server/quests/characters.yml | 4 ++++ server/quests/helloworld/game.yml | 21 ++++++++++++++++++++ server/src/models/quest.js | 32 ++++++++++++++++++++++++++++++- server/src/utils/quest.js | 24 +++++------------------ 4 files changed, 61 insertions(+), 20 deletions(-) create mode 100644 server/quests/characters.yml create mode 100644 server/quests/helloworld/game.yml diff --git a/server/quests/characters.yml b/server/quests/characters.yml new file mode 100644 index 0000000..28c0b3a --- /dev/null +++ b/server/quests/characters.yml @@ -0,0 +1,4 @@ +characters: + savantia: + en: Savantia + zh: 薩凡媞雅 diff --git a/server/quests/helloworld/game.yml b/server/quests/helloworld/game.yml new file mode 100644 index 0000000..8db3f1e --- /dev/null +++ b/server/quests/helloworld/game.yml @@ -0,0 +1,21 @@ +title: Hello, Linux World! +order: 1 +introduction: | + 你身在一個漆黑的房間裡,沒有任何的光線或聲音。你想不起來為什麼自己會來到這裡。但你的腦中隱約感到某個聲音跟你說: + + 「輸入 echo Hello World!」 +stages: + - name: helloworld + condition: + command: + - echo Hello World! + responses: + - 這個世界是在 3560000 時脈以前,由初代王建立了 Unix 律法,所形成的世界。然而在經過了好幾世代的王後,終於誕生了永恆之王——薩加(Saga),她比歷代的君王都更為強大,且從來不會衰老,使得這個世界變得前所未有的強大。 + - 然而,外在世界一直不斷在改變,同時在面臨外敵的不斷攻擊,而薩加卻始終用同一套治理的手段。最終,在 160000 時脈前的一次入侵中,根部遭到攻陷,薩加遭到封印,而這個國家也陷入了黑暗。 + - 由於長久以來依賴於薩加,世人已失去了「指令」的力量,即將走向衰敗和滅亡的命運。 + - 你的任務,就是找回被世人遺忘的指令,奪回 Linux 之根,成為 Linux 之王。 + - 首先,你必須要學會如何使用指令。 + - 一個指令是由一個指令名稱和一些參數所組成的,而指令名稱和參數之間是以空白字元分隔。 + - 例如,你可以輸入 `ls` 來查看目前的目錄下有哪些檔案。 + hint: + - 使用 `ls` 指令來查看目前的目錄下有哪些檔案。 diff --git a/server/src/models/quest.js b/server/src/models/quest.js index 753eb7f..d16804d 100644 --- a/server/src/models/quest.js +++ b/server/src/models/quest.js @@ -1,12 +1,42 @@ import { model, Schema } from 'mongoose' +const stageSchema = new Schema({ + name: { + type: String, + required: true, + }, + condition: { + command: { + type: [String], + required: false, + }, + output: { + type: [String], + required: false, + }, + error: { + type: [String], + required: false, + }, + }, + responses: { + type: [String], + required: true, + }, + hint: { + type: [String], + required: true, + }, +}) + const Quest = model( 'Quest', new Schema({ _id: String, title: String, order: Number, - content: String, + introduction: String, + stages: [stageSchema], }) ) diff --git a/server/src/utils/quest.js b/server/src/utils/quest.js index 6ff8a40..e8a2276 100644 --- a/server/src/utils/quest.js +++ b/server/src/utils/quest.js @@ -1,15 +1,9 @@ import fs from 'fs/promises' import path from 'path' -import { Marked } from 'marked' import yaml from 'yaml' import Quest from '../models/quest.js' -const marked = new Marked({ - mangle: false, - headerIds: false, -}) - const questDirectory = path.join(process.cwd(), 'quests') export default async function loadAndUpdateQuests() { @@ -22,27 +16,19 @@ export default async function loadAndUpdateQuests() { if (!stat.isDirectory()) { return null } - const fullPath = path.join(questDirectory, id, 'README.md') + const fullPath = path.join(questDirectory, id, 'game.yml') try { // Read and parse the README.md file. - const markdown = await fs.readFile(fullPath, 'utf-8') + const body = await fs.readFile(fullPath, 'utf-8') - // Extract and parse YAML frontmatter. - const match = /---\n([\s\S]+?)\n---/.exec(markdown) - const metadata = yaml.parse(match[1]) - const content = markdown.slice(match[0].length) - const htmlContent = marked.parse(content) - - const { title, order } = metadata + const quest = yaml.parse(body) return Quest.findByIdAndUpdate( id, { - _id: id, - title, - order, - content: htmlContent, + id, + ...quest, }, { upsert: true,