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 Area Repair v0.1.0
FrizzQOL.AreaRepair.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("FrizzQOL.AreaRepair")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+390888ce9958d39dc59b6d4c12697e4d38569584")] [assembly: AssemblyProduct("FrizzQOL.AreaRepair")] [assembly: AssemblyTitle("FrizzQOL.AreaRepair")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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 RepairRules { public static bool IsInRange(float distance, float radius) { if (radius > 0f) { return distance <= radius; } return false; } public static bool ShouldRepair(bool isDamaged, float distance, float radius) { if (isDamaged) { return IsInRange(distance, radius); } return false; } public static bool ShouldAreaRepair(bool hoveredRepairAccepted) { return hoveredRepairAccepted; } public static bool ShouldRepairNearby(float distance, float radius, bool wardAllows) { if (wardAllows) { return IsInRange(distance, radius); } return false; } } public sealed class RepairIndex<T> where T : class { private readonly struct Pos { public readonly float X; public readonly float Y; public readonly float Z; public Pos(float x, float y, float z) { X = x; Y = y; Z = z; } } private readonly struct Cell : IEquatable<Cell> { public readonly int X; public readonly int Y; public readonly int Z; public Cell(int x, int y, int z) { X = x; Y = y; Z = z; } public bool Equals(Cell other) { if (X == other.X && Y == other.Y) { return Z == other.Z; } return false; } public override bool Equals(object obj) { if (obj is Cell other) { return Equals(other); } return false; } public override int GetHashCode() { return (((X * 397) ^ Y) * 397) ^ Z; } } private readonly float _cell; private readonly Dictionary<T, Cell> _cellOf = new Dictionary<T, Cell>(); private readonly Dictionary<T, Pos> _pos = new Dictionary<T, Pos>(); private readonly Dictionary<Cell, List<T>> _cells = new Dictionary<Cell, List<T>>(); public int Count => _cellOf.Count; public int LastVisited { get; private set; } public RepairIndex(float cellSize) { if (cellSize <= 0f) { throw new ArgumentOutOfRangeException("cellSize"); } _cell = cellSize; } public void Add(T item, float x, float y, float z) { if (item != null) { Remove(item); Cell cell = CellOf(x, y, z); _cellOf[item] = cell; _pos[item] = new Pos(x, y, z); if (!_cells.TryGetValue(cell, out var value)) { value = new List<T>(); _cells[cell] = value; } value.Add(item); } } public void Remove(T item) { if (item == null || !_cellOf.TryGetValue(item, out var value)) { return; } _cellOf.Remove(item); _pos.Remove(item); if (_cells.TryGetValue(value, out var value2)) { value2.Remove(item); if (value2.Count == 0) { _cells.Remove(value); } } } public void Collect(float x, float y, float z, float radius, List<T> results) { if (results == null) { throw new ArgumentNullException("results"); } results.Clear(); LastVisited = 0; if (radius <= 0f || _cellOf.Count == 0) { return; } double num = Math.Floor((x - radius) / _cell); double num2 = Math.Floor((x + radius) / _cell); double num3 = Math.Floor((y - radius) / _cell); double num4 = Math.Floor((y + radius) / _cell); double num5 = Math.Floor((z - radius) / _cell); double num6 = Math.Floor((z + radius) / _cell); double num7 = num2 - num + 1.0; double num8 = num4 - num3 + 1.0; double num9 = num6 - num5 + 1.0; if (num7 * num8 * num9 > (double)_cellOf.Count || num7 > 32.0 || num8 > 32.0 || num9 > 32.0 || num < -2147483648.0 || num2 > 2147483647.0 || num3 < -2147483648.0 || num4 > 2147483647.0 || num5 < -2147483648.0 || num6 > 2147483647.0) { ScanAll(x, y, z, radius * radius, results); return; } float r = radius * radius; int num10 = (int)num; int num11 = (int)num2; int num12 = (int)num3; int num13 = (int)num4; int num14 = (int)num5; int num15 = (int)num6; for (int i = num10; i <= num11; i++) { for (int j = num12; j <= num13; j++) { for (int k = num14; k <= num15; k++) { if (_cells.TryGetValue(new Cell(i, j, k), out var value)) { Visit(value, x, y, z, r, results); } } } } } private void ScanAll(float x, float y, float z, float r2, List<T> results) { foreach (KeyValuePair<T, Pos> po in _pos) { LastVisited++; Pos value = po.Value; float num = value.X - x; float num2 = value.Y - y; float num3 = value.Z - z; if (num * num + num2 * num2 + num3 * num3 <= r2) { results.Add(po.Key); } } } private void Visit(List<T> list, float x, float y, float z, float r2, List<T> results) { for (int i = 0; i < list.Count; i++) { T val = list[i]; LastVisited++; if (_pos.TryGetValue(val, out var value)) { float num = value.X - x; float num2 = value.Y - y; float num3 = value.Z - z; if (num * num + num2 * num2 + num3 * num3 <= r2) { results.Add(val); } } } } private Cell CellOf(float x, float y, float z) { return new Cell(Floor(x), Floor(y), Floor(z)); } private int Floor(float value) { return (int)Math.Floor(value / _cell); } } namespace AreaRepair { [BepInPlugin("com.frizzqol.arearepair", "FrizzQOL Area Repair", "0.1.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.frizzqol.arearepair"; public const string PluginName = "FrizzQOL Area Repair"; public const string PluginVersion = "0.1.0"; internal static ConfigEntry<float> RepairRadius; private Harmony _harmony; internal static Plugin Instance { get; private set; } private void Awake() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown Instance = this; RepairRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RepairRadius", 5f, "Sphere radius in meters around the hammer-repair target. 0 or less disables area repair."); _harmony = new Harmony("com.frizzqol.arearepair"); try { _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"FrizzQOL Area Repair 0.1.0 loaded"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to patch Player.Repair: " + ex.Message)); } } internal static float CurrentRadius() { if (RepairRadius == null) { return 5f; } return RepairRadius.Value; } internal static void LogInfo(string message) { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)message); } } internal static void LogWarning(string message) { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogWarning((object)message); } } internal static void LogError(string message) { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogError((object)message); } } } [HarmonyPatch(typeof(Player), "Repair", new Type[] { typeof(ItemData), typeof(Piece) })] internal static class RepairPatch { private const float CellSize = 16f; private static readonly RepairIndex<Piece> Index = new RepairIndex<Piece>(16f); private static readonly List<Piece> Nearby = new List<Piece>(); private static readonly FieldInfo GhostLayerField = AccessTools.Field(typeof(Piece), "s_ghostLayer"); private static bool _busy; private static bool _watchHover; private static bool _hoverAccepted; private static int _ghostLayer = int.MinValue; internal static void NoteHoverRepair(bool accepted) { if (_watchHover) { _hoverAccepted = accepted; } } internal static void Track(Piece piece) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)piece == (Object)null)) { Vector3 position = ((Component)piece).transform.position; Index.Add(piece, position.x, position.y, position.z); } } internal static void Untrack(Piece piece) { Index.Remove(piece); } private static void Prefix() { if (!_busy) { _watchHover = true; _hoverAccepted = false; } } private static void Postfix(Player __instance) { if (_busy) { return; } _watchHover = false; if (!RepairRules.ShouldAreaRepair(_hoverAccepted) || (Object)(object)__instance == (Object)null) { return; } Piece hoveringPiece = __instance.GetHoveringPiece(); if ((Object)(object)hoveringPiece == (Object)null) { return; } float num = Plugin.CurrentRadius(); if (num <= 0f) { return; } try { _busy = true; RepairNearby(hoveringPiece, num); } finally { _busy = false; } } private static void Finalizer() { _watchHover = false; } private static void RepairNearby(Piece target, float radius) { //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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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) Vector3 position = ((Component)target).transform.position; Index.Collect(position.x, position.y, position.z, radius, Nearby); int num = 0; try { for (int i = 0; i < Nearby.Count; i++) { Piece val = Nearby[i]; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)target || IsGhost(val)) { continue; } Vector3 position2 = ((Component)val).transform.position; float distance = Vector3.Distance(position, position2); bool wardAllows = PrivateArea.CheckAccess(position2, 0f, false, false); if (RepairRules.ShouldRepairNearby(distance, radius, wardAllows)) { WearNTear component = ((Component)val).GetComponent<WearNTear>(); if (!((Object)(object)component == (Object)null) && component.Repair()) { num++; } } } } finally { Nearby.Clear(); } if (num > 0) { Plugin.LogInfo("Repaired " + num + " extra pieces."); } } private static bool IsGhost(Piece piece) { if (_ghostLayer == int.MinValue) { _ghostLayer = ((((GhostLayerField != null) ? GhostLayerField.GetValue(null) : null) is int num) ? num : (-1)); } if (_ghostLayer >= 0) { return ((Component)piece).gameObject.layer == _ghostLayer; } return false; } } [HarmonyPatch(typeof(WearNTear), "Repair")] internal static class WearRepairResultPatch { private static void Postfix(bool __result) { RepairPatch.NoteHoverRepair(__result); } } [HarmonyPatch(typeof(Piece), "Awake")] internal static class PieceTrackPatch { private static void Postfix(Piece __instance) { RepairPatch.Track(__instance); } } [HarmonyPatch(typeof(Piece), "OnDestroy")] internal static class PieceUntrackPatch { private static void Postfix(Piece __instance) { RepairPatch.Untrack(__instance); } } }