using System; using System.Reflection; using HarmonyLib; using SQL; using Svelto.DataStructures; namespace CLre.Fixes { public class OfflineSpawnpointSavingFloatFix { } [Bugfix(name = "OfflineSpawnpointSavingFloatFix", description = "Make spawnpoints save properly for everyone, even when floats contain a comma", more = "https://trello.com/c/hpADhDhQ/21-login-goes-to-original-spawn", component = BugfixType.HarmonyPatch, id = 9)] [HarmonyPatch] class OfflineSavePlayerSpawnPointRequest_DoRequest_Patch { private const string QUERY = "INSERT OR REPLACE INTO spawnpoints (gameId, uniqueId, PublicID, x, y, z, selected) VALUES (@GameId, @UniqueId, @PublicId, @X, @Y, @Z, @Selected)"; [HarmonyPrefix] public static bool BeforeMethodCall(object __instance, object ____dependency) { //API.Utility.Logging.Log("Intercepting OfflineSavePlayerSpawnPointRequest.DoRequest"); if (____dependency == null) return true; #if DEBUG API.Utility.Logging.Log("Replacing OfflineSavePlayerSpawnPointRequest.DoRequest SQL squery 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("@UniqueId", dep.Field("uniqueId").Value)); sqlParams.Add(new SQLParam("@PublicId", dep.Field("PublicId").Value)); sqlParams.Add(new SQLParam("@X", dep.Field("x").Value)); sqlParams.Add(new SQLParam("@Y", dep.Field("y").Value)); sqlParams.Add(new SQLParam("@Z", dep.Field("z").Value)); sqlParams.Add(new SQLParam("@Selected", dep.Field("selected").Value? 1 : 0)); // actually perform query sql.ExecuteSaveQuery(QUERY, OnComplete, OnError, sqlParams); #if DEBUG API.Utility.Logging.Log("Executed corrected spawnpoint saving SQL query"); #endif return false; } private static void OnComplete(int numberRowsEdited) { #if DEBUG API.Utility.Logging.Log($"Completed OfflineSavePlayerSpawnPointRequest_DoRequest_Patch SQL Query ({numberRowsEdited} rows)"); #endif } private static void OnError(Exception e) { #if DEBUG API.Utility.Logging.LogError($"Error in OfflineSavePlayerSpawnPointRequest_DoRequest_Patch SQL Query: {e}\n{e.StackTrace}"); #endif } [HarmonyTargetMethod] public static MethodBase Target() { return AccessTools.Method("Requests.Offline.Server.OfflineSavePlayerSpawnPointRequest:DoRequest"); } } }