robloxmemoryapi 0.3.0__tar.gz → 0.3.2__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.
Files changed (36) hide show
  1. robloxmemoryapi-0.3.2/.github/workflows/publish.yml +84 -0
  2. robloxmemoryapi-0.3.2/.gitignore +12 -0
  3. robloxmemoryapi-0.3.2/.luaurc +5 -0
  4. robloxmemoryapi-0.3.2/CMakeLists.txt +18 -0
  5. {robloxmemoryapi-0.3.0/src/robloxmemoryapi.egg-info → robloxmemoryapi-0.3.2}/PKG-INFO +15 -16
  6. robloxmemoryapi-0.3.2/example.py +106 -0
  7. robloxmemoryapi-0.3.2/misc/BytecodeGen.luau +16 -0
  8. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/pyproject.toml +15 -13
  9. robloxmemoryapi-0.3.2/rokit.toml +7 -0
  10. robloxmemoryapi-0.3.2/src/robloxmemoryapi/__init__.py +231 -0
  11. robloxmemoryapi-0.3.2/src/robloxmemoryapi/_native/__init__.py +1 -0
  12. robloxmemoryapi-0.3.2/src/robloxmemoryapi/_native/memory.cpp +998 -0
  13. robloxmemoryapi-0.3.2/src/robloxmemoryapi/_version.py +44 -0
  14. robloxmemoryapi-0.3.2/src/robloxmemoryapi/utils/macos.py +153 -0
  15. robloxmemoryapi-0.3.2/src/robloxmemoryapi/utils/memory.py +42 -0
  16. robloxmemoryapi-0.3.2/src/robloxmemoryapi/utils/offsets.py +43 -0
  17. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/src/robloxmemoryapi/utils/rbx/instance.py +14 -3
  18. robloxmemoryapi-0.3.0/PKG-INFO +0 -69
  19. robloxmemoryapi-0.3.0/setup.cfg +0 -4
  20. robloxmemoryapi-0.3.0/src/robloxmemoryapi/__init__.py +0 -108
  21. robloxmemoryapi-0.3.0/src/robloxmemoryapi/utils/memory.py +0 -450
  22. robloxmemoryapi-0.3.0/src/robloxmemoryapi/utils/offsets.py +0 -24
  23. robloxmemoryapi-0.3.0/src/robloxmemoryapi.egg-info/SOURCES.txt +0 -20
  24. robloxmemoryapi-0.3.0/src/robloxmemoryapi.egg-info/dependency_links.txt +0 -1
  25. robloxmemoryapi-0.3.0/src/robloxmemoryapi.egg-info/requires.txt +0 -4
  26. robloxmemoryapi-0.3.0/src/robloxmemoryapi.egg-info/top_level.txt +0 -1
  27. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/LICENSE.md +0 -0
  28. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/README.md +0 -0
  29. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/src/robloxmemoryapi/utils/__init__.py +0 -0
  30. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/src/robloxmemoryapi/utils/luau/__init__.py +0 -0
  31. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/src/robloxmemoryapi/utils/luau/parser.py +0 -0
  32. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/src/robloxmemoryapi/utils/rbx/__init__.py +0 -0
  33. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/src/robloxmemoryapi/utils/rbx/bytecode/decryptor.py +0 -0
  34. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/src/robloxmemoryapi/utils/rbx/bytecode/encryptor.py +0 -0
  35. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/src/robloxmemoryapi/utils/rbx/datastructures.py +0 -0
  36. {robloxmemoryapi-0.3.0 → robloxmemoryapi-0.3.2}/src/robloxmemoryapi/utils/rbx/fflags.py +0 -0
@@ -0,0 +1,84 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ release:
6
+ types: [published]
7
+
8
+ jobs:
9
+ build-sdist:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - name: Check out repository
13
+ uses: actions/checkout@v4
14
+
15
+ - name: Set up Python
16
+ uses: actions/setup-python@v5
17
+ with:
18
+ python-version: "3.11"
19
+
20
+ - name: Build source distribution
21
+ run: |
22
+ python -m pip install --upgrade pip
23
+ python -m pip install build
24
+ python -m build --sdist
25
+
26
+ - name: Upload source distribution
27
+ uses: actions/upload-artifact@v4
28
+ with:
29
+ name: sdist
30
+ path: dist/*.tar.gz
31
+
32
+ build-wheels:
33
+ name: Build wheels on ${{ matrix.os }}
34
+ runs-on: ${{ matrix.os }}
35
+ strategy:
36
+ fail-fast: false
37
+ matrix:
38
+ include:
39
+ - os: windows-latest
40
+ cibw_archs: AMD64
41
+ - os: macos-15-intel
42
+ cibw_archs: x86_64
43
+ - os: macos-15
44
+ cibw_archs: arm64
45
+
46
+ steps:
47
+ - name: Check out repository
48
+ uses: actions/checkout@v4
49
+
50
+ - name: Set up Python
51
+ uses: actions/setup-python@v5
52
+ with:
53
+ python-version: "3.11"
54
+
55
+ - name: Build wheels
56
+ uses: pypa/cibuildwheel@v2.20.0
57
+ env:
58
+ CIBW_BUILD: "cp39-* cp310-* cp311-* cp312-* cp313-*"
59
+ CIBW_SKIP: "pp* *-musllinux*"
60
+ CIBW_ARCHS: ${{ matrix.cibw_archs }}
61
+
62
+ - name: Upload wheels
63
+ uses: actions/upload-artifact@v4
64
+ with:
65
+ name: wheels-${{ matrix.os }}
66
+ path: wheelhouse/*.whl
67
+
68
+ publish:
69
+ needs: [build-sdist, build-wheels]
70
+ runs-on: ubuntu-latest
71
+
72
+ steps:
73
+ - name: Download distributions
74
+ uses: actions/download-artifact@v4
75
+ with:
76
+ pattern: "*"
77
+ merge-multiple: true
78
+ path: dist
79
+
80
+ - name: Publish to PyPI
81
+ uses: pypa/gh-action-pypi-publish@release/v1
82
+ with:
83
+ password: ${{ secrets.PYPI_API_TOKEN }}
84
+ skip-existing: true
@@ -0,0 +1,12 @@
1
+ .DS_Store
2
+ offset_finder.py
3
+ **/__pycache__/
4
+ dist/
5
+ build/
6
+ *.egg-info/
7
+ .eggs/
8
+ pip-wheel-metadata/
9
+ .venv/
10
+ venv/
11
+ misc/BytecodeToWrite.luac
12
+ documentation/
@@ -0,0 +1,5 @@
1
+ {
2
+ "aliases": {
3
+ "lune": "~/.lune/.typedefs/0.10.4/"
4
+ }
5
+ }
@@ -0,0 +1,18 @@
1
+ cmake_minimum_required(VERSION 3.15)
2
+
3
+ project(robloxmemoryapi_native LANGUAGES CXX)
4
+
5
+ find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)
6
+ find_package(pybind11 CONFIG REQUIRED)
7
+
8
+ pybind11_add_module(memory MODULE src/robloxmemoryapi/_native/memory.cpp)
9
+ target_compile_features(memory PRIVATE cxx_std_17)
10
+
11
+ if(WIN32)
12
+ target_link_libraries(memory PRIVATE psapi)
13
+ endif()
14
+
15
+ install(TARGETS memory
16
+ LIBRARY DESTINATION robloxmemoryapi/_native
17
+ RUNTIME DESTINATION robloxmemoryapi/_native
18
+ )
@@ -1,33 +1,32 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.1
2
2
  Name: robloxmemoryapi
3
- Version: 0.3.0
3
+ Version: 0.3.2
4
4
  Summary: Python Library that abstracts reading and writing data from the Roblox DataModel
5
- Author-email: upio <notpoiu@users.noreply.github.com>, mstudio45 <mstudio45@users.noreply.github.com>, ActualMasterOogway <ActualMasterOogway@users.noreply.github.com>
5
+ Keywords: roblox,memory,windows,macOS
6
+ Author-Email: upio <notpoiu@users.noreply.github.com>, mstudio45 <mstudio45@users.noreply.github.com>, ActualMasterOogway <ActualMasterOogway@users.noreply.github.com>
6
7
  License: Copyright 2025 upio, mstudio45, master oogway
7
-
8
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11
-
12
- THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13
-
14
- Project-URL: Homepage, https://github.com/notpoiu/RobloxMemoryAPI
15
- Project-URL: Issues, https://github.com/notpoiu/RobloxMemoryAPI/issues
16
- Keywords: roblox,memory,windows
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14
+
17
15
  Classifier: Programming Language :: Python :: 3
18
16
  Classifier: License :: OSI Approved :: MIT License
19
17
  Classifier: Operating System :: Microsoft :: Windows
18
+ Classifier: Operating System :: MacOS
20
19
  Classifier: Development Status :: 3 - Alpha
21
20
  Classifier: Intended Audience :: Developers
22
21
  Classifier: Topic :: Software Development :: Libraries
22
+ Project-URL: Homepage, https://github.com/notpoiu/RobloxMemoryAPI
23
+ Project-URL: Issues, https://github.com/notpoiu/RobloxMemoryAPI/issues
23
24
  Requires-Python: >=3.9
24
- Description-Content-Type: text/markdown
25
- License-File: LICENSE.md
26
25
  Requires-Dist: requests>=2.0
27
26
  Requires-Dist: zstandard>=0.19.0
28
27
  Requires-Dist: xxhash>=3.6.0
29
28
  Requires-Dist: blake3>=1.0.8
30
- Dynamic: license-file
29
+ Description-Content-Type: text/markdown
31
30
 
32
31
  # RobloxMemoryAPI
33
32
 
@@ -0,0 +1,106 @@
1
+ from robloxmemoryapi import RobloxGameClient, RobloxRandom
2
+ from robloxmemoryapi.utils.rbx.datastructures import UDim2
3
+ import platform
4
+ import os
5
+ import hashlib
6
+
7
+ ## Random Class ##
8
+ Test = RobloxRandom(5)
9
+ print("Roblox Random Demo")
10
+ print("math.random() with seed '5' result:", Test.NextNumber())
11
+
12
+ ## Memory Reading ###
13
+ if platform.system() != "Windows":
14
+ print("Sorry! The memory reading module only works in windows, trying to access it will cause client.failed = True")
15
+ exit()
16
+
17
+ # Create a client instance
18
+ # allow_write is by default False, but can be enabled by passing True
19
+ client = RobloxGameClient(allow_write=True)
20
+ # client = RobloxGameClient(pid=2398) # PID is also possible
21
+
22
+ if client.failed:
23
+ print("Failed to get data model")
24
+ exit()
25
+
26
+ # Get the client's data model
27
+ game = client.DataModel
28
+
29
+ print("")
30
+
31
+ # Refresh hooks let you react when Roblox swaps between home screen and game.
32
+ def on_refresh(datamodel):
33
+ if game.is_lua_app():
34
+ print("[Refresh] You are now in the Roblox Home Screen.")
35
+ else:
36
+ print(f"[Refresh] You are now in-game (PlaceId: {game.PlaceId})")
37
+
38
+ # Register callback (optional invoke to run immediately with the current model).
39
+ game.bind_to_refresh(on_refresh, invoke_if_ready=True)
40
+
41
+ LocalPlayer = game.Players.LocalPlayer
42
+
43
+ print("")
44
+
45
+ # Print some info about the game
46
+ print("RobloxMemoryAPI Demo:")
47
+ print("An External Roblox Memory Reader")
48
+ print("==============================")
49
+ print("PlaceID:", game.PlaceId)
50
+ print("GameID:", game.GameId)
51
+ print("JobId:", game.JobId)
52
+ print("Loaded:", game.IsLoaded())
53
+ print("==============================")
54
+ print("Player Name:", LocalPlayer.Name, f"({LocalPlayer.DisplayName} | userid: {LocalPlayer.UserId})")
55
+
56
+ # LuaApp = Roblox Home Screen
57
+ if not game.is_lua_app():
58
+ print("Player HRP Parent:", LocalPlayer.Character.PrimaryPart.GetFullName())
59
+ print("Health:", LocalPlayer.Character.Humanoid.Health, LocalPlayer.Character.Humanoid.MaxHealth)
60
+ print("Player Count:", len(game.Players.GetPlayers()))
61
+ print("==============================")
62
+ print("CurrentCamera CFrame:", game.Workspace.CurrentCamera.CFrame)
63
+ print("CurrentCamera FOV:", game.Workspace.CurrentCamera.FieldOfView)
64
+ print("CurrentCamera ViewportSize:", game.Workspace.CurrentCamera.ViewportSize)
65
+
66
+ print("")
67
+
68
+ # Attributes
69
+ print("Attributes:")
70
+ for name, attribute in game.Workspace.GetAttributes().items():
71
+ print(f"Attribute: '{name}' | Type: {attribute.type_name} | Value: {attribute.value}")
72
+
73
+ print("")
74
+
75
+ if game.Workspace.GetAttribute("Test") is not None:
76
+ print("Test attribute found, testing...")
77
+ print(f"Old attribute: {game.Workspace.GetAttribute("Test")}")
78
+ game.Workspace.SetAttribute("Test", "Hello World")
79
+ print(f"New attribute: {game.Workspace.GetAttribute("Test")}")
80
+
81
+ print("")
82
+
83
+ # Bytecode operations (READING)
84
+ PlayerModule = LocalPlayer.PlayerScripts.PlayerModule
85
+ if PlayerModule is not None and PlayerModule.Bytecode is not None:
86
+ print("PlayerModule Script Hash:", hashlib.sha384(PlayerModule.RawBytecode).hexdigest())
87
+
88
+ # Bytecode write operations (WRITING)
89
+ if os.path.exists("misc/BytecodeToWrite.luac"):
90
+ with open("misc/BytecodeToWrite.luac", "rb") as f:
91
+ BytecodeToWrite = f.read()
92
+
93
+ PlayerModule.Bytecode = BytecodeToWrite
94
+ print("Set bytecode of PlayerModule to BytecodeToWrite.luac")
95
+ else:
96
+ print("misc/BytecodeToWrite.luac not found")
97
+ else:
98
+ print("Roblox is not in a game. No preview data available.")
99
+
100
+ # Write to the client's memory (kills player)
101
+ #LocalPlayer.Character.Humanoid.Health = 0
102
+
103
+ print("")
104
+
105
+ input("Press Enter to close.\n\n")
106
+ client.close()
@@ -0,0 +1,16 @@
1
+ local fs = require("@lune/fs")
2
+ local luau = require("@lune/luau")
3
+
4
+ fs.writeFile("BytecodeToWrite.luac", luau.compile([[
5
+ print("Hello World! :D")
6
+
7
+ local function sum(...)
8
+ local s = 0
9
+ for i, v in {...} do
10
+ s += v
11
+ end
12
+ return s
13
+ end
14
+ return sum(1, 2, 3, 4)]], {
15
+ optimizationLevel = 2
16
+ }))
@@ -1,10 +1,10 @@
1
1
  [build-system]
2
- requires = ["setuptools>=68", "wheel"]
3
- build-backend = "setuptools.build_meta"
2
+ requires = ["scikit-build-core>=0.10", "pybind11>=2.12"]
3
+ build-backend = "scikit_build_core.build"
4
4
 
5
5
  [project]
6
6
  name = "robloxmemoryapi"
7
- version = "0.3.0"
7
+ version = "0.3.2"
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"
@@ -14,11 +14,12 @@ authors = [
14
14
  { name = "mstudio45", email = "mstudio45@users.noreply.github.com" },
15
15
  { name = "ActualMasterOogway", email = "ActualMasterOogway@users.noreply.github.com" },
16
16
  ]
17
- keywords = ["roblox", "memory", "windows"]
17
+ keywords = ["roblox", "memory", "windows", "macOS"]
18
18
  classifiers = [
19
19
  "Programming Language :: Python :: 3",
20
20
  "License :: OSI Approved :: MIT License",
21
21
  "Operating System :: Microsoft :: Windows",
22
+ "Operating System :: MacOS",
22
23
  "Development Status :: 3 - Alpha",
23
24
  "Intended Audience :: Developers",
24
25
  "Topic :: Software Development :: Libraries",
@@ -34,13 +35,14 @@ dependencies = [
34
35
  Homepage = "https://github.com/notpoiu/RobloxMemoryAPI"
35
36
  Issues = "https://github.com/notpoiu/RobloxMemoryAPI/issues"
36
37
 
37
- [tool.setuptools]
38
- package-dir = {"" = "src"}
39
- include-package-data = true
40
-
41
- [tool.setuptools.packages.find]
42
- where = ["src"]
43
-
44
- [tool.setuptools.package-data]
45
- robloxmemoryapi = ["data/*.json"]
38
+ [tool.scikit-build]
39
+ minimum-version = "build-system.requires"
40
+ build-dir = "build/{wheel_tag}"
41
+ wheel.packages = ["src/robloxmemoryapi"]
46
42
 
43
+ [tool.scikit-build.sdist]
44
+ include = [
45
+ "CMakeLists.txt",
46
+ "src/robloxmemoryapi/**/*.cpp",
47
+ "src/robloxmemoryapi/**/*.py",
48
+ ]
@@ -0,0 +1,7 @@
1
+ # This file lists tools managed by Rokit, a toolchain manager for Roblox projects.
2
+ # For more information, see https://github.com/rojo-rbx/rokit
3
+
4
+ # New tools can be added by running `rokit add <tool>` in a terminal.
5
+
6
+ [tools]
7
+ lune = "lune-org/lune@0.10.4"
@@ -0,0 +1,231 @@
1
+ import platform
2
+ import math
3
+ import os
4
+ import subprocess
5
+ import sys
6
+ import tempfile
7
+
8
+ from ._version import __version__
9
+
10
+ __all__ = [
11
+ "RobloxRandom",
12
+ "RobloxGameClient",
13
+ "codesign_roblox_macos",
14
+ "codesign_python_macos",
15
+ "__version__",
16
+ ]
17
+
18
+
19
+ def codesign_roblox_macos(
20
+ app_path: str | os.PathLike[str] | None = None,
21
+ *,
22
+ silicon_app_path: str | os.PathLike[str] = "/Applications/Roblox.app",
23
+ intel_app_path: str | os.PathLike[str] = "/Applications/RobloxPlayer.app",
24
+ use_sudo: bool = True,
25
+ ) -> str:
26
+ """Ad-hoc sign a macOS Roblox app bundle for local memory access workflows."""
27
+ if platform.system() != "Darwin":
28
+ raise RuntimeError("codesign_roblox_macos is only available on macOS.")
29
+
30
+ if app_path is None:
31
+ app_path = silicon_app_path if platform.machine().lower() == "arm64" else intel_app_path
32
+
33
+ app_path = os.fspath(app_path)
34
+ if not os.path.exists(app_path):
35
+ raise FileNotFoundError(app_path)
36
+
37
+ sudo_prefix = ["sudo"] if use_sudo and os.geteuid() != 0 else []
38
+ subprocess.run(
39
+ sudo_prefix + ["codesign", "--remove-signature", app_path],
40
+ stdout=subprocess.DEVNULL,
41
+ stderr=subprocess.DEVNULL,
42
+ check=False,
43
+ )
44
+ subprocess.run(
45
+ sudo_prefix + ["codesign", "--force", "--deep", "--sign", "-", app_path],
46
+ check=True,
47
+ )
48
+
49
+ return app_path
50
+
51
+
52
+ def codesign_python_macos(
53
+ executable_path: str | os.PathLike[str] | None = None,
54
+ *,
55
+ use_sudo: bool = True,
56
+ ) -> str:
57
+ """Ad-hoc sign the Python executable/launcher with the macOS debugger entitlement."""
58
+ if platform.system() != "Darwin":
59
+ raise RuntimeError("codesign_python_macos is only available on macOS.")
60
+
61
+ if executable_path is None:
62
+ executable_path = sys.executable
63
+
64
+ executable_path = os.path.realpath(os.fspath(executable_path))
65
+ if not os.path.exists(executable_path):
66
+ raise FileNotFoundError(executable_path)
67
+
68
+ entitlements = """<?xml version="1.0" encoding="UTF-8"?>
69
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
70
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
71
+ <plist version="1.0">
72
+ <dict>
73
+ <key>com.apple.security.cs.debugger</key>
74
+ <true/>
75
+ <key>com.apple.security.get-task-allow</key>
76
+ <true/>
77
+ <key>SecTaskAccess</key>
78
+ <array><string>allowed</string></array>
79
+ </dict>
80
+ </plist>
81
+ """
82
+
83
+ sudo_prefix = ["sudo"] if use_sudo and os.geteuid() != 0 else []
84
+ with tempfile.NamedTemporaryFile("w", suffix=".plist", delete=False) as entitlement_file:
85
+ entitlement_file.write(entitlements)
86
+ entitlement_path = entitlement_file.name
87
+
88
+ try:
89
+ subprocess.run(
90
+ sudo_prefix + ["codesign", "--remove-signature", executable_path],
91
+ stdout=subprocess.DEVNULL,
92
+ stderr=subprocess.DEVNULL,
93
+ check=False,
94
+ )
95
+ subprocess.run(
96
+ sudo_prefix
97
+ + [
98
+ "codesign",
99
+ "--force",
100
+ "--sign",
101
+ "-",
102
+ "--entitlements",
103
+ entitlement_path,
104
+ executable_path,
105
+ ],
106
+ check=True,
107
+ )
108
+ finally:
109
+ try:
110
+ os.unlink(entitlement_path)
111
+ except OSError:
112
+ pass
113
+
114
+ return executable_path
115
+
116
+
117
+ class RobloxRandom:
118
+ MULT = 6364136223846793005
119
+ INC = 105
120
+ MASK64 = (1 << 64) - 1
121
+
122
+ def __init__(self, seed):
123
+ s = math.floor(seed)
124
+
125
+ self._state = 0
126
+ self._inc = RobloxRandom.INC
127
+ self._next_internal() # warm-up #1
128
+ self._state = (self._state + s) & RobloxRandom.MASK64
129
+ self._next_internal() # warm-up #2
130
+
131
+ def _next_internal(self):
132
+ old = self._state
133
+ self._state = (old * RobloxRandom.MULT + self._inc) & RobloxRandom.MASK64
134
+ x = ((old >> 18) ^ old) >> 27
135
+ r = old >> 59
136
+ return ((x >> r) | (x << ((32 - r) & 31))) & 0xFFFFFFFF
137
+
138
+ def _next_fraction64(self):
139
+ lo = self._next_internal()
140
+ hi = self._next_internal()
141
+ bits = (hi << 32) | lo
142
+ return bits / 2**64
143
+
144
+ def NextNumber(self, minimum=0.0, maximum=1.0):
145
+ frac = self._next_fraction64()
146
+ return minimum + frac * (maximum - minimum)
147
+
148
+ def NextInteger(self, a, b=None):
149
+ if b is None:
150
+ u = a
151
+ r = self._next_internal()
152
+ return ((u * r) >> 32) + 1
153
+ else:
154
+ lo, hi = (a, b) if a <= b else (b, a)
155
+ u = hi - lo + 1
156
+ r = self._next_internal()
157
+ return ((u * r) >> 32) + lo
158
+
159
+ class RobloxGameClient:
160
+ def __init__(
161
+ self,
162
+ pid: int = None,
163
+ process_name: str = "RobloxPlayerBeta.exe",
164
+ allow_write: bool = False,
165
+ ):
166
+ system = platform.system()
167
+ if system not in {"Windows", "Darwin"}:
168
+ self.failed = True
169
+ return
170
+
171
+ if system == "Darwin" and os.geteuid() != 0:
172
+ raise PermissionError(
173
+ "macOS memory access requires running the Python process with sudo/root. "
174
+ "Run this script with sudo and try again."
175
+ )
176
+
177
+ from .utils.memory import (
178
+ EvasiveProcess,
179
+ PROCESS_QUERY_INFORMATION,
180
+ PROCESS_VM_READ,
181
+ PROCESS_VM_WRITE,
182
+ PROCESS_VM_OPERATION,
183
+ get_pid_by_name,
184
+ )
185
+
186
+ if system == "Darwin" and process_name == "RobloxPlayerBeta.exe":
187
+ process_name = "RobloxPlayer"
188
+
189
+ if pid is None:
190
+ self.pid = get_pid_by_name(process_name)
191
+ else:
192
+ self.pid = pid
193
+
194
+ if self.pid is None or self.pid == 0:
195
+ raise ValueError("Failed to get PID.")
196
+
197
+ if system == "Darwin":
198
+ os.environ["ROBLOXMEMORYAPI_ROBLOX_PID"] = str(self.pid)
199
+
200
+ desired_access = PROCESS_VM_READ | PROCESS_QUERY_INFORMATION
201
+ if allow_write:
202
+ desired_access |= PROCESS_VM_WRITE | PROCESS_VM_OPERATION
203
+
204
+ self.memory_module = EvasiveProcess(self.pid, desired_access)
205
+ self.failed = False
206
+ self._fflags = None
207
+
208
+ def close(self):
209
+ self.memory_module.close()
210
+
211
+ @property
212
+ def FFlags(self):
213
+ if platform.system() not in {"Windows", "Darwin"}:
214
+ raise RuntimeError("This module is only compatible with Windows and macOS.")
215
+ elif self.failed:
216
+ raise RuntimeError("There was an error while getting access to memory. Please try again later.")
217
+
218
+ if self._fflags is None:
219
+ from .utils.rbx.fflags import FFlagManager
220
+ self._fflags = FFlagManager(self.memory_module)
221
+ return self._fflags
222
+
223
+ @property
224
+ def DataModel(self):
225
+ if platform.system() not in {"Windows", "Darwin"}:
226
+ raise RuntimeError("This module is only compatible with Windows and macOS.")
227
+ elif self.failed:
228
+ raise RuntimeError("There was an error while getting access to memory. Please try again later.")
229
+
230
+ from .utils.rbx.instance import DataModel
231
+ return DataModel(self.memory_module)
@@ -0,0 +1 @@
1
+ """Native extension package for robloxmemoryapi."""