using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using MKCConfig.Modules;
using MKCOptions;
using RandomMoonModule;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("TeleportOnStart")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TeleportOnStart")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("cab8e5d2-d03f-45d6-87ae-c4c178e7df7e")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("MrKixcat.MKCConfig", "MKCConfig", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public static Plugin Instance;
public static Config ConfigInstance;
private void Awake()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Expected O, but got Unknown
ConfigInstance = new Config(((BaseUnityPlugin)this).Config);
if ((Object)(object)Instance == (Object)null)
{
Instance = this;
}
Harmony val = new Harmony("MrKixcat.MKCConfig");
val.PatchAll(Assembly.GetExecutingAssembly());
Debug.Log((object)"MKCConfig initialized!");
}
}
public class ScrapReporterModule : MonoBehaviour
{
[CompilerGenerated]
private sealed class <DelayedReport>d__7 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public ScrapReporterModule <>4__this;
private (int interior, int exterior) <counts>5__1;
private string <msg>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DelayedReport>d__7(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<msg>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(<>4__this.delaySeconds);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (!HasReported)
{
HasReported = true;
<counts>5__1 = ScanScrapInScene();
<msg>5__2 = $"Début de round ! Scrap : Intérieur = {<counts>5__1.interior}, Extérieur = {<counts>5__1.exterior}";
SendChatMessage(<msg>5__2);
Object.Destroy((Object)(object)((Component)<>4__this).gameObject);
<msg>5__2 = null;
}
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 ManualLogSource Logger;
private float delaySeconds = 1f;
private static bool HasReported;
public void Init(ManualLogSource logger, float delay = 1f)
{
Logger = logger;
delaySeconds = delay;
}
public static (int interior, int exterior) ScanScrapInScene()
{
int num = 0;
int num2 = 0;
GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
GrabbableObject[] array2 = array;
foreach (GrabbableObject val in array2)
{
if (!((Object)(object)val == (Object)null) && val.itemProperties.isScrap && !val.isInShipRoom)
{
if (val.isInFactory && !val.itemProperties.itemName.Equals("Hive") && !val.itemProperties.itemName.Equals("Egg"))
{
num++;
}
else
{
num2++;
}
}
}
return (num, num2);
}
public static void SendChatMessage(string message)
{
HUDManager instance = HUDManager.Instance;
PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null || ((Object)TimeOfDay.Instance.currentLevel).name.Equals("CompanyBuildingLevel"))
{
Debug.LogWarning((object)"[ScrapReporter] Cannot send message, HUD or player null.");
}
else
{
instance.AddTextToChatOnServer(message, -1);
}
}
public void StartScrapReport()
{
((MonoBehaviour)this).StartCoroutine(DelayedReport());
}
[IteratorStateMachine(typeof(<DelayedReport>d__7))]
public IEnumerator DelayedReport()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DelayedReport>d__7(0)
{
<>4__this = this
};
}
public static void ResetReportFlag()
{
HasReported = false;
}
}
namespace MKCConfig.Modules
{
public class TeleportModule : NetworkBehaviour
{
[CompilerGenerated]
private sealed class <TeleportAllPlayersCoroutine>d__2 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public TeleportModule <>4__this;
private float <configDelay>5__1;
private RoundManager <rm>5__2;
private GameObject[] <nodes>5__3;
private PlayerControllerB[] <>s__4;
private int <>s__5;
private PlayerControllerB <player>5__6;
private int <randomIndex>5__7;
private Transform <randomNode>5__8;
private Vector3 <pos>5__9;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <TeleportAllPlayersCoroutine>d__2(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<rm>5__2 = null;
<nodes>5__3 = null;
<>s__4 = null;
<player>5__6 = null;
<randomNode>5__8 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Expected O, but got Unknown
//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0202: Unknown result type (might be due to invalid IL or missing references)
//IL_0204: Unknown result type (might be due to invalid IL or missing references)
//IL_0209: Unknown result type (might be due to invalid IL or missing references)
//IL_020f: Unknown result type (might be due to invalid IL or missing references)
//IL_0214: Unknown result type (might be due to invalid IL or missing references)
//IL_0237: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if (HasTeleported)
{
return false;
}
HasTeleported = true;
if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsHost)
{
return false;
}
<configDelay>5__1 = (float)Config.TeleportDelay.Value / 1000f;
if (<configDelay>5__1 > 0f)
{
<>2__current = (object)new WaitForSeconds(<configDelay>5__1);
<>1__state = 1;
return true;
}
break;
case 1:
<>1__state = -1;
break;
}
<rm>5__2 = RoundManager.Instance;
if ((Object)(object)<rm>5__2 == (Object)null)
{
Debug.LogError((object)"[TeleportModule] RoundManager is null. Cannot teleport.");
return false;
}
<nodes>5__3 = <rm>5__2.insideAINodes;
if (<nodes>5__3 == null || <nodes>5__3.Length == 0)
{
Debug.LogError((object)"[TeleportModule] No inside AI nodes found (Array is empty).");
return false;
}
if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null)
{
return false;
}
<>s__4 = StartOfRound.Instance.allPlayerScripts;
for (<>s__5 = 0; <>s__5 < <>s__4.Length; <>s__5++)
{
<player>5__6 = <>s__4[<>s__5];
if (!((Object)(object)<player>5__6 == (Object)null) && !<player>5__6.isPlayerDead && !(<player>5__6.playerUsername == ""))
{
<randomIndex>5__7 = Random.Range(0, <nodes>5__3.Length);
if (!((Object)(object)<nodes>5__3[<randomIndex>5__7] == (Object)null))
{
<randomNode>5__8 = <nodes>5__3[<randomIndex>5__7].transform;
<pos>5__9 = <rm>5__2.GetRandomNavMeshPositionInRadius(<randomNode>5__8.position, 15f, default(NavMeshHit));
if (<pos>5__9 != Vector3.zero)
{
<>4__this.TeleportClientRpc(<player>5__6.playerClientId, <pos>5__9);
}
else
{
Debug.LogWarning((object)("[TeleportModule] Could not find valid NavMesh position for player " + <player>5__6.playerUsername + "."));
}
<randomNode>5__8 = null;
<player>5__6 = null;
}
}
}
<>s__4 = null;
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();
}
}
public static TeleportModule Instance;
public static bool HasTeleported;
[IteratorStateMachine(typeof(<TeleportAllPlayersCoroutine>d__2))]
public IEnumerator TeleportAllPlayersCoroutine()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <TeleportAllPlayersCoroutine>d__2(0)
{
<>4__this = this
};
}
private void PerformTeleport(PlayerControllerB player, Vector3 pos)
{
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Invalid comparison between Unknown and I4
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Expected I4, but got Unknown
if ((Object)(object)player == (Object)null)
{
return;
}
Terminal val = Object.FindObjectOfType<Terminal>();
if ((Object)(object)val != (Object)null && val.terminalInUse && player.inTerminalMenu)
{
val.QuitTerminal(true);
}
if (((NetworkBehaviour)player).IsOwner && (Object)(object)HUDManager.Instance != (Object)null)
{
HUDManager.Instance.ShakeCamera((ScreenShakeType)1);
}
player.TeleportPlayer(pos, false, 0f, true, true);
player.isInsideFactory = true;
player.isInElevator = false;
player.isInHangarShipRoom = false;
player.velocityLastFrame = Vector3.zero;
if ((Object)(object)TimeOfDay.Instance != (Object)null && (int)TimeOfDay.Instance.currentLevelWeather != -1)
{
int num = (int)TimeOfDay.Instance.currentLevelWeather;
if (num >= 0 && num < TimeOfDay.Instance.effects.Length)
{
TimeOfDay.Instance.effects[num].effectEnabled = false;
}
}
}
[ClientRpc]
public void TeleportClientRpc(ulong clientId, Vector3 pos)
{
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)StartOfRound.Instance == (Object)null))
{
PlayerControllerB val = ((IEnumerable<PlayerControllerB>)StartOfRound.Instance.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB p) => p.playerClientId == clientId));
if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).IsOwner)
{
PerformTeleport(val, pos);
}
}
}
public static void ResetTeleportedFlag()
{
HasTeleported = false;
}
}
}
namespace MKCConfig.Patches
{
[HarmonyPatch(typeof(StartOfRound))]
internal class MasterPatch_RandomMoon
{
[HarmonyPrefix]
[HarmonyPatch("StartGame")]
private static void Prefix_StartGame()
{
if (!((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.IsHost && Config.EnableRandomMoon.Value)
{
RandomMoonRouter.ResetStartedFlag();
Debug.Log((object)"[RandomMoon] Routing to a random moon");
RandomMoonRouter.RouteToRandomPlanet();
}
}
}
[HarmonyPatch(typeof(StartOfRound))]
internal class MasterPatch_ScrapReporter
{
[HarmonyPostfix]
[HarmonyPatch("openingDoorsSequence")]
private static void Postfix_LevelGenerated()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Expected O, but got Unknown
if (!((Object)(object)NetworkManager.Singleton == (Object)null) && NetworkManager.Singleton.IsHost && Config.EnableScrapReporter.Value)
{
ScrapReporterModule.ResetReportFlag();
GameObject val = new GameObject("ScrapReporter");
ScrapReporterModule scrapReporterModule = val.AddComponent<ScrapReporterModule>();
scrapReporterModule.Init(null, 2f);
((MonoBehaviour)scrapReporterModule).StartCoroutine(scrapReporterModule.DelayedReport());
}
}
}
[HarmonyPatch(typeof(StartOfRound))]
internal class MasterPatch_Teleport
{
[CompilerGenerated]
private sealed class <WaitForDoorsThenTeleport>d__1 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
private float <timeOut>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitForDoorsThenTeleport>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if ((Object)(object)StartOfRound.Instance == (Object)null)
{
return false;
}
Debug.Log((object)"[Teleport] Waiting for ship doors to open...");
<timeOut>5__1 = 10f;
break;
case 1:
<>1__state = -1;
break;
}
if ((Object)(object)StartOfRound.Instance != (Object)null && !StartOfRound.Instance.shipDoorsEnabled && <timeOut>5__1 > 0f)
{
<timeOut>5__1 -= Time.deltaTime;
<>2__current = null;
<>1__state = 1;
return true;
}
if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)TeleportModule.Instance == (Object)null)
{
return false;
}
Debug.Log((object)"[Teleport] Ship doors open (or timeout). Teleporting players...");
((MonoBehaviour)TeleportModule.Instance).StartCoroutine(TeleportModule.Instance.TeleportAllPlayersCoroutine());
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();
}
}
[HarmonyPostfix]
[HarmonyPatch("SceneManager_OnLoadComplete1")]
private static void Postfix_SceneLoad()
{
if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)TimeOfDay.Instance == (Object)null || !Config.EnableTeleport.Value || (Object)(object)TimeOfDay.Instance.currentLevel == (Object)null || ((Object)TimeOfDay.Instance.currentLevel).name.Equals("CompanyBuildingLevel"))
{
return;
}
TeleportModule.ResetTeleportedFlag();
if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsHost && !((Object)(object)((Component)StartOfRound.Instance).gameObject == (Object)null))
{
if ((Object)(object)TeleportModule.Instance == (Object)null)
{
TeleportModule.Instance = ((Component)StartOfRound.Instance).gameObject.AddComponent<TeleportModule>();
}
((MonoBehaviour)TeleportModule.Instance).StartCoroutine(WaitForDoorsThenTeleport());
}
}
[IteratorStateMachine(typeof(<WaitForDoorsThenTeleport>d__1))]
private static IEnumerator WaitForDoorsThenTeleport()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitForDoorsThenTeleport>d__1(0);
}
}
}
namespace RandomMoonModule
{
public static class RandomMoonRouter
{
public static bool HasStarted = false;
public static string MoonBlacklistStr = Config.MoonBlacklist.Value;
private static List<string> MoonBlacklist = new List<string>();
private static void SetupBlacklist()
{
MoonBlacklist.Clear();
if (!string.IsNullOrEmpty(MoonBlacklistStr))
{
MoonBlacklist = (from s in MoonBlacklistStr.Split(new char[1] { ',' })
select s.Trim().ToLowerInvariant()).ToList();
}
}
public static void RouteToRandomPlanet()
{
if (HasStarted || (Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsHost)
{
return;
}
SetupBlacklist();
if (TimeOfDay.Instance.daysUntilDeadline == 0 && TimeOfDay.Instance.profitQuota > TimeOfDay.Instance.quotaFulfilled)
{
StartOfRound.Instance.ChangeLevel(3);
StartOfRound.Instance.ArriveAtLevel();
HasStarted = true;
return;
}
List<SelectableLevel> source = StartOfRound.Instance.levels.ToList();
List<SelectableLevel> list = source.Where((SelectableLevel m) => !MoonBlacklist.Contains(((Object)m).name.Trim().ToLowerInvariant()) && ((Object)m).name != ((Object)TimeOfDay.Instance.currentLevel).name).ToList();
if (list.Count == 0)
{
list = source.Where((SelectableLevel m) => ((Object)m).name != ((Object)TimeOfDay.Instance.currentLevel).name).ToList();
}
SelectableLevel val = list[Random.Range(0, list.Count)];
StartOfRound.Instance.ChangeLevel(val.levelID);
StartOfRound.Instance.ArriveAtLevel();
HasStarted = true;
Debug.Log((object)("[RandomMoonModule] Routed to moon " + ((Object)val).name + "."));
}
public static void ResetStartedFlag()
{
HasStarted = false;
}
}
}
namespace MKCOptions
{
public class Config
{
public static ConfigEntry<bool> EnableTeleport;
public static ConfigEntry<int> TeleportDelay;
public static ConfigEntry<bool> EnableScrapReporter;
public static ConfigEntry<bool> EnableRandomMoon;
public static ConfigEntry<string> MoonBlacklist;
public static ConfigEntry<bool> EnableClientLever;
public Config(ConfigFile config)
{
EnableTeleport = config.Bind<bool>("TeleportOnStart", "Enable Teleport", true, "Teleport all players when a round starts.");
TeleportDelay = config.Bind<int>("TeleportOnStart", "Teleport Delay", 0, "Delay before being teleported (ms)");
EnableScrapReporter = config.Bind<bool>("ScrapReporter", "Enable Scrap Reporter", true, "Scan inside/outside scrap and send results in chat at round start.");
EnableRandomMoon = config.Bind<bool>("RandomMoon", "Enable Random Moon", true, "Pick a random moon automatically when the ship starts.");
MoonBlacklist = config.Bind<string>("RandomMoon", "Moon Blacklist", "CompanyBuildingLevel,LiquidationLevel", "Comma-separated list of moons to exclude.");
EnableClientLever = config.Bind<bool>("ShipLever", "Enable Client Ship Lever", true, "Permet aux clients (non-hôtes) d'utiliser le levier de décollage du vaisseau.");
}
}
}