@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.
- package/README.md +60 -0
- package/dist/core/cmd.d.ts +148 -0
- package/dist/core/cmd.d.ts.map +1 -0
- package/dist/core/cmd.js +177 -0
- package/dist/core/cmd.js.map +1 -0
- package/dist/core/menu.d.ts +300 -0
- package/dist/core/menu.d.ts.map +1 -0
- package/dist/core/menu.js +449 -0
- package/dist/core/menu.js.map +1 -0
- package/dist/core/msg.d.ts +300 -0
- package/dist/core/msg.d.ts.map +1 -0
- package/dist/core/msg.js +374 -0
- package/dist/core/msg.js.map +1 -0
- package/dist/core/resource.d.ts +137 -0
- package/dist/core/resource.d.ts.map +1 -0
- package/dist/core/resource.js +171 -0
- package/dist/core/resource.js.map +1 -0
- package/dist/core/sound.d.ts +262 -0
- package/dist/core/sound.d.ts.map +1 -0
- package/dist/core/sound.js +300 -0
- package/dist/core/sound.js.map +1 -0
- package/dist/enhanced/entity.d.ts +263 -0
- package/dist/enhanced/entity.d.ts.map +1 -0
- package/dist/enhanced/entity.js +447 -0
- package/dist/enhanced/entity.js.map +1 -0
- package/dist/enhanced/events.d.ts +257 -0
- package/dist/enhanced/events.d.ts.map +1 -0
- package/dist/enhanced/events.js +350 -0
- package/dist/enhanced/events.js.map +1 -0
- package/dist/enhanced/player.d.ts +272 -0
- package/dist/enhanced/player.d.ts.map +1 -0
- package/dist/enhanced/player.js +389 -0
- package/dist/enhanced/player.js.map +1 -0
- package/dist/enhanced/trace.d.ts +198 -0
- package/dist/enhanced/trace.d.ts.map +1 -0
- package/dist/enhanced/trace.js +311 -0
- package/dist/enhanced/trace.js.map +1 -0
- package/dist/index.d.ts +88 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +120 -0
- package/dist/index.js.map +1 -0
- package/dist/native/cvar.d.ts +49 -0
- package/dist/native/cvar.d.ts.map +1 -0
- package/dist/native/cvar.js +169 -0
- package/dist/native/cvar.js.map +1 -0
- package/dist/native/file.d.ts +221 -0
- package/dist/native/file.d.ts.map +1 -0
- package/dist/native/file.js +353 -0
- package/dist/native/file.js.map +1 -0
- package/dist/types/dll.d.ts +109 -0
- package/dist/types/engine.d.ts +319 -0
- package/dist/types/enums.d.ts +434 -0
- package/dist/types/events.d.ts +2432 -0
- package/dist/types/index.d.ts +38 -0
- package/dist/types/structures.d.ts +1144 -0
- package/dist/utils/util.d.ts +202 -0
- package/dist/utils/util.d.ts.map +1 -0
- package/dist/utils/util.js +318 -0
- package/dist/utils/util.js.map +1 -0
- package/package.json +167 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import type NodemodMsg from '../core/msg';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration options for HUD text display.
|
|
4
|
+
*/
|
|
5
|
+
export interface HudTextOptions {
|
|
6
|
+
/** X coordinate on screen (default: 4000 - screen center) */
|
|
7
|
+
x?: number;
|
|
8
|
+
/** Y coordinate on screen (default: 4000 - screen center) */
|
|
9
|
+
y?: number;
|
|
10
|
+
/** Visual effect type */
|
|
11
|
+
effect?: number;
|
|
12
|
+
/** Red color component (0-255) */
|
|
13
|
+
r?: number;
|
|
14
|
+
/** Green color component (0-255) */
|
|
15
|
+
g?: number;
|
|
16
|
+
/** Blue color component (0-255) */
|
|
17
|
+
b?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Comprehensive utility class providing helper functions for entity management, player communication,
|
|
21
|
+
* and low-level entity data manipulation. Includes automatic player connection tracking and various
|
|
22
|
+
* convenience methods for common server operations.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* // Send chat message to player
|
|
27
|
+
* const player = nodemod.players[0];
|
|
28
|
+
* nodemodCore.util.sendChat('Welcome to the server!', player);
|
|
29
|
+
*
|
|
30
|
+
* // Show HUD text with custom styling
|
|
31
|
+
* nodemodCore.util.showHudText(player, 'Health: 100', {
|
|
32
|
+
* x: 100, y: 200, r: 255, g: 0, b: 0
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* // Get player connection info
|
|
36
|
+
* const playerInfo = nodemodCore.util.getConnectedPlayersInfo();
|
|
37
|
+
* playerInfo.forEach(info => {
|
|
38
|
+
* console.log(`${info.name} (${info.steamId}) from ${info.ipAddress}`);
|
|
39
|
+
* });
|
|
40
|
+
*
|
|
41
|
+
* // Debug entity data
|
|
42
|
+
* nodemodCore.util.dumpOffsets(player, 1000);
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export default class NodemodUtil {
|
|
46
|
+
/** Message service for network communication */
|
|
47
|
+
private msg;
|
|
48
|
+
/** Map storing player IP addresses by entity index */
|
|
49
|
+
private playerIpMap;
|
|
50
|
+
/**
|
|
51
|
+
* Creates a new NodemodUtil instance.
|
|
52
|
+
* Automatically sets up player connection tracking.
|
|
53
|
+
*
|
|
54
|
+
* @param msgService - Message service for network communication
|
|
55
|
+
*/
|
|
56
|
+
constructor(msgService: NodemodMsg);
|
|
57
|
+
private setupPlayerTracking;
|
|
58
|
+
/**
|
|
59
|
+
* Converts an entity reference to its numeric index.
|
|
60
|
+
* Handles both entity objects and numeric indices safely.
|
|
61
|
+
*
|
|
62
|
+
* @param entity - Entity object, numeric index, or null
|
|
63
|
+
* @returns Entity index number or null if invalid
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const player = nodemod.players[0];
|
|
68
|
+
* const playerId = nodemodCore.util.forceEntityId(player);
|
|
69
|
+
* console.log(`Player ID: ${playerId}`);
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
forceEntityId(entity: nodemod.Entity | number | null): number | null;
|
|
73
|
+
/**
|
|
74
|
+
* Converts an entity reference to an entity object.
|
|
75
|
+
* Handles both entity objects and numeric indices safely.
|
|
76
|
+
*
|
|
77
|
+
* @param entity - Entity object, numeric index, or null
|
|
78
|
+
* @returns Entity object or null if invalid
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const entityObj = nodemodCore.util.forceEntityObject(1);
|
|
83
|
+
* if (entityObj) {
|
|
84
|
+
* console.log(`Entity name: ${entityObj.netname}`);
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
forceEntityObject(entity?: nodemod.Entity | number | null): nodemod.Entity | null;
|
|
89
|
+
/**
|
|
90
|
+
* Sends a chat message to a specific player or all players.
|
|
91
|
+
* Automatically handles multi-line messages by splitting on newlines.
|
|
92
|
+
*
|
|
93
|
+
* @param message - Message text to send (supports newlines)
|
|
94
|
+
* @param target - Target player entity/index, or null for all players
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* // Send to specific player
|
|
99
|
+
* const player = nodemod.players[0];
|
|
100
|
+
* nodemodCore.util.sendChat('Welcome back!', player);
|
|
101
|
+
*
|
|
102
|
+
* // Send multi-line message
|
|
103
|
+
* nodemodCore.util.sendChat('Line 1\\nLine 2\\nLine 3', player);
|
|
104
|
+
*
|
|
105
|
+
* // Broadcast to all players
|
|
106
|
+
* nodemodCore.util.sendChat('Server announcement', null);
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
sendChat(message: string, target: nodemod.Entity | number | null): void;
|
|
110
|
+
/**
|
|
111
|
+
* Displays HUD text to one or more players with optional styling.
|
|
112
|
+
* Supports both simple text display and advanced positioned text with colors.
|
|
113
|
+
*
|
|
114
|
+
* @param entity - Target entity, array of entities, or entity index
|
|
115
|
+
* @param text - Text to display on the HUD
|
|
116
|
+
* @param options - Optional positioning and color settings
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* // Simple HUD message
|
|
121
|
+
* nodemodCore.util.showHudText(player, 'Health: 100');
|
|
122
|
+
*
|
|
123
|
+
* // Styled HUD message at specific position
|
|
124
|
+
* nodemodCore.util.showHudText(player, 'LOW HEALTH!', {
|
|
125
|
+
* x: 100, y: 300, r: 255, g: 0, b: 0
|
|
126
|
+
* });
|
|
127
|
+
*
|
|
128
|
+
* // Show to multiple players
|
|
129
|
+
* nodemodCore.util.showHudText([player1, player2], 'Round starts soon');
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
showHudText(entity: nodemod.Entity | nodemod.Entity[] | number, text: string, options?: HudTextOptions | null): void;
|
|
133
|
+
rainbowizeString(text: string): string;
|
|
134
|
+
messageClient(client: nodemod.Entity, message: string): void;
|
|
135
|
+
messageAll(message: string): void;
|
|
136
|
+
isValidEntity(entity: nodemod.Entity): boolean;
|
|
137
|
+
getUserId(player: nodemod.Entity): number;
|
|
138
|
+
getSteamId(player: nodemod.Entity): string;
|
|
139
|
+
getIpAddress(player: nodemod.Entity): string;
|
|
140
|
+
/**
|
|
141
|
+
* Gets detailed information about all connected players.
|
|
142
|
+
* Includes entity references, names, IDs, and network information.
|
|
143
|
+
*
|
|
144
|
+
* @returns Array of player information objects
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const players = nodemodCore.util.getConnectedPlayersInfo();
|
|
149
|
+
* console.log(`${players.length} players connected:`);
|
|
150
|
+
*
|
|
151
|
+
* players.forEach(player => {
|
|
152
|
+
* console.log(`${player.name} (${player.steamId}) from ${player.ipAddress}`);
|
|
153
|
+
*
|
|
154
|
+
* // Check if player is admin
|
|
155
|
+
* if (isAdminSteamId(player.steamId)) {
|
|
156
|
+
* nodemodCore.util.sendChat('Welcome back, admin!', player.entity);
|
|
157
|
+
* }
|
|
158
|
+
* });
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
getConnectedPlayersInfo(): Array<{
|
|
162
|
+
entity: nodemod.Entity;
|
|
163
|
+
name: string;
|
|
164
|
+
userId: number;
|
|
165
|
+
steamId: string;
|
|
166
|
+
ipAddress: string;
|
|
167
|
+
}>;
|
|
168
|
+
/**
|
|
169
|
+
* Clear all tracked player connection data (manual cleanup)
|
|
170
|
+
* Use this to reset the IP tracking map if needed
|
|
171
|
+
*/
|
|
172
|
+
clearPlayerTracking(): void;
|
|
173
|
+
/**
|
|
174
|
+
* Read a 32-bit little-endian integer from entity private data
|
|
175
|
+
* @param entity The entity to read from
|
|
176
|
+
* @param offset The byte offset to read from
|
|
177
|
+
* @returns The integer value or null if buffer is invalid
|
|
178
|
+
*/
|
|
179
|
+
readInt32LE(entity: nodemod.Entity, offset: number): number | null;
|
|
180
|
+
/**
|
|
181
|
+
* Write a 32-bit little-endian integer to entity private data
|
|
182
|
+
* @param entity The entity to write to
|
|
183
|
+
* @param offset The byte offset to write to
|
|
184
|
+
* @param value The integer value to write
|
|
185
|
+
*/
|
|
186
|
+
writeInt32LE(entity: nodemod.Entity, offset: number, value: number): void;
|
|
187
|
+
/**
|
|
188
|
+
* Dump all non-zero private data values for an entity (debugging utility)
|
|
189
|
+
* @param entity The entity to dump data for
|
|
190
|
+
* @param maxOffset Maximum offset to check (default 10000)
|
|
191
|
+
*/
|
|
192
|
+
dumpOffsets(entity: nodemod.Entity, maxOffset?: number): void;
|
|
193
|
+
/**
|
|
194
|
+
* Search for specific values in entity private data (debugging utility)
|
|
195
|
+
* @param entity The entity to search
|
|
196
|
+
* @param searchValue The value to search for
|
|
197
|
+
* @param start Starting offset (default 0)
|
|
198
|
+
* @param maxOffset Maximum offset to search (default 2000)
|
|
199
|
+
*/
|
|
200
|
+
searchOffsets(entity: nodemod.Entity, searchValue: number, start?: number, maxOffset?: number): void;
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=util.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/utils/util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const msg_1 = require("../core/msg");
|
|
4
|
+
/**
|
|
5
|
+
* Comprehensive utility class providing helper functions for entity management, player communication,
|
|
6
|
+
* and low-level entity data manipulation. Includes automatic player connection tracking and various
|
|
7
|
+
* convenience methods for common server operations.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Send chat message to player
|
|
12
|
+
* const player = nodemod.players[0];
|
|
13
|
+
* nodemodCore.util.sendChat('Welcome to the server!', player);
|
|
14
|
+
*
|
|
15
|
+
* // Show HUD text with custom styling
|
|
16
|
+
* nodemodCore.util.showHudText(player, 'Health: 100', {
|
|
17
|
+
* x: 100, y: 200, r: 255, g: 0, b: 0
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Get player connection info
|
|
21
|
+
* const playerInfo = nodemodCore.util.getConnectedPlayersInfo();
|
|
22
|
+
* playerInfo.forEach(info => {
|
|
23
|
+
* console.log(`${info.name} (${info.steamId}) from ${info.ipAddress}`);
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Debug entity data
|
|
27
|
+
* nodemodCore.util.dumpOffsets(player, 1000);
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
class NodemodUtil {
|
|
31
|
+
/** Message service for network communication */
|
|
32
|
+
msg;
|
|
33
|
+
/** Map storing player IP addresses by entity index */
|
|
34
|
+
playerIpMap = new Map(); // entityIndex -> IP address
|
|
35
|
+
/**
|
|
36
|
+
* Creates a new NodemodUtil instance.
|
|
37
|
+
* Automatically sets up player connection tracking.
|
|
38
|
+
*
|
|
39
|
+
* @param msgService - Message service for network communication
|
|
40
|
+
*/
|
|
41
|
+
constructor(msgService) {
|
|
42
|
+
this.msg = msgService;
|
|
43
|
+
this.setupPlayerTracking();
|
|
44
|
+
}
|
|
45
|
+
setupPlayerTracking() {
|
|
46
|
+
// Track player connections to store IP addresses
|
|
47
|
+
nodemod.on('dllClientConnect', (entity, name, address, rejectReason) => {
|
|
48
|
+
const entityIndex = nodemod.eng.indexOfEdict(entity);
|
|
49
|
+
this.playerIpMap.set(entityIndex, address);
|
|
50
|
+
});
|
|
51
|
+
// Clean up when players disconnect
|
|
52
|
+
nodemod.on('dllClientDisconnect', (entity) => {
|
|
53
|
+
const entityIndex = nodemod.eng.indexOfEdict(entity);
|
|
54
|
+
this.playerIpMap.delete(entityIndex);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Converts an entity reference to its numeric index.
|
|
59
|
+
* Handles both entity objects and numeric indices safely.
|
|
60
|
+
*
|
|
61
|
+
* @param entity - Entity object, numeric index, or null
|
|
62
|
+
* @returns Entity index number or null if invalid
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const player = nodemod.players[0];
|
|
67
|
+
* const playerId = nodemodCore.util.forceEntityId(player);
|
|
68
|
+
* console.log(`Player ID: ${playerId}`);
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
forceEntityId(entity) {
|
|
72
|
+
if (!entity) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
return typeof entity === 'number' ? entity : nodemod.eng.indexOfEdict(entity);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Converts an entity reference to an entity object.
|
|
79
|
+
* Handles both entity objects and numeric indices safely.
|
|
80
|
+
*
|
|
81
|
+
* @param entity - Entity object, numeric index, or null
|
|
82
|
+
* @returns Entity object or null if invalid
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```typescript
|
|
86
|
+
* const entityObj = nodemodCore.util.forceEntityObject(1);
|
|
87
|
+
* if (entityObj) {
|
|
88
|
+
* console.log(`Entity name: ${entityObj.netname}`);
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
forceEntityObject(entity) {
|
|
93
|
+
if (!entity) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
return typeof entity === 'number' ? nodemod.eng.pEntityOfEntIndex(entity) : entity;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Sends a chat message to a specific player or all players.
|
|
100
|
+
* Automatically handles multi-line messages by splitting on newlines.
|
|
101
|
+
*
|
|
102
|
+
* @param message - Message text to send (supports newlines)
|
|
103
|
+
* @param target - Target player entity/index, or null for all players
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```typescript
|
|
107
|
+
* // Send to specific player
|
|
108
|
+
* const player = nodemod.players[0];
|
|
109
|
+
* nodemodCore.util.sendChat('Welcome back!', player);
|
|
110
|
+
*
|
|
111
|
+
* // Send multi-line message
|
|
112
|
+
* nodemodCore.util.sendChat('Line 1\\nLine 2\\nLine 3', player);
|
|
113
|
+
*
|
|
114
|
+
* // Broadcast to all players
|
|
115
|
+
* nodemodCore.util.sendChat('Server announcement', null);
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
sendChat(message, target) {
|
|
119
|
+
message.split('\n').forEach(value => {
|
|
120
|
+
if (value.trim()) { // Only send non-empty lines
|
|
121
|
+
this.msg.send({
|
|
122
|
+
entity: target,
|
|
123
|
+
type: 'SayText',
|
|
124
|
+
data: [
|
|
125
|
+
{ type: 'byte', value: 0 },
|
|
126
|
+
{ type: 'string', value: value + '\n' } // Ensure each message ends with \n
|
|
127
|
+
]
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Displays HUD text to one or more players with optional styling.
|
|
134
|
+
* Supports both simple text display and advanced positioned text with colors.
|
|
135
|
+
*
|
|
136
|
+
* @param entity - Target entity, array of entities, or entity index
|
|
137
|
+
* @param text - Text to display on the HUD
|
|
138
|
+
* @param options - Optional positioning and color settings
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* // Simple HUD message
|
|
143
|
+
* nodemodCore.util.showHudText(player, 'Health: 100');
|
|
144
|
+
*
|
|
145
|
+
* // Styled HUD message at specific position
|
|
146
|
+
* nodemodCore.util.showHudText(player, 'LOW HEALTH!', {
|
|
147
|
+
* x: 100, y: 300, r: 255, g: 0, b: 0
|
|
148
|
+
* });
|
|
149
|
+
*
|
|
150
|
+
* // Show to multiple players
|
|
151
|
+
* nodemodCore.util.showHudText([player1, player2], 'Round starts soon');
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
showHudText(entity, text, options) {
|
|
155
|
+
if (Array.isArray(entity)) {
|
|
156
|
+
entity.forEach(v => this.showHudText(v, text, options || null));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (options) {
|
|
160
|
+
this.msg.send({
|
|
161
|
+
type: msg_1.MsgTypes.tempentity,
|
|
162
|
+
dest: entity ? msg_1.MsgDest.one_unreliable : msg_1.MsgDest.broadcast,
|
|
163
|
+
entity: entity || null,
|
|
164
|
+
data: [
|
|
165
|
+
{ type: 'byte', value: 29 },
|
|
166
|
+
{ type: 'byte', value: -1 }, // channel
|
|
167
|
+
{ type: 'short', value: options.x || 4000 },
|
|
168
|
+
{ type: 'short', value: options.y || 4000 },
|
|
169
|
+
{ type: 'byte', value: options.effect || 0 },
|
|
170
|
+
{ type: 'byte', value: options.r || 0 },
|
|
171
|
+
{ type: 'byte', value: options.g || 0 },
|
|
172
|
+
{ type: 'byte', value: options.b || 0 },
|
|
173
|
+
{ type: 'byte', value: 0 }, // a
|
|
174
|
+
{ type: 'byte', value: 255 },
|
|
175
|
+
{ type: 'byte', value: 255 },
|
|
176
|
+
{ type: 'byte', value: 250 },
|
|
177
|
+
{ type: 'byte', value: 0 },
|
|
178
|
+
{ type: 'short', value: 100 }, // fadein
|
|
179
|
+
{ type: 'short', value: 100 }, // fadeout
|
|
180
|
+
{ type: 'short', value: 800 }, // hold
|
|
181
|
+
// { type: 'short', value: 29 }, // fxtime
|
|
182
|
+
{ type: 'string', value: text }
|
|
183
|
+
]
|
|
184
|
+
});
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
this.msg.send({
|
|
188
|
+
type: 'HudText',
|
|
189
|
+
data: [{ type: 'string', value: text }],
|
|
190
|
+
entity: entity || null
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
rainbowizeString(text) {
|
|
194
|
+
return text.split('').map(v => `^${Math.floor(Math.random() * 10)}${v}`).join('');
|
|
195
|
+
}
|
|
196
|
+
// Message helper methods
|
|
197
|
+
messageClient(client, message) {
|
|
198
|
+
this.sendChat(message + "\n", client);
|
|
199
|
+
}
|
|
200
|
+
messageAll(message) {
|
|
201
|
+
nodemod.players.forEach(player => {
|
|
202
|
+
this.sendChat(message, player);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
// Entity validation helper
|
|
206
|
+
isValidEntity(entity) {
|
|
207
|
+
return !!(entity && entity.netname);
|
|
208
|
+
}
|
|
209
|
+
// Player info helpers
|
|
210
|
+
getUserId(player) {
|
|
211
|
+
return nodemod.eng.indexOfEdict(player);
|
|
212
|
+
}
|
|
213
|
+
getSteamId(player) {
|
|
214
|
+
// Mock implementation - would need proper Steam ID extraction
|
|
215
|
+
return nodemod.eng.getPlayerAuthId(player);
|
|
216
|
+
}
|
|
217
|
+
getIpAddress(player) {
|
|
218
|
+
const entityIndex = nodemod.eng.indexOfEdict(player);
|
|
219
|
+
return this.playerIpMap.get(entityIndex) || "Unknown";
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Gets detailed information about all connected players.
|
|
223
|
+
* Includes entity references, names, IDs, and network information.
|
|
224
|
+
*
|
|
225
|
+
* @returns Array of player information objects
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```typescript
|
|
229
|
+
* const players = nodemodCore.util.getConnectedPlayersInfo();
|
|
230
|
+
* console.log(`${players.length} players connected:`);
|
|
231
|
+
*
|
|
232
|
+
* players.forEach(player => {
|
|
233
|
+
* console.log(`${player.name} (${player.steamId}) from ${player.ipAddress}`);
|
|
234
|
+
*
|
|
235
|
+
* // Check if player is admin
|
|
236
|
+
* if (isAdminSteamId(player.steamId)) {
|
|
237
|
+
* nodemodCore.util.sendChat('Welcome back, admin!', player.entity);
|
|
238
|
+
* }
|
|
239
|
+
* });
|
|
240
|
+
* ```
|
|
241
|
+
*/
|
|
242
|
+
getConnectedPlayersInfo() {
|
|
243
|
+
return nodemod.players.map(player => ({
|
|
244
|
+
entity: player,
|
|
245
|
+
name: player.netname,
|
|
246
|
+
userId: this.getUserId(player),
|
|
247
|
+
steamId: this.getSteamId(player),
|
|
248
|
+
ipAddress: this.getIpAddress(player)
|
|
249
|
+
}));
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Clear all tracked player connection data (manual cleanup)
|
|
253
|
+
* Use this to reset the IP tracking map if needed
|
|
254
|
+
*/
|
|
255
|
+
clearPlayerTracking() {
|
|
256
|
+
this.playerIpMap.clear();
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Read a 32-bit little-endian integer from entity private data
|
|
260
|
+
* @param entity The entity to read from
|
|
261
|
+
* @param offset The byte offset to read from
|
|
262
|
+
* @returns The integer value or null if buffer is invalid
|
|
263
|
+
*/
|
|
264
|
+
readInt32LE(entity, offset) {
|
|
265
|
+
const buffer = entity.getPrivateDataBuffer(offset, 4);
|
|
266
|
+
if (!buffer)
|
|
267
|
+
return null;
|
|
268
|
+
return buffer.readInt32LE(0);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Write a 32-bit little-endian integer to entity private data
|
|
272
|
+
* @param entity The entity to write to
|
|
273
|
+
* @param offset The byte offset to write to
|
|
274
|
+
* @param value The integer value to write
|
|
275
|
+
*/
|
|
276
|
+
writeInt32LE(entity, offset, value) {
|
|
277
|
+
const buffer = Buffer.from(new Int32Array([value]).buffer);
|
|
278
|
+
entity.writePrivateDataBuffer(offset, buffer);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Dump all non-zero private data values for an entity (debugging utility)
|
|
282
|
+
* @param entity The entity to dump data for
|
|
283
|
+
* @param maxOffset Maximum offset to check (default 10000)
|
|
284
|
+
*/
|
|
285
|
+
dumpOffsets(entity, maxOffset = 10000) {
|
|
286
|
+
console.log(`=== Entity Private Data Dump ===`);
|
|
287
|
+
for (let byteOffset = 0; byteOffset < maxOffset; byteOffset += 4) {
|
|
288
|
+
const buf = entity.getPrivateDataBuffer(byteOffset, 4);
|
|
289
|
+
const val = buf?.readInt32LE(0);
|
|
290
|
+
if (val !== 0) {
|
|
291
|
+
const intIndex = byteOffset / 4;
|
|
292
|
+
console.log(`Byte offset ${byteOffset} (int index ${intIndex}): ${val} (0x${val?.toString(16)})`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
console.log(`=== End Entity Dump ===`);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Search for specific values in entity private data (debugging utility)
|
|
299
|
+
* @param entity The entity to search
|
|
300
|
+
* @param searchValue The value to search for
|
|
301
|
+
* @param start Starting offset (default 0)
|
|
302
|
+
* @param maxOffset Maximum offset to search (default 2000)
|
|
303
|
+
*/
|
|
304
|
+
searchOffsets(entity, searchValue, start = 0, maxOffset = 2000) {
|
|
305
|
+
console.log(`=== Searching for value ${searchValue} (0x${searchValue.toString(16)}) ===`);
|
|
306
|
+
for (let byteOffset = start; byteOffset < maxOffset; byteOffset += 4) {
|
|
307
|
+
const buf = entity.getPrivateDataBuffer(byteOffset, 4);
|
|
308
|
+
const val = buf?.readInt32LE(0);
|
|
309
|
+
if (val === searchValue) {
|
|
310
|
+
const intIndex = byteOffset / 4;
|
|
311
|
+
console.log(`Found at byte offset ${byteOffset} (int index ${intIndex}): ${val} (0x${val?.toString(16)})`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
console.log(`=== End Search ===`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
exports.default = NodemodUtil;
|
|
318
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/utils/util.ts"],"names":[],"mappings":";;AAAA,qCAAgD;AAqBhD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAqB,WAAW;IAC9B,gDAAgD;IACxC,GAAG,CAAa;IACxB,sDAAsD;IAC9C,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC,CAAC,4BAA4B;IAE7E;;;;;OAKG;IACH,YAAY,UAAsB;QAChC,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC;QACtB,IAAI,CAAC,mBAAmB,EAAE,CAAC;IAC7B,CAAC;IAEO,mBAAmB;QACzB,iDAAiD;QACjD,OAAO,CAAC,EAAE,CAAC,kBAAkB,EAAE,CAAC,MAAsB,EAAE,IAAY,EAAE,OAAe,EAAE,YAAoB,EAAE,EAAE;YAC7G,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YACrD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,mCAAmC;QACnC,OAAO,CAAC,EAAE,CAAC,qBAAqB,EAAE,CAAC,MAAsB,EAAE,EAAE;YAC3D,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YACrD,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,aAAa,CAAC,MAAsC;QAClD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAChF,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,MAAuC;QACvD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACrF,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,QAAQ,CAAC,OAAe,EAAE,MAAsC;QAC9D,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAClC,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,4BAA4B;gBAC9C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;oBACZ,MAAM,EAAE,MAAM;oBACd,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE;wBACJ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE;wBAC1B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,CAAC,mCAAmC;qBAC5E;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,WAAW,CAAC,MAAkD,EAAE,IAAY,EAAE,OAA+B;QAC3G,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC;YAChE,OAAO;QACT,CAAC;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,cAAQ,CAAC,UAAU;gBACzB,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,aAAO,CAAC,cAAc,CAAC,CAAC,CAAC,aAAO,CAAC,SAAS;gBACzD,MAAM,EAAE,MAAM,IAAI,IAAI;gBACtB,IAAI,EAAE;oBACJ,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;oBAC3B,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,UAAU;oBACvC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,IAAI,EAAE;oBAC3C,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,IAAI,EAAE;oBAC3C,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE;oBAC5C,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;oBACvC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;oBACvC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE;oBACvC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,IAAI;oBAChC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;oBAC5B,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;oBAC5B,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE;oBAC5B,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE;oBAC1B,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,SAAS;oBACxC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,UAAU;oBACzC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,OAAO;oBACtC,0CAA0C;oBAC1C,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE;iBAChC;aACF,CAAC,CAAC;YAEH,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YACvC,MAAM,EAAE,MAAM,IAAI,IAAI;SACvB,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,IAAY;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,yBAAyB;IACzB,aAAa,CAAC,MAAsB,EAAE,OAAe;QACnD,IAAI,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,UAAU,CAAC,OAAe;QACxB,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;YAC/B,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,2BAA2B;IAC3B,aAAa,CAAC,MAAsB;QAClC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,sBAAsB;IACtB,SAAS,CAAC,MAAsB;QAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,UAAU,CAAC,MAAsB;QAC/B,8DAA8D;QAC9D,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IAC7C,CAAC;IAED,YAAY,CAAC,MAAsB;QACjC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,SAAS,CAAC;IACxD,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,uBAAuB;QAOrB,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACpC,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,MAAM,CAAC,OAAO;YACpB,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;YAC9B,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAChC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;SACrC,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;;OAGG;IACH,mBAAmB;QACjB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED;;;;;OAKG;IACH,WAAW,CAAC,MAAsB,EAAE,MAAc;QAChD,MAAM,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,MAAsB,EAAE,MAAc,EAAE,KAAa;QAChE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC3D,MAAM,CAAC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,MAAsB,EAAE,YAAoB,KAAK;QAC3D,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,SAAS,EAAE,UAAU,IAAI,CAAC,EAAE,CAAC;YACjE,MAAM,GAAG,GAAG,MAAM,CAAC,oBAAoB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YACvD,MAAM,GAAG,GAAG,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;YAChC,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;gBACd,MAAM,QAAQ,GAAG,UAAU,GAAG,CAAC,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,eAAe,UAAU,eAAe,QAAQ,MAAM,GAAG,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;YACpG,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;OAMG;IACH,aAAa,CAAC,MAAsB,EAAE,WAAmB,EAAE,QAAgB,CAAC,EAAE,YAAoB,IAAI;QACpG,OAAO,CAAC,GAAG,CAAC,2BAA2B,WAAW,OAAO,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QAC1F,KAAK,IAAI,UAAU,GAAG,KAAK,EAAE,UAAU,GAAG,SAAS,EAAE,UAAU,IAAI,CAAC,EAAE,CAAC;YACrE,MAAM,GAAG,GAAG,MAAM,CAAC,oBAAoB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YACvD,MAAM,GAAG,GAAG,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;YAChC,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;gBACxB,MAAM,QAAQ,GAAG,UAAU,GAAG,CAAC,CAAC;gBAChC,OAAO,CAAC,GAAG,CAAC,wBAAwB,UAAU,eAAe,QAAQ,MAAM,GAAG,OAAO,GAAG,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;YAC7G,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACpC,CAAC;CACF;AA5TD,8BA4TC"}
|