Skip to content

Commit b68261b

Browse files
committed
feat: add BasePart Reflectance/Locked/Massless + MeshPart/Texture support
- Added BasePart::Reflectance (float), Locked (bool), Massless (bool) properties with read/write support (dumper v2.1.3) - Added MeshPart::MeshId and MeshPart::TextureId (string) properties - Extended TextureId to support Decal and Texture instances - Added meshpart_offsets and textures_offsets globals
1 parent c5879d0 commit b68261b

2 files changed

Lines changed: 125 additions & 8 deletions

File tree

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "robloxmemoryapi"
7-
version = "0.2.6"
7+
version = "0.2.7"
88
description = "Python Library that abstracts reading and writing data from the Roblox DataModel"
99
readme = { file = "README.md", content-type = "text/markdown" }
1010
requires-python = ">=3.9"

‎src/robloxmemoryapi/utils/rbx/instance.py‎

Lines changed: 124 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
attachment_offsets = Offsets["Attachment"]
3030
air_properties_offsets = Offsets["AirProperties"]
3131
seat_offsets = Offsets["Seat"]
32+
meshpart_offsets = Offsets["MeshPart"]
33+
textures_offsets = Offsets["Textures"]
3234

3335
ROTATION_MATRIX_FLOATS = 9
3436

@@ -612,6 +614,69 @@ def Color(self, value):
612614
bytes([r & 0xFF, g & 0xFF, b & 0xFF])
613615
)
614616

617+
@property
618+
def Reflectance(self):
619+
if "part" not in self.ClassName.lower():
620+
return None
621+
622+
return self.memory_module.read_float(
623+
self.raw_address,
624+
basepart_offsets["Reflectance"]
625+
)
626+
627+
@Reflectance.setter
628+
def Reflectance(self, value: float):
629+
if "part" not in self.ClassName.lower():
630+
raise AttributeError("Reflectance is only available on BasePart-derived instances.")
631+
self._ensure_writable()
632+
633+
self.memory_module.write_float(
634+
self.raw_address + basepart_offsets["Reflectance"],
635+
float(value)
636+
)
637+
638+
@property
639+
def Locked(self):
640+
if "part" not in self.ClassName.lower():
641+
return None
642+
643+
return self.memory_module.read_bool(
644+
self.raw_address,
645+
basepart_offsets["Locked"]
646+
)
647+
648+
@Locked.setter
649+
def Locked(self, value: bool):
650+
if "part" not in self.ClassName.lower():
651+
raise AttributeError("Locked is only available on BasePart-derived instances.")
652+
self._ensure_writable()
653+
654+
self.memory_module.write_bool(
655+
self.raw_address + basepart_offsets["Locked"],
656+
bool(value)
657+
)
658+
659+
@property
660+
def Massless(self):
661+
if "part" not in self.ClassName.lower():
662+
return None
663+
664+
return self.memory_module.read_bool(
665+
self.raw_address,
666+
basepart_offsets["Massless"]
667+
)
668+
669+
@Massless.setter
670+
def Massless(self, value: bool):
671+
if "part" not in self.ClassName.lower():
672+
raise AttributeError("Massless is only available on BasePart-derived instances.")
673+
self._ensure_writable()
674+
675+
self.memory_module.write_bool(
676+
self.raw_address + basepart_offsets["Massless"],
677+
bool(value)
678+
)
679+
615680
def _read_primitive_flags(self):
616681
data = self.memory_module.read(
617682
self.primitive_address + primitive_offsets["Flags"],
@@ -1132,20 +1197,72 @@ def RequiresHandle(self, value: bool):
11321197

11331198
@property
11341199
def TextureId(self):
1135-
if self.ClassName != "Tool":
1200+
className = self.ClassName
1201+
if className == "Tool":
1202+
return self.memory_module.read_string(
1203+
self.raw_address,
1204+
tool_offsets["TextureId"]
1205+
)
1206+
elif className == "MeshPart":
1207+
return self.memory_module.read_string(
1208+
self.raw_address,
1209+
meshpart_offsets["Texture"]
1210+
)
1211+
elif className == "Decal":
1212+
return self.memory_module.read_string(
1213+
self.raw_address,
1214+
textures_offsets["Decal_Texture"]
1215+
)
1216+
elif className == "Texture":
1217+
return self.memory_module.read_string(
1218+
self.raw_address,
1219+
textures_offsets["Texture_Texture"]
1220+
)
1221+
return None
1222+
1223+
@TextureId.setter
1224+
def TextureId(self, value: str):
1225+
className = self.ClassName
1226+
self._ensure_writable()
1227+
if className == "Tool":
1228+
self.memory_module.write_string(
1229+
self.raw_address + tool_offsets["TextureId"],
1230+
str(value)
1231+
)
1232+
elif className == "MeshPart":
1233+
self.memory_module.write_string(
1234+
self.raw_address + meshpart_offsets["Texture"],
1235+
str(value)
1236+
)
1237+
elif className == "Decal":
1238+
self.memory_module.write_string(
1239+
self.raw_address + textures_offsets["Decal_Texture"],
1240+
str(value)
1241+
)
1242+
elif className == "Texture":
1243+
self.memory_module.write_string(
1244+
self.raw_address + textures_offsets["Texture_Texture"],
1245+
str(value)
1246+
)
1247+
else:
1248+
raise AttributeError("TextureId is only available on Tool, MeshPart, Decal, or Texture instances.")
1249+
1250+
@property
1251+
def MeshId(self):
1252+
if self.ClassName != "MeshPart":
11361253
return None
11371254
return self.memory_module.read_string(
11381255
self.raw_address,
1139-
tool_offsets["TextureId"]
1256+
meshpart_offsets["MeshId"]
11401257
)
11411258

1142-
@TextureId.setter
1143-
def TextureId(self, value: str):
1144-
if self.ClassName != "Tool":
1145-
raise AttributeError("TextureId is only available on Tool instances.")
1259+
@MeshId.setter
1260+
def MeshId(self, value: str):
1261+
if self.ClassName != "MeshPart":
1262+
raise AttributeError("MeshId is only available on MeshPart instances.")
11461263
self._ensure_writable()
11471264
self.memory_module.write_string(
1148-
self.raw_address + tool_offsets["TextureId"],
1265+
self.raw_address + meshpart_offsets["MeshId"],
11491266
str(value)
11501267
)
11511268

0 commit comments

Comments
 (0)