bun-memory 1.1.1 → 1.1.3
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/package.json +3 -1
- package/runtime/extensions.ts +238 -0
- package/structs/Memory.ts +48 -1
- package/types/Memory.ts +734 -0
- package/types/global.d.ts +751 -0
package/types/Memory.ts
ADDED
|
@@ -0,0 +1,734 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the Memory module providing cross-process memory manipulation.
|
|
3
|
+
*
|
|
4
|
+
* This module exports type definitions used by the Memory class for type-safe
|
|
5
|
+
* interaction with process memory, modules, and various data structures commonly
|
|
6
|
+
* found in native applications and games.
|
|
7
|
+
*
|
|
8
|
+
* These types ensure proper TypeScript support when working with:
|
|
9
|
+
* - Process modules and their metadata
|
|
10
|
+
* - Memory regions and their properties
|
|
11
|
+
* - Mathematical structures (vectors and quaternions)
|
|
12
|
+
* - FFI-compatible buffer types for memory operations
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import Memory, { Module, Vector3, Quaternion } from './Memory';
|
|
17
|
+
*
|
|
18
|
+
* const memory = new Memory('game.exe');
|
|
19
|
+
*
|
|
20
|
+
* // Type-safe module access
|
|
21
|
+
* const mainModule: Module = memory.modules['game.exe'];
|
|
22
|
+
* console.log(`Base: 0x${mainModule.base.toString(16)}`);
|
|
23
|
+
*
|
|
24
|
+
* // Type-safe vector operations
|
|
25
|
+
* const position: Vector3 = memory.vector3(0x12345678n);
|
|
26
|
+
* memory.vector3(0x12345678n, { x: position.x + 10, y: position.y, z: position.z });
|
|
27
|
+
*
|
|
28
|
+
* memory.close();
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Represents a loaded module within a target process.
|
|
34
|
+
*
|
|
35
|
+
* Modules are executable files (EXE, DLL) that have been loaded into a process's
|
|
36
|
+
* address space. Each module has a base address where it's loaded, a name
|
|
37
|
+
* (typically the filename), and a size indicating how much memory it occupies.
|
|
38
|
+
*
|
|
39
|
+
* This information is essential for:
|
|
40
|
+
* - Calculating absolute addresses from relative offsets
|
|
41
|
+
* - Understanding memory layout of the target process
|
|
42
|
+
* - Identifying specific libraries or executables
|
|
43
|
+
* - Memory scanning within specific module boundaries
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const memory = new Memory('notepad.exe');
|
|
48
|
+
* const modules = memory.modules;
|
|
49
|
+
*
|
|
50
|
+
* // Access the main executable module
|
|
51
|
+
* const mainModule: Module = modules['notepad.exe'];
|
|
52
|
+
* console.log(`Main module loaded at: 0x${mainModule.base.toString(16)}`);
|
|
53
|
+
* console.log(`Module size: ${mainModule.size} bytes`);
|
|
54
|
+
*
|
|
55
|
+
* // Access a system library
|
|
56
|
+
* const kernel32: Module = modules['kernel32.dll'];
|
|
57
|
+
* console.log(`Kernel32 base: 0x${kernel32.base.toString(16)}`);
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* // Calculate absolute address from relative offset
|
|
63
|
+
* const gameModule: Module = memory.modules['game.exe'];
|
|
64
|
+
* const relativeOffset = 0x12345678;
|
|
65
|
+
* const absoluteAddress = gameModule.base + BigInt(relativeOffset);
|
|
66
|
+
*
|
|
67
|
+
* // Read data at the calculated address
|
|
68
|
+
* const health = memory.f32(absoluteAddress);
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* // Enumerate all loaded modules
|
|
74
|
+
* function listModules(memory: Memory) {
|
|
75
|
+
* const modules = memory.modules;
|
|
76
|
+
*
|
|
77
|
+
* console.log('Loaded modules:');
|
|
78
|
+
* for (const [name, module] of Object.entries(modules)) {
|
|
79
|
+
* console.log(` ${name}:`);
|
|
80
|
+
* console.log(` Base: 0x${module.base.toString(16)}`);
|
|
81
|
+
* console.log(` Size: ${module.size} bytes`);
|
|
82
|
+
* console.log(` End: 0x${(module.base + BigInt(module.size)).toString(16)}`);
|
|
83
|
+
* }
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export type Module = {
|
|
88
|
+
/**
|
|
89
|
+
* Base memory address where the module is loaded.
|
|
90
|
+
*
|
|
91
|
+
* This is the virtual memory address where the module's first byte resides
|
|
92
|
+
* in the target process. All relative offsets within the module should be
|
|
93
|
+
* added to this base address to get the absolute memory address.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* const module: Module = memory.modules['example.dll'];
|
|
98
|
+
* const functionOffset = 0x1000; // Relative offset to a function
|
|
99
|
+
* const functionAddress = module.base + BigInt(functionOffset);
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
base: bigint;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Name of the module, typically the filename.
|
|
106
|
+
*
|
|
107
|
+
* This is usually the filename of the executable or library, including
|
|
108
|
+
* the file extension (e.g., 'game.exe', 'user32.dll', 'ntdll.dll').
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const modules = memory.modules;
|
|
113
|
+
*
|
|
114
|
+
* if ('game.exe' in modules) {
|
|
115
|
+
* console.log(`Game executable found: ${modules['game.exe'].name}`);
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
name: string;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Size of the module in bytes.
|
|
123
|
+
*
|
|
124
|
+
* This represents how much virtual memory the module occupies in the
|
|
125
|
+
* target process. The module occupies memory from `base` to `base + size`.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* const module: Module = memory.modules['large_library.dll'];
|
|
130
|
+
* const endAddress = module.base + BigInt(module.size);
|
|
131
|
+
*
|
|
132
|
+
* console.log(`Module spans from 0x${module.base.toString(16)} to 0x${endAddress.toString(16)}`);
|
|
133
|
+
* console.log(`Total size: ${(module.size / 1024 / 1024).toFixed(2)} MB`);
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
size: number;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Represents a quaternion for 3D rotations.
|
|
141
|
+
*
|
|
142
|
+
* Quaternions are a mathematical representation of rotations in 3D space that
|
|
143
|
+
* avoid gimbal lock and provide smooth interpolation. They consist of four
|
|
144
|
+
* components: x, y, z (vector part) and w (scalar part).
|
|
145
|
+
*
|
|
146
|
+
* Quaternions are commonly used in:
|
|
147
|
+
* - 3D games for character and camera rotations
|
|
148
|
+
* - 3D modeling and animation software
|
|
149
|
+
* - Robotics and aerospace applications
|
|
150
|
+
* - Physics simulations
|
|
151
|
+
*
|
|
152
|
+
* The quaternion components represent:
|
|
153
|
+
* - x, y, z: The axis of rotation (vector part)
|
|
154
|
+
* - w: The amount of rotation around that axis (scalar part)
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* const memory = new Memory('3d_game.exe');
|
|
159
|
+
*
|
|
160
|
+
* // Read player rotation
|
|
161
|
+
* const playerRotation: Quaternion = memory.quaternion(0x12345678n);
|
|
162
|
+
* console.log(`Player rotation: x=${playerRotation.x}, y=${playerRotation.y}, z=${playerRotation.z}, w=${playerRotation.w}`);
|
|
163
|
+
*
|
|
164
|
+
* // Set identity rotation (no rotation)
|
|
165
|
+
* const identity: Quaternion = { x: 0, y: 0, z: 0, w: 1 };
|
|
166
|
+
* memory.quaternion(0x12345678n, identity);
|
|
167
|
+
* ```
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```typescript
|
|
171
|
+
* // Read array of bone rotations for skeletal animation
|
|
172
|
+
* const boneCount = 50;
|
|
173
|
+
* const boneRotations: Quaternion[] = memory.quaternionArray(0x12345678n, boneCount);
|
|
174
|
+
*
|
|
175
|
+
* // Modify specific bone rotation
|
|
176
|
+
* boneRotations[10] = { x: 0.707, y: 0, z: 0, w: 0.707 }; // 90-degree rotation around X-axis
|
|
177
|
+
*
|
|
178
|
+
* // Write back the modified rotations
|
|
179
|
+
* memory.quaternionArray(0x12345678n, boneRotations);
|
|
180
|
+
* ```
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* // Interpolate between two rotations (basic lerp example)
|
|
185
|
+
* function lerpQuaternion(q1: Quaternion, q2: Quaternion, t: number): Quaternion {
|
|
186
|
+
* return {
|
|
187
|
+
* x: q1.x + (q2.x - q1.x) * t,
|
|
188
|
+
* y: q1.y + (q2.y - q1.y) * t,
|
|
189
|
+
* z: q1.z + (q2.z - q1.z) * t,
|
|
190
|
+
* w: q1.w + (q2.w - q1.w) * t
|
|
191
|
+
* };
|
|
192
|
+
* }
|
|
193
|
+
*
|
|
194
|
+
* const startRotation: Quaternion = memory.quaternion(0x12345678n);
|
|
195
|
+
* const endRotation: Quaternion = { x: 0, y: 0.707, z: 0, w: 0.707 };
|
|
196
|
+
* const interpolated = lerpQuaternion(startRotation, endRotation, 0.5);
|
|
197
|
+
* memory.quaternion(0x12345678n, interpolated);
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
export type Quaternion = {
|
|
201
|
+
/**
|
|
202
|
+
* W component (scalar part) of the quaternion.
|
|
203
|
+
*
|
|
204
|
+
* The w component represents the "amount" of rotation. For a normalized quaternion:
|
|
205
|
+
* - w = 1 represents no rotation (identity)
|
|
206
|
+
* - w = 0 represents a 180-degree rotation
|
|
207
|
+
* - w = cos(θ/2) where θ is the rotation angle
|
|
208
|
+
*
|
|
209
|
+
* @example
|
|
210
|
+
* ```typescript
|
|
211
|
+
* // Identity quaternion (no rotation)
|
|
212
|
+
* const identity: Quaternion = { x: 0, y: 0, z: 0, w: 1 };
|
|
213
|
+
*
|
|
214
|
+
* // 180-degree rotation around Y-axis
|
|
215
|
+
* const flip: Quaternion = { x: 0, y: 1, z: 0, w: 0 };
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
w: number;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* X component of the quaternion's vector part.
|
|
222
|
+
*
|
|
223
|
+
* The x component contributes to the axis of rotation. For rotations around
|
|
224
|
+
* the X-axis, this value will be non-zero while y and z approach zero.
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```typescript
|
|
228
|
+
* // 90-degree rotation around X-axis
|
|
229
|
+
* const xRotation: Quaternion = { x: 0.707, y: 0, z: 0, w: 0.707 };
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
x: number;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Y component of the quaternion's vector part.
|
|
236
|
+
*
|
|
237
|
+
* The y component contributes to the axis of rotation. For rotations around
|
|
238
|
+
* the Y-axis (yaw), this value will be non-zero while x and z approach zero.
|
|
239
|
+
*
|
|
240
|
+
* @example
|
|
241
|
+
* ```typescript
|
|
242
|
+
* // 45-degree yaw rotation (around Y-axis)
|
|
243
|
+
* const yawRotation: Quaternion = { x: 0, y: 0.383, z: 0, w: 0.924 };
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
y: number;
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Z component of the quaternion's vector part.
|
|
250
|
+
*
|
|
251
|
+
* The z component contributes to the axis of rotation. For rotations around
|
|
252
|
+
* the Z-axis (roll), this value will be non-zero while x and y approach zero.
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```typescript
|
|
256
|
+
* // 30-degree roll rotation (around Z-axis)
|
|
257
|
+
* const rollRotation: Quaternion = { x: 0, y: 0, z: 0.259, w: 0.966 };
|
|
258
|
+
* ```
|
|
259
|
+
*/
|
|
260
|
+
z: number;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Represents a memory region with its properties and protection flags.
|
|
265
|
+
*
|
|
266
|
+
* Memory regions are contiguous blocks of virtual memory with uniform properties
|
|
267
|
+
* such as protection flags (read/write/execute permissions), state (committed,
|
|
268
|
+
* reserved, free), and type (private, mapped, image).
|
|
269
|
+
*
|
|
270
|
+
* This information is crucial for:
|
|
271
|
+
* - Safe memory scanning and modification
|
|
272
|
+
* - Understanding memory layout and permissions
|
|
273
|
+
* - Avoiding access violations when reading/writing memory
|
|
274
|
+
* - Identifying different types of memory (code, data, heap, etc.)
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* ```typescript
|
|
278
|
+
* // This type is typically used internally by the Memory class
|
|
279
|
+
* // Users generally don't need to create Region objects directly
|
|
280
|
+
*
|
|
281
|
+
* const memory = new Memory('target_process.exe');
|
|
282
|
+
* // The regions() method (if exposed) would return Region objects
|
|
283
|
+
* ```
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* ```typescript
|
|
287
|
+
* // Understanding memory protection flags
|
|
288
|
+
* // These constants match Windows PAGE_* flags:
|
|
289
|
+
* // 0x04 = PAGE_READWRITE
|
|
290
|
+
* // 0x20 = PAGE_EXECUTE_READ
|
|
291
|
+
* // 0x40 = PAGE_EXECUTE_READWRITE
|
|
292
|
+
* // 0x02 = PAGE_READONLY
|
|
293
|
+
* ```
|
|
294
|
+
*/
|
|
295
|
+
export type Region = {
|
|
296
|
+
/**
|
|
297
|
+
* Base address of the memory region.
|
|
298
|
+
*
|
|
299
|
+
* This is the starting virtual memory address of the region. All addresses
|
|
300
|
+
* within the region fall between base and (base + size).
|
|
301
|
+
*
|
|
302
|
+
* @example
|
|
303
|
+
* ```typescript
|
|
304
|
+
* const region: Region = {
|
|
305
|
+
* base: 0x10000000n,
|
|
306
|
+
* size: 0x1000n,
|
|
307
|
+
* protect: 0x04, // PAGE_READWRITE
|
|
308
|
+
* state: 0x1000, // MEM_COMMIT
|
|
309
|
+
* type: 0x20000 // MEM_PRIVATE
|
|
310
|
+
* };
|
|
311
|
+
*
|
|
312
|
+
* // Region spans from 0x10000000 to 0x10001000
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
base: bigint;
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Memory protection flags for this region.
|
|
319
|
+
*
|
|
320
|
+
* These flags determine what operations are allowed on the memory:
|
|
321
|
+
* - Read permissions: Can the memory be read?
|
|
322
|
+
* - Write permissions: Can the memory be modified?
|
|
323
|
+
* - Execute permissions: Can code in this memory be executed?
|
|
324
|
+
*
|
|
325
|
+
* Common Windows protection flags:
|
|
326
|
+
* - 0x01: PAGE_NOACCESS - No access allowed
|
|
327
|
+
* - 0x02: PAGE_READONLY - Read-only access
|
|
328
|
+
* - 0x04: PAGE_READWRITE - Read and write access
|
|
329
|
+
* - 0x08: PAGE_WRITECOPY - Copy-on-write access
|
|
330
|
+
* - 0x10: PAGE_EXECUTE - Execute-only access
|
|
331
|
+
* - 0x20: PAGE_EXECUTE_READ - Execute and read access
|
|
332
|
+
* - 0x40: PAGE_EXECUTE_READWRITE - Execute, read, and write access
|
|
333
|
+
* - 0x100: PAGE_GUARD - Guard page (triggers exception on access)
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* ```typescript
|
|
337
|
+
* function isWritableRegion(region: Region): boolean {
|
|
338
|
+
* const writableFlags = 0x04 | 0x08 | 0x40; // READWRITE | WRITECOPY | EXECUTE_READWRITE
|
|
339
|
+
* return (region.protect & writableFlags) !== 0;
|
|
340
|
+
* }
|
|
341
|
+
*
|
|
342
|
+
* function isExecutableRegion(region: Region): boolean {
|
|
343
|
+
* const executableFlags = 0x10 | 0x20 | 0x40 | 0x80; // Various execute flags
|
|
344
|
+
* return (region.protect & executableFlags) !== 0;
|
|
345
|
+
* }
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
protect: number;
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Size of the memory region in bytes.
|
|
352
|
+
*
|
|
353
|
+
* This indicates how many bytes the region spans. The region occupies
|
|
354
|
+
* virtual addresses from base to (base + size - 1).
|
|
355
|
+
*
|
|
356
|
+
* @example
|
|
357
|
+
* ```typescript
|
|
358
|
+
* function analyzeRegion(region: Region) {
|
|
359
|
+
* const endAddress = region.base + region.size;
|
|
360
|
+
* const sizeMB = Number(region.size) / (1024 * 1024);
|
|
361
|
+
*
|
|
362
|
+
* console.log(`Region: 0x${region.base.toString(16)} - 0x${endAddress.toString(16)}`);
|
|
363
|
+
* console.log(`Size: ${sizeMB.toFixed(2)} MB`);
|
|
364
|
+
* }
|
|
365
|
+
* ```
|
|
366
|
+
*/
|
|
367
|
+
size: bigint;
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* State of the memory region.
|
|
371
|
+
*
|
|
372
|
+
* The state indicates how the virtual memory is currently being used:
|
|
373
|
+
* - MEM_COMMIT (0x1000): Memory is allocated and backed by physical storage
|
|
374
|
+
* - MEM_RESERVE (0x2000): Memory is reserved but not yet committed
|
|
375
|
+
* - MEM_FREE (0x10000): Memory is available for allocation
|
|
376
|
+
*
|
|
377
|
+
* Only committed memory (MEM_COMMIT) can be safely read from or written to.
|
|
378
|
+
*
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* function isCommittedMemory(region: Region): boolean {
|
|
382
|
+
* const MEM_COMMIT = 0x1000;
|
|
383
|
+
* return region.state === MEM_COMMIT;
|
|
384
|
+
* }
|
|
385
|
+
*
|
|
386
|
+
* function getStateDescription(state: number): string {
|
|
387
|
+
* switch (state) {
|
|
388
|
+
* case 0x1000: return 'Committed';
|
|
389
|
+
* case 0x2000: return 'Reserved';
|
|
390
|
+
* case 0x10000: return 'Free';
|
|
391
|
+
* default: return `Unknown (0x${state.toString(16)})`;
|
|
392
|
+
* }
|
|
393
|
+
* }
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
state: number;
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Type of the memory region.
|
|
400
|
+
*
|
|
401
|
+
* The type indicates how the memory was allocated and what it contains:
|
|
402
|
+
* - MEM_PRIVATE (0x20000): Private memory allocated by the process
|
|
403
|
+
* - MEM_MAPPED (0x40000): Memory-mapped file
|
|
404
|
+
* - MEM_IMAGE (0x1000000): Memory containing executable image (EXE/DLL)
|
|
405
|
+
*
|
|
406
|
+
* Different types have different characteristics and usage patterns.
|
|
407
|
+
*
|
|
408
|
+
* @example
|
|
409
|
+
* ```typescript
|
|
410
|
+
* function getMemoryTypeDescription(type: number): string {
|
|
411
|
+
* switch (type) {
|
|
412
|
+
* case 0x20000: return 'Private (heap/stack)';
|
|
413
|
+
* case 0x40000: return 'Mapped (file-backed)';
|
|
414
|
+
* case 0x1000000: return 'Image (executable)';
|
|
415
|
+
* default: return `Unknown (0x${type.toString(16)})`;
|
|
416
|
+
* }
|
|
417
|
+
* }
|
|
418
|
+
*
|
|
419
|
+
* function isExecutableImage(region: Region): boolean {
|
|
420
|
+
* const MEM_IMAGE = 0x1000000;
|
|
421
|
+
* return region.type === MEM_IMAGE;
|
|
422
|
+
* }
|
|
423
|
+
* ```
|
|
424
|
+
*/
|
|
425
|
+
type: number;
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Union type of all buffer types that can be used as scratch space for memory operations.
|
|
430
|
+
*
|
|
431
|
+
* This type represents all the binary data views that can be used with the Memory class's
|
|
432
|
+
* low-level read() and write() methods. These types all provide direct access to raw
|
|
433
|
+
* memory buffers and can be passed to FFI functions.
|
|
434
|
+
*
|
|
435
|
+
* The Scratch type ensures type safety when working with different buffer formats while
|
|
436
|
+
* maintaining compatibility with Bun's FFI system through the .ptr property extensions.
|
|
437
|
+
*
|
|
438
|
+
* Supported buffer types:
|
|
439
|
+
* - **BigInt64Array / BigUint64Array**: 64-bit integer arrays
|
|
440
|
+
* - **Buffer**: Node.js-style buffer (Bun-compatible)
|
|
441
|
+
* - **Float32Array / Float64Array**: Floating-point number arrays
|
|
442
|
+
* - **DataView**: Generic binary data view
|
|
443
|
+
* - **Int8Array / Int16Array / Int32Array**: Signed integer arrays
|
|
444
|
+
* - **Uint8Array / Uint16Array / Uint32Array / Uint8ClampedArray**: Unsigned integer arrays
|
|
445
|
+
*
|
|
446
|
+
* @example
|
|
447
|
+
* ```typescript
|
|
448
|
+
* const memory = new Memory('target.exe');
|
|
449
|
+
*
|
|
450
|
+
* // All of these are valid Scratch types:
|
|
451
|
+
* const buffer1: Scratch = new Uint8Array(1024);
|
|
452
|
+
* const buffer2: Scratch = Buffer.allocUnsafe(512);
|
|
453
|
+
* const buffer3: Scratch = new Float32Array(256);
|
|
454
|
+
* const buffer4: Scratch = new DataView(new ArrayBuffer(128));
|
|
455
|
+
*
|
|
456
|
+
* // Can be used with Memory methods:
|
|
457
|
+
* memory.read(0x12345678n, buffer1);
|
|
458
|
+
* memory.read(0x12345679n, buffer2);
|
|
459
|
+
* memory.read(0x1234567An, buffer3);
|
|
460
|
+
* ```
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* ```typescript
|
|
464
|
+
* // Type-safe function that accepts any valid scratch buffer
|
|
465
|
+
* function readMemoryBlock(memory: Memory, address: bigint, buffer: Scratch): void {
|
|
466
|
+
* memory.read(address, buffer);
|
|
467
|
+
* console.log(`Read ${buffer.byteLength} bytes from 0x${address.toString(16)}`);
|
|
468
|
+
* }
|
|
469
|
+
*
|
|
470
|
+
* // Usage with different buffer types
|
|
471
|
+
* const floatData = new Float32Array(10);
|
|
472
|
+
* const byteData = new Uint8Array(40);
|
|
473
|
+
*
|
|
474
|
+
* readMemoryBlock(memory, 0x1000000n, floatData);
|
|
475
|
+
* readMemoryBlock(memory, 0x1000100n, byteData);
|
|
476
|
+
* ```
|
|
477
|
+
*
|
|
478
|
+
* @example
|
|
479
|
+
* ```typescript
|
|
480
|
+
* // Custom memory reader with automatic buffer allocation
|
|
481
|
+
* function createScratchBuffer(size: number, type: 'bytes' | 'floats' | 'ints'): Scratch {
|
|
482
|
+
* switch (type) {
|
|
483
|
+
* case 'bytes': return new Uint8Array(size);
|
|
484
|
+
* case 'floats': return new Float32Array(size);
|
|
485
|
+
* case 'ints': return new Int32Array(size);
|
|
486
|
+
* default: throw new Error('Unknown buffer type');
|
|
487
|
+
* }
|
|
488
|
+
* }
|
|
489
|
+
*
|
|
490
|
+
* const scratchBuffer = createScratchBuffer(1024, 'bytes');
|
|
491
|
+
* memory.read(someAddress, scratchBuffer);
|
|
492
|
+
* ```
|
|
493
|
+
*/
|
|
494
|
+
export type Scratch = BigInt64Array | BigUint64Array | Buffer | Float32Array | Float64Array | DataView | Int16Array | Int32Array | Int8Array | Uint16Array | Uint8Array | Uint8ClampedArray | Uint32Array;
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Represents a 2D vector with x and y components.
|
|
498
|
+
*
|
|
499
|
+
* Vector2 is commonly used for:
|
|
500
|
+
* - 2D positions and coordinates
|
|
501
|
+
* - Screen/UI coordinates
|
|
502
|
+
* - Texture coordinates (UV mapping)
|
|
503
|
+
* - 2D velocities and directions
|
|
504
|
+
* - Size and dimension data
|
|
505
|
+
* - Mouse cursor positions
|
|
506
|
+
*
|
|
507
|
+
* @example
|
|
508
|
+
* ```typescript
|
|
509
|
+
* const memory = new Memory('2d_game.exe');
|
|
510
|
+
*
|
|
511
|
+
* // Read player position in 2D space
|
|
512
|
+
* const playerPos: Vector2 = memory.vector2(0x12345678n);
|
|
513
|
+
* console.log(`Player at (${playerPos.x}, ${playerPos.y})`);
|
|
514
|
+
*
|
|
515
|
+
* // Move player to a new location
|
|
516
|
+
* const newPosition: Vector2 = { x: 100.5, y: 200.7 };
|
|
517
|
+
* memory.vector2(0x12345678n, newPosition);
|
|
518
|
+
* ```
|
|
519
|
+
*
|
|
520
|
+
* @example
|
|
521
|
+
* ```typescript
|
|
522
|
+
* // Read array of waypoints for 2D pathfinding
|
|
523
|
+
* const waypointCount = 10;
|
|
524
|
+
* const waypoints: Vector2[] = memory.vector2Array(0x12345678n, waypointCount);
|
|
525
|
+
*
|
|
526
|
+
* // Process each waypoint
|
|
527
|
+
* waypoints.forEach((point, index) => {
|
|
528
|
+
* console.log(`Waypoint ${index}: (${point.x}, ${point.y})`);
|
|
529
|
+
* });
|
|
530
|
+
*
|
|
531
|
+
* // Add a new waypoint at the end
|
|
532
|
+
* waypoints.push({ x: 500, y: 300 });
|
|
533
|
+
* memory.vector2Array(0x12345678n, waypoints);
|
|
534
|
+
* ```
|
|
535
|
+
*
|
|
536
|
+
* @example
|
|
537
|
+
* ```typescript
|
|
538
|
+
* // Vector math operations
|
|
539
|
+
* function distance2D(a: Vector2, b: Vector2): number {
|
|
540
|
+
* const dx = b.x - a.x;
|
|
541
|
+
* const dy = b.y - a.y;
|
|
542
|
+
* return Math.sqrt(dx * dx + dy * dy);
|
|
543
|
+
* }
|
|
544
|
+
*
|
|
545
|
+
* function add2D(a: Vector2, b: Vector2): Vector2 {
|
|
546
|
+
* return { x: a.x + b.x, y: a.y + b.y };
|
|
547
|
+
* }
|
|
548
|
+
*
|
|
549
|
+
* const playerPos = memory.vector2(0x12345678n);
|
|
550
|
+
* const targetPos = memory.vector2(0x12345688n);
|
|
551
|
+
* const distanceToTarget = distance2D(playerPos, targetPos);
|
|
552
|
+
*
|
|
553
|
+
* console.log(`Distance to target: ${distanceToTarget.toFixed(2)}`);
|
|
554
|
+
* ```
|
|
555
|
+
*/
|
|
556
|
+
export type Vector2 = {
|
|
557
|
+
/**
|
|
558
|
+
* X coordinate component.
|
|
559
|
+
*
|
|
560
|
+
* In most coordinate systems:
|
|
561
|
+
* - Represents horizontal position
|
|
562
|
+
* - Positive values typically go right
|
|
563
|
+
* - For screen coordinates, usually increases left-to-right
|
|
564
|
+
*
|
|
565
|
+
* @example
|
|
566
|
+
* ```typescript
|
|
567
|
+
* const screenPos: Vector2 = { x: 640, y: 480 }; // Center of 1280x960 screen
|
|
568
|
+
* const worldPos: Vector2 = { x: -15.5, y: 23.7 }; // World coordinates
|
|
569
|
+
* ```
|
|
570
|
+
*/
|
|
571
|
+
x: number;
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Y coordinate component.
|
|
575
|
+
*
|
|
576
|
+
* In most coordinate systems:
|
|
577
|
+
* - Represents vertical position
|
|
578
|
+
* - Direction (up/down) depends on the coordinate system
|
|
579
|
+
* - Screen coordinates often have Y increasing downward
|
|
580
|
+
* - World coordinates often have Y increasing upward
|
|
581
|
+
*
|
|
582
|
+
* @example
|
|
583
|
+
* ```typescript
|
|
584
|
+
* // Screen coordinates (Y increases downward)
|
|
585
|
+
* const uiElement: Vector2 = { x: 100, y: 50 }; // 100 pixels right, 50 pixels down
|
|
586
|
+
*
|
|
587
|
+
* // 3D world coordinates (Y often increases upward)
|
|
588
|
+
* const worldPoint: Vector2 = { x: 10, y: 25 }; // 10 units east, 25 units up
|
|
589
|
+
* ```
|
|
590
|
+
*/
|
|
591
|
+
y: number;
|
|
592
|
+
};
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Represents a 3D vector with x, y, and z components.
|
|
596
|
+
*
|
|
597
|
+
* Vector3 is commonly used for:
|
|
598
|
+
* - 3D positions and coordinates
|
|
599
|
+
* - 3D velocities and directions
|
|
600
|
+
* - Surface normals in 3D graphics
|
|
601
|
+
* - RGB color values (though usually normalized to 0-1)
|
|
602
|
+
* - 3D rotations (Euler angles)
|
|
603
|
+
* - Scale factors for 3D objects
|
|
604
|
+
* - Physics forces and accelerations
|
|
605
|
+
*
|
|
606
|
+
* @example
|
|
607
|
+
* ```typescript
|
|
608
|
+
* const memory = new Memory('3d_game.exe');
|
|
609
|
+
*
|
|
610
|
+
* // Read player position in 3D world
|
|
611
|
+
* const playerPos: Vector3 = memory.vector3(0x12345678n);
|
|
612
|
+
* console.log(`Player at (${playerPos.x}, ${playerPos.y}, ${playerPos.z})`);
|
|
613
|
+
*
|
|
614
|
+
* // Teleport player to spawn point
|
|
615
|
+
* const spawnPoint: Vector3 = { x: 0, y: 10, z: 0 };
|
|
616
|
+
* memory.vector3(0x12345678n, spawnPoint);
|
|
617
|
+
* ```
|
|
618
|
+
*
|
|
619
|
+
* @example
|
|
620
|
+
* ```typescript
|
|
621
|
+
* // Read array of 3D model vertices
|
|
622
|
+
* const vertexCount = 1000;
|
|
623
|
+
* const vertices: Vector3[] = memory.vector3Array(0x12345678n, vertexCount);
|
|
624
|
+
*
|
|
625
|
+
* // Find the bounding box of the model
|
|
626
|
+
* let minX = Infinity, minY = Infinity, minZ = Infinity;
|
|
627
|
+
* let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
628
|
+
*
|
|
629
|
+
* vertices.forEach(vertex => {
|
|
630
|
+
* minX = Math.min(minX, vertex.x);
|
|
631
|
+
* maxX = Math.max(maxX, vertex.x);
|
|
632
|
+
* minY = Math.min(minY, vertex.y);
|
|
633
|
+
* maxY = Math.max(maxY, vertex.y);
|
|
634
|
+
* minZ = Math.min(minZ, vertex.z);
|
|
635
|
+
* maxZ = Math.max(maxZ, vertex.z);
|
|
636
|
+
* });
|
|
637
|
+
*
|
|
638
|
+
* console.log(`Bounding box: (${minX}, ${minY}, ${minZ}) to (${maxX}, ${maxY}, ${maxZ})`);
|
|
639
|
+
* ```
|
|
640
|
+
*
|
|
641
|
+
* @example
|
|
642
|
+
* ```typescript
|
|
643
|
+
* // Vector math operations for 3D
|
|
644
|
+
* function distance3D(a: Vector3, b: Vector3): number {
|
|
645
|
+
* const dx = b.x - a.x;
|
|
646
|
+
* const dy = b.y - a.y;
|
|
647
|
+
* const dz = b.z - a.z;
|
|
648
|
+
* return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
649
|
+
* }
|
|
650
|
+
*
|
|
651
|
+
* function normalize3D(v: Vector3): Vector3 {
|
|
652
|
+
* const length = Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
|
|
653
|
+
* if (length === 0) return { x: 0, y: 0, z: 0 };
|
|
654
|
+
* return { x: v.x / length, y: v.y / length, z: v.z / length };
|
|
655
|
+
* }
|
|
656
|
+
*
|
|
657
|
+
* function crossProduct(a: Vector3, b: Vector3): Vector3 {
|
|
658
|
+
* return {
|
|
659
|
+
* x: a.y * b.z - a.z * b.y,
|
|
660
|
+
* y: a.z * b.x - a.x * b.z,
|
|
661
|
+
* z: a.x * b.y - a.y * b.x
|
|
662
|
+
* };
|
|
663
|
+
* }
|
|
664
|
+
*
|
|
665
|
+
* const forward = memory.vector3(0x12345678n);
|
|
666
|
+
* const right = memory.vector3(0x12345688n);
|
|
667
|
+
* const up = crossProduct(forward, right); // Calculate up vector
|
|
668
|
+
* ```
|
|
669
|
+
*
|
|
670
|
+
* @example
|
|
671
|
+
* ```typescript
|
|
672
|
+
* // Color manipulation using Vector3
|
|
673
|
+
* const playerColor: Vector3 = memory.vector3(0x12345678n);
|
|
674
|
+
*
|
|
675
|
+
* // Assuming RGB values are in 0-255 range
|
|
676
|
+
* console.log(`Player color: R=${playerColor.x}, G=${playerColor.y}, B=${playerColor.z}`);
|
|
677
|
+
*
|
|
678
|
+
* // Set player color to bright red
|
|
679
|
+
* const brightRed: Vector3 = { x: 255, y: 0, z: 0 };
|
|
680
|
+
* memory.vector3(0x12345678n, brightRed);
|
|
681
|
+
* ```
|
|
682
|
+
*/
|
|
683
|
+
export type Vector3 = {
|
|
684
|
+
/**
|
|
685
|
+
* X coordinate component.
|
|
686
|
+
*
|
|
687
|
+
* In 3D coordinate systems:
|
|
688
|
+
* - Often represents the horizontal axis (left-right)
|
|
689
|
+
* - In right-handed systems, positive X typically points right
|
|
690
|
+
* - In left-handed systems, positive X typically points right
|
|
691
|
+
* - May represent red component in RGB color contexts
|
|
692
|
+
*
|
|
693
|
+
* @example
|
|
694
|
+
* ```typescript
|
|
695
|
+
* const position: Vector3 = { x: 15.5, y: 0, z: -10 }; // 15.5 units right
|
|
696
|
+
* const color: Vector3 = { x: 255, y: 128, z: 64 }; // Red component = 255
|
|
697
|
+
* ```
|
|
698
|
+
*/
|
|
699
|
+
x: number;
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Y coordinate component.
|
|
703
|
+
*
|
|
704
|
+
* In 3D coordinate systems:
|
|
705
|
+
* - Often represents the vertical axis (up-down)
|
|
706
|
+
* - In right-handed systems, positive Y typically points up
|
|
707
|
+
* - In some graphics systems, positive Y may point down
|
|
708
|
+
* - May represent green component in RGB color contexts
|
|
709
|
+
*
|
|
710
|
+
* @example
|
|
711
|
+
* ```typescript
|
|
712
|
+
* const position: Vector3 = { x: 0, y: 10.5, z: 0 }; // 10.5 units up
|
|
713
|
+
* const color: Vector3 = { x: 255, y: 128, z: 64 }; // Green component = 128
|
|
714
|
+
* ```
|
|
715
|
+
*/
|
|
716
|
+
y: number;
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Z coordinate component.
|
|
720
|
+
*
|
|
721
|
+
* In 3D coordinate systems:
|
|
722
|
+
* - Often represents the depth axis (forward-backward)
|
|
723
|
+
* - In right-handed systems, positive Z typically points toward viewer
|
|
724
|
+
* - In left-handed systems, positive Z typically points away from viewer
|
|
725
|
+
* - May represent blue component in RGB color contexts
|
|
726
|
+
*
|
|
727
|
+
* @example
|
|
728
|
+
* ```typescript
|
|
729
|
+
* const position: Vector3 = { x: 0, y: 0, z: -5.2 }; // 5.2 units away (right-handed)
|
|
730
|
+
* const color: Vector3 = { x: 255, y: 128, z: 64 }; // Blue component = 64
|
|
731
|
+
* ```
|
|
732
|
+
*/
|
|
733
|
+
z: number;
|
|
734
|
+
};
|