@kzheart_/mc-pilot 0.9.1 → 0.9.3
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/data/protocol/actions.json +231 -0
- package/data/protocol/errors.json +80 -0
- package/data/protocol/queries.json +160 -0
- package/data/variants.json +12 -9
- package/dist/commands/client.js +22 -73
- package/dist/commands/image.d.ts +2 -0
- package/dist/commands/image.js +211 -0
- package/dist/download/VersionMatrix.d.ts +1 -15
- package/dist/download/VersionMatrix.js +11 -7
- package/dist/download/client/ClientDownloader.d.ts +2 -2
- package/dist/download/client/ClientDownloader.js +35 -7
- package/dist/download/client/FabricRuntimeDownloader.d.ts +2 -0
- package/dist/download/client/FabricRuntimeDownloader.js +47 -17
- package/dist/index.js +2 -0
- package/dist/instance/ClientInstanceManager.d.ts +2 -0
- package/dist/instance/ClientInstanceManager.js +4 -1
- package/dist/schema.js +6 -6
- package/dist/util/instance-types.d.ts +1 -0
- package/package.json +5 -3
- package/scripts/launch-fabric-client.mjs +37 -3
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"requestFormat": {
|
|
4
|
+
"id": "uuid-v4",
|
|
5
|
+
"action": "string",
|
|
6
|
+
"params": "object"
|
|
7
|
+
},
|
|
8
|
+
"responseFormat": {
|
|
9
|
+
"id": "uuid-v4",
|
|
10
|
+
"success": "boolean",
|
|
11
|
+
"data": "object|null",
|
|
12
|
+
"error": "object|null"
|
|
13
|
+
},
|
|
14
|
+
"actions": [
|
|
15
|
+
{
|
|
16
|
+
"name": "chat.send",
|
|
17
|
+
"params": ["message"],
|
|
18
|
+
"description": "发送聊天消息"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "chat.command",
|
|
22
|
+
"params": ["command"],
|
|
23
|
+
"description": "执行聊天命令"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "chat.wait",
|
|
27
|
+
"params": ["match", "timeout"],
|
|
28
|
+
"description": "等待匹配的聊天消息"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "move.to",
|
|
32
|
+
"params": ["x", "y", "z"],
|
|
33
|
+
"description": "寻路移动到指定坐标"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "move.direction",
|
|
37
|
+
"params": ["direction", "blocks"],
|
|
38
|
+
"description": "朝指定方向移动"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "move.jump",
|
|
42
|
+
"params": [],
|
|
43
|
+
"description": "跳跃一次"
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"name": "move.sneak",
|
|
47
|
+
"params": ["enabled"],
|
|
48
|
+
"description": "切换潜行"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "move.sprint",
|
|
52
|
+
"params": ["enabled"],
|
|
53
|
+
"description": "切换疾跑"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "look.at",
|
|
57
|
+
"params": ["x", "y", "z"],
|
|
58
|
+
"description": "看向坐标"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "look.entity",
|
|
62
|
+
"params": ["filter"],
|
|
63
|
+
"description": "看向实体"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"name": "look.set",
|
|
67
|
+
"params": ["yaw", "pitch"],
|
|
68
|
+
"description": "设置精确视角"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"name": "block.break",
|
|
72
|
+
"params": ["x", "y", "z"],
|
|
73
|
+
"description": "破坏方块"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"name": "block.place",
|
|
77
|
+
"params": ["x", "y", "z", "face"],
|
|
78
|
+
"description": "放置方块"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "block.interact",
|
|
82
|
+
"params": ["x", "y", "z"],
|
|
83
|
+
"description": "右键交互方块"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "entity.attack",
|
|
87
|
+
"params": ["filter"],
|
|
88
|
+
"description": "攻击实体"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"name": "entity.interact",
|
|
92
|
+
"params": ["filter"],
|
|
93
|
+
"description": "右键交互实体"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"name": "entity.mount",
|
|
97
|
+
"params": ["filter"],
|
|
98
|
+
"description": "骑乘实体"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"name": "entity.dismount",
|
|
102
|
+
"params": [],
|
|
103
|
+
"description": "离开载具"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"name": "entity.steer",
|
|
107
|
+
"params": ["forward", "sideways", "jump", "sneak"],
|
|
108
|
+
"description": "控制载具"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"name": "inventory.hotbar",
|
|
112
|
+
"params": ["slot"],
|
|
113
|
+
"description": "切换快捷栏"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"name": "inventory.drop",
|
|
117
|
+
"params": ["all"],
|
|
118
|
+
"description": "丢弃手持物品"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"name": "inventory.use",
|
|
122
|
+
"params": [],
|
|
123
|
+
"description": "使用手持物品"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"name": "inventory.swap-hands",
|
|
127
|
+
"params": [],
|
|
128
|
+
"description": "交换主副手"
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"name": "gui.click",
|
|
132
|
+
"params": ["slot", "button", "key"],
|
|
133
|
+
"description": "点击 GUI 槽位"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"name": "gui.drag",
|
|
137
|
+
"params": ["slots", "button"],
|
|
138
|
+
"description": "拖拽 GUI 槽位"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"name": "gui.close",
|
|
142
|
+
"params": [],
|
|
143
|
+
"description": "关闭 GUI"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"name": "gui.wait-open",
|
|
147
|
+
"params": ["timeout"],
|
|
148
|
+
"description": "等待 GUI 打开"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"name": "gui.wait-update",
|
|
152
|
+
"params": ["timeout"],
|
|
153
|
+
"description": "等待 GUI 更新"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"name": "gui.screenshot",
|
|
157
|
+
"params": ["output"],
|
|
158
|
+
"description": "GUI 截图"
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
"name": "capture.screenshot",
|
|
162
|
+
"params": ["output", "region", "gui"],
|
|
163
|
+
"description": "屏幕截图"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"name": "sign.edit",
|
|
167
|
+
"params": ["x", "y", "z", "lines"],
|
|
168
|
+
"description": "编辑告示牌"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"name": "book.write",
|
|
172
|
+
"params": ["pages"],
|
|
173
|
+
"description": "写入书本"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"name": "book.sign",
|
|
177
|
+
"params": ["title", "author"],
|
|
178
|
+
"description": "签名书本"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"name": "channel.send",
|
|
182
|
+
"params": ["channel", "data"],
|
|
183
|
+
"description": "发送 Plugin Channel 消息"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"name": "channel.listen",
|
|
187
|
+
"params": ["channel", "timeout"],
|
|
188
|
+
"description": "等待 Plugin Channel 消息"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"name": "resourcepack.accept",
|
|
192
|
+
"params": [],
|
|
193
|
+
"description": "接受资源包"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"name": "resourcepack.reject",
|
|
197
|
+
"params": [],
|
|
198
|
+
"description": "拒绝资源包"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"name": "craft.craft",
|
|
202
|
+
"params": ["recipe"],
|
|
203
|
+
"description": "工作台合成"
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
"name": "craft.anvil",
|
|
207
|
+
"params": ["inputSlot", "rename"],
|
|
208
|
+
"description": "铁砧操作"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"name": "craft.enchant",
|
|
212
|
+
"params": ["option"],
|
|
213
|
+
"description": "附魔台操作"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"name": "craft.trade",
|
|
217
|
+
"params": ["index"],
|
|
218
|
+
"description": "交易操作"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"name": "wait.perform",
|
|
222
|
+
"params": ["seconds", "ticks", "untilHealthAbove", "untilGuiOpen", "untilOnGround", "timeout"],
|
|
223
|
+
"description": "等待与同步"
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"name": "client.reconnect",
|
|
227
|
+
"params": ["address"],
|
|
228
|
+
"description": "让客户端重新连接到指定服务器地址"
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"errors": [
|
|
4
|
+
{
|
|
5
|
+
"code": "CONNECTION_FAILED",
|
|
6
|
+
"exitCode": 1,
|
|
7
|
+
"description": "无法连接到客户端 WebSocket"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"code": "TIMEOUT",
|
|
11
|
+
"exitCode": 2,
|
|
12
|
+
"description": "操作等待超时"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"code": "CLIENT_NOT_FOUND",
|
|
16
|
+
"exitCode": 3,
|
|
17
|
+
"description": "找不到客户端"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"code": "CLIENT_NOT_RUNNING",
|
|
21
|
+
"exitCode": 3,
|
|
22
|
+
"description": "客户端未运行"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"code": "CLIENT_ALREADY_RUNNING",
|
|
26
|
+
"exitCode": 3,
|
|
27
|
+
"description": "客户端已在运行"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"code": "INVALID_PARAMS",
|
|
31
|
+
"exitCode": 4,
|
|
32
|
+
"description": "参数格式错误或缺少必要配置"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"code": "SERVER_NOT_RUNNING",
|
|
36
|
+
"exitCode": 5,
|
|
37
|
+
"description": "服务端未运行"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"code": "SERVER_ALREADY_RUNNING",
|
|
41
|
+
"exitCode": 5,
|
|
42
|
+
"description": "服务端已在运行"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"code": "GUI_NOT_OPEN",
|
|
46
|
+
"exitCode": 3,
|
|
47
|
+
"description": "没有打开的 GUI"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"code": "SLOT_OUT_OF_RANGE",
|
|
51
|
+
"exitCode": 3,
|
|
52
|
+
"description": "槽位索引超出范围"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"code": "ENTITY_NOT_FOUND",
|
|
56
|
+
"exitCode": 3,
|
|
57
|
+
"description": "找不到匹配实体"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"code": "BLOCK_OUT_OF_RANGE",
|
|
61
|
+
"exitCode": 3,
|
|
62
|
+
"description": "目标方块超出交互距离"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"code": "PATHFINDING_FAILED",
|
|
66
|
+
"exitCode": 3,
|
|
67
|
+
"description": "寻路失败"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"code": "NOT_IN_WORLD",
|
|
71
|
+
"exitCode": 3,
|
|
72
|
+
"description": "玩家不在世界中"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"code": "INTERNAL_ERROR",
|
|
76
|
+
"exitCode": 1,
|
|
77
|
+
"description": "CLI 内部错误"
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"queries": [
|
|
4
|
+
{
|
|
5
|
+
"name": "chat.history",
|
|
6
|
+
"params": ["last"],
|
|
7
|
+
"description": "获取聊天历史"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"name": "chat.last",
|
|
11
|
+
"params": [],
|
|
12
|
+
"description": "获取最后一条聊天消息"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"name": "position.get",
|
|
16
|
+
"params": [],
|
|
17
|
+
"description": "获取当前位置"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "rotation.get",
|
|
21
|
+
"params": [],
|
|
22
|
+
"description": "获取当前朝向"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "block.get",
|
|
26
|
+
"params": ["x", "y", "z"],
|
|
27
|
+
"description": "查询方块信息"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "entity.list",
|
|
31
|
+
"params": ["radius"],
|
|
32
|
+
"description": "列出范围内实体"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "entity.info",
|
|
36
|
+
"params": ["id"],
|
|
37
|
+
"description": "查询实体详情"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "inventory.get",
|
|
41
|
+
"params": [],
|
|
42
|
+
"description": "获取完整背包"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "inventory.slot",
|
|
46
|
+
"params": ["slot"],
|
|
47
|
+
"description": "获取指定槽位"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "inventory.held",
|
|
51
|
+
"params": [],
|
|
52
|
+
"description": "获取当前手持物品"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "gui.info",
|
|
56
|
+
"params": [],
|
|
57
|
+
"description": "获取 GUI 信息"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "gui.snapshot",
|
|
61
|
+
"params": [],
|
|
62
|
+
"description": "获取 GUI 快照"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "gui.slot",
|
|
66
|
+
"params": ["slot"],
|
|
67
|
+
"description": "获取 GUI 槽位"
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"name": "screen.size",
|
|
71
|
+
"params": [],
|
|
72
|
+
"description": "获取屏幕大小"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "hud.scoreboard",
|
|
76
|
+
"params": [],
|
|
77
|
+
"description": "获取侧边栏计分板"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"name": "hud.tab",
|
|
81
|
+
"params": [],
|
|
82
|
+
"description": "获取 Tab 列表"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "hud.bossbar",
|
|
86
|
+
"params": [],
|
|
87
|
+
"description": "获取 BossBar"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"name": "hud.actionbar",
|
|
91
|
+
"params": [],
|
|
92
|
+
"description": "获取 ActionBar"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"name": "hud.title",
|
|
96
|
+
"params": [],
|
|
97
|
+
"description": "获取 Title"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "hud.nametag",
|
|
101
|
+
"params": ["player"],
|
|
102
|
+
"description": "获取指定玩家名牌"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "status.health",
|
|
106
|
+
"params": [],
|
|
107
|
+
"description": "获取生命与饥饿状态"
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
"name": "status.effects",
|
|
111
|
+
"params": [],
|
|
112
|
+
"description": "获取药水效果"
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"name": "status.experience",
|
|
116
|
+
"params": [],
|
|
117
|
+
"description": "获取经验状态"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"name": "status.gamemode",
|
|
121
|
+
"params": [],
|
|
122
|
+
"description": "获取游戏模式"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"name": "status.world",
|
|
126
|
+
"params": [],
|
|
127
|
+
"description": "获取世界状态"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "status.all",
|
|
131
|
+
"params": [],
|
|
132
|
+
"description": "获取聚合状态"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"name": "sign.read",
|
|
136
|
+
"params": ["x", "y", "z"],
|
|
137
|
+
"description": "读取告示牌"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "book.read",
|
|
141
|
+
"params": [],
|
|
142
|
+
"description": "读取书本"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"name": "resourcepack.status",
|
|
146
|
+
"params": [],
|
|
147
|
+
"description": "获取资源包状态"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"name": "effects.sounds",
|
|
151
|
+
"params": ["last"],
|
|
152
|
+
"description": "获取最近音效事件"
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
"name": "effects.particles",
|
|
156
|
+
"params": ["last"],
|
|
157
|
+
"description": "获取最近粒子事件"
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
}
|
package/data/variants.json
CHANGED
|
@@ -31,11 +31,12 @@
|
|
|
31
31
|
"id": "1.20.1-forge",
|
|
32
32
|
"minecraftVersion": "1.20.1",
|
|
33
33
|
"loader": "forge",
|
|
34
|
-
"support": "
|
|
35
|
-
"validation": "
|
|
34
|
+
"support": "configured",
|
|
35
|
+
"validation": "limited",
|
|
36
36
|
"modVersion": "0.9.1",
|
|
37
37
|
"forgeVersion": "47.3.0",
|
|
38
|
-
"javaVersion": 17
|
|
38
|
+
"javaVersion": 17,
|
|
39
|
+
"gradleModule": "version-1.20.1-forge"
|
|
39
40
|
},
|
|
40
41
|
{
|
|
41
42
|
"id": "1.20.2-fabric",
|
|
@@ -53,11 +54,12 @@
|
|
|
53
54
|
"id": "1.20.2-forge",
|
|
54
55
|
"minecraftVersion": "1.20.2",
|
|
55
56
|
"loader": "forge",
|
|
56
|
-
"support": "
|
|
57
|
-
"validation": "
|
|
57
|
+
"support": "configured",
|
|
58
|
+
"validation": "limited",
|
|
58
59
|
"modVersion": "0.9.1",
|
|
59
60
|
"forgeVersion": "48.1.0",
|
|
60
|
-
"javaVersion": 17
|
|
61
|
+
"javaVersion": 17,
|
|
62
|
+
"gradleModule": "version-1.20.2-forge"
|
|
61
63
|
},
|
|
62
64
|
{
|
|
63
65
|
"id": "1.20.4-fabric",
|
|
@@ -75,11 +77,12 @@
|
|
|
75
77
|
"id": "1.20.4-forge",
|
|
76
78
|
"minecraftVersion": "1.20.4",
|
|
77
79
|
"loader": "forge",
|
|
78
|
-
"support": "
|
|
79
|
-
"validation": "
|
|
80
|
+
"support": "configured",
|
|
81
|
+
"validation": "limited",
|
|
80
82
|
"modVersion": "0.9.1",
|
|
81
83
|
"forgeVersion": "49.0.49",
|
|
82
|
-
"javaVersion": 17
|
|
84
|
+
"javaVersion": 17,
|
|
85
|
+
"gradleModule": "version-1.20.4-forge"
|
|
83
86
|
},
|
|
84
87
|
{
|
|
85
88
|
"id": "1.20.4-neoforge",
|
package/dist/commands/client.js
CHANGED
|
@@ -5,14 +5,8 @@ import { ServerInstanceManager } from "../instance/ServerInstanceManager.js";
|
|
|
5
5
|
import { MctError } from "../util/errors.js";
|
|
6
6
|
import { createRequestAction } from "./request-helpers.js";
|
|
7
7
|
import { wrapCommand } from "../util/command.js";
|
|
8
|
-
import {
|
|
9
|
-
import { findVariantByVersionAndLoader, getModArtifactFileName, loadModVariantCatalog } from "../download/ModVariantCatalog.js";
|
|
10
|
-
import { detectJava } from "../download/JavaDetector.js";
|
|
11
|
-
import { prepareManagedFabricRuntime } from "../download/client/FabricRuntimeDownloader.js";
|
|
12
|
-
import { copyFileIfMissing, downloadFile } from "../download/DownloadUtils.js";
|
|
8
|
+
import { downloadClientModToDir } from "../download/client/ClientDownloader.js";
|
|
13
9
|
import { resolveClientInstanceDir } from "../util/paths.js";
|
|
14
|
-
import { access, mkdir } from "node:fs/promises";
|
|
15
|
-
import path from "node:path";
|
|
16
10
|
export async function resolveProfileServerAddress(context, explicitServer, loadPort) {
|
|
17
11
|
if (explicitServer) {
|
|
18
12
|
return explicitServer;
|
|
@@ -50,93 +44,46 @@ export function createClientCommand() {
|
|
|
50
44
|
.description("Create a new client instance")
|
|
51
45
|
.argument("<name>", "Client instance name (e.g. fabric-1.20.4)")
|
|
52
46
|
.option("--version <version>", "Minecraft version (default: 1.21.4)")
|
|
53
|
-
.option("--loader <loader>", "Client loader: fabric (default: fabric)")
|
|
47
|
+
.option("--loader <loader>", "Client loader: fabric|forge (default: fabric)")
|
|
54
48
|
.option("--ws-port <port>", "WebSocket port (auto-assigned if omitted)", Number)
|
|
55
49
|
.option("--account <account>", "Offline username or account identifier")
|
|
56
50
|
.option("--headless", "Launch in headless mode")
|
|
51
|
+
.option("--mute", "Mute all in-game audio for this client")
|
|
52
|
+
.option("--no-mute", "Keep in-game audio enabled for this client")
|
|
57
53
|
.option("--java <command>", "Java command to use")
|
|
58
54
|
.action(wrapCommand(async (_context, { args, options }) => {
|
|
59
55
|
const clientName = args[0];
|
|
60
56
|
const loader = options.loader ?? "fabric";
|
|
61
57
|
const version = options.version ?? "1.21.4";
|
|
62
|
-
const cacheManager = new CacheManager();
|
|
63
|
-
const catalog = await loadModVariantCatalog();
|
|
64
|
-
const variant = findVariantByVersionAndLoader(catalog, version, loader);
|
|
65
|
-
if (!variant) {
|
|
66
|
-
throw new MctError({ code: "VARIANT_NOT_FOUND", message: `No mod variant found for ${version} / ${loader}` }, 4);
|
|
67
|
-
}
|
|
68
|
-
if (variant.loader !== "fabric") {
|
|
69
|
-
throw new MctError({ code: "UNSUPPORTED_LOADER", message: `Loader ${variant.loader} is not implemented yet` }, 4);
|
|
70
|
-
}
|
|
71
|
-
// Check Java
|
|
72
|
-
const java = await detectJava(options.java ?? "java");
|
|
73
|
-
const requiredJava = variant.javaVersion ?? 17;
|
|
74
|
-
if (!java.available || (java.majorVersion ?? 0) < requiredJava) {
|
|
75
|
-
throw new MctError({ code: "JAVA_NOT_FOUND", message: `Java ${requiredJava}+ is required for ${variant.id}` }, 4);
|
|
76
|
-
}
|
|
77
|
-
// Resolve mod artifact
|
|
78
|
-
const artifactFileName = getModArtifactFileName(variant);
|
|
79
|
-
const cacheArtifactPath = cacheManager.getModFile(artifactFileName);
|
|
80
|
-
const gradleModule = variant.gradleModule ?? `version-${variant.minecraftVersion}`;
|
|
81
|
-
const localBuildPath = path.join(process.cwd(), "client-mod", gradleModule, "build", "libs", artifactFileName);
|
|
82
|
-
let sourcePath;
|
|
83
|
-
try {
|
|
84
|
-
await access(localBuildPath);
|
|
85
|
-
sourcePath = localBuildPath;
|
|
86
|
-
await copyFileIfMissing(localBuildPath, cacheArtifactPath);
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
try {
|
|
90
|
-
await access(cacheArtifactPath);
|
|
91
|
-
sourcePath = cacheArtifactPath;
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
const modVersion = variant.modVersion ?? "0.9.1";
|
|
95
|
-
const baseUrl = process.env.MCT_MOD_DOWNLOAD_BASE_URL || "https://github.com/kzheart/mc-pilot/releases/download";
|
|
96
|
-
const downloadUrl = `${baseUrl}/v${modVersion}/${artifactFileName}`;
|
|
97
|
-
await downloadFile(downloadUrl, cacheArtifactPath, fetch);
|
|
98
|
-
sourcePath = cacheArtifactPath;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// Set up client instance directory
|
|
102
58
|
const instanceDir = resolveClientInstanceDir(clientName);
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const runtimeRootDir = path.join(cacheManager.getRootDir(), "client", "runtime", variant.minecraftVersion);
|
|
109
|
-
const managedRuntime = await prepareManagedFabricRuntime(variant, {
|
|
110
|
-
runtimeRootDir,
|
|
111
|
-
gameDir: minecraftDir
|
|
112
|
-
}, { fetchImpl: fetch });
|
|
113
|
-
const launchArgs = [
|
|
114
|
-
"--runtime-root", managedRuntime.runtimeRootDir,
|
|
115
|
-
"--version-id", managedRuntime.versionId,
|
|
116
|
-
"--game-dir", managedRuntime.gameDir
|
|
117
|
-
];
|
|
59
|
+
const downloaded = await downloadClientModToDir(process.cwd(), instanceDir, {
|
|
60
|
+
version,
|
|
61
|
+
loader,
|
|
62
|
+
java: options.java
|
|
63
|
+
});
|
|
118
64
|
const manager = new ClientInstanceManager(_context.globalState);
|
|
119
65
|
const meta = await manager.create({
|
|
120
66
|
name: clientName,
|
|
121
|
-
loader,
|
|
122
|
-
version:
|
|
67
|
+
loader: downloaded.loader,
|
|
68
|
+
version: downloaded.minecraftVersion,
|
|
123
69
|
wsPort: options.wsPort,
|
|
124
70
|
account: options.account,
|
|
125
71
|
headless: options.headless,
|
|
126
|
-
|
|
72
|
+
mute: options.mute,
|
|
73
|
+
launchArgs: downloaded.launchArgs,
|
|
127
74
|
env: {
|
|
128
|
-
MCT_CLIENT_MOD_VARIANT:
|
|
129
|
-
MCT_CLIENT_MOD_JAR:
|
|
75
|
+
MCT_CLIENT_MOD_VARIANT: downloaded.variantId,
|
|
76
|
+
MCT_CLIENT_MOD_JAR: downloaded.jar
|
|
130
77
|
}
|
|
131
78
|
});
|
|
132
79
|
return {
|
|
133
80
|
created: true,
|
|
134
81
|
...meta,
|
|
135
|
-
javaCommand:
|
|
136
|
-
javaVersion:
|
|
137
|
-
modsDir,
|
|
138
|
-
runtimeRootDir:
|
|
139
|
-
runtimeVersionId:
|
|
82
|
+
javaCommand: downloaded.javaCommand,
|
|
83
|
+
javaVersion: downloaded.javaVersion,
|
|
84
|
+
modsDir: downloaded.modsDir,
|
|
85
|
+
runtimeRootDir: downloaded.runtimeRootDir,
|
|
86
|
+
runtimeVersionId: downloaded.runtimeVersionId
|
|
140
87
|
};
|
|
141
88
|
}));
|
|
142
89
|
command
|
|
@@ -147,6 +94,8 @@ export function createClientCommand() {
|
|
|
147
94
|
.option("--account <account>", "Offline username or account identifier")
|
|
148
95
|
.option("--ws-port <port>", "WebSocket port override", Number)
|
|
149
96
|
.option("--headless", "Launch in headless mode")
|
|
97
|
+
.option("--mute", "Mute all in-game audio for this launch")
|
|
98
|
+
.option("--no-mute", "Keep in-game audio enabled for this launch")
|
|
150
99
|
.option("--force", "Kill any existing client with the same name before launching")
|
|
151
100
|
.action(wrapCommand(async (context, { args, options }) => {
|
|
152
101
|
const clientName = args[0] ?? context.activeProfile?.clients[0];
|