robloxmemoryapi 0.2.2__tar.gz → 0.2.3__tar.gz
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.
- {robloxmemoryapi-0.2.2/src/robloxmemoryapi.egg-info → robloxmemoryapi-0.2.3}/PKG-INFO +1 -1
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/pyproject.toml +1 -1
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/rbx/datastructures.py +25 -1
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/rbx/fflags.py +23 -29
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/rbx/instance.py +379 -22
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3/src/robloxmemoryapi.egg-info}/PKG-INFO +1 -1
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/LICENSE.md +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/README.md +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/setup.cfg +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/__init__.py +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/__init__.py +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/luau/__init__.py +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/luau/parser.py +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/memory.py +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/offsets.py +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/rbx/__init__.py +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/rbx/bytecode/decryptor.py +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/rbx/bytecode/encryptor.py +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi.egg-info/SOURCES.txt +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi.egg-info/dependency_links.txt +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi.egg-info/requires.txt +0 -0
- {robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: robloxmemoryapi
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Python Library that abstracts reading and writing data from the Roblox DataModel
|
|
5
5
|
Author-email: upio <notpoiu@users.noreply.github.com>, mstudio45 <mstudio45@users.noreply.github.com>, ActualMasterOogway <ActualMasterOogway@users.noreply.github.com>
|
|
6
6
|
License: Copyright 2025 upio, mstudio45, master oogway
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "robloxmemoryapi"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.3"
|
|
8
8
|
description = "Python Library that abstracts reading and writing data from the Roblox DataModel"
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
requires-python = ">=3.9"
|
{robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/rbx/datastructures.py
RENAMED
|
@@ -389,4 +389,28 @@ class AnimationTrack:
|
|
|
389
389
|
|
|
390
390
|
@property
|
|
391
391
|
def IsPlaying(self):
|
|
392
|
-
return self.memory_module.read_bool(self.raw_address, self._offsets["IsPlaying"])
|
|
392
|
+
return self.memory_module.read_bool(self.raw_address, self._offsets["IsPlaying"])
|
|
393
|
+
|
|
394
|
+
class FFlag:
|
|
395
|
+
__slots__ = ("name", "type", "_value", "offset", "_manager")
|
|
396
|
+
|
|
397
|
+
def __init__(self, name: str, flag_type: str, value, offset: int, manager=None):
|
|
398
|
+
self.name = name
|
|
399
|
+
self.type = flag_type
|
|
400
|
+
self._value = value
|
|
401
|
+
self.offset = offset
|
|
402
|
+
self._manager = manager
|
|
403
|
+
|
|
404
|
+
@property
|
|
405
|
+
def value(self):
|
|
406
|
+
return self._value
|
|
407
|
+
|
|
408
|
+
@value.setter
|
|
409
|
+
def value(self, new_value):
|
|
410
|
+
if self._manager is None:
|
|
411
|
+
raise RuntimeError("Cannot set value: FFlag not bound to an FFlagManager")
|
|
412
|
+
result = self._manager.set(self.name, new_value)
|
|
413
|
+
self._value = result._value
|
|
414
|
+
|
|
415
|
+
def __repr__(self):
|
|
416
|
+
return f"FFlag(name={self.name!r}, type={self.type!r}, value={self._value!r})"
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
from ..offsets import get_fflag_offsets
|
|
2
|
+
from .datastructures import FFlag
|
|
2
3
|
|
|
3
4
|
_MODULE_SIZE_LIMIT = 0x20000000
|
|
4
5
|
|
|
5
6
|
# FLog level byte → display name.
|
|
6
7
|
_FLOG_LEVELS = {
|
|
7
|
-
|
|
8
|
-
1: "Trace",
|
|
9
|
-
2: "Info",
|
|
8
|
+
2: "Error",
|
|
10
9
|
3: "Warning",
|
|
11
|
-
4: "
|
|
12
|
-
5: "
|
|
13
|
-
6: "
|
|
10
|
+
4: "Info",
|
|
11
|
+
5: "Debug",
|
|
12
|
+
6: "Verbose",
|
|
13
|
+
255: "None",
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
_VALID_FLOG_LEVELS = set(_FLOG_LEVELS.keys())
|
|
17
|
+
|
|
16
18
|
_FLOG_LEVELS_REV = {v: k for k, v in _FLOG_LEVELS.items()}
|
|
17
19
|
|
|
18
20
|
def _decode_flog(raw_int: int) -> str:
|
|
@@ -32,17 +34,6 @@ def _encode_flog(value: str) -> int:
|
|
|
32
34
|
return (level_byte << 8) | (param & 0xFF)
|
|
33
35
|
|
|
34
36
|
|
|
35
|
-
class FFlag:
|
|
36
|
-
__slots__ = ("name", "type", "value", "offset")
|
|
37
|
-
|
|
38
|
-
def __init__(self, name: str, flag_type: str, value, offset: int):
|
|
39
|
-
self.name = name
|
|
40
|
-
self.type = flag_type # "bool", "int", or "string"
|
|
41
|
-
self.value = value
|
|
42
|
-
self.offset = offset
|
|
43
|
-
|
|
44
|
-
def __repr__(self):
|
|
45
|
-
return f"FFlag(name={self.name!r}, type={self.type!r}, value={self.value!r})"
|
|
46
37
|
|
|
47
38
|
class FFlagManager:
|
|
48
39
|
def __init__(self, memory_module):
|
|
@@ -77,7 +68,11 @@ class FFlagManager:
|
|
|
77
68
|
return "bool", bool(raw[0])
|
|
78
69
|
else:
|
|
79
70
|
raw_int = int.from_bytes(raw[0:4], "little")
|
|
80
|
-
|
|
71
|
+
level_byte = (raw_int >> 8) & 0xFF
|
|
72
|
+
if level_byte in _VALID_FLOG_LEVELS:
|
|
73
|
+
return "flog", _decode_flog(raw_int)
|
|
74
|
+
else:
|
|
75
|
+
return "int", int.from_bytes(raw[0:4], "little", signed=True)
|
|
81
76
|
else:
|
|
82
77
|
str_len = int.from_bytes(raw[16:24], "little")
|
|
83
78
|
str_cap = int.from_bytes(raw[24:32], "little")
|
|
@@ -104,7 +99,7 @@ class FFlagManager:
|
|
|
104
99
|
if offset is None:
|
|
105
100
|
return None
|
|
106
101
|
flag_type, value = self._reflect(name, offset)
|
|
107
|
-
return FFlag(name, flag_type, value, offset)
|
|
102
|
+
return FFlag(name, flag_type, value, offset, manager=self)
|
|
108
103
|
|
|
109
104
|
def get_many(self, *names: str) -> dict[str, FFlag]:
|
|
110
105
|
self._ensure_offsets()
|
|
@@ -121,7 +116,7 @@ class FFlagManager:
|
|
|
121
116
|
for name, offset in self._offsets.items():
|
|
122
117
|
try:
|
|
123
118
|
flag_type, value = self._reflect(name, offset)
|
|
124
|
-
out[name] = FFlag(name, flag_type, value, offset)
|
|
119
|
+
out[name] = FFlag(name, flag_type, value, offset, manager=self)
|
|
125
120
|
except OSError:
|
|
126
121
|
pass
|
|
127
122
|
return out
|
|
@@ -146,22 +141,21 @@ class FFlagManager:
|
|
|
146
141
|
self._mem.write_int(addr, value)
|
|
147
142
|
|
|
148
143
|
elif flag_type == "string":
|
|
149
|
-
if not isinstance(value,
|
|
150
|
-
raise TypeError(f"Expected str
|
|
144
|
+
if not isinstance(value, str):
|
|
145
|
+
raise TypeError(f"Expected str for flag '{name}', got {type(value).__name__}")
|
|
151
146
|
|
|
152
|
-
|
|
153
|
-
is_flog = isinstance(current, str) and "," in current
|
|
147
|
+
self._mem.write_string(addr, str(value))
|
|
154
148
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
self._mem.write_string(addr, str(value))
|
|
149
|
+
elif flag_type == "flog":
|
|
150
|
+
if not isinstance(value, (str, int)):
|
|
151
|
+
raise TypeError(f"Expected str or int for flag '{name}', got {type(value).__name__}")
|
|
159
152
|
|
|
153
|
+
self._mem.write_int(addr, _encode_flog(str(value)) if isinstance(value, str) else value)
|
|
160
154
|
else:
|
|
161
155
|
raise RuntimeError(f"Cannot write to flag with unknown type '{flag_type}'")
|
|
162
156
|
|
|
163
157
|
new_type, new_value = self._reflect(name, offset)
|
|
164
|
-
return FFlag(name, new_type, new_value, offset)
|
|
158
|
+
return FFlag(name, new_type, new_value, offset, manager=self)
|
|
165
159
|
|
|
166
160
|
def __getitem__(self, name: str) -> FFlag:
|
|
167
161
|
flag = self.get(name)
|
|
@@ -7,6 +7,7 @@ from .bytecode import decryptor, encryptor
|
|
|
7
7
|
|
|
8
8
|
instance_offsets = Offsets["Instance"]
|
|
9
9
|
basepart_offsets = Offsets["BasePart"]
|
|
10
|
+
primitive_offsets = Offsets["Primitive"]
|
|
10
11
|
camera_offsets = Offsets["Camera"]
|
|
11
12
|
gui_offsets = Offsets["GuiObject"]
|
|
12
13
|
misc_offsets = Offsets["Misc"]
|
|
@@ -18,6 +19,8 @@ statsitem_offsets = Offsets["StatsItem"]
|
|
|
18
19
|
inputobject_offsets = Offsets["MouseService"] # InputObject uses MouseService offsets
|
|
19
20
|
animator_offsets = Offsets["Animator"]
|
|
20
21
|
animationtrack_offsets = Offsets["AnimationTrack"]
|
|
22
|
+
tool_offsets = Offsets["Tool"]
|
|
23
|
+
world_offsets = Offsets["World"]
|
|
21
24
|
|
|
22
25
|
ROTATION_MATRIX_FLOATS = 9
|
|
23
26
|
|
|
@@ -141,6 +144,11 @@ class RBXInstance:
|
|
|
141
144
|
else:
|
|
142
145
|
raise TypeError("Parent must be set to an RBXInstance, int address, or None.")
|
|
143
146
|
self._ensure_writable()
|
|
147
|
+
|
|
148
|
+
current_parent = self.Parent
|
|
149
|
+
if current_parent is not None:
|
|
150
|
+
current_parent.Children.remove(self)
|
|
151
|
+
|
|
144
152
|
self.memory_module.write_long(
|
|
145
153
|
self.raw_address + instance_offsets["Parent"],
|
|
146
154
|
target
|
|
@@ -181,11 +189,11 @@ class RBXInstance:
|
|
|
181
189
|
|
|
182
190
|
if "part" in className.lower():
|
|
183
191
|
CFrameRotation = self.memory_module.read_floats(
|
|
184
|
-
self.primitive_address +
|
|
192
|
+
self.primitive_address + primitive_offsets["Rotation"],
|
|
185
193
|
ROTATION_MATRIX_FLOATS
|
|
186
194
|
)
|
|
187
195
|
PositionData = self.memory_module.read_floats(
|
|
188
|
-
self.primitive_address +
|
|
196
|
+
self.primitive_address + primitive_offsets["Position"],
|
|
189
197
|
3
|
|
190
198
|
)
|
|
191
199
|
elif className == "Camera":
|
|
@@ -226,8 +234,8 @@ class RBXInstance:
|
|
|
226
234
|
|
|
227
235
|
className = self.ClassName
|
|
228
236
|
if "part" in className.lower():
|
|
229
|
-
rotation_address = self.primitive_address +
|
|
230
|
-
position_address = self.primitive_address +
|
|
237
|
+
rotation_address = self.primitive_address + primitive_offsets["Rotation"]
|
|
238
|
+
position_address = self.primitive_address + primitive_offsets["Position"]
|
|
231
239
|
elif className == "Camera":
|
|
232
240
|
rotation_address = self.raw_address + camera_offsets["Rotation"]
|
|
233
241
|
position_address = self.raw_address + camera_offsets["Position"]
|
|
@@ -242,7 +250,7 @@ class RBXInstance:
|
|
|
242
250
|
className = self.ClassName.lower()
|
|
243
251
|
if "part" in className:
|
|
244
252
|
position_vector3 = self.memory_module.read_floats(
|
|
245
|
-
self.primitive_address +
|
|
253
|
+
self.primitive_address + primitive_offsets["Position"],
|
|
246
254
|
3
|
|
247
255
|
)
|
|
248
256
|
return Vector3(*position_vector3)
|
|
@@ -263,7 +271,7 @@ class RBXInstance:
|
|
|
263
271
|
if "part" in className:
|
|
264
272
|
vec = self._as_vector3(value, "Position")
|
|
265
273
|
self.memory_module.write_floats(
|
|
266
|
-
self.primitive_address +
|
|
274
|
+
self.primitive_address + primitive_offsets["Position"],
|
|
267
275
|
(vec.X, vec.Y, vec.Z)
|
|
268
276
|
)
|
|
269
277
|
|
|
@@ -284,7 +292,7 @@ class RBXInstance:
|
|
|
284
292
|
|
|
285
293
|
if "part" in className.lower():
|
|
286
294
|
velocity_vector3 = self.memory_module.read_floats(
|
|
287
|
-
self.primitive_address +
|
|
295
|
+
self.primitive_address + primitive_offsets["AssemblyLinearVelocity"],
|
|
288
296
|
3
|
|
289
297
|
)
|
|
290
298
|
return Vector3(*velocity_vector3)
|
|
@@ -301,7 +309,7 @@ class RBXInstance:
|
|
|
301
309
|
|
|
302
310
|
self._ensure_writable()
|
|
303
311
|
self.memory_module.write_floats(
|
|
304
|
-
self.primitive_address +
|
|
312
|
+
self.primitive_address + primitive_offsets["AssemblyLinearVelocity"],
|
|
305
313
|
(vec.X, vec.Y, vec.Z)
|
|
306
314
|
)
|
|
307
315
|
|
|
@@ -311,7 +319,7 @@ class RBXInstance:
|
|
|
311
319
|
|
|
312
320
|
if "part" in className.lower():
|
|
313
321
|
velocity_vector3 = self.memory_module.read_floats(
|
|
314
|
-
self.primitive_address +
|
|
322
|
+
self.primitive_address + primitive_offsets["AssemblyAngularVelocity"],
|
|
315
323
|
3
|
|
316
324
|
)
|
|
317
325
|
return Vector3(*velocity_vector3)
|
|
@@ -328,7 +336,7 @@ class RBXInstance:
|
|
|
328
336
|
|
|
329
337
|
self._ensure_writable()
|
|
330
338
|
self.memory_module.write_floats(
|
|
331
|
-
self.primitive_address +
|
|
339
|
+
self.primitive_address + primitive_offsets["AssemblyAngularVelocity"],
|
|
332
340
|
(vec.X, vec.Y, vec.Z)
|
|
333
341
|
)
|
|
334
342
|
|
|
@@ -367,6 +375,16 @@ class RBXInstance:
|
|
|
367
375
|
self.raw_address,
|
|
368
376
|
proximityprompt_offsets["Enabled"]
|
|
369
377
|
)
|
|
378
|
+
elif self.ClassName == "Tool":
|
|
379
|
+
return self.memory_module.read_bool(
|
|
380
|
+
self.raw_address,
|
|
381
|
+
tool_offsets["Enabled"]
|
|
382
|
+
)
|
|
383
|
+
elif self.ClassName == "ColorCorrectionEffect":
|
|
384
|
+
return self.memory_module.read_bool(
|
|
385
|
+
self.raw_address,
|
|
386
|
+
Offsets["ColorCorrectionEffect"]["Enabled"]
|
|
387
|
+
)
|
|
370
388
|
return None
|
|
371
389
|
|
|
372
390
|
@Enabled.setter
|
|
@@ -383,8 +401,20 @@ class RBXInstance:
|
|
|
383
401
|
self.raw_address + proximityprompt_offsets["Enabled"],
|
|
384
402
|
value
|
|
385
403
|
)
|
|
404
|
+
elif self.ClassName == "Tool":
|
|
405
|
+
self._ensure_writable()
|
|
406
|
+
self.memory_module.write_bool(
|
|
407
|
+
self.raw_address + tool_offsets["Enabled"],
|
|
408
|
+
bool(value)
|
|
409
|
+
)
|
|
410
|
+
elif self.ClassName == "ColorCorrectionEffect":
|
|
411
|
+
self._ensure_writable()
|
|
412
|
+
self.memory_module.write_bool(
|
|
413
|
+
self.raw_address + Offsets["ColorCorrectionEffect"]["Enabled"],
|
|
414
|
+
bool(value)
|
|
415
|
+
)
|
|
386
416
|
else:
|
|
387
|
-
raise AttributeError("Enabled is only available on ScreenGui or
|
|
417
|
+
raise AttributeError("Enabled is only available on ScreenGui, ProximityPrompt, Tool, or ColorCorrectionEffect instances.")
|
|
388
418
|
|
|
389
419
|
@property
|
|
390
420
|
def Visible(self):
|
|
@@ -420,7 +450,7 @@ class RBXInstance:
|
|
|
420
450
|
def Size(self):
|
|
421
451
|
if "part" in self.ClassName.lower():
|
|
422
452
|
size_vector3 = self.memory_module.read_floats(
|
|
423
|
-
self.primitive_address +
|
|
453
|
+
self.primitive_address + primitive_offsets["Size"],
|
|
424
454
|
3
|
|
425
455
|
)
|
|
426
456
|
return Vector3(*size_vector3)
|
|
@@ -433,7 +463,7 @@ class RBXInstance:
|
|
|
433
463
|
if "part" in self.ClassName.lower():
|
|
434
464
|
vec = self._as_vector3(value, "Size")
|
|
435
465
|
self.memory_module.write_floats(
|
|
436
|
-
self.primitive_address +
|
|
466
|
+
self.primitive_address + primitive_offsets["Size"],
|
|
437
467
|
(vec.X, vec.Y, vec.Z)
|
|
438
468
|
)
|
|
439
469
|
else:
|
|
@@ -486,7 +516,7 @@ class RBXInstance:
|
|
|
486
516
|
|
|
487
517
|
def _read_primitive_flags(self):
|
|
488
518
|
data = self.memory_module.read(
|
|
489
|
-
self.primitive_address +
|
|
519
|
+
self.primitive_address + primitive_offsets["Flags"],
|
|
490
520
|
1
|
|
491
521
|
)
|
|
492
522
|
return int.from_bytes(data, 'little') if data else 0
|
|
@@ -494,7 +524,7 @@ class RBXInstance:
|
|
|
494
524
|
def _write_primitive_flags(self, flags: int):
|
|
495
525
|
self._ensure_writable()
|
|
496
526
|
self.memory_module.write(
|
|
497
|
-
self.primitive_address +
|
|
527
|
+
self.primitive_address + primitive_offsets["Flags"],
|
|
498
528
|
(flags & 0xFF).to_bytes(1, 'little')
|
|
499
529
|
)
|
|
500
530
|
|
|
@@ -907,6 +937,203 @@ class RBXInstance:
|
|
|
907
937
|
float(value)
|
|
908
938
|
)
|
|
909
939
|
|
|
940
|
+
@property
|
|
941
|
+
def BackgroundTransparency(self):
|
|
942
|
+
return self.memory_module.read_float(
|
|
943
|
+
self.raw_address,
|
|
944
|
+
gui_offsets["BackgroundTransparency"]
|
|
945
|
+
)
|
|
946
|
+
|
|
947
|
+
@BackgroundTransparency.setter
|
|
948
|
+
def BackgroundTransparency(self, value: float):
|
|
949
|
+
self._ensure_writable()
|
|
950
|
+
self.memory_module.write_float(
|
|
951
|
+
self.raw_address + gui_offsets["BackgroundTransparency"],
|
|
952
|
+
float(value)
|
|
953
|
+
)
|
|
954
|
+
|
|
955
|
+
@property
|
|
956
|
+
def ZIndex(self):
|
|
957
|
+
return self.memory_module.read_int(
|
|
958
|
+
self.raw_address,
|
|
959
|
+
gui_offsets["ZIndex"]
|
|
960
|
+
)
|
|
961
|
+
|
|
962
|
+
@ZIndex.setter
|
|
963
|
+
def ZIndex(self, value: int):
|
|
964
|
+
self._ensure_writable()
|
|
965
|
+
self.memory_module.write_int(
|
|
966
|
+
self.raw_address + gui_offsets["ZIndex"],
|
|
967
|
+
int(value)
|
|
968
|
+
)
|
|
969
|
+
|
|
970
|
+
# tool props #
|
|
971
|
+
@property
|
|
972
|
+
def CanBeDropped(self):
|
|
973
|
+
if self.ClassName != "Tool":
|
|
974
|
+
return None
|
|
975
|
+
return self.memory_module.read_bool(
|
|
976
|
+
self.raw_address,
|
|
977
|
+
tool_offsets["CanBeDropped"]
|
|
978
|
+
)
|
|
979
|
+
|
|
980
|
+
@CanBeDropped.setter
|
|
981
|
+
def CanBeDropped(self, value: bool):
|
|
982
|
+
if self.ClassName != "Tool":
|
|
983
|
+
raise AttributeError("CanBeDropped is only available on Tool instances.")
|
|
984
|
+
self._ensure_writable()
|
|
985
|
+
self.memory_module.write_bool(
|
|
986
|
+
self.raw_address + tool_offsets["CanBeDropped"],
|
|
987
|
+
bool(value)
|
|
988
|
+
)
|
|
989
|
+
|
|
990
|
+
@property
|
|
991
|
+
def Grip(self):
|
|
992
|
+
if self.ClassName != "Tool":
|
|
993
|
+
return None
|
|
994
|
+
grip_data = self.memory_module.read_floats(
|
|
995
|
+
self.raw_address + tool_offsets["Grip"],
|
|
996
|
+
12 # CFrame: 9 rotation + 3 position
|
|
997
|
+
)
|
|
998
|
+
return grip_data
|
|
999
|
+
|
|
1000
|
+
@property
|
|
1001
|
+
def ManualActivationOnly(self):
|
|
1002
|
+
if self.ClassName != "Tool":
|
|
1003
|
+
return None
|
|
1004
|
+
return self.memory_module.read_bool(
|
|
1005
|
+
self.raw_address,
|
|
1006
|
+
tool_offsets["ManualActivationOnly"]
|
|
1007
|
+
)
|
|
1008
|
+
|
|
1009
|
+
@ManualActivationOnly.setter
|
|
1010
|
+
def ManualActivationOnly(self, value: bool):
|
|
1011
|
+
if self.ClassName != "Tool":
|
|
1012
|
+
raise AttributeError("ManualActivationOnly is only available on Tool instances.")
|
|
1013
|
+
self._ensure_writable()
|
|
1014
|
+
self.memory_module.write_bool(
|
|
1015
|
+
self.raw_address + tool_offsets["ManualActivationOnly"],
|
|
1016
|
+
bool(value)
|
|
1017
|
+
)
|
|
1018
|
+
|
|
1019
|
+
@property
|
|
1020
|
+
def RequiresHandle(self):
|
|
1021
|
+
if self.ClassName != "Tool":
|
|
1022
|
+
return None
|
|
1023
|
+
return self.memory_module.read_bool(
|
|
1024
|
+
self.raw_address,
|
|
1025
|
+
tool_offsets["RequiresHandle"]
|
|
1026
|
+
)
|
|
1027
|
+
|
|
1028
|
+
@RequiresHandle.setter
|
|
1029
|
+
def RequiresHandle(self, value: bool):
|
|
1030
|
+
if self.ClassName != "Tool":
|
|
1031
|
+
raise AttributeError("RequiresHandle is only available on Tool instances.")
|
|
1032
|
+
self._ensure_writable()
|
|
1033
|
+
self.memory_module.write_bool(
|
|
1034
|
+
self.raw_address + tool_offsets["RequiresHandle"],
|
|
1035
|
+
bool(value)
|
|
1036
|
+
)
|
|
1037
|
+
|
|
1038
|
+
@property
|
|
1039
|
+
def TextureId(self):
|
|
1040
|
+
if self.ClassName != "Tool":
|
|
1041
|
+
return None
|
|
1042
|
+
return self.memory_module.read_string(
|
|
1043
|
+
self.raw_address,
|
|
1044
|
+
tool_offsets["TextureId"]
|
|
1045
|
+
)
|
|
1046
|
+
|
|
1047
|
+
@TextureId.setter
|
|
1048
|
+
def TextureId(self, value: str):
|
|
1049
|
+
if self.ClassName != "Tool":
|
|
1050
|
+
raise AttributeError("TextureId is only available on Tool instances.")
|
|
1051
|
+
self._ensure_writable()
|
|
1052
|
+
self.memory_module.write_string(
|
|
1053
|
+
self.raw_address + tool_offsets["TextureId"],
|
|
1054
|
+
str(value)
|
|
1055
|
+
)
|
|
1056
|
+
|
|
1057
|
+
@property
|
|
1058
|
+
def Tooltip(self):
|
|
1059
|
+
if self.ClassName != "Tool":
|
|
1060
|
+
return None
|
|
1061
|
+
return self.memory_module.read_string(
|
|
1062
|
+
self.raw_address,
|
|
1063
|
+
tool_offsets["Tooltip"]
|
|
1064
|
+
)
|
|
1065
|
+
|
|
1066
|
+
@Tooltip.setter
|
|
1067
|
+
def Tooltip(self, value: str):
|
|
1068
|
+
if self.ClassName != "Tool":
|
|
1069
|
+
raise AttributeError("Tooltip is only available on Tool instances.")
|
|
1070
|
+
self._ensure_writable()
|
|
1071
|
+
self.memory_module.write_string(
|
|
1072
|
+
self.raw_address + tool_offsets["Tooltip"],
|
|
1073
|
+
str(value)
|
|
1074
|
+
)
|
|
1075
|
+
|
|
1076
|
+
# colorcorrection props #
|
|
1077
|
+
@property
|
|
1078
|
+
def Brightness(self):
|
|
1079
|
+
if self.ClassName == "ColorCorrectionEffect":
|
|
1080
|
+
return self.memory_module.read_float(
|
|
1081
|
+
self.raw_address,
|
|
1082
|
+
Offsets["ColorCorrectionEffect"]["Brightness"]
|
|
1083
|
+
)
|
|
1084
|
+
return None
|
|
1085
|
+
|
|
1086
|
+
@Brightness.setter
|
|
1087
|
+
def Brightness(self, value: float):
|
|
1088
|
+
if self.ClassName == "ColorCorrectionEffect":
|
|
1089
|
+
self._ensure_writable()
|
|
1090
|
+
self.memory_module.write_float(
|
|
1091
|
+
self.raw_address + Offsets["ColorCorrectionEffect"]["Brightness"],
|
|
1092
|
+
float(value)
|
|
1093
|
+
)
|
|
1094
|
+
else:
|
|
1095
|
+
raise AttributeError("Brightness is only available on ColorCorrectionEffect instances (use LightingService.Brightness for Lighting).")
|
|
1096
|
+
|
|
1097
|
+
@property
|
|
1098
|
+
def Contrast(self):
|
|
1099
|
+
if self.ClassName != "ColorCorrectionEffect":
|
|
1100
|
+
return None
|
|
1101
|
+
return self.memory_module.read_float(
|
|
1102
|
+
self.raw_address,
|
|
1103
|
+
Offsets["ColorCorrectionEffect"]["Contrast"]
|
|
1104
|
+
)
|
|
1105
|
+
|
|
1106
|
+
@Contrast.setter
|
|
1107
|
+
def Contrast(self, value: float):
|
|
1108
|
+
if self.ClassName != "ColorCorrectionEffect":
|
|
1109
|
+
raise AttributeError("Contrast is only available on ColorCorrectionEffect instances.")
|
|
1110
|
+
self._ensure_writable()
|
|
1111
|
+
self.memory_module.write_float(
|
|
1112
|
+
self.raw_address + Offsets["ColorCorrectionEffect"]["Contrast"],
|
|
1113
|
+
float(value)
|
|
1114
|
+
)
|
|
1115
|
+
|
|
1116
|
+
@property
|
|
1117
|
+
def TintColor(self):
|
|
1118
|
+
if self.ClassName != "ColorCorrectionEffect":
|
|
1119
|
+
return None
|
|
1120
|
+
color_data = self.memory_module.read_floats(
|
|
1121
|
+
self.raw_address + Offsets["ColorCorrectionEffect"]["TintColor"],
|
|
1122
|
+
3
|
|
1123
|
+
)
|
|
1124
|
+
return Color3(*color_data)
|
|
1125
|
+
|
|
1126
|
+
@TintColor.setter
|
|
1127
|
+
def TintColor(self, value):
|
|
1128
|
+
if self.ClassName != "ColorCorrectionEffect":
|
|
1129
|
+
raise AttributeError("TintColor is only available on ColorCorrectionEffect instances.")
|
|
1130
|
+
self._ensure_writable()
|
|
1131
|
+
vec = self._as_color3(value, "TintColor")
|
|
1132
|
+
self.memory_module.write_floats(
|
|
1133
|
+
self.raw_address + Offsets["ColorCorrectionEffect"]["TintColor"],
|
|
1134
|
+
(vec.X, vec.Y, vec.Z)
|
|
1135
|
+
)
|
|
1136
|
+
|
|
910
1137
|
# humanoid props #
|
|
911
1138
|
@property
|
|
912
1139
|
def WalkSpeed(self):
|
|
@@ -1353,6 +1580,35 @@ class RBXInstance:
|
|
|
1353
1580
|
|
|
1354
1581
|
self.memory_module.write_long(bytecode_ptr + Offsets["ByteCode"]["Pointer"], new_content_ptr)
|
|
1355
1582
|
self.memory_module.write_int(bytecode_ptr + Offsets["ByteCode"]["Size"], new_size)
|
|
1583
|
+
|
|
1584
|
+
# script identification #
|
|
1585
|
+
@property
|
|
1586
|
+
def GUID(self):
|
|
1587
|
+
classname = self.ClassName
|
|
1588
|
+
if classname == "LocalScript":
|
|
1589
|
+
guid_offset = Offsets["LocalScript"]["GUID"]
|
|
1590
|
+
elif classname == "ModuleScript":
|
|
1591
|
+
guid_offset = Offsets["ModuleScript"]["GUID"]
|
|
1592
|
+
else:
|
|
1593
|
+
return None
|
|
1594
|
+
return self.memory_module.read_string(
|
|
1595
|
+
self.raw_address,
|
|
1596
|
+
guid_offset
|
|
1597
|
+
)
|
|
1598
|
+
|
|
1599
|
+
@property
|
|
1600
|
+
def Hash(self):
|
|
1601
|
+
classname = self.ClassName
|
|
1602
|
+
if classname == "LocalScript":
|
|
1603
|
+
hash_offset = Offsets["LocalScript"]["Hash"]
|
|
1604
|
+
elif classname == "ModuleScript":
|
|
1605
|
+
hash_offset = Offsets["ModuleScript"]["Hash"]
|
|
1606
|
+
else:
|
|
1607
|
+
return None
|
|
1608
|
+
return self.memory_module.read_string(
|
|
1609
|
+
self.raw_address,
|
|
1610
|
+
hash_offset
|
|
1611
|
+
)
|
|
1356
1612
|
|
|
1357
1613
|
# functions #
|
|
1358
1614
|
def GetChildren(self):
|
|
@@ -1725,6 +1981,36 @@ class PlayerClass(RBXInstance):
|
|
|
1725
1981
|
int(value)
|
|
1726
1982
|
)
|
|
1727
1983
|
|
|
1984
|
+
@property
|
|
1985
|
+
def HealthDisplayDistance(self):
|
|
1986
|
+
return self.memory_module.read_float(
|
|
1987
|
+
self.raw_address,
|
|
1988
|
+
self.offset_base["HealthDisplayDistance"]
|
|
1989
|
+
)
|
|
1990
|
+
|
|
1991
|
+
@HealthDisplayDistance.setter
|
|
1992
|
+
def HealthDisplayDistance(self, value: float):
|
|
1993
|
+
self._ensure_writable()
|
|
1994
|
+
self.memory_module.write_float(
|
|
1995
|
+
self.raw_address + self.offset_base["HealthDisplayDistance"],
|
|
1996
|
+
float(value)
|
|
1997
|
+
)
|
|
1998
|
+
|
|
1999
|
+
@property
|
|
2000
|
+
def NameDisplayDistance(self):
|
|
2001
|
+
return self.memory_module.read_float(
|
|
2002
|
+
self.raw_address,
|
|
2003
|
+
self.offset_base["NameDisplayDistance"]
|
|
2004
|
+
)
|
|
2005
|
+
|
|
2006
|
+
@NameDisplayDistance.setter
|
|
2007
|
+
def NameDisplayDistance(self, value: float):
|
|
2008
|
+
self._ensure_writable()
|
|
2009
|
+
self.memory_module.write_float(
|
|
2010
|
+
self.raw_address + self.offset_base["NameDisplayDistance"],
|
|
2011
|
+
float(value)
|
|
2012
|
+
)
|
|
2013
|
+
|
|
1728
2014
|
class CameraClass(RBXInstance):
|
|
1729
2015
|
def __init__(self, memory_module, camera: RBXInstance):
|
|
1730
2016
|
super().__init__(camera.raw_address, memory_module)
|
|
@@ -2235,27 +2521,27 @@ class WorkspaceService(ServiceBase):
|
|
|
2235
2521
|
|
|
2236
2522
|
@property
|
|
2237
2523
|
def Gravity(self):
|
|
2238
|
-
|
|
2524
|
+
World = self.memory_module.get_pointer(
|
|
2239
2525
|
self.instance.raw_address,
|
|
2240
|
-
self.offset_base["
|
|
2526
|
+
self.offset_base["World"]
|
|
2241
2527
|
)
|
|
2242
2528
|
|
|
2243
2529
|
return self.memory_module.read_float(
|
|
2244
|
-
|
|
2245
|
-
|
|
2530
|
+
World,
|
|
2531
|
+
world_offsets["Gravity"]
|
|
2246
2532
|
)
|
|
2247
2533
|
|
|
2248
2534
|
@Gravity.setter
|
|
2249
2535
|
def Gravity(self, value: float):
|
|
2250
2536
|
self._ensure_writable()
|
|
2251
2537
|
|
|
2252
|
-
|
|
2538
|
+
World = self.memory_module.get_pointer(
|
|
2253
2539
|
self.instance.raw_address,
|
|
2254
|
-
self.offset_base["
|
|
2540
|
+
self.offset_base["World"]
|
|
2255
2541
|
)
|
|
2256
2542
|
|
|
2257
2543
|
self.memory_module.write_float(
|
|
2258
|
-
|
|
2544
|
+
World + world_offsets["Gravity"],
|
|
2259
2545
|
float(value)
|
|
2260
2546
|
)
|
|
2261
2547
|
|
|
@@ -2469,6 +2755,77 @@ class LightingService(ServiceBase):
|
|
|
2469
2755
|
float(value)
|
|
2470
2756
|
)
|
|
2471
2757
|
|
|
2758
|
+
@property
|
|
2759
|
+
def Sky(self):
|
|
2760
|
+
if self.failed: return None
|
|
2761
|
+
sky_ptr = self.memory_module.get_pointer(
|
|
2762
|
+
self.instance.raw_address,
|
|
2763
|
+
self.offset_base["Sky"]
|
|
2764
|
+
)
|
|
2765
|
+
if sky_ptr == 0:
|
|
2766
|
+
return None
|
|
2767
|
+
return RBXInstance(sky_ptr, self.memory_module)
|
|
2768
|
+
|
|
2769
|
+
@property
|
|
2770
|
+
def Source(self):
|
|
2771
|
+
if self.failed: return None
|
|
2772
|
+
return self.memory_module.read_int(
|
|
2773
|
+
self.instance.raw_address,
|
|
2774
|
+
self.offset_base["Source"]
|
|
2775
|
+
)
|
|
2776
|
+
|
|
2777
|
+
@property
|
|
2778
|
+
def SunPosition(self):
|
|
2779
|
+
if self.failed: return None
|
|
2780
|
+
pos_data = self.memory_module.read_floats(
|
|
2781
|
+
self.instance.raw_address + self.offset_base["SunPosition"],
|
|
2782
|
+
3
|
|
2783
|
+
)
|
|
2784
|
+
return Vector3(*pos_data)
|
|
2785
|
+
|
|
2786
|
+
@property
|
|
2787
|
+
def MoonPosition(self):
|
|
2788
|
+
if self.failed: return None
|
|
2789
|
+
pos_data = self.memory_module.read_floats(
|
|
2790
|
+
self.instance.raw_address + self.offset_base["MoonPosition"],
|
|
2791
|
+
3
|
|
2792
|
+
)
|
|
2793
|
+
return Vector3(*pos_data)
|
|
2794
|
+
|
|
2795
|
+
@property
|
|
2796
|
+
def EnvironmentDiffuseScale(self):
|
|
2797
|
+
if self.failed: return 0.0
|
|
2798
|
+
return self.memory_module.read_float(
|
|
2799
|
+
self.instance.raw_address,
|
|
2800
|
+
self.offset_base["EnvironmentDiffuseScale"]
|
|
2801
|
+
)
|
|
2802
|
+
|
|
2803
|
+
@EnvironmentDiffuseScale.setter
|
|
2804
|
+
def EnvironmentDiffuseScale(self, value: float):
|
|
2805
|
+
if self.failed: return
|
|
2806
|
+
self._ensure_writable()
|
|
2807
|
+
self.memory_module.write_float(
|
|
2808
|
+
self.instance.raw_address + self.offset_base["EnvironmentDiffuseScale"],
|
|
2809
|
+
float(value)
|
|
2810
|
+
)
|
|
2811
|
+
|
|
2812
|
+
@property
|
|
2813
|
+
def EnvironmentSpecularScale(self):
|
|
2814
|
+
if self.failed: return 0.0
|
|
2815
|
+
return self.memory_module.read_float(
|
|
2816
|
+
self.instance.raw_address,
|
|
2817
|
+
self.offset_base["EnvironmentSpecularScale"]
|
|
2818
|
+
)
|
|
2819
|
+
|
|
2820
|
+
@EnvironmentSpecularScale.setter
|
|
2821
|
+
def EnvironmentSpecularScale(self, value: float):
|
|
2822
|
+
if self.failed: return
|
|
2823
|
+
self._ensure_writable()
|
|
2824
|
+
self.memory_module.write_float(
|
|
2825
|
+
self.instance.raw_address + self.offset_base["EnvironmentSpecularScale"],
|
|
2826
|
+
float(value)
|
|
2827
|
+
)
|
|
2828
|
+
|
|
2472
2829
|
class InputObject(RBXInstance):
|
|
2473
2830
|
def __init__(self, raw_address: int, memory_module):
|
|
2474
2831
|
super().__init__(raw_address, memory_module)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: robloxmemoryapi
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Python Library that abstracts reading and writing data from the Roblox DataModel
|
|
5
5
|
Author-email: upio <notpoiu@users.noreply.github.com>, mstudio45 <mstudio45@users.noreply.github.com>, ActualMasterOogway <ActualMasterOogway@users.noreply.github.com>
|
|
6
6
|
License: Copyright 2025 upio, mstudio45, master oogway
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/rbx/bytecode/decryptor.py
RENAMED
|
File without changes
|
{robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi/utils/rbx/bytecode/encryptor.py
RENAMED
|
File without changes
|
|
File without changes
|
{robloxmemoryapi-0.2.2 → robloxmemoryapi-0.2.3}/src/robloxmemoryapi.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|