using System; using System.Reflection; using HarmonyLib; using SQL; using Svelto.DataStructures; namespace CLre.Fixes { public class OfflineGameTimeSavingFloatFix { } [Bugfix(name = "OfflineGameTimeSavingFloatFix", description = "Make game time save properly for everyone, even when floats contain a comma", component = BugfixType.HarmonyPatch, id = 11)] [HarmonyPatch] class OfflineSaveServerGameTimeRequest_DoRequest_Patch { private const string QUERY = "INSERT OR REPLACE INTO gametime (gameId, gameTime) VALUES (@GameId, @GameTime)"; [HarmonyPrefix] public static bool BeforeMethodCall(object __instance, ref object ____dependency) { //API.Utility.Logging.Log("Intercepting OfflineSaveServerGameTimeRequest.DoRequest"); //if (____dependency == null) return true; #if DEBUG API.Utility.Logging.Log( "Replacing OfflineSaveServerGameTimeRequest.DoRequest SQL query with safer alternative"); #endif // TODO optimise ISQL sql = Traverse.Create(__instance).Property("sql").Value; Traverse dep = Traverse.Create(____dependency); // populate params FasterList sqlParams = new FasterList(); sqlParams.Add(new SQLParam("@GameId", dep.Field("gameId").Value)); sqlParams.Add(new SQLParam("@GameTime", dep.Field("gameTime").Value)); // actually perform query sql.ExecuteSaveQuery(QUERY, OnComplete, OnError, sqlParams); #if DEBUG API.Utility.Logging.Log("Executed corrected game time saving SQL query"); #endif return false; } private static void OnComplete(int numberRowsEdited) { #if DEBUG API.Utility.Logging.Log( $"Completed OfflineSaveServerGameTimeRequest_DoRequest_Patch SQL Query ({numberRowsEdited} rows)"); #endif } private static void OnError(Exception e) { #if DEBUG API.Utility.Logging.LogError( $"Error in OfflineSaveServerGameTimeRequest_DoRequest_Patch SQL Query: {e}\n{e.StackTrace}"); #endif } [HarmonyTargetMethod] public static MethodBase Target() { return AccessTools.Method( "Requests.ServerSaving.ServerLoginTime.OfflineSaveServerGameTimeRequest:DoRequest"); } } }