mirror of
https://github.com/luau/UniversalSynSaveInstance.git
synced 2026-02-03 22:23:03 +02:00
Some renaming & formatting changes; Updated Dumps & Dumpers
This commit is contained in:
@@ -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
|
||||
|
||||
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"
|
||||
|
||||
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,21 +79,25 @@ 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()
|
||||
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)
|
||||
@@ -92,5 +105,5 @@ try:
|
||||
output_file_path = os.path.join(script_dir, "Dump")
|
||||
with open(output_file_path, "w") as file:
|
||||
file.write(s)
|
||||
except Exception as e:
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -19,8 +19,6 @@ AnimationStreamTrack
|
||||
|
||||
AnimationTrack
|
||||
|
||||
AssetImportSession
|
||||
|
||||
AnimationImportData
|
||||
|
||||
FacsImportData
|
||||
@@ -115,6 +113,10 @@ SelectionLasso
|
||||
|
||||
HttpRequest
|
||||
|
||||
ImportSession
|
||||
|
||||
AssetImportSession
|
||||
|
||||
InputObject
|
||||
|
||||
JointInstance
|
||||
|
||||
@@ -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():
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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()
|
||||
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:
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
@@ -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:
|
||||
|
||||
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}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
current_directory = os.path.dirname(os.path.abspath(__file__))
|
||||
script_name = os.path.abspath(__file__)
|
||||
|
||||
current_directory = os.path.dirname(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]
|
||||
|
||||
|
||||
script_name = os.path.abspath(__file__)
|
||||
|
||||
|
||||
run_python_files_in_directories(current_directory, script_name)
|
||||
run_python_files_in_directories(current_directory, script_name, version_hash)
|
||||
@@ -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 "<CFrame>" .. XML_Descriptors.CFrame(raw) .. "</CFrame>"
|
||||
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 "<faces>" .. __BIT(raw.Right, raw.Top, raw.Back, raw.Left, raw.Bottom, raw.Front) .. "</faces>"
|
||||
@@ -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 "<Position>"
|
||||
-- .. udim2(raw.Position)
|
||||
@@ -967,7 +967,7 @@ XML_Descriptors = {
|
||||
.. "</YO>"
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user