Decompiled source of JusticeForF7 v2026.717.0

plugins/JusticeForF7/JusticeForF7.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JusticeForF7.Patches;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("JusticeForF7")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+da54a6a010598788c467b5d082673a1649aac93b")]
[assembly: AssemblyProduct("JusticeForF7")]
[assembly: AssemblyTitle("JusticeForF7")]
[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.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;
		}
	}
	[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 JusticeForF7
{
	public interface IJusticeSettings
	{
		bool Enabled { get; }

		bool EnableLogging { get; }

		int RescanInterval { get; }

		bool HideNameplates { get; }

		bool HideDamageNumbers { get; }

		bool HideTargetRings { get; }

		bool HideXPOrbs { get; }

		bool HideCastBars { get; }

		bool HideOtherWorldText { get; }
	}
	public interface IModLogger
	{
		void LogInfo(string message);

		void LogDebug(string message);
	}
	internal sealed class JusticeRuntime
	{
		private readonly IModLogger _log;

		private readonly IJusticeSettings _settings;

		private readonly CanvasVisibilityObserver _canvasVisibility = new CanvasVisibilityObserver();

		private Harmony? _harmony;

		private WorldUIHider? _hider;

		private bool _running;

		private bool _disabledReported;

		public JusticeRuntime(IModLogger log, IJusticeSettings settings)
		{
			_log = log;
			_settings = settings;
		}

		public void Start()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			if (_running)
			{
				return;
			}
			if (!_settings.Enabled)
			{
				ReportDisabled();
				return;
			}
			_disabledReported = false;
			_hider = new WorldUIHider(_log, _settings);
			NamePlatePatch.Hider = _hider;
			NpcNamePlatePatch.Hider = _hider;
			DmgPopPatch.Hider = _hider;
			XPBubPatch.Hider = _hider;
			_harmony = new Harmony("wow-much.justice-for-f7");
			try
			{
				_harmony.PatchAll();
				SceneManager.sceneLoaded += OnSceneLoaded;
				_running = true;
			}
			catch
			{
				Stop();
				throw;
			}
			if (_settings.EnableLogging)
			{
				_log.LogInfo("Justice for F7 v2026.717.0 loaded");
			}
		}

		public void Tick()
		{
			if (_settings.Enabled)
			{
				Start();
			}
			else if (_running)
			{
				Stop();
				ReportDisabled();
			}
			else
			{
				ReportDisabled();
			}
			if (_running && _hider != null)
			{
				_canvasVisibility.Tick(_hider);
			}
		}

		public void Stop()
		{
			if (_running)
			{
				SceneManager.sceneLoaded -= OnSceneLoaded;
			}
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_harmony = null;
			_hider?.OnUIShown();
			_hider = null;
			_canvasVisibility.Reset();
			NamePlatePatch.Hider = null;
			NpcNamePlatePatch.Hider = null;
			DmgPopPatch.Hider = null;
			XPBubPatch.Hider = null;
			_running = false;
		}

		private void ReportDisabled()
		{
			if (!_disabledReported)
			{
				_disabledReported = true;
				_log.LogInfo("Justice for F7 v2026.717.0 loaded (disabled via config)");
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			_canvasVisibility.Reset();
			_hider?.OnSceneLoaded();
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "wow-much.justice-for-f7";

		public const string Name = "Justice for F7";

		public const string Version = "2026.717.0";
	}
	internal sealed class WorldUIHider
	{
		private readonly IModLogger _log;

		private readonly IJusticeSettings _settings;

		private readonly HashSet<Renderer> _disabledRenderers = new HashSet<Renderer>();

		private readonly HashSet<GameObject> _disabledGameObjects = new HashSet<GameObject>();

		private int _framesSinceLastScan;

		public bool IsHidden { get; private set; }

		public bool SuppressDamageNumbers => IsHidden && _settings.HideDamageNumbers;

		public bool SuppressXPOrbs => IsHidden && _settings.HideXPOrbs;

		public WorldUIHider(IModLogger log, IJusticeSettings settings)
		{
			_log = log;
			_settings = settings;
		}

		public void OnUIHidden()
		{
			IsHidden = true;
			_framesSinceLastScan = 0;
			ScanAndHide();
		}

		public void OnUIShown()
		{
			IsHidden = false;
			RestoreAll();
		}

		public void Tick()
		{
			if (!IsHidden)
			{
				return;
			}
			int rescanInterval = _settings.RescanInterval;
			if (rescanInterval > 0)
			{
				_framesSinceLastScan++;
				if (_framesSinceLastScan >= rescanInterval)
				{
					_framesSinceLastScan = 0;
					ScanAndHide();
				}
			}
		}

		public void OnSceneLoaded()
		{
			_disabledRenderers.Clear();
			_disabledGameObjects.Clear();
			if (IsHidden)
			{
				_framesSinceLastScan = 0;
				ScanAndHide();
			}
		}

		internal void EnforceTargetIndicatorHidden(NamePlate? plate)
		{
			if (IsHidden && _settings.HideNameplates && !((Object)(object)plate == (Object)null))
			{
				HideGameObject(plate.TargetInd);
			}
		}

		internal void EnforceHealthBarHidden(NamePlate? plate)
		{
			if (IsHidden && _settings.HideNameplates && !((Object)(object)plate == (Object)null))
			{
				HideGameObject(plate.Lifebar);
			}
		}

		private void ScanAndHide()
		{
			int num = 0;
			if (_settings.HideNameplates)
			{
				num += HideNameplates();
			}
			if (_settings.HideDamageNumbers)
			{
				num += HideDamageNumbers();
			}
			if (_settings.HideTargetRings)
			{
				num += HideTargetRings();
			}
			if (_settings.HideXPOrbs)
			{
				num += HideXPOrbs();
			}
			if (_settings.HideCastBars)
			{
				num += HideCastBars();
			}
			if (_settings.HideOtherWorldText)
			{
				num += HideOtherWorldText();
			}
			if (_settings.EnableLogging)
			{
				_log.LogDebug($"Scan complete: {num} elements hidden");
			}
		}

		private int HideNameplates()
		{
			int num = 0;
			NamePlate[] array = Object.FindObjectsOfType<NamePlate>();
			foreach (NamePlate plate in array)
			{
				num += HideNameplateElements(plate);
			}
			return num;
		}

		private int HideNameplateElements(NamePlate plate)
		{
			if ((Object)(object)plate == (Object)null)
			{
				return 0;
			}
			int num = 0;
			Renderer component = ((Component)plate).GetComponent<Renderer>();
			if ((Object)(object)component != (Object)null && component.enabled)
			{
				component.enabled = false;
				_disabledRenderers.Add(component);
				num++;
			}
			num += HideGameObject(plate.Lifebar);
			return num + HideGameObject(plate.TargetInd);
		}

		private int HideGameObject(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null || !gameObject.activeSelf)
			{
				return 0;
			}
			gameObject.SetActive(false);
			_disabledGameObjects.Add(gameObject);
			return 1;
		}

		private int HideDamageNumbers()
		{
			int num = 0;
			DmgPop[] array = Object.FindObjectsOfType<DmgPop>();
			foreach (DmgPop val in array)
			{
				Renderer val2 = (((Object)(object)val.Num != (Object)null) ? ((Component)val.Num).GetComponent<Renderer>() : null);
				if ((Object)(object)val2 != (Object)null && val2.enabled)
				{
					val2.enabled = false;
					_disabledRenderers.Add(val2);
					num++;
				}
			}
			return num;
		}

		private int HideTargetRings()
		{
			int num = 0;
			Character[] array = Object.FindObjectsOfType<Character>();
			foreach (Character val in array)
			{
				GameObject targetRing = val.TargetRing;
				if ((Object)(object)targetRing != (Object)null && targetRing.activeSelf)
				{
					targetRing.SetActive(false);
					_disabledGameObjects.Add(targetRing);
					num++;
				}
			}
			return num;
		}

		private int HideXPOrbs()
		{
			int num = 0;
			XPBub[] array = Object.FindObjectsOfType<XPBub>();
			foreach (XPBub val in array)
			{
				Renderer component = ((Component)val).GetComponent<Renderer>();
				if ((Object)(object)component != (Object)null && component.enabled)
				{
					component.enabled = false;
					_disabledRenderers.Add(component);
					num++;
				}
			}
			return num;
		}

		private int HideCastBars()
		{
			int num = 0;
			FlashUIColors[] array = Object.FindObjectsOfType<FlashUIColors>();
			foreach (FlashUIColors val in array)
			{
				if (!((Object)(object)val.CastBar == (Object)null))
				{
					Renderer component = ((Component)val.CastBar).GetComponent<Renderer>();
					if ((Object)(object)component != (Object)null && component.enabled)
					{
						component.enabled = false;
						_disabledRenderers.Add(component);
						num++;
					}
				}
			}
			return num;
		}

		private int HideOtherWorldText()
		{
			int num = 0;
			TextMeshPro[] array = Object.FindObjectsOfType<TextMeshPro>();
			foreach (TextMeshPro val in array)
			{
				if (!((Object)(object)((Component)val).GetComponent<NamePlate>() != (Object)null) && !((Object)(object)((Component)val).GetComponent<DmgPop>() != (Object)null) && !((Object)(object)((Component)val).GetComponentInParent<DmgPop>() != (Object)null))
				{
					Renderer component = ((Component)val).GetComponent<Renderer>();
					if ((Object)(object)component != (Object)null && component.enabled)
					{
						component.enabled = false;
						_disabledRenderers.Add(component);
						num++;
					}
				}
			}
			return num;
		}

		private void RestoreAll()
		{
			int num = 0;
			int num2 = 0;
			_disabledRenderers.RemoveWhere((Renderer r) => (Object)(object)r == (Object)null);
			_disabledGameObjects.RemoveWhere((GameObject go) => (Object)(object)go == (Object)null);
			foreach (Renderer disabledRenderer in _disabledRenderers)
			{
				disabledRenderer.enabled = true;
				num++;
			}
			foreach (GameObject disabledGameObject in _disabledGameObjects)
			{
				disabledGameObject.SetActive(true);
				num2++;
			}
			_disabledRenderers.Clear();
			_disabledGameObjects.Clear();
			if (_settings.EnableLogging)
			{
				_log.LogDebug($"Restored {num} renderers, {num2} game objects");
			}
		}
	}
	[BepInPlugin("wow-much.justice-for-f7", "Justice for F7", "2026.717.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private sealed class BepInExModLogger : IModLogger
		{
			private readonly ManualLogSource _logger;

			public BepInExModLogger(ManualLogSource logger)
			{
				_logger = logger;
			}

			public void LogInfo(string message)
			{
				_logger.LogInfo((object)message);
			}

			public void LogDebug(string message)
			{
				_logger.LogDebug((object)message);
			}
		}

		private sealed class BepInExJusticeSettings : IJusticeSettings
		{
			private readonly ConfigEntry<bool> _enabled;

			private readonly ConfigEntry<bool> _enableLogging;

			private readonly ConfigEntry<int> _rescanInterval;

			private readonly ConfigEntry<bool> _hideNameplates;

			private readonly ConfigEntry<bool> _hideDamageNumbers;

			private readonly ConfigEntry<bool> _hideTargetRings;

			private readonly ConfigEntry<bool> _hideXPOrbs;

			private readonly ConfigEntry<bool> _hideCastBars;

			private readonly ConfigEntry<bool> _hideOtherWorldText;

			public bool Enabled => _enabled.Value;

			public bool EnableLogging => _enableLogging.Value;

			public int RescanInterval => _rescanInterval.Value;

			public bool HideNameplates => _hideNameplates.Value;

			public bool HideDamageNumbers => _hideDamageNumbers.Value;

			public bool HideTargetRings => _hideTargetRings.Value;

			public bool HideXPOrbs => _hideXPOrbs.Value;

			public bool HideCastBars => _hideCastBars.Value;

			public bool HideOtherWorldText => _hideOtherWorldText.Value;

			public BepInExJusticeSettings(ConfigFile config)
			{
				_enabled = config.Bind<bool>("General", "Enabled", true, "Master switch. When false, F7 behaves as vanilla.");
				_enableLogging = config.Bind<bool>("General", "EnableLogging", true, "Enable debug logging. Set to false to silence all mod log output.");
				_rescanInterval = config.Bind<int>("General", "RescanInterval", 30, "Frames between re-scans while UI is hidden (0 = disable re-scan).");
				_hideNameplates = config.Bind<bool>("Elements", "HideNameplates", true, "Hide NPC, SimPlayer, and player nameplates.");
				_hideDamageNumbers = config.Bind<bool>("Elements", "HideDamageNumbers", true, "Hide floating damage and heal numbers.");
				_hideTargetRings = config.Bind<bool>("Elements", "HideTargetRings", true, "Hide the selection ring under targeted characters.");
				_hideXPOrbs = config.Bind<bool>("Elements", "HideXPOrbs", true, "Hide XP orb particles.");
				_hideCastBars = config.Bind<bool>("Elements", "HideCastBars", true, "Hide NPC and SimPlayer cast bars above nameplates.");
				_hideOtherWorldText = config.Bind<bool>("Elements", "HideOtherWorldText", true, "Hide remaining world-space text (loot prompts, etc.).");
			}
		}

		private JusticeRuntime? _runtime;

		private void Awake()
		{
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			BepInExJusticeSettings settings = new BepInExJusticeSettings(((BaseUnityPlugin)this).Config);
			_runtime = new JusticeRuntime(new BepInExModLogger(((BaseUnityPlugin)this).Logger), settings);
			_runtime.Start();
		}

		private void Update()
		{
			_runtime?.Tick();
		}

		private void OnDestroy()
		{
			_runtime?.Stop();
			_runtime = null;
		}
	}
}
namespace JusticeForF7.Patches
{
	internal sealed class CanvasVisibilityObserver
	{
		private bool? _lastCanvasEnabled;

		public void Reset()
		{
			_lastCanvasEnabled = null;
		}

		public void Tick(WorldUIHider hider)
		{
			Canvas mainCanvas = GameData.MainCanvas;
			if ((Object)(object)mainCanvas == (Object)null)
			{
				return;
			}
			bool enabled = ((Behaviour)mainCanvas).enabled;
			if (!_lastCanvasEnabled.HasValue)
			{
				_lastCanvasEnabled = enabled;
				return;
			}
			if (enabled == _lastCanvasEnabled.Value)
			{
				hider.Tick();
				return;
			}
			_lastCanvasEnabled = enabled;
			if (enabled)
			{
				hider.OnUIShown();
			}
			else
			{
				hider.OnUIHidden();
			}
		}
	}
	internal static class DmgPopPatch
	{
		public static WorldUIHider? Hider { get; set; }

		[HarmonyPatch(typeof(Misc), "GenPopup")]
		[HarmonyPrefix]
		public static bool GenPopupPrefix(int _dmg, bool _crit, DamageType _type, Transform _tar)
		{
			return Hider == null || !Hider.SuppressDamageNumbers;
		}

		[HarmonyPatch(typeof(Misc), "GenPopupString")]
		[HarmonyPrefix]
		public static bool GenPopupStringPrefix(string _msg, Transform _tar)
		{
			return Hider == null || !Hider.SuppressDamageNumbers;
		}
	}
	[HarmonyPatch(typeof(NamePlate), "Update")]
	internal static class NamePlatePatch
	{
		public static WorldUIHider? Hider { get; set; }

		[HarmonyPostfix]
		public static void Postfix(NamePlate __instance)
		{
			Hider?.EnforceTargetIndicatorHidden(__instance);
		}
	}
	[HarmonyPatch(typeof(NPC), "HandleNameTag")]
	internal static class NpcNamePlatePatch
	{
		public static WorldUIHider? Hider { get; set; }

		[HarmonyPostfix]
		public static void Postfix(NamePlate? ___NamePlateObject)
		{
			Hider?.EnforceHealthBarHidden(___NamePlateObject);
		}
	}
	[HarmonyPatch(typeof(Misc), "GetXPBalls")]
	internal static class XPBubPatch
	{
		public static WorldUIHider? Hider { get; set; }

		[HarmonyPrefix]
		public static bool Prefix(int amt, Vector3 callPos, Transform _tar)
		{
			return Hider == null || !Hider.SuppressXPOrbs;
		}
	}
}