@kzheart_/mc-pilot 0.1.0
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/bin/mct +2 -0
- package/data/variants.json +139 -0
- package/dist/client/ClientManager.d.ts +82 -0
- package/dist/client/ClientManager.js +213 -0
- package/dist/client/WebSocketClient.d.ts +15 -0
- package/dist/client/WebSocketClient.js +76 -0
- package/dist/commands/block.d.ts +2 -0
- package/dist/commands/block.js +52 -0
- package/dist/commands/book.d.ts +2 -0
- package/dist/commands/book.js +21 -0
- package/dist/commands/channel.d.ts +2 -0
- package/dist/commands/channel.js +24 -0
- package/dist/commands/chat.d.ts +2 -0
- package/dist/commands/chat.js +31 -0
- package/dist/commands/client.d.ts +2 -0
- package/dist/commands/client.js +87 -0
- package/dist/commands/combat.d.ts +2 -0
- package/dist/commands/combat.js +46 -0
- package/dist/commands/craft.d.ts +5 -0
- package/dist/commands/craft.js +45 -0
- package/dist/commands/effects.d.ts +2 -0
- package/dist/commands/effects.js +16 -0
- package/dist/commands/entity.d.ts +2 -0
- package/dist/commands/entity.js +53 -0
- package/dist/commands/gui.d.ts +2 -0
- package/dist/commands/gui.js +49 -0
- package/dist/commands/hud.d.ts +2 -0
- package/dist/commands/hud.js +16 -0
- package/dist/commands/input.d.ts +2 -0
- package/dist/commands/input.js +124 -0
- package/dist/commands/inventory.d.ts +2 -0
- package/dist/commands/inventory.js +28 -0
- package/dist/commands/look.d.ts +2 -0
- package/dist/commands/look.js +37 -0
- package/dist/commands/move.d.ts +2 -0
- package/dist/commands/move.js +50 -0
- package/dist/commands/position.d.ts +2 -0
- package/dist/commands/position.js +7 -0
- package/dist/commands/request-helpers.d.ts +26 -0
- package/dist/commands/request-helpers.js +58 -0
- package/dist/commands/resourcepack.d.ts +2 -0
- package/dist/commands/resourcepack.js +9 -0
- package/dist/commands/rotation.d.ts +2 -0
- package/dist/commands/rotation.js +7 -0
- package/dist/commands/screen.d.ts +2 -0
- package/dist/commands/screen.js +7 -0
- package/dist/commands/screenshot.d.ts +2 -0
- package/dist/commands/screenshot.js +14 -0
- package/dist/commands/server.d.ts +2 -0
- package/dist/commands/server.js +66 -0
- package/dist/commands/sign.d.ts +2 -0
- package/dist/commands/sign.js +30 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +17 -0
- package/dist/commands/wait.d.ts +2 -0
- package/dist/commands/wait.js +23 -0
- package/dist/download/CacheManager.d.ts +20 -0
- package/dist/download/CacheManager.js +50 -0
- package/dist/download/DownloadUtils.d.ts +2 -0
- package/dist/download/DownloadUtils.js +23 -0
- package/dist/download/JavaDetector.d.ts +7 -0
- package/dist/download/JavaDetector.js +31 -0
- package/dist/download/ModVariantCatalog.d.ts +10 -0
- package/dist/download/ModVariantCatalog.js +52 -0
- package/dist/download/SearchCommand.d.ts +29 -0
- package/dist/download/SearchCommand.js +37 -0
- package/dist/download/VersionMatrix.d.ts +72 -0
- package/dist/download/VersionMatrix.js +227 -0
- package/dist/download/client/Arm64LwjglPatcher.d.ts +5 -0
- package/dist/download/client/Arm64LwjglPatcher.js +153 -0
- package/dist/download/client/ClientDownloader.d.ts +42 -0
- package/dist/download/client/ClientDownloader.js +233 -0
- package/dist/download/client/FabricRuntimeDownloader.d.ts +10 -0
- package/dist/download/client/FabricRuntimeDownloader.js +91 -0
- package/dist/download/server/ServerDownloader.d.ts +51 -0
- package/dist/download/server/ServerDownloader.js +196 -0
- package/dist/download/types.d.ts +37 -0
- package/dist/download/types.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +89 -0
- package/dist/server/ServerManager.d.ts +63 -0
- package/dist/server/ServerManager.js +114 -0
- package/dist/util/command.d.ts +10 -0
- package/dist/util/command.js +35 -0
- package/dist/util/config.d.ts +30 -0
- package/dist/util/config.js +59 -0
- package/dist/util/context.d.ts +17 -0
- package/dist/util/context.js +16 -0
- package/dist/util/errors.d.ts +20 -0
- package/dist/util/errors.js +37 -0
- package/dist/util/net.d.ts +5 -0
- package/dist/util/net.js +35 -0
- package/dist/util/output.d.ts +4 -0
- package/dist/util/output.js +23 -0
- package/dist/util/process.d.ts +3 -0
- package/dist/util/process.js +32 -0
- package/dist/util/state.d.ts +10 -0
- package/dist/util/state.js +40 -0
- package/package.json +54 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { ClientManager } from "../client/ClientManager.js";
|
|
3
|
+
import { downloadClientMod } from "../download/client/ClientDownloader.js";
|
|
4
|
+
import { buildClientSearchResults } from "../download/SearchCommand.js";
|
|
5
|
+
import { createRequestAction } from "./request-helpers.js";
|
|
6
|
+
import { wrapCommand } from "../util/command.js";
|
|
7
|
+
export function createClientCommand() {
|
|
8
|
+
const command = new Command("client").description("Manage Minecraft client");
|
|
9
|
+
command
|
|
10
|
+
.command("search")
|
|
11
|
+
.description("Search available client version and loader combinations")
|
|
12
|
+
.option("--loader <loader>", "Client loader: fabric|forge|neoforge")
|
|
13
|
+
.option("--version <version>", "Minecraft version")
|
|
14
|
+
.action(wrapCommand(async (_context, { options }) => {
|
|
15
|
+
return {
|
|
16
|
+
results: buildClientSearchResults({
|
|
17
|
+
loader: options.loader,
|
|
18
|
+
version: options.version
|
|
19
|
+
})
|
|
20
|
+
};
|
|
21
|
+
}));
|
|
22
|
+
command
|
|
23
|
+
.command("download")
|
|
24
|
+
.description("Download client mod and update config")
|
|
25
|
+
.option("--loader <loader>", "Client loader: fabric|forge|neoforge (default: fabric)")
|
|
26
|
+
.option("--version <version>", "Minecraft version (default: 1.20.4)")
|
|
27
|
+
.option("--dir <path>", "Mod download directory")
|
|
28
|
+
.option("--name <name>", "Client config name (default: \"default\"); use this name with \"client launch\"")
|
|
29
|
+
.option("--ws-port <port>", "WebSocket port for CLI-to-mod communication (default: 25560)", Number)
|
|
30
|
+
.option("--server <address>", "Default server address (e.g. localhost:25565)")
|
|
31
|
+
.option("--instance-dir <path>", "Client instance directory")
|
|
32
|
+
.option("--meta-dir <path>", "Runtime metadata directory")
|
|
33
|
+
.option("--libraries-dir <path>", "Runtime libraries directory")
|
|
34
|
+
.option("--assets-dir <path>", "Runtime assets directory")
|
|
35
|
+
.option("--natives-dir <path>", "Runtime natives directory")
|
|
36
|
+
.action(wrapCommand(async (context, { options }) => {
|
|
37
|
+
return downloadClientMod(context, options);
|
|
38
|
+
}));
|
|
39
|
+
command
|
|
40
|
+
.command("launch")
|
|
41
|
+
.description("Launch a client instance")
|
|
42
|
+
.argument("<name>", "Client name (matches a key in config \"clients\", e.g. \"default\")")
|
|
43
|
+
.option("--version <version>", "Minecraft version")
|
|
44
|
+
.option("--server <address>", "Target server address (e.g. localhost:25565)")
|
|
45
|
+
.option("--account <account>", "Offline username or account identifier")
|
|
46
|
+
.option("--ws-port <port>", "WebSocket port (default: 25560)", Number)
|
|
47
|
+
.option("--headless", "Launch in headless mode (window hidden)")
|
|
48
|
+
.action(wrapCommand(async (context, { args, options }) => {
|
|
49
|
+
const manager = new ClientManager(context);
|
|
50
|
+
return manager.launch({
|
|
51
|
+
name: args[0],
|
|
52
|
+
...options
|
|
53
|
+
});
|
|
54
|
+
}));
|
|
55
|
+
command
|
|
56
|
+
.command("stop")
|
|
57
|
+
.description("Stop a client instance")
|
|
58
|
+
.argument("<name>", "Client name")
|
|
59
|
+
.action(wrapCommand(async (context, { args }) => {
|
|
60
|
+
const manager = new ClientManager(context);
|
|
61
|
+
return manager.stop(args[0]);
|
|
62
|
+
}));
|
|
63
|
+
command
|
|
64
|
+
.command("list")
|
|
65
|
+
.description("List all client instances and their status")
|
|
66
|
+
.action(wrapCommand(async (context) => {
|
|
67
|
+
const manager = new ClientManager(context);
|
|
68
|
+
return manager.list();
|
|
69
|
+
}));
|
|
70
|
+
command
|
|
71
|
+
.command("wait-ready")
|
|
72
|
+
.description("Wait until client WebSocket is connected")
|
|
73
|
+
.argument("<name>", "Client name")
|
|
74
|
+
.option("--timeout <seconds>", "Timeout in seconds", Number)
|
|
75
|
+
.action(wrapCommand(async (context, { args, options }) => {
|
|
76
|
+
const manager = new ClientManager(context);
|
|
77
|
+
return manager.waitReady(args[0], options.timeout ?? context.config.timeout.clientReady);
|
|
78
|
+
}));
|
|
79
|
+
command
|
|
80
|
+
.command("reconnect")
|
|
81
|
+
.description("Reconnect the client to the server")
|
|
82
|
+
.option("--address <address>", "Target server address (default: from launch config)")
|
|
83
|
+
.action(createRequestAction("client.reconnect", ({ options }) => ({
|
|
84
|
+
address: options.address
|
|
85
|
+
})));
|
|
86
|
+
return command;
|
|
87
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { buildEntityFilter, createRequestAction, withTransportTimeoutBuffer } from "./request-helpers.js";
|
|
3
|
+
export function createCombatCommand() {
|
|
4
|
+
const command = new Command("combat").description("Combat combo operations");
|
|
5
|
+
const combatActionLabels = {
|
|
6
|
+
kill: "Attack target repeatedly until it dies",
|
|
7
|
+
engage: "Approach and attack target once",
|
|
8
|
+
chase: "Chase target without attacking"
|
|
9
|
+
};
|
|
10
|
+
for (const actionName of ["kill", "engage", "chase"]) {
|
|
11
|
+
command
|
|
12
|
+
.command(actionName)
|
|
13
|
+
.description(combatActionLabels[actionName])
|
|
14
|
+
.option("--type <type>", "Entity type (e.g. zombie, skeleton)")
|
|
15
|
+
.option("--name <name>", "Entity custom name")
|
|
16
|
+
.option("--nearest", "Target the nearest matching entity")
|
|
17
|
+
.option("--id <id>", "Entity network ID", Number)
|
|
18
|
+
.option("--max-distance <distance>", "Max search distance in blocks", Number)
|
|
19
|
+
.option("--timeout <seconds>", "Timeout in seconds (default: 30)", Number)
|
|
20
|
+
.action(createRequestAction(`combat.${actionName}`, ({ options }) => ({
|
|
21
|
+
filter: buildEntityFilter(options),
|
|
22
|
+
timeout: options.timeout
|
|
23
|
+
}), ({ options }, context) => withTransportTimeoutBuffer(options.timeout ? Number(options.timeout) : 30, context.config.timeout.default)));
|
|
24
|
+
}
|
|
25
|
+
command
|
|
26
|
+
.command("clear")
|
|
27
|
+
.description("Kill all entities of a type within radius")
|
|
28
|
+
.requiredOption("--type <type>", "Entity type (e.g. zombie)")
|
|
29
|
+
.option("--radius <radius>", "Search radius in blocks (default: 16)", Number)
|
|
30
|
+
.option("--timeout <seconds>", "Timeout in seconds (default: 60)", Number)
|
|
31
|
+
.action(createRequestAction("combat.clear", ({ options }) => ({
|
|
32
|
+
type: options.type,
|
|
33
|
+
radius: options.radius ?? 16,
|
|
34
|
+
timeout: options.timeout
|
|
35
|
+
}), ({ options }, context) => withTransportTimeoutBuffer(options.timeout ? Number(options.timeout) : 60, context.config.timeout.default)));
|
|
36
|
+
command
|
|
37
|
+
.command("pickup")
|
|
38
|
+
.description("Pick up nearby dropped items")
|
|
39
|
+
.option("--radius <radius>", "Pickup radius in blocks (default: 5)", Number)
|
|
40
|
+
.option("--timeout <seconds>", "Timeout in seconds (default: 10)", Number)
|
|
41
|
+
.action(createRequestAction("combat.pickup", ({ options }) => ({
|
|
42
|
+
radius: options.radius ?? 5,
|
|
43
|
+
timeout: options.timeout
|
|
44
|
+
}), ({ options }, context) => withTransportTimeoutBuffer(options.timeout ? Number(options.timeout) : 10, context.config.timeout.default)));
|
|
45
|
+
return command;
|
|
46
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { createRequestAction, parseJson } from "./request-helpers.js";
|
|
3
|
+
export function createCraftCommand() {
|
|
4
|
+
return new Command("craft")
|
|
5
|
+
.description("Crafting table recipe\n" +
|
|
6
|
+
"Prerequisite: open crafting table with \"block interact <x> <y> <z>\"\n" +
|
|
7
|
+
"Auto-places materials from inventory, crafts, and moves result to inventory.\n" +
|
|
8
|
+
"GUI closes automatically after crafting.")
|
|
9
|
+
.requiredOption("--recipe <json>", "Recipe JSON: 9-slot array in row-major order (top-left to bottom-right).\n" +
|
|
10
|
+
"Use item IDs without namespace (e.g. \"oak_planks\", not \"minecraft:oak_planks\").\n" +
|
|
11
|
+
"Example: '{\"slots\":[\"oak_planks\",\"oak_planks\",null,\"oak_planks\",\"oak_planks\",null,null,null,null]}'")
|
|
12
|
+
.action(createRequestAction("craft.craft", ({ options }) => ({ recipe: parseJson(String(options.recipe), "recipe") })));
|
|
13
|
+
}
|
|
14
|
+
export function createAnvilCommand() {
|
|
15
|
+
return new Command("anvil")
|
|
16
|
+
.description("Anvil rename operation\n" +
|
|
17
|
+
"Prerequisite: open anvil with \"block interact <x> <y> <z>\"\n" +
|
|
18
|
+
"Auto-moves item from inventory slot to anvil, renames it, and moves result back.\n" +
|
|
19
|
+
"GUI closes automatically.")
|
|
20
|
+
.requiredOption("--input-slot <slot>", "Inventory slot of the item to rename (0-8: hotbar, 9-35: main)", Number)
|
|
21
|
+
.requiredOption("--rename <name>", "New item name")
|
|
22
|
+
.action(createRequestAction("craft.anvil", ({ options }) => ({
|
|
23
|
+
inputSlot: options.inputSlot,
|
|
24
|
+
rename: options.rename
|
|
25
|
+
})));
|
|
26
|
+
}
|
|
27
|
+
export function createEnchantCommand() {
|
|
28
|
+
return new Command("enchant")
|
|
29
|
+
.description("Enchanting table operation\n" +
|
|
30
|
+
"Prerequisite: open enchanting table with \"block interact <x> <y> <z>\"\n" +
|
|
31
|
+
"You must first place the item and lapis lazuli manually via \"gui click\".\n" +
|
|
32
|
+
"Use \"gui snapshot\" to inspect slot layout. This command only selects the enchantment option.")
|
|
33
|
+
.requiredOption("--option <index>", "Enchantment option: 0 = top, 1 = middle, 2 = bottom", Number)
|
|
34
|
+
.action(createRequestAction("craft.enchant", ({ options }) => ({ option: options.option })));
|
|
35
|
+
}
|
|
36
|
+
export function createTradeCommand() {
|
|
37
|
+
return new Command("trade")
|
|
38
|
+
.description("Villager trading\n" +
|
|
39
|
+
"Prerequisite: open trade GUI with \"entity interact --nearest --type villager\"\n" +
|
|
40
|
+
"Use \"gui snapshot\" to inspect available trades.\n" +
|
|
41
|
+
"Selects the trade by index, auto-takes the result into inventory.\n" +
|
|
42
|
+
"Requires payment items already in inventory.")
|
|
43
|
+
.requiredOption("--index <index>", "Trade index (0-based)", Number)
|
|
44
|
+
.action(createRequestAction("craft.trade", ({ options }) => ({ index: options.index })));
|
|
45
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { createRequestAction } from "./request-helpers.js";
|
|
3
|
+
export function createEffectsCommand() {
|
|
4
|
+
const command = new Command("effects").description("音效与粒子事件");
|
|
5
|
+
command
|
|
6
|
+
.command("sounds")
|
|
7
|
+
.description("获取音效事件")
|
|
8
|
+
.option("--last <count>", "最近条数", Number)
|
|
9
|
+
.action(createRequestAction("effects.sounds", ({ options }) => ({ last: options.last ?? 10 })));
|
|
10
|
+
command
|
|
11
|
+
.command("particles")
|
|
12
|
+
.description("获取粒子事件")
|
|
13
|
+
.option("--last <count>", "最近条数", Number)
|
|
14
|
+
.action(createRequestAction("effects.particles", ({ options }) => ({ last: options.last ?? 10 })));
|
|
15
|
+
return command;
|
|
16
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { buildEntityFilter, createRequestAction } from "./request-helpers.js";
|
|
3
|
+
export function createEntityCommand() {
|
|
4
|
+
const command = new Command("entity").description("Entity interaction");
|
|
5
|
+
const entityActionLabels = {
|
|
6
|
+
attack: "Attack an entity",
|
|
7
|
+
interact: "Interact with an entity (right-click)",
|
|
8
|
+
mount: "Mount an entity"
|
|
9
|
+
};
|
|
10
|
+
for (const actionName of ["attack", "interact", "mount"]) {
|
|
11
|
+
command
|
|
12
|
+
.command(actionName)
|
|
13
|
+
.description(entityActionLabels[actionName])
|
|
14
|
+
.option("--type <type>", "Entity type (e.g. zombie, villager)")
|
|
15
|
+
.option("--name <name>", "Entity custom name")
|
|
16
|
+
.option("--nearest", "Target the nearest matching entity")
|
|
17
|
+
.option("--id <id>", "Entity network ID", Number)
|
|
18
|
+
.option("--max-distance <distance>", "Max search distance in blocks", Number)
|
|
19
|
+
.action(createRequestAction(`entity.${actionName}`, ({ options }) => ({
|
|
20
|
+
filter: buildEntityFilter(options)
|
|
21
|
+
})));
|
|
22
|
+
}
|
|
23
|
+
command
|
|
24
|
+
.command("list")
|
|
25
|
+
.description("List nearby entities")
|
|
26
|
+
.option("--radius <radius>", "Search radius in blocks (default: 10)", Number)
|
|
27
|
+
.action(createRequestAction("entity.list", ({ options }) => ({ radius: options.radius ?? 10 })));
|
|
28
|
+
command
|
|
29
|
+
.command("info")
|
|
30
|
+
.description("Get detailed entity info")
|
|
31
|
+
.requiredOption("--id <id>", "Entity network ID", Number)
|
|
32
|
+
.action(createRequestAction("entity.info", ({ options }) => ({ id: options.id })));
|
|
33
|
+
command
|
|
34
|
+
.command("dismount")
|
|
35
|
+
.description("Dismount from current vehicle")
|
|
36
|
+
.action(createRequestAction("entity.dismount", () => ({})));
|
|
37
|
+
command
|
|
38
|
+
.command("steer")
|
|
39
|
+
.description("Steer a mounted vehicle (flags can be combined)")
|
|
40
|
+
.option("--forward", "Move forward")
|
|
41
|
+
.option("--back", "Move backward")
|
|
42
|
+
.option("--left", "Turn left")
|
|
43
|
+
.option("--right", "Turn right")
|
|
44
|
+
.option("--jump", "Jump")
|
|
45
|
+
.option("--sneak", "Sneak / dismount")
|
|
46
|
+
.action(createRequestAction("entity.steer", ({ options }) => ({
|
|
47
|
+
forward: options.forward ? 1 : options.back ? -1 : 0,
|
|
48
|
+
sideways: options.left ? 1 : options.right ? -1 : 0,
|
|
49
|
+
jump: Boolean(options.jump),
|
|
50
|
+
sneak: Boolean(options.sneak)
|
|
51
|
+
})));
|
|
52
|
+
return command;
|
|
53
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { createRequestAction, parseNumberList, withTransportTimeoutBuffer } from "./request-helpers.js";
|
|
3
|
+
export function createGuiCommand() {
|
|
4
|
+
const command = new Command("gui").description("GUI / container interaction (use \"gui snapshot\" to inspect slot indices and contents)");
|
|
5
|
+
command.command("info").description("Get current GUI info (title, type, slot count)").action(createRequestAction("gui.info", () => ({})));
|
|
6
|
+
command.command("snapshot").description("Get full GUI snapshot with all slot contents").action(createRequestAction("gui.snapshot", () => ({})));
|
|
7
|
+
command
|
|
8
|
+
.command("slot")
|
|
9
|
+
.description("Get a specific GUI slot")
|
|
10
|
+
.argument("<slot>", "Slot index")
|
|
11
|
+
.action(createRequestAction("gui.slot", ({ args }) => ({ slot: Number(args[0]) })));
|
|
12
|
+
command
|
|
13
|
+
.command("click")
|
|
14
|
+
.description("Click a GUI slot")
|
|
15
|
+
.argument("<slot>", "Slot index")
|
|
16
|
+
.option("--button <button>", "Click button: left|right|middle|shift-left|shift-right", "left")
|
|
17
|
+
.option("--key <key>", "Number key 1-9 to quick-move item to that hotbar slot")
|
|
18
|
+
.action(createRequestAction("gui.click", ({ args, options }) => ({
|
|
19
|
+
slot: Number(args[0]),
|
|
20
|
+
button: options.button,
|
|
21
|
+
key: options.key ? Number(options.key) : undefined
|
|
22
|
+
})));
|
|
23
|
+
command
|
|
24
|
+
.command("drag")
|
|
25
|
+
.description("Drag across GUI slots (distribute items)")
|
|
26
|
+
.requiredOption("--slots <slots>", "Comma-separated slot indices, e.g. 1,2,3")
|
|
27
|
+
.requiredOption("--button <button>", "Drag button: left (split evenly) | right (one each)")
|
|
28
|
+
.action(createRequestAction("gui.drag", ({ options }) => ({
|
|
29
|
+
slots: parseNumberList(String(options.slots)),
|
|
30
|
+
button: options.button
|
|
31
|
+
})));
|
|
32
|
+
command.command("close").description("Close the current GUI").action(createRequestAction("gui.close", () => ({})));
|
|
33
|
+
command
|
|
34
|
+
.command("wait-open")
|
|
35
|
+
.description("Wait for a GUI to open")
|
|
36
|
+
.option("--timeout <seconds>", "Timeout in seconds", Number)
|
|
37
|
+
.action(createRequestAction("gui.wait-open", ({ options }) => ({ timeout: options.timeout }), ({ options }, context) => withTransportTimeoutBuffer(options.timeout ? Number(options.timeout) : undefined, context.config.timeout.default)));
|
|
38
|
+
command
|
|
39
|
+
.command("wait-update")
|
|
40
|
+
.description("Wait for the GUI to update")
|
|
41
|
+
.option("--timeout <seconds>", "Timeout in seconds", Number)
|
|
42
|
+
.action(createRequestAction("gui.wait-update", ({ options }) => ({ timeout: options.timeout }), ({ options }, context) => withTransportTimeoutBuffer(options.timeout ? Number(options.timeout) : undefined, context.config.timeout.default)));
|
|
43
|
+
command
|
|
44
|
+
.command("screenshot")
|
|
45
|
+
.description("Take a screenshot of the current GUI")
|
|
46
|
+
.requiredOption("--output <path>", "Output file path")
|
|
47
|
+
.action(createRequestAction("gui.screenshot", ({ options }) => ({ output: options.output })));
|
|
48
|
+
return command;
|
|
49
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { createRequestAction } from "./request-helpers.js";
|
|
3
|
+
export function createHudCommand() {
|
|
4
|
+
const command = new Command("hud").description("HUD element queries");
|
|
5
|
+
command.command("scoreboard").description("Get sidebar scoreboard").action(createRequestAction("hud.scoreboard", () => ({})));
|
|
6
|
+
command.command("tab").description("Get tab list (player list)").action(createRequestAction("hud.tab", () => ({})));
|
|
7
|
+
command.command("bossbar").description("Get boss bar(s)").action(createRequestAction("hud.bossbar", () => ({})));
|
|
8
|
+
command.command("actionbar").description("Get action bar text").action(createRequestAction("hud.actionbar", () => ({})));
|
|
9
|
+
command.command("title").description("Get current title/subtitle").action(createRequestAction("hud.title", () => ({})));
|
|
10
|
+
command
|
|
11
|
+
.command("nametag")
|
|
12
|
+
.description("Get a player's nametag info")
|
|
13
|
+
.requiredOption("--player <player>", "Player name")
|
|
14
|
+
.action(createRequestAction("hud.nametag", ({ options }) => ({ player: options.player })));
|
|
15
|
+
return command;
|
|
16
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { createRequestAction, withTransportTimeoutBuffer } from "./request-helpers.js";
|
|
3
|
+
function buildPointerParams(options) {
|
|
4
|
+
const modifiers = options.modifiers
|
|
5
|
+
? String(options.modifiers)
|
|
6
|
+
.split(",")
|
|
7
|
+
.map((value) => value.trim())
|
|
8
|
+
.filter(Boolean)
|
|
9
|
+
: [];
|
|
10
|
+
return {
|
|
11
|
+
button: options.button ?? "left",
|
|
12
|
+
modifiers
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export function createInputCommand() {
|
|
16
|
+
const command = new Command("input").description("Raw mouse/keyboard input");
|
|
17
|
+
command
|
|
18
|
+
.command("click")
|
|
19
|
+
.description("Click at screen coordinates")
|
|
20
|
+
.argument("<x>", "Screen X", Number)
|
|
21
|
+
.argument("<y>", "Screen Y", Number)
|
|
22
|
+
.option("--button <button>", "Mouse button: left|right|middle", "left")
|
|
23
|
+
.option("--modifiers <modifiers>", "Modifier keys, comma-separated: shift,ctrl,alt")
|
|
24
|
+
.action(createRequestAction("input.click", ({ args, options }) => ({
|
|
25
|
+
x: Number(args[0]),
|
|
26
|
+
y: Number(args[1]),
|
|
27
|
+
...buildPointerParams(options)
|
|
28
|
+
})));
|
|
29
|
+
command
|
|
30
|
+
.command("double-click")
|
|
31
|
+
.description("Double-click at screen coordinates")
|
|
32
|
+
.argument("<x>", "Screen X", Number)
|
|
33
|
+
.argument("<y>", "Screen Y", Number)
|
|
34
|
+
.option("--button <button>", "Mouse button: left|right|middle", "left")
|
|
35
|
+
.action(createRequestAction("input.double-click", ({ args, options }) => ({
|
|
36
|
+
x: Number(args[0]),
|
|
37
|
+
y: Number(args[1]),
|
|
38
|
+
button: options.button ?? "left"
|
|
39
|
+
})));
|
|
40
|
+
command
|
|
41
|
+
.command("mouse-move")
|
|
42
|
+
.description("Move mouse to screen coordinates")
|
|
43
|
+
.argument("<x>", "Screen X", Number)
|
|
44
|
+
.argument("<y>", "Screen Y", Number)
|
|
45
|
+
.action(createRequestAction("input.mouse-move", ({ args }) => ({
|
|
46
|
+
x: Number(args[0]),
|
|
47
|
+
y: Number(args[1])
|
|
48
|
+
})));
|
|
49
|
+
command
|
|
50
|
+
.command("drag")
|
|
51
|
+
.description("Mouse drag from one position to another")
|
|
52
|
+
.argument("<fromX>", "Start X", Number)
|
|
53
|
+
.argument("<fromY>", "Start Y", Number)
|
|
54
|
+
.argument("<toX>", "End X", Number)
|
|
55
|
+
.argument("<toY>", "End Y", Number)
|
|
56
|
+
.option("--button <button>", "Mouse button: left|right|middle", "left")
|
|
57
|
+
.action(createRequestAction("input.drag", ({ args, options }) => ({
|
|
58
|
+
fromX: Number(args[0]),
|
|
59
|
+
fromY: Number(args[1]),
|
|
60
|
+
toX: Number(args[2]),
|
|
61
|
+
toY: Number(args[3]),
|
|
62
|
+
button: options.button ?? "left"
|
|
63
|
+
})));
|
|
64
|
+
command
|
|
65
|
+
.command("scroll")
|
|
66
|
+
.description("Scroll mouse wheel at coordinates")
|
|
67
|
+
.argument("<x>", "Screen X", Number)
|
|
68
|
+
.argument("<y>", "Screen Y", Number)
|
|
69
|
+
.requiredOption("--delta <delta>", "Scroll amount (positive = up, negative = down)", Number)
|
|
70
|
+
.action(createRequestAction("input.scroll", ({ args, options }) => ({
|
|
71
|
+
x: Number(args[0]),
|
|
72
|
+
y: Number(args[1]),
|
|
73
|
+
delta: Number(options.delta)
|
|
74
|
+
})));
|
|
75
|
+
const keyCommand = command.command("key").description("Keyboard input");
|
|
76
|
+
keyCommand
|
|
77
|
+
.command("press")
|
|
78
|
+
.description("Press and release a key")
|
|
79
|
+
.argument("<key>", "Key name (e.g. w, a, s, d, space, escape, shift, enter, tab, e, f1)")
|
|
80
|
+
.action(createRequestAction("input.key-press", ({ args }) => ({ key: String(args[0]) })));
|
|
81
|
+
keyCommand
|
|
82
|
+
.command("hold")
|
|
83
|
+
.description("Hold a key for a duration")
|
|
84
|
+
.argument("<key>", "Key name")
|
|
85
|
+
.requiredOption("--duration <ms>", "Hold duration in milliseconds", Number)
|
|
86
|
+
.action(createRequestAction("input.key-hold", ({ args, options }) => ({
|
|
87
|
+
key: String(args[0]),
|
|
88
|
+
duration: Number(options.duration)
|
|
89
|
+
}), ({ options }, context) => withTransportTimeoutBuffer(Math.max(Number(options.duration ?? 0) / 1000 + 2, 3), context.config.timeout.default)));
|
|
90
|
+
keyCommand
|
|
91
|
+
.command("down")
|
|
92
|
+
.description("Press a key down (without releasing)")
|
|
93
|
+
.argument("<key>", "Key name")
|
|
94
|
+
.action(createRequestAction("input.key-down", ({ args }) => ({ key: String(args[0]) })));
|
|
95
|
+
keyCommand
|
|
96
|
+
.command("up")
|
|
97
|
+
.description("Release a key")
|
|
98
|
+
.argument("<key>", "Key name")
|
|
99
|
+
.action(createRequestAction("input.key-up", ({ args }) => ({ key: String(args[0]) })));
|
|
100
|
+
keyCommand
|
|
101
|
+
.command("combo")
|
|
102
|
+
.description("Press a key combination in sequence")
|
|
103
|
+
.argument("<keys...>", "Key names")
|
|
104
|
+
.action(createRequestAction("input.key-combo", ({ args }) => ({
|
|
105
|
+
keys: String(args[0])
|
|
106
|
+
.split(",")
|
|
107
|
+
.map((value) => value.trim())
|
|
108
|
+
.filter(Boolean)
|
|
109
|
+
})));
|
|
110
|
+
command
|
|
111
|
+
.command("type")
|
|
112
|
+
.description("Type text into the currently focused field")
|
|
113
|
+
.argument("<text>", "Text to type")
|
|
114
|
+
.action(createRequestAction("input.type", ({ args }) => ({ text: String(args[0]) })));
|
|
115
|
+
command
|
|
116
|
+
.command("mouse-pos")
|
|
117
|
+
.description("Get current mouse position")
|
|
118
|
+
.action(createRequestAction("input.mouse-pos", () => ({})));
|
|
119
|
+
command
|
|
120
|
+
.command("keys-down")
|
|
121
|
+
.description("Get currently held keys")
|
|
122
|
+
.action(createRequestAction("input.keys-down", () => ({})));
|
|
123
|
+
return command;
|
|
124
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { createRequestAction } from "./request-helpers.js";
|
|
3
|
+
export function createInventoryCommand() {
|
|
4
|
+
const command = new Command("inventory").description("Inventory and item operations");
|
|
5
|
+
command.command("get").description("Get full inventory contents").action(createRequestAction("inventory.get", () => ({})));
|
|
6
|
+
command
|
|
7
|
+
.command("slot")
|
|
8
|
+
.description("Get a specific inventory slot")
|
|
9
|
+
.argument("<slot>", "Slot index (0-8: hotbar, 9-35: main inventory)")
|
|
10
|
+
.action(createRequestAction("inventory.slot", ({ args }) => ({ slot: Number(args[0]) })));
|
|
11
|
+
command.command("held").description("Get currently held item").action(createRequestAction("inventory.held", () => ({})));
|
|
12
|
+
command
|
|
13
|
+
.command("hotbar")
|
|
14
|
+
.description("Switch active hotbar slot")
|
|
15
|
+
.argument("<slot>", "Hotbar slot (0-8)")
|
|
16
|
+
.action(createRequestAction("inventory.hotbar", ({ args }) => ({ slot: Number(args[0]) })));
|
|
17
|
+
command
|
|
18
|
+
.command("drop")
|
|
19
|
+
.description("Drop the held item")
|
|
20
|
+
.option("--all", "Drop the entire stack")
|
|
21
|
+
.action(createRequestAction("inventory.drop", ({ options }) => ({ all: Boolean(options.all) })));
|
|
22
|
+
command.command("use").description("Use (right-click) the held item").action(createRequestAction("inventory.use", () => ({})));
|
|
23
|
+
command
|
|
24
|
+
.command("swap-hands")
|
|
25
|
+
.description("Swap main hand and off-hand items")
|
|
26
|
+
.action(createRequestAction("inventory.swap-hands", () => ({})));
|
|
27
|
+
return command;
|
|
28
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { buildEntityFilter, createRequestAction } from "./request-helpers.js";
|
|
3
|
+
export function createLookCommand() {
|
|
4
|
+
const command = new Command("look").description("Camera / view direction control");
|
|
5
|
+
command
|
|
6
|
+
.command("at")
|
|
7
|
+
.description("Look at coordinates")
|
|
8
|
+
.argument("<x>", "X coordinate")
|
|
9
|
+
.argument("<y>", "Y coordinate")
|
|
10
|
+
.argument("<z>", "Z coordinate")
|
|
11
|
+
.action(createRequestAction("look.at", ({ args }) => ({
|
|
12
|
+
x: Number(args[0]),
|
|
13
|
+
y: Number(args[1]),
|
|
14
|
+
z: Number(args[2])
|
|
15
|
+
})));
|
|
16
|
+
command
|
|
17
|
+
.command("entity")
|
|
18
|
+
.description("Look at an entity")
|
|
19
|
+
.option("--type <type>", "Entity type (e.g. zombie, villager)")
|
|
20
|
+
.option("--name <name>", "Entity custom name")
|
|
21
|
+
.option("--nearest", "Target the nearest matching entity")
|
|
22
|
+
.option("--id <id>", "Entity network ID", Number)
|
|
23
|
+
.option("--max-distance <distance>", "Max search distance in blocks", Number)
|
|
24
|
+
.action(createRequestAction("look.entity", ({ options }) => ({
|
|
25
|
+
filter: buildEntityFilter(options)
|
|
26
|
+
})));
|
|
27
|
+
command
|
|
28
|
+
.command("set")
|
|
29
|
+
.description("Set camera angle directly")
|
|
30
|
+
.requiredOption("--yaw <yaw>", "Horizontal angle (-180 to 180: 0=south, -90=east, 90=west, ±180=north)", Number)
|
|
31
|
+
.requiredOption("--pitch <pitch>", "Vertical angle (-90=up, 0=horizon, 90=down)", Number)
|
|
32
|
+
.action(createRequestAction("look.set", ({ options }) => ({
|
|
33
|
+
yaw: options.yaw,
|
|
34
|
+
pitch: options.pitch
|
|
35
|
+
})));
|
|
36
|
+
return command;
|
|
37
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { createRequestAction, withTransportTimeoutBuffer } from "./request-helpers.js";
|
|
3
|
+
export function createMoveCommand() {
|
|
4
|
+
const command = new Command("move").description("Movement control");
|
|
5
|
+
command
|
|
6
|
+
.command("to")
|
|
7
|
+
.description("Move to coordinates (straight-line walk, may get stuck on obstacles; times out after 30s)")
|
|
8
|
+
.argument("<x>", "X coordinate")
|
|
9
|
+
.argument("<y>", "Y coordinate")
|
|
10
|
+
.argument("<z>", "Z coordinate")
|
|
11
|
+
.action(createRequestAction("move.to", ({ args }) => ({
|
|
12
|
+
x: Number(args[0]),
|
|
13
|
+
y: Number(args[1]),
|
|
14
|
+
z: Number(args[2])
|
|
15
|
+
}), (_payload, context) => withTransportTimeoutBuffer(30, context.config.timeout.default)));
|
|
16
|
+
const directionLabels = { forward: "Move forward", back: "Move backward", left: "Move left", right: "Move right" };
|
|
17
|
+
for (const direction of ["forward", "back", "left", "right"]) {
|
|
18
|
+
command
|
|
19
|
+
.command(direction)
|
|
20
|
+
.description(directionLabels[direction])
|
|
21
|
+
.argument("<blocks>", "Distance in blocks (supports decimals)")
|
|
22
|
+
.action(createRequestAction("move.direction", ({ args }) => ({
|
|
23
|
+
direction,
|
|
24
|
+
blocks: Number(args[0])
|
|
25
|
+
}), ({ args }, context) => {
|
|
26
|
+
const blocks = Math.abs(Number(args[0]));
|
|
27
|
+
const timeout = Math.max(1.5, blocks * 2.0);
|
|
28
|
+
return withTransportTimeoutBuffer(timeout, context.config.timeout.default);
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
command
|
|
32
|
+
.command("jump")
|
|
33
|
+
.description("Jump once")
|
|
34
|
+
.action(createRequestAction("move.jump", () => ({})));
|
|
35
|
+
command
|
|
36
|
+
.command("sneak")
|
|
37
|
+
.description("Toggle sneaking")
|
|
38
|
+
.argument("<state>", "on/off")
|
|
39
|
+
.action(createRequestAction("move.sneak", ({ args }) => ({
|
|
40
|
+
enabled: args[0] === "on"
|
|
41
|
+
})));
|
|
42
|
+
command
|
|
43
|
+
.command("sprint")
|
|
44
|
+
.description("Toggle sprinting")
|
|
45
|
+
.argument("<state>", "on/off")
|
|
46
|
+
.action(createRequestAction("move.sprint", ({ args }) => ({
|
|
47
|
+
enabled: args[0] === "on"
|
|
48
|
+
})));
|
|
49
|
+
return command;
|
|
50
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { createRequestAction } from "./request-helpers.js";
|
|
3
|
+
export function createPositionCommand() {
|
|
4
|
+
const command = new Command("position").description("Position query");
|
|
5
|
+
command.command("get").description("Get current player position (x, y, z)").action(createRequestAction("position.get", () => ({})));
|
|
6
|
+
return command;
|
|
7
|
+
}
|