Decompiled source of PerPlayerPaint v1.0.0

BepInEx/plugins/PerPlayerPaint/HitsujiSauce.PerPlayerPaint.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PerPlayerPaint;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HitsujiSauce.PerPlayerPaint")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PerPlayerPaint")]
[assembly: AssemblyTitle("HitsujiSauce.PerPlayerPaint")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.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]
	[Microsoft.CodeAnalysis.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]
	[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;
		}
	}
}
[HarmonyPatch(typeof(StartOfRound), "Start")]
internal class ChangeDefaultMode
{
	private static void Postfix(StartOfRound __instance)
	{
		if (!SprayConfig.fixedColor.Value)
		{
			return;
		}
		NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager;
		if (networkManager.IsServer)
		{
			int num = 0;
			int num2 = 0;
			int value = SprayConfig.targetFixedColor.Value;
			int num3;
			do
			{
				num = Random.Range(1, 100000000);
				num2++;
				Random random = new Random(num + 151);
				num3 = random.Next(0, 4);
			}
			while (num3 != SprayConfig.targetFixedColor.Value && num2 < 500);
			__instance.randomMapSeed = num;
		}
	}
}
[HarmonyPatch(typeof(StartOfRound), "ChooseNewRandomMapSeed")]
internal class StartGamePatch
{
	private static void Postfix(StartOfRound __instance)
	{
		if (!SprayConfig.fixedColor.Value)
		{
			return;
		}
		NetworkManager networkManager = ((NetworkBehaviour)__instance).NetworkManager;
		if (networkManager.IsServer)
		{
			int num = 0;
			int num2 = 0;
			int value = SprayConfig.targetFixedColor.Value;
			int num3;
			do
			{
				num = Random.Range(1, 100000000);
				num2++;
				Random random = new Random(num + 151);
				num3 = random.Next(0, 4);
			}
			while (num3 != SprayConfig.targetFixedColor.Value && num2 < 500);
			__instance.randomMapSeed = num;
		}
	}
}
[HarmonyPatch(typeof(SprayPaintItem), "EquipItem")]
public class SprayPaintEquipPatch
{
	private static void Postfix(SprayPaintItem __instance)
	{
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		if (__instance.isWeedKillerSprayBottle || !SprayConfig.perPlayerColor.Value)
		{
			return;
		}
		PlayerControllerB playerHeldBy = ((GrabbableObject)__instance).playerHeldBy;
		if ((Object)(object)playerHeldBy == (Object)null)
		{
			return;
		}
		int sprayCanMatsIndex = __instance.sprayCanMatsIndex;
		int num = __instance.sprayCanMats.Length;
		int num2 = (int)playerHeldBy.playerClientId;
		__instance.sprayCanMatsIndex = num2 % num;
		SprayStateManager.InitOriginalMats(__instance.particleMats);
		if (SprayConfig.useCustomColor.Value)
		{
			Color val2 = default(Color);
			for (int i = 0; i < 4; i++)
			{
				ConfigEntry<string> val = SprayConfig.colorHexes[i];
				Color color = (ColorUtility.TryParseHtmlString(val.Value, ref val2) ? val2 : __instance.particleMats[i].color);
				__instance.particleMats[i].color = color;
			}
		}
		((Renderer)((Component)__instance.sprayParticle).GetComponent<ParticleSystemRenderer>()).material = __instance.particleMats[__instance.sprayCanMatsIndex];
		((Renderer)((Component)__instance.sprayCanNeedsShakingParticle).GetComponent<ParticleSystemRenderer>()).material = __instance.particleMats[__instance.sprayCanMatsIndex];
		SprayStateManager.RegisterOriginalIndex((GrabbableObject)(object)__instance, sprayCanMatsIndex);
	}
}
[HarmonyPatch(typeof(SprayPaintItem), "AddSprayPaintLocal")]
public class SprayPaintDecalColorPatch
{
	private static void Postfix(SprayPaintItem __instance)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		if (__instance.isWeedKillerSprayBottle)
		{
			return;
		}
		GameObject val = SprayPaintItem.sprayPaintDecals[SprayPaintItem.sprayPaintDecalsIndex];
		if (!((Object)(object)val == (Object)null))
		{
			DecalProjector component = val.GetComponent<DecalProjector>();
			if (!((Object)(object)component == (Object)null))
			{
				component.material.color = __instance.particleMats[__instance.sprayCanMatsIndex].color;
			}
		}
	}
}
[HarmonyPatch(typeof(PlayerControllerB), "ShowNameBillboard")]
public class PlayerNameColorPatch
{
	public static Material[]? sprayParticleMats;

	public static float timer = -999f;

	private static void Postfix(PlayerControllerB __instance)
	{
		//IL_00f6: 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_012b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance == (Object)null || !SprayConfig.perPlayerColor.Value)
		{
			return;
		}
		TextMeshProUGUI usernameBillboardText = __instance.usernameBillboardText;
		if ((Object)(object)usernameBillboardText == (Object)null)
		{
			return;
		}
		float time = Time.time;
		if (sprayParticleMats == null || time - timer > 30f)
		{
			timer = time;
			SprayPaintItem[] array = Object.FindObjectsByType<SprayPaintItem>((FindObjectsSortMode)0);
			SprayPaintItem[] array2 = array;
			int num = 0;
			if (num < array2.Length)
			{
				SprayPaintItem val = array2[num];
				if (!((Object)(object)val != (Object)null) || val.isWeedKillerSprayBottle)
				{
					Debug.LogWarning((object)"No SprayPaintItem found in scene.");
					return;
				}
				sprayParticleMats = val.particleMats;
			}
			if (sprayParticleMats == null)
			{
				return;
			}
		}
		int num2 = (int)__instance.playerClientId % sprayParticleMats.Length;
		Color color = sprayParticleMats[num2].color;
		if (SprayConfig.useCustomColor.Value)
		{
			string value = SprayConfig.colorHexes[num2].Value;
			ColorUtility.TryParseHtmlString(value, ref color);
		}
		string text = "<color=#" + ColorUtility.ToHtmlStringRGB(color) + ">●</color> ";
		((TMP_Text)usernameBillboardText).text = text + __instance.playerUsername;
	}
}
[HarmonyPatch(typeof(QuickMenuManager), "Update")]
public class PlayerListNameRefreshPatch
{
	private static float nextUpdateTime;

	private static void Postfix(QuickMenuManager __instance)
	{
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		if (!SprayConfig.perPlayerColor.Value || Time.time < nextUpdateTime)
		{
			return;
		}
		nextUpdateTime = Time.time + 30f;
		Color val3 = default(Color);
		for (int i = 0; i < __instance.playerListSlots.Length; i++)
		{
			PlayerListSlot val = __instance.playerListSlots[i];
			if (!val.isConnected)
			{
				continue;
			}
			PlayerControllerB val2 = StartOfRound.Instance.allPlayerScripts[i];
			TextMeshProUGUI usernameHeader = val.usernameHeader;
			int num = (int)val2.playerClientId % SprayConfig.colorHexes.Length;
			if (SprayConfig.useCustomColor.Value)
			{
				string value = SprayConfig.colorHexes[num].Value;
				if (ColorUtility.TryParseHtmlString(value, ref val3))
				{
					string text = "<color=#" + ColorUtility.ToHtmlStringRGB(val3) + ">●</color> ";
					((TMP_Text)usernameHeader).text = text + val2.playerUsername;
				}
			}
			else
			{
				Color color = PlayerNameColorPatch.sprayParticleMats[num].color;
				string text2 = "<color=#" + ColorUtility.ToHtmlStringRGB(color) + ">●</color> ";
				((TMP_Text)usernameHeader).text = text2 + val2.playerUsername;
			}
		}
	}
}
namespace PerPlayerPaint
{
	[BepInPlugin("HitsujiSauce.PerPlayerPaint", "PerPlayerPaint", "1.0.0")]
	public class PerPlayerPaint : BaseUnityPlugin
	{
		public static ManualLogSource Log;

		public static PerPlayerPaint Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Patch();
			SprayConfig.Init(((BaseUnityPlugin)this).Config);
			Logger.LogInfo((object)"HitsujiSauce.PerPlayerPaint v1.0.0 has loaded!");
		}

		internal static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("HitsujiSauce.PerPlayerPaint");
			}
			Harmony.PatchAll();
		}

		internal static void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class SprayConfig
	{
		public static ConfigEntry<string>[] colorHexes;

		public static ConfigEntry<bool> perPlayerColor;

		public static ConfigEntry<bool> useCustomColor;

		public static ConfigEntry<bool> fixedColor;

		public static ConfigEntry<int> targetFixedColor;

		public static bool decalFirstCall;

		public static void Init(ConfigFile config)
		{
			colorHexes = new ConfigEntry<string>[4];
			for (int i = 0; i < 4; i++)
			{
				colorHexes[i] = config.Bind<string>("SprayPaintColors", $"color{i + 1}", DefaultColor(i), $"Color {i + 1} in hex format.");
			}
			perPlayerColor = config.Bind<bool>("SprayPaintColors", "PerPlayerColor", true, "Change the spray paint color for each player.");
			useCustomColor = config.Bind<bool>("SprayPaintColors", "UseCustomColors", false, "Use custom colors.");
			fixedColor = config.Bind<bool>("Host", "FixedColor", false, "fixed color of spray paint, when you buy spray paint.");
			targetFixedColor = config.Bind<int>("Host", "TargetColor", 0, "0 = green\n1 = purple\n2 = red\n3 = yellow");
			if (targetFixedColor.Value < 0 || targetFixedColor.Value >= 4)
			{
				targetFixedColor.Value = 0;
			}
			decalFirstCall = false;
		}

		public static void ReloadConfig()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			ConfigFile config = new ConfigFile(Paths.ConfigPath + "/HitsujiSauce.PerPlayerPaint.cfg", true);
			Init(config);
		}

		private static string DefaultColor(int index)
		{
			return (new string[4] { "#00FFFF", "#00FF00", "#0000FF", "#FFFF00" })[index];
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "StartGame")]
	internal class StartGameReloadConfig
	{
		private static void Prefix()
		{
			SprayConfig.ReloadConfig();
			SprayStateManager.ChangeDefaultColor();
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "OnDestroy")]
	public class ClearFreeMoonOnShutdown
	{
		private static void Postfix()
		{
			SprayStateManager.Clear();
		}
	}
	public static class SprayStateManager
	{
		private static Dictionary<GrabbableObject, int> sprayOriginalIndices = new Dictionary<GrabbableObject, int>();

		private static Material[] defaultMaterials;

		public static void RegisterOriginalIndex(GrabbableObject spray, int index)
		{
			if (!sprayOriginalIndices.ContainsKey(spray))
			{
				sprayOriginalIndices[spray] = index;
			}
		}

		public static int GetOriginalIndex(GrabbableObject spray)
		{
			int value;
			return sprayOriginalIndices.TryGetValue(spray, out value) ? value : 0;
		}

		public static void ChangeDefaultColor()
		{
			SprayPaintItem[] array = Object.FindObjectsByType<SprayPaintItem>((FindObjectsSortMode)0);
			if (defaultMaterials == null)
			{
				return;
			}
			SprayPaintItem[] array2 = array;
			foreach (SprayPaintItem val in array2)
			{
				if (!val.isWeedKillerSprayBottle)
				{
					val.sprayCanMatsIndex = GetOriginalIndex((GrabbableObject)(object)val);
					((Renderer)((Component)val.sprayParticle).GetComponent<ParticleSystemRenderer>()).material = defaultMaterials[val.sprayCanMatsIndex];
					((Renderer)((Component)val.sprayCanNeedsShakingParticle).GetComponent<ParticleSystemRenderer>()).material = defaultMaterials[val.sprayCanMatsIndex];
				}
			}
		}

		public static void ClearDestroyed()
		{
			sprayOriginalIndices = sprayOriginalIndices.Where<KeyValuePair<GrabbableObject, int>>((KeyValuePair<GrabbableObject, int> kv) => (Object)(object)kv.Key != (Object)null).ToDictionary((KeyValuePair<GrabbableObject, int> kv) => kv.Key, (KeyValuePair<GrabbableObject, int> kv) => kv.Value);
		}

		public static void Clear()
		{
			sprayOriginalIndices.Clear();
		}

		public static void InitOriginalMats(Material[] materials)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			if (defaultMaterials == null)
			{
				defaultMaterials = (Material[])(object)new Material[materials.Length];
				for (int i = 0; i < materials.Length; i++)
				{
					defaultMaterials[i] = new Material(materials[i]);
				}
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "HitsujiSauce.PerPlayerPaint";

		public const string PLUGIN_NAME = "PerPlayerPaint";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}