Decompiled source of LethalStats v1.0.1

LethalStats.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using Coroner;
using GameNetcodeStuff;
using HarmonyLib;
using LethalStats.Models;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("LethalStats")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A mod that collects your stats so you can view them at https://splitstats.io")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d78ce17398a6ea541ce02d5e69161d689d6c138e")]
[assembly: AssemblyProduct("LethalStats")]
[assembly: AssemblyTitle("LethalStats")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace LethalStats
{
	public class PluginInfo
	{
		public const string PLUGIN_GUID = "com.danos.lethalstats";

		public const string PLUGIN_NAME = "LethalStats";

		public const string PLUGIN_VERSION = "1.0.1";
	}
	[BepInPlugin("com.danos.lethalstats", "LethalStats", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class LethalStats : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("com.danos.lethalstats");

		private static LethalStats Instance;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin LethalStats is loaded!");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalStats will upload stats when you see your post-game summary screen!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "LethalStats";

		public const string PLUGIN_NAME = "LethalStats";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace LethalStats.Patches
{
	[HarmonyPatch(typeof(DepositItemsDesk), "CheckAllPlayersSoldItemsServerRpc")]
	public class DepositItemsDeskPatch
	{
		private static bool Prefix(DepositItemsDesk __instance)
		{
			try
			{
				long num = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
				if (DanosLastSent.unixTime > 0 && DanosLastSent.unixTime + 10 > num)
				{
					return true;
				}
				if ((Object)(object)__instance == (Object)null)
				{
					return true;
				}
				if (__instance.itemsOnCounter == null)
				{
					return true;
				}
				if (__instance.itemsOnCounter.Count == 0)
				{
					return true;
				}
				if ((Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
				{
					return true;
				}
				if ((Object)(object)StartOfRound.Instance == (Object)null)
				{
					return true;
				}
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)instance.localPlayerController == (Object)null)
				{
					return true;
				}
				ulong playerClientId = instance.localPlayerController.playerClientId;
				ulong playerSteamId = instance.localPlayerController.playerSteamId;
				ulong playerClientId2 = instance.allPlayerScripts[0].playerClientId;
				ulong playerSteamId2 = instance.allPlayerScripts[playerClientId2].playerSteamId;
				if (playerSteamId2 == 0)
				{
					return true;
				}
				Console.WriteLine($"[LethalStats] [DepositItemsDeskPatch]: Host Steam ID: {playerSteamId2}");
				List<DanosGlobalContributions> list = new List<DanosGlobalContributions>();
				foreach (GrabbableObject item2 in __instance.itemsOnCounter)
				{
					if (!((Object)(object)item2 == (Object)null) && !((Object)(object)item2.itemProperties == (Object)null) && item2.itemProperties.isScrap && !string.IsNullOrEmpty(item2.itemProperties.itemName))
					{
						DanosGlobalContributions item = new DanosGlobalContributions
						{
							itemName = item2.itemProperties.itemName,
							scrapValueAverage = item2.scrapValue
						};
						list.Add(item);
					}
				}
				list = (from x in list
					group x by x.itemName into x
					select new DanosGlobalContributions
					{
						itemName = x.Key,
						count = x.Count(),
						scrapValueAverage = (int)x.Average((DanosGlobalContributions y) => y.scrapValueAverage)
					}).ToList();
				var anon = new
				{
					MySteamID = playerSteamId,
					HostSteamID = playerSteamId2,
					SoldAt = num,
					ItemsSold = list
				};
				string content = JsonConvert.SerializeObject((object)anon);
				HttpClient httpClient = new HttpClient();
				httpClient.BaseAddress = new Uri("https://lethalstatsservertasks.azurewebsites.net");
				StringContent content2 = new StringContent(content, Encoding.UTF8, "application/json");
				httpClient.PostAsync("/api/PostGlobalContribution", content2);
				DanosLastSent.unixTime = num;
			}
			catch (Exception ex)
			{
				Console.WriteLine("[LethalStats] [DepositItemsDeskPatch]: Error in Prefix: " + ex.Message);
			}
			try
			{
				Terminal terminal = TerminalPatches.Terminal;
				if ((Object)(object)terminal != (Object)null)
				{
					((MonoBehaviour)terminal).StartCoroutine(TerminalPatches.GatherGlobalStatsCoroutine(terminal));
				}
			}
			catch (Exception ex2)
			{
				Console.WriteLine("[LethalStats] [DepositItemsDeskPatch]: Error in updating global challenges: " + ex2.Message);
			}
			return true;
		}
	}
	public static class DanosLastSent
	{
		public static long unixTime { get; set; }
	}
	[HarmonyPatch(typeof(HUDManager))]
	[HarmonyPatch("FillEndGameStats")]
	internal class HUDManagerFillEndGameStatsPatch
	{
		public static string DebugPrefix = "[LethalStatsMod] [HUDManagerFillEndGameStatsPatch]: ";

		public static void ShowResult(bool successful)
		{
			try
			{
				Debug.Log((object)(DebugPrefix + "ShowResult called"));
				if ((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
				{
					Debug.Log((object)(DebugPrefix + "localPlayerController is null"));
					return;
				}
				Debug.Log((object)(DebugPrefix + "localPlayerController is not null"));
				HUDManager instance = HUDManager.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					Debug.Log((object)(DebugPrefix + "hudManager is null"));
				}
				else
				{
					((MonoBehaviour)instance).StartCoroutine(ShowPostResultsCoroutine(successful, instance));
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		public static void Prefix()
		{
			try
			{
				bool flag = true;
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				if (DanosPlayerStats.HostSteamID == 0 || DanosPlayerStats.RoundID == null)
				{
					ulong playerClientId = instance.allPlayerScripts[0].playerClientId;
					ulong playerSteamId = instance.allPlayerScripts[playerClientId].playerSteamId;
					if (playerSteamId == 0)
					{
						return;
					}
					bool flag2 = playerSteamId != DanosPlayerStats.HostSteamID;
					DanosPlayerStats.HostSteamID = playerSteamId;
					if (flag2)
					{
						Debug.Log((object)(DebugPrefix + "Host changed, reset the values"));
					}
					else
					{
						Debug.Log((object)(DebugPrefix + "Host is the same, do nothing"));
					}
					DanosPlayerStats.RoundID = GenerateRoundID(instance);
					DanosPlayerStats.RoundInitialized = true;
					if (DanosPlayerStats.RoundStart == 0)
					{
						flag = false;
					}
				}
				UpdatePlayerStats(instance);
				UpdateTimeOfDayStats();
				UpdateScrapOnShip();
				UpdateRoundEnd();
				UpdateCreditsAtEnd();
				UpdateTotalScrap(instance);
				UpdateNetworkPlayerStats(instance);
				UpdateTeamStats(instance);
				UpdateFired();
				if (!flag)
				{
					DanosPlayerStats.RoundStart = DanosPlayerStats.RoundEnd;
				}
				DanosPlayerStats.RoundID = GenerateRoundID(instance);
				Debug.Log((object)(DebugPrefix + "Posting results"));
				bool flag3 = DanosPlayerStats.PostResults();
				Debug.Log((object)(DebugPrefix + $"ShowResult called {flag3}"));
				DanosPlayerStats.ResetValues();
			}
			catch (Exception ex)
			{
				Debug.Log((object)ex.Message);
			}
		}

		private static string GenerateRoundID(StartOfRound instance)
		{
			try
			{
				ulong playerClientId = instance.allPlayerScripts[0].playerClientId;
				ulong playerSteamId = instance.allPlayerScripts[playerClientId].playerSteamId;
				if (playerSteamId == 0)
				{
					return null;
				}
				bool flag = playerSteamId != DanosPlayerStats.HostSteamID;
				DanosPlayerStats.HostSteamID = playerSteamId;
				if (flag)
				{
					Debug.Log((object)(DebugPrefix + "Host changed, reset the values"));
				}
				else
				{
					Debug.Log((object)(DebugPrefix + "Host is the same, do nothing"));
				}
				List<ulong> values = (from x in instance.allPlayerScripts
					select x.playerSteamId into x
					orderby x descending
					select x).ToList();
				string text = string.Join(",", values);
				string roundString = playerSteamId + "," + text;
				return DanosPlayerStats.GetSHA256(roundString);
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
				return null;
			}
		}

		private static IEnumerator ShowPostResultsCoroutine(bool Success, HUDManager __instance)
		{
			yield return (object)new WaitForSeconds(22f);
			if (Success)
			{
				__instance.DisplayTip("Sent Stats!", "Stats successfully sent to SplitStats.io!", false, false, "LC_Tip1");
			}
			else
			{
				__instance.DisplayTip("Stats not sent!", "Failed to send stats to SplitStats.io. Try again later.", true, false, "LC_Tip1");
			}
		}

		private static void UpdateTeamStats(StartOfRound instance)
		{
			try
			{
				EndOfGameStats gameStats = instance.gameStats;
				if (gameStats == null)
				{
					return;
				}
				DanosPlayerStats.DaysOnTheJob = gameStats.daysSpent;
				DanosPlayerStats.TeamDeaths = gameStats.deaths;
				PlayerStats[] allPlayerStats = gameStats.allPlayerStats;
				if (allPlayerStats == null)
				{
					return;
				}
				PlayerStats[] array = allPlayerStats;
				foreach (PlayerStats val in array)
				{
					if (val.isActivePlayer)
					{
						DanosPlayerStats.TeamStepsTaken += val.stepsTaken;
					}
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static void UpdateFired()
		{
			try
			{
				TimeOfDay instance = TimeOfDay.Instance;
				if (!((Object)(object)instance == (Object)null))
				{
					bool flag = (float)instance.daysUntilDeadline <= 0f;
					Debug.Log((object)(DebugPrefix + "TimeUntilDeadline: " + instance.daysUntilDeadline));
					if (!flag)
					{
						DanosPlayerStats.Fired = false;
					}
					else if (DanosPlayerStats.QuotaStringA >= DanosPlayerStats.QuotaStringB)
					{
						DanosPlayerStats.Fired = false;
					}
					else
					{
						DanosPlayerStats.Fired = true;
					}
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static float CalculateLootValue()
		{
			try
			{
				GameObject val = GameObject.Find("/Environment/HangarShip");
				List<GrabbableObject> source = (from obj in val.GetComponentsInChildren<GrabbableObject>()
					where ((Object)obj).name != "ClipboardManual" && ((Object)obj).name != "StickyNoteItem"
					select obj).ToList();
				return source.Sum((GrabbableObject scrap) => scrap.scrapValue);
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
				return 0f;
			}
		}

		private static void UpdatePlayerStats(StartOfRound instance)
		{
			try
			{
				ulong playerClientId = instance.localPlayerController.playerClientId;
				PlayerStats val = instance.gameStats.allPlayerStats[playerClientId];
				DanosPlayerStats.StepsTaken = val.stepsTaken;
				UpdatePlayerDeathStats(instance);
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static void UpdatePlayerDeathStats(StartOfRound instance)
		{
			try
			{
				if (instance.localPlayerController.isPlayerDead)
				{
					AdvancedCauseOfDeath? causeOfDeath = API.GetCauseOfDeath(instance.localPlayerController);
					if (causeOfDeath.HasValue)
					{
						DanosPlayerStats.IncrementDeathCount(causeOfDeath);
					}
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static void UpdateTimeOfDayStats()
		{
			try
			{
				TimeOfDay instance = TimeOfDay.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					DanosPlayerStats.QuotaStringA = instance.quotaFulfilled;
					DanosPlayerStats.QuotaStringB = instance.profitQuota;
					DanosPlayerStats.QuotaStringC = instance.timesFulfilledQuota;
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static void UpdateScrapOnShip()
		{
			try
			{
				DanosPlayerStats.ScrapOnShip = CalculateLootValue();
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static void UpdateRoundEnd()
		{
			try
			{
				DanosPlayerStats.RoundEnd = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static void UpdateCreditsAtEnd()
		{
			try
			{
				Terminal val = Object.FindObjectOfType<Terminal>();
				if ((Object)(object)val != (Object)null)
				{
					DanosPlayerStats.CreditsAtEnd = val.groupCredits;
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static void UpdateTotalScrap(StartOfRound instance)
		{
			try
			{
				RoundManager instance2 = RoundManager.Instance;
				if ((Object)(object)instance2 != (Object)null)
				{
					DanosPlayerStats.TotalScrapOnMap = instance2.totalScrapValueInLevel;
					DanosPlayerStats.TotalScrapCollectedThisRound = instance2.scrapCollectedInLevel;
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static void UpdateNetworkPlayerStats(StartOfRound instance)
		{
			try
			{
				if ((Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
				{
					return;
				}
				ulong playerClientId = instance.localPlayerController.playerClientId;
				ulong playerSteamId = instance.localPlayerController.playerSteamId;
				string playerUsername = instance.localPlayerController.playerUsername;
				DanosPlayerStats.MySteamID = playerSteamId;
				DanosPlayerStats.MyUsername = playerUsername;
				if (instance.gameStats.allPlayerStats.Count() > (int)playerClientId)
				{
					PlayerStats val = instance.gameStats.allPlayerStats[playerClientId];
					DanosPlayerStats.StepsTaken = val.stepsTaken;
				}
				try
				{
					List<PlayerControllerB> list = instance.allPlayerScripts.Where((PlayerControllerB x) => x.playerSteamId != 0).ToList();
					DanosPlayerStats.PlayersInLobby = list.Count;
					DanosPlayerStats.PlayersDead = list.Count((PlayerControllerB x) => x.isPlayerDead);
				}
				catch (Exception ex)
				{
					Debug.Log((object)(DebugPrefix + ex.Message));
				}
			}
			catch (Exception ex2)
			{
				Debug.Log((object)(DebugPrefix + ex2.Message));
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SetItemInElevator")]
	public class SetItemInElevator_Prefix
	{
		private static bool Prefix(PlayerControllerB __instance, bool droppedInShipRoom, bool droppedInElevator, GrabbableObject gObject)
		{
			try
			{
				if ((Object)(object)gObject == (Object)null)
				{
					return true;
				}
				if ((Object)(object)gObject.itemProperties == (Object)null)
				{
					return true;
				}
				if (!gObject.itemProperties.isScrap)
				{
					return true;
				}
				if (string.IsNullOrEmpty(gObject.itemProperties.itemName))
				{
					return true;
				}
				if (gObject.isInShipRoom == droppedInShipRoom)
				{
					return true;
				}
				if (gObject.scrapPersistedThroughRounds)
				{
					return true;
				}
				if (!droppedInShipRoom)
				{
					if (DanosPlayerStats.PlayerItems.Exists((DanosPlayerItem x) => x.Id == gObject.itemProperties.itemId && x.ItemName == gObject.itemProperties.itemName))
					{
						DanosPlayerStats.PlayerItems.Remove(DanosPlayerStats.PlayerItems.Find((DanosPlayerItem x) => x.Id == gObject.itemProperties.itemId && x.ItemName == gObject.itemProperties.itemName));
					}
					return true;
				}
				DanosPlayerItem item = new DanosPlayerItem
				{
					Id = gObject.itemProperties.itemId,
					ItemName = gObject.itemProperties.itemName,
					ItemValue = gObject.scrapValue,
					CreditsWorth = gObject.itemProperties.creditsWorth,
					CollectedAt = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
				};
				DanosPlayerStats.PlayerItems.Add(item);
			}
			catch (Exception ex)
			{
				Console.WriteLine("[LethalStats] [SetItemInElevator_Prefix]: Error in Prefix: " + ex.Message);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(StartMatchLever), "PullLeverAnim")]
	public static class PullLeverAnimPatch
	{
		public static string DebugPrefix = "[LethalStats] [PullLeverAnimPatch]: ";

		private static void Postfix()
		{
			try
			{
				StartOfRound instance = StartOfRound.Instance;
				if (!((Object)(object)instance == (Object)null))
				{
					if (instance.inShipPhase)
					{
						Debug.Log((object)(DebugPrefix + "In ship phase, reset the values"));
						DanosPlayerStats.ResetValues();
						UpdateHostInfo();
						UpdateLevelName();
						UpdateRoundStartTime();
					}
					else
					{
						Debug.Log((object)(DebugPrefix + "Not in ship phase, do nothing"));
					}
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + "Error in Postfix: " + ex.Message));
			}
		}

		private static void UpdateHostInfo()
		{
			try
			{
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					return;
				}
				ulong playerClientId = instance.allPlayerScripts[0].playerClientId;
				ulong playerSteamId = instance.allPlayerScripts[playerClientId].playerSteamId;
				if (playerSteamId != 0)
				{
					bool flag = playerSteamId != DanosPlayerStats.HostSteamID;
					DanosPlayerStats.HostSteamID = playerSteamId;
					if (flag)
					{
						Debug.Log((object)(DebugPrefix + "Host changed, reset the values"));
					}
					else
					{
						Debug.Log((object)(DebugPrefix + "Host is the same, do nothing"));
					}
					DanosPlayerStats.RoundID = $"{DanosPlayerStats.HostSteamID}&&{instance.randomMapSeed}";
					DanosPlayerStats.RoundInitialized = true;
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static void UpdateLevelName()
		{
			try
			{
				StartOfRound instance = StartOfRound.Instance;
				if (!((Object)(object)instance == (Object)null))
				{
					SelectableLevel currentLevel = instance.currentLevel;
					if ((Object)(object)currentLevel != (Object)null)
					{
						DanosPlayerStats.LevelName = currentLevel.sceneName;
					}
				}
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}

		private static void UpdateRoundStartTime()
		{
			try
			{
				DanosPlayerStats.RoundStart = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
			}
			catch (Exception ex)
			{
				Debug.Log((object)(DebugPrefix + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	public static class Events
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void Awake(ref Terminal __instance)
		{
			TerminalPatches.Terminal = __instance;
		}
	}
	[HarmonyPatch(typeof(Terminal), "Start")]
	public static class TerminalPatches
	{
		public static Terminal Terminal { get; internal set; }

		private static void Postfix(Terminal __instance)
		{
			((MonoBehaviour)__instance).StartCoroutine(GatherGlobalStatsCoroutine(__instance));
		}

		public static IEnumerator GatherGlobalStatsCoroutine(Terminal a_term)
		{
			Task task = GatherGlobalStats(a_term);
			yield return (object)new WaitUntil((Func<bool>)(() => task.IsCompleted));
			if (task.Exception != null)
			{
				Debug.LogError((object)("[LethalStats] [TerminalPatches]: Error in GatherGlobalStats: " + task.Exception.Message));
			}
		}

		private static IEnumerator ShowChallengeAvailableCoroutine()
		{
			yield return (object)new WaitForSeconds(5f);
			try
			{
				if (!DanosGlobalChallenges.ShownMessageThisSession)
				{
					HUDManager hUDManager = HUDManager.Instance;
					if ((Object)(object)hUDManager != (Object)null)
					{
						hUDManager.DisplayTip("LethalStats", "New Orders available, use command \"global\" in the terminal.", false, false, "LC_Tip1");
						DanosGlobalChallenges.ShownMessageThisSession = true;
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[LethalStats] [TerminalPatches]: Error in ShowChallengeAvailableCoroutine: " + ex.Message));
			}
		}

		public static async Task GatherGlobalStats(Terminal a_term)
		{
			string DisplayText2 = "We are gathering the latest global challenge information. Please wait...";
			string terminalWord = "global";
			TerminalNode terminalNode = ScriptableObject.CreateInstance<TerminalNode>();
			terminalNode.displayText = DisplayText2;
			terminalNode.clearPreviousText = true;
			terminalNode.terminalEvent = "";
			TerminalKeyword terminalKeyword = ScriptableObject.CreateInstance<TerminalKeyword>();
			terminalKeyword.word = terminalWord;
			terminalKeyword.isVerb = false;
			terminalKeyword.specialKeywordResult = terminalNode;
			Terminal terminal = Terminal;
			if ((Object)(object)terminal != (Object)null)
			{
				if ((Object)(object)terminal.terminalNodes != (Object)null)
				{
					if ((Object)(object)((IEnumerable<TerminalKeyword>)terminal.terminalNodes.allKeywords).FirstOrDefault((Func<TerminalKeyword, bool>)((TerminalKeyword x) => x.word == terminalWord)) == (Object)null)
					{
						terminal.terminalNodes.allKeywords = CollectionExtensions.AddItem<TerminalKeyword>((IEnumerable<TerminalKeyword>)terminal.terminalNodes.allKeywords, terminalKeyword).ToArray();
						Console.WriteLine("[LethalStats] [TerminalPatches]: Terminal object has terminalKeyword");
					}
					else
					{
						Console.WriteLine("[LethalStats] [TerminalPatches]: Terminal object already has terminalKeyword");
					}
				}
				else
				{
					Console.WriteLine("[LethalStats] [TerminalPatches]: Terminal object does not have terminalNodes");
				}
			}
			else
			{
				Console.WriteLine("[LethalStats] [TerminalPatches]: Terminal object is null");
			}
			bool giveNotification = false;
			try
			{
				using HttpClient client = new HttpClient();
				HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "https://lethalstatsservertasks.azurewebsites.net/api/GetCurrentGlobalChallenges");
				HttpResponseMessage response = await client.SendAsync(request);
				if (response.IsSuccessStatusCode)
				{
					string content = await response.Content.ReadAsStringAsync();
					Debug.Log((object)content);
					DanosGlobalChallenge[] globalChallenges = JsonConvert.DeserializeObject<DanosGlobalChallenge[]>(content);
					if (globalChallenges == null)
					{
						Console.WriteLine("[LethalStats] [TerminalPatches]: GlobalChallenges is null");
						return;
					}
					DanosGlobalChallenge first = globalChallenges.FirstOrDefault();
					if (first == null)
					{
						return;
					}
					DanosGlobalChallenges.GlobalChallenge = first;
					Console.WriteLine("[LethalStats] [TerminalPatches]: GlobalChallenge: " + first.Title);
					giveNotification = true;
				}
			}
			catch (Exception ex2)
			{
				Debug.LogError((object)("[LethalStats] [TerminalPatches]: Error in GatherGlobalStats: " + ex2.Message));
			}
			DisplayText2 = "No global challenge available at this time. Please check back later.";
			if (DanosGlobalChallenges.GlobalChallenge != null)
			{
				terminalWord = "global";
				DisplayText2 = DanosGlobalChallenges.GlobalChallenge.TerminalText ?? "";
			}
			try
			{
				terminalNode.displayText = DisplayText2;
				terminalNode.clearPreviousText = true;
				terminalKeyword.word = terminalWord;
				for (int i = 0; i < terminal.terminalNodes.allKeywords.Length; i++)
				{
					if (terminal.terminalNodes.allKeywords[i].word == terminalWord)
					{
						terminal.terminalNodes.allKeywords[i] = terminalKeyword;
					}
				}
				if (giveNotification)
				{
					((MonoBehaviour)a_term).StartCoroutine(ShowChallengeAvailableCoroutine());
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[LethalStats] [TerminalPatches]: Error in GatherGlobalStats: " + ex.Message));
			}
		}
	}
}
namespace LethalStats.Models
{
	public static class DanosGlobalChallenges
	{
		public static bool ShownMessageThisSession { get; set; }

		public static DanosGlobalChallenge GlobalChallenge { get; set; }
	}
	public class GlobalChallengeList
	{
		public DanosGlobalChallenge[] Property1 { get; set; }
	}
	public class DanosGlobalChallenge
	{
		public int ID { get; set; }

		public string Title { get; set; }

		public string TerminalText { get; set; }

		public string ChallengeType { get; set; }

		public int Target { get; set; }

		public int CurrentProgress { get; set; }

		public int StartDateUTC { get; set; }

		public int EndDateUTC { get; set; }

		public string Criteria { get; set; }
	}
	public class DanosGlobalContributions
	{
		public string itemName { get; set; } = "";


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


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

	}
	public class DanosPlayerEvent
	{
		public string EventName { get; set; }

		public DateTime Timestamp { get; set; }

		public Dictionary<string, string> AdditionalDetails { get; set; }

		public DanosPlayerEvent(string eventName, Dictionary<string, string> additionalDetails = null)
		{
			EventName = eventName;
			Timestamp = DateTime.UtcNow;
			AdditionalDetails = additionalDetails ?? new Dictionary<string, string>();
		}
	}
	public class DanosPlayerItem
	{
		public int Id { get; set; } = 0;


		public string ItemName { get; set; } = "";


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


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


		public long CollectedAt { get; set; } = 0L;

	}
	public class DanosPlayerMods
	{
		public string ModGUID { get; set; } = "";


		public string ModName { get; set; } = "";


		public string ModVersion { get; set; } = "";


		public static List<DanosPlayerMods> CollectMods()
		{
			List<DanosPlayerMods> list = new List<DanosPlayerMods>();
			try
			{
				Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos;
				foreach (PluginInfo value in pluginInfos.Values)
				{
					list.Add(new DanosPlayerMods
					{
						ModGUID = value.Metadata.GUID,
						ModName = value.Metadata.Name,
						ModVersion = value.Metadata.Version.ToString()
					});
				}
			}
			catch (Exception ex)
			{
				Console.WriteLine("Error in CollectMods: " + ex.Message);
				list = new List<DanosPlayerMods>();
			}
			return list;
		}
	}
	public class DanosPlayerStats
	{
		public static string RoundID = "";

		public static DateTime LastSentResults = DateTime.MinValue;

		public static List<DanosPlayerEvent> PlayerEvents = new List<DanosPlayerEvent>();

		public static List<DanosPlayerItem> PlayerItems = new List<DanosPlayerItem>();

		public static bool HasSentResults = false;

		public static bool RoundInitialized = false;

		public static long RoundStart = 0L;

		public static long RoundEnd = 0L;

		public static long QuotaStringA = 0L;

		public static long QuotaStringB = 0L;

		public static long QuotaStringC = 0L;

		public static Dictionary<AdvancedCauseOfDeath?, int> deathCounts = new Dictionary<AdvancedCauseOfDeath?, int>();

		public static string LevelName { get; set; } = "Unknown";


		public static double RoundDuration => (double)(RoundEnd - RoundStart) / 60.0;

		public static int TotalScrapCollectedThisRound { get; set; }

		public static float TotalScrapOnMap { get; set; }

		public static int DaysOnTheJob { get; set; }

		public static float ScrapOnShip { get; set; }

		public static int ScrapValueCollected { get; set; }

		public static int TeamDeaths { get; set; }

		public static int TeamStepsTaken { get; set; }

		public static int CreditsAtEnd { get; set; }

		public static int PlayersInLobby { get; set; }

		public static int PlayersDead { get; set; }

		public static int StepsTaken { get; set; }

		public static ulong MySteamID { get; set; }

		public static string MyUsername { get; set; }

		public static ulong HostSteamID { get; set; }

		public static bool Fired { get; set; } = false;


		public static int Deaths { get; set; }

		public static void IncrementDeathCount(AdvancedCauseOfDeath? cause)
		{
			if (!deathCounts.ContainsKey(cause))
			{
				deathCounts[cause] = 0;
			}
			deathCounts[cause]++;
			Deaths++;
		}

		public static int GetDeathCount(AdvancedCauseOfDeath? cause)
		{
			return deathCounts.ContainsKey(cause) ? deathCounts[cause] : 0;
		}

		public static void ResetDeathCounts()
		{
			deathCounts.Clear();
		}

		public static bool PostResults()
		{
			try
			{
				if ((DateTime.Now - LastSentResults).TotalSeconds < 30.0)
				{
					Debug.Log((object)"Results were sent in the last 30 seconds, skipping");
					return true;
				}
				string causeOfDeath = "";
				if (Deaths > 0)
				{
					causeOfDeath = deathCounts.FirstOrDefault().Key.ToString();
				}
				int gameVersion = 49;
				try
				{
					GameNetworkManager instance = GameNetworkManager.Instance;
					if ((Object)(object)instance != (Object)null)
					{
						gameVersion = instance.gameVersionNum;
					}
				}
				catch (Exception ex)
				{
					Debug.Log((object)ex.Message);
				}
				List<DanosPlayerMods> list = new List<DanosPlayerMods>();
				try
				{
					list = DanosPlayerMods.CollectMods();
				}
				catch (Exception ex2)
				{
					Debug.Log((object)ex2.Message);
					list = new List<DanosPlayerMods>();
				}
				var anon = new
				{
					RoundID = RoundID,
					HostSteamID = HostSteamID,
					DaysOnTheJob = DaysOnTheJob,
					ScrapValueCollected = ScrapValueCollected,
					TeamDeaths = TeamDeaths,
					TeamStepsTaken = TeamStepsTaken,
					Deaths = Deaths,
					StepsTaken = StepsTaken,
					MySteamID = MySteamID,
					MyUsername = MyUsername,
					QuotaStringA = QuotaStringA,
					QuotaStringB = QuotaStringB,
					QuotaStringC = QuotaStringC,
					ScrapOnShip = ScrapOnShip,
					LevelName = LevelName,
					PlayerDied = (Deaths > 0),
					CauseOfDeath = causeOfDeath,
					RoundStart = RoundStart,
					RoundEnd = RoundEnd,
					RoundDuration = RoundDuration,
					CreditsAtEnd = CreditsAtEnd,
					PlayersInLobby = PlayersInLobby,
					PlayersDead = PlayersDead,
					TotalScrapCollectedThisRound = TotalScrapCollectedThisRound,
					TotalScrapOnMap = TotalScrapOnMap,
					Fired = Fired,
					GameVersion = gameVersion,
					Events = new List<DanosPlayerEvent>(),
					Mods = list,
					Items = PlayerItems
				};
				string content = JsonConvert.SerializeObject((object)anon);
				HttpClient httpClient = new HttpClient();
				httpClient.BaseAddress = new Uri("https://lethal.api.splitstats.io");
				StringContent content2 = new StringContent(content, Encoding.UTF8, "application/json");
				httpClient.PostAsync("/api/match/results?", content2);
				LastSentResults = DateTime.Now;
			}
			catch (Exception ex3)
			{
				Debug.Log((object)ex3.Message);
				return false;
			}
			return true;
		}

		public static void ResetValues()
		{
			RoundID = "";
			PlayerEvents = new List<DanosPlayerEvent>();
			PlayerItems = new List<DanosPlayerItem>();
			HasSentResults = false;
			DaysOnTheJob = 0;
			ScrapValueCollected = 0;
			TeamDeaths = 0;
			TeamStepsTaken = 0;
			Deaths = 0;
			StepsTaken = 0;
			MySteamID = 0uL;
			MyUsername = "";
			QuotaStringA = 0L;
			QuotaStringB = 0L;
			QuotaStringC = 0L;
			ScrapOnShip = 0f;
			LevelName = "Unknown";
			RoundStart = 0L;
			RoundEnd = 0L;
			CreditsAtEnd = 0;
			PlayersInLobby = 0;
			PlayersDead = 0;
			TotalScrapCollectedThisRound = 0;
			TotalScrapOnMap = 0f;
			Fired = false;
			ResetDeathCounts();
		}

		internal static string GetSHA256(string roundString)
		{
			using SHA256 sHA = SHA256.Create();
			byte[] array = sHA.ComputeHash(Encoding.UTF8.GetBytes(roundString));
			return BitConverter.ToString(array).Replace("-", "").ToLower();
		}
	}
}