Decompiled source of MapperFix v0.0.2

BepInEx/plugins/Mapper.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MTFO.API;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Mapper")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+66f3615c5d2fb24259bccfdb342828c4fcf59bf1")]
[assembly: AssemblyProduct("Mapper")]
[assembly: AssemblyTitle("Mapper")]
[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.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;
		}
	}
}
public static class ChargeRatioRelay
{
	private static float s_pendingRatio = -1f;

	private static int s_pendingPlayerID = -1;

	public static void Stash(int playerID, float ratio)
	{
		s_pendingPlayerID = playerID;
		s_pendingRatio = ratio;
	}

	public static bool TryConsume(int expectedPlayerID, out float ratio)
	{
		ratio = 0f;
		if (s_pendingRatio < 0f)
		{
			return false;
		}
		if (s_pendingPlayerID != expectedPlayerID)
		{
			return false;
		}
		ratio = s_pendingRatio;
		s_pendingRatio = -1f;
		s_pendingPlayerID = -1;
		return true;
	}
}
[HarmonyPatch(typeof(MapperDataCloud), "Activate")]
public class MapperDataCloudActivatePatch
{
	[HarmonyPrefix]
	private static void Prefix(MapperDataCloud __instance)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		((Behaviour)__instance).enabled = true;
		((Component)__instance).transform.position = Vector3.zero;
		((Component)__instance).transform.rotation = Quaternion.identity;
		((Component)__instance).transform.localScale = Vector3.one;
		__instance.CountX = MapperFixSettings.DummyCountX;
		__instance.CountY = MapperFixSettings.DummyCountY;
		MethodInfo methodInfo = AccessTools.Method(typeof(MapperDataCloud), "InitParticles", (Type[])null, (Type[])null);
		methodInfo.Invoke(__instance, null);
	}

	[HarmonyPostfix]
	private static void Postfix(MapperDataCloud __instance)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance.m_mapVisibilityTrans == (Object)null)
		{
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null)
			{
				__instance.m_mapVisibilityTrans = ((Component)main).transform;
			}
		}
		LayerMask maskMapperDataObject = __instance.m_maskMapperDataObject;
		if (((LayerMask)(ref maskMapperDataObject)).value == 0)
		{
			__instance.m_maskMapperDataObject = LayerMask.op_Implicit(-1);
		}
	}
}
[HarmonyPatch(typeof(MapperDataCloud), "Update")]
public class MapperDataCloudCleanupPatch
{
	private static Dictionary<int, float> s_deactivateStartTime = new Dictionary<int, float>();

	[HarmonyPostfix]
	private static void Postfix(MapperDataCloud __instance)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Invalid comparison between Unknown and I4
		int instanceID = ((Object)__instance).GetInstanceID();
		if ((int)__instance.m_state == 3)
		{
			if (!s_deactivateStartTime.ContainsKey(instanceID))
			{
				s_deactivateStartTime[instanceID] = Time.time;
			}
			else if (Time.time - s_deactivateStartTime[instanceID] > MapperFixSettings.DeactivatingTimeout)
			{
				s_deactivateStartTime.Remove(instanceID);
				Object.Destroy((Object)(object)((Component)__instance).gameObject);
			}
		}
		else
		{
			s_deactivateStartTime.Remove(instanceID);
		}
	}
}
[HarmonyPatch(typeof(MapperDataCloudManager), "DoSpawnMapperDataCloud")]
public class MapperDataCloudManagerPatch
{
	[HarmonyPatch(typeof(MapperDataCloudManager), "DoSpawnMapperDataCloud")]
	public class MapperDataCloudManagerStackTracePatch
	{
		[HarmonyPrefix]
		private static void Prefix(pSpawnMapperDataCloud data)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_0039: 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)
			if (MapperFixSettings.VerboseLogging)
			{
				StackTrace stackTrace = new StackTrace(1, fNeedFileInfo: true);
				ManualLogSource log = MapperFixPlugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(63, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[CallStack diag] DoSpawnMapperDataCloud playerID=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(data.playerID);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", cloudDepth=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(data.cloudDepth);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("\n");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<StackTrace>(stackTrace);
				}
				log.LogInfo(val);
			}
		}
	}

	private static readonly Dictionary<int, float> s_lastSpawnTime = new Dictionary<int, float>();

	[HarmonyPrefix]
	private static void Prefix(MapperDataCloudManager __instance, ref pSpawnMapperDataCloud data)
	{
		if (!((Object)(object)__instance.m_mapperCloudPrefab != (Object)null) || !((Object)(object)__instance.m_mapperDataScanPointPrefab != (Object)null))
		{
			if ((Object)(object)MapperFixPlugin.CachedCloudTemplate != (Object)null && (Object)(object)MapperFixPlugin.CachedScanPointTemplate != (Object)null)
			{
				__instance.m_mapperCloudPrefab = MapperFixPlugin.CachedCloudTemplate;
				__instance.m_mapperDataScanPointPrefab = MapperFixPlugin.CachedScanPointTemplate;
				return;
			}
			GameObject val = BuildDummyCloud();
			Object.DontDestroyOnLoad((Object)(object)val);
			MapperFixPlugin.CachedCloudTemplate = val;
			GameObject val2 = BuildDummyScanPoint();
			Object.DontDestroyOnLoad((Object)(object)val2);
			MapperFixPlugin.CachedScanPointTemplate = val2;
			__instance.m_mapperCloudPrefab = val;
			__instance.m_mapperDataScanPointPrefab = val2;
		}
	}

	[HarmonyPostfix]
	private static void Postfix(pSpawnMapperDataCloud data)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Expected O, but got Unknown
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: 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_008a: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: 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)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: 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_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: 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)
		int playerID = data.playerID;
		float time = Time.time;
		if (MapperFixSettings.VerboseLogging)
		{
			ManualLogSource log = MapperFixPlugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(110, 9, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[pSpawnMapperDataCloud diag] shape=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eMapperScanningShape>(data.shape);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" playerID=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(data.playerID);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("scanPos=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(data.scanPos);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" dirFwd=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(data.dirFwd);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" cloudDepth=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(data.cloudDepth);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("corner1=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(data.frustrumCorner1);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" corner2=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(data.frustrumCorner2);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("corner3=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(data.frustrumCorner3);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" corner4=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3>(data.frustrumCorner4);
			}
			log.LogInfo(val);
		}
		if (s_lastSpawnTime.TryGetValue(playerID, out var value) && time - value < MapperFixSettings.SequenceCooldown)
		{
			s_lastSpawnTime[playerID] = time;
			return;
		}
		s_lastSpawnTime[playerID] = time;
		Quaternion rot = ((data.dirFwd != Vector3.zero) ? Quaternion.LookRotation(data.dirFwd) : Quaternion.identity);
		float? chargeRatio = (MapperFixSettings.EnableChargeBasedScaling ? new float?(Mathf.Clamp01(data.cloudDepth)) : ((float?)null));
		MapperFixPlugin.SpawnXRayEffectAt(data.scanPos, rot, chargeRatio);
	}

	private static GameObject BuildDummyCloud()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("DummyMapperCloud");
		MapperDataCloud val2 = ((Il2CppObjectBase)val.AddComponent(Il2CppType.Of<MapperDataCloud>())).Cast<MapperDataCloud>();
		ParticleSystem val3 = val.AddComponent<ParticleSystem>();
		val3.Stop(true, (ParticleSystemStopBehavior)0);
		EmissionModule emission = val3.emission;
		emission.enabled = false;
		emission.rateOverTime = MinMaxCurve.op_Implicit(0f);
		Component component = val.GetComponent(Il2CppType.Of<ParticleSystemRenderer>());
		ParticleSystemRenderer val4 = ((component != null) ? ((Il2CppObjectBase)component).Cast<ParticleSystemRenderer>() : null);
		if ((Object)(object)val4 != (Object)null)
		{
			((Renderer)val4).enabled = false;
		}
		val2.m_particleSystem = val3;
		val2.CountX = MapperFixSettings.DummyCountX;
		val2.CountY = MapperFixSettings.DummyCountY;
		val2.ScansPerUpdate = 4;
		val2.ParticleLifeTime = MapperFixSettings.DummyParticleLifeTime;
		val2.ParticleLifeTimeResource = MapperFixSettings.DummyParticleLifeTime;
		val.transform.position = new Vector3(0f, -10000f, 0f);
		((Behaviour)val2).enabled = false;
		return val;
	}

	private static GameObject BuildDummyScanPoint()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("DummyMapperScanPoint");
		MapperDataScanPoint val2 = ((Il2CppObjectBase)val.AddComponent(Il2CppType.Of<MapperDataScanPoint>())).Cast<MapperDataScanPoint>();
		ParticleSystem val3 = val.AddComponent<ParticleSystem>();
		val3.Stop(true, (ParticleSystemStopBehavior)0);
		EmissionModule emission = val3.emission;
		emission.enabled = false;
		emission.rateOverTime = MinMaxCurve.op_Implicit(0f);
		val2.m_particleSystem = val3;
		val.transform.position = new Vector3(0f, -10000f, 0f);
		((Behaviour)val2).enabled = false;
		return val;
	}
}
[HarmonyPatch(typeof(MapperDataCloudManager), "Setup")]
public class MapperDataCloudManagerSNetDiagPatch
{
	private static bool s_alreadyLogged;

	[HarmonyPostfix]
	private static void Postfix(MapperDataCloudManager __instance)
	{
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Expected O, but got Unknown
		//IL_035b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0362: Expected O, but got Unknown
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Expected O, but got Unknown
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Expected O, but got Unknown
		if (s_alreadyLogged)
		{
			return;
		}
		s_alreadyLogged = true;
		try
		{
			object spawnMapperDataCloud = __instance.m_spawnMapperDataCloud;
			if (spawnMapperDataCloud == null)
			{
				MapperFixPlugin.Log.LogWarning((object)"[SNetDiag] m_spawnMapperDataCloud is null at Setup time.");
				return;
			}
			Type type = spawnMapperDataCloud.GetType();
			MapperFixPlugin.Log.LogInfo((object)("[SNetDiag] broadcastAction runtime type: " + type.FullName));
			FieldInfo fieldInfo = null;
			Type type2 = type;
			while (type2 != null && fieldInfo == null)
			{
				fieldInfo = type2.GetField("m_packet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				type2 = type2.BaseType;
			}
			object obj = null;
			if (fieldInfo != null)
			{
				obj = fieldInfo.GetValue(spawnMapperDataCloud);
				MapperFixPlugin.Log.LogInfo((object)"[SNetDiag] found m_packet via FIELD.");
			}
			else
			{
				PropertyInfo propertyInfo = null;
				type2 = type;
				while (type2 != null && propertyInfo == null)
				{
					propertyInfo = type2.GetProperty("m_packet", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					type2 = type2.BaseType;
				}
				if (propertyInfo != null)
				{
					obj = propertyInfo.GetValue(spawnMapperDataCloud);
					MapperFixPlugin.Log.LogInfo((object)"[SNetDiag] found m_packet via PROPERTY.");
				}
			}
			bool flag = default(bool);
			if (obj == null)
			{
				MapperFixPlugin.Log.LogWarning((object)"[SNetDiag] m_packet not found directly. Dumping all members instead:");
				type2 = type;
				while (type2 != null)
				{
					ManualLogSource log = MapperFixPlugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(28, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SNetDiag] -- members of ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(type2.FullName);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" --");
					}
					log.LogInfo(val);
					FieldInfo[] fields = type2.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (FieldInfo fieldInfo2 in fields)
					{
						ManualLogSource log2 = MapperFixPlugin.Log;
						val = new BepInExInfoLogInterpolatedStringHandler(19, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SNetDiag] field: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fieldInfo2.FieldType.Name);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fieldInfo2.Name);
						}
						log2.LogInfo(val);
					}
					PropertyInfo[] properties = type2.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (PropertyInfo propertyInfo2 in properties)
					{
						ManualLogSource log3 = MapperFixPlugin.Log;
						val = new BepInExInfoLogInterpolatedStringHandler(22, 2, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SNetDiag] property: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(propertyInfo2.PropertyType.Name);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(propertyInfo2.Name);
						}
						log3.LogInfo(val);
					}
					type2 = type2.BaseType;
				}
				return;
			}
			Type type3 = obj.GetType();
			MapperFixPlugin.Log.LogInfo((object)("[SNetDiag] packet runtime type: " + type3.FullName));
			MethodInfo[] methods = type3.GetMethods(BindingFlags.Instance | BindingFlags.Public);
			MethodInfo[] array = methods;
			foreach (MethodInfo methodInfo in array)
			{
				ParameterInfo[] parameters = methodInfo.GetParameters();
				string text = string.Join(", ", Array.ConvertAll(parameters, (ParameterInfo p) => p.ParameterType.Name + " " + p.Name));
				ManualLogSource log4 = MapperFixPlugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(32, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[SNetDiag] packet method: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodInfo.Name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("(");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") -> ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(methodInfo.ReturnType.Name);
				}
				log4.LogInfo(val);
			}
		}
		catch (Exception ex)
		{
			MapperFixPlugin.Log.LogError((object)("[SNetDiag] threw: " + ex));
		}
	}
}
[HarmonyPatch(typeof(MapperDataCloudManager), "WantSpawnMapperDataCloud")]
public class MapperDataCloudManagerWantSpawnPatch
{
	[HarmonyPrefix]
	private static void Prefix(int playerID, ref float cloudDepth)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Expected O, but got Unknown
		if (!ChargeRatioRelay.TryConsume(playerID, out var ratio))
		{
			return;
		}
		cloudDepth = ratio;
		if (MapperFixSettings.VerboseLogging)
		{
			ManualLogSource log = MapperFixPlugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(46, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[ChargeRelay] Overwrote cloudDepth with ratio=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(ratio, "F2");
			}
			log.LogInfo(val);
		}
	}
}
[HarmonyPatch(typeof(MapperDataCloudScanner), "Scan")]
public class MapperDataCloudScannerGatePatch
{
	[HarmonyPrefix]
	private static bool Prefix(MapperDataCloudScanner __instance, int scanDepthStep)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: Expected O, but got Unknown
		bool flag = MapperFixPlugin.IsTargetGear(__instance);
		if (flag && scanDepthStep == 0)
		{
			MapperTool parentTool = __instance.m_parentTool;
			bool flag2 = default(bool);
			if ((Object)(object)parentTool != (Object)null && MapperFixSettings.VerboseLogging)
			{
				ManualLogSource log = MapperFixPlugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(116, 5, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[ChargeFields RAW] m_currentChargeUp=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(parentTool.m_currentChargeUp);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m_lastFireChargeUp=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(parentTool.m_lastFireChargeUp);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m_chargeUpMaxTime=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(parentTool.m_chargeUpMaxTime);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("m_minChargeUpToFire=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(parentTool.m_minChargeUpToFire);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ScanStepsToMaxDis=");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(__instance.ScanStepsToMaxDis);
				}
				log.LogInfo(val);
			}
			if ((Object)(object)parentTool != (Object)null && MapperFixSettings.EnableChargeBasedScaling)
			{
				float num = Mathf.Clamp01(parentTool.m_lastFireChargeUp);
				int playerSlotIndex = ((Item)parentTool).Owner.PlayerSlotIndex;
				ChargeRatioRelay.Stash(playerSlotIndex, num);
				if (MapperFixSettings.VerboseLogging)
				{
					ManualLogSource log2 = MapperFixPlugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(40, 2, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[LocalCharge] m_lastFireChargeUp=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(parentTool.m_lastFireChargeUp);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ratio=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F2");
					}
					log2.LogInfo(val);
				}
			}
		}
		return flag;
	}
}
[HarmonyPatch(typeof(MapperDataCloud), "ScanParticle")]
public class MapperDataCloudScanParticlePatch
{
	[HarmonyPrefix]
	private static void Prefix(MapperDataCloud __instance, int index)
	{
		if (__instance.m_currentIndex <= index)
		{
			__instance.m_currentIndex = index + 1;
		}
	}

	[HarmonyFinalizer]
	private static Exception Finalizer(Exception __exception)
	{
		return null;
	}
}
[BepInPlugin("DarkEmperor.mapperfix", "Mapper Cloud Fix", "1.0.0")]
public class MapperFixPlugin : BasePlugin
{
	public static GameObject CachedCloudTemplate;

	public static GameObject CachedScanPointTemplate;

	private static AssetBundle s_cachedBundle;

	private static GameObject s_cachedXraysPrefab;

	internal static ManualLogSource Log = Logger.CreateLogSource("MapperFix");

	private FileSystemWatcher _configWatcher;

	private static DateTime s_lastReloadUtc = DateTime.MinValue;

	public override void Load()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Expected O, but got Unknown
		MapperFixSettings.LoadOrCreate();
		SetupConfigHotReload();
		Harmony val = new Harmony("DarkEmperor.mapperfix");
		try
		{
			val.PatchAll(Assembly.GetExecutingAssembly());
		}
		catch (Exception ex)
		{
			Log.LogError((object)("PatchAll threw: " + ex));
		}
		foreach (MethodBase patchedMethod in val.GetPatchedMethods())
		{
			Log.LogInfo((object)("Patched: " + patchedMethod.DeclaringType?.ToString() + "." + patchedMethod.Name));
		}
		ManualLogSource log = Log;
		bool flag = default(bool);
		BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(35, 1, ref flag);
		if (flag)
		{
			((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Mapper cloud fix loaded. Settings: ");
			((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(MapperFixSettings.FilePath);
		}
		log.LogInfo(val2);
	}

	private void SetupConfigHotReload()
	{
		try
		{
			string directoryName = Path.GetDirectoryName(MapperFixSettings.FilePath);
			string fileName = Path.GetFileName(MapperFixSettings.FilePath);
			_configWatcher = new FileSystemWatcher(directoryName, fileName);
			_configWatcher.NotifyFilter = NotifyFilters.LastWrite;
			_configWatcher.Changed += OnConfigFileChanged;
			_configWatcher.EnableRaisingEvents = true;
			Log.LogInfo((object)"Config hot-reload enabled — settings.jsonc 파일을 저장하면 즉시 반영됩니다.");
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("Failed to set up config hot-reload: " + ex.Message));
		}
	}

	private void OnConfigFileChanged(object sender, FileSystemEventArgs e)
	{
		DateTime utcNow = DateTime.UtcNow;
		if ((utcNow - s_lastReloadUtc).TotalMilliseconds < 500.0)
		{
			return;
		}
		s_lastReloadUtc = utcNow;
		Thread.Sleep(150);
		try
		{
			MapperFixSettings.Load();
			Log.LogInfo((object)"settings.jsonc hot-reloaded from disk.");
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("settings.jsonc reload failed: " + ex.Message));
		}
	}

	public static AssetBundle FindLoadedBundle(string nameContains)
	{
		Il2CppReferenceArray<Object> val = Resources.FindObjectsOfTypeAll(Il2CppType.Of<AssetBundle>());
		for (int i = 0; i < ((Il2CppArrayBase<Object>)(object)val).Length; i++)
		{
			Object val2 = ((Il2CppArrayBase<Object>)(object)val)[i];
			if (!(val2 == (Object)null))
			{
				AssetBundle val3 = ((Il2CppObjectBase)val2).Cast<AssetBundle>();
				if ((Object)(object)val3 != (Object)null && ((Object)val3).name.ToLower().Contains(nameContains.ToLower()))
				{
					return val3;
				}
			}
		}
		return null;
	}

	public static bool IsTargetGear(MapperDataCloudScanner scanner)
	{
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Expected O, but got Unknown
		try
		{
			MapperTool parentTool = scanner.m_parentTool;
			if ((Object)(object)parentTool == (Object)null)
			{
				Log.LogWarning((object)"IsTargetGear: m_parentTool is null, allowing by default.");
				return true;
			}
			GearCategoryDataBlock gearCategoryData = ((ItemEquippable)parentTool).GearCategoryData;
			if (gearCategoryData == null)
			{
				Log.LogWarning((object)"IsTargetGear: GearCategoryData is null, allowing by default.");
				return true;
			}
			if (TryGetPersistentID(gearCategoryData, out var persistentID))
			{
				bool flag = persistentID == MapperFixSettings.TargetGearPersistentID;
				if (MapperFixSettings.VerboseLogging)
				{
					ManualLogSource log = Log;
					bool flag2 = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 3, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[IsTargetGear] found persistentID=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(persistentID);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", target=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(MapperFixSettings.TargetGearPersistentID);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", match=");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(flag);
					}
					log.LogInfo(val);
				}
				return flag;
			}
			Log.LogWarning((object)"IsTargetGear: couldn't read persistentID, allowing by default.");
			return true;
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("IsTargetGear check threw: " + ex));
			return true;
		}
	}

	private static bool TryGetPersistentID(object dataBlock, out uint persistentID)
	{
		persistentID = 0u;
		if (dataBlock == null)
		{
			return false;
		}
		try
		{
			Type type = dataBlock.GetType();
			PropertyInfo propertyInfo = type.GetProperty("persistentID") ?? type.GetProperty("PersistentID") ?? type.GetProperty("PersistentId");
			if (propertyInfo != null)
			{
				persistentID = Convert.ToUInt32(propertyInfo.GetValue(dataBlock));
				return true;
			}
			FieldInfo fieldInfo = type.GetField("persistentID") ?? type.GetField("PersistentID");
			if (fieldInfo != null)
			{
				persistentID = Convert.ToUInt32(fieldInfo.GetValue(dataBlock));
				return true;
			}
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("TryGetPersistentID reflection failed: " + ex.Message));
		}
		return false;
	}

	public static void SpawnXRayEffectAt(Vector3 pos, Quaternion rot, float? chargeRatio = null)
	{
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Expected O, but got Unknown
		//IL_0321: Unknown result type (might be due to invalid IL or missing references)
		//IL_0328: Expected O, but got Unknown
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0353: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)s_cachedXraysPrefab == (Object)null)
		{
			if ((Object)(object)s_cachedBundle == (Object)null)
			{
				s_cachedBundle = FindLoadedBundle(MapperFixSettings.BundleNameFilter);
				if ((Object)(object)s_cachedBundle == (Object)null)
				{
					Log.LogWarning((object)"Bundle not loaded, can't spawn XRay effect.");
					return;
				}
			}
			Object obj = s_cachedBundle.LoadAsset(MapperFixSettings.XraysPrefabPath, Il2CppType.Of<GameObject>());
			s_cachedXraysPrefab = ((obj != null) ? ((Il2CppObjectBase)obj).Cast<GameObject>() : null);
			if ((Object)(object)s_cachedXraysPrefab == (Object)null)
			{
				Log.LogWarning((object)"xrays.prefab not found in bundle.");
				return;
			}
		}
		GameObject val = Object.Instantiate<GameObject>(s_cachedXraysPrefab, pos, rot);
		((Object)val).name = "XRayEffect_Live";
		Il2CppReferenceArray<Component> componentsInChildren = val.GetComponentsInChildren(Il2CppType.Of<LineRenderer>());
		for (int i = 0; i < ((Il2CppArrayBase<Component>)(object)componentsInChildren).Length; i++)
		{
			Component obj2 = ((Il2CppArrayBase<Component>)(object)componentsInChildren)[i];
			LineRenderer val2 = ((obj2 != null) ? ((Il2CppObjectBase)obj2).Cast<LineRenderer>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				((Renderer)val2).enabled = false;
			}
		}
		Component component = val.GetComponent(Il2CppType.Of<XRays>());
		XRays xraysComp = ((component != null) ? ((Il2CppObjectBase)component).Cast<XRays>() : null);
		if (MapperFixSettings.EnableXRaysCustomization)
		{
			ApplyXRaysCustomization(val);
		}
		bool flag = default(bool);
		if (MapperFixSettings.EnableChargeBasedScaling && (Object)(object)xraysComp != (Object)null && chargeRatio.HasValue)
		{
			float value = chargeRatio.Value;
			float range = Mathf.Lerp(MapperFixSettings.MinRangeAtNoCharge, MapperFixSettings.MaxRangeAtFullCharge, value);
			float square = Mathf.Lerp(MapperFixSettings.MinSquareAtNoCharge, MapperFixSettings.MaxSquareAtFullCharge, value);
			float fov = Mathf.Lerp(MapperFixSettings.MinFieldOfViewAtNoCharge, MapperFixSettings.MaxFieldOfViewAtFullCharge, value);
			TrySet(delegate
			{
				xraysComp.maxDistance = range;
			}, "XRays.maxDistance (charge scaling)");
			TrySet(delegate
			{
				xraysComp.square = square;
			}, "XRays.square (charge scaling)");
			TrySet(delegate
			{
				xraysComp.fieldOfView = fov;
			}, "XRays.fieldOfView (charge scaling)");
			if (MapperFixSettings.VerboseLogging)
			{
				ManualLogSource log = Log;
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(42, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[ChargeScaling] ratio=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(value, "F2");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" range=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(range, "F1");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" square=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(square, "F2");
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" fov=");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(fov, "F1");
				}
				log.LogInfo(val3);
			}
		}
		float emitDuration = MapperFixSettings.EmitDuration;
		if ((Object)(object)xraysComp != (Object)null)
		{
			Object.Destroy((Object)(object)xraysComp, emitDuration);
		}
		Object.Destroy((Object)(object)val, emitDuration + MapperFixSettings.CleanupSafetyBuffer);
		if (MapperFixSettings.VerboseLogging)
		{
			ManualLogSource log2 = Log;
			BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(33, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Spawned xrays.prefab at pos=");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Vector3>(pos);
				((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" rot=");
				((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<Vector3>(((Quaternion)(ref rot)).eulerAngles);
			}
			log2.LogInfo(val3);
		}
	}

	private static void ApplyXRaysCustomization(GameObject instance)
	{
		Component component = instance.GetComponent(Il2CppType.Of<XRays>());
		XRays xraysComp = ((component != null) ? ((Il2CppObjectBase)component).Cast<XRays>() : null);
		if ((Object)(object)xraysComp != (Object)null)
		{
			TrySet(delegate
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				xraysComp.scanMode = ParseEnum<ScanMode>(MapperFixSettings.ScanMode, (ScanMode)0);
			}, "XRays.scanMode");
			TrySet(delegate
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				xraysComp.scanDirection = ParseEnum<ScanDirection>(MapperFixSettings.ScanDirection, (ScanDirection)0);
			}, "XRays.scanDirection");
			TrySet(delegate
			{
				xraysComp.swipeSpeed = MapperFixSettings.SwipeSpeed;
			}, "XRays.swipeSpeed");
			TrySet(delegate
			{
				xraysComp.raysPerSecond = MapperFixSettings.RaysPerSecond;
			}, "XRays.raysPerSecond");
			TrySet(delegate
			{
				xraysComp.fieldOfView = MapperFixSettings.FieldOfView;
			}, "XRays.fieldOfView");
			TrySet(delegate
			{
				xraysComp.fieldOfViewFocused = MapperFixSettings.FieldOfViewFocused;
			}, "XRays.fieldOfViewFocused");
			TrySet(delegate
			{
				xraysComp.square = MapperFixSettings.Square;
			}, "XRays.square");
			TrySet(delegate
			{
				xraysComp.maxDistance = MapperFixSettings.MaxDistance;
			}, "XRays.maxDistance");
			TrySet(delegate
			{
				xraysComp.forwardStepSize = MapperFixSettings.ForwardStepSize;
			}, "XRays.forwardStepSize");
			TrySet(delegate
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				xraysComp.defaultColor = MapperFixSettings.ParseColor(MapperFixSettings.DefaultColor);
			}, "XRays.defaultColor");
			TrySet(delegate
			{
				xraysComp.defaultSize = MapperFixSettings.DefaultSize;
			}, "XRays.defaultSize");
			TrySet(delegate
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				xraysComp.enemyColor = MapperFixSettings.ParseColor(MapperFixSettings.EnemyColor);
			}, "XRays.enemyColor");
			TrySet(delegate
			{
				xraysComp.enemySize = MapperFixSettings.EnemySize;
			}, "XRays.enemySize");
			TrySet(delegate
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				xraysComp.interactionColor = MapperFixSettings.ParseColor(MapperFixSettings.InteractionColor);
			}, "XRays.interactionColor");
			TrySet(delegate
			{
				xraysComp.interactionSize = MapperFixSettings.InteractionSize;
			}, "XRays.interactionSize");
		}
		Component componentInChildren = instance.GetComponentInChildren(Il2CppType.Of<XRayRenderer>());
		XRayRenderer rendererComp = ((componentInChildren != null) ? ((Il2CppObjectBase)componentInChildren).Cast<XRayRenderer>() : null);
		if (!((Object)(object)rendererComp != (Object)null))
		{
			return;
		}
		TrySet(delegate
		{
			rendererComp.castShadows = MapperFixSettings.CastShadows;
		}, "XRayRenderer.castShadows");
		TrySet(delegate
		{
			rendererComp.updateBounds = MapperFixSettings.UpdateBounds;
		}, "XRayRenderer.updateBounds");
		TrySet(delegate
		{
			rendererComp.alignToView = MapperFixSettings.AlignToView;
		}, "XRayRenderer.alignToView");
		TrySet(delegate
		{
			rendererComp.alignToVelocity = MapperFixSettings.AlignToVelocity;
		}, "XRayRenderer.alignToVelocity");
		TrySet(delegate
		{
			rendererComp.range = MapperFixSettings.Range;
		}, "XRayRenderer.range");
		TrySet(delegate
		{
			rendererComp.mode = MapperFixSettings.RendererMode;
		}, "XRayRenderer.mode");
		TrySet(delegate
		{
			rendererComp.duration = MapperFixSettings.Duration;
		}, "XRayRenderer.duration");
		TrySet(delegate
		{
			rendererComp.timescale = MapperFixSettings.Timescale;
		}, "XRayRenderer.timescale");
		TrySet(delegate
		{
			rendererComp.playOnAwake = MapperFixSettings.PlayOnAwake;
		}, "XRayRenderer.playOnAwake");
		TrySet(delegate
		{
			rendererComp.loop = MapperFixSettings.Loop;
		}, "XRayRenderer.loop");
		TrySet(delegate
		{
			rendererComp.simulateInPlayer = MapperFixSettings.SimulateInPlayer;
		}, "XRayRenderer.simulateInPlayer");
		if (MapperFixSettings.InstanceCount >= 0)
		{
			TrySet(delegate
			{
				rendererComp.instanceCount = MapperFixSettings.InstanceCount;
			}, "XRayRenderer.instanceCount");
		}
	}

	private static T ParseEnum<T>(string value, T fallback) where T : struct
	{
		T result;
		return Enum.TryParse<T>(value, ignoreCase: true, out result) ? result : fallback;
	}

	private static void TrySet(Action setter, string fieldName)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		try
		{
			setter();
		}
		catch (Exception ex)
		{
			if (MapperFixSettings.VerboseLogging)
			{
				ManualLogSource log = Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(16, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to set ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(fieldName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
		}
	}
}
public static class MapperFixSettings
{
	public static float EmitDuration = 2f;

	public static float CleanupSafetyBuffer = 5f;

	public static float DeactivatingTimeout = 3f;

	public static int DummyCountX = 4;

	public static int DummyCountY = 4;

	public static float DummyParticleLifeTime = 0.5f;

	public static string BundleNameFilter = "xrays";

	public static string XraysPrefabPath = "Assets/XRays/XRays.prefab";

	public static bool VerboseLogging = false;

	public static uint TargetGearPersistentID = 10u;

	public static float SequenceCooldown = 1.5f;

	public static bool EnableXRaysCustomization = false;

	public static bool EnableChargeBasedScaling = false;

	public static float MinRangeAtNoCharge = 10f;

	public static float MaxRangeAtFullCharge = 30f;

	public static float MinSquareAtNoCharge = 0.3f;

	public static float MaxSquareAtFullCharge = 1f;

	public static float MinFieldOfViewAtNoCharge = 20f;

	public static float MaxFieldOfViewAtFullCharge = 60f;

	public static string ScanMode = "Random";

	public static string ScanDirection = "X";

	public static float SwipeSpeed = 4f;

	public static int RaysPerSecond = 10000;

	public static float FieldOfView = 55f;

	public static float FieldOfViewFocused = 15f;

	public static float Square = 0.2f;

	public static float MaxDistance = 20f;

	public static float ForwardStepSize = 3f;

	public static string DefaultColor = "0,1,0.972549,0.16";

	public static float DefaultSize = 1f;

	public static string EnemyColor = "1,0,0,0.501";

	public static float EnemySize = 1f;

	public static string InteractionColor = "1,0.490196,0,0.078";

	public static float InteractionSize = 1f;

	public static bool CastShadows = false;

	public static bool UpdateBounds = false;

	public static bool AlignToView = true;

	public static bool AlignToVelocity = false;

	public static float Range = 50f;

	public static int RendererMode = 0;

	public static float Duration = 5f;

	public static float Timescale = 1f;

	public static bool PlayOnAwake = false;

	public static bool Loop = false;

	public static bool SimulateInPlayer = true;

	public static int InstanceCount = -1;

	private static readonly Regex LinePattern = new Regex("^\\s*\"(?<key>\\w+)\"\\s*:\\s*(?<value>\"(?:[^\"\\\\]|\\\\.)*\"|true|false|-?\\d+(?:\\.\\d+)?)\\s*,?\\s*$", RegexOptions.Compiled);

	public static string FilePath { get; private set; }

	public static void LoadOrCreate()
	{
		string text;
		if (MTFOPathAPI.HasCustomPath)
		{
			text = Path.Combine(MTFOPathAPI.CustomPath, "mapper");
			MapperFixPlugin.Log.LogInfo((object)("Using MTFO custom path: " + MTFOPathAPI.CustomPath));
		}
		else
		{
			text = Path.Combine(Paths.ConfigPath, "custom", "mapper");
			MapperFixPlugin.Log.LogWarning((object)("MTFOPathAPI.HasCustomPath is false. Falling back to: " + text));
		}
		Directory.CreateDirectory(text);
		FilePath = Path.Combine(text, "mappersettings.jsonc");
		if (File.Exists(FilePath))
		{
			Load();
		}
		else
		{
			Save();
		}
	}

	public static void Load()
	{
		if (FilePath != null && File.Exists(FilePath))
		{
			Dictionary<string, string> values = ParseJsonc(File.ReadAllText(FilePath));
			EmitDuration = GetFloat(values, "EmitDuration", EmitDuration);
			CleanupSafetyBuffer = GetFloat(values, "CleanupSafetyBuffer", CleanupSafetyBuffer);
			DeactivatingTimeout = GetFloat(values, "DeactivatingTimeout", DeactivatingTimeout);
			DummyCountX = GetInt(values, "DummyCountX", DummyCountX);
			DummyCountY = GetInt(values, "DummyCountY", DummyCountY);
			DummyParticleLifeTime = GetFloat(values, "DummyParticleLifeTime", DummyParticleLifeTime);
			BundleNameFilter = GetString(values, "BundleNameFilter", BundleNameFilter);
			XraysPrefabPath = GetString(values, "XraysPrefabPath", XraysPrefabPath);
			VerboseLogging = GetBool(values, "VerboseLogging", VerboseLogging);
			TargetGearPersistentID = (uint)GetInt(values, "TargetGearPersistentID", (int)TargetGearPersistentID);
			SequenceCooldown = GetFloat(values, "SequenceCooldown", SequenceCooldown);
			EnableXRaysCustomization = GetBool(values, "EnableXRaysCustomization", EnableXRaysCustomization);
			EnableChargeBasedScaling = GetBool(values, "EnableChargeBasedScaling", EnableChargeBasedScaling);
			MinRangeAtNoCharge = GetFloat(values, "MinRangeAtNoCharge", MinRangeAtNoCharge);
			MaxRangeAtFullCharge = GetFloat(values, "MaxRangeAtFullCharge", MaxRangeAtFullCharge);
			MinSquareAtNoCharge = GetFloat(values, "MinSquareAtNoCharge", MinSquareAtNoCharge);
			MaxSquareAtFullCharge = GetFloat(values, "MaxSquareAtFullCharge", MaxSquareAtFullCharge);
			MinFieldOfViewAtNoCharge = GetFloat(values, "MinFieldOfViewAtNoCharge", MinFieldOfViewAtNoCharge);
			MaxFieldOfViewAtFullCharge = GetFloat(values, "MaxFieldOfViewAtFullCharge", MaxFieldOfViewAtFullCharge);
			ScanMode = GetString(values, "ScanMode", ScanMode);
			ScanDirection = GetString(values, "ScanDirection", ScanDirection);
			SwipeSpeed = GetFloat(values, "SwipeSpeed", SwipeSpeed);
			RaysPerSecond = GetInt(values, "RaysPerSecond", RaysPerSecond);
			FieldOfView = GetFloat(values, "FieldOfView", FieldOfView);
			FieldOfViewFocused = GetFloat(values, "FieldOfViewFocused", FieldOfViewFocused);
			Square = GetFloat(values, "Square", Square);
			MaxDistance = GetFloat(values, "MaxDistance", MaxDistance);
			ForwardStepSize = GetFloat(values, "ForwardStepSize", ForwardStepSize);
			DefaultColor = GetString(values, "DefaultColor", DefaultColor);
			DefaultSize = GetFloat(values, "DefaultSize", DefaultSize);
			EnemyColor = GetString(values, "EnemyColor", EnemyColor);
			EnemySize = GetFloat(values, "EnemySize", EnemySize);
			InteractionColor = GetString(values, "InteractionColor", InteractionColor);
			InteractionSize = GetFloat(values, "InteractionSize", InteractionSize);
			CastShadows = GetBool(values, "CastShadows", CastShadows);
			UpdateBounds = GetBool(values, "UpdateBounds", UpdateBounds);
			AlignToView = GetBool(values, "AlignToView", AlignToView);
			AlignToVelocity = GetBool(values, "AlignToVelocity", AlignToVelocity);
			Range = GetFloat(values, "Range", Range);
			RendererMode = GetInt(values, "RendererMode", RendererMode);
			Duration = GetFloat(values, "Duration", Duration);
			Timescale = GetFloat(values, "Timescale", Timescale);
			PlayOnAwake = GetBool(values, "PlayOnAwake", PlayOnAwake);
			Loop = GetBool(values, "Loop", Loop);
			SimulateInPlayer = GetBool(values, "SimulateInPlayer", SimulateInPlayer);
			InstanceCount = GetInt(values, "InstanceCount", InstanceCount);
		}
	}

	public static void Save()
	{
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.AppendLine("{");
		AppendSectionHeader(stringBuilder, "Identity");
		AppendField(stringBuilder, "TargetGearPersistentID", (int)TargetGearPersistentID, "Works only when fired from the Gear with this persistentID (default 10 = Mapper)");
		AppendSectionHeader(stringBuilder, "Advanced");
		AppendField(stringBuilder, "BundleNameFilter", BundleNameFilter, "Search keyword for the name of the AssetBundle containing xrays.prefab");
		AppendField(stringBuilder, "XraysPrefabPath", XraysPrefabPath, "The exact path to xrays.prefab in the bundle");
		AppendSectionHeader(stringBuilder, "Effect");
		AppendField(stringBuilder, "EmitDuration", EmitDuration, "Time (seconds) during which the xrays effect continues to shoot new particles when the mapper is fired");
		AppendField(stringBuilder, "CleanupSafetyBuffer", CleanupSafetyBuffer, "Additional waiting time (in seconds) after EmitDuration until the object is completely destroyed");
		AppendField(stringBuilder, "SequenceCooldown", SequenceCooldown, "If the same player signal arrives again within this time (seconds), it is considered the same firing sequence and does not respawn.");
		AppendSectionHeader(stringBuilder, "ChargeBasedScaling");
		AppendField(stringBuilder, "EnableChargeBasedScaling", EnableChargeBasedScaling, "Whether to adjust range/area proportional to charge amount (number of scan steps). Accurately reflected only on the shooter's own screen (remote players may see the default value).");
		AppendField(stringBuilder, "MinRangeAtNoCharge", MinRangeAtNoCharge, "Range (maxDistance) when charge is 0%");
		AppendField(stringBuilder, "MaxRangeAtFullCharge", MaxRangeAtFullCharge, "Range (maxDistance) when charged to 100%");
		AppendField(stringBuilder, "MinSquareAtNoCharge", MinSquareAtNoCharge, "Scan range ratio at 0% charge (square, 0~1)");
		AppendField(stringBuilder, "MaxSquareAtFullCharge", MaxSquareAtFullCharge, "Scan range ratio at 100% charge (square, 0~1)");
		AppendField(stringBuilder, "MinFieldOfViewAtNoCharge", MinFieldOfViewAtNoCharge, "Scan field of view (fieldOfView, 0~90) when charge is 0%");
		AppendField(stringBuilder, "MaxFieldOfViewAtFullCharge", MaxFieldOfViewAtFullCharge, "Scan field of view (fieldOfView, 0~90) when charge is 0%");
		AppendSectionHeader(stringBuilder, "XRaysCustomization");
		AppendField(stringBuilder, "EnableXRaysCustomization", EnableXRaysCustomization, "It must be true for the XRays/XRayRenderer settings below to be actually applied (if false, the original prefab is used).");
		AppendSectionHeader(stringBuilder, "XRays");
		AppendField(stringBuilder, "ScanMode", ScanMode, "ScanMode: Random / SwipeLoop / SwipePingPong");
		AppendField(stringBuilder, "ScanDirection", ScanDirection, "ScanDirection: X / Y");
		AppendField(stringBuilder, "SwipeSpeed", SwipeSpeed, "SwipeSpeed");
		AppendField(stringBuilder, "RaysPerSecond", RaysPerSecond, "Number of rays fired per second");
		AppendField(stringBuilder, "FieldOfView", FieldOfView, "Scan field of view (0~90)");
		AppendField(stringBuilder, "FieldOfViewFocused", FieldOfViewFocused, "Narrowing field of view when aiming (0~90)");
		AppendField(stringBuilder, "Square", Square, "Scan range aspect ratio correction (0~1)");
		AppendField(stringBuilder, "MaxDistance", MaxDistance, "Maximum scan distance");
		AppendField(stringBuilder, "ForwardStepSize", ForwardStepSize, "Forward scan step interval");
		AppendField(stringBuilder, "DefaultColor", DefaultColor, "General surface particle color \"R,G,B,A\" (0~1)");
		AppendField(stringBuilder, "DefaultSize", DefaultSize, "General surface particle size");
		AppendField(stringBuilder, "EnemyColor", EnemyColor, "Enemy indicator particle color \"R,G,B,A\"");
		AppendField(stringBuilder, "EnemySize", EnemySize, "Enemy display particle size");
		AppendField(stringBuilder, "InteractionColor", InteractionColor, "Interaction object display color \"R,G,B,A\"");
		AppendField(stringBuilder, "InteractionSize", InteractionSize, "Interaction object display size");
		AppendSectionHeader(stringBuilder, "XRayRenderer");
		AppendField(stringBuilder, "CastShadows", CastShadows, "Whether or not to have particle shadows");
		AppendField(stringBuilder, "UpdateBounds", UpdateBounds, "Whether to update rendering bounds every frame");
		AppendField(stringBuilder, "AlignToView", AlignToView, "Whether the billboard is always aligned facing the camera");
		AppendField(stringBuilder, "AlignToVelocity", AlignToVelocity, "Whether to draw by stretching in the direction of movement");
		AppendField(stringBuilder, "Range", Range, "Maximum rendering range");
		AppendField(stringBuilder, "RendererMode", RendererMode, "Internal rendering mode value (default recommended)");
		AppendField(stringBuilder, "Duration", Duration, "Total effect duration (seconds)");
		AppendField(stringBuilder, "Timescale", Timescale, "Effect playback speed scale");
		AppendField(stringBuilder, "PlayOnAwake", PlayOnAwake, "Whether to autoplay immediately after creation");
		AppendField(stringBuilder, "Loop", Loop, "Loop");
		AppendField(stringBuilder, "SimulateInPlayer", SimulateInPlayer, "Whether to simulate based on the player's perspective");
		AppendField(stringBuilder, "InstanceCount", InstanceCount, "Force number of instances (-1 means not applied)");
		AppendSectionHeader(stringBuilder, "Performance");
		AppendField(stringBuilder, "DeactivatingTimeout", DeactivatingTimeout, "Wait time (seconds) until forced cleanup when MapperDataCloud dummy is stuck in Deactivating state");
		AppendField(stringBuilder, "DummyCountX", DummyCountX, "Horizontal grid density of crash prevention dummies (lower values \u200b\u200breduce lag)");
		AppendField(stringBuilder, "DummyCountY", DummyCountY, "Vertical grid density of crash prevention dummies (lower values \u200b\u200breduce lag)");
		AppendField(stringBuilder, "DummyParticleLifeTime", DummyParticleLifeTime, "Lifespan (seconds) of crash prevention dummy particles");
		AppendSectionHeader(stringBuilder, "Debug");
		AppendField(stringBuilder, "VerboseLogging", VerboseLogging, "If true, output detailed logs related to spawn/cleanup", isLast: true);
		stringBuilder.AppendLine("}");
		Directory.CreateDirectory(Path.GetDirectoryName(FilePath));
		File.WriteAllText(FilePath, stringBuilder.ToString());
	}

	private static void AppendSectionHeader(StringBuilder sb, string sectionName)
	{
		sb.AppendLine();
		StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(51, 1, sb);
		handler.AppendLiteral("  // ===================== [");
		handler.AppendFormatted(sectionName);
		handler.AppendLiteral("] =====================");
		sb.AppendLine(ref handler);
	}

	public static Color ParseColor(string value)
	{
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			string[] array = value.Split(',');
			if (array.Length >= 3)
			{
				float num = float.Parse(array[0].Trim(), CultureInfo.InvariantCulture);
				float num2 = float.Parse(array[1].Trim(), CultureInfo.InvariantCulture);
				float num3 = float.Parse(array[2].Trim(), CultureInfo.InvariantCulture);
				float num4 = ((array.Length >= 4) ? float.Parse(array[3].Trim(), CultureInfo.InvariantCulture) : 1f);
				return new Color(num, num2, num3, num4);
			}
		}
		catch
		{
		}
		return Color.white;
	}

	private static void AppendField(StringBuilder sb, string key, object value, string comment, bool isLast = false)
	{
		string text;
		string value2;
		if (value is bool flag)
		{
			text = (flag ? "true" : "false");
			value2 = "Boolean";
		}
		else if (value is string text2)
		{
			text = "\"" + text2.Replace("\"", "\\\"") + "\"";
			value2 = "String";
		}
		else if (value is float num)
		{
			text = num.ToString(CultureInfo.InvariantCulture);
			value2 = "Single";
		}
		else
		{
			text = Convert.ToString(value, CultureInfo.InvariantCulture);
			value2 = "Int32";
		}
		StringBuilder stringBuilder = sb;
		StringBuilder stringBuilder2 = stringBuilder;
		StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(5, 1, stringBuilder);
		handler.AppendLiteral("  // ");
		handler.AppendFormatted(comment);
		stringBuilder2.AppendLine(ref handler);
		stringBuilder = sb;
		StringBuilder stringBuilder3 = stringBuilder;
		handler = new StringBuilder.AppendInterpolatedStringHandler(19, 1, stringBuilder);
		handler.AppendLiteral("  // Setting type: ");
		handler.AppendFormatted(value2);
		stringBuilder3.AppendLine(ref handler);
		stringBuilder = sb;
		StringBuilder stringBuilder4 = stringBuilder;
		handler = new StringBuilder.AppendInterpolatedStringHandler(20, 1, stringBuilder);
		handler.AppendLiteral("  // Default value: ");
		handler.AppendFormatted(text.Trim('"'));
		stringBuilder4.AppendLine(ref handler);
		stringBuilder = sb;
		StringBuilder stringBuilder5 = stringBuilder;
		handler = new StringBuilder.AppendInterpolatedStringHandler(6, 3, stringBuilder);
		handler.AppendLiteral("  \"");
		handler.AppendFormatted(key);
		handler.AppendLiteral("\": ");
		handler.AppendFormatted(text);
		handler.AppendFormatted(isLast ? "" : ",");
		stringBuilder5.AppendLine(ref handler);
	}

	private static Dictionary<string, string> ParseJsonc(string text)
	{
		Dictionary<string, string> dictionary = new Dictionary<string, string>();
		string[] array = text.Split('\n');
		foreach (string text2 in array)
		{
			string text3 = text2.Trim();
			if (text3.Length == 0 || text3.StartsWith("//") || text3 == "{" || text3 == "}")
			{
				continue;
			}
			Match match = LinePattern.Match(text3);
			if (match.Success)
			{
				string value = match.Groups["key"].Value;
				string text4 = match.Groups["value"].Value;
				if (text4.StartsWith("\"") && text4.EndsWith("\""))
				{
					text4 = text4.Substring(1, text4.Length - 2).Replace("\\\"", "\"");
				}
				dictionary[value] = text4;
			}
		}
		return dictionary;
	}

	private static string GetString(Dictionary<string, string> values, string key, string fallback)
	{
		string value;
		return values.TryGetValue(key, out value) ? value : fallback;
	}

	private static bool GetBool(Dictionary<string, string> values, string key, bool fallback)
	{
		string value;
		bool result;
		return (values.TryGetValue(key, out value) && bool.TryParse(value, out result)) ? result : fallback;
	}

	private static int GetInt(Dictionary<string, string> values, string key, int fallback)
	{
		string value;
		int result;
		return (values.TryGetValue(key, out value) && int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result)) ? result : fallback;
	}

	private static float GetFloat(Dictionary<string, string> values, string key, float fallback)
	{
		string value;
		float result;
		return (values.TryGetValue(key, out value) && float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out result)) ? result : fallback;
	}
}