Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Dungeon Splitter v1.7.0
DungeonSplitter.dll
Decompiled 8 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("DungeonSplitter")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+543217092404682fad71fd46713b2bbbe0b5c76e")] [assembly: AssemblyProduct("DungeonSplitter")] [assembly: AssemblyTitle("DungeonSplitter")] [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 DungeonSplitter { [BepInPlugin("dungeon_splitter", "Dungeon Splitter", "1.7")] public class DungeonSplitter : BaseUnityPlugin { public const string GUID = "dungeon_splitter"; public const string NAME = "Dungeon Splitter"; public const string VERSION = "1.7"; public static ConfigEntry<string> configAlwaysSend; public static ConfigEntry<float> configDungeonHeight; public static float DungeonHeight => configDungeonHeight.Value; public void Awake() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) configAlwaysSend = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Always send", "", "List of object ids that are always sent to clients. Separate with commas."); configAlwaysSend.SettingChanged += delegate { DungeonPrefabs.Postfix(); }; configDungeonHeight = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Dungeon height", 1500f, "Height at which the dungeon starts."); SetupWatcher(); new Harmony("dungeon_splitter").PatchAll(); } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath)); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath)) { return; } try { ((BaseUnityPlugin)this).Config.Reload(); } catch { Debug.LogWarning((object)"Failed to reload config file"); } } } [HarmonyPatch(typeof(ZDOMan), "CreateSyncList")] public class CreateSyncList { private static void Prefix(ZDOPeer peer) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) StateManager.Check(peer.m_peer.m_refPos); FindObjects.IsSending = true; } } [HarmonyPatch(typeof(ZDOMan), "ReleaseNearbyZDOS")] public class ReleaseNearbyZDOS { private static bool Prefix(ZDOMan __instance, Vector3 refPosition, long uid) { //IL_0002: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) StateManager.Check(refPosition); FindObjects.IsSending = false; Vector2i zone = ZoneSystem.GetZone(refPosition); int activeArea = ZoneSystem.instance.m_activeArea; int num = zone.x - activeArea; int num2 = zone.y - activeArea; int num3 = zone.x + activeArea; int num4 = zone.y + activeArea; Vector2i val = default(Vector2i); for (int i = num; i <= num3; i++) { for (int j = num2; j <= num4; j++) { ((Vector2i)(ref val))..ctor(i, j); int num5 = __instance.SectorToIndex(val); List<ZDO> value; if (num5 >= 0) { if (__instance.m_objectsBySector[num5] != null) { Process(__instance, __instance.m_objectsBySector[num5], val, uid); } } else if (__instance.m_objectsByOutsideSector.TryGetValue(val, out value)) { Process(__instance, value, val, uid); } } } return false; } private static void Process(ZDOMan zm, List<ZDO> objects, Vector2i zone, long uid) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_009d: 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) foreach (ZDO @object in objects) { if (!@object.Persistent) { continue; } bool flag = @object.m_position.y >= DungeonSplitter.DungeonHeight; bool flag2 = (flag ? StateManager.InDungeon : StateManager.OnGround); if (@object.GetOwner() == uid) { if (!flag2 || !ZNetScene.InActiveArea(@object.GetSector(), zone)) { @object.SetOwner(0L); } } else if (flag2 && (!@object.HasOwner() || !IsInPeerSameLevel(zm, flag, @object.GetOwner()) || !zm.IsInPeerActiveArea(@object.GetSector(), @object.GetOwner())) && ZNetScene.InActiveArea(@object.GetSector(), zone)) { @object.SetOwner(uid); } } } private static bool IsInPeerSameLevel(ZDOMan zm, bool inDungeon, long uid) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (uid == zm.m_sessionID) { return ZNet.instance.GetReferencePosition().y >= DungeonSplitter.DungeonHeight == inDungeon; } ZNetPeer peer = ZNet.instance.GetPeer(uid); if (peer != null) { return peer.m_refPos.y >= DungeonSplitter.DungeonHeight == inDungeon; } return false; } } [HarmonyPatch(typeof(ZNetScene), "CreateDestroyObjects")] public class CreateDestroyObjects { private static double LastCheck; private static bool AnyNearby; private static void Prefix() { //IL_0024: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return; } double netTime = ZNet.instance.m_netTime; Vector3 pos = ZNet.instance.GetReferencePosition(); if (netTime - LastCheck > 5.0) { LastCheck = netTime; AnyNearby = ZNet.instance.GetPeers().Any((ZNetPeer peer) => peer.IsReady() && Utils.DistanceXZ(peer.m_refPos, pos) < 300f); } if (AnyNearby) { StateManager.CheckForRemove(pos); } else { StateManager.Check(pos); } FindObjects.IsSending = false; } } [HarmonyPatch(typeof(ZNetScene), "IsAreaReady")] public class IsAreaReady { private static void Prefix(Vector3 point) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) StateManager.Check(point); FindObjects.IsSending = false; } } [HarmonyPatch(typeof(ZDOMan), "FindObjects")] public class FindObjects { public static HashSet<int> AlwaysSend = new HashSet<int>(); public static HashSet<int> AlwaysLoad = new HashSet<int>(); public static bool IsSending; private static bool Prefix(ZDOMan __instance, Vector2i sector, List<ZDO> objects) { //IL_0001: 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) int num = __instance.SectorToIndex(sector); List<ZDO> value; if (num >= 0) { if (__instance.m_objectsBySector[num] != null) { List<ZDO> list = new List<ZDO>(); list.AddRange(__instance.m_objectsBySector[num].Where(IsOk)); objects.AddRange(new <>z__ReadOnlyList<ZDO>(list)); return false; } } else if (__instance.m_objectsByOutsideSector.TryGetValue(sector, out value)) { List<ZDO> list2 = new List<ZDO>(); list2.AddRange(value.Where(IsOk)); objects.AddRange(new <>z__ReadOnlyList<ZDO>(list2)); } return false; } public static bool IsOk(ZDO zdo) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!AlwaysLoad.Contains(zdo.m_prefab) && !StateManager.IsSameLevel(zdo.m_position)) { if (IsSending) { return AlwaysSend.Contains(zdo.m_prefab); } return false; } return true; } } [HarmonyPatch(typeof(ZDOMan), "FindDistantObjects")] public class FindDistantObjects { private static bool Prefix(ZDOMan __instance, Vector2i sector, List<ZDO> objects) { //IL_0001: 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) int num = __instance.SectorToIndex(sector); if (num >= 0) { List<ZDO> list = __instance.m_objectsBySector[num]; if (list == null) { return false; } List<ZDO> list2 = new List<ZDO>(); list2.AddRange(list.Where((ZDO zdo) => zdo.Distant && StateManager.IsSameLevel(zdo.m_position))); objects.AddRange(new <>z__ReadOnlyList<ZDO>(list2)); return false; } if (__instance.m_objectsByOutsideSector.TryGetValue(sector, out var value)) { List<ZDO> list3 = new List<ZDO>(); list3.AddRange(value.Where((ZDO zdo) => zdo.Distant && StateManager.IsSameLevel(zdo.m_position))); objects.AddRange(new <>z__ReadOnlyList<ZDO>(list3)); } return false; } } [HarmonyPatch(typeof(ZoneSystem), "Start")] public class DungeonPrefabs { public static int ProxyHash = StringExtensionMethods.GetStableHashCode("LocationProxy"); public static int PlayerHash = StringExtensionMethods.GetStableHashCode("Player"); public static int ZoneCtrlHash = StringExtensionMethods.GetStableHashCode("_ZoneCtrl"); public static int TerrainCompilerHash = StringExtensionMethods.GetStableHashCode("_TerrainCompiler"); public static void Postfix() { HashSet<int> hashSet = new HashSet<int>(); foreach (int item in from prefab in ZNetScene.instance.m_namedPrefabs.Values where Object.op_Implicit((Object)(object)prefab.GetComponentInChildren<Teleport>()) select StringExtensionMethods.GetStableHashCode(((Object)prefab).name)) { hashSet.Add(item); } FindObjects.AlwaysLoad = hashSet; FindObjects.AlwaysLoad.Add(ProxyHash); FindObjects.AlwaysLoad.Add(ZoneCtrlHash); FindObjects.AlwaysLoad.Add(TerrainCompilerHash); hashSet = new HashSet<int>(); foreach (int item2 in from prefab in ZNetScene.instance.m_namedPrefabs.Values where Object.op_Implicit((Object)(object)prefab.GetComponent<DungeonGenerator>()) select StringExtensionMethods.GetStableHashCode(((Object)prefab).name)) { hashSet.Add(item2); } FindObjects.AlwaysSend = hashSet; foreach (string item3 in from str in DungeonSplitter.configAlwaysSend.Value.Split(new char[1] { ',' }) select str.Trim() into str where !string.IsNullOrEmpty(str) select str) { FindObjects.AlwaysSend.Add(StringExtensionMethods.GetStableHashCode(item3)); } FindObjects.AlwaysSend.Add(PlayerHash); } } public class StateManager { public static bool InDungeon; public static bool OnGround; public static double LastDungeon; public static double LastGround; private const double Delay = 2.5; public static bool IsSameLevel(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (!(pos.y >= DungeonSplitter.DungeonHeight)) { return OnGround; } return InDungeon; } public static void Check(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) OnGround = !(InDungeon = pos.y >= DungeonSplitter.DungeonHeight); } public static void CheckForRemove(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) bool num = pos.y >= DungeonSplitter.DungeonHeight; double netTime = ZNet.instance.m_netTime; if (num) { InDungeon = true; LastDungeon = netTime; OnGround = netTime - LastGround <= 2.5; } else { OnGround = true; LastGround = netTime; InDungeon = netTime - LastDungeon <= 2.5; } } } } internal sealed class <>z__ReadOnlyList<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T> { int ICollection.Count => _items.Count; bool ICollection.IsSynchronized => false; object ICollection.SyncRoot => this; object IList.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } bool IList.IsFixedSize => true; bool IList.IsReadOnly => true; int IReadOnlyCollection<T>.Count => _items.Count; T IReadOnlyList<T>.this[int index] => _items[index]; int ICollection<T>.Count => _items.Count; bool ICollection<T>.IsReadOnly => true; T IList<T>.this[int index] { get { return _items[index]; } set { throw new NotSupportedException(); } } public <>z__ReadOnlyList(List<T> items) { _items = items; } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)_items).GetEnumerator(); } void ICollection.CopyTo(Array array, int index) { ((ICollection)_items).CopyTo(array, index); } int IList.Add(object value) { throw new NotSupportedException(); } void IList.Clear() { throw new NotSupportedException(); } bool IList.Contains(object value) { return ((IList)_items).Contains(value); } int IList.IndexOf(object value) { return ((IList)_items).IndexOf(value); } void IList.Insert(int index, object value) { throw new NotSupportedException(); } void IList.Remove(object value) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return ((IEnumerable<T>)_items).GetEnumerator(); } void ICollection<T>.Add(T item) { throw new NotSupportedException(); } void ICollection<T>.Clear() { throw new NotSupportedException(); } bool ICollection<T>.Contains(T item) { return _items.Contains(item); } void ICollection<T>.CopyTo(T[] array, int arrayIndex) { _items.CopyTo(array, arrayIndex); } bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); } int IList<T>.IndexOf(T item) { return _items.IndexOf(item); } void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); } void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); } }