using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CrackMods.Shared;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Steamworks;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("CrackMorePlayers")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CrackMorePlayers")]
[assembly: AssemblyTitle("CrackMorePlayers")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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 CrackMods.Shared
{
internal static class ModHandshake
{
[HarmonyPatch(typeof(SteamLobby), "OnLobbyCreated")]
private static class PublishPatch
{
private static void Postfix(SteamLobby __instance)
{
Publish(__instance);
}
}
[HarmonyPatch(typeof(SteamLobby), "RefreshModdedLobbyData")]
private static class RefreshPatch
{
private static void Postfix(SteamLobby __instance)
{
Publish(__instance);
}
}
[HarmonyPatch(typeof(SteamLobby), "HostIsInLobby")]
private static class JoinCheckPatch
{
private static bool Prefix(CSteamID lobby, ref bool __result)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
if (!IsLeader(_ownGuid))
{
return true;
}
string lobbyData = SteamMatchmaking.GetLobbyData(lobby, "cmods");
string text = LocalToken();
if (lobbyData == text)
{
return true;
}
_pendingReason = Describe(lobbyData, text);
Debug.LogWarning((object)("[CrackMods] refusing to join: " + _pendingReason));
__result = false;
return false;
}
}
[HarmonyPatch(typeof(SteamLobby), "FailConnect")]
private static class FailMessagePatch
{
private static void Prefix(ref string messageKey)
{
if (_pendingReason != null && !(messageKey != "Error_JoinFailed"))
{
messageKey = _pendingReason;
_pendingReason = null;
}
}
}
internal const string GuidPrefix = "com.altma.crack.";
private const string LobbyKey = "cmods";
private static string _ownGuid;
private static string _pendingReason;
internal static string LocalToken()
{
List<string> list = new List<string>();
foreach (KeyValuePair<string, PluginInfo> item in Chainloader.PluginInfos.OrderBy((KeyValuePair<string, PluginInfo> k) => k.Key))
{
if (item.Key.StartsWith("com.altma.crack."))
{
string text = item.Key.Substring("com.altma.crack.".Length) + "=" + item.Value.Metadata.Version;
object instance = item.Value.Instance;
PropertyInfo propertyInfo = ((instance != null) ? AccessTools.Property(instance.GetType(), "HandshakeExtra") : null);
if (propertyInfo != null && propertyInfo.GetGetMethod() != null && propertyInfo.GetGetMethod().IsStatic)
{
text = text + "+" + propertyInfo.GetValue(null, null);
}
list.Add(text);
}
}
return string.Join(";", list.ToArray());
}
private static bool IsLeader(string ownGuid)
{
string text = (from k in Chainloader.PluginInfos.Keys
where k.StartsWith("com.altma.crack.")
orderby k
select k).FirstOrDefault();
if (text != null)
{
return text == ownGuid;
}
return true;
}
internal static void Install(string ownGuid)
{
_ownGuid = ownGuid;
}
private static void Publish(SteamLobby lobby)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
if (IsLeader(_ownGuid) && !((Object)(object)lobby == (Object)null) && ((CSteamID)(ref lobby.currentLobbyID)).IsValid())
{
string text = LocalToken();
SteamMatchmaking.SetLobbyData(lobby.currentLobbyID, "cmods", text);
Debug.Log((object)("[CrackMods] lobby mods: " + text));
}
}
internal static string Describe(string host, string local)
{
Dictionary<string, string> dictionary = Parse(host);
Dictionary<string, string> dictionary2 = Parse(local);
List<string> list = new List<string>();
foreach (string item in from k in dictionary.Keys.Union(dictionary2.Keys)
orderby k
select k)
{
dictionary.TryGetValue(item, out var value);
dictionary2.TryGetValue(item, out var value2);
if (!(value == value2))
{
list.Add(item + ": host " + (value ?? "doesn't have it") + ", you " + (value2 ?? "don't have it"));
}
}
return "CrackMods don't match the host. " + string.Join(". ", list.ToArray());
static Dictionary<string, string> Parse(string s)
{
return (from p in (s ?? "").Split(new char[1] { ';' })
where p.Contains("=")
select p).ToDictionary((string p) => p.Substring(0, p.IndexOf('=')), (string p) => p.Substring(p.IndexOf('=') + 1));
}
}
}
}
namespace CrackMorePlayers
{
internal class AnnexLighting : MonoBehaviour
{
private const uint UsedByLevel = 5u;
private const float PlayerCheckInterval = 0.25f;
private float _nextCheck;
internal static uint Layer { get; private set; } = 2u;
private static uint PickLayer()
{
int lastDefinedRenderingLayerIndex = RenderingLayerMask.GetLastDefinedRenderingLayerIndex();
for (int i = 1; i <= Mathf.Max(lastDefinedRenderingLayerIndex, 1); i++)
{
if ((5 & (1 << i)) == 0)
{
return (uint)(1 << i);
}
}
return 2u;
}
internal static string Describe()
{
return string.Format("annex light layer 0x{0:X} (defined layers: {1}; ", Layer, string.Join(", ", RenderingLayerMask.GetDefinedRenderingLayerNames())) + $"last index {RenderingLayerMask.GetLastDefinedRenderingLayerIndex()})";
}
internal static void Setup(GameObject annex)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
Layer = PickLayer();
Light[] componentsInChildren = annex.GetComponentsInChildren<Light>(true);
UniversalAdditionalLightData val3 = default(UniversalAdditionalLightData);
foreach (Light val in componentsInChildren)
{
GameObject val2 = new GameObject("CMP_RealtimeTwin");
val2.transform.SetParent(((Component)val).transform, false);
Light obj = val2.AddComponent<Light>();
obj.type = val.type;
obj.color = val.color;
obj.intensity = val.intensity;
obj.range = val.range;
obj.spotAngle = val.spotAngle;
obj.innerSpotAngle = val.innerSpotAngle;
obj.shadows = (LightShadows)0;
if (!val2.TryGetComponent<UniversalAdditionalLightData>(ref val3))
{
val3 = val2.AddComponent<UniversalAdditionalLightData>();
}
val3.renderingLayers = RenderingLayerMask.op_Implicit(Layer);
obj.renderingLayerMask = (int)Layer;
}
Renderer[] componentsInChildren2 = annex.GetComponentsInChildren<Renderer>(true);
foreach (Renderer val4 in componentsInChildren2)
{
if (val4.lightmapIndex < 0 || val4.lightmapIndex >= 65534)
{
val4.renderingLayerMask |= Layer;
}
}
annex.AddComponent<AnnexLighting>();
}
private void Update()
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
if (Time.unscaledTime < _nextCheck || (Object)(object)GameManager.instance == (Object)null)
{
return;
}
_nextCheck = Time.unscaledTime + 0.25f;
foreach (Player allPlayerCharacter in GameManager.instance.GetAllPlayerCharacters())
{
if (!((Object)(object)allPlayerCharacter == (Object)null))
{
bool flag = QuartersAnnex.Contains(allPlayerCharacter.WorldPosition);
Renderer[] componentsInChildren = ((Component)allPlayerCharacter).GetComponentsInChildren<Renderer>(true);
foreach (Renderer val in componentsInChildren)
{
val.renderingLayerMask = (flag ? (val.renderingLayerMask | Layer) : (val.renderingLayerMask & ~Layer));
}
}
}
}
}
[BepInPlugin("com.altma.crack.moreplayers", "CRACK More Players", "0.5.1")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "com.altma.crack.moreplayers";
public const string Name = "CRACK More Players";
public const string Version = "0.5.1";
internal static ManualLogSource Log;
internal static ConfigEntry<int> MaxPlayers;
internal static ConfigEntry<bool> AnnexEnabled;
public static string HandshakeExtra
{
get
{
if (AnnexEnabled == null || !AnnexEnabled.Value)
{
return "noannex";
}
return "annex";
}
}
internal static int RoomCount
{
get
{
int i;
for (i = 0; (Object)(object)QuartersRoom.Get(i) != (Object)null; i++)
{
}
return i;
}
}
private void Awake()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
MaxPlayers = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxPlayers", 8, new ConfigDescription("Maximum crew size. Every player in the lobby must run the mod. Players 5-8 get rooms in the upper quarters; beyond that, players share rooms (player 9 with player 1, 10 with 2, ...).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 32), Array.Empty<object>()));
AnnexEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Quarters", "AnnexEnabled", true, "Build the upper quarters (4 extra rooms for players 5-8, reached by a ladder through a ceiling hatch). Must be the same for every player in the lobby (joining is refused otherwise).");
ModHandshake.Install("com.altma.crack.moreplayers");
new Harmony("com.altma.crack.moreplayers").PatchAll(typeof(Plugin).Assembly);
Log.LogInfo((object)string.Format("{0} {1} loaded, MaxPlayers = {2}", "CRACK More Players", "0.5.1", MaxPlayers.Value));
}
[Conditional("DEV")]
internal static void LogDev(string message)
{
Log.LogInfo((object)message);
}
internal static int RoomOf(int playerIndex)
{
if (playerIndex < 0 || (Object)(object)QuartersRoom.Get(playerIndex) != (Object)null)
{
return playerIndex;
}
int roomCount = RoomCount;
if (roomCount <= 0)
{
return playerIndex;
}
return playerIndex % roomCount;
}
}
[HarmonyPatch(typeof(MyNetworkManager), "Awake")]
internal static class MaxConnectionsPatch
{
private static void Postfix(MyNetworkManager __instance)
{
((NetworkManager)__instance).maxConnections = Plugin.MaxPlayers.Value;
}
}
[HarmonyPatch(typeof(GameManager), "GetAvailablePlayerIndex")]
internal static class AvailablePlayerIndexPatch
{
private static bool Prefix(GameManager __instance, ref int __result)
{
int value = Plugin.MaxPlayers.Value;
int i;
for (i = 0; i < value; i++)
{
if (!__instance.players.Any((PlayerController p) => p.index == i))
{
__result = i;
return false;
}
}
__result = -1;
return false;
}
}
[HarmonyPatch(typeof(GameManager), "GetSpawnPoint")]
internal static class SpawnPointPatch
{
private static bool Prefix(int playerIndex, ref (Vector3 position, Quaternion rotation) __result)
{
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
if (playerIndex < 0 || (Object)(object)QuartersRoom.Get(playerIndex) != (Object)null)
{
return true;
}
int roomCount = Plugin.RoomCount;
if (roomCount == 0)
{
return true;
}
QuartersRoom val = QuartersRoom.Get(playerIndex % roomCount);
if ((Object)(object)val == (Object)null || (Object)(object)val.SpawnPoint == (Object)null)
{
return true;
}
Transform spawnPoint = val.SpawnPoint;
int num = playerIndex / roomCount;
__result = (position: spawnPoint.position + spawnPoint.right * (0.75f * (float)num), rotation: spawnPoint.rotation);
return false;
}
}
[HarmonyPatch(typeof(QuartersDoor), "ReaderHoldsAssignedPlayer")]
internal static class DoorAuthorizedPatch
{
private static bool Prefix(BadgeReader reader, int ____assignedPlayerIndex, ref bool __result)
{
__result = BadgeRoom(reader, out var room) && room == ____assignedPlayerIndex;
return false;
}
internal static bool BadgeRoom(BadgeReader reader, out int room)
{
room = -1;
if ((Object)(object)reader == (Object)null || !reader.HasBadgeAuthoritative)
{
return false;
}
Player signedInPlayer = reader.SignedInPlayer;
if ((Object)(object)signedInPlayer == (Object)null || (Object)(object)signedInPlayer.playerController == (Object)null)
{
return false;
}
room = Plugin.RoomOf(signedInPlayer.playerController.index);
return true;
}
}
[HarmonyPatch(typeof(QuartersDoor), "HasUnauthorizedBadge")]
internal static class DoorUnauthorizedPatch
{
private static bool Prefix(BadgeReader reader, int ____assignedPlayerIndex, ref bool __result)
{
__result = DoorAuthorizedPatch.BadgeRoom(reader, out var room) && room != ____assignedPlayerIndex;
return false;
}
}
[HarmonyPatch(typeof(Bed), "CanInteract")]
internal static class BedRoommatePatch
{
private static void Postfix(Bed __instance, PlayerItemHolder holder, int ____playerIndex, ref bool __result)
{
if (__result || ____playerIndex < 0 || (Object)(object)holder == (Object)null)
{
return;
}
Player player = holder.Player;
if (!((Object)(object)player == (Object)null) && !((Object)(object)player.playerController == (Object)null))
{
int index = player.playerController.index;
if (index != ____playerIndex && Plugin.RoomOf(index) == ____playerIndex && !((Object)(object)BreakManager.instance == (Object)null) && BreakManager.instance.IsSleepPhase && !player.IsSleepingInBed)
{
__result = true;
}
}
}
}
internal static class QuartersAnnex
{
private sealed class MeshData
{
private struct Vert
{
public Vector3 P;
public Vector3 N;
public Vector4 T;
public Vector2 Uv0;
public Vector2 Uv1;
public static Vert Lerp(Vert a, Vert b, float f)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
return new Vert
{
P = Vector3.Lerp(a.P, b.P, f),
N = Vector3.Lerp(a.N, b.N, f),
T = Vector4.Lerp(a.T, b.T, f),
Uv0 = Vector2.Lerp(a.Uv0, b.Uv0, f),
Uv1 = Vector2.Lerp(a.Uv1, b.Uv1, f)
};
}
}
private Vert[] _verts;
private int[][] _tris;
internal Vector3 Centroid
{
get
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
Vector3 val = Vector3.zero;
Vert[] verts = _verts;
for (int i = 0; i < verts.Length; i++)
{
Vert vert = verts[i];
val += vert.P;
}
if (_verts.Length == 0)
{
return val;
}
return val / (float)_verts.Length;
}
}
internal Vector2 NearestUv0(Vector3 world)
{
//IL_0018: 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)
//IL_001e: 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)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
int num = 0;
float num2 = float.MaxValue;
for (int i = 0; i < _verts.Length; i++)
{
Vector3 val = _verts[i].P - world;
float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
if (sqrMagnitude < num2)
{
num2 = sqrMagnitude;
num = i;
}
}
if (_verts.Length == 0)
{
return Vector2.zero;
}
return _verts[num].Uv0;
}
internal static MeshData Read(BinaryReader r)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
int num = r.ReadInt32();
int num2 = r.ReadInt32();
Vert[] array = new Vert[num];
for (int i = 0; i < num; i++)
{
array[i].P = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
}
for (int j = 0; j < num; j++)
{
array[j].N = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
}
for (int k = 0; k < num; k++)
{
array[k].T = new Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
}
for (int l = 0; l < num; l++)
{
array[l].Uv0 = new Vector2(r.ReadSingle(), r.ReadSingle());
}
for (int m = 0; m < num; m++)
{
array[m].Uv1 = new Vector2(r.ReadSingle(), r.ReadSingle());
}
int[][] array2 = new int[num2][];
for (int n = 0; n < num2; n++)
{
array2[n] = new int[r.ReadInt32()];
for (int num3 = 0; num3 < array2[n].Length; num3++)
{
array2[n][num3] = r.ReadInt32();
}
}
return new MeshData
{
_verts = array,
_tris = array2
};
}
internal Mesh ToLocalMesh(Transform orig, string name, Rect? hole)
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0116: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Expected O, but got Unknown
List<Vert> list = new List<Vert>(_verts);
int[][] array = new int[_tris.Length][];
for (int i = 0; i < _tris.Length; i++)
{
array[i] = (hole.HasValue ? CutHole(_tris[i], hole.Value, list) : _tris[i]);
}
Matrix4x4 worldToLocalMatrix = orig.worldToLocalMatrix;
Matrix4x4 localToWorldMatrix = orig.localToWorldMatrix;
Matrix4x4 transpose = ((Matrix4x4)(ref localToWorldMatrix)).transpose;
int count = list.Count;
Vector3[] array2 = (Vector3[])(object)new Vector3[count];
Vector3[] array3 = (Vector3[])(object)new Vector3[count];
Vector4[] array4 = (Vector4[])(object)new Vector4[count];
Vector2[] array5 = (Vector2[])(object)new Vector2[count];
Vector2[] array6 = (Vector2[])(object)new Vector2[count];
for (int j = 0; j < count; j++)
{
Vert vert = list[j];
array2[j] = ((Matrix4x4)(ref worldToLocalMatrix)).MultiplyPoint3x4(vert.P);
int num = j;
Vector3 val = ((Matrix4x4)(ref transpose)).MultiplyVector(vert.N);
array3[num] = ((Vector3)(ref val)).normalized;
val = ((Matrix4x4)(ref worldToLocalMatrix)).MultiplyVector(Vector4.op_Implicit(vert.T));
Vector3 normalized = ((Vector3)(ref val)).normalized;
array4[j] = new Vector4(normalized.x, normalized.y, normalized.z, vert.T.w);
array5[j] = vert.Uv0;
array6[j] = vert.Uv1;
}
Mesh val2 = new Mesh
{
name = name + " (annex)"
};
if (count > 65535)
{
val2.indexFormat = (IndexFormat)1;
}
val2.vertices = array2;
val2.normals = array3;
val2.tangents = array4;
val2.uv = array5;
val2.uv2 = array6;
val2.subMeshCount = array.Length;
for (int k = 0; k < array.Length; k++)
{
val2.SetTriangles(array[k], k, false);
}
val2.RecalculateBounds();
return val2;
}
private static int[] CutHole(int[] tris, Rect hole, List<Vert> verts)
{
List<int> list = new List<int>(tris.Length);
for (int i = 0; i < tris.Length; i += 3)
{
Peel(Peel(Peel(Peel(new List<Vert>
{
verts[tris[i]],
verts[tris[i + 1]],
verts[tris[i + 2]]
}, 0, ((Rect)(ref hole)).xMin, -1f, verts, list), 0, ((Rect)(ref hole)).xMax, 1f, verts, list), 2, ((Rect)(ref hole)).yMin, -1f, verts, list), 2, ((Rect)(ref hole)).yMax, 1f, verts, list);
}
return list.ToArray();
}
private static List<Vert> Peel(List<Vert> poly, int axis, float c, float sign, List<Vert> verts, List<int> result)
{
if (poly.Count < 3)
{
return poly;
}
Emit(Clip(poly, axis, c, sign), verts, result);
return Clip(poly, axis, c, 0f - sign);
}
private static List<Vert> Clip(List<Vert> poly, int axis, float c, float sign)
{
List<Vert> list = new List<Vert>(poly.Count + 2);
for (int i = 0; i < poly.Count; i++)
{
Vert vert = poly[i];
Vert b = poly[(i + 1) % poly.Count];
float num = sign * (((Vector3)(ref vert.P))[axis] - c);
float num2 = sign * (((Vector3)(ref b.P))[axis] - c);
if (num >= 0f)
{
list.Add(vert);
}
if (num >= 0f != num2 >= 0f)
{
list.Add(Vert.Lerp(vert, b, num / (num - num2)));
}
}
return list;
}
private static void Emit(List<Vert> poly, List<Vert> verts, List<int> result)
{
if (poly.Count >= 3)
{
int count = verts.Count;
verts.AddRange(poly);
for (int i = 1; i + 1 < poly.Count; i++)
{
result.Add(count);
result.Add(count + i);
result.Add(count + i + 1);
}
}
}
}
internal static readonly Vector3 Offset = new Vector3(-7f, 8.9f, 0f);
private static readonly Vector3 OrigCenter = new Vector3(-32.62f, 0f, 0f);
private const float LobbyRadius = 9.6f;
private static readonly Vector3 HatchCenter = new Vector3(-35.8f, 0f, 0f);
private const string GatePath = "Walls/PF_Lab_WallSection/SM_LabWall_GarageOpening (1)";
private static readonly string[] DropGateChildren = new string[2] { "Sound", "Obstacle" };
private const float HatchSizeX = 1.3f;
private const float HatchSizeZ = 1.2f;
private const float CeilingY = 7.55f;
private const float LadderPieceHeight = 3f;
private const string LadderPath = "FBX_Scaffolding_01/SM_Scaffolding_Ladder_01";
private static readonly string[] DropLadderChildren = new string[5] { "Blocker", "Bolt", "Cube", "PF_ImpactParticles", "Placement Ref" };
private static readonly string[] DropLobbyPrefixes = new string[5] { "Button", "Message", "Waypoint", "PF_SecurityCamera", "PF_Item_" };
private static readonly string[] DropRoomPrefixes = new string[2] { "PF_Item_", "PF_Whiteboard" };
private static readonly FieldRef<QuartersRoom, int> RoomIndex = AccessTools.FieldRefAccess<QuartersRoom, int>("_playerIndex");
private static readonly FieldRef<NetworkIdentity, bool> HasSpawned = AccessTools.FieldRefAccess<NetworkIdentity, bool>("hasSpawned");
private static GameObject _annex;
private static Dictionary<string, MeshData> _meshData;
private static readonly Dictionary<string, Mesh> MeshCache = new Dictionary<string, Mesh>();
private static Mesh _liningMesh;
internal static bool Built => (Object)(object)_annex != (Object)null;
internal static Vector3 AnnexCenter => OrigCenter + Offset;
internal static bool Contains(Vector3 pos)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: 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)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
if (!Built)
{
return false;
}
Vector3 annexCenter = AnnexCenter;
if (pos.y > annexCenter.y - 0.6f && pos.y < annexCenter.y + 8f)
{
Vector2 val = new Vector2(pos.x - annexCenter.x, pos.z - annexCenter.z);
return ((Vector2)(ref val)).sqrMagnitude < 256f;
}
return false;
}
internal static bool LobbyContains(Vector3 pos)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: 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)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
if (!Built)
{
return false;
}
Vector3 annexCenter = AnnexCenter;
if (pos.y > annexCenter.y - 1f && pos.y < annexCenter.y + 8f)
{
Vector2 val = new Vector2(pos.x - annexCenter.x, pos.z - annexCenter.z);
return ((Vector2)(ref val)).sqrMagnitude < 92.16f;
}
return false;
}
internal static void EnsureBuilt()
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Expected O, but got Unknown
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.AnnexEnabled.Value || (Object)(object)_annex != (Object)null)
{
return;
}
QuartersRoom val = QuartersRoom.Get(0);
if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).transform.parent == (Object)null)
{
return;
}
Transform parent = ((Component)val).transform.parent;
GameObject val2 = new GameObject("CMP_AnnexHolder");
val2.SetActive(false);
SceneManager.MoveGameObjectToScene(val2, ((Component)parent).gameObject.scene);
try
{
_annex = Build(parent, val2.transform);
}
catch (Exception ex)
{
Plugin.Log.LogError((object)("[Annex] build failed, players 5+ will share rooms instead. Every player must see the same result or they will desync.\n" + ex));
if ((Object)(object)_annex != (Object)null)
{
Object.Destroy((Object)(object)_annex);
}
_annex = null;
}
finally
{
Object.Destroy((Object)(object)val2);
}
}
private static GameObject Build(Transform root, Transform holder)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: 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_0201: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_021e: Unknown result type (might be due to invalid IL or missing references)
//IL_0228: Unknown result type (might be due to invalid IL or missing references)
//IL_022d: Unknown result type (might be due to invalid IL or missing references)
//IL_0232: Unknown result type (might be due to invalid IL or missing references)
//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
//IL_031f: Unknown result type (might be due to invalid IL or missing references)
//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
int roomCount = Plugin.RoomCount;
LoadMeshData();
Transform ladderSource = FindLadderSource(((Component)root).gameObject.scene);
Transform val = FindGate(((Component)root).gameObject.scene);
GameObject val2 = Object.Instantiate<GameObject>(((Component)root).gameObject, holder);
((Object)val2).name = ((Object)root).name + " (Annex)";
List<(MeshRenderer, MeshRenderer, string)> list = new List<(MeshRenderer, MeshRenderer, string)>();
List<(NetworkIdentity, NetworkIdentity)> identities = new List<(NetworkIdentity, NetworkIdentity)>();
Pair(root, val2.transform, root, "", list, identities);
val2.transform.position = root.position + Offset;
foreach (Transform item in Children(val2.transform))
{
if (((Object)item).name.StartsWith("PF_QuartersRoom"))
{
foreach (Transform item2 in Children(item))
{
if (StartsWithAny(((Object)item2).name, DropRoomPrefixes))
{
Object.DestroyImmediate((Object)(object)((Component)item2).gameObject);
}
}
}
else if (StartsWithAny(((Object)item).name, DropLobbyPrefixes))
{
Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
}
else if (!((Object)item).name.StartsWith("SM_Computer_Monitor") && (Object)(object)((Component)item).GetComponentInChildren<NetworkIdentity>(true) != (Object)null)
{
Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
}
}
QuartersRoom[] componentsInChildren = val2.GetComponentsInChildren<QuartersRoom>(true);
foreach (QuartersRoom val3 in componentsInChildren)
{
RoomIndex.Invoke(val3) += roomCount;
}
GameObject val4 = Object.Instantiate<GameObject>(((Component)val).gameObject, val2.transform);
((Object)val4).name = "CMP_AnnexGate";
Pair(val, val4.transform, val, "G:", list, null);
StripGate(val4.transform);
val4.transform.SetPositionAndRotation(val.position + Offset, val.rotation);
val4.transform.localScale = val.lossyScale;
Rect hatch = HatchRect(HatchCenter);
Transform val5 = val2.transform.Find("SM_QuartersLobby_Floor");
if ((Object)(object)val5 == (Object)null)
{
throw new InvalidOperationException("missing lobby floor");
}
int num = 0;
foreach (var (orig, val6, key) in list)
{
if (!((Object)(object)val6 == (Object)null))
{
bool flag = (Object)(object)((Component)val6).transform == (Object)(object)val5;
RebuildVisual(orig, val6, key, flag ? new Rect?(HatchRect(HatchCenter - Offset)) : ((Rect?)null));
num++;
}
}
CutBoxCollider(((Component)val5).GetComponent<BoxCollider>(), HatchCenter, 1.3f, 1.2f);
AnnexLighting.Setup(val2);
AssignSceneIds(identities);
GameObject obj = BuildHatch(root, ladderSource, holder, hatch);
val2.transform.SetParent((Transform)null, true);
obj.transform.SetParent((Transform)null, true);
return val2;
}
private static Rect HatchRect(Vector3 center)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
return new Rect(center.x - 0.65f, center.z - 0.6f, 1.3f, 1.2f);
}
private static Transform FindGate(Scene scene)
{
GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects();
foreach (GameObject val in rootGameObjects)
{
if (!(((Object)val).name != "Lab"))
{
Transform val2 = val.transform.Find("Walls/PF_Lab_WallSection/SM_LabWall_GarageOpening (1)");
if ((Object)(object)val2 != (Object)null)
{
return val2;
}
}
}
throw new InvalidOperationException("quarters gate not found");
}
private static void StripGate(Transform gate)
{
foreach (Transform item in Children(gate))
{
if (StartsWithAny(((Object)item).name, DropGateChildren))
{
Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
}
}
NetworkBehaviour[] componentsInChildren = ((Component)gate).GetComponentsInChildren<NetworkBehaviour>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
}
NetworkIdentity[] componentsInChildren2 = ((Component)gate).GetComponentsInChildren<NetworkIdentity>(true);
for (int i = 0; i < componentsInChildren2.Length; i++)
{
Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
}
((Component)gate).gameObject.SetActive(true);
}
private static Transform FindLadderSource(Scene scene)
{
GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects();
foreach (GameObject val in rootGameObjects)
{
if (((Object)val).name.StartsWith("PF_PushScaffold"))
{
Transform val2 = val.transform.Find("FBX_Scaffolding_01/SM_Scaffolding_Ladder_01");
if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).GetComponentInChildren<Ladder>(true) != (Object)null)
{
return val2;
}
}
}
throw new InvalidOperationException("no scaffold ladder found to copy");
}
private static GameObject BuildHatch(Transform root, Transform ladderSource, Transform holder, Rect hatch)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
//IL_023e: Unknown result type (might be due to invalid IL or missing references)
//IL_0245: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_0257: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("CMP_QuartersHatch");
val.transform.SetParent(holder, false);
Transform val2 = root.Find("Ceiling");
if ((Object)(object)val2 == (Object)null)
{
throw new InvalidOperationException("missing lobby ceiling");
}
MeshRenderer component = ((Component)val2).GetComponent<MeshRenderer>();
RebuildVisual(component, component, KeyOf(val2, root), hatch);
CutBoxCollider(((Component)val2).GetComponent<BoxCollider>(), HatchCenter, 1.3f, 1.2f);
float num = 7.4500003f;
float num2 = Offset.y + 0.05f - num;
float num3 = 0.05f;
Material sharedMaterial = ((Renderer)component).sharedMaterial;
Vector2 uv = _meshData[KeyOf(val2, root)].NearestUv0(HatchCenter + Vector3.up * 7.55f);
Vector3 hatchCenter = HatchCenter;
AddLining(val.transform, sharedMaterial, uv, new Vector3(((Rect)(ref hatch)).xMin - num3 / 2f, num + num2 / 2f, hatchCenter.z), new Vector3(num3, num2, 1.2f + 2f * num3));
AddLining(val.transform, sharedMaterial, uv, new Vector3(((Rect)(ref hatch)).xMax + num3 / 2f, num + num2 / 2f, hatchCenter.z), new Vector3(num3, num2, 1.2f + 2f * num3));
AddLining(val.transform, sharedMaterial, uv, new Vector3(hatchCenter.x, num + num2 / 2f, ((Rect)(ref hatch)).yMin - num3 / 2f), new Vector3(1.3f, num2, num3));
AddLining(val.transform, sharedMaterial, uv, new Vector3(hatchCenter.x, num + num2 / 2f, ((Rect)(ref hatch)).yMax + num3 / 2f), new Vector3(1.3f, num2, num3));
Quaternion val3 = Quaternion.LookRotation(Vector3.right);
float num4 = ((Rect)(ref hatch)).xMin - 0.05f;
float num5 = Offset.y;
while (num5 - 3f + 0.21f > -0.5f)
{
GameObject obj = Object.Instantiate<GameObject>(((Component)ladderSource).gameObject, val.transform);
((Object)obj).name = "CMP_HatchLadder";
StripBuildSystem(obj.transform);
obj.transform.SetPositionAndRotation(new Vector3(num4, num5, hatchCenter.z), val3);
obj.transform.localScale = Vector3.one;
obj.SetActive(true);
Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
componentsInChildren[i].enabled = true;
}
num5 -= 3f;
}
return val;
}
private static void StripBuildSystem(Transform piece)
{
foreach (Transform item in Children(piece))
{
if (StartsWithAny(((Object)item).name, DropLadderChildren))
{
Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
}
}
MonoBehaviour[] componentsInChildren = ((Component)piece).GetComponentsInChildren<MonoBehaviour>(true);
foreach (MonoBehaviour val in componentsInChildren)
{
if (!(val is Ladder))
{
Object.DestroyImmediate((Object)(object)val);
}
}
Collider[] componentsInChildren2 = ((Component)piece).GetComponentsInChildren<Collider>(true);
foreach (Collider val2 in componentsInChildren2)
{
if (val2.isTrigger && (Object)(object)((Component)val2).GetComponent<Ladder>() == (Object)null)
{
Object.DestroyImmediate((Object)(object)val2);
}
}
}
private static void AddLining(Transform parent, Material material, Vector2 uv, Vector3 center, Vector3 size)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
((Object)val).name = "CMP_HatchLining";
val.transform.SetParent(parent, false);
val.transform.SetPositionAndRotation(center, Quaternion.identity);
val.transform.localScale = size;
MeshFilter component = val.GetComponent<MeshFilter>();
if ((Object)(object)_liningMesh == (Object)null)
{
_liningMesh = Object.Instantiate<Mesh>(component.sharedMesh);
((Object)_liningMesh).name = "CMP_HatchLining";
Vector2[] array = (Vector2[])(object)new Vector2[_liningMesh.vertexCount];
for (int i = 0; i < array.Length; i++)
{
array[i] = uv;
}
_liningMesh.uv = array;
}
component.sharedMesh = _liningMesh;
if ((Object)(object)material != (Object)null)
{
((Renderer)val.GetComponent<MeshRenderer>()).sharedMaterial = material;
}
}
private static void CutBoxCollider(BoxCollider box, Vector3 holeWorld, float sizeX, float sizeZ)
{
//IL_001b: 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_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: 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_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)box == (Object)null)
{
throw new InvalidOperationException("hatch surface has no box collider");
}
Transform transform = ((Component)box).transform;
Vector3 val = transform.InverseTransformPoint(holeWorld);
Vector3 val2 = transform.InverseTransformVector(new Vector3(sizeX / 2f, 0f, 0f));
Vector3 val3 = transform.InverseTransformVector(new Vector3(0f, 0f, sizeZ / 2f));
float num = Mathf.Abs(val2.x) + Mathf.Abs(val3.x);
float num2 = Mathf.Abs(val2.z) + Mathf.Abs(val3.z);
Vector3 center = box.center;
Vector3 size = box.size;
float x = center.x - size.x / 2f;
float x2 = center.x + size.x / 2f;
float z = center.z - size.z / 2f;
float z2 = center.z + size.z / 2f;
float num3 = val.x - num;
float num4 = val.x + num;
float z3 = val.z - num2;
float z4 = val.z + num2;
AddBox(box, x, num3, z, z2);
AddBox(box, num4, x2, z, z2);
AddBox(box, num3, num4, z, z3);
AddBox(box, num3, num4, z4, z2);
((Collider)box).enabled = false;
}
private static void AddBox(BoxCollider like, float x0, float x1, float z0, float z1)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
if (!(x1 - x0 < 0.01f) && !(z1 - z0 < 0.01f))
{
BoxCollider obj = ((Component)like).gameObject.AddComponent<BoxCollider>();
obj.center = new Vector3((x0 + x1) / 2f, like.center.y, (z0 + z1) / 2f);
obj.size = new Vector3(x1 - x0, like.size.y, z1 - z0);
((Collider)obj).isTrigger = ((Collider)like).isTrigger;
((Collider)obj).sharedMaterial = ((Collider)like).sharedMaterial;
}
}
private static void Pair(Transform o, Transform c, Transform root, string keyPrefix, List<(MeshRenderer, MeshRenderer, string)> visuals, List<(NetworkIdentity, NetworkIdentity)> identities)
{
MeshRenderer component = ((Component)o).GetComponent<MeshRenderer>();
if ((Object)(object)component != (Object)null && ((Renderer)component).isPartOfStaticBatch)
{
visuals.Add((component, ((Component)c).GetComponent<MeshRenderer>(), keyPrefix + KeyOf(o, root)));
}
NetworkIdentity component2 = ((Component)o).GetComponent<NetworkIdentity>();
if ((Object)(object)component2 != (Object)null)
{
identities?.Add((component2, ((Component)c).GetComponent<NetworkIdentity>()));
}
for (int i = 0; i < o.childCount; i++)
{
Pair(o.GetChild(i), c.GetChild(i), root, keyPrefix, visuals, identities);
}
}
private static void RebuildVisual(MeshRenderer orig, MeshRenderer target, string key, Rect? hole)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
string key2 = (hole.HasValue ? (key + "#" + ((object)hole.Value/*cast due to .constrained prefix*/).ToString()) : key);
if (!MeshCache.TryGetValue(key2, out var value))
{
if (!_meshData.TryGetValue(key, out var value2))
{
Plugin.Log.LogWarning((object)("[Annex] no extracted mesh for '" + ((Object)orig).name + "' (" + key + "), hiding it"));
((Renderer)target).enabled = false;
return;
}
Bounds bounds = ((Renderer)orig).bounds;
((Bounds)(ref bounds)).Expand(0.5f);
if (!((Bounds)(ref bounds)).Contains(value2.Centroid))
{
Plugin.Log.LogWarning((object)("[Annex] extracted mesh for '" + ((Object)orig).name + "' (" + key + ") doesn't match its renderer, hiding it"));
((Renderer)target).enabled = false;
return;
}
Mesh val = (MeshCache[key2] = value2.ToLocalMesh(((Component)orig).transform, ((Object)orig).name, hole));
value = val;
}
GameObject val3 = new GameObject(((Object)orig).name + " (visual)")
{
layer = ((Component)target).gameObject.layer
};
val3.transform.SetParent(((Component)target).transform, false);
val3.AddComponent<MeshFilter>().sharedMesh = value;
MeshRenderer obj = val3.AddComponent<MeshRenderer>();
((Renderer)obj).sharedMaterials = ((Renderer)orig).sharedMaterials;
((Renderer)obj).shadowCastingMode = ((Renderer)orig).shadowCastingMode;
((Renderer)obj).receiveShadows = ((Renderer)orig).receiveShadows;
((Renderer)obj).lightProbeUsage = ((Renderer)orig).lightProbeUsage;
((Renderer)obj).reflectionProbeUsage = ((Renderer)orig).reflectionProbeUsage;
((Renderer)obj).renderingLayerMask = ((Renderer)orig).renderingLayerMask;
((Renderer)obj).lightmapIndex = ((Renderer)orig).lightmapIndex;
((Renderer)obj).lightmapScaleOffset = new Vector4(1f, 1f, 0f, 0f);
((Renderer)obj).enabled = ((Renderer)orig).enabled;
((Renderer)target).enabled = false;
}
private static void AssignSceneIds(List<(NetworkIdentity orig, NetworkIdentity copy)> identities)
{
HashSet<ulong> hashSet = new HashSet<ulong>();
NetworkIdentity[] array = Resources.FindObjectsOfTypeAll<NetworkIdentity>();
foreach (NetworkIdentity val in array)
{
if (val.sceneId != 0L)
{
hashSet.Add(val.sceneId);
}
}
foreach (var (val2, val3) in identities)
{
if (!((Object)(object)val3 == (Object)null))
{
ulong num = val2.sceneId & 0xFFFFFFFF00000000uL;
uint a = (uint)val2.sceneId;
uint num2 = 0u;
ulong num3;
do
{
num3 = num | Fnv(a, 2720923648u + num2++);
}
while (hashSet.Contains(num3));
hashSet.Add(num3);
val3.sceneId = num3;
HasSpawned.Invoke(val3) = false;
}
}
}
private static uint Fnv(uint a, uint b)
{
uint num = 2166136261u;
for (int i = 0; i < 4; i++)
{
num ^= (a >> 8 * i) & 0xFF;
num *= 16777619;
}
for (int j = 0; j < 4; j++)
{
num ^= (b >> 8 * j) & 0xFF;
num *= 16777619;
}
if (num != 0)
{
return num;
}
return 1u;
}
private static List<Transform> Children(Transform t)
{
List<Transform> list = new List<Transform>(t.childCount);
for (int i = 0; i < t.childCount; i++)
{
list.Add(t.GetChild(i));
}
return list;
}
private static bool StartsWithAny(string s, string[] prefixes)
{
foreach (string value in prefixes)
{
if (s.StartsWith(value, StringComparison.Ordinal))
{
return true;
}
}
return false;
}
private static string KeyOf(Transform t, Transform root)
{
List<string> list = new List<string>();
while ((Object)(object)t != (Object)(object)root)
{
list.Add(t.GetSiblingIndex().ToString());
t = t.parent;
}
list.Reverse();
return string.Join("/", list.ToArray());
}
private static void LoadMeshData()
{
if (_meshData != null)
{
return;
}
string text = Path.Combine(Path.GetDirectoryName(typeof(Plugin).Assembly.Location), "quarters_meshes.bin");
Dictionary<string, MeshData> dictionary = new Dictionary<string, MeshData>();
using (FileStream stream = File.OpenRead(text))
{
using GZipStream input = new GZipStream(stream, CompressionMode.Decompress);
using BinaryReader binaryReader = new BinaryReader(input);
if (new string(binaryReader.ReadChars(4)) != "CMPQ")
{
throw new InvalidDataException(text + ": bad header");
}
if (binaryReader.ReadInt32() != 1)
{
throw new InvalidDataException(text + ": unsupported version");
}
int num = binaryReader.ReadInt32();
for (int i = 0; i < num; i++)
{
string key = new string(binaryReader.ReadChars(binaryReader.ReadInt32()));
dictionary[key] = MeshData.Read(binaryReader);
}
}
_meshData = dictionary;
}
}
[HarmonyPatch(typeof(NetworkServer), "SpawnObjects")]
internal static class AnnexServerPatch
{
private static void Prefix()
{
QuartersAnnex.EnsureBuilt();
}
}
[HarmonyPatch(typeof(NetworkClient), "PrepareToSpawnSceneObjects")]
internal static class AnnexClientPatch
{
private static void Prefix()
{
QuartersAnnex.EnsureBuilt();
}
}
[HarmonyPatch(typeof(QuartersRoom), "IsInAnyQuarters")]
internal static class AnnexInQuartersPatch
{
private static void Postfix(Vector3 pos, ref bool __result)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
if (!__result)
{
__result = QuartersAnnex.LobbyContains(pos);
}
}
}
}