mirror of
https://github.com/linux-odyssey/linux-odyssey.git
synced 2026-11-08 11:30:12 +08:00
feat: add hints to session, update API
This commit is contained in:
1 parent
ae61bfc768
commit
6f368f761e
8 files changed
+52
-46
No files matched your search
@@ -26,6 +26,15 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./data:/data/db
|
- ./data:/data/db
|
||||||
|
|
||||||
|
swagger:
|
||||||
|
image: swaggerapi/swagger-editor:latest
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
volumes:
|
||||||
|
- ./server/swagger.yaml:/tmp/swagger.yaml
|
||||||
|
environment:
|
||||||
|
- SWAGGER_FILE=/tmp/swagger.yaml
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
internal:
|
internal:
|
||||||
players:
|
players:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
title: Hello, Linux World!
|
title: Hello, Linux World!
|
||||||
order: 1
|
order: 1
|
||||||
introduction: |
|
instruction: |
|
||||||
你身在一個漆黑的房間裡,沒有任何的光線或聲音。你想不起來為什麼自己會來到這裡。但你的腦中隱約感到某個聲音跟你說:
|
你身在一個漆黑的房間裡,沒有任何的光線或聲音。你想不起來為什麼自己會來到這裡。但你的腦中隱約感到某個聲音跟你說:
|
||||||
|
|
||||||
「輸入 echo Hello World!」
|
「輸入 echo Hello World!」
|
||||||
@@ -17,7 +17,7 @@ stages:
|
|||||||
- 首先,你必須要學會如何使用指令。
|
- 首先,你必須要學會如何使用指令。
|
||||||
- 一個指令是由一個指令名稱和一些參數所組成的,而指令名稱和參數之間是以空白字元分隔。
|
- 一個指令是由一個指令名稱和一些參數所組成的,而指令名稱和參數之間是以空白字元分隔。
|
||||||
- 例如,你可以輸入 `ls` 來查看目前的目錄下有哪些檔案。
|
- 例如,你可以輸入 `ls` 來查看目前的目錄下有哪些檔案。
|
||||||
hint:
|
hints:
|
||||||
- 使用 `ls` 指令來查看目前的目錄下有哪些檔案。
|
- 使用 `ls` 指令來查看目前的目錄下有哪些檔案。
|
||||||
next: ls
|
next: ls
|
||||||
- id: ls
|
- id: ls
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ 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)
|
||||||
const { token, command, pwd, exit_code, output } = req.body
|
const { token, command, pwd, output, error } = req.body
|
||||||
|
|
||||||
if (!command) {
|
if (!command) {
|
||||||
res.status(400).json({ message: 'command is required' })
|
res.status(400).json({ message: 'command is required' })
|
||||||
@@ -33,8 +33,8 @@ export async function newCommand(req, res) {
|
|||||||
session,
|
session,
|
||||||
command,
|
command,
|
||||||
pwd,
|
pwd,
|
||||||
exit_code,
|
|
||||||
output,
|
output,
|
||||||
|
error,
|
||||||
})
|
})
|
||||||
|
|
||||||
await c.save()
|
await c.save()
|
||||||
|
|||||||
@@ -3,9 +3,8 @@ import Quest from '../../models/quest.js'
|
|||||||
export async function getQuests(req, res) {
|
export async function getQuests(req, res) {
|
||||||
const quests = await Quest.find({}).sort({ order: 1 })
|
const quests = await Quest.find({}).sort({ order: 1 })
|
||||||
res.json(
|
res.json(
|
||||||
quests.map(({ name, title, order, _id }) => ({
|
quests.map(({ title, order, _id }) => ({
|
||||||
_id,
|
_id,
|
||||||
name,
|
|
||||||
title,
|
title,
|
||||||
order,
|
order,
|
||||||
}))
|
}))
|
||||||
@@ -19,5 +18,6 @@ export async function getQuestDetail(req, res) {
|
|||||||
res.status(404).json({ message: 'Quest not found.' })
|
res.status(404).json({ message: 'Quest not found.' })
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res.json(quest)
|
const { _id, title, order, instruction } = quest
|
||||||
|
res.json({ _id, title, order, instruction })
|
||||||
}
|
}
|
||||||
@@ -28,6 +28,7 @@ const commandHandler = async (session, commandInput) => {
|
|||||||
if (!commandMatch || !outputMatch || !errorMatch) return {}
|
if (!commandMatch || !outputMatch || !errorMatch) return {}
|
||||||
|
|
||||||
session.completion.push(session.progress)
|
session.completion.push(session.progress)
|
||||||
|
session.hints.push(...stage.hints)
|
||||||
|
|
||||||
const nextStage = quest.stages.find((s) => s.id === stage.next)
|
const nextStage = quest.stages.find((s) => s.id === stage.next)
|
||||||
session.progress = nextStage.id
|
session.progress = nextStage.id
|
||||||
@@ -35,7 +36,6 @@ const commandHandler = async (session, commandInput) => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
responses: stage.responses,
|
responses: stage.responses,
|
||||||
hint: stage.hint,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const stageSchema = new Schema({
|
|||||||
type: [String],
|
type: [String],
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
hint: {
|
hints: {
|
||||||
type: [String],
|
type: [String],
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
@@ -39,7 +39,7 @@ const Quest = model(
|
|||||||
_id: String,
|
_id: String,
|
||||||
title: String,
|
title: String,
|
||||||
order: Number,
|
order: Number,
|
||||||
introduction: String,
|
instruction: String,
|
||||||
stages: [stageSchema],
|
stages: [stageSchema],
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ const Session = model(
|
|||||||
finishedAt: Date,
|
finishedAt: Date,
|
||||||
progress: String,
|
progress: String,
|
||||||
completion: [String],
|
completion: [String],
|
||||||
|
hints: [String],
|
||||||
},
|
},
|
||||||
{ timestamps: true }
|
{ timestamps: true }
|
||||||
)
|
)
|
||||||
|
|||||||
+32
-36
@@ -1,6 +1,8 @@
|
|||||||
openapi: 3.0.0
|
openapi: 3.0.0
|
||||||
servers:
|
servers:
|
||||||
- url: /api/v1
|
- url: /api/v1
|
||||||
|
- url: https://odyssey.wancat.cc/api/v1
|
||||||
|
- url: http://localhost:3000/api/v1
|
||||||
info:
|
info:
|
||||||
description: Linux Odyssey API
|
description: Linux Odyssey API
|
||||||
version: '1.0.0'
|
version: '1.0.0'
|
||||||
@@ -304,6 +306,10 @@ paths:
|
|||||||
responses:
|
responses:
|
||||||
'201':
|
'201':
|
||||||
description: Command recorded successfully
|
description: Command recorded successfully
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/CommandResponse'
|
||||||
'400':
|
'400':
|
||||||
description: Invalid request body
|
description: Invalid request body
|
||||||
'401':
|
'401':
|
||||||
@@ -333,10 +339,9 @@ components:
|
|||||||
title:
|
title:
|
||||||
type: string
|
type: string
|
||||||
example: Hello World
|
example: Hello World
|
||||||
content:
|
instruction:
|
||||||
type: string
|
type: string
|
||||||
format: html
|
example: 'In this quest, you need to learn how to use `ls` to list the file.'
|
||||||
example: '<h1>Hello World</h1>'
|
|
||||||
order:
|
order:
|
||||||
type: number
|
type: number
|
||||||
|
|
||||||
@@ -372,20 +377,21 @@ components:
|
|||||||
finished_at:
|
finished_at:
|
||||||
type: string
|
type: string
|
||||||
format: date-time
|
format: date-time
|
||||||
terminals:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
graphs:
|
|
||||||
$ref: '#/components/schemas/TreeNode'
|
|
||||||
progress:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/Progress'
|
|
||||||
hints:
|
hints:
|
||||||
type: array
|
type: array
|
||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/Hint'
|
type: string
|
||||||
|
example: '`ls -al` to list detail information of all files.'
|
||||||
|
progress:
|
||||||
|
type: string
|
||||||
|
description: current stage id
|
||||||
|
example: helloworld
|
||||||
|
completion:
|
||||||
|
type: array
|
||||||
|
description: list of completed stage ids
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
example: helloworld
|
||||||
|
|
||||||
SessionSummary:
|
SessionSummary:
|
||||||
type: object
|
type: object
|
||||||
@@ -418,28 +424,6 @@ components:
|
|||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/TreeNode'
|
$ref: '#/components/schemas/TreeNode'
|
||||||
|
|
||||||
Progress:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
finished_at:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
skipped_at:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
|
|
||||||
Hint:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
content:
|
|
||||||
type: string
|
|
||||||
source:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
Command:
|
Command:
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
@@ -461,6 +445,18 @@ components:
|
|||||||
output:
|
output:
|
||||||
type: string
|
type: string
|
||||||
description: The output of the command
|
description: The output of the command
|
||||||
|
error:
|
||||||
|
type: string
|
||||||
|
description: The error message of the command
|
||||||
|
|
||||||
|
CommandResponse:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
responses:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
example: 'You have completed the quest!'
|
||||||
|
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
BearerAuth:
|
BearerAuth:
|
||||||
|
|||||||
Reference in new issue
Block a user