bun-memory 1.1.13 → 1.1.15
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 +56 -21
- package/package.json +1 -1
- package/structs/Memory.ts +243 -6
- package/types/Memory.ts +91 -0
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# bun-memory
|
|
2
2
|
|
|
3
|
-
High-performance Windows process memory utilities for [Bun](https://bun.sh) using `bun:ffi` and
|
|
3
|
+
High-performance Windows process memory utilities for [Bun](https://bun.sh) using `bun:ffi` and
|
|
4
|
+
Win32 APIs.
|
|
4
5
|
|
|
5
6
|
## Features
|
|
6
7
|
|
|
@@ -32,40 +33,59 @@ See [example/trigger-bot.ts](example/trigger-bot.ts) for a real-world example fo
|
|
|
32
33
|
import Memory from 'bun-memory';
|
|
33
34
|
|
|
34
35
|
// Attach to process by name…
|
|
35
|
-
const memory = new Memory('
|
|
36
|
+
const memory = new Memory('cs2.exe');
|
|
36
37
|
// …or PID…
|
|
37
38
|
const memory = new Memory(1_234);
|
|
38
39
|
|
|
39
40
|
// Access loaded modules…
|
|
40
41
|
const modules = memory.modules;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
|
|
43
|
+
const client = modules['client.dll'];
|
|
44
|
+
|
|
45
|
+
console.log(`Base address: 0x${client.base.toString(16)}`);
|
|
46
|
+
console.log(`Size: ${client.size} bytes`);
|
|
44
47
|
|
|
45
48
|
// Read a 32-bit integer…
|
|
46
|
-
const value = memory.i32(0x12345678n);
|
|
49
|
+
const value = memory.i32(client.base + 0x12345678n);
|
|
47
50
|
|
|
48
51
|
// Write a float…
|
|
49
|
-
memory.f32(0x12345678n, 3.14159);
|
|
52
|
+
memory.f32(client.base + 0x12345678n, 3.14159);
|
|
50
53
|
|
|
51
54
|
// Clean up…
|
|
52
55
|
memory.close();
|
|
53
56
|
```
|
|
54
57
|
|
|
55
|
-
###
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
### API — Typed Reads / Writes
|
|
59
|
+
|
|
60
|
+
A `Memory` instance exposes typed helpers for reading and writing process memory. Pairs indicate
|
|
61
|
+
scalar and array variants; entries without a pair are scalar-only or array-only.
|
|
62
|
+
|
|
63
|
+
- bool
|
|
64
|
+
- cString
|
|
65
|
+
- f32 / f32Array
|
|
66
|
+
- f64 / f64Array
|
|
67
|
+
- i16 / i16Array
|
|
68
|
+
- i32 / i32Array
|
|
69
|
+
- i64 / i64Array
|
|
70
|
+
- i8 / i8Array
|
|
71
|
+
- matrix3x3
|
|
72
|
+
- matrix3x4
|
|
73
|
+
- matrix4x4
|
|
74
|
+
- networkUtlVector
|
|
75
|
+
- qAngle / qAngleArray
|
|
76
|
+
- quaternion / quaternionArray
|
|
77
|
+
- u16 / u16Array
|
|
78
|
+
- u32 / u32Array
|
|
79
|
+
- u64 / u64Array
|
|
80
|
+
- u8 / u8Array
|
|
81
|
+
- vector2 / vector2Array
|
|
82
|
+
- vector3 / vector3Array
|
|
83
|
+
- vector4 / vector4Array
|
|
84
|
+
|
|
85
|
+
### Efficient Reads / Writes Using Scratches
|
|
86
|
+
|
|
87
|
+
There are many ways to use `scratch`es. Scratches are great for avoiding allocation costs by reusing
|
|
88
|
+
a preexisting array, buffer, string, etc.
|
|
69
89
|
|
|
70
90
|
```ts
|
|
71
91
|
const handles = new Uint32Array(0x100);
|
|
@@ -110,6 +130,21 @@ const scratch = Buffer.allocUnsafe(0x100);
|
|
|
110
130
|
memory.read(myAddress, scratch);
|
|
111
131
|
```
|
|
112
132
|
|
|
133
|
+
```ts
|
|
134
|
+
const scratch = new Uint32Array(0x10);
|
|
135
|
+
memory.read(myAddress, scratch);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Pattern Scanning
|
|
139
|
+
|
|
140
|
+
Pattern scanning is temporarily disabled but will return shortly.
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
const offset = memory.findPattern('aa??bbccdd??ff', mainModule.modBaseAddr, mainModule.modBaseSize);
|
|
144
|
+
const value = memory.bool(offset + 0x1234n);
|
|
145
|
+
memory.close();
|
|
146
|
+
```
|
|
147
|
+
|
|
113
148
|
## Notes
|
|
114
149
|
|
|
115
150
|
- Only works with Bun and Windows.
|
package/package.json
CHANGED
package/structs/Memory.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
// TODO: Reintroduce findPattern(…)…
|
|
2
|
-
// TODO: Reintroduce indexOf(…)…
|
|
3
|
-
// TODO: String methods…
|
|
4
|
-
|
|
5
1
|
import { CString, FFIType, dlopen, read } from 'bun:ffi';
|
|
6
2
|
|
|
7
|
-
import type { Module, NetworkUtlVector, Quaternion, Region, Scratch, Vector2, Vector3 } from '../types/Memory';
|
|
3
|
+
import type { Module, NetworkUtlVector, QAngle, Quaternion, Region, Scratch, Vector2, Vector3, Vector4 } from '../types/Memory';
|
|
8
4
|
import Win32Error from './Win32Error';
|
|
9
5
|
|
|
10
6
|
const { f32, f64, i16, i32, i64, i8, u16, u32, u64, u8 } = read;
|
|
@@ -33,6 +29,8 @@ const { symbols: Kernel32 } = dlopen('kernel32.dll', {
|
|
|
33
29
|
* This class allows reading from and writing to memory addresses in external processes,
|
|
34
30
|
* supporting various data types including primitives, arrays, and custom structures like vectors and quaternions.
|
|
35
31
|
*
|
|
32
|
+
* @todo Reimplement `findPattern(…)`.
|
|
33
|
+
*
|
|
36
34
|
* @example
|
|
37
35
|
* ```typescript
|
|
38
36
|
* // Connect to a process by name
|
|
@@ -168,7 +166,16 @@ class Memory {
|
|
|
168
166
|
private readonly ScratchMemoryBasicInformation = Buffer.allocUnsafe(0x30 /* sizeof(MEMORY_BASIC_INFORMATION) */);
|
|
169
167
|
private readonly ScratchModuleEntry32W = Buffer.allocUnsafe(0x438 /* sizeof(MODULEENTRY32W) */);
|
|
170
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Reusable UTF-16 decoder for interpreting raw process memory as UTF-16 text.
|
|
171
|
+
* Kept as a singleton to avoid repeated allocations in hot paths.
|
|
172
|
+
*/
|
|
171
173
|
private static readonly TextDecoderUTF16 = new TextDecoder('utf-16');
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Reusable UTF-8 decoder for interpreting raw process memory as UTF-8 text.
|
|
177
|
+
* Kept as a singleton to avoid repeated allocations in hot paths.
|
|
178
|
+
*/
|
|
172
179
|
private static readonly TextDecoderUTF8 = new TextDecoder('utf-8');
|
|
173
180
|
|
|
174
181
|
/**
|
|
@@ -314,7 +321,7 @@ class Memory {
|
|
|
314
321
|
return;
|
|
315
322
|
}
|
|
316
323
|
|
|
317
|
-
// Public
|
|
324
|
+
// Public read / write methods…
|
|
318
325
|
|
|
319
326
|
/**
|
|
320
327
|
* Closes the handle to the target process and releases resources.
|
|
@@ -933,6 +940,26 @@ class Memory {
|
|
|
933
940
|
return this;
|
|
934
941
|
}
|
|
935
942
|
|
|
943
|
+
public matrix3x4(address: bigint): Float32Array;
|
|
944
|
+
public matrix3x4(address: bigint, values: Float32Array): this;
|
|
945
|
+
public matrix3x4(address: bigint, values?: Float32Array): Float32Array | this {
|
|
946
|
+
if (values === undefined) {
|
|
947
|
+
const scratch = new Float32Array(0x0c);
|
|
948
|
+
|
|
949
|
+
this.read(address, scratch);
|
|
950
|
+
|
|
951
|
+
return scratch;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
if (values.length !== 0x0c) {
|
|
955
|
+
throw new RangeError('values.length must be 12.');
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
this.write(address, values);
|
|
959
|
+
|
|
960
|
+
return this;
|
|
961
|
+
}
|
|
962
|
+
|
|
936
963
|
/**
|
|
937
964
|
* Reads a 4×4 matrix from memory or writes a 4×4 matrix to memory.
|
|
938
965
|
*
|
|
@@ -1029,6 +1056,103 @@ class Memory {
|
|
|
1029
1056
|
return this;
|
|
1030
1057
|
}
|
|
1031
1058
|
|
|
1059
|
+
/**
|
|
1060
|
+
* Reads a set of Euler angles from memory or writes a set of Euler angles to memory.
|
|
1061
|
+
*
|
|
1062
|
+
* Angles are stored as three 32-bit floats in the order **pitch, yaw, roll**.
|
|
1063
|
+
*
|
|
1064
|
+
* @param address - Memory address to read from or write to
|
|
1065
|
+
* @param value - Optional `QAngle` to write. If omitted, performs a read operation
|
|
1066
|
+
* @returns The `QAngle` value when reading, or this `Memory` instance when writing
|
|
1067
|
+
*
|
|
1068
|
+
* @example
|
|
1069
|
+
* ```typescript
|
|
1070
|
+
* // Read current view angles
|
|
1071
|
+
* const view = memory.qAngle(0x12345678n);
|
|
1072
|
+
*
|
|
1073
|
+
* // Write new view angles (e.g., level the roll)
|
|
1074
|
+
* memory.qAngle(0x12345678n, { ...view, roll: 0 });
|
|
1075
|
+
* ```
|
|
1076
|
+
*/
|
|
1077
|
+
|
|
1078
|
+
public qAngle(address: bigint): QAngle;
|
|
1079
|
+
public qAngle(address: bigint, value: QAngle): this;
|
|
1080
|
+
public qAngle(address: bigint, value?: QAngle): QAngle | this {
|
|
1081
|
+
if (value === undefined) {
|
|
1082
|
+
this.read(address, this.Scratch12);
|
|
1083
|
+
|
|
1084
|
+
const pitch = f32(this.Scratch12.ptr);
|
|
1085
|
+
const roll = f32(this.Scratch12.ptr, 0x08);
|
|
1086
|
+
const yaw = f32(this.Scratch12.ptr, 0x04);
|
|
1087
|
+
|
|
1088
|
+
return { pitch, roll, yaw };
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
this.Scratch12Buffer.writeFloatLE(value.pitch);
|
|
1092
|
+
this.Scratch12Buffer.writeFloatLE(value.roll, 0x08);
|
|
1093
|
+
this.Scratch12Buffer.writeFloatLE(value.yaw, 0x04);
|
|
1094
|
+
|
|
1095
|
+
this.write(address, this.Scratch12);
|
|
1096
|
+
|
|
1097
|
+
return this;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
/**
|
|
1101
|
+
* Reads an array of Euler angles from memory or writes an array of Euler angles to memory.
|
|
1102
|
+
*
|
|
1103
|
+
* Each element is three 32-bit floats in the order **pitch, yaw, roll**.
|
|
1104
|
+
*
|
|
1105
|
+
* @param address - Memory address to read from or write to
|
|
1106
|
+
* @param lengthOrValues - Length of array to read, or array of `QAngle` values to write
|
|
1107
|
+
* @returns `QAngle[]` when reading, or this `Memory` instance when writing
|
|
1108
|
+
*
|
|
1109
|
+
* @example
|
|
1110
|
+
* ```typescript
|
|
1111
|
+
* // Read bone aim offsets
|
|
1112
|
+
* const bones = memory.qAngleArray(0x12345678n, 64);
|
|
1113
|
+
*
|
|
1114
|
+
* // Write new bone angles (e.g., reset all roll to zero)
|
|
1115
|
+
* bones.forEach(b => (b.roll = 0));
|
|
1116
|
+
* memory.qAngleArray(0x12345678n, bones);
|
|
1117
|
+
* ```
|
|
1118
|
+
*/
|
|
1119
|
+
public qAngleArray(address: bigint, length: number): QAngle[];
|
|
1120
|
+
public qAngleArray(address: bigint, values: QAngle[]): this;
|
|
1121
|
+
public qAngleArray(address: bigint, lengthOrValues: QAngle[] | number): QAngle[] | this {
|
|
1122
|
+
if (typeof lengthOrValues === 'number') {
|
|
1123
|
+
const length = lengthOrValues;
|
|
1124
|
+
const scratch = new Float32Array(length * 0x03);
|
|
1125
|
+
|
|
1126
|
+
this.read(address, scratch);
|
|
1127
|
+
|
|
1128
|
+
const result = new Array<QAngle>(length);
|
|
1129
|
+
|
|
1130
|
+
for (let i = 0, j = 0; i < length; i++, j += 0x03) {
|
|
1131
|
+
const pitch = scratch[j];
|
|
1132
|
+
const yaw = scratch[j + 0x01];
|
|
1133
|
+
const roll = scratch[j + 0x02];
|
|
1134
|
+
result[i] = { pitch, yaw, roll };
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
return result;
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
const values = lengthOrValues;
|
|
1141
|
+
const scratch = new Float32Array(values.length * 0x03);
|
|
1142
|
+
|
|
1143
|
+
for (let i = 0, j = 0; i < values.length; i++, j += 0x03) {
|
|
1144
|
+
const qAngle = values[i];
|
|
1145
|
+
|
|
1146
|
+
scratch[j] = qAngle.pitch;
|
|
1147
|
+
scratch[j + 0x02] = qAngle.roll;
|
|
1148
|
+
scratch[j + 0x01] = qAngle.yaw;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
this.write(address, scratch);
|
|
1152
|
+
|
|
1153
|
+
return this;
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1032
1156
|
/**
|
|
1033
1157
|
* Reads a quaternion (4D rotation) from memory or writes a quaternion to memory.
|
|
1034
1158
|
* Quaternions are stored as four 32-bit floats: x, y, z, w.
|
|
@@ -1604,6 +1728,119 @@ class Memory {
|
|
|
1604
1728
|
|
|
1605
1729
|
return this;
|
|
1606
1730
|
}
|
|
1731
|
+
|
|
1732
|
+
/**
|
|
1733
|
+
* Reads a 4D vector from memory or writes a 4D vector to memory.
|
|
1734
|
+
*
|
|
1735
|
+
* Uses the same 16-byte layout as {@link Memory.quaternion}: four 32-bit floats
|
|
1736
|
+
* stored in the order **x, y, z, w**. Returned objects are shaped as `{ w, x, y, z }`.
|
|
1737
|
+
*
|
|
1738
|
+
* @param address - Memory address to read from or write to
|
|
1739
|
+
* @param value - Optional `Vector4` to write. If omitted, performs a read operation
|
|
1740
|
+
* @returns The `Vector4` value when reading, or this `Memory` instance when writing
|
|
1741
|
+
*
|
|
1742
|
+
* @example
|
|
1743
|
+
* ```typescript
|
|
1744
|
+
* // Read directional data in projective space
|
|
1745
|
+
* const value = memory.vector4(0x12345678n);
|
|
1746
|
+
*
|
|
1747
|
+
* // Write a vector4 value (e.g., identity quaternion)
|
|
1748
|
+
* memory.vector4(0x12345678n, { x: 0, y: 0, z: 0, w: 1 });
|
|
1749
|
+
* ```
|
|
1750
|
+
*/
|
|
1751
|
+
public vector4(address: bigint): Vector4;
|
|
1752
|
+
public vector4(address: bigint, value: Vector4): this;
|
|
1753
|
+
public vector4(address: bigint, value?: Vector4): Vector4 | this {
|
|
1754
|
+
// TypeScript is funny sometimes, isn't it?… 🫠…
|
|
1755
|
+
if (value === undefined) {
|
|
1756
|
+
return this.quaternion(address);
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
return this.quaternion(address, value);
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
/**
|
|
1763
|
+
* Reads an array of 4D vectors from memory or writes an array of 4D vectors to memory.
|
|
1764
|
+
*
|
|
1765
|
+
* Each element uses the same 16-byte layout as {@link Memory.quaternionArray}:
|
|
1766
|
+
* four 32-bit floats stored in the order **x, y, z, w**.
|
|
1767
|
+
*
|
|
1768
|
+
* @param address - Memory address to read from or write to
|
|
1769
|
+
* @param lengthOrValues - Length of array to read, or array of `Vector4` values to write
|
|
1770
|
+
* @returns `Vector4[]` when reading, or this `Memory` instance when writing
|
|
1771
|
+
*
|
|
1772
|
+
* @example
|
|
1773
|
+
* ```typescript
|
|
1774
|
+
* // Read per-vertex tangent vectors (xyzw)
|
|
1775
|
+
* const tangents = memory.vector4Array(0x12345678n, 1024);
|
|
1776
|
+
*
|
|
1777
|
+
* // Write tangent vectors (eg. normalize w to 1.0)
|
|
1778
|
+
* tangents.forEach(v => (v.w = 1.0));
|
|
1779
|
+
* memory.vector4Array(0x12345678n, tangents);
|
|
1780
|
+
* ```
|
|
1781
|
+
*/
|
|
1782
|
+
public vector4Array(address: bigint, length: number): Vector4[];
|
|
1783
|
+
public vector4Array(address: bigint, values: Vector4[]): this;
|
|
1784
|
+
public vector4Array(address: bigint, lengthOrValues: Vector4[] | number): Vector4[] | this {
|
|
1785
|
+
// TypeScript is funny sometimes, isn't it?… 🫠…
|
|
1786
|
+
if (typeof lengthOrValues === 'number') {
|
|
1787
|
+
return this.quaternionArray(address, lengthOrValues);
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
return this.quaternionArray(address, lengthOrValues);
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
// Public utility methods…
|
|
1794
|
+
|
|
1795
|
+
/**
|
|
1796
|
+
* Searches a memory range for a byte sequence and returns the absolute address of the first match.
|
|
1797
|
+
*
|
|
1798
|
+
* This method reads `length` bytes starting at `address` into a temporary buffer and performs a
|
|
1799
|
+
* subsequence search. No region or protection checking is performed; ensure the range is readable
|
|
1800
|
+
* before calling.
|
|
1801
|
+
*
|
|
1802
|
+
* The `needle` accepts any Scratch-compatible buffer or view (`Buffer`, `TypedArray`, or `DataView`).
|
|
1803
|
+
* Bytes are matched exactly as laid out in memory. :contentReference[oaicite:0]{index=0}
|
|
1804
|
+
*
|
|
1805
|
+
* @param needle - Byte sequence to search for (Scratch-compatible buffer or view)
|
|
1806
|
+
* @param address - Base memory address to begin searching (inclusive)
|
|
1807
|
+
* @param length - Number of bytes to scan
|
|
1808
|
+
* @returns Absolute address (`bigint`) of the first match, or `-1n` when not found
|
|
1809
|
+
*
|
|
1810
|
+
* @example
|
|
1811
|
+
* ```typescript
|
|
1812
|
+
* // Search a loaded module for a byte sequence
|
|
1813
|
+
* const client = memory.modules['client.dll'];
|
|
1814
|
+
*
|
|
1815
|
+
* const needle = Buffer.from([0x48, 0x8B, 0x05, 0x00, 0x00, 0x00, 0x00]);
|
|
1816
|
+
* const matchAddress = memory.indexOf(needle, client.base, client.size);
|
|
1817
|
+
* ```
|
|
1818
|
+
*
|
|
1819
|
+
* @example
|
|
1820
|
+
* ```typescript
|
|
1821
|
+
* // Search using a Uint32Array needle (bytes are matched exactly as laid out in memory)
|
|
1822
|
+
* const needle = new Uint32Array([0xDEADBEEF, 0x11223344]);
|
|
1823
|
+
* const matchAddress = memory.indexOf(needle, client.base, client.size);
|
|
1824
|
+
* ```
|
|
1825
|
+
*/
|
|
1826
|
+
|
|
1827
|
+
public indexOf(needle: Scratch, address: bigint, length: number): bigint {
|
|
1828
|
+
const haystackUint8Array = new Uint8Array(length);
|
|
1829
|
+
|
|
1830
|
+
this.read(address, haystackUint8Array);
|
|
1831
|
+
|
|
1832
|
+
const haystackBuffer = Buffer.from(haystackUint8Array.buffer, haystackUint8Array.byteOffset, haystackUint8Array.byteLength);
|
|
1833
|
+
|
|
1834
|
+
const needleUint8Array = ArrayBuffer.isView(needle) //
|
|
1835
|
+
? new Uint8Array(needle.buffer, needle.byteOffset, needle.byteLength)
|
|
1836
|
+
: new Uint8Array(needle);
|
|
1837
|
+
|
|
1838
|
+
const needleBuffer = Buffer.from(needleUint8Array.buffer, needleUint8Array.byteOffset, needleUint8Array.byteLength);
|
|
1839
|
+
|
|
1840
|
+
const indexOf = haystackBuffer.indexOf(needleBuffer);
|
|
1841
|
+
|
|
1842
|
+
return indexOf !== -1 ? BigInt(indexOf) + address : -1n;
|
|
1843
|
+
}
|
|
1607
1844
|
}
|
|
1608
1845
|
|
|
1609
1846
|
export default Memory;
|
package/types/Memory.ts
CHANGED
|
@@ -319,6 +319,68 @@ export type Quaternion = {
|
|
|
319
319
|
z: number;
|
|
320
320
|
};
|
|
321
321
|
|
|
322
|
+
/**
|
|
323
|
+
* Represents an orientation using Euler angles.
|
|
324
|
+
*
|
|
325
|
+
* `QAngle` stores three 32-bit floating-point angles that describe rotation
|
|
326
|
+
* in degrees around the principal axes: `pitch` (X), `yaw` (Y), and `roll` (Z).
|
|
327
|
+
* This format is common in Source-engine-style telemetry and many gameplay
|
|
328
|
+
* camera systems. For quaternions, see {@link Quaternion}.
|
|
329
|
+
*
|
|
330
|
+
* Typical uses include:
|
|
331
|
+
* - Camera/view rotations
|
|
332
|
+
* - Bone/attachment orientations
|
|
333
|
+
* - Aim and recoil calculations
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* ```typescript
|
|
337
|
+
* // Read and tweak view angles
|
|
338
|
+
* const view: QAngle = memory.qAngle(0x12345678n);
|
|
339
|
+
* const leveled: QAngle = { pitch: 0, yaw: view.yaw, roll: 0 };
|
|
340
|
+
* memory.qAngle(0x12345678n, leveled);
|
|
341
|
+
* ```
|
|
342
|
+
*/
|
|
343
|
+
export interface QAngle {
|
|
344
|
+
/**
|
|
345
|
+
* Rotation around the X axis, in degrees.
|
|
346
|
+
*
|
|
347
|
+
* Positive values pitch the nose downward in many right-handed game
|
|
348
|
+
* coordinate systems; verify the target engine’s convention before writing.
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
351
|
+
* ```typescript
|
|
352
|
+
* const aimDown: QAngle = { pitch: 10, yaw: 0, roll: 0 };
|
|
353
|
+
* ```
|
|
354
|
+
*/
|
|
355
|
+
pitch: number;
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Rotation around the Z axis, in degrees.
|
|
359
|
+
*
|
|
360
|
+
* Often used for banking/tilt effects. Some engines clamp or ignore roll for
|
|
361
|
+
* first-person cameras.
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* ```typescript
|
|
365
|
+
* const slightBank: QAngle = { pitch: 0, yaw: 0, roll: 5 };
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
roll: number;
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Rotation around the Y axis, in degrees.
|
|
372
|
+
*
|
|
373
|
+
* Positive values typically turn to the right (clockwise when viewed from
|
|
374
|
+
* above) in right-handed systems.
|
|
375
|
+
*
|
|
376
|
+
* @example
|
|
377
|
+
* ```typescript
|
|
378
|
+
* const turnRight: QAngle = { pitch: 0, yaw: 90, roll: 0 };
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
yaw: number;
|
|
382
|
+
}
|
|
383
|
+
|
|
322
384
|
/**
|
|
323
385
|
* Represents a memory region with its properties and protection flags.
|
|
324
386
|
*
|
|
@@ -791,3 +853,32 @@ export type Vector3 = {
|
|
|
791
853
|
*/
|
|
792
854
|
z: number;
|
|
793
855
|
};
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* Represents a 4D vector with w, x, y, z components.
|
|
859
|
+
*
|
|
860
|
+
* Common use cases:
|
|
861
|
+
* - Homogeneous coordinates (w ≠ 0)
|
|
862
|
+
* - Colors with alpha (x = R, y = G, z = B, w = A)
|
|
863
|
+
* - Packed attributes and shader parameters
|
|
864
|
+
* - As a quaternion carrier when interoperating with APIs expecting {x,y,z,w}
|
|
865
|
+
*
|
|
866
|
+
* Memory layout used by {@link Memory.vector4} is four 32-bit floats stored in
|
|
867
|
+
* the order **x, y, z, w**, while this type exposes `{ w, x, y, z }` for
|
|
868
|
+
* consistency with {@link Quaternion}.
|
|
869
|
+
*
|
|
870
|
+
* @example
|
|
871
|
+
* ```typescript
|
|
872
|
+
* // RGBA color
|
|
873
|
+
* const red: Vector4 = { x: 255, y: 0, z: 0, w: 255 };
|
|
874
|
+
*
|
|
875
|
+
* // Homogeneous point (x, y, z, w)
|
|
876
|
+
* const p: Vector4 = { x: 10, y: 20, z: 30, w: 1 };
|
|
877
|
+
* ```
|
|
878
|
+
*/
|
|
879
|
+
export type Vector4 = {
|
|
880
|
+
w: number;
|
|
881
|
+
x: number;
|
|
882
|
+
y: number;
|
|
883
|
+
z: number;
|
|
884
|
+
};
|