using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using IKEASimulator_Fixer.Patches;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
[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("")]
[assembly: AssemblyCompany("sasnews")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+0b87d15f3ef4e643400cec9f0e8e83de13e340b0")]
[assembly: AssemblyProduct("IKEASimulator_Fixer")]
[assembly: AssemblyTitle("IKEASimulator_Fixer")]
[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.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 IKEASimulator_Fixer
{
[HarmonyPatch(typeof(PlayerController))]
internal static class ExamplePlayerControllerPatch
{
[HarmonyPrefix]
[HarmonyPatch("Start")]
private static void Start_Prefix(PlayerController __instance)
{
IKEASimulator_Fixer.Logger.LogDebug((object)$"{__instance} Start Prefix");
}
[HarmonyPostfix]
[HarmonyPatch("Start")]
private static void Start_Postfix(PlayerController __instance)
{
IKEASimulator_Fixer.Logger.LogDebug((object)$"{__instance} Start Postfix");
}
}
[BepInPlugin("sasnews.IKEASimulator_Fixer", "IKEASimulator_Fixer", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class IKEASimulator_Fixer : BaseUnityPlugin
{
public const string PluginGUID = "sasnews.IKEASimulator_Fixer";
public const string PluginName = "IKEASimulator_Fixer";
public const string PluginVersion = "1.0.0";
private static bool _ikeaPatched;
internal static IKEASimulator_Fixer Instance { get; private set; }
internal static ManualLogSource Logger => Instance._logger;
private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;
internal Harmony? Harmony { get; private set; }
public static ConfigEntry<bool> EnableImmediatePhysics { get; private set; }
private void Awake()
{
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Expected O, but got Unknown
Instance = this;
((Component)this).gameObject.transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
EnableImmediatePhysics = ((BaseUnityPlugin)this).Config.Bind<bool>("Physics", "EnableImmediatePhysics", false, "true: オブジェクトがスポーン直後から落下する\nfalse: つかむまで固定される(デフォルト)");
EnableImmediatePhysics.SettingChanged += OnImmediatePhysicsSettingChanged;
Logger.LogInfo((object)"=================================================");
Logger.LogInfo((object)"IKEASimulator_Fixer v1.0.0");
Logger.LogInfo((object)"REPOLib 3.x Compatibility Patch");
Logger.LogInfo((object)$"EnableImmediatePhysics: {EnableImmediatePhysics.Value}");
Logger.LogInfo((object)"=================================================");
Harmony = new Harmony("sasnews.IKEASimulator_Fixer");
AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad;
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
if (assembly.GetName().Name == "IKEASimulator")
{
Logger.LogWarning((object)"IKEASimulator already loaded - attempting late patch");
ApplyIKEAPatches(assembly);
break;
}
}
Logger.LogInfo((object)"Waiting for IKEASimulator to load...");
Logger.LogInfo((object)"=================================================");
}
private void OnAssemblyLoad(object? sender, AssemblyLoadEventArgs args)
{
if (args.LoadedAssembly.GetName().Name == "IKEASimulator")
{
Logger.LogInfo((object)"=================================================");
Logger.LogInfo((object)"→ IKEASimulator.dll detected loading!");
Logger.LogInfo((object)"=================================================");
ApplyIKEAPatches(args.LoadedAssembly);
}
}
private void ApplyIKEAPatches(Assembly ikeaAssembly)
{
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Expected O, but got Unknown
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Expected O, but got Unknown
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Expected O, but got Unknown
if (_ikeaPatched)
{
Logger.LogInfo((object)"(Patches already applied)");
return;
}
try
{
Type type = ikeaAssembly.GetType("IKEASimulator.IKEASimulator");
if (type == null)
{
Logger.LogError((object)"Could not find IKEASimulator.IKEASimulator type!");
return;
}
Logger.LogInfo((object)"Applying critical patches BEFORE Awake executes...");
MethodInfo methodInfo = AccessTools.Method(type, "Awake", (Type[])null, (Type[])null);
if (methodInfo != null)
{
HarmonyMethod val = new HarmonyMethod(typeof(IKEACriticalPatches), "Awake_Prefix", (Type[])null);
Harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ IKEASimulator.Awake → COMPLETE TAKEOVER");
}
else
{
Logger.LogError((object)" ✗ Could not find Awake method!");
}
MethodInfo methodInfo2 = AccessTools.Method(type, "Start", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
HarmonyMethod val2 = new HarmonyMethod(typeof(IKEACriticalPatches), "Start_Prefix", (Type[])null);
Harmony.Patch((MethodBase)methodInfo2, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ IKEASimulator.Start → COMPLETE TAKEOVER");
}
MethodInfo methodInfo3 = AccessTools.Method(type, "Patch", (Type[])null, (Type[])null);
if (methodInfo3 != null)
{
HarmonyMethod val3 = new HarmonyMethod(typeof(IKEACriticalPatches), "Patch_Prefix", (Type[])null);
Harmony.Patch((MethodBase)methodInfo3, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ IKEASimulator.Patch → BLOCKED (IL incompatible patches)");
}
ApplyNetworkManagerPatches(ikeaAssembly);
ApplySafetyPatches();
_ikeaPatched = true;
Logger.LogInfo((object)"=================================================");
Logger.LogInfo((object)"✓ All critical patches applied successfully!");
Logger.LogInfo((object)"=================================================");
}
catch (Exception arg)
{
Logger.LogError((object)$"Failed to apply patches: {arg}");
}
}
private void ApplyNetworkManagerPatches(Assembly ikeaAssembly)
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Expected O, but got Unknown
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Expected O, but got Unknown
try
{
Type type = ikeaAssembly.GetType("IKEASimulator.NetworkManager");
if (type == null)
{
Logger.LogWarning((object)" NetworkManager type not found - skipping NM patches");
return;
}
MethodInfo methodInfo = AccessTools.Method(type, "OnCreatedRoom", (Type[])null, (Type[])null);
if (methodInfo != null)
{
HarmonyMethod val = new HarmonyMethod(typeof(NetworkManagerPatches), "OnCreatedRoom_Prefix", (Type[])null);
Harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ NetworkManager.OnCreatedRoom → Fixed");
}
MethodInfo methodInfo2 = AccessTools.Method(type, "SingleplayerRoomData", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
HarmonyMethod val2 = new HarmonyMethod(typeof(NetworkManagerPatches), "SingleplayerRoomData_Prefix", (Type[])null);
Harmony.Patch((MethodBase)methodInfo2, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ NetworkManager.SingleplayerRoomData → Fixed");
}
}
catch (Exception ex)
{
Logger.LogWarning((object)(" NetworkManager patches partially failed: " + ex.Message));
}
}
private void ApplySafetyPatches()
{
try
{
ClientRoomDataPatches.ApplyPatches(Harmony);
PathMapperPatches.ApplyPatches(Harmony);
FurnitureConversionPatches.ApplyPatches(Harmony);
DestructionSafetyPatches.ApplyPatches(Harmony);
Harmony.CreateClassProcessor(typeof(ModuleSafetyPatch)).Patch();
Logger.LogInfo((object)" ✓ Module.Start safety finalizer");
Harmony.CreateClassProcessor(typeof(LevelGeneratorSafetyPatch)).Patch();
Logger.LogInfo((object)" ✓ LevelGenerator.ModuleGeneration safety finalizer");
}
catch (Exception ex)
{
Logger.LogWarning((object)("Safety patches partially failed: " + ex.Message));
}
}
private void OnDestroy()
{
AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad;
EnableImmediatePhysics.SettingChanged -= OnImmediatePhysicsSettingChanged;
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void OnImmediatePhysicsSettingChanged(object? sender, EventArgs e)
{
if (!EnableImmediatePhysics.Value)
{
Logger.LogInfo((object)"EnableImmediatePhysics disabled - new objects will be fixed until grabbed");
return;
}
Logger.LogInfo((object)"EnableImmediatePhysics enabled - enabling physics on all existing objects...");
try
{
Type type = AccessTools.TypeByName("IKEASimulator.PropsParenting");
if (type == null)
{
return;
}
FieldInfo fieldInfo = AccessTools.Field(type, "allowMovement");
if (!(fieldInfo == null))
{
Object[] array = Object.FindObjectsOfType(type);
int num = 0;
Object[] array2 = array;
foreach (Object obj in array2)
{
fieldInfo.SetValue(obj, true);
num++;
}
Logger.LogInfo((object)$" ✓ Enabled physics on {num} objects");
}
}
catch (Exception ex)
{
Logger.LogWarning((object)("Failed to enable physics on existing objects: " + ex.Message));
}
}
}
}
namespace IKEASimulator_Fixer.Patches
{
public static class ClientRoomDataPatches
{
private static ManualLogSource Logger => IKEASimulator_Fixer.Logger;
public static void ApplyPatches(Harmony harmony)
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Expected O, but got Unknown
Type type = AccessTools.TypeByName("IKEASimulator.NetworkManager");
if (type != null)
{
MethodInfo methodInfo = AccessTools.Method(type, "OnJoinedRoom", (Type[])null, (Type[])null);
if (methodInfo != null)
{
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(ClientRoomDataPatches), "OnJoinedRoom_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ NetworkManager.OnJoinedRoom → Patched");
}
}
}
public static void OnJoinedRoom_Postfix(object __instance)
{
try
{
Logger.LogInfo((object)"[ClientRoomData] Joined Room. Checking for RoomData...");
MonoBehaviour val = (MonoBehaviour)((__instance is MonoBehaviour) ? __instance : null);
if ((Object)(object)val == (Object)null)
{
return;
}
Type type = __instance.GetType();
FieldInfo fieldInfo = AccessTools.Field(type, "roomData");
object? obj = fieldInfo?.GetValue(__instance);
GameObject val2 = (GameObject)((obj is GameObject) ? obj : null);
if (!((Object)(object)val2 == (Object)null))
{
return;
}
Logger.LogInfo((object)"[ClientRoomData] RoomData missing on Client. Instantiating locally...");
GameObject val3 = null;
string prefabId = "managers/roomdata";
val3 = IKEACriticalPatches.GetPrefab(prefabId);
if ((Object)(object)val3 == (Object)null)
{
foreach (KeyValuePair<string, GameObject> prefab in IKEACriticalPatches.Prefabs)
{
if (prefab.Key.ToLower().Contains("roomdata"))
{
val3 = prefab.Value;
break;
}
}
}
if ((Object)(object)val3 != (Object)null)
{
GameObject val4 = Object.Instantiate<GameObject>(val3);
fieldInfo?.SetValue(__instance, val4);
Logger.LogInfo((object)("[ClientRoomData] RoomData instantiated: " + ((Object)val4).name));
Type type2 = AccessTools.TypeByName("IKEASimulator.PathMapper");
if (type2 != null)
{
Component component = val4.GetComponent(type2);
AccessTools.Property(type, "PathMapper")?.SetValue(__instance, component);
}
}
else
{
Logger.LogError((object)"[ClientRoomData] Failed to find RoomData prefab!");
}
}
catch (Exception arg)
{
Logger.LogError((object)$"OnJoinedRoom_Postfix error: {arg}");
}
}
}
public static class DestructionSafetyPatches
{
private static ManualLogSource Logger => IKEASimulator_Fixer.Logger;
public static void ApplyPatches(Harmony harmony)
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Expected O, but got Unknown
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Expected O, but got Unknown
try
{
Type type = AccessTools.TypeByName("PhysGrabObjectImpactDetector");
if (type != null)
{
MethodInfo methodInfo = AccessTools.Method(type, "BreakRPC", (Type[])null, (Type[])null);
if (methodInfo != null)
{
harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(DestructionSafetyPatches), "BreakRPC_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ PhysGrabObjectImpactDetector.BreakRPC → Patched (Safety Wrapper)");
}
MethodInfo methodInfo2 = AccessTools.Method(type, "DestroyObjectRPC", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(DestructionSafetyPatches), "DestroyObjectRPC_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ PhysGrabObjectImpactDetector.DestroyObjectRPC → Patched (Safety Wrapper)");
}
}
}
catch (Exception arg)
{
Logger.LogError((object)$"DestructionSafetyPatches.ApplyPatches failed: {arg}");
}
}
public static bool BreakRPC_Prefix(object __instance, PhotonMessageInfo _info)
{
try
{
Component val = (Component)((__instance is Component) ? __instance : null);
if ((Object)(object)val == (Object)null)
{
Logger.LogWarning((object)"[Safety] BreakRPC skipped: instance is null or not a Component");
return false;
}
if ((Object)(object)val.gameObject == (Object)null)
{
Logger.LogWarning((object)"[Safety] BreakRPC skipped: gameObject is null");
return false;
}
return true;
}
catch (Exception ex)
{
Logger.LogError((object)("[Safety] BreakRPC_Prefix Error: " + ex.Message));
return false;
}
}
public static bool DestroyObjectRPC_Prefix(object __instance, PhotonMessageInfo _info)
{
try
{
Component val = (Component)((__instance is Component) ? __instance : null);
if ((Object)(object)val == (Object)null)
{
Logger.LogWarning((object)"[Safety] DestroyObjectRPC skipped: instance is null or not a Component");
return false;
}
if ((Object)(object)val.gameObject == (Object)null)
{
Logger.LogWarning((object)"[Safety] DestroyObjectRPC skipped: gameObject is null");
return false;
}
return true;
}
catch (Exception ex)
{
Logger.LogError((object)("[Safety] DestroyObjectRPC_Prefix Error: " + ex.Message));
return false;
}
}
}
public static class FurnitureConversionPatches
{
[CompilerGenerated]
private sealed class <EnableMovementAfterDelay>d__27 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public object propsParenting;
public Type propsParentingType;
private FieldInfo <allowMovementField>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <EnableMovementAfterDelay>d__27(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<allowMovementField>5__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(2f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
try
{
<allowMovementField>5__1 = AccessTools.Field(propsParentingType, "allowMovement");
if (<allowMovementField>5__1 != null)
{
<allowMovementField>5__1.SetValue(propsParenting, true);
}
<allowMovementField>5__1 = null;
}
catch
{
}
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();
}
}
[CompilerGenerated]
private sealed class <RunPrefabSpawning>d__29 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public IEnumerator original;
private List<Action> <spawnActions>5__1;
private int <toSpawn>5__2;
private object <pathMapper>5__3;
private List<Action> <actionsToRun>5__4;
private List<Action>.Enumerator <>s__5;
private Action <action>5__6;
private MethodInfo <clearMethod>5__7;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <RunPrefabSpawning>d__29(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 2)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<spawnActions>5__1 = null;
<pathMapper>5__3 = null;
<actionsToRun>5__4 = null;
<>s__5 = default(List<Action>.Enumerator);
<action>5__6 = null;
<clearMethod>5__7 = null;
<>1__state = -2;
}
private bool MoveNext()
{
try
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
goto IL_005d;
case 1:
<>1__state = -1;
goto IL_005d;
case 2:
{
<>1__state = -3;
<action>5__6 = null;
goto IL_0156;
}
IL_005d:
if (original.MoveNext())
{
<>2__current = original.Current;
<>1__state = 1;
return true;
}
<spawnActions>5__1 = GetSpawnActions();
<toSpawn>5__2 = GetToSpawn();
Logger.LogInfo((object)$"Furniture conversion: {<spawnActions>5__1?.Count ?? 0} actions, ToSpawn: {<toSpawn>5__2}");
if (<spawnActions>5__1 == null || <spawnActions>5__1.Count <= 0)
{
break;
}
<actionsToRun>5__4 = new List<Action>(<spawnActions>5__1);
<spawnActions>5__1.Clear();
<>s__5 = <actionsToRun>5__4.GetEnumerator();
<>1__state = -3;
goto IL_0156;
IL_0156:
if (<>s__5.MoveNext())
{
<action>5__6 = <>s__5.Current;
<action>5__6();
<>2__current = null;
<>1__state = 2;
return true;
}
<>m__Finally1();
<>s__5 = default(List<Action>.Enumerator);
<actionsToRun>5__4 = null;
break;
}
_spawnedField?.SetValue(null, 0);
_toSpawnField?.SetValue(null, 0);
<pathMapper>5__3 = GetPathMapper();
if (<pathMapper>5__3 != null)
{
<clearMethod>5__7 = AccessTools.Method(<pathMapper>5__3.GetType(), "ClearAllPaths", (Type[])null, (Type[])null);
<clearMethod>5__7?.Invoke(<pathMapper>5__3, null);
<clearMethod>5__7 = null;
}
return false;
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
((IDisposable)<>s__5).Dispose();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static FieldInfo? _toSpawnField;
private static FieldInfo? _spawnedField;
private static FieldInfo? _spawnActionsField;
private static FieldInfo? _furnitureLimitField;
private static object? _cachedWrapper;
private static bool _wrapperInitialized;
private static ManualLogSource Logger => IKEASimulator_Fixer.Logger;
public static void ApplyPatches(Harmony harmony)
{
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Expected O, but got Unknown
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f6: Expected O, but got Unknown
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
//IL_0166: Expected O, but got Unknown
//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
//IL_01e2: Expected O, but got Unknown
//IL_0226: Unknown result type (might be due to invalid IL or missing references)
//IL_0233: Expected O, but got Unknown
try
{
Type type = AccessTools.TypeByName("IKEASimulator.IKEASimulator");
if (type != null)
{
_toSpawnField = AccessTools.Field(type, "ToSpawn");
_spawnedField = AccessTools.Field(type, "Spawned");
_spawnActionsField = AccessTools.Field(type, "SpawnActions");
_furnitureLimitField = AccessTools.Field(type, "FurnitureLimit");
Logger.LogInfo((object)$" IKEASimulator fields: ToSpawn={_toSpawnField != null}, SpawnActions={_spawnActionsField != null}");
}
Type type2 = AccessTools.TypeByName("Module");
if (type2 != null)
{
MethodInfo methodInfo = AccessTools.Method(type2, "Start", (Type[])null, (Type[])null);
if (methodInfo != null)
{
HarmonyMethod val = new HarmonyMethod(typeof(FurnitureConversionPatches), "ModuleStart_Prefix", (Type[])null);
HarmonyMethod val2 = new HarmonyMethod(typeof(FurnitureConversionPatches), "ModuleStart_Postfix", (Type[])null);
harmony.Patch((MethodBase)methodInfo, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ Module.Start → Patched");
}
}
Type type3 = AccessTools.TypeByName("LevelGenerator");
if (type3 != null)
{
MethodInfo methodInfo2 = AccessTools.Method(type3, "ModuleGeneration", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
HarmonyMethod val3 = new HarmonyMethod(typeof(FurnitureConversionPatches), "ModuleGeneration_Postfix", (Type[])null);
harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val3, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ LevelGenerator.ModuleGeneration → Patched");
}
}
Type type4 = AccessTools.TypeByName("PhysGrabObject");
if (type4 != null)
{
MethodInfo methodInfo3 = AccessTools.Method(type4, "GrabStarted", (Type[])null, (Type[])null);
if (methodInfo3 != null)
{
harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(FurnitureConversionPatches), "PhysGrabObject_GrabStarted_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ PhysGrabObject.GrabStarted → Patched");
}
MethodInfo methodInfo4 = AccessTools.Method(type4, "GrabStartedRPC", (Type[])null, (Type[])null);
if (methodInfo4 != null)
{
harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(typeof(FurnitureConversionPatches), "PhysGrabObject_GrabStartedRPC_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ PhysGrabObject.GrabStartedRPC → Patched");
}
}
}
catch (Exception arg)
{
Logger.LogError((object)$"FurnitureConversionPatches.ApplyPatches failed: {arg}");
}
}
private static int GetToSpawn()
{
if (_toSpawnField != null)
{
return (int)_toSpawnField.GetValue(null);
}
return 0;
}
private static void SetToSpawn(int value)
{
_toSpawnField?.SetValue(null, value);
}
private static void IncrementToSpawn()
{
if (_toSpawnField != null)
{
int num = (int)_toSpawnField.GetValue(null);
_toSpawnField.SetValue(null, num + 1);
}
}
private static List<Action>? GetSpawnActions()
{
if (_spawnActionsField != null)
{
return _spawnActionsField.GetValue(null) as List<Action>;
}
return null;
}
private static int GetFurnitureLimit()
{
if (_furnitureLimitField != null)
{
object value = _furnitureLimitField.GetValue(null);
if (value != null)
{
PropertyInfo propertyInfo = AccessTools.Property(value.GetType(), "Value");
if (propertyInfo != null)
{
return (int)(propertyInfo.GetValue(value) ?? ((object)(-1)));
}
}
}
return -1;
}
public static void PhysGrabObject_GrabStarted_Postfix(object __instance)
{
try
{
if (IsMultiplayer())
{
return;
}
Component val = (Component)((__instance is Component) ? __instance : null);
if (!((Object)(object)val != (Object)null))
{
return;
}
Type type = AccessTools.TypeByName("IKEASimulator.PropsParenting");
if (type != null)
{
Component component = val.gameObject.GetComponent(type);
if ((Object)(object)component != (Object)null)
{
AccessTools.Method(type, "OnGrabStarted", (Type[])null, (Type[])null)?.Invoke(component, null);
}
}
}
catch
{
}
}
public static void PhysGrabObject_GrabStartedRPC_Postfix(object __instance)
{
try
{
Component val = (Component)((__instance is Component) ? __instance : null);
if (!((Object)(object)val != (Object)null))
{
return;
}
Type type = AccessTools.TypeByName("IKEASimulator.PropsParenting");
if (type != null)
{
Component component = val.gameObject.GetComponent(type);
if ((Object)(object)component != (Object)null)
{
AccessTools.Method(type, "OnGrabStarted", (Type[])null, (Type[])null)?.Invoke(component, null);
}
}
}
catch
{
}
}
private static bool IsMasterClientOrSingleplayer()
{
try
{
Type type = AccessTools.TypeByName("SemiFunc");
MethodInfo methodInfo = AccessTools.Method(type, "IsMasterClientOrSingleplayer", (Type[])null, (Type[])null);
if (methodInfo != null)
{
return (bool)methodInfo.Invoke(null, null);
}
}
catch
{
}
return true;
}
private static bool RunIsLevel()
{
try
{
Type type = AccessTools.TypeByName("SemiFunc");
MethodInfo methodInfo = AccessTools.Method(type, "RunIsLevel", (Type[])null, (Type[])null);
if (methodInfo != null)
{
return (bool)methodInfo.Invoke(null, null);
}
}
catch
{
}
return false;
}
private static bool IsMultiplayer()
{
try
{
Type type = AccessTools.TypeByName("SemiFunc");
MethodInfo methodInfo = AccessTools.Method(type, "IsMultiplayer", (Type[])null, (Type[])null);
if (methodInfo != null)
{
return (bool)methodInfo.Invoke(null, null);
}
}
catch
{
}
return false;
}
private static object? GetWrapper()
{
if (_wrapperInitialized)
{
return _cachedWrapper;
}
_wrapperInitialized = true;
try
{
GameObject prefab = IKEACriticalPatches.GetPrefab("FurnitureWrapper");
if ((Object)(object)prefab != (Object)null)
{
Type type = AccessTools.TypeByName("ValuableObject");
if (type != null)
{
_cachedWrapper = prefab.GetComponent(type);
if (_cachedWrapper != null)
{
Logger.LogInfo((object)" FurnitureWrapper obtained from cache");
return _cachedWrapper;
}
}
}
Logger.LogWarning((object)" FurnitureWrapper not found in cache");
}
catch (Exception ex)
{
Logger.LogError((object)("GetWrapper error: " + ex.Message));
}
return null;
}
private static object? GetNetworkManager()
{
return IKEACriticalPatches.CachedNetworkManager;
}
private static object? GetPathMapper()
{
object networkManager = GetNetworkManager();
if (networkManager == null)
{
return null;
}
try
{
return AccessTools.Property(networkManager.GetType(), "PathMapper")?.GetValue(networkManager);
}
catch
{
}
return null;
}
public static void ModuleStart_Prefix(object __instance)
{
try
{
bool flag = IsMasterClientOrSingleplayer();
bool flag2 = RunIsLevel();
MonoBehaviour val = (MonoBehaviour)((__instance is MonoBehaviour) ? __instance : null);
string text = ((val != null) ? ((Object)val).name : null) ?? "unknown";
if ((Object)(object)val != (Object)null)
{
string text2 = ((Object)val).name;
Transform parent = ((Component)val).transform.parent;
while ((Object)(object)parent != (Object)null)
{
text2 = ((Object)parent).name + "/" + text2;
parent = parent.parent;
}
Logger.LogInfo((object)("[Prefix] Module: " + text + ", FullPath: " + text2));
if (!flag && flag2 && (Object)(object)((Component)val).transform.parent == (Object)null)
{
GameObject val2 = GameObject.Find("Level Generator");
if ((Object)(object)val2 != (Object)null)
{
Transform val3 = val2.transform.Find("Level");
if ((Object)(object)val3 != (Object)null)
{
((Component)val).transform.SetParent(val3, true);
Logger.LogInfo((object)(" [Fix] Reparented " + text + " to Level Generator/Level"));
}
}
}
}
Logger.LogInfo((object)$"[Prefix] Module: {text}, IsMaster: {flag}, RunIsLevel: {flag2}");
if (!flag2 || (Object)(object)val == (Object)null)
{
return;
}
if (!IsMultiplayer())
{
object networkManager = GetNetworkManager();
if (networkManager != null)
{
AccessTools.Method(networkManager.GetType(), "SingleplayerRoomData", (Type[])null, (Type[])null)?.Invoke(networkManager, null);
}
}
Type type = AccessTools.TypeByName("IKEASimulator.PropSwitchContext");
if (type == null)
{
return;
}
Component val4 = ((Component)val).gameObject.AddComponent(type);
if ((Object)(object)val4 == (Object)null)
{
return;
}
AccessTools.Field(type, "ModuleName")?.SetValue(val4, ((Object)val).name);
if (!flag)
{
return;
}
object pathMapper = GetPathMapper();
if (pathMapper != null)
{
MethodInfo methodInfo = AccessTools.Method(pathMapper.GetType(), "MapPath", (Type[])null, (Type[])null);
if (methodInfo != null)
{
object value = methodInfo.Invoke(pathMapper, new object[1] { ((Object)val).name });
AccessTools.Field(type, "PathId")?.SetValue(val4, value);
}
}
else
{
object networkManager2 = GetNetworkManager();
Logger.LogWarning((object)(" [Prefix] PathMapper is null! NetworkManager: " + ((networkManager2 != null) ? "found" : "NULL")));
}
}
catch (Exception ex)
{
Logger.LogWarning((object)("ModuleStart_Prefix error: " + ex.Message));
}
}
public static void ModuleStart_Postfix(object __instance)
{
//IL_0219: Unknown result type (might be due to invalid IL or missing references)
//IL_0220: Expected O, but got Unknown
//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
//IL_02be: Expected O, but got Unknown
//IL_0380: Unknown result type (might be due to invalid IL or missing references)
//IL_0387: Expected O, but got Unknown
//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0403: Unknown result type (might be due to invalid IL or missing references)
//IL_0408: Unknown result type (might be due to invalid IL or missing references)
try
{
bool flag = IsMasterClientOrSingleplayer();
bool flag2 = RunIsLevel();
MonoBehaviour val = (MonoBehaviour)((__instance is MonoBehaviour) ? __instance : null);
string arg = ((val != null) ? ((Object)val).name : null) ?? "unknown";
Logger.LogInfo((object)$"[Postfix] Module: {arg}, IsMaster: {flag}, RunIsLevel: {flag2}");
if (!flag2 || (Object)(object)val == (Object)null)
{
return;
}
object wrapper = GetWrapper();
if (wrapper == null)
{
Logger.LogWarning((object)"FurnitureWrapper not found");
return;
}
Type type = AccessTools.TypeByName("IKEASimulator.PropSwitchContext");
if (type == null)
{
Logger.LogWarning((object)"PropSwitchContext type not found");
return;
}
Component component = ((Component)val).gameObject.GetComponent(type);
if ((Object)(object)component == (Object)null)
{
Logger.LogWarning((object)("PropSwitchContext not found on " + ((Object)val).name));
return;
}
FieldInfo fieldInfo = AccessTools.Field(type, "ModuleName");
FieldInfo fieldInfo2 = AccessTools.Field(type, "PathId");
string text = fieldInfo?.GetValue(component) as string;
int? num = fieldInfo2?.GetValue(component) as int?;
if (text == null)
{
Logger.LogWarning((object)" ModuleName is null, skipping");
return;
}
if (flag && !num.HasValue)
{
Logger.LogWarning((object)" PathId is null on Master, skipping spawn");
return;
}
Type type2 = AccessTools.TypeByName("IKEASimulator.PropUtils");
if (type2 != null)
{
AccessTools.Field(type2, "ModuleName")?.SetValue(null, text);
AccessTools.Field(type2, "PathId")?.SetValue(null, num);
}
Transform val2 = null;
foreach (Transform item in ((Component)val).transform)
{
Transform val3 = item;
if (((Object)val3).name.Contains(" Props ") && ((Object)val3).name.StartsWith("-") && ((Object)val3).name.EndsWith("-"))
{
val2 = val3;
break;
}
}
if ((Object)(object)val2 == (Object)null)
{
return;
}
Transform val4 = null;
foreach (Transform item2 in val2)
{
Transform val5 = item2;
if (((Object)val5).name == "Props")
{
val4 = val5;
break;
}
}
if ((Object)(object)val4 == (Object)null)
{
return;
}
int furnitureLimit = GetFurnitureLimit();
int num2 = 0;
List<Action> list = null;
if (flag)
{
list = GetSpawnActions();
if (list == null)
{
return;
}
}
GameObject wrapperPrefab = IKEACriticalPatches.GetPrefab("FurnitureWrapper");
if ((Object)(object)wrapperPrefab == (Object)null)
{
return;
}
foreach (Transform item3 in val4)
{
Transform val6 = item3;
if (furnitureLimit != -1 && GetToSpawn() >= furnitureLimit)
{
break;
}
if (!HasValidCollider(val6) || !HasMeshRenderer(val6))
{
continue;
}
IncrementToSpawn();
num2++;
string propName = ((Object)val6).name;
Vector3 position = val6.position;
Quaternion rotation = val6.rotation;
if (!flag || !num.HasValue)
{
continue;
}
int capturedPathId = num.Value;
list?.Add(delegate
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
try
{
SpawnFurnitureWrapper(wrapperPrefab, position, rotation, capturedPathId, propName);
}
catch (Exception ex2)
{
Logger.LogWarning((object)("Spawn error for " + propName + ": " + ex2.Message));
}
});
}
if (num2 > 0)
{
Logger.LogInfo((object)$"Found {num2} Props in {text} (Disabled)");
}
}
catch (Exception ex)
{
Logger.LogWarning((object)("ModuleStart_Postfix error: " + ex.Message));
}
}
private static bool HasValidCollider(Transform transform)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Expected O, but got Unknown
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Expected O, but got Unknown
MeshCollider component = ((Component)transform).GetComponent<MeshCollider>();
if ((Object)(object)component != (Object)null && !component.convex)
{
return false;
}
foreach (Transform item in transform)
{
Transform val = item;
MeshCollider component2 = ((Component)val).GetComponent<MeshCollider>();
if ((Object)(object)component2 != (Object)null && !component2.convex)
{
return false;
}
}
if ((Object)(object)((Component)transform).GetComponent<BoxCollider>() != (Object)null || (Object)(object)((Component)transform).GetComponent<SphereCollider>() != (Object)null || (Object)(object)((Component)transform).GetComponent<CapsuleCollider>() != (Object)null)
{
if (transform.childCount <= 0)
{
return true;
}
foreach (Transform item2 in transform)
{
Transform transform2 = item2;
if (HasValidCollider(transform2))
{
return true;
}
}
}
foreach (Transform item3 in transform)
{
Transform transform3 = item3;
if (HasValidCollider(transform3))
{
return true;
}
}
return false;
}
private static bool HasMeshRenderer(Transform transform)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
if ((Object)(object)((Component)transform).GetComponent<MeshRenderer>() != (Object)null)
{
return true;
}
foreach (Transform item in transform)
{
Transform transform2 = item;
if (HasMeshRenderer(transform2))
{
return true;
}
}
return false;
}
private static void SpawnFurnitureWrapper(GameObject prefab, Vector3 position, Quaternion rotation, int pathId, string propName)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
try
{
GameObject val = IKEACriticalPatches.SpawnPrefab("furniturewrapper", position, rotation);
if ((Object)(object)val == (Object)null)
{
val = Object.Instantiate<GameObject>(prefab, position, rotation);
Logger.LogDebug((object)" FurnitureWrapper spawned via direct Instantiate (fallback)");
}
if (!((Object)(object)val != (Object)null))
{
return;
}
Type type = AccessTools.TypeByName("IKEASimulator.PropsParenting");
if (type != null)
{
Component component = val.GetComponent(type);
if ((Object)(object)component != (Object)null)
{
Type type2 = AccessTools.TypeByName("Photon.Pun.PhotonView");
Component val2 = ((type2 != null) ? val.GetComponent(type2) : null);
bool flag = false;
if ((Object)(object)val2 != (Object)null && IsMultiplayer())
{
MethodInfo methodInfo = AccessTools.Method(type2, "RPC", new Type[3]
{
typeof(string),
typeof(RpcTarget),
typeof(object[])
}, (Type[])null);
if (methodInfo != null)
{
methodInfo.Invoke(val2, new object[3]
{
"SetPropPathRPC",
(object)(RpcTarget)0,
new object[2] { pathId, propName }
});
flag = true;
Logger.LogInfo((object)(" [Spawn] Sent SetPropPathRPC(All) for " + propName));
}
}
if (!flag)
{
MethodInfo methodInfo2 = AccessTools.Method(type, "SetPropPathRPC", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
methodInfo2.Invoke(component, new object[2] { pathId, propName });
Logger.LogDebug((object)(" [Spawn] Invoked SetPropPathRPC (Direct) for " + propName));
}
}
if (IKEASimulator_Fixer.EnableImmediatePhysics.Value)
{
MonoBehaviour val3 = (MonoBehaviour)(object)((component is MonoBehaviour) ? component : null);
if ((Object)(object)val3 != (Object)null)
{
val3.StartCoroutine(EnableMovementAfterDelay(component, type));
}
}
}
}
if (_spawnedField != null)
{
int num = (int)_spawnedField.GetValue(null);
_spawnedField.SetValue(null, num + 1);
}
}
catch (Exception ex)
{
Logger.LogWarning((object)("SpawnFurnitureWrapper error: " + ex.Message));
}
}
[IteratorStateMachine(typeof(<EnableMovementAfterDelay>d__27))]
private static IEnumerator EnableMovementAfterDelay(object propsParenting, Type propsParentingType)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <EnableMovementAfterDelay>d__27(0)
{
propsParenting = propsParenting,
propsParentingType = propsParentingType
};
}
public static void ModuleGeneration_Postfix(object __instance, ref IEnumerator __result)
{
__result = RunPrefabSpawning(__result);
}
[IteratorStateMachine(typeof(<RunPrefabSpawning>d__29))]
private static IEnumerator RunPrefabSpawning(IEnumerator original)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <RunPrefabSpawning>d__29(0)
{
original = original
};
}
}
public static class PathMapperPatches
{
public const byte MapPathEventCode = 142;
private static ManualLogSource Logger => IKEASimulator_Fixer.Logger;
public static void ApplyPatches(Harmony harmony)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Expected O, but got Unknown
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Expected O, but got Unknown
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Expected O, but got Unknown
try
{
Type type = AccessTools.TypeByName("IKEASimulator.PathMapper");
if (type == null)
{
Logger.LogWarning((object)" ✗ PathMapper type not found");
return;
}
MethodInfo methodInfo = AccessTools.Method(type, "Start", (Type[])null, (Type[])null);
if (methodInfo != null)
{
harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PathMapperPatches), "Start_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ PathMapper.Start → Patched (Event Register)");
}
MethodInfo methodInfo2 = AccessTools.Method(type, "OnDestroy", (Type[])null, (Type[])null);
if (methodInfo2 != null)
{
harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(PathMapperPatches), "OnDestroy_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ PathMapper.OnDestroy → Patched");
}
MethodInfo methodInfo3 = AccessTools.Method(type, "MapPath", (Type[])null, (Type[])null);
if (methodInfo3 != null)
{
harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(PathMapperPatches), "MapPath_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Logger.LogInfo((object)" ✓ PathMapper.MapPath → Patched (Event Raise)");
}
}
catch (Exception arg)
{
Logger.LogError((object)$"PathMapperPatches.ApplyPatches failed: {arg}");
}
}
public static bool MapPath_Prefix(object __instance, string path, ref int __result)
{
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Expected O, but got Unknown
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
try
{
Type type = __instance.GetType();
FieldInfo fieldInfo = AccessTools.Field(type, "nextPathId");
FieldInfo fieldInfo2 = AccessTools.Field(type, "pathMap");
if (fieldInfo == null || fieldInfo2 == null)
{
return true;
}
int num = (int)fieldInfo.GetValue(__instance);
if (fieldInfo2.GetValue(__instance) is IDictionary dictionary)
{
dictionary[num] = path;
Logger.LogDebug((object)$"[PathMapper.MapPath] Added: {num} → {path}");
if (PhotonNetwork.InRoom)
{
object[] array = new object[2] { num, path };
RaiseEventOptions val = new RaiseEventOptions
{
Receivers = (ReceiverGroup)0,
CachingOption = (EventCaching)4
};
PhotonNetwork.RaiseEvent((byte)142, (object)array, val, SendOptions.SendReliable);
}
}
fieldInfo.SetValue(__instance, num + 1);
__result = num;
return false;
}
catch (Exception ex)
{
Logger.LogWarning((object)("[PathMapper.MapPath] Error: " + ex.Message));
return true;
}
}
public static bool Start_Prefix(object __instance)
{
try
{
PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
object cachedNetworkManager = IKEACriticalPatches.CachedNetworkManager;
if (cachedNetworkManager == null)
{
return false;
}
PropertyInfo propertyInfo = AccessTools.Property(cachedNetworkManager.GetType(), "PathMapper");
if (propertyInfo != null)
{
propertyInfo.SetValue(cachedNetworkManager, __instance);
Logger.LogInfo((object)" [PathMapper] Configured NetworkManager.PathMapper reference");
}
else
{
Logger.LogWarning((object)" [PathMapper] Could not find PathMapper property on NetworkManager!");
}
Component val = (Component)((__instance is Component) ? __instance : null);
if ((Object)(object)val == (Object)null)
{
return false;
}
MethodInfo methodInfo = AccessTools.Method(cachedNetworkManager.GetType(), "SetRoomData", (Type[])null, (Type[])null);
if (methodInfo != null)
{
methodInfo.Invoke(cachedNetworkManager, new object[1] { val.gameObject });
}
Object.DontDestroyOnLoad((Object)(object)val.gameObject);
return false;
}
catch (Exception)
{
return false;
}
}
public static bool OnDestroy_Prefix()
{
try
{
PhotonNetwork.NetworkingClient.EventReceived -= OnEvent;
return false;
}
catch
{
return false;
}
}
private static void OnEvent(EventData photonEvent)
{
if (photonEvent.Code != 142)
{
return;
}
try
{
object[] array = (object[])photonEvent.CustomData;
int num = (int)array[0];
string value = (string)array[1];
object cachedNetworkManager = IKEACriticalPatches.CachedNetworkManager;
if (cachedNetworkManager != null)
{
object obj = AccessTools.Property(cachedNetworkManager.GetType(), "PathMapper")?.GetValue(cachedNetworkManager);
if (obj != null && AccessTools.Field(obj.GetType(), "pathMap")?.GetValue(obj) is IDictionary dictionary)
{
dictionary[num] = value;
}
}
}
catch (Exception ex)
{
Logger.LogWarning((object)("OnEvent error: " + ex.Message));
}
}
}
[HarmonyPatch(typeof(Harmony), "PatchAll", new Type[] { typeof(Assembly) })]
internal static class HarmonyPatchAllFinalizer
{
private static bool _patchesApplied;
[HarmonyPrefix]
private static bool Prefix(Harmony __instance, Assembly assembly)
{
if (assembly == null)
{
return true;
}
string text = assembly.GetName().Name ?? "";
if (text == "IKEASimulator" || text.Contains("IKEASimulator"))
{
IKEASimulator_Fixer.Logger.LogInfo((object)"=================================================");
IKEASimulator_Fixer.Logger.LogInfo((object)"→ Intercepted IKEASimulator Harmony.PatchAll()");
IKEASimulator_Fixer.Logger.LogInfo((object)" SKIPPING all IKEASimulator patches (IL incompatible)");
if (!_patchesApplied)
{
IKEASimulator_Fixer.Logger.LogInfo((object)" Applying REPOLib 3.x compatible patches...");
try
{
IKEASimulator_Fixer.Logger.LogInfo((object)" ✓ Patches handled by Fixer!");
_patchesApplied = true;
}
catch (Exception ex)
{
IKEASimulator_Fixer.Logger.LogError((object)(" ✗ Failed to apply patches: " + ex.Message));
IKEASimulator_Fixer.Logger.LogDebug((object)ex.ToString());
}
}
else
{
IKEASimulator_Fixer.Logger.LogInfo((object)" (Patches already applied)");
}
IKEASimulator_Fixer.Logger.LogInfo((object)"=================================================");
return false;
}
return true;
}
[HarmonyFinalizer]
private static Exception? Finalizer(Exception? __exception, Harmony __instance, Assembly assembly)
{
if (__exception != null)
{
string text = assembly?.GetName().Name ?? "unknown";
if (text.Contains("IKEASimulator"))
{
IKEASimulator_Fixer.Logger.LogWarning((object)"=================================================");
IKEASimulator_Fixer.Logger.LogWarning((object)"⊗ Suppressed Harmony.PatchAll() error from IKEASimulator");
IKEASimulator_Fixer.Logger.LogInfo((object)(" → Error: " + __exception.Message));
IKEASimulator_Fixer.Logger.LogWarning((object)"=================================================");
return null;
}
}
return __exception;
}
}
public static class IKEACriticalPatches
{
private static ManualLogSource Logger => IKEASimulator_Fixer.Logger;
public static AssetBundle? LoadedBundle { get; private set; }
public static Dictionary<string, GameObject> Prefabs { get; } = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase);
public static Dictionary<string, object> PrefabRefs { get; } = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
public static object? IKEAInstance { get; private set; }
public static bool Initialized { get; private set; }
public static object? CachedNetworkManager { get; private set; }
public static GameObject? ManagerInstance { get; private set; }
public static bool Awake_Prefix(object __instance)
{
try
{
Logger.LogInfo((object)"=== IKEASimulator Fixer: Awake Override ===");
IKEAInstance = __instance;
Type type = __instance.GetType();
PropertyInfo propertyInfo = AccessTools.Property(type, "Instance");
if (propertyInfo != null && propertyInfo.GetSetMethod(nonPublic: true) != null)
{
propertyInfo.SetValue(null, __instance);
Logger.LogInfo((object)" ✓ IKEASimulator.Instance set");
}
else
{
FieldInfo fieldInfo = AccessTools.Field(type, "<Instance>k__BackingField");
if (fieldInfo != null)
{
fieldInfo.SetValue(null, __instance);
Logger.LogInfo((object)" ✓ IKEASimulator.Instance set (via backing field)");
}
}
ConfigureLogging(__instance);
LoadAssetBundleSafe(__instance);
if ((Object)(object)LoadedBundle != (Object)null)
{
RegisterAllResources();
}
SetInstanceFields(__instance);
Initialized = true;
Logger.LogInfo((object)"=== Awake Override Complete ===");
return false;
}
catch (Exception arg)
{
Logger.LogError((object)$"Awake_Prefix error: {arg}");
return false;
}
}
public static bool Start_Prefix(object __instance)
{
try
{
Logger.LogInfo((object)"=== IKEASimulator Fixer: Start Override ===");
Component val = (Component)((__instance is Component) ? __instance : null);
if ((Object)(object)val == (Object)null)
{
Logger.LogError((object)" Instance is not a Component!");
return false;
}
string prefabId = "managers/ikeasimulatormanager";
GameObject prefab = GetPrefab(prefabId);
if ((Object)(object)prefab == (Object)null)
{
foreach (KeyValuePair<string, GameObject> prefab2 in Prefabs)
{
if (prefab2.Key.Contains("manager") || prefab2.Key.Contains("ikeasimulator"))
{
Logger.LogDebug((object)(" Available prefab: " + prefab2.Key));
}
}
Logger.LogWarning((object)" IKEASimulatorManager prefab not found in cache");
Logger.LogWarning((object)" NetworkManager will not be initialized - some features may not work");
return false;
}
GameObject val2 = Object.Instantiate<GameObject>(prefab, val.transform);
if ((Object)(object)val2 != (Object)null)
{
ManagerInstance = val2;
Type type = AccessTools.TypeByName("IKEASimulator.NetworkManager");
if (type != null)
{
Component val3 = (Component)(CachedNetworkManager = val2.GetComponent(type));
Type type2 = __instance.GetType();
FieldInfo fieldInfo = AccessTools.Field(type2, "networkManager");
if (fieldInfo != null && (Object)(object)val3 != (Object)null)
{
fieldInfo.SetValue(__instance, val3);
Logger.LogInfo((object)" ✓ NetworkManager component obtained and cached");
}
else
{
Logger.LogWarning((object)$" NetworkManager setup: nmField={fieldInfo != null}, nmComponent={(Object)(object)val3 != (Object)null}");
}
}
val2.transform.parent = null;
((Object)val2).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)(object)val2);
Logger.LogInfo((object)" ✓ IKEASimulatorManager instantiated locally");
}
Logger.LogInfo((object)"Initializing IKEASimulator Mod (via Fixer)");
Logger.LogInfo((object)"=== Start Override Complete ===");
return false;
}
catch (Exception arg)
{
Logger.LogError((object)$"Start_Prefix error: {arg}");
return false;
}
}
public static bool Patch_Prefix()
{
Logger.LogInfo((object)" → Skipping IKEASimulator.Patch() (IL incompatible with REPOLib 3.x)");
return false;
}
private static void ConfigureLogging(object instance)
{
try
{
Logger.LogInfo((object)" ✓ Logging configured via BepInEx");
}
catch (Exception ex)
{
Logger.LogDebug((object)("ConfigureLogging: " + ex.Message));
}
}
private static void LoadAssetBundleSafe(object instance)
{
try
{
BaseUnityPlugin val = (BaseUnityPlugin)((instance is BaseUnityPlugin) ? instance : null);
if ((Object)(object)val == (Object)null)
{
return;
}
string location = val.Info.Location;
string path = Path.GetDirectoryName(location) ?? "";
string text = Path.Combine(path, "IKEASimulator.bundle");
Logger.LogInfo((object)(" Loading bundle: " + text));
if (!File.Exists(text))
{
Logger.LogError((object)" ✗ Bundle file not found!");
return;
}
if ((Object)(object)LoadedBundle != (Object)null)
{
Logger.LogInfo((object)" Bundle already loaded");
return;
}
LoadedBundle = AssetBundle.LoadFromFile(text);
if ((Object)(object)LoadedBundle != (Object)null)
{
Logger.LogInfo((object)" ✓ AssetBundle loaded successfully");
}
else
{
Logger.LogError((object)" ✗ AssetBundle.LoadFromFile returned null");
}
}
catch (Exception arg)
{
Logger.LogError((object)$"LoadAssetBundleSafe error: {arg}");
}
}
private static void RegisterAllResources()
{
Logger.LogInfo((object)" Registering resources with REPOLib 3.x...");
Type type = AccessTools.TypeByName("REPOLib.Modules.NetworkPrefabs");
Type type2 = AccessTools.TypeByName("REPOLib.Modules.Valuables");
MethodInfo methodInfo = ((type != null) ? AccessTools.Method(type, "RegisterNetworkPrefab", new Type[2]
{
typeof(string),
typeof(GameObject)
}, (Type[])null) : null);
MethodInfo methodInfo2 = ((type2 != null) ? AccessTools.Method(type2, "RegisterValuable", new Type[1] { typeof(GameObject) }, (Type[])null) : null);
Logger.LogInfo((object)" REPOLib API:");
Logger.LogInfo((object)(" NetworkPrefabs.RegisterNetworkPrefab: " + ((methodInfo != null) ? "✓" : "✗")));
Logger.LogInfo((object)(" Valuables.RegisterValuable: " + ((methodInfo2 != null) ? "✓" : "✗")));
if ((Object)(object)LoadedBundle == (Object)null)
{
return;
}
string[] allAssetNames = LoadedBundle.GetAllAssetNames();
foreach (string text in allAssetNames)
{
if (text.EndsWith(".prefab"))
{
GameObject val = LoadedBundle.LoadAsset<GameObject>(text);
if ((Object)(object)val != (Object)null && (text.Contains("/valuables/") || text.Contains("/assets/")) && !text.ToLowerInvariant().Contains("manager") && !text.ToLowerInvariant().Contains("roomdata"))
{
OptimizeNetworkPrefab(val, text);
}
}
}
string[] allAssetNames2 = LoadedBundle.GetAllAssetNames();
int num = 0;
int num2 = 0;
string[] array = allAssetNames2;
foreach (string text2 in array)
{
try
{
if (!text2.EndsWith(".prefab"))
{
continue;
}
GameObject val2 = LoadedBundle.LoadAsset<GameObject>(text2);
if ((Object)(object)val2 == (Object)null)
{
continue;
}
string text3 = ExtractPrefabId(text2);
if (text2.Contains("/assets/") && methodInfo != null)
{
try
{
object obj = methodInfo.Invoke(null, new object[2] { text3, val2 });
Prefabs[text3] = val2;
if (obj != null)
{
PrefabRefs[text3] = obj;
num++;
}
}
catch (TargetInvocationException ex)
{
Logger.LogDebug((object)(" " + text3 + ": " + ex.InnerException?.Message));
Prefabs[text3] = val2;
}
}
else
{
if (!text2.Contains("/valuables/") || !(methodInfo2 != null))
{
continue;
}
try
{
methodInfo2.Invoke(null, new object[1] { val2 });
num2++;
string text4 = ((Object)val2).name.ToLowerInvariant();
Prefabs[text4] = val2;
if (!(text4 == "furniturewrapper") || !(methodInfo != null))
{
continue;
}
try
{
object obj2 = methodInfo.Invoke(null, new object[2] { text4, val2 });
if (obj2 != null)
{
PrefabRefs[text4] = obj2;
Logger.LogInfo((object)(" Cached valuable as NetworkPrefab: " + text4));
}
}
catch (Exception ex2)
{
Logger.LogDebug((object)(" FurnitureWrapper NetworkPrefab registration: " + ex2.Message));
}
}
catch (TargetInvocationException ex3)
{
Logger.LogDebug((object)(" Valuable " + ((Object)val2).name + ": " + ex3.InnerException?.Message));
}
continue;
}
}
catch (Exception ex4)
{
Logger.LogDebug((object)(" Error processing " + text2 + ": " + ex4.Message));
}
}
Logger.LogInfo((object)" Registration results:");
Logger.LogInfo((object)$" Network Prefabs: {num} registered, {Prefabs.Count} cached");
Logger.LogInfo((object)$" Valuables: {num2}");
}
private static string ExtractPrefabId(string assetPath)
{
int num = assetPath.IndexOf("/assets/", StringComparison.OrdinalIgnoreCase);
if (num >= 0 && num + 8 < assetPath.Length)
{
string text = assetPath.Substring(num + 8);
return text.Replace(".prefab", "");
}
return Path.GetFileNameWithoutExtension(assetPath);
}
private static void SetInstanceFields(object instance)
{
try
{
Type type = instance.GetType();
FieldInfo fieldInfo = AccessTools.Field(type, "assetBundle");
if (fieldInfo != null)
{
fieldInfo.SetValue(instance, LoadedBundle);
}
FieldInfo fieldInfo2 = AccessTools.Field(type, "prefabs");
if (fieldInfo2 != null)
{
fieldInfo2.SetValue(instance, Prefabs);
}
Logger.LogInfo((object)" ✓ Instance fields configured");
}
catch (Exception ex)
{
Logger.LogDebug((object)("SetInstanceFields: " + ex.Message));
}
}
public static GameObject? GetPrefab(string prefabId)
{
string text = prefabId?.ToLowerInvariant() ?? "";
if (Prefabs.TryGetValue(text, out GameObject value))
{
return value;
}
foreach (KeyValuePair<string, GameObject> prefab in Prefabs)
{
if (prefab.Key.EndsWith(text) || prefab.Key.EndsWith("/" + text))
{
return prefab.Value;
}
}
return null;
}
public static GameObject? SpawnPrefab(string prefabId, Vector3 position, Quaternion rotation)
{
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
try
{
string text = prefabId?.ToLowerInvariant() ?? "";
if (PrefabRefs.TryGetValue(text, out object value))
{
Type type = AccessTools.TypeByName("REPOLib.Modules.NetworkPrefabs");
if (type != null)
{
MethodInfo methodInfo = AccessTools.Method(type, "SpawnNetworkPrefab", new Type[5]
{
value.GetType(),
typeof(Vector3),
typeof(Quaternion),
typeof(byte),
typeof(object[])
}, (Type[])null);
if (methodInfo != null)
{
object obj = methodInfo.Invoke(null, new object[5]
{
value,
position,
rotation,
(byte)0,
null
});
if (obj != null)
{
Logger.LogInfo((object)(" [Spawn] Networked Spawn Success: " + text));
return (GameObject?)((obj is GameObject) ? obj : null);
}
}
}
}
Logger.LogWarning((object)(" [Spawn] Falling back to Local Instantiation for " + text));
GameObject prefab = GetPrefab(text);
if ((Object)(object)prefab != (Object)null)
{
GameObject val = Object.Instantiate<GameObject>(prefab, position, rotation);
if ((Object)(object)val != (Object)null)
{
Type type2 = AccessTools.TypeByName("Photon.Pun.PhotonView");
if (type2 != null)
{
}
Logger.LogInfo((object)$" [Spawn] Local Instantiated: {((Object)val).name} at {position}");
return val;
}
}
Logger.LogWarning((object)(" SpawnPrefab failed for '" + prefabId + "'"));
return null;
}
catch (Exception arg)
{
Logger.LogError((object)$"SpawnPrefab error for {prefabId}: {arg}");
return null;
}
}
private static void OptimizeNetworkPrefab(GameObject prefab, string prefabName)
{
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
try
{
PhotonView val2 = prefab.GetComponent<PhotonView>();
if ((Object)(object)val2 == (Object)null)
{
val2 = prefab.AddComponent<PhotonView>();
Logger.LogDebug((object)(" [Optimize] Added PhotonView to " + ((Object)prefab).name));
}
PhotonTransformView val3 = prefab.GetComponent<PhotonTransformView>();
if ((Object)(object)val3 == (Object)null)
{
val3 = prefab.AddComponent<PhotonTransformView>();
Logger.LogDebug((object)(" [Optimize] Added PhotonTransformView to " + ((Object)prefab).name));
}
SetBool(val3, "m_SynchronizePosition", val: true);
SetBool(val3, "m_SynchronizeRotation", val: true);
if (!val2.ObservedComponents.Contains((Component)(object)val3))
{
val2.ObservedComponents.Add((Component)(object)val3);
val2.Synchronization = (ViewSynchronization)3;
}
Logger.LogInfo((object)$" [Optimize] Configured {((Object)prefab).name}: PV={(Object)(object)val2 != (Object)null}, PTV={(Object)(object)val3 != (Object)null}");
}
catch (Exception ex)
{
Logger.LogWarning((object)(" [Optimize] Failed to optimize " + ((Object)prefab).name + ": " + ex.Message));
}
static void SetBool(object target, string name, bool val)
{
FieldInfo fieldInfo = AccessTools.Field(target.GetType(), name);
if (fieldInfo != null)
{
fieldInfo.SetValue(target, val);
}
}
}
}
public static class NetworkManagerPatches
{
[CompilerGenerated]
private sealed class <InstantiateRoomDataFixed>d__4 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public object networkManager;
private Type <photonNetworkType>5__1;
private bool <isMasterClient>5__2;
private Type <nmType>5__3;
private FieldInfo <roomDataField>5__4;
private GameObject <existingRoomData>5__5;
private FieldInfo <retryCountField>5__6;
private int <retryCount>5__7;
private PropertyInfo <isMasterClientProp>5__8;
private GameObject <roomData>5__9;
private Type <pathMapperType>5__10;
private Component <pathMapperComponent>5__11;
private PropertyInfo <pathMapperProp>5__12;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <InstantiateRoomDataFixed>d__4(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<photonNetworkType>5__1 = null;
<nmType>5__3 = null;
<roomDataField>5__4 = null;
<existingRoomData>5__5 = null;
<retryCountField>5__6 = null;
<isMasterClientProp>5__8 = null;
<roomData>5__9 = null;
<pathMapperType>5__10 = null;
<pathMapperComponent>5__11 = null;
<pathMapperProp>5__12 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_025d: Unknown result type (might be due to invalid IL or missing references)
//IL_0267: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
{
<>1__state = -1;
<photonNetworkType>5__1 = AccessTools.TypeByName("Photon.Pun.PhotonNetwork");
<isMasterClient>5__2 = false;
if (<photonNetworkType>5__1 != null)
{
<isMasterClientProp>5__8 = AccessTools.Property(<photonNetworkType>5__1, "IsMasterClient");
if (<isMasterClientProp>5__8 != null)
{
<isMasterClient>5__2 = (bool)(<isMasterClientProp>5__8.GetValue(null) ?? ((object)false));
}
<isMasterClientProp>5__8 = null;
}
if (!<isMasterClient>5__2)
{
return false;
}
<nmType>5__3 = networkManager.GetType();
<roomDataField>5__4 = AccessTools.Field(<nmType>5__3, "roomData");
ref GameObject reference = ref <existingRoomData>5__5;
object? obj = <roomDataField>5__4?.GetValue(networkManager);
reference = (GameObject)((obj is GameObject) ? obj : null);
if ((Object)(object)<existingRoomData>5__5 != (Object)null)
{
return false;
}
<retryCountField>5__6 = AccessTools.Field(<nmType>5__3, "retryCount");
<retryCount>5__7 = (int)(<retryCountField>5__6?.GetValue(networkManager) ?? ((object)0));
break;
}
case 1:
<>1__state = -1;
<roomData>5__9 = null;
break;
}
if (<retryCount>5__7 < 5)
{
<roomData>5__9 = InstantiateRoomDataLocal();
if ((Object)(object)<roomData>5__9 != (Object)null)
{
<roomDataField>5__4?.SetValue(networkManager, <roomData>5__9);
<pathMapperType>5__10 = AccessTools.TypeByName("IKEASimulator.PathMapper");
if (<pathMapperType>5__10 != null)
{
<pathMapperComponent>5__11 = <roomData>5__9.GetComponent(<pathMapperType>5__10);
<pathMapperProp>5__12 = AccessTools.Property(<nmType>5__3, "PathMapper");
<pathMapperProp>5__12?.SetValue(networkManager, <pathMapperComponent>5__11);
<pathMapperComponent>5__11 = null;
<pathMapperProp>5__12 = null;
}
Logger.LogDebug((object)" InstantiateRoomData: RoomData instantiated locally");
return false;
}
<retryCount>5__7++;
<retryCountField>5__6?.SetValue(networkManager, <retryCount>5__7);
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 1;
return true;
}
Logger.LogWarning((object)" InstantiateRoomData: Failed to create RoomData after 5 retries");
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 => IKEASimulator_Fixer.Logger;
public static bool OnCreatedRoom_Prefix(object __instance)
{
try
{
Logger.LogDebug((object)"NetworkManager.OnCreatedRoom intercepted");
MonoBehaviour val = (MonoBehaviour)((__instance is MonoBehaviour) ? __instance : null);
if ((Object)(object)val == (Object)null)
{
return true;
}
val.StartCoroutine(InstantiateRoomDataFixed(__instance));
return false;
}
catch (Exception arg)
{
Logger.LogError((object)$"OnCreatedRoom_Prefix error: {arg}");
return false;
}
}
public static bool SingleplayerRoomData_Prefix(object __instance)
{
try
{
Logger.LogDebug((object)"NetworkManager.SingleplayerRoomData intercepted");
Type type = __instance.GetType();
AccessTools.Field(type, "isSingleplayer")?.SetValue(__instance, true);
FieldInfo fieldInfo = AccessTools.Field(type, "roomData");
object? obj = fieldInfo?.GetValue(__instance);
GameObject val = (GameObject)((obj is GameObject) ? obj : null);
if ((Object)(object)val != (Object)null)
{
return false;
}
GameObject val2 = InstantiateRoomDataLocal();
if ((Object)(object)val2 != (Object)null)
{
fieldInfo?.SetValue(__instance, val2);
Type type2 = AccessTools.TypeByName("IKEASimulator.PathMapper");
if (type2 != null)
{
Component component = val2.GetComponent(type2);
AccessTools.Property(type, "PathMapper")?.SetValue(__instance, component);
}
Logger.LogDebug((object)" SingleplayerRoomData: RoomData instantiated locally");
}
return false;
}
catch (Exception arg)
{
Logger.LogError((object)$"SingleplayerRoomData_Prefix error: {arg}");
return false;
}
}
[IteratorStateMachine(typeof(<InstantiateRoomDataFixed>d__4))]
private static IEnumerator InstantiateRoomDataFixed(object networkManager)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <InstantiateRoomDataFixed>d__4(0)
{
networkManager = networkManager
};
}
private static GameObject? InstantiateRoomDataLocal()
{
try
{
string prefabId = "managers/roomdata";
GameObject val = IKEACriticalPatches.GetPrefab(prefabId);
if ((Object)(object)val == (Object)null)
{
foreach (KeyValuePair<string, GameObject> prefab in IKEACriticalPatches.Prefabs)
{
if (prefab.Key.ToLower().Contains("roomdata"))
{
val = prefab.Value;
Logger.LogDebug((object)(" Found RoomData prefab with key: " + prefab.Key));
break;
}
}
}
if ((Object)(object)val == (Object)null)
{
Logger.LogWarning((object)" RoomData prefab not found in cache");
return null;
}
return Object.Instantiate<GameObject>(val);
}
catch (Exception arg)
{
Logger.LogError((object)$"InstantiateRoomDataLocal error: {arg}");
return null;
}
}
}
[HarmonyPatch(typeof(Module), "Start")]
internal static class ModuleSafetyPatch
{
[HarmonyFinalizer]
private static Exception? Finalizer(Exception? __exception, Module __instance)
{
if (__exception != null && __exception is NullReferenceException)
{
string text = __exception.StackTrace ?? "";
if (text.Contains("IKEASimulator"))
{
IKEASimulator_Fixer.Logger.LogWarning((object)("Suppressed IKEASimulator NullReferenceException in Module.Start for " + (((__instance != null) ? ((Object)__instance).name : null) ?? "unknown")));
return null;
}
}
return __exception;
}
}
[HarmonyPatch(typeof(LevelGenerator), "ModuleGeneration")]
internal static class LevelGeneratorSafetyPatch
{
[HarmonyFinalizer]
private static Exception? Finalizer(Exception? __exception)
{
if (__exception != null && __exception is NullReferenceException)
{
string text = __exception.StackTrace ?? "";
if (text.Contains("IKEASimulator"))
{
IKEASimulator_Fixer.Logger.LogWarning((object)"Suppressed IKEASimulator NullReferenceException in LevelGenerator.ModuleGeneration");
return null;
}
}
return __exception;
}
}
}