using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon;
using Pigeon.Math;
using Pigeon.Movement;
using Sparroh.UI;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Sparroh")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("RedactedNotification")]
[assembly: AssemblyTitle("RedactedNotification")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[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;
}
}
}
public static class ConfigManager
{
private const float DebounceSeconds = 0.25f;
private static ConfigFile config;
private static ManualLogSource logger;
private static FileSystemWatcher configWatcher;
private static volatile bool pendingRefresh;
private static volatile bool reloadPending;
private static float lastReloadTime;
public static ConfigEntry<bool> EnableHud { get; private set; }
public static ConfigEntry<bool> ShowWhenNotDetected { get; private set; }
public static ConfigEntry<string> AlertText { get; private set; }
public static ConfigEntry<string> IdleText { get; private set; }
public static ConfigEntry<bool> EnableBlink { get; private set; }
public static ConfigEntry<float> BlinkSpeed { get; private set; }
public static ConfigEntry<float> BlinkMinAlpha { get; private set; }
public static HudAnchors Anchors { get; private set; }
public static void Initialize(ConfigFile configFile, ManualLogSource log)
{
config = configFile;
logger = log;
EnableHud = config.Bind<bool>("General", "Enable Notification", true, "Show the ERROR REDACTED board notification on the player HUD.");
ShowWhenNotDetected = config.Bind<bool>("General", "Show When Not Detected", false, "When enabled, always show a grey idle indicator (\"no ERROR detected.\") when ERROR REDACTED is not on the board. When disabled, the HUD is hidden until the modifier appears.");
AlertText = config.Bind<string>("General", "Alert Text", "ERROR REDACTED has appeared!", "Text shown when ERROR REDACTED is on the current mission board.");
IdleText = config.Bind<string>("General", "Idle Text", "no ERROR detected.", "Text shown in idle mode when ERROR REDACTED is not on the board.");
EnableBlink = config.Bind<bool>("General", "Enable Blink", true, "Pulse the alert HUD when ERROR REDACTED is on the board so it is easier to notice.");
BlinkSpeed = config.Bind<float>("General", "Blink Speed", 2f, "Blink rate in full cycles per second (soft alpha pulse). Reasonable range: 1–3.");
BlinkMinAlpha = config.Bind<float>("General", "Blink Min Alpha", 0.35f, "Minimum alpha during the dim phase of the blink (0–1). Higher = subtler blink.");
Anchors = HudAnchors.Bind(config, "Notification", 0.5f, 0.12f, "HUD Positioning");
EnableHud.SettingChanged += OnSettingChanged;
ShowWhenNotDetected.SettingChanged += OnSettingChanged;
AlertText.SettingChanged += OnSettingChanged;
IdleText.SettingChanged += OnSettingChanged;
EnableBlink.SettingChanged += OnSettingChanged;
BlinkSpeed.SettingChanged += OnSettingChanged;
BlinkMinAlpha.SettingChanged += OnSettingChanged;
try
{
SetupFileWatcher();
}
catch (Exception ex)
{
logger.LogError((object)("Error setting up config file watcher: " + ex.Message));
}
}
public static void Tick()
{
if (!reloadPending || Time.unscaledTime - lastReloadTime < 0.25f)
{
return;
}
reloadPending = false;
lastReloadTime = Time.unscaledTime;
try
{
config.Reload();
pendingRefresh = true;
logger.LogInfo((object)"Config reloaded from disk.");
}
catch (Exception ex)
{
logger.LogError((object)("Error reloading config: " + ex.Message));
}
}
public static bool ConsumePendingRefresh()
{
if (!pendingRefresh)
{
return false;
}
pendingRefresh = false;
return true;
}
public static void Dispose()
{
if (EnableHud != null)
{
EnableHud.SettingChanged -= OnSettingChanged;
}
if (ShowWhenNotDetected != null)
{
ShowWhenNotDetected.SettingChanged -= OnSettingChanged;
}
if (AlertText != null)
{
AlertText.SettingChanged -= OnSettingChanged;
}
if (IdleText != null)
{
IdleText.SettingChanged -= OnSettingChanged;
}
if (EnableBlink != null)
{
EnableBlink.SettingChanged -= OnSettingChanged;
}
if (BlinkSpeed != null)
{
BlinkSpeed.SettingChanged -= OnSettingChanged;
}
if (BlinkMinAlpha != null)
{
BlinkMinAlpha.SettingChanged -= OnSettingChanged;
}
if (configWatcher != null)
{
configWatcher.EnableRaisingEvents = false;
configWatcher.Changed -= OnConfigFileChanged;
configWatcher.Created -= OnConfigFileChanged;
configWatcher.Renamed -= OnConfigFileChanged;
configWatcher.Dispose();
configWatcher = null;
}
}
private static void SetupFileWatcher()
{
configWatcher = new FileSystemWatcher(Paths.ConfigPath, "sparroh.redactednotification.cfg");
configWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
configWatcher.Changed += OnConfigFileChanged;
configWatcher.Created += OnConfigFileChanged;
configWatcher.Renamed += OnConfigFileChanged;
configWatcher.EnableRaisingEvents = true;
}
private static void OnConfigFileChanged(object sender, FileSystemEventArgs e)
{
reloadPending = true;
}
private static void OnSettingChanged(object sender, EventArgs e)
{
pendingRefresh = true;
}
}
[BepInPlugin("sparroh.redactednotification", "RedactedNotification", "1.0.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class RedactedNotificationPlugin : BaseUnityPlugin
{
public const string PluginGUID = "sparroh.redactednotification";
public const string PluginName = "RedactedNotification";
public const string PluginVersion = "1.0.2";
internal static ManualLogSource Logger;
private Harmony _harmony;
private RedactedHUD _hud;
internal static RedactedBoardScanner Scanner { get; private set; }
private void Awake()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
ConfigManager.Initialize(((BaseUnityPlugin)this).Config, Logger);
try
{
_harmony = new Harmony("sparroh.redactednotification");
}
catch (Exception ex)
{
Logger.LogError((object)("Failed to create Harmony instance: " + ex.Message));
return;
}
try
{
Scanner = new RedactedBoardScanner();
_hud = new RedactedHUD(Scanner);
}
catch (Exception ex2)
{
Logger.LogError((object)("Failed to initialize RedactedNotification: " + ex2.Message));
}
try
{
_harmony.PatchAll();
}
catch (Exception ex3)
{
Logger.LogError((object)("Failed to apply Harmony patches: " + ex3.Message));
}
Logger.LogInfo((object)"RedactedNotification v1.0.2 loaded.");
}
private void Update()
{
ConfigManager.Tick();
if (ConfigManager.ConsumePendingRefresh())
{
try
{
_hud?.OnConfigChanged();
}
catch (Exception ex)
{
Logger.LogError((object)("Error in RedactedHUD.OnConfigChanged(): " + ex.Message));
}
}
try
{
Scanner?.Update();
}
catch (Exception ex2)
{
Logger.LogError((object)("Error in RedactedBoardScanner.Update(): " + ex2.Message));
}
try
{
_hud?.UpdateHudVisibility();
}
catch (Exception ex3)
{
Logger.LogError((object)("Error in RedactedHUD.UpdateHudVisibility(): " + ex3.Message));
}
try
{
_hud?.Update();
}
catch (Exception ex4)
{
Logger.LogError((object)("Error in RedactedHUD.Update(): " + ex4.Message));
}
}
private void OnDestroy()
{
try
{
_hud?.OnDestroy();
}
catch (Exception ex)
{
Logger.LogError((object)("Error in RedactedHUD.OnDestroy(): " + ex.Message));
}
ConfigManager.Dispose();
try
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
catch (Exception ex2)
{
Logger.LogError((object)("Error unpatching Harmony: " + ex2.Message));
}
}
}
public sealed class RedactedBoardScanner
{
private bool _resolveAttempted;
public bool HasRedactedOnBoard { get; private set; }
public int MatchCount { get; private set; }
public MissionModifier RedactedModifier { get; private set; }
public int RedactedIndex { get; private set; } = -1;
public int LastScannedSeed { get; private set; } = int.MinValue;
public bool IsResolved
{
get
{
if (RedactedIndex >= 0)
{
return (Object)(object)RedactedModifier != (Object)null;
}
return false;
}
}
public void Update()
{
try
{
if (!((Object)(object)Global.Instance == (Object)null) && (IsResolved || TryResolveRedacted()))
{
int missionSelectSeed = Global.MissionSelectSeed;
if (missionSelectSeed != LastScannedSeed)
{
LastScannedSeed = missionSelectSeed;
RescanBoard(missionSelectSeed);
}
}
}
catch (Exception ex)
{
RedactedNotificationPlugin.Logger.LogError((object)("RedactedBoardScanner.Update failed: " + ex.Message));
}
}
public void ForceRescan()
{
if (!((Object)(object)Global.Instance == (Object)null) && (IsResolved || TryResolveRedacted()))
{
LastScannedSeed = Global.MissionSelectSeed;
RescanBoard(LastScannedSeed);
}
}
public void ObserveMission(ref MissionData mission)
{
if ((IsResolved || TryResolveRedacted()) && MissionHasRedacted(ref mission) && !HasRedactedOnBoard)
{
HasRedactedOnBoard = true;
RedactedNotificationPlugin.Logger.LogInfo((object)"ERROR REDACTED observed on mission select board.");
}
}
public bool TryResolveRedacted()
{
if (IsResolved)
{
return true;
}
if ((Object)(object)Global.Instance == (Object)null || Global.Instance.MissionModifiers == null)
{
return false;
}
if (_resolveAttempted)
{
_ = RedactedIndex;
_ = 0;
}
_resolveAttempted = true;
WeightedArray<MissionModifier> missionModifiers = Global.Instance.MissionModifiers;
int length = missionModifiers.Length;
for (int i = 0; i < length; i++)
{
MissionModifier val = missionModifiers[i];
if (!((Object)(object)val == (Object)null) && IsErrorRedacted(val))
{
RedactedIndex = i;
RedactedModifier = val;
RedactedNotificationPlugin.Logger.LogInfo((object)$"Resolved ERROR REDACTED modifier at index {i} (APIName='{val.APIName}', Name='{SafeName(val)}').");
return true;
}
}
for (int j = 0; j < length; j++)
{
MissionModifier val2 = missionModifiers[j];
if (!((Object)(object)val2 == (Object)null))
{
string text = val2.APIName ?? string.Empty;
string text2 = SafeName(val2);
string text3 = (text + " " + text2).ToLowerInvariant();
if (text3.Contains("redact") || text3.Contains("error redacted") || text3.Contains("error_redacted"))
{
RedactedIndex = j;
RedactedModifier = val2;
RedactedNotificationPlugin.Logger.LogInfo((object)$"Resolved ERROR REDACTED modifier (fallback) at index {j} (APIName='{text}').");
return true;
}
}
}
return false;
}
private static string SafeName(MissionModifier mod)
{
try
{
return ((mod != null) ? mod.Name : null) ?? string.Empty;
}
catch
{
return string.Empty;
}
}
private static bool IsErrorRedacted(MissionModifier mod)
{
if ((Object)(object)mod == (Object)null)
{
return false;
}
string text = (mod.APIName ?? string.Empty).ToLowerInvariant();
if ((text.Contains("error_redacted") || text.Contains("error-redacted") || text == "redacted" || text.Contains("redacted")) && text.Contains("redact"))
{
return true;
}
try
{
string text2 = (mod.Name ?? string.Empty).ToLowerInvariant();
if (text2.Contains("error") && text2.Contains("redact"))
{
return true;
}
if (text2 == "error redacted" || text2.Contains("error redacted"))
{
return true;
}
}
catch
{
}
return false;
}
private void RescanBoard(int currentSeed)
{
HasRedactedOnBoard = false;
MatchCount = 0;
if ((Object)(object)Global.Instance == (Object)null || Global.Instance.Regions == null)
{
return;
}
try
{
Mission mission = Global.GetMission("intro");
if ((Object)(object)mission != (Object)null && PlayerData.Instance != null && !PlayerData.Instance.HasCompletedMission(mission))
{
RedactedNotificationPlugin.Logger.LogDebug((object)"Board scan skipped: intro mission not completed.");
return;
}
}
catch
{
}
WorldRegion[] regions = Global.Instance.Regions;
foreach (WorldRegion val in regions)
{
if (!((Object)(object)val == (Object)null) && !val.LockRegion)
{
ScanRegion(val, currentSeed);
}
}
if (HasRedactedOnBoard)
{
RedactedNotificationPlugin.Logger.LogInfo((object)$"ERROR REDACTED present on mission board (seed={currentSeed}, matches={MatchCount}).");
}
else
{
RedactedNotificationPlugin.Logger.LogDebug((object)$"Board scan complete (seed={currentSeed}): no ERROR REDACTED.");
}
}
private void ScanRegion(WorldRegion region, int currentSeed)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: 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)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
//IL_01f2: 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_021b: Unknown result type (might be due to invalid IL or missing references)
//IL_0222: 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_02b1: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_023d: Unknown result type (might be due to invalid IL or missing references)
//IL_0247: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
int[] array = new int[Global.Instance.Missions.Length];
int num = FillValidMissions(region.Flags, array);
Random val = default(Random);
((Random)(ref val))..ctor(MathUtil.Squirrel3Hash((region.ID + 3173412) * 71239192, currentSeed));
bool[] array2 = new bool[Global.Instance.Missions.Length];
Random val2 = default(Random);
MissionData data = default(MissionData);
for (int i = 0; i < 8; i++)
{
if (num == 0)
{
num = FillValidMissions(region.Flags, array);
}
if (num == 0)
{
break;
}
int num2 = ((Random)(ref val)).Next() + 1;
((Random)(ref val2))..ctor(MathUtil.Squirrel3Hash(num2, currentSeed));
LevelFlags val3 = region.Flags;
bool flag = false;
if (i >= 7 && (region.Flags & 0x8000) != 0)
{
SceneData[] legacyScenes = region.LegacyScenes;
if (legacyScenes != null && legacyScenes.Length != 0)
{
flag = true;
val3 = (LevelFlags)(val3 & -32769);
for (int num3 = num - 1; num3 >= 0; num3--)
{
if ((Global.Instance.Missions[array[num3]].MissionFlags & 0x400) == 0)
{
array[num3] = array[num - 1];
num--;
}
}
}
}
if (num == 0)
{
num = FillValidMissions(val3, array);
}
if (num == 0)
{
break;
}
int num4 = ((Random)(ref val2)).Next(num);
int num5 = array[num4];
array[num4] = array[num - 1];
num--;
array2[num5] = true;
Mission val4 = Global.Instance.Missions[num5];
if (!((Object)(object)val4 == (Object)null))
{
SceneData[] array3 = ((flag && region.LegacyScenes != null && region.LegacyScenes.Length != 0) ? region.LegacyScenes : region.Scenes);
if (array3 != null && array3.Length != 0)
{
SceneData val5 = array3[((Random)(ref val2)).Next(array3.Length)];
((MissionData)(ref data))..ctor(num2, val4, region, val5, Global.Instance.DefaultMissionContainer, val4.GetAdditionalData());
CheckAndCount(ref data);
}
}
}
for (int j = 0; j < Global.Instance.Missions.Length; j++)
{
Mission val6 = Global.Instance.Missions[j];
if (!((Object)(object)val6 == (Object)null))
{
if ((val6.MissionFlags & 1) == 0 && val6.ShowHiddenMissionInSelectScreen(region))
{
int missionSeed = ((Random)(ref val)).Next() + 1;
AddSpecialMission(val6, missionSeed, region, currentSeed, spawnInDesignedScene: false);
}
else if ((val6.MissionFlags & 0x20) != 0 && !array2[j])
{
array2[j] = true;
int missionSeed2 = ((Random)(ref val)).Next() + 1;
bool spawnInDesignedScene = (val6.MissionFlags & 0x400) != 0 && ((Random)(ref val)).NextFloat() <= 0.35f;
AddSpecialMission(val6, missionSeed2, region, currentSeed, spawnInDesignedScene);
}
}
}
for (int k = 0; k < Global.Instance.Missions.Length; k++)
{
Mission val7 = Global.Instance.Missions[k];
if (!((Object)(object)val7 == (Object)null) && (val7.MissionFlags & 0x80) != 0)
{
float rareSpawnChance = val7.GetRareSpawnChance();
if (((Random)(ref val)).NextFloat() < rareSpawnChance)
{
int missionSeed3 = ((Random)(ref val)).Next() + 1;
AddSpecialMission(val7, missionSeed3, region, currentSeed, spawnInDesignedScene: false);
}
}
}
}
private void AddSpecialMission(Mission mission, int missionSeed, WorldRegion region, int currentSeed, bool spawnInDesignedScene)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
Random val = default(Random);
((Random)(ref val))..ctor(MathUtil.Squirrel3Hash(missionSeed, currentSeed));
SceneData[] array = region.Scenes;
if (spawnInDesignedScene && (region.Flags & 0x8000) != 0)
{
SceneData[] legacyScenes = region.LegacyScenes;
if (legacyScenes != null && legacyScenes.Length != 0)
{
array = legacyScenes;
}
}
if (array != null && array.Length != 0)
{
SceneData val2 = array[((Random)(ref val)).Next(array.Length)];
MissionData data = default(MissionData);
((MissionData)(ref data))..ctor(missionSeed, mission, region, val2, Global.Instance.DefaultMissionContainer, mission.GetAdditionalData());
CheckAndCount(ref data);
}
}
private void CheckAndCount(ref MissionData data)
{
if (MissionHasRedacted(ref data))
{
HasRedactedOnBoard = true;
MatchCount++;
}
}
public bool MissionHasRedacted(ref MissionData data)
{
if (!IsResolved)
{
return false;
}
int modifierCount = ((MissionData)(ref data)).GetModifierCount();
if (modifierCount <= 0)
{
return false;
}
for (int i = 0; i < modifierCount; i++)
{
if (((MissionData)(ref data)).GetModifier(i) == RedactedIndex)
{
return true;
}
}
return false;
}
private static int FillValidMissions(LevelFlags compatibleLevels, int[] indexBuffer, int onlyThisIndex = -1)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: 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_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: 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)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
Mission[] missions = Global.Instance.Missions;
int result = 0;
for (int i = 0; i < missions.Length; i++)
{
if (onlyThisIndex >= 0)
{
indexBuffer[result++] = onlyThisIndex;
}
else if ((missions[i].MissionFlags & 0x80) == 0)
{
bool flag = false;
if ((missions[i].MissionFlags & 0x200) != 0 && (compatibleLevels & 0x8000) != 0)
{
flag = true;
}
bool flag2 = false;
if ((missions[i].MissionFlags & 0x400) != 0 && (compatibleLevels & 0x8000) == 0)
{
flag2 = true;
}
if ((flag || flag2) && missions[i].CanBeSelected() && (missions[i].CompatibleLevels & 0x640F0 & compatibleLevels) != 0 && (missions[i].MissionFlags & 2) == 0)
{
indexBuffer[result++] = i;
}
}
}
return result;
}
}
public sealed class RedactedHUD
{
private readonly RedactedBoardScanner _scanner;
private Color _baseAlertColor = UIColors.Orchid;
private Color _baseIdleColor = UIColors.TextMuted;
private Sprite _fallbackTriangle;
private HudHandle _hud;
private Image _iconImage;
private bool _lastDetected;
private bool _lastShowIdle;
public static RedactedHUD Instance { get; private set; }
private bool IsHudAlive
{
get
{
if (HudHandle.IsValid(_hud))
{
return _hud.Primary != null;
}
return false;
}
}
public RedactedHUD(RedactedBoardScanner scanner)
{
//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_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
_scanner = scanner;
Instance = this;
}
public void OnConfigChanged()
{
if (ConfigManager.EnableHud != null && !ConfigManager.EnableHud.Value && _hud != null)
{
DestroyHud();
}
UpdateHudVisibility();
RefreshVisual(force: true);
ApplyBlinkAlpha(1f);
}
public void Update()
{
try
{
if (ConfigManager.EnableHud == null || !ConfigManager.EnableHud.Value)
{
if (IsHudAlive && _hud.IsActive)
{
_hud.SetActive(false);
}
return;
}
if (_hud != null && !IsHudAlive)
{
ClearDestroyedHud();
}
if ((Object)(object)Player.LocalPlayer == (Object)null || (Object)(object)Player.LocalPlayer.PlayerLook == (Object)null || (Object)(object)Player.LocalPlayer.PlayerLook.Reticle == (Object)null)
{
return;
}
bool flag = _scanner != null && _scanner.HasRedactedOnBoard;
if (!flag && (ConfigManager.ShowWhenNotDetected == null || !ConfigManager.ShowWhenNotDetected.Value))
{
if (IsHudAlive)
{
_hud.SetActive(false);
}
return;
}
if (!IsHudAlive)
{
CreateHud();
if (!IsHudAlive)
{
return;
}
}
_hud.SetActive(true);
RefreshVisual(force: false);
UpdateBlink(flag);
}
catch (Exception ex)
{
RedactedNotificationPlugin.Logger.LogError((object)("Error in RedactedHUD.Update(): " + ex.Message));
}
}
private void UpdateBlink(bool detected)
{
if (IsHudAlive)
{
if (!detected || ConfigManager.EnableBlink == null || !ConfigManager.EnableBlink.Value)
{
ApplyBlinkAlpha(1f);
return;
}
float num = ((ConfigManager.BlinkSpeed != null) ? Mathf.Max(0.1f, ConfigManager.BlinkSpeed.Value) : 2f);
float num2 = ((ConfigManager.BlinkMinAlpha != null) ? Mathf.Clamp01(ConfigManager.BlinkMinAlpha.Value) : 0.35f);
float num3 = Mathf.PingPong(Time.unscaledTime * num, 1f);
float alpha = Mathf.Lerp(num2, 1f, num3);
ApplyBlinkAlpha(alpha);
}
}
private void ApplyBlinkAlpha(float alpha)
{
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: 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_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: 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 (IsHudAlive)
{
alpha = Mathf.Clamp01(alpha);
if (_hud.Primary != null && (Object)(object)_hud.Primary.Tmp != (Object)null)
{
Color color = (_lastDetected ? _baseAlertColor : _baseIdleColor);
color.a = alpha;
((Graphic)_hud.Primary.Tmp).color = color;
}
if ((Object)(object)_iconImage != (Object)null)
{
Color color2 = ((Graphic)_iconImage).color;
float num = (_lastDetected ? 1f : 0.85f);
color2.a = num * alpha;
((Graphic)_iconImage).color = color2;
}
}
}
public void UpdateHudVisibility()
{
if (!IsHudAlive)
{
ClearDestroyedHud();
return;
}
if (ConfigManager.EnableHud == null || !ConfigManager.EnableHud.Value)
{
_hud.SetActive(false);
return;
}
bool active = (_scanner != null && _scanner.HasRedactedOnBoard) || (ConfigManager.ShowWhenNotDetected != null && ConfigManager.ShowWhenNotDetected.Value);
_hud.SetActive(active);
}
private void ClearDestroyedHud()
{
_hud = null;
_iconImage = null;
}
private void CreateHud()
{
//IL_0059: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: 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_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_018d: Unknown result type (might be due to invalid IL or missing references)
//IL_0197: Unknown result type (might be due to invalid IL or missing references)
if (IsHudAlive)
{
return;
}
ClearDestroyedHud();
HudAnchors anchors = ConfigManager.Anchors;
float num = ((anchors != null) ? anchors.XValue : 0.5f);
float num2 = ((anchors != null) ? anchors.YValue : 0.12f);
_hud = HudBuilder.Create("RedactedNotificationHUD").ParentToReticle(true).Anchor(num, num2)
.Pivot(new Vector2(0.5f, 0.5f))
.Size(420f, 32f, true)
.AddText("StatusText", 18f, (TextAlignmentOptions)514)
.Build();
if (!IsHudAlive)
{
return;
}
try
{
RectTransform val = UIFactory.CreateRect("RedactedIcon", (Transform)(object)_hud.Rect);
val.anchorMin = new Vector2(0f, 0.5f);
val.anchorMax = new Vector2(0f, 0.5f);
val.pivot = new Vector2(0f, 0.5f);
val.sizeDelta = UITheme.ScaledSize(28f, 28f);
val.anchoredPosition = new Vector2(UITheme.S(4f), 0f);
_iconImage = ((Component)val).gameObject.AddComponent<Image>();
((Graphic)_iconImage).raycastTarget = false;
_iconImage.preserveAspect = true;
if (_hud.Primary != null && (Object)(object)_hud.Primary.Rect != (Object)null)
{
RectTransform rect = _hud.Primary.Rect;
rect.offsetMin = new Vector2(UITheme.S(34f), rect.offsetMin.y);
}
}
catch (Exception ex)
{
RedactedNotificationPlugin.Logger.LogWarning((object)("Could not create redacted icon: " + ex.Message));
_iconImage = null;
}
if (anchors != null)
{
_hud.EnableReposition("sparroh.redactednotification", "ERROR REDACTED Alert", anchors);
}
_lastDetected = false;
_lastShowIdle = false;
RefreshVisual(force: true);
}
private void DestroyHud()
{
if (_hud != null)
{
if (_hud.IsAlive)
{
_hud.Destroy();
}
_hud = null;
}
_iconImage = null;
}
private void RefreshVisual(bool force)
{
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
if (!IsHudAlive)
{
return;
}
bool flag = _scanner != null && _scanner.HasRedactedOnBoard;
bool flag2 = ConfigManager.ShowWhenNotDetected != null && ConfigManager.ShowWhenNotDetected.Value;
if (force || flag != _lastDetected || flag2 != _lastShowIdle)
{
_lastDetected = flag;
_lastShowIdle = flag2;
if (flag)
{
string text = ((ConfigManager.AlertText != null) ? ConfigManager.AlertText.Value : "ERROR REDACTED has appeared!");
_baseAlertColor = GetAlertColor();
_hud.Primary.Text = text;
((Graphic)_hud.Primary.Tmp).color = _baseAlertColor;
ApplyIcon(alert: true);
ApplyBlinkAlpha(1f);
}
else if (flag2)
{
string text2 = ((ConfigManager.IdleText != null) ? ConfigManager.IdleText.Value : "no ERROR detected.");
_baseIdleColor = UIColors.TextMuted;
_hud.Primary.Text = text2;
((Graphic)_hud.Primary.Tmp).color = _baseIdleColor;
ApplyIcon(alert: false);
ApplyBlinkAlpha(1f);
}
}
}
private Color GetAlertColor()
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
try
{
if (_scanner != null && (Object)(object)_scanner.RedactedModifier != (Object)null)
{
return _scanner.RedactedModifier.IconColor;
}
}
catch
{
}
return UIColors.Orchid;
}
private void ApplyIcon(bool alert)
{
//IL_0015: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_iconImage == (Object)null)
{
return;
}
Sprite val = null;
Color alertColor = default(Color);
if (alert)
{
alertColor = GetAlertColor();
try
{
if (_scanner != null && (Object)(object)_scanner.RedactedModifier != (Object)null)
{
val = _scanner.RedactedModifier.Icon;
}
}
catch
{
}
}
else
{
((Color)(ref alertColor))..ctor(0.45f, 0.45f, 0.48f, 0.85f);
try
{
if (_scanner != null && (Object)(object)_scanner.RedactedModifier != (Object)null)
{
val = _scanner.RedactedModifier.Icon;
}
}
catch
{
}
}
if ((Object)(object)val == (Object)null)
{
val = GetFallbackTriangle();
}
_iconImage.sprite = val;
((Graphic)_iconImage).color = alertColor;
((Behaviour)_iconImage).enabled = (Object)(object)val != (Object)null;
}
private Sprite GetFallbackTriangle()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_fallbackTriangle != (Object)null)
{
return _fallbackTriangle;
}
Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false);
((Texture)val).filterMode = (FilterMode)1;
((Texture)val).wrapMode = (TextureWrapMode)1;
Color val2 = default(Color);
((Color)(ref val2))..ctor(0f, 0f, 0f, 0f);
Color white = Color.white;
for (int i = 0; i < 32; i++)
{
for (int j = 0; j < 32; j++)
{
float num = ((float)j + 0.5f) / 32f;
float num2 = ((float)i + 0.5f) / 32f;
float num3 = num2 * 0.5f;
bool flag = num2 >= 0.12f && num2 <= 0.92f && Mathf.Abs(num - 0.5f) <= num3 * 0.9f;
val.SetPixel(j, i, flag ? white : val2);
}
}
val.Apply(false, true);
_fallbackTriangle = Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 100f);
return _fallbackTriangle;
}
public void OnDestroy()
{
try
{
DestroyHud();
}
catch (Exception ex)
{
RedactedNotificationPlugin.Logger.LogError((object)("Error in RedactedHUD.OnDestroy(): " + ex.Message));
}
}
}
[HarmonyPatch]
public static class RedactedPatches
{
[HarmonyPatch(typeof(MissionSelectButton), "Setup", new Type[]
{
typeof(MissionData),
typeof(MissionSelectWindow),
typeof(bool),
typeof(bool),
typeof(bool)
})]
[HarmonyPostfix]
private static void MissionSelectButton_Setup_Postfix(MissionSelectButton __instance)
{
try
{
if (RedactedNotificationPlugin.Scanner != null && !((Object)(object)__instance == (Object)null))
{
ref MissionData mission = ref __instance.Mission;
RedactedNotificationPlugin.Scanner.ObserveMission(ref mission);
}
}
catch
{
}
}
[HarmonyPatch(typeof(MissionSelectWindow), "Setup")]
[HarmonyPostfix]
private static void MissionSelectWindow_Setup_Postfix()
{
try
{
RedactedNotificationPlugin.Scanner?.ForceRescan();
}
catch
{
}
}
}
namespace RedactedNotification
{
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "RedactedNotification";
public const string PLUGIN_NAME = "RedactedNotification";
public const string PLUGIN_VERSION = "1.0.2";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}