Decompiled source of Map Editing extender v1.0.3
Map_Editing_extender.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using DM; using HarmonyLib; using Landfall.TABS; using Landfall.TABS.GameState; using Landfall.TABS.TeamEdge; using Landfall.TABS_Input; using LevelCreator; using Pathfinding; using SCPE; using TFBGames; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.Rendering.PostProcessing; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Mod name")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("made in SFT by FhpSlime")] [assembly: AssemblyCopyright("Copyright © 2022")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("3a45c3cf-230c-4310-952f-0887d4266a22")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace MAPX { public static class UManager { public static string modname; public static string modder; private static string com; static UManager() { modname = "SFT"; modder = "FhpSlime"; } public static void SetRiders(UnitBlueprint me, UnitBlueprint[] riders) { } public static void EditBlueprint(UnitBlueprint unit, LandfallContentDatabase db) { } public static void EditClothes(GameObject cloth, CharacterItem item, PropItemData data, Unit unit, int index, LandfallContentDatabase db) { } public static void EditProjectiles(GameObject proj, ProjectileHit projhit, Unit unit, LandfallContentDatabase db) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (unit.unitBlueprint.Entity.Name == "unit name") { Transform transform = proj.transform; transform.localScale *= 3f; } } public static void EditCombatMoves(GameObject move, int index, Unit unit, LandfallContentDatabase db) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00ba: Expected O, but got Unknown if (unit.unitBlueprint.Entity.Name == "unit name" && Object.op_Implicit((Object)(object)move.GetComponentInChildren<DodgeMove>())) { move.GetComponentInChildren<DodgeMove>().moves[0].forceCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[5] { new Keyframe(0f, 1f), new Keyframe(1f, -2f), new Keyframe(2f, 5f), new Keyframe(6f, -16f), new Keyframe(8f, 0f) }); } } public static void CodeAfterSpawn(Unit unit, LandfallContentDatabase db) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (unit.unitBlueprint.Entity.Name == "unit name") { Transform head = unit.data.head; head.localScale *= 2f; } } public static void Init(LandfallContentDatabase db) { MyModItems.GetInstance(); com = "——————————Fations and Units——————————"; com = "——————————Clothes——————————"; com = "——————————Weapons——————————"; com = "——————————Effects——————————"; com = "——————————Explosions——————————"; com = "——————————UnitBases——————————"; com = "——————————Projectiles——————————"; com = "——————————Moves——————————"; } public static void EditWeapons(GameObject weapon, Team team, Unit unit, MeleeWeapon melee, RangeWeapon range, LandfallContentDatabase db) { } } [BepInPlugin("mapX", "mapX", "1.0.0")] internal class Loader : BaseUnityPlugin { private void Awake() { ((MonoBehaviour)this).StartCoroutine("call"); } private IEnumerator call() { yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)Object.FindObjectOfType<ServiceLocator>() != (Object)null)); yield return (object)new WaitUntil((Func<bool>)(() => ServiceLocator.GetService<ISaveLoaderService>() != null)); yield return (object)new WaitForSecondsRealtime(0.3f); UManager.Init(ContentDatabase.Instance().LandfallContentDatabase); new Harmony(UManager.modname).PatchAll(); Debug.Log((object)"[Mod_Name] 正在应用地图编辑器限制突破补丁..."); LevelEditorPatches.ApplyPatches(); } } } public class Item : MonoBehaviour { public enum kind { Weapon, Cloth, Skill, Unit, Projectile, Other } public string name; public kind Kind; } namespace MAPX { public class MyModItems : MonoBehaviour { private static Dictionary<string, Item> items; private static MyModItems instance { get; set; } public static MyModItems GetInstance() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)instance == (Object)null) { instance = new GameObject("MyModItems").AddComponent<MyModItems>(); Object.DontDestroyOnLoad((Object)(object)instance); } return instance; } public void AddItem(Item item) { items.Add(item.name, item); } public Item GetItem(string name) { Item value = new Item { name = null, Kind = Item.kind.Other }; items.TryGetValue(name, out value); return value; } } internal static class LevelEditorPatches { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Action<object> <>9__92_0; public static Comparison<KeyValuePair<Vector3Int, float>> <>9__41_0; public static Func<ParameterInfo, string> <>9__48_0; public static Func<ParameterInfo, string> <>9__48_1; public static Action<object> <>9__93_0; public static UnityAction <>9__143_0; public static UnityAction <>9__143_1; public static UnityAction <>9__143_2; public static UnityAction <>9__143_3; public static UnityAction <>9__143_4; internal int <TrimChunksByDistanceAndImportance>b__41_0(KeyValuePair<Vector3Int, float> a, KeyValuePair<Vector3Int, float> b) { return b.Value.CompareTo(a.Value); } internal string <PatchPlaceObjectStateOnRotate>b__48_0(ParameterInfo p) { return p.ParameterType.Name + " " + p.Name; } internal string <PatchPlaceObjectStateOnRotate>b__48_1(ParameterInfo p) { return p.ParameterType.Name + " " + p.Name; } internal void <LevelSettings_InitWeatherList_Postfix>b__92_0(object index) { DMEditor.Instance.SetWeather((int)index); } internal void <LevelSettings_InitMusicList_Postfix>b__93_0(object music) { DMEditor.Instance.SetMusic((string)music); } internal void <ToolBar_BuildSubHotbars_Postfix>b__143_0() { SwitchToMaterialReplacerTool(); } internal void <ToolBar_BuildSubHotbars_Postfix>b__143_1() { SwitchToWaterEffectTool(); } internal void <ToolBar_BuildSubHotbars_Postfix>b__143_2() { SwitchToSkyboxTool(); } internal void <ToolBar_BuildSubHotbars_Postfix>b__143_3() { SwitchToTransformTool(); } internal void <ToolBar_BuildSubHotbars_Postfix>b__143_4() { SwitchToFilterTool(); } } private enum RotationAxis { X, Y, Z } private const int ScaleFactor = 3; private static bool s_boundsExpanded; private static Vector3Int? s_baselineChunkCount; private const int MaxChunkCount = 20000; private static float s_throttleUntil; private static readonly float s_throttledQuota; private static SpawnLevelState s_lastState; private static bool s_navResetDone; private static Dictionary<Settings, string> s_customMusicNames; private static Dictionary<Settings, string> s_customMusicNamesLatest; private static string s_pendingCustomMusicName; private static RotationAxis s_currentRotationAxis; internal static Sprite s_materialReplacerIcon; internal static MaterialReplacerTool s_materialReplacerToolInstance; private static bool s_restoringMaterials; private static bool s_isInitialLoad; private static float s_lastUpdateLevelTime; private static bool s_updateLevelInProgress; private static WeatherParticleCameraFollower s_weatherParticleFollower; private static float s_updateLevelStartTime; private const float UPDATE_LEVEL_TIMEOUT = 15f; private static FieldInfo s_mapRadiusSqrField; private static HashSet<CameraMovement> s_disabledInstances; private static bool s_sizeLimitLoaded; private static Vector3Int? s_customChunkCount; private static Vector3Int? s_expandedChunkCount; private static FieldInfo s_waterSizeXField; private static FieldInfo s_waterSizeZField; private static Vector3? s_customWaterSize; private static Vector3 s_defaultWaterSize; private static Dictionary<object, Vector3> s_waterSizeCache; private static Dictionary<object, Vector3> s_levelLatestWaterSizeCache; private static Vector3? s_deserializedWaterSize; private static FieldInfo s_waterSizeYField; private static FieldInfo s_waterPosXField; private static FieldInfo s_waterPosZField; internal static Sprite s_waterEffectIcon; internal static WaterEffectTool s_waterEffectToolInstance; private static Vector2? s_customWaterPositionXZ; private static Dictionary<object, Vector2> s_waterPositionXZCache; private static Dictionary<object, Vector2> s_levelLatestWaterPositionXZCache; private static Vector2? s_deserializedWaterPositionXZ; private static readonly Vector2 s_waterPlayModeOffsetXZ; internal static Sprite s_skyboxIcon; internal static SkyboxTool s_skyboxToolInstance; internal static Sprite s_transformIcon; internal static TransformTool s_transformToolInstance; private static Coroutine s_updateLevelCoroutine; internal static Sprite s_filterIcon; internal static FilterTool s_filterToolInstance; internal static AssetBundle s_renderAssetBundle; internal static bool s_renderBundleLoaded; private static string s_currentSavingFilePath; private static HashSet<PostProcessVolume> s_adjustedVolumes; public static bool IsTerrainLoading { get; private set; } public static void ApplyPatches() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) new Harmony(UManager.modname + ".LevelEditorPatches").PatchAll(typeof(LevelEditorPatches)); LogLevelUtilConstants(); CustomMusicManager.Create(); PatchPlaceObjectStateOnRotate(); PatchPlaceObjectStateOnScale(); PatchScaleMethods(); } public static void LogCurrentLimits() { //IL_0005: 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_0041: 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) Debug.Log((object)$"[LevelEditorPatches] chunkCount={Level.chunkCount}"); Debug.Log((object)$"[LevelEditorPatches] voxelBounds size={((BoundsInt)(ref VoxelChunk.voxelBounds)).size}"); Debug.Log((object)$"[LevelEditorPatches] materialBounds size={((BoundsInt)(ref MaterialChunk.materialBounds)).size}"); Debug.Log((object)$"[LevelEditorPatches] foliageBounds size={((BoundsInt)(ref FoliageChunk.foliageBounds)).size}"); } private static void EnsureChunkExists(Volume volume, Vector3Int chunkPosition) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0032: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_0072: 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_0078: 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_00b3: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_00f5: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) if (!(typeof(Volume).GetField("m_volumeMeshChunks", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(volume) as Dictionary<Vector3Int, VolumeMeshChunk>).ContainsKey(chunkPosition)) { VolumeChunk val = new VolumeChunk { voxelChunk = new VoxelChunk { densities = new float[((Vector3Int)(ref VoxelChunk.noOfCells)).z + 1, ((Vector3Int)(ref VoxelChunk.noOfCells)).y + 1, ((Vector3Int)(ref VoxelChunk.noOfCells)).x + 1], version = 0 }, materialChunk = new MaterialChunk { densities = new float[((Vector3Int)(ref MaterialChunk.noOfCells)).z + 1, ((Vector3Int)(ref MaterialChunk.noOfCells)).y + 1, ((Vector3Int)(ref MaterialChunk.noOfCells)).x + 1], version = 0 }, foliageChunk = new FoliageChunk { densities = new float[((Vector3Int)(ref FoliageChunk.noOfCells)).z + 1, ((Vector3Int)(ref FoliageChunk.noOfCells)).y + 1, ((Vector3Int)(ref FoliageChunk.noOfCells)).x + 1], version = 0 } }; MethodInfo method = typeof(Volume).GetMethod("SetChunk", BindingFlags.Instance | BindingFlags.Public); if (!(method == null)) { method.Invoke(volume, new object[2] { chunkPosition, val }); } } } [HarmonyPrefix] [HarmonyPatch(typeof(SpawnLevel), "Awake")] private static void SpawnLevel_Awake_Prefix() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) ExpandBounds(); s_lastState = (SpawnLevelState)0; s_navResetDone = false; } private static void ExpandBounds() { //IL_018f: 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_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0045: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0207: 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_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) try { LoadSizeLimitFromFile(); Vector3Int value; if (!s_boundsExpanded) { s_baselineChunkCount = Level.chunkCount; value = s_baselineChunkCount.Value; int num = Mathf.Max(1, ((Vector3Int)(ref value)).x * 3); value = s_baselineChunkCount.Value; int num2 = Mathf.Max(1, ((Vector3Int)(ref value)).y * 3); value = s_baselineChunkCount.Value; Vector3Int val = default(Vector3Int); ((Vector3Int)(ref val))..ctor(num, num2, Mathf.Max(1, ((Vector3Int)(ref value)).z * 3)); Vector3Int val2 = default(Vector3Int); if (s_customChunkCount.HasValue) { int x = ((Vector3Int)(ref val)).x; value = s_customChunkCount.Value; int num3 = Mathf.Max(x, ((Vector3Int)(ref value)).x); int y = ((Vector3Int)(ref val)).y; value = s_customChunkCount.Value; int num4 = Mathf.Max(y, ((Vector3Int)(ref value)).y); int z = ((Vector3Int)(ref val)).z; value = s_customChunkCount.Value; ((Vector3Int)(ref val2))..ctor(num3, num4, Mathf.Max(z, ((Vector3Int)(ref value)).z)); } else { val2 = val; } Level.chunkCount = val2; s_expandedChunkCount = val2; VoxelChunk.voxelBounds = new BoundsInt(Vector3Int.one, Level.chunkCount * VoxelChunk.noOfCells - Vector3Int.one); MaterialChunk.materialBounds = new BoundsInt(Vector3Int.zero, Level.chunkCount * MaterialChunk.noOfCells + Vector3Int.one); FoliageChunk.foliageBounds = new BoundsInt(Vector3Int.zero, Level.chunkCount * FoliageChunk.noOfCells); s_boundsExpanded = true; Debug.Log((object)$"[LevelEditorPatches] Expanded chunkCount to {Level.chunkCount}"); return; } value = s_baselineChunkCount.Value; int num5 = Mathf.Max(1, ((Vector3Int)(ref value)).x * 3); value = s_baselineChunkCount.Value; int num6 = Mathf.Max(1, ((Vector3Int)(ref value)).y * 3); value = s_baselineChunkCount.Value; Vector3Int val3 = default(Vector3Int); ((Vector3Int)(ref val3))..ctor(num5, num6, Mathf.Max(1, ((Vector3Int)(ref value)).z * 3)); Vector3Int? val4 = s_expandedChunkCount; ? val5; if (!val4.HasValue) { if (!s_customChunkCount.HasValue) { val5 = val3; } else { int x2 = ((Vector3Int)(ref val3)).x; value = s_customChunkCount.Value; int num7 = Mathf.Max(x2, ((Vector3Int)(ref value)).x); int y2 = ((Vector3Int)(ref val3)).y; value = s_customChunkCount.Value; int num8 = Mathf.Max(y2, ((Vector3Int)(ref value)).y); int z2 = ((Vector3Int)(ref val3)).z; value = s_customChunkCount.Value; val5 = new Vector3Int(num7, num8, Mathf.Max(z2, ((Vector3Int)(ref value)).z)); } } else { val5 = val4.GetValueOrDefault(); } Vector3Int val6 = (Vector3Int)val5; if (Level.chunkCount != val6) { Level.chunkCount = val6; VoxelChunk.voxelBounds = new BoundsInt(Vector3Int.one, Level.chunkCount * VoxelChunk.noOfCells - Vector3Int.one); MaterialChunk.materialBounds = new BoundsInt(Vector3Int.zero, Level.chunkCount * MaterialChunk.noOfCells + Vector3Int.one); FoliageChunk.foliageBounds = new BoundsInt(Vector3Int.zero, Level.chunkCount * FoliageChunk.noOfCells); Debug.Log((object)"[LevelEditorPatches] Reapplied expanded bounds after reset"); } } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to expand bounds: " + ex)); } } [HarmonyPostfix] [HarmonyPatch(typeof(Level_Latest), "ParseLevel")] private static void LevelLatest_ParseLevel_Postfix(ref Level_Latest __result) { try { if ((Object)(object)Object.FindObjectOfType<DMEditor>() != (Object)null) { Debug.Log((object)"[LevelEditorPatches] Skipping empty chunk pruning in editor mode to preserve all terrain"); } else if (__result != null && __result.chunks != null && __result.chunks.compressedVoxelChunks != null) { List<CompressedChunk> compressedVoxelChunks = __result.chunks.compressedVoxelChunks; int count = compressedVoxelChunks.Count; compressedVoxelChunks.RemoveAll(IsEmptyCompressedChunk); int count2 = compressedVoxelChunks.Count; if (count != count2) { Debug.Log((object)$"[LevelEditorPatches] Pruned empty chunks: {count - count2} removed, {count2} kept"); } } } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to prune empty chunks: " + ex)); } } private static bool IsEmptyCompressedChunk(CompressedChunk c) { //IL_0000: 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) try { if (string.IsNullOrEmpty(c.voxelDensities)) { return true; } byte[] array = Convert.FromBase64String(c.voxelDensities); if (array.Length >= 2 && array[0] == 0) { return array[1] == 0; } if (array.Length > 1 && array[0] == 1) { int num = 0; for (int i = 1; i < array.Length; i++) { if (array[i] != 0) { num++; if (num > 0) { break; } } } return num == 0; } } catch { } return false; } [HarmonyPostfix] [HarmonyPatch(typeof(Level_Latest), "BuildLevel")] private static void LevelLatest_BuildLevel_Postfix(ref Level __result) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) try { if (__result == null || __result.volume == null || __result.volume.volumeChunks == null) { return; } if ((Object)(object)Object.FindObjectOfType<DMEditor>() != (Object)null) { Debug.Log((object)"[LevelEditorPatches] Skipping chunk pruning in editor mode to preserve all terrain"); return; } Dictionary<Vector3Int, VolumeChunk> volumeChunks = __result.volume.volumeChunks; List<Vector3Int> list = new List<Vector3Int>(); foreach (KeyValuePair<Vector3Int, VolumeChunk> item in volumeChunks) { if (IsEmptyVolumeChunk(item.Value)) { list.Add(item.Key); } } for (int i = 0; i < list.Count; i++) { volumeChunks.Remove(list[i]); } if (list.Count > 0) { Debug.Log((object)$"[LevelEditorPatches] Pruned empty chunks on load: {list.Count}"); } TrimChunksByDistanceAndImportance(volumeChunks, 5000); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to prune empty chunks on load: " + ex)); } } private static bool IsEmptyVolumeChunk(VolumeChunk chunk) { if (chunk == null || chunk.voxelChunk == null || chunk.voxelChunk.densities == null) { return true; } float[,,] densities = chunk.voxelChunk.densities; for (int i = 0; i < densities.GetLength(0) - 1; i++) { for (int j = 0; j < densities.GetLength(1) - 1; j++) { for (int k = 0; k < densities.GetLength(2) - 1; k++) { if (densities[i, j, k] > 0f) { return false; } } } } return true; } private static void TrimChunksByDistanceAndImportance(Dictionary<Vector3Int, VolumeChunk> dict, int maxCount) { //IL_001f: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_003f: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) try { int count = dict.Count; if (count <= maxCount || maxCount <= 0 || Application.isPlaying) { return; } Vector3 val = Vector3.zero; foreach (Vector3Int key in dict.Keys) { val += Vector3Int.op_Implicit(key); } val /= (float)Mathf.Max(1, count); List<KeyValuePair<Vector3Int, float>> list = new List<KeyValuePair<Vector3Int, float>>(count); foreach (KeyValuePair<Vector3Int, VolumeChunk> item in dict) { Vector3 val2 = Vector3Int.op_Implicit(item.Key) - val; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; float value = SumDensitiesFast(item.Value.voxelChunk?.densities) - sqrMagnitude * 0.001f; list.Add(new KeyValuePair<Vector3Int, float>(item.Key, value)); } list.Sort((KeyValuePair<Vector3Int, float> a, KeyValuePair<Vector3Int, float> b) => b.Value.CompareTo(a.Value)); for (int i = maxCount; i < list.Count; i++) { dict.Remove(list[i].Key); } Debug.Log((object)$"[LevelEditorPatches] Trimmed chunks: kept {maxCount}, pruned {Mathf.Max(0, list.Count - maxCount)}"); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to trim chunks: " + ex)); } } private static float SumDensitiesFast(float[,,] d) { if (d == null) { return 0f; } float num = 0f; int num2 = d.GetLength(0) - 1; int num3 = d.GetLength(1) - 1; int num4 = d.GetLength(2) - 1; for (int i = 0; i < num2; i += 2) { for (int j = 0; j < num3; j += 2) { for (int k = 0; k < num4; k += 2) { num += d[i, j, k]; } } } return num; } [HarmonyPostfix] [HarmonyPatch(typeof(Volume), "Update")] private static void Volume_Update_Postfix(Volume __instance) { try { if (Time.realtimeSinceStartup <= s_throttleUntil) { object value = typeof(Volume).GetField("m_volumeMeshChunkUpdater", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance); FieldInfo? field = value.GetType().GetField("updateQuotaInSeconds", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); float num = Mathf.Min((float)field.GetValue(value), s_throttledQuota); field.SetValue(value, num); } } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to throttle volume updates: " + ex)); } } static LevelEditorPatches() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) s_materialReplacerIcon = null; s_materialReplacerToolInstance = null; s_waterEffectIcon = null; s_waterEffectToolInstance = null; s_skyboxIcon = null; s_skyboxToolInstance = null; s_transformIcon = null; s_transformToolInstance = null; s_filterIcon = null; s_filterToolInstance = null; s_renderAssetBundle = null; s_renderBundleLoaded = false; s_restoringMaterials = false; s_isInitialLoad = true; s_lastUpdateLevelTime = 0f; s_updateLevelInProgress = false; s_updateLevelStartTime = 0f; s_updateLevelCoroutine = null; s_weatherParticleFollower = null; s_sizeLimitLoaded = false; s_customChunkCount = null; s_expandedChunkCount = null; s_customWaterSize = null; s_customWaterPositionXZ = null; s_defaultWaterSize = new Vector3(1f, 1f, 1f); s_currentSavingFilePath = null; s_currentRotationAxis = RotationAxis.Y; s_customMusicNames = new Dictionary<Settings, string>(); s_customMusicNamesLatest = new Dictionary<Settings, string>(); s_pendingCustomMusicName = null; s_mapRadiusSqrField = null; s_disabledInstances = new HashSet<CameraMovement>(); s_waterSizeCache = new Dictionary<object, Vector3>(); s_waterPositionXZCache = new Dictionary<object, Vector2>(); s_levelLatestWaterSizeCache = new Dictionary<object, Vector3>(); s_levelLatestWaterPositionXZCache = new Dictionary<object, Vector2>(); s_deserializedWaterSize = null; s_deserializedWaterPositionXZ = null; s_waterSizeXField = null; s_waterSizeYField = null; s_waterSizeZField = null; s_waterPosXField = null; s_waterPosZField = null; s_waterPlayModeOffsetXZ = new Vector2(-65f, -35f); s_adjustedVolumes = new HashSet<PostProcessVolume>(); s_throttledQuota = 0.0016666667f; s_navResetDone = false; s_lastState = (SpawnLevelState)0; } [HarmonyPrefix] [HarmonyPatch(typeof(Volume), "SetChunks")] private static bool Volume_SetChunks_Prefix(Volume __instance, Dictionary<Vector3Int, VolumeChunk> volumeChunks) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) try { if (volumeChunks == null) { return true; } bool flag = (Object)(object)Object.FindObjectOfType<DMEditor>() != (Object)null; Dictionary<Vector3Int, VolumeChunk> dictionary = new Dictionary<Vector3Int, VolumeChunk>(volumeChunks.Count); foreach (KeyValuePair<Vector3Int, VolumeChunk> volumeChunk in volumeChunks) { if (!IsEmptyVolumeChunk(volumeChunk.Value)) { dictionary[volumeChunk.Key] = volumeChunk.Value; } } if (flag) { Debug.Log((object)"[LevelEditorPatches] Skipping distance trimming in editor mode for Volume.SetChunks"); } else { TrimChunksByDistanceAndImportance(dictionary, 5000); } ((MonoBehaviour)__instance).StartCoroutine(StageSetChunks(__instance, dictionary)); return false; } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to stage SetChunks: " + ex)); return true; } } private static IEnumerator StageSetChunks(Volume vol, Dictionary<Vector3Int, VolumeChunk> target) { IsTerrainLoading = true; FieldInfo field = typeof(Volume).GetField("m_volumeMeshChunks", BindingFlags.Instance | BindingFlags.NonPublic); if (!(field.GetValue(vol) is Dictionary<Vector3Int, VolumeMeshChunk> existingMap)) { Debug.LogError((object)"[LevelEditorPatches] Failed to get m_volumeMeshChunks field"); IsTerrainLoading = false; yield break; } List<Vector3Int> toRemove = new List<Vector3Int>(); foreach (KeyValuePair<Vector3Int, VolumeMeshChunk> item in existingMap) { if (!target.ContainsKey(item.Key)) { toRemove.Add(item.Key); } } for (int i = 0; i < toRemove.Count; i++) { Vector3Int key = toRemove[i]; if (existingMap.TryGetValue(key, out var value)) { existingMap.Remove(key); if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)((Component)value).gameObject); } } if (i % 20 == 0) { yield return null; } } int added = 0; float realtimeSinceStartup = Time.realtimeSinceStartup; foreach (KeyValuePair<Vector3Int, VolumeChunk> item2 in target) { try { vol.SetChunk(item2.Key, item2.Value); } catch (Exception arg) { Debug.LogError((object)$"[LevelEditorPatches] Error setting chunk at {item2.Key}: {arg}"); } added++; if (added % 10 == 0 || Time.realtimeSinceStartup - realtimeSinceStartup > 0.01f) { yield return null; realtimeSinceStartup = Time.realtimeSinceStartup; } } yield return null; IsTerrainLoading = false; } [HarmonyPostfix] [HarmonyPatch(typeof(TABSSceneManager), "LoadLevelCreator")] private static void TABSSceneManager_LoadLevelCreator_Postfix() { MonoBehaviour val = Object.FindObjectOfType<MonoBehaviour>(); if ((Object)(object)val == (Object)null) { return; } val.StartCoroutine(DelayedExpandBounds()); if ((Object)(object)s_weatherParticleFollower != (Object)null) { if ((Object)(object)((Component)s_weatherParticleFollower).gameObject != (Object)null) { Object.Destroy((Object)(object)s_weatherParticleFollower); } s_weatherParticleFollower = null; } } private static IEnumerator DelayedExpandBounds() { yield return (object)new WaitForSeconds(0.1f); ExpandBounds(); } public static void LogObjectPlacementLimits() { try { Debug.Log((object)$"[LevelEditorPatches] maxObjectCount={2000}"); Debug.Log((object)$"[LevelEditorPatches] maxHiearchyDepth={5}"); Debug.Log((object)$"[LevelEditorPatches] positionRange=[{-16f}, {144f}]"); Debug.Log((object)$"[LevelEditorPatches] scaleRange=[{0.1f}, {40f}]"); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to log object placement limits: " + ex)); } } [HarmonyPrefix] [HarmonyPatch(typeof(LevelUtil), "AnalyzeLevel")] private static bool LevelUtil_AnalyzeLevel_Prefix(GameObject rootObject, ref AnalyzeLevelResult __result) { try { __result = (AnalyzeLevelResult)0; Debug.Log((object)"[LevelEditorPatches] Bypassed all object placement limits via AnalyzeLevel patch"); return false; } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to bypass placement limits: " + ex)); return true; } } [HarmonyPrefix] [HarmonyPatch(typeof(DMEditor), "Start")] private static void DMEditor_Start_Prefix() { try { LeanTween.init(10000); Debug.Log((object)"[LevelEditorPatches] Increased LeanTween init count to 10000"); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to increase LeanTween init count: " + ex)); } } [HarmonyPostfix] [HarmonyPatch(typeof(TABSSceneManager), "LoadLevelCreator")] private static void TABSSceneManager_LoadLevelCreator_Postfix_ObjectLimits() { try { MonoBehaviour val = Object.FindObjectOfType<MonoBehaviour>(); if ((Object)(object)val != (Object)null) { val.StartCoroutine(DelayedObjectLimitsSetup()); } } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to setup object limits on scene load: " + ex)); } } private static IEnumerator DelayedObjectLimitsSetup() { yield return (object)new WaitForSeconds(0.2f); try { LogObjectPlacementLimits(); Debug.Log((object)"[LevelEditorPatches] Object placement limits setup completed"); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to complete object limits setup: " + ex)); } } private static void LogLevelUtilConstants() { try { Debug.Log((object)$"[LevelEditorPatches] Original maxObjectCount={2000}"); Debug.Log((object)$"[LevelEditorPatches] Original maxHiearchyDepth={5}"); Debug.Log((object)$"[LevelEditorPatches] Original positionRange=[{-16f}, {144f}]"); Debug.Log((object)$"[LevelEditorPatches] Original scaleRange=[{0.1f}, {40f}]"); Debug.Log((object)"[LevelEditorPatches] Note: These constants cannot be modified at runtime, but AnalyzeLevel method is patched to bypass all checks"); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to log LevelUtil constants: " + ex)); } } [HarmonyPostfix] [HarmonyPatch(typeof(SpawnLevel), "BuildLevelData")] private static void SpawnLevel_BuildLevelData_Postfix(SpawnLevel __instance) { } [HarmonyPrefix] [HarmonyPatch(typeof(SpawnLevel), "PathFindingScan")] private static void SpawnLevel_PathFindingScan_Prefix(SpawnLevel __instance) { } [HarmonyPostfix] [HarmonyPatch(typeof(SpawnLevel), "Update")] private static void SpawnLevel_Update_Postfix(SpawnLevel __instance) { //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_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 try { SpawnLevelState getSpawnLevelState = SpawnLevel.GetSpawnLevelState; if (getSpawnLevelState != s_lastState) { s_lastState = getSpawnLevelState; } if (!s_navResetDone && (int)getSpawnLevelState == 4 && SpawnLevel.finishedPathfindingScan) { s_navResetDone = true; ((MonoBehaviour)__instance).StartCoroutine(ResetNavmeshOnce()); } } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to schedule pathfinding rescan: " + ex)); } } [HarmonyPrefix] [HarmonyPatch(typeof(DamageOverTimeEffect), "ResetUnitColours")] private static bool DamageOverTimeEffect_ResetUnitColours_Prefix(DamageOverTimeEffect __instance) { try { if ((Object)(object)__instance == (Object)null) { return false; } FieldInfo field = typeof(DamageOverTimeEffect).GetField("removedColor", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(__instance); if (value is bool && (bool)value) { return false; } } FieldInfo field2 = typeof(DamageOverTimeEffect).GetField("colorHandler", BindingFlags.Instance | BindingFlags.NonPublic); if (field2 == null) { return true; } object value2 = field2.GetValue(__instance); if (value2 == null) { if (field != null) { field.SetValue(__instance, true); } return false; } FieldInfo field3 = typeof(DamageOverTimeEffect).GetField("color", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); object obj = null; if (field3 != null) { obj = field3.GetValue(__instance); if (obj == null) { if (field != null) { field.SetValue(__instance, true); } return false; } } PropertyInfo property = value2.GetType().GetProperty("colors", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null) { if (field != null) { field.SetValue(__instance, true); } return false; } object value3 = property.GetValue(value2); if (value3 == null) { if (field != null) { field.SetValue(__instance, true); } return false; } PropertyInfo property2 = value3.GetType().GetProperty("Count", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property2 == null) { if (field != null) { field.SetValue(__instance, true); } return false; } string text = null; if (obj != null) { PropertyInfo property3 = obj.GetType().GetProperty("colorName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property3 != null) { object value4 = property3.GetValue(obj); if (value4 != null) { text = value4.ToString(); } } } try { int num = (int)property2.GetValue(value3); MethodInfo method = value3.GetType().GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); PropertyInfo property4 = value3.GetType().GetProperty("Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int num2 = num - 1; num2 >= 0; num2--) { try { object obj2 = null; if (method != null) { obj2 = method.Invoke(value3, new object[1] { num2 }); } else if (property4 != null) { obj2 = property4.GetValue(value3, new object[1] { num2 }); } if (obj2 != null && text != null) { PropertyInfo property5 = obj2.GetType().GetProperty("colorName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property5 != null) { object value5 = property5.GetValue(obj2); if (value5 != null && value5.ToString() == text) { MethodInfo method2 = value3.GetType().GetMethod("RemoveAt", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method2 != null) { method2.Invoke(value3, new object[1] { num2 }); } } } } } catch { } } MethodInfo method3 = value2.GetType().GetMethod("UpdateColors", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method3 != null) { try { method3.Invoke(value2, null); } catch { } } if (field != null) { field.SetValue(__instance, true); } } catch (Exception arg) { Debug.LogWarning((object)$"[LevelEditorPatches] Error executing ResetUnitColours logic: {arg}"); if (field != null) { field.SetValue(__instance, true); } } return false; } catch (Exception ex) { Debug.LogWarning((object)("[LevelEditorPatches] Error in DamageOverTimeEffect.ResetUnitColours patch: " + ex)); try { FieldInfo field4 = typeof(DamageOverTimeEffect).GetField("removedColor", BindingFlags.Instance | BindingFlags.NonPublic); if (field4 != null && (Object)(object)__instance != (Object)null) { field4.SetValue(__instance, true); } } catch { } return false; } } private static void ExpandPathfindingBounds(SpawnLevel spawnLevel) { } private static IEnumerator ResetNavmeshOnce() { yield return null; try { AstarPath active = AstarPath.active; if ((Object)(object)active == (Object)null) { Debug.LogWarning((object)"[LevelEditorPatches] AstarPath.active is null, skip nav reset"); yield break; } Bounds? colliderBounds = GetColliderBounds(); if (colliderBounds.HasValue) { Bounds value = colliderBounds.Value; if (!(((Bounds)(ref value)).size == Vector3.zero)) { Bounds value2 = colliderBounds.Value; NavGraph[] graphs = active.graphs; foreach (NavGraph obj in graphs) { RecastGraph val; if ((val = (RecastGraph)(object)((obj is RecastGraph) ? obj : null)) != null) { val.mask = LayerMask.op_Implicit(512); val.forcedBoundsCenter = ((Bounds)(ref value2)).center; ((NavmeshBase)val).forcedBoundsSize = ((Bounds)(ref value2)).size; } } Debug.Log((object)"[LevelEditorPatches] Resetting navmesh with collider bounds..."); active.Scan(active.graphs); Debug.Log((object)"[LevelEditorPatches] Navmesh reset complete."); yield break; } } Debug.LogWarning((object)"[LevelEditorPatches] No collider bounds found, skip nav reset"); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Navmesh reset failed: " + ex)); } } private static Bounds? GetColliderBounds() { //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) Bounds? result; try { Collider[] array = Object.FindObjectsOfType<Collider>(); if (array == null || array.Length == 0) { return null; } Bounds bounds = array[0].bounds; for (int i = 1; i < array.Length; i++) { ((Bounds)(ref bounds)).Encapsulate(array[i].bounds); } return bounds; } catch { result = null; } return result; } [HarmonyPrefix] [HarmonyPatch(typeof(SpawnLevel), "ReturnToEditor")] private static void SpawnLevel_ReturnToEditor_Prefix() { try { s_adjustedVolumes.Clear(); FilterMenu.PreserveFilterResourcesBeforeSceneUnload(); ExpandBounds(); s_throttleUntil = Time.realtimeSinceStartup + 5f; Debug.Log((object)"[LevelEditorPatches] Maintained expanded bounds when returning to editor"); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed to maintain expanded bounds: " + ex)); } } [HarmonyPrefix] [HarmonyPatch(typeof(Volume), "GetModifiableVoxelChunkDensities", new Type[] { typeof(Vector3Int) })] private static void Volume_GetModifiableVoxelChunkDensities_Prefix(Volume __instance, Vector3Int chunkPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) EnsureChunkExists(__instance, chunkPosition); } [HarmonyPrefix] [HarmonyPatch(typeof(Volume), "GetModifiableMaterialChunkDensities", new Type[] { typeof(Vector3Int) })] private static void Volume_GetModifiableMaterialChunkDensities_Prefix(Volume __instance, Vector3Int chunkPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) EnsureChunkExists(__instance, chunkPosition); } [HarmonyPrefix] [HarmonyPatch(typeof(Volume), "GetModifiableFoliageChunkDensities", new Type[] { typeof(Vector3Int) })] private static void Volume_GetModifiableFoliageChunkDensities_Prefix(Volume __instance, Vector3Int chunkPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) EnsureChunkExists(__instance, chunkPosition); } [HarmonyPrefix] [HarmonyPatch(typeof(MeshBuilder), "GetMaterial", new Type[] { typeof(float[,,]), typeof(Vector3), typeof(Vector3Int) })] private static bool MeshBuilder_GetMaterial_Prefix(float[,,] materials, Vector3 midPoint, Vector3Int limitedChunkSize, ref float __result) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) try { if (materials == null) { __result = 0f; return false; } int length = materials.GetLength(2); int length2 = materials.GetLength(1); int length3 = materials.GetLength(0); if (length <= 0 || length2 <= 0 || length3 <= 0) { __result = 0f; return false; } int num = Mathf.Max(0, Mathf.Min(((Vector3Int)(ref limitedChunkSize)).x, length) - 1); int num2 = Mathf.Max(0, Mathf.Min(((Vector3Int)(ref limitedChunkSize)).y, length2) - 1); int num3 = Mathf.Max(0, Mathf.Min(((Vector3Int)(ref limitedChunkSize)).z, length3) - 1); Vector3 val = new Vector3(midPoint.x * (float)((Vector3Int)(ref MaterialChunk.noOfCells)).x / (float)((Vector3Int)(ref VoxelChunk.noOfCells)).x, midPoint.y * (float)((Vector3Int)(ref MaterialChunk.noOfCells)).y / (float)((Vector3Int)(ref VoxelChunk.noOfCells)).y, midPoint.z * (float)((Vector3Int)(ref MaterialChunk.noOfCells)).z / (float)((Vector3Int)(ref VoxelChunk.noOfCells)).z); int num4 = Mathf.Clamp(Mathf.FloorToInt(val.x), 0, num); int num5 = Mathf.Clamp(num4 + 1, 0, num); float num6 = val.x - (float)num4; int num7 = Mathf.Clamp(Mathf.FloorToInt(val.y), 0, num2); int num8 = Mathf.Clamp(num7 + 1, 0, num2); float num9 = val.y - (float)num7; int num10 = Mathf.Clamp(Mathf.FloorToInt(val.z), 0, num3); int num11 = Mathf.Clamp(num10 + 1, 0, num3); float num12 = val.z - (float)num10; if (num10 >= 0 && num10 < length3 && num7 >= 0 && num7 < length2 && num4 >= 0 && num4 < length && num5 >= 0 && num5 < length && num8 >= 0 && num8 < length2 && num11 >= 0 && num11 < length3) { __result = Utility.LerpCyclic(Utility.LerpCyclic(Utility.LerpCyclic(materials[num10, num7, num4], materials[num10, num7, num5], num6), Utility.LerpCyclic(materials[num10, num8, num4], materials[num10, num8, num5], num6), num9), Utility.LerpCyclic(Utility.LerpCyclic(materials[num11, num7, num4], materials[num11, num7, num5], num6), Utility.LerpCyclic(materials[num11, num8, num4], materials[num11, num8, num5], num6), num9), num12); return false; } __result = 0f; return false; } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Error in GetMaterial patch: " + ex)); __result = 0f; return false; } } [HarmonyPrefix] [HarmonyPatch(typeof(DMEditor), "UpdateLevel")] private static bool DMEditor_UpdateLevel_Prefix(DMEditor __instance) { //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) if (s_updateLevelInProgress) { float num = Time.time - s_updateLevelStartTime; if (!(num > 15f)) { Debug.LogWarning((object)"[LevelEditorPatches] UpdateLevel 被调用但已有操作在进行中,跳过本次调用"); return false; } Debug.LogWarning((object)$"[LevelEditorPatches] UpdateLevel 执行超时({num:F1}秒),强制重置并允许新的调用"); s_updateLevelInProgress = false; s_updateLevelStartTime = 0f; if (s_updateLevelCoroutine != null && (Object)(object)__instance != (Object)null) { ((MonoBehaviour)__instance).StopCoroutine(s_updateLevelCoroutine); s_updateLevelCoroutine = null; } } bool flag = false; try { StackTrace stackTrace = new StackTrace(); for (int i = 0; i < stackTrace.FrameCount && i < 10; i++) { StackFrame frame = stackTrace.GetFrame(i); if (frame != null && frame.GetMethod() != null) { string name = frame.GetMethod().Name; if (name == "Undo" || name == "Redo") { flag = true; break; } } } } catch { if ((Object)(object)__instance.LevelRootObject != (Object)null) { DMEditorComponent[] componentsInChildren = __instance.LevelRootObject.GetComponentsInChildren<DMEditorComponent>(true); flag = !s_isInitialLoad && componentsInChildren != null && componentsInChildren.Length != 0; } } if (s_isInitialLoad) { s_isInitialLoad = false; } if (!flag && !s_isInitialLoad && (Object)(object)__instance.LevelRootObject != (Object)null) { DMEditorComponent[] componentsInChildren2 = __instance.LevelRootObject.GetComponentsInChildren<DMEditorComponent>(true); if (componentsInChildren2 != null && componentsInChildren2.Length != 0) { flag = true; } } if (flag) { Debug.Log((object)"[LevelEditorPatches] 检测到撤回操作,使用同步方式快速执行"); s_updateLevelInProgress = true; s_updateLevelStartTime = Time.time; try { object? obj2 = typeof(DMEditor).GetField("m_levelVolume", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance); Volume val = (Volume)((obj2 is Volume) ? obj2 : null); if (val != null && val.volumeChunks != null) { __instance.VolumeRootObject.SetChunks(val.volumeChunks); } MethodInfo method = typeof(DMEditor).GetMethod("AddChildrenToExistingEditorObjects", BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { method.Invoke(__instance, new object[1] { __instance.LevelRootObject }); } object? obj3 = typeof(DMEditor).GetField("m_levelScene", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance); Scene val2 = (Scene)((obj3 is Scene) ? obj3 : null); if (val2 != null) { foreach (EntityTreeNode item in LevelUtil.BuildEntityTrees(val2.flatEntities)) { DMEditorComponent val3 = __instance.InstantiateEditorObjectUsingExistingEditorObjects(item, __instance.LevelRootObject); if ((Object)(object)val3 != (Object)null) { __instance.MarkObjectForSnapping(val3); } } } FieldInfo field = typeof(DMEditor).GetField("existingEditorObjects", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null && field.GetValue(__instance) is Dictionary<Guid, DMEditorComponent> dictionary) { foreach (KeyValuePair<Guid, DMEditorComponent> item2 in dictionary) { if ((Object)(object)item2.Value != (Object)null) { Object.Destroy((Object)(object)((Component)item2.Value).gameObject); } } dictionary.Clear(); } MethodInfo method2 = typeof(DMEditor).GetMethod("InitiateEditorObjects", BindingFlags.Instance | BindingFlags.NonPublic); if (method2 != null) { method2.Invoke(__instance, null); } } finally { s_updateLevelInProgress = false; s_updateLevelCoroutine = null; } return false; } if (s_updateLevelInProgress || s_updateLevelCoroutine != null) { Debug.LogWarning((object)"[LevelEditorPatches] UpdateLevel 被调用但已有协程在运行,跳过本次调用"); return false; } s_updateLevelInProgress = true; s_updateLevelStartTime = Time.time; s_updateLevelCoroutine = ((MonoBehaviour)__instance).StartCoroutine(UpdateLevelCoroutine(__instance, flag)); return false; } [HarmonyPostfix] [HarmonyPatch(typeof(LevelSettings), "InitMusicList")] private static void LevelSettings_InitMusicList_Postfix(LevelSettings __instance) { //IL_0097: 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_00d9: 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_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) try { if (!((Object)(object)CustomMusicManager.Instance != (Object)null) || CustomMusicManager.Instance.CustomCategories.Count <= 0) { return; } CycleSelector musicSelector = __instance.m_musicSelector; if ((Object)(object)musicSelector == (Object)null) { Debug.LogWarning((object)"[LevelEditorPatches] Music selector is null, skipping custom music injection"); return; } List<CycleSelectorOption> list = (List<CycleSelectorOption>)AccessTools.Field(typeof(CycleSelector), "m_options").GetValue(musicSelector); if (list == null) { Debug.LogWarning((object)"[LevelEditorPatches] Options list is null, skipping custom music injection"); return; } object obj = null; if (list.Count > 0) { int index = musicSelector.Index; if (index >= 0 && index < list.Count) { obj = list[index].value; } } foreach (string customCategory in CustomMusicManager.Instance.CustomCategories) { list.Add(new CycleSelectorOption { displayName = customCategory, value = customCategory }); } if (list.Count == 0) { Debug.LogWarning((object)"[LevelEditorPatches] Options list is empty after adding custom music, skipping Init"); return; } string text = null; if ((Object)(object)DMEditor.Instance != (Object)null && DMEditor.Instance.LevelSettings != null) { text = GetCustomMusicName(DMEditor.Instance.LevelSettings); } int num = 0; if (!string.IsNullOrEmpty(text)) { for (int i = 0; i < list.Count; i++) { if (list[i].value != null && list[i].value.Equals(text)) { num = i; break; } } } else if (obj != null) { for (int j = 0; j < list.Count; j++) { if (list[j].value != null && list[j].value.Equals(obj)) { num = j; break; } } } if (num < 0 || num >= list.Count) { Debug.LogWarning((object)$"[LevelEditorPatches] Calculated index {num} is out of range [0, {list.Count - 1}], using 0"); num = 0; } musicSelector.Init(list, (Action<object>)delegate(object music) { DMEditor.Instance.SetMusic((string)music); }, num); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Error in InitMusicList postfix: " + ex)); } } [HarmonyPostfix] [HarmonyPatch(typeof(MusicHandler), "Init")] private static void MusicHandler_Init_Postfix(MusicHandler __instance) { if (!((Object)(object)CustomMusicManager.Instance != (Object)null)) { return; } foreach (string customCategory in CustomMusicManager.Instance.CustomCategories) { CustomMusicManager.Instance.AddToHandler(__instance, customCategory); } } [HarmonyPrefix] [HarmonyPatch(typeof(DMEditor), "SetMusic", new Type[] { typeof(string) })] private static bool DMEditor_SetMusic_String_Prefix(string musicName, DMEditor __instance) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 if ((Object)(object)CustomMusicManager.Instance != (Object)null && CustomMusicManager.Instance.CustomCategories.Contains(musicName)) { GameStateManager service = ServiceLocator.GetService<GameStateManager>(); string text = ((service != null && (int)service.GameState == 1) ? "/Battle" : "/Placement"); MusicHandler service2 = ServiceLocator.GetService<MusicHandler>(); if ((Object)(object)service2 != (Object)null) { string text2 = musicName + text; if (service2.m_songs.ContainsKey(text2)) { service2.PlaySong(text2); CustomMusicManager.Instance.CurrentCustomMusicCategory = musicName; Settings levelSettings = __instance.LevelSettings; levelSettings.musicIndex = -1; SetCustomMusicName(levelSettings, musicName); Debug.Log((object)("[CustomMusicManager] Playing custom music: " + text2)); return false; } Debug.LogWarning((object)("[CustomMusicManager] Custom music not found: " + text2)); } return false; } if ((Object)(object)CustomMusicManager.Instance != (Object)null) { CustomMusicManager.Instance.CurrentCustomMusicCategory = string.Empty; } SetCustomMusicName(__instance.LevelSettings, null); return true; } [HarmonyPostfix] [HarmonyPatch(typeof(DMEditor), "SetMusic", new Type[] { typeof(int) })] private static void DMEditor_SetMusic_Int_Postfix(DMEditor __instance) { if ((Object)(object)CustomMusicManager.Instance != (Object)null) { CustomMusicManager.Instance.CurrentCustomMusicCategory = string.Empty; } Settings levelSettings = __instance.LevelSettings; if (levelSettings.musicIndex >= 0) { SetCustomMusicName(levelSettings, null); } } private static void SetCustomMusicName(Settings settings, string musicName) { if (settings != null) { if (string.IsNullOrEmpty(musicName)) { s_customMusicNames.Remove(settings); } else { s_customMusicNames[settings] = musicName; } } } private static string GetCustomMusicName(Settings settings) { if (settings == null) { return null; } s_customMusicNames.TryGetValue(settings, out var value); return value; } private static void SetCustomMusicNameLatest(Settings settings, string musicName) { if (settings != null) { if (string.IsNullOrEmpty(musicName)) { s_customMusicNamesLatest.Remove(settings); } else { s_customMusicNamesLatest[settings] = musicName; } } } private static string GetCustomMusicNameLatest(Settings settings) { if (settings == null) { return null; } s_customMusicNamesLatest.TryGetValue(settings, out var value); return value; } [HarmonyPostfix] [HarmonyPatch(typeof(Level_Latest), "ParseLevel")] private static void Level_Latest_ParseLevel_Postfix(Level level, ref Level_Latest __result) { //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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (__result == null || __result.settings == null || level == null || level.settings == null) { return; } string customMusicName = GetCustomMusicName(level.settings); if (!string.IsNullOrEmpty(customMusicName)) { bool flag = TrySetCustomMusicNameViaReflection(__result.settings, customMusicName); if (!flag) { SetCustomMusicNameLatest(__result.settings, customMusicName); } Debug.Log((object)("[CustomMusicManager] Serialized custom music name: " + customMusicName + " (reflection: " + flag + ")")); } try { Vector3 waterSize = GetWaterSize(level.settings); Vector2? waterPositionXZ = GetWaterPositionXZ(level.settings); if (waterSize != s_defaultWaterSize || s_customWaterSize.HasValue) { s_levelLatestWaterSizeCache[__result] = waterSize; Debug.Log((object)$"[LevelEditorPatches] 序列化时保存水体大小: ({waterSize.x}, {waterSize.y}, {waterSize.z})"); } if (waterPositionXZ.HasValue) { s_levelLatestWaterPositionXZCache[__result] = waterPositionXZ.Value; Debug.Log((object)$"[LevelEditorPatches] 序列化时保存水体位置XZ: ({waterPositionXZ.Value.x}, {waterPositionXZ.Value.y})"); } } catch (Exception arg) { Debug.LogError((object)$"[LevelEditorPatches] 保存水体大小/位置到序列化缓存时出错: {arg}"); } } [HarmonyPostfix] [HarmonyPatch(typeof(Level_Latest), "BuildLevel")] private static void Level_Latest_BuildLevel_Postfix(ref Level __result, Level_Latest __instance) { //IL_00a3: 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) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) if (__result == null || __result.settings == null || __instance == null || __instance.settings == null) { return; } string text = TryGetCustomMusicNameViaReflection(__instance.settings); if (string.IsNullOrEmpty(text)) { text = GetCustomMusicNameLatest(__instance.settings); } if (string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(s_pendingCustomMusicName)) { text = s_pendingCustomMusicName; SetCustomMusicNameLatest(__instance.settings, text); s_pendingCustomMusicName = null; } if (!string.IsNullOrEmpty(text)) { SetCustomMusicName(__result.settings, text); __result.settings.musicIndex = -1; Debug.Log((object)("[CustomMusicManager] Deserialized custom music name: " + text)); } try { Vector3 val = s_defaultWaterSize; Vector2? val2 = null; if (!s_deserializedWaterSize.HasValue) { val = (Vector3)((!s_levelLatestWaterSizeCache.TryGetValue(__instance, out var value)) ? (((??)s_customWaterSize) ?? s_defaultWaterSize) : value); } else { val = s_deserializedWaterSize.Value; s_deserializedWaterSize = null; } if (!s_deserializedWaterPositionXZ.HasValue) { val2 = ((!s_levelLatestWaterPositionXZCache.TryGetValue(__instance, out var value2)) ? s_customWaterPositionXZ : new Vector2?(value2)); } else { val2 = s_deserializedWaterPositionXZ.Value; s_deserializedWaterPositionXZ = null; } SetWaterSize(__result.settings, val); if (val2.HasValue) { SetWaterPositionXZ(__result.settings, val2); } s_waterSizeCache[__result.settings] = val; if (val2.HasValue) { s_waterPositionXZCache[__result.settings] = val2.Value; } object[] obj = new object[4] { val.x, val.y, val.z, null }; object obj2; if (!val2.HasValue) { obj2 = "使用原始位置"; } else { Vector2 value3 = val2.Value; obj2 = ((object)(Vector2)(ref value3)).ToString(); } obj[3] = obj2; Debug.Log((object)string.Format("[LevelEditorPatches] 反序列化时恢复水体大小: ({0}, {1}, {2}), 位置XZ: {3}", obj)); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] 从序列化缓存恢复水体大小/位置时出错: " + ex)); } } [HarmonyPostfix] [HarmonyPatch(typeof(SpawnLevel), "BuildLevelSettings")] private static void SpawnLevel_BuildLevelSettings_Postfix(SpawnLevel __instance, Settings settings) { //IL_0078: 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) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) try { if (settings != null) { string customMusicName = GetCustomMusicName(settings); if (string.IsNullOrEmpty(customMusicName) && settings.musicIndex == -1) { customMusicName = GetCustomMusicName(settings); } if (!string.IsNullOrEmpty(customMusicName)) { MusicHandler service = ServiceLocator.GetService<MusicHandler>(); if ((Object)(object)service != (Object)null) { service.OverrideSongCategory = customMusicName; if ((Object)(object)CustomMusicManager.Instance != (Object)null) { CustomMusicManager.Instance.CurrentCustomMusicCategory = customMusicName; } service.PlaySongPlacement(TABSSceneManager.CurrentLoadedMap); Debug.Log((object)("[CustomMusicManager] Loaded custom music in play mode: " + customMusicName)); } } try { Vector3 waterSize = GetWaterSize(settings); Vector2? waterPositionXZ = GetWaterPositionXZ(settings); FieldInfo field = typeof(SpawnLevel).GetField("water", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object? value = field.GetValue(__instance); GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val != (Object)null) { ApplyWaterSize(val, waterSize, waterPositionXZ, isPlayMode: true); object[] obj = new object[4] { waterSize.x, waterSize.y, waterSize.z, null }; object obj2; if (!waterPositionXZ.HasValue) { obj2 = "使用原始位置"; } else { Vector2 value2 = waterPositionXZ.Value; obj2 = ((object)(Vector2)(ref value2)).ToString(); } obj[3] = obj2; Debug.Log((object)string.Format("[LevelEditorPatches] 在游玩模式应用水体大小: ({0}, {1}, {2}), 位置XZ: {3} (已应用游玩模式偏移)", obj)); if (!string.IsNullOrEmpty(settings.presetName) && settings.presetName.Contains("Viking")) { ConvertWaterToIce(val); Debug.Log((object)"[LevelEditorPatches] Viking风格:已将自带水体转换为实体冰面"); } } else { Debug.LogWarning((object)"[LevelEditorPatches] 在游玩模式中,water 对象为 null"); } } else { Debug.LogWarning((object)"[LevelEditorPatches] 无法找到 SpawnLevel.water 字段"); } } catch (Exception arg) { Debug.LogError((object)$"[LevelEditorPatches] 在游玩模式应用水体大小时出错: {arg}"); } } ((MonoBehaviour)__instance).StartCoroutine(DelayedReinitializeWeatherParticleFollower(__instance)); string text = FilterMenu.GetFilterDataForSerialization(); if (string.IsNullOrEmpty(text) && !string.IsNullOrEmpty(FilterMenu.s_pendingFilterData)) { text = FilterMenu.s_pendingFilterData; } if (!string.IsNullOrEmpty(text)) { ((MonoBehaviour)__instance).StartCoroutine(DelayedApplyFilterInPlayMode(text)); } } catch (Exception ex) { Debug.LogError((object)("[CustomMusicManager] Failed to load custom music in play mode: " + ex)); } } [HarmonyPostfix] [HarmonyPatch(typeof(DMEditor), "BuildLevelSettings")] private static void DMEditor_BuildLevelSettings_Postfix(DMEditor __instance) { try { Settings levelSettings = __instance.LevelSettings; if (levelSettings != null) { string customMusicName = GetCustomMusicName(levelSettings); if (!string.IsNullOrEmpty(customMusicName)) { ((MonoBehaviour)__instance).StartCoroutine(DelayedSetCustomMusic(__instance, customMusicName)); } } ((MonoBehaviour)__instance).StartCoroutine(DelayedReinitializeWeatherParticleFollowerEditor(__instance)); FilterMenu.LoadLevelFilter(); } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Failed in DMEditor_BuildLevelSettings_Postfix: " + ex)); } } private static IEnumerator DelayedSetCustomMusic(DMEditor editor, string musicName) { yield return (object)new WaitForEndOfFrame(); try { editor.SetMusic(musicName); Debug.Log((object)("[CustomMusicManager] Restored custom music in editor: " + musicName)); } catch (Exception ex) { Debug.LogError((object)("[CustomMusicManager] Failed to set custom music in editor: " + ex)); } } [HarmonyPrefix] [HarmonyPatch(typeof(Utility), "Unzip")] private static bool Utility_Unzip_Prefix(byte[] bytes, ref byte[] __result) { if (bytes == null) { Debug.LogError((object)"[LevelEditorPatches] Utility.Unzip called with null bytes - file read may have failed"); __result = null; return false; } return true; } [HarmonyPrefix] [HarmonyPatch(typeof(LevelSerializer), "Deserialize")] private static bool LevelSerializer_Deserialize_Prefix(byte[] levelBytes, ref Level __result) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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) if (levelBytes == null) { Debug.LogError((object)"[LevelEditorPatches] LevelSerializer.Deserialize called with null bytes - cannot deserialize level"); __result = null; return false; } try { int length = levelBytes.GetLength(0); if (length >= 6) { byte[] array = new byte[4] { 103, 140, 84, 76 }; if (array[0] == levelBytes[0] && array[1] == levelBytes[1] && array[2] == levelBytes[2] && array[3] == levelBytes[3] && (ushort)(levelBytes[4] * 256 + levelBytes[5]) == 4) { string @string = Encoding.UTF8.GetString(levelBytes, 6, length - 6); string text = ExtractCustomMusicNameFromJson(@string); if (!string.IsNullOrEmpty(text)) { s_pendingCustomMusicName = text; Debug.Log((object)("[CustomMusicManager] Extracted customMusicName from JSON: " + text)); } Vector3? val = ExtractWaterSizeFromJson(@string); if (val.HasValue) { s_deserializedWaterSize = val.Value; Debug.Log((object)$"[LevelEditorPatches] 从 JSON 提取水体大小: ({val.Value.x}, {val.Value.y}, {val.Value.z})"); } Vector2? val2 = ExtractWaterPositionXZFromJson(@string); if (val2.HasValue) { s_deserializedWaterPositionXZ = val2.Value; Debug.Log((object)$"[LevelEditorPatches] 从 JSON 提取水体位置XZ: ({val2.Value.x}, {val2.Value.y})"); } string[] array2 = ExtractSkyboxNamesFromJson(@string); if (array2 != null && array2.Length >= 4) { SkyboxTool.SetSkyboxNames(array2[0], array2[1], array2[2], array2[3]); Debug.Log((object)("[LevelEditorPatches] 从 JSON 提取天空盒名称: Morning=" + array2[0] + ", Day=" + array2[1] + ", Night=" + array2[2] + ", Single=" + array2[3])); ApplyLoadedSkyboxTextures(array2[0], array2[1], array2[2], array2[3]); } string text2 = ExtractFilterDataFromJson(@string); if (!string.IsNullOrEmpty(text2)) { FilterMenu.SetFilterDataFromDeserialization(text2); Debug.Log((object)$"[LevelEditorPatches] 从 JSON 提取滤镜数据 (长度: {text2.Length} 字符)"); ApplyLoadedFilter(text2); } } } } catch (Exception ex) { Debug.LogWarning((object)("[CustomMusicManager] Failed to extract customMusicName from JSON in Deserialize: " + ex)); } return true; } [HarmonyPrefix] [HarmonyPatch(typeof(DMEditor), "LoadLevel", new Type[] { typeof(StartState), typeof(string) })] private static bool DMEditor_LoadLevel_WithParams_Prefix(DMEditor __instance, StartState startState, string filePath) { //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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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) try { FileHandlingFileType fileType; if (filePath.Contains(Paths.PlayerLevelDirectoryName) || filePath.Contains(Paths.TestMapName)) { fileType = (FileHandlingFileType)2; } else { fileType = (FileHandlingFileType)1; } File.Exists(filePath, fileType, (Action<bool>)delegate(bool exists) { //IL_000c: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_018b: Unknown result type (might be due to invalid IL or missing references) if (exists) { StartState val = startState; if ((int)val != 0) { if ((int)val == 1 && filePath.Contains(Paths.PlayerLevelDirectoryName)) { FieldInfo field = typeof(DMEditor).GetField("m_editorState", BindingFlags.Static | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(null); if (value != null) { MethodInfo method = value.GetType().GetMethod("SetCurrentFilePath", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { method.Invoke(value, new object[1] { filePath }); } } } } } else { FieldInfo field2 = typeof(DMEditor).GetField("m_editorState", BindingFlags.Static | BindingFlags.NonPublic); if (field2 != null) { object value2 = field2.GetValue(null); if (value2 != null) { MethodInfo method2 = value2.GetType().GetMethod("SetCurrentFilePath", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); PropertyInfo property = value2.GetType().GetProperty("MapIsDirty", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo methodInfo = ((property != null) ? property.GetSetMethod() : null); if (method2 != null) { method2.Invoke(value2, new object[1] { string.Empty }); } if (methodInfo != null) { methodInfo.Invoke(value2, new object[1] { false }); } } } } Debug.Log((object)("Loading " + filePath)); File.ReadAllBytes(filePath, fileType, (Action<byte[], Exception>)delegate(byte[] bytes, Exception e) { try { if (e != null) { Debug.LogError((object)("[LevelEditorPatches] Failed to read file: " + filePath + ", Error: " + e.Message)); } else if (bytes == null) { Debug.LogError((object)("[LevelEditorPatches] File read returned null bytes: " + filePath)); } else { byte[] array = Utility.Unzip(bytes); if (array == null) { Debug.LogError((object)("[LevelEditorPatches] Failed to unzip file: " + filePath)); } else { Level val2 = LevelSerializer.Deserialize(array); if (val2 == null) { Debug.LogError((object)("[LevelEditorPatches] Failed to deserialize level: " + filePath)); } else { if (filePath != Paths.TestMapPath) { __instance.ClearUndoHistory(); } FieldInfo field3 = typeof(DMEditor).GetField("m_levelSettings", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field4 = typeof(DMEditor).GetField("m_levelScene", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field5 = typeof(DMEditor).GetField("m_levelVolume", BindingFlags.Instance | BindingFlags.NonPublic); if (field3 != null) { field3.SetValue(__instance, val2.settings); Settings settings = val2.settings; if (settings != null) { if (settings.musicIndex == -1) { if (string.IsNullOrEmpty(GetCustomMusicName(settings))) { settings.musicIndex = 0; Debug.Log((object)"[LevelEditorPatches] Reset invalid custom music index -1 to 0"); } } else if (settings.musicIndex < 0) { settings.musicIndex = 0; Debug.Log((object)$"[LevelEditorPatches] Reset negative music index {settings.musicIndex} to 0"); } else if (AudioManager.MusicClips != null && settings.musicIndex >= AudioManager.MusicClips.Length) { settings.musicIndex = 0; Debug.Log((object)$"[LevelEditorPatches] Reset out-of-range music index {settings.musicIndex} to 0"); } } } __instance.BuildLevelSettings(); if (field4 != null) { field4.SetValue(__instance, val2.scene); } if (field5 != null) { field5.SetValue(__instance, val2.volume); } __instance.VolumeRootObject.InvalidateAllChunks(); s_updateLevelInProgress = false; s_updateLevelStartTime = 0f; if (s_updateLevelCoroutine != null) { ((MonoBehaviour)__instance).StopCoroutine(s_updateLevelCoroutine); s_updateLevelCoroutine = null; } __instance.UpdateLevel(); __instance.playerController.ResetView(); LevelUtility.AddRecentLevel(filePath); ScreenshotTool.Screenshots.Clear(); StartMenu.SetBackButtonState((StartMenuBackState)2); FieldInfo field6 = typeof(DMEditor).GetField("LevelWasDirtyWhenEnteredPlayMode", BindingFlags.Static | BindingFlags.Public); if (field6 != null) { field6.SetValue(null, false); } } } } } catch (Exception ex2) { Debug.LogError((object)("[LevelEditorPatches] Error in LoadLevel callback: " + ex2)); } }); } }); return false; } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Error in LoadLevel prefix: " + ex)); return true; } } [HarmonyPrefix] [HarmonyPatch(typeof(DMEditor), "SetMusic", new Type[] { typeof(int) })] private static bool DMEditor_SetMusic_Int_Prefix(DMEditor __instance, ref int index) { try { if (index < 0) { if (index == -1) { Settings levelSettings = __instance.LevelSettings; if (levelSettings != null) { if (!string.IsNullOrEmpty(GetCustomMusicName(levelSettings))) { return true; } Debug.LogWarning((object)"[LevelEditorPatches] Invalid custom music index -1, resetting to 0"); index = 0; } else { Debug.LogWarning((object)"[LevelEditorPatches] Settings is null, resetting music index to 0"); index = 0; } } else { Debug.LogWarning((object)$"[LevelEditorPatches] Invalid music index {index}, resetting to 0"); index = 0; } } else if (AudioManager.MusicClips != null && index >= AudioManager.MusicClips.Length) { Debug.LogWarning((object)$"[LevelEditorPatches] Music index {index} out of range [0, {AudioManager.MusicClips.Length - 1}], resetting to 0"); index = 0; } return true; } catch (Exception ex) { Debug.LogError((object)("[LevelEditorPatches] Error in SetMusic prefix: " + ex)); index = 0; return true; } } private static FieldInfo GetCustomMusicFieldInfo() { return typeof(Settings).GetField("customMusicName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } private static bool TrySetCustomMusicNameViaReflection(Settings settings, string musicName) { try { FieldInfo customMusicFieldInfo = GetCustomMusicFieldInfo(); if (customMusicFieldInfo != null) { customMusicFieldInfo.SetValue(settings, musicName); return true; } } catch (Exception ex) { Debug.LogWarning((object)("[CustomMusicManager] Failed to set customMusicName via reflection: " + ex)); } return false; } private static string TryGetCustomMusicNameViaReflection(Settings settings) { try { FieldInfo customMusicFieldInfo = GetCustomMusicFieldInfo(); if (customMusicFieldInfo != null) { return customMusicFieldInfo.GetValue(settings) as string; } } catch (Exception ex) { Debug.LogWarning((object)("[CustomMusicManager] Failed to get customMusicName via reflection: " + ex)); } return null; } private static string AddCustomMusicNameToJson(string json, string customMusicName) { if (string.IsNullOrEmpty(customMusicName) || string.IsNullOrEmpty(json)) { return json; } try { string text = customMusicName.Replace("\\", "\\\\").Replace("\"", "\\\"").Replace("\n", "\\n") .Replace("\r", "\\r") .Replace("\t", "\\t"); int num = json.IndexOf("\"settings\":{"); if (num == -1) { return json; } int num2 = json.IndexOf('{', num + "\"settings\":".Length); if (num2 == -1) { return json; } int num3 = 0; int num4 = -1; for (int i = num2; i < json.Length; i++) { if (json[i] == '{') { num3++; } else if (json[i] == '}') { num3--; if (num3 == 0) { num4 = i; break; } } } if (num4 == -1) { return json; } string text2 = json.Substring(num2 + 1, num4 - num2 - 1); if (text2.Contains("\"customMusicName\"")) { Regex regex = new Regex("\"customMusicName\"\\s*:\\s*\"[^\"]*\""); string replacement = "\"customMusicName\":\"" + text + "\""; string text3 = regex.Replace(text2, replacement); return json.Substring(0, num2 + 1) + text3 + json.Substring(num4); } string text4 = ",\"customMusicName\":\"" + text + "\""; if (text2.Trim().Length > 0) { return json.Substring(0, num4) + text4 + json.Substring(num4); } return json.Substring(0, num4) + "\"customMusicName\":\"" + text + "\"" + json.Substring(num4); } catch (Exception ex) { Debug.LogError((object)("[CustomMusicManager] Failed to add customMusicName to JSON: " + ex)); return json; } } private static string ExtractCustomMusicNameFromJson(string json) { if (string.IsNullOrEmpty(json)) { return null; } try { Match match = new Regex("\"customMusicName\"\\s*:\\s*\"([^\"]*)\"").Match(json); if (match.Success && match.Groups.Count > 1) { return match.Groups[1].Value; } } catch (Exception ex) { Debug.LogError((object)("[CustomMusicManager] Failed to extract customMusicName from JSON: " + ex)); } return null; } [HarmonyPostfix] [HarmonyPatch(typeof(LevelSerializer), "Serialize")] private static void LevelSerializer_Serialize_Postfix(Level level, ref byte[] __result) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00c9: 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_00f7: 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_0127: Unknown result type (might be due to invalid IL or missing references) if (__result == null || level == null || level.settings == null) { return; } try { if (__result.Length < 6) { return; } string text = Encoding.UTF8.GetString(__result, 6, __result.Length - 6); string text2 = text; bool flag = false; string customMusicName = GetCustomMusicName(level.settings); if (!string.IsNullOrEmpty(customMusicName)) { text2 = AddCustomMusicNameToJson(text2, customMusicName); if (text2 != text) { flag = true; text = text2; Debug.Log((object)("[CustomMusicManager] Added customMusicName to serialized JSON: " + customMusicName)); } } Vector3 waterSize = GetWaterSize(level.settings); Vector2? waterPositionXZ = GetWaterPositionXZ(level.settings); if (waterSize != s_defaultWaterSize || s_customWaterSize.HasValue) { text2 = AddWaterSizeToJson(text2, waterSize); if (text2 != text) { flag = true; text = text2; Debug.Log((object)$"[LevelEditorPatches] 序列化时扩展 JSON,添加水体大小: ({waterSize.x}, {waterSize.y}, {waterSize.z})"); } } if (waterPositionXZ.HasValue) { text2 = AddWaterPositionXZToJson(text2, waterPositionXZ.Value); if (text2 != text) { flag = true; text = text2; Debug.Log((object)$"[LevelEditorPatches] 序列化时扩展 JSON,添加水体位置XZ: ({waterPositionXZ.Value.x}, {waterPositionXZ.Value.y})"); } } if (!string.IsNullOrEmpty(SkyboxTool.MorningName) || !string.IsNullOrEmpty(SkyboxTool.DayName) || !string.IsNullOrEmpty(SkyboxTool.NightName) || !string.IsNullOrEmpty(SkyboxTool.SingleSkyboxName)) { text2 = AddSkyboxNamesToJson(text2, SkyboxTool.MorningName, SkyboxTool.DayName, SkyboxTool.NightName, SkyboxTool.SingleSkyboxName); if (text2 != text) { flag = true; text = text2; Debug.Log((object)("[LevelEditorPatches] 序列化时扩展 JSON,添加天空盒名称: Morning=" + SkyboxTool.MorningName + ", Day=" + SkyboxTool.DayName + ", Night=" + SkyboxTool.NightName + ", Single=" + SkyboxTool.SingleSkyboxName)); } } if ((Object)(object)DMEditor.Instance != (Object)null && (Object)(object)DMEditor.Instance.postProcessVolume != (Object)null && (Object)(object)DMEditor.Instance.postProcessVolume.sharedProfile != (Object)null) { PostProcessProfile sharedProfile = DMEditor.Instance.postProcessVolume.sharedProfile; bool flag2 = false; LevelPresetData[] allPresets = LevelPresetData.GetAllPresets(); foreach (LevelPresetData val in allPresets) { if ((Object)(object)val != (Object)null && (Object)(object)val.PostProcessProfile != (Object)null && (Object)(object)val.PostProcessProfile == (Object)(object)sharedProfile) { flag2 = true; break; } } bool flag3 = false; FilterMenu filterMenu = FilterMenu.Create(); if ((Object)(object)filterMenu != (Object)null) { FieldInfo field = typeof(FilterMenu).GetField("s_levelFilterData", BindingFlags.Static | BindingFlags.NonPublic); if (field != null && field.GetValue(null) is Dictionary<string, string> dictionary && dictionary.Count > 0 && !string.IsNullOrEmpty(s_currentSavingFilePath)) { string text3 = s_currentSavingFilePath.Replace('\\', '/'); flag3 = dictionary.ContainsKey(text3); if (!flag3) { foreach (string key in dictionary.Keys) { string text4 = key.Replace('\\', '/'); if (text4 == text3 || text3.EndsWith(text4) || text4.EndsWith(text3)) { flag3 = true; break; } } } if (flag3) { Debug.Log((object)"[LevelEditorPatches] 检测到滤镜缓存中有当前地图的数据,说明用户修改了滤镜"); } } FieldInfo field2 = typeof(FilterMenu).GetField("m_customLevelProfile", BindingFlags.Instance | BindingFlags.NonPublic); if (field2 != null) { object? value = field2.GetValue(filterMenu); PostProcessProfile val2 = (PostProcessProfile)((value is PostProcessProfile) ? value : null); if ((Object)(object)val2 != (Object)null) { flag3 = true; Debug.Log((object)("[LevelEditorPatches] 检测到 FilterMenu 有自定义滤镜标记: " + ((Object)val2).name)); } } } if (((Object)sharedProfile).name.Contains("_Copy") || !flag2 || flag3) { if ((Object)(object)filterMenu == (Object)null) { filterMenu = FilterMenu.Create(); } if ((Object)(object)filterMenu != (Object)null) { string text5 = filterMenu.SerializeProfileToJson(sharedProfile); if (!string.IsNullOrEmpty(text5)) { text2 = AddFilterDataToJson(text2, text5); if (text2 != text) { flag = true; text = text2; Debug.Log((object)$"[LevelEditorPatches] 序列化时扩展 JSON,添加滤镜数据 (滤镜: {((Object)sharedProfile).name}, 长度: {text5.Length} 字符, hasFilterInCache={flag3})"); s_currentSavingFilePath = null; } else { Debug.LogWarning((object)"[LevelEditorPatches] 序列化时添加滤镜数据失败:AddFilterDataToJson 返回的 JSON 未改变");