using 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);
}
}
}
}