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 MCZombieLegacyCompat v1.1.0
patchers/MCZombieLegacyCompat/MCZombieLegacyCompat.Patcher.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using Mono.Cecil; using Mono.Cecil.Cil; using Mono.Collections.Generic; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MCZombieLegacyCompat.Patcher")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("MCZombieLegacyCompat.Patcher")] [assembly: AssemblyTitle("MCZombieLegacyCompat.Patcher")] [assembly: AssemblyVersion("1.1.0.0")] namespace CaptainTeam.MCZombieCompat; internal sealed class LegacyRewriter { internal const string MarkerTypeName = "CaptainTeam.MCZombieCompat.PatchedMarker"; private const string ShimTypeName = "CaptainTeam.MCZombieCompat.Shims.PaintedUtilsShims"; private readonly ModuleDefinition _module; private readonly ModuleDefinition _shims; private readonly Action<string> _log; private readonly Dictionary<string, MethodDefinition> _copiedShims = new Dictionary<string, MethodDefinition>(); private TypeDefinition _shimHost; internal LegacyRewriter(ModuleDefinition module, ModuleDefinition shims, Action<string> log) { _module = module; _shims = shims; _log = log; } internal static bool IsPatched(ModuleDefinition module) { return ((IEnumerable<TypeDefinition>)module.Types).Any((TypeDefinition t) => ((MemberReference)t).FullName == "CaptainTeam.MCZombieCompat.PatchedMarker"); } internal int Rewrite() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown int num = 0; foreach (TypeDefinition item in _module.GetTypes().ToList()) { foreach (MethodDefinition item2 in ((IEnumerable<MethodDefinition>)item.Methods).Where((MethodDefinition m) => m.HasBody).ToList()) { num += RewriteMethod(item2); } } if (num > 0) { _module.Types.Add(new TypeDefinition("CaptainTeam.MCZombieCompat", "PatchedMarker", (TypeAttributes)384, _module.TypeSystem.Object)); } return num; } private int RewriteMethod(MethodDefinition method) { int num = 0; ILProcessor iLProcessor = method.Body.GetILProcessor(); foreach (Instruction item in ((IEnumerable<Instruction>)method.Body.Instructions).ToList()) { object operand = item.Operand; MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null); if (val != null && !(val is MethodDefinition) && !Resolves((MemberReference)(object)val)) { if (TryRewriteCall(method, iLProcessor, item, val)) { num++; _log(" " + ((MemberReference)method.DeclaringType).Name + "::" + ((MemberReference)method).Name + " -> " + ((MemberReference)((MemberReference)val).DeclaringType).Name + "." + ((MemberReference)val).Name); } continue; } object operand2 = item.Operand; FieldReference val2 = (FieldReference)((operand2 is FieldReference) ? operand2 : null); if (val2 != null && !(val2 is FieldDefinition) && !Resolves((MemberReference)(object)val2) && TryRewriteField(iLProcessor, item, val2)) { num++; _log(" " + ((MemberReference)method.DeclaringType).Name + "::" + ((MemberReference)method).Name + " -> " + ((MemberReference)((MemberReference)val2).DeclaringType).Name + "." + ((MemberReference)val2).Name); } } return num; } private bool TryRewriteCall(MethodDefinition method, ILProcessor il, Instruction ins, MethodReference mref) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) string fullName = ((MemberReference)((MemberReference)mref).DeclaringType).FullName; string[] array = ((IEnumerable<ParameterDefinition>)mref.Parameters).Select((ParameterDefinition p) => ((MemberReference)((ParameterReference)p).ParameterType).FullName).ToArray(); if (fullName == "EnemyNavMeshAgent" && ((MemberReference)mref).Name == "Warp" && array.Length == 1) { MethodReference val = FindMethod(((MemberReference)mref).DeclaringType, "Warp", "UnityEngine.Vector3", "System.Boolean"); if (val == null) { return false; } Instruction val2 = il.Create(ins.OpCode, val); ReplaceWith(il, ins, il.Create(OpCodes.Ldc_I4_0), val2); return true; } if (fullName == "PhysGrabber" && ((MemberReference)mref).Name == "ReleaseObject" && array.Length == 1 && array[0] == "System.Single") { MethodReference val3 = FindMethod(((MemberReference)mref).DeclaringType, "ReleaseObject", "System.Int32", "System.Single"); if (val3 == null) { return false; } VariableDefinition val4 = new VariableDefinition(_module.TypeSystem.Single); method.Body.Variables.Add(val4); method.Body.InitLocals = true; ReplaceWith(il, ins, il.Create(OpCodes.Stloc, val4), il.Create(OpCodes.Ldc_I4_M1), il.Create(OpCodes.Ldloc, val4), il.Create(ins.OpCode, val3)); return true; } if (fullName == "REPOLib.Modules.NetworkPrefabs" && ((MemberReference)mref).Name == "SpawnNetworkPrefab" && array.Length == 5 && array[0] == "System.String") { return RedirectToShim(il, ins, "SpawnNetworkPrefabById"); } if (fullName == "REPOLib.Modules.Valuables" && ((MemberReference)mref).Name == "SpawnValuable" && array.Length == 3 && array[0] == "ValuableObject") { return RedirectToShim(il, ins, "SpawnValuableObject"); } if (fullName == "REPOLib.Modules.NetworkPrefabs" && ((MemberReference)mref).Name == "RegisterNetworkPrefab" && array.Length == 1 && ((MemberReference)mref.ReturnType).FullName == "System.Void") { return RedirectToShim(il, ins, "RegisterNetworkPrefab"); } return false; } private bool TryRewriteField(ILProcessor il, Instruction ins, FieldReference fref) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) if (((MemberReference)((MemberReference)fref).DeclaringType).FullName == "PlayerAvatar" && ((MemberReference)fref).Name == "localCameraTransform" && ins.OpCode == OpCodes.Ldfld) { TypeDefinition obj = ((MemberReference)fref).DeclaringType.Resolve(); FieldDefinition val = ((obj != null) ? ((IEnumerable<FieldDefinition>)obj.Fields).FirstOrDefault((Func<FieldDefinition, bool>)((FieldDefinition f) => ((MemberReference)f).Name == "localCamera")) : null); if (val == null) { return false; } MethodDefinition val2 = FindInHierarchy(((FieldReference)val).FieldType.Resolve(), "UnityEngine.Component", "get_transform"); if (val2 == null) { return false; } ReplaceWith(il, ins, il.Create(OpCodes.Ldfld, _module.ImportReference((FieldReference)(object)val)), il.Create(OpCodes.Callvirt, _module.ImportReference((MethodReference)(object)val2))); return true; } return false; } private static void ReplaceWith(ILProcessor il, Instruction ins, params Instruction[] replacement) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) ins.OpCode = replacement[0].OpCode; ins.Operand = replacement[0].Operand; Instruction val = ins; for (int i = 1; i < replacement.Length; i++) { il.InsertAfter(val, replacement[i]); val = replacement[i]; } } private bool RedirectToShim(ILProcessor il, Instruction ins, string shimName) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) MethodDefinition orCopyShim = GetOrCopyShim(shimName); if (orCopyShim == null) { return false; } ins.OpCode = OpCodes.Call; ins.Operand = orCopyShim; return true; } private MethodReference FindMethod(TypeReference owner, string name, params string[] parameterTypes) { TypeDefinition obj = owner.Resolve(); MethodDefinition val = ((obj != null) ? ((IEnumerable<MethodDefinition>)obj.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition x) => ((MemberReference)x).Name == name && ((IEnumerable<ParameterDefinition>)((MethodReference)x).Parameters).Select((ParameterDefinition p) => ((MemberReference)((ParameterReference)p).ParameterType).FullName).SequenceEqual(parameterTypes))) : null); if (val != null) { return _module.ImportReference((MethodReference)(object)val); } return null; } private static MethodDefinition FindInHierarchy(TypeDefinition type, string declaringType, string name) { while (type != null) { if (((MemberReference)type).FullName == declaringType) { return ((IEnumerable<MethodDefinition>)type.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == name && !((MethodReference)m).HasParameters)); } TypeReference baseType = type.BaseType; type = ((baseType != null) ? baseType.Resolve() : null); } return null; } private static bool Resolves(MemberReference member) { try { MethodReference val = (MethodReference)(object)((member is MethodReference) ? member : null); if (val == null) { FieldReference val2 = (FieldReference)(object)((member is FieldReference) ? member : null); if (val2 != null) { return val2.Resolve() != null; } return true; } return val.Resolve() != null; } catch (Exception) { return false; } } private MethodDefinition GetOrCopyShim(string name) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown if (_copiedShims.TryGetValue(name, out var value)) { return value; } TypeDefinition type = _shims.GetType("CaptainTeam.MCZombieCompat.Shims.PaintedUtilsShims"); MethodDefinition val = ((type != null) ? ((IEnumerable<MethodDefinition>)type.Methods).FirstOrDefault((Func<MethodDefinition, bool>)((MethodDefinition m) => ((MemberReference)m).Name == name)) : null); if (val == null) { return null; } if (_shimHost == null) { _shimHost = new TypeDefinition("CaptainTeam.MCZombieCompat", "PaintedUtilsShims", (TypeAttributes)1048961, _module.TypeSystem.Object); _module.Types.Add(_shimHost); } MethodDefinition val2 = CopyMethod(val); _shimHost.Methods.Add(val2); _copiedShims[name] = val2; return val2; } private MethodDefinition CopyMethod(MethodDefinition src) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_006e: Expected O, but got Unknown //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_0413: Expected O, but got Unknown MethodDefinition val = new MethodDefinition(((MemberReference)src).Name, src.Attributes, _module.ImportReference(((MethodReference)src).ReturnType)); Dictionary<ParameterDefinition, ParameterDefinition> dictionary = new Dictionary<ParameterDefinition, ParameterDefinition>(); Enumerator<ParameterDefinition> enumerator = ((MethodReference)src).Parameters.GetEnumerator(); try { while (enumerator.MoveNext()) { ParameterDefinition current = enumerator.Current; ParameterDefinition val2 = new ParameterDefinition(((ParameterReference)current).Name, current.Attributes, _module.ImportReference(((ParameterReference)current).ParameterType)); ((MethodReference)val).Parameters.Add(val2); dictionary[current] = val2; } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } Dictionary<VariableDefinition, VariableDefinition> dictionary2 = new Dictionary<VariableDefinition, VariableDefinition>(); Enumerator<VariableDefinition> enumerator2 = src.Body.Variables.GetEnumerator(); try { while (enumerator2.MoveNext()) { VariableDefinition current2 = enumerator2.Current; VariableDefinition val3 = new VariableDefinition(_module.ImportReference(((VariableReference)current2).VariableType)); val.Body.Variables.Add(val3); dictionary2[current2] = val3; } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } val.Body.InitLocals = src.Body.InitLocals; val.Body.MaxStackSize = src.Body.MaxStackSize; Dictionary<Instruction, Instruction> insMap = new Dictionary<Instruction, Instruction>(); Enumerator<Instruction> enumerator3 = src.Body.Instructions.GetEnumerator(); try { while (enumerator3.MoveNext()) { Instruction current3 = enumerator3.Current; Instruction val4 = Instruction.Create(OpCodes.Nop); val4.OpCode = current3.OpCode; insMap[current3] = val4; val.Body.Instructions.Add(val4); } } finally { ((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose(); } enumerator3 = src.Body.Instructions.GetEnumerator(); try { while (enumerator3.MoveNext()) { Instruction current4 = enumerator3.Current; Instruction val5 = insMap[current4]; object operand = current4.Operand; Instruction val6 = (Instruction)((operand is Instruction) ? operand : null); if (val6 == null) { if (!(operand is Instruction[] source)) { VariableDefinition val7 = (VariableDefinition)((operand is VariableDefinition) ? operand : null); if (val7 == null) { ParameterDefinition val8 = (ParameterDefinition)((operand is ParameterDefinition) ? operand : null); if (val8 == null) { MethodReference val9 = (MethodReference)((operand is MethodReference) ? operand : null); if (val9 == null) { FieldReference val10 = (FieldReference)((operand is FieldReference) ? operand : null); if (val10 == null) { TypeReference val11 = (TypeReference)((operand is TypeReference) ? operand : null); if (val11 != null) { val5.Operand = _module.ImportReference(val11); } else { val5.Operand = current4.Operand; } } else { val5.Operand = _module.ImportReference(val10); } } else { val5.Operand = _module.ImportReference(val9); } } else { val5.Operand = dictionary[val8]; } } else { val5.Operand = dictionary2[val7]; } } else { val5.Operand = source.Select((Instruction t) => insMap[t]).ToArray(); } } else { val5.Operand = insMap[val6]; } } } finally { ((IDisposable)enumerator3/*cast due to .constrained prefix*/).Dispose(); } Enumerator<ExceptionHandler> enumerator4 = src.Body.ExceptionHandlers.GetEnumerator(); try { while (enumerator4.MoveNext()) { ExceptionHandler current5 = enumerator4.Current; val.Body.ExceptionHandlers.Add(new ExceptionHandler(current5.HandlerType) { TryStart = Map(insMap, current5.TryStart), TryEnd = Map(insMap, current5.TryEnd), HandlerStart = Map(insMap, current5.HandlerStart), HandlerEnd = Map(insMap, current5.HandlerEnd), FilterStart = Map(insMap, current5.FilterStart), CatchType = ((current5.CatchType == null) ? null : _module.ImportReference(current5.CatchType)) }); } return val; } finally { ((IDisposable)enumerator4/*cast due to .constrained prefix*/).Dispose(); } } private static Instruction Map(Dictionary<Instruction, Instruction> map, Instruction i) { if (i != null) { return map[i]; } return null; } } public static class Patcher { private static readonly string[] Targets = new string[2] { "MCZombieMod.dll", "PaintedUtils.dll" }; private static readonly ManualLogSource Log = Logger.CreateLogSource("MCZombieLegacyCompat.Patcher"); public static IEnumerable<string> TargetDLLs => new string[0]; public static void Patch(AssemblyDefinition assembly) { } public static void Initialize() { try { ModuleDefinition shims = LoadShims(); string[] targets = Targets; foreach (string searchPattern in targets) { string[] files = Directory.GetFiles(Paths.PluginPath, searchPattern, SearchOption.AllDirectories); for (int j = 0; j < files.Length; j++) { PatchFile(files[j], shims); } } } catch (Exception ex) { Log.LogError((object)("Patcher failed: " + ex)); } } private static void PatchFile(string path, ModuleDefinition shims) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown try { DefaultAssemblyResolver val = CreateResolver(); try { using MemoryStream memoryStream = new MemoryStream(File.ReadAllBytes(path)); ModuleDefinition val2 = ModuleDefinition.ReadModule((Stream)memoryStream, new ReaderParameters { AssemblyResolver = (IAssemblyResolver)(object)val, ReadingMode = (ReadingMode)1 }); try { if (LegacyRewriter.IsPatched(val2)) { Log.LogInfo((object)(Path.GetFileName(path) + ": already patched.")); return; } List<string> list = new List<string>(); int num = new LegacyRewriter(val2, shims, list.Add).Rewrite(); if (num == 0) { Log.LogInfo((object)(Path.GetFileName(path) + ": no legacy call sites found, left untouched.")); return; } MemoryStream memoryStream2 = new MemoryStream(); val2.Write((Stream)memoryStream2); string text = path + ".ctbak"; if (!File.Exists(text)) { File.Copy(path, text); } File.WriteAllBytes(path, memoryStream2.ToArray()); Log.LogInfo((object)(Path.GetFileName(path) + ": " + num + " legacy call site(s) rewritten (backup: " + Path.GetFileName(text) + ").")); foreach (string item in list) { Log.LogDebug((object)item); } } finally { ((IDisposable)val2)?.Dispose(); } } finally { ((IDisposable)val)?.Dispose(); } } catch (Exception ex) { Log.LogError((object)(Path.GetFileName(path) + ": rewrite failed, file left untouched: " + ex)); } } private static DefaultAssemblyResolver CreateResolver() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown DefaultAssemblyResolver val = new DefaultAssemblyResolver(); ((BaseAssemblyResolver)val).AddSearchDirectory(Paths.ManagedPath); ((BaseAssemblyResolver)val).AddSearchDirectory(Paths.BepInExAssemblyDirectory); ((BaseAssemblyResolver)val).AddSearchDirectory(Paths.PluginPath); string[] directories = Directory.GetDirectories(Paths.PluginPath, "*", SearchOption.AllDirectories); foreach (string text in directories) { ((BaseAssemblyResolver)val).AddSearchDirectory(text); } return val; } private static ModuleDefinition LoadShims() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown using Stream stream = typeof(Patcher).Assembly.GetManifestResourceStream("MCZombieCompatShims.dll"); MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); memoryStream.Position = 0L; return ModuleDefinition.ReadModule((Stream)memoryStream, new ReaderParameters { ReadingMode = (ReadingMode)1 }); } }
plugins/MCZombieLegacyCompat/MCZombieFix.dll
Decompiled a week 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.Serialization; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MCZombieFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("MCZombieFix")] [assembly: AssemblyTitle("MCZombieFix")] [assembly: AssemblyVersion("1.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 MCZombieFix { internal static class EnemyRegistration { internal static object LastMCZombieSetup { get; private set; } internal static void RegisterEnemy(object setup) { if (setup != null) { LastMCZombieSetup = setup; Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "REPOLib", StringComparison.OrdinalIgnoreCase)); if (assembly == null) { throw new InvalidOperationException("REPOLib assembly not loaded."); } Type enemyContentType = assembly.GetType("REPOLib.Objects.Sdk.EnemyContent", throwOnError: false); Type type = assembly.GetType("REPOLib.Modules.Enemies", throwOnError: false); if (enemyContentType == null || type == null) { throw new MissingMemberException("REPOLib 4 EnemyContent/Enemies type not found."); } object obj = CreateScriptableObject(enemyContentType); if (obj == null) { throw new InvalidOperationException("Could not create EnemyContent."); } FieldInfo? field = enemyContentType.GetField("_setup", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = enemyContentType.GetField("_spawnObjects", BindingFlags.Instance | BindingFlags.NonPublic); if (field == null || field2 == null) { throw new MissingFieldException("EnemyContent._setup/_spawnObjects not found."); } List<object> list = FindMCZombiePrefabs(); if (list.Count == 0) { throw new InvalidOperationException("Prefab 'Enemy - MCZombie' not found."); } field.SetValue(obj, setup); AssignSpawnObjects(field2, obj, list); MethodInfo? methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(delegate(MethodInfo m) { ParameterInfo[] parameters = m.GetParameters(); return m.Name == "RegisterEnemy" && parameters.Length == 1 && parameters[0].ParameterType == enemyContentType; }); if (methodInfo == null) { throw new MissingMethodException("REPOLib Enemies.RegisterEnemy(EnemyContent) not found."); } methodInfo.Invoke(null, new object[1] { obj }); Plugin.Log.LogInfo((object)"MCZombie registered through REPOLib 4."); } } private static object CreateScriptableObject(Type contentType) { return (FindLoadedType("UnityEngine.ScriptableObject")?.GetMethod("CreateInstance", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(Type) }, null))?.Invoke(null, new object[1] { contentType }); } private static List<object> FindMCZombiePrefabs() { List<object> list = new List<object>(); Type type = FindLoadedType("UnityEngine.AssetBundle"); Type type2 = FindLoadedType("UnityEngine.GameObject"); if (type == null || type2 == null) { return list; } if (!(type.GetMethod("GetAllLoadedAssetBundles", BindingFlags.Static | BindingFlags.Public)?.Invoke(null, null) is IEnumerable enumerable)) { return list; } MethodInfo methodInfo = type.GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "LoadAllAssets" && m.IsGenericMethodDefinition && m.GetParameters().Length == 0); if (methodInfo == null) { return list; } MethodInfo methodInfo2 = methodInfo.MakeGenericMethod(type2); PropertyInfo property = type2.GetProperty("name", BindingFlags.Instance | BindingFlags.Public); foreach (object item in enumerable) { if (item == null) { continue; } Array array; try { array = methodInfo2.Invoke(item, null) as Array; } catch { continue; } if (array == null) { continue; } foreach (object item2 in array) { if (item2 != null && ((property?.GetValue(item2, null) as string) ?? string.Empty).IndexOf("Enemy - MCZombie", StringComparison.OrdinalIgnoreCase) >= 0 && !list.Contains(item2)) { list.Add(item2); } } } return list; } private static void AssignSpawnObjects(FieldInfo field, object target, List<object> prefabs) { Type fieldType = field.FieldType; if (!fieldType.IsGenericType || fieldType.GetGenericTypeDefinition() != typeof(List<>)) { throw new InvalidOperationException("Unsupported _spawnObjects type: " + fieldType.FullName); } Type type = fieldType.GetGenericArguments()[0]; IList list = (IList)Activator.CreateInstance(fieldType); foreach (object prefab in prefabs) { if (prefab != null && type.IsInstanceOfType(prefab)) { list.Add(prefab); } } if (list.Count == 0) { throw new InvalidOperationException("No MCZombie prefab compatible with _spawnObjects."); } field.SetValue(target, list); } private static Type FindLoadedType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType(fullName, throwOnError: false); if (type != null) { return type; } } return null; } } internal sealed class FleshSickness : MonoBehaviour { private const byte PukeEventCode = 173; private const float SicknessDuration = 45f; private const float PukeDuration = 3f; private static FleshSickness _instance; private static GameObject _pukeTemplate; private static bool _templateMissingLogged; private static readonly HashSet<int> EatenFlesh = new HashSet<int>(); private float _sickUntil = -1f; private float _nextPukeAt = -1f; private bool _eventSubscribed; internal static void Install(Harmony harmony, GameObject host) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_007d: Expected O, but got Unknown _instance = host.AddComponent<FleshSickness>(); Type type = AccessTools.TypeByName("MCZombieMod.Items.RottenFleshValuable"); MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "EatFlesh", (Type[])null, (Type[])null) : null); if (methodInfo == null) { Plugin.Log.LogWarning((object)"Rotten Flesh sickness unavailable: RottenFleshValuable.EatFlesh not found."); return; } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(FleshSickness), "EatFleshPrefix", (Type[])null), new HarmonyMethod(typeof(FleshSickness), "EatFleshPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"Rotten Flesh eating guard and sickness effect installed."); } private static bool EatFleshPrefix(MonoBehaviour __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown if ((Object)__instance == (Object)null) { return false; } return EatenFlesh.Add(((Object)__instance).GetInstanceID()); } private static void EatFleshPostfix(GameObject player) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0061: Expected O, but got Unknown if (Plugin.FleshSicknessEffect != null && Plugin.FleshSicknessEffect.Value && !((Object)_instance == (Object)null)) { PlayerAvatar val = (((Object)player != (Object)null) ? player.GetComponent<PlayerAvatar>() : null); if (!((Object)val == (Object)null) && !((Object)val != (Object)PlayerAvatar.instance)) { _instance.StartSickness(); } } } private void StartSickness() { bool num = Time.time < _sickUntil; _sickUntil = Time.time + 45f; if (!num) { _nextPukeAt = Time.time + Random.Range(4f, 7f); Plugin.Log.LogInfo((object)("Rotten Flesh: local player is sick for " + 45f + "s.")); } } private void Update() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown if (!_eventSubscribed && (Object)GameManager.instance != (Object)null && SemiFunc.IsMultiplayer() && (Object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated) { PhotonNetwork.NetworkingClient.EventReceived += OnEvent; _eventSubscribed = true; } if (_sickUntil < 0f) { return; } if (Time.time >= _sickUntil) { _sickUntil = -1f; _nextPukeAt = -1f; } else { if (!(_nextPukeAt > 0f) || !(Time.time >= _nextPukeAt)) { return; } _nextPukeAt = Time.time + Random.Range(10f, 20f); PlayerAvatar instance = PlayerAvatar.instance; if (!((Object)instance == (Object)null)) { PlayPuke(instance); if (SemiFunc.IsMultiplayer() && (Object)(object)instance.photonView != (Object)null) { PhotonNetwork.RaiseEvent((byte)173, (object)instance.photonView.ViewID, new RaiseEventOptions { Receivers = (ReceiverGroup)0 }, SendOptions.SendReliable); } } } } private static void OnEvent(EventData data) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown if (data.Code == 173 && data.CustomData is int num && !((Object)_instance == (Object)null) && (Plugin.FleshSicknessEffect == null || Plugin.FleshSicknessEffect.Value)) { PhotonView val = PhotonView.Find(num); PlayerAvatar val2 = (((Object)val != (Object)null) ? ((Component)val).GetComponent<PlayerAvatar>() : null); if ((Object)val2 != (Object)null) { _instance.PlayPuke(val2); } } } private void PlayPuke(PlayerAvatar avatar) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0018: 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_002c: Expected O, but got Unknown //IL_002c: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown GameObject pukeTemplate = GetPukeTemplate(); if ((Object)pukeTemplate == (Object)null) { return; } Transform val = null; if ((Object)avatar == (Object)PlayerAvatar.instance && (Object)avatar.localCamera != (Object)null) { val = ((Component)avatar.localCamera).transform; } else if ((Object)avatar.playerAvatarVisuals != (Object)null) { val = avatar.playerAvatarVisuals.headLookAtTransform ?? ((Component)avatar.playerAvatarVisuals).transform; } if (!((Object)val == (Object)null)) { GameObject val2 = Object.Instantiate<GameObject>(pukeTemplate, val); val2.SetActive(true); SemiPuke componentInChildren = val2.GetComponentInChildren<SemiPuke>(true); if ((Object)componentInChildren == (Object)null) { Object.Destroy((Object)(object)val2); } else { ((MonoBehaviour)this).StartCoroutine(PukeRoutine(val2, componentInChildren, val)); } } } private static IEnumerator PukeRoutine(GameObject effect, SemiPuke puke, Transform mouth) { float timer = 0f; while (timer < 3f && (Object)effect != (Object)null && (Object)mouth != (Object)null) { Vector3 val = mouth.position + mouth.forward * 0.3f - mouth.up * 0.2f; puke.PukeActive(val, mouth.rotation); timer += Time.deltaTime; yield return null; } if ((Object)effect != (Object)null) { Object.Destroy((Object)(object)effect, 2f); } } private static GameObject GetPukeTemplate() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) //IL_005d: Expected O, but got Unknown if ((Object)_pukeTemplate != (Object)null) { return _pukeTemplate; } SemiPuke[] array = Resources.FindObjectsOfTypeAll<SemiPuke>(); foreach (SemiPuke val in array) { if ((Object)val == (Object)null) { continue; } Scene scene = ((Component)val).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { Transform baseParticlesTransform = val.BaseParticlesTransform; if (!((Object)baseParticlesTransform != (Object)null) || baseParticlesTransform.IsChildOf(((Component)val).transform)) { _pukeTemplate = ((Component)val).gameObject; Plugin.Log.LogInfo((object)("Rotten Flesh: puke effect template found: " + ((Object)_pukeTemplate).name)); return _pukeTemplate; } } } if (!_templateMissingLogged) { _templateMissingLogged = true; Plugin.Log.LogWarning((object)"Rotten Flesh: no SemiPuke template found; sickness has no visual effect."); } return null; } } public static class LegacyCallBridge { public static void RegisterNetworkPrefabLegacyCompat(GameObject prefab) { NetworkPrefabCompat.RegisterLegacy(prefab); } public static ValuableObject GetValuableByNameCompat(string valuableName) { return ValuableCompat.GetByNameLegacy(valuableName); } public static void WarpCompat(object enemyNavMeshAgent, Vector3 position) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) if (enemyNavMeshAgent == null) { return; } try { Type type = enemyNavMeshAgent.GetType(); MethodInfo methodInfo = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(MethodInfo m) { ParameterInfo[] parameters = m.GetParameters(); return m.Name == "Warp" && parameters.Length == 1 && parameters[0].ParameterType == typeof(Vector3); }); if (methodInfo != null) { methodInfo.Invoke(enemyNavMeshAgent, new object[1] { position }); return; } Type type2 = type; while (type2 != null) { FieldInfo[] fields = type2.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if ((fieldInfo.FieldType.FullName ?? string.Empty) != "UnityEngine.AI.NavMeshAgent") { continue; } object value = fieldInfo.GetValue(enemyNavMeshAgent); if (value != null) { MethodInfo method = value.GetType().GetMethod("Warp", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(Vector3) }, null); if (!(method == null)) { method.Invoke(value, new object[1] { position }); return; } } } type2 = type2.BaseType; } Component val = (Component)((enemyNavMeshAgent is Component) ? enemyNavMeshAgent : null); if ((Object)val != (Object)null) { val.transform.position = position; } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)("MCZombie WarpCompat failed: " + ex)); } } } public static GameObject SpawnNetworkPrefabLegacy(string prefabId, Vector3 position, Quaternion rotation, byte group, object[] data) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return NetworkPrefabCompat.SpawnLegacy(prefabId, position, rotation, group, data); } public static GameObject SpawnValuableLegacy(object valuable, Vector3 position, Quaternion rotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return ValuableCompat.SpawnLegacy(valuable, position, rotation); } public static void ReleaseObjectLegacy(object physGrabber, float force, object coroutineContext) { if (physGrabber == null) { return; } try { int num = TryResolvePhotonViewIdFromEatContext(coroutineContext); if (num <= 0) { num = TryResolveGrabbedPhotonViewId(physGrabber); } if (num <= 0) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"Rotten Flesh ReleaseObject bridge: could not resolve held item PhotonView ID."); } return; } MethodInfo method = physGrabber.GetType().GetMethod("ReleaseObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(int), typeof(float) }, null); if (method == null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)"Rotten Flesh ReleaseObject bridge: current ReleaseObject(int, float) was not found."); } return; } method.Invoke(physGrabber, new object[2] { num, force }); ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)("Rotten Flesh: legacy PhysGrabber.ReleaseObject(float) adapted to ReleaseObject(viewID=" + num + ", force=" + force + ").")); } } catch (TargetInvocationException ex) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogError((object)("Rotten Flesh ReleaseObject bridge failed: " + (ex.InnerException ?? ex))); } } catch (Exception ex2) { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogError((object)("Rotten Flesh ReleaseObject bridge failed: " + ex2)); } } } private static int TryResolvePhotonViewIdFromEatContext(object coroutineContext) { if (coroutineContext == null) { return -1; } try { object obj = coroutineContext; Type type = obj.GetType(); FieldInfo field = type.GetField("<>4__this", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(obj); if (value != null) { obj = value; } } int num = TryResolvePhotonViewId(obj); if (num > 0) { return num; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { string text = fieldInfo.Name ?? string.Empty; if (text.IndexOf("this", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("flesh", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("valuable", StringComparison.OrdinalIgnoreCase) >= 0) { num = TryResolvePhotonViewId(fieldInfo.GetValue(coroutineContext)); if (num > 0) { return num; } } } } catch { } return -1; } private static int TryResolveGrabbedPhotonViewId(object physGrabber) { if (physGrabber == null) { return -1; } try { Type type = physGrabber.GetType(); while (type != null) { FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { string text = fieldInfo.Name ?? string.Empty; if (text.IndexOf("grab", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("held", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("object", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("target", StringComparison.OrdinalIgnoreCase) >= 0) { object value; try { value = fieldInfo.GetValue(physGrabber); } catch { continue; } int num = TryResolvePhotonViewId(value); if (num > 0) { return num; } } } PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.GetIndexParameters().Length != 0) { continue; } string text2 = propertyInfo.Name ?? string.Empty; if (text2.IndexOf("grab", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("held", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("object", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("target", StringComparison.OrdinalIgnoreCase) >= 0) { object value2; try { value2 = propertyInfo.GetValue(physGrabber, null); } catch { continue; } int num2 = TryResolvePhotonViewId(value2); if (num2 > 0) { return num2; } } } type = type.BaseType; } } catch { } return -1; } private static int TryResolvePhotonViewId(object value) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown if (value == null) { return -1; } try { Type type = value.GetType(); if ((type.FullName ?? string.Empty).IndexOf("PhotonView", StringComparison.OrdinalIgnoreCase) >= 0) { int num = ReadViewId(value); if (num > 0) { return num; } } string[] array = new string[3] { "photonView", "PhotonView", "_photonView" }; foreach (string name in array) { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { int num2 = ReadViewId(field.GetValue(value)); if (num2 > 0) { return num2; } } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.GetIndexParameters().Length == 0) { int num3 = ReadViewId(property.GetValue(value, null)); if (num3 > 0) { return num3; } } } Component val = (Component)((value is Component) ? value : null); GameObject val2 = (GameObject)((value is GameObject) ? value : null); if ((Object)val != (Object)null) { val2 = val.gameObject; } if ((Object)val2 != (Object)null) { Component[] components = val2.GetComponents<Component>(); foreach (Component val3 in components) { if (!((Object)val3 == (Object)null) && (((object)val3).GetType().FullName ?? string.Empty).IndexOf("PhotonView", StringComparison.OrdinalIgnoreCase) >= 0) { int num4 = ReadViewId(val3); if (num4 > 0) { return num4; } } } } array = new string[6] { "gameObject", "GameObject", "transform", "Transform", "physGrabObject", "PhysGrabObject" }; foreach (string name2 in array) { FieldInfo field2 = type.GetField(name2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 != null) { object value2 = field2.GetValue(value); if (value2 != value) { int num5 = TryResolvePhotonViewId(value2); if (num5 > 0) { return num5; } } } PropertyInfo property2 = type.GetProperty(name2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(property2 != null) || property2.GetIndexParameters().Length != 0) { continue; } object value3 = property2.GetValue(value, null); if (value3 != value) { int num6 = TryResolvePhotonViewId(value3); if (num6 > 0) { return num6; } } } } catch { } return -1; } private static int ReadViewId(object photonView) { if (photonView == null) { return -1; } try { Type type = photonView.GetType(); PropertyInfo property = type.GetProperty("ViewID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.GetIndexParameters().Length == 0) { object value = property.GetValue(photonView, null); if (value != null) { return Convert.ToInt32(value); } } FieldInfo field = type.GetField("ViewID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object value2 = field.GetValue(photonView); if (value2 != null) { return Convert.ToInt32(value2); } } } catch { } return -1; } } internal static class LegacyEnemyLookupCompat { internal static void Install(Harmony harmony) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown try { MethodInfo methodInfo = (AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "REPOLib", StringComparison.OrdinalIgnoreCase))?.GetType("REPOLib.Modules.Enemies", throwOnError: false))?.GetMethod("GetEnemyByName", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null); MethodInfo method = typeof(LegacyEnemyLookupCompat).GetMethod("GetEnemyByNamePrefix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo == null || method == null) { Plugin.Log.LogWarning((object)"MCZombie legacy GetEnemyByName bridge could not be installed."); return; } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"MCZombie legacy GetEnemyByName bridge installed."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("MCZombie legacy GetEnemyByName bridge failed: " + ex)); } } private static bool GetEnemyByNamePrefix(string name, ref EnemySetup __result) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown if (string.IsNullOrEmpty(name)) { return true; } if (name.IndexOf("Zombie", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("MCZombie", StringComparison.OrdinalIgnoreCase) < 0) { return true; } object lastMCZombieSetup = EnemyRegistration.LastMCZombieSetup; EnemySetup val = (EnemySetup)((lastMCZombieSetup is EnemySetup) ? lastMCZombieSetup : null); if ((Object)val == (Object)null) { val = TryFindModernMCZombieSetup(); } if ((Object)val == (Object)null) { return true; } __result = val; Plugin.Log.LogInfo((object)("MCZombie legacy GetEnemyByName redirected to modern EnemySetup | requested='" + name + "'.")); return false; } private static EnemySetup TryFindModernMCZombieSetup() { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown try { Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "REPOLib", StringComparison.OrdinalIgnoreCase))?.GetType("REPOLib.Modules.Enemies", throwOnError: false); if (type == null) { return null; } string[] array = new string[2] { "AllEnemies", "RegisteredEnemies" }; foreach (string name in array) { if (!(type.GetProperty(name, BindingFlags.Static | BindingFlags.Public)?.GetValue(null, null) is IEnumerable enumerable)) { continue; } foreach (object item in enumerable) { EnemySetup val = ResolveEnemySetup(item); if (!((Object)val == (Object)null)) { string text = ((Object)val).name ?? string.Empty; if (text.IndexOf("Zombie", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("MCZombie", StringComparison.OrdinalIgnoreCase) >= 0) { return val; } } } } } catch { } return null; } private static EnemySetup ResolveEnemySetup(object value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown if (value == null) { return null; } EnemySetup val = (EnemySetup)((value is EnemySetup) ? value : null); if ((Object)(object)val != (Object)null) { return val; } Type type = value.GetType(); string[] array = new string[5] { "_setup", "setup", "Setup", "enemySetup", "EnemySetup" }; foreach (string name in array) { try { object obj = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value); EnemySetup val2 = (EnemySetup)((obj is EnemySetup) ? obj : null); if ((Object)(object)val2 != (Object)null) { return val2; } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.GetIndexParameters().Length == 0) { object value2 = property.GetValue(value, null); EnemySetup val3 = (EnemySetup)((value2 is EnemySetup) ? value2 : null); if ((Object)(object)val3 != (Object)null) { return val3; } } } catch { } } return null; } } internal static class MCZombieAwakeCompat { internal static bool Prefix(object __instance) { if (__instance == null) { Plugin.Log.LogError((object)"MCZombie Awake prefix received null instance."); return false; } try { Type type = __instance.GetType(); Plugin.Log.LogInfo((object)"Running clean MCZombieMod.Awake compatibility path."); SetStaticMember(type, "Instance", __instance); SetupMCZombieConfig(__instance, type); DetachTransform(__instance); InvokeNoArgs(__instance, type, "LoadAssetBundle"); RegisterEnemiesFromLoadedBundle(__instance, type); NetworkPrefabCompat.CacheAndRegisterFromMCZombieBundle(GetAssetBundle(__instance, type)); InvokeNoArgs(__instance, type, "FixAllPrefabAudioMixerGroups", optional: true); SetupOriginalHarmony(__instance, type); InvokeNoArgs(__instance, type, "Patch", optional: true); Plugin.Log.LogInfo((object)"MCZombieMod initialized through MCZombieFix 1.1.0."); return false; } catch (Exception ex) { Plugin.Log.LogError((object)("MCZombie compatible Awake failed: " + Unwrap(ex))); return false; } } private static void SetupMCZombieConfig(object instance, Type pluginType) { Type type = pluginType.Assembly.GetType("MCZombieMod.MCZombieConfig", throwOnError: false); if (type == null) { Plugin.Log.LogWarning((object)"MCZombieConfig type not found."); return; } object configFile = FindBepInExConfigFile(instance, pluginType); ConstructorInfo[] constructors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Plugin.Log.LogInfo((object)("MCZombieConfig constructors: " + string.Join(" | ", constructors.Select(DescribeConstructor).ToArray()))); object obj = null; foreach (ConstructorInfo item in constructors.OrderBy((ConstructorInfo c) => c.GetParameters().Length)) { object[] array = BuildConstructorArguments(item.GetParameters(), instance, configFile); if (array == null) { continue; } try { obj = item.Invoke(array); if (obj != null) { break; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("MCZombieConfig constructor failed: " + DescribeConstructor(item) + " | " + Unwrap(ex).Message)); } } if (obj == null) { try { obj = FormatterServices.GetUninitializedObject(type); Plugin.Log.LogWarning((object)"MCZombieConfig created without constructor as fallback."); } catch { obj = null; } } if (obj == null) { Plugin.Log.LogWarning((object)"Could not construct MCZombieConfig."); } else if (AssignMCZombieConfig(pluginType, instance, type, obj)) { Plugin.Log.LogInfo((object)"MCZombieConfig initialized and assigned."); } else { Plugin.Log.LogWarning((object)"MCZombieConfig object created but no compatible storage member was found."); } } private static bool AssignMCZombieConfig(Type pluginType, object instance, Type configType, object mcConfig) { BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = pluginType.GetField("Config", bindingFlags); if (field != null && field.FieldType.IsAssignableFrom(configType)) { field.SetValue(null, mcConfig); Plugin.Log.LogInfo((object)("MCZombieConfig assigned to static field: " + pluginType.FullName + "." + field.Name)); return true; } PropertyInfo property = pluginType.GetProperty("Config", bindingFlags); if (property != null && property.CanWrite && property.PropertyType.IsAssignableFrom(configType)) { property.SetValue(null, mcConfig, null); Plugin.Log.LogInfo((object)("MCZombieConfig assigned to static property: " + pluginType.FullName + "." + property.Name)); return true; } FieldInfo[] fields = pluginType.GetFields(bindingFlags); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == configType || fieldInfo.FieldType.IsAssignableFrom(configType)) { fieldInfo.SetValue(null, mcConfig); Plugin.Log.LogInfo((object)("MCZombieConfig assigned by type to static field: " + pluginType.FullName + "." + fieldInfo.Name)); return true; } } PropertyInfo[] properties = pluginType.GetProperties(bindingFlags); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.CanWrite && (propertyInfo.PropertyType == configType || propertyInfo.PropertyType.IsAssignableFrom(configType))) { propertyInfo.SetValue(null, mcConfig, null); Plugin.Log.LogInfo((object)("MCZombieConfig assigned by type to static property: " + pluginType.FullName + "." + propertyInfo.Name)); return true; } } fields = pluginType.GetFields(bindingAttr); foreach (FieldInfo fieldInfo2 in fields) { if (fieldInfo2.FieldType == configType || fieldInfo2.FieldType.IsAssignableFrom(configType)) { fieldInfo2.SetValue(instance, mcConfig); Plugin.Log.LogInfo((object)("MCZombieConfig assigned by type to instance field: " + pluginType.FullName + "." + fieldInfo2.Name)); return true; } } properties = pluginType.GetProperties(bindingAttr); foreach (PropertyInfo propertyInfo2 in properties) { if (propertyInfo2.CanWrite && (propertyInfo2.PropertyType == configType || propertyInfo2.PropertyType.IsAssignableFrom(configType))) { propertyInfo2.SetValue(instance, mcConfig, null); Plugin.Log.LogInfo((object)("MCZombieConfig assigned by type to instance property: " + pluginType.FullName + "." + propertyInfo2.Name)); return true; } } string text = string.Join(" | ", (from f in pluginType.GetFields(bindingFlags | BindingFlags.Instance) select (f.IsStatic ? "static " : "instance ") + f.FieldType.FullName + " " + f.Name).ToArray()); string text2 = string.Join(" | ", (from prop in pluginType.GetProperties(bindingFlags | BindingFlags.Instance) select prop.PropertyType.FullName + " " + prop.Name + " [write=" + prop.CanWrite + "]").ToArray()); Plugin.Log.LogWarning((object)("MCZombie storage diagnostics | fields: " + text)); Plugin.Log.LogWarning((object)("MCZombie storage diagnostics | properties: " + text2)); return false; } private static object FindBepInExConfigFile(object instance, Type type) { Type type2 = type; while (type2 != null) { PropertyInfo property = type2.GetProperty("Config", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && typeof(ConfigFile).IsAssignableFrom(property.PropertyType)) { try { object value = property.GetValue(instance, null); if (value != null) { Plugin.Log.LogInfo((object)("BepInEx ConfigFile resolved from " + type2.FullName + ".Config.")); return value; } } catch { } } type2 = type2.BaseType; } return null; } private static object[] BuildConstructorArguments(ParameterInfo[] parameters, object mcZombiePlugin, object configFile) { object[] array = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameterInfo = parameters[i]; Type parameterType = parameterInfo.ParameterType; if (configFile != null && parameterType.IsInstanceOfType(configFile)) { array[i] = configFile; continue; } if (mcZombiePlugin != null && parameterType.IsInstanceOfType(mcZombiePlugin)) { array[i] = mcZombiePlugin; continue; } if (typeof(ManualLogSource).IsAssignableFrom(parameterType)) { array[i] = Plugin.Log; continue; } if (parameterInfo.HasDefaultValue) { array[i] = parameterInfo.DefaultValue; continue; } if (!parameterType.IsValueType) { array[i] = null; continue; } try { array[i] = Activator.CreateInstance(parameterType); } catch { return null; } } return array; } private static string DescribeConstructor(ConstructorInfo ctor) { return ".ctor(" + string.Join(", ", (from p in ctor.GetParameters() select p.ParameterType.FullName + " " + p.Name).ToArray()) + ")"; } private static object GetAssetBundle(object instance, Type pluginType) { return pluginType.GetField("_assetBundle", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(instance) ?? throw new InvalidOperationException("MCZombie _assetBundle is null after LoadAssetBundle()."); } private static void RegisterEnemiesFromLoadedBundle(object instance, Type pluginType) { object assetBundle = GetAssetBundle(instance, pluginType); Type type = FindLoadedType("EnemySetup"); if (type == null) { throw new MissingMemberException("EnemySetup game type not found."); } MethodInfo? methodInfo = assetBundle.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "LoadAllAssets" && m.IsGenericMethodDefinition && m.GetParameters().Length == 0); if (methodInfo == null) { throw new MissingMethodException("AssetBundle.LoadAllAssets<T>() not found."); } if (!(methodInfo.MakeGenericMethod(type).Invoke(assetBundle, null) is Array { Length: not 0 } array)) { throw new InvalidOperationException("No EnemySetup found in MCZombie asset bundle."); } int num = 0; foreach (object item in array) { if (item != null) { EnemyRegistration.RegisterEnemy(item); num++; } } Plugin.Log.LogInfo((object)("MCZombie EnemySetup assets processed: " + num)); } private static void DetachTransform(object instance) { object obj = instance.GetType().GetProperty("transform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(instance, null); obj?.GetType().GetProperty("parent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(obj, null, null); } private static void SetupOriginalHarmony(object instance, Type pluginType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown Harmony value = new Harmony("MCZombieMod.compat.original"); if (!SetMember(instance, pluginType, "Harmony", value)) { Plugin.Log.LogWarning((object)"MCZombie Harmony member not found; Patch() will still be attempted."); } } private static void InvokeNoArgs(object instance, Type type, string methodName, bool optional = false) { MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method == null) { if (!optional) { throw new MissingMethodException(type.FullName, methodName); } Plugin.Log.LogWarning((object)(methodName + "() not found; skipped.")); } else { method.Invoke(instance, null); } } private static bool SetMember(object instance, Type type, string name, object value) { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && (value == null || field.FieldType.IsInstanceOfType(value))) { field.SetValue(instance, value); return true; } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite && (value == null || property.PropertyType.IsInstanceOfType(value))) { property.SetValue(instance, value, null); return true; } return false; } private static bool SetStaticMember(Type type, string name, object value) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(null, value); return true; } PropertyInfo property = type.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(null, value, null); return true; } return false; } private static Type FindLoadedType(string simpleOrFullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type type = assembly.GetType(simpleOrFullName, throwOnError: false); if (type != null) { return type; } try { Type type2 = assembly.GetTypes().FirstOrDefault((Type t) => t.Name == simpleOrFullName); if (type2 != null) { return type2; } } catch { } } return null; } private static Exception Unwrap(Exception ex) { while (ex is TargetInvocationException && ex.InnerException != null) { ex = ex.InnerException; } return ex; } } internal static class MinecraftSpawnGuarantee { private static string _trackedLevel = string.Empty; private static float _levelSeenAt = -1f; private static bool _doneForLevel; private static object _pendingVictim; private static float _pendingAt; private const int MaxReplacementAttempts = 5; private static int _replacementAttempts; private static int _cachedZombieDifficulty = int.MinValue; internal static IEnumerator Loop() { while (true) { yield return (object)new WaitForSeconds(2f); try { if (Plugin.GuaranteeMinecraftZombie == null || !Plugin.GuaranteeMinecraftZombie.Value) { continue; } string currentLevelName = GetCurrentLevelName(); if (!IsMinecraftLevelName(currentLevelName)) { ResetLevelState(); } else { if (!IsHostOrSingleplayer() || EnemyRegistration.LastMCZombieSetup == null) { continue; } if (!string.Equals(_trackedLevel, currentLevelName, StringComparison.OrdinalIgnoreCase)) { _trackedLevel = currentLevelName; _levelSeenAt = Time.realtimeSinceStartup; _doneForLevel = false; _pendingVictim = null; _pendingAt = 0f; _replacementAttempts = 0; Plugin.Log.LogInfo((object)("Minecraft level detected: '" + currentLevelName + "'. Waiting for normal enemy spawn selection.")); } else { if (_doneForLevel || _levelSeenAt < 0f || Time.realtimeSinceStartup - _levelSeenAt < 10f) { continue; } int num = CountActiveMCZombies(); if (num > 0) { if (_pendingVictim != null) { string enemyName = GetEnemyName(_pendingVictim); RemoveEnemyFromDirector(_pendingVictim); DestroyEnemyNetworkSafe(_pendingVictim); Plugin.Log.LogInfo((object)("MCZombie LIVE QUOTA REPLACE complete | replaced='" + enemyName + "' | zombieCount=" + num + " | level='" + currentLevelName + "'")); } else { Plugin.Log.LogInfo((object)("MCZombie LIVE QUOTA OK | zombie already active naturally | count=" + num + " | level='" + currentLevelName + "'")); } _pendingVictim = null; _doneForLevel = true; } else if (_pendingVictim != null) { if (Time.realtimeSinceStartup - _pendingAt > 6f) { Plugin.Log.LogWarning((object)"MCZombie LIVE QUOTA: spawned zombie was not confirmed after 6s; original enemy kept."); _pendingVictim = null; _pendingAt = 0f; } } else if (++_replacementAttempts > 5) { _doneForLevel = true; Plugin.Log.LogWarning((object)("MCZombie LIVE QUOTA: no replacement after " + 5 + " attempts; giving up for '" + currentLevelName + "'.")); } else { BeginReplacement(currentLevelName); } } continue; } } catch (Exception ex) { Plugin.Log.LogError((object)("MCZombie Minecraft quota replacement failed: " + Unwrap(ex))); } } } private static void BeginReplacement(string level) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) if (EnemyRegistration.LastMCZombieSetup == null) { return; } if (!TryGetZombieDifficulty(out var difficulty)) { Plugin.Log.LogWarning((object)"MCZombie LIVE QUOTA: zombie difficulty unavailable; waiting."); return; } Type type = FindLoadedType("EnemyParent"); if (type == null) { return; } Object[] array = Object.FindObjectsOfType(type); if (array == null || array.Length == 0) { return; } Transform val = FindAnyPlayerTransform(); object obj = null; float num = -1f; Object[] array2 = array; foreach (Object val2 in array2) { Component val3 = (Component)((val2 is Component) ? val2 : null); if (!((Object)val3 == (Object)null) && !((Object)val3.gameObject == (Object)null) && val3.gameObject.activeInHierarchy && !IsZombieName(GetEnemyName(val2)) && !IsZombieName(((Object)val3).name) && !IsZombieName(((Object)val3.gameObject).name) && TryReadInt(val2, "difficulty", out var value) && value == difficulty) { float num2 = (((Object)val != (Object)null) ? Vector3.Distance(val.position, val3.transform.position) : 0f); if (obj == null || num2 > num) { obj = val2; num = num2; } } } if (obj == null) { Plugin.Log.LogWarning((object)("MCZombie LIVE QUOTA: no active enemy of zombie tier " + difficulty + " available to replace without changing the tier quota.")); return; } Component val4 = (Component)((obj is Component) ? obj : null); if (!((Object)val4 == (Object)null)) { Vector3 val5 = SnapToLevelPoint(val4.transform.position); Quaternion rotation = val4.transform.rotation; string enemyName = GetEnemyName(obj); if (!SpawnMCZombie(val5, rotation)) { Plugin.Log.LogWarning((object)"MCZombie LIVE QUOTA: modern zombie spawn failed; original enemy kept."); return; } _pendingVictim = obj; _pendingAt = Time.realtimeSinceStartup; Plugin.Log.LogInfo((object)("MCZombie LIVE QUOTA REPLACE pending | replace='" + enemyName + "' | tier=" + difficulty + " | spawnAt=" + Vec(val5) + " | level='" + level + "'")); } } private static bool SpawnMCZombie(Vector3 position, Quaternion rotation) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) try { object setup = EnemyRegistration.LastMCZombieSetup; if (setup == null) { return false; } Type type = FindAssembly("REPOLib")?.GetType("REPOLib.Modules.Enemies", throwOnError: false); if (type == null) { return false; } MethodInfo methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(delegate(MethodInfo m) { if (m.Name != "SpawnEnemy") { return false; } ParameterInfo[] parameters = m.GetParameters(); return parameters.Length == 4 && parameters[0].ParameterType.IsInstanceOfType(setup) && parameters[1].ParameterType == typeof(Vector3) && parameters[2].ParameterType == typeof(Quaternion) && parameters[3].ParameterType == typeof(bool); }); if (methodInfo == null) { Plugin.Log.LogWarning((object)"REPOLib Enemies.SpawnEnemy(EnemySetup, Vector3, Quaternion, bool) not found."); return false; } object obj = methodInfo.Invoke(null, new object[4] { setup, position, rotation, false }); if (!(obj is IEnumerable enumerable)) { return obj != null; } foreach (object item in enumerable) { if (item != null) { return true; } } return false; } catch (Exception ex) { Plugin.Log.LogError((object)("MCZombie modern spawn failed: " + Unwrap(ex))); return false; } } private static bool TryGetZombieDifficulty(out int difficulty) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown difficulty = -1; if (_cachedZombieDifficulty != int.MinValue) { difficulty = _cachedZombieDifficulty; return true; } Type type = FindLoadedType("EnemyParent"); if (type == null) { return false; } GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>(); if (array == null) { return false; } GameObject[] array2 = array; foreach (GameObject val in array2) { if ((Object)val == (Object)null || string.IsNullOrEmpty(((Object)val).name) || ((Object)val).name.IndexOf("Enemy - MCZombie", StringComparison.OrdinalIgnoreCase) < 0) { continue; } Component[] componentsInChildren = val.GetComponentsInChildren(type, true); if (componentsInChildren == null) { continue; } Component[] array3 = componentsInChildren; foreach (Component val2 in array3) { if ((Object)val2 != (Object)null && TryReadInt(val2, "difficulty", out difficulty)) { _cachedZombieDifficulty = difficulty; return true; } } } return false; } private static int CountActiveMCZombies() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown Type type = FindLoadedType("EnemyParent"); if (type == null) { return 0; } Object[] array = Object.FindObjectsOfType(type); if (array == null) { return 0; } int num = 0; Object[] array2 = array; foreach (Object val in array2) { Component val2 = (Component)((val is Component) ? val : null); if (!((Object)val2 == (Object)null) && !((Object)val2.gameObject == (Object)null) && val2.gameObject.activeInHierarchy && (IsZombieName(GetEnemyName(val)) || IsZombieName(((Object)val2).name) || IsZombieName(((Object)val2.gameObject).name))) { num++; } } return num; } private static bool IsZombieName(string value) { if (string.IsNullOrEmpty(value)) { return false; } if (value.IndexOf("MCZombie", StringComparison.OrdinalIgnoreCase) < 0 && value.IndexOf("MC Zombie", StringComparison.OrdinalIgnoreCase) < 0) { return value.IndexOf("Enemy - MCZombie", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static string GetEnemyName(object enemyParent) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown string text = GetMemberValue(enemyParent, "enemyName") as string; if (!string.IsNullOrEmpty(text)) { return text; } Component val = (Component)((enemyParent is Component) ? enemyParent : null); if ((Object)val != (Object)null) { object obj = ((Object)val).name; if (obj == null) { GameObject gameObject = val.gameObject; obj = (((Object)(object)gameObject != (Object)null) ? ((Object)gameObject).name : null) ?? "<unknown>"; } return (string)obj; } return "<unknown>"; } private static void RemoveEnemyFromDirector(object parent) { if (parent == null) { return; } try { Type type = FindLoadedType("EnemyDirector"); if (!(type == null)) { Object val = Object.FindObjectOfType(type); if (!(val == (Object)null) && GetMemberValue(val, "enemiesSpawned") is IList list && list.Contains(parent)) { list.Remove(parent); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Could not remove replaced enemy from EnemyDirector list: " + Unwrap(ex).Message)); } } private static void DestroyEnemyNetworkSafe(object parent) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown Component val = (Component)((parent is Component) ? parent : null); if ((Object)val == (Object)null || (Object)val.gameObject == (Object)null) { return; } GameObject gameObject = val.gameObject; try { MethodInfo methodInfo = (FindAssembly("PhotonUnityNetworking")?.GetType("Photon.Pun.PhotonNetwork", throwOnError: false))?.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(delegate(MethodInfo m) { ParameterInfo[] parameters = m.GetParameters(); return m.Name == "Destroy" && parameters.Length == 1 && parameters[0].ParameterType == typeof(GameObject); }); if (methodInfo != null) { methodInfo.Invoke(null, new object[1] { gameObject }); return; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Photon destroy failed; using Unity Destroy: " + Unwrap(ex).Message)); } Object.Destroy((Object)gameObject); } private static bool IsHostOrSingleplayer() { try { Type type = FindAssembly("PhotonUnityNetworking")?.GetType("Photon.Pun.PhotonNetwork", throwOnError: false); if (type == null) { return true; } PropertyInfo property = type.GetProperty("InRoom", BindingFlags.Static | BindingFlags.Public); if (!(property != null) || !Convert.ToBoolean(property.GetValue(null, null))) { return true; } PropertyInfo property2 = type.GetProperty("IsMasterClient", BindingFlags.Static | BindingFlags.Public); return property2 != null && Convert.ToBoolean(property2.GetValue(null, null)); } catch { return true; } } private static string GetCurrentLevelName() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown try { Type type = FindLoadedType("RunManager"); if (type != null) { object obj = GetStaticMemberValue(type, "instance") ?? GetStaticMemberValue(type, "Instance"); if (obj != null) { object obj2 = GetMemberValue(obj, "levelCurrent") ?? GetMemberValue(obj, "LevelCurrent"); if (obj2 != null) { Object val = (Object)((obj2 is Object) ? obj2 : null); if (val != (Object)null && !string.IsNullOrEmpty(val.name)) { return val.name; } string[] array = new string[4] { "name", "Name", "levelName", "LevelName" }; foreach (string name in array) { string text = GetMemberValue(obj2, name) as string; if (!string.IsNullOrEmpty(text)) { return text; } } } } } } catch { } return string.Empty; } private static bool IsMinecraftLevelName(string levelName) { if (string.IsNullOrEmpty(levelName)) { return false; } if (levelName.IndexOf("Minecraft Village", StringComparison.OrdinalIgnoreCase) < 0 && levelName.IndexOf("Minecraft Cave", StringComparison.OrdinalIgnoreCase) < 0 && levelName.IndexOf("Minecraft Stronghold", StringComparison.OrdinalIgnoreCase) < 0) { return levelName.IndexOf("Stronghold", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static Transform FindAnyPlayerTransform() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) try { Type type = FindLoadedType("PlayerAvatar"); if (type == null) { return null; } Object[] array = Object.FindObjectsOfType(type); if (array == null || array.Length == 0) { return null; } Object[] array2 = array; foreach (Object val in array2) { Component val2 = (Component)((val is Component) ? val : null); if (!((Object)val2 == (Object)null) && !((Object)val2.gameObject == (Object)null) && val2.gameObject.activeInHierarchy) { object obj = GetMemberValue(val2, "isLocal") ?? GetMemberValue(val2, "isLocalPlayer"); if (obj is bool && (bool)obj) { return val2.transform; } } } Object val3 = array[0]; Object val4 = ((val3 is Component) ? val3 : null); return (val4 != (Object)null) ? ((Component)val4).transform : null; } catch { return null; } } private static bool TryReadInt(object target, string name, out int value) { value = -1; try { object memberValue = GetMemberValue(target, name); if (memberValue == null) { return false; } value = Convert.ToInt32(memberValue); return true; } catch { return false; } } private static object GetMemberValue(object target, string name) { if (target == null || string.IsNullOrEmpty(name)) { return null; } Type type = target.GetType(); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = type.GetField(name, bindingAttr); if (field != null) { try { return field.GetValue(target); } catch { } } PropertyInfo property = type.GetProperty(name, bindingAttr); if (property != null && property.CanRead) { try { return property.GetValue(target, null); } catch { } } return null; } private static object GetStaticMemberValue(Type type, string name) { BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = type.GetField(name, bindingAttr); if (field != null) { try { return field.GetValue(null); } catch { } } PropertyInfo property = type.GetProperty(name, bindingAttr); if (property != null && property.CanRead) { try { return property.GetValue(null, null); } catch { } } return null; } private static Type FindLoadedType(string simpleOrFullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type type = assembly.GetType(simpleOrFullName, throwOnError: false); if (type != null) { return type; } try { Type type2 = assembly.GetTypes().FirstOrDefault((Type t) => t.Name == simpleOrFullName); if (type2 != null) { return type2; } } catch { } } return null; } private static Assembly FindAssembly(string name) { return AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, name, StringComparison.OrdinalIgnoreCase)); } private static Exception Unwrap(Exception ex) { while (ex is TargetInvocationException && ex.InnerException != null) { ex = ex.InnerException; } return ex; } private static string Vec(Vector3 v) { return "(" + v.x.ToString("0.00") + "," + v.y.ToString("0.00") + "," + v.z.ToString("0.00") + ")"; } private static void ResetLevelState() { _trackedLevel = string.Empty; _levelSeenAt = -1f; _doneForLevel = false; _pendingVictim = null; _pendingAt = 0f; _replacementAttempts = 0; } private static Vector3 SnapToLevelPoint(Vector3 position) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_006d: Expected O, but got Unknown //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_00a1: Unknown result type (might be due to invalid IL or missing references) try { LevelPoint val = null; float num = float.MaxValue; foreach (LevelPoint item in SemiFunc.LevelPointsGetAll()) { if (!((Object)item == (Object)null)) { float num2 = Vector3.Distance(position, ((Component)item).transform.position); if (num2 < num) { val = item; num = num2; } } } if ((Object)val != (Object)null) { return ((Component)val).transform.position; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("MCZombie LIVE QUOTA: level point lookup failed, using enemy position: " + ex.Message)); } return position; } } internal static class NetworkPrefabCompat { private static readonly Dictionary<string, GameObject> Cache = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase); internal static void CacheAndRegisterFromMCZombieBundle(object bundle) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown if (bundle == null) { return; } MethodInfo methodInfo = bundle.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "LoadAllAssets" && m.IsGenericMethodDefinition && m.GetParameters().Length == 0); if (methodInfo == null || !(methodInfo.MakeGenericMethod(typeof(GameObject)).Invoke(bundle, null) is Array array)) { return; } int num = 0; foreach (GameObject item in array) { GameObject val = item; if (!((Object)val == (Object)null) && !string.IsNullOrEmpty(((Object)val).name) && ((Object)val).name.IndexOf("Rotten Flesh", StringComparison.OrdinalIgnoreCase) >= 0) { CachePrefab(val); TryRegisterModern(val); num++; } } if (num > 0) { Plugin.Log.LogInfo((object)("Rotten Flesh network prefab(s) cached: " + num)); } else { Plugin.Log.LogWarning((object)"No Rotten Flesh GameObject found in MCZombie asset bundle."); } } internal static GameObject Find(string prefabId) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown if (string.IsNullOrEmpty(prefabId)) { return null; } if (Cache.TryGetValue(prefabId, out var value) && (Object)value != (Object)null) { return value; } string text = Normalize(prefabId); foreach (KeyValuePair<string, GameObject> item in Cache) { if ((Object)item.Value != (Object)null && Normalize(item.Key) == text) { return item.Value; } } return null; } internal static GameObject SpawnLegacy(string prefabId, Vector3 position, Quaternion rotation, byte group, object[] data) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Expected O, but got Unknown try { Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "REPOLib", StringComparison.OrdinalIgnoreCase))?.GetType("REPOLib.Modules.NetworkPrefabs", throwOnError: false); if (type == null) { throw new MissingMemberException("REPOLib.Modules.NetworkPrefabs not found."); } MethodInfo methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(delegate(MethodInfo m) { ParameterInfo[] parameters = m.GetParameters(); return m.Name == "GetNetworkPrefabRef" && parameters.Length == 1 && parameters[0].ParameterType == typeof(string); }); object obj = null; if (methodInfo != null) { try { obj = methodInfo.Invoke(null, new object[1] { prefabId }); } catch { } } if (obj == null) { GameObject val = Find(prefabId); if ((Object)val != (Object)null) { TryRegisterModern(val); if (methodInfo != null) { try { obj = methodInfo.Invoke(null, new object[1] { prefabId }); } catch { } } } } MethodInfo methodInfo2 = type.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(delegate(MethodInfo m) { if (m.Name != "SpawnNetworkPrefab") { return false; } ParameterInfo[] parameters = m.GetParameters(); return parameters.Length == 5 && parameters[0].ParameterType.Name.IndexOf("PrefabRef", StringComparison.OrdinalIgnoreCase) >= 0 && parameters[1].ParameterType == typeof(Vector3) && parameters[2].ParameterType == typeof(Quaternion) && parameters[3].ParameterType == typeof(byte) && parameters[4].ParameterType == typeof(object[]); }); if (methodInfo2 == null) { throw new MissingMethodException("Modern SpawnNetworkPrefab(PrefabRef, Vector3, Quaternion, byte, object[]) not found."); } if (obj == null) { Plugin.Log.LogWarning((object)("PaintedUtils: network prefab ID not resolvable: " + prefabId)); return null; } object obj4 = methodInfo2.Invoke(null, new object[5] { obj, position, rotation, group, data }); object obj5 = ((obj4 is GameObject) ? obj4 : null); Plugin.Log.LogInfo((object)("PaintedUtils: legacy SpawnNetworkPrefab adapted for '" + prefabId + "'.")); return (GameObject)obj5; } catch (Exception ex) { Plugin.Log.LogError((object)("PaintedUtils SpawnNetworkPrefab compatibility failed: " + ex)); return null; } } private static void CachePrefab(GameObject prefab) { Cache[((Object)prefab).name] = prefab; if (((Object)prefab).name.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { string text = ((Object)prefab).name.Substring(0, ((Object)prefab).name.Length - "(Clone)".Length).Trim(); if (!string.IsNullOrEmpty(text)) { Cache[text] = prefab; } } } internal static void RegisterLegacy(GameObject prefab) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown if (!((Object)prefab == (Object)null)) { CachePrefab(prefab); TryRegisterModern(prefab); } } private static void TryRegisterModern(GameObject prefab) { try { Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "REPOLib", StringComparison.OrdinalIgnoreCase))?.GetType("REPOLib.Modules.NetworkPrefabs", throwOnError: false); if (!(type == null)) { MethodInfo methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(delegate(MethodInfo m) { ParameterInfo[] parameters = m.GetParameters(); return m.Name == "RegisterNetworkPrefab" && parameters.Length == 1 && parameters[0].ParameterType == typeof(GameObject); }); if (methodInfo != null) { methodInfo.Invoke(null, new object[1] { prefab }); Plugin.Log.LogInfo((object)"Rotten Flesh registered through modern NetworkPrefabs runtime API."); } else { Plugin.Log.LogInfo((object)"Rotten Flesh cached for compatibility; no direct GameObject registration overload found."); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Rotten Flesh network registration warning: " + ex.Message)); } } private static string Normalize(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } string text = value.Trim(); if (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - 7).Trim(); } return new string(text.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray()); } } internal static class PaintedUtilsCompat { internal static bool SkipLegacyPatchAll() { Plugin.Log.LogInfo((object)"Skipped PaintedUtils legacy Harmony PatchAll incompatible with REPOLib 4."); return false; } } [BepInPlugin("000.CaptainTeam.MCZombieFix", "MCZombie Fix", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; private Harmony _harmony; internal static ConfigEntry<bool> GuaranteeMinecraftZombie; internal static ConfigEntry<bool> FleshSicknessEffect; private void Awake() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Logger.LogInfo((object)"MCZombieFix 1.1.0 loaded."); GuaranteeMinecraftZombie = ((BaseUnityPlugin)this).Config.Bind<bool>("MCZombie Compatibility", "Guarantee Zombie On Minecraft Maps", true, "Guarantees one MCZombie on Minecraft Village, Cave and Stronghold by replacing one active enemy of the same difficulty tier."); FleshSicknessEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("Rotten Flesh", "Sickness Effect", true, "After eating Rotten Flesh the player gets sick for a while and pukes a few times (game's own puke effect, visible to everyone)."); _harmony = new Harmony("000.CaptainTeam.MCZombieFix.runtime"); InstallPaintedUtilsPatchGuard(); InstallMCZombieAwakePatch(); LegacyEnemyLookupCompat.Install(_harmony); FleshSickness.Install(_harmony, ((Component)this).gameObject); ZombieGrabFix.Install(_harmony); ((MonoBehaviour)this).StartCoroutine(MinecraftSpawnGuarantee.Loop()); if (GuaranteeMinecraftZombie.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"MCZombie Minecraft quota replacement active."); } } private void InstallPaintedUtilsPatchGuard() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "PaintedUtils", StringComparison.OrdinalIgnoreCase)); if (assembly == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"PaintedUtils assembly not loaded yet."); return; } Type type = assembly.GetType("PaintedUtils.PaintedUtils", throwOnError: false); if (type == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"PaintedUtils.PaintedUtils type not found."); return; } MethodInfo methodInfo = AccessTools.Method(type, "Patch", (Type[])null, (Type[])null); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"PaintedUtils.Patch() not found."); return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(PaintedUtilsCompat), "SkipLegacyPatchAll", (Type[])null, (Type[])null); _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"PaintedUtils legacy PatchAll guarded for REPOLib 4."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to install PaintedUtils compatibility guard: " + ex)); } } private void InstallMCZombieAwakePatch() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown try { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "MCZombieMod", StringComparison.OrdinalIgnoreCase)); if (assembly == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"MCZombieMod assembly is not loaded yet."); return; } Type type = assembly.GetType("MCZombieMod.MCZombieMod", throwOnError: false); if (type == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"MCZombieMod.MCZombieMod type not found."); return; } MethodInfo methodInfo = AccessTools.Method(type, "Awake", (Type[])null, (Type[])null); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"MCZombieMod.Awake() not found."); return; } MethodInfo methodInfo2 = AccessTools.Method(typeof(MCZombieAwakeCompat), "Prefix", (Type[])null, (Type[])null); _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"MCZombieMod.Awake compatibility patch installed BEFORE MCZombie startup."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to install MCZombie compatibility patch: " + ex)); } } } internal static class ValuableCompat { internal static GameObject SpawnLegacy(object valuable, Vector3 position, Quaternion rotation) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) try { if (valuable == null) { return null; } GameObject val = ToGameObject(valuable); Type? obj = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "REPOLib", StringComparison.OrdinalIgnoreCase))?.GetType("REPOLib.Modules.Valuables", throwOnError: false); if (obj == null) { throw new MissingMemberException("REPOLib.Modules.Valuables not found."); } foreach (MethodInfo item in from m in obj.GetMethods(BindingFlags.Static | BindingFlags.Public) where m.Name == "SpawnValuable" select m) { object[] array = TryBuildArgs(item.GetParameters(), valuable, val, position, rotation); if (array == null) { continue; } try { GameObject val2 = ToGameObject(item.Invoke(null, array)); if ((Object)val2 != (Object)null) { Plugin.Log.LogInfo((object)("PaintedUtils: legacy SpawnValuable adapted through " + Describe(item) + ".")); return val2; } } catch (TargetInvocationException ex) { Plugin.Log.LogWarning((object)("SpawnValuable overload failed: " + (ex.InnerException?.Message ?? ex.Message))); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("SpawnValuable overload failed: " + ex2.Message)); } } if ((Object)val != (Object)null && IsHostOrSingleplayer()) { GameObject result = Object.Instantiate<GameObject>(val, position, rotation); Plugin.Log.LogWarning((object)"PaintedUtils: no modern SpawnValuable overload matched; used host-only local Instantiate fallback."); return result; } Plugin.Log.LogWarning((object)"PaintedUtils: no compatible modern SpawnValuable overload found."); return null; } catch (Exception ex3) { Plugin.Log.LogError((object)("PaintedUtils SpawnValuable compatibility failed: " + ex3)); return null; } } internal static ValuableObject GetByNameLegacy(string valuableName) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown if (string.IsNullOrEmpty(valuableName)) { return null; } try { Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "REPOLib", StringComparison.OrdinalIgnoreCase))?.GetType("REPOLib.Modules.Valuables", throwOnError: false); if (type != null) { foreach (MethodInfo item in type.GetMethods(BindingFlags.Static | BindingFlags.Public).Where(delegate(MethodInfo m) { ParameterInfo[] parameters = m.GetParameters(); return parameters.Length == 1 && parameters[0].ParameterType == typeof(string) && (m.Name.IndexOf("Valuable", StringComparison.OrdinalIgnoreCase) >= 0 || m.Name.IndexOf("Prefab", StringComparison.OrdinalIgnoreCase) >= 0); })) { try { ValuableObject val = ToValuableObject(item.Invoke(null, new object[1] { valuableName })); if ((Object)val != (Object)null) { Plugin.Log.LogInfo((object)("PaintedUtils: legacy GetValuableByName adapted through " + Describe(item) + " for '" + valuableName + "'.")); return val; } } catch { } } } ValuableObject[] array = Resources.FindObjectsOfTypeAll<ValuableObject>(); string text = NormalizeName(valuableName); ValuableObject[] array2 = array; foreach (ValuableObject val2 in array2) { if (!((Object)val2 == (Object)null) && NormalizeName(((Object)((Component)val2).gameObject != (Object)null) ? ((Object)((Component)val2).gameObject).name : ((Object)val2).name) == text) { Plugin.Log.LogInfo((object)("PaintedUtils: legacy GetValuableByName resolved from loaded assets for '" + valuableName + "'.")); return val2; } } Plugin.Log.LogWarning((object)("PaintedUtils: valuable not found by legacy name '" + valuableName + "'.")); return null; } catch (Exception ex) { Plugin.Log.LogError((object)("PaintedUtils GetValuableByName compatibility failed: " + ex)); return null; } } private static ValuableObject ToValuableObject(object value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown if (value == null) { return null; } ValuableObject val = (ValuableObject)((value is ValuableObject) ? value : null); if ((Object)val != (Object)null) { return val; } GameObject val2 = (GameObject)((value is GameObject) ? value : null); if ((Object)val2 != (Object)null) { return val2.GetComponent<ValuableObject>(); } Component val3 = (Component)((value is Component) ? value : null); if ((Object)val3 != (Object)null) { return val3.GetComponent<ValuableObject>(); } Type type = value.GetType(); string[] array = new string[6] { "Prefab", "prefab", "Value", "value", "GameObject", "gameObject" }; foreach (string name in array) { PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.GetIndexParameters().Length == 0) { try { ValuableObject val4 = ToValuableObject(property.GetValue(value, null)); if ((Object)val4 != (Object)null) { return val4; } } catch { } } FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field != null)) { continue; } try { ValuableObject val5 = ToValuableObject(field.GetValue(value)); if ((Object)val5 != (Object)null) { return val5; } } catch { } } return null; } private static string NormalizeName(string value) { if (string.IsNullOrEmpty(value)) { return string.Empty; } string text = value.Trim(); if (text.EndsWith("(Clone)", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - 7).Trim(); } return new string(text.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray()); } private static object[] TryBuildArgs(ParameterInfo[] parameters, object valuable, GameObject prefab, Vector3 position, Quaternion rotation) { //IL_002f: 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) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown object[] array = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameterInfo = parameters[i]; Type parameterType = parameterInfo.ParameterType; if (parameterType == typeof(Vector3)) { array[i] = position; continue; } if (parameterType == typeof(Quaternion)) { array[i] = rotation; continue; } if (parameterType.IsInstanceOfType(valuable)) { array[i] = valuable; continue; } if (parameterType == typeof(GameObject)) { array[i] = prefab; continue; } if (parameterType == typeof(string)) { array[i] = (((Object)prefab != (Object)null) ? ((Object)prefab).name : string.Empty); continue; } object obj = null; if (parameterType.Name.IndexOf("PrefabRef", StringComparison.OrdinalIgnoreCase) >= 0) { obj = FindValuablePrefabRef(parameterType, prefab); if (obj == null) { obj = ConstructPrefabRef(parameterType, prefab); } } if (obj != null && parameterType.IsInstanceOfType(obj)) { array[i] = obj; continue; } if (parameterInfo.HasDefaultValue) { array[i] = parameterInfo.DefaultValue; continue; } if (parameterType == typeof(bool)) { array[i] = false; continue; } if (parameterType.IsValueType) { array[i] = Activator.CreateInstance(parameterType); continue; } return null; } return array; } private static object FindValuablePrefabRef(Type expectedType, GameObject prefab) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown if ((Object)prefab == (Object)null) { return null; } try { if (!(((AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => string.Equals(a.GetName().Name, "REPOLib", StringComparison.OrdinalIgnoreCase))?.GetType("REPOLib.Modules.Valuables", throwOnError: false))?.GetProperty("AllValuables", BindingFlags.Static | BindingFlags.Public))?.GetValue(null, null) is IEnumerable enumerable)) { return null; } object obj = null; foreach (object item in enumerable) { if (item == null || !expectedType.IsInstanceOfType(item)) { continue; } GameObject val = ToGameObject(item); if (!((Object)val == (Object)null)) { if ((Object)(object)val == (Object)(object)prefab) { return item; } if (obj == null && string.Equals(((Object)val).name, ((Object)prefab).name, StringComparison.OrdinalIgnoreCase)) { obj = item; } } } return obj; } catch { return null; } } private static object ConstructPrefabRef(Type targetType, GameObject prefab) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown if (targetType == null || (Object)prefab == (Object)null) { return null; } try { ConstructorInfo[] constructors = targetType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (ConstructorInfo constructorInfo in constructors) { ParameterInfo[] parameters = constructorInfo.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == typeof(GameObject)) { return constructorInfo.Invoke(new object[1] { prefab }); } if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string)) { return constructorInfo.Invoke(new object[1] { ((Object)prefab).name }); } } } catch { } return null; } private static GameObject ToGameObject(object value) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown if (value == null) { return null; } GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val != (Object)null) { return val; } Component val2 = (Component)((value is Component) ? value : null); if ((Object)(object)val2 != (Object)null) { return val2.gameObject; } Type type = value.GetType(); string[] array = new string[4] { "gameObject", "GameObject", "prefab", "Prefab" }; foreach (string name in array) { try { PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.GetIndexParameters().Length == 0) { object value2 = property.GetValue(value, null); if (value2 != value) { GameObject val3 = ToGameObject(value2); if ((Object)val3 != (Object)null) { return val3; } } } FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field != null)) { continue; } object value3 = field.GetValue(value); if (value3 != value) { GameObject val4 = ToGameObject(value3); if ((Object)val4 != (Object)null) { return val4; } } } catch { } } return null; } private static bool IsHostOrSingleplayer() { try { Type type = Type.GetType("Photon.Pun.PhotonNetwork, PhotonUnityNetworking"); if (type == null) { return true; } PropertyInfo property = type.GetProperty("InRoom", BindingFlags.Static | BindingFlags.Public); if (!(property != null) || !Convert.ToBoolean(property.GetValue(null, null))) { return true; } PropertyInfo property2 = type.GetProperty("IsMasterClient", BindingFlags.Static | BindingFlags.Public); return property2 != null && Convert.ToBoolean(property2.GetValue(null, null)); } catch { return false; } } private static string Describe(MethodInfo method) { return method.DeclaringType?.FullName + "." + method.Name + "(" + string.Join(", ", (from p in method.GetParameters() select p.ParameterType.Name).ToArray()) + ")"; } } internal static class ZombieGrabFix { private static FieldInfo _enemyField; private static FieldInfo _photonViewField; private static FieldInfo _targetPlayerField; private static FieldInfo _currentStateField; private static MethodInfo _updateState; private static Type _stateType; private static readonly FieldInfo EnemyVisionField = AccessTools.Field(typeof(Enemy), "Vision"); private static readonly FieldInfo EnemyRigidbodyField = AccessTools.Field(typeof(Enemy), "Rigidbody"); private static readonly FieldInfo VisionPlayerField = AccessTools.Field(typeof(EnemyVision), "onVisionTriggeredPlayer"); private static readonly FieldInfo RigidbodyGrabObjectField = AccessTools.Field(typeof(EnemyRigidbody), "physGrabObject"); private static readonly FieldInfo GrabbersField = AccessTools.Field(typeof(PhysGrabObject), "playerGrabbing"); private static readonly FieldInfo GrabberAvatarField = AccessTools.Field(typeof(PhysGrabber), "playerAvatar"); internal static void Install(Harmony harmony) { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown Type type = AccessTools.TypeByName("MCZombieMod.AI.EnemyMCZombie"); MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "OnGrabbed", (Type[])null, (Type[])null) : null); if (methodInfo == null) { Plugin.Log.LogWarning((object)"MCZombie grab fix unavailable: EnemyMCZombie.OnGrabbed not found."); return; } _enemyField = AccessTools.Field(type, "_enemy"); _photonViewField = AccessTools.Field(type, "_photonView"); _targetPlayerField = AccessTools.Field(type, "_targetPlayer"); _currentStateField = AccessTools.Field(type, "currentState"); _stateType = AccessTools.Inner(type, "State"); _updateState = ((_stateType != null) ? AccessTools.Method(type, "UpdateState", new Type[1] { _stateType }, (Type[])null) : null); if (_enemyField == null || _photonViewField == null || _targetPlayerField == null || _currentStateField == null || _updateState == null) { Plugin.Log.LogWarning((object)"MCZombie grab fix unavailable: EnemyMCZombie members changed."); return; } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ZombieGrabFix), "OnGrabbedPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"MCZombie grab fix installed."); } private static bool OnGrabbedPrefix(MonoBehaviour __instance) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown try { if (!SemiFunc.IsMasterClientOrSingleplayer()) { return false; } switch (Convert.ToString(_currentStateField.GetValue(__instance))) { case "Attack": case "Chase": case "Stun": return false; default: { object? value = _enemyField.GetValue(__instance); PlayerAvatar val = FindTarget((Enemy)((value is Enemy) ? value : null)); if ((Object)val == (Object)null) { return false; } _targetPlayerField.SetValue(__instance, val); if (SemiFunc.IsMultiplayer()) { object? value2 = _photonViewField.GetValue(__instance); PhotonView val2 = (PhotonView)((value2 is PhotonView) ? value2 : null); if (val2 != null && (Object)val.photonView != (Object)null) { val2.RPC("UpdatePlayerTargetRPC", (RpcTarget)0, new object[1] { val.photonView.ViewID }); } } _updateState.Invoke(__instance, new object[1] { Enum.Parse(_stateType, "Chase") }); break; } } } catch (Exception ex) { Plugin.Log.LogDebug((object)("MCZombie grab fix: " + ex.Message)); } return false; } private static PlayerAvatar FindTarget(Enemy enemy) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown if ((Object)enemy == (Object)null) { return null; } object obj = EnemyVisionField?.GetValue(enemy); if (obj != null) { object? obj2 = VisionPlayerField?.GetValue(obj); PlayerAvatar val = (PlayerAvatar)((obj2 is PlayerAvatar) ? obj2 : null); if (val != null && (Object)val != (Object)null) { return val; } } object obj3 = EnemyRigidbodyField?.GetValue(enemy); object obj4 = ((obj3 == null) ? null : RigidbodyGrabObjectField?.GetValue(obj3)); if (obj4 != null && GrabbersField?.GetValue(obj4) is IList list) { foreach (object item in list) { if (item != null) { object? obj5 = GrabberAvatarField?.GetValue(item); PlayerAvatar val2 = (PlayerAvatar)((obj5 is PlayerAvatar) ? obj5 : null); if (val2 != null && (Object)val2 != (Object)null) { return val2; } } } } return null; } } }