@66rpg/lumimaker 0.1.36 → 0.1.38

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.
@@ -1,170 +1,170 @@
1
- ---
2
- name: lumimaker-play-sdk
3
- description: 幻光社区播放页游戏宿主 SDK(window.CgMakerSdk)接入指引。在游戏内实现用户登录、展示昵称头像、查询游玩/购买权限(章节锁)、安全返回社区或进入全屏时使用。平台自动注入 SDK 脚本,严禁手动引入或打包 SDK 文件。
4
- ---
5
-
6
- # 游戏宿主 SDK(CgMakerSdk)
7
-
8
- 游戏发布后,将在幻光社区的**播放页**(宿主环境)内通过 iframe 运行。宿主环境会在全局自动注入 `window.CgMakerSdk` 对象,为游戏提供登录验证、用户信息读取、游戏购买/游玩权限查询、安全跳转以及全屏播放等能力。
9
-
10
- > **核心原则**:
11
- > 1. **严禁在工程中引入 SDK 文件**:平台在发布时会自动将 SDK 注入游戏 HTML。**切勿**下载 `lumimaker-game.js`、**切勿**拷进 `dist/` 或源码、**切勿**手动编写 `<script src="...lumimaker-game.js">`。
12
- > 2. **SDK 不负责画面渲染**:游戏的画布、UI 与核心玩法逻辑完全由您自己的代码绘制。
13
- > 3. **本地开发无宿主**:本地使用 `npm run dev` 预览时无宿主环境,`ready()` 握手超时属于正常现象,无需进行 mock。
14
-
15
- ---
16
-
17
- ## 1. 适用场景
18
-
19
- - **用户信息与登录**:需要在游戏内唤起社区登录、展示玩家昵称/头像,或保存玩家专属云端进度。
20
- - **权限与章节锁**:根据用户是否已购买或是否拥有游玩权限,控制后续关卡锁或自制试玩结束提示。
21
- - **页面导航与全屏**:在游戏界面提供“返回社区首页”、“查看作者主页”、“返回上一页”或“切换全屏”按钮。
22
- - **环境疑问解答**:确认 SDK 是否需要 npm 安装、文件存放位置等疑问(无需安装,平台运行时注入)。
23
-
24
- ---
25
-
26
- ## 2. 快速接入示例
27
-
28
- 在游戏代码中,仅通过 `window.CgMakerSdk` 与宿主进行通信。**切勿使用原生 `postMessage`,切勿尝试读取或操作 token**。
29
-
30
- ```js
31
- // 初始化并连接宿主播放页
32
- async function initPlaySdk() {
33
- const sdk = window.CgMakerSdk
34
- if (!sdk) {
35
- // 本地开发预览,或当前页面未运行在社区播放页中
36
- return null
37
- }
38
-
39
- // 1. 与宿主建立握手(约 5 秒超时,超时不会抛出异常,而是返回 ready: false)
40
- const { ready, context, error } = await sdk.ready()
41
- if (!ready) {
42
- console.debug('未连接到宿主环境(本地预览时此情况属正常现象):', error)
43
- return null
44
- }
45
-
46
- // 2. 检查并按需请求登录(如未登录,引导用户唤起社区登录弹窗)
47
- if (!sdk.isLoggedIn()) {
48
- try {
49
- await sdk.requireLogin()
50
- } catch (err) {
51
- if (err && err.code === 'LOGIN_CANCELLED') {
52
- // 用户主动关闭了登录弹窗,游戏可继续以访客模式运行
53
- console.log('用户取消了登录')
54
- return null
55
- }
56
- throw err
57
- }
58
- }
59
-
60
- // 3. 查询当前游戏在社区的发布信息与权限
61
- const gameInfo = await sdk.queryGame()
62
- // 可根据 gameInfo.can_play / gameInfo.purchased 控制游戏内的章节锁等自制 UI
63
- // 注意:切勿使用 gameInfo.play_url 强行进行页面重定向
64
-
65
- // 4. 监听环境与登录态变化(如用户在外部切换语言或完成登录)
66
- const unbind = sdk.onChange((nextContext) => {
67
- // 收到环境变化,在此处刷新游戏内的个人信息或文案
68
- })
69
-
70
- return { sdk, context, gameInfo, unbind }
71
- }
72
-
73
- // 页面加载完成后调用
74
- initPlaySdk().then((host) => {
75
- if (!host) return
76
-
77
- // 示例:按钮点击事件绑定
78
- // document.getElementById('btn-home').onclick = () => host.sdk.navigateHome()
79
- // document.getElementById('btn-author').onclick = () => host.sdk.navigateAuthorPage()
80
- // document.getElementById('btn-back').onclick = () => host.sdk.navigateBack()
81
- // document.getElementById('btn-fullscreen').onclick = () => host.sdk.requestFullscreen()
82
-
83
- // 页面卸载或组件销毁时,解除监听
84
- // window.addEventListener('unload', () => host.unbind())
85
- })
86
- ```
87
-
88
- ---
89
-
90
- ## 3. TypeScript 类型声明(可选)
91
-
92
- 若使用 TypeScript 开发,可将以下全局声明加入项目声明文件(如 `src/env.d.ts`):
93
-
94
- ```ts
95
- export {}
96
-
97
- declare global {
98
- interface Window {
99
- CgMakerSdk?: {
100
- version: string
101
- ready(): Promise<{ ready: boolean; context: CgMakerContext | null; error?: string }>
102
- isReady(): boolean
103
- getError(): string | null
104
- getContext(): CgMakerContext | null
105
- onChange(fn: (context: CgMakerContext) => void): () => void
106
- isLoggedIn(): boolean
107
- requireLogin(): Promise<void>
108
- queryGame(): Promise<CgMakerGameInfo>
109
- queryUser(): Promise<CgMakerUserInfo>
110
- navigateHome(): void
111
- navigateAuthorPage(): void
112
- navigateBack(): void
113
- requestFullscreen(): Promise<void>
114
- exitFullscreen(): Promise<void>
115
- }
116
- }
117
-
118
- interface CgMakerContext {
119
- gameId: string
120
- lang: string
121
- user: CgMakerUserInfo | null
122
- variant: 1 | 2 | 3 // 1 正式版 · 2 试玩版 · 3 衍生版
123
- }
124
-
125
- interface CgMakerUserInfo {
126
- username: string
127
- nickname: string
128
- avatar: string
129
- }
130
-
131
- interface CgMakerGameInfo {
132
- game_id: string
133
- owner: string
134
- name: string
135
- summary: string
136
- cover_url: string
137
- variant: number
138
- can_play: boolean
139
- purchased: boolean
140
- play_url: string
141
- }
142
- }
143
- ```
144
-
145
- ---
146
-
147
- ## 4. 核心规范与操作红线
148
-
149
- 1. **宿主注入与源码纯净**:
150
- - **绝对不要**将 `lumimaker-game.js` 文件放入工程或产物目录中。
151
- - **绝对不要**在 HTML 中手动写 `<script src="...lumimaker-game.js">`,发版时系统会自动安全注入。
152
- 2. **安全通信边界**:
153
- - 严禁自行调用 `window.parent.postMessage`,严禁尝试向父级页面读取、打印或篡改鉴权 token。
154
- - 严禁在游戏内自行实现社区账号登录、签发 token、创建订单或支付逻辑,所有交互均通过 SDK 提供的标准方法交由宿主承接。
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 资源。
165
-
166
- ---
167
-
168
- ## 5. API 完整参考
169
-
170
- 详细的方法签名、字段解释与错误码对照表,请查阅 [API 接口规范细则](references/api.md)。
1
+ ---
2
+ name: lumimaker-play-sdk
3
+ description: 幻光文游社区播放页 SDK(window.CgMakerSdk)接入指引。在作品内实现用户登录、展示昵称头像、查询游玩/购买权限(章节锁)、安全返回社区或进入全屏时使用。平台自动注入 SDK 脚本,严禁手动引入或打包 SDK 文件。
4
+ ---
5
+
6
+ # 播放页 SDK(CgMakerSdk)
7
+
8
+ 作品发布后,将在幻光文游社区的**播放页**(宿主环境)内通过 iframe 运行。宿主环境会在全局自动注入 `window.CgMakerSdk` 对象,为作品提供登录验证、用户信息读取、作品购买/游玩权限查询、安全跳转以及全屏播放等能力。
9
+
10
+ > **核心原则**:
11
+ > 1. **严禁在工程中引入 SDK 文件**:平台在发布时会自动将 SDK 注入作品 HTML。**切勿**下载 `lumimaker-game.js`、**切勿**拷进 `dist/` 或源码、**切勿**手动编写 `<script src="...lumimaker-game.js">`。
12
+ > 2. **SDK 不负责画面渲染**:作品的画布、UI 与核心玩法逻辑完全由您自己的代码绘制。
13
+ > 3. **本地开发无宿主**:本地使用 `npm run dev` 预览时无宿主环境,`ready()` 握手超时属于正常现象,无需进行 mock。
14
+
15
+ ---
16
+
17
+ ## 1. 适用场景
18
+
19
+ - **用户信息与登录**:需要在作品内唤起社区登录、展示玩家昵称/头像,或保存玩家专属云端进度。
20
+ - **权限与章节锁**:根据用户是否已购买或是否拥有游玩权限,控制后续关卡锁或自制试玩结束提示。
21
+ - **页面导航与全屏**:在作品界面提供“返回社区首页”、“查看作者主页”、“返回上一页”或“切换全屏”按钮。
22
+ - **环境疑问解答**:确认 SDK 是否需要 npm 安装、文件存放位置等疑问(无需安装,平台运行时注入)。
23
+
24
+ ---
25
+
26
+ ## 2. 快速接入示例
27
+
28
+ 在作品代码中,仅通过 `window.CgMakerSdk` 与宿主进行通信。**切勿使用原生 `postMessage`,切勿尝试读取或操作 token**。
29
+
30
+ ```js
31
+ // 初始化并连接宿主播放页
32
+ async function initPlaySdk() {
33
+ const sdk = window.CgMakerSdk
34
+ if (!sdk) {
35
+ // 本地开发预览,或当前页面未运行在社区播放页中
36
+ return null
37
+ }
38
+
39
+ // 1. 与宿主建立握手(约 5 秒超时,超时不会抛出异常,而是返回 ready: false)
40
+ const { ready, context, error } = await sdk.ready()
41
+ if (!ready) {
42
+ console.debug('未连接到宿主环境(本地预览时此情况属正常现象):', error)
43
+ return null
44
+ }
45
+
46
+ // 2. 检查并按需请求登录(如未登录,引导用户唤起社区登录弹窗)
47
+ if (!sdk.isLoggedIn()) {
48
+ try {
49
+ await sdk.requireLogin()
50
+ } catch (err) {
51
+ if (err && err.code === 'LOGIN_CANCELLED') {
52
+ // 用户主动关闭了登录弹窗,作品可继续以访客模式运行
53
+ console.log('用户取消了登录')
54
+ return null
55
+ }
56
+ throw err
57
+ }
58
+ }
59
+
60
+ // 3. 查询当前作品在社区的发布信息与权限
61
+ const gameInfo = await sdk.queryGame()
62
+ // 可根据 gameInfo.can_play / gameInfo.purchased 控制作品内的章节锁等自制 UI
63
+ // 注意:切勿使用 gameInfo.play_url 强行进行页面重定向
64
+
65
+ // 4. 监听环境与登录态变化(如用户在外部切换语言或完成登录)
66
+ const unbind = sdk.onChange((nextContext) => {
67
+ // 收到环境变化,在此处刷新作品内的个人信息或文案
68
+ })
69
+
70
+ return { sdk, context, gameInfo, unbind }
71
+ }
72
+
73
+ // 页面加载完成后调用
74
+ initPlaySdk().then((host) => {
75
+ if (!host) return
76
+
77
+ // 示例:按钮点击事件绑定
78
+ // document.getElementById('btn-home').onclick = () => host.sdk.navigateHome()
79
+ // document.getElementById('btn-author').onclick = () => host.sdk.navigateAuthorPage()
80
+ // document.getElementById('btn-back').onclick = () => host.sdk.navigateBack()
81
+ // document.getElementById('btn-fullscreen').onclick = () => host.sdk.requestFullscreen()
82
+
83
+ // 页面卸载或组件销毁时,解除监听
84
+ // window.addEventListener('unload', () => host.unbind())
85
+ })
86
+ ```
87
+
88
+ ---
89
+
90
+ ## 3. TypeScript 类型声明(可选)
91
+
92
+ 若使用 TypeScript 开发,可将以下全局声明加入项目声明文件(如 `src/env.d.ts`):
93
+
94
+ ```ts
95
+ export {}
96
+
97
+ declare global {
98
+ interface Window {
99
+ CgMakerSdk?: {
100
+ version: string
101
+ ready(): Promise<{ ready: boolean; context: CgMakerContext | null; error?: string }>
102
+ isReady(): boolean
103
+ getError(): string | null
104
+ getContext(): CgMakerContext | null
105
+ onChange(fn: (context: CgMakerContext) => void): () => void
106
+ isLoggedIn(): boolean
107
+ requireLogin(): Promise<void>
108
+ queryGame(): Promise<CgMakerGameInfo>
109
+ queryUser(): Promise<CgMakerUserInfo>
110
+ navigateHome(): void
111
+ navigateAuthorPage(): void
112
+ navigateBack(): void
113
+ requestFullscreen(): Promise<void>
114
+ exitFullscreen(): Promise<void>
115
+ }
116
+ }
117
+
118
+ interface CgMakerContext {
119
+ gameId: string
120
+ lang: string
121
+ user: CgMakerUserInfo | null
122
+ variant: 1 | 2 | 3 // 1 正式版 · 2 试玩版 · 3 衍生版
123
+ }
124
+
125
+ interface CgMakerUserInfo {
126
+ username: string
127
+ nickname: string
128
+ avatar: string
129
+ }
130
+
131
+ interface CgMakerGameInfo {
132
+ game_id: string
133
+ owner: string
134
+ name: string
135
+ summary: string
136
+ cover_url: string
137
+ variant: number
138
+ can_play: boolean
139
+ purchased: boolean
140
+ play_url: string
141
+ }
142
+ }
143
+ ```
144
+
145
+ ---
146
+
147
+ ## 4. 核心规范与操作红线
148
+
149
+ 1. **宿主注入与源码纯净**:
150
+ - **绝对不要**将 `lumimaker-game.js` 文件放入工程或产物目录中。
151
+ - **绝对不要**在 HTML 中手动写 `<script src="...lumimaker-game.js">`,发版时系统会自动安全注入。
152
+ 2. **安全通信边界**:
153
+ - 严禁自行调用 `window.parent.postMessage`,严禁尝试向父级页面读取、打印或篡改鉴权 token。
154
+ - 严禁在作品内自行实现社区账号登录、签发 token、创建订单或支付逻辑,所有交互均通过 SDK 提供的标准方法交由宿主承接。
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 资源。
165
+
166
+ ---
167
+
168
+ ## 5. API 完整参考
169
+
170
+ 详细的方法签名、字段解释与错误码对照表,请查阅 [API 接口规范细则](references/api.md)。
@@ -1,100 +1,100 @@
1
- # CgMakerSdk 接口规范细则
2
-
3
- 全局挂载对象为 `window.CgMakerSdk`。当游戏发布到平台并在社区播放页(iframe)中运行时,平台宿主会自动将此对象注入到全局环境中。
4
-
5
- ---
6
-
7
- ## 1. 生命周期与上下文
8
-
9
- ### 1.1 核心方法
10
-
11
- | 方法 / 属性 | 返回类型 | 功能与使用说明 |
12
- |---|---|---|
13
- | `version` | string | 当前 SDK 脚本的版本号字符串(如 `"0.1.0"`)。 |
14
- | `ready()` | `Promise<{ ready: boolean; context: CgMakerContext \| null; error?: string }>` | 与宿主播放页握手建立连接。<br>• 握手超时时间约为 5 秒。<br>• **超时不会抛出异常**,而是返回 `ready: false`,并在 `error` 字段中说明“等待主站数据超时”(本地预览时属正常表现)。 |
15
- | `isReady()` | boolean | 检查当前是否已成功完成握手并获取到环境上下文。 |
16
- | `getError()` | string \| null | 获取最近一次握手失败的具体错误信息。 |
17
- | `getContext()` | CgMakerContext \| null | 直接获取当前环境上下文对象(未握手成功时返回 `null`)。上下文内不包含敏感 token。 |
18
- | `onChange(fn)` | `() => void` | 监听环境上下文或用户登录态的变化(如外部切换了语言或登录状态改变)。<br>• 参数 `fn` 接收最新的 `context` 对象。<br>• **必须保存并调用该方法的返回值以取消事件监听**,避免组件销毁后造成内存泄漏。 |
19
- | `isLoggedIn()` | boolean | 快捷检查当前是否已有用户登录态。 |
20
- | `getGameId()` | string \| null | 快捷获取当前游戏的唯一标识 ID。 |
21
- | `getUser()` | CgMakerUserInfo \| null | 快捷获取当前已登录用户的基本信息。 |
22
-
23
- ### 1.2 环境上下文对象 (`CgMakerContext`)
24
-
25
- 调用 `getContext()` 或握手成功后返回的上下文结构如下:
26
-
27
- | 字段 | 类型 | 说明 |
28
- |---|---|---|
29
- | `gameId` | string | 当前作品在平台上的全局游戏 ID。 |
30
- | `lang` | string | 播放页当前的语言代码(如 `"zh"`、`"en"` 等)。 |
31
- | `user` | object \| null | 当前登录的用户信息对象(未登录时为 `null`),包含 `username`、`nickname`、`avatar`。 |
32
- | `variant` | number | 当前作品的版本形态:`1` 正式版 · `2` 试玩版(demo) · `3` 衍生版。 |
33
- | `parentOrigin` | string | 仅供 SDK 内部验证跨域消息来源的安全字段,游戏业务逻辑切勿依赖此字段。 |
34
-
35
- ---
36
-
37
- ## 2. 账号与登录认证
38
-
39
- | 方法 | 返回类型 | 功能与使用说明 |
40
- |---|---|---|
41
- | `requireLogin()` | `Promise<void>` | 要求用户进行登录。<br>• 若当前已处于登录状态,Promise 将立即以成功状态 resolve。<br>• 若当前未登录,宿主将弹出社区官方登录窗口。<br>• 若用户主动关闭或取消登录窗口,Promise 将以带有错误码 `LOGIN_CANCELLED` 的异常 reject。 |
42
-
43
- > **提示**:未登录时,试玩版(demo)通常仍允许玩家离线体验基础内容;但此时调用 `queryGame()` 或 `queryUser()` 均会抛出 `NOT_LOGGED_IN` 错误。
44
-
45
- ---
46
-
47
- ## 3. 游戏与用户信息查询
48
-
49
- 调用查询接口前,必须已处于登录状态,否则接口将返回错误码 `NOT_LOGGED_IN`。**严禁在游戏内自行携带 Cookie 请求社区后端接口**。
50
-
51
- | 方法 | 返回类型 | 功能与使用说明 |
52
- |---|---|---|
53
- | `queryGame()` | `Promise<CgMakerGameInfo>` | 查询当前游戏作品在平台的发布信息、价格及游玩授权状态。 |
54
- | `queryUser()` | `Promise<CgMakerUserInfo>` | 查询当前已登录用户的详细个人资料(包含 `username`、`nickname`、`avatar`)。 |
55
-
56
- ### `queryGame()` 返回常用字段一览
57
-
58
- | 字段名称 | 数据类型 | 说明与业务指引 |
59
- |---|---|---|
60
- | `game_id` | string | 作品 ID。 |
61
- | `name` | string | 作品在平台显示的名称。 |
62
- | `owner` | string | 作品作者的平台用户名。 |
63
- | `summary` | string | 作品简介摘要。 |
64
- | `cover_url` | string | 封面图地址。 |
65
- | `variant` | number | 作品形态:`1` 正式版 · `2` 试玩版。 |
66
- | `parent_game_id`| string \| null | 若为试玩版,对应关联的正式版游戏 ID。 |
67
- | `price_flower` | number | 作品标价(鲜花数)。 |
68
- | `price_cny` | number | 作品人民币售价(分)。 |
69
- | `status` | number | 作品状态:`1` 正常启用 · `2` 已禁用。 |
70
- | `purchased` | boolean | 当前登录用户是否已购买该可售作品(未购买时为 `false`)。 |
71
- | `can_play` | boolean | 当前用户当前是否具备游玩权限。游戏可用此字段控制后续章节锁。 |
72
- | `play_url` | string | 播放链接。**严禁使用此 URL 自行进行页面重定向**。 |
73
-
74
- ---
75
-
76
- ## 4. 页面导航与全屏控制
77
-
78
- 为保证运行沙箱安全,页面跳转与全屏控制**只允许调用以下无参方法**。严禁直接操作 `window.top.location`,切勿向这些方法中传入自定义 URL。
79
-
80
- | 方法 | 返回类型 | 功能与说明 |
81
- |---|---|---|
82
- | `navigateHome()` | void | 触发播放器外壳返回幻光社区首页。 |
83
- | `navigateAuthorPage()`| void | 触发播放器外壳打开该作品作者的社区个人主页。 |
84
- | `navigateBack()` | void | 触发返回上一级页面(若外壳无上一页历史,默认返回作品社区帖子)。 |
85
- | `requestFullscreen()`| `Promise<void>` | 请求将**播放器整体外壳**切换至全屏状态(全屏由外壳容器承接,游戏无需自改样式)。 |
86
- | `exitFullscreen()` | `Promise<void>` | 请求退出播放器外壳的全屏状态。 |
87
-
88
- ---
89
-
90
- ## 5. 错误码与异常处理
91
-
92
- 当 SDK 方法调用失败时,抛出的错误对象(`CgMakerError`)通常包含 `code` 属性。常见错误码对照如下:
93
-
94
- | 错误代码 (`code`) | 触发场景 | 推荐处理方案 |
95
- |---|---|---|
96
- | `NOT_LOGGED_IN` | 当前用户未登录,或调用 `queryGame` / `queryUser` 时鉴权未通过。 | 引导调用 `requireLogin()` 完成登录,或在游戏内提示访客限制。 |
97
- | `LOGIN_CANCELLED` | 唤起登录窗口后,用户主动点击关闭或取消。 | 视为非致命取消操作,允许玩家继续游玩未锁定关卡或保留在当前界面。 |
98
- | `TIMEOUT` | 跨窗口握手通信超时或请求宿主桥接超时(注:`ready()` 超时仅返回 `ready: false`,不抛出本错误)。 | 检查运行环境是否处于沙箱异常状态,做好容错兜底。 |
99
- | `FULLSCREEN_DENIED`| 浏览器安全策略拦截全屏请求(例如未在真实用户点击手势内调用)。 | 确保仅在按钮的 `click` 等显式手势回调中调用 `requestFullscreen()`。 |
100
- | `FAILED` | 其他未知系统级或通信层错误。 | 记录调试日志,对用户展示通用重试提示。 |
1
+ # CgMakerSdk 接口规范细则
2
+
3
+ 全局挂载对象为 `window.CgMakerSdk`。当作品发布到平台并在社区播放页(iframe)中运行时,平台宿主会自动将此对象注入到全局环境中。
4
+
5
+ ---
6
+
7
+ ## 1. 生命周期与上下文
8
+
9
+ ### 1.1 核心方法
10
+
11
+ | 方法 / 属性 | 返回类型 | 功能与使用说明 |
12
+ |---|---|---|
13
+ | `version` | string | 当前 SDK 脚本的版本号字符串(如 `"0.1.0"`)。 |
14
+ | `ready()` | `Promise<{ ready: boolean; context: CgMakerContext \| null; error?: string }>` | 与宿主播放页握手建立连接。<br>• 握手超时时间约为 5 秒。<br>• **超时不会抛出异常**,而是返回 `ready: false`,并在 `error` 字段中说明“等待主站数据超时”(本地预览时属正常表现)。 |
15
+ | `isReady()` | boolean | 检查当前是否已成功完成握手并获取到环境上下文。 |
16
+ | `getError()` | string \| null | 获取最近一次握手失败的具体错误信息。 |
17
+ | `getContext()` | CgMakerContext \| null | 直接获取当前环境上下文对象(未握手成功时返回 `null`)。上下文内不包含敏感 token。 |
18
+ | `onChange(fn)` | `() => void` | 监听环境上下文或用户登录态的变化(如外部切换了语言或登录状态改变)。<br>• 参数 `fn` 接收最新的 `context` 对象。<br>• **必须保存并调用该方法的返回值以取消事件监听**,避免组件销毁后造成内存泄漏。 |
19
+ | `isLoggedIn()` | boolean | 快捷检查当前是否已有用户登录态。 |
20
+ | `getGameId()` | string \| null | 快捷获取当前作品的唯一标识 ID。 |
21
+ | `getUser()` | CgMakerUserInfo \| null | 快捷获取当前已登录用户的基本信息。 |
22
+
23
+ ### 1.2 环境上下文对象 (`CgMakerContext`)
24
+
25
+ 调用 `getContext()` 或握手成功后返回的上下文结构如下:
26
+
27
+ | 字段 | 类型 | 说明 |
28
+ |---|---|---|
29
+ | `gameId` | string | 当前作品在平台上的全局作品 ID。 |
30
+ | `lang` | string | 播放页当前的语言代码(如 `"zh"`、`"en"` 等)。 |
31
+ | `user` | object \| null | 当前登录的用户信息对象(未登录时为 `null`),包含 `username`、`nickname`、`avatar`。 |
32
+ | `variant` | number | 当前作品的版本形态:`1` 正式版 · `2` 试玩版(demo) · `3` 衍生版。 |
33
+ | `parentOrigin` | string | 仅供 SDK 内部验证跨域消息来源的安全字段,作品业务逻辑切勿依赖此字段。 |
34
+
35
+ ---
36
+
37
+ ## 2. 账号与登录认证
38
+
39
+ | 方法 | 返回类型 | 功能与使用说明 |
40
+ |---|---|---|
41
+ | `requireLogin()` | `Promise<void>` | 要求用户进行登录。<br>• 若当前已处于登录状态,Promise 将立即以成功状态 resolve。<br>• 若当前未登录,宿主将弹出社区官方登录窗口。<br>• 若用户主动关闭或取消登录窗口,Promise 将以带有错误码 `LOGIN_CANCELLED` 的异常 reject。 |
42
+
43
+ > **提示**:未登录时,试玩版(demo)通常仍允许玩家离线体验基础内容;但此时调用 `queryGame()` 或 `queryUser()` 均会抛出 `NOT_LOGGED_IN` 错误。
44
+
45
+ ---
46
+
47
+ ## 3. 作品与用户信息查询
48
+
49
+ 调用查询接口前,必须已处于登录状态,否则接口将返回错误码 `NOT_LOGGED_IN`。**严禁在作品内自行携带 Cookie 请求社区后端接口**。
50
+
51
+ | 方法 | 返回类型 | 功能与使用说明 |
52
+ |---|---|---|
53
+ | `queryGame()` | `Promise<CgMakerGameInfo>` | 查询当前作品在平台的发布信息、价格及游玩授权状态。 |
54
+ | `queryUser()` | `Promise<CgMakerUserInfo>` | 查询当前已登录用户的详细个人资料(包含 `username`、`nickname`、`avatar`)。 |
55
+
56
+ ### `queryGame()` 返回常用字段一览
57
+
58
+ | 字段名称 | 数据类型 | 说明与业务指引 |
59
+ |---|---|---|
60
+ | `game_id` | string | 作品 ID。 |
61
+ | `name` | string | 作品在平台显示的名称。 |
62
+ | `owner` | string | 作品作者的平台用户名。 |
63
+ | `summary` | string | 作品简介摘要。 |
64
+ | `cover_url` | string | 封面图地址。 |
65
+ | `variant` | number | 作品形态:`1` 正式版 · `2` 试玩版。 |
66
+ | `parent_game_id`| string \| null | 若为试玩版,对应关联的正式版作品 ID。 |
67
+ | `price_flower` | number | 作品标价(鲜花数)。 |
68
+ | `price_cny` | number | 作品人民币售价(分)。 |
69
+ | `status` | number | 作品状态:`1` 正常启用 · `2` 已禁用。 |
70
+ | `purchased` | boolean | 当前登录用户是否已购买该可售作品(未购买时为 `false`)。 |
71
+ | `can_play` | boolean | 当前用户当前是否具备游玩权限。作品可用此字段控制后续章节锁。 |
72
+ | `play_url` | string | 播放链接。**严禁使用此 URL 自行进行页面重定向**。 |
73
+
74
+ ---
75
+
76
+ ## 4. 页面导航与全屏控制
77
+
78
+ 为保证运行沙箱安全,页面跳转与全屏控制**只允许调用以下无参方法**。严禁直接操作 `window.top.location`,切勿向这些方法中传入自定义 URL。
79
+
80
+ | 方法 | 返回类型 | 功能与说明 |
81
+ |---|---|---|
82
+ | `navigateHome()` | void | 触发播放器外壳返回幻光文游社区首页。 |
83
+ | `navigateAuthorPage()`| void | 触发播放器外壳打开该作品作者的社区个人主页。 |
84
+ | `navigateBack()` | void | 触发返回上一级页面(若外壳无上一页历史,默认返回作品社区帖子)。 |
85
+ | `requestFullscreen()`| `Promise<void>` | 请求将**播放器整体外壳**切换至全屏状态(全屏由外壳容器承接,作品无需自改样式)。 |
86
+ | `exitFullscreen()` | `Promise<void>` | 请求退出播放器外壳的全屏状态。 |
87
+
88
+ ---
89
+
90
+ ## 5. 错误码与异常处理
91
+
92
+ 当 SDK 方法调用失败时,抛出的错误对象(`CgMakerError`)通常包含 `code` 属性。常见错误码对照如下:
93
+
94
+ | 错误代码 (`code`) | 触发场景 | 推荐处理方案 |
95
+ |---|---|---|
96
+ | `NOT_LOGGED_IN` | 当前用户未登录,或调用 `queryGame` / `queryUser` 时鉴权未通过。 | 引导调用 `requireLogin()` 完成登录,或在作品内提示访客限制。 |
97
+ | `LOGIN_CANCELLED` | 唤起登录窗口后,用户主动点击关闭或取消。 | 视为非致命取消操作,允许玩家继续游玩未锁定关卡或保留在当前界面。 |
98
+ | `TIMEOUT` | 跨窗口握手通信超时或请求宿主桥接超时(注:`ready()` 超时仅返回 `ready: false`,不抛出本错误)。 | 检查运行环境是否处于沙箱异常状态,做好容错兜底。 |
99
+ | `FULLSCREEN_DENIED`| 浏览器安全策略拦截全屏请求(例如未在真实用户点击手势内调用)。 | 确保仅在按钮的 `click` 等显式手势回调中调用 `requestFullscreen()`。 |
100
+ | `FAILED` | 其他未知系统级或通信层错误。 | 记录调试日志,对用户展示通用重试提示。 |
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: lumimaker-template-spec
3
- description: 幻光 lumimaker 模板工程规范。用户准备发布模板、做模板、询问工程是否符合模板规范,或调整模板目录、scripts 脚本、package.json 字段与 dist 产物时使用。不符合时对照模板规范协议调整适配。
3
+ description: 幻光文游社区模板工程规范。用户准备发布模板、做模板、询问工程是否符合模板规范,或调整模板目录、scripts 脚本、package.json 字段与 dist 产物时使用。不符合时对照模板规范协议调整适配。
4
4
  ---
5
5
 
6
6
  # 模板规范指引
7
7
 
8
- 本技能用于验证当前工程是否符合幻光平台模板规范,并在不合规时引导进行标准化调整。
8
+ 本技能用于验证当前工程是否符合幻光文游社区模板规范,并在不合规时引导进行标准化调整。
9
9
 
10
10
  所有硬性规则与格式要求均以 [模板规范协议](references/protocol.md) 为唯一事实来源。本技能仅提供操作流程与排查指引。
11
11