Decompiled source of TiltiSlip v1.0.0

BepInEx/plugins/MoSadie-TiltiSlip/com.mosadie.tiltislip.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using MoCore;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Subpixel;
using Subpixel.Events;
using UnityEngine;
using UnityEngine.Events;

[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("com.mosadie.tiltislip")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Trigger in-game actions based on Tiltify Donations")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+db2c0b58f4bf348275d34a6cb2a1b7d240147e0c")]
[assembly: AssemblyProduct("TiltiSlip")]
[assembly: AssemblyTitle("com.mosadie.tiltislip")]
[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 TiltiSlip
{
	public class Actions
	{
		private static readonly StationType[] types;

		internal static void recieveOrder(string msg, string user = null, bool overrideActionsEnabled = false)
		{
			if (!(TiltiSlip.ActionsEnabled || overrideActionsEnabled))
			{
				TiltiSlip.Log.LogInfo((object)"Actions are disabled, ignoring recieveOrder");
				return;
			}
			try
			{
				ThreadingHelper.Instance.StartSyncInvoke((Action)delegate
				{
					//IL_0046: Unknown result type (might be due to invalid IL or missing references)
					//IL_0050: Expected O, but got Unknown
					if (user != null)
					{
						msg = "\"" + msg + "\" -" + user;
					}
					OrderVo val = OrderHelpers.CreateLocal((OrderIssuer)2, (OrderType)0, msg);
					Svc.Get<Events>().Dispatch<OrderGivenEvent>(new OrderGivenEvent(val, (CustomizableArgs?)null));
				});
			}
			catch (Exception ex)
			{
				TiltiSlip.Log.LogError((object)ex);
			}
			TiltiSlip.DebugLogInfo("recieveOrder by " + user + ": " + msg);
		}

		internal static void sendOrder(string msg, string user = null)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (!TiltiSlip.ActionsEnabled)
			{
				TiltiSlip.Log.LogInfo((object)"Actions are disabled, ignoring sendOrder");
				return;
			}
			try
			{
				if (!GetIsCaptainOrFirstMate())
				{
					TiltiSlip.DebugLogError("Not captain or first mate, cannot send order");
					return;
				}
				if (user != null)
				{
					msg = "\"" + msg + "\" -" + user;
				}
				RequestCatalog.CaptainIssueOrderAll((OrderType)7, msg);
			}
			catch (Exception ex)
			{
				TiltiSlip.Log.LogError((object)ex);
			}
		}

		private static bool GetIsCaptainOrFirstMate()
		{
			try
			{
				if (Svc.Get<MpSvc>() == null)
				{
					TiltiSlip.Log.LogError((object)"An error occurred handling self crew. null MpSvc.");
					return false;
				}
				MpClientController clients = Svc.Get<MpSvc>().Clients;
				if (clients == null || clients.LocalClient == null)
				{
					TiltiSlip.Log.LogError((object)"An error occurred handling self crew. null clients or local client.");
					return false;
				}
				return ((SlipClient)clients.LocalClient).Roles.Has(Roles.Captain) || ((SlipClient)clients.LocalClient).Roles.Has(Roles.FirstMate);
			}
			catch (Exception ex)
			{
				TiltiSlip.Log.LogError((object)("An error occurred while checking if the crewmate is the captain or first mate: " + ex.Message));
				return false;
			}
		}

		internal static void focusRandomCrew(string source)
		{
			if (!TiltiSlip.ActionsEnabled)
			{
				TiltiSlip.Log.LogInfo((object)"Actions are disabled, ignoring focusRandomCrew");
				return;
			}
			try
			{
				MpSvc val = Svc.Get<MpSvc>();
				if (val == null)
				{
					TiltiSlip.DebugLogError("mpSvc is null! focusRandomCrew");
					return;
				}
				List<Crewmate> crewmatesOnBoard = val.Crew.CrewmatesOnBoard;
				if (crewmatesOnBoard == null || crewmatesOnBoard.Count == 0)
				{
					TiltiSlip.DebugLogError("crew is empty! focusRandomCrew");
					return;
				}
				TiltiSlip.DebugLogInfo($"There are {crewmatesOnBoard.Count} crewmates");
				int num = new Random().Next(crewmatesOnBoard.Count);
				TiltiSlip.DebugLogInfo($"Random index is {num}");
				TiltiSlip.DebugLogInfo("Getting current crewmate");
				Crewmate val2 = crewmatesOnBoard[num];
				if ((Object)(object)val2 == (Object)null)
				{
					TiltiSlip.DebugLogError("target is null! focusRandomCrew");
					return;
				}
				TiltiSlip.DebugLogInfo("Target is " + val2.Client.Player.DisplayName);
				recieveOrder("Let's take a look at what " + val2.Client.Player.DisplayName + " is up to...", source);
				Mainstay<CameraOperator>.Main.Movement.CamFollowCrewmate(val2);
			}
			catch (Exception ex)
			{
				TiltiSlip.Log.LogError((object)ex);
			}
		}

		internal static void focusSelf(string source)
		{
			if (!TiltiSlip.ActionsEnabled)
			{
				TiltiSlip.Log.LogInfo((object)"Actions are disabled, ignoring focusSelf");
				return;
			}
			try
			{
				MpSvc val = Svc.Get<MpSvc>();
				if (val == null)
				{
					TiltiSlip.DebugLogError("mpSvc is null! focusSelf");
					return;
				}
				List<Crewmate> crew = ((SlipClient)val.Clients.LocalClient).Crew;
				if (crew == null || crew.Count == 0)
				{
					TiltiSlip.DebugLogError("crewList is empty! focusSelf");
					return;
				}
				Crewmate val2 = crew[0];
				recieveOrder("You should take a look at yourself!", source);
				Mainstay<CameraOperator>.Main.Movement.CamFollowCrewmate(val2);
			}
			catch (Exception ex)
			{
				TiltiSlip.Log.LogError((object)ex);
			}
		}

		internal static void dropGems(string source)
		{
			if (!TiltiSlip.ActionsEnabled)
			{
				TiltiSlip.Log.LogInfo((object)"Actions are disabled, ignoring dropGems");
				return;
			}
			try
			{
				GameObject val = GameObject.Find("GemInventoryHud");
				if ((Object)(object)val == (Object)null)
				{
					TiltiSlip.DebugLogError("Gem HUD is null!");
					return;
				}
				GemInventoryHud component = val.GetComponent<GemInventoryHud>();
				if ((Object)(object)component == (Object)null)
				{
					TiltiSlip.DebugLogError("GemInventoryHud is null!");
					return;
				}
				((BaseInventoryHud)component).DropItems();
				recieveOrder("Drop it like it's hot!", source);
			}
			catch (Exception ex)
			{
				TiltiSlip.Log.LogError((object)ex);
			}
		}

		internal static void renameShip(string name, string source)
		{
			if (!TiltiSlip.ActionsEnabled)
			{
				TiltiSlip.Log.LogInfo((object)"Actions are disabled, ignoring renameShip");
				return;
			}
			try
			{
				if (!EditableText.IsTextUsable(name))
				{
					TiltiSlip.DebugLogError("Ship name " + name + " is not usable!");
					recieveOrder("I would have renamed the ship, but the name was invalid!", source);
					return;
				}
				LocalPlayerPrefs.SetShipName(name);
				recieveOrder("Can the ship be named " + name + " instead?", source);
				GameObject val = GameObject.Find("Canvas/PixelPerfectCanvas/DialogManager/DialogArea/CaptainConsole(Clone)/Captain Console Root/Captain Console Row/Column A/Bottom Row/ShipStatusPanel");
				if ((Object)(object)val == (Object)null)
				{
					val = GameObject.Find("Canvas/PixelPerfectCanvas/DialogManager/StagingArea/CaptainConsole(Clone)/Captain Console Root/Captain Console Row/Column A/Bottom Row/ShipStatusPanel");
					if ((Object)(object)val == (Object)null)
					{
						TiltiSlip.DebugLogError("ShipStatusPanel is null!");
						return;
					}
				}
				ShipStatsPanel component = val.GetComponent<ShipStatsPanel>();
				if ((Object)(object)component == (Object)null)
				{
					TiltiSlip.DebugLogError("ShipStatsPanel is null!");
				}
				else
				{
					component.ShipNameText.SetUpInitialText(name);
				}
			}
			catch (Exception ex)
			{
				TiltiSlip.Log.LogError((object)ex);
			}
		}

		internal static void goToRandomStation(string source)
		{
			if (!TiltiSlip.ActionsEnabled)
			{
				TiltiSlip.Log.LogInfo((object)"Actions are disabled, ignoring goToRandomStation");
				return;
			}
			try
			{
				ThreadingHelper.Instance.StartSyncInvoke((Action)delegate
				{
					//IL_0027: Unknown result type (might be due to invalid IL or missing references)
					//IL_002d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0044: Unknown result type (might be due to invalid IL or missing references)
					//IL_0083: Unknown result type (might be due to invalid IL or missing references)
					if (Svc.Get<MpSvc>() == null)
					{
						TiltiSlip.DebugLogError("mpSvc is null! goToRandomStation");
					}
					else
					{
						int num = Random.RandomRangeInt(0, types.Length);
						StationType val = types[num];
						List<Station> stationsOfType = Mainstay<StationManager>.Main.GetStationsOfType(val);
						if (stationsOfType == null || stationsOfType.Count == 0)
						{
							TiltiSlip.DebugLogError($"stations is empty for type {val}! goToRandomStation");
						}
						else
						{
							int index = Random.RandomRangeInt(0, stationsOfType.Count);
							Station val2 = stationsOfType[index];
							recieveOrder("Look over there!", source);
							Svc.Get<Events>().Dispatch<StationClick>(new StationClick(val2));
						}
					}
				});
			}
			catch (Exception ex)
			{
				TiltiSlip.Log.LogError((object)ex);
			}
		}

		static Actions()
		{
			StationType[] array = new StationType[7];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			types = (StationType[])(object)array;
		}
	}
	[BepInPlugin("com.mosadie.tiltislip", "TiltiSlip", "1.0.0")]
	[BepInProcess("Slipstream_Win.exe")]
	public class TiltiSlip : BaseUnityPlugin, IMoPlugin, IMoHttpHandler
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__15_1;

			public static UnityAction <>9__15_2;

			public static Action <>9__15_0;

			internal void <OnShipLoaded>b__15_0()
			{
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Expected O, but got Unknown
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Expected O, but got Unknown
				string text = "Thank you for using TiltiSlip! Please ensure you are using this plugin responsibly, as some actions may affect other players. Would you like TiltiSlip enabled for this ship?" + (enableNumPadKeys.Value ? " You can use the NumPad0 button to enable/disable actions at anytime." : "");
				object obj = <>9__15_1;
				if (obj == null)
				{
					UnityAction val = delegate
					{
						EnableActions();
					};
					<>9__15_1 = val;
					obj = (object)val;
				}
				object obj2 = <>9__15_2;
				if (obj2 == null)
				{
					UnityAction val2 = delegate
					{
						DisableActions();
					};
					<>9__15_2 = val2;
					obj2 = (object)val2;
				}
				DialogManager.QuickTwoChoice(text, "TiltiSlip", (UnityAction)obj, (UnityAction)obj2, true, (ButtonColor)1, "ENABLE", "DISABLE", "Also if you haven't yet, check out the wiki for setup instructions!", "Open Wiki", "https://mosadie.link/tswiki", (Alignment)1);
			}

			internal void <OnShipLoaded>b__15_1()
			{
				EnableActions();
			}

			internal void <OnShipLoaded>b__15_2()
			{
				DisableActions();
			}
		}

		private static ConfigEntry<bool> debugLogs;

		private static ConfigEntry<string> webhookKey;

		private static ConfigEntry<bool> enableNumPadKeys;

		internal static ManualLogSource Log;

		public static readonly string COMPATIBLE_GAME_VERSION = "4.1595";

		public static readonly string GAME_VERSION_URL = "https://raw.githubusercontent.com/MoSadie/tiltislip/refs/heads/main/versions.json";

		public static bool ActionsEnabled = false;

		public static void EnableActions()
		{
			ActionsEnabled = true;
			DebugLogInfo("TiltiSlip actions have been enabled.");
			Actions.recieveOrder("TiltiSlip actions have been enabled.", "TiltiSlip", overrideActionsEnabled: true);
		}

		public static void DisableActions()
		{
			ActionsEnabled = false;
			DebugLogInfo("TiltiSlip actions have been disabled.");
			Actions.recieveOrder("TiltiSlip actions have been disabled.", "TiltiSlip", overrideActionsEnabled: true);
		}

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			if (!MoCore.RegisterPlugin((IMoPlugin)(object)this))
			{
				Log.LogError((object)"Failed to register plugin with MoCore. Please check the logs for more information.");
				return;
			}
			webhookKey = ((BaseUnityPlugin)this).Config.Bind<string>("Webhook", "Webhook Key", "default", (ConfigDescription)null);
			debugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Debug Logs", false, (ConfigDescription)null);
			enableNumPadKeys = ((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "Enable Numpad Keys", true, "Enables numpad keys for manually triggering actions. Useful for demoing actions to viewers. Also NumPad 0 can bse used to temporally disable/enable actions if there's too much happening.");
			Svc.Get<Events>().AddListener<ShipLoadedEvent>((Action<ShipLoadedEvent>)OnShipLoaded);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin com.mosadie.tiltislip is loaded!");
		}

		internal static void DebugLogInfo(string message)
		{
			if (debugLogs.Value)
			{
				Log.LogInfo((object)message);
			}
		}

		internal static void DebugLogWarn(string message)
		{
			if (debugLogs.Value)
			{
				Log.LogWarning((object)message);
			}
		}

		internal static void DebugLogError(string message)
		{
			if (debugLogs.Value)
			{
				Log.LogError((object)message);
			}
		}

		internal static void DebugLogDebug(string message)
		{
			if (debugLogs.Value)
			{
				Log.LogDebug((object)message);
			}
		}

		public void Update()
		{
			if (!enableNumPadKeys.Value)
			{
				return;
			}
			if (Input.GetKeyDown((KeyCode)257) && CanUseKeybind())
			{
				Actions.recieveOrder("Example Donation Message", "TiltiSlip");
			}
			if (Input.GetKeyDown((KeyCode)258) && CanUseKeybind())
			{
				Actions.sendOrder("Example Custom Order", "TiltiSlip");
			}
			if (Input.GetKeyDown((KeyCode)259) && CanUseKeybind())
			{
				Actions.focusRandomCrew("TiltiSlip");
			}
			if (Input.GetKeyDown((KeyCode)260) && CanUseKeybind())
			{
				Actions.focusSelf("TiltiSlip");
			}
			if (Input.GetKeyDown((KeyCode)261) && CanUseKeybind())
			{
				Actions.goToRandomStation("TiltiSlip");
			}
			if (Input.GetKeyDown((KeyCode)262) && CanUseKeybind())
			{
				Actions.renameShip("TiltiSlip Ship", "TiltiSlip");
			}
			if (Input.GetKeyDown((KeyCode)263) && CanUseKeybind())
			{
				Actions.dropGems("TiltiSlip");
			}
			if (Input.GetKeyDown((KeyCode)256) && CanUseKeybind())
			{
				if (ActionsEnabled)
				{
					DisableActions();
				}
				else
				{
					EnableActions();
				}
			}
		}

		private void OnShipLoaded(ShipLoadedEvent e)
		{
			DebugLogInfo("Ship loaded. Showing dialog");
			ThreadingHelper.Instance.StartSyncInvoke((Action)delegate
			{
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Expected O, but got Unknown
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Expected O, but got Unknown
				string text = "Thank you for using TiltiSlip! Please ensure you are using this plugin responsibly, as some actions may affect other players. Would you like TiltiSlip enabled for this ship?" + (enableNumPadKeys.Value ? " You can use the NumPad0 button to enable/disable actions at anytime." : "");
				object obj = <>c.<>9__15_1;
				if (obj == null)
				{
					UnityAction val = delegate
					{
						EnableActions();
					};
					<>c.<>9__15_1 = val;
					obj = (object)val;
				}
				object obj2 = <>c.<>9__15_2;
				if (obj2 == null)
				{
					UnityAction val2 = delegate
					{
						DisableActions();
					};
					<>c.<>9__15_2 = val2;
					obj2 = (object)val2;
				}
				DialogManager.QuickTwoChoice(text, "TiltiSlip", (UnityAction)obj, (UnityAction)obj2, true, (ButtonColor)1, "ENABLE", "DISABLE", "Also if you haven't yet, check out the wiki for setup instructions!", "Open Wiki", "https://mosadie.link/tswiki", (Alignment)1);
			});
		}

		private bool CanUseKeybind()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Invalid comparison between Unknown and I4
			if ((Object)(object)Mainstay<LocalCrewSelectionManager>.Main == (Object)null)
			{
				DebugLogWarn("Attempted to check keybind, but no local crew selection manager is found! (likely not on a ship!)");
				return false;
			}
			LocalCrewmate selectedLocalCrewmate = Mainstay<LocalCrewSelectionManager>.Main.GetSelectedLocalCrewmate();
			if ((Object)(object)selectedLocalCrewmate == (Object)null || (Object)(object)selectedLocalCrewmate.Crewmate == (Object)null)
			{
				DebugLogWarn("Attempted to check keybind, but no local crewmate is found!");
				return false;
			}
			if ((Object)(object)selectedLocalCrewmate.Crewmate.CurrentStation != (Object)null && (int)selectedLocalCrewmate.Crewmate.CurrentStation.StationType == 3)
			{
				DebugLogWarn("Attempted to check keybind, but local crewmate is on the helm!");
				return false;
			}
			return true;
		}

		public HttpListenerResponse HandleRequest(HttpListenerRequest request, HttpListenerResponse response)
		{
			DebugLogInfo("Handling request");
			try
			{
				HttpStatusCode statusCode;
				string s;
				if (request.RawUrl.Split('?', 2)[0].Contains("debug"))
				{
					string body = new StreamReader(request.InputStream).ReadToEnd();
					HandleDebugMessage(body);
					statusCode = HttpStatusCode.OK;
					s = "Debug message handled";
					response.StatusCode = (int)statusCode;
					response.Headers.Add("Access-Control-Allow-Origin", "*");
					byte[] bytes = Encoding.UTF8.GetBytes(s);
					response.ContentLength64 = bytes.Length;
					response.OutputStream.Write(bytes, 0, bytes.Length);
					return response;
				}
				bool flag = request.Headers.AllKeys.Contains<string>("X-Tiltify-Signature");
				bool flag2 = request.Headers.AllKeys.Contains<string>("X-Tiltify-Timestamp");
				if (!flag || !flag2)
				{
					statusCode = HttpStatusCode.OK;
					s = "Missing required headers";
					DebugLogWarn($"Missing required headers: Sign: {flag} Timestamp: {flag2}");
				}
				else
				{
					string signature = request.Headers.Get("X-Tiltify-Signature");
					string timestamp = request.Headers.Get("X-Tiltify-Timestamp");
					string body2 = new StreamReader(request.InputStream).ReadToEnd();
					if (IsValidMessage(body2, webhookKey.Value, timestamp, signature))
					{
						statusCode = HttpStatusCode.OK;
						s = "Valid message";
						HandleTiltifyMessage(body2);
					}
					else
					{
						statusCode = HttpStatusCode.OK;
						s = "Invalid message";
					}
				}
				response.StatusCode = (int)statusCode;
				response.Headers.Add("Access-Control-Allow-Origin", "*");
				byte[] bytes2 = Encoding.UTF8.GetBytes(s);
				response.ContentLength64 = bytes2.Length;
				response.OutputStream.Write(bytes2, 0, bytes2.Length);
				return response;
			}
			catch (Exception ex)
			{
				Log.LogError((object)"An error occurred while handling the request.");
				Log.LogError((object)ex.Message);
				Log.LogError((object)ex.StackTrace);
				response.StatusCode = 500;
				return response;
			}
		}

		private void HandleTiltifyMessage(string body)
		{
			JObject val = JsonConvert.DeserializeObject<JObject>(body);
			if (Extensions.Value<string>((IEnumerable<JToken>)val["meta"][(object)"event_type"]) == "public:direct:donation_updated")
			{
				string text = Extensions.Value<string>((IEnumerable<JToken>)val["data"][(object)"donor_name"]);
				string text2 = Extensions.Value<string>((IEnumerable<JToken>)val["data"][(object)"amount"][(object)"value"]);
				string text3 = Extensions.Value<string>((IEnumerable<JToken>)val["data"][(object)"amount"][(object)"currency"]);
				string text4 = Extensions.Value<string>((IEnumerable<JToken>)val["data"][(object)"donor_comment"]);
				DebugLogInfo(text + " donated " + text2 + " " + text3 + " with the comment \"" + text4 + "\"");
				char c = text2[text2.Length - 1];
				Actions.recieveOrder(text + " just donated " + text2 + " " + text3, "Tiltify");
				switch (c)
				{
				case '1':
					Actions.recieveOrder(text4, text);
					break;
				case '2':
					Actions.sendOrder(text4, text);
					break;
				case '3':
					Actions.focusRandomCrew(text);
					break;
				case '4':
					Actions.focusSelf(text);
					break;
				case '5':
					Actions.goToRandomStation(text);
					break;
				case '6':
					Actions.renameShip(text4, text);
					break;
				case '7':
					Actions.dropGems(text);
					break;
				}
			}
		}

		private void HandleDebugMessage(string body)
		{
			JObject val = JsonConvert.DeserializeObject<JObject>(body);
			string text = Extensions.Value<string>((IEnumerable<JToken>)val["action"]);
			string text2 = (val.ContainsKey("source") ? Extensions.Value<string>((IEnumerable<JToken>)val["source"]) : "Debug");
			switch (text)
			{
			case "receiveOrder":
				Actions.recieveOrder(Extensions.Value<string>((IEnumerable<JToken>)val["message"]), text2);
				break;
			case "sendOrder":
				Actions.sendOrder(Extensions.Value<string>((IEnumerable<JToken>)val["order"]), text2);
				break;
			case "focusRandomCrew":
				Actions.focusRandomCrew(text2);
				break;
			case "focusSelf":
				Actions.focusSelf(text2);
				break;
			case "goToRandomStation":
				Actions.goToRandomStation(text2);
				break;
			case "renameShip":
				Actions.renameShip(Extensions.Value<string>((IEnumerable<JToken>)val["name"]), text2);
				break;
			case "dropGems":
				Actions.dropGems(text2);
				break;
			default:
				DebugLogWarn("Unknown action: " + text);
				break;
			}
		}

		public string GetCompatibleGameVersion()
		{
			return COMPATIBLE_GAME_VERSION;
		}

		public string GetVersionCheckUrl()
		{
			return GAME_VERSION_URL;
		}

		public BaseUnityPlugin GetPluginObject()
		{
			return (BaseUnityPlugin)(object)this;
		}

		public static bool IsValidMessage(string body, string secret, string timestamp, string signature)
		{
			try
			{
				string s = timestamp + "." + body;
				return Convert.ToBase64String(new HMACSHA256(Encoding.UTF8.GetBytes(secret)).ComputeHash(Encoding.UTF8.GetBytes(s))).Equals(signature);
			}
			catch (Exception ex)
			{
				Log.LogError((object)"An error occurred while validating the message.");
				Log.LogError((object)ex.Message);
				Log.LogError((object)ex.StackTrace);
				return false;
			}
		}

		private static bool TestMessageValidation()
		{
			string signature = "4OSwlhTt0EcrlSQFlqgE18FOtT+EKX4qTJdJeC8oV/o=";
			string timestamp = "2023-04-18T16:49:00.617031Z";
			string secret = "13c3b68914487acd1c68d85857ee1cfc308f15510f2d8e71273ee0f8a42d9d00";
			return IsValidMessage("{\"data\":{\"amount\":{\"currency\":\"USD\",\"value\":\"82.95\"},\"campaign_id\":\"a4fd5207-bd9f-4712-920a-85f8d92cf4e6\",\"completed_at\":\"2023-04-18T16:48:26.510702Z\",\"created_at\":\"2023-04-18T03:36:36.510717Z\",\"donor_comment\":\"Rerum quo necessitatibus voluptas provident ad molestiae ipsam.\",\"donor_name\":\"Jirachi\",\"fundraising_event_id\":null,\"id\":\"dfa25dcc-2026-4320-a5b7-5da076efeb05\",\"legacy_id\":0,\"poll_id\":null,\"poll_option_id\":null,\"reward_id\":null,\"sustained\":false,\"target_id\":null,\"team_event_id\":null},\"meta\":{\"attempted_at\":\"2023-04-18T16:49:00.617031Z\",\"event_type\":\"public:direct:donation_updated\",\"generated_at\":\"2023-04-18T16:48:59.510758Z\",\"id\":\"d8768e26-1092-4f4c-a829-a2698cd19664\",\"subscription_source_id\":\"00000000-0000-0000-0000-000000000000\",\"subscription_source_type\":\"test\"}}", secret, timestamp, signature);
		}

		public IMoHttpHandler GetHttpHandler()
		{
			return (IMoHttpHandler)(object)this;
		}

		public string GetPrefix()
		{
			return "tiltislip";
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.mosadie.tiltislip";

		public const string PLUGIN_NAME = "TiltiSlip";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}