Please disclose if your mod was created primarily 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 TheFlash v1.5.1
TheFlash.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.TheFlash.CustomRpc; using OPJosMod.TheFlash.Patches; using OPJosMod.TheFlash.Utils; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [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 float defaultSprintMultiplier; public static float defaultMaxSprintSpeed; public static float walkMultiplier; public static float maxWalkSpeed; public static Key flashTimeButton; } } namespace OPJosMod.TheFlash { public static class GlobalVariables { public static bool ModActivated; } [BepInPlugin("OpJosMod.TheFlash", "TheFlash", "1.5.1")] public class OpJosMod : BaseUnityPlugin { private const string modGUID = "OpJosMod.TheFlash"; private const string modName = "TheFlash"; private const string modVersion = "1.5.1"; private readonly Harmony harmony = new Harmony("OpJosMod.TheFlash"); private static OpJosMod Instance; internal ManualLogSource mls; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } mls = Logger.CreateLogSource("OpJosMod.TheFlash"); setupConfig(); CompleteRecievedTasks.SetLogSource(mls); PatchesForRPC.SetLogSource(mls); RpcMessageHandler.SetLogSource(mls); PlayerControllerBPatch.SetLogSource(mls); EntranceTeleportPatch.SetLogSource(mls); ShipTeleporterPatch.SetLogSource(mls); harmony.PatchAll(); } private void setupConfig() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<float> val = ((BaseUnityPlugin)this).Config.Bind<float>("Sprint Multiplier", "SprintMultiplier", 1.04f, "How fast your speed rams up when sprinting"); ConfigEntry<float> val2 = ((BaseUnityPlugin)this).Config.Bind<float>("Max Sprint Speed", "MaxSprintSpeed", 15f, "How fast you can run with flash time off"); ConfigEntry<float> val3 = ((BaseUnityPlugin)this).Config.Bind<float>("Walk Multiplier", "WalkMultiplier", 1.05f, "How fast you accelerate to top speed while walking"); ConfigEntry<float> val4 = ((BaseUnityPlugin)this).Config.Bind<float>("Max Walk Speed", "MaxWalkSpeed", 8f, "How fast you walk"); ConfigEntry<Key> val5 = ((BaseUnityPlugin)this).Config.Bind<Key>("Flash Time Button", "FlashTimeButton", (Key)32, "Button used to toggle flash time"); ConfigVariables.defaultSprintMultiplier = val.Value; ConfigVariables.defaultMaxSprintSpeed = val2.Value; ConfigVariables.walkMultiplier = val3.Value; ConfigVariables.maxWalkSpeed = val4.Value; ConfigVariables.flashTimeButton = val5.Value; } } } namespace OPJosMod.TheFlash.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.TheFlash.Patches { [HarmonyPatch(typeof(ShipTeleporter))] internal class ShipTeleporterPatch : MonoBehaviour { private static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } [HarmonyPatch("beamUpPlayer")] [HarmonyPrefix] private static void beamUpPlayerPatch() { if (GlobalVariables.ModActivated) { PlayerControllerB targetedPlayer = StartOfRound.Instance.mapScreen.targetedPlayer; if ((Object)(object)targetedPlayer != (Object)null && targetedPlayer.playerClientId == StartOfRound.Instance.localPlayerController.playerClientId) { PlayerControllerBPatch.RemoveMeshForPlayer(); } } } [HarmonyPatch("beamOutPlayer")] [HarmonyPostfix] private static void beamOutPlayerPatch() { if (GlobalVariables.ModActivated) { PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if (localPlayerController.isInsideFactory) { PlayerControllerBPatch.InitializeNaveMeshForPlayer(); } } } } [HarmonyPatch(typeof(EntranceTeleport))] internal class EntranceTeleportPatch : MonoBehaviour { private static ManualLogSource mls; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; } [HarmonyPatch("TeleportPlayer")] [HarmonyPostfix] private static void TeleportPlayerPatch() { if (GlobalVariables.ModActivated) { PlayerControllerBPatch.InitializeNaveMeshForPlayer(); } } } [HarmonyPatch(typeof(PlayerControllerB))] internal class PlayerControllerBPatch : MonoBehaviour { private static ManualLogSource mls; private static float increasedSprintMultiplier = 10f; private static float increasedMaxSprintSpeed = 1500f; private static float sprintMultiplier; private static float maxSprintSpeed; private static bool adjustingSpeed = false; private static int speedMode = 0; private static NavMeshPath path1; private static NavMeshAgent agent; private static bool moveTowardsDestination = false; private static Vector3 destination; public static bool hasInitialized = false; private static List<Vector3> runToLocations = null; private static bool customIsSprinting = false; public static void SetLogSource(ManualLogSource logSource) { mls = logSource; sprintMultiplier = ConfigVariables.defaultSprintMultiplier; maxSprintSpeed = ConfigVariables.defaultMaxSprintSpeed; } [HarmonyPatch("Update")] [HarmonyPostfix] private static void patchUpdate(PlayerControllerB __instance) { //IL_015d: Unknown result type (might be due to invalid IL or missing references) if (!GlobalVariables.ModActivated) { return; } FieldInfo field = typeof(PlayerControllerB).GetField("sprintMultiplier", BindingFlags.Instance | BindingFlags.NonPublic); if (ReflectionUtils.GetFieldValue<bool>(__instance, "isWalking")) { object value = field.GetValue(__instance); if (__instance.isSprinting) { float num = (float)value * sprintMultiplier; if (__instance.isInsideFactory && speedMode == 1) { maxSprintSpeed = 1f; } else if (speedMode == 1) { maxSprintSpeed = increasedMaxSprintSpeed; } else if (speedMode == 0) { maxSprintSpeed = ConfigVariables.defaultMaxSprintSpeed; } if (num < maxSprintSpeed) { field.SetValue(__instance, num); } } else { if ((float)value > ConfigVariables.maxWalkSpeed) { field.SetValue(__instance, ConfigVariables.maxWalkSpeed); } float num2 = (float)value * ConfigVariables.walkMultiplier; if (num2 < ConfigVariables.maxWalkSpeed) { field.SetValue(__instance, num2); } } } if (((NetworkBehaviour)__instance).IsOwner && !__instance.inTerminalMenu && !__instance.isTypingChat) { try { if (((ButtonControl)Keyboard.current[ConfigVariables.flashTimeButton]).wasPressedThisFrame && !adjustingSpeed) { adjustingSpeed = true; ((MonoBehaviour)__instance).StartCoroutine(toggleSpeed(__instance)); } } catch { } } AutoWalk(__instance); } [HarmonyPatch("KillPlayer")] [HarmonyPrefix] private static void killPlayerPatch(PlayerControllerB __instance) { if (GlobalVariables.ModActivated && __instance.playerClientId == StartOfRound.Instance.localPlayerController.playerClientId) { RemoveMeshForPlayer(); } } private static IEnumerator toggleSpeed(PlayerControllerB __instance) { yield return (object)new WaitForSeconds(1f); if (speedMode == 0) { mls.LogMessage((object)"speed mode set to 1"); HUDManager.Instance.DisplayTip("Flash Time", "On", false, false, "LC_Tip1"); speedMode = 1; sprintMultiplier = increasedSprintMultiplier; maxSprintSpeed = increasedMaxSprintSpeed; InitializeNaveMeshForPlayer(); } else if (speedMode == 1) { mls.LogMessage((object)"speed mode set to 0"); HUDManager.Instance.DisplayTip("Flash Time", "Off", false, false, "LC_Tip1"); speedMode = 0; sprintMultiplier = ConfigVariables.defaultSprintMultiplier; maxSprintSpeed = ConfigVariables.defaultMaxSprintSpeed; RemoveMeshForPlayer(); } adjustingSpeed = false; } private static IEnumerator vibratePlayer(PlayerControllerB __instance) { float vibrateAmount = 0.005f; Vector3 forwardDirection = ((Component)__instance).transform.forward; Vector3 rightDirection = Vector3.Cross(Vector3.up, forwardDirection); float randomDirectionSign = ((Random.Range(0, 2) == 0) ? (-1f) : 1f); Vector3 randomVibration = vibrateAmount * randomDirectionSign * rightDirection; __instance.thisController.Move(randomVibration); yield return (object)new WaitForSeconds(0.005f); __instance.thisController.Move(-randomVibration); yield return (object)new WaitForSeconds(0.005f); } private static void AutoWalk(PlayerControllerB __instance) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) if (!hasInitialized || !((Object)(object)((Component)__instance).gameObject.GetComponent<NavMeshAgent>() != (Object)null)) { return; } if (__instance.isSprinting && speedMode == 1) { if (!moveTowardsDestination) { startRunToNewPosition(__instance); } } else { ((Behaviour)agent).enabled = false; moveTowardsDestination = false; } if (moveTowardsDestination && __instance.isInsideFactory) { if (Vector3.Distance(((Component)__instance).transform.position, destination) < 3f) { mls.LogMessage((object)"reached destination!"); startRunToNewPosition(__instance); } agent.SetDestination(destination); } } public static void InitializeNaveMeshForPlayer() { //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) try { PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null || (Object)(object)((Component)localPlayerController).gameObject == (Object)null || !localPlayerController.isInsideFactory) { Debug.LogError((object)"PlayerControllerB instance or its GameObject is null. or they are outside"); return; } Debug.Log((object)("Initializing NavMeshAgent for player with client ID: " + localPlayerController.playerClientId)); if ((Object)(object)((Component)localPlayerController).gameObject.GetComponent<NavMeshAgent>() == (Object)null) { int num = 1000; agent = ((Component)localPlayerController).gameObject.AddComponent<NavMeshAgent>(); agent.speed = 5f * (float)num; agent.acceleration = 250f * (float)(num / 2); agent.angularSpeed = 1000f * (float)(num / 2); agent.stoppingDistance = 0.2f; agent.autoBraking = false; agent.autoTraverseOffMeshLink = true; agent.obstacleAvoidanceType = (ObstacleAvoidanceType)0; agent.radius = 0.4f; agent.height = 2f; agent.avoidancePriority = 50; agent.autoRepath = true; agent.updateRotation = true; agent.updatePosition = true; agent.updateUpAxis = false; hasInitialized = true; } else { agent = ((Component)localPlayerController).gameObject.GetComponent<NavMeshAgent>(); mls.LogMessage((object)"didnt re-add nav mesh as it already existed"); } runToLocations = (from x in Object.FindObjectsOfType<EnemyVent>() select ((Component)x).transform.position).ToList(); runToLocations.Add(RoundManager.FindMainEntrancePosition(false, false)); ((Behaviour)agent).enabled = false; moveTowardsDestination = false; } catch (Exception ex) { mls.LogError((object)ex); } } public static void RemoveMeshForPlayer() { PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController; if ((Object)(object)((Component)localPlayerController).gameObject.GetComponent<NavMeshAgent>() != (Object)null) { Object.Destroy((Object)(object)((Component)localPlayerController).gameObject.GetComponent<NavMeshAgent>()); } } private static void startRunToNewPosition(PlayerControllerB player) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) ((Behaviour)agent).enabled = true; float[] second = runToLocations.Select((Vector3 pos) => Vector3.Distance(pos, ((Component)player).transform.position)).ToArray(); var source = runToLocations.Zip(second, (Vector3 pos, float dist) => new { Position = pos, Distance = dist }); var source2 = source.OrderByDescending(pair => pair.Distance).ToArray(); List<Vector3> list = source2.Select(pair => pair.Position).ToList(); int index = Random.Range(0, list.Count / 2); Vector3 destinationToPosition = list[index]; if (!SetDestinationToPosition(destinationToPosition) && list.Count > 0) { list.ElementAt(Random.Range(0, list.Count / 2)); } } private static bool SetDestinationToPosition(Vector3 position) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) try { mls.LogMessage((object)$"setting desitination to positon: {position}"); position = RoundManager.Instance.GetNavMeshPosition(position, RoundManager.Instance.navHit, 1.75f, -1); moveTowardsDestination = true; destination = RoundManager.Instance.GetNavMeshPosition(position, RoundManager.Instance.navHit, -1f, -1); mls.LogMessage((object)$"destination is: {destination}"); return true; } catch (Exception ex) { mls.LogError((object)ex); InitializeNaveMeshForPlayer(); } return false; } } } namespace OPJosMod.TheFlash.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 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, ErrorNoTask } public static class MessageTaskUtil { public static string GetCode(MessageTasks code) { return code switch { MessageTasks.ModActivated => ":ModActivated:", 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; } return MessageTasks.ErrorNoTask; } } 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; RpcMessage rpcMessage = new RpcMessage(MessageTasks.ModActivated, PatchesForRPC.mls.SourceName, (int)__instance.localPlayerController.playerClientId, MessageCodes.Request); RpcMessageHandler.SendRpcMessage(rpcMessage); } } } public class RpcMessage { public MessageTasks Task { get; set; } public string Message { get; set; } public int FromUser { get; set; } public MessageCodes MessageCode { get; set; } public RpcMessage(MessageTasks task, string message, int user, MessageCodes code) { Task = task; Message = message; FromUser = user; MessageCode = code; } public string getMessageWithCode() { return MessageCodeUtil.GetCode(MessageCode) + MessageTaskUtil.GetCode(Task) + Message; } } public static class RpcMessageHandler { private static ManualLogSource mls; private static float lastSentTime = Time.time; private static float messageWaitTime = 0.5f; 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(MessageTasks task, string message) { RpcMessage message2 = new RpcMessage(task, 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.ErrorNoTask: mls.LogError((object)"got an error task"); break; } } } }