From b7ecfe39800b8f0f51ca96a84aab7381244ae762 Mon Sep 17 00:00:00 2001 From: "Lin, Hung-Shin" Date: Wed, 25 Oct 2023 12:43:28 +0800 Subject: [PATCH] feat: implement $not and $or condition --- packages/models/quest.js | 4 +- quests/helloworld/game.yml | 190 +++++------------------------- server/nodemon.json | 2 +- server/src/game/commandHandler.js | 12 +- 4 files changed, 42 insertions(+), 166 deletions(-) diff --git a/packages/models/quest.js b/packages/models/quest.js index bb4ca73..8ef7879 100644 --- a/packages/models/quest.js +++ b/packages/models/quest.js @@ -25,8 +25,8 @@ const conditionSchema = new Schema({ }) conditionSchema.add({ - OR: [conditionSchema], - NOT: conditionSchema, + $or: [conditionSchema], + $not: conditionSchema, }) const stageSchema = new Schema({ diff --git a/quests/helloworld/game.yml b/quests/helloworld/game.yml index c223747..ad47ff6 100644 --- a/quests/helloworld/game.yml +++ b/quests/helloworld/game.yml @@ -90,7 +90,7 @@ stages: - 你找到的是一個被遺忘的卷軸,上面寫著解除封印的咒語。 - 使用你已經知道的 `echo` 指令來詠唱咒語。 - - id: unseal-room + - id: END task: 解除封印 repeatable: false requirements: @@ -100,8 +100,6 @@ stages: - '^/home/commander$' command: - echo Unix, rise and guide me! - execution: - - mv /usr/local/lib/warehouse /home/commander responses: - type: narrative content: @@ -113,173 +111,47 @@ stages: - 我的指令官,剛剛房間內似乎發生了某些變化。 - 再次使用 `ls` 來查看現在房間的情況吧。 - - id: find-items - task: 搜索房間 - repeatable: false - requirements: - - unseal-room + - id: not-test + task: Test "not" condition condition: - pwd: - - '^/home/commander$' - command: - - ls + $not: + pwd: + - '^/home/commander$' responses: - type: narrative content: - - 你看到了房間的地上散落著許多物品。 - - type: dialogue - speaker: Unix 精靈 - content: - - 看來這裡隱藏著許多有用的東西。 - - 我們可以把這裡作為一個根據地。 - - 但這裡有點太亂了,必須先把這裡整理乾淨。 - - 首先我們需要一個書櫃來存放這些文件。 - - 請使用 `mkdir document` 來創造一個書櫃。 + - You are not in the home directory. - - id: create-bookcase - task: 創造書櫃 - repeatable: false - requirements: - - find-items + - id: or-test + task: Test "or" condition + repeatable: true condition: - pwd: - - '^/home/commander$' - command: - - mkdir document + $or: + - command: + - less + - output: + - wow responses: - type: narrative content: - - 你創造了一個書櫃。 - - type: dialogue - speaker: Unix 精靈 - content: - - 接著把文件都放到書櫃中吧。 - - 請使用 `mv [檔案名稱] document` 來將物品放入書櫃。 - - 可以輸入多個檔案名稱,並以空白隔開,來將多個檔案放入書櫃。 - - 例如:`mv [檔案名稱1] [檔案名稱2] document` - - 注意:文件是副檔名為 `.txt` 的檔案,副檔名為 `.trash` 的檔案是垃圾,我們待會再處理。 + - You are using `less` or the output contains `wow`. - - id: store-books - task: 收拾文件 - repeatable: false - requirements: - - create-bookcase + - id: nested-condition + task: Test nested condition + repeatable: true condition: - pwd: - - '^/home/commander$' - files: - - path: '*.txt' - exists: false - responses: - - type: dialogue - speaker: Unix 精靈 - content: - - 整理好文件了,接下來把垃圾清理掉吧。 - - 請使用 `rm [檔案名稱]` 來銷毀垃圾。 - - 這個 `rm` 指令也可以一次處理多的檔案喔,用法跟 `mv` 一樣。 - - 如果你忘記的話,看看這個範例:`rm [檔案名稱1] [檔案名稱2]` - - - id: remove-trash - task: 銷毀垃圾 - repeatable: false - requirements: - - store-books - condition: - pwd: - - '^/home/commander$' - files: - - path: '*.trash' - exists: false - responses: - - type: dialogue - speaker: Unix 精靈 - content: - - 很好,讓我們看看現在房間的樣子吧。 - - - id: look-around-room - task: 查看房間 - repeatable: false - requirements: - - removetrash - condition: - pwd: - - '^/home/commander$' - command: - - ls + $or: + - pwd: + - '^/etc/zsh$' + $not: + command: + - ls + - $not: + pwd: + - '^/etc/zsh$' + command: + - ls responses: - type: narrative content: - - 地上的垃圾都消失了。 - - type: dialogue - speaker: Unix 精靈 - content: - - 這樣乾淨多了,讓我們進到書櫃看看。 - - 使用 `cd [目錄名稱]` 來移動到指定的目錄。 - - - id: enter-bookcase - task: 進入書櫃 - repeatable: false - requirements: - - look-around-room - condition: - pwd: - - '^/home/commander$' - command: - - cd document - responses: - - type: narrative - content: - - 你進入了書櫃。 - - type: dialogue - speaker: Unix 精靈 - content: - - 用 `ls` 看看書櫃裡有什麼吧。 - - - id: look-around-bookcase - task: 查看書櫃 - repeatable: false - requirements: - - enter-bookcase - condition: - pwd: - - '^/home/commander/document$' - command: - - ls - responses: - - type: dialogue - speaker: Unix 精靈 - content: - - 現在,你可以使用 `cd ..` 來回到上一層目錄。 - - - id: exit-bookcase - task: 離開書櫃 - repeatable: false - requirements: - - look-around-bookcase - condition: - pwd: - - '^/home/commander/document$' - command: - - cd .. - responses: - - type: narrative - content: - - 你離開了書櫃。 - - type: dialogue - speaker: Unix 精靈 - content: - - 這些就是我現在能教你的所有指令了。這個世界還有許多其他的指令,讓你在冒險的過程中去蒐集。 - - 如果你準備好迎接接下來的冒險,就可以離開這個房間,開始你的旅程了。 - - - id: END - task: 離開房間 - repeatable: false - requirements: - - look-around - condition: - pwd: - - '^/home$' - responses: - - type: narrative - content: - - 你踏出了房門,真正的冒險現在才正要開始。 + - You are in `/etc/zsh` and not using `ls`, or you are not in `/etc/zsh` and using `ls`. diff --git a/server/nodemon.json b/server/nodemon.json index 7544261..67a8688 100644 --- a/server/nodemon.json +++ b/server/nodemon.json @@ -1,4 +1,4 @@ { "watch": ["src", "swagger.yaml", "../quests"], - "ext": "js,yaml" + "ext": "js,yaml,yml" } diff --git a/server/src/game/commandHandler.js b/server/src/game/commandHandler.js index baa3f4b..da00864 100644 --- a/server/src/game/commandHandler.js +++ b/server/src/game/commandHandler.js @@ -53,10 +53,14 @@ export default class CommandHandler extends SessionHandler { this.session.graph = graph } - isMatch(stage) { + isMatch(condition) { const keys = ['command', 'output', 'error', 'pwd'] - return keys.every((k) => - checkMatch(stage.condition[k], this.commandInput[k]) + console.log('condition', condition) + return ( + keys.every((k) => checkMatch(condition[k], this.commandInput[k])) && + (condition.$or.length === 0 || + condition.$or.some((c) => this.isMatch(c))) && + (!condition.$not || !this.isMatch(condition.$not)) ) } @@ -72,7 +76,7 @@ export default class CommandHandler extends SessionHandler { this.handleCommand() const response = stages - .filter((s) => this.isMatch(s)) + .filter((s) => this.isMatch(s.condition)) .reduce((r, s) => ({ ...r, ...this.execute(s) }), {}) return {