bun-memory 1.1.49 → 2.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/example/benchmark.ts +11 -16
- package/example/trigger-bot.ts +11 -17
- package/index.ts +5 -2
- package/package.json +1 -1
- package/structs/Module.ts +40 -0
- package/structs/{Memory.ts → Process.ts} +3332 -3037
- package/structs/Win32Error.ts +1 -1
- package/types/{Memory.ts → Process.ts} +26 -31
package/example/benchmark.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// ! This benchmark may take 1-2+ minutes. It repeatedly traverses the entire entity list in
|
|
3
3
|
// ! Counter-Strike 2, storing it into `EntityClassInfoNames`…
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import Process from 'bun-memory';
|
|
6
6
|
|
|
7
7
|
// Get the latest client_dll.json and offsets.json from:
|
|
8
8
|
// https://github.com/a2x/cs2-dumper/tree/main/output
|
|
@@ -21,27 +21,22 @@ const Client = {
|
|
|
21
21
|
} & { Other: { [K in keyof (typeof OffsetsJSON)['client.dll']]: bigint } };
|
|
22
22
|
|
|
23
23
|
// Open a handle to cs2.exe…
|
|
24
|
-
const cs2 = new
|
|
24
|
+
const cs2 = new Process('cs2.exe');
|
|
25
25
|
|
|
26
|
-
// Get the
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
// Make sure client.dll is loaded…
|
|
30
|
-
if (ClientPtr === undefined) {
|
|
31
|
-
throw new TypeError('ClientPtr must not be undefined.');
|
|
32
|
-
}
|
|
26
|
+
// Get the client.dll module…
|
|
27
|
+
const client = cs2.module('client.dll');
|
|
33
28
|
|
|
34
29
|
// Warmup…
|
|
35
30
|
console.log('Warming up…');
|
|
36
31
|
|
|
37
32
|
for (let i = 0; i < Iterations; i++) {
|
|
38
|
-
const GlobalVarsPtr =
|
|
33
|
+
const GlobalVarsPtr = client.u64(Client.Other.dwGlobalVars);
|
|
39
34
|
/* */ const CurTime = cs2.f32(GlobalVarsPtr + 0x30n);
|
|
40
35
|
|
|
41
|
-
const lPlayerControllerPtr =
|
|
36
|
+
const lPlayerControllerPtr = client.u64(Client.Other.dwLocalPlayerController);
|
|
42
37
|
/* */ const lPlayerName = cs2.string(lPlayerControllerPtr + Client.CBasePlayerController.m_iszPlayerName, 32);
|
|
43
38
|
|
|
44
|
-
const lPlayerPawnPtr =
|
|
39
|
+
const lPlayerPawnPtr = client.u64(Client.Other.dwLocalPlayerPawn);
|
|
45
40
|
/* */ const lHealth = cs2.u32(lPlayerPawnPtr + Client.C_BaseEntity.m_iHealth);
|
|
46
41
|
/* */ const lTeamNum = cs2.u8(lPlayerPawnPtr + Client.C_BaseEntity.m_iTeamNum);
|
|
47
42
|
}
|
|
@@ -60,7 +55,7 @@ for (let i = 0; i < 5; i++) {
|
|
|
60
55
|
|
|
61
56
|
const start = performance.now();
|
|
62
57
|
|
|
63
|
-
const EntityListPtr =
|
|
58
|
+
const EntityListPtr = client.u64(Client.Other.dwEntityList);
|
|
64
59
|
|
|
65
60
|
for (let j = 0; j < Iterations; j++) {
|
|
66
61
|
try {
|
|
@@ -69,7 +64,7 @@ for (let i = 0; i < 5; i++) {
|
|
|
69
64
|
|
|
70
65
|
// Traverse each of the potential 64 entity chunks…
|
|
71
66
|
for (let k = 0; k < 0x40; k++) {
|
|
72
|
-
const EntityChunkPtr = EntityListScratch[k]
|
|
67
|
+
const EntityChunkPtr = EntityListScratch[k]!;
|
|
73
68
|
|
|
74
69
|
if (EntityChunkPtr === 0n) {
|
|
75
70
|
continue;
|
|
@@ -79,13 +74,13 @@ for (let i = 0; i < 5; i++) {
|
|
|
79
74
|
|
|
80
75
|
// Traverse the potential 512 entities in that chunk…
|
|
81
76
|
for (let j = 0x00, l = 0x00; j < 0x200; j++, l += 0x0e) {
|
|
82
|
-
const BaseEntityPtr = EntityChunkScratch[l]
|
|
77
|
+
const BaseEntityPtr = EntityChunkScratch[l]!;
|
|
83
78
|
|
|
84
79
|
if (BaseEntityPtr === 0n) {
|
|
85
80
|
continue;
|
|
86
81
|
}
|
|
87
82
|
|
|
88
|
-
const EntityClassInfoPtr = EntityChunkScratch[l + 0x01]
|
|
83
|
+
const EntityClassInfoPtr = EntityChunkScratch[l + 0x01]!;
|
|
89
84
|
|
|
90
85
|
let Name = EntityClassInfoNames.get(EntityClassInfoPtr);
|
|
91
86
|
|
package/example/trigger-bot.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FFIType, dlopen, ptr } from 'bun:ffi';
|
|
2
2
|
import { sleep } from 'bun';
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import Process from 'bun-memory';
|
|
5
5
|
|
|
6
6
|
// Get the latest client_dll.json and offsets.json from:
|
|
7
7
|
// https://github.com/a2x/cs2-dumper/tree/main/output
|
|
@@ -29,34 +29,28 @@ const Client = {
|
|
|
29
29
|
} & { Other: { [K in keyof (typeof OffsetsJSON)['client.dll']]: bigint } };
|
|
30
30
|
|
|
31
31
|
// Open a handle to cs2.exe…
|
|
32
|
-
const cs2 = new
|
|
32
|
+
const cs2 = new Process('cs2.exe');
|
|
33
33
|
|
|
34
|
-
// Get the
|
|
35
|
-
const client = cs2.
|
|
36
|
-
|
|
37
|
-
if (client === undefined) {
|
|
38
|
-
throw new TypeError('client must not be undefined.');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const ClientPtr = client.base;
|
|
34
|
+
// Get the client.dll module…
|
|
35
|
+
const client = cs2.module('client.dll');
|
|
42
36
|
|
|
43
37
|
// Create a cache for class name strings… 🫠…
|
|
44
38
|
const Cache_Names = new Map<bigint, string>();
|
|
45
39
|
|
|
46
40
|
let ticks = 0;
|
|
47
41
|
|
|
48
|
-
async function tick(
|
|
42
|
+
async function tick() {
|
|
49
43
|
try {
|
|
50
44
|
ticks++;
|
|
51
45
|
|
|
52
46
|
// Read relevant info from memory…
|
|
53
|
-
const GlobalVarsPtr =
|
|
47
|
+
const GlobalVarsPtr = client.u64(Client.Other.dwGlobalVars);
|
|
54
48
|
/* */ const CurTime = cs2.f32(GlobalVarsPtr + 0x30n);
|
|
55
49
|
|
|
56
|
-
const Local_PlayerControllerPtr =
|
|
50
|
+
const Local_PlayerControllerPtr = client.u64(Client.Other.dwLocalPlayerController);
|
|
57
51
|
/* */ const Local_TickBase = cs2.u32(Local_PlayerControllerPtr + Client.CBasePlayerController.m_nTickBase);
|
|
58
52
|
|
|
59
|
-
const Local_PlayerPawnPtr =
|
|
53
|
+
const Local_PlayerPawnPtr = client.u64(Client.Other.dwLocalPlayerPawn);
|
|
60
54
|
/* */ const Local_FlashOverlayAlpha = cs2.f32(Local_PlayerPawnPtr + Client.C_CSPlayerPawnBase.m_flFlashOverlayAlpha);
|
|
61
55
|
/* */ const Local_IDEntIndex = cs2.i32(Local_PlayerPawnPtr + Client.C_CSPlayerPawn.m_iIDEntIndex);
|
|
62
56
|
/* */ const Local_IsScoped = cs2.i32(Local_PlayerPawnPtr + Client.C_CSPlayerPawn.m_bIsScoped);
|
|
@@ -89,7 +83,7 @@ async function tick(ClientPtr: bigint) {
|
|
|
89
83
|
// Weapon types: https://swiftlys2.net/sdk/cs2/types/csweapontype
|
|
90
84
|
|
|
91
85
|
// Get the entity that we're aiming at from the entity list…
|
|
92
|
-
const EntityListPtr =
|
|
86
|
+
const EntityListPtr = client.u64(Client.Other.dwEntityList);
|
|
93
87
|
/* */ const EntityChunkPtr = cs2.u64(EntityListPtr + (BigInt(Local_IDEntIndex) >> 0x09n) * 0x08n + 0x10n);
|
|
94
88
|
/* */ const BaseEntityPtr = cs2.u64(EntityChunkPtr + (BigInt(Local_IDEntIndex) & 0x1ffn) * 0x70n);
|
|
95
89
|
/* */ const EntityClassInfoPtr = cs2.u64(EntityChunkPtr + (BigInt(Local_IDEntIndex) & 0x1ffn) * 0x70n + 0x08n);
|
|
@@ -132,12 +126,12 @@ async function tick(ClientPtr: bigint) {
|
|
|
132
126
|
// console.error(error);
|
|
133
127
|
return;
|
|
134
128
|
} finally {
|
|
135
|
-
setImmediate(tick
|
|
129
|
+
setImmediate(tick);
|
|
136
130
|
}
|
|
137
131
|
}
|
|
138
132
|
|
|
139
133
|
// Start the tick loop…
|
|
140
|
-
setImmediate(tick
|
|
134
|
+
setImmediate(tick);
|
|
141
135
|
|
|
142
136
|
// Log ticks per second…
|
|
143
137
|
setInterval(() => {
|
package/index.ts
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type Process from './Process';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents a loaded module in a process.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const cs2 = new Process('cs2.exe');
|
|
9
|
+
* const client = cs2.module('client.dll');
|
|
10
|
+
* console.log(client.modBaseAddr, client.modBaseSize, client.szExePath);
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
class Module {
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new Module instance.
|
|
16
|
+
* @param process Parent process instance.
|
|
17
|
+
* @param hModule Module handle.
|
|
18
|
+
* @param modBaseAddr Base address of the module.
|
|
19
|
+
* @param modBaseSize Module size in bytes.
|
|
20
|
+
* @param szExePath Full path to the module.
|
|
21
|
+
* @param szModule Module filename.
|
|
22
|
+
*/
|
|
23
|
+
constructor(
|
|
24
|
+
public readonly process: Process,
|
|
25
|
+
public readonly hModule: bigint,
|
|
26
|
+
public readonly modBaseAddr: bigint,
|
|
27
|
+
public readonly modBaseSize: number,
|
|
28
|
+
public readonly szExePath: string,
|
|
29
|
+
public readonly szModule: string,
|
|
30
|
+
) {
|
|
31
|
+
this.modEndAddr = modBaseAddr + BigInt(modBaseSize);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* End address of the module (modBaseAddr + modBaseSize).
|
|
36
|
+
*/
|
|
37
|
+
public readonly modEndAddr: bigint;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export default Module;
|