@66rpg/lumimaker 0.1.37 → 0.1.39
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/README.md +3 -3
- package/dist/index.js +38 -38
- package/dist/validate.js +1 -1
- package/package.json +5 -5
- package/share/find-rust-bin.mjs +1 -1
- package/skill/lumimaker/SKILL.md +10 -10
- package/skill/lumimaker/references/common-commands.md +2 -2
- package/skill/lumimaker/references/publish-game.md +51 -51
- package/skill/lumimaker/references/publish-project.md +1 -1
- package/skill/lumimaker/references/publish-template.md +1 -1
- package/skill/lumimaker-free-audio/SKILL.md +42 -42
- package/skill/lumimaker-play-sdk/SKILL.md +170 -170
- package/skill/lumimaker-play-sdk/references/api.md +100 -100
- package/skill/lumimaker-template-spec/SKILL.md +2 -2
- package/skill/lumimaker-template-spec/references/protocol.md +113 -113
|
@@ -1,51 +1,51 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
用于将当前工程打包后的静态产物(`dist
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## 1. 核心命令
|
|
8
|
-
|
|
9
|
-
| 发布类型 | 命令 | 前置构建命令 | 说明 |
|
|
10
|
-
|---|---|---|---|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## 2. 发布前置流程
|
|
17
|
-
|
|
18
|
-
1. **先构建,后发布**:
|
|
19
|
-
- 发布正式版前,必须先在工程根目录执行 `npm run build`。
|
|
20
|
-
- 发布试玩版前,必须先在工程根目录执行 `npm run build:demo`。
|
|
21
|
-
- **产物共用机制**:正式版与试玩版的构建产物均输出到工程根目录的 `dist/`,后构建的一方会覆盖前一方。因此,每次构建完成后须立即执行对应的发布命令,切勿连续构建后再发。
|
|
22
|
-
2. **纯静态与本地化**:
|
|
23
|
-
- 静态产物中引用的所有资源(图片、音频、字体、脚本、样式)必须全部打包在 `dist/` 本地文件中,严禁在页面中引用在线 CDN 外链。
|
|
24
|
-
- 平台播放器会在运行时自动向页面注入 `window.CgMakerSdk`,切勿手动将 SDK 文件打包进产物中。
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## 3. 关键交互与规则
|
|
29
|
-
|
|
30
|
-
### 3.1 明确作品版本类型(正式版 vs demo)
|
|
31
|
-
- **不要擅自假设**:若用户未明确说明发正式版还是试玩版,切勿默认发布正式版。应先执行不带 `--demo`、不带 `--yes` 的 `npx lumimaker publish`。CLI 会探测已有作品记录并返回选项信封,此时应使用大白话向用户说明已有作品情况,询问本次发哪一种。
|
|
32
|
-
- **只要试玩的场景**:若用户明确表示“只发试玩”、“发 demo”、“不要正式版”,必须使用 `npm run build:demo` 并配合 `npx lumimaker publish --demo`。**严禁**先发布正式版再发布试玩版。
|
|
33
|
-
- **禁止并行**:用户没说要试玩时,不要跑 `publish --demo`,更不要和正式版 `publish` 一起发。同一工程同一时刻只允许一条发布命令;上一条没结束(含超时后进程可能还在)时不要再发。
|
|
34
|
-
|
|
35
|
-
### 3.2 确认信息与 `--yes` 参数
|
|
36
|
-
- 首次执行发布命令时,**切勿直接追加 `--yes` 参数**。
|
|
37
|
-
- 若 CLI 返回退出码 11
|
|
38
|
-
- **仅在用户明确点头同意后**,方可追加 `--yes` 参数重新运行发布命令;若用户拒绝,立即终止操作。
|
|
39
|
-
|
|
40
|
-
### 3.3 横竖屏适配红线
|
|
41
|
-
- 若用户**没有明确提出**做横竖屏改造(例如横屏、竖屏、横竖都能玩、转屏适配、方向选择等),**绝对不要**修改源码 `index.html`,不要添加任何转屏、宽高比判断或方向选择代码,不要新建 `index.h.html` 或 `index.v.html`。
|
|
42
|
-
- 直接使用工程现有配置打包并发布。不要主动询问用户“是否要做横竖屏改造”。
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## 4. 发布结果与交付
|
|
47
|
-
|
|
48
|
-
发布完成后,CLI 会在终端输出中文卡片。请直接提取其中的关键信息告知用户:
|
|
49
|
-
- **发布状态**:如「发版成功」(已直接通过)或「已提交审核」(审核中)。
|
|
50
|
-
- **帖子链接**:提取输出中的「帖子:...」或「帖子(草稿,确认后才会公开):...」整行链接展示给用户。不要向用户展示版本 ID 或关联帖 ID
|
|
51
|
-
- 平台作品 ID(`game_id`)等信息将由平台自动记录在工程本地 `.lumimaker/game.json` 中,无需手动维护。
|
|
1
|
+
# 发布作品相关命令
|
|
2
|
+
|
|
3
|
+
用于将当前工程打包后的静态产物(`dist/`)发布为网页作品或试玩(demo)。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 核心命令
|
|
8
|
+
|
|
9
|
+
| 发布类型 | 命令 | 前置构建命令 | 说明 |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| **正式版作品** | `npx lumimaker publish` | `npm run build` | 仅当用户明确要求发布正式版时使用。 |
|
|
12
|
+
| **试玩版作品(demo)** | `npx lumimaker publish --demo` | `npm run build:demo` | 试玩在平台为独立作品,用户只要 demo 时必须使用。 |
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 2. 发布前置流程
|
|
17
|
+
|
|
18
|
+
1. **先构建,后发布**:
|
|
19
|
+
- 发布正式版前,必须先在工程根目录执行 `npm run build`。
|
|
20
|
+
- 发布试玩版前,必须先在工程根目录执行 `npm run build:demo`。
|
|
21
|
+
- **产物共用机制**:正式版与试玩版的构建产物均输出到工程根目录的 `dist/`,后构建的一方会覆盖前一方。因此,每次构建完成后须立即执行对应的发布命令,切勿连续构建后再发。
|
|
22
|
+
2. **纯静态与本地化**:
|
|
23
|
+
- 静态产物中引用的所有资源(图片、音频、字体、脚本、样式)必须全部打包在 `dist/` 本地文件中,严禁在页面中引用在线 CDN 外链。
|
|
24
|
+
- 平台播放器会在运行时自动向页面注入 `window.CgMakerSdk`,切勿手动将 SDK 文件打包进产物中。
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 3. 关键交互与规则
|
|
29
|
+
|
|
30
|
+
### 3.1 明确作品版本类型(正式版 vs demo)
|
|
31
|
+
- **不要擅自假设**:若用户未明确说明发正式版还是试玩版,切勿默认发布正式版。应先执行不带 `--demo`、不带 `--yes` 的 `npx lumimaker publish`。CLI 会探测已有作品记录并返回选项信封,此时应使用大白话向用户说明已有作品情况,询问本次发哪一种。
|
|
32
|
+
- **只要试玩的场景**:若用户明确表示“只发试玩”、“发 demo”、“不要正式版”,必须使用 `npm run build:demo` 并配合 `npx lumimaker publish --demo`。**严禁**先发布正式版再发布试玩版。
|
|
33
|
+
- **禁止并行**:用户没说要试玩时,不要跑 `publish --demo`,更不要和正式版 `publish` 一起发。同一工程同一时刻只允许一条发布命令;上一条没结束(含超时后进程可能还在)时不要再发。
|
|
34
|
+
|
|
35
|
+
### 3.2 确认信息与 `--yes` 参数
|
|
36
|
+
- 首次执行发布命令时,**切勿直接追加 `--yes` 参数**。
|
|
37
|
+
- 若 CLI 返回退出码 11 并列出待确认信息(包括作品名称、版本、发布类型等),请使用大白话将上述摘要逐一转述给用户。
|
|
38
|
+
- **仅在用户明确点头同意后**,方可追加 `--yes` 参数重新运行发布命令;若用户拒绝,立即终止操作。
|
|
39
|
+
|
|
40
|
+
### 3.3 横竖屏适配红线
|
|
41
|
+
- 若用户**没有明确提出**做横竖屏改造(例如横屏、竖屏、横竖都能玩、转屏适配、方向选择等),**绝对不要**修改源码 `index.html`,不要添加任何转屏、宽高比判断或方向选择代码,不要新建 `index.h.html` 或 `index.v.html`。
|
|
42
|
+
- 直接使用工程现有配置打包并发布。不要主动询问用户“是否要做横竖屏改造”。
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 4. 发布结果与交付
|
|
47
|
+
|
|
48
|
+
发布完成后,CLI 会在终端输出中文卡片。请直接提取其中的关键信息告知用户:
|
|
49
|
+
- **发布状态**:如「发版成功」(已直接通过)或「已提交审核」(审核中)。
|
|
50
|
+
- **帖子链接**:提取输出中的「帖子:...」或「帖子(草稿,确认后才会公开):...」整行链接展示给用户。不要向用户展示版本 ID 或关联帖 ID。不要展示正式版或试玩的作品地址(播放页、带 `lumimaker.66rpg.com` 或 `cg-maker.66rpg.com` 的链接)。
|
|
51
|
+
- 平台作品 ID(`game_id`)等信息将由平台自动记录在工程本地 `.lumimaker/game.json` 中,无需手动维护。
|
|
@@ -21,7 +21,7 @@ npx lumimaker publish-project
|
|
|
21
21
|
- 开源工程直接打包发布整套源码(包含工程内的资源),**没有独立的数据包通道**。
|
|
22
22
|
- **切勿**添加 `--with-assets`、`--fork` 等模板专用的参数。
|
|
23
23
|
2. **纯源码与依赖真实可用**:
|
|
24
|
-
- 上传的工程代码会自动排除 `node_modules/`
|
|
24
|
+
- 上传的工程代码会自动排除 `node_modules/`、`dist/` 等中间文件,以及 `package-lock.json`、`yarn.lock`、`pnpm-lock.yaml`、`npm-shrinkwrap.json`、`bun.lock`、`bun.lockb`。
|
|
25
25
|
- `package.json` 中的依赖包必须公开可用,版本真实存在。
|
|
26
26
|
- 工程运行时所有素材与依赖必须使用工程本地文件,严禁使用外部 CDN 链接。
|
|
27
27
|
3. **本地身份记录**:
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
- 模板代码发布前,建议先执行 `npx lumimaker validate-template`,确保工程目录、脚本与基础配置符合 [模板规范协议](../lumimaker-template-spec/references/protocol.md)。
|
|
23
23
|
- 建议执行 `npm run validate` 检查数据包内部数据的合规性。CLI 在发布模板时不会自动执行这些检查,作者或 Agent 须在发版前自行确认。
|
|
24
24
|
2. **纯源码与依赖真实可用**:
|
|
25
|
-
- 发布的模板代码 zip 中**绝对不包含 `node_modules
|
|
25
|
+
- 发布的模板代码 zip 中**绝对不包含 `node_modules/`**,也不包含 `package-lock.json`、`yarn.lock`、`pnpm-lock.yaml`、`npm-shrinkwrap.json`、`bun.lock`、`bun.lockb`(含子目录同名文件)。
|
|
26
26
|
- `package.json` 中的依赖包必须是公开可安装的稳定版本,严禁写入未发布的本地私有包或不存在的版本号。
|
|
27
27
|
- 模板运行时所有资源必须全部存放在工程本地(`assets/` 或源码内),严禁依赖在线 CDN 外链。
|
|
28
28
|
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: lumimaker-free-audio
|
|
3
|
-
description: 帮用户从幻光免费素材里选背景音乐或音效,并下载到工程里使用。用户提到免费音乐、配乐、背景音乐、BGM、音效、SE
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# 免费背景音乐和音效
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
跟用户说话用日常说法。不要提列表网址、`title`、`description`、`path`、`base_url`。
|
|
11
|
-
|
|
12
|
-
## 跟用户怎么说
|
|
13
|
-
|
|
14
|
-
- 选好了:说清是背景音乐还是音效、曲名,以及你起的中文文件名。例如:「给你配了一段适合战斗的背景音乐,名字叫「作战」,文件是 `assets/bgm/紧张战斗.mp3`。」
|
|
15
|
-
- 没有合适的:直接说免费素材里没有贴近这个场景的。不要凑合下一条。
|
|
16
|
-
- 下载失败:说这条素材暂时取不到。不要改用网上的音频链接代替。
|
|
17
|
-
|
|
18
|
-
## 只从这两份列表里选
|
|
19
|
-
|
|
20
|
-
列表不区分测试、调试、正式。请求时带 `Referer: https://lumi.66rpg.com/`。不要把整份列表写进工程,也不要贴给用户。
|
|
21
|
-
|
|
22
|
-
| 用户要的 | 列表 |
|
|
23
|
-
|---|---|
|
|
24
|
-
| 背景音乐 | `https://lumimaker.66rpg.com/common/asset-hub/release/public/bgm.json` |
|
|
25
|
-
| 音效 | `https://lumimaker.66rpg.com/common/asset-hub/release/public/se.json` |
|
|
26
|
-
|
|
27
|
-
对照用户描述的场景,只看每条的 `title` 和 `description` 做语义挑选。`path` 只用来拼下载地址,不拿来筛选,也不拿来当文件名。
|
|
28
|
-
|
|
29
|
-
## 先下载到工程里再用
|
|
30
|
-
|
|
31
|
-
下载地址是 `${base_url}${path}`,不要在网址末尾加 `.mp3`。`base_url` 和 `path` 都在对应列表里,`base_url` 末尾已经有斜杠。
|
|
32
|
-
|
|
33
|
-
工程说明里如果已经规定了音频放在哪,就放进那个目录。没有规定时:
|
|
34
|
-
|
|
35
|
-
- 背景音乐放 `assets/bgm/`
|
|
36
|
-
- 音效放 `assets/se/`
|
|
37
|
-
|
|
38
|
-
存到本地时自行起一个中文文件名,语义要贴近这段音乐或音效的用途,并加上 `.mp3`。例如战斗用的背景音乐可以存成 `assets/bgm/紧张战斗.mp3`,开门音效可以存成 `assets/se/开门.mp3`。文件名只用中文和数字,不要空格、斜杠、反斜杠、冒号或其他符号。同名文件已经存在时,换一个更具体的中文名,不要覆盖。只有用户明确指定了命名语言(例如要求英文或拼音)时,才改用那种语言。用户没指定时,禁止用英文、拼音或编号。
|
|
39
|
-
|
|
40
|
-
**禁止用数据里的 `path` 当文件名。** `path` 整段、最后一段、其中的编号或哈希,都不能当作本地文件名,也不能稍作改写后使用。`path` 为 `7d/7d5aadad0dfabb6e81540fcaba583940` 时,禁止存成 `7d5aadad0dfabb6e81540fcaba583940.mp3` 或 `7d/7d5aadad0dfabb6e81540fcaba583940.mp3`。下载地址仍然是 `${base_url}${path}`,不要在网址末尾加 `.mp3`。
|
|
41
|
-
|
|
42
|
-
作品里只引用这个本地文件。列表地址和下载地址都不能写进网页、脚本、样式、数据或配置。只有存到本地的文件名才带 `.mp3`。
|
|
1
|
+
---
|
|
2
|
+
name: lumimaker-free-audio
|
|
3
|
+
description: 帮用户从幻光免费素材里选背景音乐或音效,并下载到工程里使用。用户提到免费音乐、配乐、背景音乐、BGM、音效、SE 时使用。按曲名和介绍做语义挑选。必须先存到本地再引用,不能把网上的音频地址写进作品、模板或开源工程。禁止用列表里的 path 当本地文件名。文件名默认用中文,除非用户指定了命名语言。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 免费背景音乐和音效
|
|
7
|
+
|
|
8
|
+
用户想给作品、模板或开源工程配一段免费的背景音乐或音效时,用这份说明。背景音乐和 BGM 是同一件事,音效和 SE 是同一件事。
|
|
9
|
+
|
|
10
|
+
跟用户说话用日常说法。不要提列表网址、`title`、`description`、`path`、`base_url`。
|
|
11
|
+
|
|
12
|
+
## 跟用户怎么说
|
|
13
|
+
|
|
14
|
+
- 选好了:说清是背景音乐还是音效、曲名,以及你起的中文文件名。例如:「给你配了一段适合战斗的背景音乐,名字叫「作战」,文件是 `assets/bgm/紧张战斗.mp3`。」
|
|
15
|
+
- 没有合适的:直接说免费素材里没有贴近这个场景的。不要凑合下一条。
|
|
16
|
+
- 下载失败:说这条素材暂时取不到。不要改用网上的音频链接代替。
|
|
17
|
+
|
|
18
|
+
## 只从这两份列表里选
|
|
19
|
+
|
|
20
|
+
列表不区分测试、调试、正式。请求时带 `Referer: https://lumi.66rpg.com/`。不要把整份列表写进工程,也不要贴给用户。
|
|
21
|
+
|
|
22
|
+
| 用户要的 | 列表 |
|
|
23
|
+
|---|---|
|
|
24
|
+
| 背景音乐 | `https://lumimaker.66rpg.com/common/asset-hub/release/public/bgm.json` |
|
|
25
|
+
| 音效 | `https://lumimaker.66rpg.com/common/asset-hub/release/public/se.json` |
|
|
26
|
+
|
|
27
|
+
对照用户描述的场景,只看每条的 `title` 和 `description` 做语义挑选。`path` 只用来拼下载地址,不拿来筛选,也不拿来当文件名。
|
|
28
|
+
|
|
29
|
+
## 先下载到工程里再用
|
|
30
|
+
|
|
31
|
+
下载地址是 `${base_url}${path}`,不要在网址末尾加 `.mp3`。`base_url` 和 `path` 都在对应列表里,`base_url` 末尾已经有斜杠。
|
|
32
|
+
|
|
33
|
+
工程说明里如果已经规定了音频放在哪,就放进那个目录。没有规定时:
|
|
34
|
+
|
|
35
|
+
- 背景音乐放 `assets/bgm/`
|
|
36
|
+
- 音效放 `assets/se/`
|
|
37
|
+
|
|
38
|
+
存到本地时自行起一个中文文件名,语义要贴近这段音乐或音效的用途,并加上 `.mp3`。例如战斗用的背景音乐可以存成 `assets/bgm/紧张战斗.mp3`,开门音效可以存成 `assets/se/开门.mp3`。文件名只用中文和数字,不要空格、斜杠、反斜杠、冒号或其他符号。同名文件已经存在时,换一个更具体的中文名,不要覆盖。只有用户明确指定了命名语言(例如要求英文或拼音)时,才改用那种语言。用户没指定时,禁止用英文、拼音或编号。
|
|
39
|
+
|
|
40
|
+
**禁止用数据里的 `path` 当文件名。** `path` 整段、最后一段、其中的编号或哈希,都不能当作本地文件名,也不能稍作改写后使用。`path` 为 `7d/7d5aadad0dfabb6e81540fcaba583940` 时,禁止存成 `7d5aadad0dfabb6e81540fcaba583940.mp3` 或 `7d/7d5aadad0dfabb6e81540fcaba583940.mp3`。下载地址仍然是 `${base_url}${path}`,不要在网址末尾加 `.mp3`。
|
|
41
|
+
|
|
42
|
+
作品里只引用这个本地文件。列表地址和下载地址都不能写进网页、脚本、样式、数据或配置。只有存到本地的文件名才带 `.mp3`。
|
|
@@ -1,170 +1,170 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: lumimaker-play-sdk
|
|
3
|
-
description:
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
> **核心原则**:
|
|
11
|
-
> 1. **严禁在工程中引入 SDK 文件**:平台在发布时会自动将 SDK
|
|
12
|
-
> 2. **SDK
|
|
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
|
-
|
|
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
|
|
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
|
-
-
|
|
155
|
-
3. **页面导航红线**:
|
|
156
|
-
- 严禁使用 `window.top.location` 进行整页重定向。
|
|
157
|
-
- 页面返回与跳转必须且仅能调用 `navigateHome()`、`navigateAuthorPage()`、`navigateBack()` 等无参方法,切勿向方法中传递自定义 URL。
|
|
158
|
-
- 切勿使用 `queryGame()` 返回的 `play_url` 进行跳转。
|
|
159
|
-
4. **权限与购买体验**:
|
|
160
|
-
-
|
|
161
|
-
-
|
|
162
|
-
5. **本地开发调试预期**:
|
|
163
|
-
- 本地 `npm run dev` 阶段不存在宿主环境,`sdk.ready()` 握手超时为正常情况,请做好判空保护,**不要在本地伪造假登录或假用户数据**。
|
|
164
|
-
-
|
|
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)。
|