using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LC_API.BundleAPI;
using LC_API.ClientAPI;
using LC_API.Comp;
using LC_API.Data;
using LC_API.Extensions;
using LC_API.GameInterfaceAPI;
using LC_API.ManualPatches;
using LC_API.ServerAPI;
using Microsoft.CodeAnalysis;
using Steamworks;
using Steamworks.Data;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("LC_API")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Utilities for plugin devs")]
[assembly: AssemblyFileVersion("2.1.4.0")]
[assembly: AssemblyInformationalVersion("2.1.4")]
[assembly: AssemblyProduct("LC_API")]
[assembly: AssemblyTitle("LC_API")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.4.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 LC_API
{
internal static class CheatDatabase
{
private const string DAT_CD_BROADCAST = "LC_API_CD_Broadcast";
private const string SIG_REQ_GUID = "LC_API_ReqGUID";
private const string SIG_SEND_MODS = "LC_APISendMods";
private static Dictionary<string, PluginInfo> PluginsLoaded = new Dictionary<string, PluginInfo>();
public static void RunLocalCheatDetector()
{
PluginsLoaded = Chainloader.PluginInfos;
using Dictionary<string, PluginInfo>.ValueCollection.Enumerator enumerator = PluginsLoaded.Values.GetEnumerator();
while (enumerator.MoveNext())
{
switch (enumerator.Current.Metadata.GUID)
{
case "mikes.lethalcompany.mikestweaks":
case "mom.llama.enhancer":
case "Posiedon.GameMaster":
case "LethalCompanyScalingMaster":
case "verity.amberalert":
ModdedServer.SetServerModdedOnly();
break;
}
}
}
public static void OtherPlayerCheatDetector()
{
Plugin.Log.LogWarning((object)"Asking all other players for their mod list..");
GameTips.ShowTip("Mod List:", "Asking all other players for installed mods..");
GameTips.ShowTip("Mod List:", "Check the logs for more detailed results.\n<size=13>(Note that if someone doesnt show up on the list, they may not have LC_API installed)</size>");
Networking.Broadcast("LC_API_CD_Broadcast", "LC_API_ReqGUID");
}
internal static void CDNetGetString(string data, string signature)
{
if (data == "LC_API_CD_Broadcast" && signature == "LC_API_ReqGUID")
{
string text = "";
foreach (PluginInfo value in PluginsLoaded.Values)
{
text = text + "\n" + value.Metadata.GUID;
}
Networking.Broadcast(GameNetworkManager.Instance.localPlayerController.playerUsername + " responded with these mods:" + text, "LC_APISendMods");
}
if (signature == "LC_APISendMods")
{
GameTips.ShowTip("Mod List:", data);
Plugin.Log.LogWarning((object)data);
}
}
}
[BepInPlugin("LC_API", "LC_API", "2.1.4")]
public sealed class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
private ConfigEntry<bool> configOverrideModServer;
private ConfigEntry<bool> configLegacyAssetLoading;
private ConfigEntry<bool> configDisableBundleLoader;
public static bool Initialized { get; private set; }
private void Awake()
{
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Expected O, but got Unknown
//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
//IL_01c6: Expected O, but got Unknown
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
//IL_01d8: Expected O, but got Unknown
//IL_01df: Unknown result type (might be due to invalid IL or missing references)
//IL_01eb: Expected O, but got Unknown
configOverrideModServer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Force modded server browser", false, "Should the API force you into the modded server browser?");
configLegacyAssetLoading = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Legacy asset bundle loading", false, "Should the BundleLoader use legacy asset loading? Turning this on may help with loading assets from older plugins.");
configDisableBundleLoader = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Disable BundleLoader", false, "Should the BundleLoader be turned off? Enable this if you are having problems with mods that load assets using a different method from LC_API's BundleLoader.");
CommandHandler.commandPrefix = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Prefix", "/", "Command prefix");
Log = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogWarning((object)"\n.____ _________ _____ __________ .___ \r\n| | \\_ ___ \\ / _ \\ \\______ \\| | \r\n| | / \\ \\/ / /_\\ \\ | ___/| | \r\n| |___\\ \\____ / | \\| | | | \r\n|_______ \\\\______ /______\\____|__ /|____| |___| \r\n \\/ \\//_____/ \\/ \r\n ");
((BaseUnityPlugin)this).Logger.LogInfo((object)"LC_API Starting up..");
if (configOverrideModServer.Value)
{
ModdedServer.SetServerModdedOnly();
}
Harmony val = new Harmony("ModAPI");
MethodInfo methodInfo = AccessTools.Method(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyCreated", (Type[])null, (Type[])null);
AccessTools.Method(typeof(GameNetworkManager), "LobbyDataIsJoinable", (Type[])null, (Type[])null);
MethodInfo methodInfo2 = AccessTools.Method(typeof(ServerPatch), "OnLobbyCreate", (Type[])null, (Type[])null);
MethodInfo methodInfo3 = AccessTools.Method(typeof(MenuManager), "Awake", (Type[])null, (Type[])null);
MethodInfo methodInfo4 = AccessTools.Method(typeof(ServerPatch), "CacheMenuManager", (Type[])null, (Type[])null);
MethodInfo methodInfo5 = AccessTools.Method(typeof(HUDManager), "AddChatMessage", (Type[])null, (Type[])null);
MethodInfo methodInfo6 = AccessTools.Method(typeof(ServerPatch), "ChatInterpreter", (Type[])null, (Type[])null);
MethodInfo methodInfo7 = AccessTools.Method(typeof(HUDManager), "SubmitChat_performed", (Type[])null, (Type[])null);
MethodInfo methodInfo8 = AccessTools.Method(typeof(CommandHandler.SubmitChatPatch), "Transpiler", (Type[])null, (Type[])null);
val.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
val.Patch((MethodBase)methodInfo5, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
val.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
val.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo8), (HarmonyMethod)null, (HarmonyMethod)null);
Networking.GetString = (Action<string, string>)Delegate.Combine(Networking.GetString, new Action<string, string>(CheatDatabase.CDNetGetString));
Networking.GetListString = (Action<List<string>, string>)Delegate.Combine(Networking.GetListString, new Action<List<string>, string>(Networking.LCAPI_NET_SYNCVAR_SET));
}
internal void Start()
{
Initialize();
}
internal void OnDestroy()
{
Initialize();
}
internal void Initialize()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
if (!Initialized)
{
Initialized = true;
if (!configDisableBundleLoader.Value)
{
BundleLoader.Load(configLegacyAssetLoading.Value);
}
GameObject val = new GameObject("API");
Object.DontDestroyOnLoad((Object)val);
val.AddComponent<LC_APIManager>();
((BaseUnityPlugin)this).Logger.LogInfo((object)"LC_API Started!");
CheatDatabase.RunLocalCheatDetector();
}
}
internal static void PatchMethodManual(MethodInfo method, MethodInfo patch, Harmony harmony)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
harmony.Patch((MethodBase)method, new HarmonyMethod(patch), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "LC_API";
public const string PLUGIN_NAME = "LC_API";
public const string PLUGIN_VERSION = "2.1.4";
}
}
namespace LC_API.ServerAPI
{
public static class ModdedServer
{
private static bool moddedOnly;
[Obsolete("Use SetServerModdedOnly() instead. This will be removed/private in a future update.")]
public static bool setModdedOnly;
public static bool ModdedOnly => moddedOnly;
public static void SetServerModdedOnly()
{
moddedOnly = true;
Plugin.Log.LogMessage((object)"A plugin has set your game to only allow you to play with other people who have mods!");
}
public static void OnSceneLoaded()
{
if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && ModdedOnly)
{
GameNetworkManager instance = GameNetworkManager.Instance;
instance.gameVersionNum += 16440;
setModdedOnly = true;
}
}
}
public static class Networking
{
public static Action<string, string> GetString = delegate
{
};
public static Action<List<string>, string> GetListString = delegate
{
};
public static Action<int, string> GetInt = delegate
{
};
public static Action<float, string> GetFloat = delegate
{
};
public static Action<Vector3, string> GetVector3 = delegate
{
};
private static Dictionary<string, string> syncStringVars = new Dictionary<string, string>();
public static void Broadcast(string data, string signature)
{
if (data.Contains("/"))
{
Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( / )");
return;
}
HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data + "/" + signature + "/" + NetworkBroadcastDataType.BDstring.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
}
public static void Broadcast(List<string> data, string signature)
{
string text = "";
foreach (string datum in data)
{
if (datum.Contains("/"))
{
Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( / )");
return;
}
if (datum.Contains("\n"))
{
Plugin.Log.LogError((object)"Invalid character in broadcasted string event! ( NewLine )");
return;
}
text = text + datum + "\n";
}
HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data?.ToString() + "/" + signature + "/" + NetworkBroadcastDataType.BDlistString.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
}
public static void Broadcast(int data, string signature)
{
HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data + "/" + signature + "/" + NetworkBroadcastDataType.BDint.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
}
public static void Broadcast(float data, string signature)
{
HUDManager.Instance.AddTextToChatOnServer("<size=0>NWE/" + data + "/" + signature + "/" + NetworkBroadcastDataType.BDfloat.ToString() + "/" + GameNetworkManager.Instance.localPlayerController.playerClientId + "/</size>", -1);
}
public static void Broadcast(Vector3 data, string signature)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
HUDManager instance = HUDManager.Instance;
string[] obj = new string[9] { "<size=0>NWE/", null, null, null, null, null, null, null, null };
Vector3 val = data;
obj[1] = ((object)(Vector3)(ref val)).ToString();
obj[2] = "/";
obj[3] = signature;
obj[4] = "/";
obj[5] = NetworkBroadcastDataType.BDvector3.ToString();
obj[6] = "/";
obj[7] = GameNetworkManager.Instance.localPlayerController.playerClientId.ToString();
obj[8] = "/</size>";
instance.AddTextToChatOnServer(string.Concat(obj), -1);
}
public static void RegisterSyncVariable(string name)
{
if (!syncStringVars.ContainsKey(name))
{
syncStringVars.Add(name, "");
}
else
{
Plugin.Log.LogError((object)("Cannot register Sync Variable! A Sync Variable has already been registered with name " + name));
}
}
public static void SetSyncVariable(string name, string value)
{
if (syncStringVars.ContainsKey(name))
{
syncStringVars[name] = value;
Broadcast(new List<string> { name, value }, "LCAPI_NET_SYNCVAR_SET");
}
else
{
Plugin.Log.LogError((object)("Cannot set the value of Sync Variable " + name + " as it is not registered!"));
}
}
private static void SetSyncVariableB(string name, string value)
{
if (syncStringVars.ContainsKey(name))
{
syncStringVars[name] = value;
}
else
{
Plugin.Log.LogError((object)("Cannot set the value of Sync Variable " + name + " as it is not registered!"));
}
}
internal static void LCAPI_NET_SYNCVAR_SET(List<string> list, string arg2)
{
if (arg2 == "LCAPI_NET_SYNCVAR_SET")
{
SetSyncVariableB(list[0], list[1]);
}
}
public static string GetSyncVariable(string name)
{
if (syncStringVars.ContainsKey(name))
{
return syncStringVars[name];
}
Plugin.Log.LogError((object)("Cannot get the value of Sync Variable " + name + " as it is not registered!"));
return "";
}
private static void GotString(string data, string signature)
{
}
private static void GotInt(int data, string signature)
{
}
private static void GotFloat(float data, string signature)
{
}
private static void GotVector3(Vector3 data, string signature)
{
}
}
}
namespace LC_API.ManualPatches
{
internal static class ServerPatch
{
internal static bool OnLobbyCreate(GameNetworkManager __instance, Result result, Lobby lobby)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Invalid comparison between Unknown and I4
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
if ((int)result != 1)
{
Debug.LogError((object)$"Lobby could not be created! {result}", (Object)(object)__instance);
}
__instance.lobbyHostSettings.lobbyName = "[MODDED]" + __instance.lobbyHostSettings.lobbyName.ToString();
Plugin.Log.LogMessage((object)"server pre-setup success");
return true;
}
internal static bool CacheMenuManager(MenuManager __instance)
{
LC_APIManager.MenuManager = __instance;
return true;
}
internal static bool ChatInterpreter(HUDManager __instance, string chatMessage)
{
//IL_0312: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
if (!chatMessage.Contains("NWE") || !chatMessage.Contains("<size=0>"))
{
return true;
}
string[] array = chatMessage.Split(new char[1] { '/' });
if (array.Length < 5)
{
if (array.Length >= 3)
{
if (!int.TryParse(array[4], out var result))
{
Plugin.Log.LogWarning((object)"Failed to parse player ID!!");
return false;
}
if ((result == (int)GameNetworkManager.Instance.localPlayerController.playerClientId) & !LC_APIManager.netTester)
{
return false;
}
Enum.TryParse<NetworkBroadcastDataType>(array[3], out var result2);
switch (result2)
{
case NetworkBroadcastDataType.BDstring:
Networking.GetString(array[1], array[2]);
break;
case NetworkBroadcastDataType.BDint:
Networking.GetInt(int.Parse(array[1]), array[2]);
break;
case NetworkBroadcastDataType.BDfloat:
Networking.GetFloat(float.Parse(array[1]), array[2]);
break;
case NetworkBroadcastDataType.BDvector3:
{
string[] array2 = array[1].Replace("(", "").Replace(")", "").Split(new char[1] { ',' });
Vector3 arg = default(Vector3);
if (array2.Length == 3)
{
if (float.TryParse(array2[0], out var result3) && float.TryParse(array2[1], out var result4) && float.TryParse(array2[2], out var result5))
{
arg.x = result3;
arg.y = result4;
arg.z = result5;
}
else
{
Plugin.Log.LogError((object)"Vector3 Network receive fail. This is a failure of the API, and it should be reported as a bug.");
}
}
else
{
Plugin.Log.LogError((object)"Vector3 Network receive fail. This is a failure of the API, and it should be reported as a bug.");
}
Networking.GetVector3(arg, array[2]);
break;
}
case NetworkBroadcastDataType.BDlistString:
{
string[] source = array[1].Split(new char[1] { '\n' });
Networking.GetListString(source.ToList(), array[2]);
break;
}
}
_ = LC_APIManager.netTester;
return false;
}
Plugin.Log.LogError((object)"Generic Network receive fail. This is a failure of the API, and it should be reported as a bug.");
Plugin.Log.LogError((object)$"Generic Network receive fail (expected 5+ data fragments, got {array.Length}). This is a failure of the API, and it should be reported as a bug.");
return true;
}
if (!int.TryParse(array[4], out var result6))
{
Plugin.Log.LogWarning((object)("Failed to parse player ID '" + array[4] + "'!!"));
return false;
}
if ((result6 == (int)GameNetworkManager.Instance.localPlayerController.playerClientId) & !LC_APIManager.netTester)
{
return false;
}
if (!Enum.TryParse<NetworkBroadcastDataType>(array[3], out var result7))
{
Plugin.Log.LogError((object)("Unknown datatype - unable to parse '" + array[3] + "' into a known data type!"));
return false;
}
switch (result7)
{
case NetworkBroadcastDataType.BDstring:
Networking.GetString.InvokeActionSafe(array[1], array[2]);
break;
case NetworkBroadcastDataType.BDint:
Networking.GetInt.InvokeActionSafe(int.Parse(array[1]), array[2]);
break;
case NetworkBroadcastDataType.BDfloat:
Networking.GetFloat.InvokeActionSafe(float.Parse(array[1]), array[2]);
break;
case NetworkBroadcastDataType.BDvector3:
{
string text = array[1].Trim('(', ')');
string[] array3 = text.Split(new char[1] { ',' });
Vector3 param = default(Vector3);
float result8;
float result9;
float result10;
if (array3.Length != 3)
{
Plugin.Log.LogError((object)$"Vector3 Network receive fail (expected 3 numbers, got {array3.Length} number(?)(s) instead). This is a failure of the API, and it should be reported as a bug. (passing an empty Vector3 in its place)");
}
else if (float.TryParse(array3[0], out result8) && float.TryParse(array3[1], out result9) && float.TryParse(array3[2], out result10))
{
param.x = result8;
param.y = result9;
param.z = result10;
}
else
{
Plugin.Log.LogError((object)("Vector3 Network receive fail (failed to parse '" + text + "' as numbers). This is a failure of the API, and it should be reported as a bug."));
}
Networking.GetVector3.InvokeActionSafe(param, array[2]);
break;
}
}
_ = LC_APIManager.netTester;
return false;
}
internal static bool ChatCommands(HUDManager __instance, CallbackContext context)
{
if (__instance.chatTextField.text.ToLower().Contains("/modcheck"))
{
CheatDatabase.OtherPlayerCheatDetector();
return false;
}
return true;
}
}
}
namespace LC_API.GameInterfaceAPI
{
public static class GameState
{
private static readonly Action NothingAction = delegate
{
};
public static int AlivePlayerCount { get; private set; }
public static ShipState ShipState { get; private set; }
public static event Action PlayerDied;
public static event Action LandOnMoon;
public static event Action WentIntoOrbit;
public static event Action ShipStartedLeaving;
internal static void GSUpdate()
{
if (!((Object)(object)StartOfRound.Instance == (Object)null))
{
if (StartOfRound.Instance.shipHasLanded && ShipState != ShipState.OnMoon)
{
ShipState = ShipState.OnMoon;
GameState.LandOnMoon.InvokeActionSafe();
}
if (StartOfRound.Instance.inShipPhase && ShipState != 0)
{
ShipState = ShipState.InOrbit;
GameState.WentIntoOrbit.InvokeActionSafe();
}
if (StartOfRound.Instance.shipIsLeaving && ShipState != ShipState.LeavingMoon)
{
ShipState = ShipState.LeavingMoon;
GameState.ShipStartedLeaving.InvokeActionSafe();
}
if (AlivePlayerCount < StartOfRound.Instance.livingPlayers)
{
GameState.PlayerDied.InvokeActionSafe();
}
AlivePlayerCount = StartOfRound.Instance.livingPlayers;
}
}
static GameState()
{
GameState.PlayerDied = NothingAction;
GameState.LandOnMoon = NothingAction;
GameState.WentIntoOrbit = NothingAction;
GameState.ShipStartedLeaving = NothingAction;
}
}
public class GameTips
{
private static List<string> tipHeaders = new List<string>();
private static List<string> tipBodys = new List<string>();
private static float lastMessageTime;
public static void ShowTip(string header, string body)
{
tipHeaders.Add(header);
tipBodys.Add(body);
}
public static void UpdateInternal()
{
lastMessageTime -= Time.deltaTime;
if ((tipHeaders.Count > 0) & (lastMessageTime < 0f))
{
lastMessageTime = 5f;
if ((Object)(object)HUDManager.Instance != (Object)null)
{
HUDManager.Instance.DisplayTip(tipHeaders[0], tipBodys[0], false, false, "LC_Tip1");
}
tipHeaders.RemoveAt(0);
tipBodys.RemoveAt(0);
}
}
}
}
namespace LC_API.Extensions
{
public static class DelegateExtensions
{
private static readonly PropertyInfo PluginGetLogger = AccessTools.Property(typeof(BaseUnityPlugin), "Logger");
public static void InvokeActionSafe(this Action action)
{
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
if (action == null)
{
return;
}
Delegate[] invocationList = action.GetInvocationList();
foreach (Delegate @delegate in invocationList)
{
try
{
((Action)@delegate)();
}
catch (Exception ex)
{
Plugin.Log.LogError((object)"Exception while invoking hook callback!");
string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
if (val == null)
{
Plugin.Log.LogError((object)ex.ToString());
break;
}
((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
}
}
}
public static void InvokeActionSafe<T>(this Action<T> action, T param)
{
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
if (action == null)
{
return;
}
Delegate[] invocationList = action.GetInvocationList();
foreach (Delegate @delegate in invocationList)
{
try
{
((Action<T>)@delegate)(param);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)"Exception while invoking hook callback!");
string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
if (val == null)
{
Plugin.Log.LogError((object)ex.ToString());
break;
}
((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
}
}
}
public static void InvokeActionSafe<T1, T2>(this Action<T1, T2> action, T1 param1, T2 param2)
{
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
if (action == null)
{
return;
}
Delegate[] invocationList = action.GetInvocationList();
foreach (Delegate @delegate in invocationList)
{
try
{
((Action<T1, T2>)@delegate)(param1, param2);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)"Exception while invoking hook callback!");
string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
if (val == null)
{
Plugin.Log.LogError((object)ex.ToString());
break;
}
((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
}
}
}
internal static void InvokeParameterlessDelegate<T>(this T paramlessDelegate) where T : Delegate
{
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
if ((Delegate?)paramlessDelegate == (Delegate?)null)
{
return;
}
Delegate[] invocationList = paramlessDelegate.GetInvocationList();
foreach (Delegate @delegate in invocationList)
{
try
{
((T)@delegate).DynamicInvoke();
}
catch (Exception ex)
{
Plugin.Log.LogError((object)"Exception while invoking hook callback!");
string asmName = @delegate.GetMethodInfo().DeclaringType.Assembly.FullName;
PluginInfo val = ((IEnumerable<PluginInfo>)Chainloader.PluginInfos.Values).FirstOrDefault((Func<PluginInfo, bool>)((PluginInfo pi) => ((object)pi.Instance).GetType().Assembly.FullName == asmName));
if (val == null)
{
Plugin.Log.LogError((object)ex.ToString());
break;
}
((ManualLogSource)PluginGetLogger.GetValue(val.Instance)).LogError((object)ex.ToString());
}
}
}
}
}
namespace LC_API.Data
{
internal enum NetworkBroadcastDataType
{
Unknown,
BDint,
BDfloat,
BDvector3,
BDstring,
BDlistString
}
public enum ShipState
{
InOrbit,
OnMoon,
LeavingMoon
}
}
namespace LC_API.Comp
{
internal class LC_APIManager : MonoBehaviour
{
public static MenuManager MenuManager;
public static bool netTester;
private static int playerCount;
private static bool wanttoCheckMods;
private static float lobbychecktimer;
public void Update()
{
GameState.GSUpdate();
GameTips.UpdateInternal();
if ((((Object)(object)HUDManager.Instance != (Object)null) & netTester) && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null)
{
Networking.Broadcast("testerData", "testerSignature");
}
if (!ModdedServer.setModdedOnly)
{
ModdedServer.OnSceneLoaded();
}
else if (ModdedServer.ModdedOnly && (Object)(object)MenuManager != (Object)null && Object.op_Implicit((Object)(object)MenuManager.versionNumberText))
{
((TMP_Text)MenuManager.versionNumberText).text = $"v{GameNetworkManager.Instance.gameVersionNum - 16440}\nMOD";
}
if ((Object)(object)GameNetworkManager.Instance != (Object)null)
{
if (playerCount < GameNetworkManager.Instance.connectedPlayers)
{
lobbychecktimer = -4.5f;
wanttoCheckMods = true;
}
playerCount = GameNetworkManager.Instance.connectedPlayers;
}
if (lobbychecktimer < 0f)
{
lobbychecktimer += Time.deltaTime;
}
else if (wanttoCheckMods && (Object)(object)HUDManager.Instance != (Object)null)
{
wanttoCheckMods = false;
CD();
}
}
private void CD()
{
CheatDatabase.OtherPlayerCheatDetector();
}
}
}
namespace LC_API.ClientAPI
{
public static class CommandHandler
{
internal static class SubmitChatPatch
{
private static bool HandleMessage(HUDManager manager)
{
string text = manager.chatTextField.text;
if (!Utility.IsNullOrWhiteSpace(text) && text.StartsWith(commandPrefix.Value))
{
string[] array = text.Split(new char[1] { ' ' });
string text2 = array[0].Substring(commandPrefix.Value.Length);
if (TryGetCommandHandler(text2, out var handler))
{
string[] obj = array.Skip(1).ToArray();
try
{
handler(obj);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("Error handling command: " + text2));
Plugin.Log.LogError((object)ex);
}
}
manager.localPlayer.isTypingChat = false;
manager.chatTextField.text = "";
EventSystem.current.SetSelectedGameObject((GameObject)null);
((Behaviour)manager.typingIndicator).enabled = false;
return true;
}
return false;
}
internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
{
List<CodeInstruction> newInstructions = new List<CodeInstruction>(instructions);
Label label = generator.DefineLabel();
newInstructions[newInstructions.Count - 1].labels.Add(label);
int index = newInstructions.FindIndex((CodeInstruction i) => i.opcode == OpCodes.Ldfld && (FieldInfo)i.operand == AccessTools.Field(typeof(PlayerControllerB), "isPlayerDead")) - 2;
newInstructions.InsertRange(index, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[3]
{
CodeInstructionExtensions.MoveLabelsFrom(new CodeInstruction(OpCodes.Ldarg_0, (object)null), newInstructions[index]),
new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(SubmitChatPatch), "HandleMessage", (Type[])null, (Type[])null)),
new CodeInstruction(OpCodes.Brtrue, (object)label)
});
for (int z = 0; z < newInstructions.Count; z++)
{
yield return newInstructions[z];
}
}
}
internal static ConfigEntry<string> commandPrefix;
internal static Dictionary<string, Action<string[]>> CommandHandlers = new Dictionary<string, Action<string[]>>();
internal static Dictionary<string, List<string>> CommandAliases = new Dictionary<string, List<string>>();
public static bool RegisterCommand(string command, Action<string[]> handler)
{
if (command.Contains(" ") || CommandHandlers.ContainsKey(command))
{
return false;
}
CommandHandlers.Add(command, handler);
return true;
}
public static bool RegisterCommand(string command, List<string> aliases, Action<string[]> handler)
{
if (command.Contains(" ") || GetCommandHandler(command) != null)
{
return false;
}
foreach (string alias in aliases)
{
if (alias.Contains(" ") || GetCommandHandler(alias) != null)
{
return false;
}
}
CommandHandlers.Add(command, handler);
CommandAliases.Add(command, aliases);
return true;
}
public static bool UnregisterCommand(string command)
{
CommandAliases.Remove(command);
return CommandHandlers.Remove(command);
}
internal static Action<string[]> GetCommandHandler(string command)
{
if (CommandHandlers.TryGetValue(command, out var value))
{
return value;
}
foreach (KeyValuePair<string, List<string>> commandAlias in CommandAliases)
{
if (commandAlias.Value.Contains(command))
{
return CommandHandlers[commandAlias.Key];
}
}
return null;
}
internal static bool TryGetCommandHandler(string command, out Action<string[]> handler)
{
handler = GetCommandHandler(command);
return handler != null;
}
}
}
namespace LC_API.BundleAPI
{
public static class BundleLoader
{
[Obsolete("Use OnLoadedBundles instead. This will be removed/private in a future update.")]
public delegate void OnLoadedAssetsDelegate();
[Obsolete("Use GetLoadedAsset instead. This will be removed/private in a future update.")]
public static ConcurrentDictionary<string, Object> assets = new ConcurrentDictionary<string, Object>();
[Obsolete("Use OnLoadedBundles instead. This will be removed/private in a future update.")]
public static OnLoadedAssetsDelegate OnLoadedAssets = LoadAssetsCompleted;
public static bool AssetsInLegacyDirectory { get; private set; }
public static bool LegacyLoadingEnabled { get; private set; }
public static event Action OnLoadedBundles;
internal static void Load(bool legacyLoading)
{
LegacyLoadingEnabled = legacyLoading;
Plugin.Log.LogMessage((object)"BundleAPI will now load all asset bundles...");
string path = Path.Combine(Paths.BepInExRootPath, "Bundles");
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
Plugin.Log.LogMessage((object)"BundleAPI Created legacy bundle directory in BepInEx/Bundles");
}
string[] array = (from x in Directory.GetFiles(path, "*", SearchOption.AllDirectories)
where !x.EndsWith(".manifest", StringComparison.CurrentCultureIgnoreCase)
select x).ToArray();
AssetsInLegacyDirectory = array.Length != 0;
if (!AssetsInLegacyDirectory)
{
Plugin.Log.LogMessage((object)"BundleAPI got no assets to load from legacy directory");
}
if (AssetsInLegacyDirectory)
{
Plugin.Log.LogWarning((object)"The path BepInEx > Bundles is outdated and should not be used anymore! Bundles will be loaded from BepInEx > plugins from now on");
LoadAllAssetsFromDirectory(array, legacyLoading);
}
string[] invalidEndings = new string[8] { ".dll", ".json", ".png", ".md", ".old", ".txt", ".exe", ".lem" };
path = Path.Combine(Paths.BepInExRootPath, "plugins");
array = (from file in Directory.GetFiles(path, "*", SearchOption.AllDirectories)
where !invalidEndings.Any((string ending) => file.EndsWith(ending, StringComparison.CurrentCultureIgnoreCase))
select file).ToArray();
byte[] bytes = Encoding.ASCII.GetBytes("UnityFS");
List<string> list = new List<string>();
string[] array2 = array;
foreach (string text in array2)
{
byte[] array3 = new byte[bytes.Length];
using (FileStream fileStream = File.Open(text, FileMode.Open))
{
fileStream.Read(array3, 0, array3.Length);
}
if (array3.SequenceEqual(bytes))
{
list.Add(text);
}
}
array = list.ToArray();
if (array.Length == 0)
{
Plugin.Log.LogMessage((object)"BundleAPI got no assets to load from plugins folder");
}
else
{
LoadAllAssetsFromDirectory(array, legacyLoading);
}
OnLoadedAssets.InvokeParameterlessDelegate();
BundleLoader.OnLoadedBundles.InvokeActionSafe();
}
private static void LoadAllAssetsFromDirectory(string[] array, bool legacyLoading)
{
if (legacyLoading)
{
Plugin.Log.LogMessage((object)("BundleAPI got " + array.Length + " AssetBundles to load!"));
for (int i = 0; i < array.Length; i++)
{
try
{
SaveAsset(array[i], legacyLoading);
}
catch (Exception)
{
Plugin.Log.LogError((object)("Failed to load an assetbundle! Path: " + array[i]));
}
}
return;
}
Plugin.Log.LogMessage((object)("BundleAPI got " + array.Length + " AssetBundles to load!"));
for (int j = 0; j < array.Length; j++)
{
try
{
SaveAsset(array[j], legacyLoading);
}
catch (Exception)
{
Plugin.Log.LogError((object)("Failed to load an assetbundle! Path: " + array[j]));
}
}
}
public static void SaveAsset(string path, bool legacyLoad)
{
AssetBundle val = AssetBundle.LoadFromFile(path);
try
{
string[] allAssetNames = val.GetAllAssetNames();
foreach (string text in allAssetNames)
{
Plugin.Log.LogMessage((object)("Got asset for load: " + text));
Object val2 = val.LoadAsset(text);
if (val2 == (Object)null)
{
Plugin.Log.LogWarning((object)$"Skipped/failed loading an asset (from bundle '{((Object)val).name}') - Asset path: {val2}");
continue;
}
string key = (legacyLoad ? text.ToUpper() : text.ToLower());
if (assets.ContainsKey(key))
{
Plugin.Log.LogError((object)"BundleAPI got duplicate asset!");
break;
}
assets.TryAdd(key, val2);
Plugin.Log.LogMessage((object)("Loaded asset: " + val2.name));
}
}
finally
{
if (val != null)
{
val.Unload(false);
}
}
}
public static TAsset GetLoadedAsset<TAsset>(string itemPath) where TAsset : Object
{
Object value = null;
if (LegacyLoadingEnabled)
{
assets.TryGetValue(itemPath.ToUpper(), out value);
}
if (value == (Object)null)
{
assets.TryGetValue(itemPath.ToLower(), out value);
}
return (TAsset)(object)value;
}
private static void LoadAssetsCompleted()
{
Plugin.Log.LogMessage((object)"BundleAPI finished loading all assets.");
}
static BundleLoader()
{
BundleLoader.OnLoadedBundles = LoadAssetsCompleted;
}
}
}