using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using MoCore;
using RegionVo;
using UnityEngine;
[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.slipchat")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Local API for sending in-game announcements.")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: AssemblyInformationalVersion("0.1.1+1be4c9dd2b56013e207ce32f94d1b677f830f9a9")]
[assembly: AssemblyProduct("SlipChat")]
[assembly: AssemblyTitle("com.mosadie.slipchat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace SlipChat
{
[BepInPlugin("com.mosadie.slipchat", "SlipChat", "0.1.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInProcess("Slipstream_Win.exe")]
public class Plugin : BaseUnityPlugin, MoPlugin
{
private static ConfigEntry<int> port;
private static ConfigEntry<bool> debugMode;
private static HttpListener listener = null;
internal static ManualLogSource Log;
public static readonly string COMPATIBLE_GAME_VERSION = "4.1579";
public static readonly string GAME_VERSION_URL = "https://raw.githubusercontent.com/MoSadie/SlipChat/refs/heads/main/versions.json";
private void Awake()
{
try
{
Log = ((BaseUnityPlugin)this).Logger;
if (!MoCore.RegisterPlugin((MoPlugin)(object)this))
{
Log.LogError((object)"Failed to register plugin with MoCore. Please check the logs for more information.");
return;
}
port = ((BaseUnityPlugin)this).Config.Bind<int>("Server Settings", "Port", 8002, "Port to listen on.");
debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Developer Settings", "Debug Mode", false, "Enable debug mode, preventing the game from actually sending the order.");
if (!HttpListener.IsSupported)
{
Log.LogError((object)"HttpListener is not supported on this platform.");
listener = null;
return;
}
listener = new HttpListener();
listener.Prefixes.Add($"http://127.0.0.1:{port.Value}/sendchat/");
listener.Prefixes.Add($"http://localhost:{port.Value}/sendchat/");
listener.Start();
listener.BeginGetContext(HandleRequest, listener);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin com.mosadie.slipchat is loaded!");
Application.quitting += ApplicationQuitting;
}
catch (PlatformNotSupportedException ex)
{
Log.LogError((object)"HttpListener is not supported on this platform.");
Log.LogError((object)ex.Message);
}
catch (Exception ex2)
{
Log.LogError((object)"An error occurred while starting the plugin.");
Log.LogError((object)ex2.Message);
}
}
private void HandleRequest(IAsyncResult result)
{
//IL_0118: Unknown result type (might be due to invalid IL or missing references)
((BaseUnityPlugin)this).Logger.LogInfo((object)"Handling request");
try
{
HttpListener httpListener = (HttpListener)result.AsyncState;
HttpListenerContext httpListenerContext = httpListener.EndGetContext(result);
HttpListenerRequest request = httpListenerContext.Request;
HttpListenerResponse response = httpListenerContext.Response;
_ = request.RawUrl.Split('?', 2)[0];
HttpStatusCode statusCode;
string s;
if (!canUseAndOnHelm())
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Captain Seat check failed. IsCaptain: {getIsCaptain()} IsFirstMate: {getIsFirstMate()} AndOnHelm: {canUseAndOnHelm()}");
statusCode = HttpStatusCode.Forbidden;
s = "You are not the captain/first mate or are not seated on the helm.";
}
else
{
string text = request.QueryString["message"];
((BaseUnityPlugin)this).Logger.LogInfo((object)("Pre-parsed Message: " + text));
if (text != null)
{
text = VariableHandler.ParseVariables(text);
if (!EditableText.IsTextUsable(text))
{
((BaseUnityPlugin)this).Logger.LogInfo((object)$"Message is not usable: Null/Whitespace: {string.IsNullOrWhiteSpace(text)}. Null/Empty: {string.IsNullOrEmpty(text)}");
statusCode = HttpStatusCode.BadRequest;
s = "Message is not usable.";
}
else
{
if (!debugMode.Value)
{
RequestCatalog.CaptainIssueOrderAll((OrderType)7, text);
((BaseUnityPlugin)this).Logger.LogInfo((object)("Message sent: " + text));
}
else
{
((BaseUnityPlugin)this).Logger.LogInfo((object)("Debug mode enabled, message not sent: " + text));
}
statusCode = HttpStatusCode.OK;
s = "Message sent!";
}
}
else
{
statusCode = HttpStatusCode.BadRequest;
s = "No message provided.";
}
}
response.StatusCode = (int)statusCode;
response.Headers.Add("Access-Control-Allow-Origin", "*");
byte[] bytes = Encoding.UTF8.GetBytes(s);
response.ContentLength64 = bytes.Length;
Stream outputStream = response.OutputStream;
outputStream.Write(bytes, 0, bytes.Length);
outputStream.Close();
VariableHandler.Reset();
httpListener.BeginGetContext(HandleRequest, httpListener);
}
catch (Exception ex)
{
Log.LogError((object)"An error occurred while handling the request.");
Log.LogError((object)ex.Message);
}
}
private static bool getIsCaptain()
{
try
{
if (Svc.Get<MpSvc>() == null)
{
Log.LogError((object)"An error occurred handling self crew. null MpSvc.");
return false;
}
MpCaptainController captains = Svc.Get<MpSvc>().Captains;
if (captains == null || captains.CaptainClient == null)
{
return false;
}
return captains.CaptainClient.IsLocal;
}
catch (Exception ex)
{
Log.LogError((object)("An error occurred while checking if the crewmate is the captain: " + ex.Message));
return false;
}
}
private static bool getIsFirstMate()
{
try
{
if (Svc.Get<MpSvc>() == null)
{
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)
{
return false;
}
return ((SlipClient)clients.LocalClient).Roles.Has(Roles.FirstMate);
}
catch (Exception ex)
{
Log.LogError((object)("An error occurred while checking if the crewmate is the first mate: " + ex.Message));
return false;
}
}
private static bool canUseAndOnHelm()
{
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
if (!getIsCaptain() && !getIsFirstMate())
{
Log.LogInfo((object)"Not captain or first mate.");
return false;
}
try
{
MpSvc val = Svc.Get<MpSvc>();
if (val == null)
{
Log.LogError((object)"An error occurred handling helm check. null MpSvc.");
return false;
}
MpClientController clients = val.Clients;
if (clients == null)
{
Log.LogWarning((object)"An error occurred handling helm check. null Clients.");
return false;
}
LocalSlipClient localClient = clients.LocalClient;
if (clients.LocalClient == null)
{
Log.LogWarning((object)"An error occurred handling helm check. null LocalClient.");
return false;
}
List<Crewmate> crew = ((SlipClient)localClient).Crew;
if (crew == null)
{
Log.LogWarning((object)"An error occurred handling helm check. null Crew list.");
return false;
}
for (int i = 0; i < crew.Count; i++)
{
Log.LogInfo((object)$"Checking crewmate {i}: {crew[i].Client.Player.DisplayName} {crew[i].CurrentStation.StationType}");
if ((Object)(object)crew[i] != (Object)null && (Object)(object)crew[1].CurrentStation != (Object)null && ((object)(StationType)(ref crew[i].CurrentStation.StationType)).Equals((object)(StationType)3))
{
Log.LogInfo((object)"Found valid crew on helm.");
return true;
}
}
Log.LogInfo((object)"No valid crew on helm.");
return false;
}
catch (Exception ex)
{
Log.LogError((object)("An error occurred while checking if the crewmate is the captain/first mate and seated on the helm: " + ex.Message));
Log.LogError((object)ex.StackTrace);
return false;
}
}
private void ApplicationQuitting()
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Stopping server");
if (listener != null)
{
listener.Close();
}
}
public string GetCompatibleGameVersion()
{
return COMPATIBLE_GAME_VERSION;
}
public string GetVersionCheckUrl()
{
return GAME_VERSION_URL;
}
public BaseUnityPlugin GetPluginObject()
{
return (BaseUnityPlugin)(object)this;
}
}
internal class VariableHandler
{
private static Dictionary<string, string> crewMap = new Dictionary<string, string>();
internal static string ParseVariables(string message)
{
string[] array = message.Split(' ');
string text = "";
string[] array2 = array;
foreach (string text2 in array2)
{
if (text2.StartsWith("$"))
{
string variableValue = GetVariableValue(text2.Substring(1));
text = ((variableValue != null) ? (text + variableValue + " ") : (text + text2 + " "));
}
else
{
text = text + text2 + " ";
}
}
return text.Trim();
}
internal static string GetVariableValue(string variable)
{
//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0503: Unknown result type (might be due to invalid IL or missing references)
string text = "";
while (variable.Length > 0 && !char.IsLetterOrDigit(variable[variable.Length - 1]))
{
text = variable[variable.Length - 1] + text;
variable = variable.Substring(0, variable.Length - 1);
}
string text2 = "";
if (variable.StartsWith("randomCrew"))
{
text2 = GetRandomCrewMember(variable.Substring(10, variable.Length - 11));
}
else if (variable.StartsWith("crew"))
{
text2 = GetCrewMember(variable.Substring(5, variable.Length - 6));
}
else
{
switch (variable)
{
case "version":
text2 = "0.1.1";
break;
case "captain":
text2 = Svc.Get<MpSvc>().Captains.CaptainClient.Player.DisplayName;
break;
case "enemyName":
{
MpScenarioController scenarios5 = Svc.Get<MpSvc>().Scenarios;
text2 = ((scenarios5 != null && scenarios5.CurrentScenario != null && scenarios5.CurrentScenario.Battle != null && scenarios5.CurrentScenario.Battle.Metadata.EnemyName != null) ? scenarios5.CurrentScenario.Battle.Metadata.EnemyName : "");
break;
}
case "enemyIntel":
{
MpScenarioController scenarios2 = Svc.Get<MpSvc>().Scenarios;
text2 = ((scenarios2 != null && scenarios2.CurrentScenario != null && scenarios2.CurrentScenario.Battle != null && scenarios2.CurrentScenario.Battle.Metadata.IntelDescription != null) ? scenarios2.CurrentScenario.Battle.Metadata.IntelDescription : "");
break;
}
case "enemyInvader":
case "enemyInvaders":
{
MpScenarioController scenarios6 = Svc.Get<MpSvc>().Scenarios;
text2 = ((scenarios6 != null && scenarios6.CurrentScenario != null && scenarios6.CurrentScenario.Battle != null && scenarios6.CurrentScenario.Battle.Metadata.InvaderDescription != null) ? scenarios6.CurrentScenario.Battle.Metadata.InvaderDescription : "");
break;
}
case "enemyThreat":
{
MpScenarioController scenarios3 = Svc.Get<MpSvc>().Scenarios;
text2 = ((scenarios3 != null && scenarios3.CurrentScenario != null && scenarios3.CurrentScenario.Battle != null) ? scenarios3.CurrentScenario.Battle.Metadata.ThreatLevel.ToString() : "");
break;
}
case "enemySpeed":
{
MpScenarioController scenarios = Svc.Get<MpSvc>().Scenarios;
text2 = ((scenarios != null && scenarios.CurrentScenario != null && scenarios.CurrentScenario.Battle != null) ? scenarios.CurrentScenario.Battle.Metadata.SpeedLevel.ToString() : "");
break;
}
case "enemyCargo":
{
MpScenarioController scenarios4 = Svc.Get<MpSvc>().Scenarios;
text2 = ((scenarios4 != null && scenarios4.CurrentScenario != null && scenarios4.CurrentScenario.Battle != null) ? scenarios4.CurrentScenario.Battle.Metadata.CargoLevel.ToString() : "");
break;
}
case "campaignName":
{
MpCampaignController campaigns2 = Svc.Get<MpSvc>().Campaigns;
if (campaigns2 != null && campaigns2.CurrentCampaign != null && campaigns2.CurrentCampaign.CaptainCampaign != null && campaigns2.CurrentCampaign.CaptainCampaign.CampaignVo != null)
{
RegionMetadataVo metadata = ((Root)(ref campaigns2.CurrentCampaign.CaptainCampaign.CampaignVo.RegionVo)).Metadata;
if (((RegionMetadataVo)(ref metadata)).Name != null)
{
metadata = ((Root)(ref campaigns2.CurrentCampaign.CaptainCampaign.CampaignVo.RegionVo)).Metadata;
text2 = ((RegionMetadataVo)(ref metadata)).Name;
break;
}
}
text2 = "";
break;
}
case "sectorName":
{
MpCampaignController campaigns = Svc.Get<MpSvc>().Campaigns;
text2 = ((campaigns != null && campaigns.CurrentCampaign != null && campaigns.CurrentCampaign.CaptainCampaign != null && campaigns.CurrentCampaign.CaptainCampaign.CampaignVo != null && campaigns.CurrentCampaign.CaptainCampaign.CampaignVo.CurrentSectorVo != null && ((SectorDefVo)(ref campaigns.CurrentCampaign.CaptainCampaign.CampaignVo.CurrentSectorVo.Definition)).Name != null) ? ((SectorDefVo)(ref campaigns.CurrentCampaign.CaptainCampaign.CampaignVo.CurrentSectorVo.Definition)).Name : "");
break;
}
default:
text2 = "";
break;
}
}
return text2 + text;
}
internal static string GetRandomCrewMember(string id)
{
if (crewMap.ContainsKey(id))
{
return crewMap[id];
}
Dictionary<int, Crewmate> dictionary = Svc.Get<MpSvc>().Crew.CrewMap;
if (dictionary.Count == 0)
{
return "";
}
Random random = new Random();
Crewmate val = dictionary[random.Next(dictionary.Count)];
crewMap.Add(id, val.Client.Player.DisplayName);
return val.Client.Player.DisplayName;
}
internal static string GetCrewMember(string id)
{
Dictionary<int, Crewmate> dictionary = Svc.Get<MpSvc>().Crew.CrewMap;
if (dictionary.Count == 0)
{
return "";
}
int result = 0;
if (!int.TryParse(id, out result))
{
return "";
}
if (!dictionary.ContainsKey(result))
{
return "";
}
return dictionary[result].Client.Player.DisplayName;
}
internal static void Reset()
{
crewMap.Clear();
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.mosadie.slipchat";
public const string PLUGIN_NAME = "SlipChat";
public const string PLUGIN_VERSION = "0.1.1";
}
}