Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of OneHitShovel v1.5.1
OneHitShovel.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using OPJosMod.OneHitShovel.CustomRpc; using OPJosMod.OneHitShovel.Patches; using OPJosMod.OneHitShovel.Utils; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("OPJosMod")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("OPJosMod")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("70095872-b952-4e27-bbc4-3d70d0238f39")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace OPJosMod { public static class ConfigVariables { public static bool syncDeathAnimations; } } namespace OPJosMod.OneHitShovel { public static class Constants { public static List<string> humanoidNames = new List<string> { "SpringManModel", "DressGirlModel", "MeshContainer", "SpringMan(Clone)", "DressGirl(Clone)", "JesterEnemy(Clone)" }; public static string[] fourLeggedNames = new string[2] { "PufferModel", "PufferEnemy(Clone)" }; public static string[] dieInPlaceNames = new string[3] { "Bone.", "Bone", "SandWorm(Clone)" }; public static string[] slimeNames = new string[10] { "BoneEast", "BoneNorth", "BoneSouth", "BoneWest", "BoneNorthWest", "BoneNorthEast", "BoneSouthEast", "BoneSouthWest", "Center", "Blob(Clone)" }; public static string[] mechNames = new string[2] { "ClawTrigger", "RadMechEnemy(Clone)" }; } public static class CustomEnemyDeaths { private static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } public static void killHumanoid(GameObject gameObject) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) mls.LogMessage((object)("try to kill " + ((Object)gameObject).name)); gameObject.transform.rotation = Quaternion.Euler(-90f, 0f, 90f); Renderer component = gameObject.GetComponent<Renderer>(); float num; if (!((Object)(object)component != (Object)null)) { num = 0.1f; } else { Bounds bounds = component.bounds; num = ((Bounds)(ref bounds)).size.x * 0.1f; } float num2 = num; Transform transform = gameObject.transform; transform.position += new Vector3(0f, num2, 0f); Collider[] componentsInChildren = gameObject.GetComponentsInChildren<Collider>(); Collider[] array = componentsInChildren; foreach (Collider val in array) { val.enabled = false; } EnemyAI val2 = findClosestEnemyAI(gameObject.transform.position); if ((Object)(object)val2 != (Object)null) { mls.LogMessage((object)"enemy ai isn't null"); val2.isEnemyDead = true; ((Behaviour)val2.creatureAnimator).enabled = false; stopAllSounds(val2); } else { mls.LogMessage((object)"enemy ai is null"); } } public static IEnumerator KillMech(Vector3 hitLocation, bool updateOnServer = false) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) EnemyAI enemyAI = findClosestEnemyAI(hitLocation); try { mls.LogMessage((object)"trying to kill mech"); if (enemyAI is RadMechAI) { RadMechAI radMech = (RadMechAI)enemyAI; ((MonoBehaviour)radMech).StopAllCoroutines(); killHumanoid(((Component)radMech).gameObject); if (updateOnServer) { updateLocationOnServer(((Component)radMech).gameObject); } radMech.DisableSpotlight(); radMech.DisableBlowtorch(); radMech.DisableThrusterSmoke(); ((EnemyAI)radMech).enemyHP = 0; ((Behaviour)radMech.engineSFX).enabled = false; radMech.chargeForwardAudio.volume = 0f; radMech.engineSFX.volume = 0f; radMech.flyingDistantAudio.volume = 0f; radMech.spotlightOnAudio.volume = 0f; radMech.LocalLRADAudio.volume = 0f; radMech.LocalLRADAudio2.volume = 0f; radMech.blowtorchAudio.volume = 0f; } } catch { } yield return (object)new WaitForSeconds(0.2f); killHumanoid(((Component)enemyAI).gameObject); } public static void killInPlace(GameObject gameObject) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) mls.LogMessage((object)("try to kill " + ((Object)gameObject).name)); Collider[] componentsInChildren = gameObject.GetComponentsInChildren<Collider>(); Collider[] array = componentsInChildren; foreach (Collider val in array) { val.enabled = false; } EnemyAI val2 = findClosestEnemyAI(gameObject.transform.position); if ((Object)(object)val2 != (Object)null) { mls.LogMessage((object)"enemy ai isn't null"); val2.isEnemyDead = true; ((Behaviour)val2.creatureAnimator).enabled = false; stopAllSounds(val2); } else { mls.LogMessage((object)"enemy ai is null"); } } public static void killFourLegged(GameObject gameObject) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) mls.LogMessage((object)("try to kill " + ((Object)gameObject).name)); gameObject.transform.rotation = Quaternion.Euler(180f, 0f, 0f); Renderer component = gameObject.GetComponent<Renderer>(); float num; if (!((Object)(object)component != (Object)null)) { num = 1f; } else { Bounds bounds = component.bounds; num = ((Bounds)(ref bounds)).size.y * 0.1f; } float num2 = num; Transform transform = gameObject.transform; transform.position += new Vector3(0f, num2, 0f); Collider[] componentsInChildren = gameObject.GetComponentsInChildren<Collider>(); Collider[] array = componentsInChildren; foreach (Collider val in array) { val.enabled = false; } EnemyAI val2 = findClosestEnemyAI(gameObject.transform.position); if ((Object)(object)val2 != (Object)null) { mls.LogMessage((object)"enemy ai isn't null"); val2.isEnemyDead = true; ((Behaviour)val2.creatureAnimator).enabled = false; stopAllSounds(val2); } else { mls.LogMessage((object)"enemy ai is null"); } } public static void killSlime(GameObject gameObject) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) mls.LogMessage((object)("try to kill " + ((Object)gameObject).name)); EnemyAI val = findClosestEnemyAI(gameObject.transform.position); if ((Object)(object)val != (Object)null) { mls.LogMessage((object)"enemy ai isn't null"); val.isEnemyDead = true; ((Behaviour)val.creatureAnimator).enabled = false; } else { mls.LogMessage((object)"enemy ai is null"); } Object.Destroy((Object)(object)val); stopAllSounds(val); string[] slimeNames = Constants.slimeNames; foreach (string name in slimeNames) { destroySlimePart(gameObject, name); } } public static void updateLocationOnServer(GameObject gameObject) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) EnemyAI val = findClosestEnemyAI(gameObject.transform.position); if ((Object)(object)val != (Object)null) { val.KillEnemyServerRpc(false); } else { mls.LogMessage((object)"no enemy to kill"); } if (ConfigVariables.syncDeathAnimations) { string code = MessageTaskUtil.GetCode(MessageTasks.EnemyDied); Vector3 position = gameObject.transform.position; string message = code + ((object)(Vector3)(ref position)).ToString(); RpcMessage message2 = new RpcMessage(message, (int)StartOfRound.Instance.localPlayerController.playerClientId, MessageCodes.Request); RpcMessageHandler.SendRpcMessage(message2); } else { val.KillEnemyServerRpc(true); } } private static void stopAllSounds(EnemyAI enemy) { AudioSource[] componentsInChildren = ((Component)enemy).GetComponentsInChildren<AudioSource>(); AudioSource[] array = componentsInChildren; foreach (AudioSource val in array) { val.Stop(); } } private static void destroySlimePart(GameObject gameObject, string name) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) GameObject[] array = Object.FindObjectsOfType<GameObject>(); GameObject val = null; float num = float.PositiveInfinity; GameObject[] array2 = array; foreach (GameObject val2 in array2) { if (((Object)val2).name == name) { float num2 = Vector3.Distance(gameObject.transform.position, val2.transform.position); if (num2 < num && num2 < 15f) { num = num2; val = val2; } } } if ((Object)(object)val != (Object)null) { mls.LogMessage((object)("Closest Enemy with name '" + name + "' found: " + ((Object)val).name)); } else { mls.LogMessage((object)("No Enemy with name '" + name + "' found in the scene.")); } Object.Destroy((Object)(object)val); } public static EnemyAI findClosestEnemyAI(Vector3 location) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) EnemyAI val = null; EnemyAI[] array = Object.FindObjectsOfType<EnemyAI>(); float num = float.PositiveInfinity; EnemyAI[] array2 = array; foreach (EnemyAI val2 in array2) { float num2 = Vector3.Distance(location, ((Component)val2).transform.position); if (num2 < num) { num = num2; val = val2; } } if ((Object)(object)val != (Object)null) { mls.LogMessage((object)("Closest EnemyAI found: " + ((Object)val).name)); } else { mls.LogError((object)"No EnemyAI found in the scene."); } return val; } public static void KillAnyEnemy(EnemyAI enemy) { mls.LogMessage((object)("enemy died " + ((Object)enemy).name)); GameObject gameObject = ((Component)enemy).gameObject; KillGameObjectEnemy(gameObject); } public static void KillGameObjectEnemy(GameObject gameObject) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gameObject != (Object)null && ((Object)gameObject).name != "Player") { mls.LogMessage((object)("kill game object with name: " + ((Object)gameObject).name)); if (Constants.humanoidNames.Contains(((Object)gameObject).name)) { killHumanoid(gameObject); } if (Constants.fourLeggedNames.Contains(((Object)gameObject).name)) { killFourLegged(gameObject); } if (Constants.slimeNames.Contains(((Object)gameObject).name)) { killSlime(gameObject); } if (Constants.mechNames.Contains(((Object)gameObject).name)) { ((MonoBehaviour)StartOfRound.Instance.localPlayerController).StartCoroutine(KillMech(gameObject.transform.position)); } if (((Object)gameObject).name == null) { return; } int num = ((Object)gameObject).name.LastIndexOf('.'); if (num != -1) { string value = ((Object)gameObject).name.Substring(0, num + 1); if (Constants.dieInPlaceNames.Contains(value)) { killInPlace(gameObject); } } } else { mls.LogError((object)"game object was null"); } } } public static class GeneralUtil { public static Vector3 StringToVector3(string s) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) string[] array = s.Trim('(', ')').Split(new char[1] { ',' }); float num = float.Parse(array[0]); float num2 = float.Parse(array[1]); float num3 = float.Parse(array[2]); return new Vector3(num, num2, num3); } public static int GetGameVersion() { try { return GameNetworkManager.Instance.gameVersionNum; } catch { } return 0; } } public static class GlobalVariables { public static bool ModActivated; } [BepInPlugin("OpJosMod.OneHitShovel", "OneHitShovel", "1.5.1")] public class OpJosMod : BaseUnityPlugin { private const string modGUID = "OpJosMod.OneHitShovel"; private const string modName = "OneHitShovel"; private const string modVersion = "1.5.1"; private readonly Harmony harmony = new Harmony("OpJosMod.OneHitShovel"); private static OpJosMod Instance; internal ManualLogSource mls; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } mls = Logger.CreateLogSource("OpJosMod.OneHitShovel"); setupConfig(); PatchesForRPC.SetLogSource(mls); RpcMessageHandler.SetLogSource(mls); CompleteRecievedTasks.SetLogSource(mls); ShovelPatch.SetLogSource(mls); CustomEnemyDeaths.SetLogSource(mls); harmony.PatchAll(); } private void setupConfig() { ConfigEntry<bool> val = ((BaseUnityPlugin)this).Config.Bind<bool>("Custom Death Animations", "CustomDeathAnimations", true, "Setting for attempting to sync death animations for enemies that can't normally die. If off the enemies will just despawn instead."); ConfigVariables.syncDeathAnimations = val.Value; } } } namespace OPJosMod.OneHitShovel.Utils { public class ReflectionUtils { public static void InvokeMethod(object obj, string methodName, object[] parameters) { Type type = obj.GetType(); MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); method.Invoke(obj, parameters); } public static void InvokeMethod(object obj, Type forceType, string methodName, object[] parameters) { MethodInfo method = forceType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); method.Invoke(obj, parameters); } public static void SetPropertyValue(object obj, string propertyName, object value) { Type type = obj.GetType(); PropertyInfo property = type.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); property.SetValue(obj, value); } public static T InvokeMethod<T>(object obj, string methodName, object[] parameters) { Type type = obj.GetType(); MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (T)method.Invoke(obj, parameters); } public static T GetFieldValue<T>(object obj, string fieldName) { Type type = obj.GetType(); FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); return (T)field.GetValue(obj); } public static void SetFieldValue(object obj, string fieldName, object value) { Type type = obj.GetType(); FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); field.SetValue(obj, value); } } } namespace OPJosMod.OneHitShovel.Patches { [HarmonyPatch(typeof(Shovel))] internal class ShovelPatch { private static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } [HarmonyPatch("HitShovel")] [HarmonyPrefix] private static void hitShovelPatch(Shovel __instance) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) if (!GlobalVariables.ModActivated) { return; } try { __instance.shovelHitForce = 30; GameObject val = null; PlayerControllerB fieldValue = ReflectionUtils.GetFieldValue<PlayerControllerB>(__instance, "previousPlayerHeldBy"); RaycastHit[] fieldValue2 = ReflectionUtils.GetFieldValue<RaycastHit[]>(__instance, "objectsHitByShovel"); List<RaycastHit> fieldValue3 = ReflectionUtils.GetFieldValue<List<RaycastHit>>(__instance, "objectsHitByShovelList"); int fieldValue4 = ReflectionUtils.GetFieldValue<int>(__instance, "shovelMask"); fieldValue2 = Physics.SphereCastAll(((Component)fieldValue.gameplayCamera).transform.position + ((Component)fieldValue.gameplayCamera).transform.right * -0.35f, 0.8f, ((Component)fieldValue.gameplayCamera).transform.forward, 1.5f, fieldValue4, (QueryTriggerInteraction)2); fieldValue3 = fieldValue2.OrderBy((RaycastHit x) => ((RaycastHit)(ref x)).distance).ToList(); IHittable val3 = default(IHittable); for (int i = 0; i < fieldValue3.Count; i++) { RaycastHit val2 = fieldValue3[i]; if (((Component)((RaycastHit)(ref val2)).transform).TryGetComponent<IHittable>(ref val3) && !((Object)((Component)((RaycastHit)(ref val2)).transform).gameObject).name.Contains("Player")) { mls.LogMessage((object)("Hit object: " + ((Object)((Component)((RaycastHit)(ref val2)).transform).gameObject).name)); val = ((Component)((RaycastHit)(ref val2)).transform).gameObject; } } if ((Object)(object)val != (Object)null) { CustomEnemyDeaths.KillGameObjectEnemy(val); CustomEnemyDeaths.updateLocationOnServer(val); } Vector3? val4 = checkIfHitMech(); if (val4.HasValue) { ((MonoBehaviour)StartOfRound.Instance.localPlayerController).StartCoroutine(CustomEnemyDeaths.KillMech(val4.Value, updateOnServer: true)); } } catch (Exception ex) { mls.LogError((object)ex); } } private static Vector3? checkIfHitMech() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) try { PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; RadMechAI[] array = Object.FindObjectsOfType<RadMechAI>(); if (array.Length == 0) { return null; } RadMechAI val = null; float num = float.PositiveInfinity; RadMechAI[] array2 = array; foreach (RadMechAI val2 in array2) { Vector3 val3 = ((Component)val2).transform.position - ((Component)localPlayerController).transform.position; if (Vector3.Dot(((Component)localPlayerController).transform.forward, ((Vector3)(ref val3)).normalized) > 0.5f) { float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude <= 3f && magnitude < num) { num = magnitude; val = val2; } } } if ((Object)(object)val == (Object)null) { return null; } return ((Component)val).transform.position; } catch { return null; } } } } namespace OPJosMod.OneHitShovel.CustomRpc { public static class CompleteRecievedTasks { private static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } public static void ModActivated(string modName) { if (mls.SourceName == modName) { mls.LogMessage((object)"Mod Activated"); GlobalVariables.ModActivated = true; } } public static void EnemyDied(string position) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) Vector3 location = GeneralUtil.StringToVector3(position); EnemyAI val = CustomEnemyDeaths.findClosestEnemyAI(location); if ((Object)(object)val != (Object)null) { CustomEnemyDeaths.KillAnyEnemy(val); } else { mls.LogMessage((object)"couldnt find enemy to kill"); } } } public enum MessageCodes { Request, Response } public static class MessageCodeUtil { public static string GetCode(MessageCodes code) { return code switch { MessageCodes.Request => ":rpcRequest:", MessageCodes.Response => ":rpcResponse:", _ => ":Error:", }; } public static bool stringContainsMessageCode(string givenString) { return givenString.Contains(GetCode(MessageCodes.Request)) || givenString.Contains(GetCode(MessageCodes.Response)); } public static string returnMessageWithoutCode(string message) { if (stringContainsMessageCode(message)) { int length = GetCode(MessageCodes.Request).Length; return message.Substring(length); } return message; } } public enum MessageTasks { ModActivated, EnemyDied, ErrorNoTask } public static class MessageTaskUtil { public static string GetCode(MessageTasks code) { return code switch { MessageTasks.ModActivated => ":ModActivated:", MessageTasks.EnemyDied => ":EnemyDied:", MessageTasks.ErrorNoTask => ":Error:", _ => ":Error:", }; } public static string getMessageWithoutTask(string message) { foreach (MessageTasks value in Enum.GetValues(typeof(MessageTasks))) { string code2 = GetCode(value); message = message.Replace(code2, ""); } return message.Trim(); } public static MessageTasks getMessageTask(string givenString) { if (givenString.Contains(GetCode(MessageTasks.ModActivated))) { return MessageTasks.ModActivated; } if (givenString.Contains(GetCode(MessageTasks.EnemyDied))) { return MessageTasks.EnemyDied; } return MessageTasks.ErrorNoTask; } } public class RpcMessage { public string Message { get; set; } public int FromUser { get; set; } public MessageCodes MessageCode { get; set; } public RpcMessage(string message, int user, MessageCodes code) { Message = message; FromUser = user; MessageCode = code; } public string getMessageWithCode() { return MessageCodeUtil.GetCode(MessageCode) + Message; } } public static class RpcMessageHandler { private static ManualLogSource mls; private static float lastSentTime = Time.time; private static float messageWaitTime = 1f; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } public static void SendRpcMessage(RpcMessage message) { if (!(Time.time - lastSentTime > messageWaitTime)) { return; } lastSentTime = Time.time; HUDManager instance = HUDManager.Instance; if ((Object)(object)instance != (Object)null) { MethodInfo method = typeof(HUDManager).GetMethod("AddPlayerChatMessageServerRpc", BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { object[] parameters = new object[2] { message.getMessageWithCode(), message.FromUser }; method.Invoke(instance, parameters); } else { mls.LogError((object)"AddPlayerChatMessageServerRpc method not found in HUDManager class."); } } else { mls.LogError((object)"HUDManager.Instance is null."); } } public static void ReceiveRpcMessage(string message, int user) { if (user != (int)StartOfRound.Instance.localPlayerController.playerClientId) { string text = MessageCodeUtil.returnMessageWithoutCode(message); if (message.Contains(MessageCodeUtil.GetCode(MessageCodes.Request))) { MessageTasks messageTask = MessageTaskUtil.getMessageTask(text); string messageWithoutTask = MessageTaskUtil.getMessageWithoutTask(text); handleTask(messageTask, messageWithoutTask); } else if (message.Contains(MessageCodeUtil.GetCode(MessageCodes.Response))) { mls.LogMessage((object)"got the response that the other clients recieved this message"); } } } public static void SendRpcResponse(string message) { RpcMessage message2 = new RpcMessage(message, (int)StartOfRound.Instance.localPlayerController.playerClientId, MessageCodes.Response); SendRpcMessage(message2); } private static void handleTask(MessageTasks task, string message) { switch (task) { case MessageTasks.ModActivated: CompleteRecievedTasks.ModActivated(message); break; case MessageTasks.EnemyDied: CompleteRecievedTasks.EnemyDied(message); break; case MessageTasks.ErrorNoTask: mls.LogError((object)"got an error task"); break; } } } public static class PatchesForRPC { public static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } } [HarmonyPatch(typeof(HUDManager))] internal static class HUDManagerPatchForRPC { private static float lastRecievedAt = Time.time; private static string lastRecievedMessage = ""; private static float messageWaitTime = 0.5f; [HarmonyPatch("AddPlayerChatMessageClientRpc")] [HarmonyPrefix] private static void addPlayerChatMessageClientRpcPatch(ref string chatMessage, ref int playerId) { if (MessageCodeUtil.stringContainsMessageCode(chatMessage) && (Time.time - lastRecievedAt > messageWaitTime || chatMessage != lastRecievedMessage)) { lastRecievedAt = Time.time; lastRecievedMessage = chatMessage; RpcMessageHandler.ReceiveRpcMessage(chatMessage, playerId); } } [HarmonyPatch("AddChatMessage")] [HarmonyPrefix] private static bool addChatMessagePatch(ref string chatMessage) { if (MessageCodeUtil.stringContainsMessageCode(chatMessage)) { return false; } return true; } } [HarmonyPatch(typeof(StartOfRound))] internal static class StartOfRoundPatchForRPC { [HarmonyPatch("OnClientConnect")] [HarmonyPostfix] private static void patchOnClientConnect(StartOfRound __instance) { ((MonoBehaviour)__instance).StartCoroutine(activateModForOthers(__instance)); } [HarmonyPatch("Start")] [HarmonyPostfix] private static void patchStart(StartOfRound __instance) { if (((NetworkBehaviour)__instance).IsHost) { GlobalVariables.ModActivated = true; } } [HarmonyPatch("OnLocalDisconnect")] [HarmonyPostfix] private static void patchOnLocalDisconnect(StartOfRound __instance) { GlobalVariables.ModActivated = false; } private static IEnumerator activateModForOthers(StartOfRound __instance) { yield return (object)new WaitForSeconds(3f); if (((NetworkBehaviour)__instance).IsHost) { GlobalVariables.ModActivated = true; string message = MessageTaskUtil.GetCode(MessageTasks.ModActivated) + PatchesForRPC.mls.SourceName; RpcMessage rpcMessage = new RpcMessage(message, (int)__instance.localPlayerController.playerClientId, MessageCodes.Request); RpcMessageHandler.SendRpcMessage(rpcMessage); } } } }