@s2script/sdk 0.4.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/admin.d.ts CHANGED
@@ -7,26 +7,43 @@
7
7
 
8
8
  /** SourceMod-parity admin flag bitmask constants (SM bit values). */
9
9
  export declare const ADMFLAG: {
10
+ /** Reserved-slot access (`1<<0` = 1). */
10
11
  readonly RESERVATION: number;
12
+ /** Generic admin — the baseline "is an admin" flag (`1<<1` = 2). */
11
13
  readonly GENERIC: number;
14
+ /** May kick players (`1<<2` = 4). */
12
15
  readonly KICK: number;
16
+ /** May ban players (`1<<3` = 8). */
13
17
  readonly BAN: number;
18
+ /** May remove bans (`1<<4` = 16). */
14
19
  readonly UNBAN: number;
20
+ /** May slay/slap players (`1<<5` = 32). */
15
21
  readonly SLAY: number;
22
+ /** May change the map (`1<<6` = 64). */
16
23
  readonly CHANGEMAP: number;
24
+ /** May change most convars (`1<<7` = 128). */
17
25
  readonly CONVARS: number;
26
+ /** May execute config files (`1<<8` = 256). */
18
27
  readonly CONFIG: number;
28
+ /** Admin-chat and other special chat privileges (`1<<9` = 512). */
19
29
  readonly CHAT: number;
30
+ /** May start votes (`1<<10` = 1024). */
20
31
  readonly VOTE: number;
32
+ /** May set the server password (`1<<11` = 2048). */
21
33
  readonly PASSWORD: number;
34
+ /** May use rcon commands (`1<<12` = 4096). */
22
35
  readonly RCON: number;
36
+ /** May change cheat convars and use cheat commands (`1<<13` = 8192). */
23
37
  readonly CHEATS: number;
38
+ /** Full access — implicitly satisfies every flag (`1<<14` = 16384). See {@link AdminInfo.hasFlags}. */
24
39
  readonly ROOT: number;
25
40
  };
26
41
 
27
42
  /** An admin entry: their SteamID64, their combined flag mask, and a helper to check flags. */
28
43
  export interface AdminInfo {
44
+ /** This admin's SteamID64 (decimal string). */
29
45
  readonly steamId: string;
46
+ /** Combined flag mask (union of file + runtime tiers and group flags) — test against {@link ADMFLAG} bits. */
30
47
  readonly flags: number;
31
48
  /** Immunity level (0 = none). A lower-immunity admin cannot target a higher one. */
32
49
  readonly immunity: number;
@@ -38,13 +55,23 @@ export interface AdminInfo {
38
55
 
39
56
  /** A resolved admin group (from admin_groups.json): its flags, immunity, and per-command overrides. */
40
57
  export interface AdminGroup {
58
+ /** The group's name (its key in admin_groups.json). */
41
59
  readonly name: string;
60
+ /** Flag mask granted to every member — {@link ADMFLAG} bits. */
42
61
  readonly flags: number;
62
+ /** Immunity level conferred by membership (0 = none). */
43
63
  readonly immunity: number;
64
+ /** Per-command access overrides, keyed by command name: `public` opens it to all, `mask` is the required flags. */
44
65
  readonly overrides: Readonly<Record<string, { public: boolean; mask: number }>>;
45
66
  }
46
67
 
47
- /** The admin API: add/remove runtime admins, look up by SteamID or slot, reload from file. */
68
+ /**
69
+ * The admin API: add/remove runtime admins, look up by SteamID or slot, reload from file.
70
+ * @example
71
+ * import { Admin, ADMFLAG } from "@s2script/sdk/admin";
72
+ * const a = Admin.forSlot(p.slot);
73
+ * const adminStr = a ? "yes(flags=0x" + a.flags.toString(16) + ")" : "no";
74
+ */
48
75
  export declare const Admin: {
49
76
  /** Add (or overwrite) a runtime admin. Not persisted to admins.json. */
50
77
  add(steamId: string, flags: number, immunity?: number): void;
package/bans.d.ts CHANGED
@@ -29,7 +29,14 @@ export interface BanEntry {
29
29
  reason: string;
30
30
  }
31
31
 
32
- /** The ban API: add/remove bans, look up by SteamID64, list, and reload from bans.json. */
32
+ /**
33
+ * The ban API: add/remove bans, look up by SteamID64, list, and reload from bans.json.
34
+ * @example
35
+ * import { Bans } from "@s2script/sdk/bans";
36
+ * // Connect-time enforcement inside a Clients.onConnect handler.
37
+ * const b = Bans.get(c.steamId);
38
+ * if (b && (b.until === 0 || b.until > Date.now() / 1000)) c.kickWithReason(b.reason);
39
+ */
33
40
  export declare const Bans: {
34
41
  /** Add (or overwrite) a ban and persist it to bans.json. `minutes <= 0` = permanent. */
35
42
  add(steamId: string, minutes: number, reason?: string): void;
package/chat.d.ts CHANGED
@@ -1,6 +1,12 @@
1
1
  /** @s2script/chat — print messages to player chat. NO runtime code (injected at load). */
2
- import type { HookResultValue } from "./events";
3
2
 
3
+ /**
4
+ * Print messages to player chat (SayText2), with a caller-owned {@link Chat.color} prefix.
5
+ * @example
6
+ * import { Chat } from "@s2script/sdk/chat";
7
+ * Chat.toAll("[Vote] Result: " + winner);
8
+ * Chat.toSlot(slot, "Usage: @@<target> <message>");
9
+ */
4
10
  export declare const Chat: {
5
11
  /**
6
12
  * An opaque prefix prepended to every chat message (NOT rcon/console replies). Color is content the
@@ -13,10 +19,4 @@ export declare const Chat: {
13
19
  toSlot(slot: number, message: string): void;
14
20
  /** Print to every live player's chat. */
15
21
  toAll(message: string): void;
16
- /**
17
- * Subscribe to raw player chat. The handler receives the speaker's `slot`, the raw `text`, and
18
- * `teamonly`. Returning `>= HookResult.Handled` (2) suppresses the broadcast (SM-parity). Non-command
19
- * chat lines are delivered here; the `@`-trigger layer subscribes through this.
20
- */
21
- onMessage(handler: (slot: number, text: string, teamonly: boolean) => HookResultValue | void): void;
22
22
  };
package/clients.d.ts CHANGED
@@ -2,8 +2,10 @@
2
2
  * @s2script/clients — engine-generic client handle + lifecycle events.
3
3
  * Resolved at runtime via globalThis.__s2pkg_clients. Import: import { Client, Clients } from "./clients";
4
4
  */
5
+
5
6
  /** A connected client, identified by its 0-based slot (CPlayerSlot). Slot-backed; getters read live. */
6
7
  export declare class Client {
8
+ /** The client's 0-based engine slot (`CPlayerSlot`) — the handle's stable identity for its connection. */
7
9
  readonly slot: number;
8
10
  /** True while a client occupies this slot. */
9
11
  isValid(): boolean;
@@ -35,27 +37,15 @@ export declare class Client {
35
37
  */
36
38
  voiceMuted: boolean;
37
39
  }
40
+ /**
41
+ * Look up connected clients by slot or enumerate them all.
42
+ * @example
43
+ * import { Clients } from "@s2script/sdk/clients";
44
+ * console.log(`onLoad — all()=${Clients.all().length} clients`);
45
+ */
38
46
  export declare const Clients: {
39
- /** Fires when a client connects (all clients incl. bots; carries name/xuid). May be async. */
40
- onConnect(handler: (client: Client) => void | Promise<void>): void;
41
- /** Fires when a client is put in the server (controller/pawn context now exists). May be async. */
42
- onPutInServer(handler: (client: Client) => void | Promise<void>): void;
43
- /** Fires when a client goes active (spawned / in-game). May be async. */
44
- onActive(handler: (client: Client) => void | Promise<void>): void;
45
- /** Fires when a client is fully connected. May be async. */
46
- onFullyConnect(handler: (client: Client) => void | Promise<void>): void;
47
- /** Fires when a client disconnects. Only `.slot` is guaranteed live here — capture identity earlier if needed. */
48
- onDisconnect(handler: (client: Client) => void): void;
49
- /** Fires when a client's settings (name/cvars) change. */
50
- onSettingsChanged(handler: (client: Client) => void): void;
51
- /**
52
- * Fires while a client transmits voice. Throttled to at most one dispatch per client per second;
53
- * the FIRST packet of a transmission always fires (a lazy mute-on-talk lands immediately).
54
- * Handlers should be idempotent. Never fires for bots.
55
- */
56
- onVoice(handler: (client: Client) => void): void;
57
47
  /** The client in `slot`, or null if the slot is empty. */
58
48
  fromSlot(slot: number): Client | null;
59
- /** Every currently-connected client. */
49
+ /** Every currently-connected client (bots included). */
60
50
  all(): Client[];
61
51
  };
package/commands.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  /** @s2script/commands — register server commands. NO runtime code (injected at load). */
2
- export interface CommandContext {
2
+
3
+ /**
4
+ * The parsed invocation handed to a command callback: who called it, its arguments (multiple typed
5
+ * accessors), and a caller-appropriate `reply` channel. Valid only for the duration of the callback.
6
+ */
7
+ export interface CommandInvocation {
3
8
  /** 0-based caller slot, or -1 for the server console. */
4
9
  readonly callerSlot: number;
5
10
  /** argString split on whitespace (0-based; the command name is NOT included). Kept for compat. */
@@ -32,10 +37,15 @@ export interface ChatTrigger {
32
37
  readonly argString: string;
33
38
  }
34
39
 
40
+ /**
41
+ * Command-registry utilities: dispatch by name, parse/route chat triggers, and enumerate the global
42
+ * registry. Commands themselves are registered through the plugin context (`ctx.commands.register*`).
43
+ * @example
44
+ * import { Commands } from "@s2script/sdk/commands";
45
+ * // sm_help backend: every registered command + its required admin flag mask.
46
+ * const cmds = Commands.list().slice().sort((a, b) => (a.name < b.name ? -1 : 1));
47
+ */
35
48
  export declare const Commands: {
36
- register(name: string, handler: (ctx: CommandContext) => void): void;
37
- registerServer(name: string, handler: (ctx: CommandContext) => void): void;
38
- registerAdmin(name: string, flags: number, handler: (ctx: CommandContext) => void): void;
39
49
  /** Invoke a registered command by name in THIS plugin (applying its gating). Returns true if it exists. */
40
50
  dispatch(name: string, slot: number, argString: string): boolean;
41
51
  /** Parse a chat message for a trigger (`!`/`/`). Returns the parsed trigger, or null if it's ordinary chat. */
package/config.d.ts CHANGED
@@ -1,14 +1,24 @@
1
1
  /** @s2script/config — typed access to the plugin's materialized config. NO runtime code. */
2
2
  /** A materialized config value: a scalar, or a nested section object of further values. */
3
3
  export type ConfigValue = string | number | boolean | { [k: string]: ConfigValue };
4
+ /** The whole materialized config: top-level keys to {@link ConfigValue}s. Passed to `ctx.config.onChange`. */
4
5
  export type Config = Record<string, ConfigValue>;
6
+ /**
7
+ * Typed access to this plugin's materialized config values (declared under `s2script.config` in the manifest).
8
+ * @example
9
+ * import { config } from "@s2script/sdk/config";
10
+ * // plugins/antiflood/src/plugin.ts:31 — re-read on live-reload
11
+ * const maxTokens = config.getInt("max_tokens");
12
+ */
5
13
  export declare const config: {
14
+ /** A config value as a string. `""` if the key is absent. */
6
15
  getString(key: string): string;
16
+ /** A config value as an integer. `0` if the key is absent or non-numeric. */
7
17
  getInt(key: string): number;
18
+ /** A config value as a float. `0` if the key is absent or non-numeric. */
8
19
  getFloat(key: string): number;
20
+ /** A config value as a boolean. `false` if the key is absent. */
9
21
  getBool(key: string): boolean;
10
- /** Opt into live-reload: the handler fires with the re-materialized config when the file changes. */
11
- onChange(handler: (cfg: Config) => void): void;
12
22
  /** Read a raw file from the configs dir (name includes its extension, e.g. "maplist.txt"). null if absent. */
13
23
  readFile(name: string): string | null;
14
24
  /** Write a raw file to the configs dir (creates/overwrites). */
package/console.d.ts CHANGED
@@ -5,8 +5,17 @@
5
5
 
6
6
  /** Engine-provided console (log/error/warn/info). Also available as the global `console`. */
7
7
  export declare const console: {
8
+ /**
9
+ * Write a line to the server console (and the log). Arguments are stringified and space-joined.
10
+ * @example
11
+ * import { console } from "@s2script/sdk/console";
12
+ * console.log("[antiflood] onLoad — chat flood protection active");
13
+ */
8
14
  log(...data: any[]): void;
15
+ /** Write a line at error severity. */
9
16
  error(...data: any[]): void;
17
+ /** Write a line at warning severity. */
10
18
  warn(...data: any[]): void;
19
+ /** Write a line at info severity. */
11
20
  info(...data: any[]): void;
12
21
  };
package/cookies.d.ts CHANGED
@@ -1,10 +1,43 @@
1
1
  /** @s2script/cookies — SM-parity client preference cookies. NO runtime code (injected as __s2pkg_cookies). */
2
2
  import type { Client } from "./clients";
3
- export enum CookieAccess { Public, Protected, Private }
4
- export interface Cookie { readonly name: string; readonly access: CookieAccess; readonly default: string; }
5
- export interface CookieOptions { description?: string; access?: CookieAccess; default?: string; }
3
+
4
+ /** SM-parity access level carried as metadata on a {@link Cookie} definition (client cookie-menu visibility/editability). */
5
+ export enum CookieAccess {
6
+ /** Visible and editable by the client in the cookie menu. */
7
+ Public,
8
+ /** Visible to the client but not editable. */
9
+ Protected,
10
+ /** Hidden from the client; plugin-only. */
11
+ Private,
12
+ }
13
+ /** A registered cookie definition — the handle passed to {@link Cookies.get}/{@link Cookies.set}. */
14
+ export interface Cookie {
15
+ /** Unique cookie name (the DB key). */
16
+ readonly name: string;
17
+ /** Client visibility/editability, per {@link CookieAccess}. */
18
+ readonly access: CookieAccess;
19
+ /** Value returned by {@link Cookies.get} when the client has no stored value. */
20
+ readonly default: string;
21
+ }
22
+ /** Options for {@link Cookies.register}. */
23
+ export interface CookieOptions {
24
+ /** Human-readable description (shown in a cookie menu). */
25
+ description?: string;
26
+ /** Client visibility/editability. @defaultValue {@link CookieAccess.Public} */
27
+ access?: CookieAccess;
28
+ /** Fallback value when the client has no stored value. @defaultValue `""` */
29
+ default?: string;
30
+ }
31
+ /** Entry point for registering and reading/writing client preference cookies. */
6
32
  export declare const Cookies: {
7
- /** Register (or return an existing) cookie definition. */
33
+ /**
34
+ * Register (or return an existing) cookie definition. Idempotent per plugin context — the same name
35
+ * returns the already-registered {@link Cookie}.
36
+ * @example
37
+ * import { Cookies } from "@s2script/sdk/cookies";
38
+ * const boots = Cookies.register("demo_boots", { default: "0" });
39
+ * const n = parseInt(Cookies.get(client, boots), 10);
40
+ */
8
41
  register(name: string, opts?: CookieOptions): Cookie;
9
42
  /** Cache value for this client (a stored "" is a real value), else the cookie's default. Default for bots. */
10
43
  get(client: Client, cookie: Cookie): string;
@@ -19,7 +52,4 @@ export declare const Cookies: {
19
52
  * clientprefs plugin to persist directly next frame — an offline SteamID never fires the disconnect
20
53
  * flush. No-op for "0" (bot/unset). */
21
54
  setAuthId(steamId: string, cookie: Cookie, value: string): void;
22
- /** Fires once per client, after that client's cookies finish loading (`OnClientCookiesCached`
23
- * parity) — post-frame, after the load's async DB read completes. */
24
- onCached(handler: (client: Client) => void): void;
25
55
  };
package/damage.d.ts CHANGED
@@ -4,7 +4,13 @@
4
4
  */
5
5
  import type { EntityRef } from "./entity";
6
6
 
7
- /** A block-scoped view of the current damage event (valid only inside a Damage.onPre handler). */
7
+ /**
8
+ * A block-scoped view of the current damage event (valid only inside a Damage.onPre handler).
9
+ * @example
10
+ * import type { DamageInfo } from "@s2script/sdk/damage";
11
+ * // plugins/basecommands/src/plugin.ts:81 — halve the damage (assign 0 to block it entirely)
12
+ * ctx.entities.onDamage((info: DamageInfo) => { info.damage = info.damage / 2; });
13
+ */
8
14
  export interface DamageInfo {
9
15
  /** The damage amount (m_flDamage). Assigning MODIFIES the live damage; set to 0 to block. */
10
16
  damage: number;
@@ -17,8 +23,3 @@ export interface DamageInfo {
17
23
  /** The victim — the entity taking damage (the hooked `this`), or null if stale. */
18
24
  readonly victim: EntityRef | null;
19
25
  }
20
-
21
- export declare const Damage: {
22
- /** Register a pre-damage hook. The handler reads/modifies the DamageInfo in place (damage=0 blocks). */
23
- onPre(handler: (info: DamageInfo) => void): void;
24
- };
package/db.d.ts CHANGED
@@ -1,26 +1,64 @@
1
1
  /** @s2script/db — engine-generic async SQLite database. NO runtime code (injected as __s2pkg_db). */
2
+
3
+ /** A value bindable as a SQL parameter or returned in a {@link Row}. */
2
4
  export type SqlValue = string | number | boolean | null;
5
+ /** One query result row — a column-name→{@link SqlValue} map. */
3
6
  export type Row = Record<string, SqlValue>;
4
- export interface ExecuteResult { changes: number; lastInsertId: number; }
7
+ /** The outcome of a non-SELECT statement run via {@link Database.execute}. */
8
+ export interface ExecuteResult {
9
+ /** Rows affected by the statement (INSERT/UPDATE/DELETE). */
10
+ changes: number;
11
+ /** Rowid of the last inserted row (0 if the statement inserted nothing). */
12
+ lastInsertId: number;
13
+ }
5
14
 
15
+ /** A driver-owned connection — what a {@link Driver} hands back from {@link Driver.connect}. */
6
16
  export interface DriverConnection {
17
+ /** Run a SELECT and resolve every result {@link Row}; `params` bind `?` placeholders. */
7
18
  query(sql: string, params?: SqlValue[]): Promise<Row[]>;
19
+ /** Run a non-SELECT statement and resolve its {@link ExecuteResult}; `params` bind `?` placeholders. */
8
20
  execute(sql: string, params?: SqlValue[]): Promise<ExecuteResult>;
21
+ /** Close the underlying connection. */
9
22
  close(): Promise<void>;
10
23
  }
11
- export interface ConnectionConfig { driver: string; name: string; [k: string]: unknown; }
24
+ /** Named-connection config resolved by {@link Database.open} and passed to {@link Driver.connect}. */
25
+ export interface ConnectionConfig {
26
+ /** Driver name to connect with (e.g. `"sqlite"`). */
27
+ driver: string;
28
+ /** The connection's configured name. */
29
+ name: string;
30
+ /** Driver-specific options (path, host, credentials, …). */
31
+ [k: string]: unknown;
32
+ }
33
+ /** A registered database backend; register a custom one via {@link Database.registerDriver}. */
12
34
  export interface Driver {
35
+ /** The driver's name, matched against {@link ConnectionConfig.driver}. */
13
36
  readonly name: string;
37
+ /** Open a connection for `config`, resolving a {@link DriverConnection}. */
14
38
  connect(config: ConnectionConfig): Promise<DriverConnection>;
15
39
  }
16
40
  /** A live database connection (delegates to its driver). */
17
41
  export interface Database {
42
+ /** Run a SELECT and resolve every result {@link Row}; `params` bind `?` placeholders. */
18
43
  query(sql: string, params?: SqlValue[]): Promise<Row[]>;
44
+ /** Run a non-SELECT statement and resolve its {@link ExecuteResult}; `params` bind `?` placeholders. */
19
45
  execute(sql: string, params?: SqlValue[]): Promise<ExecuteResult>;
46
+ /** Close the connection. */
20
47
  close(): Promise<void>;
21
48
  }
49
+ /** Entry point for opening databases and registering drivers. */
22
50
  export declare const Database: {
23
- /** Open a connection by name (default "default"). Resolves the driver + config, then connects. */
51
+ /**
52
+ * Open a connection by name (default `"default"`). Resolves the driver + config, then connects.
53
+ * @param name - Connection name from config; omit for `"default"`.
54
+ * @returns Resolves the connected {@link Database} handle.
55
+ * @throws Rejects if the name is unknown or the driver fails to connect.
56
+ * @example
57
+ * import { Database } from "@s2script/sdk/db";
58
+ * const db = await Database.open("clientprefs");
59
+ * await db.execute("CREATE TABLE IF NOT EXISTS cookies (steamid TEXT, name TEXT, value TEXT)");
60
+ * const rows = await db.query("SELECT value FROM cookies WHERE steamid = ?", ["76561199999999999"]);
61
+ */
24
62
  open(name?: string): Promise<Database>;
25
63
  /** Register a custom driver (per-plugin context). SQLite is built in. */
26
64
  registerDriver(driver: Driver): void;