From 27893b9ef5cfdbbf124a18aac9e9957b6e24c8fe Mon Sep 17 00:00:00 2001
From: phoriah <95628489+phoriah@users.noreply.github.com>
Date: Fri, 11 Apr 2025 17:02:24 +0200
Subject: [PATCH] Some renaming & formatting changes; Updated Dumps & Dumpers
---
Tools/DataType Dumper/DataType Dumper.py | 87 +++++++++++--------
Tools/DataType Dumper/Dump | 11 ++-
Tools/NotCreatable Dumper/Dump | 6 +-
.../NotCreatable Dumper.py | 81 +++++++++--------
Tools/Run Dumpers.py | 29 ++++---
saveinstance.luau | 54 ++++++------
6 files changed, 151 insertions(+), 117 deletions(-)
diff --git a/Tools/DataType Dumper/DataType Dumper.py b/Tools/DataType Dumper/DataType Dumper.py
index bf96c3f..78d2acd 100644
--- a/Tools/DataType Dumper/DataType Dumper.py
+++ b/Tools/DataType Dumper/DataType Dumper.py
@@ -1,6 +1,7 @@
import requests
import os
import re
+import sys
def array_to_dictionary(table, hybrid_mode=None):
@@ -24,33 +25,41 @@ datatypes = []
datatypes_set = set()
-def api():
+def api(version_hash=None):
+ if version_hash:
+ # Use the provided version hash
+ api_dump_url = f"https://setup.rbxcdn.com/{version_hash}-API-Dump.json"
+ try:
+ response = requests.get(api_dump_url)
+ response.raise_for_status()
+ return response
+ except requests.RequestException as e:
+ print(f"Error fetching API dump for {version_hash}: {e}")
+ sys.exit(1)
+ else:
+ # Fall back to the original method of finding the latest version
+ deploy_history_url = "https://setup.rbxcdn.com/DeployHistory.txt"
+ deploy_history = requests.get(deploy_history_url).text
- deploy_history_url = "https://setup.rbxcdn.com/DeployHistory.txt"
- deploy_history = requests.get(deploy_history_url).text
+ lines = deploy_history.splitlines()
- lines = deploy_history.splitlines()
-
- for line in reversed(lines):
-
- match = re.search(r"(version-[^\s]+)", line)
-
- if match:
- version_hash = match.group(1)
-
- api_dump_url = f"https://setup.rbxcdn.com/{version_hash}-Full-API-Dump.json"
-
- try:
- response = requests.get(api_dump_url)
- response.raise_for_status()
- return response
-
- except requests.RequestException as e:
- print(f"Error fetching API dump for {version_hash}: {e}")
+ for line in reversed(lines):
+ match = re.search(r"(version-[^\s]+)", line)
+ if match:
+ version_hash = match.group(1)
+ api_dump_url = (
+ f"https://setup.rbxcdn.com/{version_hash}-Full-API-Dump.json"
+ )
+ try:
+ response = requests.get(api_dump_url)
+ response.raise_for_status()
+ return response
+ except requests.RequestException as e:
+ print(f"Error fetching API dump for {version_hash}: {e}")
-def fetch_api():
- response = api()
+def fetch_api(version_hash=None):
+ response = api(version_hash)
api_classes = response.json()["Classes"]
global datatypes
@@ -70,27 +79,31 @@ def fetch_api():
member_tags = array_to_dictionary(member_tags)
serialization = member["Serialization"]
- if serialization["CanLoad"] :
+ if True:
value_type = member["ValueType"]
value_type_name = value_type["Name"]
value_type_cat = value_type["Category"]
if value_type_cat == "Enum":
- value_type_name = "Enum"
+ value_type_name = ""
if value_type_cat == "Class":
- value_type_name = "Class"
+ value_type_name = ""
if value_type_name not in datatypes_set:
datatypes_set.add(value_type_name)
datatypes.append(value_type_name)
-try:
- fetch_api()
- datatypes.sort()
- s = "\n".join(datatypes) + "\n"
- print(s)
- script_dir = os.path.dirname(os.path.realpath(__file__))
- output_file_path = os.path.join(script_dir, "Dump")
- with open(output_file_path, "w") as file:
- file.write(s)
-except Exception as e:
- print(f"Error: {e}")
+if __name__ == "__main__":
+ version_hash = None
+ if len(sys.argv) > 1:
+ version_hash = sys.argv[1]
+ try:
+ fetch_api(version_hash)
+ datatypes.sort()
+ s = "\n".join(datatypes) + "\n"
+ print(s)
+ script_dir = os.path.dirname(os.path.realpath(__file__))
+ output_file_path = os.path.join(script_dir, "Dump")
+ with open(output_file_path, "w") as file:
+ file.write(s)
+ except Exception as e:
+ print(f"Error: {e}")
diff --git a/Tools/DataType Dumper/Dump b/Tools/DataType Dumper/Dump
index 016abe5..d87045e 100644
--- a/Tools/DataType Dumper/Dump
+++ b/Tools/DataType Dumper/Dump
@@ -1,16 +1,19 @@
+
Axes
BinaryString
BrickColor
CFrame
-Class
+CSGPropertyData
Color3
Color3uint8
ColorSequence
Content
ContentId
-Enum
+DateTime
Faces
+FacsReplicationData
Font
+NetAssetRef
NumberRange
NumberSequence
OptionalCoordinateFrame
@@ -21,8 +24,12 @@ QDir
QFont
Ray
Rect
+Region3int16
+ReplicationPV
SecurityCapabilities
SharedString
+SystemAddress
+TweenInfo
UDim
UDim2
UniqueId
diff --git a/Tools/NotCreatable Dumper/Dump b/Tools/NotCreatable Dumper/Dump
index b092f4f..21f4512 100644
--- a/Tools/NotCreatable Dumper/Dump
+++ b/Tools/NotCreatable Dumper/Dump
@@ -19,8 +19,6 @@ AnimationStreamTrack
AnimationTrack
-AssetImportSession
-
AnimationImportData
FacsImportData
@@ -115,6 +113,10 @@ SelectionLasso
HttpRequest
+ImportSession
+
+AssetImportSession
+
InputObject
JointInstance
diff --git a/Tools/NotCreatable Dumper/NotCreatable Dumper.py b/Tools/NotCreatable Dumper/NotCreatable Dumper.py
index 587cb5a..f29e245 100644
--- a/Tools/NotCreatable Dumper/NotCreatable Dumper.py
+++ b/Tools/NotCreatable Dumper/NotCreatable Dumper.py
@@ -1,7 +1,7 @@
import requests
import os
import re
-
+import sys
def array_to_dictionary(table, hybrid_mode=None):
tmp = {}
@@ -22,34 +22,38 @@ def array_to_dictionary(table, hybrid_mode=None):
s = "\n"
+def api(version_hash=None):
+ if version_hash:
+ # Use the provided version hash
+ api_dump_url = f"https://setup.rbxcdn.com/{version_hash}-Full-API-Dump.json"
+ try:
+ response = requests.get(api_dump_url)
+ response.raise_for_status()
+ return response
+ except requests.RequestException as e:
+ print(f"Error fetching API dump for {version_hash}: {e}")
+ sys.exit(1)
+ else:
+ # Fall back to the original method of finding the latest version
+ deploy_history_url = "https://setup.rbxcdn.com/DeployHistory.txt"
+ deploy_history = requests.get(deploy_history_url).text
-def api():
+ lines = deploy_history.splitlines()
- deploy_history_url = "https://setup.rbxcdn.com/DeployHistory.txt"
- deploy_history = requests.get(deploy_history_url).text
+ for line in reversed(lines):
+ match = re.search(r"(version-[^\s]+)", line)
+ if match:
+ version_hash = match.group(1)
+ api_dump_url = f"https://setup.rbxcdn.com/{version_hash}-Full-API-Dump.json"
+ try:
+ response = requests.get(api_dump_url)
+ response.raise_for_status()
+ return response
+ except requests.RequestException as e:
+ print(f"Error fetching API dump for {version_hash}: {e}")
- lines = deploy_history.splitlines()
-
- for line in reversed(lines):
-
- match = re.search(r"(version-[^\s]+)", line)
-
- if match:
- version_hash = match.group(1)
-
- api_dump_url = f"https://setup.rbxcdn.com/{version_hash}-Full-API-Dump.json"
-
- try:
- response = requests.get(api_dump_url)
- response.raise_for_status()
- return response
-
- except requests.RequestException as e:
- print(f"Error fetching API dump for {version_hash}: {e}")
-
-
-def fetch_api():
- response = api()
+def fetch_api(version_hash=None):
+ response = api(version_hash)
api_classes = response.json()["Classes"]
global s
@@ -93,13 +97,18 @@ def fetch_api():
return class_list
-
-try:
- fetch_api()
- print(s)
- script_dir = os.path.dirname(os.path.realpath(__file__))
- output_file_path = os.path.join(script_dir, "Dump")
- with open(output_file_path, "w") as file:
- file.write(s)
-except Exception as e:
- print(f"Error: {e}")
+if __name__ == "__main__":
+ # Check if version hash was passed as a command line argument
+ version_hash = None
+ if len(sys.argv) > 1:
+ version_hash = sys.argv[1]
+
+ try:
+ fetch_api(version_hash)
+ print(s)
+ script_dir = os.path.dirname(os.path.realpath(__file__))
+ output_file_path = os.path.join(script_dir, "Dump")
+ with open(output_file_path, "w") as file:
+ file.write(s)
+ except Exception as e:
+ print(f"Error: {e}")
\ No newline at end of file
diff --git a/Tools/Run Dumpers.py b/Tools/Run Dumpers.py
index b3461be..40eb27d 100644
--- a/Tools/Run Dumpers.py
+++ b/Tools/Run Dumpers.py
@@ -1,9 +1,8 @@
import os
import subprocess
+import sys
-
-def run_python_files_in_directories(directory, script_name):
-
+def run_python_files_in_directories(directory, script_name, version_hash=None):
for root, dirs, files in os.walk(directory):
for file in files:
if file.endswith(".py"):
@@ -13,17 +12,21 @@ def run_python_files_in_directories(directory, script_name):
continue
print(f"Found Python file: {file_path}")
try:
-
- subprocess.run(["python", file_path], check=True)
+ if version_hash:
+ subprocess.run(["python", file_path, version_hash], check=True)
+ else:
+ subprocess.run(["python", file_path], check=True)
print(f"Executed: {file_path}")
except subprocess.CalledProcessError as e:
print(f"Error running {file_path}: {e}")
-
-current_directory = os.path.dirname(os.path.abspath(__file__))
-
-
-script_name = os.path.abspath(__file__)
-
-
-run_python_files_in_directories(current_directory, script_name)
+if __name__ == "__main__":
+ current_directory = os.path.dirname(os.path.abspath(__file__))
+ script_name = os.path.abspath(__file__)
+
+ # Check if version hash was passed as a command line argument
+ version_hash = None
+ if len(sys.argv) > 1:
+ version_hash = sys.argv[1]
+
+ run_python_files_in_directories(current_directory, script_name, version_hash)
\ No newline at end of file
diff --git a/saveinstance.luau b/saveinstance.luau
index 202f004..a59f26c 100644
--- a/saveinstance.luau
+++ b/saveinstance.luau
@@ -11,13 +11,13 @@ local function ArrayToDict(t, hydridMode, valueOverride, typeStrict)
local tmp = {}
if hydridMode then
- for some1, some2 in t do
- if type(some1) == "number" then
- tmp[some2] = valueOverride or true
- elseif type(some2) == "table" then
- tmp[some1] = ArrayToDict(some2, hydridMode) -- Some1 is Class, Some2 is Name
+ for any1, any2 in t do
+ if type(any1) == "number" then
+ tmp[any2] = valueOverride or true
+ elseif type(any2) == "table" then
+ tmp[any1] = ArrayToDict(any2, hydridMode) -- any1 is Class, any2 is Name
else
- tmp[some1] = some2
+ tmp[any1] = any2
end
end
else
@@ -687,7 +687,7 @@ XML_Descriptors = {
__ENUM = function(raw)
return raw.Value, "token"
end,
- __EXTREME = function(raw)
+ __NORMALIZE_NUMBER = function(raw)
if raw ~= raw then
return "NAN"
elseif raw == math.huge then
@@ -698,7 +698,7 @@ XML_Descriptors = {
return raw
end,
- __EXTREME_RANGE = function(raw)
+ __NORMALIZE_RANGE = function(raw)
return raw ~= raw and "0" or raw -- Normally we should return "-nan(ind)" instead of "0" but this adds more compatibility
end,
__MINMAX = function(min, max, descriptor)
@@ -710,14 +710,14 @@ XML_Descriptors = {
__SEQUENCE = function(raw, valueFormatter)
-- The value is the text content, formatted as a space-separated list of floating point numbers.
-- tostring(raw) also works (but way slower rn)
- local __EXTREME_RANGE = XML_Descriptors.__EXTREME_RANGE
+ local __NORMALIZE_RANGE = XML_Descriptors.__NORMALIZE_RANGE
local sequence = ""
for _, keypoint in raw.Keypoints do
local Value = keypoint.Value
- sequence ..= keypoint.Time .. " " .. (valueFormatter and valueFormatter(Value) or __EXTREME_RANGE(Value) .. " " .. __EXTREME_RANGE(
+ sequence ..= keypoint.Time .. " " .. (valueFormatter and valueFormatter(Value) or __NORMALIZE_RANGE(Value) .. " " .. __NORMALIZE_RANGE(
keypoint.Envelope
) .. " ") -- ? Trailing whitespace is only needed for lune compatibility
end
@@ -801,13 +801,13 @@ XML_Descriptors = {
-- The value is the text content, formatted as a space-separated list of FLOATing point numbers.
return XML_Descriptors.__SEQUENCE(raw, function(color3)
- local __EXTREME_RANGE = XML_Descriptors.__EXTREME_RANGE
+ local __NORMALIZE_RANGE = XML_Descriptors.__NORMALIZE_RANGE
- return __EXTREME_RANGE(color3.R)
+ return __NORMALIZE_RANGE(color3.R)
.. " "
- .. __EXTREME_RANGE(color3.G)
+ .. __NORMALIZE_RANGE(color3.G)
.. " "
- .. __EXTREME_RANGE(color3.B)
+ .. __NORMALIZE_RANGE(color3.B)
.. " 0 "
end)
end,
@@ -824,7 +824,7 @@ XML_Descriptors = {
CoordinateFrame = function(raw)
return "" .. XML_Descriptors.CFrame(raw) .. ""
end,
- -- DateTime = function(raw) return raw.UnixTimestampMillis end, -- TODO
+ -- DateTime = function(raw) return raw.UnixTimestampMillis end, -- ? Not sure
Faces = function(raw)
-- The text of this element is formatted as an integer between 0 and 63
return "" .. __BIT(raw.Right, raw.Top, raw.Back, raw.Left, raw.Bottom, raw.Front) .. ""
@@ -864,14 +864,14 @@ XML_Descriptors = {
end,
NumberRange = function(raw) -- tostring(raw) also works
-- The value is the text content, formatted as a space-separated list of floating point numbers.
- local __EXTREME_RANGE = XML_Descriptors.__EXTREME_RANGE
+ local __NORMALIZE_RANGE = XML_Descriptors.__NORMALIZE_RANGE
- return __EXTREME_RANGE(raw.Min) .. " " .. __EXTREME_RANGE(raw.Max) --[[.. " "]] -- ! This might be required for compatibility; __EXTREME_RANGE is not needed here but it fixes the issue where "nan 10" value would reset to "0 0"
+ return __NORMALIZE_RANGE(raw.Min) .. " " .. __NORMALIZE_RANGE(raw.Max) --[[.. " "]] -- ! This might be required for compatibility; __NORMALIZE_RANGE is not needed here but it fixes the issue where "nan 10" value would reset to "0 0"
end,
NumberSequence = nil,
-- NumberSequence = Descriptors.__SEQUENCE,
- -- Path2DControlPoint = function(raw) -- Not sure
+ -- Path2DControlPoint = function(raw) -- ? Not sure
-- local udim2 = XML_Descriptors.UDim2
-- return ""
-- .. udim2(raw.Position)
@@ -967,7 +967,7 @@ XML_Descriptors = {
.. ""
end,
- -- UniqueId = function(raw)
+ -- UniqueId = function(raw) -- ? Not sure -- ? No idea if this even needs a Descriptor
-- --[[
-- UniqueId properties might be random everytime Studio saves a place file
-- and don't have a use right now outside of packages, which SSI doesn't
@@ -975,7 +975,7 @@ XML_Descriptors = {
-- them until we have to.
-- ]]
-- -- https://github.com/MaximumADHD/Roblox-Client-Tracker/blob/roblox/LuaPackages/Packages/_Index/ApolloClientTesting/ApolloClientTesting/utilities/common/makeUniqueId.lua#L62
- -- return "" -- ? No idea if this even needs a Descriptor
+ -- return ""
-- end,
Vector2 = function(raw)
@@ -1013,10 +1013,10 @@ XML_Descriptors = {
--------------------------------------------------------------
-----------%localappdata%/Roblox/GlobalSettings_13.xml--------
--------------------------------------------------------------
- -- QDir = function(raw)
+ -- QDir = function(raw) -- ? Not sure
-- return raw
-- end,
- -- QFont = function(raw)
+ -- QFont = function(raw) -- ? Not sure
-- return raw
-- end,
}
@@ -1090,10 +1090,10 @@ for descriptorName, redirectName in
NumberSequence = "__SEQUENCE",
Vector2int16 = "Vector2",
Vector3int16 = "Vector3",
- double = "__EXTREME",
- float = "__EXTREME",
- int = "__EXTREME",
- int64 = "__EXTREME",
+ double = "__NORMALIZE_NUMBER",
+ float = "__NORMALIZE_NUMBER",
+ int = "__NORMALIZE_NUMBER",
+ int64 = "__NORMALIZE_NUMBER",
}
do
XML_Descriptors[descriptorName] = XML_Descriptors[redirectName]
@@ -1598,7 +1598,7 @@ local GLOBAL_ENV = getgenv and getgenv() or _G or shared
--- @field AntiIdle boolean -- Prevents the 20-minute-Idle Kick. ___Default:___ true
--- Anonymous {boolean|table{UserId = string, Name = string}} -- * **RISKY:** Cleans the file of any info related to your account like: Name, UserId. This is useful for some games that might store that info in GUIs or other Instances. Might potentially mess up parts of strings that contain characters that match your Name or parts of numbers that match your UserId. Can also be a table with UserId & Name keys. ___Default:___ false
--- @field ShowStatus boolean -- ___Default:___ true
---- @field Callback boolean -- If set, the serialized data will be sent to the callback function instead of to file. ___Default:___ false
+--- @field Callback function -- If set, the serialized data will be sent to the callback function instead of to file. ___Default:___ false
--- @field mode string -- Valid modes: full, optimized, scripts. Change this to invalid mode like "invalid" if you only want ExtraInstances. "optimized" mode is **NOT** supported with *@Object* option. ___Default:___ `"optimized"`
--- @field noscripts boolean -- ___Aliases:___ `Decompile`. ___Default:___ false
--- @field scriptcache boolean -- ___Default:___ true