Unofficial CardLife revival project, pronounced like "celery"
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

244 lignes
9.8KB

  1. using System;
  2. using System.Reflection;
  3. using System.Runtime.CompilerServices;
  4. using CLre.API.Synergy;
  5. using CLre.API.Utility;
  6. using Game.DataLoader;
  7. using Game.Handhelds;
  8. using GameNetworkLayer.Shared;
  9. using HarmonyLib;
  10. using NetworkFramework.Shared;
  11. using Svelto.ECS;
  12. using UnityEngine;
  13. using VoxelFarm.GameServer;
  14. namespace CLre.Fixes
  15. {
  16. [Bugfix(name = "TerrainModificationFailedHandler",
  17. description = "Actually handle TerrainModificationFailed network messages",
  18. more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools",
  19. component = BugfixType.Initialiser, id = 8)]
  20. public class TerrainModifyReset
  21. {
  22. private static TerrainModifyResetEngine _tmrEngine = null;
  23. public static void Init()
  24. {
  25. _tmrEngine = new TerrainModifyResetEngine();
  26. }
  27. }
  28. [Bugfix(name = "TerrainModificationFailedHandler",
  29. description = "Actually handle TerrainModificationFailed network messages",
  30. more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools",
  31. component = BugfixType.Workaround, id = 8)]
  32. public class TerrainModifyResetEngine : API.Engines.GameObsoleteEnginePostBuild, IDataAccess
  33. {
  34. private Reflection.INetMsgClientListener_RegisterListener<API.Synergy.Tweaks.SerializedCLreTerrainModifyRejection> _registerListener;
  35. public override void Ready()
  36. {
  37. _registerListener =
  38. Reflection.MethodAsDelegate<Reflection.INetMsgClientListener_RegisterListener<API.Synergy.Tweaks.SerializedCLreTerrainModifyRejection>>(
  39. "GameNetworkLayer.Client.NetMessageClientListener:RegisterListener",
  40. generics: new [] {typeof(API.Synergy.Tweaks.SerializedCLreTerrainModifyRejection)},
  41. instance: MainLevel_BuildClasses_Patch.netMessageListener);
  42. _registerListener(NetworkDispatcherCode.TerrainModificationFailed, OnMessageReceived);
  43. }
  44. private void OnMessageReceived(ref API.Synergy.Tweaks.SerializedCLreTerrainModifyRejection data)
  45. {
  46. if (!data.Ok())
  47. {
  48. // reset terrain visuals
  49. // TODO optimise
  50. #if DEBUG
  51. API.Utility.Logging.MetaLog($"data.resourceId: {data.resourceId}");
  52. #endif
  53. AddTerrain(ref data);
  54. }
  55. }
  56. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  57. private static void GetTerrainRelativePosition(ref Vector3 pos)
  58. {
  59. // This uses decompiled code from VoxelFarm.Shared.VoxelFarmGameUtils:GetTerrainRelativePosition
  60. // there's no point in calling that simple function when I have to jump through hoops with reflection
  61. //
  62. // there's also nothing particularly unique (ie copyrightable) about this code,
  63. // so the lawyers can suck it (also suing a benevolent project is a shitty move)
  64. pos.x /= 0.083333336f;
  65. pos.y /= 0.041666668f;
  66. pos.z /= 0.083333336f;
  67. }
  68. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  69. private static void AddTerrain(ref API.Synergy.Tweaks.SerializedCLreTerrainModifyRejection data)
  70. {
  71. // This uses decompiled code from VoxelFarm.GameServer.TerrainModelClientServer:AddTerrain
  72. // there's no point in calling that simple function when I have to jump through hoops with reflection
  73. // to supply the parameters to it
  74. //
  75. // Also this is not unique functionality, and comes from the logic of how the placement modes work
  76. switch (data.toolMode)
  77. {
  78. case ToolModeType.Block:
  79. MainLevel_BuildClasses_Patch.tmcs.AddDisc(0, data.hit, (int)data.resourceId, 5, 5);
  80. break;
  81. case ToolModeType.Disc:
  82. MainLevel_BuildClasses_Patch.tmcs.AddDisc(0, data.hit, (int)data.resourceId, 1, 5);
  83. break;
  84. case ToolModeType.Voxel:
  85. MainLevel_BuildClasses_Patch.tmcs.AddSingleVoxel(0, data.hit, (int)data.resourceId);
  86. break;
  87. }
  88. }
  89. public IDataDB dataDB { get; set; }
  90. }
  91. [Bugfix(name = "TerrainModificationFailedHandler",
  92. description = "Actually handle TerrainModificationFailed network messages",
  93. more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools",
  94. component = BugfixType.HarmonyPatch, id = 8)]
  95. [HarmonyPatch]
  96. class TerrainPendingModificationEngineClient_Add_Patch
  97. {
  98. internal static object _terrainModifyInputNode = null;
  99. [HarmonyPrefix]
  100. public static void BeforeMethodCall(object node)
  101. {
  102. #if DEBUG
  103. API.Utility.Logging.MetaLog("Intercepting VoxelFarm.Client.TerrainPendingModificationEngineClient:Add()");
  104. #endif
  105. _terrainModifyInputNode = node;
  106. }
  107. [HarmonyTargetMethod]
  108. public static MethodBase Target()
  109. {
  110. return AccessTools.Method("VoxelFarm.Client.TerrainPendingModificationEngineClient:Add", new []{ AccessTools.TypeByName("VoxelFarm.Shared.TerrainModifyInputNode")});
  111. }
  112. }
  113. /*[Bugfix(name = "TerrainModificationFailedHandler",
  114. description = "Actually handle TerrainModificationFailed network messages",
  115. more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools",
  116. component = BugfixType.HarmonyPatch, id = 8)]
  117. [HarmonyPatch]
  118. class TerrainPendingModificationEngineClient_OnBlockRemoved_Patch
  119. {
  120. [HarmonyPrefix]
  121. public static bool BeforeMethodCall(int sender, ref ISerializedNetData terrainModifyInputData)
  122. {
  123. #if DEBUG
  124. API.Utility.Logging.MetaLog($"Intercepting VoxelFarm.Client.TerrainPendingModificationEngineClient:OnBlockRemoved({sender}, {terrainModifyInputData})");
  125. #endif
  126. return false;
  127. }
  128. [HarmonyTargetMethod]
  129. public static MethodBase Target()
  130. {
  131. return AccessTools.Method("VoxelFarm.Client.TerrainPendingModificationEngineClient:OnBlockRemoved");
  132. }
  133. }*/
  134. [Bugfix(name = "TerrainModificationFailedHandler",
  135. description = "Actually handle TerrainModificationFailed network messages",
  136. more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools",
  137. component = BugfixType.Debug, id = 8)]
  138. [HarmonyPatch]
  139. class SpadeEngine_FinishDigging_Patch
  140. {
  141. internal static int CurrentMaterialId = 0;
  142. [HarmonyPrefix]
  143. public static void BeforeMethodCall(object toolNode, int ____currentMaterialId)
  144. {
  145. #if DEBUG
  146. API.Utility.Logging.MetaLog($"Intercepting Game.Handhelds.SpadeEngine:FinishDigging:GetTerrainMaterial(...) material:{____currentMaterialId}");
  147. #endif
  148. CurrentMaterialId = ____currentMaterialId;
  149. }
  150. [HarmonyTargetMethod]
  151. public static MethodBase Target()
  152. {
  153. return AccessTools.Method("Game.Handhelds.SpadeEngine:FinishDigging");
  154. }
  155. }
  156. [Bugfix(name = "TerrainModificationFailedHandler",
  157. description = "Actually handle TerrainModificationFailed network messages",
  158. more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools",
  159. component = BugfixType.Debug, id = 8)]
  160. [HarmonyPatch]
  161. class TerrainModifyInputData_InjectValues_Patch
  162. {
  163. [HarmonyPrefix]
  164. public static void BeforeMethodCall(ref uint resourceId)
  165. {
  166. #if DEBUG
  167. API.Utility.Logging.MetaLog($"VoxelFarm.Shared.TerrainModifyInputData:InjectValues({resourceId}, ...)");
  168. #endif
  169. if (resourceId == 0) resourceId = (uint) SpadeEngine_FinishDigging_Patch.CurrentMaterialId;
  170. }
  171. [HarmonyTargetMethod]
  172. public static MethodBase Target()
  173. {
  174. return AccessTools.Method("VoxelFarm.Shared.TerrainModifyInputData:InjectValues");
  175. }
  176. }
  177. [Bugfix(name = "TerrainModificationFailedHandler",
  178. description = "Actually handle TerrainModificationFailed network messages",
  179. more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools",
  180. component = BugfixType.HarmonyPatch, id = 8)]
  181. [HarmonyPatch]
  182. class NetMessageClientListener_RegisterListener_Patch
  183. {
  184. [HarmonyPrefix]
  185. public static bool BeforeMethodCall(NetworkDispatcherCode code)
  186. {
  187. #if DEBUG
  188. API.Utility.Logging.MetaLog($"Intercepting GameNetworkLayer.Client.NetMessageClientListener:RegisterListener({code}, ...)");
  189. #endif
  190. // don't allow for standard TerrainModificationFailed listener to be registered
  191. // because it's a different type and that's illegal
  192. return code != NetworkDispatcherCode.TerrainModificationFailed;
  193. }
  194. [HarmonyTargetMethod]
  195. public static MethodBase Target()
  196. {
  197. return AccessTools.Method("GameNetworkLayer.Client.NetMessageClientListener:RegisterListener", generics: new []{ typeof(SerializedEmptyNetData)});
  198. }
  199. }
  200. // this disables terrain destruction
  201. /*[Bugfix(name = "TerrainModificationFailedHandler",
  202. description = "Actually handle TerrainModificationFailed network messages",
  203. more = "https://trello.com/c/Pq5lcB1p/23-moderation-tools",
  204. component = BugfixType.Debug, id = 8)]
  205. [HarmonyPatch]
  206. class TerrainModificationEngineServer_RemoveTerrainInput_Patch
  207. {
  208. [HarmonyPrefix]
  209. public static bool BeforeMethodCall(int senderPlayerId, ref ISerializedNetData data)
  210. {
  211. #if DEBUG
  212. API.Utility.Logging.MetaLog($"Intercepting client-side GameServer.VoxelFarm.Server.TerrainModificationEngineServer:RemoveTerrainInput({senderPlayerId}, {data})");
  213. #endif
  214. return false;
  215. }
  216. [HarmonyTargetMethod]
  217. public static MethodBase Target()
  218. {
  219. return AccessTools.Method("GameServer.VoxelFarm.Server.TerrainModificationEngineServer:RemoveTerrainInput");
  220. }
  221. }*/
  222. }