Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Compass v1.1.0
Compass.dll
Decompiled 3 weeks agousing 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<string, Coroutine> pendingImageReloads = new Dictionary<string, Coroutine>(StringComparer.OrdinalIgnoreCase); private const float imageReloadDelay = 0.1f; private const int imageReloadAttempts = 5; public static ConfigEntry<bool> configLocked; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> loggingEnabled; public static ConfigEntry<OrientationType> orientation; public static ConfigEntry<AnchorPositionType> anchorPosition; public static ConfigEntry<float> scale; public static ConfigEntry<Vector2> offset; public static ConfigEntry<bool> showCenter; public static ConfigEntry<bool> detailedMode; public static ConfigEntry<CompassPinType> showPins; public static ConfigEntry<string> pinNamesToIgnore; public static ConfigEntry<bool> showOnlyLastDeath; public static ConfigEntry<bool> hideChecked; public static ConfigEntry<bool> hideShared; public static ConfigEntry<bool> alwaysShowPinText; public static ConfigEntry<KeyboardShortcut> holdToAlwaysShowPings; public static ConfigEntry<KeyboardShortcut> holdToAlwaysShowShouts; public static ConfigEntry<KeyboardShortcut> holdToAlwaysShowPlayerPin; public static ConfigEntry<KeyboardShortcut> holdToShowText; public static ConfigEntry<Vector2> pinsAlpha; public static ConfigEntry<Vector2> pinsScale; public static ConfigEntry<Vector4> pinsStyleConditions; public static ConfigEntry<Color> compassColor; public static ConfigEntry<Color> centerColor; public static ConfigEntry<Color> pinsColor; public static ConfigEntry<float> pinTextSize; public static ConfigEntry<Color> pinTextColor; public static ConfigEntry<FontStyles> pinTextFormat; public static ConfigEntry<Vector2> pinNameOffset; public static ConfigEntry<Vector2> pinOffset; public static ConfigEntry<bool> pinNameScaleDistant; public static readonly string configDirectory = Path.Combine(Paths.ConfigPath, "shudnal.Compass"); private void Awake() { instance = this; ConfigInit(); ((ConditionalConfigSync)configSync).AddLockingConfigEntry<bool>(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<Vector2>("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<KeyboardShortcut>("Pins", "Hold to show shouts at any distance", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Hold to show player shouts without distance filter.", synchronizedSetting: true); holdToAlwaysShowPlayerPin = config<KeyboardShortcut>("Pins", "Hold to show players at any distance", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Hold to show players with public positions without distance filter.", synchronizedSetting: true); holdToAlwaysShowPings = config<KeyboardShortcut>("Pins", "Hold to show pings at any distance", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Hold to show player pings without distance filter.", synchronizedSetting: true); holdToShowText = config<KeyboardShortcut>("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<Color>("Style", "Compass color", Color.white - new Color(0f, 0f, 0f, 0.5f), "Compass color"); centerColor = config<Color>("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<Color>("Pin style", "Color", Color.clear, "Pins color. If not set - default is white"); pinsAlpha = config<Vector2>("Pin style", "Alpha", new Vector2(1f, 0.33f), "Pins alpha. X for max alpha, Y for min alpha"); pinsScale = config<Vector2>("Pin style", "Scale", new Vector2(1f, 0.33f), "Pins scale. X for max scale, Y for min scale"); pinOffset = config<Vector2>("Pin style", "Pin offset", Vector2.zero, "Additional pin offset relative to the compass. Y is flipped automatically for top/bottom anchor modes."); pinsStyleConditions = config<Vector4>("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<Color>("Pin text style", "Color", Color.white, "Pin text color"); pinTextFormat = config<FontStyles>("Pin text style", "Format", (FontStyles)1, "Pin text format"); pinNameOffset = config<Vector2>("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<T> config<T>(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = false) { return ((ConditionalConfigSync)configSync).AddConfigEntry<T>(((BaseUnityPlugin)this).Config, group, name, defaultValue, description, (ConfigSyncMode)1, synchronizedSetting).SourceConfig; } private ConfigEntry<T> serverConfig<T>(string group, string name, T defaultValue, ConfigDescription description) { return ((ConditionalConfigSync)configSync).AddConfigEntry<T>(((BaseUnityPlugin)this).Config, group, name, defaultValue, description, (ConfigSyncMode)0, true).SourceConfig; } private ConfigEntry<T> config<T>(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<object>()), synchronizedSetting); } private ConfigEntry<T> serverConfig<T>(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<object>())); } 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<string>(StringComparer.OrdinalIgnoreCase); CompassHUD.filteredWildcardPatterns.Clear(); IEnumerable<string> 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<ConfigEntryBase>? 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<ConfigEntryBase> 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<GUILayoutOption>()); List<string> list = new List<string>(); List<string> list2 = ((string)cfg.BoxedValue).Split(new string[1] { splitString }, StringSplitOptions.None).ToList(); for (int num = 0; num < list2.Count; num++) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); 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<GUILayoutOption>()) && !valueOrDefault) { flag = true; } else { list.Add(text2); } if (GUILayout.Button("+", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty<GUILayoutOption>()) && !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<RectTransform>(pinElement, (Transform)(object)pinsRootObject); ((Component)rect).gameObject.SetActive(true); image = ((Component)rect).GetComponent<Image>(); 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<TMP_Text>() : 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<PinData> tempPins = new List<PinData>(); public static readonly List<PinElement> pinsList = new List<PinElement>(); public static HashSet<string> filteredNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase); public static readonly List<WildcardPattern> filteredWildcardPatterns = new List<WildcardPattern>(); 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<RectTransform>(); ((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<Image>()).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<Image>(); 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<RectMask2D>(); val3.GetComponent<RectTransform>().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<Mask>(); maskComponent.showMaskGraphic = false; maskImage = maskObject.GetComponent<Image>(); 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<RectTransform>(); ((Transform)pinsRootObject).SetParent(maskObject.transform, false); pinElement = new GameObject("PinElement", new Type[1] { typeof(RectTransform) }) { layer = layerUI }.GetComponent<RectTransform>(); ((Transform)pinElement).SetParent(parentObject.transform, false); ((Component)pinElement).gameObject.AddComponent<Image>(); ((Component)pinElement).gameObject.SetActive(false); GameObject val4 = Object.Instantiate<GameObject>(((Component)Minimap.instance.m_pinPrefab.transform.Find("Checked")).gameObject, (Transform)(object)pinElement); ((Object)val4).name = "Checked"; val4.SetActive(false); GameObject val5 = Object.Instantiate<GameObject>(((Component)Minimap.instance.m_pinNamePrefab.transform.Find("Name")).gameObject, (Transform)(object)pinElement); ((Object)val5).name = "Name"; val5.GetComponent<TMP_Text>().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<RectTransform>(); } ((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<PinElement>((IEnumerable<PinElement>)pinsList, (Action<PinElement>)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<PinElement>((IEnumerable<PinElement>)pinsList, (Action<PinElement>)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<PinType, PinType>(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<PinData> pinList) { CollectionExtensions.Do<PinData>((IEnumerable<PinData>)pinList, (Action<PinData>)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<PinElement>((IEnumerable<PinElement>)pinsList, (Action<PinElement>)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<string, ImageFileInfo> images = new Dictionary<string, ImageFileInfo>(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<Image>(); 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<RectTransform>(); component.sizeDelta = new Vector2((float)((spriteWidthOverride == 0) ? ((Texture)texture).width : spriteWidthOverride), (float)((Texture)texture).height); Image val = gameObject.GetComponent<Image>() ?? gameObject.AddComponent<Image>(); 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<bool> syncEnabled; internal readonly CustomSyncedValue<string> payload; internal bool IsRemoteOverrideActive => !((ConditionalConfigSync)Compass.configSync).IsSourceOfTruth && payload.Value != "local"; internal SyncedImage(string imageID, ConfigEntry<bool> syncEnabled) { this.imageID = imageID; this.syncEnabled = syncEnabled; payload = new CustomSyncedValue<string>((ConditionalConfigSync)(object)Compass.configSync, "Image " + imageID, "local", 0, (IEqualityComparer<string>)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<string, SyncedImage> syncedImages = new Dictionary<string, SyncedImage>(StringComparer.OrdinalIgnoreCase); internal static void Register(Func<string, string, bool, string, ConfigEntry<bool>> serverConfig) { string[] array = imageIDs; foreach (string text in array) { string text2 = Path.ChangeExtension(text, "png"); ConfigEntry<bool> 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(); } } }