using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using ConditionalConfigSync; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Compass")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Compass")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("873ca971-9465-4427-a377-7523973b9138")] [assembly: AssemblyFileVersion("1.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } public class WildcardPattern { private readonly string _expression; private readonly Regex _regex; public WildcardPattern(string pattern) { if (string.IsNullOrEmpty(pattern)) { throw new ArgumentNullException("pattern"); } _expression = "^" + Regex.Escape(pattern).Replace("\\\\\\?", "??").Replace("\\?", ".") .Replace("??", "\\?") .Replace("\\\\\\*", "**") .Replace("\\*", ".*") .Replace("**", "\\*") + "$"; _regex = new Regex(_expression, RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant); } public bool IsMatch(string value) { return _regex.IsMatch(value); } } namespace Compass { [BepInPlugin("shudnal.Compass", "Compass", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Compass : BaseUnityPlugin { public enum OrientationType { Camera, Player } public enum AnchorPositionType { Top, Bottom } [Flags] public enum CompassPinType { None = 0, Icon0 = 1, Icon1 = 2, Icon2 = 4, Icon3 = 8, Icon4 = 0x10, Death = 0x20, Bed = 0x40, Shout = 0x80, Boss = 0x100, Player = 0x200, RandomEvent = 0x400, Ping = 0x800, EventArea = 0x1000, HildirQuest = 0x2000, Static = 0x4000, Custom = 0x8000, All = 0xFFFF } public const string pluginID = "shudnal.Compass"; public const string pluginName = "Compass"; public const string pluginVersion = "1.1.0"; private readonly Harmony harmony = new Harmony("shudnal.Compass"); internal static readonly ConfigSync configSync = new ConfigSync("shudnal.Compass") { DisplayName = "Compass", CurrentVersion = "1.1.0", MinimumRequiredVersion = "1.1.0", ModRequired = false }; internal static Compass instance; private static FileSystemWatcher imageFileWatcher; private static readonly Dictionary pendingImageReloads = new Dictionary(StringComparer.OrdinalIgnoreCase); private const float imageReloadDelay = 0.1f; private const int imageReloadAttempts = 5; public static ConfigEntry configLocked; public static ConfigEntry modEnabled; public static ConfigEntry loggingEnabled; public static ConfigEntry orientation; public static ConfigEntry anchorPosition; public static ConfigEntry scale; public static ConfigEntry offset; public static ConfigEntry showCenter; public static ConfigEntry detailedMode; public static ConfigEntry showPins; public static ConfigEntry pinNamesToIgnore; public static ConfigEntry showOnlyLastDeath; public static ConfigEntry hideChecked; public static ConfigEntry hideShared; public static ConfigEntry alwaysShowPinText; public static ConfigEntry holdToAlwaysShowPings; public static ConfigEntry holdToAlwaysShowShouts; public static ConfigEntry holdToAlwaysShowPlayerPin; public static ConfigEntry holdToShowText; public static ConfigEntry pinsAlpha; public static ConfigEntry pinsScale; public static ConfigEntry pinsStyleConditions; public static ConfigEntry compassColor; public static ConfigEntry centerColor; public static ConfigEntry pinsColor; public static ConfigEntry pinTextSize; public static ConfigEntry pinTextColor; public static ConfigEntry pinTextFormat; public static ConfigEntry pinNameOffset; public static ConfigEntry pinOffset; public static ConfigEntry pinNameScaleDistant; public static readonly string configDirectory = Path.Combine(Paths.ConfigPath, "shudnal.Compass"); private void Awake() { instance = this; ConfigInit(); ((ConditionalConfigSync)configSync).AddLockingConfigEntry(configLocked); harmony.PatchAll(); Game.isModded = true; CompassHUD.CheckImageFiles(); ImageSync.Initialize(); SetupFileWatcher(); } private void ConfigInit() { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Expected O, but got Unknown //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0321: 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_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04e4: Unknown result type (might be due to invalid IL or missing references) //IL_050e: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Unknown result type (might be due to invalid IL or missing references) //IL_0562: Unknown result type (might be due to invalid IL or missing references) //IL_05d2: Unknown result type (might be due to invalid IL or missing references) //IL_060e: Unknown result type (might be due to invalid IL or missing references) configLocked = serverConfig("General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only."); modEnabled = config("General", "Enabled", defaultValue: true, "Enable the mod.", synchronizedSetting: true); loggingEnabled = config("General", "Logging enabled", defaultValue: false, "Enable logging."); modEnabled.SettingChanged += delegate { CompassHUD.UpdateParentObject(); }; orientation = config("Compass", "Orientation based on", OrientationType.Camera, "Orientation type. Camera direction or player eyes direction could be used as a center of a compass.", synchronizedSetting: true); anchorPosition = config("Compass", "Anchor position", AnchorPositionType.Top, "Defines whether compass is anchored to top or bottom side of the screen.", synchronizedSetting: true); scale = config("Compass", "Scale", 1f, "Scale of whole compass component"); offset = config("Compass", "Position offset", Vector2.zero, "Offset from selected anchor position. X moves compass left/right. Y moves compass down from top, up from bottom."); showCenter = config("Compass", "Show center", defaultValue: true, "Show center marker"); detailedMode = config("Compass", "Detailed mode", defaultValue: false, "Use the detailed compass, center, and mask image set.", synchronizedSetting: true); anchorPosition.SettingChanged += delegate { CompassHUD.UpdateImageMode(); }; scale.SettingChanged += delegate { CompassHUD.UpdateParentObject(); }; offset.SettingChanged += delegate { CompassHUD.UpdateParentObject(); }; showCenter.SettingChanged += delegate { CompassHUD.UpdateCenterObject(); }; detailedMode.SettingChanged += delegate { CompassHUD.UpdateImageMode(); }; showPins = config("Pins", "Show pins", CompassPinType.All, "Pin types to show on the compass. Use Configuration Manager for more convenient editing.\nStatic - fixed locations like Haldor, Hildir, Bog Witch, Sacrificial Stones\nCustom - Any custom pin type added by other mods\nEventArea - red circle around an event\nRandomEvent - red exclamation mark of an event", synchronizedSetting: true); pinNamesToIgnore = config("Pins", "Ignore pin names", "Silver&&Obsidian&&Copper&&Tin", new ConfigDescription("&& separated pin names to ignore. Wildcards * and ? supported. Use Configuration Manager for more convenient editing.", (AcceptableValueBase)null, new object[1] { new CustomConfigs.ConfigurationManagerAttributes { CustomDrawer = CustomConfigs.DrawSeparatedStrings("&&") } }), synchronizedSetting: true); showOnlyLastDeath = config("Pins", "Show only last death", defaultValue: true, "Death pins except the last one will be hidden.", synchronizedSetting: true); hideChecked = config("Pins", "Hide checked pins", defaultValue: false, "Hide pins checked by red cross.", synchronizedSetting: true); hideShared = config("Pins", "Hide shared pins", defaultValue: false, "Hide pins shared via Cartography Table.", synchronizedSetting: true); holdToAlwaysShowShouts = config("Pins", "Hold to show shouts at any distance", new KeyboardShortcut((KeyCode)308, Array.Empty()), "Hold to show player shouts without distance filter.", synchronizedSetting: true); holdToAlwaysShowPlayerPin = config("Pins", "Hold to show players at any distance", new KeyboardShortcut((KeyCode)308, Array.Empty()), "Hold to show players with public positions without distance filter.", synchronizedSetting: true); holdToAlwaysShowPings = config("Pins", "Hold to show pings at any distance", new KeyboardShortcut((KeyCode)308, Array.Empty()), "Hold to show player pings without distance filter.", synchronizedSetting: true); holdToShowText = config("Pins", "Hold to show pin text", new KeyboardShortcut((KeyCode)306, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Hold to show pin text if it is set.", synchronizedSetting: true); alwaysShowPinText = config("Pins", "Always show pin text", defaultValue: false, "Always show pin text if it is set.", synchronizedSetting: true); showPins.SettingChanged += delegate { CompassHUD.UpdatePinsObject(); }; pinNamesToIgnore.SettingChanged += delegate { UpdatePinFilterNames(); }; UpdatePinFilterNames(); compassColor = config("Style", "Compass color", Color.white - new Color(0f, 0f, 0f, 0.5f), "Compass color"); centerColor = config("Style", "Center color", Color.yellow - new Color(0f, 0f, 0f, 0.5f), "Center marker color"); compassColor.SettingChanged += delegate { CompassHUD.UpdateCompassObject(); }; centerColor.SettingChanged += delegate { CompassHUD.UpdateCenterObject(); }; pinsColor = config("Pin style", "Color", Color.clear, "Pins color. If not set - default is white"); pinsAlpha = config("Pin style", "Alpha", new Vector2(1f, 0.33f), "Pins alpha. X for max alpha, Y for min alpha"); pinsScale = config("Pin style", "Scale", new Vector2(1f, 0.33f), "Pins scale. X for max scale, Y for min scale"); pinOffset = config("Pin style", "Pin offset", Vector2.zero, "Additional pin offset relative to the compass. Y is flipped automatically for top/bottom anchor modes."); pinsStyleConditions = config("Pin style", "Style conditions", new Vector4(1f, 20f, 250f, 550f), "Conditions for alpha and scale application\nX - Minimum distance to show pins\nY - Distance where pins will start to become smaller. Size is at maximum. Alpha is at maximum.\nZ - Distance where pins will start to become more transparent. Size is at minimum. Alpha is at maximum.\nW - Maximum distance to show pins. Size is at minimum. Alpha is at minimum.", synchronizedSetting: true); pinsStyleConditions.SettingChanged += delegate { UpdatePinsStyleConditions(); }; UpdatePinsStyleConditions(); pinTextSize = config("Pin text style", "Size", 18f, "Pin text size"); pinTextColor = config("Pin text style", "Color", Color.white, "Pin text color"); pinTextFormat = config("Pin text style", "Format", (FontStyles)1, "Pin text format"); pinNameOffset = config("Pin text style", "Name offset", Vector2.zero, "Additional name offset relative to the pin icon. Y is flipped automatically for top/bottom anchor modes."); pinNameScaleDistant = config("Pin text style", "Scale distant pin text", defaultValue: true, "Scale pin text size a bit when it becomes too distant"); pinTextSize.SettingChanged += delegate { CompassHUD.UpdatePinTextStyle(); }; pinTextColor.SettingChanged += delegate { CompassHUD.UpdatePinTextStyle(); }; pinTextFormat.SettingChanged += delegate { CompassHUD.UpdatePinTextStyle(); }; ImageSync.Register((string group, string name, bool defaultValue, string description) => serverConfig(group, name, defaultValue, description)); } private void OnDestroy() { imageFileWatcher?.Dispose(); imageFileWatcher = null; foreach (Coroutine value in pendingImageReloads.Values) { if (value != null) { ((MonoBehaviour)this).StopCoroutine(value); } } pendingImageReloads.Clear(); ((BaseUnityPlugin)this).Config.Save(); instance = null; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } private ConfigEntry config(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = false) { return ((ConditionalConfigSync)configSync).AddConfigEntry(((BaseUnityPlugin)this).Config, group, name, defaultValue, description, (ConfigSyncMode)1, synchronizedSetting).SourceConfig; } private ConfigEntry serverConfig(string group, string name, T defaultValue, ConfigDescription description) { return ((ConditionalConfigSync)configSync).AddConfigEntry(((BaseUnityPlugin)this).Config, group, name, defaultValue, description, (ConfigSyncMode)0, true).SourceConfig; } private ConfigEntry config(string group, string name, T defaultValue, string description, bool synchronizedSetting = false) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty()), synchronizedSetting); } private ConfigEntry serverConfig(string group, string name, T defaultValue, string description) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown return serverConfig(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty())); } public static void LogInfo(object data) { if (loggingEnabled.Value) { ((BaseUnityPlugin)instance).Logger.LogInfo(data); } } public static void LogWarning(object data) { ((BaseUnityPlugin)instance).Logger.LogWarning(data); } private static void UpdatePinFilterNames() { CompassHUD.filteredNames = new HashSet(StringComparer.OrdinalIgnoreCase); CompassHUD.filteredWildcardPatterns.Clear(); IEnumerable enumerable = from value in pinNamesToIgnore.Value.Split(new string[1] { "&&" }, StringSplitOptions.RemoveEmptyEntries) select value.Trim() into value where !string.IsNullOrWhiteSpace(value) select value; foreach (string item in enumerable) { if (item.IndexOf('*') >= 0 || item.IndexOf('?') >= 0) { CompassHUD.filteredWildcardPatterns.Add(new WildcardPattern(item)); } else { CompassHUD.filteredNames.Add(item); } } } private static void UpdatePinsStyleConditions() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0023: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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) //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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) Vector4 value = pinsStyleConditions.Value; float num = Mathf.Max(0f, Mathf.Floor(value.x)); float num2 = Mathf.Max(num, Mathf.Floor(value.y)); float num3 = Mathf.Max(num2 + 1f, Mathf.Floor(value.z)); float num4 = Mathf.Max(num3 + 1f, Mathf.Floor(value.w)); CompassHUD.effectivePinsStyleConditions = new Vector4(num, num2, num3, num4); if (value != CompassHUD.effectivePinsStyleConditions) { LogWarning($"Invalid Pin style conditions {value}. Runtime values were normalized to {CompassHUD.effectivePinsStyleConditions}."); } } public static void SetupFileWatcher() { imageFileWatcher?.Dispose(); imageFileWatcher = new FileSystemWatcher(configDirectory, ImageFileInfo.filter) { IncludeSubdirectories = false, SynchronizingObject = ThreadingHelper.SynchronizingObject }; imageFileWatcher.Changed += OnTextureFileChange; imageFileWatcher.Created += OnTextureFileChange; imageFileWatcher.Renamed += OnTextureFileChange; imageFileWatcher.Deleted += OnTextureFileChange; imageFileWatcher.EnableRaisingEvents = true; } private static void OnTextureFileChange(object sender, FileSystemEventArgs eargs) { QueueImageFileRefresh(eargs.Name); if (eargs is RenamedEventArgs e) { QueueImageFileRefresh(e.OldName); } } private static void QueueImageFileRefresh(string filename) { if ((Object)(object)instance == (Object)null || string.IsNullOrEmpty(filename)) { return; } string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filename); if (ImageFileInfo.images.ContainsKey(fileNameWithoutExtension)) { if (pendingImageReloads.TryGetValue(fileNameWithoutExtension, out var value) && value != null) { ((MonoBehaviour)instance).StopCoroutine(value); } pendingImageReloads[fileNameWithoutExtension] = ((MonoBehaviour)instance).StartCoroutine(RefreshImageFile(fileNameWithoutExtension)); } } private static IEnumerator RefreshImageFile(string imageID) { yield return (object)new WaitForSecondsRealtime(0.1f); ImageFileInfo imageInfo = ImageFileInfo.GetImageInfo(imageID); if (ImageSync.IsRemoteOverrideActive(imageID)) { pendingImageReloads.Remove(imageID); yield break; } int attempt = 0; while (attempt < 5) { if (!File.Exists(imageInfo.filePath)) { ImageFileInfo.TryClearFile(imageInfo.fileName); ImageSync.Publish(imageID); pendingImageReloads.Remove(imageID); yield break; } if (ImageFileInfo.TryLoadFile(imageInfo.fileName)) { ImageSync.Publish(imageID); pendingImageReloads.Remove(imageID); yield break; } yield return (object)new WaitForSecondsRealtime(0.1f); int num = attempt + 1; attempt = num; } pendingImageReloads.Remove(imageID); LogWarning("Failed to reload image " + imageInfo.fileName + ". The previous valid image remains active."); } internal static byte[] GetEmbeddedFileData(string filename) { Assembly executingAssembly = Assembly.GetExecutingAssembly(); string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename)); Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(name); byte[] array = new byte[manifestResourceStream.Length]; manifestResourceStream.Read(array, 0, array.Length); return array; } } internal class CustomConfigs { internal class ConfigurationManagerAttributes { [UsedImplicitly] public Action? CustomDrawer; } internal static object? configManager; internal static Type? configManagerStyles; internal static GUIStyle GetStyle(GUIStyle other) { //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) //IL_0051: Expected O, but got Unknown if (configManagerStyles == null) { return other; } FieldInfo fieldInfo = AccessTools.Field(configManagerStyles, "fontSize"); if (fieldInfo == null) { return other; } return new GUIStyle(other) { fontSize = (int)fieldInfo.GetValue(configManagerStyles) }; } internal static void Awake() { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "ConfigurationManager"); Type type = assembly?.GetType("ConfigurationManager.ConfigurationManager"); configManager = ((type == null) ? null : Chainloader.ManagerObject.GetComponent(type)); configManagerStyles = assembly?.GetType("ConfigurationManager.ConfigurationManagerStyles"); } internal static Action DrawSeparatedStrings(string splitString) { return delegate(ConfigEntryBase cfg) { //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select((object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : ((bool?)null)).FirstOrDefault((bool? v) => v.HasValue) == true; bool flag = false; GUILayout.BeginVertical(Array.Empty()); List list = new List(); List list2 = ((string)cfg.BoxedValue).Split(new string[1] { splitString }, StringSplitOptions.None).ToList(); for (int num = 0; num < list2.Count; num++) { GUILayout.BeginHorizontal(Array.Empty()); string text = list2[num]; string text2 = GUILayout.TextField(text, GetStyle(GUI.skin.textArea), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (text2 != text && !valueOrDefault) { flag = true; } if (GUILayout.Button("x", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty()) && !valueOrDefault) { flag = true; } else { list.Add(text2); } if (GUILayout.Button("+", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty()) && !valueOrDefault) { flag = true; list.Add(""); } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); if (flag) { cfg.BoxedValue = string.Join(splitString, list); } }; } } internal static class CompassHUD { public class PinElement { public string name; public RectTransform rect; public Image image; public GameObject checkedIcon; public TMP_Text text; public PinElement() { rect = Object.Instantiate(pinElement, (Transform)(object)pinsRootObject); ((Component)rect).gameObject.SetActive(true); image = ((Component)rect).GetComponent(); Transform obj = ((Transform)rect).Find("Checked"); checkedIcon = ((obj != null) ? ((Component)obj).gameObject : null); Transform obj2 = ((Transform)rect).Find("Name"); text = ((obj2 != null) ? ((Component)obj2).GetComponent() : null); pinsList.Add(this); } public void Destroy() { RectTransform obj = rect; Object.Destroy((Object)(object)((obj != null) ? ((Component)obj).gameObject : null)); } } [HarmonyPatch(typeof(Hud), "Awake")] private static class Hud_Awake_Initialize { private static void Postfix() { InitializeCompass(); } } [HarmonyPatch(typeof(Hud), "Update")] public static class Hud_Update_Compass { public static void Postfix() { UpdateCompass(); } } [HarmonyPatch(typeof(Hud), "OnDestroy")] public static class Hud_OnDestroy_Compass { public static void Postfix() { DestroyCompass(); } } [HarmonyPatch(typeof(Player), "SetCrouch")] public static class Player_SetCrouch_PreventCrouchingOnControlPress { private static bool IsCtrlDown(KeyboardShortcut shortcut) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return (ZInput.GetButton("Crouch") || ZInput.GetButton("JoyCrouch")) && IsShortcutDown(shortcut); } [HarmonyPriority(800)] public static bool Prefix() { //IL_0005: 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) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) return !IsCtrlDown(Compass.holdToAlwaysShowPings.Value) && !IsCtrlDown(Compass.holdToAlwaysShowPlayerPin.Value) && !IsCtrlDown(Compass.holdToAlwaysShowShouts.Value) && !IsCtrlDown(Compass.holdToShowText.Value); } } public const string fileNameCompass = "compass"; public const string fileNameCompassBottom = "compass_bottom"; public const string fileNameCompassDetailed = "compass_detailed"; public const string fileNameCompassDetailedBottom = "compass_detailed_bottom"; public const string fileNameCenter = "center"; public const string fileNameCenterBottom = "center_bottom"; public const string fileNameCenterDetailed = "center_detailed"; public const string fileNameCenterDetailedBottom = "center_detailed_bottom"; public const string fileNameMask = "mask"; public const string fileNameMaskDetailed = "mask_detailed"; public const string fileNameOverlay = "overlay"; public const string fileNameUnderlay = "underlay"; private const string objectRootName = "Compass_Parent"; private const string objectOverlayName = "Overlay"; private const string objectUnderlayName = "Underlay"; private const string objectGlobalMaskName = "GlobalMask"; private const string objectMaskName = "Mask"; private const string objectCompassName = "Compass"; private const string objectCenterName = "Center"; private const string objectPinsRootName = "Pins"; private const string objectPinElementName = "PinElement"; private const string objectPinElementCheckedName = "Checked"; private const string objectPinElementNameName = "Name"; private static readonly int layerUI = LayerMask.NameToLayer("UI"); public static GameObject parentObject; public static GameObject compassObject; public static GameObject centerObject; public static GameObject maskObject; public static RectTransform pinsRootObject; public static RectTransform pinElement; public static RectTransform compassTransform; public static Mask maskComponent; public static Image maskImage; public static float compassWidth; public static readonly List tempPins = new List(); public static readonly List pinsList = new List(); public static HashSet filteredNames = new HashSet(StringComparer.OrdinalIgnoreCase); public static readonly List filteredWildcardPatterns = new List(); public static Vector4 effectivePinsStyleConditions = new Vector4(1f, 20f, 250f, 550f); private static Transform AnchorTransform { get { object result; if (Compass.orientation.Value != Compass.OrientationType.Camera) { Player localPlayer = Player.m_localPlayer; result = ((localPlayer != null) ? ((Component)localPlayer).transform : null); } else { GameCamera instance = GameCamera.instance; result = ((instance != null) ? ((Component)instance).transform : null); } return (Transform)result; } } public static void CheckImageFiles() { Directory.CreateDirectory(Compass.configDirectory); string[] array = new string[10] { "compass", "compass_bottom", "compass_detailed", "compass_detailed_bottom", "center", "center_bottom", "center_detailed", "center_detailed_bottom", "mask", "mask_detailed" }; string[] array2 = array; foreach (string id in array2) { CheckFile(id); } static void CheckFile(string id2) { ImageFileInfo imageInfo = ImageFileInfo.GetImageInfo(id2); if (!imageInfo.initialized) { File.WriteAllBytes(imageInfo.filePath, Compass.GetEmbeddedFileData(imageInfo.fileName)); imageInfo.Load(); } } } public static void UpdateParentObject() { //IL_0038: 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_010c: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)parentObject)) { return; } parentObject.SetActive(Compass.modEnabled.Value); RectTransform component = parentObject.GetComponent(); ((Transform)component).localScale = Vector3.one * Compass.scale.Value; ImageFileInfo activeCompassImageInfo = GetActiveCompassImageInfo(); Texture2D texture = activeCompassImageInfo.texture; if (activeCompassImageInfo.initialized && Object.op_Implicit((Object)(object)texture)) { if (Compass.anchorPosition.Value == Compass.AnchorPositionType.Bottom) { component.anchorMin = new Vector2(0.5f, 0f); component.anchorMax = new Vector2(0.5f, 0f); component.anchoredPosition = new Vector2(0f, (float)(((Texture)texture).height / 2)) + new Vector2(0f - Compass.offset.Value.x, Compass.offset.Value.y); } else { component.anchorMin = new Vector2(0.5f, 1f); component.anchorMax = new Vector2(0.5f, 1f); component.anchoredPosition = new Vector2(0f, (float)(-((Texture)texture).height / 2)) - Compass.offset.Value; } } } private static ImageFileInfo GetActiveCompassImageInfo() { return GetActiveImageInfo("compass", "compass_bottom", "compass_detailed", "compass_detailed_bottom"); } private static ImageFileInfo GetActiveCenterImageInfo() { return GetActiveImageInfo("center", "center_bottom", "center_detailed", "center_detailed_bottom"); } private static ImageFileInfo GetActiveMaskImageInfo() { ImageFileInfo imageInfo = ImageFileInfo.GetImageInfo("mask_detailed"); if (Compass.detailedMode.Value && imageInfo.initialized) { return imageInfo; } return ImageFileInfo.GetImageInfo("mask"); } private static ImageFileInfo GetActiveImageInfo(string defaultId, string bottomId, string detailedId, string detailedBottomId) { bool flag = Compass.anchorPosition.Value == Compass.AnchorPositionType.Bottom; string[] array = ((!Compass.detailedMode.Value) ? ((!flag) ? new string[1] { defaultId } : new string[2] { bottomId, defaultId }) : ((!flag) ? new string[2] { detailedId, defaultId } : new string[4] { detailedBottomId, bottomId, detailedId, defaultId })); string[] array2 = array; foreach (string id in array2) { ImageFileInfo imageInfo = ImageFileInfo.GetImageInfo(id); if (imageInfo.initialized) { return imageInfo; } } return ImageFileInfo.GetImageInfo(defaultId); } private static void BindActiveImage(GameObject target, ImageFileInfo activeImage, params string[] imageIds) { foreach (string id in imageIds) { ImageFileInfo.GetImageInfo(id).SetGameObject(null); } activeImage.SetGameObject(target).UpdateGameObject(); } public static void UpdateAnchorImages() { if (Object.op_Implicit((Object)(object)compassObject) && Object.op_Implicit((Object)(object)centerObject)) { BindActiveImage(compassObject, GetActiveCompassImageInfo(), "compass", "compass_bottom", "compass_detailed", "compass_detailed_bottom"); BindActiveImage(centerObject, GetActiveCenterImageInfo(), "center", "center_bottom", "center_detailed", "center_detailed_bottom"); } } public static void UpdateImageMode() { UpdateAnchorImages(); UpdateMaskObject(); UpdateParentObject(); UpdateCompassObject(); UpdateCenterObject(); UpdatePinsObject(); } public static void UpdateCenterObject() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)centerObject)) { ((Graphic)centerObject.GetComponent()).color = Compass.centerColor.Value; centerObject.SetActive(Compass.showCenter.Value); } } public static void UpdateMaskObject() { if (Object.op_Implicit((Object)(object)maskObject)) { ImageFileInfo activeCompassImageInfo = GetActiveCompassImageInfo(); ImageFileInfo activeMaskImageInfo = GetActiveMaskImageInfo(); ImageFileInfo.GetImageInfo("mask").SetGameObject(null); ImageFileInfo.GetImageInfo("mask_detailed").SetGameObject(null); if (activeCompassImageInfo.initialized && Object.op_Implicit((Object)(object)activeCompassImageInfo.texture) && activeMaskImageInfo.initialized) { activeMaskImageInfo.SetSpriteWidth(((Texture)activeCompassImageInfo.texture).width / 2).SetGameObject(maskObject).UpdateGameObject(); } } } public static void UpdateCompassObject() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)compassObject)) { Image component = compassObject.GetComponent(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.sprite)) { compassWidth = 0f; return; } ((Graphic)component).color = Compass.compassColor.Value; Rect rect = component.sprite.rect; compassWidth = ((Rect)(ref rect)).width; } } public static void UpdatePinsObject() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)pinsRootObject)) { ((Component)pinsRootObject).gameObject.SetActive(Compass.showPins.Value != Compass.CompassPinType.None); ImageFileInfo activeCompassImageInfo = GetActiveCompassImageInfo(); if (activeCompassImageInfo.initialized && Object.op_Implicit((Object)(object)activeCompassImageInfo.texture)) { pinsRootObject.sizeDelta = new Vector2((float)(((Texture)activeCompassImageInfo.texture).width / 2), (float)((Texture)activeCompassImageInfo.texture).height); } RectTransform obj = pinElement; if (obj != null) { obj.SetSizeWithCurrentAnchors((Axis)0, pinsRootObject.sizeDelta.y); } RectTransform obj2 = pinElement; if (obj2 != null) { obj2.SetSizeWithCurrentAnchors((Axis)1, pinsRootObject.sizeDelta.y); } } } public static void InitializeCompass() { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Expected O, but got Unknown //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Expected O, but got Unknown //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Expected O, but got Unknown //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Expected O, but got Unknown //IL_043a: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) pinsList.Clear(); tempPins.Clear(); ImageFileInfo activeCompassImageInfo = GetActiveCompassImageInfo(); if (!activeCompassImageInfo.initialized) { Compass.LogWarning("Mandatory file " + activeCompassImageInfo.fileName + " is not found"); return; } ImageFileInfo activeCenterImageInfo = GetActiveCenterImageInfo(); if (!activeCenterImageInfo.initialized) { Compass.LogWarning("Mandatory file " + activeCenterImageInfo.fileName + " is not found"); return; } ImageFileInfo activeMaskImageInfo = GetActiveMaskImageInfo(); if (!activeMaskImageInfo.initialized) { Compass.LogWarning("Mandatory file " + activeMaskImageInfo.fileName + " is not found"); return; } parentObject = new GameObject("Compass_Parent", new Type[1] { typeof(RectTransform) }) { layer = layerUI }; parentObject.transform.SetParent(Hud.instance.m_rootObject.transform); GameObject val = new GameObject("Overlay", new Type[1] { typeof(RectTransform) }) { layer = layerUI }; val.transform.SetParent(parentObject.transform, false); ImageFileInfo.SetGameObject("overlay", val).UpdateGameObject(); GameObject val2 = new GameObject("Underlay", new Type[1] { typeof(RectTransform) }) { layer = layerUI }; val2.transform.SetParent(parentObject.transform, false); ImageFileInfo.SetGameObject("underlay", val2).UpdateGameObject(); GameObject val3 = new GameObject("GlobalMask", new Type[1] { typeof(RectTransform) }) { layer = layerUI }; val3.transform.SetParent(parentObject.transform, false); val3.AddComponent(); val3.GetComponent().sizeDelta = new Vector2(1600f, 100f); maskObject = new GameObject("Mask", new Type[1] { typeof(RectTransform) }) { layer = layerUI }; maskObject.transform.SetParent(val3.transform, false); UpdateMaskObject(); maskComponent = maskObject.AddComponent(); maskComponent.showMaskGraphic = false; maskImage = maskObject.GetComponent(); compassObject = new GameObject("Compass", new Type[1] { typeof(RectTransform) }) { layer = layerUI }; compassObject.transform.SetParent(maskObject.transform, false); activeCompassImageInfo.SetGameObject(compassObject).UpdateGameObject(); Action textureChanged = UpdateImageMode; ImageFileInfo.GetImageInfo("compass").textureChanged = textureChanged; ImageFileInfo.GetImageInfo("compass_bottom").textureChanged = textureChanged; ImageFileInfo.GetImageInfo("compass_detailed").textureChanged = textureChanged; ImageFileInfo.GetImageInfo("compass_detailed_bottom").textureChanged = textureChanged; centerObject = new GameObject("Center", new Type[1] { typeof(RectTransform) }) { layer = layerUI }; centerObject.transform.SetParent(val3.transform, false); activeCenterImageInfo.SetGameObject(centerObject).UpdateGameObject(); Action textureChanged2 = delegate { UpdateAnchorImages(); UpdateCenterObject(); }; ImageFileInfo.GetImageInfo("center").textureChanged = textureChanged2; ImageFileInfo.GetImageInfo("center_bottom").textureChanged = textureChanged2; ImageFileInfo.GetImageInfo("center_detailed").textureChanged = textureChanged2; ImageFileInfo.GetImageInfo("center_detailed_bottom").textureChanged = textureChanged2; Action textureChanged3 = UpdateMaskObject; ImageFileInfo.GetImageInfo("mask").textureChanged = textureChanged3; ImageFileInfo.GetImageInfo("mask_detailed").textureChanged = textureChanged3; pinsRootObject = new GameObject("Pins", new Type[1] { typeof(RectTransform) }) { layer = layerUI }.GetComponent(); ((Transform)pinsRootObject).SetParent(maskObject.transform, false); pinElement = new GameObject("PinElement", new Type[1] { typeof(RectTransform) }) { layer = layerUI }.GetComponent(); ((Transform)pinElement).SetParent(parentObject.transform, false); ((Component)pinElement).gameObject.AddComponent(); ((Component)pinElement).gameObject.SetActive(false); GameObject val4 = Object.Instantiate(((Component)Minimap.instance.m_pinPrefab.transform.Find("Checked")).gameObject, (Transform)(object)pinElement); ((Object)val4).name = "Checked"; val4.SetActive(false); GameObject val5 = Object.Instantiate(((Component)Minimap.instance.m_pinNamePrefab.transform.Find("Name")).gameObject, (Transform)(object)pinElement); ((Object)val5).name = "Name"; val5.GetComponent().fontSizeMax = 24f; val5.SetActive(false); val.transform.SetAsLastSibling(); UpdateAnchorImages(); UpdateParentObject(); UpdateCenterObject(); UpdateCompassObject(); UpdatePinsObject(); } public static void UpdateCompass() { //IL_0037: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if (Compass.modEnabled.Value && Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)compassObject)) { float num = AnchorTransform.eulerAngles.y; if (num > 180f) { num -= 360f; } num *= -(float)Math.PI / 180f; if (compassTransform == null) { compassTransform = compassObject.GetComponent(); } ((Transform)compassTransform).localPosition = Vector3.right * (compassWidth / 2f) * num / ((float)Math.PI * 2f) - new Vector3(compassWidth * 0.125f, 0f, 0f); UpdatePins(); } } public static void UpdatePinTextStyle() { CollectionExtensions.Do((IEnumerable)pinsList, (Action)delegate(PinElement pin) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)pin.text == (Object)null)) { pin.text.enableAutoSizing = false; pin.text.fontSize = Compass.pinTextSize.Value; ((Graphic)pin.text).color = Compass.pinTextColor.Value; pin.text.fontStyle = Compass.pinTextFormat.Value; } }); } public static void DestroyCompass() { parentObject = null; compassObject = null; centerObject = null; maskObject = null; pinsRootObject = null; pinElement = null; compassTransform = null; maskComponent = null; maskImage = null; CollectionExtensions.Do((IEnumerable)pinsList, (Action)delegate(PinElement pin) { pin.Destroy(); }); pinsList.Clear(); tempPins.Clear(); } private static void UpdatePinList() { tempPins.Clear(); AddPinRange(Minimap.instance.m_pins); if (ShowAllPingPins()) { AddPinRange(Minimap.instance.m_pingPins); } if (ShowAllShoutPins()) { AddPinRange(Minimap.instance.m_shoutPins); } if (ShowAllPlayerPins()) { AddPinRange(Minimap.instance.m_playerPins); } tempPins.Sort((PinData x, PinData y) => ComparePins(x, y)); static int ComparePins(PinData x, PinData y) { //IL_0002: 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_005f: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (y.m_pos == x.m_pos) { if ((int)x.m_type == 13) { return -1; } if ((int)y.m_type == 13) { return 1; } ref PinType type = ref y.m_type; object target = x.m_type; return ((Enum)Unsafe.As(ref type)/*cast due to .constrained prefix*/).CompareTo(target); } return Utils.DistanceXZ(AnchorTransform.position, y.m_pos).CompareTo(Utils.DistanceXZ(AnchorTransform.position, x.m_pos)); } } public static bool IsShortcutDown(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && ZInput.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey, true) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode key) => ZInput.GetKey(key, true)); } private static bool ShowAllPlayerPins() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) return Compass.alwaysShowPinText.Value || IsShortcutDown(Compass.holdToAlwaysShowPlayerPin.Value); } private static bool ShowAllShoutPins() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) return Compass.alwaysShowPinText.Value || IsShortcutDown(Compass.holdToAlwaysShowShouts.Value); } private static bool ShowAllPingPins() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) return Compass.alwaysShowPinText.Value || IsShortcutDown(Compass.holdToAlwaysShowPings.Value); } private static bool ShowPinText() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) return Compass.alwaysShowPinText.Value || IsShortcutDown(Compass.holdToShowText.Value); } private static void AddPinRange(List pinList) { CollectionExtensions.Do((IEnumerable)pinList, (Action)AddPin); } private static void AddPin(PinData pin) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) if (pin == null || (Compass.hideChecked.Value && pin.m_checked) || (Compass.hideShared.Value && pin.m_ownerID != 0)) { return; } Compass.CompassPinType pinType = GetPinType(pin.m_type); if (!Compass.showPins.Value.HasFlag(pinType) || (Compass.showOnlyLastDeath.Value && pinType == Compass.CompassPinType.Death && pin.m_pos != Game.instance.GetPlayerProfile().GetDeathPoint())) { return; } if (!IsDynamicPinToShow(pinType)) { float num = Utils.DistanceXZ(AnchorTransform.position, pin.m_pos); if (num < effectivePinsStyleConditions.x || num > effectivePinsStyleConditions.w || filteredNames.Contains(pin.m_name) || filteredWildcardPatterns.Any((WildcardPattern pattern) => pattern.IsMatch(pin.m_name))) { return; } } if (!tempPins.Contains(pin)) { tempPins.Add(pin); } } private static Compass.CompassPinType GetPinType(PinType pinType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected I4, but got Unknown if (1 == 0) { } Compass.CompassPinType result = (int)pinType switch { 0 => Compass.CompassPinType.Icon0, 1 => Compass.CompassPinType.Icon1, 2 => Compass.CompassPinType.Icon2, 3 => Compass.CompassPinType.Icon3, 6 => Compass.CompassPinType.Icon4, 4 => Compass.CompassPinType.Death, 5 => Compass.CompassPinType.Bed, 7 => Compass.CompassPinType.Shout, 9 => Compass.CompassPinType.Boss, 10 => Compass.CompassPinType.Player, 11 => Compass.CompassPinType.RandomEvent, 12 => Compass.CompassPinType.Ping, 13 => Compass.CompassPinType.EventArea, 14 => Compass.CompassPinType.HildirQuest, 15 => Compass.CompassPinType.HildirQuest, 16 => Compass.CompassPinType.HildirQuest, 8 => Compass.CompassPinType.Static, _ => Compass.CompassPinType.Custom, }; if (1 == 0) { } return result; } public static void UpdatePins() { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: 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_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0359: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_054b: Unknown result type (might be due to invalid IL or missing references) //IL_056c: Unknown result type (might be due to invalid IL or missing references) //IL_04b6: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_0504: Unknown result type (might be due to invalid IL or missing references) //IL_0513: Unknown result type (might be due to invalid IL or missing references) //IL_051e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)pinsRootObject) || !((Component)pinsRootObject).gameObject.activeInHierarchy || (Object)(object)AnchorTransform == (Object)null) { return; } UpdatePinList(); if (pinsList.Count != tempPins.Count) { CollectionExtensions.Do((IEnumerable)pinsList, (Action)delegate(PinElement pin) { pin.Destroy(); }); pinsList.Clear(); for (int num = 0; num < tempPins.Count; num++) { new PinElement(); } } Sprite sprite = GetActiveCompassImageInfo().sprite; if (!Object.op_Implicit((Object)(object)sprite)) { return; } Rect rect = sprite.rect; bool flag = false; bool flag2 = Compass.anchorPosition.Value == Compass.AnchorPositionType.Bottom; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Compass.pinOffset.Value.x, 0f - Compass.pinOffset.Value.y); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Compass.pinNameOffset.Value.x, 0f - Compass.pinNameOffset.Value.y); Color val3 = ((Compass.pinsColor.Value == Color.clear) ? Color.white : Compass.pinsColor.Value); for (int num2 = 0; num2 < tempPins.Count; num2++) { PinElement pinElement = pinsList[num2]; PinData val4 = tempPins[num2]; pinElement.name = val4.m_name; pinElement.image.sprite = val4.m_icon; bool flag3 = IsDynamicPinToShow(val4.m_type); float num3 = Utils.DistanceXZ(AnchorTransform.position, val4.m_pos); if (num3 > effectivePinsStyleConditions.y && flag3) { num3 = effectivePinsStyleConditions.y; } float num4 = Mathf.Lerp(Compass.pinsScale.Value.x, Compass.pinsScale.Value.y, (num3 - effectivePinsStyleConditions.y) / (effectivePinsStyleConditions.z - effectivePinsStyleConditions.y)); float num5 = Mathf.Lerp(Compass.pinsAlpha.Value.x, Compass.pinsAlpha.Value.y, (num3 - effectivePinsStyleConditions.z) / (effectivePinsStyleConditions.w - effectivePinsStyleConditions.z)); float num6 = (Compass.pinNameScaleDistant.Value ? Mathf.Lerp(1f, 0.8f, Mathf.InverseLerp(effectivePinsStyleConditions.z, effectivePinsStyleConditions.w, num3)) : 1f); ((Transform)pinElement.rect).localScale = Vector3.one * num4; ((Transform)pinElement.rect).localPosition = Vector3.right * (((Rect)(ref rect)).width / 2f) * GetAngle(val4.m_pos) / ((float)Math.PI * 2f) + val; ((Graphic)pinElement.image).color = new Color(val3.r, val3.g, val3.b, val4.m_animate ? Compass.pinsAlpha.Value.x : num5); ((Transform)pinElement.rect).SetSiblingIndex(num2); GameObject checkedIcon = pinElement.checkedIcon; if (checkedIcon != null) { checkedIcon.SetActive(val4.m_checked); } bool flag4 = (Object)(object)pinElement.text != (Object)null && !string.IsNullOrWhiteSpace(val4.m_name) && (flag3 || ShowPinText()); TMP_Text text = pinElement.text; if (text != null) { ((Component)text).gameObject.SetActive(flag4); } if (flag4) { pinElement.text.SetText(GetPinText(val4)); pinElement.text.enableAutoSizing = false; pinElement.text.fontSize = Compass.pinTextSize.Value; ((Graphic)pinElement.text).color = Compass.pinTextColor.Value; pinElement.text.fontStyle = Compass.pinTextFormat.Value; pinElement.text.verticalAlignment = (VerticalAlignmentOptions)(flag2 ? 1024 : 256); RectTransform rectTransform = pinElement.text.rectTransform; rectTransform.anchorMin = new Vector2(0.5f, 0.5f); rectTransform.anchorMax = new Vector2(0.5f, 0.5f); rectTransform.pivot = new Vector2(0.5f, flag2 ? 0f : 1f); ((Transform)rectTransform).localScale = Vector3.one * (num6 / num4); float num7 = pinElement.rect.sizeDelta.y / 2f; float num8 = (flag2 ? 1f : (-1f)); rectTransform.anchoredPosition = new Vector2(val2.x / num4, num8 * num7 + val2.y / num4); flag = true; } if (val4.m_animate && !flag3) { RectTransform rect2 = pinElement.rect; ((Transform)rect2).localScale = ((Transform)rect2).localScale * (0.9f + Mathf.Sin(Time.time * 5f) * 0.2f); } } ((Behaviour)maskComponent).enabled = !flag; ((Behaviour)maskImage).enabled = !flag; } public static bool IsDynamicPinToShow(Compass.CompassPinType pinType) { return (pinType == Compass.CompassPinType.Shout && ShowAllShoutPins()) || (pinType == Compass.CompassPinType.Player && ShowAllPlayerPins()) || (pinType == Compass.CompassPinType.Ping && ShowAllPingPins()); } public static bool IsDynamicPinToShow(PinType pinType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return IsDynamicPinToShow(GetPinType(pinType)); } public static float GetAngle(Vector3 position) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) return GetAtan2(AnchorTransform.InverseTransformPoint(new Vector3(position.x, AnchorTransform.position.y, position.z))); } public static float GetAtan2(Vector3 vector) { //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) return Mathf.Atan2(vector.x, vector.z); } public static string GetPinText(PinData pin) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) return (string.IsNullOrEmpty(pin.m_author.m_userID) || pin.m_author == ((IUser)PlatformManager.DistributionPlatform.LocalUser).PlatformUserID) ? Localization.instance.Localize(pin.m_name) : CensorShittyWords.FilterUGC(Localization.instance.Localize(pin.m_name), (UGCType)4, pin.m_author, 0L); } } public class ImageFileInfo { public static readonly Dictionary images = new Dictionary(StringComparer.OrdinalIgnoreCase); public const string ext = "png"; public static string filter = GetFilename("*"); public string fileID; public string fileName; public string filePath; public Texture2D texture; public bool initialized = false; public GameObject gameObject; public Sprite sprite; public int spriteWidthOverride; public Action textureChanged; public ImageFileInfo(string id) { fileID = id; fileName = GetFilename(id); filePath = Path.Combine(Compass.configDirectory, fileName); Load(); images[fileID] = this; } public bool Load() { if (!TryReadFileData(out var imageData)) { return false; } bool flag = Load(imageData); if (flag) { Compass.LogInfo("Loaded image from config folder: " + fileName); } return flag; } public bool Load(byte[] imageData) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (imageData == null || imageData.Length == 0) { return false; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, true); try { if (!ImageConversion.LoadImage(val, imageData)) { Object.Destroy((Object)(object)val); return false; } } catch (Exception) { Object.Destroy((Object)(object)val); return false; } ((Texture)val).wrapMode = (TextureWrapMode)1; Texture2D val2 = texture; texture = val; initialized = true; InitSprite(); UpdateGameObject(); Update(); textureChanged?.Invoke(); if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2); } return true; } public bool TryReadValidFileData(out byte[] imageData) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown imageData = null; if (!TryReadFileData(out var imageData2)) { return false; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, true); bool flag; try { flag = ImageConversion.LoadImage(val, imageData2); } catch (Exception) { flag = false; } finally { Object.Destroy((Object)(object)val); } if (!flag) { return false; } imageData = imageData2; return true; } private bool TryReadFileData(out byte[] imageData) { imageData = null; if (!File.Exists(filePath)) { return false; } try { imageData = File.ReadAllBytes(filePath); return imageData.Length != 0; } catch (IOException) { return false; } catch (UnauthorizedAccessException) { return false; } catch (Exception) { return false; } } public void Clear() { if (Object.op_Implicit((Object)(object)gameObject)) { Image component = gameObject.GetComponent(); if (Object.op_Implicit((Object)(object)component) && (Object)(object)component.sprite == (Object)(object)sprite) { component.sprite = null; } } if ((Object)(object)texture != (Object)null) { Object.Destroy((Object)(object)texture); texture = null; } if ((Object)(object)sprite != (Object)null) { Object.Destroy((Object)(object)sprite); sprite = null; } initialized = false; Update(); } public void Update() { GameObject obj = gameObject; if (obj != null) { obj.SetActive(initialized); } } public ImageFileInfo SetSpriteWidth(int width) { spriteWidthOverride = width; InitSprite(); return this; } public ImageFileInfo SetGameObject(GameObject gameObject) { this.gameObject = gameObject; return this; } public void UpdateGameObject() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)gameObject) && initialized) { RectTransform component = gameObject.GetComponent(); component.sizeDelta = new Vector2((float)((spriteWidthOverride == 0) ? ((Texture)texture).width : spriteWidthOverride), (float)((Texture)texture).height); Image val = gameObject.GetComponent() ?? gameObject.AddComponent(); val.sprite = sprite; val.preserveAspect = true; } } private void InitSprite() { //IL_005e: 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) if ((Object)(object)sprite != (Object)null) { Object.Destroy((Object)(object)sprite); } sprite = ((!initialized) ? null : Sprite.Create(texture, new Rect(0f, 0f, (float)((spriteWidthOverride == 0) ? ((Texture)texture).width : spriteWidthOverride), (float)((Texture)texture).height), Vector2.zero)); } private static string GetFilename(string filename) { return Path.ChangeExtension(filename, "png"); } public static ImageFileInfo SetGameObject(string id, GameObject gameObject) { return GetImageInfo(id).SetGameObject(gameObject); } public static ImageFileInfo GetImageInfo(string id) { ImageFileInfo value; return images.TryGetValue(id, out value) ? value : new ImageFileInfo(id); } public static void TryClearFile(string filename) { if (images.TryGetValue(Path.GetFileNameWithoutExtension(filename), out var value)) { value.Clear(); value.textureChanged?.Invoke(); } } public static bool TryLoadFile(string filename) { ImageFileInfo value; return images.TryGetValue(Path.GetFileNameWithoutExtension(filename), out value) && value.Load(); } } internal static class ImageSync { private sealed class SyncedImage { internal readonly string imageID; internal readonly ConfigEntry syncEnabled; internal readonly CustomSyncedValue payload; internal bool IsRemoteOverrideActive => !((ConditionalConfigSync)Compass.configSync).IsSourceOfTruth && payload.Value != "local"; internal SyncedImage(string imageID, ConfigEntry syncEnabled) { this.imageID = imageID; this.syncEnabled = syncEnabled; payload = new CustomSyncedValue((ConditionalConfigSync)(object)Compass.configSync, "Image " + imageID, "local", 0, (IEqualityComparer)null); ((CustomSyncedValueBase)payload).ValueChanged += Apply; syncEnabled.SettingChanged += OnSyncSettingChanged; } private void OnSyncSettingChanged(object sender, EventArgs e) { if (((ConditionalConfigSync)Compass.configSync).IsSourceOfTruth) { Publish(forceNotify: false); } } internal void Initialize() { if (syncEnabled.Value) { Publish(forceNotify: true); } else { payload.AssignLocalValueIfChanged("local"); } } internal void StoreLocalFallback() { payload.AssignLocalValueIfChanged("local"); } internal void Publish(bool forceNotify) { if (!((ConditionalConfigSync)Compass.configSync).IsSourceOfTruth) { return; } string text = BuildPayload(); if (text != null) { if (forceNotify) { payload.AssignLocalValueAndNotify(text); } else { payload.AssignLocalValueIfChanged(text); } } } private string BuildPayload() { if (!syncEnabled.Value) { return "local"; } ImageFileInfo imageInfo = ImageFileInfo.GetImageInfo(imageID); if (!File.Exists(imageInfo.filePath)) { return "missing"; } if (!imageInfo.TryReadValidFileData(out var imageData)) { Compass.LogWarning("Failed to synchronize invalid image " + imageInfo.fileName + ". The previous synchronized image remains active."); return null; } return "png:" + Convert.ToBase64String(imageData); } private void Apply() { ImageFileInfo imageInfo = ImageFileInfo.GetImageInfo(imageID); string value = payload.Value; if (string.IsNullOrEmpty(value)) { Compass.LogWarning("Received empty synchronized image payload for " + imageInfo.fileName + "."); return; } if (value == "local") { ApplyLocalFile(imageInfo); return; } if (value == "missing") { ClearAndNotify(imageInfo); return; } if (!value.StartsWith("png:", StringComparison.Ordinal)) { Compass.LogWarning("Received unsupported synchronized image payload for " + imageInfo.fileName + "."); return; } try { byte[] imageData = Convert.FromBase64String(value.Substring("png:".Length)); if (!imageInfo.Load(imageData)) { Compass.LogWarning("Failed to apply synchronized image " + imageInfo.fileName + ". The previous valid image remains active."); } } catch (FormatException) { Compass.LogWarning("Received malformed synchronized image data for " + imageInfo.fileName + "."); } } } private const string localPayload = "local"; private const string missingPayload = "missing"; private const string dataPrefix = "png:"; private const string configSection = "Server image sync"; internal static readonly string[] imageIDs = new string[12] { "compass", "compass_bottom", "compass_detailed", "compass_detailed_bottom", "center", "center_bottom", "center_detailed", "center_detailed_bottom", "mask", "mask_detailed", "overlay", "underlay" }; private static readonly Dictionary syncedImages = new Dictionary(StringComparer.OrdinalIgnoreCase); internal static void Register(Func> serverConfig) { string[] array = imageIDs; foreach (string text in array) { string text2 = Path.ChangeExtension(text, "png"); ConfigEntry syncEnabled = serverConfig("Server image sync", "Sync " + text2, arg3: false, "Synchronize " + text2 + " from the server. When disabled, every client uses its local file."); syncedImages[text] = new SyncedImage(text, syncEnabled); } ((ConditionalConfigSync)Compass.configSync).SourceOfTruthChanged += OnSourceOfTruthChanged; ((ConditionalConfigSync)Compass.configSync).ServerConnectionReset += OnServerConnectionReset; } internal static void Initialize() { foreach (SyncedImage value in syncedImages.Values) { value.Initialize(); } } internal static bool IsRemoteOverrideActive(string imageID) { SyncedImage value; return syncedImages.TryGetValue(imageID, out value) && value.IsRemoteOverrideActive; } internal static void Publish(string imageID) { if (syncedImages.TryGetValue(imageID, out var value)) { value.Publish(forceNotify: false); } } private static void OnSourceOfTruthChanged(bool isSourceOfTruth) { if (isSourceOfTruth) { return; } foreach (SyncedImage value in syncedImages.Values) { value.StoreLocalFallback(); } } private static void OnServerConnectionReset() { foreach (SyncedImage value in syncedImages.Values) { value.Publish(forceNotify: true); } } private static void ApplyLocalFile(ImageFileInfo imageInfo) { if (!imageInfo.Load() && !File.Exists(imageInfo.filePath)) { ClearAndNotify(imageInfo); } } private static void ClearAndNotify(ImageFileInfo imageInfo) { imageInfo.Clear(); imageInfo.textureChanged?.Invoke(); } } }