Decompiled source of GTZLethalMod v1.1.1

plugins/GTZLethalMod.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GTZLethalMod.Features.CustomEmoteAudio;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("GTZLethalMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+41f01b085815e0a8c3631f2e97aa8face1705466")]
[assembly: AssemblyProduct("GTZLethalMod")]
[assembly: AssemblyTitle("GTZLethalMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace GTZLethalMod
{
	public static class Config
	{
		public static ConfigFile File => ((BaseUnityPlugin)Plugin.Instance).Config;

		public static Dictionary<string, ConfigEntryBase> CurrentEntries { get; } = new Dictionary<string, ConfigEntryBase>();


		public static ConfigEntry<bool> Debug { get; private set; } = null;


		public static ConfigEntry<string> EmoteAudioOverrides { get; private set; } = null;


		public static ConfigEntry<float> VehicleSpeedModifier { get; private set; } = null;


		public static ConfigEntry<bool> LGUAndLPCompatFix { get; private set; } = null;


		public static void BindConfigSettings()
		{
			Logger.Log("Binding Configs");
			Debug = AddConfigEntry("Advanced", "Debug", "Whether to print out debug logs.", defaultValue: false);
			EmoteAudioOverrides = AddConfigEntry("Emote Audio", "Overrides", "Overrides the audio of emotes from 'TooManyEmotes'. Config entries are formatting as follows: 'name1,path1|name2,path2' etc...", "smug_dance,Assets/PeaceAndTranquility.ogg");
			VehicleSpeedModifier = AddConfigEntry("Vehicles", "Speed Modifier", "Car go brrr?", 1f);
			LGUAndLPCompatFix = AddConfigEntry("Compatability", "LGU + LP Max Health Fix", "Fix", defaultValue: true);
			File.Save();
		}

		private static ConfigEntry<T> AddConfigEntry<T>(string section, string name, string description, T defaultValue)
		{
			ConfigEntry<T> val = File.Bind<T>(section, name, defaultValue, description);
			CurrentEntries.Add(((ConfigEntryBase)val).Definition.Key, (ConfigEntryBase)(object)val);
			return val;
		}

		private static void RemoveOldConfigs()
		{
		}
	}
	public class Logger
	{
		private static ManualLogSource logger;

		public static void Initialize()
		{
			try
			{
				logger = Logger.CreateLogSource($"{((BaseUnityPlugin)Plugin.Instance).Info.Metadata.Name}-{((BaseUnityPlugin)Plugin.Instance).Info.Metadata.Version}");
			}
			catch
			{
				logger = Plugin.DefaultLogger;
			}
		}

		public static void Log(string msg)
		{
			logger.LogInfo((object)msg);
		}

		public static void Warning(string msg)
		{
			logger.LogWarning((object)msg);
		}

		public static void Error(string msg)
		{
			logger.LogError((object)msg);
		}

		public static void Debug(string msg)
		{
			if (Config.Debug.Value)
			{
				logger.LogDebug((object)msg);
			}
		}
	}
	public class PathManager
	{
		public static string PluginDirectory { get; private set; }

		public static string GetPath(string subdirectory)
		{
			return Path.Combine(PluginDirectory, subdirectory);
		}

		internal static void Initialize()
		{
			PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location) ?? throw new InvalidOperationException("Couldn't get directory name from " + ((BaseUnityPlugin)Plugin.Instance).Info.Location);
		}
	}
	[BepInPlugin("Someone.GTZLethalMod", "GTZLethalMod", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "Someone.GTZLethalMod";

		public const string Name = "GTZLethalMod";

		public const string Version = "1.0.0";

		public static Plugin Instance { get; private set; }

		public static Harmony Harmony { get; private set; }

		public static ManualLogSource DefaultLogger => ((BaseUnityPlugin)Instance).Logger;

		public void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			Instance = this;
			Logger.Initialize();
			PathManager.Initialize();
			Config.BindConfigSettings();
			AudioSetter.Initialize();
			try
			{
				Harmony = new Harmony("Someone.GTZLethalMod");
				Harmony.PatchAll();
			}
			catch (Exception ex)
			{
				Logger.Error(ex.ToString());
			}
			Logger.Log("GTZLethalMod has finished loading!");
		}
	}
}
namespace GTZLethalMod.Fixes
{
	[HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")]
	public class DamagePlayer
	{
		private static MethodInfo? hpMethod;

		public static bool Prepare()
		{
			if (!Config.LGUAndLPCompatFix.Value)
			{
				return false;
			}
			hpMethod = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly asm) => asm.GetName().Name.Contains("LethalProgression"))?.GetType("LethalProgression.Skills.Upgrades.MaxHP")?.GetMethod("GetNewMaxHealth");
			bool num = (object)hpMethod != null;
			if (!num)
			{
				Logger.Warning("Failed to fix DamagePlayer + LP MaxHP: HPMethod could not be found!");
			}
			return num;
		}

		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			if ((object)hpMethod == null)
			{
				throw new InvalidOperationException();
			}
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Mathf), "Clamp", new Type[3]
				{
					typeof(int),
					typeof(int),
					typeof(int)
				}, (Type[])null), (string)null)
			}).Insert((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)hpMethod)
			});
			return val.InstructionEnumeration();
		}
	}
	[HarmonyPatch]
	public class Medkit
	{
		private static MethodInfo? target;

		private static MethodInfo? hpMethod;

		public static bool Prepare()
		{
			if (!Config.LGUAndLPCompatFix.Value)
			{
				return false;
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			target = assemblies.FirstOrDefault((Assembly asm) => asm.GetName().Name.Contains("MoreShipUpgrades"))?.GetType("MoreShipUpgrades.UpgradeComponents.Items.Medkit")?.GetMethod("AttemptToHealPlayer", BindingFlags.Instance | BindingFlags.NonPublic);
			hpMethod = assemblies.FirstOrDefault((Assembly asm) => asm.GetName().Name.Contains("LethalProgression"))?.GetType("LethalProgression.Skills.Upgrades.MaxHP")?.GetMethod("GetNewMaxHealth");
			int num;
			if ((object)target != null)
			{
				num = (((object)hpMethod != null) ? 1 : 0);
				if (num != 0)
				{
					goto IL_0111;
				}
			}
			else
			{
				num = 0;
			}
			Logger.Warning("Failed to fix LGU Medkit + LP MaxHP! Target: " + (target?.ToString() ?? "null") + ", HpMethod: " + (hpMethod?.ToString() ?? "null"));
			goto IL_0111;
			IL_0111:
			return (byte)num != 0;
		}

		public static MethodInfo TargetMethod()
		{
			return target ?? throw new InvalidOperationException();
		}

		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			if ((object)hpMethod == null)
			{
				throw new InvalidOperationException();
			}
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.Start().MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction x) => CodeInstructionExtensions.LoadsConstant(x, 100L)), (string)null)
			}).Repeat((Action<CodeMatcher>)delegate(CodeMatcher m)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Expected O, but got Unknown
				m.Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)hpMethod)
				});
			}, (Action<string>)null);
			return val.InstructionEnumeration();
		}
	}
}
namespace GTZLethalMod.Features.VehicleModifiers
{
	[HarmonyPatch(typeof(VehicleController), "FixedUpdate")]
	public class CarSpeed
	{
		private static float Value => Config.VehicleSpeedModifier.Value;

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchStartForward((CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(VehicleController), "speed"), (string)null)
			});
			val.Advance(1);
			val.Insert((CodeInstruction[])(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.PropertyGetter(typeof(CarSpeed), "Value")),
				new CodeInstruction(OpCodes.Mul, (object)null)
			});
			val.Repeat((Action<CodeMatcher>)delegate(CodeMatcher cm)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Expected O, but got Unknown
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Expected O, but got Unknown
				cm.Advance(1);
				cm.Insert((CodeInstruction[])(object)new CodeInstruction[2]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.PropertyGetter(typeof(CarSpeed), "Value")),
					new CodeInstruction(OpCodes.Mul, (object)null)
				});
			}, (Action<string>)null);
			return val.InstructionEnumeration();
		}
	}
}
namespace GTZLethalMod.Features.CustomEmoteAudio
{
	public class AudioSetter
	{
		private static Assembly? EmotesAssembly { get; set; }

		private static Type? AudioManager { get; set; }

		private static FieldInfo? DmcaAudioClipsField { get; set; }

		private static Dictionary<string, AudioClip>? DmcaAudioClips { get; set; }

		private static Type? EmotesManager { get; set; }

		private static FieldInfo? AllEmotesField { get; set; }

		private static IEnumerable? AllEmotes { get; set; }

		private static Type? EmoteType { get; set; }

		private static MethodInfo? AudioClipNameGetter { get; set; }

		private static FieldInfo? IsBoomboxAudioField { get; set; }

		internal static void Initialize()
		{
			EmotesAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name.Contains("TooManyEmotes"));
			if ((object)EmotesAssembly == null)
			{
				Logger.Debug("Emotes assembly not found");
				return;
			}
			AudioManager = EmotesAssembly.GetType("TooManyEmotes.Audio.AudioManager");
			if ((object)AudioManager == null)
			{
				Logger.Debug("Audio manager not found");
				return;
			}
			DmcaAudioClipsField = AudioManager.GetField("audioClipsDictDmca", BindingFlags.Static | BindingFlags.NonPublic);
			if ((object)DmcaAudioClipsField == null)
			{
				Logger.Debug("DmcaAudioClips not found");
				return;
			}
			DmcaAudioClips = DmcaAudioClipsField.GetValue(null) as Dictionary<string, AudioClip>;
			if (DmcaAudioClips == null)
			{
				Logger.Debug("DmcaAudioClips not found");
				return;
			}
			EmotesManager = EmotesAssembly.GetType("TooManyEmotes.EmotesManager");
			if ((object)EmotesManager == null)
			{
				Logger.Debug("EmotesManager not found");
				return;
			}
			AllEmotesField = EmotesManager.GetField("allUnlockableEmotes", BindingFlags.Static | BindingFlags.Public);
			if ((object)AllEmotesField == null)
			{
				Logger.Debug("AllEmotesField not found");
				return;
			}
			AllEmotes = AllEmotesField.GetValue(null) as IEnumerable;
			if (AllEmotes == null)
			{
				Logger.Debug("AllEmotes not found");
				return;
			}
			EmoteType = EmotesAssembly.GetType("TooManyEmotes.UnlockableEmote");
			if ((object)EmoteType == null)
			{
				Logger.Debug("EmoteType not found");
				return;
			}
			AudioClipNameGetter = EmoteType.GetProperty("audioClipName", BindingFlags.Instance | BindingFlags.Public)?.GetMethod;
			if ((object)AudioClipNameGetter == null)
			{
				Logger.Debug("AudioClipNameGetter not found");
				return;
			}
			IsBoomboxAudioField = EmoteType.GetField("_isBoomboxAudio", BindingFlags.Instance | BindingFlags.NonPublic);
			SetAudio();
		}

		private static AudioType GetAudioTypeFromExtension(string filePath)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			switch (Path.GetExtension(filePath).ToLower())
			{
			case ".wav":
				return (AudioType)20;
			case ".mp3":
				return (AudioType)13;
			case ".ogg":
				return (AudioType)14;
			case ".aiff":
			case ".aif":
				return (AudioType)2;
			default:
				return (AudioType)0;
			}
		}

		private static void SetAudio()
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Invalid comparison between Unknown and I4
			Logger.Debug("Setting audio clips");
			if (DmcaAudioClips == null)
			{
				Logger.Debug("DmcaAudioClips not found, not running SetAudio");
				return;
			}
			string value = Config.EmoteAudioOverrides.Value;
			string[] array = value.Split(new char[1] { '|' });
			if (array.Length == 0)
			{
				Logger.Warning("Config couldn't be parsed. Value: [" + value + "]");
			}
			string[] array2 = array;
			foreach (string text in array2)
			{
				string[] array3 = text.Split(new char[1] { ',' });
				if (array3.Length != 2)
				{
					Logger.Warning("Cannot parse " + text);
					continue;
				}
				string text2 = ((Environment.OSVersion.Platform != PlatformID.Win32NT) ? ("file://" + PathManager.PluginDirectory + "/" + array3[1]) : ("file:///" + (PathManager.PluginDirectory + "/" + array3[1]).Replace('\\', '/')));
				Logger.Debug("Sending web request to " + text2);
				UnityWebRequest audioClip;
				UnityWebRequestAsyncOperation val;
				try
				{
					audioClip = UnityWebRequestMultimedia.GetAudioClip(text2, GetAudioTypeFromExtension(text2));
					val = audioClip.SendWebRequest();
				}
				catch (Exception ex)
				{
					Logger.Error(ex.ToString());
					break;
				}
				Logger.Debug("Entering while loop");
				while (!((AsyncOperation)val).isDone)
				{
					Logger.Debug("Waiting...");
					Thread.Sleep(100);
				}
				Logger.Debug("Done waiting");
				try
				{
					if ((int)audioClip.result == 1)
					{
						AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
						((Object)content).name = array3[0];
						DmcaAudioClips[array3[0]] = content;
						Logger.Debug("Successfully set audio " + ((Object)content).name + " to " + text2 + ".");
						if (AllEmotes == null || (object)AudioClipNameGetter == null || (object)IsBoomboxAudioField == null)
						{
							continue;
						}
						foreach (object allEmote in AllEmotes)
						{
							if (!((string)AudioClipNameGetter.Invoke(allEmote, null) != ((Object)content).name))
							{
								IsBoomboxAudioField.SetValue(allEmote, false);
							}
						}
						continue;
					}
					Logger.Error("Failed to load audio clip: " + audioClip.error);
				}
				catch (Exception ex2)
				{
					Logger.Error(ex2.ToString());
				}
			}
		}
	}
}