From d96a5827d9226e7e24e60300831837272f9c4cc9 Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Sun, 14 Jun 2026 08:54:00 -0400 Subject: Use Invariant Culture when parsing config Signed-off-by: Andrew Opalach --- Plugin.cs | 69 +++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/Plugin.cs b/Plugin.cs index 8346ff6..3c84d50 100755 --- a/Plugin.cs +++ b/Plugin.cs @@ -2,6 +2,7 @@ //#define SHADER_FEATURES using System.Numerics; +using System.Globalization; using System.Runtime.InteropServices; #if ENABLE_ASSERTS using System.Diagnostics; @@ -71,12 +72,21 @@ namespace WorldTuningTool ((int)MathF.Round(v.W * 255.0f) << 24)); } - private static string Vector3ToString(Vector3 v) + private static float StringToSingle(string s) { return Convert.ToSingle(s, CultureInfo.InvariantCulture); } + private static bool StringToBoolean(string s) { return Convert.ToBoolean(s, CultureInfo.InvariantCulture); } + private static int StringToInt32(string s, int fromBase = 10) { - return $"{v.X},{v.Y},{v.Z}"; + if (fromBase == 10) { + return Convert.ToInt32(s, CultureInfo.InvariantCulture); + } else { + return Convert.ToInt32(s, fromBase); + } } + private static string SingleToString(float f, string? format = null) { return f.ToString(format, CultureInfo.InvariantCulture); } + private static string BooleanToString(bool b) { return b.ToString(CultureInfo.InvariantCulture); } + private static string Int32ToString(int i, string? format = null) { return i.ToString(format, CultureInfo.InvariantCulture); } - private static Vector3 Vector3FromString(string s) + private static Vector3 StringToVector3(string s) { if (String.IsNullOrEmpty(s)) { @@ -87,10 +97,12 @@ namespace WorldTuningTool { throw new FormatException(); } - return new Vector3( - Convert.ToSingle(vs[0]), - Convert.ToSingle(vs[1]), - Convert.ToSingle(vs[2])); + return new Vector3(StringToSingle(vs[0]), StringToSingle(vs[1]), StringToSingle(vs[2])); + } + + private static string Vector3ToString(Vector3 v) + { + return string.Format(CultureInfo.InvariantCulture, "{0},{1},{2}", v.X, v.Y, v.Z); } public enum ParameterType @@ -970,18 +982,17 @@ namespace WorldTuningTool { case ParameterType.BOOL: case ParameterType.FLAG: - return (sValueInt != 0).ToString(); + return BooleanToString(sValueInt != 0); case ParameterType.BYTE: - return sValueInt.ToString(); case ParameterType.INT: case ParameterType.SHADOW_RESOLUTION: - return sValueInt.ToString(); + return Int32ToString(sValueInt); case ParameterType.HEX: case ParameterType.COLOR: - return sValueInt.ToString("X8"); + return Int32ToString(sValueInt, "X8"); case ParameterType.FLOAT: case ParameterType.PATCH_FLOAT: - return sValueV.X.ToString(); + return SingleToString(sValueV.X); case ParameterType.VECTOR3: Vector3 sValueV3 = new Vector3(sValueV.X, sValueV.Y, sValueV.Z); return Vector3ToString(sValueV3); @@ -1000,25 +1011,23 @@ namespace WorldTuningTool { case ParameterType.BOOL: case ParameterType.FLAG: - valueInt = ByteFlag(Convert.ToBoolean(value)); + valueInt = ByteFlag(StringToBoolean(value)); break; case ParameterType.BYTE: - valueInt = Convert.ToInt32(value); - break; case ParameterType.INT: case ParameterType.SHADOW_RESOLUTION: - valueInt = Convert.ToInt32(value); + valueInt = StringToInt32(value); break; case ParameterType.HEX: case ParameterType.COLOR: - valueInt = Convert.ToInt32(value, 16); + valueInt = StringToInt32(value, 16); break; case ParameterType.FLOAT: case ParameterType.PATCH_FLOAT: - valueV.X = Convert.ToSingle(value); + valueV.X = StringToSingle(value); break; case ParameterType.VECTOR3: - Vector3 valueV3 = Vector3FromString(value); + Vector3 valueV3 = StringToVector3(value); valueV = new Vector4(valueV3.X, valueV3.Y, valueV3.Z, 0.0f); break; case ParameterType.VECTOR4: @@ -1268,8 +1277,8 @@ namespace WorldTuningTool newParameter("Broad Area Shadow Center", 0x5540 + 0x40, ParameterType.VECTOR3), newParameter("Broad Area Shadow Range", 0x5560 + 0x40, ParameterType.VECTOR3), newParameter("Broad Area Shadow Direction", 0x5550 + 0x40, ParameterType.VECTOR3, pStep(0.00025f)), - newParameter("Broad Area Shadow Max LOD Level", 0x5524, ParameterType.FLOAT), - newParameter("Broad Area Shadow Culling Size", 0x5528, ParameterType.FLOAT), + newParameter("Broad Area Shadow Max LOD Level", 0x5524, ParameterType.FLOAT, pMin(0.0f)), + newParameter("Broad Area Shadow Culling Size", 0x5528, ParameterType.FLOAT, pMin(0.0f)), newParameter("Broad Area Shadow Precision", 0x5518, ParameterType.INT, pMinMaxStep(0, 2, 1)) }; @@ -1305,17 +1314,17 @@ namespace WorldTuningTool newParameter("SSAO Sloped Depth Bias", 0xB4B4, ParameterType.FLOAT, pStep(0.00001f)), newParameter("SSAO Max Depth Bias", 0xB4B8, ParameterType.FLOAT, pStep(0.00001f)), newParameter("SSAO Dispersion", 0xB4BC, ParameterType.FLOAT), - newParameter("SSAO Effect", 0xB430, ParameterType.FLOAT), - newParameter("SSAO Effect GI", 0xB434, ParameterType.FLOAT), - newParameter("SSAO Depth Difference", 0xB4C0, ParameterType.FLOAT), - newParameter("SSAO Samples Per Pixel", 0xB4C4, ParameterType.FLOAT), + newParameter("SSAO Effect", 0xB430, ParameterType.FLOAT, pStep(0.001f)), + newParameter("SSAO Effect GI", 0xB434, ParameterType.FLOAT, pStep(0.001f)), + newParameter("SSAO Depth Difference", 0xB4C0, ParameterType.FLOAT, pStep(0.01f)), + newParameter("SSAO Samples Per Pixel", 0xB4C4, ParameterType.FLOAT, pStep(1.0f)), newParameter("SSAO Max Sample Num", 0xB4C8, ParameterType.INT, pStep(1)), newParameter("SSAO Max Sample Num (HQ)", 0xB4D0, ParameterType.INT, pStep(1)), newParameter("SSAO Radius", 0xB4D4, ParameterType.FLOAT), - newParameter("SSAO Bias", 0xB4D8, ParameterType.FLOAT), - newParameter("SSAO Intensity", 0xB4E0, ParameterType.FLOAT), + newParameter("SSAO Bias", 0xB4D8, ParameterType.FLOAT, pStep(0.0001f)), + newParameter("SSAO Intensity", 0xB4E0, ParameterType.FLOAT, pMin(0.0f)), newParameter("SSAO Use HiZ", 0xB4E5, ParameterType.BOOL), - newParameter("SSAO Edge Atten Rate", 0xB4DC, ParameterType.FLOAT) + newParameter("SSAO Edge Atten Rate", 0xB4DC, ParameterType.FLOAT, pStep(0.001f)) }; private delegate void UpdateSSLRParams(nint stackOffset); @@ -1972,10 +1981,8 @@ namespace WorldTuningTool Assert(addr == 0x141754438); defaultViewModeLODLimit_2 = new Patch(addr + 0x24, [0x07]); - // Unknown. @TODO: Figure this out. - defaultViewModeLODLimit_3 = new Patch(new IntPtr(0x14128F1AC) + 0x1, [0x07]); - // Talking to NPC. + defaultViewModeLODLimit_3 = new Patch(new IntPtr(0x14128F1AC) + 0x1, [0x07]); defaultViewModeLODLimit_4 = new Patch(new IntPtr(0x14128F1AC) + 0xF, [0x07]); addr = PatternScanner.FindFirst(Pattern.FromString("74 4D 33 C0 48 81 C1 00 02 00 00 F3 0F 10 11 0F 2F CA 72 0C FF C0 48 83 C1 04 83 F8 03 72 EC C3")); -- cgit v1.2.3-101-g0448