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 CurrentEntries { get; } = new Dictionary(); public static ConfigEntry Debug { get; private set; } = null; public static ConfigEntry EmoteAudioOverrides { get; private set; } = null; public static ConfigEntry VehicleSpeedModifier { get; private set; } = null; public static ConfigEntry 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 AddConfigEntry(string section, string name, string description, T defaultValue) { ConfigEntry val = File.Bind(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 Transpiler(IEnumerable 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 Transpiler(IEnumerable 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 x) => CodeInstructionExtensions.LoadsConstant(x, 100L)), (string)null) }).Repeat((Action)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)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 Transpiler(IEnumerable 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)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)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? 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; 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()); } } } } }