Decompiled source of ColourfulFlashlights v4.0.1

ColourfulFlashlights.dll

Decompiled a month ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ColourfulFlashlights;
using ColourfulFlashlights.NetcodePatcher;
using ColourfulFlashlights.Properties;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Unity.Collections;
using Unity.Netcode;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ColourfulFlashlights")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("4.0.1.0")]
[assembly: AssemblyInformationalVersion("4.0.1+76b75d314d4b952dfc60ed937fdd93bfe94b11c9")]
[assembly: AssemblyProduct("ColourfulFlashlights")]
[assembly: AssemblyTitle("ColourfulFlashlights")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("4.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
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;
		}
	}
}
public enum FlashlightMode
{
	Fixed,
	Cycle,
	SmoothCycle,
	Random,
	Health,
	Rainbow
}
public class FlashlightState
{
	public FlashlightMode Mode = FlashlightMode.Fixed;

	public List<Color> Colors = new List<Color>();

	public int Speed = 10;
}
namespace ColourfulFlashlights
{
	public class ConfigHandler
	{
		public ConfigFile configFile;

		public ConfigEntry<bool> syncOthers;

		public ConfigEntry<bool> syncOwn;

		public ConfigEntry<bool> syncCyclicFX;

		public void Init()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			Directory.CreateDirectory(Path.GetDirectoryName(Plugin.configPath));
			configFile = new ConfigFile(Plugin.configPath, true);
			syncOthers = configFile.Bind<bool>("Multiplayer", "Sync Others", true, "If true, you will see other player's flashlight settings. If false, all other players flashlights will be default (white).");
			syncOwn = configFile.Bind<bool>("Multiplayer", "Sync Own", true, "If true, other players will see your custom flashlight settings. If false, your flashlight will appear default (white) to other players.");
			syncCyclicFX = configFile.Bind<bool>("Multiplayer", "Sync Cyclic Effects", true, "If true, cyclic effects you or others create, such as potential fast flashing or strobing, will sync. If false, only fixed colours will sync.");
		}
	}
	public class FlashlightData
	{
		public FlashlightItem Flashlight;

		public FlashlightMode Mode;

		public List<Color> Colors;

		public int Speed;

		private Color currentColour;

		private float currentHue;

		private float cycleTime = 0f;

		private int cycleIndex = 0;

		public float EffectSpeed => 0.25f * Mathf.Pow((float)Speed / 20f, 2.5f);

		public FlashlightData(FlashlightItem flashlight, List<Color> colors, FlashlightMode mode, int speed = 10)
		{
			Flashlight = flashlight;
			Mode = mode;
			Colors = colors.ToList();
			Speed = speed;
			if (mode == FlashlightMode.Health && ((GrabbableObject)flashlight).isHeld)
			{
				Plugin.playerMaxHealth = Math.Max(((GrabbableObject)flashlight).playerHeldBy.health, 100);
			}
		}

		public bool IsEqual(FlashlightData other)
		{
			return Mode == other.Mode && Speed == other.Speed && Colors.SequenceEqual(other.Colors);
		}

		public void Update(float deltaTime)
		{
			if (((GrabbableObject)Flashlight).isBeingUsed)
			{
				if (Flashlight == null)
				{
					Plugin.flashlightHandler.RemoveFlashlight(Flashlight);
				}
				switch (Mode)
				{
				case FlashlightMode.Fixed:
				case FlashlightMode.Random:
					Fixed();
					break;
				case FlashlightMode.Rainbow:
					Rainbow(deltaTime);
					break;
				case FlashlightMode.Cycle:
					Cycle(deltaTime, smooth: false);
					break;
				case FlashlightMode.SmoothCycle:
					Cycle(deltaTime, smooth: true);
					break;
				case FlashlightMode.Health:
					Health();
					break;
				}
			}
		}

		private void Fixed()
		{
			//IL_0008: 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)
			currentColour = Colors.First();
			SetColour();
		}

		private void Cycle(float deltaTime, bool smooth)
		{
			//IL_0076: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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)
			cycleTime += deltaTime * (EffectSpeed * 4f);
			int index = (cycleIndex + 1) % Colors.Count;
			if (smooth)
			{
				currentColour = Color.Lerp(Colors[cycleIndex], Colors[index], cycleTime);
			}
			else
			{
				currentColour = Colors[cycleIndex];
			}
			if (cycleTime >= 1f)
			{
				cycleTime = 0f;
				cycleIndex = index;
			}
			SetColour();
		}

		private void Rainbow(float deltaTime)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			currentHue += deltaTime * EffectSpeed;
			currentHue = Mathf.Repeat(currentHue, 1f);
			currentColour = Color.HSVToRGB(currentHue, 1f, 1f);
			SetColour();
		}

		private void Health()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//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)
			if (((GrabbableObject)Flashlight).isHeld)
			{
				if (((GrabbableObject)Flashlight).playerHeldBy.health > Plugin.playerMaxHealth)
				{
					Plugin.playerMaxHealth = ((GrabbableObject)Flashlight).playerHeldBy.health;
				}
				float num = Mathf.InverseLerp(0.1f, 1f, (float)((GrabbableObject)Flashlight).playerHeldBy.health / (float)Plugin.playerMaxHealth);
				currentColour = Color.Lerp(Colors[1], Colors[0], num);
				SetColour();
			}
		}

		private void SetColour()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			Flashlight.flashlightBulb.color = currentColour;
			Flashlight.flashlightBulbGlow.color = currentColour;
			if (((GrabbableObject)Flashlight).isHeld)
			{
				((GrabbableObject)Flashlight).playerHeldBy.helmetLight.color = currentColour;
			}
		}
	}
	public class FlashlightHandler
	{
		public Dictionary<FlashlightItem, FlashlightData> Flashlights = new Dictionary<FlashlightItem, FlashlightData>();

		public void SetFlashlight(FlashlightData data)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (data.Mode != FlashlightMode.Random && data.Colors.Count == 0)
			{
				data.Colors.Add(Color.white);
			}
			if (Flashlights.ContainsKey(data.Flashlight))
			{
				Flashlights.Remove(data.Flashlight);
				Flashlights.Add(data.Flashlight, data);
				Plugin.mls.LogDebug((object)"Updated flashlight data");
			}
			else
			{
				Flashlights.Add(data.Flashlight, data);
				Plugin.mls.LogDebug((object)"Added new flashlight data");
			}
		}

		public void RemoveFlashlight(FlashlightItem flashlight)
		{
			Flashlights.Remove(flashlight);
		}

		public void CFUpdate(float deltaTime)
		{
			foreach (FlashlightData value in Flashlights.Values)
			{
				value.Update(deltaTime);
			}
		}
	}
	public static class Assets
	{
		public static AssetBundle MainAssetBundle;

		public static void PopulateAssets()
		{
			if ((Object)(object)MainAssetBundle == (Object)null)
			{
				MainAssetBundle = AssetBundle.LoadFromMemory(Resources.cfasset);
			}
		}
	}
	public static class Helpers
	{
		private static readonly Regex HexRegex = new Regex("^#([0-9A-Fa-f]{6})$", RegexOptions.Compiled);

		private static readonly Random rand = new Random();

		public static Dictionary<string, string> colourDict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "White", "#FFFFFF" },
			{ "Blue", "#0000FF" },
			{ "Red", "#FF0000" },
			{ "Green", "#2FDE2F" },
			{ "Yellow", "#FFFF00" },
			{ "Pink", "#FC96FF" },
			{ "Orange", "#FF7B00" },
			{ "Purple", "#7E00F5" }
		};

		public static Color? HexStringToColor(string hex)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Color value = default(Color);
			if (GetValidHexCode(hex, out hex) && ColorUtility.TryParseHtmlString(hex, ref value))
			{
				return value;
			}
			return null;
		}

		public static List<Color> HexListToColors(List<string> data)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			List<Color> list = new List<Color>();
			foreach (string datum in data)
			{
				if (list.Count >= 10)
				{
					break;
				}
				if (!GetValidHexCode(datum, out var code))
				{
					continue;
				}
				Color? val = HexStringToColor(code);
				if (val.HasValue)
				{
					Color valueOrDefault = val.GetValueOrDefault();
					if (true)
					{
						list.Add(valueOrDefault);
					}
				}
			}
			return list;
		}

		public static List<string> ColorsToHexList(List<Color> data)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			foreach (Color datum in data)
			{
				list.Add(ColorToHexString(datum));
			}
			return list;
		}

		public static string ColorToHexString(Color colour)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string text = ColorUtility.ToHtmlStringRGB(colour);
			return "#" + text;
		}

		public static string ColorsToHexString(List<Color> colours)
		{
			return string.Join(",", colours.Select((Color c) => ColorToHexString(c)));
		}

		public static Color? NameToColor(string name)
		{
			if (colourDict.TryGetValue(name.Trim(), out var value))
			{
				return HexStringToColor(value);
			}
			return null;
		}

		public static int GetSpeedFromArgs(string[] args)
		{
			int result;
			if (args.Length > 2)
			{
				return int.TryParse(args[2], out result) ? Math.Clamp(result, 1, 20) : Plugin.activeState.Speed;
			}
			return Plugin.activeState.Speed;
		}

		public static bool IsValidHexCode(string hex)
		{
			if (!hex.StartsWith("#"))
			{
				hex = "#" + hex;
			}
			return HexRegex.IsMatch(hex);
		}

		public static bool GetValidHexCode(string hex, out string code)
		{
			code = "";
			if (Utility.IsNullOrWhiteSpace(hex))
			{
				return false;
			}
			code = hex.Trim();
			if (!code.StartsWith("#"))
			{
				code = "#" + code;
			}
			return HexRegex.IsMatch(code);
		}

		public static Color GetUniqueRandomColor(List<Color> colours, int prevIndex, out int index)
		{
			//IL_0035: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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)
			index = -1;
			if (colours == null || colours.Count == 0)
			{
				return Random.ColorHSV(0f, 1f, 0.5f, 1f, 0.5f, 1f);
			}
			if (colours.Count == 1)
			{
				return colours[0];
			}
			int num;
			do
			{
				num = rand.Next(colours.Count);
			}
			while (num == prevIndex);
			index = num;
			return colours[num];
		}

		public static string GetStateText(FlashlightState state, string name = "")
		{
			//IL_002c: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			FlashlightMode mode = state.Mode;
			bool flag = ((mode == FlashlightMode.Fixed || (uint)(mode - 3) <= 1u) ? true : false);
			bool flag2 = flag;
			string text = "Colour: " + ColorToHexString(state.Colors[0]);
			if (state.Mode == FlashlightMode.Random)
			{
				text = ((state.Colors.Count <= 1) ? "Colour: Random!" : $"Colour count: {state.Colors.Count}");
			}
			else if (state.Mode == FlashlightMode.Health)
			{
				text = "Colours: [100% HP] " + ColorToHexString(state.Colors[0]) + " | [0% HP] " + ColorToHexString(state.Colors[1]);
			}
			else if (state.Mode == FlashlightMode.Rainbow)
			{
				text = "Colours: Rainbow!";
			}
			else if (state.Colors.Count > 1)
			{
				text = $"Colour count: {state.Colors.Count}";
			}
			return ((name.Length < 1) ? "" : ("Preset name: " + name + "\n")) + $"Mode: {state.Mode} [{(int)state.Mode}]\n" + "Speed: " + (flag2 ? "N/A" : $"{state.Speed}") + "\n" + text;
		}

		public static void UpdateState(List<Color> colours, FlashlightMode mode, int speed)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = ((IEnumerable<PlayerControllerB>)RoundManager.Instance.playersManager.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB p) => p.playerClientId == Plugin.playerId));
			if ((Object)(object)val != (Object)null)
			{
				if (mode == FlashlightMode.Random)
				{
					Plugin.randomColours = colours;
					colours = new List<Color>(1) { GetUniqueRandomColor(colours, -1, out var index) };
					Plugin.prevRandIndex = index;
				}
				else
				{
					Plugin.randomColours = new List<Color>();
					Plugin.prevRandIndex = -1;
				}
				string text = ColorsToHexString(colours);
				Plugin.activeState = new FlashlightState
				{
					Colors = colours,
					Mode = mode,
					Speed = speed
				};
				SaveHandler.SaveData();
				if (!Plugin.config.syncOwn.Value || !Plugin.config.syncCyclicFX.Value)
				{
					text = "#FFFFFF";
					mode = FlashlightMode.Fixed;
				}
				CFNetwork.Instance.SetPlayerColourServerRpc(Plugin.playerId, mode, FixedString128Bytes.op_Implicit(text), speed);
			}
			else
			{
				Plugin.mls.LogDebug((object)"Player was null?");
			}
		}
	}
	public struct CFPlayerData : INetworkSerializable, IEquatable<CFPlayerData>
	{
		public ulong ClientId;

		public FlashlightMode Mode;

		public FixedString128Bytes Colors;

		public int Speed;

		public unsafe void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			((BufferSerializer<ulong>*)(&serializer))->SerializeValue<ulong>(ref ClientId, default(ForPrimitives));
			((BufferSerializer<FlashlightMode>*)(&serializer))->SerializeValue<FlashlightMode>(ref Mode, default(ForEnums));
			((BufferSerializer<FixedString128Bytes>*)(&serializer))->SerializeValue<FixedString128Bytes>(ref Colors, default(ForFixedStrings));
			((BufferSerializer<int>*)(&serializer))->SerializeValue<int>(ref Speed, default(ForPrimitives));
		}

		public bool Equals(CFPlayerData other)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			return ClientId == other.ClientId && Mode == other.Mode && Speed == other.Speed && ((FixedString128Bytes)(ref Colors)).Equals(other.Colors);
		}

		public readonly List<Color> GetColors()
		{
			//IL_0008: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			List<Color> list = new List<Color>();
			FixedString128Bytes colors = Colors;
			string[] array = ((object)(FixedString128Bytes)(ref colors)).ToString().Split(',', StringSplitOptions.RemoveEmptyEntries);
			string[] array2 = array;
			Color item = default(Color);
			foreach (string text in array2)
			{
				if (ColorUtility.TryParseHtmlString(text, ref item))
				{
					list.Add(item);
				}
			}
			return list;
		}

		public override int GetHashCode()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return HashCode.Combine<ulong, FlashlightMode, FixedString128Bytes, int>(ClientId, Mode, Colors, Speed);
		}
	}
	public class CFNetwork : NetworkBehaviour
	{
		public NetworkList<CFPlayerData> PlayerData;

		public static CFNetwork Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			PlayerData = new NetworkList<CFPlayerData>();
		}

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			PlayerData.OnListChanged += OnListChanged;
			Plugin.mls.LogInfo((object)"Network ready!");
		}

		public override void OnNetworkDespawn()
		{
			((NetworkBehaviour)this).OnNetworkDespawn();
			PlayerData.OnListChanged -= OnListChanged;
			Plugin.mls.LogInfo((object)"Network closed!");
		}

		private void OnListChanged(NetworkListEvent<CFPlayerData> e)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			ApplyFlashlightColour(e.Value);
		}

		public CFPlayerData? GetPlayerData(ulong clientId)
		{
			foreach (CFPlayerData playerDatum in PlayerData)
			{
				if (playerDatum.ClientId == clientId)
				{
					return playerDatum;
				}
			}
			return null;
		}

		private void ApplyFlashlightColour(CFPlayerData data)
		{
			PlayerControllerB val = ((IEnumerable<PlayerControllerB>)RoundManager.Instance.playersManager.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB p) => p.playerClientId == data.ClientId));
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			IEnumerable<FlashlightItem> enumerable = val.ItemSlots.OfType<FlashlightItem>();
			foreach (FlashlightItem item in enumerable)
			{
				FlashlightData flashlight = new FlashlightData(item, data.GetColors(), data.Mode, data.Speed);
				Plugin.flashlightHandler.SetFlashlight(flashlight);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SetPlayerColourServerRpc(ulong clientId, FlashlightMode mode, FixedString128Bytes colors, int speed)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_0090: 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_00ab: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(558749639u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, clientId);
				((FastBufferWriter)(ref val2)).WriteValueSafe<FlashlightMode>(ref mode, default(ForEnums));
				((FastBufferWriter)(ref val2)).WriteValueSafe<FixedString128Bytes>(ref colors, default(ForFixedStrings));
				BytePacker.WriteValueBitPacked(val2, speed);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 558749639u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
			{
				return;
			}
			base.__rpc_exec_stage = (__RpcExecStage)0;
			Plugin.mls.LogDebug((object)"SetPlayerColourServerRpc Sent");
			if (!((NetworkBehaviour)this).IsServer)
			{
				return;
			}
			CFPlayerData cFPlayerData = default(CFPlayerData);
			cFPlayerData.ClientId = clientId;
			cFPlayerData.Mode = mode;
			cFPlayerData.Colors = colors;
			cFPlayerData.Speed = speed;
			CFPlayerData cFPlayerData2 = cFPlayerData;
			int num = -1;
			for (int i = 0; i < PlayerData.Count; i++)
			{
				if (PlayerData[i].ClientId == clientId)
				{
					num = i;
					break;
				}
			}
			if (num >= 0)
			{
				PlayerData[num] = cFPlayerData2;
			}
			else
			{
				PlayerData.Add(cFPlayerData2);
			}
		}

		protected override void __initializeVariables()
		{
			if (PlayerData == null)
			{
				throw new Exception("CFNetwork.PlayerData cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)PlayerData).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)PlayerData, "PlayerData");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)PlayerData);
			((NetworkBehaviour)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(558749639u, new RpcReceiveHandler(__rpc_handler_558749639), "SetPlayerColourServerRpc");
			((NetworkBehaviour)this).__initializeRpcs();
		}

		private static void __rpc_handler_558749639(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				FlashlightMode mode = default(FlashlightMode);
				((FastBufferReader)(ref reader)).ReadValueSafe<FlashlightMode>(ref mode, default(ForEnums));
				FixedString128Bytes colors = default(FixedString128Bytes);
				((FastBufferReader)(ref reader)).ReadValueSafe<FixedString128Bytes>(ref colors, default(ForFixedStrings));
				int speed = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref speed);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((CFNetwork)(object)target).SetPlayerColourServerRpc(clientId, mode, colors, speed);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "CFNetwork";
		}
	}
	[HarmonyPatch]
	public class NetworkObjectManager
	{
		private static GameObject networkPrefab;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		public static void Init()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (!((Object)(object)networkPrefab != (Object)null))
			{
				networkPrefab = (GameObject)Assets.MainAssetBundle.LoadAsset("CFNetworkHandler");
				networkPrefab.AddComponent<CFNetwork>();
				NetworkManager.Singleton.AddNetworkPrefab(networkPrefab);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		private static void SpawnNetworkHandler()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				GameObject val = Object.Instantiate<GameObject>(networkPrefab, Vector3.zero, Quaternion.identity);
				val.GetComponent<NetworkObject>().Spawn(false);
			}
		}
	}
	public static class Patches
	{
		[HarmonyPatch(typeof(FlashlightItem))]
		public class CFFlashlightItemPatch
		{
			[HarmonyPatch("SwitchFlashlight")]
			[HarmonyPostfix]
			public static void SwitchFlashlightPatch(FlashlightItem __instance, bool on)
			{
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0118: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_025f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0223: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				if (!((GrabbableObject)__instance).isBeingUsed)
				{
					Plugin.flashlightWasActive = false;
					return;
				}
				ulong playerClientId = ((GrabbableObject)__instance).playerHeldBy.playerClientId;
				if (playerClientId == Plugin.playerId)
				{
					if (Plugin.firstFlashlight)
					{
						if (Plugin.activeState.Colors.Count > 0 && Plugin.activeState.Mode == FlashlightMode.Fixed && Plugin.activeState.Colors[0] == Color.white)
						{
							HUDManager.Instance.DisplayTip("Change flashlight colour!", "Type 'cf' into the ship terminal for guidance!", false, false, "LC_Tip1");
						}
						Plugin.firstFlashlight = false;
					}
					if (on && !Plugin.flashlightWasActive && Plugin.activeState.Mode == FlashlightMode.Random)
					{
						Plugin.flashlightWasActive = true;
						int index;
						Color uniqueRandomColor = Helpers.GetUniqueRandomColor(Plugin.randomColours, Plugin.prevRandIndex, out index);
						Plugin.activeState.Colors[0] = uniqueRandomColor;
						Plugin.prevRandIndex = index;
						CFNetwork.Instance.SetPlayerColourServerRpc(Plugin.playerId, FlashlightMode.Random, FixedString128Bytes.op_Implicit(Helpers.ColorToHexString(uniqueRandomColor)), 0);
					}
					FlashlightData flashlight = new FlashlightData(__instance, Plugin.activeState.Colors, Plugin.activeState.Mode, Plugin.activeState.Speed);
					Plugin.flashlightHandler.SetFlashlight(flashlight);
					return;
				}
				CFPlayerData? playerData = CFNetwork.Instance.GetPlayerData(playerClientId);
				if (!playerData.HasValue)
				{
					Plugin.mls.LogDebug((object)$"No player data found - id {playerClientId}");
					return;
				}
				FlashlightData flashlightData = new FlashlightData(__instance, playerData.Value.GetColors(), playerData.Value.Mode, playerData.Value.Speed);
				if (!Plugin.config.syncCyclicFX.Value && flashlightData.Mode != 0)
				{
					flashlightData.Mode = FlashlightMode.Fixed;
					if (flashlightData.Colors.Count < 1)
					{
						flashlightData.Colors = new List<Color>(1) { Color.white };
					}
				}
				if (!Plugin.config.syncOthers.Value)
				{
					flashlightData.Mode = FlashlightMode.Fixed;
					flashlightData.Colors = new List<Color>(1) { Color.white };
				}
				Plugin.flashlightHandler.SetFlashlight(flashlightData);
			}
		}

		[HarmonyPatch(typeof(PlayerControllerB))]
		public class CFPlayerControllerBPatch
		{
			[HarmonyPatch("SpawnPlayerAnimation")]
			[HarmonyPostfix]
			public static void SpawnPlayerPatch(PlayerControllerB __instance)
			{
				//IL_0094: Unknown result type (might be due to invalid IL or missing references)
				if (__instance == null)
				{
					Plugin.mls.LogError((object)"PlayerControllerB instance is null");
					return;
				}
				Plugin.playerId = __instance.playerClientId;
				Plugin.playerMaxHealth = __instance.health;
				string text;
				FlashlightMode mode;
				if (!Plugin.config.syncOwn.Value || !Plugin.config.syncCyclicFX.Value)
				{
					text = "#FFFFFF";
					mode = FlashlightMode.Fixed;
				}
				else
				{
					text = Helpers.ColorsToHexString(Plugin.activeState.Colors);
					mode = Plugin.activeState.Mode;
				}
				CFNetwork.Instance.SetPlayerColourServerRpc(Plugin.playerId, mode, FixedString128Bytes.op_Implicit(text), Plugin.activeState.Speed);
				Plugin.mls.LogInfo((object)$"Player spawned with client id: {Plugin.playerId}");
			}

			[HarmonyPatch("Update")]
			[HarmonyPostfix]
			public static void UpdatePatch()
			{
				Plugin.flashlightHandler.CFUpdate(Time.deltaTime);
			}
		}

		[HarmonyPatch(typeof(NetworkBehaviour))]
		public class CFNetworkBehaviourPatch
		{
			[HarmonyPatch("OnDestroy")]
			[HarmonyPostfix]
			public static void OnDestroyPatch(NetworkBehaviour __instance)
			{
				FlashlightItem val = (FlashlightItem)(object)((__instance is FlashlightItem) ? __instance : null);
				if (val != null)
				{
					Plugin.flashlightHandler.RemoveFlashlight(val);
					Plugin.mls.LogDebug((object)"Flashlight destroyed. Removed from handler.");
				}
			}
		}

		[HarmonyPatch(typeof(RoundManager))]
		public class CFRoundManagerPatch
		{
			[HarmonyPatch("OnDestroy")]
			[HarmonyPostfix]
			public static void OnDestroyPatch(RoundManager __instance)
			{
				Plugin.flashlightHandler.Flashlights.Clear();
				Plugin.mls.LogDebug((object)"Game ended. Cleared handler.");
			}
		}
	}
	[BepInPlugin("Cubly.ColourfulFlashlights", "ColourfulFlashlights", "4.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string MOD_NAME = "ColourfulFlashlights";

		private const string MOD_GUID = "Cubly.ColourfulFlashlights";

		public const string MOD_VERSION = "4.0.1";

		public static string userPresetsPath = Path.Combine(Paths.ConfigPath, "ColourfulFlashlights", "UserPresets.json");

		public static string configPath = Path.Combine(Paths.ConfigPath, "ColourfulFlashlights", "Config.cfg");

		private readonly Harmony harmony = new Harmony("Cubly.ColourfulFlashlights");

		public static Plugin Instance;

		public static ConfigHandler config = new ConfigHandler();

		public static ManualLogSource mls;

		public static Dictionary<string, FlashlightState> UserPresets = new Dictionary<string, FlashlightState>();

		public static Dictionary<ulong, Color> PlayerColours = new Dictionary<ulong, Color>();

		public static ulong playerId;

		public static int playerMaxHealth = 100;

		public static bool firstFlashlight = true;

		public static FlashlightState activeState = new FlashlightState();

		public static bool flashlightWasActive = false;

		public static List<Color> randomColours = new List<Color>();

		public static int prevRandIndex = -1;

		public static FlashlightHandler flashlightHandler = new FlashlightHandler();

		private FileSystemWatcher watcher;

		private DateTime lastReload;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = Logger.CreateLogSource("Cubly.ColourfulFlashlights");
			config.Init();
			SaveHandler.Init();
			harmony.PatchAll();
			Assets.PopulateAssets();
			watcher = new FileSystemWatcher(Path.GetDirectoryName(configPath))
			{
				NotifyFilter = NotifyFilters.LastWrite
			};
			watcher.Changed += delegate(object _, FileSystemEventArgs e)
			{
				Thread.Sleep(100);
				if ((DateTime.Now - lastReload).TotalMilliseconds > 300.0)
				{
					lastReload = DateTime.Now;
					if (e.FullPath.EndsWith("UserPresets.json"))
					{
						mls.LogInfo((object)"Reloading user presets...");
						SaveHandler.LoadUserPresets();
					}
					else if (e.FullPath.EndsWith("Config.cfg"))
					{
						mls.LogInfo((object)"Reloading configuration...");
						config.configFile.Reload();
						mls.LogInfo((object)"Loaded configuration.");
					}
				}
			};
			watcher.EnableRaisingEvents = true;
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			mls.LogInfo((object)"ColourfulFlashlights 4.0.1 loaded!");
		}
	}
	public class UserData
	{
		public string name { get; set; }

		public FlashlightMode mode { get; set; } = FlashlightMode.Fixed;


		public int speed { get; set; } = 10;


		public List<string> colours { get; set; } = new List<string>();

	}
	internal class SaveHandler
	{
		public static void Init()
		{
			try
			{
				Directory.CreateDirectory(Path.GetDirectoryName(Plugin.userPresetsPath));
				if (!File.Exists(Plugin.userPresetsPath))
				{
					UserData item = new UserData
					{
						name = "example"
					};
					List<UserData> list = new List<UserData>(1) { item };
					string path = Path.Combine(Paths.ConfigPath, "Cubly.ColourfulFlashlights.cfg");
					if (File.Exists(path))
					{
						Plugin.mls.LogInfo((object)"Migrating old configuration to UserPresets.json");
						List<UserData> list2 = MigrateOldConfig();
						if (list2.Count > 0)
						{
							list = list2;
							File.Delete(path);
						}
					}
					string contents = JsonConvert.SerializeObject((object)list, (Formatting)1);
					File.WriteAllText(Plugin.userPresetsPath, contents);
					Plugin.mls.LogInfo((object)"Created UserPresets.json");
				}
			}
			catch (Exception ex)
			{
				Plugin.mls.LogInfo((object)"Error initialising ColourfulFlashlights save data.");
				Plugin.mls.LogError((object)ex.Message);
			}
			LoadData();
			LoadUserPresets();
		}

		public static void SaveData()
		{
			try
			{
				string path = Application.persistentDataPath + "\\ColourfulFlashlights.json";
				string contents = JsonUtility.ToJson((object)Plugin.activeState);
				File.WriteAllText(path, contents);
				Plugin.mls.LogInfo((object)"Data saved.");
			}
			catch (Exception ex)
			{
				Plugin.mls.LogInfo((object)"Error when saving data.");
				Plugin.mls.LogError((object)ex.Message);
			}
		}

		public static void LoadData()
		{
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string path = Application.persistentDataPath + "\\ColourfulFlashlights.json";
				string path2 = Application.persistentDataPath + "\\ColourfulFlashlights.txt";
				if (File.Exists(path))
				{
					string text = File.ReadAllText(path);
					FlashlightState flashlightState = JsonUtility.FromJson<FlashlightState>(text);
					if (flashlightState.Colors.Count == 0 && flashlightState.Mode != FlashlightMode.Random)
					{
						flashlightState.Colors.Add(Color.white);
						if (flashlightState.Mode == FlashlightMode.Health)
						{
							flashlightState.Colors.Add(Color.red);
						}
					}
					if (!Enum.IsDefined(typeof(FlashlightMode), flashlightState.Mode))
					{
						flashlightState.Mode = FlashlightMode.Fixed;
					}
					Plugin.activeState = flashlightState;
					Plugin.mls.LogInfo((object)"Loaded data from save.");
					if (File.Exists(path2))
					{
						File.Delete(path2);
						Plugin.mls.LogInfo((object)"Removed old save data.");
					}
				}
				else
				{
					Plugin.activeState.Colors.Add(Color.white);
					Plugin.mls.LogInfo((object)"Save file not found, loading defaults...");
				}
			}
			catch (Exception ex)
			{
				Plugin.activeState.Colors.Add(Color.white);
				Plugin.mls.LogInfo((object)"Invalid save file, loading defaults...");
				Plugin.mls.LogError((object)ex.Message);
			}
		}

		public static void LoadUserPresets()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			try
			{
				string userPresetsPath = Plugin.userPresetsPath;
				if (File.Exists(userPresetsPath))
				{
					string text = File.ReadAllText(userPresetsPath);
					if (string.IsNullOrWhiteSpace(text))
					{
						Plugin.mls.LogInfo((object)"No presets were loaded! UserPresets.json is empty!");
						return;
					}
					JsonSerializerSettings val = new JsonSerializerSettings
					{
						ObjectCreationHandling = (ObjectCreationHandling)2
					};
					List<UserData> list = JsonConvert.DeserializeObject<List<UserData>>(text, val);
					if (list != null)
					{
						Plugin.UserPresets.Clear();
						for (int i = 0; i < list.Count; i++)
						{
							UserData userData = list[i];
							string text2 = userData.name.Replace(" ", "").ToLowerInvariant();
							if (text2.Length > 15)
							{
								text2 = text2.Substring(0, 15);
							}
							if (Plugin.UserPresets.ContainsKey(text2))
							{
								continue;
							}
							UserData userData2 = userData;
							if (userData2.colours == null)
							{
								List<string> list3 = (userData2.colours = new List<string>());
							}
							userData.colours = userData.colours.Where((string c) => Helpers.IsValidHexCode(c)).ToList();
							if (userData.colours.Count == 0 && userData.mode != FlashlightMode.Random)
							{
								userData.colours.Add("#FFFFFF");
								if (userData.mode == FlashlightMode.Health)
								{
									userData.colours.Add("#FF0000");
								}
							}
							if (!Enum.IsDefined(typeof(FlashlightMode), userData.mode))
							{
								userData.mode = FlashlightMode.Fixed;
							}
							Plugin.UserPresets[text2] = new FlashlightState
							{
								Mode = userData.mode,
								Speed = Math.Clamp(userData.speed, 1, 20),
								Colors = Helpers.HexListToColors(userData.colours.Take(16).ToList())
							};
						}
						if (Plugin.UserPresets.Count > 0)
						{
							int count = Plugin.UserPresets.Count;
							Plugin.mls.LogInfo((object)string.Format("Loaded {0} user preset{1}.", count, (count > 1) ? "s" : ""));
						}
						else
						{
							Plugin.mls.LogInfo((object)"No presets were loaded!");
						}
					}
					else
					{
						Plugin.mls.LogInfo((object)"No presets were loaded! UserPresets.json is empty!");
					}
				}
				else
				{
					Plugin.mls.LogInfo((object)"No presets were loaded! UserPreset.json contains invalid data.");
				}
			}
			catch (Exception ex)
			{
				Plugin.mls.LogInfo((object)"Could not load user presets. Maybe the syntax is wrong?");
				Plugin.mls.LogError((object)ex.Message);
			}
		}

		public static bool SaveUserPreset(string name, FlashlightState state)
		{
			try
			{
				Plugin.mls.LogInfo((object)"Saving user presets...");
				if (Plugin.UserPresets.ContainsKey(name))
				{
					Plugin.UserPresets[name] = state;
				}
				else
				{
					Plugin.UserPresets.Add(name, state);
				}
				List<UserData> list = new List<UserData>();
				foreach (KeyValuePair<string, FlashlightState> userPreset in Plugin.UserPresets)
				{
					userPreset.Deconstruct(out var key, out var value);
					string name2 = key;
					FlashlightState flashlightState = value;
					UserData item = new UserData
					{
						name = name2,
						mode = flashlightState.Mode,
						speed = flashlightState.Speed,
						colours = Helpers.ColorsToHexList(flashlightState.Colors)
					};
					list.Add(item);
				}
				string userPresetsPath = Plugin.userPresetsPath;
				string contents = JsonConvert.SerializeObject((object)list, (Formatting)1);
				File.WriteAllText(Plugin.userPresetsPath, contents);
				Plugin.mls.LogInfo((object)"Saved user presets.");
				return true;
			}
			catch (Exception ex)
			{
				Plugin.mls.LogInfo((object)"Failed to save user presets!");
				Plugin.mls.LogError((object)ex.Message);
				return false;
			}
		}

		private static List<UserData> MigrateOldConfig()
		{
			ConfigEntry<string> val = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>("Custom Presets", "Custom 1", "", (ConfigDescription)null);
			ConfigEntry<string> val2 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>("Custom Presets", "Custom 2", "", (ConfigDescription)null);
			ConfigEntry<string> val3 = ((BaseUnityPlugin)Plugin.Instance).Config.Bind<string>("Custom Presets", "Custom 3", "", (ConfigDescription)null);
			ConfigEntry<string>[] array = new ConfigEntry<string>[3] { val, val2, val3 };
			List<UserData> list = new List<UserData>();
			((BaseUnityPlugin)Plugin.Instance).Config.Reload();
			ConfigEntry<string> val4 = default(ConfigEntry<string>);
			for (int i = 0; i < array.Length; i++)
			{
				if (((BaseUnityPlugin)Plugin.Instance).Config.TryGetEntry<string>(((ConfigEntryBase)array[i]).Definition, ref val4))
				{
					Plugin.mls.LogInfo((object)$"cfg {i} - val: {val4.Value}");
					list.Add(new UserData
					{
						name = (i + 1).ToString(),
						speed = 0,
						mode = FlashlightMode.Fixed,
						colours = new List<string>(1) { val4.Value }
					});
				}
				((BaseUnityPlugin)Plugin.Instance).Config.Remove(((ConfigEntryBase)array[i]).Definition);
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(TerminalEvent))]
	public static class TerminalPatch
	{
		public static Terminal terminal;

		private static bool modifiedOtherNode;

		private static string presetNameToSave;

		[HarmonyPatch(typeof(Terminal), "Awake")]
		[HarmonyPostfix]
		public static void TerminalAwake(Terminal __instance)
		{
			terminal = __instance;
		}

		[HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")]
		[HarmonyPostfix]
		private static void OnBeginUsingTerminal(Terminal __instance)
		{
			if (modifiedOtherNode)
			{
				return;
			}
			modifiedOtherNode = true;
			TerminalKeyword[] allKeywords = __instance.terminalNodes.allKeywords;
			foreach (TerminalKeyword val in allKeywords)
			{
				if (((Object)val).name == "Other")
				{
					TerminalNode specialKeywordResult = val.specialKeywordResult;
					string text = ">SCAN\nTo scan for the number of items left on the current planet.";
					string value = "\n\n>CF\nTo customise the colour of your flashlight.";
					int num = specialKeywordResult.displayText.IndexOf(text);
					if (num > -1)
					{
						int startIndex = num + text.Length;
						specialKeywordResult.displayText = specialKeywordResult.displayText.Insert(startIndex, value);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
		[HarmonyPrefix]
		private static bool ParsePlayerSentence(ref TerminalNode __result, Terminal __instance)
		{
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_076c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0771: Unknown result type (might be due to invalid IL or missing references)
			//IL_0785: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_07de: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f2: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.screenText.text.Length < 1)
			{
				return true;
			}
			string text = __instance.screenText.text;
			int textAdded = __instance.textAdded;
			int length = text.Length;
			int num = length - textAdded;
			string text2 = text.Substring(num, length - num).ToLowerInvariant().Trim();
			string[] array = text2.Split(' ');
			if (array.Length == 0)
			{
				return true;
			}
			if (presetNameToSave != null)
			{
				if ("confirm".StartsWith(text2))
				{
					if (SaveHandler.SaveUserPreset(presetNameToSave, Plugin.activeState))
					{
						__result = SuccessNode("Overwrote the preset with name: " + presetNameToSave + "\n\nTo use this preset at anytime, enter:\ncf preset " + presetNameToSave);
					}
					else
					{
						__result = ErrorNode("There was an error trying to save user presets.\n\nPlease try again.");
					}
					presetNameToSave = null;
					return false;
				}
				__result = CustomNode("Cancelled preset save operation!\n\nYour preset: '" + presetNameToSave + "' was not overwritten.");
				presetNameToSave = null;
				return true;
			}
			if (array[0] == "cf")
			{
				if (array.Length == 1)
				{
					__result = BaseNode();
					return false;
				}
				switch (array[1])
				{
				case "help":
					__result = HelpNode();
					return false;
				case "rainbow":
				{
					int speedFromArgs2 = Helpers.GetSpeedFromArgs(array);
					Helpers.UpdateState(new List<Color>(1) { Color.white }, FlashlightMode.Rainbow, speedFromArgs2);
					__result = SuccessNode("'Rainbow' effect applied!\n\n[New State]\n" + Helpers.GetStateText(Plugin.activeState));
					return false;
				}
				case "disco":
				{
					int speedFromArgs = Helpers.GetSpeedFromArgs(array);
					List<Color> colours3 = new List<Color>(5)
					{
						Color.red,
						Color.blue,
						Color.green,
						Color.magenta,
						Color.yellow
					};
					Helpers.UpdateState(colours3, FlashlightMode.Cycle, speedFromArgs);
					__result = SuccessNode("'Disco' effect applied!\n\n[New State]\n" + Helpers.GetStateText(Plugin.activeState));
					return false;
				}
				case "random":
					Helpers.UpdateState(new List<Color>(), FlashlightMode.Random, 0);
					__result = SuccessNode("'Random' effect applied!\n\n[New State]\n" + Helpers.GetStateText(Plugin.activeState));
					return false;
				case "health":
					Helpers.UpdateState(new List<Color>(2)
					{
						Color.white,
						Color.red
					}, FlashlightMode.Health, 0);
					__result = SuccessNode("'Health' effect applied!\n\n[New State]\n" + Helpers.GetStateText(Plugin.activeState));
					return false;
				case "state":
					__result = CustomNode("[Current State]\n" + Helpers.GetStateText(Plugin.activeState) + "\n");
					return false;
				case "preset":
				{
					FlashlightState value;
					if (array.Length < 3)
					{
						if (Plugin.UserPresets.Count > 0)
						{
							__result = CustomNode("You can create custom presets in the UserPresets.json configuration file. Find more information on the plugin's Thunderstore page.\n\n[Current Presets]\n" + string.Join(", ", Plugin.UserPresets.Keys) + "\n\nExample usage: cf preset " + Plugin.UserPresets.Keys.First() + "\n");
						}
						else
						{
							__result = CustomNode("You can create custom presets in the UserPresets.json configuration file. Find more information on the plugin's Thunderstore page.\n\n[Current Presets]\nNo presets were found!\n\nMake sure to correctly define presets in UserPresets.json\n");
						}
					}
					else if (Plugin.UserPresets.TryGetValue(array[2], out value))
					{
						Helpers.UpdateState(value.Colors, value.Mode, value.Speed);
						__result = CustomNode("Preset applied!\n\n[New State]\n" + Helpers.GetStateText(Plugin.activeState, array[2]) + "\n");
					}
					else if (Plugin.UserPresets.Count > 0)
					{
						__result = CustomNode("The preset '" + array[2] + "' could not be found!\n\n[Current Presets]\n" + string.Join(", ", Plugin.UserPresets.Keys) + "\n\nExample usage: cf preset " + Plugin.UserPresets.Keys.First());
					}
					else
					{
						__result = CustomNode("The preset '" + array[2] + "' could not be found!\n\n[Current Presets]\nNo presets were found!\n\nMake sure to correctly define presets in UserPresets.json");
					}
					return false;
				}
				case "speed":
				{
					FlashlightMode mode = Plugin.activeState.Mode;
					if ((mode == FlashlightMode.Fixed || (uint)(mode - 3) <= 1u) ? true : false)
					{
						__result = CustomNode($"Your flashlight is set to: {Plugin.activeState.Mode}\n\nThe speed setting is not used for this mode.");
					}
					else if (array.Length < 3)
					{
						__result = ErrorNode("Please provide a speed [1-20]\nHigher is faster.\n\ne.g. cf speed 8");
					}
					else
					{
						FlashlightState activeState = Plugin.activeState;
						int speedFromArgs3 = Helpers.GetSpeedFromArgs(array);
						Helpers.UpdateState(activeState.Colors, activeState.Mode, speedFromArgs3);
						__result = SuccessNode($"Speed updated [{activeState.Speed} -> {speedFromArgs3}]\n\n[New State]\n{Helpers.GetStateText(Plugin.activeState)}");
					}
					return false;
				}
				case "save":
					if (array.Length < 3)
					{
						__result = ErrorNode("A name for the preset was not provided!\n\nPlease provide a name, for example:\ncf save mypreset\n\nIf you provide the name of an existing preset, that preset will be overwritten. Preset names are case-insensitive and can be a maximum of 15 characters long.");
					}
					else
					{
						string text3 = array[2].Trim().ToLowerInvariant();
						if (text3.Length > 15)
						{
							__result = ErrorNode($"Preset name too long!\n\nYour preset name was {text3.Length}.\nThe maximum length is 15 characters.");
							return false;
						}
						if (Plugin.UserPresets.ContainsKey(text3))
						{
							presetNameToSave = text3;
							__result = ConfirmSaveNode(text3);
						}
						else if (SaveHandler.SaveUserPreset(text3, Plugin.activeState))
						{
							__result = SuccessNode("Saved the current flashlight state as a new preset with name: " + text3 + "\n\nTo use this preset at anytime, enter:\ncf preset " + text3);
						}
						else
						{
							__result = ErrorNode("There was an error trying to save user presets.\n\nPlease try again.");
						}
					}
					return false;
				default:
				{
					Color? val = Helpers.NameToColor(array[1]);
					if (val.HasValue)
					{
						Color valueOrDefault = val.GetValueOrDefault();
						if (true)
						{
							List<Color> colours = new List<Color>(1) { valueOrDefault };
							Helpers.UpdateState(colours, FlashlightMode.Fixed, 0);
							__result = SuccessNode("Colour " + array[1] + " applied!\n\n[New State]\n" + Helpers.GetStateText(Plugin.activeState));
							goto IL_083f;
						}
					}
					val = Helpers.HexStringToColor(array[1]);
					if (val.HasValue)
					{
						Color valueOrDefault2 = val.GetValueOrDefault();
						if (true)
						{
							List<Color> colours2 = new List<Color>(1) { valueOrDefault2 };
							Helpers.UpdateState(colours2, FlashlightMode.Fixed, 0);
							__result = SuccessNode("Colour " + array[1] + " applied!\n\n[New State]\n" + Helpers.GetStateText(Plugin.activeState));
							goto IL_083f;
						}
					}
					__result = ErrorNode("Please provide a valid colour or command!\n\nExamples:   cf purple   cf #FF00CC\n\nEnter  cf help  for a list of commands.");
					goto IL_083f;
				}
				case null:
					break;
					IL_083f:
					return false;
				}
			}
			return true;
		}

		private static TerminalNode BaseNode()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			return new TerminalNode
			{
				displayText = "[ColourfulFlashlights] Version 4.0.0\n\nCustomise your flashlight colour!\n\nBasic usage:\n\n>CF [colour]       e.g.  cf purple\n\nValid colours: white, blue, red, yellow, orange, green, pink, purple\n\nYou can also use a hex code, e.g.  cf #FF00DD\n\n>CF HELP\nFor more options and a list of colour names\n\n\n",
				clearPreviousText = true,
				acceptAnything = false
			};
		}

		private static TerminalNode HelpNode()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			return new TerminalNode
			{
				displayText = "[ColourfulFlashlights]\n\n>CF [colour]        e.g.  cf #ff00dd\nUse a colour name (see below) or hex code\n\n>CF PRESET [name]   e.g.  cf preset 2\nLoad a preset by name from UserPresets.json\n\n>CF SPEED [1-20]\nChange the speed of an effect\n\n>CF [effect] [speed]\nUse a built-in effect: random, rainbow, disco\n\nValid colour names:\nwhite, blue, red, yellow, orange, green, pink, purple\n\n",
				clearPreviousText = true,
				acceptAnything = false
			};
		}

		private static TerminalNode SuccessNode(string text)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			return new TerminalNode
			{
				displayText = "[ColourfulFlashlights]\n\nSUCCESS!\n\n" + text + "\n\n\n",
				clearPreviousText = true,
				acceptAnything = false
			};
		}

		private static TerminalNode ErrorNode(string text)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			return new TerminalNode
			{
				displayText = "[ColourfulFlashlights]\n\nERROR!\n\n" + text + "\n\n\n",
				clearPreviousText = true,
				acceptAnything = false
			};
		}

		private static TerminalNode CustomNode(string text)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			return new TerminalNode
			{
				displayText = "[ColourfulFlashlights]\n\n" + text + "\n\n",
				clearPreviousText = true,
				acceptAnything = false
			};
		}

		private static TerminalNode ConfirmSaveNode(string presetName)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0032: Expected O, but got Unknown
			return new TerminalNode
			{
				displayText = "[ColourfulFlashlights]\n\nEXISTING PRESET!\n\nYou are about to overwrite the preset: " + presetName + "\n\nPlease CONFIRM or DENY.\n\n\n",
				isConfirmationNode = true,
				acceptAnything = false,
				clearPreviousText = true
			};
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ColourfulFlashlights";

		public const string PLUGIN_NAME = "ColourfulFlashlights";

		public const string PLUGIN_VERSION = "4.0.1";
	}
}
namespace ColourfulFlashlights.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("ColourfulFlashlights.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] cfasset
		{
			get
			{
				object @object = ResourceManager.GetObject("cfasset", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
			NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable<CFPlayerData>();
			NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<CFPlayerData>();
		}
	}
}
namespace ColourfulFlashlights.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}