@nodemod/core 1.0.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.
Files changed (60) hide show
  1. package/README.md +60 -0
  2. package/dist/core/cmd.d.ts +148 -0
  3. package/dist/core/cmd.d.ts.map +1 -0
  4. package/dist/core/cmd.js +177 -0
  5. package/dist/core/cmd.js.map +1 -0
  6. package/dist/core/menu.d.ts +300 -0
  7. package/dist/core/menu.d.ts.map +1 -0
  8. package/dist/core/menu.js +449 -0
  9. package/dist/core/menu.js.map +1 -0
  10. package/dist/core/msg.d.ts +300 -0
  11. package/dist/core/msg.d.ts.map +1 -0
  12. package/dist/core/msg.js +374 -0
  13. package/dist/core/msg.js.map +1 -0
  14. package/dist/core/resource.d.ts +137 -0
  15. package/dist/core/resource.d.ts.map +1 -0
  16. package/dist/core/resource.js +171 -0
  17. package/dist/core/resource.js.map +1 -0
  18. package/dist/core/sound.d.ts +262 -0
  19. package/dist/core/sound.d.ts.map +1 -0
  20. package/dist/core/sound.js +300 -0
  21. package/dist/core/sound.js.map +1 -0
  22. package/dist/enhanced/entity.d.ts +263 -0
  23. package/dist/enhanced/entity.d.ts.map +1 -0
  24. package/dist/enhanced/entity.js +447 -0
  25. package/dist/enhanced/entity.js.map +1 -0
  26. package/dist/enhanced/events.d.ts +257 -0
  27. package/dist/enhanced/events.d.ts.map +1 -0
  28. package/dist/enhanced/events.js +350 -0
  29. package/dist/enhanced/events.js.map +1 -0
  30. package/dist/enhanced/player.d.ts +272 -0
  31. package/dist/enhanced/player.d.ts.map +1 -0
  32. package/dist/enhanced/player.js +389 -0
  33. package/dist/enhanced/player.js.map +1 -0
  34. package/dist/enhanced/trace.d.ts +198 -0
  35. package/dist/enhanced/trace.d.ts.map +1 -0
  36. package/dist/enhanced/trace.js +311 -0
  37. package/dist/enhanced/trace.js.map +1 -0
  38. package/dist/index.d.ts +88 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +120 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/native/cvar.d.ts +49 -0
  43. package/dist/native/cvar.d.ts.map +1 -0
  44. package/dist/native/cvar.js +169 -0
  45. package/dist/native/cvar.js.map +1 -0
  46. package/dist/native/file.d.ts +221 -0
  47. package/dist/native/file.d.ts.map +1 -0
  48. package/dist/native/file.js +353 -0
  49. package/dist/native/file.js.map +1 -0
  50. package/dist/types/dll.d.ts +109 -0
  51. package/dist/types/engine.d.ts +319 -0
  52. package/dist/types/enums.d.ts +434 -0
  53. package/dist/types/events.d.ts +2432 -0
  54. package/dist/types/index.d.ts +38 -0
  55. package/dist/types/structures.d.ts +1144 -0
  56. package/dist/utils/util.d.ts +202 -0
  57. package/dist/utils/util.d.ts.map +1 -0
  58. package/dist/utils/util.js +318 -0
  59. package/dist/utils/util.js.map +1 -0
  60. package/package.json +167 -0
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Internal event listener metadata for enhanced event management.
3
+ */
4
+ export interface EventListener<T extends keyof nodemod.EventCallbacks> {
5
+ /** The wrapped handler function */
6
+ handler: nodemod.EventCallbacks[T];
7
+ /** The original handler function */
8
+ original: nodemod.EventCallbacks[T];
9
+ /** Priority level for execution order */
10
+ priority: number;
11
+ }
12
+ /**
13
+ * Options for configuring event listeners.
14
+ */
15
+ export interface EventOptions {
16
+ /** Execute the handler only once, then automatically remove it */
17
+ once?: boolean;
18
+ /** Priority level (higher numbers execute first) */
19
+ priority?: number;
20
+ }
21
+ /**
22
+ * Enhanced player information for connection events.
23
+ */
24
+ export interface PlayerInfo {
25
+ /** Player entity */
26
+ entity: nodemod.Entity;
27
+ /** Player entity index */
28
+ id: number;
29
+ /** Player display name */
30
+ name: string;
31
+ /** Player IP address (if available) */
32
+ address?: string;
33
+ /** Player Steam ID */
34
+ steamId: string;
35
+ /** Player user ID (if available) */
36
+ userId?: number;
37
+ }
38
+ /**
39
+ * Enhanced spawn information for entity/player spawn events.
40
+ */
41
+ export interface SpawnInfo {
42
+ /** Spawned entity */
43
+ entity: nodemod.Entity;
44
+ /** Entity index */
45
+ id: number;
46
+ /** Entity name (for players) */
47
+ name?: string;
48
+ /** Entity class name */
49
+ className: string;
50
+ }
51
+ /**
52
+ * Frame timing and server state information.
53
+ */
54
+ export interface FrameInfo {
55
+ /** Current server time */
56
+ time: number;
57
+ /** Current map name */
58
+ mapname: string;
59
+ /** Number of connected players */
60
+ playerCount: number;
61
+ }
62
+ /** Type alias for event handler functions */
63
+ export type EventHandler<T extends keyof nodemod.EventCallbacks = keyof nodemod.EventCallbacks> = nodemod.EventCallbacks[T];
64
+ /** Type alias for event filtering predicates */
65
+ export type EventPredicate<T extends keyof nodemod.EventCallbacks = keyof nodemod.EventCallbacks> = (...args: Parameters<nodemod.EventCallbacks[T]>) => boolean;
66
+ /** Type alias for event transformation functions */
67
+ export type EventTransformer<T extends keyof nodemod.EventCallbacks = keyof nodemod.EventCallbacks> = (...args: Parameters<nodemod.EventCallbacks[T]>) => any;
68
+ /**
69
+ * Enhanced event system providing advanced event handling capabilities on top of nodemod's native events.
70
+ * Features include priority-based execution, one-time listeners, event filtering, throttling, and debouncing.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * // Basic event listening
75
+ * nodemodCore.events.on('dllClientConnect', (entity, name) => {
76
+ * console.log(`${name} connected`);
77
+ * });
78
+ *
79
+ * // One-time event listener
80
+ * nodemodCore.events.once('dllSpawn', (entity) => {
81
+ * console.log('First spawn event received');
82
+ * });
83
+ *
84
+ * // Priority-based event handling
85
+ * nodemodCore.events.on('dllClientCommand', handleCommand, { priority: 10 });
86
+ * nodemodCore.events.on('dllClientCommand', logCommand, { priority: 1 });
87
+ *
88
+ * // Event filtering
89
+ * nodemodCore.events.filter('dllClientConnect',
90
+ * (entity, name) => name.startsWith('Admin'),
91
+ * (entity, name) => console.log(`Admin ${name} connected`)
92
+ * );
93
+ *
94
+ * // Throttled events (max once per second)
95
+ * nodemodCore.events.throttle('dllStartFrame', frameHandler, 1000);
96
+ * ```
97
+ */
98
+ export default class NodemodEvents {
99
+ /** Map of active event listeners organized by event name */
100
+ private eventListeners;
101
+ /**
102
+ * Creates a new NodemodEvents instance and initializes enhanced event handlers.
103
+ */
104
+ constructor();
105
+ /**
106
+ * Adds an event listener with enhanced options like priority and one-time execution.
107
+ *
108
+ * @param eventName - Name of the event to listen for
109
+ * @param handler - Function to execute when event occurs
110
+ * @param options - Additional options for the listener
111
+ * @returns This instance for method chaining
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * // Basic event listener
116
+ * nodemodCore.events.on('dllClientConnect', (entity, name) => {
117
+ * console.log(`${name} joined the server`);
118
+ * });
119
+ *
120
+ * // High-priority listener (executes first)
121
+ * nodemodCore.events.on('dllClientCommand', (entity, command) => {
122
+ * console.log('Processing command:', command);
123
+ * }, { priority: 100 });
124
+ *
125
+ * // One-time listener
126
+ * nodemodCore.events.on('dllSpawn', (entity) => {
127
+ * console.log('First entity spawned');
128
+ * }, { once: true });
129
+ * ```
130
+ */
131
+ on<T extends keyof nodemod.EventCallbacks>(eventName: T, handler: nodemod.EventCallbacks[T], options?: EventOptions): this;
132
+ off<T extends keyof nodemod.EventCallbacks>(eventName: T, handler: nodemod.EventCallbacks[T]): this;
133
+ /**
134
+ * Adds a one-time event listener that automatically removes itself after first execution.
135
+ *
136
+ * @param eventName - Name of the event to listen for
137
+ * @param handler - Function to execute when event occurs
138
+ * @returns This instance for method chaining
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * // Listen for first player connection only
143
+ * nodemodCore.events.once('dllClientConnect', (entity, name) => {
144
+ * console.log(`First player ${name} connected - starting game logic`);
145
+ * });
146
+ *
147
+ * // Wait for map change
148
+ * nodemodCore.events.once('dllSpawn', () => {
149
+ * console.log('Map fully loaded');
150
+ * });
151
+ * ```
152
+ */
153
+ once<T extends keyof nodemod.EventCallbacks>(eventName: T, handler: nodemod.EventCallbacks[T]): this;
154
+ clearListeners(eventName?: keyof nodemod.EventCallbacks): this;
155
+ getListeners<T extends keyof nodemod.EventCallbacks>(eventName: T): EventListener<T>[];
156
+ private initializeEvents;
157
+ /**
158
+ * Waits for a specific event to occur and returns its parameters as a promise.
159
+ * Useful for async/await patterns with events.
160
+ *
161
+ * @param eventName - Name of the event to wait for
162
+ * @param timeout - Timeout in milliseconds (default: 10000)
163
+ * @returns Promise that resolves with event parameters or rejects on timeout
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * // Wait for player connection
168
+ * try {
169
+ * const [entity, name] = await nodemodCore.events.waitFor('dllClientConnect', 30000);
170
+ * console.log(`Player ${name} connected within 30 seconds`);
171
+ * } catch (error) {
172
+ * console.log('No player connected within timeout');
173
+ * }
174
+ *
175
+ * // Wait for entity spawn with shorter timeout
176
+ * const [spawnedEntity] = await nodemodCore.events.waitFor('dllSpawn', 5000);
177
+ * ```
178
+ */
179
+ waitFor<T extends keyof nodemod.EventCallbacks>(eventName: T, timeout?: number): Promise<Parameters<nodemod.EventCallbacks[T]>>;
180
+ /**
181
+ * Adds an event listener that only executes when a predicate condition is met.
182
+ *
183
+ * @param eventName - Name of the event to listen for
184
+ * @param predicate - Function that returns true if the handler should execute
185
+ * @param handler - Function to execute when event occurs and predicate is true
186
+ * @returns This instance for method chaining
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * // Only handle commands from admins
191
+ * nodemodCore.events.filter('dllClientCommand',
192
+ * (entity, command) => isAdmin(entity),
193
+ * (entity, command) => handleAdminCommand(entity, command)
194
+ * );
195
+ *
196
+ * // Only handle player connections with specific names
197
+ * nodemodCore.events.filter('dllClientConnect',
198
+ * (entity, name) => name.startsWith('VIP_'),
199
+ * (entity, name) => grantVipAccess(entity)
200
+ * );
201
+ * ```
202
+ */
203
+ filter<T extends keyof nodemod.EventCallbacks>(eventName: T, predicate: EventPredicate<T>, handler: nodemod.EventCallbacks[T]): this;
204
+ map<T extends keyof nodemod.EventCallbacks>(eventName: T, transformer: EventTransformer<T>, newEventName?: keyof nodemod.EventCallbacks): this;
205
+ /**
206
+ * Adds a throttled event listener that limits execution to once per specified interval.
207
+ * Useful for performance optimization with high-frequency events.
208
+ *
209
+ * @param eventName - Name of the event to listen for
210
+ * @param handler - Function to execute when event occurs
211
+ * @param delay - Minimum interval between executions in milliseconds (default: 1000)
212
+ * @returns This instance for method chaining
213
+ *
214
+ * @example
215
+ * ```typescript
216
+ * // Throttle frame events to once per second
217
+ * nodemodCore.events.throttle('dllStartFrame', () => {
218
+ * console.log('Frame update (max once per second)');
219
+ * }, 1000);
220
+ *
221
+ * // Throttle player movement tracking
222
+ * nodemodCore.events.throttle('dllClientCommand', (entity, command) => {
223
+ * if (command.startsWith('+move')) {
224
+ * updatePlayerPosition(entity);
225
+ * }
226
+ * }, 500); // Max twice per second
227
+ * ```
228
+ */
229
+ throttle<T extends keyof nodemod.EventCallbacks>(eventName: T, handler: nodemod.EventCallbacks[T], delay?: number): this;
230
+ /**
231
+ * Adds a debounced event listener that delays execution until after the specified interval
232
+ * has passed since the last event occurrence. Useful for handling rapid successive events.
233
+ *
234
+ * @param eventName - Name of the event to listen for
235
+ * @param handler - Function to execute when event occurs
236
+ * @param delay - Delay in milliseconds after last event before execution (default: 1000)
237
+ * @returns This instance for method chaining
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * // Debounce player input to handle final command only
242
+ * nodemodCore.events.debounce('dllClientCommand', (entity, command) => {
243
+ * if (command.startsWith('buy_')) {
244
+ * processPurchase(entity, command);
245
+ * }
246
+ * }, 300); // Wait 300ms after last buy command
247
+ *
248
+ * // Debounce entity spawning for batch processing
249
+ * nodemodCore.events.debounce('dllSpawn', () => {
250
+ * console.log('Finished spawning entities');
251
+ * optimizeMapEntities();
252
+ * }, 2000);
253
+ * ```
254
+ */
255
+ debounce<T extends keyof nodemod.EventCallbacks>(eventName: T, handler: nodemod.EventCallbacks[T], delay?: number): this;
256
+ }
257
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/enhanced/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,350 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // Extend the nodemod namespace to include missing methods
4
+ /**
5
+ * Enhanced event system providing advanced event handling capabilities on top of nodemod's native events.
6
+ * Features include priority-based execution, one-time listeners, event filtering, throttling, and debouncing.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * // Basic event listening
11
+ * nodemodCore.events.on('dllClientConnect', (entity, name) => {
12
+ * console.log(`${name} connected`);
13
+ * });
14
+ *
15
+ * // One-time event listener
16
+ * nodemodCore.events.once('dllSpawn', (entity) => {
17
+ * console.log('First spawn event received');
18
+ * });
19
+ *
20
+ * // Priority-based event handling
21
+ * nodemodCore.events.on('dllClientCommand', handleCommand, { priority: 10 });
22
+ * nodemodCore.events.on('dllClientCommand', logCommand, { priority: 1 });
23
+ *
24
+ * // Event filtering
25
+ * nodemodCore.events.filter('dllClientConnect',
26
+ * (entity, name) => name.startsWith('Admin'),
27
+ * (entity, name) => console.log(`Admin ${name} connected`)
28
+ * );
29
+ *
30
+ * // Throttled events (max once per second)
31
+ * nodemodCore.events.throttle('dllStartFrame', frameHandler, 1000);
32
+ * ```
33
+ */
34
+ class NodemodEvents {
35
+ /** Map of active event listeners organized by event name */
36
+ eventListeners = new Map();
37
+ /**
38
+ * Creates a new NodemodEvents instance and initializes enhanced event handlers.
39
+ */
40
+ constructor() {
41
+ this.initializeEvents();
42
+ }
43
+ /**
44
+ * Adds an event listener with enhanced options like priority and one-time execution.
45
+ *
46
+ * @param eventName - Name of the event to listen for
47
+ * @param handler - Function to execute when event occurs
48
+ * @param options - Additional options for the listener
49
+ * @returns This instance for method chaining
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * // Basic event listener
54
+ * nodemodCore.events.on('dllClientConnect', (entity, name) => {
55
+ * console.log(`${name} joined the server`);
56
+ * });
57
+ *
58
+ * // High-priority listener (executes first)
59
+ * nodemodCore.events.on('dllClientCommand', (entity, command) => {
60
+ * console.log('Processing command:', command);
61
+ * }, { priority: 100 });
62
+ *
63
+ * // One-time listener
64
+ * nodemodCore.events.on('dllSpawn', (entity) => {
65
+ * console.log('First entity spawned');
66
+ * }, { once: true });
67
+ * ```
68
+ */
69
+ on(eventName, handler, options = {}) {
70
+ const wrappedHandler = (options.once) ?
71
+ ((...args) => {
72
+ handler(...args);
73
+ this.off(eventName, wrappedHandler);
74
+ }) : handler;
75
+ if (!this.eventListeners.has(eventName)) {
76
+ this.eventListeners.set(eventName, []);
77
+ }
78
+ this.eventListeners.get(eventName).push({
79
+ handler: wrappedHandler,
80
+ original: handler,
81
+ priority: options.priority || 0
82
+ });
83
+ // Sort by priority (higher priority first)
84
+ this.eventListeners.get(eventName).sort((a, b) => b.priority - a.priority);
85
+ nodemod.on(eventName, wrappedHandler);
86
+ return this;
87
+ }
88
+ // Remove event listener
89
+ off(eventName, handler) {
90
+ if (!this.eventListeners.has(eventName))
91
+ return this;
92
+ const listeners = this.eventListeners.get(eventName);
93
+ const index = listeners.findIndex(l => l.original === handler || l.handler === handler);
94
+ if (index !== -1) {
95
+ nodemod.removeListener(eventName, listeners[index].handler);
96
+ listeners.splice(index, 1);
97
+ if (listeners.length === 0) {
98
+ this.eventListeners.delete(eventName);
99
+ }
100
+ }
101
+ return this;
102
+ }
103
+ /**
104
+ * Adds a one-time event listener that automatically removes itself after first execution.
105
+ *
106
+ * @param eventName - Name of the event to listen for
107
+ * @param handler - Function to execute when event occurs
108
+ * @returns This instance for method chaining
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * // Listen for first player connection only
113
+ * nodemodCore.events.once('dllClientConnect', (entity, name) => {
114
+ * console.log(`First player ${name} connected - starting game logic`);
115
+ * });
116
+ *
117
+ * // Wait for map change
118
+ * nodemodCore.events.once('dllSpawn', () => {
119
+ * console.log('Map fully loaded');
120
+ * });
121
+ * ```
122
+ */
123
+ once(eventName, handler) {
124
+ return this.on(eventName, handler, { once: true });
125
+ }
126
+ // Clear all listeners for an event
127
+ clearListeners(eventName) {
128
+ if (eventName) {
129
+ nodemod.clearListeners(eventName);
130
+ this.eventListeners.delete(eventName);
131
+ }
132
+ else {
133
+ // Clear all listeners
134
+ for (const [event] of this.eventListeners) {
135
+ nodemod.clearListeners(event);
136
+ }
137
+ this.eventListeners.clear();
138
+ }
139
+ return this;
140
+ }
141
+ // Get list of active event listeners
142
+ getListeners(eventName) {
143
+ return this.eventListeners.get(eventName) || [];
144
+ }
145
+ // Initialize commonly used event handlers with utilities
146
+ initializeEvents() {
147
+ // Player connection events with enhanced data
148
+ this.on('dllClientConnect', (entity, name, address, rejectReason) => {
149
+ const playerId = nodemod.eng.indexOfEdict(entity);
150
+ const playerInfo = {
151
+ entity,
152
+ id: playerId,
153
+ name: name,
154
+ address: address,
155
+ steamId: nodemod.eng.getPlayerAuthId(entity),
156
+ userId: nodemod.eng.getPlayerUserId(entity)
157
+ };
158
+ // Custom event - not calling nodemod functions
159
+ });
160
+ this.on('dllClientDisconnect', (entity) => {
161
+ const playerId = nodemod.eng.indexOfEdict(entity);
162
+ const playerInfo = {
163
+ entity,
164
+ id: playerId,
165
+ name: entity.netname,
166
+ steamId: nodemod.eng.getPlayerAuthId(entity)
167
+ };
168
+ // Custom event - not calling nodemod functions
169
+ });
170
+ // Enhanced spawn event
171
+ this.on('dllSpawn', (entity) => {
172
+ if (entity.netname) {
173
+ // Player spawn
174
+ const playerSpawnInfo = {
175
+ entity,
176
+ id: nodemod.eng.indexOfEdict(entity),
177
+ name: entity.netname,
178
+ className: entity.classname
179
+ };
180
+ // Custom event - not calling nodemod functions
181
+ }
182
+ else {
183
+ // Entity spawn
184
+ const entitySpawnInfo = {
185
+ entity,
186
+ id: nodemod.eng.indexOfEdict(entity),
187
+ className: entity.classname
188
+ };
189
+ // Custom event - not calling nodemod functions
190
+ }
191
+ });
192
+ // Frame timing events
193
+ this.on('dllStartFrame', () => {
194
+ const frameInfo = {
195
+ time: nodemod.time,
196
+ mapname: nodemod.mapname,
197
+ playerCount: nodemod.players.length
198
+ };
199
+ // Custom event - not calling nodemod functions
200
+ });
201
+ }
202
+ // Custom emit removed - only using nodemod events
203
+ // Event helper methods
204
+ /**
205
+ * Waits for a specific event to occur and returns its parameters as a promise.
206
+ * Useful for async/await patterns with events.
207
+ *
208
+ * @param eventName - Name of the event to wait for
209
+ * @param timeout - Timeout in milliseconds (default: 10000)
210
+ * @returns Promise that resolves with event parameters or rejects on timeout
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * // Wait for player connection
215
+ * try {
216
+ * const [entity, name] = await nodemodCore.events.waitFor('dllClientConnect', 30000);
217
+ * console.log(`Player ${name} connected within 30 seconds`);
218
+ * } catch (error) {
219
+ * console.log('No player connected within timeout');
220
+ * }
221
+ *
222
+ * // Wait for entity spawn with shorter timeout
223
+ * const [spawnedEntity] = await nodemodCore.events.waitFor('dllSpawn', 5000);
224
+ * ```
225
+ */
226
+ waitFor(eventName, timeout = 10000) {
227
+ return new Promise((resolve, reject) => {
228
+ const timeoutId = setTimeout(() => {
229
+ this.off(eventName, handler);
230
+ reject(new Error(`Event ${eventName} timeout after ${timeout}ms`));
231
+ }, timeout);
232
+ const handler = ((...args) => {
233
+ clearTimeout(timeoutId);
234
+ resolve(args);
235
+ });
236
+ this.once(eventName, handler);
237
+ });
238
+ }
239
+ /**
240
+ * Adds an event listener that only executes when a predicate condition is met.
241
+ *
242
+ * @param eventName - Name of the event to listen for
243
+ * @param predicate - Function that returns true if the handler should execute
244
+ * @param handler - Function to execute when event occurs and predicate is true
245
+ * @returns This instance for method chaining
246
+ *
247
+ * @example
248
+ * ```typescript
249
+ * // Only handle commands from admins
250
+ * nodemodCore.events.filter('dllClientCommand',
251
+ * (entity, command) => isAdmin(entity),
252
+ * (entity, command) => handleAdminCommand(entity, command)
253
+ * );
254
+ *
255
+ * // Only handle player connections with specific names
256
+ * nodemodCore.events.filter('dllClientConnect',
257
+ * (entity, name) => name.startsWith('VIP_'),
258
+ * (entity, name) => grantVipAccess(entity)
259
+ * );
260
+ * ```
261
+ */
262
+ filter(eventName, predicate, handler) {
263
+ const wrappedHandler = function (...args) {
264
+ if (predicate(...args)) {
265
+ // @ts-ignore - TypeScript can't guarantee spread matches exact signature but it's safe here
266
+ return handler(...args);
267
+ }
268
+ };
269
+ return this.on(eventName, wrappedHandler);
270
+ }
271
+ // Event mapping/transformation
272
+ map(eventName, transformer, newEventName) {
273
+ return this.on(eventName, ((...args) => {
274
+ const transformed = transformer(...args);
275
+ // Note: mapping to custom events not supported in strict mode
276
+ }));
277
+ }
278
+ /**
279
+ * Adds a throttled event listener that limits execution to once per specified interval.
280
+ * Useful for performance optimization with high-frequency events.
281
+ *
282
+ * @param eventName - Name of the event to listen for
283
+ * @param handler - Function to execute when event occurs
284
+ * @param delay - Minimum interval between executions in milliseconds (default: 1000)
285
+ * @returns This instance for method chaining
286
+ *
287
+ * @example
288
+ * ```typescript
289
+ * // Throttle frame events to once per second
290
+ * nodemodCore.events.throttle('dllStartFrame', () => {
291
+ * console.log('Frame update (max once per second)');
292
+ * }, 1000);
293
+ *
294
+ * // Throttle player movement tracking
295
+ * nodemodCore.events.throttle('dllClientCommand', (entity, command) => {
296
+ * if (command.startsWith('+move')) {
297
+ * updatePlayerPosition(entity);
298
+ * }
299
+ * }, 500); // Max twice per second
300
+ * ```
301
+ */
302
+ throttle(eventName, handler, delay = 1000) {
303
+ let lastCall = 0;
304
+ const wrappedHandler = function (...args) {
305
+ const now = Date.now();
306
+ if (now - lastCall >= delay) {
307
+ lastCall = now;
308
+ // @ts-ignore - TypeScript can't guarantee spread matches exact signature but it's safe here
309
+ return handler(...args);
310
+ }
311
+ };
312
+ return this.on(eventName, wrappedHandler);
313
+ }
314
+ /**
315
+ * Adds a debounced event listener that delays execution until after the specified interval
316
+ * has passed since the last event occurrence. Useful for handling rapid successive events.
317
+ *
318
+ * @param eventName - Name of the event to listen for
319
+ * @param handler - Function to execute when event occurs
320
+ * @param delay - Delay in milliseconds after last event before execution (default: 1000)
321
+ * @returns This instance for method chaining
322
+ *
323
+ * @example
324
+ * ```typescript
325
+ * // Debounce player input to handle final command only
326
+ * nodemodCore.events.debounce('dllClientCommand', (entity, command) => {
327
+ * if (command.startsWith('buy_')) {
328
+ * processPurchase(entity, command);
329
+ * }
330
+ * }, 300); // Wait 300ms after last buy command
331
+ *
332
+ * // Debounce entity spawning for batch processing
333
+ * nodemodCore.events.debounce('dllSpawn', () => {
334
+ * console.log('Finished spawning entities');
335
+ * optimizeMapEntities();
336
+ * }, 2000);
337
+ * ```
338
+ */
339
+ debounce(eventName, handler, delay = 1000) {
340
+ let timeoutId;
341
+ const wrappedHandler = function (...args) {
342
+ clearTimeout(timeoutId);
343
+ // @ts-ignore - TypeScript can't guarantee spread matches exact signature but it's safe here
344
+ timeoutId = setTimeout(() => handler(...args), delay);
345
+ };
346
+ return this.on(eventName, wrappedHandler);
347
+ }
348
+ }
349
+ exports.default = NodemodEvents;
350
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/enhanced/events.ts"],"names":[],"mappings":"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"}