@s2script/sdk 0.5.0 → 0.6.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/LICENSE-APACHE +201 -0
- package/LICENSE-MIT +21 -0
- package/README.md +40 -6
- package/admin.d.ts +28 -1
- package/bans.d.ts +8 -1
- package/chat.d.ts +7 -0
- package/clients.d.ts +9 -1
- package/commands.d.ts +65 -4
- package/config.d.ts +12 -0
- package/console.d.ts +9 -0
- package/cookies.d.ts +37 -4
- package/damage.d.ts +7 -1
- package/db.d.ts +41 -3
- package/dist/cli.js +460 -25
- package/entity.d.ts +27 -1
- package/events.d.ts +27 -1
- package/globals.d.ts +6 -1
- package/http.d.ts +35 -4
- package/interfaces.d.ts +8 -1
- package/math.d.ts +15 -1
- package/menu.d.ts +92 -7
- package/net.d.ts +26 -2
- package/package.json +6 -3
- package/plugin.d.ts +85 -2
- package/plugins.d.ts +9 -0
- package/server.d.ts +8 -0
- package/sound.d.ts +9 -0
- package/timers.d.ts +7 -1
- package/topmenu.d.ts +15 -0
- package/trace.d.ts +8 -0
- package/translations.d.ts +10 -0
- package/transmit.d.ts +8 -0
- package/usercmd.d.ts +6 -0
- package/usermessages.d.ts +18 -0
- package/votes.d.ts +46 -3
- package/ws.d.ts +18 -1
package/sound.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** @s2script/sound — engine-generic sound: emit a named SoundEvent + register custom precache paths. */
|
|
2
2
|
import type { EntityRef } from "./entity";
|
|
3
3
|
|
|
4
|
+
/** Options for {@link Sound.emit} — the source entity, recipient slots, and volume. */
|
|
4
5
|
export interface SoundEmitOptions {
|
|
5
6
|
/** Source entity (serial-gated; a stale ref emits nothing and returns 0). Omitted -> worldspawn
|
|
6
7
|
* (a global/2D sound). */
|
|
@@ -22,6 +23,14 @@ export interface PrecacheContext {
|
|
|
22
23
|
add(path: string): boolean;
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Engine-generic sound entry point — play a named SoundEvent to some or all clients.
|
|
28
|
+
* @example
|
|
29
|
+
* import { Sound } from "@s2script/sdk/sound";
|
|
30
|
+
* // global 2D broadcast to every valid client (worldspawn source):
|
|
31
|
+
* const guid = Sound.emit("MyPack.Ping");
|
|
32
|
+
* if (guid === 0) console.log("emit failed (unresolved name / stale source)");
|
|
33
|
+
*/
|
|
25
34
|
export declare const Sound: {
|
|
26
35
|
/** Play a named SoundEvent (the engine resolves name->hash; built-in soundevents need no
|
|
27
36
|
* precache). Returns the engine sound GUID (nonzero) or 0 on failure (unresolved engine
|
package/timers.d.ts
CHANGED
|
@@ -3,7 +3,13 @@
|
|
|
3
3
|
* NO runtime code: the engine injects the implementation at load time.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Await a delay of `ms` milliseconds before continuing. Tick-integrated (resumes on a game frame).
|
|
8
|
+
* @example
|
|
9
|
+
* import { delay } from "@s2script/sdk/timers";
|
|
10
|
+
* // plugins/funcommands/src/plugin.ts:77 — sm_freeze auto-unfreeze after `secs`
|
|
11
|
+
* delay(secs * 1000).then(() => { const q = Player.fromSlot(slot); if (q && q.pawn) q.pawn.moveType = WALK; });
|
|
12
|
+
*/
|
|
7
13
|
export declare function delay(ms: number): Promise<void>;
|
|
8
14
|
/** Yield to the next microtick. */
|
|
9
15
|
export declare function nextTick(): Promise<void>;
|
package/topmenu.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/** @s2script/topmenu — the extensible admin/top menu registry. NO runtime code (injected at load). */
|
|
2
|
+
|
|
3
|
+
/** A single registered top-menu entry (an admin command surfaced in the adminmenu). */
|
|
2
4
|
export interface TopMenuItem {
|
|
3
5
|
/** Plugin-namespaced unique id, e.g. "playercommands:slap". A duplicate id replaces. */
|
|
4
6
|
id: string;
|
|
@@ -9,10 +11,23 @@ export interface TopMenuItem {
|
|
|
9
11
|
/** Runs in THIS plugin's context when an admin selects the item; receives the admin's 0-based slot. */
|
|
10
12
|
onSelect: (adminSlot: number) => void;
|
|
11
13
|
}
|
|
14
|
+
/** A handler-free copy of the whole registry — what a menu renderer reads to build the display. */
|
|
12
15
|
export interface TopMenuSnapshot {
|
|
16
|
+
/** All category names, in registration order. */
|
|
13
17
|
categories: string[];
|
|
18
|
+
/** Every registered item's metadata (no `onSelect`), tagged with its category. */
|
|
14
19
|
items: { id: string; category: string; name: string; flags: number }[];
|
|
15
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* The shared admin/top-menu registry — renderers read {@link TopMenu.snapshot} and dispatch picks
|
|
23
|
+
* through {@link TopMenu.select}; items are contributed by plugins via their own ctx.topmenu.
|
|
24
|
+
* @example
|
|
25
|
+
* import { TopMenu } from "@s2script/sdk/topmenu";
|
|
26
|
+
* const snap = TopMenu.snapshot();
|
|
27
|
+
* for (const cat of snap.categories) renderCategory(cat);
|
|
28
|
+
* // when the admin picks an item id, dispatch it back to its owner plugin:
|
|
29
|
+
* m.onSelect(e => { TopMenu.select(e.info, slot); });
|
|
30
|
+
*/
|
|
16
31
|
export declare const TopMenu: {
|
|
17
32
|
/** All categories + item metadata (no handlers) — the adminmenu renderer reads this. */
|
|
18
33
|
snapshot(): TopMenuSnapshot;
|
package/trace.d.ts
CHANGED
|
@@ -57,6 +57,14 @@ export interface TraceOptions {
|
|
|
57
57
|
ignoreEntity?: EntityRef;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Ray-tracing entry point — `line`/`ray`/`hull` traces over the Source 2 physics scene.
|
|
62
|
+
* @example
|
|
63
|
+
* import { Trace } from "@s2script/sdk/trace";
|
|
64
|
+
* import { Vector } from "@s2script/sdk/math";
|
|
65
|
+
* const down = Trace.line(new Vector(o.x, o.y, o.z + 500), new Vector(o.x, o.y, o.z - 100));
|
|
66
|
+
* if (down.didHit) console.log(down.fraction, down.endPos);
|
|
67
|
+
*/
|
|
60
68
|
export declare const Trace: {
|
|
61
69
|
/** A line trace from `start` to `end`. */
|
|
62
70
|
line(start: Vector, end: Vector, opts?: TraceOptions): TraceHit;
|
package/translations.d.ts
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
/** @s2script/translations — SourceMod-style i18n (per-client language, phrase files, {1} formatting). */
|
|
2
|
+
|
|
3
|
+
/** A phrase set: key → template string, where `{1}`/`{2}`/… are positional substitution slots. */
|
|
2
4
|
export type Phrases = Record<string, string>;
|
|
5
|
+
/**
|
|
6
|
+
* SourceMod-style translation registry: seed a default phrase set, override it per language from
|
|
7
|
+
* `translations/<code>/<name>.phrases.json`, then translate a key for a given client's language.
|
|
8
|
+
* @example
|
|
9
|
+
* import { Translations } from "@s2script/sdk/translations";
|
|
10
|
+
* Translations.load("trdemo", { Greeting: "Hello {1}", Bye: "Goodbye {1}" });
|
|
11
|
+
* console.log(Translations.translate(-1, "Greeting", "world")); // "Hello world"
|
|
12
|
+
*/
|
|
3
13
|
export declare const Translations: {
|
|
4
14
|
/** Register a phrase set: `seed` is the built-in English default; translations/<code>/<name>.phrases.json overrides per language. */
|
|
5
15
|
load(name: string, seed: Phrases): void;
|
package/transmit.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* engine-side hook enforces it every snapshot — zero JS runs in the per-client hot path. */
|
|
4
4
|
import type { EntityRef } from "./entity";
|
|
5
5
|
|
|
6
|
+
/** Hot-path measurement counters returned by {@link Transmit.stats}. */
|
|
6
7
|
export interface TransmitStats {
|
|
7
8
|
/** CheckTransmit invocations observed since load/reset. */
|
|
8
9
|
snapshots: number;
|
|
@@ -16,6 +17,13 @@ export interface TransmitStats {
|
|
|
16
17
|
nsMax: number;
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Declarative per-client entity visibility: hide an entity from some viewers, enforced engine-side each snapshot.
|
|
22
|
+
* @example
|
|
23
|
+
* import { Transmit } from "@s2script/sdk/transmit";
|
|
24
|
+
* // examples/transmit-demo/src/plugin.ts:58 — show `prop` ONLY to one viewer slot
|
|
25
|
+
* const ok = Transmit.setVisibleTo(prop, [slot]);
|
|
26
|
+
*/
|
|
19
27
|
export declare const Transmit: {
|
|
20
28
|
/** Replace this plugin's visibility rule for `entity`: it is transmitted ONLY to the given viewer
|
|
21
29
|
* slots (an empty array = hidden from everyone). Multiple plugins AND-merge — an entity reaches a
|
package/usercmd.d.ts
CHANGED
|
@@ -11,6 +11,12 @@ import type { QAngle } from "./math";
|
|
|
11
11
|
* handler — a stashed `UserCmdView` used after the handler returns, or across an `await`,
|
|
12
12
|
* reads/writes nothing). There is exactly ONE `UserCmdView` instance for the whole process; every
|
|
13
13
|
* handler call operates on it.
|
|
14
|
+
* @example
|
|
15
|
+
* import type { UserCmdView } from "@s2script/sdk/usercmd";
|
|
16
|
+
* // examples/usercmd-demo/src/plugin.ts:21 — read this tick's input
|
|
17
|
+
* ctx.clients.onRunCmd((cmd: UserCmdView, info: { slot: number }) => {
|
|
18
|
+
* console.log(`slot=${info.slot} fwd=${cmd.forwardMove} btn=${cmd.buttons}`);
|
|
19
|
+
* });
|
|
14
20
|
*/
|
|
15
21
|
export interface UserCmdView {
|
|
16
22
|
/** +forward / -back. Normalized to roughly [-1, 1] (not the legacy ±450 units). */
|
package/usermessages.d.ts
CHANGED
|
@@ -3,9 +3,13 @@ import type { HookResultValue } from "./events";
|
|
|
3
3
|
/** A general protobuf user-message builder. Build then send in one synchronous burst. */
|
|
4
4
|
export class UserMessage {
|
|
5
5
|
constructor(name: string);
|
|
6
|
+
/** Set an integer field. Returns `this` for chaining. */
|
|
6
7
|
setInt(field: string, value: number): this;
|
|
8
|
+
/** Set a float field. Returns `this` for chaining. */
|
|
7
9
|
setFloat(field: string, value: number): this;
|
|
10
|
+
/** Set a string field. Returns `this` for chaining. */
|
|
8
11
|
setString(field: string, value: string): this;
|
|
12
|
+
/** Set a boolean field. Returns `this` for chaining. */
|
|
9
13
|
setBool(field: string, value: boolean): this;
|
|
10
14
|
/** Infer the setter from the JS value type. */
|
|
11
15
|
set(field: string, value: number | string | boolean): this;
|
|
@@ -28,15 +32,29 @@ export interface UserMessageView {
|
|
|
28
32
|
readonly recipients: number[];
|
|
29
33
|
/** protobuf TextFormat dump — the documented FALLBACK for unmapped messages only; prefer typed reads. */
|
|
30
34
|
readonly debugString: string;
|
|
35
|
+
/** Whether `path` is present on the current message. Dotted nested paths supported ("origin.x"). */
|
|
31
36
|
hasField(path: string): boolean;
|
|
32
37
|
/** Scalar int read (int32/uint32/fixed32/enum; bool as 0/1). Dotted nested paths supported
|
|
33
38
|
* ("origin.x" walks sub-messages). null = no such field / repeated / no current message. */
|
|
34
39
|
readInt(path: string): number | null;
|
|
40
|
+
/** Scalar float read (float/double). Dotted nested paths supported. null if absent/repeated/no message. */
|
|
35
41
|
readFloat(path: string): number | null;
|
|
42
|
+
/** Scalar bool read. Dotted nested paths supported. null if absent/repeated/no message. */
|
|
36
43
|
readBool(path: string): boolean | null;
|
|
44
|
+
/** Scalar string/bytes read. Dotted nested paths supported. null if absent/repeated/no message. */
|
|
37
45
|
readString(path: string): string | null;
|
|
38
46
|
}
|
|
39
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Intercept outbound user messages before delivery (read typed fields, optionally suppress the send).
|
|
50
|
+
* @example
|
|
51
|
+
* import { UserMessages } from "@s2script/sdk/usermessages";
|
|
52
|
+
* import { HookResult, type HookResultValue } from "@s2script/sdk/events";
|
|
53
|
+
* // examples/usermsg-demo/src/plugin.ts:15 — blanket-block radio text
|
|
54
|
+
* UserMessages.onPre("CCSUsrMsg_RadioText", (m): HookResultValue | void => {
|
|
55
|
+
* if (blockRadio) return HookResult.Handled;
|
|
56
|
+
* });
|
|
57
|
+
*/
|
|
40
58
|
export declare const UserMessages: {
|
|
41
59
|
/** Pre-hook an outbound user message by unscoped name (partial match, SayText2-style; the view
|
|
42
60
|
* carries the canonical name). Runs SYNCHRONOUSLY before delivery. Return >= HookResult.Handled
|
package/votes.d.ts
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
/** @s2script/votes — chat-ballot voting with revote + an optional live center tally. NO runtime code (injected at load). */
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
/** The outcome delivered to {@link VoteConfig.onEnd} when a vote ends. */
|
|
4
|
+
export interface VoteResult {
|
|
5
|
+
/** 0-based index of the winning option, or null on a tie or zero votes. */
|
|
6
|
+
readonly winner: number | null;
|
|
7
|
+
/** Per-option vote counts, parallel to {@link VoteConfig.options}. */
|
|
8
|
+
readonly counts: number[];
|
|
9
|
+
/** Total votes cast. */
|
|
10
|
+
readonly total: number;
|
|
11
|
+
}
|
|
12
|
+
/** Configuration for {@link Vote.start}. */
|
|
3
13
|
export interface VoteConfig {
|
|
14
|
+
/** The question shown to voters. */
|
|
4
15
|
question: string;
|
|
5
16
|
/** 2..9 options (chat votes are single-digit). */
|
|
6
17
|
options: string[];
|
|
@@ -8,13 +19,45 @@ export interface VoteConfig {
|
|
|
8
19
|
duration: number;
|
|
9
20
|
/** show a live center tally (default false — the SM chat-only way). */
|
|
10
21
|
showLiveTally?: boolean;
|
|
22
|
+
/** Called once when the vote ends (or is exhausted), with the tallied {@link VoteResult}. It may start a new vote (the lock is released first). */
|
|
11
23
|
onEnd: (result: VoteResult) => void;
|
|
12
24
|
}
|
|
13
|
-
|
|
14
|
-
export interface
|
|
25
|
+
/** A per-tick snapshot of an in-progress vote, handed to a {@link VoteTallyRenderer}. */
|
|
26
|
+
export interface VoteTally {
|
|
27
|
+
/** The question being voted on. */
|
|
28
|
+
question: string;
|
|
29
|
+
/** Each option's label and current vote count. */
|
|
30
|
+
options: { label: string; count: number }[];
|
|
31
|
+
/** Total votes cast so far. */
|
|
32
|
+
total: number;
|
|
33
|
+
/** Seconds remaining before the vote ends. */
|
|
34
|
+
secondsLeft: number;
|
|
35
|
+
}
|
|
36
|
+
/** A live-tally display backend for votes — registered via {@link Vote.registerTallyRenderer}. */
|
|
37
|
+
export interface VoteTallyRenderer {
|
|
38
|
+
/** Show/update the running tally for `slot`. */
|
|
39
|
+
show(slot: number, tally: VoteTally): void;
|
|
40
|
+
/** Remove the tally display for `slot` (the vote ended or the player left). */
|
|
41
|
+
clear(slot: number): void;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The voting entry point — one active chat-ballot vote at a time, tallied on close.
|
|
45
|
+
* @example
|
|
46
|
+
* import { Vote } from "@s2script/sdk/votes";
|
|
47
|
+
* Vote.start({
|
|
48
|
+
* question: `Kick ${name}?`,
|
|
49
|
+
* options: ["Yes", "No"],
|
|
50
|
+
* duration: 20,
|
|
51
|
+
* showLiveTally: true,
|
|
52
|
+
* onEnd: (r) => {
|
|
53
|
+
* if (r.winner === 0 && r.counts[0] > r.total / 2) kick(name);
|
|
54
|
+
* },
|
|
55
|
+
* });
|
|
56
|
+
*/
|
|
15
57
|
export declare const Vote: {
|
|
16
58
|
/** Start a vote (chat ballot to all connected players). Returns false if one is already active. */
|
|
17
59
|
start(config: VoteConfig): boolean;
|
|
60
|
+
/** True while a vote is running (the single-vote lock is held). */
|
|
18
61
|
isActive(): boolean;
|
|
19
62
|
/** Abort the active vote (no onEnd). */
|
|
20
63
|
cancel(): void;
|
package/ws.d.ts
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
/** @s2script/ws — client WebSocket. NO runtime code (injected as __s2pkg_ws). */
|
|
2
|
+
|
|
3
|
+
/** An open WebSocket connection — a per-plugin handle over a copied message stream (no live socket crosses to JS). */
|
|
2
4
|
export interface WebSocket {
|
|
5
|
+
/** Register a handler invoked for each inbound text frame. */
|
|
3
6
|
onMessage(handler: (data: string) => void): void;
|
|
7
|
+
/** Register a handler for connection close; `code`/`reason` come from the close frame. */
|
|
4
8
|
onClose(handler: (code: number, reason: string) => void): void;
|
|
9
|
+
/** Register a handler for a transport error; `err` is the error text. */
|
|
5
10
|
onError(handler: (err: string) => void): void;
|
|
11
|
+
/** Send a text frame. */
|
|
6
12
|
send(data: string): void;
|
|
13
|
+
/** Close the connection. */
|
|
7
14
|
close(): void;
|
|
8
15
|
}
|
|
16
|
+
/** Entry point for opening WebSocket connections. */
|
|
9
17
|
export declare const WebSocket: {
|
|
10
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Connect to a WebSocket server (`wss://` for TLS) off the game thread.
|
|
20
|
+
* @returns Resolves on the open handshake with the live {@link WebSocket} handle.
|
|
21
|
+
* @throws Rejects on connect failure (bad URL, refused, TLS/handshake error).
|
|
22
|
+
* @example
|
|
23
|
+
* import { WebSocket } from "@s2script/sdk/ws";
|
|
24
|
+
* const ws = await WebSocket.connect("wss://ws.postman-echo.com/raw");
|
|
25
|
+
* ws.onMessage((data) => { console.log("echo:", data); ws.close(); });
|
|
26
|
+
* ws.send("hello-from-s2script");
|
|
27
|
+
*/
|
|
11
28
|
connect(url: string): Promise<WebSocket>;
|
|
12
29
|
};
|