@s2script/sdk 0.21.0 → 0.23.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/README.md +12 -4
- package/clients.d.ts +2 -7
- package/commands.d.ts +52 -5
- package/config.d.ts +5 -0
- package/damage.d.ts +12 -7
- package/dist/cli.js +363 -129
- package/entity.d.ts +1 -1
- package/events.d.ts +4 -3
- package/index.d.ts +47 -0
- package/package.json +8 -2
- package/phrases.d.ts +5 -4
- package/plugin.d.ts +103 -43
- package/sdkhooks.d.ts +543 -0
- package/server.d.ts +5 -5
- package/translations.d.ts +6 -4
- package/unsafe.d.ts +28 -8
package/README.md
CHANGED
|
@@ -19,13 +19,21 @@ Copy the `.s2sp` into `addons/s2script/plugins/` on a running server and it load
|
|
|
19
19
|
re-drop to hot-reload, delete to unload. No restart.
|
|
20
20
|
|
|
21
21
|
```ts
|
|
22
|
-
import {
|
|
22
|
+
import { command, hook } from "@s2script/sdk";
|
|
23
|
+
import type { Client } from "@s2script/sdk";
|
|
23
24
|
|
|
24
|
-
export
|
|
25
|
-
|
|
25
|
+
export function OnPluginStart(): void {
|
|
26
|
+
command("hello", (cmd) => {
|
|
26
27
|
cmd.reply("hello from s2script");
|
|
27
28
|
});
|
|
28
|
-
|
|
29
|
+
hook.on("player_spawn", (ev) => {
|
|
30
|
+
console.log("spawned", ev.getPlayerSlot("userid"));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function OnClientPostAdminCheck(client: Client): void {
|
|
35
|
+
client.chat("welcome");
|
|
36
|
+
}
|
|
29
37
|
```
|
|
30
38
|
|
|
31
39
|
This package is **types-only** — the engine injects the implementation at load time, and
|
package/clients.d.ts
CHANGED
|
@@ -60,13 +60,8 @@ export declare class Client {
|
|
|
60
60
|
* or a name that is not a registered console **command** (a ConVar such as `mp_friendlyfire` is
|
|
61
61
|
* refused: use `Server.command` for those).
|
|
62
62
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* the isolate borrow across all JS, so re-entering the dispatcher hits the documented
|
|
66
|
-
* re-entrancy skip. (This is not a permissions issue: every s2script command is registered
|
|
67
|
-
* client-executable, which is why a player can type it in their own console.) To invoke another
|
|
68
|
-
* plugin's behaviour, use a cross-plugin interface rather than faking its command. See
|
|
69
|
-
* docs/superpowers/specs/2026-07-25-client-command-design.md §12.
|
|
63
|
+
* Engine commands (`say`, `kill`, …) execute. A command registered by an s2script plugin runs
|
|
64
|
+
* that plugin's JS handler before this returns.
|
|
70
65
|
*
|
|
71
66
|
* @example
|
|
72
67
|
* client.fakeCommand("say hello"); // as though the player typed it
|
package/commands.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export interface CommandInvocation {
|
|
|
57
57
|
*
|
|
58
58
|
* @example
|
|
59
59
|
* // `!help` answers in chat; `sm_help` typed at a console answers in that console.
|
|
60
|
-
*
|
|
60
|
+
* command("sm_help", (cmd) => { cmd.reply("[SM] Commands: …"); return HookResult.Handled; });
|
|
61
61
|
*/
|
|
62
62
|
reply(message: string): void;
|
|
63
63
|
/**
|
|
@@ -81,6 +81,53 @@ export interface CommandInvocation {
|
|
|
81
81
|
* never in the way. */
|
|
82
82
|
replyT(key: PhraseKey, ...args: (string | number)[]): void;
|
|
83
83
|
}
|
|
84
|
+
|
|
85
|
+
/** Alias for {@link CommandInvocation} — the SourceMod-shaped name for a parsed invocation. */
|
|
86
|
+
export type Command = CommandInvocation;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* A command callback: the parsed invocation, plus an optional {@link HookResultValue}.
|
|
90
|
+
* SourceMod `Plugin_Handled` is {@link HookResult}.Handled — return it from a command you own
|
|
91
|
+
* (usage errors included; the command was still consumed). Omit the return (`void`) to continue —
|
|
92
|
+
* the same as returning {@link HookResult}.Continue. Engine SUPERCEDE-on-Continue is not this API;
|
|
93
|
+
* chat `!` vs `/` suppress is unchanged.
|
|
94
|
+
*/
|
|
95
|
+
export type CommandHandler = (
|
|
96
|
+
cmd: CommandInvocation,
|
|
97
|
+
) => HookResultValue | void | Promise<HookResultValue | void>;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Register a public command in the load window (SourceMod `RegConsoleCmd`).
|
|
101
|
+
* Callable only while `OnPluginStart` is running — throws after settle.
|
|
102
|
+
*
|
|
103
|
+
* `.admin` / `.server` are the `RegAdminCmd` / `RegServerCmd` shapes: name the handler anything.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* import { command, ADMFLAG, HookResult } from "@s2script/sdk";
|
|
107
|
+
* export function OnPluginStart(): void {
|
|
108
|
+
* command.admin("sm_kick", ADMFLAG.KICK, kick);
|
|
109
|
+
* }
|
|
110
|
+
* function kick(cmd: CommandInvocation): HookResultValue {
|
|
111
|
+
* cmd.reply("kicked");
|
|
112
|
+
* return HookResult.Handled;
|
|
113
|
+
* }
|
|
114
|
+
*/
|
|
115
|
+
export declare const command: {
|
|
116
|
+
(name: string, handler: CommandHandler): void;
|
|
117
|
+
/** Register an admin command gated by `flags` (an `ADMFLAG` bitmask). */
|
|
118
|
+
admin(name: string, flags: number, handler: CommandHandler): void;
|
|
119
|
+
/** Register a server-only command (console/rcon, not client-runnable). */
|
|
120
|
+
server(name: string, handler: CommandHandler): void;
|
|
121
|
+
/**
|
|
122
|
+
* Observe an existing CLIENT command by name — SourceMod's `AddCommandListener`.
|
|
123
|
+
* Load-window only. Same contract as {@link CtxCommands.onClientCommand} (on PluginContext).
|
|
124
|
+
*/
|
|
125
|
+
onClientCommand(
|
|
126
|
+
name: string,
|
|
127
|
+
handler: (slot: number, argString: string) => HookResultValue | void,
|
|
128
|
+
): void;
|
|
129
|
+
};
|
|
130
|
+
|
|
84
131
|
/** A parsed chat trigger: which command + args, and whether it was the silent (`/`) trigger. */
|
|
85
132
|
export interface ChatTrigger {
|
|
86
133
|
/** `true` = the silent trigger (`/`, hidden); `false` = the public trigger (`!`). */
|
|
@@ -93,9 +140,9 @@ export interface ChatTrigger {
|
|
|
93
140
|
|
|
94
141
|
/**
|
|
95
142
|
* Command-registry utilities: dispatch by name, parse/route chat triggers, and enumerate the global
|
|
96
|
-
* registry. Commands themselves are registered
|
|
143
|
+
* registry. Commands themselves are registered in the load window via {@link command}.
|
|
97
144
|
* @example
|
|
98
|
-
* import { Commands } from "@s2script/sdk
|
|
145
|
+
* import { Commands } from "@s2script/sdk";
|
|
99
146
|
* // sm_help backend: every registered command + its required admin flag mask.
|
|
100
147
|
* const cmds = Commands.list().slice().sort((a, b) => (a.name < b.name ? -1 : 1));
|
|
101
148
|
*/
|
|
@@ -122,7 +169,7 @@ export declare const Commands: {
|
|
|
122
169
|
/**
|
|
123
170
|
* Observe a CLIENT command by name — SourceMod's `AddCommandListener`.
|
|
124
171
|
*
|
|
125
|
-
* Unlike {@link
|
|
172
|
+
* Unlike {@link command}, which CREATES a command, this hooks one that already exists — including
|
|
126
173
|
* commands the engine itself owns (`player_ping`, `jointeam`, `drop`, `buy`). Registering a
|
|
127
174
|
* ConCommand of an engine-owned name fails outright ("unable to link multiple ConCommands named
|
|
128
175
|
* X"), so this is the only way to see those.
|
|
@@ -133,7 +180,7 @@ export declare const Commands: {
|
|
|
133
180
|
*
|
|
134
181
|
* @example
|
|
135
182
|
* // Middle-mouse ping opens the shop, and still places the ping.
|
|
136
|
-
*
|
|
183
|
+
* command.onClientCommand("player_ping", (slot) => { openShop(slot); });
|
|
137
184
|
*/
|
|
138
185
|
onClientCommand(name: string, handler: (slot: number, argString: string) => HookResultValue | void): void;
|
|
139
186
|
/** Every globally-registered command with its required admin `flags`: `0` = anyone, `-1` = console/server-only,
|
package/config.d.ts
CHANGED
|
@@ -23,4 +23,9 @@ export declare const config: {
|
|
|
23
23
|
readFile(name: string): string | null;
|
|
24
24
|
/** Write a raw file to the configs dir (creates/overwrites). */
|
|
25
25
|
writeFile(name: string, content: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Fires when this plugin's config file is re-materialized on disk. Ledgered per plugin.
|
|
28
|
+
* Not load-window-gated (safe from `OnPluginStart` or from `ctx.config.onChange`).
|
|
29
|
+
*/
|
|
30
|
+
onChange(handler: (cfg: Config) => void): void;
|
|
26
31
|
};
|
package/damage.d.ts
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @s2script/damage —
|
|
3
|
-
*
|
|
2
|
+
* @s2script/damage — the block-scoped {@link DamageInfo} view of a live `CTakeDamageInfo`.
|
|
3
|
+
* NO runtime code (injected at load). Engine-generic: `CTakeDamageInfo` is a Source 2 type.
|
|
4
|
+
*
|
|
5
|
+
* Subscribe with `SDKHook` (`SDKHookType.OnTakeDamage` / `OnTakeDamagePost`), not a global mux.
|
|
4
6
|
*/
|
|
5
7
|
import type { EntityRef } from "./entity";
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
|
-
* A block-scoped view of the current damage event (valid only inside
|
|
10
|
+
* A block-scoped view of the current damage event (valid only inside an `OnTakeDamage` or
|
|
11
|
+
* `OnTakeDamagePost` SDKHook).
|
|
9
12
|
* @example
|
|
10
|
-
* import type { DamageInfo } from "@s2script/sdk
|
|
11
|
-
*
|
|
12
|
-
* ctx.entities.onDamage((info: DamageInfo) => { info.damage = info.damage / 2; });
|
|
13
|
+
* import type { DamageInfo } from "@s2script/sdk";
|
|
14
|
+
* function onTakeDamage(info: DamageInfo) { info.damage = info.damage / 2; }
|
|
13
15
|
*/
|
|
14
16
|
export interface DamageInfo {
|
|
15
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* The damage amount (`m_flDamage`). On the pre-hook, assigning MODIFIES the live damage; set to
|
|
19
|
+
* 0 to block. On `OnTakeDamagePost`, assignment is ignored (the original already ran).
|
|
20
|
+
*/
|
|
16
21
|
damage: number;
|
|
17
22
|
/** The damage-type bit flags (m_bitsDamageType). */
|
|
18
23
|
readonly damageType: number;
|