@s2script/sdk 0.5.0 → 0.5.1

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/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
- export interface VoteResult { readonly winner: number | null; readonly counts: number[]; readonly total: number; }
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
- export interface VoteTally { question: string; options: { label: string; count: number }[]; total: number; secondsLeft: number; }
14
- export interface VoteTallyRenderer { show(slot: number, tally: VoteTally): void; clear(slot: number): void; }
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
- /** Connect to a WebSocket server (wss:// for TLS). Resolves on the open handshake; rejects on connect failure. */
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
  };