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 DefendYourBase v0.2.5
DefendYourBase.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("DefendYourBase")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DefendYourBase")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("9f8a1b6e-6d0e-4dab-bbd8-9ed433836544")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] internal sealed class ConfigurationManagerAttributes { public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput); public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public CustomHotkeyDrawerFunc CustomHotkeyDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; } namespace neobotics.ValheimMods; internal class DebugUtils { public static void ObjectInspector(object o) { if (o == null) { Debug.Log((object)"Object is null"); return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; Type type = o.GetType(); Debug.Log((object)(o.ToString() + " Type " + type.Name)); PropertyInfo[] properties = type.GetProperties(bindingAttr); foreach (PropertyInfo propertyInfo in properties) { Debug.Log((object)$"{type.Name}.{propertyInfo.Name} = {propertyInfo.GetValue(o)}"); } FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo field in fields) { FieldPrinter(o, type, field); } } public static void MethodInspector(object o) { if (o == null) { Debug.Log((object)"Object is null"); return; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; Type type = o.GetType(); Debug.Log((object)(o.ToString() + " Type " + type.Name)); MethodInfo[] methods = type.GetMethods(bindingAttr); foreach (MethodInfo methodInfo in methods) { methodInfo.GetParameters(); string arg = string.Join(", ", (from x in methodInfo.GetParameters() select x.ParameterType?.ToString() + " " + x.Name).ToArray()); Debug.Log((object)$"{methodInfo.ReturnType} {methodInfo.Name} ({arg})"); } } private static void ItemDataInspector(ItemData item) { ObjectInspector(item); ObjectInspector(item.m_shared); } private static void FieldPrinter(object o, Type t, FieldInfo field) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown try { if (field.FieldType == typeof(ItemData)) { ItemData val = (ItemData)field.GetValue(o); if (val != null) { ItemDataInspector(val); } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]"); } } else if (field.FieldType == typeof(Transform)) { Transform val2 = (Transform)field.GetValue(o); if ((Object)(object)val2 != (Object)null) { Debug.Log((object)("\tTransform.parent = " + ((Object)val2.parent).name)); } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]"); } } else if (field.FieldType == typeof(EffectList)) { EffectList val3 = (EffectList)field.GetValue(o); if (val3 != null) { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}:"); EffectData[] effectPrefabs = val3.m_effectPrefabs; foreach (EffectData val4 in effectPrefabs) { Debug.Log((object)("\tEffectData.m_prefab = " + ((Object)val4.m_prefab).name)); } } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)} [null]"); } } else { Debug.Log((object)$"{t.Name}.{field.Name} = {field.GetValue(o)}"); } } catch (Exception) { Debug.Log((object)("Exception accessing " + t?.Name + "." + field?.Name)); } } public static void GameObjectInspector(GameObject go) { Debug.Log((object)("\n\nInspecting GameObject " + ((Object)go).name)); ObjectInspector(go); Component[] componentsInChildren = go.GetComponentsInChildren<Component>(); foreach (Component val in componentsInChildren) { try { string obj = ((val != null) ? ((Object)val).name : null); object obj2; if (val == null) { obj2 = null; } else { Transform transform = val.transform; if (transform == null) { obj2 = null; } else { Transform parent = transform.parent; obj2 = ((parent != null) ? ((Object)parent).name : null); } } Debug.Log((object)("\n\nInspecting Component " + obj + " with parent " + (string?)obj2)); ObjectInspector(val); } catch (Exception) { } } } public static void PrintList<T>(List<T> l) { foreach (T item in l) { Debug.Log((object)item.ToString()); } } public static void ComponentInspector(Component c) { Debug.Log((object)("\n\nInspecting Component " + ((Object)c).name)); ObjectInspector(c); } public static void EffectsInspector(EffectList e) { EffectData[] effectPrefabs = e.m_effectPrefabs; Debug.Log((object)$"Effect list has effects {e.HasEffects()} count {effectPrefabs.Length}"); EffectData[] array = effectPrefabs; foreach (EffectData val in array) { Debug.Log((object)$"Effect Data {val} prefab name {((Object)val.m_prefab).name} prefab GameObject name {((Object)val.m_prefab.gameObject).name}"); } } public static void PrintInventory() { foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems()) { Debug.Log((object)allItem.m_shared.m_name); } } public static void PrintAllObjects() { ZNetScene.instance.m_prefabs.ForEach(delegate(GameObject x) { Debug.Log((object)("GameObject " + ((Object)x).name)); }); } public static void PrintAllCharacters() { Character.GetAllCharacters().ForEach(delegate(Character x) { Debug.Log((object)("Character " + ((Object)x).name)); }); } public static void PrintAllLayers() { string[] array = (from index in Enumerable.Range(0, 31) select LayerMask.LayerToName(index) into l where !string.IsNullOrEmpty(l) select l).ToArray(); foreach (string text in array) { Debug.Log((object)("Layer " + text + " " + Convert.ToString(LayerMask.NameToLayer(text), 2).PadLeft(32, '0'))); } } } public class DelegatedConfigEntry<T> : DelegatedConfigEntryBase { private ConfigEntry<T> _entry; private EventHandler rootHandler; private Action<object, EventArgs> clientDelegate; private Logging Log; public ConfigEntry<T> ConfigEntry { get { return _entry; } set { _entry = value; if (_entry != null && rootHandler != null) { _entry.SettingChanged += rootHandler; } Name = ((ConfigEntryBase)_entry).Definition.Key; Section = ((ConfigEntryBase)_entry).Definition.Section; ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue(); Log.Trace("Set " + Section + " " + Name + " to serialized value " + ServerValue); } } public T Value { get { return _entry.Value; } set { _entry.Value = value; } } public DelegatedConfigEntry(bool useServerDelegate = false) : this((Action<object, EventArgs>)null, useServerDelegate) { } public DelegatedConfigEntry(Action<object, EventArgs> delegateHandler, bool useServerDelegate = false) { Log = Logging.GetLogger(); Log.Trace("DelegatedConfigEntry"); if (delegateHandler != null) { clientDelegate = delegateHandler; } if (useServerDelegate) { Log.Trace("Configuring server delegate"); rootHandler = delegate(object s, EventArgs e) { ServerDelegate(s, e); }; ServerConfiguration.ServerDelegatedEntries.Add(this); } else if (clientDelegate != null) { rootHandler = delegate(object s, EventArgs e) { clientDelegate(s, e); }; } } private void ServerDelegate(object sender, EventArgs args) { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Expected O, but got Unknown Logging.GetLogger().Trace("ServerDelegate"); _entry.SettingChanged -= rootHandler; ZNet instance = ZNet.instance; bool? flag = ((instance != null) ? new bool?(instance.IsServer()) : null); if (flag.HasValue) { if (flag == false && ServerConfiguration.Instance.ReceivedServerValues) { if (ServerValue != null) { ((ConfigEntryBase)_entry).SetSerializedValue(ServerValue); Log.Debug("Setting " + Name + " to server value " + ServerValue); } } else if (flag == true) { ServerValue = ((ConfigEntryBase)_entry).GetSerializedValue(); ServerConfiguration.Instance.SendConfigToAllClients(sender, (SettingChangedEventArgs)args); } } if (clientDelegate != null) { clientDelegate(sender, args); } _entry.SettingChanged += rootHandler; } public void EnableHandler(bool setActive) { if (setActive) { _entry.SettingChanged += rootHandler; } else { _entry.SettingChanged -= rootHandler; } } public bool IsKeyPressed() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0060: Unknown result type (might be due to invalid IL or missing references) if (ConfigEntry is ConfigEntry<KeyboardShortcut> val) { KeyboardShortcut value = val.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } if (!Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { return false; } return true; } Log.Error("Keyboard read attempted on non-KeyboardShortcut config."); return false; } public bool IsKeyDown() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0060: Unknown result type (might be due to invalid IL or missing references) if (ConfigEntry is ConfigEntry<KeyboardShortcut> val) { KeyboardShortcut value = val.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } if (!Input.GetKey(((KeyboardShortcut)(ref value)).MainKey)) { return false; } return true; } Log.Error("Keyboard read attempted on non-KeyboardShortcut config."); return false; } public bool IsKeyReleased() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0060: Unknown result type (might be due to invalid IL or missing references) if (ConfigEntry is ConfigEntry<KeyboardShortcut> val) { KeyboardShortcut value = val.Value; foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!Input.GetKeyUp(modifier)) { return false; } } if (!Input.GetKeyUp(((KeyboardShortcut)(ref value)).MainKey)) { return false; } return true; } Log.Error("Keyboard read attempted on non-KeyboardShortcut config."); return false; } } public class DelegatedConfigEntryBase { public string Name; public string Section; public string ServerValue; } internal class HarmonyHelper { public enum PatchType { Prefix, Postfix, Transpiler, Finalizer } private static Dictionary<string, string> detectionSet = new Dictionary<string, string>(); private static Dictionary<string, string> unpatchMods = new Dictionary<string, string>(); public static void GetDetectionSet(Dictionary<string, string> harmonyIds) { Logging logger = Logging.GetLogger(); foreach (KeyValuePair<string, string> harmonyId in harmonyIds) { if (Harmony.HasAnyPatches(harmonyId.Key)) { logger.Debug("Detected " + harmonyId.Value + " from Harmony"); if (!detectionSet.ContainsKey(harmonyId.Key)) { detectionSet.Add(harmonyId.Key, harmonyId.Value); } } else if (Chainloader.PluginInfos.ContainsKey(harmonyId.Key)) { logger.Debug("Detected " + harmonyId.Value + " from BepInEx"); if (!detectionSet.ContainsKey(harmonyId.Key)) { detectionSet.Add(harmonyId.Key, harmonyId.Value); } } } } public static void AddExclusion(string key) { if (detectionSet.ContainsKey(key)) { unpatchMods.Add(key, detectionSet[key]); } } public static void UnpatchMods(Harmony harmony) { Logging logger = Logging.GetLogger(); foreach (KeyValuePair<string, string> unpatchMod in unpatchMods) { logger.Warning("Not compatible with " + unpatchMod.Value); harmony.UnpatchAll(unpatchMod.Key); detectionSet.Remove(unpatchMod.Key); logger.Warning("Disabled " + unpatchMod.Value); } } public static bool IsModDetected(string key) { return detectionSet.ContainsKey(key); } public static bool IsModNameDetected(string value) { return detectionSet.ContainsValue(value); } public static bool TryGetDetectedModName(string key, out string mod) { return detectionSet.TryGetValue(key, out mod); } public static bool TryGetDetectedModKey(string value, out string key) { key = null; foreach (string key2 in detectionSet.Keys) { if (detectionSet[key2] == value) { key = key2; return true; } } return false; } public static string AddAnonymousPatch(string baseMethodName, PatchType patchType, string modName, string patchMethodName = null) { string text = null; int num = 0; Logging logger = Logging.GetLogger(); foreach (MethodBase item in Harmony.GetAllPatchedMethods().ToList()) { MethodBaseExtensions.HasMethodBody(item); Patches patchInfo = Harmony.GetPatchInfo(item); ReadOnlyCollection<Patch> readOnlyCollection = patchInfo.Prefixes; switch (patchType) { case PatchType.Postfix: readOnlyCollection = patchInfo.Postfixes; break; case PatchType.Prefix: readOnlyCollection = patchInfo.Prefixes; break; case PatchType.Transpiler: readOnlyCollection = patchInfo.Transpilers; break; case PatchType.Finalizer: readOnlyCollection = patchInfo.Finalizers; break; } foreach (Patch item2 in readOnlyCollection) { if (!item2.owner.StartsWith("harmony-auto") || !(item.Name == baseMethodName)) { continue; } if (patchMethodName != null) { if (item2.PatchMethod.Name == patchMethodName) { num++; text = item2.owner; } } else { num++; text = item2.owner; } } if (num == 1) { detectionSet.Add(text, modName); logger.Info($"Added unique anonymous {baseMethodName} {patchType}: {text} as {modName}"); } else if (num > 1) { text = null; logger.Warning($"Found multiple anonymous {baseMethodName} {patchType} entries. Can't identify correct patch to remove or modify."); } } if (num == 0) { logger.Info("No patch found for " + modName); } return text; } } public class Logging { public enum LogLevels { Critical, Error, Warning, Info, Debug, Trace } private static Logging _logger; public LogLevels LogLevel { get; set; } public string ModName { get; set; } private Logging(LogLevels level, string name) { LogLevel = level; ModName = name; } public static Logging GetLogger(LogLevels level, string name) { if (_logger == null) { _logger = new Logging(level, name); } return _logger; } public static Logging GetLogger() { if (_logger == null) { throw new NullReferenceException("Logger not initialized"); } return _logger; } public void Trace(string msg) { if (LogLevel >= LogLevels.Trace) { Debug.Log((object)Message(msg)); } } public void Debug(string msg) { if (LogLevel >= LogLevels.Debug) { Debug.Log((object)Message(msg)); } } public void Info(string msg) { if (LogLevel >= LogLevels.Info) { Debug.Log((object)Message(msg)); } } public void Warning(string msg) { if (LogLevel >= LogLevels.Warning) { Debug.LogWarning((object)Message(msg)); } } public void Error(string msg) { if (LogLevel >= LogLevels.Error) { Debug.LogWarning((object)Message(msg)); } } public void Error(Exception e) { Error(e, stackTrace: false); } public void Error(Exception e, bool stackTrace) { if (LogLevel >= LogLevels.Error) { Warning(Message(e.Message)); if (stackTrace) { Warning(e.StackTrace); } } } public void Critical(Exception e) { if (LogLevel >= LogLevels.Critical) { Debug(Message(e.Message)); Error(e.StackTrace); } } private string Message(string msg) { return ModName + ": " + msg; } public static void ChangeLogging(object s, EventArgs e) { SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); GetLogger().Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}"); GetLogger().LogLevel = Cfg.debugLevel.Value; } } public class ServerConfiguration { [HarmonyPatch(typeof(ZNet), "StopAll")] private static class ZNet_Shutdown_Patch { [HarmonyPrefix] private static void ZNet_StopAll_Prefix(ZNet __instance) { Log.Debug("ZNet_StopAll_Patch_Prefix"); if (Instance != null) { Instance.ReceivedServerValues = false; } } } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] private static class ZNet_OnNewConnection_Patch { private static void Postfix(ZNet __instance, ZNetPeer peer) { Log.Debug("ZNet OnNewConnection postfix"); if (!__instance.IsServer()) { try { peer.m_rpc.Register<ZPackage>("ClientConfigReceiver." + GetPluginGuid(), (Action<ZRpc, ZPackage>)Instance.RPC_ClientConfigReceiver); Log.Debug("Player registered RPC_ClientConfigReceiver"); return; } catch (Exception) { Log.Warning("Failed to register RPC"); return; } } try { Instance.SendConfigToClient(peer); } catch (Exception) { Log.Warning("Error sending server configuration to client"); } } } public static List<DelegatedConfigEntryBase> ServerDelegatedEntries = new List<DelegatedConfigEntryBase>(); private static ConfigFile LocalConfig; private static BaseUnityPlugin Mod; private static string ConfigFileName; private static ServerConfiguration _instance; private static Logging Log; public bool IsSetup; public bool ReceivedServerValues; public FileSystemWatcher ConfigWatcher; private const string NOT_CONFIGURED = "ServerConfiguration not initialized. Setup first."; public static ServerConfiguration Instance { get { if (_instance == null) { _instance = new ServerConfiguration(); } return _instance; } } private ServerConfiguration() { } public void Setup(ConfigFile config, BaseUnityPlugin modInstance) { LocalConfig = config; Log = Logging.GetLogger(); Log.Trace("ServerConfiguration Setup"); Mod = modInstance; ConfigFileName = Path.GetFileName(LocalConfig.ConfigFilePath); IsSetup = true; } public void CreateConfigWatcher() { ConfigWatcher = Utils.CreateFileWatcher(LocalConfig.ConfigFilePath, LoadConfig); } private void LoadConfig(object sender, FileSystemEventArgs e) { if (!File.Exists(LocalConfig.ConfigFilePath)) { return; } try { Log.Debug($"Loading configuration {e.ChangeType}"); LocalConfig.Reload(); } catch { Log.Error("Error loading configuration file " + ConfigFileName); } } public static string GetPluginGuid() { return Mod.Info.Metadata.GUID; } public void RPC_ClientConfigReceiver(ZRpc zrpc, ZPackage package) { if (!Instance.IsSetup) { Log.Error("ServerConfiguration not initialized. Setup first."); return; } Log.Debug("ClientConfigReceiver"); string section; string name; while (package.GetPos() < package.Size()) { section = package.ReadString(); name = package.ReadString(); string text = package.ReadString(); Log.Trace("Reading " + section + " " + name + " value " + text + " from ZPackage"); DelegatedConfigEntryBase delegatedConfigEntryBase = ServerDelegatedEntries.Find((DelegatedConfigEntryBase e) => e.Name == name && e.Section == section); if (delegatedConfigEntryBase != null) { Log.Trace("Found DCEB on client and setting to server value " + text); delegatedConfigEntryBase.ServerValue = text; } ConfigEntryBase val = LocalConfig[section, name]; if (val != null) { Log.Trace("Found local CEB and setting underlying config value " + text); val.SetSerializedValue(text); } } ReceivedServerValues = true; } internal void WriteConfigEntries(ZPackage zpkg) { foreach (DelegatedConfigEntryBase serverDelegatedEntry in ServerDelegatedEntries) { Log.Trace("Writing " + serverDelegatedEntry.Section + " " + serverDelegatedEntry.Name + " value " + serverDelegatedEntry.ServerValue + " to ZPackage"); zpkg.Write(serverDelegatedEntry.Section); zpkg.Write(serverDelegatedEntry.Name); zpkg.Write(serverDelegatedEntry.ServerValue); } } internal void SendConfigToClient(ZNetPeer peer) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (!Instance.IsSetup) { Log.Error("ServerConfiguration not initialized. Setup first."); return; } Log.Debug("SendConfigToClient"); ZPackage val = new ZPackage(); WriteConfigEntries(val); peer.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { val }); Log.Trace("Invoked ClientConfigReceiver on peer"); } public void SendConfigToAllClients(object o, SettingChangedEventArgs e) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown if (!IsSetup) { Log.Error("ServerConfiguration not initialized. Setup first."); } else if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZNet.instance.GetPeerConnections() > 0) { Log.Debug("SendConfigToAllClients"); ZPackage zpkg = new ZPackage(); WriteConfigEntries(zpkg); ((MonoBehaviour)Mod).StartCoroutine(_instance.Co_BroadcastConfig(zpkg)); } } private IEnumerator Co_BroadcastConfig(ZPackage zpkg) { Log.Debug("Co_BroadcastConfig"); List<ZNetPeer> connectedPeers = ZNet.instance.GetConnectedPeers(); foreach (ZNetPeer item in connectedPeers) { if (item != ZNet.instance.GetServerPeer()) { item.m_rpc.Invoke("ClientConfigReceiver." + GetPluginGuid(), new object[1] { zpkg }); Log.Trace("Invoked ClientConfigReceiver on peer"); } yield return null; } } } internal class Utils { public static TEnum Guardrails<TEnum>(string value, TEnum enumDefault) where TEnum : struct { if (Enum.TryParse<TEnum>(value, ignoreCase: true, out var result)) { return result; } return enumDefault; } public static int Guardrails(int value, int lbound, int ubound) { if (value < lbound) { return lbound; } if (value > ubound) { return ubound; } return value; } public static string truncate(string value, int maxChars) { if (value == null) { return null; } if (value.Length <= maxChars) { return value; } return value.Substring(0, maxChars); } public static void GetCharactersInRangeXZ(Vector3 point, float radius, List<Character> characters) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) float num = radius * radius; foreach (Character s_character in Character.s_characters) { if (DistanceSqrXZ(((Component)s_character).transform.position, point) < num) { characters.Add(s_character); } } } public static float DistanceSqr(Vector3 v0, Vector3 v1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) float num = v1.x - v0.x; float num2 = v1.y - v0.y; float num3 = v1.z - v0.z; return num * num + num2 * num2 + num3 * num3; } public static float DistanceSqrXZ(Vector3 v0, Vector3 v1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = v1.x - v0.x; float num2 = v1.z - v0.z; return num * num + num2 * num2; } public static float DistanceXZ(Vector3 v0, Vector3 v1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) float num = v1.x - v0.x; float num2 = v1.z - v0.z; return Mathf.Sqrt(num * num + num2 * num2); } public static float Guardrails(float value, float lbound, float ubound) { if (value < lbound) { return lbound; } if (value > ubound) { return ubound; } return value; } public static string UnClonifiedName(string name) { if (name == null) { return null; } int num = name.IndexOf("(Clone)"); if (num < 1) { return name; } return name.Substring(0, num); } public static void SetTranslator(int id, string idText) { typeof(Localization).GetMethod("AddWord", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(Localization.instance, new object[2] { "skill_" + id, idText }); } public static string GetTranslated(int id) { Logging.GetLogger().Debug(string.Format("Got translation for id {0} to {1}", id, Localization.instance.Localize("skill_" + id))); return Localization.instance.Localize("$skill_" + id); } public static string GetAssemblyPathedFile(string fileName) { return new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName.Replace('\\', '/') + "/" + fileName; } public static Sprite GetPrefabIcon(string prefabName) { Sprite result = null; GameObject prefab = GetPrefab(prefabName); ItemDrop val = default(ItemDrop); if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref val)) { result = val.m_itemData.GetIcon(); } return result; } public static Player GetPlayerByZDOID(ZDOID zid) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) foreach (Player allPlayer in Player.GetAllPlayers()) { ZDOID zDOID = ((Character)allPlayer).GetZDOID(); if (((ZDOID)(ref zDOID)).Equals(zid)) { return allPlayer; } } return null; } public static Character GetCharacterByZDOID(string cid) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) foreach (Character allCharacter in Character.GetAllCharacters()) { ZDOID zDOID = allCharacter.GetZDOID(); if (((object)(ZDOID)(ref zDOID)).ToString().Equals(cid)) { return allCharacter; } } return null; } public static Character GetCharacterByZDOID(ZDOID cid) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) foreach (Character allCharacter in Character.GetAllCharacters()) { ZDOID zDOID = allCharacter.GetZDOID(); if (((ZDOID)(ref zDOID)).Equals(cid)) { return allCharacter; } } return null; } public static ZNetPeer GetPeerByRPC(ZRpc rpc) { foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { if (peer.m_rpc == rpc) { return peer; } } return null; } public static List<GameObject> GetGameObjectsOfType(Type t) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) List<GameObject> list = new List<GameObject>(); Object[] array = Object.FindObjectsOfType(t); foreach (Object val in array) { list.Add(((Component)val).gameObject); } return list; } public static GameObject GetClosestGameObjectOfType(Type t, Vector3 point, float radius) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return GetGameObjectsOfTypeInRangeByDistance(t, point, radius)?[0]; } public static List<GameObject> GetGameObjectsOfTypeInRangeByDistance(Type t, Vector3 point, float radius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) List<KeyValuePair<GameObject, float>> list = new List<KeyValuePair<GameObject, float>>(); List<GameObject> gameObjectsOfTypeInRange = GetGameObjectsOfTypeInRange(t, point, radius); if (gameObjectsOfTypeInRange.Count > 0) { foreach (GameObject item in gameObjectsOfTypeInRange) { list.Add(new KeyValuePair<GameObject, float>(item, Vector3.Distance(item.transform.position, point))); } list.Sort((KeyValuePair<GameObject, float> pair1, KeyValuePair<GameObject, float> pair2) => pair1.Value.CompareTo(pair2.Value)); return list.ConvertAll((KeyValuePair<GameObject, float> x) => x.Key); } return null; } public static List<GameObject> GetGameObjectsOfTypeInRange(Type t, Vector3 point, float radius) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return (from x in GetGameObjectsOfType(t) where Vector3.Distance(x.transform.position, point) < radius select x).ToList(); } public static float GetPointDepth(Vector3 p) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return ZoneSystem.instance.m_waterLevel - GetSolidHeight(p); } public static List<string> GetDelimitedStringAsList(string delimitedString, char delimiter) { List<string> list = new List<string>(); string[] array = delimitedString.Split(new char[1] { delimiter }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { list.Add(text.Trim()); } return list; } public static float GetSolidHeight(Vector3 p) { //IL_0021: 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_004b: Unknown result type (might be due to invalid IL or missing references) int solidRayMask = ZoneSystem.instance.m_solidRayMask; float result = 0f; p.y += 1000f; RaycastHit val = default(RaycastHit); if (Physics.Raycast(p, Vector3.down, ref val, 2000f, solidRayMask) && !Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody)) { result = ((RaycastHit)(ref val)).point.y; } return result; } public static Transform FindChild(Transform aParent, string aName) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown foreach (Transform item in aParent) { Transform val = item; if (((Object)val).name == aName) { return val; } Transform val2 = FindChild(val, aName); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } public static Transform FindParent(Transform go) { while ((Object)(object)go.parent != (Object)null) { go = go.parent; } return go; } public static GameObject GetPrefab(int prefabHash) { return GetPrefabByHash(prefabHash); } public static GameObject GetPrefabByHash(int prefabHash) { GameObject val = ObjectDB.instance.GetItemPrefab(prefabHash); Logging logger = Logging.GetLogger(); if ((Object)(object)val != (Object)null) { logger.Debug("Found prefab in ObjectDB"); } else { ZNetScene instance = ZNetScene.instance; val = ((instance != null) ? instance.GetPrefab(prefabHash) : null); if ((Object)(object)val != (Object)null) { logger.Debug("Found prefab in Scene"); } } return val; } public static GameObject GetPrefab(string prefabName) { GameObject val = ObjectDB.instance.GetItemPrefab(prefabName); Logging logger = Logging.GetLogger(); if ((Object)(object)val != (Object)null) { logger.Debug("Found " + prefabName + " in ObjectDB"); } else { ZNetScene instance = ZNetScene.instance; val = ((instance != null) ? instance.GetPrefab(prefabName) : null); if ((Object)(object)val != (Object)null) { logger.Debug("Found " + prefabName + " in Scene"); } } return val; } public static string SerializeFromDictionary<K, V>(string delimp, string delimc, IDictionary<K, V> dict) { if (dict == null) { return null; } IEnumerable<string> values = dict.Select(delegate(KeyValuePair<K, V> kvp) { KeyValuePair<K, V> keyValuePair = kvp; string? obj = keyValuePair.Key?.ToString(); string text = delimc; keyValuePair = kvp; return obj + text + keyValuePair.Value; }); return string.Join(delimp, values); } public static void DeserializeToDictionary<K, V>(string serializedString, string delimp, string delimc, ref IDictionary<K, V> dict) { if (dict == null) { return; } dict.Clear(); string[] separator = new string[1] { delimp }; string[] separator2 = new string[1] { delimc }; string[] array = serializedString.Split(separator, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(separator2, StringSplitOptions.RemoveEmptyEntries); if (array2.Length == 2) { dict.Add(TypedValue<K>(array2[0]), TypedValue<V>(array2[1])); } } } public static FileSystemWatcher CreateFileWatcher(string fullPath, FileSystemEventHandler handler) { string fileName = Path.GetFileName(fullPath); FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(fullPath.Substring(0, fullPath.Length - fileName.Length), fileName); fileSystemWatcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime; fileSystemWatcher.Changed += handler; fileSystemWatcher.Created += handler; fileSystemWatcher.IncludeSubdirectories = false; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; return fileSystemWatcher; } public static T TypedValue<T>(object a) { return (T)Convert.ChangeType(a, typeof(T)); } public static float TimeAdjustedRamp(float maxValue, float duration, float elapsedTime, float pctFromStartRise, float pctFromEndFall) { float num = elapsedTime / duration; if (num <= pctFromStartRise) { return maxValue * (num / pctFromStartRise); } if (num >= 1f - pctFromEndFall) { return maxValue * ((1f - num) / pctFromEndFall); } return maxValue; } public static bool CopyComponentToGameObject(Component original, ref GameObject destination) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown Logging logger = Logging.GetLogger(); Type type = ((object)original).GetType(); logger.Debug($"Original Type is {type}"); GameObject obj = destination; logger.Debug("Destination GameObject " + ((obj != null) ? ((Object)obj).name : null)); Component val = destination.GetComponent(type); if ((Object)(object)val == (Object)null) { val = destination.AddComponent(type); } if ((Object)(object)val == (Object)null) { logger.Debug("Destination component is null"); return false; } Component val2 = (Component)Activator.CreateInstance(type); if ((Object)(object)val2 == (Object)null) { logger.Debug("Destination component is null"); return false; } if ((Object)(object)val2 == (Object)null) { logger.Debug("Boxed component is null"); return false; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(val2, fieldInfo.GetValue(original)); } val = val2; return true; } public static bool CopyObject(object original, object target) { Logging logger = Logging.GetLogger(); Type type = original.GetType(); Type type2 = target.GetType(); if (type == null) { logger.Warning("Copy Object: Source object is null"); Activator.CreateInstance(type); return false; } if (type2 == null) { logger.Warning("Copy Object: Destination object is null"); return false; } if (type2 != type) { logger.Warning("Copy Object: Source and destination components are different types"); return false; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(target, fieldInfo.GetValue(original)); } return true; } } internal class Cfg { public static DelegatedConfigEntry<bool> guardAttacks; public static DelegatedConfigEntry<Logging.LogLevels> debugLevel; public static DelegatedConfigEntry<bool> biomeRestriction; public static DelegatedConfigEntry<bool> bossProgression; public static DelegatedConfigEntry<int> piecesNeeded; public static DelegatedConfigEntry<int> proximityCheckRadius; public static DelegatedConfigEntry<int> stationsNeeded; public static DelegatedConfigEntry<int> bedsNeeded; public static DelegatedConfigEntry<string> creatureBiomeMapping; public static DelegatedConfigEntry<bool> allowLevels; public static void BepInExConfig(BaseUnityPlugin _instance) { //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Expected O, but got Unknown ServerConfiguration.Instance.Setup(_instance.Config, _instance); debugLevel = new DelegatedConfigEntry<Logging.LogLevels>(ChangeLogging); debugLevel.ConfigEntry = _instance.Config.Bind<Logging.LogLevels>("Utility", "LogLevel", Logging.LogLevels.Info, "Controls the level of information contained in the log"); Logging.GetLogger().LogLevel = debugLevel.Value; biomeRestriction = new DelegatedConfigEntry<bool>(useServerDelegate: true); biomeRestriction.ConfigEntry = _instance.Config.Bind<bool>("Restrictions", "Limit by biome", false, "If enabled, restricts summoned creatures to those that can spawn in the selected ward's biome, or 'higher' biomes, e.g. a Troll can be summoned to a ward in the Plains, but a Seeker cannot.@"); bossProgression = new DelegatedConfigEntry<bool>(useServerDelegate: true); bossProgression.ConfigEntry = _instance.Config.Bind<bool>("Restrictions", "Limit by Progression", false, "If enabled, allows creatures to be summoned in 'lower' biomes once a boss is defeated, e.g. Once Bonemass is defeated, a Draugr can be summoned to a ward in the Meadows, Black Forest and Swamp.@"); piecesNeeded = new DelegatedConfigEntry<int>(useServerDelegate: true); piecesNeeded.ConfigEntry = _instance.Config.Bind<int>("Restrictions", "Minimum Base Pieces", 100, "The minimum number of build pieces that must be in proximity to the ward to be considered a 'base' (based on the Piece Check Radius)@"); proximityCheckRadius = new DelegatedConfigEntry<int>(useServerDelegate: true); proximityCheckRadius.ConfigEntry = _instance.Config.Bind<int>("Restrictions", "Base Check Radius", 50, "The radius from the ward to check for a 'base' that allows the ward to be used for summoning a guard.@"); stationsNeeded = new DelegatedConfigEntry<int>(useServerDelegate: true); stationsNeeded.ConfigEntry = _instance.Config.Bind<int>("Restrictions", "Minimum Base Crafting Stations", 1, "The minimum number of crafting stations that must be in proximity to the ward to be considered a 'base' (based on the Piece Check Radius)@"); bedsNeeded = new DelegatedConfigEntry<int>(useServerDelegate: true); bedsNeeded.ConfigEntry = _instance.Config.Bind<int>("Restrictions", "Minimum Base Beds", 1, "The minmium number of beds that must be in proximity to the ward to be considered a 'base' (based on the Piece Check Radius)@"); allowLevels = new DelegatedConfigEntry<bool>(useServerDelegate: true); allowLevels.ConfigEntry = _instance.Config.Bind<bool>("Restrictions", "Enable Guardian Levels", true, "If enabled, allows trophies from 'starred' creatures to summon guardians of the same level, i.e. a trophy from a 2-star will summon a 2-star guardian.@"); creatureBiomeMapping = new DelegatedConfigEntry<string>(DefendYourBase.ChangeBiomeMapping, useServerDelegate: true); creatureBiomeMapping.ConfigEntry = _instance.Config.Bind<string>("Hidden", "Creature Biome Mapping", DefendYourBase.creatureConfigString, new ConfigDescription("The list of creature-to-biome mappings. Used by server authoritative configs only. Edit the CreatureBiomeMap.txt file to change local mapping.@", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = false } })); ServerConfiguration.Instance.CreateConfigWatcher(); } public static void ChangeLogging(object s, EventArgs e) { Logging logger = Logging.GetLogger(); SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); logger.Debug($"ChangeLog {val.ChangedSetting.Definition.Key} to {val.ChangedSetting.BoxedValue}"); logger.LogLevel = debugLevel.Value; } } internal class CreatureInfo { public string Name { get; } public bool Tamed { get; } public bool Tapped { get; } public bool Boss { get; } public int Level { get; } public bool DropsEnabled { get; } public CreatureInfo(string name, bool tamed, bool tapped, bool boss, int level, bool dropsEnabled) { Name = name; Tamed = tamed; Tapped = tapped; Boss = boss; Level = level; DropsEnabled = dropsEnabled; } } [BepInPlugin("neobotics.valheim_mod.defendyourbase", "DefendYourBase", "0.2.5")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class DefendYourBase : BaseUnityPlugin { [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Patch { [HarmonyPostfix] private static void ZNetScene_Awake_Postfix(ZNetScene __instance) { Log.Debug("ZNetScene_Awake_Patch_Postfix"); BuildTrophyCreatureMap(); } } [HarmonyPatch(typeof(PrivateArea), "UseItem")] private static class PrivateArea_UseItem_Patch { [HarmonyPostfix] private static void PrivateArea_UseItem_Postfix(PrivateArea __instance, Humanoid user, ItemData item, ref bool __result) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Invalid comparison between Unknown and I4 //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_0380: 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_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: 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_0415: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) Log.Debug("PrivateArea_UseItem_Patch_Postfix"); if (!((Character)user).IsPlayer()) { return; } if ((int)item.m_shared.m_itemType != 13) { Log.Debug(item.m_shared.m_name + " is not a trophy"); return; } __result = true; int quality = item.m_quality; if (!trophyCreatureMap.TryGetValue(item.m_shared.m_name, out var value)) { Log.Debug("Trophy not mapped"); ((Character)Player.m_localPlayer).Message((MessageType)2, "This creature cannot be summoned as a guard.", 0, (Sprite)null); return; } Player val = (Player)(object)((user is Player) ? user : null); if (__instance.GetCreatorName() != val.GetPlayerName()) { Log.Debug("Can't summon on someone else's ward"); ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't summon a guard on someone else's ward.", 0, (Sprite)null); return; } if (__instance.m_nview.GetZDO().GetBool(WARD_FLAG, false)) { Log.Debug("Ward already has a guard"); ((Character)Player.m_localPlayer).Message((MessageType)2, "This ward already has a guard.", 0, (Sprite)null); return; } if ((Cfg.piecesNeeded.Value > 0 || Cfg.stationsNeeded.Value > 0) && Cfg.proximityCheckRadius.Value > 0 && !CheckPiecesInRadius(((Component)__instance).transform.position, Cfg.proximityCheckRadius.Value, Cfg.piecesNeeded.Value, Cfg.stationsNeeded.Value, Cfg.bedsNeeded.Value)) { Log.Debug("Ward is not close enough to a large enough base"); ((Character)Player.m_localPlayer).Message((MessageType)2, "The ward must be close to a large enough base.", 0, (Sprite)null); return; } List<ZDO> list = new List<ZDO>(); if (GetAllGuardedWardZDOs(list)) { foreach (ZDO item2 in list) { if (Vector3.Distance(item2.m_position, ((Component)__instance).transform.position) < __instance.m_radius) { Log.Debug("A guarded ward is within selected ward's radius of protection"); ((Character)Player.m_localPlayer).Message((MessageType)2, "You can only have one ward guarded within a protected area.", 0, (Sprite)null); return; } } } GameObject prefabByHash = Utils.GetPrefabByHash(value); string text = string.Empty; if ((Object)(object)prefabByHash == (Object)null) { Log.Warning("Can't find creature prefab for trophy."); return; } MonsterAI val2 = default(MonsterAI); if (!prefabByHash.TryGetComponent<MonsterAI>(ref val2)) { Log.Debug("Creature has no MonsterAI"); ((Character)Player.m_localPlayer).Message((MessageType)2, "This creature cannot be summoned as a guard.", 0, (Sprite)null); return; } Character val3 = default(Character); if (!prefabByHash.TryGetComponent<Character>(ref val3)) { Log.Warning("Creature has no Character"); ((Character)Player.m_localPlayer).Message((MessageType)2, "This creature cannot be summoned as a guard.", 0, (Sprite)null); return; } if (val3.m_boss) { Log.Debug("Can't summon a boss"); ((Character)Player.m_localPlayer).Message((MessageType)2, "You can't summon a boss as a guard.", 0, (Sprite)null); return; } bool flag = true; bool flag2 = false; if (Cfg.bossProgression.Value) { flag2 = CheckBossLevel(((Component)__instance).transform.position, item.m_shared.m_name); flag = false; } if (Cfg.biomeRestriction.Value) { flag = CheckGuardBiome(((Component)__instance).transform.position, item.m_shared.m_name); } if (!(flag || flag2)) { Log.Debug($"Guard not valid for biome {flag} or boss {flag2}"); ((Character)Player.m_localPlayer).Message((MessageType)2, $"This guard is not allowed in the {Heightmap.FindBiome(((Component)__instance).transform.position)}.", 0, (Sprite)null); return; } Log.Debug("Summoning Guard"); Vector3 val4 = ((Component)__instance).transform.position + ((Component)__instance).transform.forward * 2f; GameObject obj = Object.Instantiate<GameObject>(prefabByHash, val4, Quaternion.identity); ConsumeItem(user, item); Character val5 = default(Character); if (obj.TryGetComponent<Character>(ref val5)) { text = val5.m_name; } ZDO zDO = val5.m_nview.GetZDO(); zDO.Set(GUARD_PATROL_POINT, ((Component)__instance).transform.position); ZDOMan.instance.ForceSendZDO(zDO.m_uid); ZDO zDO2 = __instance.m_nview.GetZDO(); zDO2.Set(WARD_FLAG, true); ZDOMan.instance.ForceSendZDO(zDO2.m_uid); SetUpGuard(obj, __instance.m_radius, ((Component)__instance).transform.position, quality); Object.Instantiate<GameObject>(Utils.GetPrefab("vfx_spawn"), ((Component)__instance).transform.position, Quaternion.identity); Object.Instantiate<GameObject>(Utils.GetPrefab("sfx_offering"), ((Component)__instance).transform.position, Quaternion.identity); ((Character)val).Message((MessageType)2, Localization.instance.Localize("Summoned " + text), 0, (Sprite)null); } } [HarmonyPatch(typeof(Character), "OnDeath")] private static class Character_OnDeath_Patch { [HarmonyPrefix] private static void Character_OnDeath_Prefix(Character __instance) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) Log.Debug("Character_OnDeath_Patch_Prefix"); Vector3 position = default(Vector3); if (!__instance.m_nview.GetZDO().GetVec3(GUARD_PATROL_POINT, ref position)) { return; } Log.Debug("Guardian died"); List<ZDO> list = new List<ZDO>(); if (GetAllGuardedWardZDOs(list)) { ZDO val = list.Find((ZDO x) => x.m_position == position); if (val != null) { Log.Debug("Guardian ward found"); val.Set(WARD_FLAG, false); ZDOMan.instance.ForceSendZDO(val.m_uid); } } } } [HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[] { typeof(Character), typeof(Character) })] private static class BaseAI_IsEnemy_Patch { [HarmonyPostfix] private static void BaseAI_IsEnemy_Postfix(BaseAI __instance, Character a, Character b, ref bool __result) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)a == (Object)null) && !((Object)(object)b == (Object)null)) { object obj; if (a == null) { obj = null; } else { ZNetView nview = a.m_nview; obj = ((nview != null) ? nview.GetZDO() : null); } ZDO val = (ZDO)obj; object obj2; if (b == null) { obj2 = null; } else { ZNetView nview2 = b.m_nview; obj2 = ((nview2 != null) ? nview2.GetZDO() : null); } ZDO val2 = (ZDO)obj2; Vector3 val3 = default(Vector3); if (val != null && val2 != null && ((val.GetVec3(WARD_FLAG, ref val3) && !b.m_tamed) || (val2.GetVec3(WARD_FLAG, ref val3) && !a.m_tamed))) { __result = true; } } } } [HarmonyPatch(typeof(MonsterAI), "UpdateTarget")] private static class MonsterAI_UpdateTarget_Patch { [HarmonyPostfix] private static void MonsterAI_UpdateTarget_Postfix(MonsterAI __instance, Humanoid humanoid, float dt) { Log.Debug("MonsterAI_UpdateTarget_Patch_Postfix"); ZDO val = ((BaseAI)(__instance?)).m_nview?.m_zdo; Vector3 val2 = default(Vector3); if (val != null && val.GetVec3(GUARD_PATROL_POINT, ref val2) && ((BaseAI)__instance).IsAlerted() && (Object)(object)__instance.m_targetCreature == (Object)null && __instance.m_timeSinceSensedTargetCreature > 1f) { ((BaseAI)__instance).SetAlerted(false); __instance.m_targetCreature = null; __instance.m_targetStatic = null; __instance.m_timeSinceAttacking = 0f; __instance.m_updateTargetTimer = 0f; } } } [HarmonyPatch(typeof(BaseAI), "ResetRandomMovement")] private static class BaseAI_ResetRandomMovement_Patch { [HarmonyPrefix] private static void BaseAI_ResetRandomMovement_Prefix(BaseAI __instance) { Log.Debug("BaseAI_ResetRandomMovement_Patch_Prefix"); } [HarmonyPostfix] private static void BaseAI_ResetRandomMovement_Postfix(BaseAI __instance) { Log.Debug("BaseAI_ResetRandomMovement_Patch_Postfix"); } } [HarmonyPatch(typeof(WearNTear), "Destroy")] private static class WearNTear_Destroy_Patch { [HarmonyPrefix] private static void WearNTear_Destroy_Prefix(WearNTear __instance) { //IL_0052: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) Log.Debug("WearNTear_Destroy_Patch_Prefix"); if (!__instance.m_nview.GetZDO().GetBool(WARD_FLAG, false)) { return; } List<ZDO> list = new List<ZDO>(); if (!TryGetGuardZDOs(list)) { return; } foreach (ZDO item in list) { if (item.GetVec3(GUARD_PATROL_POINT, Vector3.zero) == ((Component)__instance).gameObject.transform.position) { Object.Instantiate<GameObject>(Utils.GetPrefab("vfx_odin_despawn"), item.m_position, Quaternion.identity); ZNetView val = ZNetScene.instance.FindInstance(item); if ((Object)(object)val != (Object)null) { val.Destroy(); } break; } } } } [HarmonyPatch(typeof(ZNetScene), "CreateObject")] private static class ZNetScene_CreateObject_Patch { [HarmonyPostfix] private static void ZNetScene_CreateObject_Postfix(ZNetScene __instance, ZDO zdo, ref GameObject __result) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) Vector3 patrolPoint = default(Vector3); if ((Object)(object)__result == (Object)null || !zdo.GetVec3(GUARD_PATROL_POINT, ref patrolPoint)) { return; } Log.Debug("Creating tamed Guard"); if (privateAreaRadius == 0f) { privateAreaRadius = 32f; GameObject prefab = Utils.GetPrefab("guard_stone"); if ((Object)(object)prefab != (Object)null) { PrivateArea val = default(PrivateArea); if (prefab.TryGetComponent<PrivateArea>(ref val)) { privateAreaRadius = val.m_radius; Log.Debug($"Setting Ward radius to {privateAreaRadius}"); } else { Log.Debug("Can't get Ward PrivateArea"); } } else { Log.Debug("Cant find Ward prefab"); } } SetUpGuard(__result, privateAreaRadius, patrolPoint); } } [HarmonyPatch(typeof(CharacterDrop), "OnDeath")] private static class CharacterDrop_OnDeath_Patch { [HarmonyPrefix] private static void CharacterDrop_OnDeath_Prefix(CharacterDrop __instance) { if (Cfg.allowLevels.Value) { Log.Debug("CharacterDrop_OnDeath_Patch_Prefix"); Character character = __instance.m_character; if ((Object)(object)character != (Object)null && !character.IsPlayer() && character.GetLevel() > 0) { s_tempCreatureLevel = character.GetLevel(); } } } [HarmonyPostfix] private static void CharacterDrop_OnDeath_Postfix(CharacterDrop __instance, ref CreatureInfo __state) { if (Cfg.allowLevels.Value) { Log.Debug("CharacterDrop_OnDeath_Patch_Postfix"); s_tempCreatureLevel = 0; } } } [HarmonyPatch(typeof(CharacterDrop), "DropItems")] [HarmonyPriority(0)] private static class CharacterDrop_DropItems_Patch { [HarmonyPrefix] private static bool CharacterDrop_DropItems_Prefix(CharacterDrop __instance, List<KeyValuePair<GameObject, int>> drops, Vector3 centerPos, float dropArea, bool ___m_dropsEnabled) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0119: Unknown result type (might be due to invalid IL or missing references) Log.Debug("CharacterDrop_DropItems_Patch_Prefix"); if (!Cfg.allowLevels.Value || s_tempCreatureLevel <= 0) { return true; } foreach (KeyValuePair<GameObject, int> drop in drops) { for (int i = 0; i < drop.Value; i++) { Quaternion val = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f); Vector3 val2 = Random.insideUnitSphere * dropArea; GameObject obj = Object.Instantiate<GameObject>(drop.Key, centerPos + val2, val); ItemDrop component = obj.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null && (int)component.m_itemData.m_shared.m_itemType == 13) { Log.Debug("Adding level to trophy"); component.m_itemData.m_quality = s_tempCreatureLevel; component.m_itemData.m_shared.m_maxQuality = s_tempCreatureLevel; component.m_itemData.m_worldLevel = (byte)Game.m_worldLevel; } Rigidbody component2 = obj.GetComponent<Rigidbody>(); if (Object.op_Implicit((Object)(object)component2)) { Vector3 insideUnitSphere = Random.insideUnitSphere; if (insideUnitSphere.y < 0f) { insideUnitSphere.y = 0f - insideUnitSphere.y; } component2.AddForce(insideUnitSphere * 5f, (ForceMode)2); } } } return false; } } [HarmonyPatch(typeof(Ragdoll), "SaveLootList")] private static class Ragdoll_SaveLootList_Patch { [HarmonyPostfix] private static void Ragdoll_SaveLootList_Postfix(Ragdoll __instance, CharacterDrop characterDrop, ZNetView ___m_nview) { //IL_0086: Unknown result type (might be due to invalid IL or missing references) if (!Cfg.allowLevels.Value) { return; } Log.Debug("Ragdoll_SaveLootList_Patch_Postfix"); Character character = characterDrop.m_character; if ((Object)(object)character?.m_nview != (Object)null && !character.IsPlayer() && character.GetLevel() > 0) { ZDO zDO = __instance.m_nview.GetZDO(); if (zDO != null && zDO.IsValid()) { Log.Debug("Setting character level on Ragdoll zdo"); zDO.Set(TROPHY_LEVEL, character.GetLevel(), false); ZDOMan.instance.ForceSendZDO(zDO.m_uid); } } } } [HarmonyPatch(typeof(Ragdoll), "SpawnLoot")] private static class Ragdoll_SpawnLoot_Patch { [HarmonyPrefix] private static void Ragdoll_SpawnLoot_Prefix(Ragdoll __instance, Vector3 center) { if (Cfg.allowLevels.Value) { Log.Debug("Ragdoll_SpawnLoot_Patch_Postfix"); ZDO zDO = __instance.m_nview.GetZDO(); if (zDO.IsValid() && zDO.GetInt(TROPHY_LEVEL, 0) > 0) { s_tempCreatureLevel = zDO.GetInt(TROPHY_LEVEL, 0); } } } [HarmonyPostfix] private static void Ragdoll_SpawnLoot_Postfix(Ragdoll __instance, Vector3 center, ZNetView ___m_nview) { if (Cfg.allowLevels.Value) { Log.Debug("Ragdoll_SpawnLoot_Patch_Postfix"); s_tempCreatureLevel = 0; } } } [HarmonyPatch(typeof(BaseAI), "Flee")] private static class BaseAI_Flee_Patch { [HarmonyPrefix] private static bool BaseAI_Flee_Prefix(BaseAI __instance, float dt, Vector3 from) { ZDO val = __instance?.m_nview?.m_zdo; Vector3 val2 = default(Vector3); if (val != null && val.GetVec3(GUARD_PATROL_POINT, ref val2)) { return false; } return true; } } [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] private static class InventoryGrid_UpdateGui_Patch { [HarmonyPostfix] private static void InventoryGrid_UpdateGui_Postfix(InventoryGrid __instance) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 if (!Cfg.allowLevels.Value) { return; } foreach (ItemData allItem in __instance.m_inventory.GetAllItems()) { if ((int)allItem.m_shared.m_itemType != 13) { continue; } Element element = __instance.GetElement(allItem.m_gridPos.x, allItem.m_gridPos.y, __instance.m_width); if (((Behaviour)element.m_icon).enabled) { int num = allItem.m_quality - 1; if (num > 0) { ((Behaviour)element.m_quality).enabled = true; element.m_quality.text = num.ToString(); } } } } } private static DefendYourBase _modInstance; private static string Mod = "DefendYourBase"; private static string LcMod = Mod.ToLower(); public static Logging Log; public static Faction tamedGuardFaction = (Faction)StringExtensionMethods.GetStableHashCode("TamedGuard"); public static int GUARD_PATROL_POINT = StringExtensionMethods.GetStableHashCode("Tamed_Guard"); public static int WARD_FLAG = StringExtensionMethods.GetStableHashCode("Guarded_Ward"); public static string TROPHY_STRING = "DYB_CL_1847_"; public static int TROPHY_LEVEL = StringExtensionMethods.GetStableHashCode(TROPHY_STRING); private const string CANNOT_BE_SUMMONED = "This creature cannot be summoned as a guard."; internal static int s_tempCreatureLevel = 0; private static List<int> prefabHashes = new List<int>(); private static int prefabHash = 0; private static float privateAreaRadius = 0f; private static FileSystemWatcher mappingWatcher = null; private static List<string> hauntNames = new List<string>(); private static Harmony harmony = null; private static IDictionary<string, int> trophyCreatureMap = new Dictionary<string, int>(); private static Dictionary<Biome, int> biomeValues = new Dictionary<Biome, int> { { (Biome)1, 1 }, { (Biome)8, 2 }, { (Biome)2, 3 }, { (Biome)4, 4 }, { (Biome)16, 5 }, { (Biome)512, 6 }, { (Biome)32, 7 }, { (Biome)64, 8 }, { (Biome)256, 3 } }; private static Dictionary<string, int> trophyBiomeMap = new Dictionary<string, int>(); public static string creatureConfigString = "$item_trophy_greydwarf,1;$item_trophy_greydwarfbrute,1;$item_trophy_greydwarfshaman,1;$item_trophy_boar,1;$item_trophy_neck,1;$item_trophy_skeleton,1;$item_trophy_troll,2;$item_trophy_skeleton_hildir,3;$item_trophy_skeletonpoison,3;$item_trophy_wraith,3;$item_trophy_abomination,3;$item_trophy_blob,3;$item_trophy_draugr,3;$item_trophy_draugrelite,3;$item_trophy_leech,3;$item_trophy_surtling,3;$item_trophy_fenring,4;$item_trophy_cultist,4;$item_trophy_sgolem,4;$item_trophy_cultist_hildir,4;$item_trophy_ulv,4;$item_trophy_wolf,4;$item_trophy_goblin,5;$item_trophy_goblinbrute,5;$item_trophy_brutebro,5;$item_trophy_goblinshaman,5;$item_trophy_shamanbro,5;$item_trophy_deathsquito,5;$item_trophy_growth,5;$item_trophy_lox,5;$item_trophy_gjall,6;$item_trophy_dvergr,6;$item_trophy_seeker,6;$item_trophy_seeker_brute,6;$item_trophy_hatchling,4;$item_trophy_tick,6;$item_trophy_asksvin,7;$item_trophy_bonemaw,7;$item_trophy_charredarcher,7 ;$item_trophy_charredmage,7;$item_trophy_charredmelee,7;$item_trophy_fader,7;$item_trophy_fallenvalkyrie,7;$item_trophy_morgen,7;$item_trophy_volture,7;$item_trophy_serpent,3"; public static DefendYourBase GetInstance() { return _modInstance; } private void Awake() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown _modInstance = this; harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); harmony.PatchAll(Assembly.GetExecutingAssembly()); ConfigureMod(); Log.Info("Awake"); } private void ConfigureMod() { Log = Logging.GetLogger(Logging.LogLevels.Info, Mod); SetCreatureBiomeMapping(); BuildTrophyBiomeMap(creatureConfigString); Cfg.BepInExConfig((BaseUnityPlugin)(object)_modInstance); if (Cfg.creatureBiomeMapping.Value != creatureConfigString) { Cfg.creatureBiomeMapping.Value = creatureConfigString; } } private void OnDestroy() { harmony.UnpatchSelf(); } private static void BuildTrophyBiomeMap(string stringMapping) { Log.Debug("BuildTrophyBiomeMap"); trophyBiomeMap.Clear(); string[] array = stringMapping.Split(new char[1] { ';' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ',' }); if (array2.Length == 2 && int.TryParse(array2[1], out var result)) { string text = array2[0].Trim(); if (!trophyBiomeMap.ContainsKey(text)) { trophyBiomeMap.Add(text, result); Log.Debug($"Added trophy {text} with biome {result}"); } } } } public static void ChangeBiomeMapping(object s, EventArgs e) { SettingChangedEventArgs val = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null); Log.Debug("ChangeBiomeMapping " + val.ChangedSetting.Definition.Key); creatureConfigString = Cfg.creatureBiomeMapping.Value; BuildTrophyBiomeMap(Cfg.creatureBiomeMapping.Value); } public static bool SetCreatureBiomeMapping() { Log.Debug("SetCreatureBiomeMapping"); try { string assemblyPathedFile = Utils.GetAssemblyPathedFile("CreatureBiomeMap.txt"); if (!File.Exists(assemblyPathedFile)) { Log.Warning("Creature mapping file is missing. Using vanilla assignment."); return false; } string[] value = File.ReadAllLines(assemblyPathedFile); creatureConfigString = string.Join(";", value).Replace(" ", string.Empty); if (mappingWatcher == null) { mappingWatcher = Utils.CreateFileWatcher(assemblyPathedFile, ReloadMapping); Log.Debug("Created mapping file watcher"); } } catch (Exception) { Log.Warning("Can't read external creature mapping file. Using vanilla assignment."); return false; } return true; } private static void ReloadMapping() { Log.Debug("ReloadMapping"); if (SetCreatureBiomeMapping()) { Log.Debug("Reloading creature biome mapping from file"); if (Cfg.creatureBiomeMapping.Value != creatureConfigString) { Cfg.creatureBiomeMapping.Value = creatureConfigString; Log.Trace(Cfg.creatureBiomeMapping.Value); } } } private static void ReloadMapping(object sender, FileSystemEventArgs e) { ReloadMapping(); } public static void BuildTrophyCreatureMap() { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Invalid comparison between Unknown and I4 Log.Debug("BuildTrophyCreatureMap"); CharacterDrop val = default(CharacterDrop); ItemDrop val2 = default(ItemDrop); foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { Character component = (Character)(object)prefab.GetComponent<Humanoid>(); if ((Object)(object)component == (Object)null) { component = prefab.GetComponent<Character>(); } if (!((Object)(object)component != (Object)null) || !prefab.TryGetComponent<CharacterDrop>(ref val)) { continue; } foreach (Drop drop in val.m_drops) { if ((Object)(object)drop.m_prefab != (Object)null && drop.m_prefab.TryGetComponent<ItemDrop>(ref val2) && (int)val2.m_itemData.m_shared.m_itemType == 13 && !trophyCreatureMap.ContainsKey(val2.m_itemData.m_shared.m_name)) { trophyCreatureMap.Add(val2.m_itemData.m_shared.m_name, StringExtensionMethods.GetStableHashCode(((Object)prefab).name)); } } } } public static bool GetAllGuardedWardZDOs(List<ZDO> zdos) { Log.Debug("GetAllGuardedWardZDOs"); zdos.Clear(); foreach (ZDO value in ZDOMan.instance.m_objectsByID.Values) { if (value.IsValid() && value.GetBool(WARD_FLAG, false) && !zdos.Contains(value)) { zdos.Add(value); } } return zdos.Count > 0; } public static bool GetAllTamedZDOs(List<ZDO> zdos) { Log.Debug("GetAllTamedZDOs"); foreach (ZDO value in ZDOMan.instance.m_objectsByID.Values) { if (value.IsValid() && value.GetBool(ZDOVars.s_tamed, false)) { zdos.Add(value); } } return zdos.Count > 0; } public static bool TryGetGuardZDOs(List<ZDO> guards) { Log.Debug("TryGetGuardZDOs"); guards.Clear(); List<ZDO> list = new List<ZDO>(); Log.Debug("Searching for tamed Guard ZDOs"); GetAllTamedZDOs(list); Vector3 val = default(Vector3); foreach (ZDO item in list) { if (item.GetVec3(GUARD_PATROL_POINT, ref val)) { Log.Debug("Found bound Guard ZDO"); guards.Add(item); } } return guards.Count > 0; } private static bool CheckPiecesInRadius(Vector3 point, float dist, int piecesMin, int stationsMin, int bedsMin) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) Log.Debug("CheckPiecesInRadius"); int num = 0; int num2 = 0; int num3 = 0; List<WearNTear> allInstances = WearNTear.GetAllInstances(); if (allInstances.Count < piecesMin + stationsMin) { return false; } CraftingStation val = default(CraftingStation); Bed val2 = default(Bed); foreach (WearNTear item in allInstances) { if (Vector3.Distance(point, ((Component)item).transform.position) < dist) { num++; if (((Component)item).gameObject.TryGetComponent<CraftingStation>(ref val)) { num2++; } if (((Component)item).gameObject.TryGetComponent<Bed>(ref val2)) { num3++; } } if (num >= piecesMin && num2 >= stationsMin && num3 >= bedsMin) { return true; } } Log.Debug($"Base check failed: {num} pieces & {num2} stations {num3} beds found within radius {Cfg.proximityCheckRadius.Value}"); return false; } private static bool CheckGuardBiome(Vector3 location, string trophyName) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) Log.Debug("CheckGuardBiome"); if (biomeValues.TryGetValue(Heightmap.FindBiome(location), out var value) && value > 0 && trophyBiomeMap.TryGetValue(trophyName, out var value2) && value2 > 0) { Log.Debug($"Biome value heightmap {value} guard {value2} "); return value2 <= value; } return false; } private static int GetMaxBossLevel() { int num = 0; ZoneSystem instance = ZoneSystem.instance; if (instance.GetGlobalKey((GlobalKeys)32)) { num++; } if (instance.GetGlobalKey((GlobalKeys)35)) { num++; } if (instance.GetGlobalKey((GlobalKeys)36)) { num++; } if (instance.GetGlobalKey((GlobalKeys)33)) { num++; } if (instance.GetGlobalKey((GlobalKeys)34)) { num++; } if (instance.GetGlobalKey("defeated_queen")) { num++; } if (instance.GetGlobalKey("defeated_fader")) { num++; } return num; } private static bool CheckBossLevel(Vector3 location, string trophyName) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) Log.Debug("CheckBossLevel"); if (biomeValues.TryGetValue(Heightmap.FindBiome(location), out var value) && value > 0 && trophyBiomeMap.TryGetValue(trophyName, out var value2) && value2 > 0) { int maxBossLevel = GetMaxBossLevel(); Log.Debug($"Biome value heightmap {value} guard {value2} boss {maxBossLevel} "); return value2 <= maxBossLevel; } return false; } private static bool SetUpGuard(GameObject guard, float radius, Vector3 patrolPoint, int level = 0) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) Log.Debug("SetUpGuard"); if ((Object)(object)guard == (Object)null) { Log.Warning("Guard is missing in action. Can't setup"); return false; } Character component = guard.GetComponent<Character>(); if ((Object)(object)component == (Object)null) { Log.Warning("Guard is missing Character component. Can't setup"); return false; } MonsterAI component2 = guard.GetComponent<MonsterAI>(); if ((Object)(object)component2 == (Object)null) { Log.Warning("Guard is missing useable monster AI component. Can't setup"); return false; } component.SetLevel(level); component.SetTamed(true); ((BaseAI)component2).m_patrol = true; ((BaseAI)component2).SetPatrolPoint(patrolPoint); ((BaseAI)component2).m_viewAngle = Mathf.Max(120f, ((BaseAI)component2).m_viewAngle); ((BaseAI)component2).m_viewRange = Mathf.Max(30f, ((BaseAI)component2).m_viewRange); component2.m_alertRange = Math.Max(30f, component2.m_alertRange); component2.m_maxChaseDistance = 0f; component2.m_circleTargetInterval = 0f; component2.m_circleTargetDuration = 2f; component2.m_circleTargetDistance = 4f; component.m_damageModifiers.m_fire = (DamageModifier)3; component.m_tolerateSmoke = true; if (Cfg.allowLevels.Value && level > 0) { component.m_level = level; } CharacterDrop val = default(CharacterDrop); if (guard.TryGetComponent<CharacterDrop>(ref val)) { Object.Destroy((Object)(object)val); } DebugUtils.ObjectInspector(component.m_damageModifiers); return true; } public static bool TryGetGuardInScene(ZDO zdo, out GameObject guard) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) Log.Debug("TryGetGuardInScene"); guard = null; if (ZNetScene.instance.HaveInstance(zdo)) { Log.Debug("Guard has an instance"); guard = ZNetScene.instance.FindInstance(zdo.m_uid); if ((Object)(object)guard != (Object)null) { Log.Debug("Found Guard instance in scene"); return true; } } return false; } private static void SendOneDestroyed(ZDOID zdoid) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_000e: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(1); val.Write(zdoid); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "DestroyZDO", new object[1] { val }); } private static void ConsumeItem(Humanoid user, ItemData item) { user.GetInventory().RemoveOneItem(item); } private static void SendAllDestroyed(List<ZDO> zdos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(zdos.Count); foreach (ZDO zdo in zdos) { val.Write(zdo.m_uid); } ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "DestroyZDO", new object[1] { val }); } }