Decompiled source of MarkerMod v1.3.1

MarkerMod.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Bifrost.Cooked;
using HarmonyLib;
using MarkerMod;
using MarkerMod.Config;
using MarkerMod.Managers;
using MarkerMod.Services;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using Mimic.Actors;
using MimicAPI.GameAPI;
using ReluProtocol;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "MarkerMod", "1.3.0", "DooDesch", null)]
[assembly: MelonGame("ReLUGames", "MIMESIS")]
[assembly: MelonOptionalDependencies(new string[] { "MimicAPI" })]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MarkerMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.3.1.0")]
[assembly: AssemblyInformationalVersion("1.3.1+4ef3110a75d8c7036021dff97484327dbbeb3d1d")]
[assembly: AssemblyProduct("MarkerMod")]
[assembly: AssemblyTitle("MarkerMod")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 MarkerMod
{
	public class Core : MelonMod
	{
		public override void OnInitializeMelon()
		{
			MarkerPreferences.Initialize();
			((MelonBase)this).HarmonyInstance.PatchAll();
			((MelonBase)this).LoggerInstance.Msg($"MarkerMod initialized. Lifespan={MarkerPreferences.PermanentLifetimeSeconds:F0}s, Footprints={MarkerPreferences.KeepFootprints}, Puddles={MarkerPreferences.KeepPuddles}, InfinitePaintballs={MarkerPreferences.InfinitePaintballs}");
		}
	}
}
namespace MarkerMod.Patches
{
	[HarmonyPatch(typeof(FieldSkillActor), "Spawn")]
	internal static class FieldSkillActorSpawnPatch
	{
		[CompilerGenerated]
		private sealed class <ApplyColorToProjectileCoroutine>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public FieldSkillActor actor;

			public Color color;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ApplyColorToProjectileCoroutine>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if ((Object)(object)actor != (Object)null && (Object)(object)((Component)actor).transform != (Object)null)
					{
						MaterialColorService.ApplyColorToTransform(((Component)actor).transform, color, useDefaultMaterial: false);
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <Transpiler>d__2 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private IEnumerator<CodeInstruction> <>7__wrap1;

			private CodeInstruction <instruction>5__3;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Transpiler>d__2(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 1u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = null;
				<instruction>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>7__wrap1 = instructions.GetEnumerator();
						<>1__state = -3;
						goto IL_00bf;
					case 1:
						<>1__state = -3;
						<instruction>5__3.operand = DestroyOverride;
						goto IL_0099;
					case 2:
						{
							<>1__state = -3;
							<instruction>5__3 = null;
							goto IL_00bf;
						}
						IL_00bf:
						if (<>7__wrap1.MoveNext())
						{
							<instruction>5__3 = <>7__wrap1.Current;
							if (CodeInstructionExtensions.Calls(<instruction>5__3, Destroy2Arg))
							{
								<>2__current = new CodeInstruction(OpCodes.Ldarg_1, (object)null);
								<>1__state = 1;
								return true;
							}
							goto IL_0099;
						}
						<>m__Finally1();
						<>7__wrap1 = null;
						return false;
						IL_0099:
						<>2__current = <instruction>5__3;
						<>1__state = 2;
						return true;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap1 != null)
				{
					<>7__wrap1.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<Transpiler>d__2 <Transpiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<Transpiler>d__ = this;
				}
				else
				{
					<Transpiler>d__ = new <Transpiler>d__2(0);
				}
				<Transpiler>d__.instructions = <>3__instructions;
				return <Transpiler>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		private static readonly MethodInfo Destroy2Arg = AccessTools.Method(typeof(Object), "Destroy", new Type[2]
		{
			typeof(Object),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo DestroyOverride = AccessTools.Method(typeof(PaintPersistenceManager), "DestroyWithOverride", (Type[])null, (Type[])null);

		[IteratorStateMachine(typeof(<Transpiler>d__2))]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Transpiler>d__2(-2)
			{
				<>3__instructions = instructions
			};
		}

		[HarmonyPostfix]
		public static void Postfix(FieldSkillActor __instance, FieldSkillObjectInfo fieldSkillObjectInfo, ref float __result)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			PaintPersistenceManager.TrackDecal(fieldSkillObjectInfo);
			__result = PaintPersistenceManager.OverrideLifetime(fieldSkillObjectInfo, __result);
			if (!MarkerPreferences.EnablePaintballColorChange || fieldSkillObjectInfo == null)
			{
				return;
			}
			try
			{
				if (PaintBallColorManager.IsPaintball(fieldSkillObjectInfo.fieldSkillMasterID) && PaintBallColorManager.HasColorBeenSelected() && (Object)(object)__instance != (Object)null)
				{
					((MonoBehaviour)__instance).StartCoroutine(ApplyColorToProjectileCoroutine(__instance, PaintBallColorManager.GetCurrentColor()));
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[PaintballProjectileColor] Error: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		[IteratorStateMachine(typeof(<ApplyColorToProjectileCoroutine>d__4))]
		private static IEnumerator ApplyColorToProjectileCoroutine(FieldSkillActor actor, Color color)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ApplyColorToProjectileCoroutine>d__4(0)
			{
				actor = actor,
				color = color
			};
		}
	}
	[HarmonyPatch(typeof(GameMainBase), "SpawnFieldSkill")]
	internal static class GameMainBaseSpawnFieldSkillPatch
	{
		[CompilerGenerated]
		private sealed class <Transpiler>d__2 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private IEnumerator<CodeInstruction> <>7__wrap1;

			private CodeInstruction <instruction>5__3;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Transpiler>d__2(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 1u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<>7__wrap1 = null;
				<instruction>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<>7__wrap1 = instructions.GetEnumerator();
						<>1__state = -3;
						goto IL_00bf;
					case 1:
						<>1__state = -3;
						<instruction>5__3.operand = DestroyOverride;
						goto IL_0099;
					case 2:
						{
							<>1__state = -3;
							<instruction>5__3 = null;
							goto IL_00bf;
						}
						IL_00bf:
						if (<>7__wrap1.MoveNext())
						{
							<instruction>5__3 = <>7__wrap1.Current;
							if (CodeInstructionExtensions.Calls(<instruction>5__3, Destroy2Arg))
							{
								<>2__current = new CodeInstruction(OpCodes.Ldarg_1, (object)null);
								<>1__state = 1;
								return true;
							}
							goto IL_0099;
						}
						<>m__Finally1();
						<>7__wrap1 = null;
						return false;
						IL_0099:
						<>2__current = <instruction>5__3;
						<>1__state = 2;
						return true;
					}
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap1 != null)
				{
					<>7__wrap1.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<Transpiler>d__2 <Transpiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<Transpiler>d__ = this;
				}
				else
				{
					<Transpiler>d__ = new <Transpiler>d__2(0);
				}
				<Transpiler>d__.instructions = <>3__instructions;
				return <Transpiler>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		private static readonly MethodInfo Destroy2Arg = AccessTools.Method(typeof(Object), "Destroy", new Type[2]
		{
			typeof(Object),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo DestroyOverride = AccessTools.Method(typeof(PaintPersistenceManager), "DestroyWithOverride", (Type[])null, (Type[])null);

		[IteratorStateMachine(typeof(<Transpiler>d__2))]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Transpiler>d__2(-2)
			{
				<>3__instructions = instructions
			};
		}
	}
	[HarmonyPatch(typeof(WorldDecal), "Activate")]
	internal static class WorldDecalActivatePatch
	{
		[HarmonyPrefix]
		public static void Prefix(WorldDecal __instance)
		{
			if (PaintPersistenceManager.IsPermanentDecal(__instance.decalId))
			{
				__instance.lifetimeMSec = PaintPersistenceManager.PermanentLifetimeMilliseconds;
				__instance.fadeoutMSec = 0L;
			}
		}
	}
	[HarmonyPatch(typeof(DecalData), "CreateDecalData")]
	internal static class DecalDataCreatePatch
	{
		[HarmonyPrefix]
		public static void Prefix(string pathWithSocket, ref string colorId, ref long lifetimeMSec, ref long fadeoutMSec, Transform spawnBase)
		{
			bool flag = !string.IsNullOrEmpty(pathWithSocket) && pathWithSocket.IndexOf("paint", StringComparison.OrdinalIgnoreCase) >= 0;
			bool flag2 = (Object)(object)spawnBase != (Object)null;
			bool flag3 = false;
			if (MarkerPreferences.KeepFootprints && flag2 && flag)
			{
				flag3 = true;
			}
			if (MarkerPreferences.KeepPuddles && !flag2 && flag)
			{
				flag3 = true;
			}
			if (flag3)
			{
				lifetimeMSec = PaintPersistenceManager.PermanentLifetimeMilliseconds;
				fadeoutMSec = 0L;
			}
			if (MarkerPreferences.EnablePaintballColorChange && flag)
			{
				string decalColorIdForCurrentColor = DecalColorService.GetDecalColorIdForCurrentColor();
				if (!string.IsNullOrEmpty(decalColorIdForCurrentColor))
				{
					colorId = decalColorIdForCurrentColor;
				}
			}
		}

		[HarmonyPostfix]
		public static void Postfix(DecalData __result, string pathWithSocket, Transform spawnBase)
		{
			bool flag = !string.IsNullOrEmpty(pathWithSocket) && pathWithSocket.IndexOf("paint", StringComparison.OrdinalIgnoreCase) >= 0;
			bool flag2 = (Object)(object)spawnBase != (Object)null;
			if (MarkerPreferences.KeepFootprints && flag2 && flag && __result != null)
			{
				PaintPersistenceManager.TrackDecalIfNeeded(__result);
			}
		}
	}
	[HarmonyPatch(typeof(EquipmentItemElement), "SetDurability")]
	internal static class EquipmentItemElementSetDurabilityPatch
	{
		private static readonly HashSet<int> PaintballMasterIDs = new HashSet<int> { 2030, 70010, 70011, 70012, 70013, 70014, 70015, 70016, 70017, 70018 };

		[HarmonyPrefix]
		public static bool Prefix(EquipmentItemElement __instance, int durability)
		{
			if (!MarkerPreferences.InfinitePaintballs)
			{
				return true;
			}
			try
			{
				int fieldValue = ReflectionHelper.GetFieldValue<int>((object)__instance, "ItemMasterID");
				if (PaintballMasterIDs.Contains(fieldValue))
				{
					int propertyValue = ReflectionHelper.GetPropertyValue<int>((object)__instance, "RemainDurability");
					if (durability < propertyValue)
					{
						return false;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Warning("[InfinitePaintballs] Error in SetDurability patch: " + ex.Message);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(ProtoActor), "Update")]
	internal static class PaintBallColorUpdatePatch
	{
		private static long lastSelectedItemID = -1L;

		private static bool wasRightMouseButtonPressedLastFrame = false;

		[HarmonyPostfix]
		public static void Postfix(ProtoActor __instance)
		{
			if (!MarkerPreferences.EnablePaintballColorChange)
			{
				return;
			}
			try
			{
				if (!__instance.AmIAvatar())
				{
					return;
				}
				if ((Object)(object)PlayerAPI.GetLocalPlayer() == (Object)null)
				{
					lastSelectedItemID = -1L;
					return;
				}
				object localInventory = PlayerAPI.GetLocalInventory();
				if (localInventory == null)
				{
					lastSelectedItemID = -1L;
					return;
				}
				object propertyValue = ReflectionHelper.GetPropertyValue(localInventory, "SelectedItem");
				if (propertyValue == null)
				{
					if (lastSelectedItemID != -1)
					{
						MelonLogger.Msg("[PaintBallColor] No item selected");
						lastSelectedItemID = -1L;
					}
					return;
				}
				object propertyValue2 = ReflectionHelper.GetPropertyValue(propertyValue, "ItemID");
				object propertyValue3 = ReflectionHelper.GetPropertyValue(propertyValue, "ItemMasterID");
				if (propertyValue2 == null || propertyValue3 == null)
				{
					return;
				}
				long num = Convert.ToInt64(propertyValue2);
				bool flag = PaintBallColorManager.IsPaintball(Convert.ToInt32(propertyValue3));
				if (flag && num != lastSelectedItemID)
				{
					PaintBallColorManager.ResetColorSelection();
					PaintBallColorManager.ApplyColorToPaintball(propertyValue);
					lastSelectedItemID = num;
				}
				else if (!flag && lastSelectedItemID != -1)
				{
					lastSelectedItemID = -1L;
					PaintBallColorManager.ResetColorSelection();
				}
				if (flag)
				{
					Mouse current = Mouse.current;
					if (current != null)
					{
						bool isPressed = current.rightButton.isPressed;
						bool num2 = isPressed && !wasRightMouseButtonPressedLastFrame;
						wasRightMouseButtonPressedLastFrame = isPressed;
						if (num2)
						{
							PaintBallColorManager.CycleColor();
							PaintBallColorManager.ApplyColorToPaintball(propertyValue);
							string currentColorName = PaintBallColorManager.GetCurrentColorName();
							MelonLogger.Msg("[PaintBallColor] Farbe geändert zu: " + currentColorName);
						}
					}
				}
				else
				{
					wasRightMouseButtonPressedLastFrame = false;
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[PaintBallColor] Error: " + ex.Message + "\n" + ex.StackTrace);
			}
		}
	}
}
namespace MarkerMod.Services
{
	internal static class MaterialColorService
	{
		private static readonly Dictionary<string, Material> originalMaterialsCache = new Dictionary<string, Material>();

		internal static void ApplyColorToRenderer(Renderer renderer, Color color, bool useDefaultMaterial)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			if ((Object)(object)renderer == (Object)null)
			{
				return;
			}
			Material[] materials = renderer.materials;
			if (materials == null || materials.Length == 0)
			{
				return;
			}
			for (int i = 0; i < materials.Length; i++)
			{
				if ((Object)(object)materials[i] != (Object)null)
				{
					Material orCacheOriginalMaterial = GetOrCacheOriginalMaterial($"{((Object)renderer).GetInstanceID()}_{i}", materials[i]);
					if (useDefaultMaterial)
					{
						materials[i] = new Material(orCacheOriginalMaterial);
						continue;
					}
					Material val = new Material(orCacheOriginalMaterial);
					ApplyColorToMaterial(val, color);
					materials[i] = val;
				}
			}
			renderer.materials = materials;
		}

		internal static void ApplyColorToTransform(Transform transform, Color color, bool useDefaultMaterial)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)transform == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)transform).GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren != null && componentsInChildren.Length != 0)
			{
				Renderer[] array = componentsInChildren;
				for (int i = 0; i < array.Length; i++)
				{
					ApplyColorToRenderer(array[i], color, useDefaultMaterial);
				}
			}
		}

		private static Material GetOrCacheOriginalMaterial(string materialKey, Material currentMaterial)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			if (!originalMaterialsCache.ContainsKey(materialKey))
			{
				Material val = new Material(currentMaterial);
				if (val.HasProperty("_MainTex") && (Object)(object)val.GetTexture("_MainTex") == (Object)(object)Texture2D.whiteTexture)
				{
					val.SetTexture("_MainTex", (Texture)null);
				}
				if (val.HasProperty("_BaseMap") && (Object)(object)val.GetTexture("_BaseMap") == (Object)(object)Texture2D.whiteTexture)
				{
					val.SetTexture("_BaseMap", (Texture)null);
				}
				originalMaterialsCache[materialKey] = val;
				return val;
			}
			return originalMaterialsCache[materialKey];
		}

		private static void ApplyColorToMaterial(Material material, Color color)
		{
			//IL_0013: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			if (material.HasProperty("_Color"))
			{
				ReplaceTextureWithWhite(material);
				if (IsBlackColor(color))
				{
					material.SetColor("_Color", new Color(0.15f, 0.15f, 0.15f, 1f));
				}
				else
				{
					material.SetColor("_Color", color);
				}
			}
			else if (material.HasProperty("_BaseColor"))
			{
				ReplaceTextureWithWhite(material);
				if (IsBlackColor(color))
				{
					material.SetColor("_BaseColor", new Color(0.15f, 0.15f, 0.15f, 1f));
				}
				else
				{
					material.SetColor("_BaseColor", color);
				}
			}
			else if (material.HasProperty("_TintColor"))
			{
				ReplaceTextureWithWhite(material);
				if (IsBlackColor(color))
				{
					material.SetColor("_TintColor", new Color(0.15f, 0.15f, 0.15f, 1f));
				}
				else
				{
					material.SetColor("_TintColor", color);
				}
			}
		}

		private static void ReplaceTextureWithWhite(Material material)
		{
			if (material.HasProperty("_MainTex"))
			{
				material.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture);
			}
			if (material.HasProperty("_BaseMap"))
			{
				material.SetTexture("_BaseMap", (Texture)(object)Texture2D.whiteTexture);
			}
		}

		private static bool IsBlackColor(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			if (color.r < 0.1f && color.g < 0.1f)
			{
				return color.b < 0.1f;
			}
			return false;
		}
	}
	internal static class DecalColorService
	{
		private static readonly string[] ColorIds = new string[8] { "red", "yellow", "green", "blue", "orange", "purple", "white", "black" };

		internal static string GetDecalColorIdForCurrentColor()
		{
			int currentColorIndex = PaintBallColorManager.GetCurrentColorIndex();
			if (currentColorIndex == -1 || !PaintBallColorManager.HasColorBeenSelected())
			{
				return string.Empty;
			}
			if (currentColorIndex >= 0 && currentColorIndex < ColorIds.Length)
			{
				return ColorIds[currentColorIndex];
			}
			return string.Empty;
		}

		internal static string GetDecalColorIdForColor(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			//IL_003a: 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_0087: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: 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_016f: Unknown result type (might be due to invalid IL or missing references)
			if (color.r > 0.9f && color.g < 0.1f && color.b < 0.1f)
			{
				return "red";
			}
			if (color.r > 0.9f && color.g > 0.9f && color.b < 0.1f)
			{
				return "yellow";
			}
			if (color.r < 0.1f && color.g > 0.9f && color.b < 0.1f)
			{
				return "green";
			}
			if (color.r < 0.1f && color.g < 0.1f && color.b > 0.9f)
			{
				return "blue";
			}
			if (color.r > 0.9f && color.g > 0.4f && color.g < 0.6f && color.b < 0.1f)
			{
				return "orange";
			}
			if (color.r > 0.4f && color.r < 0.6f && color.g < 0.1f && color.b > 0.9f)
			{
				return "purple";
			}
			if (color.r > 0.9f && color.g > 0.9f && color.b > 0.9f)
			{
				return "white";
			}
			if (color.r < 0.1f && color.g < 0.1f && color.b < 0.1f)
			{
				return "black";
			}
			return string.Empty;
		}
	}
}
namespace MarkerMod.Managers
{
	internal static class PaintPersistenceManager
	{
		private const int PaintspotMasterId = 71001;

		private static readonly HashSet<int> PaintballMasterIds = new HashSet<int> { 70010, 70011, 70012, 70013, 70014, 70015, 70016, 70017, 70018 };

		private static readonly HashSet<string> PermanentDecalIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static readonly object DecalLock = new object();

		private static readonly Func<Hub, DataManager> DataManagerGetter = CreateDataManagerGetter();

		internal static long PermanentLifetimeMilliseconds
		{
			get
			{
				double num = (double)MarkerPreferences.PermanentLifetimeSeconds * 1000.0;
				if (!(num >= 9.223372036854776E+18))
				{
					return (long)Math.Max(1.0, num);
				}
				return long.MaxValue;
			}
		}

		internal static bool ShouldKeep(FieldSkillObjectInfo info)
		{
			if (info == null)
			{
				return false;
			}
			if (MarkerPreferences.KeepFootprints && info.fieldSkillMasterID == 71001)
			{
				return true;
			}
			if (MarkerPreferences.KeepPuddles && PaintballMasterIds.Contains(info.fieldSkillMasterID))
			{
				return true;
			}
			return false;
		}

		internal static float OverrideLifetime(FieldSkillObjectInfo info, float originalSeconds)
		{
			if (!ShouldKeep(info))
			{
				return originalSeconds;
			}
			return MathF.Max(originalSeconds, MarkerPreferences.PermanentLifetimeSeconds);
		}

		internal static void DestroyWithOverride(Object target, float originalSeconds, FieldSkillObjectInfo info)
		{
			Object.Destroy(target, OverrideLifetime(info, originalSeconds));
		}

		internal static void TrackDecal(FieldSkillObjectInfo info)
		{
			if (!MarkerPreferences.KeepFootprints || info == null || info.fieldSkillMasterID != 71001)
			{
				return;
			}
			FieldSkillMemberInfo val = ResolveMemberInfo(info);
			if (val == null || string.IsNullOrEmpty(val.DecalId))
			{
				return;
			}
			lock (DecalLock)
			{
				PermanentDecalIds.Add(val.DecalId);
			}
		}

		internal static bool IsPermanentDecal(string decalId)
		{
			if (string.IsNullOrWhiteSpace(decalId))
			{
				return false;
			}
			lock (DecalLock)
			{
				return PermanentDecalIds.Contains(decalId);
			}
		}

		internal static void EnsureDecalLifetime(DecalData decalData)
		{
		}

		internal static void TrackDecalIfNeeded(DecalData decalData)
		{
			if (decalData == null || !MarkerPreferences.KeepFootprints || string.IsNullOrEmpty(decalData.DecalId) || !((Object)(object)decalData.SpawnBase != (Object)null) || (!ContainsPaintKeyword(decalData.DecalId) && !ContainsPaintKeyword(decalData.Socket)))
			{
				return;
			}
			lock (DecalLock)
			{
				PermanentDecalIds.Add(decalData.DecalId);
			}
		}

		private static bool ContainsPaintKeyword(string value)
		{
			if (!string.IsNullOrEmpty(value))
			{
				return value.IndexOf("paint", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		private static FieldSkillMemberInfo ResolveMemberInfo(FieldSkillObjectInfo info)
		{
			Hub s = Hub.s;
			if ((Object)(object)s == (Object)null)
			{
				return null;
			}
			DataManager val = DataManagerGetter(s);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			FieldSkillInfo fieldSkillData = val.ExcelDataManager.GetFieldSkillData(info.fieldSkillMasterID);
			if (fieldSkillData == null)
			{
				return null;
			}
			if (!fieldSkillData.FieldSkillMemberInfos.TryGetValue(info.fieldSkillIndex, out var value))
			{
				return null;
			}
			return value;
		}

		private static Func<Hub, DataManager> CreateDataManagerGetter()
		{
			return (Hub hub) => (!((Object)(object)hub != (Object)null)) ? null : ReflectionHelper.GetPropertyValue<DataManager>((object)hub, "dataman");
		}
	}
	internal static class PaintBallColorManager
	{
		private static readonly List<Color> ColorPalette = new List<Color>
		{
			new Color(1f, 0f, 0f, 1f),
			new Color(1f, 1f, 0f, 1f),
			new Color(0f, 1f, 0f, 1f),
			new Color(0f, 0f, 1f, 1f),
			new Color(1f, 0.5f, 0f, 1f),
			new Color(0.5f, 0f, 1f, 1f),
			new Color(1f, 1f, 1f, 1f),
			new Color(0f, 0f, 0f, 1f)
		};

		private static int currentColorIndex = -1;

		private static bool hasColorBeenSelected = false;

		private static readonly HashSet<int> PaintballMasterIDs = new HashSet<int> { 2030, 70010, 70011, 70012, 70013, 70014, 70015, 70016, 70017, 70018 };

		internal static void CycleColor()
		{
			hasColorBeenSelected = true;
			if (currentColorIndex == -1)
			{
				currentColorIndex = 0;
			}
			else if (currentColorIndex == ColorPalette.Count - 1)
			{
				currentColorIndex = -1;
			}
			else
			{
				currentColorIndex++;
			}
		}

		internal static void ResetColorSelection()
		{
			hasColorBeenSelected = false;
			currentColorIndex = -1;
		}

		internal static Color GetCurrentColor()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (currentColorIndex == -1)
			{
				return Color.white;
			}
			return ColorPalette[currentColorIndex];
		}

		internal static string GetCurrentColorName()
		{
			return currentColorIndex switch
			{
				-1 => "Default", 
				0 => "Rot", 
				1 => "Gelb", 
				2 => "Grün", 
				3 => "Blau", 
				4 => "Orange", 
				5 => "Lila", 
				6 => "Weiß", 
				7 => "Schwarz", 
				_ => "Unbekannt", 
			};
		}

		internal static bool IsPaintball(int itemMasterID)
		{
			return PaintballMasterIDs.Contains(itemMasterID);
		}

		internal static void ApplyColorToPaintball(object inventoryItem)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (inventoryItem == null)
			{
				return;
			}
			try
			{
				Transform propertyValue = ReflectionHelper.GetPropertyValue<Transform>(inventoryItem, "Transform");
				if ((Object)(object)propertyValue == (Object)null)
				{
					return;
				}
				bool useDefaultMaterial = !hasColorBeenSelected || currentColorIndex == -1;
				Color currentColor = GetCurrentColor();
				Renderer[] componentsInChildren = ((Component)propertyValue).GetComponentsInChildren<Renderer>(true);
				if (componentsInChildren != null && componentsInChildren.Length != 0)
				{
					Renderer[] array = componentsInChildren;
					for (int i = 0; i < array.Length; i++)
					{
						MaterialColorService.ApplyColorToRenderer(array[i], currentColor, useDefaultMaterial);
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("[PaintBallColorManager] Error: " + ex.Message + "\n" + ex.StackTrace);
			}
		}

		internal static bool HasColorBeenSelected()
		{
			return hasColorBeenSelected;
		}

		internal static int GetCurrentColorIndex()
		{
			return currentColorIndex;
		}
	}
}
namespace MarkerMod.Config
{
	internal static class MarkerPreferences
	{
		private const string CategoryId = "MarkerMod";

		private static MelonPreferences_Category _category;

		private static MelonPreferences_Entry<bool> _keepFootprints;

		private static MelonPreferences_Entry<bool> _keepPuddles;

		private static MelonPreferences_Entry<float> _lifetimeSeconds;

		private static MelonPreferences_Entry<bool> _infinitePaintballs;

		private static MelonPreferences_Entry<bool> _enablePaintballColorChange;

		internal static bool KeepFootprints => _keepFootprints.Value;

		internal static bool KeepPuddles => _keepPuddles.Value;

		internal static float PermanentLifetimeSeconds => Mathf.Max(1f, _lifetimeSeconds.Value);

		internal static bool InfinitePaintballs => _infinitePaintballs.Value;

		internal static bool EnablePaintballColorChange => _enablePaintballColorChange.Value;

		internal static void Initialize()
		{
			if (_category == null)
			{
				_category = MelonPreferences.CreateCategory("MarkerMod", "Marker Mod");
				_keepFootprints = CreateEntry("keepFootprints", defaultValue: true, "Keep Footprints", "Keep paint footprints after puddles dry. When enabled, paint footprints will persist even after the paint puddles have dried up. Default: true");
				_keepPuddles = CreateEntry("keepPuddles", defaultValue: false, "Keep Puddles", "Keep spawned paint puddles as well. When enabled, both paint footprints and paint puddles will persist. Default: false");
				_lifetimeSeconds = CreateEntry("permanentLifetimeSeconds", 86400f, "Lifetime", "Lifetime in seconds for persistent paint. This determines how long paint marks will remain visible. Default: 86400 (24 hours)");
				_infinitePaintballs = CreateEntry("infinitePaintballs", defaultValue: false, "Infinite Paintballs", "Paintballs are not consumed when thrown. When enabled, you can throw paintballs infinitely without them being removed from your inventory. Default: false");
				_enablePaintballColorChange = CreateEntry("enablePaintballColorChange", defaultValue: true, "Enable Paintball Color Change", "Allow changing paintball color by right-clicking. When enabled, you can cycle through colors (Red, Yellow, Green, Blue, Orange, Purple, White, Black) by right-clicking while holding a paintball. Default: true");
			}
		}

		private static MelonPreferences_Entry<T> CreateEntry<T>(string identifier, T defaultValue, string displayName, string description = null)
		{
			if (_category == null)
			{
				throw new InvalidOperationException("Preference category not initialized.");
			}
			return _category.CreateEntry<T>(identifier, defaultValue, displayName, description, false, false, (ValueValidator)null, (string)null);
		}
	}
}