yeow-api 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/package.json +10 -0
- package/src/block.ts +17 -0
- package/src/command.ts +40 -0
- package/src/entity.ts +36 -0
- package/src/event.ts +78 -0
- package/src/fs.ts +33 -0
- package/src/http.ts +69 -0
- package/src/index.ts +15 -0
- package/src/inventory.ts +33 -0
- package/src/location.ts +24 -0
- package/src/path.ts +23 -0
- package/src/player.ts +65 -0
- package/src/server.ts +17 -0
- package/src/task.ts +17 -0
- package/src/world.ts +33 -0
package/package.json
ADDED
package/src/block.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { call } from './task.js';
|
|
2
|
+
import { Location } from './location.js';
|
|
3
|
+
|
|
4
|
+
export class Block {
|
|
5
|
+
constructor(
|
|
6
|
+
public readonly world: string,
|
|
7
|
+
public readonly x: number,
|
|
8
|
+
public readonly y: number,
|
|
9
|
+
public readonly z: number,
|
|
10
|
+
public readonly type: string
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
get location(): Location { return new Location(this.x, this.y, this.z, undefined, undefined, this.world); }
|
|
14
|
+
isSolid(): boolean { return call('block.isSolid', { world: this.world, x: this.x, y: this.y, z: this.z }) as boolean; }
|
|
15
|
+
isLiquid(): boolean { return call('block.isLiquid', { world: this.world, x: this.x, y: this.y, z: this.z }) as boolean; }
|
|
16
|
+
isEmpty(): boolean { return call('block.isEmpty', { world: this.world, x: this.x, y: this.y, z: this.z }) as boolean; }
|
|
17
|
+
}
|
package/src/command.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { call } from './task.js';
|
|
2
|
+
|
|
3
|
+
export interface CommandOptions {
|
|
4
|
+
description?: string;
|
|
5
|
+
usage?: string;
|
|
6
|
+
permission?: string;
|
|
7
|
+
aliases?: string[];
|
|
8
|
+
executor: (payload: CommandPayload) => void;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface CommandPayload {
|
|
12
|
+
sender: { name: string; uuid: string; isPlayer: boolean };
|
|
13
|
+
args: string[];
|
|
14
|
+
label: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function registerCommand(name: string, options: CommandOptions): boolean {
|
|
18
|
+
const executor = options.executor;
|
|
19
|
+
const pluginName = (globalThis as any).__plugin?.name || 'unknown';
|
|
20
|
+
|
|
21
|
+
const cbId = (globalThis as any)._registerCallback((payload: CommandPayload) => {
|
|
22
|
+
const sender = payload.sender;
|
|
23
|
+
if (sender?.uuid && sender.isPlayer) {
|
|
24
|
+
(sender as any).sendMessage = (msg: string) => {
|
|
25
|
+
call('player.sendMessage', { uuid: sender.uuid, message: msg });
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
executor(payload);
|
|
29
|
+
}, { persistent: true });
|
|
30
|
+
|
|
31
|
+
return call('command.register', {
|
|
32
|
+
pluginName,
|
|
33
|
+
commandName: name,
|
|
34
|
+
callbackId: String(cbId),
|
|
35
|
+
description: options.description,
|
|
36
|
+
usage: options.usage,
|
|
37
|
+
permission: options.permission,
|
|
38
|
+
aliases: options.aliases,
|
|
39
|
+
}) as boolean;
|
|
40
|
+
}
|
package/src/entity.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { call } from './task.js';
|
|
2
|
+
import { Location } from './location.js';
|
|
3
|
+
|
|
4
|
+
export class Entity {
|
|
5
|
+
constructor(public readonly uuid: string) {}
|
|
6
|
+
|
|
7
|
+
get type(): string { return call('entity.getType', { uuid: this.uuid }) as string; }
|
|
8
|
+
get name(): string { return call('entity.getName', { uuid: this.uuid }) as string; }
|
|
9
|
+
get customName(): string | null { return call('entity.getCustomName', { uuid: this.uuid }) as string | null; }
|
|
10
|
+
set customName(v: string | null) { call('entity.setCustomName', { uuid: this.uuid, value: v }); }
|
|
11
|
+
setCustomNameVisible(v: boolean): Promise<void> { return call('entity.setCustomNameVisible', { uuid: this.uuid, value: v }) as Promise<void>; }
|
|
12
|
+
get world(): string | null { return call('entity.getWorld', { uuid: this.uuid }) as string | null; }
|
|
13
|
+
get location(): Location | null { const r = call('entity.getLocation', { uuid: this.uuid }); return r ? Location.from(r as any) : null; }
|
|
14
|
+
get isGlowing(): boolean { return call('entity.isGlowing', { uuid: this.uuid }) as boolean; }
|
|
15
|
+
set isGlowing(v: boolean) { call('entity.setGlowing', { uuid: this.uuid, value: v }); }
|
|
16
|
+
get isInvulnerable(): boolean { return call('entity.isInvulnerable', { uuid: this.uuid }) as boolean; }
|
|
17
|
+
set isInvulnerable(v: boolean) { call('entity.setInvulnerable', { uuid: this.uuid, value: v }); }
|
|
18
|
+
get isSilent(): boolean { return call('entity.isSilent', { uuid: this.uuid }) as boolean; }
|
|
19
|
+
set isSilent(v: boolean) { call('entity.setSilent', { uuid: this.uuid, value: v }); }
|
|
20
|
+
get hasGravity(): boolean { return call('entity.hasGravity', { uuid: this.uuid }) as boolean; }
|
|
21
|
+
set hasGravity(v: boolean) { call('entity.setGravity', { uuid: this.uuid, value: v }); }
|
|
22
|
+
get passengers(): string[] { return call('entity.getPassengers', { uuid: this.uuid }) as string[]; }
|
|
23
|
+
get vehicle(): string | null { return call('entity.getVehicle', { uuid: this.uuid }) as string | null; }
|
|
24
|
+
|
|
25
|
+
remove(): Promise<void> { return call('entity.remove', { uuid: this.uuid }) as Promise<void>; }
|
|
26
|
+
removeSync(): void { call('entity.remove', { uuid: this.uuid }); }
|
|
27
|
+
teleport(loc: Location): Promise<void> { return call('entity.teleport', { uuid: this.uuid, ...loc.toObject() }) as Promise<void>; }
|
|
28
|
+
teleportSync(loc: Location): void { call('entity.teleport', { uuid: this.uuid, ...loc.toObject() }); }
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class LivingEntity extends Entity {
|
|
32
|
+
get health(): number { return call('entity.getHealth', { uuid: this.uuid }) as number; }
|
|
33
|
+
set health(v: number) { call('entity.setHealth', { uuid: this.uuid, value: v }); }
|
|
34
|
+
get maxHealth(): number { return call('entity.getMaxHealth', { uuid: this.uuid }) as number; }
|
|
35
|
+
get isDead(): boolean { return call('entity.isDead', { uuid: this.uuid }) as boolean; }
|
|
36
|
+
}
|
package/src/event.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { call } from './task.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Event subscription with cancellation support.
|
|
5
|
+
* Sync handlers: e.cancelled = true takes effect immediately (sync task intercepted by EventBridge).
|
|
6
|
+
* Async handlers: e.cancelled is @deprecated (no effect after await).
|
|
7
|
+
*/
|
|
8
|
+
const _handlers: Record<string, Array<{ h: Function; async: boolean }>> = {};
|
|
9
|
+
|
|
10
|
+
function _process(internalType: string, snapshot: Record<string, unknown>): Record<string, unknown> {
|
|
11
|
+
const entries = _handlers[internalType];
|
|
12
|
+
if (!entries?.length) return {};
|
|
13
|
+
|
|
14
|
+
const cancellable = snapshot._cancellable;
|
|
15
|
+
const mods: Record<string, unknown> = {};
|
|
16
|
+
|
|
17
|
+
for (const entry of entries) {
|
|
18
|
+
try {
|
|
19
|
+
const proxy: any = {};
|
|
20
|
+
for (const key of Object.keys(snapshot)) {
|
|
21
|
+
if (!key.startsWith('_')) proxy[key] = snapshot[key];
|
|
22
|
+
}
|
|
23
|
+
if (cancellable) {
|
|
24
|
+
Object.defineProperty(proxy, 'cancelled', {
|
|
25
|
+
get: () => call('event.isCancelled', {}),
|
|
26
|
+
set: (v: boolean) => { call('event.setCancelled', { cancelled: v }); },
|
|
27
|
+
enumerable: true,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
entry.h(proxy);
|
|
31
|
+
} catch (e: any) { console.error(`event handler error: ${e?.message || e}`); }
|
|
32
|
+
}
|
|
33
|
+
return mods;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Install the global event handler that init.js calls
|
|
37
|
+
(globalThis as any)._onEvent = (msg: any) => {
|
|
38
|
+
const eventType = msg.ev;
|
|
39
|
+
_process(eventType, msg.sn);
|
|
40
|
+
// Notify Java that event processing is done
|
|
41
|
+
if (typeof (globalThis as any)._eventComplete === 'function') {
|
|
42
|
+
(globalThis as any)._eventComplete(eventType);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export function eventOn(eventType: string, handler: (e: any) => void): () => void {
|
|
47
|
+
const async = handler.constructor.name === 'AsyncFunction';
|
|
48
|
+
if (!_handlers[eventType]) {
|
|
49
|
+
_handlers[eventType] = [];
|
|
50
|
+
call('event.subscribe', {
|
|
51
|
+
pluginName: (globalThis as any).__plugin?.name || 'unknown',
|
|
52
|
+
eventType,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const entry = { h: handler, async };
|
|
56
|
+
_handlers[eventType].push(entry);
|
|
57
|
+
return () => eventOff(eventType, handler);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function eventOnce(eventType: string, handler: (e: any) => void): () => void {
|
|
61
|
+
const wrapper = (e: any) => { eventOff(eventType, wrapper); handler(e); };
|
|
62
|
+
return eventOn(eventType, wrapper);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function eventOff(eventType: string, handler: (e: any) => void) {
|
|
66
|
+
const entries = _handlers[eventType];
|
|
67
|
+
if (!entries) return;
|
|
68
|
+
for (let i = 0; i < entries.length; i++) {
|
|
69
|
+
if (entries[i].h === handler) { entries.splice(i, 1); break; }
|
|
70
|
+
}
|
|
71
|
+
if (entries.length === 0) {
|
|
72
|
+
delete _handlers[eventType];
|
|
73
|
+
call('event.unsubscribe', {
|
|
74
|
+
pluginName: (globalThis as any).__plugin?.name || 'unknown',
|
|
75
|
+
eventType,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
package/src/fs.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { call } from './task.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Async file system operations. Paths are resolved relative to the server root.
|
|
5
|
+
* All sync variants have the `Sync` suffix.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export function readFile(path: string): Promise<string> {
|
|
9
|
+
return call('fs.readFile', { path }) as Promise<string>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function readFileSync(path: string): string {
|
|
13
|
+
return call('fs.readFile', { path }) as string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function writeFile(path: string, data: string): Promise<void> {
|
|
17
|
+
return call('fs.writeFile', { path, data }) as Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function writeFileSync(path: string, data: string): void {
|
|
21
|
+
call('fs.writeFile', { path, data });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function existsSync(path: string): boolean {
|
|
25
|
+
return call('fs.exists', { path }) as boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const fs = {
|
|
29
|
+
readFile, readFileSync,
|
|
30
|
+
writeFile, writeFileSync,
|
|
31
|
+
existsSync,
|
|
32
|
+
// ... more to come
|
|
33
|
+
};
|
package/src/http.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { call, post } from './task.js';
|
|
2
|
+
|
|
3
|
+
const _servers: Set<string> = new Set();
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Start an HTTP server on a random available port.
|
|
7
|
+
* The callback receives: { connId, serverId, method, path, query, headers, body }
|
|
8
|
+
* Response is sent via http.respond(task: { serverId, connId, status?, headers?, body? })
|
|
9
|
+
*/
|
|
10
|
+
export function listen(
|
|
11
|
+
callback: (req: HttpRequest) => void,
|
|
12
|
+
port?: number
|
|
13
|
+
): Promise<{ serverId: string; port: number }> {
|
|
14
|
+
return new Promise((resolve, reject) => {
|
|
15
|
+
const cbId = (globalThis as any)._registerCallback((payload: HttpRequest) => {
|
|
16
|
+
callback(payload);
|
|
17
|
+
}, { persistent: true });
|
|
18
|
+
|
|
19
|
+
const result = call('http.listen', {
|
|
20
|
+
pluginName: (globalThis as any).__plugin?.name || 'unknown',
|
|
21
|
+
callbackId: String(cbId),
|
|
22
|
+
port: port || 0,
|
|
23
|
+
}) as { serverId: string; port: number };
|
|
24
|
+
|
|
25
|
+
_servers.add(result.serverId);
|
|
26
|
+
resolve(result);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Send an HTTP response to a pending connection.
|
|
32
|
+
*/
|
|
33
|
+
export function respond(serverId: string, connId: string, options: {
|
|
34
|
+
status?: number; headers?: Record<string, string>; body?: string;
|
|
35
|
+
}): Promise<void> {
|
|
36
|
+
return call('http.respond', {
|
|
37
|
+
serverId,
|
|
38
|
+
connId,
|
|
39
|
+
status: options.status || 200,
|
|
40
|
+
headers: options.headers || {},
|
|
41
|
+
body: options.body || '',
|
|
42
|
+
}) as Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Stop an HTTP server and release its port.
|
|
47
|
+
*/
|
|
48
|
+
export function close(serverId: string): Promise<void> {
|
|
49
|
+
_servers.delete(serverId);
|
|
50
|
+
return call('http.close', { serverId }) as Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Auto-close all servers when the plugin is disabled. */
|
|
54
|
+
(globalThis as any)._registerCallback(() => {
|
|
55
|
+
for (const id of _servers) {
|
|
56
|
+
try { call('http.close', { serverId: id }); } catch {}
|
|
57
|
+
}
|
|
58
|
+
_servers.clear();
|
|
59
|
+
}, { persistent: true });
|
|
60
|
+
|
|
61
|
+
export interface HttpRequest {
|
|
62
|
+
connId: string;
|
|
63
|
+
serverId: string;
|
|
64
|
+
method: string;
|
|
65
|
+
path: string;
|
|
66
|
+
query: string;
|
|
67
|
+
headers: Record<string, string>;
|
|
68
|
+
body: string;
|
|
69
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { call, post } from './task.js';
|
|
2
|
+
export { Location } from './location.js';
|
|
3
|
+
export { Entity, LivingEntity } from './entity.js';
|
|
4
|
+
export { Player } from './player.js';
|
|
5
|
+
export { World } from './world.js';
|
|
6
|
+
export { Block } from './block.js';
|
|
7
|
+
export { Inventory } from './inventory.js';
|
|
8
|
+
export { fs, readFileSync, writeFileSync, existsSync } from './fs.js';
|
|
9
|
+
export { path, join, basename, dirname, extname } from './path.js';
|
|
10
|
+
export { registerCommand } from './command.js';
|
|
11
|
+
export type { CommandOptions, CommandPayload } from './command.js';
|
|
12
|
+
export { eventOn, eventOnce, eventOff } from './event.js';
|
|
13
|
+
export { listen, respond, close } from './http.js';
|
|
14
|
+
export type { HttpRequest } from './http.js';
|
|
15
|
+
export { broadcast, broadcastSync, getMotd, getVersion } from './server.js';
|
package/src/inventory.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { call } from './task.js';
|
|
2
|
+
|
|
3
|
+
export class Inventory {
|
|
4
|
+
constructor(private readonly uuid: string) {}
|
|
5
|
+
|
|
6
|
+
getItem(slot: number): { type: string; amount: number } | null {
|
|
7
|
+
return call('inventory.getItem', { uuid: this.uuid, slot }) as any;
|
|
8
|
+
}
|
|
9
|
+
setItem(slot: number, itemType: string, amount?: number): Promise<void> {
|
|
10
|
+
return call('inventory.setItem', { uuid: this.uuid, slot, itemType, amount }) as Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
setItemSync(slot: number, itemType: string, amount?: number): void {
|
|
13
|
+
call('inventory.setItem', { uuid: this.uuid, slot, itemType, amount });
|
|
14
|
+
}
|
|
15
|
+
addItem(itemType: string, amount?: number): Promise<void> {
|
|
16
|
+
return call('inventory.addItem', { uuid: this.uuid, itemType, amount }) as Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
addItemSync(itemType: string, amount?: number): void {
|
|
19
|
+
call('inventory.addItem', { uuid: this.uuid, itemType, amount });
|
|
20
|
+
}
|
|
21
|
+
removeItem(itemType: string, amount?: number): Promise<void> {
|
|
22
|
+
return call('inventory.removeItem', { uuid: this.uuid, itemType, amount }) as Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
removeItemSync(itemType: string, amount?: number): void {
|
|
25
|
+
call('inventory.removeItem', { uuid: this.uuid, itemType, amount });
|
|
26
|
+
}
|
|
27
|
+
clear(slot?: number): Promise<void> {
|
|
28
|
+
return call('inventory.clear', { uuid: this.uuid, slot }) as Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
clearSync(slot?: number): void {
|
|
31
|
+
call('inventory.clear', { uuid: this.uuid, slot });
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/location.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { call } from './task.js';
|
|
2
|
+
|
|
3
|
+
export class Location {
|
|
4
|
+
constructor(
|
|
5
|
+
public readonly x: number,
|
|
6
|
+
public readonly y: number,
|
|
7
|
+
public readonly z: number,
|
|
8
|
+
public readonly yaw: number = 0,
|
|
9
|
+
public readonly pitch: number = 0,
|
|
10
|
+
public readonly world?: string
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
static from(raw: Record<string, unknown>): Location {
|
|
14
|
+
return new Location(
|
|
15
|
+
raw.x as number, raw.y as number, raw.z as number,
|
|
16
|
+
(raw.yaw as number) ?? 0, (raw.pitch as number) ?? 0,
|
|
17
|
+
raw.world as string | undefined
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
toObject(): Record<string, unknown> {
|
|
22
|
+
return { x: this.x, y: this.y, z: this.z, yaw: this.yaw, pitch: this.pitch, world: this.world };
|
|
23
|
+
}
|
|
24
|
+
}
|
package/src/path.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function join(...segments: (string | null | undefined)[]): string {
|
|
2
|
+
return segments.filter(s => s != null).join('/').replace(/\/+/g, '/').replace(/\/$/, '') || '.';
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function basename(p: string): string {
|
|
6
|
+
const s = p.replace(/\/+$/, '');
|
|
7
|
+
const i = s.lastIndexOf('/');
|
|
8
|
+
return i === -1 ? s : s.substring(i + 1);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function dirname(p: string): string {
|
|
12
|
+
const s = p.replace(/\/+$/, '');
|
|
13
|
+
const i = s.lastIndexOf('/');
|
|
14
|
+
return i === -1 ? '.' : s.substring(0, i) || '/';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function extname(p: string): string {
|
|
18
|
+
const b = basename(p);
|
|
19
|
+
const i = b.lastIndexOf('.');
|
|
20
|
+
return i === -1 ? '' : b.substring(i);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const path = { join, basename, dirname, extname };
|
package/src/player.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { call } from './task.js';
|
|
2
|
+
import { Location } from './location.js';
|
|
3
|
+
import { LivingEntity } from './entity.js';
|
|
4
|
+
import { Inventory } from './inventory.js';
|
|
5
|
+
|
|
6
|
+
export class Player extends LivingEntity {
|
|
7
|
+
static get(identifier: string): Player | null { const d = call('player.get',{identifier}) as any; return d?new Player(d.uuid,d.name):null; }
|
|
8
|
+
static getAll(): Player[] { return (call('player.getAll',{}) as any[]).map((r:any)=>new Player(r.uuid,r.name)); }
|
|
9
|
+
|
|
10
|
+
constructor(uuid: string, private _name?: string) { super(uuid); }
|
|
11
|
+
get name(): string { return this._name ?? ''; }
|
|
12
|
+
get ping(): number { return call('player.getPing',{uuid:this.uuid}) as number; }
|
|
13
|
+
get gamemode(): string { return call('player.getGamemode',{uuid:this.uuid}) as string; }
|
|
14
|
+
set gamemode(v: string) { call('player.setGamemode',{uuid:this.uuid,value:v}); }
|
|
15
|
+
get displayName(): string { return call('player.getDisplayName',{uuid:this.uuid}) as string; }
|
|
16
|
+
set displayName(v: string) { call('player.setDisplayName',{uuid:this.uuid,value:v}); }
|
|
17
|
+
get playerListName(): string { return call('player.getPlayerListName',{uuid:this.uuid}) as string; }
|
|
18
|
+
set playerListName(v: string) { call('player.setPlayerListName',{uuid:this.uuid,value:v}); }
|
|
19
|
+
get foodLevel(): number { return call('player.getFoodLevel',{uuid:this.uuid}) as number; }
|
|
20
|
+
set foodLevel(v: number) { call('player.setFoodLevel',{uuid:this.uuid,value:v}); }
|
|
21
|
+
get saturation(): number { return call('player.getSaturation',{uuid:this.uuid}) as number; }
|
|
22
|
+
set saturation(v: number) { call('player.setSaturation',{uuid:this.uuid,value:v}); }
|
|
23
|
+
get exp(): number { return call('player.getExp',{uuid:this.uuid}) as number; }
|
|
24
|
+
set exp(v: number) { call('player.setExp',{uuid:this.uuid,value:v}); }
|
|
25
|
+
get level(): number { return call('player.getLevel',{uuid:this.uuid}) as number; }
|
|
26
|
+
set level(v: number) { call('player.setLevel',{uuid:this.uuid,value:v}); }
|
|
27
|
+
get totalExperience(): number { return call('player.getTotalExperience',{uuid:this.uuid}) as number; }
|
|
28
|
+
giveExp(v: number): Promise<void> { return call('player.giveExp',{uuid:this.uuid,value:v}) as Promise<void>; }
|
|
29
|
+
giveExpSync(v: number): void { call('player.giveExp',{uuid:this.uuid,value:v}); }
|
|
30
|
+
get isOp(): boolean { return call('player.isOp',{uuid:this.uuid}) as boolean; }
|
|
31
|
+
get allowFlight(): boolean { return call('player.getAllowFlight',{uuid:this.uuid}) as boolean; }
|
|
32
|
+
set allowFlight(v: boolean) { call('player.setAllowFlight',{uuid:this.uuid,value:v}); }
|
|
33
|
+
get isFlying(): boolean { return call('player.isFlying',{uuid:this.uuid}) as boolean; }
|
|
34
|
+
set isFlying(v: boolean) { call('player.setFlying',{uuid:this.uuid,value:v}); }
|
|
35
|
+
get walkSpeed(): number { return call('player.getWalkSpeed',{uuid:this.uuid}) as number; }
|
|
36
|
+
set walkSpeed(v: number) { call('player.setWalkSpeed',{uuid:this.uuid,value:v}); }
|
|
37
|
+
get flySpeed(): number { return call('player.getFlySpeed',{uuid:this.uuid}) as number; }
|
|
38
|
+
set flySpeed(v: number) { call('player.setFlySpeed',{uuid:this.uuid,value:v}); }
|
|
39
|
+
hasPermission(node: string): boolean { return call('player.hasPermission',{uuid:this.uuid,node}) as boolean; }
|
|
40
|
+
get compassTarget(): Location | null { const r=call('player.getCompassTarget',{uuid:this.uuid}) as any; return r?Location.from(r):null; }
|
|
41
|
+
set compassTarget(loc: Location) { call('player.setCompassTarget',{uuid:this.uuid,...loc.toObject()}); }
|
|
42
|
+
get bedSpawnLocation(): Location | null { const r=call('player.getBedSpawnLocation',{uuid:this.uuid}) as any; return r?Location.from(r):null; }
|
|
43
|
+
setBedSpawnLocation(loc: Location): Promise<void> { return call('player.setBedSpawnLocation',{uuid:this.uuid,...loc.toObject()}) as Promise<void>; }
|
|
44
|
+
setBedSpawnLocationSync(loc: Location): void { call('player.setBedSpawnLocation',{uuid:this.uuid,...loc.toObject()}); }
|
|
45
|
+
|
|
46
|
+
sendMessage(msg: string): Promise<void> { return call('player.sendMessage',{uuid:this.uuid,message:msg}) as Promise<void>; }
|
|
47
|
+
sendMessageSync(msg: string): void { call('player.sendMessage',{uuid:this.uuid,message:msg}); }
|
|
48
|
+
sendTitle(title: string, subtitle?: string, fadeIn?: number, stay?: number, fadeOut?: number): Promise<void> {
|
|
49
|
+
return call('player.sendTitle',{uuid:this.uuid,title,subtitle,fadeIn,stay,fadeOut}) as Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
sendTitleSync(title: string, subtitle?: string, fadeIn?: number, stay?: number, fadeOut?: number): void {
|
|
52
|
+
call('player.sendTitle',{uuid:this.uuid,title,subtitle,fadeIn,stay,fadeOut});
|
|
53
|
+
}
|
|
54
|
+
playSound(sound: string, volume?: number, pitch?: number): Promise<void> {
|
|
55
|
+
return call('player.playSound',{uuid:this.uuid,sound,volume,pitch}) as Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
playSoundSync(sound: string, volume?: number, pitch?: number): void {
|
|
58
|
+
call('player.playSound',{uuid:this.uuid,sound,volume,pitch});
|
|
59
|
+
}
|
|
60
|
+
kick(reason?: string): Promise<void> { return call('player.kick',{uuid:this.uuid,reason}) as Promise<void>; }
|
|
61
|
+
kickSync(reason?: string): void { call('player.kick',{uuid:this.uuid,reason}); }
|
|
62
|
+
|
|
63
|
+
private _inv: Inventory | null = null;
|
|
64
|
+
get inventory(): Inventory { return this._inv ?? (this._inv = new Inventory(this.uuid)); }
|
|
65
|
+
}
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { call } from './task.js';
|
|
2
|
+
|
|
3
|
+
export function broadcast(msg: string): Promise<void> {
|
|
4
|
+
return call('server.broadcast', { message: msg }) as Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function broadcastSync(msg: string): void {
|
|
8
|
+
call('server.broadcast', { message: msg });
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function getMotd(): string {
|
|
12
|
+
return call('server.getMotd', {}) as string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getVersion(): string {
|
|
16
|
+
return call('server.getVersion', {}) as string;
|
|
17
|
+
}
|
package/src/task.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function call(type: string, params: Record<string, unknown> = {}): unknown {
|
|
2
|
+
const raw = (globalThis as any).$submitSync(type, JSON.stringify(params));
|
|
3
|
+
if (typeof raw !== 'string') return raw;
|
|
4
|
+
const result = JSON.parse(raw);
|
|
5
|
+
if (result.err) throw new Error(result.err);
|
|
6
|
+
return result;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function post(type: string, params: Record<string, unknown> = {}): Promise<unknown> {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
const cbId = (globalThis as any)._registerCallback((result: any) => {
|
|
12
|
+
if (result?.err) reject(new Error(result.err));
|
|
13
|
+
else resolve(result);
|
|
14
|
+
});
|
|
15
|
+
(globalThis as any).$submitAsync(type, JSON.stringify(params), cbId);
|
|
16
|
+
});
|
|
17
|
+
}
|
package/src/world.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { call } from './task.js';
|
|
2
|
+
import { Location } from './location.js';
|
|
3
|
+
|
|
4
|
+
export class World {
|
|
5
|
+
static get(name: string): World | null { const d = call('world.get', { name }) as any; return d ? new World(d.name) : null; }
|
|
6
|
+
static getAll(): World[] { return (call('world.getAll', {}) as any[]).map((r: any) => new World(r.name)); }
|
|
7
|
+
|
|
8
|
+
constructor(public readonly name: string) {}
|
|
9
|
+
|
|
10
|
+
get time(): number { return call('world.getTime', { world: this.name }) as number; }
|
|
11
|
+
set time(v: number) { call('world.setTime', { world: this.name, value: v }); }
|
|
12
|
+
get storm(): boolean { return call('world.getStorm', { world: this.name }) as boolean; }
|
|
13
|
+
set storm(v: boolean) { call('world.setStorm', { world: this.name, value: v }); }
|
|
14
|
+
get thundering(): boolean { return call('world.getThundering', { world: this.name }) as boolean; }
|
|
15
|
+
set thundering(v: boolean) { call('world.setThundering', { world: this.name, value: v }); }
|
|
16
|
+
get difficulty(): string { return call('world.getDifficulty', { world: this.name }) as string; }
|
|
17
|
+
set difficulty(v: string) { call('world.setDifficulty', { world: this.name, value: v }); }
|
|
18
|
+
get spawnLocation(): Location | null { const r = call('world.getSpawnLocation', { world: this.name }) as any; return r ? new Location(r.x,r.y,r.z,r.yaw,r.pitch) : null; }
|
|
19
|
+
set spawnLocation(v: Location) { call('world.setSpawnLocation', { world: this.name, ...v.toObject() }); }
|
|
20
|
+
|
|
21
|
+
getGameRule(rule: string): string | null { return call('world.getGameRule', { world: this.name, rule }) as string | null; }
|
|
22
|
+
setGameRuleSync(rule: string, value: string): boolean { return call('world.setGameRule', { world: this.name, rule, value }) as boolean; }
|
|
23
|
+
getBiome(x: number, y: number, z: number): string { return call('world.getBiome', { world: this.name, x, y, z }) as string; }
|
|
24
|
+
getBlock(x: number, y: number, z: number): any { const r = call('world.getBlock', { world: this.name, x, y, z }); return r; }
|
|
25
|
+
setBlockSync(x: number, y: number, z: number, type: string) { call('world.setBlock', { world: this.name, x, y, z, blockType: type }); }
|
|
26
|
+
getEntities(): string[] { return call('world.getEntities', { world: this.name }) as string[]; }
|
|
27
|
+
getPlayers(): string[] { return call('world.getPlayers', { world: this.name }) as string[]; }
|
|
28
|
+
getNearbyEntities(x: number, y: number, z: number, r: number): string[] { return call('world.getNearbyEntities', { world: this.name, x, y, z, radius: r }) as string[]; }
|
|
29
|
+
dropItemSync(x: number, y: number, z: number, type: string, amount?: number) { call('world.dropItem', { world: this.name, x, y, z, itemType: type, amount }); }
|
|
30
|
+
strikeLightningSync(x: number, y: number, z: number) { call('world.strikeLightning', { world: this.name, x, y, z }); }
|
|
31
|
+
strikeLightningEffectSync(x: number, y: number, z: number) { call('world.strikeLightningEffect', { world: this.name, x, y, z }); }
|
|
32
|
+
createExplosionSync(x: number, y: number, z: number, power?: number, fire?: boolean, breaks?: boolean) { call('world.createExplosion', { world: this.name, x, y, z, power, setFire: fire, breakBlocks: breaks }); }
|
|
33
|
+
}
|