using 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.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; using neobotics.ModSdk; [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("HUDCompass")] [assembly: AssemblyConfiguration("Deploy")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+2f5a08b95604d67cc60886abaebc12e51eace539")] [assembly: AssemblyProduct("HUDCompass")] [assembly: AssemblyTitle("HUDCompass")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] public sealed class ConfigurationManagerAttributes { public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput); public bool? ShowRangeAsPercent; public Action 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 ObjToStr; public Func StrToObj; } namespace neobotics.ModSdk { public class AudioHelper : MonoBehaviour { private readonly Dictionary audioClips = new Dictionary(); private Logging logger; public void Awake() { logger = Logging.GetLogger(); logger.Debug("AudidHelper.Awake"); } public void Start() { logger.Debug("AudioHelper.Start"); ZRoutedRpc.instance.Register("NeoPlayClip", (Action)RPC_NeoPlayClip); } public void RPC_NeoPlayClip(long sender, Vector3 sourcePoint, string clipName) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (ZNet.instance.IsDedicated()) { return; } try { NeoPlayClip(sourcePoint, clipName); } catch (Exception e) { logger.Error(e, stackTrace: false); } } public void Play(Vector3 sourcePoint, string clipName) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "NeoPlayClip", new object[2] { sourcePoint, clipName }); } public void NeoPlayClip(Vector3 sourcePoint, string clipName) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)Player.m_localPlayer).transform.position; NeoPlayClip(sourcePoint, position, clipName); } public void NeoPlayClip(Vector3 sourcePoint, Vector3 targetPoint, string clipName) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (!audioClips.TryGetValue(clipName.ToLower(), out var value)) { logger.Warning("Couldn't find audio clip for " + clipName); return; } Vector3 val = sourcePoint - targetPoint; Vector3 normalized = ((Vector3)(ref val)).normalized; float num = (Vector3.Distance(sourcePoint, targetPoint) + 1f) / 10f; AudioSource.PlayClipAtPoint(value, targetPoint + normalized * num, 1f); } public float GetClipDuration(string clipName) { if (!audioClips.TryGetValue(clipName.ToLower(), out var value)) { return -1f; } return value.length; } internal void LoadAudioResources(string resourceFolder) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) audioClips.Clear(); logger.Debug("LoadAudioResources"); string[] files = Directory.GetFiles(resourceFolder, "*.*", SearchOption.TopDirectoryOnly); foreach (string text in files) { string text2 = Path.GetExtension(text).ToLowerInvariant(); AudioType val = (AudioType)0; if (!(text2 == ".wav")) { if (text2 == ".mp3") { val = (AudioType)13; } } else { val = (AudioType)20; } if ((int)val != 0) { ((MonoBehaviour)this).StartCoroutine(LoadExternalClip(text, val)); } } } private IEnumerator LoadExternalClip(string filePath, AudioType type) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) string uri = new Uri(filePath).AbsoluteUri; string clipName = Path.GetFileName(filePath).ToLowerInvariant(); UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(uri, type); yield return req.SendWebRequest(); if ((int)req.result == 1) { AudioClip content = DownloadHandlerAudioClip.GetContent(req); audioClips[clipName] = content; logger.Debug("Loaded external audio: " + clipName); } else { logger.Warning("Failed to load external audio: " + uri); } } } internal class CircularList { private List circle; private int index; public int Index => index; public CircularList(List source, T startingElement) { circle = new List(source); index = circle.FindIndex((T x) => x.Equals(startingElement)); } public T Next() { index = ((index < circle.Count - 1) ? (index + 1) : 0); return circle[index]; } public T Previous() { index = ((index > 0) ? (index - 1) : (circle.Count - 1)); return circle[index]; } } public static class ConfigFolderHelper { private const string ROOT = "Neobotics"; public static string GetOrCreateModConfigFolder(string modName) { string text = Path.Combine(Paths.ConfigPath, "Neobotics", modName); Directory.CreateDirectory(text); return text; } } public class ConfigMock { public bool Value { get; set; } } public class CrossPlatformRandom : Random { private const int LCG_MULTIPLIER = 134775813; private const int LCG_INCREMENT = 1; private int _seed; public float value => (float)NextDouble(); public CrossPlatformRandom() { Random random = new Random(); _seed = random.Next(); } public CrossPlatformRandom(int seed) { _seed = seed; } public float Range(int min, int max) { return Next(min, max); } public float Range(float min, float max) { return Mathf.Lerp(min, max, (float)NextDouble()); } private int GetNext() { _seed = _seed * 134775813 + 1; return _seed; } public override int Next() { return Next(int.MaxValue); } public override int Next(int maxValue) { if (maxValue < 0) { throw new ArgumentOutOfRangeException("maxValue is less than zero."); } return (int)((long)(uint)GetNext() * (long)(uint)maxValue >>> 32); } public override int Next(int minValue, int maxValue) { if (minValue > maxValue) { throw new ArgumentOutOfRangeException("minValue is greater than maxValue."); } return minValue + Next(maxValue - minValue); } public override double NextDouble() { return Sample(); } protected override double Sample() { return (double)Next() / 2147483647.0; } } internal class CustomDataWrapper { private Dictionary playerData; private Dictionary Data { get; set; } public CustomDataWrapper(Dictionary sourceData, string keyPrefix) { CustomDataWrapper customDataWrapper = this; playerData = sourceData; Data = new Dictionary(); sourceData.Keys.ToList().ForEach(delegate(string key) { if (key.StartsWith(keyPrefix)) { customDataWrapper.Data.Add(key, sourceData[key]); } }); } public void Add(string key, string value) { Data.Add(key, value); playerData.Add(key, value); } public bool Remove(string key) { return Data.Remove(key) & playerData.Remove(key); } public void Set(string key, string value) { if (Data.ContainsKey(key)) { Data[key] = value; } else { Data.Add(key, value); } if (playerData.ContainsKey(key)) { playerData[key] = value; } else { playerData.Add(key, value); } } public string Get(string key) { if (Data.ContainsKey(key)) { return Data[key]; } return null; } public bool ContainsKey(string key) { return Data.ContainsKey(key); } public void PreSaveSync() { foreach (KeyValuePair datum in Data) { if (!playerData.ContainsKey(datum.Key)) { playerData.Add(datum.Key, datum.Value); } } } } internal class DebugUtils { internal 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)("Object: " + o.ToString() + " Type " + type.Name)); PropertyInfo[] properties = type.GetProperties(bindingAttr); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.CanRead) { Debug.Log((object)$"Property: {type.Name}.{propertyInfo.Name} = {propertyInfo.GetValue(o)}"); continue; } Debug.Log((object)("Property: " + type.Name + "." + propertyInfo.Name + " is write-only")); } FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo field in fields) { FieldPrinter(o, type, field); } } internal 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)("Method: " + 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)); } } internal static void GameObjectInspector(GameObject go) { if ((Object)(object)go == (Object)null) { Debug.Log((object)"\n\nGame Object is null"); return; } Debug.Log((object)("\n\nInspecting GameObject " + ((Object)go).name)); ObjectInspector(go); Component[] componentsInChildren = go.GetComponentsInChildren(); if (componentsInChildren.Length == 0) { return; } Component[] array = componentsInChildren; foreach (Component c in array) { try { ComponentInspector(c); } catch (Exception) { } } } internal static void PrintList(List l) { foreach (T item in l) { Debug.Log((object)item.ToString()); } } internal static void ComponentInspector(Component c) { string obj = ((c != null) ? ((Object)c).name : null); object obj2; if (c == null) { obj2 = null; } else { Transform transform = c.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(c); } internal 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}"); } } internal static void PrintInventory() { foreach (ItemData allItem in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems()) { Debug.Log((object)allItem.m_shared.m_name); } } internal static void PrintAllObjects() { ZNetScene.instance.m_prefabs.ForEach(delegate(GameObject x) { Debug.Log((object)("GameObject " + ((Object)x).name)); }); } internal static void PrintAllCharacters() { Character.GetAllCharacters().ForEach(delegate(Character x) { Debug.Log((object)("Character " + ((Object)x).name)); }); } internal 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 : DelegatedConfigEntryBase { private ConfigEntry _entry; private EventHandler rootHandler; private Action clientDelegate; private Logging Log; public ConfigEntry 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)null, useServerDelegate) { } public DelegatedConfigEntry(Action 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown Logging.GetLogger().Trace("ServerDelegate"); _entry.SettingChanged -= rootHandler; ZNet instance = ZNet.instance; bool? flag = ((instance != null) ? new bool?(instance.IsServer()) : ((bool?)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) if (ConfigEntry is ConfigEntry val) { return InputEvaluator.IsPressed(val.Value); } 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) if (ConfigEntry is ConfigEntry val) { return InputEvaluator.IsDown(val.Value); } 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) if (ConfigEntry is ConfigEntry val) { return InputEvaluator.IsReleased(val.Value); } 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 detectionSet = new Dictionary(); private static Dictionary unpatchMods = new Dictionary(); public static IReadOnlyDictionary DetectionSet => detectionSet; public static void GetDetectionSet(Dictionary harmonyIds) { Logging logger = Logging.GetLogger(); foreach (KeyValuePair 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 AddToUnpatch(string key) { if (detectionSet.ContainsKey(key)) { unpatchMods.Add(key, detectionSet[key]); } } public static void UnpatchMods(Harmony harmony) { Logging logger = Logging.GetLogger(); foreach (KeyValuePair unpatchMod in unpatchMods) { logger.Warning("Not compatible with " + unpatchMod.Value); Harmony.UnpatchID(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 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 ImageHelper { private readonly string externalFolder; private readonly Logging logger; private bool isEmbedded; public ImageHelper(string externalFolder) : this(externalFolder, embedded: false) { } public ImageHelper(string externalFolder, bool embedded = true) { this.externalFolder = externalFolder; logger = Logging.GetLogger(); isEmbedded = embedded; } public Sprite LoadSprite(string name, int width, int height, bool linear = false, float pixelsPerUnit = 100f) { logger.Debug("Reading image and creating sprite " + name); if (TryLoadImage(name, width, height, linear, out var image)) { return LoadSprite(image, pixelsPerUnit); } return null; } public Sprite LoadSprite(Texture2D texture, float pixelsPerUnit = 100f) { return LoadSprite(texture, ((Object)texture).name, ((Texture)texture).width, ((Texture)texture).height, pixelsPerUnit); } public Sprite LoadSprite(Texture2D texture, string name, float width, float height, float pixelsPerUnit = 100f) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)texture == (Object)null) { return null; } if (string.IsNullOrWhiteSpace(name)) { name = ((Object)texture).name; } logger.Debug("Creating sprite " + name + " from existing texture"); Sprite obj = Sprite.Create(texture, new Rect(0f, 0f, width, height), Vector2.zero, pixelsPerUnit); if ((Object)(object)obj == (Object)null) { throw new ApplicationException("Can't create sprite " + name); } ((Object)obj).name = name; return obj; } public bool TryLoadImage(string name, int width, int height, bool linear, out Texture2D image) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown image = null; byte[] array = null; if (isEmbedded) { Stream manifestResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(externalFolder + "." + name); if (manifestResourceStream == null) { throw new FileNotFoundException("Can't find " + name + " in " + externalFolder); } array = new byte[manifestResourceStream.Length]; manifestResourceStream.Read(array, 0, (int)manifestResourceStream.Length); } else { string text = Path.Combine(externalFolder, name); logger.Debug("Reading external file " + text); if (!File.Exists(text)) { throw new FileNotFoundException("Cannot find image " + name); } array = File.ReadAllBytes(text); } Texture2D val = new Texture2D(width, height, (TextureFormat)4, true, linear); if (!ImageConversion.LoadImage(val, array, false)) { throw new FileLoadException("Can't load image " + name); } image = val; return true; } } internal class InputCycler { private static InputCycler _instance; private bool useMouseWheel; private DelegatedConfigEntry keyAdvance; private DelegatedConfigEntry keyReferse; public static InputCycler Instance { get { if (_instance == null) { _instance = new InputCycler(); } return _instance; } } private InputCycler() { } public void Init(bool useMouseWheel, DelegatedConfigEntry keyAdvance, DelegatedConfigEntry keyReverse = null) { this.useMouseWheel = useMouseWheel; this.keyAdvance = keyAdvance; keyReferse = keyReverse; } } internal static class InputEvaluator { public unsafe static bool IsPressed(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0056: Unknown result type (might be due to invalid IL or missing references) object obj = KeyboardShortcut.Empty; if (((object)(*(KeyboardShortcut*)(&shortcut))/*cast due to .constrained prefix*/).Equals(obj)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if ((int)modifier != 0 && !Input.GetKey(modifier)) { return false; } } return Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey); } public unsafe static bool IsDown(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0056: Unknown result type (might be due to invalid IL or missing references) object obj = KeyboardShortcut.Empty; if (((object)(*(KeyboardShortcut*)(&shortcut))/*cast due to .constrained prefix*/).Equals(obj)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if ((int)modifier != 0 && !Input.GetKey(modifier)) { return false; } } return Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey); } public unsafe static bool IsReleased(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0056: Unknown result type (might be due to invalid IL or missing references) object obj = KeyboardShortcut.Empty; if (((object)(*(KeyboardShortcut*)(&shortcut))/*cast due to .constrained prefix*/).Equals(obj)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if ((int)modifier != 0 && !Input.GetKeyUp(modifier)) { return false; } } return Input.GetKeyUp(((KeyboardShortcut)(ref shortcut)).MainKey); } } public class IterativeStopwatch : Stopwatch { private double startMillis; private Logging Log = Logging.GetLogger(); public long Iterations { get; private set; } public double IterationMicroseconds { get; private set; } public double TotalElapsedMicroseconds { get; private set; } public double IterationMilliseconds { get; private set; } public double TotalElapsedMilliseconds { get; private set; } public double AverageMicroseconds { get; private set; } public double AverageMilliseconds { get; private set; } public IterativeStopwatch() { Iterations = 0L; } public new void Start() { startMillis = base.Elapsed.TotalMilliseconds; base.Start(); } public new void Stop() { if (base.IsRunning) { base.Stop(); Iterations++; IterationMilliseconds = base.Elapsed.TotalMilliseconds - startMillis; IterationMicroseconds = IterationMilliseconds * 1000.0; TotalElapsedMilliseconds = base.Elapsed.TotalMilliseconds; TotalElapsedMicroseconds = base.Elapsed.TotalMilliseconds * 1000.0; AverageMilliseconds = TotalElapsedMilliseconds / (double)Iterations; AverageMicroseconds = TotalElapsedMicroseconds / (double)Iterations; } } public new void Reset() { startMillis = 0.0; Iterations = 0L; base.Reset(); } public new void Restart() { startMillis = 0.0; Iterations = 0L; base.Restart(); } } public static class JsonHelper { [Serializable] private class JsonWrapper { public T[] Items; } public static T[] FromJson(string json) { return JsonUtility.FromJson>(json).Items; } public static string ToJson(T[] array) { return JsonUtility.ToJson((object)new JsonWrapper { Items = array }); } public static string ToJson(T[] array, bool prettyPrint) { return JsonUtility.ToJson((object)new JsonWrapper { Items = array }, prettyPrint); } } public class Logging { internal enum LogLevels { Critical, Error, Warning, Info, Debug, Trace } private static Logging _instance; public static Logging Instance { get { if (_instance == null) { throw new InvalidOperationException("Logging.Instance was accessed before initialization. Call Logging.Initialize() in your mod's startup code first."); } return _instance; } private set { _instance = value; } } internal LogLevels LogLevel { get; set; } internal string ModName { get; private set; } private Logging(LogLevels level, string name) { LogLevel = level; ModName = name; } internal static Logging Initialize(LogLevels level, string name) { if (_instance != null) { Instance.Warning("Logger is already initialized. Using existing logger"); return _instance; } Instance = new Logging(level, name); return _instance; } internal static Logging GetLogger(LogLevels level, string name) { if (_instance == null) { Initialize(level, name); } return Instance; } internal static Logging GetLogger() { return Instance; } internal void Trace(string msg) { if (LogLevel >= LogLevels.Trace) { Debug.Log((object)Message(msg)); } } internal void Debug(string msg) { if (LogLevel >= LogLevels.Debug) { Debug.Log((object)Message(msg)); } } internal void Info(string msg) { if (LogLevel >= LogLevels.Info) { Debug.Log((object)Message(msg)); } } internal void Warning(string msg) { if (LogLevel >= LogLevels.Warning) { Debug.LogWarning((object)Message(msg)); } } internal void Error(string msg) { if (LogLevel >= LogLevels.Error) { Debug.LogWarning((object)Message(msg)); } } internal void Error(Exception e) { Error(e, stackTrace: false); } internal void Error(Exception e, bool stackTrace) { if (LogLevel >= LogLevels.Error) { Warning(Message(e.Message)); if (stackTrace) { Warning(e.StackTrace); } } } internal void Critical(Exception e) { if (LogLevel >= LogLevels.Critical) { Debug(Message(e.Message)); Error(e.StackTrace); } } private string Message(string msg) { return ModName + ": " + msg; } internal bool Testing() { return Instance.LogLevel >= LogLevels.Debug; } internal static void ChangeLogging(object s, EventArgs e) { ConfigEntry val = s as ConfigEntry; if (_instance != null) { Instance.LogLevel = val.Value; Instance.Info($"Change {((ConfigEntryBase)val).Definition.Key} to {val.Value}"); } } } public static class ModResourceBootstrap { public static string InitializeModResources(Type pluginType, string modName) { string orCreateModConfigFolder = ConfigFolderHelper.GetOrCreateModConfigFolder(modName); string? name = pluginType.Assembly.GetName().Name; if (!Directory.Exists(orCreateModConfigFolder)) { Directory.CreateDirectory(orCreateModConfigFolder); Logging.Instance.Debug("Created subfolder layout: " + orCreateModConfigFolder); } string text = name + ".Resources."; Logging.Instance.Debug("Scanning assembly for standard prefix: " + text); ExtractResources(pluginType.Assembly, text, orCreateModConfigFolder); return orCreateModConfigFolder; } private static void ExtractResources(Assembly asm, string prefix, string targetFolder) { string[] manifestResourceNames = asm.GetManifestResourceNames(); foreach (string text in manifestResourceNames) { if (!text.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { continue; } string text2 = text.Substring(prefix.Length); string text3 = Path.Combine(targetFolder, text2); if (File.Exists(text3)) { continue; } try { Logging.Instance.Debug("Extracting asset: " + text2 + " -> " + text3); using Stream stream = asm.GetManifestResourceStream(text); if (stream == null) { Logging.Instance.Error("Could not access resource stream for: " + text); continue; } using FileStream destination = File.Create(text3); stream.CopyTo(destination); } catch (Exception ex) { Logging.Instance.Error("Failed to unpack embedded asset " + text2 + ": " + ex.Message); } } } } public class ServerConfiguration { [HarmonyPatch(typeof(ZNet), "StopAll")] private static class ZNet_Shutdown_Patch { [HarmonyPrefix] private static void ZNet_StopAll_Prefix(ZNet __instance) { if (_instance != null) { Log.Debug("ZNet_StopAll_Patch_Prefix"); _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("ClientConfigReceiver." + GetPluginGuid(), (Action)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 ServerDelegatedEntries = new List(); 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 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; } } } public class Utils { public static TEnum Guardrails(string value, TEnum enumDefault) where TEnum : struct { if (Enum.TryParse(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 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 PinData GetClosestPin(Vector3 pos, float radius, PinType pType) { //IL_004b: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) PinData result = null; float num = float.MaxValue; float num2 = radius * radius; if ((Object)(object)Minimap.instance != (Object)null) { foreach (PinData pin in Minimap.instance.m_pins) { if ((Object)(object)pin.m_uiElement != (Object)null && pin.m_type == pType) { float num3 = DistanceSqrXZ(pos, pin.m_pos); if (Logging.Instance.LogLevel >= Logging.LogLevels.Debug) { Logging.Instance.Debug($"Testing for pin at {pin.m_pos} within radius {radius} from {pos}"); } if (num3 < num2 && num3 < num) { Logging.Instance.Debug("Pin is within radius"); num = num3; result = pin; } } } } return result; } public static float DistanceSqr(Vector3 v0, Vector3 v1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0007: Unknown result type (might be due to invalid IL or missing references) Vector3 val = v1 - v0; return ((Vector3)(ref val)).sqrMagnitude; } 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 Vector3 ClosestPoint(Vector3 point, IEnumerable collection, Func selector) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) Vector3 result = default(Vector3); float num = float.MaxValue; foreach (T item in collection) { Vector3 val = selector(item); Vector3 val2 = val - point; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = val; } } return result; } public static T ClosestObject(Vector3 point, IEnumerable collection, Func selector) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) T result = default(T); float num = float.MaxValue; foreach (T item in collection) { Vector3 val = selector(item) - point; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = item; } } return result; } public static Vector3 ClosestPointXZ(Vector3 point, IEnumerable collection, Func selector) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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) //IL_003b: 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) Vector3 result = default(Vector3); float num = float.MaxValue; foreach (T item in collection) { Vector3 val = selector(item); float num2 = DistanceSqrXZ(val, point); if (num2 < num) { num = num2; result = val; } } return result; } public static T ClosestObjectXZ(Vector3 point, IEnumerable collection, Func selector) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) T result = default(T); float num = float.MaxValue; foreach (T item in collection) { float num2 = DistanceSqrXZ(selector(item), point); if (num2 < num) { num = num2; result = item; } } return result; } 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) { Localization.instance.AddWord("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.op_Implicit((Object)(object)prefab) && prefab.TryGetComponent(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()) { if (((object)allCharacter.GetZDOID()/*cast due to .constrained prefix*/).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 GetGameObjectsOfType(Type t) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) List list = new List(); Object[] array = Object.FindObjectsByType(t, (FindObjectsSortMode)0); 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 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> list = new List>(); List gameObjectsOfTypeInRange = GetGameObjectsOfTypeInRange(t, point, radius); if (gameObjectsOfTypeInRange.Count > 0) { foreach (GameObject item in gameObjectsOfTypeInRange) { list.Add(new KeyValuePair(item, Vector3.Distance(item.transform.position, point))); } list.Sort((KeyValuePair pair1, KeyValuePair pair2) => pair1.Value.CompareTo(pair2.Value)); return list.ConvertAll((KeyValuePair x) => x.Key); } return null; } public static List 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) float radiusSq = radius * radius; return GetGameObjectsOfType(t).Where(delegate(GameObject x) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val = x.transform.position - point; return ((Vector3)(ref val)).sqrMagnitude < radiusSq; }).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 GetDelimitedStringAsList(string delimitedString, char delimiter) { List list = new List(); 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 bool IsPrefabInScene(string prefabName) { return IsPrefabInScene(StringExtensionMethods.GetStableHashCode(prefabName)); } public static bool IsPrefabInScene(int prefabHash) { ZNetScene instance = ZNetScene.instance; return (Object)(object)((instance != null) ? instance.GetPrefab(prefabHash) : null) != (Object)null; } public static bool TryGetPrefab(string prefabName, out GameObject prefab) { return TryGetPrefab(StringExtensionMethods.GetStableHashCode(prefabName), out prefab); } public static bool TryGetPrefab(int prefabHash, out GameObject prefab) { prefab = GetPrefabByHash(prefabHash); return (Object)(object)prefab != (Object)null; } public static GameObject GetPrefabByHash(int prefabHash) { GameObject val = null; Logging logger = Logging.GetLogger(); 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; } val = ObjectDB.instance.GetItemPrefab(prefabHash); if ((Object)(object)val != (Object)null) { logger.Debug("Found prefab in ObjectDB"); return val; } logger.Debug("No prefab found"); return val; } public static GameObject GetPrefab(int prefabHash) { return GetPrefabByHash(prefabHash); } public static GameObject GetPrefab(string prefabName) { return GetPrefabByHash(StringExtensionMethods.GetStableHashCode(prefabName)); } public static void LoadPrefabInScene(GameObject prefab) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name); if ((Object)(object)ZNetScene.instance != (Object)null && !ZNetScene.instance.m_namedPrefabs.ContainsKey(stableHashCode)) { ZNetScene.instance.m_prefabs.Add(prefab); ZNetScene.instance.m_namedPrefabs[stableHashCode] = prefab; } } public static GameObject SpawnObject(string prefabName, Vector3 position, Quaternion rotation, bool persist = true) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (TryGetPrefab(prefabName, out var prefab)) { return SpawnObject(prefab, position, rotation, persist); } return null; } public static GameObject SpawnObject(GameObject prefab, Vector3 position, Quaternion rotation, bool persist = true) { //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) LoadPrefabInScene(prefab); GameObject val = Object.Instantiate(prefab, position, rotation); ZNetView val2 = default(ZNetView); if (persist && val.TryGetComponent(ref val2)) { val2.GetZDO().Persistent = true; } return val; } public static string SerializeFromDictionary(string delimp, string delimc, IDictionary dict) { if (dict == null) { return null; } IEnumerable values = dict.Select(delegate(KeyValuePair kvp) { KeyValuePair 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(string serializedString, string delimp, string delimc, ref IDictionary 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(array2[0]), TypedValue(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(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 Color IntToColor(int rgba) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) float num = (float)((rgba >> 16) & 0xFF) / 255f; float num2 = (float)((rgba >> 8) & 0xFF) / 255f; float num3 = (float)(rgba & 0xFF) / 255f; float num4 = (float)((rgba >> 24) & 0xFF) / 255f; return new Color(num, num2, num3, num4); } public static bool CopyComponentToGameObject(Component original, ref GameObject destination) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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.op_Implicit((Object)(object)val)) { val = destination.AddComponent(type); } if (!Object.op_Implicit((Object)(object)val)) { logger.Debug("Destination component is null"); return false; } Component val2 = (Component)Activator.CreateInstance(type); if (!Object.op_Implicit((Object)(object)val2)) { logger.Debug("Destination component is null"); return false; } if (!Object.op_Implicit((Object)(object)val2)) { 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"); 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; } } } namespace neobotics.ValheimMods { internal class Cfg { public static DelegatedConfigEntry enableCompass; public static DelegatedConfigEntry showHideCompass; public static DelegatedConfigEntry compassToggle; public static ConfigEntry colorCompass = null; public static ConfigEntry colorPins = null; public static ConfigEntry colorCenterMark = null; public static ConfigEntry compassUsePlayerDirection = null; public static ConfigEntry compassYOffset = null; public static ConfigEntry compassScale = null; public static ConfigEntry scalePinsMin = null; public static ConfigEntry scalePins = null; public static ConfigEntry compassShowCenterMark = null; public static ConfigEntry useDynamicColorsOnCompass = null; public static ConfigEntry hideCompassWhileMapOpen; public static DelegatedConfigEntry ignoredPinNames; public static DelegatedConfigEntry ignoredPinTypes; public static DelegatedConfigEntry alwaysVisible; public static DelegatedConfigEntry distancePinsMin; public static DelegatedConfigEntry distancePinsMax; public static DelegatedConfigEntry playerPinBehavior; public static DelegatedConfigEntry compassShowMyPlayerPin; public static DelegatedConfigEntry showShips; public static DelegatedConfigEntry showCarts; public static DelegatedConfigEntry showPortals; public static DelegatedConfigEntry showDynamicPinsOnMap; public static DelegatedConfigEntry showDynamicPinsOnCompass; public static DelegatedConfigEntry showDynamicNamesOnMap; public static DelegatedConfigEntry playerPinUpdateInterval; public static DelegatedConfigEntry hideCompassIndoors; public static DelegatedConfigEntry hideCompassInCombat; public static DelegatedConfigEntry hideCompassInCombatDelay; public static DelegatedConfigEntry hideCompassInFog; public static DelegatedConfigEntry hideCompassInMist; public static DelegatedConfigEntry hideCompassWhileRunning; public static ConfigEntry activePortalColor = null; public static ConfigEntry portalColor = null; public static ConfigEntry shipColor = null; public static ConfigEntry cartColor = null; public static ConfigEntry autoDeleteDeathPin = null; public static DelegatedConfigEntry debugLevel; private static KeyCode[] keyModifiers = (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }; public static KeyboardShortcut keyConfigItemDefault = new KeyboardShortcut((KeyCode)99, keyModifiers); public static void BepInExConfig(BaseUnityPlugin _instance) { //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Expected O, but got Unknown //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Expected O, but got Unknown //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_052a: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Expected O, but got Unknown //IL_05c7: Unknown result type (might be due to invalid IL or missing references) //IL_05eb: Unknown result type (might be due to invalid IL or missing references) //IL_060f: Unknown result type (might be due to invalid IL or missing references) //IL_0633: Unknown result type (might be due to invalid IL or missing references) //IL_070d: Unknown result type (might be due to invalid IL or missing references) //IL_0717: Expected O, but got Unknown //IL_07cb: Unknown result type (might be due to invalid IL or missing references) ServerConfiguration.Instance.Setup(_instance.Config, _instance); enableCompass = new DelegatedConfigEntry(HUDCompass.SettingChanged_EnableCompass, useServerDelegate: true); showHideCompass = new DelegatedConfigEntry(HUDCompass.SettingChanged_ShowCompass); compassToggle = new DelegatedConfigEntry(); ignoredPinNames = new DelegatedConfigEntry(HUDCompass.SettingChanged_IgnoredNames, useServerDelegate: true); ignoredPinTypes = new DelegatedConfigEntry(HUDCompass.SettingChanged_IgnoredTypes, useServerDelegate: true); alwaysVisible = new DelegatedConfigEntry(HUDCompass.SettingChanged_VisibleBehavior, useServerDelegate: true); distancePinsMin = new DelegatedConfigEntry(useServerDelegate: true); distancePinsMax = new DelegatedConfigEntry(useServerDelegate: true); playerPinBehavior = new DelegatedConfigEntry(HUDCompass.SettingChanged_PlayerPinBehavior, useServerDelegate: true); compassShowMyPlayerPin = new DelegatedConfigEntry(HUDCompass.SettingChanged_ShowMyPlayerPin); showShips = new DelegatedConfigEntry(useServerDelegate: true); showCarts = new DelegatedConfigEntry(useServerDelegate: true); showPortals = new DelegatedConfigEntry(useServerDelegate: true); showDynamicPinsOnMap = new DelegatedConfigEntry(DynamicMapMarkers.SettingChanged_MapPins, useServerDelegate: true); showDynamicNamesOnMap = new DelegatedConfigEntry(DynamicMapMarkers.SettingChanged_MapPins); showDynamicPinsOnCompass = new DelegatedConfigEntry(useServerDelegate: true); playerPinUpdateInterval = new DelegatedConfigEntry(useServerDelegate: true); hideCompassIndoors = new DelegatedConfigEntry(useServerDelegate: true); hideCompassInCombat = new DelegatedConfigEntry(useServerDelegate: true); hideCompassInCombatDelay = new DelegatedConfigEntry(useServerDelegate: true); hideCompassInFog = new DelegatedConfigEntry(useServerDelegate: true); hideCompassInMist = new DelegatedConfigEntry(useServerDelegate: true); hideCompassWhileRunning = new DelegatedConfigEntry(useServerDelegate: true); debugLevel = new DelegatedConfigEntry(Logging.ChangeLogging); debugLevel.ConfigEntry = _instance.Config.Bind("Z - Utility", "LogLevel", Logging.LogLevels.Info, "Controls the level of information contained in the log"); Logging.Instance.LogLevel = debugLevel.Value; enableCompass.ConfigEntry = _instance.Config.Bind("A - HUD Compass", "Enable Compass", true, "Enable or Disable the Compass HUD.@"); showHideCompass.ConfigEntry = _instance.Config.Bind("A - HUD Compass", "Show Compass", true, "Show or Hide the HUD compass. Use the Toggle Compass key to change in-game."); compassUsePlayerDirection = _instance.Config.Bind("B - Compass Display", "Use Player Direction", false, "Orient the compass based on the direction the player is facing, rather than the middle of the screen."); compassScale = _instance.Config.Bind("B - Compass Display", "Compass Scale", 0.75f, new ConfigDescription("Sets the overall scale of the compass on the screen", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 3f), Array.Empty())); compassYOffset = _instance.Config.Bind("B - Compass Display", "Offset (Y)", 0, "Offset from the top of the screen in pixels."); distancePinsMin.ConfigEntry = _instance.Config.Bind("B - Compass Display", "Distance (Minimum)", 1, "Minimum distance from pin to show on compass.@"); distancePinsMax.ConfigEntry = _instance.Config.Bind("B - Compass Display", "Distance (Maximum)", 300, "Maximum distance from pin to show on compass.@"); playerPinBehavior.ConfigEntry = _instance.Config.Bind("B - Compass Display", "Player Pin Visibility", HUDCompass.PlayerPinBehavior.PlayerChoice, "Force player pins (multiplayer) to appear or not appear on the compass and map, or let the player decide. Overrides Show My Player Pin if not set to PlayerChoice.@"); compassShowMyPlayerPin.ConfigEntry = _instance.Config.Bind("B - Compass Display", "Show My Player Pin", true, "Shows or hides your player pin (multiplayer) on the compass if playing no-map where visibility setting is not available. Overriden by server if Player Pin Behavior is not set to PlayerChoice."); scalePins = _instance.Config.Bind("B - Compass Display", "Pins Scale", 1f, new ConfigDescription("Sets the overall scale of the pins on the on the screen", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 4f), Array.Empty())); scalePinsMin = _instance.Config.Bind("B - Compass Display", "Minimum Pin Size", 0.25f, "Enlarge or shrink the scale of the pins at their furthest visible distance."); compassShowCenterMark = _instance.Config.Bind("B - Compass Display", "Show Center Mark", false, "(Optional) Show center mark graphic."); hideCompassWhileMapOpen = _instance.Config.Bind("B - Compass Display", "Hide HUD While Map Open", true, "Hide the HUD display while the large map is open."); ignoredPinNames.ConfigEntry = _instance.Config.Bind("C - Ignore", "Pin Names", "Silver,Obsidian,Copper,Tin", "Ignore location pins with these names (comma separated, no spaces). A string ending with an asterisk (*) will match any pin name starFire,House,Pin,Portal,Start,Haldir,Hildir,Death,Bed,Shout,Boss,Player,RandomEvent,Ping,EventAreating with that string. A string beginning with an asterisk (*) will match any pin name ending with that string.@"); ignoredPinTypes.ConfigEntry = _instance.Config.Bind("C - Ignore", "Pin Types", "Shout,Ping", "Ignore location pins of these types (comma separated, no spaces). Types include: .@"); colorCompass = _instance.Config.Bind("E - Compass Colors", "Compass Color", Color.white, "(Optional) Adjust the main color of the compass."); colorPins = _instance.Config.Bind("E - Compass Colors", "Pin Color", Color.white, "(Optional) Adjust the color of the location pins on the compass."); colorCenterMark = _instance.Config.Bind("E - Compass Colors", "Center Mark Color", Color.yellow, "(Optional) Adjust the color of the center mark graphic."); showDynamicPinsOnMap.ConfigEntry = _instance.Config.Bind("F - Dynamic Pins", "Show dynamic pins on map", true, "Display pins for ships, carts and portals on the main and minimap. Controlled individually below.@"); showDynamicPinsOnCompass.ConfigEntry = _instance.Config.Bind("F - Dynamic Pins", "Show dynamic pins on compass", true, "Display pins for ships, carts and portals on the compass. Controlled individually below.@"); showDynamicNamesOnMap.ConfigEntry = _instance.Config.Bind("H - Dynamic Names", "Show dynamic names on map", true, "Display boat and cart types (i.e., Raft, Karve, Longship) and Portal names on the large map."); playerPinUpdateInterval.ConfigEntry = _instance.Config.Bind("F - Dynamic Pins", "Player pin refresh pin interval", 2f, new ConfigDescription("Interval in seconds between refresh of player pins on map and compass. Decrease for 'smoother' updates of player pins. Zero refreshes every frame. NOTE: Valheim default for Player pin refresh is 2 seconds. Decreasing can reduce multiplayer performance.@", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 2f), Array.Empty())); showShips.ConfigEntry = _instance.Config.Bind("G - Dynamic Types", "Show Ships", true, "Show ships on the map and compass.@"); showCarts.ConfigEntry = _instance.Config.Bind("G - Dynamic Types", "Show Carts", true, "Show carts on the map and compass.@"); showPortals.ConfigEntry = _instance.Config.Bind("G - Dynamic Types", "Show Portals", true, "Show portals on the map and compass.@"); activePortalColor = _instance.Config.Bind("I - Dynamic Map Colors", "Active portal color on map", new Color(255f, 153f, 51f), "Color of portal icons with active connections."); portalColor = _instance.Config.Bind("I - Dynamic Map Colors", "Portal color", Color.white, "Color of portal icons on map."); shipColor = _instance.Config.Bind("I - Dynamic Map Colors", "Ship color", Color.yellow, "Color of ship icons on map."); cartColor = _instance.Config.Bind("I - Dynamic Map Colors", "Cart color", Color.cyan, "Color of cart icons on map."); useDynamicColorsOnCompass = _instance.Config.Bind("I - Dynamic Map Colors", "Use colors on compass", false, "Use colors for dynamic pins on the compass"); alwaysVisible.ConfigEntry = _instance.Config.Bind("J - Visibility", "Always Visible", "", "Always display pins of these types or names (comma separated, no spaces) at full size regardless of distance.@"); hideCompassInMist.ConfigEntry = _instance.Config.Bind("K - Immersion", "Hide Compass in Mist", false, "Turn off the compass in mist.@"); hideCompassInCombat.ConfigEntry = _instance.Config.Bind("K - Immersion", "Hide Compass in Combat", false, "Turn off the compass while in combat.@"); hideCompassInCombatDelay.ConfigEntry = _instance.Config.Bind("K - Immersion", "Hide Compass in Combat delay", 2f, new ConfigDescription("The amount of time after combat actions before the compass is re-displayed.@", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 10f), Array.Empty())); hideCompassInFog.ConfigEntry = _instance.Config.Bind("K - Immersion", "Hide Compass in Fog", false, "Turn off the compass in dense fog.@"); hideCompassIndoors.ConfigEntry = _instance.Config.Bind("K - Immersion", "Hide Compass Indoors", false, "Turn off the compass when you're in dungeons or sheltered.@"); hideCompassWhileRunning.ConfigEntry = _instance.Config.Bind("K - Immersion", "Hide Compass While Running", false, "Turn off the compass while running. Stop or walk to get your bearings.@"); autoDeleteDeathPin = _instance.Config.Bind("L - Death Pin Management", "Auto Remove Death Pin", false, "Automatically remove death pin when Tombstone is emptied, or if no Tombstone is created."); compassToggle = new DelegatedConfigEntry(); compassToggle.ConfigEntry = _instance.Config.Bind("A - HUD Compass", "Toggle Compass Key", keyConfigItemDefault, "Key used in-game to toggle the compass visibility."); ServerConfiguration.Instance.CreateConfigWatcher(); } } public enum MarkerGroup { Ship, Cart, Portal, ActivePortal } public class DynamicMapMarkers { [HarmonyPatch(typeof(ZNet), "RPC_ServerHandshake")] private static class ZNet_RPC_ServerHandshake_Patch { [HarmonyPrefix] private static void ZNet_RPC_ServerHandshake_Prefix(ZNet __instance) { HUDCompass.Log.Debug("ZNet_RPC_ServerHandshake_Patch_Prefix"); } } [HarmonyPatch(typeof(ZNet), "RPC_ClientHandshake")] private static class ZNet_RPC_ClientHandshake_Patch { [HarmonyPrefix] private static void ZNet_RPC_ClientHandshake_Prefix(ZNet __instance) { HUDCompass.Log.Debug("ZNet_RPC_ClientHandshake_Patch_Prefix"); HUDCompass.Log.Info("Cleaning up previous server markers"); s_dmm.DestroyMarkers(); } } [HarmonyPatch(typeof(Game), "Start")] private static class Game_Start_Patch { [HarmonyPostfix] private static void Game_Start_DMM_Postfix(Game __instance) { HUDCompass.Log.Debug("Game_Start_DMM_Postfix"); ZRoutedRpc.instance.Register("AddMarkerFromServer", (Method)RPC_AddMarkerFromServer); HUDCompass.Log.Debug("Registered RPC AddMarkerFromServer"); } } [HarmonyPatch(typeof(FejdStartup), "Start")] private static class FejdStartup_Start_Patch { [HarmonyPostfix] private static void FejdStartup_Start_Postfix(FejdStartup __instance) { HUDCompass.Log.Debug("FejdStartup_Start_Patch_Postfix"); BuildDynamicMarkerTypes(); } } [HarmonyPatch(typeof(World), "LoadWorld")] private static class World_LoadWorld_Patch { [HarmonyPostfix] private static void World_LoadWorld_Postfix(World __instance) { HUDCompass.Log.Debug("World_LoadWorld_Patch_Postfix"); HUDCompass.Log.Info("Cleaning up previous world's markers"); s_dmm.DestroyMarkers(); } } [HarmonyPatch(typeof(ZNet), "RPC_CharacterID")] private static class ZNet_RPC_CharacterID_Patch { [HarmonyPostfix] private static void ZNet_RPC_CharacterID_Postfix(ZNet __instance, ZRpc rpc, ZDOID characterID) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) HUDCompass.Log.Debug("ZNet_RPC_CharacterID_Patch_Postfix"); ZNetPeer peerByZDOID = GetPeerByZDOID(characterID); if (!ZNet.instance.IsServer() || peerByZDOID == null || !(characterID != ZDOID.None) || !(peerByZDOID.m_characterID != ZDOID.None)) { return; } if (!ZNet.instance.IsDedicated()) { ZDOID characterID2 = peerByZDOID.m_characterID; Player localPlayer = Player.m_localPlayer; ZDOID? val = ((localPlayer != null) ? new ZDOID?(((Character)localPlayer).GetZDOID()) : ((ZDOID?)null)); if (val.HasValue && characterID2 == val.GetValueOrDefault()) { return; } } s_dmm.BuildMarkers(); HUDCompass.Log.Info($"Sending {s_dmm.Markers.Count} dynamic markers to {peerByZDOID.m_playerName}"); foreach (MarkerData value in s_dmm.Markers.Values) { ZRoutedRpc.instance.InvokeRoutedRPC(peerByZDOID.m_uid, "AddMarkerFromServer", new object[6] { value.Zdoid, value.Type.PrefabHash, value.Position, value.Creator, value.IsActivePortal, value.Label }); } } } [HarmonyPatch(typeof(ZDOMan), "HandleDestroyedZDO")] private static class ZDOMan_HandleDestroyedZDO_Patch { [HarmonyPostfix] private static void ZDOMan_HandleDestroyedZDO_Postfix(ZDOMan __instance, ZDOID uid) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) RemoveMarker(uid); } } [HarmonyPatch(typeof(ZNet), "SendPeriodicData")] private static class ZNet_SendPeriodicData_Patch { [HarmonyPrefix] private static bool ZNet_SendPeriodicData_Prefix(ZNet __instance, float dt) { dmm_playerPinPeriodicTimer += dt; if (dmm_playerPinPeriodicTimer < Cfg.playerPinUpdateInterval.Value) { return true; } dmm_playerPinPeriodicTimer = 0f; if (__instance.IsServer()) { __instance.SendNetTime(); __instance.SendPlayerList(); } return true; } } [HarmonyPatch(typeof(ZDOMan), "CreateNewZDO", new Type[] { typeof(ZDOID), typeof(Vector3), typeof(int) })] private static class ZDOMan_CreateNewZDO_Patch { [HarmonyPostfix] private static void ZDOMan_CreateNewZDO_Postfix(ZDOMan __instance, ZDOID uid, Vector3 position, int prefabHashIn) { //IL_0001: 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_0061: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = __instance.GetZDO(uid); if (zDO != null) { int key = ((prefabHashIn != 0) ? prefabHashIn : zDO.GetPrefab()); if (s_dmm.MarkerTypes.ContainsKey(key) && !s_dmm.Markers.ContainsKey(uid)) { AddMarkerFromZDO(zDO); HUDCompass.Log.Debug($"Added marker from new ZDO for {s_dmm.MarkerTypes[key].Name} at {position}"); } } } } [HarmonyPatch(typeof(ZNetScene), "AddInstance")] private static class ZNetScene_AddInstance_Patch { [HarmonyPostfix] private static void ZNetScene_AddInstance_Postfix(ZDO zdo) { AddMarkerFromZDO(zdo); } } [HarmonyPatch(typeof(ZDOMan), "AddToSector")] private static class ZDOMan_AddToSector_Patch { [HarmonyPostfix] private static void ZDOMan_AddToSector_Postfix(ZDOMan __instance, ZDO zdo) { AddMarkerFromZDO(zdo); } } [HarmonyPatch(typeof(Minimap), "UpdatePins")] private static class Minimap_UpdatePins_Patch { [HarmonyPostfix] private static void Minimap_UpdatePins_DMM_Postfix(Minimap __instance, float ___m_largeZoom) { //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_015e: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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_01ec: 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) HUDCompass.Log.Trace("Minimap_UpdatePins_DMM_Postfix"); s_dmm.PinData.Clear(); if (s_dmm.Markers.Count <= 0 || !((Object)(object)Minimap.instance?.m_largeRoot != (Object)null)) { return; } RawImage val = (Minimap.instance.m_largeRoot.activeSelf ? Minimap.instance.m_mapImageLarge : Minimap.instance.m_mapImageSmall); float size = (Minimap.instance.m_largeRoot.activeSelf ? Minimap.instance.m_pinSizeLarge : Minimap.instance.m_pinSizeSmall); RectTransform parent = (Minimap.instance.m_largeRoot.activeSelf ? Minimap.instance.m_pinRootLarge : Minimap.instance.m_pinRootSmall); foreach (MarkerData value in s_dmm.Markers.Values) { bool flag = false; ZDO zDO = ZDOMan.instance.GetZDO(value.Zdoid); if (zDO != null) { value.Position = zDO.m_position; flag = IsAttachedToPlayer(zDO); if (IsPortalType(value.Type)) { value.IsActivePortal = zDO.GetConnectionZDOID((ConnectionType)1) != ZDOID.None; value.Label = zDO.GetString(ZDOVars.s_tag, value.Label); } } Vector3 position = value.Position; int num; if (Cfg.showDynamicPinsOnCompass.Value && value.Type.Show && Minimap.instance.m_visibleIconTypes[value.Type.PinType] && !flag) { num = (Minimap.instance.IsExplored(value.Position) ? 1 : 0); if (num != 0) { PinData item = s_dmm.MarkerToPinData(value); if (!s_dmm.PinData.Contains(item)) { s_dmm.PinData.Add(item); } } } else { num = 0; } if (num != 0 && Minimap.instance.IsPointVisible(position, val)) { DrawMarker(value, size, parent, val, ___m_largeZoom, Minimap.instance.m_largeRoot.activeSelf); } else { MarkerData.Destroy(value); } } } } [HarmonyPatch(typeof(Player), "OnSpawned")] private static class Player_OnSpawned_DMM_Patch { [HarmonyPostfix] private static void Player_OnSpawned_DMM_Postfix(Player __instance) { HUDCompass.Log.Debug("Player_OnSpawned_DMM_Postfix"); if (ZNet.IsSinglePlayer) { s_dmm.BuildMarkers(); } } } [HarmonyPatch(typeof(Minimap), "Start")] private static class Minimap_Start_Patch { [HarmonyPostfix] private static void Minimap_Start_Postfix(Minimap __instance) { //IL_00f7: 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_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) HUDCompass.Log.Debug("Minimap_Start_Patch_Postfix"); if ((Object)(object)s_dmm.PortalMarkerSprite == (Object)null) { foreach (SpriteData icon in Minimap.instance.m_icons) { if (!(((Object)icon.m_icon).name == "mapicon_portal")) { continue; } HUDCompass.Log.Debug("Updating portal map icon"); s_dmm.PortalMarkerSprite = icon.m_icon; foreach (MarkerType value in s_dmm.MarkerTypes.Values) { if (IsPortalType(value)) { value.Sprite = s_dmm.PortalMarkerSprite; } } break; } } foreach (SpriteData icon2 in Minimap.instance.m_icons) { HUDCompass.Log.Debug($"icon name {((Object)icon2.m_icon).name} {icon2.m_name}"); } } } [HarmonyPatch(typeof(ZNetScene), "OnZDODestroyed")] private static class ZNetScene_OnZDODestroyed_Patch { [HarmonyPrefix] private static void ZNetScene_OnZDODestroyed_Prefix(ZDO zdo) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) HUDCompass.Log.Trace("ZNetScene_OnZDODestroyed_Patch_Prefix"); if (s_dmm.Markers.ContainsKey(zdo.m_uid)) { RemoveMarker(zdo.m_uid); } } } public Dictionary MarkerTypes; public Dictionary Markers; public Sprite PortalMarkerSprite; public Sprite CheckedMarkerSprite; public List PinData; private Sprite ShipMarkerSprite; private Sprite CartMarkerSprite; private static DynamicMapMarkers s_dmm; private static float dmm_playerPinPeriodicTimer = 0f; private static Dictionary reversePrefabLookup = new Dictionary { { -661882940, "portal_wood" }, { 1854482458, "portal_stone" }, { -918756884, "portal_obsidian" }, { 1239683413, "portal_ancient" }, { -1743606895, "portal_blackmarble" }, { 49675204, "Cart" }, { -811948769, "VikingShip_Ashlands" }, { 118230510, "VikingShip" }, { 49675681, "Raft" }, { -925528333, "Karve" }, { -231530696, "BatteringRam" }, { 1146805026, "Catapult" } }; public DynamicMapMarkers() { s_dmm = this; MarkerTypes = new Dictionary(); Markers = new Dictionary(); PinData = new List(); try { ShipMarkerSprite = HUDCompass.s_imageHelper.LoadSprite("mapicon_anchor.png", 2, 2, linear: false, 50f); CartMarkerSprite = HUDCompass.s_imageHelper.LoadSprite("mapicon_cart.png", 2, 2, linear: false, 50f); } catch (Exception e) { HUDCompass.Log.Warning("Could not load dynamic images"); HUDCompass.Log.Error(e); Object.Destroy((Object)(object)HUDCompass.s_instance); } } public PinData MarkerToPinData(MarkerData marker) { //IL_0003: 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) //IL_0019: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown if (marker != null) { return new PinData { m_icon = marker.Type.Sprite, m_pos = marker.Position, m_name = (marker.IsActivePortal ? MarkerGroup.ActivePortal.ToString() : marker.Type.Group.ToString()), m_type = (PinType)8, m_ownerID = marker.Creator }; } return null; } public static void SettingChanged_MapPins(object sender, EventArgs e) { } public static bool GetAllZDOsWithPrefab(string prefab, List zdos) { return GetAllZDOsWithPrefab(StringExtensionMethods.GetStableHashCode(prefab), zdos); } public static bool GetAllZDOsWithPrefab(int prefab, List zdos) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) HUDCompass.Log.Debug("GetAllZDOsWithPrefab"); foreach (ZDO value in ZDOMan.instance.m_objectsByID.Values) { if (value.GetPrefab() == prefab && !zdos.Contains(value)) { if (HUDCompass.Log.LogLevel >= Logging.LogLevels.Debug) { HUDCompass.Log.Debug($"Getting ZDO for {prefab} at {value.m_position}"); } zdos.Add(value); } } zdos.RemoveAll((Predicate)ZDOMan.InvalidZDO); return true; } public static ZNetPeer GetPeerByZDOID(ZDOID charZdoid) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) foreach (ZNetPeer peer in ZNet.instance.m_peers) { if (peer.IsReady() && peer.m_characterID == charZdoid) { return peer; } } return null; } internal static void BuildDynamicMarkerTypes() { HUDCompass.Log.Debug("BuildDynamicMarkerTypes"); s_dmm.MarkerTypes.Clear(); List list = new List { new MarkerType("portal_wood", s_dmm.PortalMarkerSprite, "$piece_portal", MarkerGroup.Portal, (PinType)6, Cfg.showPortals.ConfigEntry), new MarkerType("portal_stone", s_dmm.PortalMarkerSprite, "$piece_portal_stone", MarkerGroup.Portal, (PinType)6, Cfg.showPortals.ConfigEntry), new MarkerType("portal_obsidian", s_dmm.PortalMarkerSprite, "$piece_portal_obsidian", MarkerGroup.Portal, (PinType)6, Cfg.showPortals.ConfigEntry), new MarkerType("portal_ancient", s_dmm.PortalMarkerSprite, "$piece_portal_ancient", MarkerGroup.Portal, (PinType)6, Cfg.showPortals.ConfigEntry), new MarkerType("portal_blackmarble", s_dmm.PortalMarkerSprite, "$piece_portal_blackmarble", MarkerGroup.Portal, (PinType)6, Cfg.showPortals.ConfigEntry) }; Ship val2 = default(Ship); Piece val3 = default(Piece); Vagon val4 = default(Vagon); Piece val5 = default(Piece); foreach (GameObject item in ObjectDB.instance.m_items) { PieceTable val = item.GetComponent()?.m_itemData.m_shared.m_buildPieces; if (!((Object)(object)val != (Object)null)) { continue; } foreach (GameObject piece in val.m_pieces) { if (piece.TryGetComponent(ref val2)) { if (piece.TryGetComponent(ref val3)) { list.Add(new MarkerType(((Object)piece).name, s_dmm.ShipMarkerSprite, val3.m_name, MarkerGroup.Ship, (PinType)8, Cfg.showShips.ConfigEntry)); HUDCompass.Log.Debug("Found plan for " + ((Object)piece).name + " " + val3.m_name); } } else if (piece.TryGetComponent(ref val4) && piece.TryGetComponent(ref val5)) { list.Add(new MarkerType(((Object)piece).name, s_dmm.CartMarkerSprite, val5.m_name, MarkerGroup.Cart, (PinType)8, Cfg.showCarts.ConfigEntry)); HUDCompass.Log.Debug("Found plan for " + ((Object)piece).name + " " + val5.m_name); } } } foreach (MarkerType item2 in list) { if (!s_dmm.MarkerTypes.ContainsKey(item2.PrefabHash)) { HUDCompass.Log.Debug("Added Dynamic Marker Type " + item2.Prefab); s_dmm.MarkerTypes.Add(item2.PrefabHash, item2); } } } public void DestroyMarkers() { HUDCompass.Log.Debug("DestroyMarkers"); foreach (MarkerData value in Markers.Values) { MarkerData.Destroy(value); } Markers.Clear(); } public void BuildMarkers() { HUDCompass.Log.Debug("BuildMarkers"); DestroyMarkers(); List list = new List(); foreach (int key in s_dmm.MarkerTypes.Keys) { GetAllZDOsWithPrefab(key, list); foreach (ZDO item in list) { AddMarkerFromZDO(item); } list.Clear(); } } private static void RPC_AddMarkerFromServer(long id, ZDOID zdoid, int prefabHash, Vector3 position, long creator, bool active, string label) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!ZNet.instance.IsServer()) { AddMarkerFromServer(zdoid, prefabHash, position, creator, active, label); } } private static void AddMarkerFromServer(ZDOID zdoid, int prefabHash, Vector3 position, long creator, bool active, string label) { //IL_000a: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (!s_dmm.Markers.ContainsKey(zdoid)) { MarkerData markerData = new MarkerData(); markerData.Type = s_dmm.MarkerTypes[prefabHash]; markerData.Zdoid = zdoid; markerData.Position = position; markerData.Creator = creator; markerData.IsActivePortal = active; markerData.Label = label; markerData.Marker = null; markerData.Nametag = null; s_dmm.Markers.Add(markerData.Zdoid, markerData); if (HUDCompass.Log.LogLevel >= Logging.LogLevels.Debug) { HUDCompass.Log.Debug($"Added {markerData.Type.Name} Marker from Server: active {markerData.IsActivePortal} tag {markerData.Label}"); } } } private static void RPC_RemoveDynamicMarker(long id, ZDOID zdoid) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) HUDCompass.Log.Debug("RPC_RemoveDynamicMarker"); if (!ZNet.instance.IsDedicated()) { RemoveMarker(zdoid); } } private static void RemoveMarker(ZDOID zdoid) { //IL_000a: 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) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (s_dmm.Markers.ContainsKey(zdoid) && s_dmm.Markers[zdoid] != null) { MarkerData.Destroy(s_dmm.Markers[zdoid]); } s_dmm.Markers.Remove(zdoid); } internal static void AddMarkerFromZDO(ZDO zdo) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_00a1: 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) int prefab = zdo.GetPrefab(); if (s_dmm.MarkerTypes.ContainsKey(prefab) && !s_dmm.Markers.ContainsKey(zdo.m_uid)) { MarkerData markerData = new MarkerData(); markerData.Zdoid = zdo.m_uid; markerData.Position = zdo.m_position; markerData.Type = s_dmm.MarkerTypes[prefab]; markerData.IsActivePortal = false; markerData.Label = Localization.instance.Localize(markerData.Type.Name); if (IsPortalType(markerData.Type)) { markerData.IsActivePortal = zdo.GetConnectionZDOID((ConnectionType)1) != ZDOID.None; markerData.Label = zdo.GetString(ZDOVars.s_tag, markerData.Label); } markerData.Creator = zdo.GetLong(ZDOVars.s_creator, HUDCompass.s_localPlayerID); if (HUDCompass.Log.LogLevel >= Logging.LogLevels.Debug) { HUDCompass.Log.Debug("Added " + markerData.Type.Name + " Marker from ZDO"); } s_dmm.Markers.Add(zdo.m_uid, markerData); } } private static bool IsPortalType(MarkerType mt) { if (mt.Group != MarkerGroup.Portal) { return mt.Group == MarkerGroup.ActivePortal; } return true; } private static bool IsAttachedToPlayer(ZDO zdo) { if (zdo == null) { return false; } ZNetView val = ZNetScene.instance.FindInstance(zdo); if ((Object)(object)val != (Object)null) { GameObject gameObject = ((Component)val).gameObject; if ((Object)(object)gameObject != (Object)null) { Ship component = gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { return component.HaveControllingPlayer(); } Vagon component2 = gameObject.GetComponent(); object obj; if (component2 == null) { obj = null; } else { ConfigurableJoint attachJoin = component2.m_attachJoin; obj = ((attachJoin != null) ? ((Joint)attachJoin).connectedBody : null); } if ((Object)obj != (Object)null) { return true; } } } return false; } private static void DrawMarker(MarkerData data, float size, RectTransform parent, RawImage targetMapRawImage, float largeMapZoom, bool isLargeMap) { //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) GameObject val = data.Marker; GameObject val2 = data.Nametag; if (data == null) { HUDCompass.Log.Warning("Marker data is null"); return; } if ((Object)(object)parent == (Object)null) { HUDCompass.Log.Warning("Parent transform is null"); return; } if ((Object)(object)targetMapRawImage == (Object)null) { HUDCompass.Log.Warning("Target map raw image is null"); return; } RectTransform val3; if ((Object)(object)val == (Object)null || (Object)(object)val.transform.parent != (Object)(object)parent) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } if ((Object)(object)Minimap.instance?.m_pinPrefab == (Object)null) { HUDCompass.Log.Warning("Minimap pin prefabHash is null"); return; } val = Object.Instantiate(Minimap.instance.m_pinPrefab); if ((Object)(object)val == (Object)null) { HUDCompass.Log.Warning("Unable to create new pin object "); return; } data.Marker = val; Transform transform = val.transform; val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null); Image component = val.GetComponent(); if ((Object)(object)component == (Object)null) { HUDCompass.Log.Warning("Pin image is missing"); return; } component.sprite = data.Type.Sprite; switch (data.Type.Group) { case MarkerGroup.Portal: ((Graphic)component).color = (data.IsActivePortal ? Cfg.activePortalColor.Value : Cfg.portalColor.Value); break; case MarkerGroup.Cart: ((Graphic)component).color = Cfg.cartColor.Value; break; case MarkerGroup.Ship: ((Graphic)component).color = Cfg.shipColor.Value; break; default: ((Graphic)component).color = Color.white; break; } _ = Player.m_localPlayer; if (data.Creator != HUDCompass.s_localPlayerID) { float num = ((Graphic)component).color.a / 2f; ((Graphic)component).color = new Color(((Graphic)component).color.r, ((Graphic)component).color.g, ((Graphic)component).color.b, num); } ((Transform)val3).SetParent((Transform)(object)parent, false); val3.SetSizeWithCurrentAnchors((Axis)0, size); val3.SetSizeWithCurrentAnchors((Axis)1, size); } Transform transform2 = val.transform; val3 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null); float num2 = default(float); float num3 = default(float); Minimap.instance.WorldToMapPoint(data.Position, ref num2, ref num3); Vector2 anchoredPosition = (val3.anchoredPosition = Minimap.instance.MapPointToLocalGuiPos(num2, num3, targetMapRawImage)); Transform val5 = val.transform.Find("Checked"); if ((Object)(object)val5 != (Object)null) { ((Component)val5).gameObject.SetActive(false); } HUDCompass.Log.Trace($"pin {((Object)val).name} active {val.activeInHierarchy} marker {data.Type} label {data.Label} zdoid {data.Zdoid}"); if (val.activeInHierarchy != Cfg.showDynamicPinsOnMap.Value) { HUDCompass.Log.Debug("Changed State"); val.SetActive(Cfg.showDynamicPinsOnMap.Value); } if (!isLargeMap) { return; } RectTransform component2; if ((Object)(object)val2 == (Object)null || (Object)(object)val2.transform.parent != (Object)(object)parent) { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } val2 = Object.Instantiate(Minimap.instance.m_pinNamePrefab, (Transform)(object)parent); TMP_Text componentInChildren = val2.GetComponentInChildren(); componentInChildren.text = data.Label; switch (data.Type.Group) { case MarkerGroup.Portal: ((Graphic)componentInChildren).color = (data.IsActivePortal ? Cfg.activePortalColor.Value : Cfg.portalColor.Value); break; case MarkerGroup.Cart: ((Graphic)componentInChildren).color = Cfg.cartColor.Value; break; case MarkerGroup.Ship: ((Graphic)componentInChildren).color = Cfg.shipColor.Value; break; default: ((Graphic)componentInChildren).color = Color.white; break; } component2 = val2.GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Transform)component2).SetParent((Transform)(object)parent, false); data.Nametag = val2; } } Transform transform3 = val2.transform; component2 = (RectTransform)(object)((transform3 is RectTransform) ? transform3 : null); component2.anchoredPosition = anchoredPosition; if (val2.activeInHierarchy != Cfg.showDynamicNamesOnMap.Value) { val2.SetActive(Cfg.showDynamicNamesOnMap.Value); } } } [BepInPlugin("neobotics.valheim_mod.hudcompass", "HUDCompass", "1.1.9")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] public class HUDCompass : BaseUnityPlugin { public enum PlayerPinBehavior { ForceOn, ForceOff, PlayerChoice } [HarmonyPatch(typeof(Minimap), "OnTogglePublicPosition")] private static class Minimap_OnTogglePublicPosition_Patch { [HarmonyPostfix] private static void Minimap_OnTogglePublicPosition_Postfix(Minimap __instance) { Log.Debug("Minimap_OnTogglePublicPosition_Postfix"); bool flag = Minimap.instance.m_publicPosition.isOn; switch (Cfg.playerPinBehavior.Value) { case PlayerPinBehavior.ForceOff: flag = false; break; case PlayerPinBehavior.ForceOn: flag = true; break; } ZNet.instance.SetPublicReferencePosition(flag); Minimap.instance.m_publicPosition.isOn = flag; Cfg.compassShowMyPlayerPin.ConfigEntry.SettingChanged -= SettingChanged_ShowMyPlayerPin; Cfg.compassShowMyPlayerPin.Value = flag; Cfg.compassShowMyPlayerPin.ConfigEntry.SettingChanged += SettingChanged_ShowMyPlayerPin; } } [HarmonyPatch(typeof(Player), "OnSpawned")] private static class Player_OnSpawned_HC_Patch { [HarmonyPostfix] private static void Player_OnSpawned_HC_Postfix(Player __instance) { Log.Debug("Player_OnSpawned_HC_Postfix"); s_localPlayerID = Game.instance.GetPlayerProfile().GetPlayerID(); ManagePinVisibility(); } } [HarmonyPatch(typeof(Hud), "Awake")] internal static class HudAwakeCompassPatch { internal static void Postfix(Hud __instance) { Log.Debug("Hud_Awake_Postfix"); try { if (s_imageHelper.TryLoadImage("compass.png", 1, 1, linear: true, out var image) && ((Texture)image).width > 0) { float width = (float)((Texture)image).width / 2f; s_spriteCompass = s_imageHelper.LoadSprite(image); if (s_imageHelper.TryLoadImage("mask.png", 1, 1, linear: true, out var image2) && ((Texture)image2).width > 0) { s_spriteMask = s_imageHelper.LoadSprite(image2, null, width, ((Texture)image2).height); if (s_imageHelper.TryLoadImage("center.png", 1, 1, linear: true, out var image3) && ((Texture)image3).width > 0) { s_spriteCenter = s_imageHelper.LoadSprite(image3); } } } } catch (Exception e) { Log.Error("Could not load compass images"); Log.Error(e); Object.Destroy((Object)(object)s_instance); } ConfigHUD(__instance); } } [HarmonyPatch(typeof(Hud), "Update")] private static class HudUpdateCompassPatch { [HarmonyPostfix] private static void Hud_Update_Prefix(Hud __instance) { //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Expected O, but got Unknown //IL_048b: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_04d0: Unknown result type (might be due to invalid IL or missing references) //IL_058b: Unknown result type (might be due to invalid IL or missing references) //IL_0590: Unknown result type (might be due to invalid IL or missing references) //IL_0595: Unknown result type (might be due to invalid IL or missing references) //IL_0571: Unknown result type (might be due to invalid IL or missing references) //IL_0576: Unknown result type (might be due to invalid IL or missing references) //IL_057b: Unknown result type (might be due to invalid IL or missing references) //IL_0597: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_0622: Unknown result type (might be due to invalid IL or missing references) //IL_0629: Expected O, but got Unknown //IL_065f: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_06be: Unknown result type (might be due to invalid IL or missing references) //IL_06c5: Unknown result type (might be due to invalid IL or missing references) //IL_06cf: Unknown result type (might be due to invalid IL or missing references) //IL_06de: Unknown result type (might be due to invalid IL or missing references) //IL_06ef: Unknown result type (might be due to invalid IL or missing references) //IL_0810: Unknown result type (might be due to invalid IL or missing references) //IL_0822: Unknown result type (might be due to invalid IL or missing references) //IL_0828: Unknown result type (might be due to invalid IL or missing references) //IL_0832: Unknown result type (might be due to invalid IL or missing references) //IL_0760: Unknown result type (might be due to invalid IL or missing references) //IL_0850: Unknown result type (might be due to invalid IL or missing references) //IL_085e: Unknown result type (might be due to invalid IL or missing references) //IL_07be: Unknown result type (might be due to invalid IL or missing references) //IL_07d0: Unknown result type (might be due to invalid IL or missing references) //IL_07e2: Unknown result type (might be due to invalid IL or missing references) //IL_07f4: Unknown result type (might be due to invalid IL or missing references) //IL_0804: Unknown result type (might be due to invalid IL or missing references) //IL_0773: Unknown result type (might be due to invalid IL or missing references) //IL_0786: Unknown result type (might be due to invalid IL or missing references) //IL_0799: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Cfg.enableCompass.Value || (Object)(object)localPlayer == (Object)null) { return; } bool flag = Cfg.showHideCompass.Value && (!Cfg.hideCompassIndoors.Value || !((Character)localPlayer).InInterior()) && (!Cfg.hideCompassWhileRunning.Value || !((Character)localPlayer).IsRunning()) && (!Cfg.hideCompassInCombat.Value || !IsAttacking(localPlayer)) && (!Cfg.hideCompassInMist.Value || !IsInMist(localPlayer)) && (!Cfg.hideCompassInFog.Value || !IsTooFoggy()) && (!Cfg.hideCompassWhileMapOpen.Value || !Minimap.instance.m_largeRoot.activeSelf) && Hud.instance.IsVisible(); if (s_objectParent.activeInHierarchy != flag) { s_objectParent.SetActive(flag); } if (!flag) { return; } if ((Object)(object)s_spriteCompass == (Object)null) { Log.Debug("Compass is null"); return; } if ((Object)(object)s_spriteMask == (Object)null) { Log.Debug("Mask is null"); return; } float num = ((!Cfg.compassUsePlayerDirection.Value) ? ((Component)GameCamera.instance).transform.eulerAngles.y : ((Component)Player.m_localPlayer).transform.eulerAngles.y); if (num > 180f) { num -= 360f; } num *= -MathF.PI / 180f; Rect rect = s_objectCompass.GetComponent().sprite.rect; float num2 = 1f; CanvasScaler val = GuiScaler.m_scalers?.Find((GuiScaler x) => ((Object)x.m_canvasScaler).name == "LoadingGUI")?.m_canvasScaler; if ((Object)(object)val != (Object)null) { num2 = val.scaleFactor; } ((Transform)s_objectCompass.GetComponent()).localPosition = Vector3.right * (((Rect)(ref rect)).width / 2f) * num / (MathF.PI * 2f) - new Vector3(((Rect)(ref rect)).width * 0.125f, 0f, 0f); ((Graphic)s_objectCompass.GetComponent()).color = Cfg.colorCompass.Value; ((Transform)s_objectParent.GetComponent()).localScale = Vector3.one * Cfg.compassScale.Value; int num3 = Mathf.RoundToInt(((Rect)(ref rect)).height * num2 * Cfg.compassScale.Value / 2f); ((Transform)s_objectParent.GetComponent()).position = new Vector3((float)(Screen.width / 2), (float)(Screen.height - num3 - Cfg.compassYOffset.Value), 0f); if ((Object)(object)s_objectCenterMark != (Object)null) { if (Cfg.compassShowCenterMark.Value) { ((Graphic)s_objectCenterMark.GetComponent()).color = Cfg.colorCenterMark.Value; } if (s_objectCenterMark.activeInHierarchy != Cfg.compassShowCenterMark.Value) { s_objectCenterMark.SetActive(Cfg.compassShowCenterMark.Value); } } else { Log.Debug("Center is null"); } _ = s_objectPins.transform.childCount; List list = new List(); foreach (Transform item in s_objectPins.transform) { Transform val2 = item; list.Add(((Object)val2).name); } List list2 = new List(); list2.AddRange(Minimap.instance.m_pins); list2.AddRange(Minimap.instance.m_locationPins.Values); if (Cfg.playerPinBehavior.Value != PlayerPinBehavior.ForceOff) { list2.AddRange(Minimap.instance.m_playerPins); } PinData deathPin = Minimap.instance.m_deathPin; if (deathPin != null) { list2.Add(deathPin); } if (Cfg.showDynamicPinsOnCompass.Value) { list2.AddRange(s_dmm.PinData); } Transform transform = ((Component)Player.m_localPlayer).transform; float num4 = 0f; if (1f - Cfg.scalePinsMin.Value > 0f) { num4 = (float)Cfg.distancePinsMax.Value / (1f - Cfg.scalePinsMin.Value); } Cfg.ignoredPinNames.Value.Contains("*"); foreach (PinData item2 in list2) { if (!Minimap.instance.m_visibleIconTypes[item2.m_type]) { continue; } string text = ((object)Unsafe.As(ref item2.m_pos)/*cast due to .constrained prefix*/).ToString(); list.Remove(text); Transform val3 = s_objectPins.transform.Find(text); float num5 = Vector3.Distance(transform.position, item2.m_pos); bool flag2 = MatchTypeOrName(s_alwaysVisible, item2); bool num6 = MatchType(s_ignoredTypes, item2); bool flag3 = MatchNameOrWildcard(s_ignoredNames, s_ignoredWildcardPrefixes, s_ignoredWildcardSuffixes, item2.m_name); bool flag4 = false; if (!num6 && !flag3 && (flag2 || IsInBounds(num5, Cfg.distancePinsMin.Value, Cfg.distancePinsMax.Value))) { flag4 = true; } if ((Object)(object)val3 != (Object)null) { ((Component)val3).gameObject.SetActive(flag4); } if (!flag4) { continue; } Vector3 val4 = ((!Cfg.compassUsePlayerDirection.Value) ? ((Component)GameCamera.instance).transform.InverseTransformPoint(item2.m_pos) : transform.InverseTransformPoint(item2.m_pos)); num = Mathf.Atan2(val4.x, val4.z); GameObject val5; RectTransform val6; Image val7; if ((Object)(object)val3 == (Object)null) { if (Log.LogLevel >= Logging.LogLevels.Trace) { Logging log = Log; object[] obj = new object[5] { item2.m_name, item2.m_type, null, null, null }; Sprite icon = item2.m_icon; obj[2] = ((icon != null) ? ((Object)icon).name : null); obj[3] = num5; obj[4] = flag2; log.Trace(string.Format("Adding new pin object for name {0} type {1} icon {2} distance {3} always show {4}", obj)); } val5 = new GameObject(); ((Object)val5).name = ((object)Unsafe.As(ref item2.m_pos)/*cast due to .constrained prefix*/).ToString(); val6 = val5.AddComponent(); ((Transform)val6).SetParent(s_objectPins.transform, false); val6.anchoredPosition = Vector2.zero; val7 = val5.AddComponent(); } else { val5 = ((Component)val3).gameObject; val6 = ((Component)val3).GetComponent(); val7 = ((Component)val3).GetComponent(); } float num7 = (flag2 ? 1f : ((Cfg.scalePinsMin.Value < 1f) ? ((num4 - num5) / num4) : 1f)); ((Transform)val6).localScale = Vector3.one * num7 * 0.5f * Cfg.scalePins.Value; ((Graphic)val7).color = Cfg.colorPins.Value; val7.sprite = item2.m_icon; if (Cfg.useDynamicColorsOnCompass.Value) { switch (item2.m_name) { case "Ship": ((Graphic)val7).color = Cfg.shipColor.Value; break; case "Cart": ((Graphic)val7).color = Cfg.cartColor.Value; break; case "Portal": ((Graphic)val7).color = Cfg.portalColor.Value; break; case "ActivePortal": ((Graphic)val7).color = Cfg.activePortalColor.Value; break; } } if (item2.m_ownerID != 0L && item2.m_ownerID != s_localPlayerID) { ((Graphic)val7).color = new Color(((Graphic)val7).color.r * 0.7f, ((Graphic)val7).color.g * 0.7f, ((Graphic)val7).color.b * 0.7f, ((Graphic)val7).color.a * 0.8f); } ((Transform)val6).localPosition = Vector3.right * (((Rect)(ref rect)).width / 2f) * num / (MathF.PI * 2f); if ((Object)(object)s_dmm.CheckedMarkerSprite != (Object)null) { SetCheckedOverlay(val5, Color.red, item2.m_checked, ((Graphic)val7).color.a); } } foreach (string item3 in list) { Object.Destroy((Object)(object)((Component)s_objectPins.transform.Find(item3)).gameObject); } } } [HarmonyPatch(typeof(Minimap), "UpdatePins")] private static class Minimap_UpdatePins_Patch { [HarmonyPostfix] private static void Minimap_UpdatePins_HC_Postfix(Minimap __instance) { Log.Trace("Minimap_UpdatePins_HC_Postfix"); if ((Object)(object)s_dmm.CheckedMarkerSprite == (Object)null) { s_dmm.CheckedMarkerSprite = GetCheckedSprite(__instance.m_pinPrefab); } } } [HarmonyPatch(typeof(Player), "Update")] public static class Player_Update_Patch { private static void Prefix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && OkToKey(__instance) && Cfg.compassToggle.IsKeyPressed()) { Cfg.showHideCompass.Value = !Cfg.showHideCompass.Value; } } } [HarmonyPatch(typeof(Minimap), "ToggleIconFilter")] private static class Minimap_ToggleIconFilter_Patch { [HarmonyPrefix] private static void Minimap_ToggleIconFilter_Prefix(Minimap __instance, PinType type) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) Log.Debug($"Minimap_ToggleIconFilter_Patch_Prefix PinType {type}"); } } internal const string PLUGIN_NAME = "HUDCompass"; internal const string PLUGIN_VERSION = "1.1.9"; internal const string PLUGIN_GUID = "neobotics.valheim_mod.hudcompass"; internal static string s_resourceFolder; internal const string FILE_COMPASS = "compass.png"; internal const string FILE_MASK = "mask.png"; internal const string FILE_CENTER = "center.png"; internal static HUDCompass s_instance; private static Harmony harmony; internal static GameObject s_objectCompass; internal static GameObject s_objectPins; internal static GameObject s_objectParent; internal static GameObject s_objectCenterMark; internal static List s_ignoredNames = new List(); internal static List s_ignoredWildcardPrefixes = new List(); internal static List s_ignoredWildcardSuffixes = new List(); internal static List s_ignoredTypes = new List(); internal static List s_alwaysVisible = new List(); internal static Sprite s_spriteCompass = null; internal static Sprite s_spriteMask = null; internal static Sprite s_spriteCenter = null; public static Logging Log; public static DynamicMapMarkers s_dmm = null; public static long s_localPlayerID = 0L; public static ImageHelper s_imageHelper; internal static bool s_initial_server_enabled_state = true; internal static bool s_wasTombstoneCreated = false; internal static bool s_isNewDeathPin = false; internal static bool s_checkedPinsOnce = false; internal const string c_PinTxt = "Death Pin found at location"; private static Dictionary s_typeAlias = new Dictionary { { "mapicon_fire", "Fire" }, { "mapicon_house", "House" }, { "mapicon_hammer", "Hammer" }, { "mapicon_trader", "Halder" }, { "mapicon_hilder", "Hilder" }, { "mapicon_start", "Start" }, { "mapicon_pin", "Pin" }, { "mapicon_portal", "Portal" }, { "mapicon_cart", "Cart" }, { "mapicon_anchor", "Ship" }, { "mapicon_trader_swamp", "BogWitch" }, { "mapicon_boss", "Boss" } }; private static bool s_player_in_mist = false; private static float s_next_check = 0f; private static float s_attack_done = 0f; private void Awake() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown s_instance = this; Log = Logging.Initialize(Logging.LogLevels.Info, "HUDCompass"); Cfg.BepInExConfig((BaseUnityPlugin)(object)s_instance); s_resourceFolder = ModResourceBootstrap.InitializeModResources(typeof(HUDCompass), "HUDCompass"); s_imageHelper = new ImageHelper(s_resourceFolder); IgnoredNames(); IgnoredTypes(); VisibleBehavior(); s_dmm = new DynamicMapMarkers(); harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); harmony.PatchAll(Assembly.GetExecutingAssembly()); harmony.PatchAll(typeof(DynamicMapMarkers)); Log.Info("Awake"); } private void Start() { Game.isModded = true; } private void OnDestroy() { Log.Info("Unloading"); ((BaseUnityPlugin)this).Config.Save(); Log.Debug("Cleaning up markers unloading mod"); s_dmm.DestroyMarkers(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private static bool MatchNameOrWildcard(List exact, List wildcardPrefixes, List wildcardSuffixes, string name) { if (Utility.IsNullOrWhiteSpace(name)) { return false; } if (exact.Contains(name)) { return true; } if (wildcardPrefixes.Count > 0) { foreach (string wildcardPrefix in wildcardPrefixes) { if (wildcardPrefix.Length > 0 && name.Length >= wildcardPrefix.Length && wildcardPrefix == name.Substring(0, wildcardPrefix.Length)) { return true; } } } if (wildcardSuffixes.Count > 0) { foreach (string wildcardSuffix in wildcardSuffixes) { if (name.Length >= wildcardSuffix.Length && wildcardSuffix == name.Substring(name.Length - wildcardSuffix.Length)) { return true; } } } return false; } private static bool MatchType(List matches, PinData pin) { if (pin == null || matches.Count == 0) { return false; } Sprite icon = pin.m_icon; string item = ((((icon != null) ? ((Object)icon).name : null) != null && s_typeAlias.ContainsKey(((Object)pin.m_icon).name)) ? s_typeAlias[((Object)pin.m_icon).name] : ((object)Unsafe.As(ref pin.m_type)/*cast due to .constrained prefix*/).ToString()); return matches.Contains(item); } private static bool MatchTypeOrName(List matches, PinData pin) { if (pin == null || matches.Count == 0) { return false; } if (!MatchType(matches, pin)) { return matches.Contains(pin.m_name); } return true; } private static bool IsInBounds(float dist, float min, float max) { if (dist <= max) { return dist >= min; } return false; } private static bool IsInMist(Player player) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Time.time > s_next_check) { s_player_in_mist = ParticleMist.IsInMist(((Component)player).transform.position); s_next_check = Time.time + 2f; } if (Log.LogLevel >= Logging.LogLevels.Trace && s_player_in_mist) { Log.Trace("In mist period."); } return s_player_in_mist; } private static bool IsTooFoggy() { bool flag = RenderSettings.fog && (Object)(object)EnvMan.instance?.m_dirLight != (Object)null && ((double)RenderSettings.fogDensity > 0.75 || ((double)EnvMan.instance.m_dirLight.intensity < 0.25 && (double)RenderSettings.fogDensity > 0.5)); if (Log.LogLevel >= Logging.LogLevels.Trace && flag) { Log.Trace($"Obscuring fog {RenderSettings.fogDensity} light {EnvMan.instance.m_dirLight.intensity}"); } return flag; } private static bool IsAttacking(Player player) { if (((Character)player).InAttack() || ((Character)player).IsStaggering() || ((Character)player).IsKnockedBack()) { s_attack_done = Time.time + Cfg.hideCompassInCombatDelay.Value; } bool flag = Time.time < s_attack_done; if (Log.LogLevel >= Logging.LogLevels.Trace && flag) { Log.Trace("Within combat period."); } return flag; } private static Sprite GetCheckedSprite(GameObject spritePrefab) { Sprite val = null; GameObject obj = Object.Instantiate(spritePrefab); object obj2; if (obj == null) { obj2 = null; } else { Transform transform = obj.transform; if (transform == null) { obj2 = null; } else { GameObject gameObject = ((Component)transform.Find("Checked")).gameObject; if (gameObject == null) { obj2 = null; } else { Image component = gameObject.GetComponent(); obj2 = ((component != null) ? component.sprite : null); } } } val = (Sprite)obj2; Log.Debug(((Object)(object)val == (Object)null) ? "Couldn't get checked sprite" : "Got checked sprite"); return val; } private static void SetCheckedOverlay(GameObject po, Color baseColor, bool active, float alphaMultiplier = 1f) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)s_dmm.CheckedMarkerSprite == (Object)null)) { Transform val = po.transform.Find("checked"); GameObject val2; if ((Object)(object)val == (Object)null) { val2 = new GameObject("checked"); RectTransform obj = val2.AddComponent(); ((Transform)obj).SetParent(po.transform, false); obj.anchorMin = Vector2.zero; obj.anchorMax = Vector2.one; obj.offsetMin = Vector2.zero; obj.offsetMax = Vector2.zero; obj.anchoredPosition = Vector2.zero; ((Transform)obj).localScale = Vector3.one; Image obj2 = val2.AddComponent(); ((Graphic)obj2).raycastTarget = false; obj2.preserveAspect = true; obj2.type = (Type)0; ((Graphic)obj2).material = null; obj2.sprite = s_dmm.CheckedMarkerSprite; Color color = baseColor; color.a *= alphaMultiplier; ((Graphic)obj2).color = color; val2.transform.SetAsLastSibling(); } else { val2 = ((Component)val).gameObject; } if (val2.activeInHierarchy != active) { val2.SetActive(active); } } } internal static void ConfigureHUD() { ConfigHUD(Hud.m_instance); } internal static void ConfigHUD(Hud hudInstance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Expected O, but got Unknown //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: 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_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) s_objectParent = new GameObject(); ((Object)s_objectParent).name = "Compass"; ((Transform)s_objectParent.AddComponent()).SetParent(hudInstance.m_rootObject.transform, false); GameObject val = new GameObject(); ((Object)val).name = "Mask"; RectTransform obj = val.AddComponent(); ((Transform)obj).SetParent(s_objectParent.transform, false); Rect rect = s_spriteCompass.rect; float width = ((Rect)(ref rect)).width; rect = s_spriteCompass.rect; obj.sizeDelta = new Vector2(width, ((Rect)(ref rect)).height); ((Transform)obj).localScale = Vector3.one * Cfg.compassScale.Value; obj.anchoredPosition = Vector2.zero; Image obj2 = val.AddComponent(); obj2.sprite = s_spriteMask; obj2.preserveAspect = true; val.AddComponent().showMaskGraphic = false; s_objectCompass = new GameObject(); ((Object)s_objectCompass).name = "Image"; RectTransform obj3 = s_objectCompass.AddComponent(); ((Transform)obj3).SetParent(val.transform, false); ((Transform)obj3).localScale = Vector3.one; obj3.anchoredPosition = Vector2.zero; rect = s_spriteCompass.rect; float width2 = ((Rect)(ref rect)).width; rect = s_spriteCompass.rect; obj3.sizeDelta = new Vector2(width2, ((Rect)(ref rect)).height); Image obj4 = s_objectCompass.AddComponent(); obj4.sprite = s_spriteCompass; obj4.preserveAspect = true; if ((Object)(object)s_spriteCenter != (Object)null) { s_objectCenterMark = new GameObject(); ((Object)s_objectCenterMark).name = "CenterMark"; RectTransform obj5 = s_objectCenterMark.AddComponent(); ((Transform)obj5).SetParent(val.transform, false); ((Transform)obj5).localScale = Vector3.one; obj5.anchoredPosition = Vector2.zero; rect = s_spriteCenter.rect; float width3 = ((Rect)(ref rect)).width; rect = s_spriteCenter.rect; obj5.sizeDelta = new Vector2(width3, ((Rect)(ref rect)).height); Image obj6 = s_objectCenterMark.AddComponent(); obj6.sprite = s_spriteCenter; obj6.preserveAspect = true; } s_objectPins = new GameObject(); ((Object)s_objectPins).name = "Pins"; RectTransform obj7 = s_objectPins.AddComponent(); ((Transform)obj7).SetParent(val.transform, false); ((Transform)obj7).localScale = Vector3.one; obj7.anchoredPosition = Vector2.zero; rect = s_spriteMask.rect; float width4 = ((Rect)(ref rect)).width; rect = s_spriteMask.rect; obj7.sizeDelta = new Vector2(width4, ((Rect)(ref rect)).height); s_objectParent.SetActive(Cfg.enableCompass.Value && Cfg.showHideCompass.Value); } private static bool OkToKey(Player player) { if (!Chat.instance.HasFocus() && !Console.IsVisible() && (Object)(object)TextViewer.instance != (Object)null && !TextViewer.instance.IsVisible() && !GameCamera.InFreeFly() && !TextInput.IsVisible() && !StoreGui.IsVisible() && !((Character)player).InCutscene() && !((Character)player).InBed() && !((Character)player).IsTeleporting()) { return !((Character)player).IsDead(); } return false; } private static void SetInitialPlayerPinCfgVisibility() { if ((Object)(object)Minimap.instance != (Object)null) { Cfg.compassShowMyPlayerPin.ConfigEntry.SettingChanged -= SettingChanged_ShowMyPlayerPin; Cfg.compassShowMyPlayerPin.Value = Object.op_Implicit((Object)(object)Minimap.instance.m_publicPosition); Cfg.compassShowMyPlayerPin.ConfigEntry.SettingChanged += SettingChanged_ShowMyPlayerPin; } } public static void SettingChanged_PlayerPinBehavior(object sender, EventArgs e) { ManagePinVisibility(); } public static void SettingChanged_ShowMyPlayerPin(object sender, EventArgs e) { ManagePinVisibility(); } public static void ManagePinVisibility() { bool flag = Cfg.compassShowMyPlayerPin.Value; switch (Cfg.playerPinBehavior.Value) { case PlayerPinBehavior.ForceOff: flag = false; break; case PlayerPinBehavior.ForceOn: flag = true; break; } if ((Object)(object)ZNet.instance != (Object)null) { ZNet.instance.SetPublicReferencePosition(flag); } if ((Object)(object)Minimap.instance?.m_largeRoot != (Object)null) { Minimap.instance.m_publicPosition.isOn = flag; } Cfg.compassShowMyPlayerPin.ConfigEntry.SettingChanged -= SettingChanged_ShowMyPlayerPin; Cfg.compassShowMyPlayerPin.Value = flag; Cfg.compassShowMyPlayerPin.ConfigEntry.SettingChanged += SettingChanged_ShowMyPlayerPin; } public static void SettingChanged_ShowCompass(object sender, EventArgs e) { if ((Object)(object)s_objectParent != (Object)null && Cfg.enableCompass.Value) { s_objectParent.SetActive(Cfg.showHideCompass.Value); } } public static void SettingChanged_EnableCompass(object sender, EventArgs e) { if ((Object)(object)s_objectParent != (Object)null) { s_objectParent.SetActive(Cfg.enableCompass.Value && Cfg.showHideCompass.Value); } } public static void SettingChanged_IgnoredNames(object sender, EventArgs e) { IgnoredNames(); } public static void IgnoredNames() { s_ignoredNames.Clear(); s_ignoredWildcardPrefixes.Clear(); s_ignoredWildcardSuffixes.Clear(); string[] array = Cfg.ignoredPinNames.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Contains("*")) { bool flag = false; bool flag2 = false; if (text.StartsWith("*")) { text = text.Substring(1); flag = true; } if (text.EndsWith("*")) { text = text.Substring(0, text.Length - 1); flag2 = true; } if (flag) { s_ignoredWildcardSuffixes.Add(text); } if (flag2) { s_ignoredWildcardPrefixes.Add(text); } } else { s_ignoredNames.Add(text); } } } public static void SettingChanged_IgnoredTypes(object sender, EventArgs e) { IgnoredTypes(); } public static void IgnoredTypes() { s_ignoredTypes.Clear(); string[] array = Cfg.ignoredPinTypes.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { s_ignoredTypes.Add(text.Trim()); } } public static void SettingChanged_VisibleBehavior(object sender, EventArgs e) { VisibleBehavior(); } public static void VisibleBehavior() { s_alwaysVisible.Clear(); string[] array = Cfg.alwaysVisible.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { s_alwaysVisible.Add(text.Trim()); } } } [Serializable] public class MarkerData { public MarkerType Type { get; set; } public GameObject Marker { get; set; } public ZDOID Zdoid { get; set; } public string Label { get; set; } public Vector3 Position { get; set; } public GameObject Nametag { get; set; } public bool IsActivePortal { get; set; } public long Creator { get; set; } public static void Destroy(MarkerData md) { Object.Destroy((Object)(object)md.Marker); Object.Destroy((Object)(object)md.Nametag); } } public class MarkerType { public string Prefab { get; } public int PrefabHash { get; } public Sprite Sprite { get; set; } public string Name { get; } public MarkerGroup Group { get; set; } private ConfigEntry _showConifgEntry { get; } public PinType PinType { get; set; } public bool Show => _showConifgEntry.Value; public MarkerType(string prefab, Sprite sprite, string name, MarkerGroup group, PinType pintype, ConfigEntry show) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) Prefab = prefab; PrefabHash = StringExtensionMethods.GetStableHashCode(prefab); Sprite = sprite; Name = name; Group = group; PinType = pintype; _showConifgEntry = show; } } internal class TombstonePinPatches { [HarmonyPatch(typeof(Player), "CreateTombStone")] private static class Player_CreateTombstone_Patch { [HarmonyPrefix] private static void Player_CreateTombStone_Prefix(Player __instance) { Log.Debug("Player_CreateTombStone_Patch_Prefix"); HUDCompass.s_wasTombstoneCreated = ((Humanoid)__instance).m_inventory.NrOfItems() > 0; HUDCompass.s_isNewDeathPin = true; } } [HarmonyPatch(typeof(Minimap), "AddPin")] private static class Minimap_AddPin_Patch { [HarmonyPostfix] private static void Minimap_AddPin_Postfix(Minimap __instance, PinType type, PinData __result) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 Log.Debug("Minimap_AddPin_Patch_Postfix"); if ((int)type == 4 && HUDCompass.s_isNewDeathPin) { HUDCompass.s_isNewDeathPin = false; if (Cfg.autoDeleteDeathPin.Value && !HUDCompass.s_wasTombstoneCreated && __result != null) { __instance.RemovePin(__result); Log.Debug("No tombstone created. Removed empty inventory death pin."); } } } } [HarmonyPatch(typeof(TombStone), "Setup")] private static class TombStone_Setup_Patch { [HarmonyPostfix] private static void TombStone_Setup_Postfix(TombStone __instance) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) Log.Debug("TombStone_Setup_Patch_Postfix"); ZDO zDO = __instance.m_nview.GetZDO(); if (zDO != null) { Vector3 vec = zDO.GetVec3(ZDOVars.s_spawnPoint, Vector3.positiveInfinity); if (vec == Vector3.positiveInfinity) { Log.Warning("Can't find Tombstone spawn point in Setup"); return; } Log.Debug($"Setting Tombstone spawn point to {vec}"); zDO.Set("HUDCompass_1847_Key", vec); } } } [HarmonyPatch(typeof(TombStone), "OnTakeAllSuccess")] private static class TombStone_OnTakeAllSuccess_Patch { [HarmonyPrefix] private static void TombStone_OnTakeAllSuccess_Prefix(TombStone __instance, out PinData __state) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Invalid comparison between Unknown and I4 //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) Log.Debug("TombStone_OnTakeAllSuccess_Patch_Prefix"); __state = null; if (!Cfg.autoDeleteDeathPin.Value) { return; } ZNetView nview = __instance.m_nview; ZDO val = ((nview != null) ? nview.GetZDO() : null); if (val == null) { return; } Vector3 vec = val.GetVec3("HUDCompass_1847_Key", Vector3.positiveInfinity); if (vec == Vector3.positiveInfinity) { Log.Debug("Didn't find Tombstone custom key. Trying default spawn point."); vec = val.GetVec3(ZDOVars.s_spawnPoint, Vector3.positiveInfinity); } if (vec == Vector3.positiveInfinity) { Log.Warning("Couldn't find Tombstone spawn point"); return; } val.GetLong(ZDOVars.s_owner, 0L); if ((Object)(object)Minimap.instance == (Object)null) { Log.Warning("Minimap is missing"); return; } foreach (PinData item in Minimap.instance?.m_pins) { if (item != null && (int)item.m_type == 4 && Utils.DistanceSqrXZ(item.m_pos, vec) < 0.01f) { __state = item; break; } } if (__state == null) { Log.Debug("Death Pin position lookup failed"); } else { Log.Debug($"Found Death Pin at {__state.m_pos}"); } } [HarmonyPostfix] private static void TombStone_OnTakeAllSuccess_Postfix(TombStone __instance, PinData __state) { Log.Debug("TombStone_OnTakeAllSuccess_Patch_Postfix"); if (Cfg.autoDeleteDeathPin.Value && __state != null && (Object)(object)Minimap.instance != (Object)null && Minimap.instance.m_pins.Contains(__state)) { Minimap.instance.RemovePin(__state); Log.Debug("Removed death pin."); } } } internal static Logging Log = Logging.Instance; public const string c_HudKey = "HUDCompass_1847_Key"; } }