@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/sdkhooks.d.ts
ADDED
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @s2script/sdkhooks — per-entity SDKHooks (SourceMod `SDKHook` / `SDKUnhook`).
|
|
3
|
+
* NO runtime code: the engine injects the implementation at load time.
|
|
4
|
+
*/
|
|
5
|
+
import type { EntityRef } from "./entity";
|
|
6
|
+
import type { DamageInfo } from "./damage";
|
|
7
|
+
import type { HookResultValue } from "./events";
|
|
8
|
+
import type { Client } from "./clients";
|
|
9
|
+
|
|
10
|
+
type TouchCallback = (entity: EntityRef, other: EntityRef | null) => HookResultValue | void;
|
|
11
|
+
type TouchPostCallback = (entity: EntityRef, other: EntityRef | null) => void;
|
|
12
|
+
type WeaponCallback = (entity: EntityRef, weapon: EntityRef | null) => HookResultValue | void;
|
|
13
|
+
type WeaponPostCallback = (entity: EntityRef, weapon: EntityRef | null) => void;
|
|
14
|
+
type ThisCallback = (entity: EntityRef) => HookResultValue | void;
|
|
15
|
+
type ThisVoidCallback = (entity: EntityRef) => void;
|
|
16
|
+
type FireBulletsPostCallback = (entity: EntityRef, shots: number, weaponName: string) => void;
|
|
17
|
+
type ReloadPostCallback = (weapon: EntityRef, successful: boolean) => void;
|
|
18
|
+
type UseCallback = (
|
|
19
|
+
entity: EntityRef,
|
|
20
|
+
activator: EntityRef | null,
|
|
21
|
+
caller: EntityRef | null,
|
|
22
|
+
type: UseTypeValue,
|
|
23
|
+
value: number,
|
|
24
|
+
) => HookResultValue | void;
|
|
25
|
+
type UsePostCallback = (
|
|
26
|
+
entity: EntityRef,
|
|
27
|
+
activator: EntityRef | null,
|
|
28
|
+
caller: EntityRef | null,
|
|
29
|
+
type: UseTypeValue,
|
|
30
|
+
value: number,
|
|
31
|
+
) => void;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* `CBaseEntity::Use` use-type (`USE_OFF` / `USE_ON` / `USE_SET` / `USE_TOGGLE`).
|
|
35
|
+
*/
|
|
36
|
+
export type UseTypeValue = 0 | 1 | 2 | 3;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* `CBaseEntity::Use` use-type constants (wiki `USE_*`).
|
|
40
|
+
*/
|
|
41
|
+
export declare const UseType: {
|
|
42
|
+
/** `USE_OFF` — turn off. */
|
|
43
|
+
readonly Off: 0;
|
|
44
|
+
/** `USE_ON` — turn on. */
|
|
45
|
+
readonly On: 1;
|
|
46
|
+
/** `USE_SET` — set to `value`. */
|
|
47
|
+
readonly Set: 2;
|
|
48
|
+
/** `USE_TOGGLE` — toggle. */
|
|
49
|
+
readonly Toggle: 3;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Shipped SDKHook types. Wiki names without the `SDKHook_` prefix. A wiki name whose engine
|
|
54
|
+
* backing failed or is absent returns `false` from {@link SDKHook} (does not throw). A string
|
|
55
|
+
* that is not a member here throws.
|
|
56
|
+
*/
|
|
57
|
+
export declare const SDKHookType: {
|
|
58
|
+
/** Pre-apply damage (`DispatchTraceAttack`). Mutate {@link DamageInfo.damage} in place. */
|
|
59
|
+
readonly OnTakeDamage: "OnTakeDamage";
|
|
60
|
+
/**
|
|
61
|
+
* CheckTransmit mux (wiki `SDKHook_SetTransmit`). `Handled` / `Stop` hide this entity from this
|
|
62
|
+
* viewer. AND-merge with `Transmit.setVisibleTo`: either API can hide; SetTransmit cannot
|
|
63
|
+
* un-hide a native mask clear. There is no `SetTransmitPost`.
|
|
64
|
+
*/
|
|
65
|
+
readonly SetTransmit: "SetTransmit";
|
|
66
|
+
/** `CBaseEntity::StartTouch` pre. `Handled` / `Stop` skip the original virtual. */
|
|
67
|
+
readonly StartTouch: "StartTouch";
|
|
68
|
+
/** `CBaseEntity::Touch` pre. `Handled` / `Stop` skip the original virtual. */
|
|
69
|
+
readonly Touch: "Touch";
|
|
70
|
+
/** `CBaseEntity::EndTouch` pre. `Handled` / `Stop` skip the original virtual. */
|
|
71
|
+
readonly EndTouch: "EndTouch";
|
|
72
|
+
/** `CBaseEntity::Blocked` pre. `Handled` / `Stop` skip the original virtual. */
|
|
73
|
+
readonly Blocked: "Blocked";
|
|
74
|
+
/** `StartTouch` post. Return is ignored. */
|
|
75
|
+
readonly StartTouchPost: "StartTouchPost";
|
|
76
|
+
/** `Touch` post. Return is ignored. */
|
|
77
|
+
readonly TouchPost: "TouchPost";
|
|
78
|
+
/** `EndTouch` post. Return is ignored. */
|
|
79
|
+
readonly EndTouchPost: "EndTouchPost";
|
|
80
|
+
/** `Blocked` post. Return is ignored. */
|
|
81
|
+
readonly BlockedPost: "BlockedPost";
|
|
82
|
+
/** `CBaseEntity::Spawn` pre. `Handled` / `Stop` skip the original virtual. */
|
|
83
|
+
readonly Spawn: "Spawn";
|
|
84
|
+
/** `Spawn` post. Return is ignored. */
|
|
85
|
+
readonly SpawnPost: "SpawnPost";
|
|
86
|
+
/** `CBaseEntity::Think` pre. `Handled` / `Stop` skip the original virtual. */
|
|
87
|
+
readonly Think: "Think";
|
|
88
|
+
/** `Think` post. Return is ignored. */
|
|
89
|
+
readonly ThinkPost: "ThinkPost";
|
|
90
|
+
/** Player `PreThink`. Return is ignored. */
|
|
91
|
+
readonly PreThink: "PreThink";
|
|
92
|
+
/** `PreThink` post. Return is ignored. */
|
|
93
|
+
readonly PreThinkPost: "PreThinkPost";
|
|
94
|
+
/** Player `PostThink`. Return is ignored. */
|
|
95
|
+
readonly PostThink: "PostThink";
|
|
96
|
+
/** `PostThink` post. Return is ignored. */
|
|
97
|
+
readonly PostThinkPost: "PostThinkPost";
|
|
98
|
+
/** `CBaseEntity::Use` pre. `Handled` / `Stop` skip the original virtual. */
|
|
99
|
+
readonly Use: "Use";
|
|
100
|
+
/** `Use` post. Return is ignored. */
|
|
101
|
+
readonly UsePost: "UsePost";
|
|
102
|
+
/** `GetMaxHealth`. Mutate `info.maxHealth`. `Handled` / `Stop` SUPERCEDE the original. */
|
|
103
|
+
readonly GetMaxHealth: "GetMaxHealth";
|
|
104
|
+
/** `ShouldCollide`. Return a boolean (not {@link HookResultValue}); last defined wins. */
|
|
105
|
+
readonly ShouldCollide: "ShouldCollide";
|
|
106
|
+
/** `VPhysicsUpdate`. Return is ignored. */
|
|
107
|
+
readonly VPhysicsUpdate: "VPhysicsUpdate";
|
|
108
|
+
/** `VPhysicsUpdate` post. Return is ignored. */
|
|
109
|
+
readonly VPhysicsUpdatePost: "VPhysicsUpdatePost";
|
|
110
|
+
/** `GroundEntChanged` post. Return is ignored. */
|
|
111
|
+
readonly GroundEntChangedPost: "GroundEntChangedPost";
|
|
112
|
+
/** `CanBeAutobalanced`. Return a boolean (not {@link HookResultValue}); last defined wins. */
|
|
113
|
+
readonly CanBeAutobalanced: "CanBeAutobalanced";
|
|
114
|
+
/**
|
|
115
|
+
* Post-apply damage (`DispatchTraceAttack` after the original). {@link DamageInfo} is read-only
|
|
116
|
+
* for effect; mutations are not written back. Return is ignored.
|
|
117
|
+
*/
|
|
118
|
+
readonly OnTakeDamagePost: "OnTakeDamagePost";
|
|
119
|
+
/**
|
|
120
|
+
* `OnTakeDamageAlive` pre. CS2 has no distinct function yet — {@link SDKHook} returns `false`.
|
|
121
|
+
*/
|
|
122
|
+
readonly OnTakeDamageAlive: "OnTakeDamageAlive";
|
|
123
|
+
/**
|
|
124
|
+
* `OnTakeDamageAlive` post. CS2 has no distinct function yet — {@link SDKHook} returns `false`.
|
|
125
|
+
*/
|
|
126
|
+
readonly OnTakeDamageAlivePost: "OnTakeDamageAlivePost";
|
|
127
|
+
/**
|
|
128
|
+
* `TraceAttack` pre ({@link TraceAttackInfo}). No distinct CS2 virtual yet — {@link SDKHook}
|
|
129
|
+
* returns `false` (OnTakeDamage remains the DTA mux).
|
|
130
|
+
*/
|
|
131
|
+
readonly TraceAttack: "TraceAttack";
|
|
132
|
+
/**
|
|
133
|
+
* `TraceAttack` post. No distinct CS2 virtual yet — {@link SDKHook} returns `false`.
|
|
134
|
+
*/
|
|
135
|
+
readonly TraceAttackPost: "TraceAttackPost";
|
|
136
|
+
/**
|
|
137
|
+
* `FireBulletsPost`. Wiki already documents this as often absent. {@link SDKHook} returns `false`
|
|
138
|
+
* until a live path is found.
|
|
139
|
+
*/
|
|
140
|
+
readonly FireBulletsPost: "FireBulletsPost";
|
|
141
|
+
/** Weapon reload pre. `Handled` / `Stop` skip the original virtual. Missing VP → `false`. */
|
|
142
|
+
readonly Reload: "Reload";
|
|
143
|
+
/** Weapon reload post. `(weapon, successful)`. No bool-return thunk yet — {@link SDKHook} returns `false`. */
|
|
144
|
+
readonly ReloadPost: "ReloadPost";
|
|
145
|
+
/** `WeaponCanUse` pre. Callback is `(entity, weapon)`. Missing ItemServices VP → `false`. */
|
|
146
|
+
readonly WeaponCanUse: "WeaponCanUse";
|
|
147
|
+
/** `WeaponCanUse` post. Return is ignored. Missing VP → `false`. */
|
|
148
|
+
readonly WeaponCanUsePost: "WeaponCanUsePost";
|
|
149
|
+
/** `WeaponCanSwitchTo` pre. Callback is `(entity, weapon)`. Missing VP → `false`. */
|
|
150
|
+
readonly WeaponCanSwitchTo: "WeaponCanSwitchTo";
|
|
151
|
+
/** `WeaponCanSwitchTo` post. Return is ignored. Missing VP → `false`. */
|
|
152
|
+
readonly WeaponCanSwitchToPost: "WeaponCanSwitchToPost";
|
|
153
|
+
/** `WeaponDrop` pre. Callback is `(entity, weapon)`. Missing VP → `false`. */
|
|
154
|
+
readonly WeaponDrop: "WeaponDrop";
|
|
155
|
+
/** `WeaponDrop` post. Return is ignored. Missing VP → `false`. */
|
|
156
|
+
readonly WeaponDropPost: "WeaponDropPost";
|
|
157
|
+
/** `WeaponEquip` pre. Callback is `(entity, weapon)`. Missing VP → `false`. */
|
|
158
|
+
readonly WeaponEquip: "WeaponEquip";
|
|
159
|
+
/** `WeaponEquip` post. Return is ignored. Missing VP → `false`. */
|
|
160
|
+
readonly WeaponEquipPost: "WeaponEquipPost";
|
|
161
|
+
/** `WeaponSwitch` pre. Callback is `(entity, weapon)`. Missing VP → `false`. */
|
|
162
|
+
readonly WeaponSwitch: "WeaponSwitch";
|
|
163
|
+
/** `WeaponSwitch` post. Return is ignored. Missing VP → `false`. */
|
|
164
|
+
readonly WeaponSwitchPost: "WeaponSwitchPost";
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Block-scoped view of a `TraceAttack` callback. Mutate {@link TraceAttackInfo.damage} on the
|
|
169
|
+
* pre-hook. Valid only during the handler.
|
|
170
|
+
*/
|
|
171
|
+
export interface TraceAttackInfo {
|
|
172
|
+
/** Incoming damage. Mutate in place on the pre-hook. */
|
|
173
|
+
damage: number;
|
|
174
|
+
/** Damage type bits. */
|
|
175
|
+
readonly damageType: number;
|
|
176
|
+
/** Ammo type index. */
|
|
177
|
+
readonly ammoType: number;
|
|
178
|
+
/** Hitbox index. */
|
|
179
|
+
readonly hitbox: number;
|
|
180
|
+
/** Hitgroup index. */
|
|
181
|
+
readonly hitgroup: number;
|
|
182
|
+
/** Attacking entity, books-gated. */
|
|
183
|
+
readonly attacker: EntityRef | null;
|
|
184
|
+
/** Inflicting entity, books-gated. */
|
|
185
|
+
readonly inflictor: EntityRef | null;
|
|
186
|
+
/** Victim entity, books-gated. */
|
|
187
|
+
readonly victim: EntityRef | null;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Hook `entity` for `type`. Auto-unhooked on entity destroy and plugin unload.
|
|
192
|
+
*
|
|
193
|
+
* Not load-window-only — call from `OnEntityCreated`, `OnPluginStart` (ents already live), or any
|
|
194
|
+
* time you hold a live {@link EntityRef}.
|
|
195
|
+
*
|
|
196
|
+
* `OnTakeDamage`: mutate `info.damage` in place. No return needed. Return `HookResult.Handled` to
|
|
197
|
+
* zero the hit; `HookResult.Stop` to also skip later hooks.
|
|
198
|
+
*
|
|
199
|
+
* @returns `true` if the hook was recorded. `false` on `null`/stale `entity` (does not throw).
|
|
200
|
+
* @example
|
|
201
|
+
* import { SDKHook, SDKHookType, Entity } from "@s2script/sdk";
|
|
202
|
+
* import type { EntityRef, DamageInfo } from "@s2script/sdk";
|
|
203
|
+
*
|
|
204
|
+
* export function OnPluginStart(): void {
|
|
205
|
+
* for (const pawn of Entity.findByClass("player")) {
|
|
206
|
+
* SDKHook(pawn, SDKHookType.OnTakeDamage, onTakeDamage);
|
|
207
|
+
* }
|
|
208
|
+
* }
|
|
209
|
+
* export function OnEntityCreated(entity: EntityRef | null, className: string): void {
|
|
210
|
+
* if (!entity || className !== "player") return;
|
|
211
|
+
* SDKHook(entity, SDKHookType.OnTakeDamage, onTakeDamage);
|
|
212
|
+
* }
|
|
213
|
+
* function onTakeDamage(info: DamageInfo) {
|
|
214
|
+
* info.damage /= 2;
|
|
215
|
+
* }
|
|
216
|
+
*/
|
|
217
|
+
export declare function SDKHook(
|
|
218
|
+
entity: EntityRef | null,
|
|
219
|
+
type: "OnTakeDamage",
|
|
220
|
+
callback: (info: DamageInfo) => HookResultValue | void,
|
|
221
|
+
): boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Post-apply damage. {@link DamageInfo} is a read of the live info after the original ran.
|
|
224
|
+
* Return is ignored; Handled does not zero the hit (that is the pre-hook).
|
|
225
|
+
*/
|
|
226
|
+
export declare function SDKHook(
|
|
227
|
+
entity: EntityRef | null,
|
|
228
|
+
type: "OnTakeDamagePost",
|
|
229
|
+
callback: (info: DamageInfo) => void,
|
|
230
|
+
): boolean;
|
|
231
|
+
/**
|
|
232
|
+
* `OnTakeDamageAlive` pre. No CS2 backing yet — always returns `false`.
|
|
233
|
+
*/
|
|
234
|
+
export declare function SDKHook(
|
|
235
|
+
entity: EntityRef | null,
|
|
236
|
+
type: "OnTakeDamageAlive",
|
|
237
|
+
callback: (info: DamageInfo) => HookResultValue | void,
|
|
238
|
+
): boolean;
|
|
239
|
+
/**
|
|
240
|
+
* `OnTakeDamageAlive` post. No CS2 backing yet — always returns `false`.
|
|
241
|
+
*/
|
|
242
|
+
export declare function SDKHook(
|
|
243
|
+
entity: EntityRef | null,
|
|
244
|
+
type: "OnTakeDamageAlivePost",
|
|
245
|
+
callback: (info: DamageInfo) => void,
|
|
246
|
+
): boolean;
|
|
247
|
+
/**
|
|
248
|
+
* `TraceAttack` pre. No distinct CS2 virtual yet — always returns `false`.
|
|
249
|
+
*/
|
|
250
|
+
export declare function SDKHook(
|
|
251
|
+
entity: EntityRef | null,
|
|
252
|
+
type: "TraceAttack",
|
|
253
|
+
callback: (info: TraceAttackInfo) => HookResultValue | void,
|
|
254
|
+
): boolean;
|
|
255
|
+
/**
|
|
256
|
+
* `TraceAttack` post. No distinct CS2 virtual yet — always returns `false`.
|
|
257
|
+
*/
|
|
258
|
+
export declare function SDKHook(
|
|
259
|
+
entity: EntityRef | null,
|
|
260
|
+
type: "TraceAttackPost",
|
|
261
|
+
callback: (info: TraceAttackInfo) => void,
|
|
262
|
+
): boolean;
|
|
263
|
+
/**
|
|
264
|
+
* `FireBulletsPost`. No CS2 backing yet — always returns `false`.
|
|
265
|
+
*/
|
|
266
|
+
export declare function SDKHook(
|
|
267
|
+
entity: EntityRef | null,
|
|
268
|
+
type: "FireBulletsPost",
|
|
269
|
+
callback: FireBulletsPostCallback,
|
|
270
|
+
): boolean;
|
|
271
|
+
/**
|
|
272
|
+
* Touch-family pre-hook. Callback is `(entity, other)`. Omit return = Continue.
|
|
273
|
+
* `Handled` / `Stop` SUPERCEDE the original virtual (`Stop` also skips later callbacks).
|
|
274
|
+
*/
|
|
275
|
+
export declare function SDKHook(
|
|
276
|
+
entity: EntityRef | null,
|
|
277
|
+
type: "StartTouch" | "Touch" | "EndTouch" | "Blocked",
|
|
278
|
+
callback: TouchCallback,
|
|
279
|
+
): boolean;
|
|
280
|
+
/**
|
|
281
|
+
* Touch-family post-hook. Return is ignored; the original virtual already ran.
|
|
282
|
+
*/
|
|
283
|
+
export declare function SDKHook(
|
|
284
|
+
entity: EntityRef | null,
|
|
285
|
+
type: "StartTouchPost" | "TouchPost" | "EndTouchPost" | "BlockedPost",
|
|
286
|
+
callback: TouchPostCallback,
|
|
287
|
+
): boolean;
|
|
288
|
+
/**
|
|
289
|
+
* Spawn / Think pre-hook. Callback is `(entity)`. Omit return = Continue.
|
|
290
|
+
* `Handled` / `Stop` SUPERCEDE the original virtual (`Stop` also skips later callbacks).
|
|
291
|
+
*/
|
|
292
|
+
export declare function SDKHook(
|
|
293
|
+
entity: EntityRef | null,
|
|
294
|
+
type: "Spawn" | "Think" | "Reload",
|
|
295
|
+
callback: ThisCallback,
|
|
296
|
+
): boolean;
|
|
297
|
+
/**
|
|
298
|
+
* Void this-only hooks (Posts, PreThink/PostThink, VPhysicsUpdate, GroundEntChangedPost).
|
|
299
|
+
* Return is ignored.
|
|
300
|
+
*/
|
|
301
|
+
export declare function SDKHook(
|
|
302
|
+
entity: EntityRef | null,
|
|
303
|
+
type:
|
|
304
|
+
| "SpawnPost"
|
|
305
|
+
| "ThinkPost"
|
|
306
|
+
| "PreThink"
|
|
307
|
+
| "PreThinkPost"
|
|
308
|
+
| "PostThink"
|
|
309
|
+
| "PostThinkPost"
|
|
310
|
+
| "VPhysicsUpdate"
|
|
311
|
+
| "VPhysicsUpdatePost"
|
|
312
|
+
| "GroundEntChangedPost",
|
|
313
|
+
callback: ThisVoidCallback,
|
|
314
|
+
): boolean;
|
|
315
|
+
/**
|
|
316
|
+
* `Use` pre-hook. `Handled` / `Stop` SUPERCEDE the original virtual.
|
|
317
|
+
*/
|
|
318
|
+
export declare function SDKHook(
|
|
319
|
+
entity: EntityRef | null,
|
|
320
|
+
type: "Use",
|
|
321
|
+
callback: UseCallback,
|
|
322
|
+
): boolean;
|
|
323
|
+
/**
|
|
324
|
+
* `Use` post-hook. Return is ignored.
|
|
325
|
+
*/
|
|
326
|
+
export declare function SDKHook(
|
|
327
|
+
entity: EntityRef | null,
|
|
328
|
+
type: "UsePost",
|
|
329
|
+
callback: UsePostCallback,
|
|
330
|
+
): boolean;
|
|
331
|
+
/**
|
|
332
|
+
* `GetMaxHealth`. Mutate `info.maxHealth` in place. `Handled` / `Stop` SUPERCEDE with the new value.
|
|
333
|
+
*/
|
|
334
|
+
export declare function SDKHook(
|
|
335
|
+
entity: EntityRef | null,
|
|
336
|
+
type: "GetMaxHealth",
|
|
337
|
+
callback: (info: { maxHealth: number }) => HookResultValue | void,
|
|
338
|
+
): boolean;
|
|
339
|
+
/**
|
|
340
|
+
* `ShouldCollide`. Return a boolean (not HookResult); last defined return wins, default original.
|
|
341
|
+
*/
|
|
342
|
+
export declare function SDKHook(
|
|
343
|
+
entity: EntityRef | null,
|
|
344
|
+
type: "ShouldCollide",
|
|
345
|
+
callback: (
|
|
346
|
+
entity: EntityRef,
|
|
347
|
+
collisionGroup: number,
|
|
348
|
+
contentsMask: number,
|
|
349
|
+
originalResult: boolean,
|
|
350
|
+
) => boolean,
|
|
351
|
+
): boolean;
|
|
352
|
+
/**
|
|
353
|
+
* `CanBeAutobalanced`. Return a boolean (not HookResult); last defined return wins, default original.
|
|
354
|
+
* Callback is skipped when the hooked entity has no {@link Client} — never a raw slot `0`.
|
|
355
|
+
*/
|
|
356
|
+
export declare function SDKHook(
|
|
357
|
+
entity: EntityRef | null,
|
|
358
|
+
type: "CanBeAutobalanced",
|
|
359
|
+
callback: (client: Client, origRet: boolean) => boolean,
|
|
360
|
+
): boolean;
|
|
361
|
+
/**
|
|
362
|
+
* SetTransmit. Callback is `(entity, client)`. Omit return = Continue.
|
|
363
|
+
* `Handled` / `Stop` hide this entity from this viewer (AND-merge with `Transmit.setVisibleTo`;
|
|
364
|
+
* cannot un-hide a native mask clear). `Stop` also skips later SetTransmit callbacks on that pair.
|
|
365
|
+
*/
|
|
366
|
+
export declare function SDKHook(
|
|
367
|
+
entity: EntityRef | null,
|
|
368
|
+
type: "SetTransmit",
|
|
369
|
+
callback: (entity: EntityRef, client: Client) => HookResultValue | void,
|
|
370
|
+
): boolean;
|
|
371
|
+
/**
|
|
372
|
+
* Weapon-family pre-hook. Callback is `(entity, weapon)`. Omit return = Continue.
|
|
373
|
+
* `Handled` / `Stop` SUPERCEDE the original virtual. Missing ItemServices VP → `false`.
|
|
374
|
+
*/
|
|
375
|
+
export declare function SDKHook(
|
|
376
|
+
entity: EntityRef | null,
|
|
377
|
+
type: "WeaponCanUse" | "WeaponCanSwitchTo" | "WeaponDrop" | "WeaponEquip" | "WeaponSwitch",
|
|
378
|
+
callback: WeaponCallback,
|
|
379
|
+
): boolean;
|
|
380
|
+
/**
|
|
381
|
+
* Weapon-family post-hook. Return is ignored. Missing VP → `false`.
|
|
382
|
+
*/
|
|
383
|
+
export declare function SDKHook(
|
|
384
|
+
entity: EntityRef | null,
|
|
385
|
+
type:
|
|
386
|
+
| "WeaponCanUsePost"
|
|
387
|
+
| "WeaponCanSwitchToPost"
|
|
388
|
+
| "WeaponDropPost"
|
|
389
|
+
| "WeaponEquipPost"
|
|
390
|
+
| "WeaponSwitchPost",
|
|
391
|
+
callback: WeaponPostCallback,
|
|
392
|
+
): boolean;
|
|
393
|
+
/**
|
|
394
|
+
* `ReloadPost`. Callback is `(weapon, successful)`. No CS2 backing yet — always returns `false`.
|
|
395
|
+
*/
|
|
396
|
+
export declare function SDKHook(
|
|
397
|
+
entity: EntityRef | null,
|
|
398
|
+
type: "ReloadPost",
|
|
399
|
+
callback: ReloadPostCallback,
|
|
400
|
+
): boolean;
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Remove one matching `(entity, type, callback)` hook. Callback identity is the function reference.
|
|
404
|
+
* @returns `true` if an entry was removed.
|
|
405
|
+
*/
|
|
406
|
+
export declare function SDKUnhook(
|
|
407
|
+
entity: EntityRef | null,
|
|
408
|
+
type: "OnTakeDamage",
|
|
409
|
+
callback: (info: DamageInfo) => HookResultValue | void,
|
|
410
|
+
): boolean;
|
|
411
|
+
/** Remove an `OnTakeDamagePost` hook. */
|
|
412
|
+
export declare function SDKUnhook(
|
|
413
|
+
entity: EntityRef | null,
|
|
414
|
+
type: "OnTakeDamagePost",
|
|
415
|
+
callback: (info: DamageInfo) => void,
|
|
416
|
+
): boolean;
|
|
417
|
+
/** Remove an `OnTakeDamageAlive` hook. */
|
|
418
|
+
export declare function SDKUnhook(
|
|
419
|
+
entity: EntityRef | null,
|
|
420
|
+
type: "OnTakeDamageAlive",
|
|
421
|
+
callback: (info: DamageInfo) => HookResultValue | void,
|
|
422
|
+
): boolean;
|
|
423
|
+
/** Remove an `OnTakeDamageAlivePost` hook. */
|
|
424
|
+
export declare function SDKUnhook(
|
|
425
|
+
entity: EntityRef | null,
|
|
426
|
+
type: "OnTakeDamageAlivePost",
|
|
427
|
+
callback: (info: DamageInfo) => void,
|
|
428
|
+
): boolean;
|
|
429
|
+
/** Remove a `TraceAttack` hook. */
|
|
430
|
+
export declare function SDKUnhook(
|
|
431
|
+
entity: EntityRef | null,
|
|
432
|
+
type: "TraceAttack",
|
|
433
|
+
callback: (info: TraceAttackInfo) => HookResultValue | void,
|
|
434
|
+
): boolean;
|
|
435
|
+
/** Remove a `TraceAttackPost` hook. */
|
|
436
|
+
export declare function SDKUnhook(
|
|
437
|
+
entity: EntityRef | null,
|
|
438
|
+
type: "TraceAttackPost",
|
|
439
|
+
callback: (info: TraceAttackInfo) => void,
|
|
440
|
+
): boolean;
|
|
441
|
+
/** Remove a `FireBulletsPost` hook. */
|
|
442
|
+
export declare function SDKUnhook(
|
|
443
|
+
entity: EntityRef | null,
|
|
444
|
+
type: "FireBulletsPost",
|
|
445
|
+
callback: FireBulletsPostCallback,
|
|
446
|
+
): boolean;
|
|
447
|
+
/** Remove a Touch-family pre-hook. */
|
|
448
|
+
export declare function SDKUnhook(
|
|
449
|
+
entity: EntityRef | null,
|
|
450
|
+
type: "StartTouch" | "Touch" | "EndTouch" | "Blocked",
|
|
451
|
+
callback: TouchCallback,
|
|
452
|
+
): boolean;
|
|
453
|
+
/** Remove a Touch-family post-hook. */
|
|
454
|
+
export declare function SDKUnhook(
|
|
455
|
+
entity: EntityRef | null,
|
|
456
|
+
type: "StartTouchPost" | "TouchPost" | "EndTouchPost" | "BlockedPost",
|
|
457
|
+
callback: TouchPostCallback,
|
|
458
|
+
): boolean;
|
|
459
|
+
/** Remove a Spawn / Think pre-hook. */
|
|
460
|
+
export declare function SDKUnhook(
|
|
461
|
+
entity: EntityRef | null,
|
|
462
|
+
type: "Spawn" | "Think" | "Reload",
|
|
463
|
+
callback: ThisCallback,
|
|
464
|
+
): boolean;
|
|
465
|
+
/** Remove a void this-only hook. */
|
|
466
|
+
export declare function SDKUnhook(
|
|
467
|
+
entity: EntityRef | null,
|
|
468
|
+
type:
|
|
469
|
+
| "SpawnPost"
|
|
470
|
+
| "ThinkPost"
|
|
471
|
+
| "PreThink"
|
|
472
|
+
| "PreThinkPost"
|
|
473
|
+
| "PostThink"
|
|
474
|
+
| "PostThinkPost"
|
|
475
|
+
| "VPhysicsUpdate"
|
|
476
|
+
| "VPhysicsUpdatePost"
|
|
477
|
+
| "GroundEntChangedPost",
|
|
478
|
+
callback: ThisVoidCallback,
|
|
479
|
+
): boolean;
|
|
480
|
+
/** Remove a `Use` pre-hook. */
|
|
481
|
+
export declare function SDKUnhook(
|
|
482
|
+
entity: EntityRef | null,
|
|
483
|
+
type: "Use",
|
|
484
|
+
callback: UseCallback,
|
|
485
|
+
): boolean;
|
|
486
|
+
/** Remove a `Use` post-hook. */
|
|
487
|
+
export declare function SDKUnhook(
|
|
488
|
+
entity: EntityRef | null,
|
|
489
|
+
type: "UsePost",
|
|
490
|
+
callback: UsePostCallback,
|
|
491
|
+
): boolean;
|
|
492
|
+
/** Remove a `GetMaxHealth` hook. */
|
|
493
|
+
export declare function SDKUnhook(
|
|
494
|
+
entity: EntityRef | null,
|
|
495
|
+
type: "GetMaxHealth",
|
|
496
|
+
callback: (info: { maxHealth: number }) => HookResultValue | void,
|
|
497
|
+
): boolean;
|
|
498
|
+
/** Remove a `ShouldCollide` hook. */
|
|
499
|
+
export declare function SDKUnhook(
|
|
500
|
+
entity: EntityRef | null,
|
|
501
|
+
type: "ShouldCollide",
|
|
502
|
+
callback: (
|
|
503
|
+
entity: EntityRef,
|
|
504
|
+
collisionGroup: number,
|
|
505
|
+
contentsMask: number,
|
|
506
|
+
originalResult: boolean,
|
|
507
|
+
) => boolean,
|
|
508
|
+
): boolean;
|
|
509
|
+
/** Remove a `CanBeAutobalanced` hook. */
|
|
510
|
+
export declare function SDKUnhook(
|
|
511
|
+
entity: EntityRef | null,
|
|
512
|
+
type: "CanBeAutobalanced",
|
|
513
|
+
callback: (client: Client, origRet: boolean) => boolean,
|
|
514
|
+
): boolean;
|
|
515
|
+
/** Remove a SetTransmit hook. */
|
|
516
|
+
export declare function SDKUnhook(
|
|
517
|
+
entity: EntityRef | null,
|
|
518
|
+
type: "SetTransmit",
|
|
519
|
+
callback: (entity: EntityRef, client: Client) => HookResultValue | void,
|
|
520
|
+
): boolean;
|
|
521
|
+
/** Remove a Weapon-family pre-hook. */
|
|
522
|
+
export declare function SDKUnhook(
|
|
523
|
+
entity: EntityRef | null,
|
|
524
|
+
type: "WeaponCanUse" | "WeaponCanSwitchTo" | "WeaponDrop" | "WeaponEquip" | "WeaponSwitch",
|
|
525
|
+
callback: WeaponCallback,
|
|
526
|
+
): boolean;
|
|
527
|
+
/** Remove a Weapon-family post-hook. */
|
|
528
|
+
export declare function SDKUnhook(
|
|
529
|
+
entity: EntityRef | null,
|
|
530
|
+
type:
|
|
531
|
+
| "WeaponCanUsePost"
|
|
532
|
+
| "WeaponCanSwitchToPost"
|
|
533
|
+
| "WeaponDropPost"
|
|
534
|
+
| "WeaponEquipPost"
|
|
535
|
+
| "WeaponSwitchPost",
|
|
536
|
+
callback: WeaponPostCallback,
|
|
537
|
+
): boolean;
|
|
538
|
+
/** Remove a `ReloadPost` hook. */
|
|
539
|
+
export declare function SDKUnhook(
|
|
540
|
+
entity: EntityRef | null,
|
|
541
|
+
type: "ReloadPost",
|
|
542
|
+
callback: ReloadPostCallback,
|
|
543
|
+
): boolean;
|
package/server.d.ts
CHANGED
|
@@ -15,16 +15,16 @@ export declare const Server: {
|
|
|
15
15
|
/** A cvar's current value as a string. `""` if the cvar doesn't exist (or an unsupported type → `"<type>"`). */
|
|
16
16
|
getCvar(name: string): string;
|
|
17
17
|
/**
|
|
18
|
-
* Set a cvar
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* Set a cvar through `ICvar` now (SourceMod `SetConVarString`). Not a console command: `;` in
|
|
19
|
+
* `value` is data, not a second command. `getCvar` and `onCvarChange` see the new value before
|
|
20
|
+
* this returns. `false` if the cvar does not exist or the string cannot become that type.
|
|
21
21
|
*/
|
|
22
|
-
setCvar(name: string, value: string):
|
|
22
|
+
setCvar(name: string, value: string): boolean;
|
|
23
23
|
/**
|
|
24
24
|
* Register a plugin-owned ConVar (CSSharp FakeConVar / SM CreateConVar parity). Idempotent —
|
|
25
25
|
* re-registering an existing name is a no-op success, and the cvar + its value persist across
|
|
26
26
|
* plugin reloads (SourceMod parity). The shim adds FCVAR_RELEASE (customer-visible); `flags`
|
|
27
|
-
* are additive raw FCVAR bits. Read the value with `getCvar`; set it with `setCvar
|
|
27
|
+
* are additive raw FCVAR bits. Read the value with `getCvar`; set it with `setCvar`.
|
|
28
28
|
* `min`/`max` apply to numeric types only.
|
|
29
29
|
*/
|
|
30
30
|
registerCvar(name: string, opts: {
|
package/translations.d.ts
CHANGED
|
@@ -13,13 +13,15 @@ export type Phrases = Record<string, string>;
|
|
|
13
13
|
* for it automatically, the same rule SourceMod's `LoadTranslations` enforces:
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* import { command, translations } from "@s2script/sdk";
|
|
17
|
+
* import { ADMFLAG } from "@s2script/sdk";
|
|
18
|
+
* export function OnPluginStart(): void {
|
|
19
|
+
* translations.load("basecomm", "common");
|
|
20
|
+
* command.admin("sm_gag", ADMFLAG.CHAT, (cmd) => {
|
|
19
21
|
* cmd.replyT("Usage Gag"); // key-checked
|
|
20
22
|
* Chat.toSlot(p.slot, Translations.translate(p.slot, "Gagged Player", n));
|
|
21
23
|
* });
|
|
22
|
-
* }
|
|
24
|
+
* }
|
|
23
25
|
*
|
|
24
26
|
* Keys are checked against the files that plugin loads — see `@s2script/sdk/phrases`.
|
|
25
27
|
*/
|
package/unsafe.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @s2script/sdk/unsafe — plugin-declared engine calls. NO runtime code: the
|
|
3
|
-
* implementation at load (`__s2pkg_unsafe`).
|
|
2
|
+
* @s2script/sdk/unsafe — plugin-declared engine calls and inbound hooks. NO runtime code: the
|
|
3
|
+
* engine injects the implementation at load (`__s2pkg_unsafe`).
|
|
4
4
|
*
|
|
5
|
-
* UNSAFE by design. A declared call reaches a real engine function
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* UNSAFE by design. A declared call reaches a real engine function; a declared hook patches
|
|
6
|
+
* that function's prologue. The framework validates every descriptor at load and degrades a
|
|
7
|
+
* failure to `null`, but it cannot prove your signature or vtable index names the function you
|
|
8
|
+
* meant. Calls require manifest `permissions: ["engine:calls"]`; hooks require the separate
|
|
9
|
+
* `"engine:hooks"` permission. Both also need an operator allow-list entry
|
|
10
|
+
* (see docs/superpowers/specs/2026-07-24-plugin-gamedata-design.md §6 and ARCHITECTURE.md §2.0.7).
|
|
9
11
|
*/
|
|
10
12
|
|
|
11
13
|
/**
|
|
@@ -15,13 +17,21 @@
|
|
|
15
17
|
export interface EngineCalls {}
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
|
-
*
|
|
20
|
+
* The inbound hooks this plugin declares. The base interface is EMPTY — `s2s build` generates
|
|
21
|
+
* `.s2script/hooks.d.ts`, which augments this from your gamedata's `hooks` section.
|
|
22
|
+
*/
|
|
23
|
+
export interface EngineHooks {}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Plugin-declared engine calls and inbound hooks, resolved from this plugin's own gamedata.
|
|
19
27
|
*
|
|
20
28
|
* @example
|
|
21
29
|
* import { Engine } from "@s2script/sdk/unsafe";
|
|
22
30
|
* // Resolve ONCE at load — null means the descriptor failed a load-time gate.
|
|
23
31
|
* const ignite = Engine.call("ignite");
|
|
24
32
|
* if (!ignite) console.log(`unavailable: ${Engine.status("ignite")}`);
|
|
33
|
+
* const onFoo = Engine.hook("onFoo");
|
|
34
|
+
* if (onFoo) onFoo((view) => { view.reason = 0; });
|
|
25
35
|
*/
|
|
26
36
|
export declare const Engine: {
|
|
27
37
|
/**
|
|
@@ -30,6 +40,16 @@ export declare const Engine: {
|
|
|
30
40
|
* operator-allow-listed). Guard once at load; the returned function is a plain callable.
|
|
31
41
|
*/
|
|
32
42
|
call<K extends keyof EngineCalls>(name: K): EngineCalls[K] | null;
|
|
33
|
-
/** Why a descriptor is unavailable; `"available"` when it resolved. For diagnostics/operator reports. */
|
|
43
|
+
/** Why a call descriptor is unavailable; `"available"` when it resolved. For diagnostics/operator reports. */
|
|
34
44
|
status(name: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* The declared hook's subscribe function, or `null` when its descriptor failed a load-time
|
|
47
|
+
* gate (same class of reasons as {@link Engine.call}, plus a missing `validate` or an unknown
|
|
48
|
+
* thunk shape). Guard once at load; the returned function records the handler and lazily
|
|
49
|
+
* installs the detour. The owner is always the calling plugin — you cannot subscribe to
|
|
50
|
+
* another plugin's hook through this factory (game-package hooks hang off `ctx.*`).
|
|
51
|
+
*/
|
|
52
|
+
hook<K extends keyof EngineHooks>(name: K): EngineHooks[K] | null;
|
|
53
|
+
/** Why a hook descriptor is unavailable; `"available"` when it resolved. */
|
|
54
|
+
hookStatus(name: string): string;
|
|
35
55
|
};
|