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<string, string> PathsByName = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<string, Sprite> SpriteCache = new Dictionary<string, Sprite>(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<string> list = new List<string>(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<Image, Claim> Claims = new Dictionary<Image, Claim>();
private static readonly List<Image> ImageBuffer = new List<Image>();
private static readonly List<Transform> Roots = new List<Transform>();
private static readonly List<Image> Stale = new List<Image>();
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<Image>(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<Mask>() != (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<Image, Claim> 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<Image, Claim> 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<Graphic>());
}
}
[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<string> _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<string>("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<string>(names) : null), Array.Empty<object>()));
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();
}
}
}
}