Decompiled source of BiggerSprayMod v1.6.2

BiggerSprayMod.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BiggerSprayMod.gif;
using BiggerSprayMod.web;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.Networking;

[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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("MishaOpstal")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.3.1.0")]
[assembly: AssemblyInformationalVersion("1.3.1+b75a1a6532e758488b8f4bd86fd642315808bc77")]
[assembly: AssemblyProduct("BiggerSprayMod")]
[assembly: AssemblyTitle("BiggerSprayMod")]
[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.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;
		}
	}
}
namespace BiggerSprayMod
{
	[BepInPlugin("MishaOpstal.BigSprayMod", "Bigger Spray Mod", "1.6.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BiggerSprayMod : BaseUnityPlugin, IOnEventCallback
	{
		[CompilerGenerated]
		private sealed class <ScheduleSprayRemoval>d__42 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string sprayId;

			public float lifetime;

			public BiggerSprayMod <>4__this;

			private bool <removed>5__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (string.IsNullOrEmpty(sprayId) || lifetime <= 0f)
					{
						return false;
					}
					<>4__this._sprayExpirationTimes[sprayId] = Time.time + lifetime;
					<>2__current = (object)new WaitForSeconds(lifetime);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<removed>5__1 = <>4__this._sprayUtils.RemoveSprayById(sprayId);
					if (<removed>5__1 && PhotonNetwork.IsConnected && PhotonNetwork.IsMasterClient)
					{
						<>4__this._networkUtils.SendRemoveSprayToNetwork(sprayId);
						<>4__this._sprayExpirationTimes.Remove(sprayId);
						if (<>4__this._sprayRemovalCoroutines.ContainsKey(sprayId))
						{
							<>4__this._sprayRemovalCoroutines.Remove(sprayId);
						}
						<>4__this.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Host removed spray " + sprayId + " and notified clients");
					}
					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();
			}
		}

		public float _lastSprayTime = -999f;

		public const float CooldownTime = 0.5f;

		public Texture2D? _cachedSprayTexture;

		public List<string> _availableImages = new List<string>();

		public string? _imagesFolderPath;

		public readonly List<GameObject> _spawnedSprays = new List<GameObject>();

		public Material _sprayMaterialTemplate;

		public Material _previewMaterialTemplate;

		public float _hostSprayLifetime = 60f;

		public int _hostMaxSprays = 10;

		public bool _registeredCallbacks;

		private Dictionary<string, float> _sprayExpirationTimes = new Dictionary<string, float>();

		public Dictionary<string, Coroutine> _sprayRemovalCoroutines = new Dictionary<string, Coroutine>();

		private float _lastHostCleanupTime = 0f;

		private const float HostCleanupInterval = 1f;

		public bool _isScaling = false;

		public float _currentScalePreview;

		public GameObject _scalePreviewObject;

		public Vector2 _originalImageDimensions = new Vector2(1f, 1f);

		public ConfigManager _configManager;

		public InputManager _inputManager;

		public ScalingUtils _scalingUtils;

		public ImageUtils _imageUtils;

		public SprayUtils _sprayUtils;

		public NetworkUtils _networkUtils;

		public WebUtils _webUtils;

		public GifManager _gifManager;

		public GifAssetManager _gifAssetManager;

		public TmpFilesUploader _tmpFilesUploader;

		public static BiggerSprayMod Instance { get; private set; }

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			_configManager = new ConfigManager(this);
			_inputManager = new InputManager(this);
			_scalingUtils = new ScalingUtils(this);
			_imageUtils = new ImageUtils(this);
			_sprayUtils = new SprayUtils(this);
			_webUtils = new WebUtils(this);
			_networkUtils = new NetworkUtils(this);
			_gifManager = new GifManager(this, _webUtils);
			_gifAssetManager = new GifAssetManager(this, _webUtils);
			_tmpFilesUploader = new TmpFilesUploader(this);
			_imagesFolderPath = Path.Combine(Paths.ConfigPath, "BiggerSprayImages");
			_imageUtils.LoadAvailableImages();
			_configManager.Initialize();
			_sprayUtils.CreateSprayPrefabs();
			string filePath = Path.Combine(_imagesFolderPath, _configManager.SelectedSprayImage.Value);
			_cachedSprayTexture = _imageUtils.LoadTexture(filePath);
			if ((Object)(object)_cachedSprayTexture != (Object)null)
			{
				_originalImageDimensions = new Vector2((float)((Texture)_cachedSprayTexture).width, (float)((Texture)_cachedSprayTexture).height);
			}
			Patch();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[BiggerSprayMod] Initialized successfully.");
		}

		private void OnDestroy()
		{
			if (_registeredCallbacks)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
			}
			foreach (GameObject spawnedSpray in _spawnedSprays)
			{
				if ((Object)(object)spawnedSpray != (Object)null)
				{
					Object.Destroy((Object)(object)spawnedSpray);
				}
			}
			_spawnedSprays.Clear();
			if ((Object)(object)_scalePreviewObject != (Object)null)
			{
				Object.Destroy((Object)(object)_scalePreviewObject);
				_scalePreviewObject = null;
			}
			if (_webUtils != null)
			{
				_webUtils.DisposeAllGifs();
			}
			if (_gifAssetManager != null)
			{
				_gifAssetManager.Dispose();
			}
			if (_tmpFilesUploader != null)
			{
				_tmpFilesUploader.CleanupExpiredCache();
				_tmpFilesUploader.DisposeTextures();
			}
			if ((Object)(object)_cachedSprayTexture != (Object)null)
			{
				_cachedSprayTexture = null;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[BiggerSprayMod] Plugin resources cleaned up on destroy");
		}

		internal void Patch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
			if (!_registeredCallbacks && PhotonNetwork.IsConnected)
			{
				PhotonNetwork.AddCallbackTarget((object)this);
				_registeredCallbacks = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[BiggerSprayMod] Registered for Photon callbacks.");
			}
			_inputManager.ProcessInputs();
			_sprayUtils.CheckForRefreshSprays();
			CheckForRefreshGifs();
			_gifManager.Update();
			if (Time.frameCount % 3600 == 0)
			{
				_gifAssetManager.CleanupOldAssets();
				_tmpFilesUploader.CleanupExpiredCache();
				_tmpFilesUploader.CleanupDownloadCache();
			}
			if (PhotonNetwork.IsMasterClient && PhotonNetwork.IsConnected && Time.time > _lastHostCleanupTime + 1f)
			{
				UpdateHostSprayManagement();
				_lastHostCleanupTime = Time.time;
			}
		}

		[IteratorStateMachine(typeof(<ScheduleSprayRemoval>d__42))]
		public IEnumerator ScheduleSprayRemoval(string sprayId, float lifetime)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ScheduleSprayRemoval>d__42(0)
			{
				<>4__this = this,
				sprayId = sprayId,
				lifetime = lifetime
			};
		}

		private void UpdateHostSprayManagement()
		{
			if (!PhotonNetwork.IsMasterClient || !PhotonNetwork.IsConnected)
			{
				return;
			}
			float time = Time.time;
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, float> sprayExpirationTime in _sprayExpirationTimes)
			{
				if (time >= sprayExpirationTime.Value)
				{
					list.Add(sprayExpirationTime.Key);
				}
			}
			foreach (string item in list)
			{
				if (_sprayRemovalCoroutines.TryGetValue(item, out Coroutine value))
				{
					if (value != null)
					{
						((MonoBehaviour)this).StopCoroutine(value);
					}
					_sprayRemovalCoroutines.Remove(item);
				}
				if (_sprayUtils.RemoveSprayById(item))
				{
					_networkUtils.SendRemoveSprayToNetwork(item);
					LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Host removed expired spray " + item);
				}
				_sprayExpirationTimes.Remove(item);
			}
			EnforceMaxSprays();
		}

		private void EnforceMaxSprays()
		{
			if (!PhotonNetwork.IsMasterClient || !PhotonNetwork.IsConnected)
			{
				return;
			}
			int value = _configManager.MaxSpraysAllowed.Value;
			if (_spawnedSprays.Count <= value)
			{
				return;
			}
			int num = _spawnedSprays.Count - value;
			for (int i = 0; i < num && i < _spawnedSprays.Count; i++)
			{
				GameObject val = _spawnedSprays[0];
				if ((Object)(object)val != (Object)null)
				{
					SprayIdentifier component = val.GetComponent<SprayIdentifier>();
					if ((Object)(object)component != (Object)null && !string.IsNullOrEmpty(component.SprayId))
					{
						string sprayId = component.SprayId;
						if (_sprayRemovalCoroutines.TryGetValue(sprayId, out Coroutine value2))
						{
							if (value2 != null)
							{
								((MonoBehaviour)this).StopCoroutine(value2);
							}
							_sprayRemovalCoroutines.Remove(sprayId);
						}
						_sprayUtils.RemoveSprayById(sprayId);
						_networkUtils.SendRemoveSprayToNetwork(sprayId);
						_sprayExpirationTimes.Remove(sprayId);
						LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Host removed oldest spray " + sprayId + " to enforce limit");
					}
					else
					{
						_spawnedSprays.Remove(val);
						Object.Destroy((Object)(object)val);
					}
				}
				else
				{
					_spawnedSprays.RemoveAt(0);
				}
			}
		}

		private void CheckForRefreshGifs()
		{
			if (_configManager.RefreshGifsButton.Value)
			{
				LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Refreshing GIFs list...");
				_gifManager.RefreshGifList();
				_configManager.RefreshGifsButton.Value = false;
				LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] GIFs list refreshed successfully.");
			}
			if (_configManager.OpenGifConfigFolderButton.Value)
			{
				_gifManager.OpenGifConfigFolder();
				_configManager.OpenGifConfigFolderButton.Value = false;
			}
		}

		public void OnEvent(EventData photonEvent)
		{
			_networkUtils.OnNetworkEvent(photonEvent);
		}

		public void LogMessage(Enum messageType, string message)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			if (messageType is LogLevel val)
			{
				if ((int)val <= 4)
				{
					if ((int)val == 2)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)message);
						return;
					}
					if ((int)val == 4)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)message);
						return;
					}
				}
				else
				{
					if ((int)val == 16)
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)message);
						return;
					}
					if ((int)val == 32)
					{
						((BaseUnityPlugin)this).Logger.LogDebug((object)message);
						return;
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)message);
		}

		public string GetPluginPath()
		{
			string location = Assembly.GetExecutingAssembly().Location;
			if (string.IsNullOrEmpty(location))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"[BiggerSprayMod] Failed to get plugin path.");
				return string.Empty;
			}
			return location;
		}

		public void UpdateAllSprayLifetimes()
		{
			if (!PhotonNetwork.IsMasterClient || !PhotonNetwork.IsConnected)
			{
				return;
			}
			float value = _configManager.SprayLifetimeSeconds.Value;
			float time = Time.time;
			Dictionary<string, float> dictionary = new Dictionary<string, float>();
			LogMessage((Enum)(object)(LogLevel)16, $"[BiggerSprayMod] Host updating all spray lifetimes to {value} seconds");
			if (value <= 0f)
			{
				foreach (Coroutine value3 in _sprayRemovalCoroutines.Values)
				{
					if (value3 != null)
					{
						((MonoBehaviour)this).StopCoroutine(value3);
					}
				}
				_sprayRemovalCoroutines.Clear();
				_sprayExpirationTimes.Clear();
				LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] All sprays set to permanent (no expiration)");
				return;
			}
			foreach (GameObject spawnedSpray in _spawnedSprays)
			{
				if ((Object)(object)spawnedSpray == (Object)null)
				{
					continue;
				}
				SprayIdentifier component = spawnedSpray.GetComponent<SprayIdentifier>();
				if (!((Object)(object)component == (Object)null) && !string.IsNullOrEmpty(component.SprayId))
				{
					string sprayId = component.SprayId;
					if (_sprayRemovalCoroutines.TryGetValue(sprayId, out Coroutine value2) && value2 != null)
					{
						((MonoBehaviour)this).StopCoroutine(value2);
					}
					dictionary[sprayId] = time + value;
					_sprayRemovalCoroutines[sprayId] = ((MonoBehaviour)this).StartCoroutine(ScheduleSprayRemoval(sprayId, value));
				}
			}
			_sprayExpirationTimes = dictionary;
			LogMessage((Enum)(object)(LogLevel)16, $"[BiggerSprayMod] Updated {dictionary.Count} spray lifetimes");
		}
	}
	[HarmonyPatch(typeof(ChatManager))]
	public class ChatManagerPatches
	{
		[HarmonyPatch("MessageSend")]
		[HarmonyPrefix]
		private static bool MessageSendPreFix(ChatManager __instance, bool _possessed)
		{
			if (Regex.IsMatch(__instance.chatMessage, "^\\/addgifspray\\s+(.+)$"))
			{
				Match match = Regex.Match(__instance.chatMessage, "^\\/addgifspray\\s+(.+)$");
				if (match.Success && match.Groups.Count > 1)
				{
					string text = match.Groups[1].Value.Trim();
					if (string.IsNullOrWhiteSpace(text))
					{
						__instance.chatMessage = "GIF name cannot be empty!";
						return true;
					}
					text = GifDataSender.SanitizeGifName(text);
					string systemCopyBuffer = GUIUtility.systemCopyBuffer;
					if (string.IsNullOrWhiteSpace(systemCopyBuffer) || !systemCopyBuffer.StartsWith("http"))
					{
						__instance.chatMessage = "Invalid URL in clipboard!";
						return true;
					}
					if (!BiggerSprayMod.Instance._webUtils.IsTrustedUrl(systemCopyBuffer))
					{
						__instance.chatMessage = "URL is not trusted!";
						return true;
					}
					if (AddGifToConfig(text, systemCopyBuffer))
					{
						BiggerSprayMod.Instance._gifManager.RefreshGifList();
						__instance.chatMessage = "Added GIF: " + text;
					}
					else
					{
						__instance.chatMessage = "Failed to add GIF!";
					}
					return true;
				}
			}
			if (Regex.IsMatch(__instance.chatMessage, "^\\/addspray\\s+(.+)$"))
			{
				Match match2 = Regex.Match(__instance.chatMessage, "^\\/addspray\\s+(.+)$");
				if (match2.Success && match2.Groups.Count > 1)
				{
					string sprayName = match2.Groups[1].Value.Trim();
					if (string.IsNullOrWhiteSpace(sprayName))
					{
						__instance.chatMessage = "Spray name cannot be empty!";
						return true;
					}
					sprayName = GifDataSender.SanitizeGifName(sprayName);
					string systemCopyBuffer2 = GUIUtility.systemCopyBuffer;
					if (string.IsNullOrWhiteSpace(systemCopyBuffer2) || !systemCopyBuffer2.StartsWith("http"))
					{
						__instance.chatMessage = "Invalid URL in clipboard!";
						return true;
					}
					if (!BiggerSprayMod.Instance._webUtils.IsTrustedUrl(systemCopyBuffer2))
					{
						__instance.chatMessage = "URL is not trusted!";
						return true;
					}
					((MonoBehaviour)BiggerSprayMod.Instance).StartCoroutine(BiggerSprayMod.Instance._webUtils.DownloadImageCoroutine(systemCopyBuffer2, sprayName, delegate(bool success)
					{
						if (success)
						{
							BiggerSprayMod.Instance._imageUtils.LoadAvailableImages();
							BiggerSprayMod.Instance._configManager.UpdateImageListConfig();
							BiggerSprayMod.Instance.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Added spray image: " + sprayName);
						}
						else
						{
							BiggerSprayMod.Instance.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Failed to add spray image: " + sprayName);
						}
					}));
					__instance.chatMessage = "Downloading spray: " + sprayName + "...";
					return true;
				}
			}
			return true;
		}

		private static bool AddGifToConfig(string gifName, string gifUrl)
		{
			try
			{
				string path = Path.Combine(Paths.ConfigPath, "BiggerSprayGifs.json");
				GifConfig gifConfig = ((!File.Exists(path)) ? GifConfig.CreateDefault() : GifConfig.Load(path));
				bool flag = false;
				foreach (GifEntry gif in gifConfig.Gifs)
				{
					if (gif.Name.Equals(gifName, StringComparison.OrdinalIgnoreCase))
					{
						gif.Url = gifUrl;
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					gifConfig.Gifs.Add(new GifEntry
					{
						Name = gifName,
						Url = gifUrl
					});
				}
				gifConfig.Save(path);
				return true;
			}
			catch (Exception)
			{
				return false;
			}
		}
	}
	public class ConfigManager
	{
		private readonly BiggerSprayMod _plugin;

		public ConfigEntry<KeyCode> SprayKey;

		public ConfigEntry<KeyCode> PreviousSprayKey;

		public ConfigEntry<KeyCode> NextSprayKey;

		public ConfigEntry<KeyCode> ScaleKey;

		public ConfigEntry<KeyCode> IncreaseScaleKey;

		public ConfigEntry<KeyCode> DecreaseScaleKey;

		public ConfigEntry<KeyCode> ToggleGifModeKey;

		public ConfigEntry<float> SprayScale;

		public ConfigEntry<float> SprayLifetimeSeconds;

		public ConfigEntry<int> MaxSpraysAllowed;

		public ConfigEntry<string> SelectedSprayImage;

		public ConfigEntry<string> SelectedGifName;

		public ConfigEntry<bool> RefreshSpraysButton;

		public ConfigEntry<bool> RefreshGifsButton;

		public ConfigEntry<bool> OpenGifConfigFolderButton;

		public ConfigEntry<bool> OpenImagesFolderButton;

		public ConfigEntry<Color> ScalePreviewColor;

		public ConfigEntry<float> MinScaleSize;

		public ConfigEntry<float> MaxScaleSize;

		public ConfigEntry<float> ScaleSpeed;

		public ConfigEntry<bool> UseScrollWheel;

		public ConfigEntry<bool> ShowSprayIfLarge;

		public ConfigEntry<float> GifAnimationFps;

		public ConfigEntry<bool> AnimateGifsInWorld;

		public ConfigManager(BiggerSprayMod plugin)
		{
			_plugin = plugin;
		}

		public void Initialize()
		{
			SetupConfig();
		}

		private void SetupConfig()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Expected O, but got Unknown
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Expected O, but got Unknown
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Expected O, but got Unknown
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Expected O, but got Unknown
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Expected O, but got Unknown
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Expected O, but got Unknown
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Expected O, but got Unknown
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Expected O, but got Unknown
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Expected O, but got Unknown
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Expected O, but got Unknown
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Expected O, but got Unknown
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Expected O, but got Unknown
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Expected O, but got Unknown
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Expected O, but got Unknown
			//IL_04ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f8: Expected O, but got Unknown
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Expected O, but got Unknown
			//IL_0574: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Expected O, but got Unknown
			//IL_05b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c1: Expected O, but got Unknown
			//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0604: Expected O, but got Unknown
			//IL_0633: Unknown result type (might be due to invalid IL or missing references)
			//IL_0643: Unknown result type (might be due to invalid IL or missing references)
			//IL_064d: Expected O, but got Unknown
			if (_plugin._availableImages == null || _plugin._availableImages.Count == 0)
			{
				_plugin._availableImages = new List<string>(1) { "DefaultSpray.png" };
			}
			SprayLifetimeSeconds = ((BaseUnityPlugin)_plugin).Config.Bind<float>("Host Settings", "Spray Lifetime (Seconds)", 60f, new ConfigDescription("How long the spray should last. Set to 0 for permanent sprays.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 300f), Array.Empty<object>()));
			SprayLifetimeSeconds.SettingChanged += delegate
			{
				if (PhotonNetwork.IsMasterClient && PhotonNetwork.IsConnected)
				{
					_plugin.UpdateAllSprayLifetimes();
				}
			};
			MaxSpraysAllowed = ((BaseUnityPlugin)_plugin).Config.Bind<int>("Host Settings", "Max Sprays", 10, new ConfigDescription("Maximum number of sprays before the oldest is deleted.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			SelectedSprayImage = ((BaseUnityPlugin)_plugin).Config.Bind<string>("Spray Settings", "Selected Spray Image", _plugin._availableImages.FirstOrDefault() ?? "DefaultSpray.png", new ConfigDescription("The image used for spraying.", (AcceptableValueBase)(object)new AcceptableValueList<string>(_plugin._availableImages.ToArray()), Array.Empty<object>()));
			SelectedSprayImage.SettingChanged += delegate
			{
				//IL_008f: 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)
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Image selection changed. Reloading texture...");
				string filePath = Path.Combine(_plugin._imagesFolderPath, SelectedSprayImage.Value);
				_plugin._cachedSprayTexture = _plugin._imageUtils.LoadTexture(filePath);
				if ((Object)(object)_plugin._cachedSprayTexture != (Object)null)
				{
					_plugin._originalImageDimensions = new Vector2((float)((Texture)_plugin._cachedSprayTexture).width, (float)((Texture)_plugin._cachedSprayTexture).height);
				}
			};
			RefreshSpraysButton = ((BaseUnityPlugin)_plugin).Config.Bind<bool>("Spray Settings", "Refresh Sprays", false, new ConfigDescription("Set to TRUE to refresh the list of available sprays.", (AcceptableValueBase)null, Array.Empty<object>()));
			SprayKey = ((BaseUnityPlugin)_plugin).Config.Bind<KeyCode>("Spray Settings", "Spray Key", (KeyCode)102, new ConfigDescription("The key used to spray.", (AcceptableValueBase)null, Array.Empty<object>()));
			PreviousSprayKey = ((BaseUnityPlugin)_plugin).Config.Bind<KeyCode>("Spray Settings", "Previous Spray/GIF Key", (KeyCode)276, new ConfigDescription("The key used to select the previous spray image or GIF.", (AcceptableValueBase)null, Array.Empty<object>()));
			NextSprayKey = ((BaseUnityPlugin)_plugin).Config.Bind<KeyCode>("Spray Settings", "Next Spray/GIF Key", (KeyCode)275, new ConfigDescription("The key used to select the next spray image or GIF.", (AcceptableValueBase)null, Array.Empty<object>()));
			ShowSprayIfLarge = ((BaseUnityPlugin)_plugin).Config.Bind<bool>("Spray Settings", "Show spray if it exceeds the size limit locally", true, new ConfigDescription("Show the spray even if the image is large (Locally).", (AcceptableValueBase)null, Array.Empty<object>()));
			OpenImagesFolderButton = ((BaseUnityPlugin)_plugin).Config.Bind<bool>("Spray Settings", "Open Images Folder", false, new ConfigDescription("Set to TRUE to open the folder containing the spray images.", (AcceptableValueBase)null, Array.Empty<object>()));
			ToggleGifModeKey = ((BaseUnityPlugin)_plugin).Config.Bind<KeyCode>("GIF Settings", "Toggle GIF Mode Key", (KeyCode)103, new ConfigDescription("The key used to toggle between regular spray and GIF mode.", (AcceptableValueBase)null, Array.Empty<object>()));
			RefreshGifsButton = ((BaseUnityPlugin)_plugin).Config.Bind<bool>("GIF Settings", "Refresh GIFs", false, new ConfigDescription("Set to TRUE to refresh the list of available GIFs from configuration file.", (AcceptableValueBase)null, Array.Empty<object>()));
			OpenGifConfigFolderButton = ((BaseUnityPlugin)_plugin).Config.Bind<bool>("GIF Settings", "Open GIF Config Folder", false, new ConfigDescription("Set to TRUE to open the folder containing the GIF configuration file.", (AcceptableValueBase)null, Array.Empty<object>()));
			GifAnimationFps = ((BaseUnityPlugin)_plugin).Config.Bind<float>("GIF Settings", "GIF Animation FPS", 30f, new ConfigDescription("The frames per second rate for GIF animations in the world.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>()));
			AnimateGifsInWorld = ((BaseUnityPlugin)_plugin).Config.Bind<bool>("GIF Settings", "Animate GIFs In World", true, new ConfigDescription("When enabled, GIF sprays will be animated in the world. Disable for performance.", (AcceptableValueBase)null, Array.Empty<object>()));
			AnimateGifsInWorld.SettingChanged += delegate
			{
				_plugin._gifAssetManager.SetAllAnimatorsPaused(!AnimateGifsInWorld.Value);
			};
			SelectedGifName = ((BaseUnityPlugin)_plugin).Config.Bind<string>("GIF Settings", "Selected GIF", (_plugin._gifManager.AvailableGifs.Count > 0) ? _plugin._gifManager.AvailableGifs[0] : "No GIFs Available", new ConfigDescription("The GIF used for spraying when in GIF mode.", (AcceptableValueBase)(object)new AcceptableValueList<string>(_plugin._gifManager.AvailableGifs.ToArray()), Array.Empty<object>()));
			SelectedGifName.SettingChanged += delegate
			{
				if (_plugin._gifManager.IsGifMode && SelectedGifName.Value != _plugin._gifManager.CurrentGifName)
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] GIF selection changed to: " + SelectedGifName.Value);
					_plugin._gifManager.SelectGif(SelectedGifName.Value);
				}
			};
			ScaleKey = ((BaseUnityPlugin)_plugin).Config.Bind<KeyCode>("Scale Settings", "Scale Preview Key", (KeyCode)308, new ConfigDescription("Hold this key to preview the scale.", (AcceptableValueBase)null, Array.Empty<object>()));
			IncreaseScaleKey = ((BaseUnityPlugin)_plugin).Config.Bind<KeyCode>("Scale Settings", "Increase Scale Key", (KeyCode)61, new ConfigDescription("Press this key to increase the spray scale (+ key by default).", (AcceptableValueBase)null, Array.Empty<object>()));
			DecreaseScaleKey = ((BaseUnityPlugin)_plugin).Config.Bind<KeyCode>("Scale Settings", "Decrease Scale Key", (KeyCode)45, new ConfigDescription("Press this key to decrease the spray scale (- key by default).", (AcceptableValueBase)null, Array.Empty<object>()));
			UseScrollWheel = ((BaseUnityPlugin)_plugin).Config.Bind<bool>("Scale Settings", "Use Scroll Wheel", true, new ConfigDescription("Enable scroll wheel to adjust scale while holding the Scale Preview Key.", (AcceptableValueBase)null, Array.Empty<object>()));
			SprayScale = ((BaseUnityPlugin)_plugin).Config.Bind<float>("Scale Settings", "Spray Scale", 1f, new ConfigDescription("The size of the spray.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			MinScaleSize = ((BaseUnityPlugin)_plugin).Config.Bind<float>("Scale Settings", "Minimum Scale", 0.1f, new ConfigDescription("The minimum allowed scale size.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()));
			MaxScaleSize = ((BaseUnityPlugin)_plugin).Config.Bind<float>("Scale Settings", "Maximum Scale", 5f, new ConfigDescription("The maximum allowed scale size.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			ScaleSpeed = ((BaseUnityPlugin)_plugin).Config.Bind<float>("Scale Settings", "Scale Speed", 0.1f, new ConfigDescription("How quickly the spray scales when adjusting.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>()));
			ScalePreviewColor = ((BaseUnityPlugin)_plugin).Config.Bind<Color>("Scale Settings", "Scale Preview Color", new Color(0f, 1f, 0f, 0.5f), new ConfigDescription("The color of the scale preview.", (AcceptableValueBase)null, Array.Empty<object>()));
		}

		public void UpdateImageListConfig()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			if (_plugin._availableImages.Count == 0)
			{
				_plugin._availableImages.Add("No Images Available");
			}
			((BaseUnityPlugin)_plugin).Config.Remove(((ConfigEntryBase)SelectedSprayImage).Definition);
			SelectedSprayImage = ((BaseUnityPlugin)_plugin).Config.Bind<string>("Spray Settings", "Selected Spray Image", _plugin._availableImages.Contains(SelectedSprayImage.Value) ? SelectedSprayImage.Value : _plugin._availableImages[0], new ConfigDescription("The image used for spraying.", (AcceptableValueBase)(object)new AcceptableValueList<string>(_plugin._availableImages.ToArray()), Array.Empty<object>()));
			SelectedSprayImage.SettingChanged += delegate
			{
				//IL_0077: Unknown result type (might be due to invalid IL or missing references)
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				string filePath = Path.Combine(_plugin._imagesFolderPath, SelectedSprayImage.Value);
				_plugin._cachedSprayTexture = _plugin._imageUtils.LoadTexture(filePath);
				if ((Object)(object)_plugin._cachedSprayTexture != (Object)null)
				{
					_plugin._originalImageDimensions = new Vector2((float)((Texture)_plugin._cachedSprayTexture).width, (float)((Texture)_plugin._cachedSprayTexture).height);
				}
			};
		}
	}
	public class ImageUtils
	{
		private BiggerSprayMod _plugin;

		public ImageUtils(BiggerSprayMod plugin)
		{
			_plugin = plugin;
		}

		public void LoadAvailableImages()
		{
			if (!Directory.Exists(_plugin._imagesFolderPath))
			{
				Directory.CreateDirectory(_plugin._imagesFolderPath ?? _plugin.GetPluginPath());
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Created images directory at " + _plugin._imagesFolderPath);
			}
			_plugin._availableImages = (from f in Directory.GetFiles(_plugin._imagesFolderPath ?? _plugin.GetPluginPath(), "*.*", SearchOption.TopDirectoryOnly)
				where f.EndsWith(".png", StringComparison.OrdinalIgnoreCase) || f.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase)
				select f).Select(Path.GetFileName).ToList();
			if (_plugin._availableImages.Count == 0)
			{
				_plugin._sprayUtils.CreateDefaultSpray();
			}
		}

		public Texture2D LoadTexture(string filePath)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			if (!File.Exists(filePath))
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] File not found at " + filePath);
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(filePath);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (ImageConversion.LoadImage(val, array))
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)16, $"[BiggerSprayMod] Successfully loaded texture: {filePath} ({((Texture)val).width}x{((Texture)val).height})");
					return val;
				}
				_plugin.LogMessage((Enum)(object)(LogLevel)4, "[BiggerSprayMod] Failed to load texture from " + filePath);
				return null;
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error loading texture: " + ex.Message);
				return null;
			}
		}

		public byte[] CompressImage(byte[] data)
		{
			using MemoryStream memoryStream = new MemoryStream();
			using (GZipStream gZipStream = new GZipStream(memoryStream, CompressionMode.Compress))
			{
				gZipStream.Write(data, 0, data.Length);
			}
			return memoryStream.ToArray();
		}

		public byte[] DecompressImage(byte[] compressedData)
		{
			using MemoryStream stream = new MemoryStream(compressedData);
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			gZipStream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}
	}
	public class InputManager
	{
		private readonly BiggerSprayMod _plugin;

		public InputManager(BiggerSprayMod plugin)
		{
			_plugin = plugin;
		}

		public void ProcessInputs()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: 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_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(_plugin._configManager.ToggleGifModeKey.Value))
			{
				_plugin._gifManager.ToggleGifMode();
			}
			if (_plugin._gifManager.IsGifMode)
			{
				if (Input.GetKeyDown(_plugin._configManager.PreviousSprayKey.Value))
				{
					_plugin._gifManager.SelectPreviousGif();
					if (!string.IsNullOrEmpty(_plugin._gifManager.CurrentGifName))
					{
						_plugin._configManager.SelectedGifName.Value = _plugin._gifManager.CurrentGifName;
					}
				}
				else if (Input.GetKeyDown(_plugin._configManager.NextSprayKey.Value))
				{
					_plugin._gifManager.SelectNextGif();
					if (!string.IsNullOrEmpty(_plugin._gifManager.CurrentGifName))
					{
						_plugin._configManager.SelectedGifName.Value = _plugin._gifManager.CurrentGifName;
					}
				}
			}
			else if (Input.GetKeyDown(_plugin._configManager.PreviousSprayKey.Value))
			{
				SelectPreviousSpray();
			}
			else if (Input.GetKeyDown(_plugin._configManager.NextSprayKey.Value))
			{
				SelectNextSpray();
			}
			if (Input.GetKeyDown(_plugin._configManager.ScaleKey.Value))
			{
				ScalingUtils.StartScalingMode();
			}
			else if (Input.GetKeyUp(_plugin._configManager.ScaleKey.Value))
			{
				ScalingUtils.StopScalingMode();
			}
			if (Input.GetKeyDown(_plugin._configManager.IncreaseScaleKey.Value))
			{
				_plugin._scalingUtils.AdjustScale(_plugin._configManager.ScaleSpeed.Value);
			}
			else if (Input.GetKeyDown(_plugin._configManager.DecreaseScaleKey.Value))
			{
				_plugin._scalingUtils.AdjustScale(0f - _plugin._configManager.ScaleSpeed.Value);
			}
			if (_plugin._isScaling && _plugin._configManager.UseScrollWheel.Value)
			{
				float y = Input.mouseScrollDelta.y;
				if (Mathf.Abs(y) > 0.01f)
				{
					_plugin._scalingUtils.AdjustScale(y * _plugin._configManager.ScaleSpeed.Value);
				}
			}
			if (_plugin._isScaling)
			{
				_plugin._scalingUtils.UpdateScalingPreview();
			}
			else if (Input.GetKeyDown(_plugin._configManager.SprayKey.Value))
			{
				_plugin._sprayUtils.TrySpray();
			}
		}

		private void SelectPreviousSpray()
		{
			int num = _plugin._availableImages.IndexOf(_plugin._configManager.SelectedSprayImage.Value);
			int index = (num - 1 + _plugin._availableImages.Count) % _plugin._availableImages.Count;
			_plugin._configManager.SelectedSprayImage.Value = _plugin._availableImages[index];
		}

		private void SelectNextSpray()
		{
			int num = _plugin._availableImages.IndexOf(_plugin._configManager.SelectedSprayImage.Value);
			int index = (num + 1) % _plugin._availableImages.Count;
			_plugin._configManager.SelectedSprayImage.Value = _plugin._availableImages[index];
		}
	}
	public class NetworkUtils
	{
		[CompilerGenerated]
		private sealed class <>c__DisplayClass20_0
		{
			public NetworkUtils <>4__this;

			public Vector3 position;

			public Quaternion rotation;

			public Vector2 scale;

			public string sprayId;

			public float lifetime;

			public int maxSprays;

			public string url;

			internal void <DownloadAndPlaceSprayFromUrl>b__0(Texture2D texture)
			{
				//IL_001e: 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_002b: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)texture != (Object)null)
				{
					<>4__this._plugin._sprayUtils.PlaceSprayWithCustomScale(position, rotation, texture, scale, sprayId, lifetime, maxSprays);
					<>4__this._plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Successfully placed spray from URL with cached texture");
				}
				else
				{
					<>4__this._plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Failed to download texture from URL: " + url);
				}
			}
		}

		[CompilerGenerated]
		private sealed class <DownloadAndPlaceSprayFromUrl>d__20 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public string url;

			public Vector3 position;

			public Quaternion rotation;

			public Vector2 scale;

			public string sprayId;

			public float lifetime;

			public int maxSprays;

			public NetworkUtils <>4__this;

			private <>c__DisplayClass20_0 <>8__1;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: 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_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>8__1 = new <>c__DisplayClass20_0();
					<>8__1.<>4__this = <>4__this;
					<>8__1.position = position;
					<>8__1.rotation = rotation;
					<>8__1.scale = scale;
					<>8__1.sprayId = sprayId;
					<>8__1.lifetime = lifetime;
					<>8__1.maxSprays = maxSprays;
					<>8__1.url = url;
					<>4__this._plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Downloading spray from URL: " + <>8__1.url);
					<>2__current = <>4__this._plugin._tmpFilesUploader.DownloadImageWithCacheCoroutine(<>8__1.url, delegate(Texture2D texture)
					{
						//IL_001e: 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_002b: Unknown result type (might be due to invalid IL or missing references)
						if ((Object)(object)texture != (Object)null)
						{
							<>8__1.<>4__this._plugin._sprayUtils.PlaceSprayWithCustomScale(<>8__1.position, <>8__1.rotation, texture, <>8__1.scale, <>8__1.sprayId, <>8__1.lifetime, <>8__1.maxSprays);
							<>8__1.<>4__this._plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Successfully placed spray from URL with cached texture");
						}
						else
						{
							<>8__1.<>4__this._plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Failed to download texture from URL: " + <>8__1.url);
						}
					});
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					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();
			}
		}

		private BiggerSprayMod _plugin;

		public const byte SprayEventCode = 42;

		public const byte SettingsRequestEventCode = 43;

		public const byte SettingsResponseEventCode = 44;

		public const byte GifSprayEventCode = 45;

		public const byte RemoveSprayEventCode = 46;

		public const byte UrlSprayEventCode = 47;

		public NetworkUtils(BiggerSprayMod plugin)
		{
			_plugin = plugin;
		}

		public void OnNetworkEvent(EventData photonEvent)
		{
			switch (photonEvent.Code)
			{
			case 42:
				_plugin._sprayUtils.HandleSprayEvent(photonEvent);
				break;
			case 45:
				HandleGifSprayEvent(photonEvent);
				break;
			case 43:
				if (PhotonNetwork.IsMasterClient)
				{
					SendHostSettings();
				}
				break;
			case 44:
				HandleSettingsResponse(photonEvent);
				break;
			case 46:
				HandleRemoveSprayEvent(photonEvent);
				break;
			case 47:
				HandleUrlSprayEvent(photonEvent);
				break;
			}
		}

		public void RequestHostSettings()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			if (PhotonNetwork.IsConnected && !PhotonNetwork.IsMasterClient)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Requesting settings from host...");
				PhotonNetwork.RaiseEvent((byte)43, (object)null, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)2
				}, SendOptions.SendReliable);
			}
		}

		private void SendHostSettings()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			if (PhotonNetwork.IsMasterClient)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Sending host settings to clients...");
				object[] array = new object[2]
				{
					_plugin._configManager.SprayLifetimeSeconds.Value,
					_plugin._configManager.MaxSpraysAllowed.Value
				};
				PhotonNetwork.RaiseEvent((byte)44, (object)array, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendReliable);
			}
		}

		public void SendSprayToNetwork(Vector3 hitPoint, Vector3 hitNormal, string sprayId)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			try
			{
				if (_plugin._gifManager.IsGifMode && !string.IsNullOrEmpty(_plugin._gifManager.CurrentGifName))
				{
					SendGifSprayToNetwork(hitPoint, hitNormal, sprayId);
					return;
				}
				byte[] data = ImageConversion.EncodeToPNG(_plugin._cachedSprayTexture);
				byte[] array = _plugin._imageUtils.CompressImage(data);
				if (array.Length > 1000000)
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)4, "[BiggerSprayMod] Spray image too large to send over network!" + $" ({array.Length} bytes > 1000000 bytes)");
					return;
				}
				Vector2 val = _plugin._scalingUtils.CalculateContainedScale(_plugin._configManager.SprayScale.Value);
				object[] array2 = new object[6] { array, hitPoint, hitNormal, val.x, val.y, sprayId };
				PhotonNetwork.RaiseEvent((byte)42, (object)array2, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendReliable);
				_plugin.LogMessage((Enum)(object)(LogLevel)16, $"[BiggerSprayMod] Sent spray to network ({array.Length} bytes)");
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error sending spray: " + ex.Message);
			}
		}

		public void SendGifSprayToNetwork(Vector3 hitPoint, Vector3 hitNormal, string sprayId)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			try
			{
				if (!string.IsNullOrEmpty(_plugin._gifManager.CurrentGifName))
				{
					string gifUrlByName = _plugin._gifManager.GetGifUrlByName(_plugin._gifManager.CurrentGifName);
					if (string.IsNullOrEmpty(gifUrlByName))
					{
						_plugin.LogMessage((Enum)(object)(LogLevel)4, "[BiggerSprayMod] Cannot send GIF spray: URL not found");
						return;
					}
					Vector2 val = _plugin._scalingUtils.CalculateContainedScale(_plugin._configManager.SprayScale.Value);
					object[] array = new object[7]
					{
						_plugin._gifManager.CurrentGifName,
						gifUrlByName,
						hitPoint,
						hitNormal,
						val.x,
						val.y,
						sprayId
					};
					PhotonNetwork.RaiseEvent((byte)45, (object)array, new RaiseEventOptions
					{
						Receivers = (ReceiverGroup)0
					}, SendOptions.SendReliable);
					_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Sent GIF spray to network: " + _plugin._gifManager.CurrentGifName);
				}
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error sending GIF spray: " + ex.Message);
			}
		}

		public void SendRemoveSprayToNetwork(string sprayId)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			try
			{
				PhotonNetwork.RaiseEvent((byte)46, (object)sprayId, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendReliable);
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Host sent remove spray command for ID: " + sprayId);
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error sending remove spray command: " + ex.Message);
			}
		}

		private void HandleRemoveSprayEvent(EventData photonEvent)
		{
			if (PhotonNetwork.IsMasterClient)
			{
				return;
			}
			try
			{
				string text = (string)photonEvent.CustomData;
				if (_plugin._sprayUtils.RemoveSprayById(text))
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Removed spray by host command, ID: " + text);
				}
				else
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Spray with ID " + text + " not found (may already be removed)");
				}
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error handling remove spray event: " + ex.Message);
			}
		}

		private void HandleGifSprayEvent(EventData photonEvent)
		{
			//IL_0023: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				object[] array = (object[])photonEvent.CustomData;
				string text = (string)array[0];
				string text2 = (string)array[1];
				Vector3 val = (Vector3)array[2];
				Vector3 val2 = (Vector3)array[3];
				float num = (float)array[4];
				float num2 = (float)array[5];
				string sprayId = ((array.Length > 6) ? ((string)array[6]) : Guid.NewGuid().ToString());
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Received GIF spray: " + text + " (" + text2 + ")");
				Vector3 position = val + val2 * 0.01f;
				Quaternion rotation = Quaternion.LookRotation(val2);
				PlaceAnimatedGifSprayByUrl(position, rotation, text2, new Vector2(num, num2), sprayId, 0f, _plugin._hostMaxSprays);
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error processing GIF spray: " + ex.Message);
			}
		}

		public void PlaceAnimatedGifSpray(Vector3 position, Quaternion rotation, WebUtils.GifData gifData, Vector2 scale, string sprayId, float lifetime, int maxSprays)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			try
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)16, $"[BiggerSprayMod] Creating animated GIF spray with {gifData.Frames.Count} frames...");
				GameObject val = GameObject.CreatePrimitive((PrimitiveType)5);
				((Object)val).name = "BiggerSpray_GifInstance";
				Object.Destroy((Object)(object)val.GetComponent<Collider>());
				val.transform.position = position;
				val.transform.rotation = rotation;
				val.transform.localScale = new Vector3(0f - scale.x, scale.y, 1f);
				Material val2 = new Material(_plugin._sprayMaterialTemplate);
				val2.mainTexture = (Texture)(object)gifData.Frames[0];
				val2.SetFloat("_Mode", 2f);
				val2.SetInt("_SrcBlend", 5);
				val2.SetInt("_DstBlend", 10);
				val2.SetInt("_ZWrite", 0);
				val2.DisableKeyword("_ALPHATEST_ON");
				val2.EnableKeyword("_ALPHABLEND_ON");
				val2.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				val2.renderQueue = 3000;
				((Renderer)val.GetComponent<MeshRenderer>()).material = val2;
				GifSpriteAnimator gifSpriteAnimator = val.AddComponent<GifSpriteAnimator>();
				gifSpriteAnimator.Initialize(gifData, _plugin._configManager.GifAnimationFps.Value);
				_plugin._sprayUtils.RegisterSpray(val, sprayId);
				_plugin._spawnedSprays.Add(val);
				if (lifetime > 0f && !PhotonNetwork.IsConnected)
				{
					Object.Destroy((Object)(object)val, lifetime);
				}
				if (!PhotonNetwork.IsConnected && _plugin._spawnedSprays.Count > maxSprays)
				{
					while (_plugin._spawnedSprays.Count > maxSprays)
					{
						GameObject val3 = _plugin._spawnedSprays[0];
						_plugin._spawnedSprays.RemoveAt(0);
						if ((Object)(object)val3 != (Object)null)
						{
							Object.Destroy((Object)(object)val3);
						}
					}
				}
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Animated GIF spray placed successfully.");
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error placing animated GIF spray: " + ex.Message);
			}
		}

		public void PlaceAnimatedGifSprayByUrl(Vector3 position, Quaternion rotation, string gifUrl, Vector2 scale, string sprayId, float lifetime, int maxSprays)
		{
			//IL_006e: 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_0088: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			try
			{
				if (string.IsNullOrEmpty(gifUrl))
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Cannot place GIF spray: URL is empty");
					return;
				}
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Creating animated GIF spray from URL: " + gifUrl);
				GameObject val = GameObject.CreatePrimitive((PrimitiveType)5);
				((Object)val).name = "BiggerSpray_GifInstance";
				Object.Destroy((Object)(object)val.GetComponent<Collider>());
				val.transform.position = position;
				val.transform.rotation = rotation;
				val.transform.localScale = new Vector3(0f - scale.x, scale.y, 1f);
				Material val2 = new Material(_plugin._sprayMaterialTemplate);
				val2.SetFloat("_Mode", 2f);
				val2.SetInt("_SrcBlend", 5);
				val2.SetInt("_DstBlend", 10);
				val2.SetInt("_ZWrite", 0);
				val2.DisableKeyword("_ALPHATEST_ON");
				val2.EnableKeyword("_ALPHABLEND_ON");
				val2.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				val2.renderQueue = 3000;
				((Renderer)val.GetComponent<MeshRenderer>()).material = val2;
				GifSpriteAnimator gifSpriteAnimator = val.AddComponent<GifSpriteAnimator>();
				gifSpriteAnimator.Initialize(gifUrl, _plugin._configManager.GifAnimationFps.Value);
				gifSpriteAnimator.SetPaused(!_plugin._configManager.AnimateGifsInWorld.Value);
				_plugin._sprayUtils.RegisterSpray(val, sprayId);
				_plugin._spawnedSprays.Add(val);
				if (lifetime > 0f && !PhotonNetwork.IsConnected)
				{
					Object.Destroy((Object)(object)val, lifetime);
				}
				if (!PhotonNetwork.IsConnected && _plugin._spawnedSprays.Count > maxSprays)
				{
					while (_plugin._spawnedSprays.Count > maxSprays)
					{
						GameObject val3 = _plugin._spawnedSprays[0];
						_plugin._spawnedSprays.RemoveAt(0);
						if ((Object)(object)val3 != (Object)null)
						{
							Object.Destroy((Object)(object)val3);
						}
					}
				}
				string text = (_plugin._configManager.AnimateGifsInWorld.Value ? "animated" : "paused");
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] " + text + " GIF spray from URL placed successfully.");
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error placing animated GIF spray from URL: " + ex.Message);
			}
		}

		private void HandleSettingsResponse(EventData photonEvent)
		{
			try
			{
				object[] array = (object[])photonEvent.CustomData;
				_plugin._hostSprayLifetime = (float)array[0];
				_plugin._hostMaxSprays = (int)array[1];
				_plugin.LogMessage((Enum)(object)(LogLevel)16, $"[BiggerSprayMod] Received host settings: Lifetime={_plugin._hostSprayLifetime}s, MaxSprays={_plugin._hostMaxSprays}");
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error processing settings response: " + ex.Message);
			}
		}

		private void HandleUrlSprayEvent(EventData photonEvent)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0028: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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)
			//IL_0092: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				object[] array = (object[])photonEvent.CustomData;
				string text = (string)array[0];
				Vector3 val = (Vector3)array[1];
				Vector3 val2 = (Vector3)array[2];
				float num = (float)array[3];
				float num2 = (float)array[4];
				string sprayId = ((array.Length > 5) ? ((string)array[5]) : Guid.NewGuid().ToString());
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Received spray from tmpfiles.org URL: " + text);
				Vector3 position = val + val2 * 0.01f;
				Quaternion rotation = Quaternion.LookRotation(val2);
				((MonoBehaviour)_plugin).StartCoroutine(DownloadAndPlaceSprayFromUrl(text, position, rotation, new Vector2(num, num2), sprayId, 0f, _plugin._hostMaxSprays));
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error processing URL spray: " + ex.Message);
			}
		}

		[IteratorStateMachine(typeof(<DownloadAndPlaceSprayFromUrl>d__20))]
		private IEnumerator DownloadAndPlaceSprayFromUrl(string url, Vector3 position, Quaternion rotation, Vector2 scale, string sprayId, float lifetime, int maxSprays)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_001d: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DownloadAndPlaceSprayFromUrl>d__20(0)
			{
				<>4__this = this,
				url = url,
				position = position,
				rotation = rotation,
				scale = scale,
				sprayId = sprayId,
				lifetime = lifetime,
				maxSprays = maxSprays
			};
		}

		public void SendUrlSprayToNetwork(Vector3 hitPoint, Vector3 hitNormal, string sprayId, string sprayName)
		{
			//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)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			string sprayId2 = sprayId;
			try
			{
				if (_plugin._tmpFilesUploader == null || (Object)(object)_plugin._cachedSprayTexture == (Object)null)
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Cannot send URL spray: Uploader or texture is null");
					return;
				}
				Vector2 adjustedScale = _plugin._scalingUtils.CalculateContainedScale(_plugin._configManager.SprayScale.Value);
				if (_plugin._tmpFilesUploader.HasValidCachedUrl(sprayName))
				{
					string cachedUrl = _plugin._tmpFilesUploader.GetCachedUrl(sprayName);
					_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Using cached tmpfiles.org URL for " + sprayName + ": " + cachedUrl);
					SendUrlToNetwork(cachedUrl, hitPoint, hitNormal, adjustedScale, sprayId2);
					return;
				}
				byte[] imageData = ImageConversion.EncodeToPNG(_plugin._cachedSprayTexture);
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Uploading spray to tmpfiles.org for network sharing...");
				_plugin._tmpFilesUploader.UploadImage(sprayName, imageData, delegate(bool success, string url)
				{
					//IL_0084: Unknown result type (might be due to invalid IL or missing references)
					//IL_008f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0027: Unknown result type (might be due to invalid IL or missing references)
					//IL_0032: Unknown result type (might be due to invalid IL or missing references)
					//IL_0038: Unknown result type (might be due to invalid IL or missing references)
					if (success && !string.IsNullOrEmpty(url))
					{
						SendUrlToNetwork(url, hitPoint, hitNormal, adjustedScale, sprayId2);
					}
					else
					{
						_plugin.LogMessage((Enum)(object)(LogLevel)4, "[BiggerSprayMod] Failed to upload to tmpfiles.org, falling back to direct transfer");
						SendSprayToNetwork(hitPoint, hitNormal, sprayId2);
					}
				});
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error sending URL spray: " + ex.Message);
				SendSprayToNetwork(hitPoint, hitNormal, sprayId2);
			}
		}

		private void SendUrlToNetwork(string url, Vector3 hitPoint, Vector3 hitNormal, Vector2 scale, string sprayId)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//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_005b: Expected O, but got Unknown
			try
			{
				object[] array = new object[6] { url, hitPoint, hitNormal, scale.x, scale.y, sprayId };
				PhotonNetwork.RaiseEvent((byte)47, (object)array, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendReliable);
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Sent tmpfiles.org URL spray to network: " + url);
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error sending URL to network: " + ex.Message);
			}
		}
	}
	public class ScalingUtils
	{
		private static BiggerSprayMod _plugin;

		public ScalingUtils(BiggerSprayMod plugin)
		{
			_plugin = plugin;
		}

		public static void StartScalingMode()
		{
			_plugin._isScaling = true;
			_plugin._currentScalePreview = _plugin._configManager.SprayScale.Value;
			CreateScalePreview();
		}

		public static void StopScalingMode()
		{
			_plugin._isScaling = false;
			_plugin._configManager.SprayScale.Value = _plugin._currentScalePreview;
			if ((Object)(object)_plugin._scalePreviewObject != (Object)null)
			{
				Object.Destroy((Object)(object)_plugin._scalePreviewObject);
				_plugin._scalePreviewObject = null;
			}
		}

		public static void CreateScalePreview()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_plugin._scalePreviewObject != (Object)null)
			{
				Object.Destroy((Object)(object)_plugin._scalePreviewObject);
			}
			Ray val = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f));
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, 100f))
			{
				_plugin._scalePreviewObject = GameObject.CreatePrimitive((PrimitiveType)5);
				((Object)_plugin._scalePreviewObject).name = "SprayScalePreview";
				Object.Destroy((Object)(object)_plugin._scalePreviewObject.GetComponent<Collider>());
				Vector3 position = ((RaycastHit)(ref val2)).point + ((RaycastHit)(ref val2)).normal * 0.01f;
				Quaternion rotation = Quaternion.LookRotation(((RaycastHit)(ref val2)).normal);
				_plugin._scalePreviewObject.transform.position = position;
				_plugin._scalePreviewObject.transform.rotation = rotation;
				UpdatePreviewScale(_plugin._currentScalePreview);
				Material val3 = new Material(_plugin._previewMaterialTemplate);
				if ((Object)(object)_plugin._cachedSprayTexture != (Object)null)
				{
					val3.mainTexture = (Texture)(object)_plugin._cachedSprayTexture;
				}
				val3.color = _plugin._configManager.ScalePreviewColor.Value;
				val3.SetFloat("_Mode", 2f);
				val3.SetInt("_SrcBlend", 5);
				val3.SetInt("_DstBlend", 10);
				val3.SetInt("_ZWrite", 0);
				val3.DisableKeyword("_ALPHATEST_ON");
				val3.EnableKeyword("_ALPHABLEND_ON");
				val3.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				val3.renderQueue = 3000;
				((Renderer)_plugin._scalePreviewObject.GetComponent<MeshRenderer>()).material = val3;
			}
		}

		public static void UpdatePreviewScale(float scale)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_plugin._scalePreviewObject == (Object)null))
			{
				Vector2 val = _plugin._scalingUtils.CalculateContainedScale(scale);
				_plugin._scalePreviewObject.transform.localScale = new Vector3(0f - val.x, val.y, 1f);
			}
		}

		public void UpdateScalingPreview()
		{
			//IL_0030: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_plugin._scalePreviewObject == (Object)null)
			{
				CreateScalePreview();
				return;
			}
			Ray val = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f));
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, 100f))
			{
				Vector3 position = ((RaycastHit)(ref val2)).point + ((RaycastHit)(ref val2)).normal * 0.01f;
				Quaternion rotation = Quaternion.LookRotation(((RaycastHit)(ref val2)).normal);
				_plugin._scalePreviewObject.transform.position = position;
				_plugin._scalePreviewObject.transform.rotation = rotation;
			}
		}

		public Vector2 CalculateContainedScale(float baseScale)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			if ((Object)(object)_plugin._cachedSprayTexture == (Object)null)
			{
				return new Vector2(baseScale, baseScale);
			}
			float x = _plugin._originalImageDimensions.x;
			float y = _plugin._originalImageDimensions.y;
			float num = x / y;
			if (x > y)
			{
				return new Vector2(baseScale, baseScale / num);
			}
			return new Vector2(baseScale * num, baseScale);
		}

		public void AdjustScale(float amount)
		{
			if (_plugin._isScaling)
			{
				_plugin._currentScalePreview = Mathf.Clamp(_plugin._currentScalePreview + amount, _plugin._configManager.MinScaleSize.Value, _plugin._configManager.MaxScaleSize.Value);
				if ((Object)(object)_plugin._scalePreviewObject != (Object)null)
				{
					UpdatePreviewScale(_plugin._currentScalePreview);
				}
			}
			else
			{
				_plugin._configManager.SprayScale.Value = Mathf.Clamp(_plugin._configManager.SprayScale.Value + amount, _plugin._configManager.MinScaleSize.Value, _plugin._configManager.MaxScaleSize.Value);
			}
		}
	}
	public class SprayUtils
	{
		private BiggerSprayMod _plugin;

		private Dictionary<string, GameObject> _sprayIdsToGameObjects = new Dictionary<string, GameObject>();

		public SprayUtils(BiggerSprayMod plugin)
		{
			_plugin = plugin;
		}

		public void CreateSprayPrefabs()
		{
			//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_007e: Expected O, but got Unknown
			//IL_0085: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Creating spray materials...");
			Shader val = Shader.Find("Sprites/Default");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Unlit/Texture");
				if ((Object)(object)val == (Object)null)
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Failed to find suitable shader. Sprays may not appear correctly.");
					return;
				}
			}
			_plugin._sprayMaterialTemplate = new Material(val)
			{
				mainTexture = (Texture)(object)Texture2D.whiteTexture
			};
			_plugin._previewMaterialTemplate = new Material(val)
			{
				mainTexture = (Texture)(object)Texture2D.whiteTexture,
				color = _plugin._configManager.ScalePreviewColor.Value
			};
			_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Spray materials ready.");
		}

		public void RegisterSpray(GameObject spray, string sprayId)
		{
			if (!((Object)(object)spray == (Object)null) && !string.IsNullOrEmpty(sprayId))
			{
				SprayIdentifier sprayIdentifier = spray.AddComponent<SprayIdentifier>();
				sprayIdentifier.SprayId = sprayId;
				_sprayIdsToGameObjects[sprayId] = spray;
			}
		}

		public bool RemoveSprayById(string sprayId)
		{
			if (string.IsNullOrEmpty(sprayId) || !_sprayIdsToGameObjects.TryGetValue(sprayId, out GameObject value))
			{
				return false;
			}
			_sprayIdsToGameObjects.Remove(sprayId);
			if (_plugin._spawnedSprays.Contains(value))
			{
				_plugin._spawnedSprays.Remove(value);
			}
			if ((Object)(object)value != (Object)null)
			{
				Object.Destroy((Object)(object)value);
				return true;
			}
			return false;
		}

		public void CreateDefaultSpray()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Texture2D val = new Texture2D(256, 256, (TextureFormat)4, false);
				Color[] array = (Color[])(object)new Color[65536];
				for (int i = 0; i < 256; i++)
				{
					for (int j = 0; j < 256; j++)
					{
						float num = Vector2.Distance(new Vector2((float)j, (float)i), new Vector2(128f, 128f));
						float num2 = Mathf.Clamp01(1f - num / 128f);
						array[i * 256 + j] = new Color(1f, 0f, 0f, num2 * num2);
					}
				}
				val.SetPixels(array);
				val.Apply();
				string path = Path.Combine(_plugin._imagesFolderPath ?? _plugin.GetPluginPath(), "DefaultSpray.png");
				File.WriteAllBytes(path, ImageConversion.EncodeToPNG(val));
				_plugin._availableImages.Add("DefaultSpray.png");
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Created default spray image.");
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Failed to create default spray: " + ex.Message);
				_plugin._availableImages.Add("No Images Available");
			}
		}

		public void CheckForRefreshSprays()
		{
			if (_plugin._configManager.OpenImagesFolderButton.Value)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Opening image folder...");
				string text = _plugin._imagesFolderPath ?? _plugin.GetPluginPath();
				Application.OpenURL(text);
				_plugin._configManager.OpenImagesFolderButton.Value = false;
			}
			if (_plugin._configManager.RefreshSpraysButton.Value)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Refreshing sprays list...");
				_plugin._imageUtils.LoadAvailableImages();
				_plugin._configManager.UpdateImageListConfig();
				_plugin._configManager.RefreshSpraysButton.Value = false;
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Sprays list refreshed successfully.");
			}
		}

		public void PlaceSpray(Vector3 position, Quaternion rotation, float lifetime, int maxSprays)
		{
			//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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			string sprayId = Guid.NewGuid().ToString();
			Vector2 scale = _plugin._scalingUtils.CalculateContainedScale(_plugin._configManager.SprayScale.Value);
			PlaceSprayWithCustomScale(position, rotation, _plugin._cachedSprayTexture, scale, sprayId, lifetime, maxSprays);
			if (PhotonNetwork.IsMasterClient && PhotonNetwork.IsConnected && lifetime > 0f)
			{
				((MonoBehaviour)_plugin).StartCoroutine(_plugin.ScheduleSprayRemoval(sprayId, lifetime));
			}
		}

		public void PlaceSprayWithCustomScale(Vector3 position, Quaternion rotation, Texture2D texture, Vector2 scale, string sprayId, float lifetime, int maxSprays)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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)
			//IL_00a7: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			if ((Object)(object)texture == (Object)null)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)4, "[BiggerSprayMod] Cannot place spray with null texture.");
				return;
			}
			try
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)16, $"[BiggerSprayMod] Creating spray from texture with scale ({scale.x}, {scale.y})...");
				GameObject val = GameObject.CreatePrimitive((PrimitiveType)5);
				((Object)val).name = "BiggerSpray_Instance";
				Object.Destroy((Object)(object)val.GetComponent<Collider>());
				val.transform.position = position;
				val.transform.rotation = rotation;
				val.transform.localScale = new Vector3(0f - scale.x, scale.y, 1f);
				Material val2 = new Material(_plugin._sprayMaterialTemplate);
				val2.mainTexture = (Texture)(object)texture;
				val2.SetFloat("_Mode", 2f);
				val2.SetInt("_SrcBlend", 5);
				val2.SetInt("_DstBlend", 10);
				val2.SetInt("_ZWrite", 0);
				val2.DisableKeyword("_ALPHATEST_ON");
				val2.EnableKeyword("_ALPHABLEND_ON");
				val2.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				val2.renderQueue = 3000;
				((Renderer)val.GetComponent<MeshRenderer>()).material = val2;
				RegisterSpray(val, sprayId);
				_plugin._spawnedSprays.Add(val);
				if (lifetime > 0f && !PhotonNetwork.IsConnected)
				{
					Object.Destroy((Object)(object)val, lifetime);
				}
				if (!PhotonNetwork.IsConnected && _plugin._spawnedSprays.Count > maxSprays)
				{
					while (_plugin._spawnedSprays.Count > maxSprays)
					{
						GameObject val3 = _plugin._spawnedSprays[0];
						_plugin._spawnedSprays.RemoveAt(0);
						if ((Object)(object)val3 != (Object)null)
						{
							Object.Destroy((Object)(object)val3);
						}
					}
				}
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Spray placed successfully.");
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] Error placing spray: " + ex.Message);
			}
		}

		public void HandleSprayEvent(EventData photonEvent)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_008b: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				object[] array = (object[])photonEvent.CustomData;
				byte[] compressedData = (byte[])array[0];
				Vector3 val = (Vector3)array[1];
				Vector3 val2 = (Vector3)array[2];
				float num = (float)array[3];
				float num2 = (float)array[4];
				string sprayId = ((array.Length > 5) ? ((string)array[5]) : Guid.NewGuid().ToString());
				byte[] array2 = _plugin._imageUtils.DecompressImage(compressedData);
				Texture2D val3 = new Texture2D(2, 2, (TextureFormat)4, false);
				ImageConversion.LoadImage(val3, array2);
				Vector3 position = val + val2 * 0.01f;
				Quaternion rotation = Quaternion.LookRotation(val2);
				PlaceSprayWithCustomScale(position, rotation, val3, new Vector2(num, num2), sprayId, 0f, _plugin._hostMaxSprays);
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Received and placed remote spray.");
			}
			catch (Exception ex)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Error processing remote spray: " + ex.Message);
			}
		}

		public void TrySpray()
		{
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0523: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Attempting to spray...");
			float num = 0.5f;
			float num2 = (PhotonNetwork.IsMasterClient ? _plugin._configManager.SprayLifetimeSeconds.Value : _plugin._hostSprayLifetime);
			int maxSprays = (PhotonNetwork.IsMasterClient ? _plugin._configManager.MaxSpraysAllowed.Value : _plugin._hostMaxSprays);
			if (PhotonNetwork.IsConnected && !PhotonNetwork.IsMasterClient)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] Using host settings for spray properties.");
				_plugin._networkUtils.RequestHostSettings();
			}
			if (Time.time - _plugin._lastSprayTime < num)
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)4, "[BiggerSprayMod] Spray is on cooldown.");
				return;
			}
			if (_plugin._gifManager.IsGifMode)
			{
				if (string.IsNullOrEmpty(_plugin._gifManager.CurrentGifName) || _plugin._gifManager.CurrentGifName == "No GIFs Available" || _plugin._gifManager.CurrentGifName == "GIFs Disabled - Invalid JSON")
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] No valid GIF selected.");
					return;
				}
				if ((Object)(object)_plugin._cachedSprayTexture == (Object)null)
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] No valid GIF texture loaded. Cannot spray.");
					return;
				}
			}
			else
			{
				if ((Object)(object)_plugin._cachedSprayTexture == (Object)null)
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] No valid spray texture loaded. Cannot spray.");
					return;
				}
				if (string.IsNullOrEmpty(_plugin._configManager.SelectedSprayImage.Value) || _plugin._configManager.SelectedSprayImage.Value == "No Images Available")
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)2, "[BiggerSprayMod] No valid spray selected.");
					return;
				}
				string text = Path.Combine(_plugin._imagesFolderPath ?? _plugin.GetPluginPath(), _plugin._configManager.SelectedSprayImage.Value);
				if (File.Exists(text))
				{
					long length = new FileInfo(text).Length;
					if (length > 5000000)
					{
						_plugin.LogMessage((Enum)(object)(LogLevel)4, "[BiggerSprayMod] Selected image is too large to spray.");
						if (!_plugin._configManager.ShowSprayIfLarge.Value)
						{
							_plugin.LogMessage((Enum)(object)(LogLevel)4, "[BiggerSprayMod] Not sending large image to network.");
							return;
						}
					}
				}
			}
			Ray val = Camera.main.ViewportPointToRay(new Vector3(0.5f, 0.5f));
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, 100f))
			{
				string text2 = Guid.NewGuid().ToString();
				Vector3 position = ((RaycastHit)(ref val2)).point + ((RaycastHit)(ref val2)).normal * 0.01f;
				Quaternion rotation = Quaternion.LookRotation(((RaycastHit)(ref val2)).normal);
				if (_plugin._gifManager.IsGifMode)
				{
					string gifUrlByName = _plugin._gifManager.GetGifUrlByName(_plugin._gifManager.CurrentGifName);
					if (!string.IsNullOrEmpty(gifUrlByName))
					{
						Vector2 scale = _plugin._scalingUtils.CalculateContainedScale(_plugin._configManager.SprayScale.Value);
						_plugin._networkUtils.PlaceAnimatedGifSprayByUrl(position, rotation, gifUrlByName, scale, text2, num2, maxSprays);
						if (PhotonNetwork.IsConnected)
						{
							_plugin._networkUtils.SendSprayToNetwork(((RaycastHit)(ref val2)).point, ((RaycastHit)(ref val2)).normal, text2);
						}
						if (PhotonNetwork.IsMasterClient && PhotonNetwork.IsConnected && num2 > 0f)
						{
							Coroutine value = ((MonoBehaviour)_plugin).StartCoroutine(_plugin.ScheduleSprayRemoval(text2, num2));
							_plugin._sprayRemovalCoroutines[text2] = value;
						}
						_plugin._lastSprayTime = Time.time;
						return;
					}
				}
				PlaceSpray(position, rotation, num2, maxSprays);
				if (PhotonNetwork.IsConnected)
				{
					if (!_plugin._gifManager.IsGifMode)
					{
						_plugin._networkUtils.SendUrlSprayToNetwork(((RaycastHit)(ref val2)).point, ((RaycastHit)(ref val2)).normal, text2, _plugin._configManager.SelectedSprayImage.Value);
					}
					else
					{
						_plugin._networkUtils.SendSprayToNetwork(((RaycastHit)(ref val2)).point, ((RaycastHit)(ref val2)).normal, text2);
					}
					if (PhotonNetwork.IsMasterClient && num2 > 0f)
					{
						Coroutine value2 = ((MonoBehaviour)_plugin).StartCoroutine(_plugin.ScheduleSprayRemoval(text2, num2));
						_plugin._sprayRemovalCoroutines[text2] = value2;
					}
				}
				_plugin._lastSprayTime = Time.time;
			}
			else
			{
				_plugin.LogMessage((Enum)(object)(LogLevel)4, "[BiggerSprayMod] No valid surface detected to spray onto.");
			}
		}
	}
	public class SprayIdentifier : MonoBehaviour
	{
		public string SprayId { get; set; }
	}
}
namespace BiggerSprayMod.web
{
	public class GifAssetManager
	{
		public class GifAsset
		{
			public string Url { get; private set; }

			public List<Texture2D> Frames { get; private set; } = new List<Texture2D>();


			public List<float> Delays { get; private set; } = new List<float>();


			public bool IsLoading { get; set; } = false;


			public bool IsValid { get; set; } = false;


			public bool HasFailedLoading { get; set; } = false;


			public DateTime LastAccessed { get; set; } = DateTime.Now;


			public int FailedAttempts { get; set; } = 0;


			public GifAsset(string url)
			{
				Url = url;
			}

			public void SetData(List<Texture2D> frames, List<float> delays)
			{
				Frames = frames;
				Delays = delays;
				IsValid = Frames != null && Frames.Count > 0 && !Frames.Any((Texture2D f) => (Object)(object)f == (Object)null);
				IsLoading = false;
				LastAccessed = DateTime.Now;
			}

			public void Invalidate()
			{
				IsValid = false;
			}

			public void MarkAsAccessed()
			{
				LastAccessed = DateTime.Now;
			}

			public void Clear()
			{
				if (Frames != null)
				{
					foreach (Texture2D frame in Frames)
					{
						if ((Object)(object)frame != (Object)null)
						{
							Object.Destroy((Object)(object)frame);
						}
					}
					Frames.Clear();
				}
				if (Delays != null)
				{
					Delays.Clear();
				}
				IsValid = false;
				IsLoading = false;
			}
		}

		private BiggerSprayMod _plugin;

		private WebUtils _webUtils;

		private Dictionary<string, GifAsset> _gifAssets = new Dictionary<string, GifAsset>();

		private Dictionary<string, List<GifSpriteAnimator>> _activeAnimatorsByUrl = new Dictionary<string, List<GifSpriteAnimator>>();

		private Texture2D _defaultTexture;

		public GifAssetManager(BiggerSprayMod plugin, WebUtils webUtils)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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)
			_plugin = plugin;
			_webUtils = webUtils;
			_defaultTexture = new Texture2D(64, 64, (TextureFormat)4, false);
			Color[] array = (Color[])(object)new Color[4096];
			for (int i = 0; i < array.Length; i++)
			{
				int num = i % 64;
				int num2 = i / 64;
				bool flag = (num / 8 + num2 / 8) % 2 == 0;
				array[i] = (flag ? new Color(1f, 0f, 1f, 1f) : new Color(0f, 0f, 0f, 1f));
			}
			_defaultTexture.SetPixels(array);
			_defaultTexture.Apply();
			_plugin.LogMessage((Enum)(object)(LogLevel)16, "[BiggerSprayMod] GIF Asset Manager initialized");
		}

		public void RegisterAnimator(string url, GifSpriteAnimator animator)
		{
			if (!string.IsNullOrEmpty(url) && !((Object)(object)animator == (Object)null))
			{
				if (!_activeAnimatorsByUrl.TryGetValue(url, out List<GifSpriteAnimator> value))
				{
					value = new List<GifSpriteAnimator>();
					_activeAnimatorsByUrl[url] = value;
				}
				if (!value.Contains(animator))
				{
					value.Add(animator);
				}
			}
		}

		public void UnregisterAnimator(string url, GifSpriteAnimator animator)
		{
			if (!string.IsNullOrEmpty(url) && _activeAnimatorsByUrl.TryGetValue(url, out List<GifSpriteAnimator> value))
			{
				value.Remove(animator);
				if (value.Count == 0)
				{
					_activeAnimatorsByUrl.Remove(url);
				}
			}
		}

		public void GetOrLoadGifAsset(string url, Action<bool, GifAsset> callback)
		{
			Action<bool, GifAsset> callback2 = callback;
			string url2 = url;
			if (string.IsNullOrEmpty(url2))
			{
				callback2?.Invoke(arg1: false, null);
				return;
			}
			if (_gifAssets.TryGetValue(url2, out GifAsset asset))
			{
				if (asset.IsLoading)
				{
					return;
				}
				if (asset.IsValid)
				{
					asset.MarkAsAccessed();
					callback2?.Invoke(arg1: true, asset);
					return;
				}
				if (asset.HasFailedLoading && asset.FailedAttempts >= 3)
				{
					_plugin.LogMessage((Enum)(object)(LogLevel)4, "[BiggerSprayMod] GIF has failed loading too many times: " + url2);
					callback2?.Invoke(arg1: false, null);
					return;
				}
				asset.IsLoading = true;
				asset.FailedAttempts++;
				asset.Clear();
			}
			else
			{
				asset = new GifAsset(url2);
				asset.IsLoading = true;
				_gifAssets[url2] = asset;
			}
			_webUtils.StartGifDownload(url2, delegate(bool success, WebUtils.GifData gifData)
			{
				asset.IsLoading = false;
				if (success && gifData != null && gifData.Frames != null && gifData.Frames.Count > 0)
				{
					asset.SetData(gifData.Frames, gifData.Delays);
					asset.HasFailedLoading = false;
					asset.FailedAttempts = 0;
					UpdateAllAnimatorsUsingAsset(asset);
					callback2?.Invoke(arg1: true, asset);
				}
				else
				{
					asset.HasFailedLoading = true;
					if (asset.FailedAttempts >= 3)
					{
						UseDefaultTextureForUrl(url2);
					}
					callback2?.Invoke(arg1: false, null);
				}
			});
		}

		private void UpdateAllAnimatorsUsingAsset(GifAsset asset)
		{
			if (asset == null || string.IsNullOrEmpty(asset.Url) || !_activeAnimatorsByUrl.TryGetValue(asset.Url, out List<GifSpriteAnimator> value))
			{
				return;
			}
			for (int num = value.Count - 1; num >= 0; num--)
			{
				GifSpriteAnimator gifSpriteAnimator = value[num];
				if ((Object)(object)gifSpriteAnimator != (Object)null)
				{
					gifSpriteAnimator.RefreshWithAsset(asset.Frames, asset.Delays);
				}
				else
				{
					value.RemoveAt(num);
				}
			}
			if (value.Count == 0)
			{
				_activeAnimatorsByUrl.Remove(asset.Url);
			}
			_plugin.LogMessage((Enum)(object)(LogLevel)16, $"[BiggerSprayMod] Updated {value.Count} an