Decompiled source of StreamOverlays v1.3.0

com.github.zehsteam.StreamOverlays.dll

Decompiled 3 days 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.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using ShipInventory.Helpers;
using ShipInventory.Objects;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using WebSocketSharp.Net;
using WebSocketSharp.Server;
using com.github.zehsteam.StreamOverlays.Dependencies;
using com.github.zehsteam.StreamOverlays.Dependencies.ShipInventoryProxy;
using com.github.zehsteam.StreamOverlays.Dependencies.ShipInventoryProxy.Patches;
using com.github.zehsteam.StreamOverlays.Patches;
using com.github.zehsteam.StreamOverlays.Server;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.zehsteam.StreamOverlays")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0+e8d3cbd9beb145cfb30d7444a373fdbbb94cd3c3")]
[assembly: AssemblyProduct("StreamOverlays")]
[assembly: AssemblyTitle("com.github.zehsteam.StreamOverlays")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace com.github.zehsteam.StreamOverlays
{
	internal static class ConfigHelper
	{
		public static void SkipAutoGen()
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.SkipAutoGen();
			}
		}

		public static void AddButton(string section, string name, string description, string buttonText, Action callback)
		{
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.AddButton(section, name, description, buttonText, callback);
			}
		}

		public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, bool requiresRestart, string description, AcceptableValueBase acceptableValues = null, Action<T> settingChanged = null, ConfigFile configFile = null)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			if (configFile == null)
			{
				configFile = Plugin.Config;
			}
			ConfigEntry<T> configEntry = ((acceptableValues == null) ? configFile.Bind<T>(section, key, defaultValue, description) : configFile.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>())));
			if (settingChanged != null)
			{
				configEntry.SettingChanged += delegate
				{
					settingChanged?.Invoke(configEntry.Value);
				};
			}
			if (LethalConfigProxy.Enabled)
			{
				LethalConfigProxy.AddConfig<T>(configEntry, requiresRestart);
			}
			return configEntry;
		}

		public static Dictionary<ConfigDefinition, string> GetOrphanedConfigEntries(ConfigFile configFile = null)
		{
			if (configFile == null)
			{
				configFile = Plugin.Config;
			}
			PropertyInfo property = ((object)configFile).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
			return (Dictionary<ConfigDefinition, string>)property.GetValue(configFile, null);
		}

		public static void SetConfigEntryValue<T>(ConfigEntry<T> configEntry, string value)
		{
			if (typeof(T) == typeof(int) && int.TryParse(value, out var result))
			{
				configEntry.Value = (T)(object)result;
				return;
			}
			if (typeof(T) == typeof(float) && float.TryParse(value, out var result2))
			{
				configEntry.Value = (T)(object)result2;
				return;
			}
			if (typeof(T) == typeof(double) && double.TryParse(value, out var result3))
			{
				configEntry.Value = (T)(object)result3;
				return;
			}
			if (typeof(T) == typeof(bool) && bool.TryParse(value, out var result4))
			{
				configEntry.Value = (T)(object)result4;
				return;
			}
			if (typeof(T) == typeof(string))
			{
				configEntry.Value = (T)(object)value;
				return;
			}
			throw new InvalidOperationException($"Unsupported type: {typeof(T)}");
		}

		public static void ClearUnusedEntries(ConfigFile configFile = null)
		{
			if (configFile == null)
			{
				configFile = Plugin.Config;
			}
			Dictionary<ConfigDefinition, string> orphanedConfigEntries = GetOrphanedConfigEntries(configFile);
			if (orphanedConfigEntries != null)
			{
				orphanedConfigEntries.Clear();
				configFile.Save();
			}
		}
	}
	internal class ConfigManager
	{
		public ConfigEntry<bool> ExtendedLogging { get; private set; }

		public ConfigEntry<string> CrewStat_Label { get; private set; }

		public ConfigEntry<string> MoonStat_Label { get; private set; }

		public ConfigEntry<bool> MoonStat_ShowWeatherIcon { get; private set; }

		public ConfigEntry<string> DayStat_Label { get; private set; }

		public ConfigEntry<string> QuotaStat_Label { get; private set; }

		public ConfigEntry<string> LootStat_Label { get; private set; }

		public ConfigEntry<bool> LootStat_OnlyUpdateEndOfDay { get; private set; }

		public ConfigEntry<string> AveragePerDayStat_Label { get; private set; }

		public ConfigEntry<bool> Server_AutoStart { get; private set; }

		public ConfigEntry<int> Server_HttpPort { get; private set; }

		public ConfigEntry<int> Server_WebSocketPort { get; private set; }

		public ConfigManager()
		{
			BindConfigs();
			ConfigHelper.ClearUnusedEntries();
		}

		private void BindConfigs()
		{
			ConfigHelper.SkipAutoGen();
			ExtendedLogging = ConfigHelper.Bind("General", "ExtendedLogging", defaultValue: false, requiresRestart: false, "Enable extended logging.");
			CrewStat_Label = ConfigHelper.Bind("Crew Stat", "Label", "Crew: {value}", requiresRestart: false, "The formatting of the Crew stat display text. {value} is the amount of players in the current lobby.");
			CrewStat_Label.SettingChanged += delegate
			{
				WebServer.UpdateOverlaysFormatting();
			};
			MoonStat_Label = ConfigHelper.Bind("Moon Stat", "Label", "Moon: {value}", requiresRestart: false, "The formatting of the Moon stat display text. {value} is the name of the current moon.");
			MoonStat_ShowWeatherIcon = ConfigHelper.Bind("Moon Stat", "ShowWeatherIcon", defaultValue: true, requiresRestart: false, "If enabled, will show an icon for the current weather after the moon name.");
			MoonStat_Label.SettingChanged += delegate
			{
				WebServer.UpdateOverlaysFormatting();
			};
			MoonStat_ShowWeatherIcon.SettingChanged += delegate
			{
				WebServer.UpdateOverlaysData();
			};
			DayStat_Label = ConfigHelper.Bind("Day Stat", "Label", "Day: {value} ({value2}/{value3})", requiresRestart: false, "The formatting of the Day stat display text. {value} is the day number. {value2} is the day number in the current quota. {value3} is the amount of days in a quota. You can remove {value2} and {value3} if you want to.");
			DayStat_Label.SettingChanged += delegate
			{
				WebServer.UpdateOverlaysFormatting();
			};
			QuotaStat_Label = ConfigHelper.Bind("Quota Stat", "Label", "Quota {value2}: ${value}", requiresRestart: false, "The formatting of the Quota stat display text. {value} is the current profit quota. {value2} is the quota number/index. You can remove {value2} if you want to.");
			QuotaStat_Label.SettingChanged += delegate
			{
				WebServer.UpdateOverlaysFormatting();
			};
			LootStat_Label = ConfigHelper.Bind("Loot Stat", "Label", "Ship Loot: ${value}", requiresRestart: false, "The formatting of the Loot stat display text. {value} is the total scrap value on the ship and attached company cruiser.");
			LootStat_OnlyUpdateEndOfDay = ConfigHelper.Bind("Loot Stat", "OnlyUpdateEndOfDay", defaultValue: true, requiresRestart: false, "If enabled, the Loot stat will only update when the day ends or if you are in orbit.");
			LootStat_Label.SettingChanged += delegate
			{
				WebServer.UpdateOverlaysFormatting();
			};
			AveragePerDayStat_Label = ConfigHelper.Bind("Average Per Day Stat", "Label", "Avg/Day: ${value}", requiresRestart: false, "The formatting of the Average Per Day stat display text. {value} is the average collected scrap per day.");
			AveragePerDayStat_Label.SettingChanged += delegate
			{
				WebServer.UpdateOverlaysFormatting();
			};
			Server_AutoStart = ConfigHelper.Bind("Server", "AutoStart", defaultValue: true, requiresRestart: false, "If enabled, the server will automatically start when you launch the game.");
			ConfigHelper.AddButton("Server", "Start Server", "Start the server.", "Start", WebServer.Start);
			ConfigHelper.AddButton("Server", "Stop Server", "Stop the server.", "Stop", WebServer.Stop);
			Server_HttpPort = ConfigHelper.Bind("Server", "HttpPort", 8080, requiresRestart: false, "The HTTP port for the server.");
			Server_WebSocketPort = ConfigHelper.Bind("Server", "WebSocketPort", 8000, requiresRestart: false, "The WebSocket port for the server.");
		}
	}
	internal static class DayManager
	{
		public static List<DayData> DayDataList = new List<DayData>();

		public static void LoadDayData()
		{
			DayDataList = new List<DayData>();
			if (!NetworkUtils.IsServer || !SaveSystem.KeyExists("DayData"))
			{
				return;
			}
			try
			{
				string text = SaveSystem.LoadData<string>("DayData");
				DayDataList = JsonConvert.DeserializeObject<List<DayData>>(text);
				Plugin.Instance.LogInfoExtended("Loaded day data from save file. " + text);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to load day data from save file. {arg}");
			}
		}

		public static void SaveDayData()
		{
			if (!NetworkUtils.IsServer)
			{
				return;
			}
			try
			{
				string text = JsonConvert.SerializeObject((object)DayDataList);
				SaveSystem.SaveData("DayData", text);
				Plugin.Instance.LogInfoExtended("Saved day data to save file. " + text);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to save day data to save file. {arg}");
			}
		}

		public static void AddDayData(int scrapCollected)
		{
			if (CanAddDayData())
			{
				int dayNumber = GetDayNumber();
				if (!DayDataList.Any((DayData x) => x.Day == dayNumber))
				{
					DayDataList.Add(new DayData(dayNumber, scrapCollected));
				}
			}
		}

		private static bool CanAddDayData()
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.currentLevel == (Object)null)
			{
				return false;
			}
			return StartOfRound.Instance.currentLevel.spawnEnemiesAndScrap;
		}

		public static void ResetSavedDayData()
		{
			DayDataList = new List<DayData>();
			SaveDayData();
		}

		public static int GetDayNumber()
		{
			return DayDataList.Count + 1;
		}

		public static int GetAveragePerDay()
		{
			if (DayDataList.Count == 0)
			{
				return 0;
			}
			return DayDataList.Sum((DayData x) => x.ScrapCollected) / DayDataList.Count;
		}
	}
	[Serializable]
	public struct DayData
	{
		public int Day;

		public int ScrapCollected;

		public DayData(int day, int scrapCollected)
		{
			Day = day;
			ScrapCollected = scrapCollected;
		}
	}
	internal static class LootManager
	{
		private static int _shipLootTotal;

		private static int _vehicleLootTotal;

		private static int _shipInventoryLootTotal;

		public static bool CanUpdateLootTotal()
		{
			if (!Plugin.ConfigManager.LootStat_OnlyUpdateEndOfDay.Value)
			{
				return true;
			}
			if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.currentLevel == (Object)null)
			{
				return false;
			}
			if (!StartOfRound.Instance.currentLevel.spawnEnemiesAndScrap)
			{
				return true;
			}
			return StartOfRound.Instance.inShipPhase;
		}

		public static void UpdateLootTotal()
		{
			_shipLootTotal = GetShipLootTotal();
			_vehicleLootTotal = GetVehicleLootTotal();
			if (ShipInventoryProxy.Enabled)
			{
				_shipInventoryLootTotal = ShipInventoryProxy.GetLootTotal();
			}
		}

		public static int GetLootTotal()
		{
			return _shipLootTotal + _vehicleLootTotal + _shipInventoryLootTotal;
		}

		private static int GetShipLootTotal()
		{
			Transform hangarShipTransform = Utils.GetHangarShipTransform();
			if ((Object)(object)hangarShipTransform == (Object)null)
			{
				return 0;
			}
			List<GrabbableObject> list = ((Component)hangarShipTransform).GetComponentsInChildren<GrabbableObject>().ToList();
			list.AddRange(GetGrabbableObjectsFromShipPlaceableObjects());
			return list.Where(Utils.IsValidScrapAndNotHeld).Sum((GrabbableObject x) => x.scrapValue);
		}

		private static List<GrabbableObject> GetGrabbableObjectsFromShipPlaceableObjects()
		{
			List<GrabbableObject> list = new List<GrabbableObject>();
			AutoParentToShip[] array = Object.FindObjectsByType<AutoParentToShip>((FindObjectsSortMode)0);
			foreach (AutoParentToShip val in array)
			{
				if (!((Object)(object)((Component)val).transform.parent != (Object)null))
				{
					list.AddRange(((Component)val).GetComponentsInChildren<GrabbableObject>());
				}
			}
			return list;
		}

		private static int GetVehicleLootTotal()
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return 0;
			}
			try
			{
				VehicleController attachedVehicle = StartOfRound.Instance.attachedVehicle;
				if ((Object)(object)attachedVehicle == (Object)null)
				{
					return 0;
				}
				GrabbableObject[] componentsInChildren = ((Component)attachedVehicle).GetComponentsInChildren<GrabbableObject>();
				return componentsInChildren.Where(Utils.IsValidScrapAndNotHeld).Sum((GrabbableObject x) => x.scrapValue);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to get loot total from attached vehicle. {arg}");
			}
			return 0;
		}
	}
	internal static class NetworkUtils
	{
		public static bool IsConnected
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton == (Object)null)
				{
					return false;
				}
				return NetworkManager.Singleton.IsConnectedClient;
			}
		}

		public static bool IsServer
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton == (Object)null)
				{
					return false;
				}
				return NetworkManager.Singleton.IsServer;
			}
		}

		public static bool IsHost
		{
			get
			{
				if ((Object)(object)NetworkManager.Singleton == (Object)null)
				{
					return false;
				}
				return NetworkManager.Singleton.IsHost;
			}
		}

		public static ulong GetLocalClientId()
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null)
			{
				return 0uL;
			}
			return NetworkManager.Singleton.LocalClientId;
		}

		public static bool IsLocalClientId(ulong clientId)
		{
			return clientId == GetLocalClientId();
		}
	}
	internal static class PlayerUtils
	{
		public static PlayerControllerB GetLocalPlayerScript()
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return null;
			}
			return GameNetworkManager.Instance.localPlayerController;
		}

		public static bool IsLocalPlayer(PlayerControllerB playerScript)
		{
			return (Object)(object)playerScript == (Object)(object)GetLocalPlayerScript();
		}

		public static bool IsLocalPlayerSpawned()
		{
			return (Object)(object)GetLocalPlayerScript() != (Object)null;
		}

		public static PlayerControllerB GetPlayerScriptByClientId(ulong clientId)
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return null;
			}
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.actualClientId == clientId)
				{
					return val;
				}
			}
			return null;
		}
	}
	[BepInPlugin("com.github.zehsteam.StreamOverlays", "StreamOverlays", "1.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("com.github.zehsteam.StreamOverlays");

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static ConfigFile Config { get; private set; }

		internal static ConfigManager ConfigManager { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Logger = Logger.CreateLogSource("com.github.zehsteam.StreamOverlays");
			Logger.LogInfo((object)"StreamOverlays has awoken!");
			Config = Utils.CreateGlobalConfigFile();
			_harmony.PatchAll(typeof(NetworkManagerPatch));
			_harmony.PatchAll(typeof(GameNetworkManagerPatch));
			_harmony.PatchAll(typeof(StartOfRoundPatch));
			_harmony.PatchAll(typeof(TimeOfDayPatch));
			_harmony.PatchAll(typeof(PlayerControllerBPatch));
			_harmony.PatchAll(typeof(VehicleControllerPatch));
			_harmony.PatchAll(typeof(DepositItemsDeskPatch));
			if (ShipInventoryProxy.Enabled)
			{
				ShipInventoryProxy.PatchAll(_harmony);
			}
			ConfigManager = new ConfigManager();
			Task.Run((Func<Task?>)WebServer.Initialize);
		}

		public void LogInfoExtended(object data)
		{
			LogExtended((LogLevel)16, data);
		}

		public void LogExtended(LogLevel level, object data)
		{
			//IL_0022: 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)
			if (ConfigManager == null || ConfigManager.ExtendedLogging == null)
			{
				Logger.Log(level, data);
			}
			else if (ConfigManager.ExtendedLogging.Value)
			{
				Logger.Log(level, data);
			}
		}
	}
	internal static class PluginNetworkManager
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__HandleCustomMessage;
		}

		public static void Initialize()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			if ((Object)(object)NetworkManager.Singleton == (Object)null)
			{
				Plugin.Logger.LogError((object)"Failed to initialize PluginNetworkManager. NetworkManager.Singleton is null.");
				return;
			}
			if (NetworkManager.Singleton.CustomMessagingManager == null)
			{
				Plugin.Logger.LogError((object)"Failed to initialize PluginNetworkManager. NetworkManager.Singleton.CustomMessagingManager is null.");
				return;
			}
			CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
			object obj = <>O.<0>__HandleCustomMessage;
			if (obj == null)
			{
				HandleNamedMessageDelegate val = HandleCustomMessage;
				<>O.<0>__HandleCustomMessage = val;
				obj = (object)val;
			}
			customMessagingManager.RegisterNamedMessageHandler("ReceiveCustomMessage", (HandleNamedMessageDelegate)obj);
			Plugin.Logger.LogInfo((object)"PluginNetworkManager initialized successfully.");
		}

		public static void OnClientConnected(ulong clientId)
		{
			if (!NetworkUtils.IsServer)
			{
				return;
			}
			try
			{
				CustomMessage customMessage = new CustomMessage
				{
					DaysSpent = StartOfRound.Instance.gameStats.daysSpent,
					TimesFulfilledQuota = TimeOfDay.Instance.timesFulfilledQuota,
					DayDataList = DayManager.DayDataList.ToArray()
				};
				SendCustomMessageToClient(clientId, customMessage);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to send CustomMessage data to client: {clientId}. {arg}");
			}
		}

		private static void SendCustomMessageToClient(ulong clientId, CustomMessage customMessage)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0070: 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_00a2: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkUtils.IsServer)
			{
				Plugin.Logger.LogWarning((object)"Only the host can send messages to clients.");
				return;
			}
			try
			{
				FastBufferWriter val = default(FastBufferWriter);
				((FastBufferWriter)(ref val))..ctor(1024, (Allocator)2, -1);
				try
				{
					((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref customMessage.DaysSpent, default(ForPrimitives));
					((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref customMessage.TimesFulfilledQuota, default(ForPrimitives));
					int num = customMessage.DayDataList.Length;
					((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
					DayData[] dayDataList = customMessage.DayDataList;
					for (int i = 0; i < dayDataList.Length; i++)
					{
						DayData dayData = dayDataList[i];
						((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref dayData.Day, default(ForPrimitives));
						((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref dayData.ScrapCollected, default(ForPrimitives));
					}
					NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("ReceiveCustomMessage", clientId, val, (NetworkDelivery)3);
					Plugin.Logger.LogInfo((object)$"Sent CustomMessage data to client: {clientId}");
				}
				finally
				{
					((IDisposable)(FastBufferWriter)(ref val)).Dispose();
				}
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to send CustomMessage data to client: {clientId}. {arg}");
			}
		}

		private static void HandleCustomMessage(ulong senderId, FastBufferReader reader)
		{
			//IL_0038: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			if (!((FastBufferReader)(ref reader)).TryBeginRead(8))
			{
				Plugin.Logger.LogWarning((object)"Failed to deserialize message: Insufficient data.");
				return;
			}
			try
			{
				CustomMessage customMessage = new CustomMessage();
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref customMessage.DaysSpent, default(ForPrimitives));
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref customMessage.TimesFulfilledQuota, default(ForPrimitives));
				int num = default(int);
				((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
				customMessage.DayDataList = new DayData[num];
				for (int i = 0; i < num; i++)
				{
					customMessage.DayDataList[i] = default(DayData);
					((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref customMessage.DayDataList[i].Day, default(ForPrimitives));
					((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref customMessage.DayDataList[i].ScrapCollected, default(ForPrimitives));
				}
				Plugin.Logger.LogInfo((object)$"Received message from client: {senderId}");
				ApplyCustomMessageData(customMessage);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to deserialize message. {arg}");
			}
		}

		private static void ApplyCustomMessageData(CustomMessage customMessage)
		{
			if (customMessage == null)
			{
				Plugin.Logger.LogError((object)"Failed to apply CustomMessage data. CustomMessage is null.");
				return;
			}
			try
			{
				StartOfRound.Instance.gameStats.daysSpent = customMessage.DaysSpent;
				TimeOfDay.Instance.timesFulfilledQuota = customMessage.TimesFulfilledQuota;
				DayManager.DayDataList = customMessage.DayDataList.ToList();
				Plugin.Logger.LogInfo((object)"Applied CustomMessage data successfully!");
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to apply CustomMessage data. {arg}");
			}
		}
	}
	[Serializable]
	public class CustomMessage
	{
		public int DaysSpent;

		public int TimesFulfilledQuota;

		public DayData[] DayDataList;
	}
	internal static class SaveSystem
	{
		public static bool KeyExists(string key)
		{
			return ES3.KeyExists(GetBaseKey() + "." + key, GetCurrentSaveFilePath());
		}

		public static void SaveData<T>(string key, T data)
		{
			ES3.Save<T>(GetBaseKey() + "." + key, data, GetCurrentSaveFilePath());
		}

		public static T LoadData<T>(string key, T defaultValue = default(T))
		{
			return ES3.Load<T>(GetBaseKey() + "." + key, GetCurrentSaveFilePath(), defaultValue);
		}

		private static string GetBaseKey()
		{
			return MethodBase.GetCurrentMethod().DeclaringType.Namespace;
		}

		private static string GetCurrentSaveFilePath()
		{
			return GameNetworkManager.Instance.currentSaveFileName;
		}
	}
	internal static class Utils
	{
		public static string GetEnumName<T>(T e) where T : Enum
		{
			return Enum.GetName(typeof(T), e) ?? string.Empty;
		}

		public static string GetPluginDirectoryPath()
		{
			return Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location);
		}

		public static ConfigFile CreateConfigFile(string path, string name = null, bool saveOnInit = false)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			BepInPlugin metadata = MetadataHelper.GetMetadata((object)Plugin.Instance);
			if (name == null)
			{
				name = metadata.GUID;
			}
			name += ".cfg";
			return new ConfigFile(Path.Combine(path, name), saveOnInit, metadata);
		}

		public static ConfigFile CreateLocalConfigFile(string name = null, bool saveOnInit = false)
		{
			BepInPlugin metadata = MetadataHelper.GetMetadata((object)Plugin.Instance);
			if (name == null)
			{
				name = metadata.GUID + "-" + name;
			}
			return CreateConfigFile(Paths.ConfigPath, name, saveOnInit);
		}

		public static ConfigFile CreateGlobalConfigFile(string name = null, bool saveOnInit = false)
		{
			BepInPlugin metadata = MetadataHelper.GetMetadata((object)Plugin.Instance);
			string path = Path.Combine(Application.persistentDataPath, metadata.Name);
			if (name == null)
			{
				name = "global";
			}
			return CreateConfigFile(path, name, saveOnInit);
		}

		public static Transform GetHangarShipTransform()
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return null;
			}
			return StartOfRound.Instance.elevatorTransform;
		}

		public static bool CanShowOverlay()
		{
			if ((Object)(object)GameNetworkManager.Instance == (Object)null)
			{
				return false;
			}
			if (GameNetworkManager.Instance.isDisconnecting)
			{
				return false;
			}
			if (!PlayerUtils.IsLocalPlayerSpawned())
			{
				return false;
			}
			return true;
		}

		public static int GetPlayerCount()
		{
			if (NetworkUtils.IsServer)
			{
				if ((Object)(object)GameNetworkManager.Instance == (Object)null)
				{
					return 1;
				}
				return GameNetworkManager.Instance.connectedPlayers;
			}
			if ((Object)(object)StartOfRound.Instance == (Object)null)
			{
				return 1;
			}
			return StartOfRound.Instance.connectedPlayersAmount + 1;
		}

		public static string GetCurrentPlanetName()
		{
			if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.currentLevel == (Object)null)
			{
				return string.Empty;
			}
			return StartOfRound.Instance.currentLevel.PlanetName;
		}

		public static LevelWeatherType GetCurrentPlanetWeather()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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)
			if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.currentLevel == (Object)null)
			{
				return (LevelWeatherType)(-1);
			}
			return StartOfRound.Instance.currentLevel.currentWeather;
		}

		public static int GetDayInQuota()
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return 1;
			}
			int num = Mathf.Max(TimeOfDay.Instance.daysUntilDeadline, 0);
			int num2 = 3;
			return num2 - num + 1;
		}

		public static int GetProfitQuota()
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return 0;
			}
			return TimeOfDay.Instance.profitQuota;
		}

		public static int GetQuotaIndex()
		{
			if ((Object)(object)TimeOfDay.Instance == (Object)null)
			{
				return 1;
			}
			return TimeOfDay.Instance.timesFulfilledQuota + 1;
		}

		public static bool IsValidScrapAndNotHeld(GrabbableObject grabbableObject)
		{
			if (!IsValidScrap(grabbableObject))
			{
				return false;
			}
			if (grabbableObject.isHeld)
			{
				return false;
			}
			return true;
		}

		public static bool IsValidScrap(GrabbableObject grabbableObject)
		{
			if ((Object)(object)grabbableObject == (Object)null || (Object)(object)grabbableObject.itemProperties == (Object)null)
			{
				return false;
			}
			if (grabbableObject.deactivated)
			{
				return false;
			}
			return grabbableObject.itemProperties.isScrap;
		}

		public static Coroutine StartCoroutine(IEnumerator routine)
		{
			if ((Object)(object)Plugin.Instance != (Object)null)
			{
				return ((MonoBehaviour)Plugin.Instance).StartCoroutine(routine);
			}
			if ((Object)(object)GameNetworkManager.Instance != (Object)null)
			{
				return ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(routine);
			}
			Plugin.Logger.LogError((object)("Failed to start coroutine. " + routine));
			return null;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.zehsteam.StreamOverlays";

		public const string PLUGIN_NAME = "StreamOverlays";

		public const string PLUGIN_VERSION = "1.3.0";
	}
}
namespace com.github.zehsteam.StreamOverlays.Server
{
	public class OverlayBehavior : WebSocketBehavior
	{
		protected override void OnOpen()
		{
			UpdateOverlayFormatting();
			UpdateOverlayData();
		}

		public void SendJsonToClient(object jsonData)
		{
			((WebSocketBehavior)this).Send(JsonConvert.SerializeObject(jsonData));
		}

		public void UpdateOverlayFormatting()
		{
			SendJsonToClient(WebServer.GetOverlaysFormatting());
		}

		public void UpdateOverlayData()
		{
			SendJsonToClient(WebServer.GetOverlaysData());
		}
	}
	internal static class WebServer
	{
		private static HttpListener _httpListener;

		private static WebSocketServer _webSocketServer;

		private static bool _isRunning;

		public static int HttpPort => Plugin.ConfigManager.Server_HttpPort.Value;

		public static int WebSocketPort => Plugin.ConfigManager.Server_WebSocketPort.Value;

		public static bool IsRunning => _isRunning;

		public static async Task Initialize()
		{
			Application.quitting += Stop;
			if (PublicArchiveExists())
			{
				await DecompressPublicArchive();
			}
			if (!PublicFolderExists())
			{
				Plugin.Logger.LogFatal((object)"Error! The \"public\" folder does not exist. The overlays will not work. Please report the bug to the mod developer!");
			}
			if (Plugin.ConfigManager.Server_AutoStart.Value)
			{
				Start();
			}
		}

		public static void Start()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			if (_isRunning)
			{
				Plugin.Logger.LogWarning((object)"Server is already running!");
				return;
			}
			_isRunning = true;
			Task.Run((Action)StartHttpServer);
			_webSocketServer = new WebSocketServer($"ws://{IPAddress.Any}:{WebSocketPort}");
			_webSocketServer.AddWebSocketService<OverlayBehavior>("/overlay");
			_webSocketServer.Start();
			Plugin.Logger.LogInfo((object)$"WebSocket server started on ws://localhost:{WebSocketPort}");
		}

		public static void Stop()
		{
			if (_isRunning)
			{
				_isRunning = false;
				HttpListener httpListener = _httpListener;
				if (httpListener != null)
				{
					httpListener.Stop();
				}
				WebSocketServer webSocketServer = _webSocketServer;
				if (webSocketServer != null)
				{
					webSocketServer.Stop();
				}
				Plugin.Logger.LogInfo((object)"Server stopped.");
			}
		}

		private static void StartHttpServer()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			_httpListener = new HttpListener();
			_httpListener.Prefixes.Add($"http://{IPAddress.Any}:{HttpPort}/");
			_httpListener.Start();
			Plugin.Logger.LogInfo((object)$"HTTP server started on http://localhost:{HttpPort}");
			while (_isRunning)
			{
				try
				{
					HttpListenerContext context = _httpListener.GetContext();
					Task.Run(delegate
					{
						HandleHttpRequest(context);
					});
				}
				catch (Exception ex) when (!_isRunning)
				{
					Plugin.Logger.LogWarning((object)("HTTP server stopped: " + ex.Message));
				}
			}
		}

		private static void HandleHttpRequest(HttpListenerContext context)
		{
			HttpListenerRequest request = context.Request;
			HttpListenerResponse response = context.Response;
			try
			{
				string text = request.Url.LocalPath.TrimStart('/');
				Plugin.Instance.LogInfoExtended("Requested path: \"" + text + "\"");
				if (string.IsNullOrEmpty(text))
				{
					text = "overlay.html";
				}
				else if (!Path.HasExtension(text))
				{
					text += ".html";
				}
				if (text.Equals("config.js", StringComparison.OrdinalIgnoreCase))
				{
					response.ContentType = "application/javascript";
					string s = $"const webSocketPort = {WebSocketPort};";
					byte[] bytes = Encoding.UTF8.GetBytes(s);
					response.ContentLength64 = bytes.Length;
					response.OutputStream.Write(bytes, 0, bytes.Length);
					return;
				}
				string path = Path.Combine(Utils.GetPluginDirectoryPath(), "public");
				string text2 = Path.Combine(path, text);
				if (File.Exists(text2))
				{
					string mimeType = GetMimeType(text2);
					response.ContentType = mimeType;
					byte[] array = File.ReadAllBytes(text2);
					response.ContentLength64 = array.Length;
					response.OutputStream.Write(array, 0, array.Length);
				}
				else
				{
					response.StatusCode = 404;
					byte[] bytes2 = Encoding.UTF8.GetBytes("404 - File Not Found");
					response.ContentLength64 = bytes2.Length;
					response.OutputStream.Write(bytes2, 0, bytes2.Length);
				}
			}
			catch (Exception ex)
			{
				response.StatusCode = 500;
				byte[] bytes3 = Encoding.UTF8.GetBytes("500 - Internal Server Error");
				response.ContentLength64 = bytes3.Length;
				response.OutputStream.Write(bytes3, 0, bytes3.Length);
				Plugin.Logger.LogError((object)("Error serving request: " + ex.Message));
			}
			finally
			{
				response.OutputStream.Close();
			}
		}

		private static string GetMimeType(string filePath)
		{
			string text = Path.GetExtension(filePath).ToLower();
			if (1 == 0)
			{
			}
			string result = text switch
			{
				".html" => "text/html", 
				".css" => "text/css", 
				".js" => "application/javascript", 
				".png" => "image/png", 
				".jpg" => "image/jpeg", 
				".jpeg" => "image/jpeg", 
				".gif" => "image/gif", 
				".svg" => "image/svg+xml", 
				".woff" => "font/woff", 
				".woff2" => "font/woff2", 
				".ttf" => "font/ttf", 
				".otf" => "font/otf", 
				".mp3" => "audio/mpeg", 
				".wav" => "audio/wav", 
				".json" => "application/json", 
				_ => "application/octet-stream", 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		public static void SendJsonToClients(object jsonData)
		{
			if (_webSocketServer == null)
			{
				return;
			}
			string text = JsonConvert.SerializeObject(jsonData);
			foreach (string path in _webSocketServer.WebSocketServices.Paths)
			{
				WebSocketServiceHost val = _webSocketServer.WebSocketServices[path];
				val.Sessions.Broadcast(text);
			}
		}

		public static void UpdateOverlays()
		{
			UpdateOverlaysFormatting();
			UpdateOverlaysData();
		}

		public static void UpdateOverlaysFormatting()
		{
			SendJsonToClients(GetOverlaysFormatting());
		}

		public static void UpdateOverlaysData()
		{
			SendJsonToClients(GetOverlaysData());
		}

		public static object GetOverlaysFormatting()
		{
			return new
			{
				type = "formatting",
				crewLabel = Plugin.ConfigManager.CrewStat_Label.Value,
				moonLabel = Plugin.ConfigManager.MoonStat_Label.Value,
				dayLabel = Plugin.ConfigManager.DayStat_Label.Value,
				quotaLabel = Plugin.ConfigManager.QuotaStat_Label.Value,
				lootLabel = Plugin.ConfigManager.LootStat_Label.Value,
				averagePerDayLabel = Plugin.ConfigManager.AveragePerDayStat_Label.Value
			};
		}

		public static object GetOverlaysData()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			return new
			{
				type = "data",
				showOverlay = Utils.CanShowOverlay(),
				crewCount = Utils.GetPlayerCount(),
				moonName = Utils.GetCurrentPlanetName(),
				weatherName = Utils.GetEnumName<LevelWeatherType>(Utils.GetCurrentPlanetWeather()),
				showWeatherIcon = Plugin.ConfigManager.MoonStat_ShowWeatherIcon.Value,
				dayCount = DayManager.GetDayNumber(),
				dayInQuota = Utils.GetDayInQuota(),
				quotaValue = Utils.GetProfitQuota(),
				quotaIndex = Utils.GetQuotaIndex(),
				lootValue = LootManager.GetLootTotal(),
				averagePerDayValue = DayManager.GetAveragePerDay()
			};
		}

		private static bool PublicFolderExists()
		{
			return Directory.Exists(GetPublicFolderPath());
		}

		private static bool PublicArchiveExists()
		{
			return File.Exists(GetPublicArchivePath());
		}

		private static async Task DecompressPublicArchive()
		{
			string archivePath = GetPublicArchivePath();
			if (!File.Exists(archivePath))
			{
				return;
			}
			try
			{
				string extractPath = Utils.GetPluginDirectoryPath();
				await Task.Run(delegate
				{
					using ZipArchive zipArchive = ZipFile.OpenRead(archivePath);
					foreach (ZipArchiveEntry entry in zipArchive.Entries)
					{
						string text = Path.Combine(extractPath, entry.FullName);
						string directoryName = Path.GetDirectoryName(text);
						if (!string.IsNullOrEmpty(directoryName))
						{
							Directory.CreateDirectory(directoryName);
						}
						if (!entry.FullName.EndsWith("/"))
						{
							entry.ExtractToFile(text, overwrite: true);
						}
					}
				});
				File.Delete(archivePath);
				Plugin.Logger.LogInfo((object)"Successfully decompressed public archive.");
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)("Error while decompressing public archive: " + ex.Message));
			}
		}

		private static string GetPublicFolderPath()
		{
			return Path.Combine(Utils.GetPluginDirectoryPath(), "public");
		}

		private static string GetPublicArchivePath()
		{
			return Path.Combine(Utils.GetPluginDirectoryPath(), "public.zip");
		}
	}
}
namespace com.github.zehsteam.StreamOverlays.Patches
{
	[HarmonyPatch(typeof(DepositItemsDesk))]
	internal static class DepositItemsDeskPatch
	{
		[HarmonyPatch("SellAndDisplayItemProfits")]
		[HarmonyPostfix]
		private static void SellAndDisplayItemProfitsPatch()
		{
			if (LootManager.CanUpdateLootTotal())
			{
				LootManager.UpdateLootTotal();
				WebServer.UpdateOverlaysData();
			}
		}
	}
	[HarmonyPatch(typeof(GameNetworkManager))]
	internal static class GameNetworkManagerPatch
	{
		[HarmonyPatch("SaveGame")]
		[HarmonyPostfix]
		private static void SaveGamePatch()
		{
			DayManager.SaveDayData();
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("ResetSavedGameValues")]
		[HarmonyPostfix]
		private static void ResetSavedGameValuesPatch()
		{
			DayManager.ResetSavedDayData();
			WebServer.UpdateOverlaysData();
		}
	}
	[HarmonyPatch(typeof(NetworkManager))]
	internal static class NetworkManagerPatch
	{
		[HarmonyPatch("Initialize")]
		[HarmonyPostfix]
		private static void InitializePatch()
		{
			PluginNetworkManager.Initialize();
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerControllerBPatch
	{
		[HarmonyPatch("ConnectClientToPlayerObject")]
		[HarmonyPostfix]
		private static void ConnectClientToPlayerObjectPatch()
		{
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("GrabObjectClientRpc")]
		[HarmonyPostfix]
		private static void GrabObjectClientRpcPatch(NetworkObjectReference grabbedObject)
		{
			NetworkObject val = default(NetworkObject);
			GrabbableObject val2 = default(GrabbableObject);
			if (LootManager.CanUpdateLootTotal() && ((NetworkObjectReference)(ref grabbedObject)).TryGet(ref val, (NetworkManager)null) && ((Component)val).TryGetComponent<GrabbableObject>(ref val2) && (val2.isInShipRoom || val2.isInElevator))
			{
				LootManager.UpdateLootTotal();
				WebServer.UpdateOverlaysData();
			}
		}

		[HarmonyPatch("ThrowObjectClientRpc")]
		[HarmonyPostfix]
		private static void ThrowObjectClientRpcPatch(bool droppedInElevator, bool droppedInShipRoom)
		{
			if (LootManager.CanUpdateLootTotal() && (droppedInShipRoom || droppedInElevator))
			{
				LootManager.UpdateLootTotal();
				WebServer.UpdateOverlaysData();
			}
		}

		[HarmonyPatch("PlaceGrabbableObject")]
		[HarmonyPostfix]
		private static void PlaceGrabbableObjectPatch(GrabbableObject placeObject)
		{
			if (LootManager.CanUpdateLootTotal() && !((Object)(object)placeObject == (Object)null) && (placeObject.isInShipRoom || placeObject.isInElevator))
			{
				LootManager.UpdateLootTotal();
				WebServer.UpdateOverlaysData();
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	internal static class StartOfRoundPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch()
		{
			DayManager.LoadDayData();
			LootManager.UpdateLootTotal();
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("OnPlayerConnectedClientRpc")]
		[HarmonyPostfix]
		private static void OnPlayerConnectedClientRpcPatch()
		{
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("SyncShipUnlockablesClientRpc")]
		[HarmonyPostfix]
		private static void SyncShipUnlockablesClientRpcPatch()
		{
			LootManager.UpdateLootTotal();
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("OnClientConnect")]
		[HarmonyPostfix]
		private static void OnClientConnectPatch(ulong clientId)
		{
			WebServer.UpdateOverlaysData();
			PluginNetworkManager.OnClientConnected(clientId);
		}

		[HarmonyPatch("OnPlayerDC")]
		[HarmonyPostfix]
		private static void OnPlayerDCPatch()
		{
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("ChangeLevelClientRpc")]
		[HarmonyPostfix]
		private static void ChangeLevelClientRpcPatch()
		{
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("StartGame")]
		[HarmonyPostfix]
		private static void StartGamePatch()
		{
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("EndOfGame")]
		[HarmonyPostfix]
		private static void EndOfGamePatch(int scrapCollected)
		{
			DayManager.AddDayData(scrapCollected);
			LootManager.UpdateLootTotal();
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("ReviveDeadPlayers")]
		[HarmonyPostfix]
		private static void ReviveDeadPlayersPatch()
		{
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("SetMapScreenInfoToCurrentLevel")]
		[HarmonyPostfix]
		private static void SetMapScreenInfoToCurrentLevelPatch()
		{
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("ResetShip")]
		[HarmonyPostfix]
		private static void ResetShipPatch()
		{
			LootManager.UpdateLootTotal();
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("OnLocalDisconnect")]
		[HarmonyPostfix]
		private static void OnLocalDisconnectPatch()
		{
			WebServer.UpdateOverlaysData();
		}
	}
	[HarmonyPatch(typeof(TimeOfDay))]
	internal static class TimeOfDayPatch
	{
		[HarmonyPatch("SyncNewProfitQuotaClientRpc")]
		[HarmonyPostfix]
		private static void SyncNewProfitQuotaClientRpcPatch()
		{
			WebServer.UpdateOverlaysData();
		}

		[HarmonyPatch("UpdateProfitQuotaCurrentTime")]
		[HarmonyPostfix]
		private static void UpdateProfitQuotaCurrentTimePatch()
		{
			WebServer.UpdateOverlaysData();
		}
	}
	[HarmonyPatch(typeof(VehicleController))]
	internal static class VehicleControllerPatch
	{
		[HarmonyPatch("CollectItemsInTruck")]
		[HarmonyPostfix]
		private static void CollectItemsInTruckPatch()
		{
			if (LootManager.CanUpdateLootTotal())
			{
				LootManager.UpdateLootTotal();
				WebServer.UpdateOverlaysData();
			}
		}
	}
}
namespace com.github.zehsteam.StreamOverlays.Dependencies
{
	internal static class LethalConfigProxy
	{
		public const string PLUGIN_GUID = "ainavt.lc.lethalconfig";

		private static bool? _enabled;

		public static bool Enabled
		{
			get
			{
				bool valueOrDefault = _enabled.GetValueOrDefault();
				if (!_enabled.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig");
					_enabled = valueOrDefault;
				}
				return _enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SkipAutoGen()
		{
			LethalConfigManager.SkipAutoGen();
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfig<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Expected O, but got Unknown
			AcceptableValueBase acceptableValues = ((ConfigEntryBase)configEntry).Description.AcceptableValues;
			if (acceptableValues != null)
			{
				if (acceptableValues is AcceptableValueRange<float> || acceptableValues is AcceptableValueRange<int>)
				{
					AddConfigSlider<T>(configEntry, requiresRestart);
					return;
				}
				if (acceptableValues is AcceptableValueList<string>)
				{
					AddConfigDropdown<T>(configEntry, requiresRestart);
					return;
				}
			}
			if (!(configEntry is ConfigEntry<string> val))
			{
				if (!(configEntry is ConfigEntry<bool> val2))
				{
					if (!(configEntry is ConfigEntry<float> val3))
					{
						if (!(configEntry is ConfigEntry<int> val4))
						{
							throw new NotSupportedException($"Unsupported type: {typeof(T)}");
						}
						LethalConfigManager.AddConfigItem((BaseConfigItem)new IntInputFieldConfigItem(val4, requiresRestart));
					}
					else
					{
						LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatInputFieldConfigItem(val3, requiresRestart));
					}
				}
				else
				{
					LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(val2, requiresRestart));
				}
			}
			else
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new TextInputFieldConfigItem(val, requiresRestart));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfigSlider<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			if (!(configEntry is ConfigEntry<float> val))
			{
				if (!(configEntry is ConfigEntry<int> val2))
				{
					throw new NotSupportedException($"Slider not supported for type: {typeof(T)}");
				}
				LethalConfigManager.AddConfigItem((BaseConfigItem)new IntSliderConfigItem(val2, requiresRestart));
			}
			else
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(val, requiresRestart));
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddConfigDropdown<T>(ConfigEntry<T> configEntry, bool requiresRestart = false)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (configEntry is ConfigEntry<string> val)
			{
				LethalConfigManager.AddConfigItem((BaseConfigItem)new TextDropDownConfigItem(val, requiresRestart));
				return;
			}
			throw new NotSupportedException($"Dropdown not supported for type: {typeof(T)}");
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddButton(string section, string name, string description, string buttonText, Action callback)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			LethalConfigManager.AddConfigItem((BaseConfigItem)new GenericButtonConfigItem(section, name, description, buttonText, (GenericButtonHandler)delegate
			{
				callback?.Invoke();
			}));
		}
	}
}
namespace com.github.zehsteam.StreamOverlays.Dependencies.ShipInventoryProxy
{
	internal static class ShipInventoryProxy
	{
		public const string PLUGIN_GUID = "ShipInventory";

		private static bool? _enabled;

		public static bool Enabled
		{
			get
			{
				bool valueOrDefault = _enabled.GetValueOrDefault();
				if (!_enabled.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("ShipInventory");
					_enabled = valueOrDefault;
				}
				return _enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void PatchAll(Harmony harmony)
		{
			try
			{
				harmony.PatchAll(typeof(ItemManagerPatch));
				harmony.PatchAll(typeof(ChuteInteractPatch));
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to apply ShipInventory patches. {arg}");
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static int GetLootTotal()
		{
			try
			{
				return ItemManager.GetTotalValue();
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to get the total loot value from ShipInventory. {arg}");
			}
			return 0;
		}
	}
}
namespace com.github.zehsteam.StreamOverlays.Dependencies.ShipInventoryProxy.Patches
{
	[HarmonyPatch(typeof(ChuteInteract))]
	internal static class ChuteInteractPatch
	{
		[HarmonyPatch("SpawnItemClientRpc")]
		[HarmonyPostfix]
		private static void SpawnItemClientRpcPatch()
		{
			if (LootManager.CanUpdateLootTotal())
			{
				LootManager.UpdateLootTotal();
				WebServer.UpdateOverlaysData();
			}
		}
	}
	[HarmonyPatch(typeof(ItemManager))]
	internal static class ItemManagerPatch
	{
		[HarmonyPatch("SetItems")]
		[HarmonyPostfix]
		private static void SetItemsPatch()
		{
			if (LootManager.CanUpdateLootTotal())
			{
				LootManager.UpdateLootTotal();
				WebServer.UpdateOverlaysData();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}