@66rpg/lumimaker 0.1.40 → 0.1.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@66rpg/lumimaker",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.42",
|
|
4
4
|
"description": "幻光文游制作器:登录、校验并发布到幻光文游社区;validate-template(TS);login / publish 等转发 lumimaker",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"picocolors": "^1.1.1"
|
|
34
34
|
},
|
|
35
35
|
"optionalDependencies": {
|
|
36
|
-
"@66rpg/lumimaker-win32-x64": "0.1.
|
|
37
|
-
"@66rpg/lumimaker-darwin-arm64": "0.1.
|
|
38
|
-
"@66rpg/lumimaker-darwin-x64": "0.1.
|
|
36
|
+
"@66rpg/lumimaker-win32-x64": "0.1.42",
|
|
37
|
+
"@66rpg/lumimaker-darwin-arm64": "0.1.42",
|
|
38
|
+
"@66rpg/lumimaker-darwin-x64": "0.1.42"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "^22.15.0",
|
package/skill/lumimaker/SKILL.md
CHANGED
|
@@ -15,7 +15,7 @@ description: 命令操作与发布指引。用户询问如何登录、发布作
|
|
|
15
15
|
|
|
16
16
|
- **CLI 命令操作与交互规范**:由本技能(`lumimaker`)说明。
|
|
17
17
|
- **模板工程规范协议**:查阅 `lumimaker-template-spec`(校验工程目录、`package.json` 字段与脚本、构建产物)。
|
|
18
|
-
- **播放页 SDK 接入**:查阅 `lumimaker-play-sdk`(在作品代码中通过 `window.
|
|
18
|
+
- **播放页 SDK 接入**:查阅 `lumimaker-play-sdk`(在作品代码中通过 `window.LumiMakerSdk` 调用平台功能)。
|
|
19
19
|
- **免费背景音乐和音效**:查阅 `lumimaker-free-audio`(按用户描述挑选,下载到工程里再用,不要把网上的音频地址写进作品)。
|
|
20
20
|
|
|
21
21
|
---
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
- **产物共用机制**:正式版与试玩版的构建产物均输出到工程根目录的 `dist/`,后构建的一方会覆盖前一方。因此,每次构建完成后须立即执行对应的发布命令,切勿连续构建后再发。
|
|
22
22
|
2. **纯静态与本地化**:
|
|
23
23
|
- 静态产物中引用的所有资源(图片、音频、字体、脚本、样式)必须全部打包在 `dist/` 本地文件中,严禁在页面中引用在线 CDN 外链。
|
|
24
|
-
- 平台播放器会在运行时自动向页面注入 `window.
|
|
24
|
+
- 平台播放器会在运行时自动向页面注入 `window.LumiMakerSdk`,切勿手动将 SDK 文件打包进产物中。
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
@@ -1,87 +1,75 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lumimaker-play-sdk
|
|
3
|
-
description: 幻光文游社区播放页 SDK(window.
|
|
3
|
+
description: 幻光文游社区播放页 SDK(window.LumiMakerSdk)接入指引。在作品内实现用户登录、展示昵称头像、查询游玩/购买权限(章节锁)、安全返回社区、进入全屏或响应播放页静音时使用。平台自动注入 SDK 脚本,严禁手动引入或打包 SDK 文件。当前无云存档、无内购接口。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# 播放页 SDK(
|
|
6
|
+
# 播放页 SDK(LumiMakerSdk)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
作品发布后,在幻光文游社区的**播放页**(宿主)里通过 iframe 运行。平台会在玩法 HTML 里注入脚本,全局对象是 **`window.LumiMakerSdk`**(当前脚本版本 `0.1.10`)。作品用它做登录、读用户、查作品权限、安全跳转、全屏。播放页静音由脚本自动处理本页 `audio` / `video` / `AudioContext`,不必先调 API。
|
|
9
9
|
|
|
10
10
|
> **核心原则**:
|
|
11
|
-
> 1. **严禁在工程中引入 SDK
|
|
12
|
-
> 2. **SDK
|
|
13
|
-
> 3.
|
|
11
|
+
> 1. **严禁在工程中引入 SDK 文件**:发布时平台注入。**切勿**下载 `lumimaker-game.js`、**切勿**拷进 `dist/` 或源码、**切勿**手写 `<script src="...lumimaker-game.js">`。
|
|
12
|
+
> 2. **SDK 不负责画面渲染**:画布、UI 与玩法由作品自己画。
|
|
13
|
+
> 3. **本地 `npm run dev` 无宿主**:`ready()` 约 5 秒后 `ready: false`,`error` 为「等待主站数据超时」,属正常。不要 mock 登录或假用户。
|
|
14
|
+
> 4. **当前一期没有云存档、没有内购/下单接口**。不要承诺「SDK 会帮你存进度、买章节」。
|
|
15
|
+
|
|
16
|
+
脚本加载后会判定容器:只允许在**社区播放页 iframe**或**官方 App**里玩。用浏览器地址栏直接打开托管页、或被第三方站点嵌套,会跳到社区作品帖(拿不到帖则空白页)。这是客户端劝阻,卸掉脚本即可绕过;真正鉴权仍在宿主。错误文案:「请在幻光社区或官方 App 中打开」。
|
|
14
17
|
|
|
15
18
|
---
|
|
16
19
|
|
|
17
20
|
## 1. 适用场景
|
|
18
21
|
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
22
|
+
- **用户信息与登录**:唤起社区登录、展示昵称/头像。未登录的试玩仍可玩离线内容。
|
|
23
|
+
- **权限与章节锁**:读 `queryGame()` 的 `can_play` / `purchased`,画作品**自己的**关卡锁或试玩结束提示。正式版未获权时播放页会盖购买遮罩,**根本不会加载**作品 iframe。
|
|
24
|
+
- **安全跳转与全屏**:回社区首页、作者页、上一页;进入/退出播放器全屏壳。公开 API **没有** `toggleFullscreen()`。
|
|
25
|
+
- **播放页静音**:宿主拨静音后脚本已自动静音本页媒体。可选 `isMuted()` / `onMuteChange()`。
|
|
26
|
+
|
|
27
|
+
不要用本 skill 讲发版命令;发版看 `lumimaker`。
|
|
23
28
|
|
|
24
29
|
---
|
|
25
30
|
|
|
26
31
|
## 2. 快速接入示例
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
只通过 `window.LumiMakerSdk` 与宿主通信。**不要**自己 `postMessage`,**不要**读 token。
|
|
29
34
|
|
|
30
35
|
```js
|
|
31
|
-
// 初始化并连接宿主播放页
|
|
32
36
|
async function initPlaySdk() {
|
|
33
|
-
const sdk = window.
|
|
34
|
-
if (!sdk)
|
|
35
|
-
// 本地开发预览,或当前页面未运行在社区播放页中
|
|
36
|
-
return null
|
|
37
|
-
}
|
|
37
|
+
const sdk = window.LumiMakerSdk
|
|
38
|
+
if (!sdk) return null
|
|
38
39
|
|
|
39
|
-
// 1. 与宿主建立握手(约 5 秒超时,超时不会抛出异常,而是返回 ready: false)
|
|
40
40
|
const { ready, context, error } = await sdk.ready()
|
|
41
41
|
if (!ready) {
|
|
42
|
-
console.debug('
|
|
42
|
+
console.debug('未连接到宿主(本地预览正常):', error)
|
|
43
43
|
return null
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
// 2. 检查并按需请求登录(如未登录,引导用户唤起社区登录弹窗)
|
|
47
46
|
if (!sdk.isLoggedIn()) {
|
|
48
47
|
try {
|
|
49
48
|
await sdk.requireLogin()
|
|
50
49
|
} catch (err) {
|
|
51
|
-
if (err && err.code === 'LOGIN_CANCELLED')
|
|
52
|
-
// 用户主动关闭了登录弹窗,作品可继续以访客模式运行
|
|
53
|
-
console.log('用户取消了登录')
|
|
54
|
-
return null
|
|
55
|
-
}
|
|
50
|
+
if (err && err.code === 'LOGIN_CANCELLED') return null
|
|
56
51
|
throw err
|
|
57
52
|
}
|
|
58
53
|
}
|
|
59
54
|
|
|
60
|
-
// 3. 查询当前作品在社区的发布信息与权限
|
|
61
55
|
const gameInfo = await sdk.queryGame()
|
|
62
|
-
//
|
|
63
|
-
//
|
|
56
|
+
// 用 gameInfo.can_play / gameInfo.purchased 画自制章节锁
|
|
57
|
+
// 不要用 gameInfo.play_url 跳转;不要把播放地址或关联帖 ID 念给玩家
|
|
64
58
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// 收到环境变化,在此处刷新作品内的个人信息或文案
|
|
59
|
+
const unbind = sdk.onChange(() => {
|
|
60
|
+
// 登录态变化时刷新 UI。现网宿主尚未推送语言变更。
|
|
68
61
|
})
|
|
69
62
|
|
|
70
63
|
return { sdk, context, gameInfo, unbind }
|
|
71
64
|
}
|
|
72
65
|
|
|
73
|
-
// 页面加载完成后调用
|
|
74
66
|
initPlaySdk().then((host) => {
|
|
75
67
|
if (!host) return
|
|
76
|
-
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
// document.getElementById('btn-fullscreen').onclick = () => host.sdk.requestFullscreen()
|
|
82
|
-
|
|
83
|
-
// 页面卸载或组件销毁时,解除监听
|
|
84
|
-
// window.addEventListener('unload', () => host.unbind())
|
|
68
|
+
// host.sdk.navigateHome()
|
|
69
|
+
// host.sdk.navigateAuthorPage()
|
|
70
|
+
// host.sdk.navigateBack()
|
|
71
|
+
// host.sdk.requestFullscreen()
|
|
72
|
+
// host.sdk.exitFullscreen()
|
|
85
73
|
})
|
|
86
74
|
```
|
|
87
75
|
|
|
@@ -89,24 +77,28 @@ initPlaySdk().then((host) => {
|
|
|
89
77
|
|
|
90
78
|
## 3. TypeScript 类型声明(可选)
|
|
91
79
|
|
|
92
|
-
|
|
80
|
+
可放进 `src/env.d.ts`:
|
|
93
81
|
|
|
94
82
|
```ts
|
|
95
83
|
export {}
|
|
96
84
|
|
|
97
85
|
declare global {
|
|
98
86
|
interface Window {
|
|
99
|
-
|
|
87
|
+
LumiMakerSdk?: {
|
|
100
88
|
version: string
|
|
101
|
-
ready(): Promise<{ ready: boolean; context:
|
|
89
|
+
ready(): Promise<{ ready: boolean; context: LumiMakerContext | null; error?: string }>
|
|
102
90
|
isReady(): boolean
|
|
103
|
-
getError(): string
|
|
104
|
-
getContext():
|
|
105
|
-
|
|
91
|
+
getError(): string
|
|
92
|
+
getContext(): LumiMakerContext | null
|
|
93
|
+
getGameId(): string
|
|
94
|
+
getUser(): LumiMakerUser | null
|
|
106
95
|
isLoggedIn(): boolean
|
|
96
|
+
onChange(fn: (context: LumiMakerContext | null) => void): () => void
|
|
97
|
+
isMuted(): boolean
|
|
98
|
+
onMuteChange(fn: (muted: boolean) => void): () => void
|
|
107
99
|
requireLogin(): Promise<void>
|
|
108
|
-
queryGame(): Promise<
|
|
109
|
-
queryUser(): Promise<
|
|
100
|
+
queryGame(): Promise<LumiMakerGameInfo>
|
|
101
|
+
queryUser(): Promise<LumiMakerUser>
|
|
110
102
|
navigateHome(): void
|
|
111
103
|
navigateAuthorPage(): void
|
|
112
104
|
navigateBack(): void
|
|
@@ -115,26 +107,28 @@ declare global {
|
|
|
115
107
|
}
|
|
116
108
|
}
|
|
117
109
|
|
|
118
|
-
interface
|
|
110
|
+
interface LumiMakerContext {
|
|
119
111
|
gameId: string
|
|
120
112
|
lang: string
|
|
121
|
-
user:
|
|
122
|
-
variant: 1 | 2 | 3
|
|
113
|
+
user: LumiMakerUser | null
|
|
114
|
+
variant: 1 | 2 | 3
|
|
115
|
+
parentOrigin: string
|
|
123
116
|
}
|
|
124
117
|
|
|
125
|
-
interface
|
|
118
|
+
interface LumiMakerUser {
|
|
126
119
|
username: string
|
|
127
120
|
nickname: string
|
|
128
121
|
avatar: string
|
|
129
122
|
}
|
|
130
123
|
|
|
131
|
-
interface
|
|
124
|
+
interface LumiMakerGameInfo {
|
|
132
125
|
game_id: string
|
|
133
126
|
owner: string
|
|
134
127
|
name: string
|
|
135
128
|
summary: string
|
|
136
129
|
cover_url: string
|
|
137
130
|
variant: number
|
|
131
|
+
parent_game_id: string
|
|
138
132
|
can_play: boolean
|
|
139
133
|
purchased: boolean
|
|
140
134
|
play_url: string
|
|
@@ -142,29 +136,21 @@ declare global {
|
|
|
142
136
|
}
|
|
143
137
|
```
|
|
144
138
|
|
|
139
|
+
`parentOrigin` 只给 SDK 校验消息来源,作品业务不要用。`getGameId()` 未握手时是空字符串。`getError()` 无失败时是空字符串。
|
|
140
|
+
|
|
145
141
|
---
|
|
146
142
|
|
|
147
143
|
## 4. 核心规范与操作红线
|
|
148
144
|
|
|
149
|
-
1.
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
3. **页面导航红线**:
|
|
156
|
-
- 严禁使用 `window.top.location` 进行整页重定向。
|
|
157
|
-
- 页面返回与跳转必须且仅能调用 `navigateHome()`、`navigateAuthorPage()`、`navigateBack()` 等无参方法,切勿向方法中传递自定义 URL。
|
|
158
|
-
- 切勿使用 `queryGame()` 返回的 `play_url` 进行跳转。
|
|
159
|
-
4. **权限与购买体验**:
|
|
160
|
-
- 正式版作品未获游玩授权时,宿主播放页会自动覆盖平台购买界面,根本不会加载作品 iframe。
|
|
161
|
-
- 作品内只需根据 `can_play` / `purchased` 处理“已经进入作品后”的章节锁或提示,**切勿在作品内自制并复刻社区的购买结算弹窗**。
|
|
162
|
-
5. **本地开发调试预期**:
|
|
163
|
-
- 本地 `npm run dev` 阶段不存在宿主环境,`sdk.ready()` 握手超时为正常情况,请做好判空保护,**不要在本地伪造假登录或假用户数据**。
|
|
164
|
-
- 作品内的图片、音效、字体等资源依然遵循工程本地化原则,严禁使用 SDK 请求未经打包的在线 CDN 资源。
|
|
145
|
+
1. **不要把 SDK 打进工程**:不要放 `lumimaker-game.js`,不要手写 script 标签。发版会注入玩法 HTML(`index.html`;若已有语言/方向页也会注入那些页)。
|
|
146
|
+
2. **通信边界**:不要 `window.parent.postMessage`,不要读、打印、改 token。不要自己调社区登录、签发 token、下单、支付。
|
|
147
|
+
3. **跳转**:只用 `navigateHome()` / `navigateAuthorPage()` / `navigateBack()`,不要传 URL,不要 `window.top.location`。不要用 `queryGame()` 的 `play_url` 跳转。对玩家只展示帖子链接(若发版卡片有),不要念播放页地址、作品 ID、关联帖 ID。
|
|
148
|
+
4. **购买**:正式版未获权时播放页遮罩,iframe 不会开。作品内只处理「已经进来之后」的自制锁,不要复刻社区购买墙。
|
|
149
|
+
5. **本地预览**:无宿主时 `ready()` 失败正常。不要伪造登录。图音字体继续用工程本地文件。
|
|
150
|
+
6. **没有这些能力**:云存档、内购、查权买断、游戏自己切静音宿主(宿主推静音;作品只可选监听)。
|
|
165
151
|
|
|
166
152
|
---
|
|
167
153
|
|
|
168
154
|
## 5. API 完整参考
|
|
169
155
|
|
|
170
|
-
|
|
156
|
+
方法签名、字段与错误码见 [API 接口规范细则](references/api.md)。
|
|
@@ -1,100 +1,119 @@
|
|
|
1
|
-
#
|
|
1
|
+
# LumiMakerSdk 接口规范细则
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
全局对象为 **`window.LumiMakerSdk`**。发布到幻光文游社区后,在社区播放页的 iframe(或官方 App 打开的受信壳)里运行时,平台注入该对象。脚本版本见 `version`(当前 `0.1.10`)。
|
|
4
|
+
|
|
5
|
+
失败时抛出的错误对象名为 **`LumiMakerError`**,带 `code` 字符串。
|
|
6
|
+
|
|
7
|
+
作品不要自己 `postMessage`,不要读 token,不要带 Cookie 调社区接口。
|
|
4
8
|
|
|
5
9
|
---
|
|
6
10
|
|
|
7
11
|
## 1. 生命周期与上下文
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
| 方法 / 属性 | 返回类型 | 功能与使用说明 |
|
|
13
|
+
| 方法 / 属性 | 返回类型 | 说明 |
|
|
12
14
|
|---|---|---|
|
|
13
|
-
| `version` | string |
|
|
14
|
-
| `ready()` | `Promise<{ ready: boolean; context:
|
|
15
|
-
| `isReady()` | boolean |
|
|
16
|
-
| `getError()` | string
|
|
17
|
-
| `getContext()` |
|
|
18
|
-
| `
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
| `version` | string | 脚本版本,如 `"0.1.10"`。 |
|
|
16
|
+
| `ready()` | `Promise<{ ready: boolean; context: LumiMakerContext \| null; error?: string }>` | 与播放页握手。约 5 秒超时。**超时不 throw**,返回 `ready: false`。受信壳超时 `error` 为「等待主站数据超时」(本地预览正常)。未受信容器立刻失败,`error` 为「请在幻光社区或官方 App 中打开」,并跳到社区作品帖。 |
|
|
17
|
+
| `isReady()` | boolean | 是否已拿到 context。 |
|
|
18
|
+
| `getError()` | string | 最近一次握手失败文案;无失败时为空字符串。不是所有通道错误都会写入。 |
|
|
19
|
+
| `getContext()` | LumiMakerContext \| null | 公开上下文。无 token、无 api 地址。 |
|
|
20
|
+
| `getGameId()` | string | 便捷读取;未握手为空字符串。 |
|
|
21
|
+
| `getUser()` | LumiMakerUser \| null | 便捷读取当前用户。 |
|
|
22
|
+
| `isLoggedIn()` | boolean | 等价于是否已有 `getUser()`。 |
|
|
23
|
+
| `onChange(fn)` | `() => void` | context / 登录变化。`fn` 可能收到 `null`。必须用返回值取消监听。语言仅在宿主推语言消息时变;**现网播放页尚未推这条**。 |
|
|
24
|
+
| `isMuted()` | boolean | 播放页静音开关,默认 `false`。不进 `getContext()`。脚本加载后已自动听宿主并静音本页媒体,**不必调用**。 |
|
|
25
|
+
| `onMuteChange(fn)` | `() => void` | 宿主静音状态变化时回调。必须用返回值取消监听。 |
|
|
26
|
+
|
|
27
|
+
### 1.1 `getContext()` 字段
|
|
26
28
|
|
|
27
29
|
| 字段 | 类型 | 说明 |
|
|
28
30
|
|---|---|---|
|
|
29
|
-
| `gameId` | string |
|
|
30
|
-
| `lang` | string |
|
|
31
|
-
| `user` | object \| null |
|
|
32
|
-
| `variant` | number |
|
|
33
|
-
| `parentOrigin` | string | 仅供 SDK
|
|
31
|
+
| `gameId` | string | 当前作品对外 id。 |
|
|
32
|
+
| `lang` | string | 握手时播放页语言。 |
|
|
33
|
+
| `user` | object \| null | `{ username, nickname, avatar }`;未登录为 `null`。`username` 来自社区用户 id。 |
|
|
34
|
+
| `variant` | number | `1` 正式 · `2` 试玩(demo) · `3` 衍生。 |
|
|
35
|
+
| `parentOrigin` | string | 仅供 SDK 校验消息来源,作品业务不要用。 |
|
|
34
36
|
|
|
35
37
|
---
|
|
36
38
|
|
|
37
|
-
## 2.
|
|
39
|
+
## 2. 登录
|
|
38
40
|
|
|
39
|
-
| 方法 | 返回类型 |
|
|
41
|
+
| 方法 | 返回类型 | 说明 |
|
|
40
42
|
|---|---|---|
|
|
41
|
-
| `requireLogin()` | `Promise<void>` |
|
|
43
|
+
| `requireLogin()` | `Promise<void>` | 已登录立刻成功。否则请播放页弹出社区登录。用户取消 → `LOGIN_CANCELLED`。未受信壳会先抛 `UNTRUSTED_SHELL`。 |
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
未登录时试玩 iframe 仍可玩离线内容。无 token 时 `queryGame()` / `queryUser()` 得到 `NOT_LOGGED_IN`。
|
|
44
46
|
|
|
45
47
|
---
|
|
46
48
|
|
|
47
|
-
## 3.
|
|
49
|
+
## 3. 查询(须已登录)
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
游戏自己发 HTTP,`credentials: 'omit'`,只打平台 `/v1/game-sdk/*`。`game_id` 由 token 绑定,不要自己拼查询参数。
|
|
50
52
|
|
|
51
|
-
| 方法 | 返回类型 |
|
|
53
|
+
| 方法 | 返回类型 | 说明 |
|
|
52
54
|
|---|---|---|
|
|
53
|
-
| `queryGame()` | `Promise<
|
|
54
|
-
| `queryUser()` | `Promise<
|
|
55
|
+
| `queryGame()` | `Promise<LumiMakerGameInfo>` | 当前作品货架与权限。SDK 原样返回服务端对象,不做字段校验。 |
|
|
56
|
+
| `queryUser()` | `Promise<LumiMakerUser>` | `username`、`nickname`、`avatar`。 |
|
|
55
57
|
|
|
56
|
-
### `queryGame()`
|
|
58
|
+
### `queryGame()` 字段
|
|
57
59
|
|
|
58
|
-
|
|
|
60
|
+
| 字段 | 类型 | 说明 |
|
|
59
61
|
|---|---|---|
|
|
60
|
-
| `game_id` | string | 作品
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `summary` | string |
|
|
64
|
-
| `cover_url` | string |
|
|
65
|
-
| `variant` | number |
|
|
66
|
-
| `parent_game_id
|
|
67
|
-
| `price_flower` | number |
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
62
|
+
| `game_id` | string | 作品 id。不要把原始 id 念给玩家。 |
|
|
63
|
+
| `owner` | string | 作者用户名。 |
|
|
64
|
+
| `name` | string | 平台显示名。 |
|
|
65
|
+
| `summary` | string | 简介。 |
|
|
66
|
+
| `cover_url` | string | 封面地址。 |
|
|
67
|
+
| `variant` | number | `1` 正式 · `2` 试玩 · `3` 衍生。 |
|
|
68
|
+
| `parent_game_id` | string | 试玩 / 衍生关联的正式版 id;没有则为空字符串。 |
|
|
69
|
+
| `price_flower` / `price_cny` / `price_usd` | number | 标价。作品内不要用它们复刻社区购买墙。 |
|
|
70
|
+
| `latest_version_no` | number | 平台最新版本序号。不要把版本 ID 念给玩家。 |
|
|
71
|
+
| `play_url` | string | 托管播放地址。**严禁用此 URL 跳转**;也不要念给玩家。 |
|
|
72
|
+
| `post_id` | string | 关联主帖 id;demo 与正式版共用;无则为空字符串。不要念给玩家。 |
|
|
73
|
+
| `status` | number | 货架 `1` 启用 / `2` 禁用。 |
|
|
74
|
+
| `purchased` | boolean | 对该可售主体是否有已支付订单;作者未下单为 `false`。 |
|
|
75
|
+
| `can_play` | boolean | 能拿到 token 时为 `true`。用来画自制章节锁。 |
|
|
76
|
+
| `ai_model` / `engine` / `languages` / `orientations` / `play_duration` | 可选 | 可能缺省。 |
|
|
77
|
+
|
|
78
|
+
自制 UI 读 `can_play` / `purchased`。正式版未获权时播放页不会加载 iframe。
|
|
73
79
|
|
|
74
80
|
---
|
|
75
81
|
|
|
76
|
-
## 4.
|
|
82
|
+
## 4. 安全跳转与全屏
|
|
77
83
|
|
|
78
|
-
|
|
84
|
+
只允许下列无参方法。不要操作 `window.top.location`,不要传入自定义 URL。公开 API **没有** `toggleFullscreen()`(协议里宿主可认全屏 `toggle`,游戏不要调)。
|
|
79
85
|
|
|
80
|
-
| 方法 | 返回类型 |
|
|
86
|
+
| 方法 | 返回类型 | 说明 |
|
|
81
87
|
|---|---|---|
|
|
82
|
-
| `navigateHome()` | void |
|
|
83
|
-
| `navigateAuthorPage()
|
|
84
|
-
| `navigateBack()` | void |
|
|
85
|
-
| `requestFullscreen()
|
|
86
|
-
| `exitFullscreen()` | `Promise<void>` |
|
|
88
|
+
| `navigateHome()` | void | 播放页回社区首页。 |
|
|
89
|
+
| `navigateAuthorPage()` | void | 打开作者页。 |
|
|
90
|
+
| `navigateBack()` | void | 有历史则后退,否则回作品帖。 |
|
|
91
|
+
| `requestFullscreen()` | `Promise<void>` | 全屏**播放器外壳**,不是游戏改 `top`。须在真实点击等手势里调用。 |
|
|
92
|
+
| `exitFullscreen()` | `Promise<void>` | 退出播放器全屏。 |
|
|
87
93
|
|
|
88
|
-
|
|
94
|
+
浏览器拒绝全屏 → `FULLSCREEN_DENIED`。
|
|
89
95
|
|
|
90
|
-
|
|
96
|
+
---
|
|
91
97
|
|
|
92
|
-
|
|
98
|
+
## 5. 错误码
|
|
93
99
|
|
|
94
|
-
|
|
|
100
|
+
| `code` | 何时 | 处理 |
|
|
95
101
|
|---|---|---|
|
|
96
|
-
| `NOT_LOGGED_IN` |
|
|
97
|
-
| `LOGIN_CANCELLED` |
|
|
98
|
-
| `TIMEOUT` |
|
|
99
|
-
| `FULLSCREEN_DENIED
|
|
100
|
-
| `
|
|
102
|
+
| `NOT_LOGGED_IN` | 无 token,或查询鉴权失败 | 需要登录时再 `requireLogin()`;试玩可继续离线。 |
|
|
103
|
+
| `LOGIN_CANCELLED` | 用户关掉登录 | 非致命,留在当前界面。 |
|
|
104
|
+
| `TIMEOUT` | 握手或桥接超时。**`ready()` 超时只返回 `ready: false`,不 throw 本码** | 本地预览按未连接处理。 |
|
|
105
|
+
| `FULLSCREEN_DENIED` | 浏览器拒绝全屏 | 只在用户点击里请求全屏。 |
|
|
106
|
+
| `UNTRUSTED_SHELL` | 不在社区播放页 iframe / 官方 App | 提示在幻光社区或官方 App 打开。 |
|
|
107
|
+
| `FAILED` | 其它业务或通信失败 | 通用重试提示;不要把内部报文念给玩家。 |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 6. 容器(作者需要知道的行为)
|
|
112
|
+
|
|
113
|
+
| 环境 | 行为 |
|
|
114
|
+
|---|---|
|
|
115
|
+
| 社区播放页 iframe | 正常握手。 |
|
|
116
|
+
| 官方 App(本窗有官方桥) | 不跳走。没有播放页 Host 时 `ready()` 仍超时,离线可玩。 |
|
|
117
|
+
| 浏览器地址栏直开托管页,或第三方站点嵌套 | 跳到社区作品帖;拿不到帖则空白页。 |
|
|
118
|
+
|
|
119
|
+
不要把「直开托管地址」当成正规玩法入口。本地预览请继续 `npm run dev`,或嵌在社区播放页 / 官方 App。
|