Decompiled source of WKDebugAccess v1.0.3

WKDebugAccess.dll

Decompiled 4 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Steamworks;
using Steamworks.Data;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WKDebugAccess")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+892f606ebe41243b9ce1bd5bc88cc2a227080e65")]
[assembly: AssemblyProduct("WKDebugAccess")]
[assembly: AssemblyTitle("WKDebugAccess")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 WKDebugAccess
{
	[BepInPlugin("boiled.whiteknuckle.debugaccess", "WK Debug Access", "1.0.3")]
	public sealed class WKDebugAccessPlugin : BaseUnityPlugin
	{
		private sealed class WKDebugAccessRunner : MonoBehaviour
		{
			private void Update()
			{
				Heartbeat("runner update");
			}
		}

		private struct ScoreSnapshot
		{
			public int Count;

			public float Bonus;

			public float Multiplier;

			public float Total;
		}

		private const string PluginGuid = "boiled.whiteknuckle.debugaccess";

		private const string Version = "1.0.3";

		private const string Prefix = "wkdebug_";

		private const string DebugScoreId = "wkdebug-score";

		private static ManualLogSource logSource;

		private static Harmony harmony;

		private static GameObject runnerObject;

		private static bool registered;

		private static bool hooksPatched;

		private static float nextRetryLogTime;

		private static float nextStatusWriteTime;

		private static DateTime lastCommandWriteTimeUtc;

		private static readonly List<string> recentMessages = new List<string>();

		private void Awake()
		{
			logSource = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"WK Debug Access loaded. Waiting for CommandConsole.");
			PatchConsoleHooks();
			SceneManager.sceneLoaded += OnSceneLoaded;
			EnsureRunner();
			EnsureCommandFiles();
			TryRegister("plugin awake");
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			ManualLogSource obj = logSource;
			if (obj != null)
			{
				obj.LogInfo((object)"WK Debug Access plugin host destroyed; persistent runner and Harmony patches remain active.");
			}
		}

		private void Update()
		{
			Heartbeat("plugin update");
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			TryRegister("scene loaded: " + ((Scene)(ref scene)).name);
		}

		private static void PatchConsoleHooks()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			if (hooksPatched)
			{
				return;
			}
			try
			{
				harmony = new Harmony("boiled.whiteknuckle.debugaccess");
				MethodInfo methodInfo = AccessTools.Method(typeof(CommandConsole), "Awake", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(typeof(CommandConsole), "ExecuteCommand", new Type[2]
				{
					typeof(string),
					typeof(bool)
				}, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(CommandConsole), "ExecuteCommand", new Type[3]
				{
					typeof(string),
					typeof(bool),
					typeof(bool)
				}, (Type[])null);
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(WKDebugAccessPlugin), "CommandConsoleAwakePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(WKDebugAccessPlugin), "CommandConsoleExecuteCommandTwoArgsPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(WKDebugAccessPlugin), "CommandConsoleExecuteCommandThreeArgsPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				hooksPatched = true;
				ManualLogSource obj = logSource;
				if (obj != null)
				{
					obj.LogInfo((object)("Patched CommandConsole hooks. Awake=" + (methodInfo != null) + ", ExecuteCommand2=" + (methodInfo2 != null) + ", ExecuteCommand3=" + (methodInfo3 != null)));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource obj2 = logSource;
				if (obj2 != null)
				{
					obj2.LogError((object)("Failed to patch CommandConsole hooks: " + ex));
				}
			}
		}

		private static void EnsureRunner()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)runnerObject != (Object)null))
			{
				runnerObject = new GameObject("WKDebugAccessRunner");
				Object.DontDestroyOnLoad((Object)(object)runnerObject);
				((Object)runnerObject).hideFlags = (HideFlags)61;
				runnerObject.AddComponent<WKDebugAccessRunner>();
				ManualLogSource obj = logSource;
				if (obj != null)
				{
					obj.LogInfo((object)"Persistent WKDebugAccessRunner created.");
				}
			}
		}

		private static void Heartbeat(string reason)
		{
			TryRegister(reason);
			ProcessCommandFile();
			CheckHotkeys();
			WriteStatusThrottled();
		}

		private static void TryRegister(string reason)
		{
			if (registered)
			{
				return;
			}
			CommandConsole val = FindConsole();
			if ((Object)(object)val == (Object)null)
			{
				if (Time.unscaledTime >= nextRetryLogTime)
				{
					nextRetryLogTime = Time.unscaledTime + 10f;
					ManualLogSource obj = logSource;
					if (obj != null)
					{
						obj.LogInfo((object)("CommandConsole not available yet; retrying. Source=" + reason + ", found=" + CountConsoleObjects()));
					}
				}
				return;
			}
			try
			{
				if ((Object)(object)CommandConsole.instance == (Object)null)
				{
					CommandConsole.instance = val;
				}
				RegisterCommands(val);
				registered = true;
				ManualLogSource obj2 = logSource;
				if (obj2 != null)
				{
					obj2.LogInfo((object)("WK Debug Access commands registered. Source=" + reason));
				}
			}
			catch (Exception ex)
			{
				ManualLogSource obj3 = logSource;
				if (obj3 != null)
				{
					obj3.LogError((object)("Failed to register WK Debug Access commands from " + reason + ": " + ex));
				}
			}
		}

		private static CommandConsole FindConsole()
		{
			if ((Object)(object)CommandConsole.instance != (Object)null)
			{
				return CommandConsole.instance;
			}
			try
			{
				CommandConsole[] array = Resources.FindObjectsOfTypeAll<CommandConsole>();
				if (array == null || array.Length == 0)
				{
					return null;
				}
				CommandConsole val = ((IEnumerable<CommandConsole>)array).FirstOrDefault((Func<CommandConsole, bool>)((CommandConsole c) => (Object)(object)c != (Object)null && (Object)(object)c.inputField != (Object)null));
				return (CommandConsole)(((Object)(object)val != (Object)null) ? ((object)val) : ((object)((IEnumerable<CommandConsole>)array).FirstOrDefault((Func<CommandConsole, bool>)((CommandConsole c) => (Object)(object)c != (Object)null))));
			}
			catch (Exception ex)
			{
				ManualLogSource obj = logSource;
				if (obj != null)
				{
					obj.LogWarning((object)("FindConsole failed: " + ex.Message));
				}
				return null;
			}
		}

		private static int CountConsoleObjects()
		{
			try
			{
				CommandConsole[] array = Resources.FindObjectsOfTypeAll<CommandConsole>();
				return (array != null) ? array.Length : 0;
			}
			catch
			{
				return -1;
			}
		}

		private static void RegisterCommands(CommandConsole console)
		{
			SafeCommandRaw(console, "wkdebug", RootCommand, "[command] WK Debug Access root command. Try: wkdebug help");
			SafeCommandRaw(console, "wkhascheated", HasCheated, "Print CommandConsole.hasCheated.");
			SafeCommandRaw(console, "wksethascheated", SetHasCheated, "[true|false] Set CommandConsole.hasCheated.");
			SafeCommandRaw(console, "wksessioninfo", SessionInfo, "Print current gamemode/session summary.");
			SafeCommandRaw(console, "wkliststats", ListStats, "[filter] [limit=80] List StatManager.sessionStats entries.");
			SafeCommandRaw(console, "wkgetstat", GetStat, "[id] Print one session stat.");
			SafeCommandRaw(console, "wksetstat", SetStat, "[id] [value] [int|float|string optional] Set or create a session stat.");
			SafeCommandRaw(console, "wkaddstat", AddStat, "[id] [delta] [int|float optional] Add to a session stat.");
			SafeCommandRaw(console, "wkexportstats", ExportStats, "[filter optional] Export session stats to BepInEx/config/WKDebugAccess/session_stats.tsv.");
			SafeCommandRaw(console, "wksavesession", SaveSession, "[resetroom=true|false optional] Force SaveSession to campaign-save.session.");
			SafeCommandRaw(console, "wkgettime", GetTime, "Print current runtime/session/best time.");
			SafeCommandRaw(console, "wksettime", SetTime, "[seconds|mm:ss|hh:mm:ss] Set current run time.");
			SafeCommandRaw(console, "wkgetscore", GetScore, "Print runtime score entries and saved score stats.");
			SafeCommandRaw(console, "wklistscores", ListScores, "[filter] [limit=80] List CL_ScoreManager session score entries.");
			SafeCommandRaw(console, "wksetscore", SetScore, "[value] Set session score stat and wkdebug score entry.");
			SafeCommandRaw(console, "wkaddscore", AddScore, "[id] [bonus] [multiplier=0] [count=0] [title optional] Add/update runtime score entry.");
			SafeCommandRaw(console, "wkgethighscore", GetHighScore, "Print global and gamemode high score.");
			SafeCommandRaw(console, "wksethighscore", SetHighScore, "[value] Set global and gamemode high score.");
			SafeCommandRaw(console, "wkresetleaderboard", ResetLeaderboard, "[score=0] [steam leaderboard name optional] Reset local leaderboard/high score and optionally force-update Steam score.");
			SafeCommandRaw(console, "wkresetlb", ResetLeaderboard, "[score=0] [steam leaderboard name optional] Alias for wkresetleaderboard.");
			SafeCommandRaw(console, "wksetbesttime", SetBestTime, "[seconds|mm:ss|hh:mm:ss] Set global and gamemode best time.");
			SafeCommandRaw(console, "wkmarkwin", MarkWin, "[score optional] [time optional] Save win stats without opening end screen.");
			SafeCommandRaw(console, "wkcompletegame", CompleteGame, "[score optional] [time optional] Set score/time/win stats and save.");
			SafeCommandRaw(console, "wkfinishgame", FinishGame, "[win|lose] Start the game's end sequence.");
			SafeCommandRaw(console, "wkgetflag", GetFlag, "[id] Print a session/save flag.");
			SafeCommandRaw(console, "wksetflag", SetFlag, "[id] [true|false] [data optional] [save=true] Set a game flag.");
			SafeCommandRaw(console, "wklistachievements", ListAchievements, "[filter] [limit=80] List loaded achievements.");
			SafeCommandRaw(console, "wksetachievement", SetAchievement, "[id] [true|false] [save=true] Set an achievement through the game API.");
			SafeCommandRaw(console, "wksavestats", SaveStatsCommand, "[writeall=true] Save StatManager data.");
			SafeCommand(console, "help", Help, "List WK Debug Access commands.");
			SafeCommand(console, "hascheated", HasCheated, "Print CommandConsole.hasCheated.");
			SafeCommand(console, "sethascheated", SetHasCheated, "[true|false] Set CommandConsole.hasCheated without marking this command as a cheat.");
			SafeCommand(console, "sessioninfo", SessionInfo, "Print current gamemode/session summary.");
			SafeCommand(console, "liststats", ListStats, "[filter] [limit=80] List StatManager.sessionStats entries.");
			SafeCommand(console, "getstat", GetStat, "[id] Print one session stat.");
			SafeCommand(console, "setstat", SetStat, "[id] [value] [int|float|string optional] Set or create a session stat.");
			SafeCommand(console, "addstat", AddStat, "[id] [delta] [int|float optional] Add to a session stat.");
			SafeCommand(console, "exportstats", ExportStats, "[filter optional] Export session stats to BepInEx/config/WKDebugAccess/session_stats.tsv.");
			SafeCommand(console, "savesession", SaveSession, "[resetroom=true|false optional] Force SaveSession to campaign-save.session.");
			SafeCommand(console, "gettime", GetTime, "Print current runtime/session/best time.");
			SafeCommand(console, "settime", SetTime, "[seconds|mm:ss|hh:mm:ss] Set current run time.");
			SafeCommand(console, "getscore", GetScore, "Print runtime score entries and saved score stats.");
			SafeCommand(console, "listscores", ListScores, "[filter] [limit=80] List CL_ScoreManager session score entries.");
			SafeCommand(console, "setscore", SetScore, "[value] Set session score stat and wkdebug score entry.");
			SafeCommand(console, "addscore", AddScore, "[id] [bonus] [multiplier=0] [count=0] [title optional] Add/update runtime score entry.");
			SafeCommand(console, "gethighscore", GetHighScore, "Print global and gamemode high score.");
			SafeCommand(console, "sethighscore", SetHighScore, "[value] Set global and gamemode high score.");
			SafeCommand(console, "resetleaderboard", ResetLeaderboard, "[score=0] [steam leaderboard name optional] Reset local leaderboard/high score and optionally force-update Steam score.");
			SafeCommand(console, "resetlb", ResetLeaderboard, "[score=0] [steam leaderboard name optional] Alias for resetleaderboard.");
			SafeCommand(console, "setbesttime", SetBestTime, "[seconds|mm:ss|hh:mm:ss] Set global and gamemode best time.");
			SafeCommand(console, "markwin", MarkWin, "[score optional] [time optional] Save win stats without opening end screen.");
			SafeCommand(console, "completegame", CompleteGame, "[score optional] [time optional] Set score/time/win stats and save.");
			SafeCommand(console, "finishgame", FinishGame, "[win|lose] Start the game's end sequence.");
			SafeCommand(console, "getflag", GetFlag, "[id] Print a session/save flag.");
			SafeCommand(console, "setflag", SetFlag, "[id] [true|false] [data optional] [save=true] Set a game flag.");
			SafeCommand(console, "listachievements", ListAchievements, "[filter] [limit=80] List loaded achievements.");
			SafeCommand(console, "setachievement", SetAchievement, "[id] [true|false] [save=true] Set an achievement through the game API.");
			SafeCommand(console, "savestats", SaveStatsCommand, "[writeall=true] Save StatManager data.");
		}

		private static void SafeCommand(CommandConsole console, string name, Action<string[]> callback, string description)
		{
			SafeCommandRaw(console, "wkdebug_" + name, callback, description);
		}

		private static void SafeCommandRaw(CommandConsole console, string name, Action<string[]> callback, string description)
		{
			object obj = AccessTools.Method(typeof(CommandConsole), "RegisterCommand", new Type[3]
			{
				typeof(string),
				typeof(Action<string[]>),
				typeof(bool)
			}, (Type[])null).Invoke(console, new object[3] { name, callback, false });
			if (obj == null)
			{
				ManualLogSource obj2 = logSource;
				if (obj2 != null)
				{
					obj2.LogWarning((object)("RegisterCommand returned null for " + name));
				}
			}
			else
			{
				Type type = obj.GetType();
				type.GetField("cheat", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(obj, false);
				type.GetField("description", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(obj, description);
			}
		}

		private static void RootCommand(string[] args)
		{
			if (args.Length == 0)
			{
				Help(args);
			}
			else
			{
				RunSubcommand(args[0], args.Skip(1).ToArray());
			}
		}

		private static void Help(string[] args)
		{
			Log("Commands:");
			Log("  wkdebug help");
			Log("  wkdebug hascheated");
			Log("  wkdebug sethascheated false");
			Log("  wkdebug liststats [filter] [limit]");
			Log("  wkdebug getstat bank-roaches");
			Log("  wkdebug setstat bank-roaches 999 int");
			Log("  wkdebug gettime");
			Log("  wkdebug settime 12:34");
			Log("  wkdebug getscore");
			Log("  wkdebug setscore 50000");
			Log("  wkdebug addscore debug-bonus 50000 0 1 Debug Score");
			Log("  wkdebug gethighscore");
			Log("  wkdebug sethighscore 50000");
			Log("  wkdebug resetleaderboard [score=0] [steam leaderboard name optional]");
			Log("  wkdebug setbesttime 12:34");
			Log("  wkdebug markwin [score] [time]");
			Log("  wkdebug completegame [score] [time]");
			Log("  wkdebug finishgame win|lose");
			Log("  wkdebug getflag flag-id");
			Log("  wkdebug setflag flag-id true data true");
			Log("  wkdebug listachievements [filter] [limit]");
			Log("  wkdebug setachievement ACH_ID true");
			Log("  wkdebug savestats [writeall]");
			Log("  wkdebug savesession [resetroom]");
			Log("  wkdebug_hascheated");
			Log("  wkdebug_sethascheated false");
			Log("  wkdebug_sessioninfo");
			Log("  wkdebug_liststats [filter] [limit]");
			Log("  wkdebug_getstat bank-roaches");
			Log("  wkdebug_setstat bank-roaches 999 int");
			Log("  wkdebug_addstat bank-roaches 10 int");
			Log("  wkdebug_exportstats [filter]");
			Log("  wkdebug_savesession [resetroom]");
		}

		private static void CommandConsoleAwakePostfix()
		{
			TryRegister("CommandConsole.Awake postfix");
		}

		private static bool CommandConsoleExecuteCommandTwoArgsPrefix(string input)
		{
			return HandleExecuteCommandPrefix(input, "ExecuteCommand2");
		}

		private static bool CommandConsoleExecuteCommandThreeArgsPrefix(string input)
		{
			return HandleExecuteCommandPrefix(input, "ExecuteCommand3");
		}

		private static bool HandleExecuteCommandPrefix(string input, string source)
		{
			if (!string.IsNullOrWhiteSpace(input) && input.TrimStart().StartsWith("wk", StringComparison.OrdinalIgnoreCase))
			{
				ManualLogSource obj = logSource;
				if (obj != null)
				{
					obj.LogInfo((object)("Intercept candidate from " + source + ": " + input));
				}
			}
			return !TryHandleRawCommand(input);
		}

		private static bool TryHandleRawCommand(string input)
		{
			if (string.IsNullOrWhiteSpace(input))
			{
				return false;
			}
			string text = input.Trim();
			string[] array = SplitCommandLine(text);
			if (array.Length == 0)
			{
				return false;
			}
			string text2 = array[0].ToLowerInvariant();
			string text3 = null;
			string[] array2 = Array.Empty<string>();
			if (text2 == "wkdebug")
			{
				text3 = ((array.Length > 1) ? array[1] : "help");
				array2 = array.Skip(2).ToArray();
			}
			else if (text2.StartsWith("wkdebug_", StringComparison.Ordinal))
			{
				text3 = text2.Substring("wkdebug_".Length);
				array2 = array.Skip(1).ToArray();
			}
			else
			{
				if (!text2.StartsWith("wk", StringComparison.Ordinal))
				{
					return false;
				}
				text3 = text2.Substring("wk".Length);
				array2 = array.Skip(1).ToArray();
			}
			ManualLogSource obj = logSource;
			if (obj != null)
			{
				obj.LogInfo((object)("Handling WK Debug Access raw command: " + text));
			}
			RunSubcommand(text3, array2);
			return true;
		}

		private static void EnsureCommandFiles()
		{
			try
			{
				string configDir = GetConfigDir();
				Directory.CreateDirectory(configDir);
				string path = Path.Combine(configDir, "command.txt");
				if (!File.Exists(path))
				{
					File.WriteAllText(path, "# Write one command, save the file, and the mod will run it.\n# Examples:\n# sethascheated false\n# getscore\n# settime 12:34\n# setscore 50000\n# sethighscore 50000\n# resetleaderboard\n# resetleaderboard 0 \"Steam Leaderboard Name\"\n# markwin 50000 12:34\n# finishgame win\n# exportstats\n", Encoding.UTF8);
				}
				WriteStatus(force: true);
			}
			catch (Exception ex)
			{
				ManualLogSource obj = logSource;
				if (obj != null)
				{
					obj.LogWarning((object)("Could not create command files: " + ex.Message));
				}
			}
		}

		private static void ProcessCommandFile()
		{
			try
			{
				string path = Path.Combine(GetConfigDir(), "command.txt");
				if (!File.Exists(path))
				{
					EnsureCommandFiles();
					return;
				}
				DateTime lastWriteTimeUtc = File.GetLastWriteTimeUtc(path);
				if (!(lastWriteTimeUtc <= lastCommandWriteTimeUtc))
				{
					lastCommandWriteTimeUtc = lastWriteTimeUtc;
					string text = (from l in File.ReadAllLines(path)
						select l.Trim()).FirstOrDefault((string l) => l.Length > 0 && !l.StartsWith("#", StringComparison.Ordinal));
					if (!string.IsNullOrEmpty(text))
					{
						Log("Running command file command: " + text);
						RunFileCommand(text);
						WriteStatus(force: true);
					}
				}
			}
			catch (Exception ex)
			{
				Log("Command file error: " + ex.Message);
			}
		}

		private static void RunFileCommand(string command)
		{
			if (!TryHandleRawCommand(command))
			{
				string[] array = SplitCommandLine(command.Trim());
				if (array.Length != 0)
				{
					RunSubcommand(array[0], array.Skip(1).ToArray());
				}
			}
		}

		private static void CheckHotkeys()
		{
			try
			{
				if (Input.GetKeyDown((KeyCode)287))
				{
					SetHasCheated(new string[1] { "false" });
					WriteStatus(force: true);
				}
				if (Input.GetKeyDown((KeyCode)288))
				{
					ExportStats(Array.Empty<string>());
					WriteStatus(force: true);
				}
				if (Input.GetKeyDown((KeyCode)289))
				{
					SaveSession(Array.Empty<string>());
					WriteStatus(force: true);
				}
			}
			catch
			{
			}
		}

		private static void WriteStatusThrottled()
		{
			if (!(Time.unscaledTime < nextStatusWriteTime))
			{
				nextStatusWriteTime = Time.unscaledTime + 2f;
				WriteStatus(force: false);
			}
		}

		private static void WriteStatus(bool force)
		{
			try
			{
				string configDir = GetConfigDir();
				Directory.CreateDirectory(configDir);
				string path = Path.Combine(configDir, "live_status.txt");
				GameStats sessionStats = GetSessionStats();
				ScoreSnapshot scoreSnapshot = GetScoreSnapshot();
				float? currentGameTime = GetCurrentGameTime();
				float? statFloat = GetStatFloat(sessionStats, "score");
				float? statFloat2 = GetStatFloat(sessionStats, "game-time");
				float? statFloat3 = GetStatFloat(GetGlobalStats(), "score");
				float? statFloat4 = GetStatFloat(GetGamemodeStats(), "score");
				float? statFloat5 = GetStatFloat(GetGlobalStats(), "best-time");
				float? statFloat6 = GetStatFloat(GetGamemodeStats(), "best-time");
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("WKDebugAccess 1.0.3");
				stringBuilder.AppendLine("updated=" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));
				stringBuilder.AppendLine("commandsRegistered=" + registered);
				stringBuilder.AppendLine("commandConsoleObjects=" + CountConsoleObjects());
				stringBuilder.AppendLine("hasCheated=" + CommandConsole.hasCheated);
				stringBuilder.AppendLine("gamemode=" + SafeGamemodeName());
				stringBuilder.AppendLine("runHasEnded=" + CL_GameManager.runHasEnded);
				stringBuilder.AppendLine("runtimeGameTime=" + FormatNullableSeconds(currentGameTime));
				stringBuilder.AppendLine("sessionGameTime=" + FormatNullableSeconds(statFloat2));
				stringBuilder.AppendLine("sessionScoreStat=" + FormatNullableFloat(statFloat));
				stringBuilder.AppendLine("sessionScoreEntries=" + scoreSnapshot.Count);
				stringBuilder.AppendLine("sessionScoreBonus=" + FormatFloat(scoreSnapshot.Bonus));
				stringBuilder.AppendLine("sessionScoreMultiplier=" + FormatFloat(scoreSnapshot.Multiplier));
				stringBuilder.AppendLine("sessionScoreTotal=" + FormatFloat(scoreSnapshot.Total));
				stringBuilder.AppendLine("globalHighScore=" + FormatNullableFloat(statFloat3));
				stringBuilder.AppendLine("gamemodeHighScore=" + FormatNullableFloat(statFloat4));
				stringBuilder.AppendLine("globalBestTime=" + FormatNullableSeconds(statFloat5));
				stringBuilder.AppendLine("gamemodeBestTime=" + FormatNullableSeconds(statFloat6));
				stringBuilder.AppendLine("sessionStatsCount=" + (sessionStats?.statistics?.Count).GetValueOrDefault());
				stringBuilder.AppendLine("configDir=" + configDir);
				stringBuilder.AppendLine("hotkeys=F6 sethascheated false, F7 exportstats, F8 savesession");
				stringBuilder.AppendLine("commandFile=" + Path.Combine(configDir, "command.txt"));
				stringBuilder.AppendLine("lastMessages=");
				foreach (string item in recentMessages.Take(20))
				{
					stringBuilder.AppendLine(item);
				}
				File.WriteAllText(path, stringBuilder.ToString(), Encoding.UTF8);
			}
			catch (Exception ex)
			{
				if (force)
				{
					ManualLogSource obj = logSource;
					if (obj != null)
					{
						obj.LogWarning((object)("Could not write live_status.txt: " + ex.Message));
					}
				}
			}
		}

		private static void RunSubcommand(string subcommand, string[] args)
		{
			switch ((subcommand ?? "help").ToLowerInvariant())
			{
			case "help":
				Help(args);
				break;
			case "hascheated":
				HasCheated(args);
				break;
			case "sethascheated":
				SetHasCheated(args);
				break;
			case "sessioninfo":
				SessionInfo(args);
				break;
			case "liststats":
				ListStats(args);
				break;
			case "getstat":
				GetStat(args);
				break;
			case "setstat":
				SetStat(args);
				break;
			case "addstat":
				AddStat(args);
				break;
			case "exportstats":
				ExportStats(args);
				break;
			case "savesession":
				SaveSession(args);
				break;
			case "time":
			case "gettime":
				GetTime(args);
				break;
			case "settime":
				SetTime(args);
				break;
			case "getscore":
			case "score":
				GetScore(args);
				break;
			case "listscores":
				ListScores(args);
				break;
			case "setscore":
				SetScore(args);
				break;
			case "addscore":
				AddScore(args);
				break;
			case "highscore":
				if (args.Length == 0)
				{
					GetHighScore(args);
				}
				else
				{
					SetHighScore(args);
				}
				break;
			case "gethighscore":
				GetHighScore(args);
				break;
			case "sethighscore":
				SetHighScore(args);
				break;
			case "resetlb":
			case "resetleaderboard":
				ResetLeaderboard(args);
				break;
			case "besttime":
				if (args.Length == 0)
				{
					GetTime(args);
				}
				else
				{
					SetBestTime(args);
				}
				break;
			case "setbesttime":
				SetBestTime(args);
				break;
			case "markwin":
				MarkWin(args);
				break;
			case "completegame":
				CompleteGame(args);
				break;
			case "finishgame":
			case "finish":
				FinishGame(args);
				break;
			case "getflag":
				GetFlag(args);
				break;
			case "setflag":
				SetFlag(args);
				break;
			case "achievements":
			case "listachievements":
				ListAchievements(args);
				break;
			case "setachievement":
				SetAchievement(args);
				break;
			case "savestats":
			case "saveprogress":
				SaveStatsCommand(args);
				break;
			default:
				Log("Unknown WK Debug Access subcommand: " + subcommand);
				Help(args);
				break;
			}
		}

		private static void HasCheated(string[] args)
		{
			Log("CommandConsole.hasCheated = " + CommandConsole.hasCheated);
		}

		private static void SetHasCheated(string[] args)
		{
			if (args.Length < 1 || !bool.TryParse(args[0], out var result))
			{
				Log("Usage: wkdebug_sethascheated true|false");
				return;
			}
			CommandConsole.hasCheated = result;
			TrySetCheatTracker(result);
			Log("CommandConsole.hasCheated = " + CommandConsole.hasCheated);
		}

		private static void SessionInfo(string[] args)
		{
			string text = (((Object)(object)CL_GameManager.gamemode != (Object)null) ? CL_GameManager.GetGamemodeName(true, false) : "null");
			int valueOrDefault = (GetSessionStats()?.statistics?.Count).GetValueOrDefault();
			Log("Gamemode: " + text);
			Log("hasCheated: " + CommandConsole.hasCheated);
			Log("isSavedRun: " + CL_SaveManager.IsInSavedRun());
			Log("sessionStats count: " + valueOrDefault);
			Log("roaches: " + CL_GameManager.GetRoaches(false));
			Log("game-time: " + FormatNullableSeconds(GetCurrentGameTime()));
			Log("score: " + FormatNullableFloat(GetStatFloat(GetSessionStats(), "score")) + ", runtimeTotal=" + FormatFloat(GetScoreSnapshot().Total));
			Log("high score: global=" + FormatNullableFloat(GetStatFloat(GetGlobalStats(), "score")) + ", gamemode=" + FormatNullableFloat(GetStatFloat(GetGamemodeStats(), "score")));
		}

		private static void ListStats(string[] args)
		{
			GameStats sessionStats = GetSessionStats();
			if (sessionStats == null)
			{
				Log("StatManager.sessionStats is null.");
				return;
			}
			string filter = ((args.Length != 0) ? args[0] : "");
			int result = 80;
			if (args.Length > 1)
			{
				int.TryParse(args[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out result);
				if (result <= 0)
				{
					result = 80;
				}
			}
			List<Statistic> list = sessionStats.statistics.Where((Statistic s) => s != null && (string.IsNullOrEmpty(filter) || s.id.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0)).Take(result).ToList();
			Log("sessionStats matches: " + list.Count + " / total " + sessionStats.statistics.Count);
			foreach (Statistic item in list)
			{
				Log(FormatStat(item));
			}
		}

		private static void GetStat(string[] args)
		{
			if (args.Length < 1)
			{
				Log("Usage: wkdebug_getstat <id>");
				return;
			}
			Statistic val = FindSessionStat(args[0]);
			if (val == null)
			{
				Log("Session stat not found: " + args[0]);
			}
			else
			{
				Log(FormatStat(val));
			}
		}

		private unsafe static void SetStat(string[] args)
		{
			//IL_0050: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			if (args.Length < 2)
			{
				Log("Usage: wkdebug_setstat <id> <value> [int|float|string]");
				return;
			}
			GameStats sessionStats = GetSessionStats();
			if (sessionStats == null)
			{
				Log("StatManager.sessionStats is null.");
				return;
			}
			string text = args[0];
			string text2 = args[1];
			Statistic val = FindSessionStat(text);
			DataType val2 = ((args.Length > 2) ? ParseType(args[2]) : (val?.type ?? InferType(text2)));
			if (!TryParseValue(text2, val2, out var parsed))
			{
				Log("Could not parse '" + text2 + "' as " + ((object)(*(DataType*)(&val2))/*cast due to .constrained prefix*/).ToString() + ".");
			}
			else
			{
				sessionStats.SetStatistic(text, parsed, val2);
				Log("Set " + FormatStat(FindSessionStat(text)));
			}
		}

		private unsafe static void AddStat(string[] args)
		{
			//IL_0050: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Invalid comparison between Unknown and I4
			//IL_0046: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (args.Length < 2)
			{
				Log("Usage: wkdebug_addstat <id> <delta> [int|float]");
				return;
			}
			GameStats sessionStats = GetSessionStats();
			if (sessionStats == null)
			{
				Log("StatManager.sessionStats is null.");
				return;
			}
			string text = args[0];
			string text2 = args[1];
			Statistic val = FindSessionStat(text);
			DataType val2 = ((args.Length > 2) ? ParseType(args[2]) : (val?.type ?? InferType(text2)));
			object parsed;
			if ((int)val2 == 1)
			{
				Log("wkdebug_addstat only supports int/float.");
			}
			else if (!TryParseValue(text2, val2, out parsed))
			{
				Log("Could not parse '" + text2 + "' as " + ((object)(*(DataType*)(&val2))/*cast due to .constrained prefix*/).ToString() + ".");
			}
			else
			{
				sessionStats.UpdateStatistic(text, parsed, val2, (ModType)1, (DisplayType)0, (ModType)1);
				Log("Added. " + FormatStat(FindSessionStat(text)));
			}
		}

		private static void ExportStats(string[] args)
		{
			//IL_00ba: 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)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			GameStats sessionStats = GetSessionStats();
			if (sessionStats == null)
			{
				Log("StatManager.sessionStats is null.");
				return;
			}
			string value = ((args.Length != 0) ? args[0] : "");
			string text = Path.Combine(Paths.ConfigPath, "WKDebugAccess");
			Directory.CreateDirectory(text);
			string text2 = Path.Combine(text, "session_stats.tsv");
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("id\tvalue\ttype\tdefaultModType\tdisplayType");
			foreach (Statistic statistic in sessionStats.statistics)
			{
				if (statistic != null && (string.IsNullOrEmpty(value) || statistic.id.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0))
				{
					stringBuilder.Append(statistic.id).Append('\t').Append(statistic.value)
						.Append('\t')
						.Append(statistic.type)
						.Append('\t')
						.Append(statistic.defaultModType)
						.Append('\t')
						.Append(statistic.displayType)
						.AppendLine();
				}
			}
			File.WriteAllText(text2, stringBuilder.ToString(), Encoding.UTF8);
			Log("Exported session stats to: " + text2);
		}

		private static void SaveSession(string[] args)
		{
			if ((Object)(object)CL_SaveManager.instance == (Object)null)
			{
				Log("CL_SaveManager.instance is null; cannot save session here.");
				return;
			}
			bool result = false;
			if (args.Length != 0)
			{
				bool.TryParse(args[0], out result);
			}
			CL_SaveManager.instance.SaveSession(false, true, false, "", result);
			Log("SaveSession wrote current run. resetRoom=" + result + ", hasCheated=" + CommandConsole.hasCheated);
		}

		private static void GetTime(string[] args)
		{
			float? currentGameTime = GetCurrentGameTime();
			float? statFloat = GetStatFloat(GetSessionStats(), "game-time");
			float? statFloat2 = GetStatFloat(GetGlobalStats(), "best-time");
			float? statFloat3 = GetStatFloat(GetGamemodeStats(), "best-time");
			Log("runtime game-time = " + FormatNullableSeconds(currentGameTime));
			Log("session stat game-time = " + FormatNullableSeconds(statFloat));
			Log("global best-time = " + FormatNullableSeconds(statFloat2));
			Log("gamemode best-time = " + FormatNullableSeconds(statFloat3));
		}

		private static void SetTime(string[] args)
		{
			if (args.Length < 1 || !TryParseTime(args[0], out var seconds))
			{
				Log("Usage: wkdebug_settime <seconds|mm:ss|hh:mm:ss>");
			}
			else if (SetCurrentGameTime(seconds))
			{
				Log("Current run game-time set to " + FormatSeconds(seconds) + ".");
			}
		}

		private static void GetScore(string[] args)
		{
			ScoreSnapshot scoreSnapshot = GetScoreSnapshot();
			Log("runtime score entries = " + scoreSnapshot.Count);
			Log("runtime score bonus = " + FormatFloat(scoreSnapshot.Bonus));
			Log("runtime score multiplier = " + FormatFloat(scoreSnapshot.Multiplier));
			Log("runtime score total = " + FormatFloat(scoreSnapshot.Total));
			Log("session stat score = " + FormatNullableFloat(GetStatFloat(GetSessionStats(), "score")));
			GetHighScore(args);
		}

		private static void ListScores(string[] args)
		{
			SessionScore sessionScore = CL_ScoreManager.sessionScore;
			if (sessionScore == null || sessionScore.scores == null)
			{
				Log("CL_ScoreManager.sessionScore is null or empty.");
				return;
			}
			string filter = ((args.Length != 0) ? args[0] : "");
			int count = ParseOptionalInt(args, 1, 80);
			List<Score> list = sessionScore.scores.Where((Score s) => s != null && (string.IsNullOrEmpty(filter) || s.id.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0 || (s.title ?? "").IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0)).Take(count).ToList();
			Log("score entries matches: " + list.Count + " / total " + sessionScore.scores.Count);
			foreach (Score item in list)
			{
				Log(FormatScoreEntry(item));
			}
		}

		private static void SetScore(string[] args)
		{
			if (args.Length < 1 || !TryParseFloat(args[0], out var value))
			{
				Log("Usage: wkdebug_setscore <value>");
			}
			else if (SetRuntimeScoreTarget(value))
			{
				SetSessionScoreStat(value);
				ScoreSnapshot scoreSnapshot = GetScoreSnapshot();
				Log("Session score set. stat=" + FormatFloat(value) + ", runtimeTotal=" + FormatFloat(scoreSnapshot.Total) + ", entry=wkdebug-score");
			}
		}

		private static void AddScore(string[] args)
		{
			if (args.Length < 2 || !TryParseFloat(args[1], out var value))
			{
				Log("Usage: wkdebug_addscore <id> <bonus> [multiplier=0] [count=0] [title optional]");
				return;
			}
			string text = args[0];
			float value2 = 0f;
			int result = 0;
			if (args.Length > 2 && !TryParseFloat(args[2], out value2))
			{
				Log("Could not parse multiplier: " + args[2]);
				return;
			}
			if (args.Length > 3 && !int.TryParse(args[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out result))
			{
				Log("Could not parse count: " + args[3]);
				return;
			}
			string text2 = ((args.Length > 4) ? string.Join(" ", args.Skip(4).ToArray()) : text);
			SessionScore val = EnsureSessionScore();
			val.AddScore(text, text2, value, value2, result);
			ScoreSnapshot scoreSnapshot = GetScoreSnapshot();
			SetSessionScoreStat(scoreSnapshot.Total);
			Log("Added score entry. " + FormatScoreEntry(val.scoreDict[text]));
			Log("Runtime score now bonus=" + FormatFloat(scoreSnapshot.Bonus) + ", multiplier=" + FormatFloat(scoreSnapshot.Multiplier) + ", total=" + FormatFloat(scoreSnapshot.Total));
		}

		private static void GetHighScore(string[] args)
		{
			Log("global high score = " + FormatNullableFloat(GetStatFloat(GetGlobalStats(), "score")));
			Log("gamemode high score = " + FormatNullableFloat(GetStatFloat(GetGamemodeStats(), "score")) + " (" + SafeGamemodeName() + ")");
		}

		private static void SetHighScore(string[] args)
		{
			if (args.Length < 1 || !TryParseFloat(args[0], out var value))
			{
				Log("Usage: wkdebug_sethighscore <value>");
			}
			else if (SetHighScoreValue(value, persist: true))
			{
				Log("High score set to " + FormatFloat(value) + " globally and for gamemode " + SafeGamemodeName() + ".");
			}
		}

		private static void ResetLeaderboard(string[] args)
		{
			float num = 0f;
			string text = null;
			if (args.Length != 0)
			{
				if (TryParseFloat(args[0], out var value))
				{
					num = value;
					if (args.Length > 1)
					{
						text = string.Join(" ", args.Skip(1).ToArray());
					}
				}
				else
				{
					text = string.Join(" ", args);
				}
			}
			if (ResetLocalLeaderboardScore(num))
			{
				if (string.IsNullOrWhiteSpace(text))
				{
					Log("Local leaderboard/high score reset to " + FormatFloat(num) + ". To also force a Steam leaderboard score, use: resetleaderboard " + FormatFloat(num) + " \"Steam Leaderboard Name\"");
				}
				else
				{
					ResetSteamLeaderboardScoreAsync(text.Trim(), Mathf.RoundToInt(num));
				}
			}
		}

		private static void SetBestTime(string[] args)
		{
			if (args.Length < 1 || !TryParseTime(args[0], out var seconds))
			{
				Log("Usage: wkdebug_setbesttime <seconds|mm:ss|hh:mm:ss>");
			}
			else if (SetBestTimeValue(seconds, persist: true))
			{
				Log("Best time set to " + FormatSeconds(seconds) + " globally and for gamemode " + SafeGamemodeName() + ".");
			}
		}

		private static void MarkWin(string[] args)
		{
			float? scoreOverride = null;
			float? timeOverride = null;
			if (args.Length != 0)
			{
				if (!TryParseFloat(args[0], out var value))
				{
					Log("Could not parse score: " + args[0]);
					return;
				}
				scoreOverride = value;
			}
			if (args.Length > 1)
			{
				if (!TryParseTime(args[1], out var seconds))
				{
					Log("Could not parse time: " + args[1]);
					return;
				}
				timeOverride = seconds;
			}
			if (ApplyFinishStats(win: true, scoreOverride, timeOverride, save: true))
			{
				Log("Win stats saved without opening the end screen.");
			}
		}

		private static void CompleteGame(string[] args)
		{
			float? scoreOverride = null;
			float? timeOverride = null;
			if (args.Length != 0)
			{
				if (!TryParseFloat(args[0], out var value))
				{
					Log("Could not parse score: " + args[0]);
					return;
				}
				scoreOverride = value;
			}
			if (args.Length > 1)
			{
				if (!TryParseTime(args[1], out var seconds))
				{
					Log("Could not parse time: " + args[1]);
					return;
				}
				timeOverride = seconds;
			}
			if (scoreOverride.HasValue)
			{
				SetRuntimeScoreTarget(scoreOverride.Value);
				SetHighScoreValue(scoreOverride.Value, persist: false);
			}
			if (timeOverride.HasValue)
			{
				SetCurrentGameTime(timeOverride.Value);
				SetBestTimeValue(timeOverride.Value, persist: false);
			}
			if (ApplyFinishStats(win: true, scoreOverride, timeOverride, save: true))
			{
				TryUpdateUnlocks();
				Log("Complete-game stats saved. Use 'finishgame win' if you also want the in-game end sequence.");
			}
		}

		private static void FinishGame(string[] args)
		{
			bool flag = true;
			if (args.Length != 0)
			{
				switch (args[0].ToLowerInvariant())
				{
				case "win":
				case "won":
				case "true":
				case "1":
					flag = true;
					break;
				case "lose":
				case "loss":
				case "dead":
				case "false":
				case "0":
					flag = false;
					break;
				default:
					Log("Usage: wkdebug_finishgame win|lose");
					return;
				}
			}
			if ((Object)(object)CL_GameManager.gMan == (Object)null)
			{
				Log("CL_GameManager.gMan is null; cannot finish the game from here.");
				return;
			}
			CommandConsole.hasCheated = false;
			TrySetCheatTracker(active: false);
			try
			{
				if (flag)
				{
					CL_GameManager.gMan.Win();
				}
				else
				{
					MethodInfo methodInfo = AccessTools.Method(typeof(CL_GameManager), "EndGameSequence", new Type[1] { typeof(bool) }, (Type[])null);
					if (methodInfo == null)
					{
						Log("Could not find CL_GameManager.EndGameSequence(bool).");
						return;
					}
					object obj = methodInfo.Invoke(CL_GameManager.gMan, new object[1] { false });
					((MonoBehaviour)CL_GameManager.gMan).StartCoroutine((IEnumerator)obj);
				}
				Log("Started end-game sequence. win=" + flag + ", hasCheated=" + CommandConsole.hasCheated);
			}
			catch (Exception ex)
			{
				Log("finishgame failed: " + ex.Message);
			}
		}

		private static void GetFlag(string[] args)
		{
			if (args.Length < 1)
			{
				Log("Usage: wkdebug_getflag <id>");
				return;
			}
			string text = args[0];
			bool flag = false;
			if ((Object)(object)CL_GameManager.gMan != (Object)null)
			{
				SessionFlag gameFlag = CL_GameManager.GetGameFlag(text);
				if (gameFlag != null)
				{
					Log("session flag " + text + " = " + gameFlag.state + ", data=" + gameFlag.data);
					flag = true;
				}
			}
			SaveFlags val = FindSaveFlag(text);
			if (val != null)
			{
				Log("save flag " + text + " = " + val.value + ", data=" + val.data);
				flag = true;
			}
			if (!flag)
			{
				Log("Flag not found: " + text);
			}
		}

		private static void SetFlag(string[] args)
		{
			if (args.Length < 2 || !TryParseBool(args[1], out var value))
			{
				Log("Usage: wkdebug_setflag <id> <true|false> [data optional] [save=true]");
				return;
			}
			if ((Object)(object)CL_GameManager.gMan == (Object)null)
			{
				Log("CL_GameManager.gMan is null; cannot set runtime game flag.");
				return;
			}
			string text = args[0];
			string text2 = "";
			bool value2 = true;
			if (args.Length == 3)
			{
				if (TryParseBool(args[2], out var value3))
				{
					value2 = value3;
				}
				else
				{
					text2 = args[2];
				}
			}
			else if (args.Length > 3)
			{
				text2 = args[2];
				if (!TryParseBool(args[3], out value2))
				{
					Log("Could not parse save flag: " + args[3]);
					return;
				}
			}
			CL_GameManager.SetGameFlag(text, value, text2, value2, false);
			if (value2)
			{
				SaveStatsToDisk(writeAll: false);
			}
			Log("Set flag " + text + " = " + value + ", data=" + text2 + ", save=" + value2);
		}

		private static void ListAchievements(string[] args)
		{
			IEnumerable achievementsEnumerable = GetAchievementsEnumerable();
			if (achievementsEnumerable == null)
			{
				Log("CL_AchievementManager achievements are not available.");
				return;
			}
			string value = ((args.Length != 0) ? args[0] : "");
			int num = ParseOptionalInt(args, 1, 80);
			int num2 = 0;
			int num3 = 0;
			foreach (object item in achievementsEnumerable)
			{
				num2++;
				string fieldString = GetFieldString(item, "id");
				string fieldString2 = GetFieldString(item, "name");
				if ((string.IsNullOrEmpty(value) || fieldString.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0 || fieldString2.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) && num3 < num)
				{
					num3++;
					Log(fieldString + " = " + GetFieldBool(item, "flagged") + " :: " + fieldString2);
				}
			}
			Log("achievement matches shown: " + num3 + " / total " + num2);
		}

		private static void SetAchievement(string[] args)
		{
			if (args.Length < 2 || !TryParseBool(args[1], out var value))
			{
				Log("Usage: wkdebug_setachievement <id> <true|false> [save=true]");
				return;
			}
			bool value2 = true;
			if (args.Length > 2 && !TryParseBool(args[2], out value2))
			{
				Log("Could not parse save flag: " + args[2]);
				return;
			}
			CL_AchievementManager.SetAchievementValue(args[0], value);
			if (value2)
			{
				CL_AchievementManager.SaveAchievements();
				SaveStatsToDisk(writeAll: false);
			}
			Log("Set achievement " + args[0] + " = " + value + ", save=" + value2);
		}

		private static void SaveStatsCommand(string[] args)
		{
			bool value = true;
			if (args.Length != 0 && !TryParseBool(args[0], out value))
			{
				Log("Usage: wkdebug_savestats [writeall=true|false]");
			}
			else
			{
				SaveStatsToDisk(value);
			}
		}

		private static bool ApplyFinishStats(bool win, float? scoreOverride, float? timeOverride, bool save)
		{
			GameStats sessionStats = GetSessionStats();
			if (sessionStats == null)
			{
				Log("StatManager.sessionStats is null; cannot write finish stats.");
				return false;
			}
			CommandConsole.hasCheated = false;
			TrySetCheatTracker(active: false);
			float num = timeOverride ?? GetCurrentGameTime() ?? GetStatFloat(sessionStats, "game-time").GetValueOrDefault();
			float num2 = scoreOverride ?? GetGamemodePlayerScore(win) ?? GetScoreSnapshot().Total;
			if (timeOverride.HasValue)
			{
				SetCurrentGameTime(num);
			}
			if (scoreOverride.HasValue)
			{
				SetRuntimeScoreTarget(num2);
			}
			SetSessionScoreStat(num2);
			sessionStats.UpdateStatistic("game-time", (object)num, (DataType)2, (ModType)0, (DisplayType)4, (ModType)1);
			if (win)
			{
				sessionStats.UpdateStatistic("wins", (object)1, (DataType)0, (ModType)0, (DisplayType)0, (ModType)1);
				sessionStats.UpdateStatistic("best-time", (object)num, (DataType)2, (ModType)3, (DisplayType)4, (ModType)3);
			}
			if (save)
			{
				SaveStatsToDisk(writeAll: true);
			}
			SetPreviousHighScore(Math.Max(GetStatFloat(GetGamemodeStats(), "score") ?? num2, num2));
			Log("Finish stats prepared. win=" + win + ", score=" + FormatFloat(num2) + ", game-time=" + FormatSeconds(num) + ", hasCheated=" + CommandConsole.hasCheated);
			return true;
		}

		private static bool ResetLocalLeaderboardScore(float value)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			CommandConsole.hasCheated = false;
			TrySetCheatTracker(active: false);
			try
			{
				CL_ScoreManager.sessionScore = new SessionScore();
				CL_ScoreManager.sessionScore.Initialize();
				SetScoreEntry("wkdebug-score", "WK Debug Leaderboard Reset", value, 0f, 0);
				SetSessionScoreStat(value);
				if (!SetHighScoreValue(value, persist: false))
				{
					return false;
				}
				SetPreviousHighScore(value);
				SaveStatsToDisk(writeAll: false);
				TryUpdateStatUi();
				Log("Reset local leaderboard/high score. score=" + FormatFloat(value) + ", gamemode=" + SafeGamemodeName() + ", hasCheated=" + CommandConsole.hasCheated);
				return true;
			}
			catch (Exception ex)
			{
				Log("Local leaderboard reset failed: " + ex.Message);
				return false;
			}
		}

		private static async Task ResetSteamLeaderboardScoreAsync(string leaderboardName, int score)
		{
			_ = 1;
			try
			{
				if (!SteamClient.IsValid || !SteamClient.IsLoggedOn)
				{
					Log("Steam client is not connected; local leaderboard reset is done, but Steam leaderboard was not updated.");
					return;
				}
				Log("Finding Steam leaderboard '" + leaderboardName + "'...");
				Leaderboard? val = await SteamUserStats.FindLeaderboardAsync(leaderboardName);
				if (!val.HasValue)
				{
					Log("Steam leaderboard not found: " + leaderboardName);
					return;
				}
				Leaderboard value = val.Value;
				LeaderboardUpdate? val2 = await ((Leaderboard)(ref value)).ReplaceScore(score, (int[])null);
				if (!val2.HasValue)
				{
					Log("Steam leaderboard ReplaceScore failed for: " + leaderboardName);
					return;
				}
				bool flag = SteamUserStats.StoreStats();
				Log("Steam leaderboard score forced. name=" + leaderboardName + ", score=" + val2.Value.Score + ", changed=" + val2.Value.Changed + ", oldRank=" + val2.Value.OldGlobalRank + ", newRank=" + val2.Value.NewGlobalRank + ", StoreStats=" + flag);
			}
			catch (Exception ex)
			{
				Log("Steam leaderboard reset failed: " + ex.Message);
			}
		}

		private static bool SetHighScoreValue(float value, bool persist)
		{
			bool flag = false;
			GameStats globalStats = GetGlobalStats();
			if (globalStats != null)
			{
				globalStats.UpdateStatistic("score", (object)value, (DataType)2, (ModType)0, (DisplayType)0, (ModType)2);
				flag = true;
			}
			GameStats gamemodeStats = GetGamemodeStats();
			if (gamemodeStats != null)
			{
				gamemodeStats.UpdateStatistic("score", (object)value, (DataType)2, (ModType)0, (DisplayType)0, (ModType)2);
				flag = true;
			}
			if (!flag)
			{
				Log("StatManager.saveData is not available; cannot set high score.");
				return false;
			}
			SetPreviousHighScore(value);
			if (persist)
			{
				SaveStatsToDisk(writeAll: false);
			}
			return true;
		}

		private static bool SetBestTimeValue(float seconds, bool persist)
		{
			bool flag = false;
			GameStats globalStats = GetGlobalStats();
			if (globalStats != null)
			{
				globalStats.UpdateStatistic("best-time", (object)seconds, (DataType)2, (ModType)0, (DisplayType)4, (ModType)3);
				flag = true;
			}
			GameStats gamemodeStats = GetGamemodeStats();
			if (gamemodeStats != null)
			{
				gamemodeStats.UpdateStatistic("best-time", (object)seconds, (DataType)2, (ModType)0, (DisplayType)4, (ModType)3);
				flag = true;
			}
			if (!flag)
			{
				Log("StatManager.saveData is not available; cannot set best time.");
				return false;
			}
			if (persist)
			{
				SaveStatsToDisk(writeAll: false);
			}
			return true;
		}

		private static bool SaveStatsToDisk(bool writeAll)
		{
			if ((Object)(object)StatManager.instance == (Object)null)
			{
				Log("StatManager.instance is null; cannot save stats to disk yet.");
				return false;
			}
			CommandConsole.hasCheated = false;
			TrySetCheatTracker(active: false);
			try
			{
				StatManager.instance.SaveStats(writeAll);
				Log("StatManager.SaveStats(" + writeAll + ") complete. hasCheated=" + CommandConsole.hasCheated);
				return true;
			}
			catch (Exception ex)
			{
				Log("SaveStats failed: " + ex.Message);
				return false;
			}
		}

		private static bool SetCurrentGameTime(float seconds)
		{
			if (seconds < 0f)
			{
				seconds = 0f;
			}
			if ((Object)(object)CL_GameManager.gMan == (Object)null)
			{
				Log("CL_GameManager.gMan is null; cannot set runtime game-time.");
				return false;
			}
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(CL_GameManager), "SetGameTime", new Type[1] { typeof(float) }, (Type[])null);
				if (methodInfo != null)
				{
					methodInfo.Invoke(CL_GameManager.gMan, new object[1] { seconds });
				}
				else
				{
					FieldInfo fieldInfo = AccessTools.Field(typeof(CL_GameManager), "gameTime");
					if (fieldInfo == null)
					{
						Log("Could not find CL_GameManager.SetGameTime or gameTime field.");
						return false;
					}
					fieldInfo.SetValue(CL_GameManager.gMan, seconds);
				}
				GameStats sessionStats = GetSessionStats();
				if (sessionStats != null)
				{
					sessionStats.UpdateStatistic("game-time", (object)seconds, (DataType)2, (ModType)0, (DisplayType)4, (ModType)1);
				}
				return true;
			}
			catch (Exception ex)
			{
				Log("Set game-time failed: " + ex.Message);
				return false;
			}
		}

		private static float? GetCurrentGameTime()
		{
			try
			{
				if ((Object)(object)CL_GameManager.gMan != (Object)null)
				{
					return CL_GameManager.gMan.GetGameTime();
				}
			}
			catch
			{
			}
			return GetStatFloat(GetSessionStats(), "game-time");
		}

		private static float? GetGamemodePlayerScore(bool win)
		{
			try
			{
				object gamemode = CL_GameManager.gamemode;
				if (gamemode == null)
				{
					return null;
				}
				MethodInfo methodInfo = AccessTools.Method(gamemode.GetType(), "GetPlayerScore", new Type[1] { typeof(bool) }, (Type[])null);
				if (methodInfo == null)
				{
					return null;
				}
				object obj = methodInfo.Invoke(gamemode, new object[1] { win });
				if (obj == null)
				{
					return null;
				}
				return Convert.ToSingle(obj, CultureInfo.InvariantCulture);
			}
			catch
			{
				return null;
			}
		}

		private static bool SetRuntimeScoreTarget(float target)
		{
			SessionScore val = EnsureSessionScore();
			float num = 0f;
			float num2 = 0f;
			if (val.scores != null)
			{
				foreach (Score score in val.scores)
				{
					if (score != null && !string.Equals(score.id, "wkdebug-score", StringComparison.OrdinalIgnoreCase))
					{
						num += score.bonus;
						num2 += score.multiplier;
					}
				}
			}
			SetScoreEntry("wkdebug-score", "WK Debug Score", target - num, 0f - num2, 1);
			return true;
		}

		private static void SetSessionScoreStat(float value)
		{
			GameStats sessionStats = GetSessionStats();
			if (sessionStats != null)
			{
				sessionStats.UpdateStatistic("score", (object)value, (DataType)2, (ModType)0, (DisplayType)0, (ModType)2);
			}
		}

		private static SessionScore EnsureSessionScore()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			if (CL_ScoreManager.sessionScore == null)
			{
				CL_ScoreManager.sessionScore = new SessionScore();
			}
			if (CL_ScoreManager.sessionScore.scores == null || CL_ScoreManager.sessionScore.scoreDict == null)
			{
				CL_ScoreManager.sessionScore.Initialize();
			}
			return CL_ScoreManager.sessionScore;
		}

		private static void SetScoreEntry(string id, string title, float bonus, float multiplier, int count)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			SessionScore val = EnsureSessionScore();
			if (val.scoreDict == null)
			{
				val.Initialize();
			}
			if (!val.scoreDict.TryGetValue(id, out var value))
			{
				value = new Score
				{
					id = id
				};
				val.scores.Add(value);
				val.scoreDict[id] = value;
			}
			value.title = title;
			value.bonus = bonus;
			value.multiplier = multiplier;
			value.count = count;
		}

		private static ScoreSnapshot GetScoreSnapshot()
		{
			ScoreSnapshot result = new ScoreSnapshot
			{
				Multiplier = 1f
			};
			SessionScore sessionScore = CL_ScoreManager.sessionScore;
			if (sessionScore == null || sessionScore.scores == null)
			{
				result.Total = 0f;
				return result;
			}
			foreach (Score score in sessionScore.scores)
			{
				if (score != null)
				{
					result.Count++;
					result.Bonus += score.bonus;
					result.Multiplier += score.multiplier;
				}
			}
			result.Multiplier = Mathf.Max(result.Multiplier, 0f);
			result.Total = result.Bonus * result.Multiplier;
			return result;
		}

		private static string FormatScoreEntry(Score entry)
		{
			if (entry == null)
			{
				return "<null score entry>";
			}
			return entry.id + " = bonus " + FormatFloat(entry.bonus) + ", multiplier " + FormatFloat(entry.multiplier) + ", count " + entry.count + ", title=" + entry.title;
		}

		private static void SetPreviousHighScore(float value)
		{
			try
			{
				if ((Object)(object)CL_GameManager.gMan != (Object)null)
				{
					AccessTools.Field(typeof(CL_GameManager), "previousHighScore")?.SetValue(CL_GameManager.gMan, value);
				}
			}
			catch
			{
			}
		}

		private static void TryUpdateUnlocks()
		{
			try
			{
				Type type = AccessTools.TypeByName("CL_ProgressionManager");
				((type != null) ? AccessTools.Method(type, "UpdateUnlocks", new Type[1] { typeof(bool) }, (Type[])null) : null)?.Invoke(null, new object[1] { true });
			}
			catch
			{
			}
		}

		private static void TryUpdateStatUi()
		{
			try
			{
				StatManager instance = StatManager.instance;
				if (instance != null)
				{
					instance.UpdateUI();
				}
			}
			catch
			{
			}
		}

		private static GameStats GetGlobalStats()
		{
			try
			{
				if (StatManager.saveData == null || StatManager.saveData.gameStats == null)
				{
					return null;
				}
				EnsureStatsDictionary(StatManager.saveData.gameStats);
				return StatManager.saveData.gameStats;
			}
			catch
			{
				return null;
			}
		}

		private static GameStats GetGamemodeStats()
		{
			try
			{
				if (StatManager.saveData == null)
				{
					return null;
				}
				string text = SafeGamemodeName();
				if (string.IsNullOrEmpty(text) || text == "null")
				{
					return null;
				}
				GameModeData gameMode = StatManager.saveData.GetGameMode(text);
				if (gameMode == null || gameMode.stats == null)
				{
					return null;
				}
				EnsureStatsDictionary(gameMode.stats);
				return gameMode.stats;
			}
			catch
			{
				return null;
			}
		}

		private static void EnsureStatsDictionary(GameStats stats)
		{
			if (stats != null && (stats.statsDictionary == null || stats.statsDictionary.Count == 0))
			{
				stats.InitializeDictionary();
			}
		}

		private static float? GetStatFloat(GameStats stats, string id)
		{
			try
			{
				if (stats == null || string.IsNullOrEmpty(id))
				{
					return null;
				}
				EnsureStatsDictionary(stats);
				if (!stats.HasStatistic(id))
				{
					return null;
				}
				object value = stats.GetStatistic(id).GetValue();
				if (value is float value2)
				{
					return value2;
				}
				if (value is int num)
				{
					return num;
				}
				if (value is string raw && TryParseFloat(raw, out var value3))
				{
					return value3;
				}
			}
			catch
			{
				return null;
			}
			return null;
		}

		private static SaveFlags FindSaveFlag(string id)
		{
			if (StatManager.saveData?.flags == null)
			{
				return null;
			}
			return ((IEnumerable<SaveFlags>)StatManager.saveData.flags).FirstOrDefault((Func<SaveFlags, bool>)((SaveFlags f) => f != null && string.Equals(f.name, id, StringComparison.OrdinalIgnoreCase)));
		}

		private static IEnumerable GetAchievementsEnumerable()
		{
			if ((Object)(object)CL_AchievementManager.instance == (Object)null)
			{
				return null;
			}
			return AccessTools.Field(typeof(CL_AchievementManager), "achievements")?.GetValue(CL_AchievementManager.instance) as IEnumerable;
		}

		private static string GetFieldString(object obj, string fieldName)
		{
			return (obj?.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj))?.ToString() ?? "";
		}

		private static bool GetFieldBool(object obj, string fieldName)
		{
			object obj2 = obj?.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj);
			bool flag = default(bool);
			int num;
			if (obj2 is bool)
			{
				flag = (bool)obj2;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private static string SafeGamemodeName()
		{
			try
			{
				return ((Object)(object)CL_GameManager.gamemode != (Object)null) ? CL_GameManager.GetGamemodeName(true, false) : "null";
			}
			catch
			{
				return "unknown";
			}
		}

		private static int ParseOptionalInt(string[] args, int index, int defaultValue)
		{
			if (args.Length <= index || !int.TryParse(args[index], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result <= 0)
			{
				return defaultValue;
			}
			return result;
		}

		private static bool TryParseFloat(string raw, out float value)
		{
			value = 0f;
			if (!string.IsNullOrWhiteSpace(raw))
			{
				return float.TryParse(raw.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out value);
			}
			return false;
		}

		private static bool TryParseBool(string raw, out bool value)
		{
			value = false;
			if (bool.TryParse(raw, out value))
			{
				return true;
			}
			if (string.Equals(raw, "1", StringComparison.OrdinalIgnoreCase) || string.Equals(raw, "yes", StringComparison.OrdinalIgnoreCase) || string.Equals(raw, "on", StringComparison.OrdinalIgnoreCase))
			{
				value = true;
				return true;
			}
			if (string.Equals(raw, "0", StringComparison.OrdinalIgnoreCase) || string.Equals(raw, "no", StringComparison.OrdinalIgnoreCase) || string.Equals(raw, "off", StringComparison.OrdinalIgnoreCase))
			{
				value = false;
				return true;
			}
			return false;
		}

		private static bool TryParseTime(string raw, out float seconds)
		{
			seconds = 0f;
			if (string.IsNullOrWhiteSpace(raw))
			{
				return false;
			}
			raw = raw.Trim();
			if (!raw.Contains(":"))
			{
				return TryParseFloat(raw, out seconds);
			}
			string[] array = raw.Split(':');
			float num = 1f;
			for (int num2 = array.Length - 1; num2 >= 0; num2--)
			{
				if (!TryParseFloat(array[num2], out var value))
				{
					seconds = 0f;
					return false;
				}
				seconds += value * num;
				num *= 60f;
			}
			return true;
		}

		private static string FormatNullableFloat(float? value)
		{
			if (!value.HasValue)
			{
				return "null";
			}
			return FormatFloat(value.Value);
		}

		private static string FormatFloat(float value)
		{
			return value.ToString("0.###", CultureInfo.InvariantCulture);
		}

		private static string FormatNullableSeconds(float? seconds)
		{
			if (!seconds.HasValue)
			{
				return "null";
			}
			return FormatSeconds(seconds.Value);
		}

		private static string FormatSeconds(float seconds)
		{
			if (seconds < 0f)
			{
				seconds = 0f;
			}
			TimeSpan timeSpan = TimeSpan.FromSeconds(seconds);
			string text = ((timeSpan.TotalHours >= 1.0) ? timeSpan.ToString("hh\\:mm\\:ss\\.ff", CultureInfo.InvariantCulture) : timeSpan.ToString("mm\\:ss\\.ff", CultureInfo.InvariantCulture));
			return FormatFloat(seconds) + "s (" + text + ")";
		}

		private static string[] SplitCommandLine(string command)
		{
			List<string> list = new List<string>();
			StringBuilder stringBuilder = new StringBuilder();
			bool flag = false;
			foreach (char c in command)
			{
				if (c == '"')
				{
					flag = !flag;
				}
				else if (!flag && char.IsWhiteSpace(c))
				{
					if (stringBuilder.Length > 0)
					{
						list.Add(stringBuilder.ToString());
						stringBuilder.Length = 0;
					}
				}
				else
				{
					stringBuilder.Append(c);
				}
			}
			if (stringBuilder.Length > 0)
			{
				list.Add(stringBuilder.ToString());
			}
			return list.ToArray();
		}

		private static GameStats GetSessionStats()
		{
			if (StatManager.sessionStats == null)
			{
				return null;
			}
			if (StatManager.sessionStats.statsDictionary == null || StatManager.sessionStats.statsDictionary.Count == 0)
			{
				StatManager.sessionStats.InitializeDictionary();
			}
			return StatManager.sessionStats;
		}

		private static Statistic FindSessionStat(string id)
		{
			GameStats sessionStats = GetSessionStats();
			if (sessionStats == null || string.IsNullOrEmpty(id))
			{
				return null;
			}
			if (sessionStats.statsDictionary != null && sessionStats.statsDictionary.TryGetValue(id, out var value))
			{
				return value;
			}
			return ((IEnumerable<Statistic>)sessionStats.statistics).FirstOrDefault((Func<Statistic, bool>)((Statistic s) => s != null && string.Equals(s.id, id, StringComparison.OrdinalIgnoreCase)));
		}

		private static string FormatStat(Statistic stat)
		{
			if (stat == null)
			{
				return "<null>";
			}
			return stat.id + " = " + stat.value + " (" + ((object)Unsafe.As<DataType, DataType>(ref stat.type)/*cast due to .constrained prefix*/).ToString() + ", defaultMod=" + ((object)Unsafe.As<ModType, ModType>(ref stat.defaultModType)/*cast due to .constrained prefix*/).ToString() + ", display=" + ((object)Unsafe.As<DisplayType, DisplayType>(ref stat.displayType)/*cast due to .constrained prefix*/).ToString() + ")";
		}

		private static DataType ParseType(string type)
		{
			if (!string.Equals(type, "int", StringComparison.OrdinalIgnoreCase) && !string.Equals(type, "0", StringComparison.OrdinalIgnoreCase))
			{
				if (!string.Equals(type, "string", StringComparison.OrdinalIgnoreCase) && !string.Equals(type, "str", StringComparison.OrdinalIgnoreCase) && !string.Equals(type, "1", StringComparison.OrdinalIgnoreCase))
				{
					if (!string.Equals(type, "float", StringComparison.OrdinalIgnoreCase) && !string.Equals(type, "single", StringComparison.OrdinalIgnoreCase))
					{
						string.Equals(type, "2", StringComparison.OrdinalIgnoreCase);
					}
					return (DataType)2;
				}
				return (DataType)1;
			}
			return (DataType)0;
		}

		private static DataType InferType(string value)
		{
			if (!int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var _))
			{
				if (!float.TryParse(value.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out var _))
				{
					return (DataType)1;
				}
				return (DataType)2;
			}
			return (DataType)0;
		}

		private static bool TryParseValue(string rawValue, DataType type, out object parsed)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected I4, but got Unknown
			switch ((int)type)
			{
			case 0:
			{
				if (int.TryParse(rawValue, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2))
				{
					parsed = result2;
					return true;
				}
				parsed = null;
				return false;
			}
			case 2:
			{
				if (float.TryParse(rawValue.Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					parsed = result;
					return true;
				}
				parsed = null;
				return false;
			}
			case 1:
				parsed = rawValue;
				return true;
			default:
				parsed = null;
				return false;
			}
		}

		private static void TrySetCheatTracker(bool active)
		{
			try
			{
				if ((Object)(object)CL_UIManager.instance != (Object)null && (Object)(object)CL_UIManager.instance.cheatTracker != (Object)null)
				{
					CL_UIManager.instance.cheatTracker.SetActive(active);
				}
			}
			catch
			{
			}
		}

		private static void Log(string message)
		{
			string text = "[WKDebugAccess] " + message;
			recentMessages.Insert(0, DateTime.Now.ToString("HH:mm:ss", CultureInfo.InvariantCulture) + " " + message);
			while (recentMessages.Count > 40)
			{
				recentMessages.RemoveAt(recentMessages.Count - 1);
			}
			try
			{
				CommandConsole.Log(text);
			}
			catch
			{
			}
			Debug.Log((object)text);
			ManualLogSource obj2 = logSource;
			if (obj2 != null)
			{
				obj2.LogInfo((object)message);
			}
			try
			{
				string configDir = GetConfigDir();
				Directory.CreateDirectory(configDir);
				File.AppendAllText(Path.Combine(configDir, "WKDebugAccess.log"), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture) + " " + message + Environment.NewLine, Encoding.UTF8);
			}
			catch
			{
			}
		}

		private static string GetConfigDir()
		{
			return Path.Combine(Paths.ConfigPath, "WKDebugAccess");
		}
	}
}