rocketleaguesdk 1.0.0 → 1.0.1
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/examples/basic.ts +35 -47
- package/package.json +2 -2
package/examples/basic.ts
CHANGED
|
@@ -1,47 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Basic SDK Usage Example
|
|
3
3
|
*
|
|
4
|
-
* This example demonstrates
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* All memory reading logic is inline so you can see exactly how it works.
|
|
4
|
+
* This example demonstrates how to read game data from Rocket League
|
|
5
|
+
* using the generated SDK types and offsets.
|
|
8
6
|
*
|
|
9
7
|
* Run with: bun run examples/basic.ts
|
|
10
8
|
*/
|
|
11
9
|
|
|
12
|
-
import Memory from
|
|
13
|
-
|
|
14
|
-
// Import SDK types for type safety
|
|
15
|
-
import type { Structs } from '..';
|
|
16
|
-
|
|
17
|
-
// =============================================================================
|
|
18
|
-
// OFFSETS (from SDK generation)
|
|
19
|
-
// =============================================================================
|
|
20
|
-
|
|
21
|
-
// GNames and GObjects offsets discovered during SDK generation
|
|
22
|
-
// See: types/offsets.ts for the full list
|
|
23
|
-
const GNAMES_OFFSET = 0x23ed570n;
|
|
24
|
-
const GOBJECTS_OFFSET = 0x23ed5b8n;
|
|
25
|
-
|
|
26
|
-
// UObject layout (UE3 structure)
|
|
27
|
-
// These are the byte offsets to each field within a UObject
|
|
28
|
-
const UObject = {
|
|
29
|
-
Outer: 0x40, // Pointer to outer object (package/owner)
|
|
30
|
-
Name: 0x48, // FName index - lookup in GNames to get string name
|
|
31
|
-
Class: 0x50, // Pointer to the UClass that describes this object
|
|
32
|
-
} as const;
|
|
10
|
+
import Memory from "bun-memory";
|
|
33
11
|
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
12
|
+
// Import SDK types and offsets
|
|
13
|
+
import type { Structs } from "..";
|
|
14
|
+
import {
|
|
15
|
+
GNAMES_OFFSET,
|
|
16
|
+
GOBJECTS_OFFSET,
|
|
17
|
+
UObject,
|
|
18
|
+
FNameEntry,
|
|
19
|
+
} from "../types/offsets";
|
|
38
20
|
|
|
39
21
|
// CarComponent_Boost_TA offsets
|
|
40
22
|
// Found in: classes/TAGame.ts - search for "CarComponent_Boost_TA"
|
|
41
|
-
// These offsets define where boost-related data is stored in the component
|
|
42
23
|
const BoostOffsets = {
|
|
43
|
-
CurrentBoostAmount: 0x0338,
|
|
44
|
-
MaxBoostAmount:
|
|
24
|
+
CurrentBoostAmount: 0x0338, // float - current boost (0.0 to MaxBoostAmount)
|
|
25
|
+
MaxBoostAmount: 0x032c, // float - maximum boost capacity
|
|
45
26
|
} as const;
|
|
46
27
|
|
|
47
28
|
// =============================================================================
|
|
@@ -49,11 +30,11 @@ const BoostOffsets = {
|
|
|
49
30
|
// =============================================================================
|
|
50
31
|
|
|
51
32
|
// Open the process
|
|
52
|
-
const rl = new Memory(
|
|
53
|
-
const module = rl.modules[
|
|
33
|
+
const rl = new Memory("RocketLeague.exe");
|
|
34
|
+
const module = rl.modules["RocketLeague.exe"];
|
|
54
35
|
|
|
55
36
|
if (!module) {
|
|
56
|
-
throw new Error(
|
|
37
|
+
throw new Error("RocketLeague.exe not found. Is the game running?");
|
|
57
38
|
}
|
|
58
39
|
|
|
59
40
|
const base = module.base;
|
|
@@ -62,7 +43,7 @@ const base = module.base;
|
|
|
62
43
|
const gNamesPtr = rl.uPtr(base + GNAMES_OFFSET);
|
|
63
44
|
const gObjectsPtr = rl.uPtr(base + GOBJECTS_OFFSET);
|
|
64
45
|
|
|
65
|
-
console.log(
|
|
46
|
+
console.log("=== Rocket League SDK Example ===");
|
|
66
47
|
console.log(`Base: 0x${base.toString(16).toUpperCase()}`);
|
|
67
48
|
console.log(`GNames: 0x${gNamesPtr.toString(16).toUpperCase()}`);
|
|
68
49
|
console.log(`GObjects: 0x${gObjectsPtr.toString(16).toUpperCase()}`);
|
|
@@ -92,8 +73,8 @@ function getName(index: number): string {
|
|
|
92
73
|
// Read up to 256 characters (512 bytes for UTF-16)
|
|
93
74
|
const buf = Buffer.allocUnsafe(512);
|
|
94
75
|
rl.read(namePtr, buf);
|
|
95
|
-
const str = buf.toString(
|
|
96
|
-
const nullIdx = str.indexOf(
|
|
76
|
+
const str = buf.toString("utf16le");
|
|
77
|
+
const nullIdx = str.indexOf("\0");
|
|
97
78
|
return nullIdx >= 0 ? str.slice(0, nullIdx) : str;
|
|
98
79
|
} catch {
|
|
99
80
|
return "<error>";
|
|
@@ -151,7 +132,7 @@ function getObjectFullName(objPtr: bigint): string {
|
|
|
151
132
|
outer = rl.uPtr(outer + BigInt(UObject.Outer));
|
|
152
133
|
}
|
|
153
134
|
|
|
154
|
-
const path = outers.length > 0 ? outers.join(
|
|
135
|
+
const path = outers.length > 0 ? outers.join(".") + "." + name : name;
|
|
155
136
|
return `${className} ${path}`;
|
|
156
137
|
} catch {
|
|
157
138
|
return "<error>";
|
|
@@ -166,7 +147,9 @@ function getObjectFullName(objPtr: bigint): string {
|
|
|
166
147
|
* @param className - The class name to search for
|
|
167
148
|
* @yields Object pointer and full name
|
|
168
149
|
*/
|
|
169
|
-
function* findByClass(
|
|
150
|
+
function* findByClass(
|
|
151
|
+
className: string
|
|
152
|
+
): Generator<{ ptr: bigint; fullName: string }> {
|
|
170
153
|
const MAX_OBJECTS = 500_000;
|
|
171
154
|
|
|
172
155
|
for (let i = 0; i < MAX_OBJECTS; i++) {
|
|
@@ -207,27 +190,32 @@ function readFVector(address: bigint): Structs.Core.FVector {
|
|
|
207
190
|
// MAIN: FIND AND DISPLAY BOOST AMOUNTS
|
|
208
191
|
// =============================================================================
|
|
209
192
|
|
|
210
|
-
console.log(
|
|
211
|
-
console.log(
|
|
193
|
+
console.log("Searching for CarComponent_Boost_TA objects...");
|
|
194
|
+
console.log("(Make sure you are in a match to see results)");
|
|
212
195
|
console.log();
|
|
213
196
|
|
|
214
197
|
let found = 0;
|
|
215
|
-
for (const { ptr, fullName } of findByClass(
|
|
198
|
+
for (const { ptr, fullName } of findByClass("CarComponent_Boost_TA")) {
|
|
216
199
|
// Read boost values using the offsets from classes/TAGame.ts
|
|
217
200
|
const currentBoost = rl.f32(ptr + BigInt(BoostOffsets.CurrentBoostAmount));
|
|
218
201
|
const maxBoost = rl.f32(ptr + BigInt(BoostOffsets.MaxBoostAmount));
|
|
219
|
-
const percentage =
|
|
202
|
+
const percentage =
|
|
203
|
+
maxBoost > 0 ? ((currentBoost / maxBoost) * 100).toFixed(1) : "0";
|
|
220
204
|
|
|
221
205
|
console.log(`Found: ${fullName}`);
|
|
222
206
|
console.log(` Address: 0x${ptr.toString(16).toUpperCase()}`);
|
|
223
|
-
console.log(
|
|
207
|
+
console.log(
|
|
208
|
+
` Boost: ${currentBoost.toFixed(2)} / ${maxBoost.toFixed(
|
|
209
|
+
2
|
|
210
|
+
)} (${percentage}%)`
|
|
211
|
+
);
|
|
224
212
|
console.log();
|
|
225
213
|
found++;
|
|
226
214
|
}
|
|
227
215
|
|
|
228
216
|
if (found === 0) {
|
|
229
|
-
console.log(
|
|
230
|
-
console.log(
|
|
217
|
+
console.log("No boost components found.");
|
|
218
|
+
console.log("Make sure you are in a match (not main menu or replay).");
|
|
231
219
|
} else {
|
|
232
220
|
console.log(`Total: ${found} boost component(s) found`);
|
|
233
221
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rocketleaguesdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "TypeScript SDK for Rocket League - Auto-generated type definitions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -97,4 +97,4 @@
|
|
|
97
97
|
"bun-memory": "^1",
|
|
98
98
|
"typescript": "^5"
|
|
99
99
|
}
|
|
100
|
-
}
|
|
100
|
+
}
|