diff --git a/.gitignore b/.gitignore index b4fb930..55a9b0f 100644 --- a/.gitignore +++ b/.gitignore @@ -330,4 +330,5 @@ ASALocalRun/ .mfractor/ # Library Test -RobloxFileFormat.exe \ No newline at end of file +RobloxFileFormat.exe +*.lock diff --git a/Generated/Classes.cs b/Generated/Classes.cs index b985e09..b23d79c 100644 --- a/Generated/Classes.cs +++ b/Generated/Classes.cs @@ -1,5 +1,5 @@ // Auto-generated list of creatable Roblox classes. -// Updated as of 0.437.0.406875 +// Updated as of 0.438.0.407270 using System; @@ -51,6 +51,7 @@ namespace RobloxFiles IsService = true; } + [Obsolete] public string ApiKey = ""; } @@ -1139,6 +1140,7 @@ namespace RobloxFiles } public float LineHeight = 1; + public bool RichText = false; public string Text = "Button"; [Obsolete] @@ -1208,6 +1210,7 @@ namespace RobloxFiles } public float LineHeight = 1; + public bool RichText = false; public string Text = "Label"; [Obsolete] @@ -1282,6 +1285,7 @@ namespace RobloxFiles public bool MultiLine = false; public Color3 PlaceholderColor3 = Color3.FromRGB(178, 178, 178); public string PlaceholderText = ""; + public bool RichText = false; public bool ShowNativeInput = true; public string Text = "TextBox"; @@ -1840,22 +1844,22 @@ namespace RobloxFiles IsService = true; } - public Color3 Ambient = new Color3(); - public float Brightness = 2; + public Color3 Ambient = Color3.FromRGB(127, 127, 127); + public float Brightness = 1; public Color3 ColorShift_Bottom = new Color3(); public Color3 ColorShift_Top = new Color3(); public float EnvironmentDiffuseScale = 0; public float EnvironmentSpecularScale = 0; public float ExposureCompensation = 0; - public Color3 FogColor = Color3.FromRGB(192, 192, 192); + public Color3 FogColor = Color3.FromRGB(191, 191, 191); public float FogEnd = 100000; public float FogStart = 0; public float GeographicLatitude = 41.7333f; - public bool GlobalShadows = true; - public Color3 OutdoorAmbient = Color3.FromRGB(128, 128, 128); + public bool GlobalShadows = false; + public Color3 OutdoorAmbient = Color3.FromRGB(127, 127, 127); [Obsolete] - public bool Outlines = false; + public bool Outlines = true; [Obsolete] public Color3 ShadowColor = Color3.FromRGB(178, 178, 183); @@ -2167,7 +2171,7 @@ namespace RobloxFiles public byte[] MaterialColors = Convert.FromBase64String("AAAAAAAAan8/P39rf2Y/ilY+j35fi21PZmxvZbDqw8faiVpHOi4kHh4lZlw76JxKc3trhHtagcLgc4RKxr21zq2UlJSM"); public byte[] PhysicsGrid = Convert.FromBase64String("AgMAAAAAAAAAAAAAAAA="); public byte[] SmoothGrid = Convert.FromBase64String("AQU="); - public Color3 WaterColor = Color3.FromRGB(12, 84, 92); + public Color3 WaterColor = Color3.FromRGB(12, 84, 91); public float WaterReflectance = 1; public float WaterTransparency = 0.3f; public float WaterWaveSize = 0.15f; @@ -2264,7 +2268,7 @@ namespace RobloxFiles public double DistributedGameTime = 0; public bool ExplicitAutoJoints = true; public float FallenPartsDestroyHeight = -500; - public bool FilteringEnabled = true; + public bool FilteringEnabled = false; public float Gravity = 196.2f; public bool StreamingEnabled = false; public int StreamingMinRadius = 64; @@ -2833,7 +2837,7 @@ namespace RobloxFiles public ReverbType AmbientReverb = ReverbType.NoReverb; public float DistanceFactor = 3.33f; public float DopplerScale = 1; - public bool RespectFilteringEnabled = true; + public bool RespectFilteringEnabled = false; public float RolloffScale = 1; } @@ -2849,6 +2853,14 @@ namespace RobloxFiles public Color3 SparkleColor = Color3.FromRGB(144, 25, 255); } + public class SpawnerService : Instance + { + public SpawnerService() + { + IsService = true; + } + } + public class StandalonePluginScripts : Instance { } @@ -2874,7 +2886,7 @@ namespace RobloxFiles public bool AllowCustomAnimations = true; public bool AutoJumpEnabled = true; - public float CameraMaxZoomDistance = 128; + public float CameraMaxZoomDistance = 400; public float CameraMinZoomDistance = 0.5f; public CameraMode CameraMode = CameraMode.Classic; public float CharacterJumpHeight = 7.2f; diff --git a/Generated/Enums.cs b/Generated/Enums.cs index b78f573..4184f47 100644 --- a/Generated/Enums.cs +++ b/Generated/Enums.cs @@ -1,5 +1,5 @@ // Auto-generated list of Roblox enums. -// Updated as of 0.437.0.406875 +// Updated as of 0.438.0.407270 namespace RobloxFiles.Enums { @@ -1912,7 +1912,9 @@ namespace RobloxFiles.Enums DialogButtonText, DialogButtonBorder, DialogMainButton, - DialogMainButtonText + DialogMainButtonText, + InfoBarWarningBackground, + InfoBarWarningText } public enum StudioStyleGuideModifier diff --git a/LibTest/Program.cs b/LibTest/Program.cs index d4cb7d2..92d7b3b 100644 --- a/LibTest/Program.cs +++ b/LibTest/Program.cs @@ -1,18 +1,87 @@ using System; +using System.Collections.Generic; using System.Diagnostics; +using System.IO; +using System.Text.RegularExpressions; + +using RobloxFiles.DataTypes; namespace RobloxFiles { + // If the solution is built as an exe, this class is + // used to drive some basic testing of the library. + internal static class Program { + const string pattern = "\\d+$"; + + static void CountAssets(string path) + { + Console.WriteLine("Opening file..."); + RobloxFile target = RobloxFile.Open(path); + + var workspace = target.FindFirstChildOfClass(); + var assets = new HashSet(); + + foreach (Instance inst in workspace.GetDescendants()) + { + var instPath = inst.GetFullName(); + var props = inst.Properties; + + foreach (var prop in props) + { + var propName = prop.Key; + var content = prop.Value.CastValue(); + + if (content != null) + { + string url = content.Url.Trim(); + + var id = Regex + .Match(url, pattern)? + .Value; + + if (id != null && id.Length > 5) + url = "rbxassetid://" + id; + + if (url.Length > 0 && !assets.Contains(url)) + { + Console.WriteLine($"[{url}] at {instPath}.{propName}"); + assets.Add(url); + } + } + } + } + + Console.WriteLine("Done! Press any key to continue..."); + Console.Read(); + } + [STAThread] static void Main(string[] args) { - RobloxFile bin = RobloxFile.Open(@"LibTest\Binary.rbxl"); - Debugger.Break(); + if (args.Length > 0) + { + string path = args[0]; + CountAssets(path); + } + else + { + RobloxFile bin = RobloxFile.Open(@"LibTest\Binary.rbxl"); + RobloxFile xml = RobloxFile.Open(@"LibTest\Xml.rbxlx"); - RobloxFile xml = RobloxFile.Open(@"LibTest\Xml.rbxlx"); - Debugger.Break(); + Console.WriteLine("Files opened! Pausing execution for debugger analysis..."); + Debugger.Break(); + + using (FileStream binStream = File.OpenWrite(@"LibTest\Binary_SaveTest.rbxl")) + bin.Save(binStream); + + using (FileStream xmlStream = File.OpenWrite(@"LibTest\Xml_SaveTest.rbxlx")) + xml.Save(xmlStream); + + Console.WriteLine("Files saved! Pausing execution for debugger analysis..."); + Debugger.Break(); + } } } } diff --git a/Plugins/.vscode/tasks.json b/Plugins/.vscode/tasks.json index f19b956..af3f11b 100644 --- a/Plugins/.vscode/tasks.json +++ b/Plugins/.vscode/tasks.json @@ -8,6 +8,16 @@ "label": "Build Plugin", "command": "rojo build --output GenerateApiDump.rbxm", + "group": "build" + }, + + { + "type": "shell", + "label": "Build and Test Plugin", + + "command": "powershell -ExecutionPolicy ByPass -File DeployToStudio.ps1", + "dependsOn": ["Build Plugin"], + "group": { "kind": "build", diff --git a/Plugins/DeployToStudio.ps1 b/Plugins/DeployToStudio.ps1 new file mode 100644 index 0000000..be8919a --- /dev/null +++ b/Plugins/DeployToStudio.ps1 @@ -0,0 +1,7 @@ +$pluginName = "GenerateApiDump.rbxm" + +$studioKey = "HKCU:\Software\Roblox\RobloxStudio" +$contentDir = Get-ItemPropertyValue -Path $studioKey -Name "ContentFolder" + +$destPath = $contentDir + "/../BuiltInPlugins/" + $pluginName +Copy-Item -Path $pluginName -Destination $destPath \ No newline at end of file diff --git a/Plugins/GenerateApiDump.rbxm b/Plugins/GenerateApiDump.rbxm index 9c7371a..9df9c4c 100644 Binary files a/Plugins/GenerateApiDump.rbxm and b/Plugins/GenerateApiDump.rbxm differ diff --git a/Plugins/GenerateApiDump/init.server.lua b/Plugins/GenerateApiDump/init.server.lua index 3727b05..f2821d9 100644 --- a/Plugins/GenerateApiDump/init.server.lua +++ b/Plugins/GenerateApiDump/init.server.lua @@ -14,6 +14,21 @@ local singletons = StarterCharacterScripts = StarterPlayer:WaitForChild("StarterCharacterScripts"); } +local numberTypes = +{ + int = true; + long = true; + float = true; + double = true; +} + +local stringTypes = +{ + string = true; + Content = true; + ProtectedString = true; +} + local isCoreScript = pcall(function () local restricted = game:GetService("RobloxPluginGuiService") return tostring(restricted) @@ -246,6 +261,9 @@ if plugin then "Generates a C# dump of Roblox's Enum API.", "rbxasset://textures/Icon_Stream_Off@2x.png" ) + + classButton.ClickableWhenViewportHidden = true + enumButton.ClickableWhenViewportHidden = true end local function getAsync(url) @@ -266,6 +284,7 @@ local function getAsync(url) end local function generateClasses() + local env = getfenv() local version = getAsync(baseUrl .. "version.txt") local apiDump = getAsync(baseUrl .. "API-Dump.json") @@ -296,9 +315,9 @@ local function generateClasses() pcall(function () class.Object = Instance.new(className) - if ServerStorage:FindFirstChild("DumpFolder") then + if game:FindFirstChild("DumpFolder") then class.Object.Name = className - class.Object.Parent = ServerStorage.DumpFolder + class.Object.Parent = game.DumpFolder end end) end @@ -510,11 +529,41 @@ local function generateClasses() end) end - local comment = " // Default missing!" - local category = prop.ValueType.Category + local typeData = prop.ValueType + local category = typeData.Category + + if not gotValue and category ~= "Class" then + -- Fallback to implicit defaults + local typeName = typeData.Name + + if numberTypes[typeName] then + value = 0 + gotValue = true + elseif stringTypes[typeName] then + value = "" + gotValue = true + elseif category == "DataType" then + local DataType = env[typeName] + + if DataType and typeof(DataType) == "table" and not rawget(env, typeName) then + pcall(function () + value = DataType.new() + gotValue = true + end) + end + end + + local id = string.format("%s.%s", className, propName) + local src = string.format("[%s]", script.Parent:GetFullName()) + + if gotValue then + warn(src, "Fell back to implicit value for property:", id) + else + warn(src, "!! Could not figure out default value for property:", id) + end + end if gotValue then - local category = prop.ValueType.Category local formatFunc = getFormatFunction(valueType) if not formatFunc then @@ -535,7 +584,6 @@ local function generateClasses() end default = " = " .. result - comment = "" end if propTags.Deprecated then @@ -548,10 +596,9 @@ local function generateClasses() if category == "Class" then default = " = null" - comment = "" end - writeLine("public %s %s%s;%s", valueType, name, default, comment) + writeLine("public %s %s%s;", valueType, name, default) if propTags.Deprecated and i ~= #propNames then writeLine() diff --git a/Plugins/Null.rbxlx b/Plugins/Null.rbxlx new file mode 100644 index 0000000..d9ffee6 --- /dev/null +++ b/Plugins/Null.rbxlx @@ -0,0 +1,7 @@ + + + + DumpFolder + + + \ No newline at end of file diff --git a/RobloxFileFormat.csproj b/RobloxFileFormat.csproj index f92f582..1bdb031 100644 --- a/RobloxFileFormat.csproj +++ b/RobloxFileFormat.csproj @@ -6,7 +6,7 @@ Debug AnyCPU {CF50C0E2-23A7-4DC1-B4B2-E60CDE716253} - Library + Exe Properties RobloxFiles RobloxFileFormat diff --git a/RobloxFileFormat.dll b/RobloxFileFormat.dll index b3a63ab..708628e 100644 Binary files a/RobloxFileFormat.dll and b/RobloxFileFormat.dll differ