0.443.0.409841

This commit is contained in:
CloneTrooper1019 2020-08-14 12:35:27 -05:00
parent 0a6c8f38d4
commit 0ca6738cb9
12 changed files with 512 additions and 2105 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,7 +1,7 @@
local Format = {} local Format = {}
function Format.Null(value) function Format.Null(value)
return "null" return nil
end end
function Format.Bytes(value) function Format.Bytes(value)
@ -9,7 +9,13 @@ function Format.Bytes(value)
local fmt = "Convert.FromBase64String(%q)" local fmt = "Convert.FromBase64String(%q)"
return fmt:format(value) return fmt:format(value)
else else
return "new byte[0]" return "Array.Empty<byte>()"
end
end
function Format.Bool(value)
if value then
return "true"
end end
end end
@ -17,21 +23,21 @@ function Format.String(value)
return string.format("%q", value) return string.format("%q", value)
end end
function Format.Int(value) function Format.Int(value, default)
if value == 2147483647 then if value == 2147483647 then
return "int.MaxValue" return "int.MaxValue"
elseif value == -2147483648 then elseif value == -2147483648 then
return "int.MinValue" return "int.MinValue"
else elseif value ~= 0 or default then
return string.format("%i", value) return string.format("%i", value)
end end
end end
function Format.Number(value) function Format.Number(value, default)
local int = math.floor(value) local int = math.floor(value)
if math.abs(value - int) < 0.001 then if math.abs(value - int) < 0.001 then
return Format.Int(int) return Format.Int(int, default)
end end
local result = string.format("%.5f", value) local result = string.format("%.5f", value)
@ -40,10 +46,12 @@ function Format.Number(value)
return result return result
end end
function Format.Double(value) function Format.Double(value, default)
local result = Format.Number(value) local result = Format.Number(value, default)
if result == "inf" then if not result then
return nil
elseif result == "inf" then
return "double.MaxValue" return "double.MaxValue"
elseif result == "-inf" then elseif result == "-inf" then
return "double.MinValue" return "double.MinValue"
@ -52,10 +60,12 @@ function Format.Double(value)
end end
end end
function Format.Float(value) function Format.Float(value, default)
local result = Format.Number(value) local result = Format.Number(value, default)
if result == "inf" then if not result then
return nil
elseif result == "inf" then
return "float.MaxValue" return "float.MaxValue"
elseif result == "-inf" then elseif result == "-inf" then
return "float.MinValue" return "float.MinValue"
@ -73,7 +83,7 @@ function Format.Flags(flag, enum)
for _,item in pairs(enum:GetEnumItems()) do for _,item in pairs(enum:GetEnumItems()) do
if flag[item.Name] then if flag[item.Name] then
value = value + (2 ^ item.Value) value += (2 ^ item.Value)
end end
end end
@ -103,17 +113,17 @@ function Format.Color3(color)
return "new Color3()" return "new Color3()"
end end
local r = Format.Float(color.r) local r = Format.Float(color.R, true)
local g = Format.Float(color.g) local g = Format.Float(color.G, true)
local b = Format.Float(color.b) local b = Format.Float(color.B, true)
local fmt = "%s(%s, %s, %s)"; local fmt = "%s(%s, %s, %s)";
local constructor = "new Color3"; local constructor = "new Color3";
if string.find(r .. g .. b, 'f') then if string.find(r .. g .. b, 'f') then
r = Format.Int(color.r * 255) r = Format.Int(color.R * 255)
g = Format.Int(color.g * 255) g = Format.Int(color.G * 255)
b = Format.Int(color.b * 255) b = Format.Int(color.B * 255)
constructor = "Color3.FromRGB" constructor = "Color3.FromRGB"
end end
@ -126,8 +136,8 @@ function Format.UDim(udim)
return "new UDim()" return "new UDim()"
end end
local scale = Format.Float(udim.Scale) local scale = Format.Float(udim.Scale, true)
local offset = Format.Int(udim.Offset) local offset = Format.Int(udim.Offset, true)
local fmt = "new UDim(%s, %s)" local fmt = "new UDim(%s, %s)"
return fmt:format(scale, offset) return fmt:format(scale, offset)
@ -138,11 +148,11 @@ function Format.UDim2(udim2)
return "new UDim2()" return "new UDim2()"
end end
local xScale = Format.Float(udim2.X.Scale) local xScale = Format.Float(udim2.X.Scale, true)
local yScale = Format.Float(udim2.Y.Scale) local yScale = Format.Float(udim2.Y.Scale, true)
local xOffset = Format.Int(udim2.X.Offset) local xOffset = Format.Int(udim2.X.Offset, true)
local yOffset = Format.Int(udim2.Y.Offset) local yOffset = Format.Int(udim2.Y.Offset, true)
local fmt = "new UDim2(%s, %s, %s, %s)" local fmt = "new UDim2(%s, %s, %s, %s)"
return fmt:format(xScale, xOffset, yScale, yOffset) return fmt:format(xScale, xOffset, yScale, yOffset)
@ -153,8 +163,8 @@ function Format.Vector2(v2)
return "new Vector2()" return "new Vector2()"
end end
local x = Format.Float(v2.X) local x = Format.Float(v2.X, true)
local y = Format.Float(v2.Y) local y = Format.Float(v2.Y, true)
local fmt = "new Vector2(%s, %s)" local fmt = "new Vector2(%s, %s)"
return fmt:format(x, y) return fmt:format(x, y)
@ -165,9 +175,9 @@ function Format.Vector3(v3)
return "new Vector3()" return "new Vector3()"
end end
local x = Format.Float(v3.X) local x = Format.Float(v3.X, true)
local y = Format.Float(v3.Y) local y = Format.Float(v3.Y, true)
local z = Format.Float(v3.Z) local z = Format.Float(v3.Z, true)
local fmt = "new Vector3(%s, %s, %s)" local fmt = "new Vector3(%s, %s, %s)"
return fmt:format(x, y, z) return fmt:format(x, y, z)
@ -185,16 +195,16 @@ function Format.CFrame(cf)
if rot == blankCF then if rot == blankCF then
local fmt = "new CFrame(%s, %s, %s)" local fmt = "new CFrame(%s, %s, %s)"
local x = Format.Float(cf.X) local x = Format.Float(cf.X, true)
local y = Format.Float(cf.Y) local y = Format.Float(cf.Y, true)
local z = Format.Float(cf.Z) local z = Format.Float(cf.Z, true)
return fmt:format(x, y, z) return fmt:format(x, y, z)
else else
local comp = { cf:GetComponents() } local comp = { cf:GetComponents() }
for i = 1,12 do for i = 1,12 do
comp[i] = Format.Float(comp[i]) comp[i] = Format.Float(comp[i], true)
end end
local fmt = "new CFrame(%s)" local fmt = "new CFrame(%s)"
@ -209,10 +219,10 @@ function Format.NumberRange(nr)
local max = nr.Max local max = nr.Max
local fmt = "new NumberRange(%s)" local fmt = "new NumberRange(%s)"
local value = Format.Float(min) local value = Format.Float(min, true)
if min ~= max then if min ~= max then
value = value .. ", " .. Format.Float(max) value = value .. ", " .. Format.Float(max, true)
end end
return fmt:format(value) return fmt:format(value)
@ -253,7 +263,7 @@ function Format.NumberSequence(ns)
local nsKey = ns.Keypoints[1] local nsKey = ns.Keypoints[1]
local fmt = "new NumberSequence(%s)" local fmt = "new NumberSequence(%s)"
local value = Format.Float(nsKey.Value) local value = Format.Float(nsKey.Value, true)
return fmt:format(value) return fmt:format(value)
end end
@ -263,9 +273,9 @@ function Format.Vector3int16(v3)
return "new Vector3int16()" return "new Vector3int16()"
end end
local x = Format.Int(v3.X) local x = Format.Int(v3.X, true)
local y = Format.Int(v3.Y) local y = Format.Int(v3.Y, true)
local z = Format.Int(v3.Z) local z = Format.Int(v3.Z, true)
local fmt = "new Vector3int16(%s, %s, %s)" local fmt = "new Vector3int16(%s, %s, %s)"
return fmt:format(x, y, z) return fmt:format(x, y, z)

View File

@ -2,7 +2,7 @@ local function UseColor3(propName)
return return
{ {
Get = string.format("BrickColor.FromColor3(%s)", propName); Get = string.format("BrickColor.FromColor3(%s)", propName);
Set = propName .. " = value.Color"; Set = propName .. " = value?.Color";
} }
end end
@ -349,7 +349,11 @@ return
Model = Model =
{ {
Add = { ModelInPrimary = "CFrame" }; Add =
{
ModelInPrimary = "CFrame";
ModelMeshData = "BinaryString";
};
}; };
ModuleScript = ModuleScript =

View File

@ -200,9 +200,10 @@ local formatLinks =
["nil"] = "Null"; ["nil"] = "Null";
["long"] = "Int"; ["long"] = "Int";
["float"] = "Float"; ["float"] = "Float";
["byte[]"] = "Bytes"; ["byte[]"] = "Bytes";
["double"] = "Double"; ["double"] = "Double";
["boolean"] = "Bool";
["string"] = "String"; ["string"] = "String";
["Content"] = "String"; ["Content"] = "String";
@ -247,25 +248,18 @@ setmetatable(patches, patchIndex)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local baseUrl = "https://raw.githubusercontent.com/CloneTrooper1019/Roblox-Client-Tracker/roblox/" local baseUrl = "https://raw.githubusercontent.com/CloneTrooper1019/Roblox-Client-Tracker/roblox/"
local toolbar, classButton, enumButton local toolbar, button
if plugin then if plugin then
toolbar = plugin:CreateToolbar("C# API Dump") toolbar = plugin:CreateToolbar("C# API Dump")
classButton = toolbar:CreateButton( button = toolbar:CreateButton(
"Dump Classes", "Dump API",
"Generates a C# dump of Roblox's Class API.", "Generates a C# dump of Roblox's Class/Enum API.",
"rbxasset://textures/Icon_Stream_Off@2x.png" "rbxasset://textures/Icon_Stream_Off@2x.png"
) )
enumButton = toolbar:CreateButton( button.ClickableWhenViewportHidden = true
"Dump Enums",
"Generates a C# dump of Roblox's Enum API.",
"rbxasset://textures/Icon_Stream_Off@2x.png"
)
classButton.ClickableWhenViewportHidden = true
enumButton.ClickableWhenViewportHidden = true
end end
local function getAsync(url) local function getAsync(url)
@ -295,6 +289,12 @@ local function generateClasses()
local classNames = {} local classNames = {}
classes = {} classes = {}
local enumMap =
{
Axis = true;
FontSize = true;
}
for _,class in ipairs(apiDump.Classes) do for _,class in ipairs(apiDump.Classes) do
local className = class.Name local className = class.Name
local superClass = classes[class.Superclass] local superClass = classes[class.Superclass]
@ -309,9 +309,7 @@ local function generateClasses()
if classTags.Service then if classTags.Service then
pcall(function () pcall(function ()
if not className:find("Network") then class.Object = game:GetService(className)
class.Object = game:GetService(className)
end
end) end)
elseif not classTags.NotCreatable then elseif not classTags.NotCreatable then
pcall(function () pcall(function ()
@ -345,7 +343,11 @@ local function generateClasses()
writeLine("using RobloxFiles.Utility;") writeLine("using RobloxFiles.Utility;")
writeLine() writeLine()
writeLine("#pragma warning disable IDE1006 // Suppress warnings about camelCase.") writeLine("#pragma warning disable CA1041 // Provide ObsoleteAttribute message")
writeLine("#pragma warning disable CA1051 // Do not declare visible instance fields")
writeLine("#pragma warning disable CA1707 // Identifiers should not contain underscores")
writeLine("#pragma warning disable CA1716 // Identifiers should not match keywords")
writeLine("#pragma warning disable IDE1006 // Naming Styles")
writeLine() writeLine()
writeLine("namespace RobloxFiles") writeLine("namespace RobloxFiles")
@ -589,7 +591,14 @@ local function generateClasses()
result = formatFunc(value) result = formatFunc(value)
end end
default = " = " .. result if result ~= nil then
default = " = " .. result
end
if formatFunc == formatting.EnumItem then
local enumName = tostring(value.EnumType)
enumMap[enumName] = true
end
end end
if propTags.Deprecated then if propTags.Deprecated then
@ -600,10 +609,6 @@ local function generateClasses()
writeLine("[Obsolete]") writeLine("[Obsolete]")
end end
if category == "Class" then
default = " = null"
end
writeLine("public %s %s%s;", valueType, name, default) writeLine("public %s %s%s;", valueType, name, default)
if propTags.Deprecated and i ~= #propNames then if propTags.Deprecated and i ~= #propNames then
@ -625,9 +630,11 @@ local function generateClasses()
closeStack() closeStack()
exportStream("Classes") exportStream("Classes")
return enumMap
end end
local function generateEnums() local function generateEnums(whiteList)
local version = getfenv().version():gsub("%. ", ".") local version = getfenv().version():gsub("%. ", ".")
clearStream() clearStream()
@ -641,11 +648,18 @@ local function generateEnums()
local enums = Enum:GetEnums() local enums = Enum:GetEnums()
for i, enum in ipairs(enums) do for i, enum in ipairs(enums) do
writeLine("public enum %s", tostring(enum)) local enumName = tostring(enum)
if whiteList and not whiteList[enumName] then
continue
end
writeLine("public enum %s", enumName)
openStack() openStack()
local enumItems = enum:GetEnumItems() local enumItems = enum:GetEnumItems()
local lastValue = -1 local lastValue = -1
local mapped = {}
table.sort(enumItems, function (a, b) table.sort(enumItems, function (a, b)
return a.Value < b.Value return a.Value < b.Value
@ -658,16 +672,20 @@ local function generateEnums()
local name = enumItem.Name local name = enumItem.Name
local value = enumItem.Value local value = enumItem.Value
if (value - lastValue) ~= 1 then if not mapped[value] then
text = " = " .. value; if (value - lastValue) ~= 1 then
end text = " = " .. value;
end
if i == #enumItems then if i == #enumItems then
comma = "" comma = ""
end end
lastValue = value lastValue = value
writeLine("%s%s%s", name, text, comma) mapped[value] = true
writeLine("%s%s%s", name, text, comma)
end
end end
closeStack() closeStack()
@ -681,10 +699,13 @@ local function generateEnums()
exportStream("Enums") exportStream("Enums")
end end
if plugin then local function generateAll()
classButton.Click:Connect(generateClasses) local enumList = generateClasses()
enumButton.Click:Connect(generateEnums) generateEnums(enumList)
else end
generateClasses()
generateEnums() if plugin then
button.Click:Connect(generateAll)
else
generateAll()
end end

View File

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\RCT-Source\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.3.3.0\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props" Condition="Exists('..\RCT-Source\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.3.3.0\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props')" />
<Import Project="..\RCT-Source\packages\Microsoft.NetFramework.Analyzers.3.3.0\build\Microsoft.NetFramework.Analyzers.props" Condition="Exists('..\RCT-Source\packages\Microsoft.NetFramework.Analyzers.3.3.0\build\Microsoft.NetFramework.Analyzers.props')" />
<Import Project="..\RCT-Source\packages\Microsoft.NetCore.Analyzers.3.3.0\build\Microsoft.NetCore.Analyzers.props" Condition="Exists('..\RCT-Source\packages\Microsoft.NetCore.Analyzers.3.3.0\build\Microsoft.NetCore.Analyzers.props')" />
<Import Project="..\RCT-Source\packages\Microsoft.CodeQuality.Analyzers.3.3.0\build\Microsoft.CodeQuality.Analyzers.props" Condition="Exists('..\RCT-Source\packages\Microsoft.CodeQuality.Analyzers.3.3.0\build\Microsoft.CodeQuality.Analyzers.props')" />
<Import Project="..\RCT-Source\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.3.3.0\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props" Condition="Exists('..\RCT-Source\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.3.3.0\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props')" />
<Import Project="packages\Costura.Fody.4.1.0\build\Costura.Fody.props" Condition="Exists('packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" /> <Import Project="packages\Costura.Fody.4.1.0\build\Costura.Fody.props" Condition="Exists('packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
@ -47,6 +52,7 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>1</WarningLevel> <WarningLevel>1</WarningLevel>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<StartupObject /> <StartupObject />
@ -175,6 +181,17 @@
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Analyzer Include="..\RCT-Source\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.3.3.0\analyzers\dotnet\cs\Microsoft.CodeAnalysis.VersionCheckAnalyzer.resources.dll" />
<Analyzer Include="..\RCT-Source\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.3.3.0\analyzers\dotnet\Microsoft.CodeAnalysis.VersionCheckAnalyzer.dll" />
<Analyzer Include="..\RCT-Source\packages\Microsoft.CodeQuality.Analyzers.3.3.0\analyzers\dotnet\cs\Humanizer.dll" />
<Analyzer Include="..\RCT-Source\packages\Microsoft.CodeQuality.Analyzers.3.3.0\analyzers\dotnet\cs\Microsoft.CodeQuality.Analyzers.dll" />
<Analyzer Include="..\RCT-Source\packages\Microsoft.CodeQuality.Analyzers.3.3.0\analyzers\dotnet\cs\Microsoft.CodeQuality.CSharp.Analyzers.dll" />
<Analyzer Include="..\RCT-Source\packages\Microsoft.NetCore.Analyzers.3.3.0\analyzers\dotnet\cs\Microsoft.NetCore.Analyzers.dll" />
<Analyzer Include="..\RCT-Source\packages\Microsoft.NetCore.Analyzers.3.3.0\analyzers\dotnet\cs\Microsoft.NetCore.CSharp.Analyzers.dll" />
<Analyzer Include="..\RCT-Source\packages\Microsoft.NetFramework.Analyzers.3.3.0\analyzers\dotnet\cs\Microsoft.NetFramework.Analyzers.dll" />
<Analyzer Include="..\RCT-Source\packages\Microsoft.NetFramework.Analyzers.3.3.0\analyzers\dotnet\cs\Microsoft.NetFramework.CSharp.Analyzers.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup> <PropertyGroup>
<PostBuildEvent>copy /y $(TargetPath) $(ProjectDir)$(TargetFileName)</PostBuildEvent> <PostBuildEvent>copy /y $(TargetPath) $(ProjectDir)$(TargetFileName)</PostBuildEvent>
@ -185,6 +202,11 @@
</PropertyGroup> </PropertyGroup>
<Error Condition="!Exists('packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.4.1.0\build\Costura.Fody.props'))" /> <Error Condition="!Exists('packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Costura.Fody.4.1.0\build\Costura.Fody.props'))" />
<Error Condition="!Exists('packages\Fody.6.2.0\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Fody.6.2.0\build\Fody.targets'))" /> <Error Condition="!Exists('packages\Fody.6.2.0\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Fody.6.2.0\build\Fody.targets'))" />
<Error Condition="!Exists('..\RCT-Source\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.3.3.0\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props')" Text="$([System.String]::Format('$(ErrorText)', '..\RCT-Source\packages\Microsoft.CodeAnalysis.VersionCheckAnalyzer.3.3.0\build\Microsoft.CodeAnalysis.VersionCheckAnalyzer.props'))" />
<Error Condition="!Exists('..\RCT-Source\packages\Microsoft.CodeQuality.Analyzers.3.3.0\build\Microsoft.CodeQuality.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\RCT-Source\packages\Microsoft.CodeQuality.Analyzers.3.3.0\build\Microsoft.CodeQuality.Analyzers.props'))" />
<Error Condition="!Exists('..\RCT-Source\packages\Microsoft.NetCore.Analyzers.3.3.0\build\Microsoft.NetCore.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\RCT-Source\packages\Microsoft.NetCore.Analyzers.3.3.0\build\Microsoft.NetCore.Analyzers.props'))" />
<Error Condition="!Exists('..\RCT-Source\packages\Microsoft.NetFramework.Analyzers.3.3.0\build\Microsoft.NetFramework.Analyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\RCT-Source\packages\Microsoft.NetFramework.Analyzers.3.3.0\build\Microsoft.NetFramework.Analyzers.props'))" />
<Error Condition="!Exists('..\RCT-Source\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.3.3.0\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\RCT-Source\packages\Microsoft.CodeAnalysis.FxCopAnalyzers.3.3.0\build\Microsoft.CodeAnalysis.FxCopAnalyzers.props'))" />
</Target> </Target>
<Import Project="packages\Fody.6.2.0\build\Fody.targets" Condition="Exists('packages\Fody.6.2.0\build\Fody.targets')" /> <Import Project="packages\Fody.6.2.0\build\Fody.targets" Condition="Exists('packages\Fody.6.2.0\build\Fody.targets')" />
</Project> </Project>

Binary file not shown.

View File

@ -5,7 +5,7 @@ using System.Text;
internal static class Formatting internal static class Formatting
{ {
private static CultureInfo invariant => CultureInfo.InvariantCulture; private static CultureInfo Invariant => CultureInfo.InvariantCulture;
public static string ToInvariantString(this float value) public static string ToInvariantString(this float value)
{ {
@ -18,7 +18,7 @@ internal static class Formatting
else if (float.IsNaN(value)) else if (float.IsNaN(value))
result = "NAN"; result = "NAN";
else else
result = value.ToString(invariant); result = value.ToString(Invariant);
return result; return result;
} }
@ -34,75 +34,52 @@ internal static class Formatting
else if (double.IsNaN(value)) else if (double.IsNaN(value))
result = "NAN"; result = "NAN";
else else
result = value.ToString(invariant); result = value.ToString(Invariant);
return result; return result;
} }
public static string ToInvariantString(this int value) public static string ToInvariantString(this int value)
{ {
return value.ToString(invariant); return value.ToString(Invariant);
} }
public static string ToInvariantString(this object value) public static string ToInvariantString(this object value)
{ {
if (value is float) switch (value)
{ {
float f = (float)value; case double d : return d.ToInvariantString();
return f.ToInvariantString(); case float f : return f.ToInvariantString();
} case int i : return i.ToInvariantString();
else if (value is double) default : return value.ToString();
{
double d = (double)value;
return d.ToInvariantString();
}
else if (value is int)
{
int i = (int)value;
return i.ToInvariantString();
}
else
{
// Unhandled
return value.ToString();
} }
} }
public static float ParseFloat(string value) public static float ParseFloat(string value)
{ {
float result; switch (value)
{
if (value == "INF") case "NAN" : return float.NaN;
result = float.PositiveInfinity; case "INF" : return float.PositiveInfinity;
else if (value == "-INF") case "-INF" : return float.NegativeInfinity;
result = float.NegativeInfinity; default : return float.Parse(value, Invariant);
else if (value == "NAN") }
result = float.NaN;
else
result = float.Parse(value, invariant);
return result;
} }
public static double ParseDouble(string value) public static double ParseDouble(string value)
{ {
double result; switch (value)
{
if (value == "INF") case "NAN" : return double.NaN;
result = double.PositiveInfinity; case "INF" : return double.PositiveInfinity;
else if (value == "-INF") case "-INF" : return double.NegativeInfinity;
result = double.NegativeInfinity; default : return double.Parse(value, Invariant);
else if (value == "NAN") }
result = double.NaN;
else
result = double.Parse(value, invariant);
return result;
} }
public static int ParseInt(string s) public static int ParseInt(string s)
{ {
return int.Parse(s, invariant); return int.Parse(s, Invariant);
} }
public static bool FuzzyEquals(this float a, float b, float epsilon = 10e-5f) public static bool FuzzyEquals(this float a, float b, float epsilon = 10e-5f)

View File

@ -7,8 +7,8 @@ namespace RobloxFiles.Utility
// This is a lazy helper class to disambiguate between FieldInfo and PropertyInfo // This is a lazy helper class to disambiguate between FieldInfo and PropertyInfo
internal class ImplicitMember internal class ImplicitMember
{ {
private static BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase; private const BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.IgnoreCase;
private object member; private readonly object member;
private ImplicitMember(FieldInfo field) { member = field; } private ImplicitMember(FieldInfo field) { member = field; }
private ImplicitMember(PropertyInfo prop) { member = prop; } private ImplicitMember(PropertyInfo prop) { member = prop; }

View File

@ -9,7 +9,7 @@ namespace RobloxFiles.XmlFormat
{ {
public static class XmlPropertyTokens public static class XmlPropertyTokens
{ {
public static IReadOnlyDictionary<string, IXmlPropertyToken> Handlers; private static readonly Dictionary<string, IXmlPropertyToken> Handlers = new Dictionary<string, IXmlPropertyToken>();
static XmlPropertyTokens() static XmlPropertyTokens()
{ {
@ -25,22 +25,24 @@ namespace RobloxFiles.XmlFormat
.Select(handlerType => Activator.CreateInstance(handlerType)) .Select(handlerType => Activator.CreateInstance(handlerType))
.Cast<IXmlPropertyToken>(); .Cast<IXmlPropertyToken>();
var tokenHandlers = new Dictionary<string, IXmlPropertyToken>();
foreach (IXmlPropertyToken propToken in propTokens) foreach (IXmlPropertyToken propToken in propTokens)
{ {
var tokens = propToken.Token.Split(';') var tokens = propToken.Token.Split(';')
.Select(token => token.Trim()) .Select(token => token.Trim())
.ToList(); .ToList();
tokens.ForEach(token => tokenHandlers.Add(token, propToken)); tokens.ForEach(token => Handlers.Add(token, propToken));
} }
Handlers = tokenHandlers;
} }
public static bool ReadPropertyGeneric<T>(XmlNode token, out T outValue) where T : struct public static bool ReadPropertyGeneric<T>(XmlNode token, out T outValue) where T : struct
{ {
if (token == null)
{
var name = nameof(token);
throw new ArgumentNullException(name);
}
try try
{ {
string value = token.InnerText; string value = token.InnerText;
@ -65,18 +67,22 @@ namespace RobloxFiles.XmlFormat
outValue = (T)result; outValue = (T)result;
return true; return true;
} }
catch catch (NotSupportedException)
{ {
outValue = default(T); outValue = default;
return false; return false;
} }
} }
public static bool ReadPropertyGeneric<T>(Property prop, PropertyType propType, XmlNode token) where T : struct public static bool ReadPropertyGeneric<T>(Property prop, PropertyType propType, XmlNode token) where T : struct
{ {
T result; if (prop == null)
{
var name = nameof(prop);
throw new ArgumentNullException(name);
}
if (ReadPropertyGeneric(token, out result)) if (ReadPropertyGeneric(token, out T result))
{ {
prop.Type = propType; prop.Type = propType;
prop.Value = result; prop.Value = result;

View File

@ -4,5 +4,10 @@
<package id="Fody" version="6.2.0" targetFramework="net472" developmentDependency="true" /> <package id="Fody" version="6.2.0" targetFramework="net472" developmentDependency="true" />
<package id="Konscious.Security.Cryptography.Blake2" version="1.0.9" targetFramework="net472" /> <package id="Konscious.Security.Cryptography.Blake2" version="1.0.9" targetFramework="net472" />
<package id="lz4net" version="1.0.15.93" targetFramework="net452" /> <package id="lz4net" version="1.0.15.93" targetFramework="net452" />
<package id="Microsoft.CodeAnalysis.FxCopAnalyzers" version="3.3.0" targetFramework="net472" developmentDependency="true" />
<package id="Microsoft.CodeAnalysis.VersionCheckAnalyzer" version="3.3.0" targetFramework="net472" developmentDependency="true" />
<package id="Microsoft.CodeQuality.Analyzers" version="3.3.0" targetFramework="net472" developmentDependency="true" />
<package id="Microsoft.NetCore.Analyzers" version="3.3.0" targetFramework="net472" developmentDependency="true" />
<package id="Microsoft.NetFramework.Analyzers" version="3.3.0" targetFramework="net472" developmentDependency="true" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" /> <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
</packages> </packages>