using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Pigeon.Movement; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("coruscnium")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Replaces every image in the player HUD with a pride flag")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0.0")] [assembly: AssemblyProduct("PrideHUD")] [assembly: AssemblyTitle("PrideHUD")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PrideHUD { internal static class FlagLibrary { private const string PreferredDefault = "Rainbow"; private static readonly string[] SupportedExtensions = new string[3] { ".png", ".jpg", ".jpeg" }; private static readonly Dictionary PathsByName = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary SpriteCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private static string[] _names = new string[0]; public static string[] Names => _names; private static string FlagFolder { get { string location = Assembly.GetExecutingAssembly().Location; if (!string.IsNullOrEmpty(location)) { return Path.Combine(Path.GetDirectoryName(location), "flags"); } return null; } } public static void Scan() { PathsByName.Clear(); string flagFolder = FlagFolder; string[] array; try { array = (Directory.Exists(flagFolder) ? Directory.GetFiles(flagFolder) : new string[0]); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("Could not read '" + flagFolder + "': " + ex.Message)); array = new string[0]; } string[] array2 = array; foreach (string text in array2) { string fileName = Path.GetFileName(text); if (Array.IndexOf(SupportedExtensions, Path.GetExtension(fileName).ToLowerInvariant()) < 0) { continue; } string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); if (fileNameWithoutExtension.Length != 0) { if (fileNameWithoutExtension.IndexOf(',') >= 0) { Plugin.Logger.LogWarning((object)("Skipping '" + fileName + "': commas break ModSettingsMenu's dropdown.")); } else { PathsByName[fileNameWithoutExtension] = text; } } } List list = new List(PathsByName.Keys); list.Sort(StringComparer.OrdinalIgnoreCase); int num = list.FindIndex((string n) => string.Equals(n, "Rainbow", StringComparison.OrdinalIgnoreCase)); if (num > 0) { string item = list[num]; list.RemoveAt(num); list.Insert(0, item); } _names = list.ToArray(); if (_names.Length == 0) { Plugin.Logger.LogWarning((object)("No flag images found in '" + flagFolder + "' — the HUD is left alone.")); } } public static Sprite Get(string name) { if (string.IsNullOrEmpty(name)) { return null; } if (SpriteCache.TryGetValue(name, out var value)) { if ((Object)(object)value != (Object)null) { return value; } SpriteCache.Remove(name); } if (!PathsByName.TryGetValue(name, out var value2)) { return null; } Sprite val = Load(value2); SpriteCache[name] = val; return val; } private static Sprite Load(string path) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) try { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(path))) { Plugin.Logger.LogWarning((object)("Could not decode '" + Path.GetFileName(path) + "' as an image.")); Object.Destroy((Object)(object)val); return null; } ((Texture)val).wrapMode = (TextureWrapMode)0; ((Texture)val).filterMode = (FilterMode)1; ((Object)val).hideFlags = (HideFlags)61; Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0); ((Object)obj).hideFlags = (HideFlags)61; ((Object)obj).name = "PrideHUD:" + Path.GetFileNameWithoutExtension(path); return obj; } catch (Exception ex) { Plugin.Logger.LogWarning((object)("Could not load '" + path + "': " + ex.Message)); return null; } } } internal static class HudPainter { private sealed class Claim { public Sprite OriginalSprite; public Sprite OriginalOverride; public Color OriginalColor; public Sprite Applied; } private static readonly Dictionary Claims = new Dictionary(); private static readonly List ImageBuffer = new List(); private static readonly List Roots = new List(); private static readonly List Stale = new List(); private static bool _loggedSweepError; private static bool _loggedTintError; public static string Selection = "Rainbow"; public static int ClaimCount => Claims.Count; public static void Sweep() { try { CollectRoots(); if (Roots.Count == 0) { if (Claims.Count > 0) { DropDestroyedClaims(); } return; } Sprite val = FlagLibrary.Get(Selection); if ((Object)(object)val == (Object)null) { return; } foreach (Transform root in Roots) { ((Component)root).GetComponentsInChildren(true, ImageBuffer); foreach (Image item in ImageBuffer) { Apply(item, val); } } DropDestroyedClaims(); } catch (Exception arg) { if (!_loggedSweepError) { _loggedSweepError = true; Plugin.Logger.LogError((object)$"HUD sweep failed, skipping this pass: {arg}"); } } } private static void CollectRoots() { Roots.Clear(); PlayerLook instance = PlayerLook.Instance; if ((Object)(object)instance != (Object)null) { Add((Transform)(object)instance.DefaultHUDParent); Add((Transform)(object)instance.StaticReticle); Add((Transform)(object)instance.GearHUDParent); Add((Transform)(object)instance.Reticle); } if ((Object)(object)MissionHUD.Instance != (Object)null) { Add(((Component)MissionHUD.Instance).transform); } static void Add(Transform t) { if ((Object)(object)t != (Object)null) { Roots.Add(t); } } } private static void Apply(Image image, Sprite flag) { //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)image == (Object)null) { return; } Claim value; bool flag2 = Claims.TryGetValue(image, out value); if ((flag2 || !((Object)(object)image.sprite == (Object)null)) && (flag2 || !((Object)(object)((Component)image).GetComponent() != (Object)null))) { if (!flag2) { value = new Claim { OriginalSprite = image.sprite, OriginalOverride = image.overrideSprite, OriginalColor = ((Graphic)image).color }; Claims[image] = value; } else if (image.sprite != value.Applied) { value.OriginalSprite = image.sprite; } if (image.sprite != flag) { image.sprite = flag; value.Applied = flag; } if ((Object)(object)image.overrideSprite != (Object)null) { value.OriginalOverride = image.overrideSprite; image.overrideSprite = null; } NeutraliseTint(image, value); } } private static void NeutraliseTint(Image image, Claim claim) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Color color = ((Graphic)image).color; if (color.r != 1f || color.g != 1f || color.b != 1f) { claim.OriginalColor = new Color(color.r, color.g, color.b, claim.OriginalColor.a); ((Graphic)image).color = new Color(1f, 1f, 1f, color.a); } } public static void OnGraphicRetinted(Graphic graphic) { try { Image val = (Image)(object)((graphic is Image) ? graphic : null); if (val != null && Claims.TryGetValue(val, out var value)) { NeutraliseTint(val, value); } } catch (Exception arg) { if (!_loggedTintError) { _loggedTintError = true; Plugin.Logger.LogError((object)$"Failed to keep a HUD image untinted: {arg}"); } } } private static void DropDestroyedClaims() { Stale.Clear(); foreach (KeyValuePair claim in Claims) { if ((Object)(object)claim.Key == (Object)null) { Stale.Add(claim.Key); } } foreach (Image item in Stale) { Claims.Remove(item); } Stale.Clear(); } public static void Restore() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair claim in Claims) { Image key = claim.Key; Claim value = claim.Value; if (!((Object)(object)key == (Object)null)) { try { key.sprite = value.OriginalSprite; key.overrideSprite = value.OriginalOverride; ((Graphic)key).color = new Color(value.OriginalColor.r, value.OriginalColor.g, value.OriginalColor.b, ((Graphic)key).color.a); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("Could not restore a HUD image: " + ex.Message)); } } } Claims.Clear(); } } [HarmonyPatch(typeof(CharacterGraphic), "UpdateGraphicColor")] internal static class CharacterGraphicPatch { [HarmonyPostfix] private static void Postfix(CharacterGraphic __instance) { HudPainter.OnGraphicRetinted(((Component)__instance).GetComponent()); } } [MycoMod(/*Could not decode attribute arguments.*/)] [BepInPlugin("coruscnium.pridehud", "PrideHUD", "1.0.0.0")] [BepInProcess("Mycopunk.exe")] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "coruscnium.pridehud"; public const string PluginName = "PrideHUD"; public const string PluginVersion = "1.0.0.0"; internal static ManualLogSource Logger; private const float SweepInterval = 0.25f; private static ConfigEntry _flagConfig; private static FileSystemWatcher _configWatcher; private static volatile bool _pendingConfigReload; private Harmony _harmony; private float _sinceSweep; private void Awake() { //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; FlagLibrary.Scan(); string[] names = FlagLibrary.Names; _flagConfig = ((BaseUnityPlugin)this).Config.Bind("General", "Flag", (names.Length != 0) ? names[0] : "Rainbow", new ConfigDescription("Which pride flag replaces every image in the HUD.\nDrop more images into the mod's 'flags' folder to add options here.", (AcceptableValueBase)(object)((names.Length != 0) ? new AcceptableValueList(names) : null), Array.Empty())); HudPainter.Selection = _flagConfig.Value; _flagConfig.SettingChanged += delegate { HudPainter.Selection = _flagConfig.Value; }; ((BaseUnityPlugin)this).Config.Save(); try { _configWatcher = new FileSystemWatcher(Paths.ConfigPath, "coruscnium.pridehud.cfg") { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite), EnableRaisingEvents = true }; _configWatcher.Changed += OnConfigFileChanged; _configWatcher.Created += OnConfigFileChanged; _configWatcher.Renamed += OnConfigFileChanged; } catch (Exception ex) { Logger.LogWarning((object)("Could not start config file watcher: " + ex.Message)); } _harmony = new Harmony("coruscnium.pridehud"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); Logger.LogInfo((object)string.Format("{0} loaded. {1} flag(s) available, showing {2}.", "PrideHUD", names.Length, _flagConfig.Value)); } private void OnConfigFileChanged(object sender, FileSystemEventArgs e) { _pendingConfigReload = true; } private void Update() { if (_pendingConfigReload) { _pendingConfigReload = false; ((BaseUnityPlugin)this).Config.Reload(); } _sinceSweep += Time.unscaledDeltaTime; if (!(_sinceSweep < 0.25f)) { _sinceSweep = 0f; HudPainter.Sweep(); } } private void OnDestroy() { HudPainter.Restore(); if (_configWatcher != null) { _configWatcher.EnableRaisingEvents = false; _configWatcher.Changed -= OnConfigFileChanged; _configWatcher.Created -= OnConfigFileChanged; _configWatcher.Renamed -= OnConfigFileChanged; _configWatcher.Dispose(); _configWatcher = null; } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } }