using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using FastStartup;
using FastStartup.TimeSavers;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("FastStartup")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: AssemblyCompany("NoteBoxz.DevStart")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+eb5f19b6899da03b3582da56251fd3b59c437d64")]
[assembly: AssemblyProduct("NotezDevStart")]
[assembly: AssemblyTitle("NoteBoxz.DevStart")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 NotezDevStart
{
[BepInPlugin("NoteBoxz.DevStart", "NotezDevStart", "1.0.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class NotezDevStart : BaseUnityPlugin
{
public static bool autoJoinLan;
public static bool autoPullLever;
public static bool tpToEntrance;
public static bool teleportInside;
public static bool forceLANmode;
public static int playersRequired;
internal static bool IsHostInstance;
public static readonly string TempFolderPath = Path.Combine(Path.GetTempPath(), "NotezDevStart");
public static readonly string HostReadySignalPath = Path.Combine(TempFolderPath, "HostStarted");
public static NotezDevStart Instance { get; private set; } = null;
internal static ManualLogSource Logger { get; private set; } = null;
internal static Harmony? Harmony { get; set; }
private static Mutex? AppMutex { get; set; }
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
Instance = this;
Patch();
ConfigFile();
IsHostInstance = !autoJoinLan || !CheckMutex();
if (IsHostInstance)
{
SetupTempFolder();
}
Logger.LogInfo((object)"NoteBoxz.DevStart v1.0.2 has loaded!");
}
private void ConfigFile()
{
forceLANmode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ForceLANMode", true, "Force LAN mode on startup. (even if fast startup is installed)").Value;
autoJoinLan = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoJoinLAN", true, "Automatically join LAN lobbies when game is launched more than once.").Value;
playersRequired = ((BaseUnityPlugin)this).Config.Bind<int>("General", "PlayersRequired", 2, "Number of players required to start the game. (including the host)").Value;
autoPullLever = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoPullLever", false, "Automatically pull the ship's lever on startup.").Value;
tpToEntrance = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "TeleportToEntrance", false, "Automatically teleports you to the main entrance on level load (Requires 'AutoPullLever' enabled).").Value;
teleportInside = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "TeleportInside", false, "Teleports you inside the facility instead (Requires 'TeleportToEntrance' enabled).").Value;
}
private static string CensorPath(string path)
{
try
{
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
if (!string.IsNullOrEmpty(folderPath) && path.StartsWith(folderPath, StringComparison.OrdinalIgnoreCase))
{
string text = path.Substring(folderPath.Length);
string directoryName = Path.GetDirectoryName(folderPath);
return Path.Combine(directoryName, "(USER)", text.TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
}
return path;
}
catch
{
return path;
}
}
private void SetupTempFolder()
{
try
{
if (Directory.Exists(TempFolderPath))
{
string[] files = Directory.GetFiles(TempFolderPath);
foreach (string path in files)
{
try
{
File.Delete(path);
}
catch
{
}
}
}
else
{
Directory.CreateDirectory(TempFolderPath);
}
Logger.LogDebug((object)("Temp folder setup at: " + CensorPath(TempFolderPath)));
}
catch (Exception ex)
{
Logger.LogError((object)("Failed to setup temp folder: " + ex.Message));
}
}
internal static bool CheckMutex()
{
try
{
if (AppMutex == null)
{
AppMutex = new Mutex(initiallyOwned: true, "LethalCompany-NotezDevStart");
}
return AppMutex != null && !AppMutex.WaitOne(TimeSpan.Zero, exitContext: true);
}
catch
{
return false;
}
}
internal static void Patch()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Expected O, but got Unknown
if (Harmony == null)
{
Harmony = new Harmony("NoteBoxz.DevStart");
}
Logger.LogDebug((object)"Patching...");
Type[] typesWithErrorHandling = GetTypesWithErrorHandling();
Type[] array = typesWithErrorHandling;
foreach (Type type in array)
{
try
{
Harmony.PatchAll(type);
}
catch (Exception ex)
{
Logger.LogError((object)("Error patching type " + type.FullName + ": " + ex.Message));
if (ex.InnerException != null)
{
Logger.LogError((object)("Inner exception: " + ex.InnerException.Message));
}
}
}
Logger.LogDebug((object)"Finished patching!");
}
private static Type[] GetTypesWithErrorHandling()
{
try
{
return Assembly.GetExecutingAssembly().GetTypes();
}
catch (ReflectionTypeLoadException ex)
{
Logger.LogWarning((object)"ReflectionTypeLoadException caught while getting types. Some types will be skipped.");
Exception[] loaderExceptions = ex.LoaderExceptions;
foreach (Exception ex2 in loaderExceptions)
{
Logger.LogWarning((object)("Loader Exception: " + ex2.Message));
if (ex2 is FileNotFoundException ex3)
{
Logger.LogWarning((object)("Could not load file: " + ex3.FileName));
}
}
return ex.Types.Where((Type t) => t != null).ToArray();
}
catch (Exception ex4)
{
Logger.LogError((object)("Unexpected error while getting types: " + ex4.Message));
return new Type[0];
}
}
internal static void Unpatch()
{
Logger.LogDebug((object)"Unpatching...");
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
Logger.LogDebug((object)"Finished unpatching!");
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "NoteBoxz.DevStart";
public const string PLUGIN_NAME = "NotezDevStart";
public const string PLUGIN_VERSION = "1.0.2";
}
}
namespace NotezDevStart.Patches
{
[HarmonyPatch(typeof(IngamePlayerSettings))]
internal class IngamePlayerSettingsPatch
{
[HarmonyPostfix]
[HarmonyPatch("Awake")]
private static void AwakePatch(IngamePlayerSettings __instance)
{
NotezDevStart.Logger.LogMessage((object)"Loading settings from prefs before the game loads default settings");
__instance.LoadSettingsFromPrefs();
__instance.UpdateGameToMatchSettings();
}
}
[HarmonyPatch(typeof(LaunchOptionsSaver))]
internal class LaunchOptionsSaverPatch
{
[HarmonyPrefix]
[HarmonyPatch("Start")]
internal static bool Start()
{
if (!Plugin.Config.SkipLaunchMode.Value)
{
return true;
}
if (LaunchOptionsSaver.HasRan)
{
return true;
}
if (!NotezDevStart.forceLANmode)
{
return true;
}
SceneManager.LoadScene("InitSceneLANMode");
return false;
}
}
[HarmonyPatch(typeof(MenuManager))]
internal class MenuManagerPatch
{
[CompilerGenerated]
private sealed class <WaitForHostAndJoin>d__3 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public MenuManager __instance;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitForHostAndJoin>d__3(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
NotezDevStart.Logger.LogInfo((object)"Waiting for host to be ready...");
<>2__current = (object)new WaitUntil((Func<bool>)(() => File.Exists(NotezDevStart.HostReadySignalPath)));
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
NotezDevStart.Logger.LogInfo((object)"Host is ready, joining the game...");
__instance.StartAClient();
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static bool firstTimeLoad = true;
[HarmonyPostfix]
[HarmonyPatch("OnEnable")]
public static void OnEnablePatch(MenuManager __instance)
{
if (firstTimeLoad)
{
if ((Object)(object)__instance.menuButtons != (Object)null && ((Object)__instance.menuButtons).name == "MainButtons")
{
NotezDevStart.Logger.LogInfo((object)"MenuManager.OnEnablePatch() called - MainButtons");
JumpInGame(__instance);
}
else
{
NotezDevStart.Logger.LogInfo((object)"MenuManager.OnEnablePatch() called - not MainButtons");
}
}
}
private static void JumpInGame(MenuManager __instance)
{
if (!Chainloader.PluginInfos.ContainsKey("dev.flero.lethal.FastStartup") && (Object)(object)__instance.lanWarningContainer != (Object)null)
{
Object.Destroy((Object)(object)__instance.lanWarningContainer);
}
if (NotezDevStart.IsHostInstance)
{
__instance.lobbyNameInputField.text = "Placeholder";
__instance.ConfirmHostButton();
__instance.lobbyNameInputField.text = "";
}
else
{
((MonoBehaviour)__instance).StartCoroutine(WaitForHostAndJoin(__instance));
}
firstTimeLoad = false;
}
[IteratorStateMachine(typeof(<WaitForHostAndJoin>d__3))]
private static IEnumerator WaitForHostAndJoin(MenuManager __instance)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForHostAndJoin>d__3(0)
{
__instance = __instance
};
}
}
[HarmonyPatch(typeof(PreInitSceneScript))]
public static class PreInitSceneScriptPatch
{
[HarmonyPrefix]
[HarmonyPatch("SkipToFinalSetting")]
public static bool SkipToFinalSetting(PreInitSceneScript __instance)
{
if (Chainloader.PluginInfos.ContainsKey("dev.flero.lethal.FastStartup"))
{
NotezDevStart.Logger.LogInfo((object)"FastStartup is installed, skipping final setting patch.");
return true;
}
if (!NotezDevStart.forceLANmode)
{
return true;
}
__instance.launchSettingsPanelsContainer.SetActive(false);
SceneManager.LoadScene("InitSceneLANMode");
return false;
}
}
[HarmonyPatch(typeof(StartMatchLever))]
internal class StartMatchLeverPatch
{
[CompilerGenerated]
private sealed class <WaitForPlayersToPullLever>d__2 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public StartMatchLever __instance;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitForPlayersToPullLever>d__2(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
NotezDevStart.Logger.LogInfo((object)"Waiting to pull Ship Lever");
<>2__current = (object)new WaitUntil((Func<bool>)(() => StartOfRound.Instance.connectedPlayersAmount + 1 >= NotezDevStart.playersRequired));
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
NotezDevStart.Logger.LogInfo((object)"Ship Lever pulled");
hasPulledLever = true;
__instance.leverHasBeenPulled = true;
__instance.leverAnimatorObject.SetBool("pullLever", true);
__instance.triggerScript.interactable = false;
__instance.PullLever();
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static bool hasPulledLever;
[HarmonyPatch("Start")]
[HarmonyPostfix]
public static void StartPatch(StartMatchLever __instance)
{
if (NotezDevStart.autoPullLever && !hasPulledLever)
{
((MonoBehaviour)__instance).StartCoroutine(WaitForPlayersToPullLever(__instance));
}
}
[IteratorStateMachine(typeof(<WaitForPlayersToPullLever>d__2))]
public static IEnumerator WaitForPlayersToPullLever(StartMatchLever __instance)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForPlayersToPullLever>d__2(0)
{
__instance = __instance
};
}
}
[HarmonyPatch(typeof(StartOfRound))]
internal class StartOfRoundPatch
{
private static bool attemptedTp;
[HarmonyPatch("TeleportPlayerInShipIfOutOfRoomBounds")]
[HarmonyPostfix]
public static void TeleportPlayerInShipIfOutOfRoomBoundsStats(StartOfRound __instance)
{
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
if (NotezDevStart.tpToEntrance && !attemptedTp && __instance.shipDoorsEnabled)
{
NotezDevStart.Logger.LogInfo((object)"Teleporting to entrance...");
MethodInfo methodInfo = AccessTools.Method(typeof(RoundManager), "FindMainEntranceScript", (Type[])null, (Type[])null);
EntranceTeleport val = (EntranceTeleport)methodInfo.Invoke(null, new object[1] { NotezDevStart.teleportInside });
if ((Object)(object)val != (Object)null)
{
val.TeleportPlayer();
NotezDevStart.Logger.LogInfo((object)"Player teleported to entrance");
}
else
{
NotezDevStart.Logger.LogError((object)"Failed to find entrance");
}
attemptedTp = true;
}
}
[HarmonyPatch("Start")]
[HarmonyPostfix]
public static void StartPostfix(StartOfRound __instance)
{
if (NotezDevStart.IsHostInstance)
{
NotezDevStart.Logger.LogInfo((object)"Host instance is ready, creating signal file...");
try
{
File.WriteAllText(NotezDevStart.HostReadySignalPath, DateTime.Now.ToString());
NotezDevStart.Logger.LogInfo((object)"Host signal file created successfully");
}
catch (Exception ex)
{
NotezDevStart.Logger.LogError((object)("Failed to create host signal file: " + ex.Message));
}
}
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}