Please disclose if any significant portion of your mod was created 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 RegeneratingWorld v0.5.0
RegeneratingWorld.dll
Decompiled 8 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using JG224.ModCore.API; using JG224.RegeneratingWorld.Core; using JG224.RegeneratingWorld.Runtime; using Microsoft.CodeAnalysis; using SoftReferenceableAssets; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("RegeneratingWorld")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.5.0.0")] [assembly: AssemblyInformationalVersion("0.5.0")] [assembly: AssemblyProduct("RegeneratingWorld")] [assembly: AssemblyTitle("RegeneratingWorld")] [assembly: AssemblyVersion("0.5.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace JG224.RegeneratingWorld { [BepInPlugin("jg224.RegeneratingWorld", "RegeneratingWorld", "0.5.0")] [BepInDependency("com.jg224.modcore", "0.5.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "jg224.RegeneratingWorld"; public const string PluginName = "RegeneratingWorld"; public const string PluginVersion = "0.5.0"; public const string ModCoreGuid = "com.jg224.modcore"; public const int ProtocolVersion = 1; public static readonly ModuleId ModuleId = new ModuleId("regeneratingworld"); private readonly List<IDisposable> _leases = new List<IDisposable>(); private Harmony _harmony; private ICoreServices _core; internal static RegenerationRuntime Runtime { get; private set; } private void Awake() { //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) try { if (!ModCoreApi.IsAvailable) { throw new InvalidOperationException("ModCore must initialize first."); } _core = ModCoreApi.Services; SemanticVersion val = default(SemanticVersion); if (!SemanticVersion.TryParse("0.5.0", ref val)) { throw new InvalidOperationException("Invalid plugin version."); } _leases.Add(_core.Modules.Register(new ModuleDescriptor(ModuleId, "jg224.RegeneratingWorld", "RegeneratingWorld", val, 1, (ModuleSide)3, (ModuleRequirement)4, 0uL, 1, 1))); Settings settings = new Settings((BaseUnityPlugin)(object)this); _leases.AddRange(settings.Register(_core)); _leases.Add(_core.Namespaces.Register(ModuleId, (NamespaceKind)1, "jg224.rw.", 1, Array.Empty<string>())); _leases.Add(_core.Namespaces.Register(ModuleId, (NamespaceKind)4, "regeneratingworld", 1, Array.Empty<string>())); Runtime = new RegenerationRuntime(settings, _core, delegate(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); }); _leases.Add(_core.Lifecycle.Subscribe(ModuleId, (LifecycleEventKind)3, (Action<LifecycleEvent>)delegate { Runtime?.Stop(); }, 0)); _leases.Add(_core.Lifecycle.Subscribe(ModuleId, (LifecycleEventKind)9, (Action<LifecycleEvent>)delegate { Runtime?.Stop(); }, 0)); _harmony = new Harmony("jg224.RegeneratingWorld"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); _core.Modules.SetState(ModuleId, (ModuleRuntimeState)2, "Server restoration scheduler ready."); Game.isModded = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"RegeneratingWorld 0.5.0 loaded. Server settings control regeneration."); } catch (Exception ex) { ICoreServices core = _core; if (core != null) { core.Modules.SetState(ModuleId, (ModuleRuntimeState)5, ex.Message); } ((BaseUnityPlugin)this).Logger.LogError((object)("RegeneratingWorld failed safely: " + ex)); Shutdown(); throw; } } private void Update() { Runtime?.Tick(); } private void OnDestroy() { Shutdown(); } private void Shutdown() { Runtime?.Stop(); Runtime = null; Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; for (int num = _leases.Count - 1; num >= 0; num--) { _leases[num].Dispose(); } _leases.Clear(); } } internal sealed class Settings { private readonly List<ConfigEntryBase> _entries = new List<ConfigEntryBase>(); internal readonly ConfigEntry<bool> Enabled; internal readonly ConfigEntry<bool> Terrain; internal readonly ConfigEntry<bool> Locations; internal readonly ConfigEntry<bool> Resources; internal readonly ConfigEntry<float> TerrainDays; internal readonly ConfigEntry<float> LocationDays; internal readonly ConfigEntry<float> ResourceDays; internal readonly ConfigEntry<float> StationRadius; internal readonly ConfigEntry<float> PlayerRadius; internal readonly ConfigEntry<int> ScanSeconds; internal Settings(BaseUnityPlugin plugin) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown ConfigFile val = PluginConfigFiles.Attach(plugin, new ConfigFile(Path.Combine(Paths.ConfigPath, "jg224.RegeneratingWorld.cfg"), true, plugin.Info.Metadata)); Enabled = Add<bool>(val.Bind<bool>("General", "Enabled", true, "Server-owned master switch. Disabling retains restoration records.")); Terrain = Add<bool>(val.Bind<bool>("Terrain", "Enabled", true, "Restore unprotected digging, raising, flattening and ground paint.")); Locations = Add<bool>(val.Bind<bool>("Locations", "Enabled", true, "Restore dungeons, Fuling camps, Dvergr sites and Ashlands fortresses.")); Resources = Add<bool>(val.Bind<bool>("Resources", "Enabled", true, "Regrow tracked natural vegetation and mined resources.")); TerrainDays = Days(val, "Terrain", "ResetDays", 30f); LocationDays = Days(val, "Locations", "ResetDays", 30f); ResourceDays = Days(val, "Resources", "FallbackResetDays", 30f); StationRadius = Add<float>(val.Bind<float>("Protection", "CraftingStationRadius", 40f, new ConfigDescription("Meters protected around every crafting station, including unloaded stations. Independent of crafting range mods.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 200f), Array.Empty<object>()))); PlayerRadius = Add<float>(val.Bind<float>("Protection", "PlayerSafetyRadius", 100f, new ConfigDescription("Additional meters around a reset area in which online players postpone restoration.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(32f, 500f), Array.Empty<object>()))); ScanSeconds = Add<int>(val.Bind<int>("General", "ScanIntervalSeconds", 60, new ConfigDescription("Time between bounded server scans. Timers use world time, including sleep, and survive saves.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 600), Array.Empty<object>()))); } private ConfigEntry<float> Days(ConfigFile file, string section, string key, float value) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown return Add<float>(file.Bind<float>(section, key, value, new ConfigDescription("In-game days before this restoration becomes due.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 1000f), Array.Empty<object>()))); } private ConfigEntry<T> Add<T>(ConfigEntry<T> entry) { _entries.Add((ConfigEntryBase)(object)entry); return entry; } internal IEnumerable<IDisposable> Register(ICoreServices core) { foreach (ConfigEntryBase entry in _entries) { yield return core.Configuration.Register(new ConfigSettingDescriptor(Plugin.ModuleId, entry.Definition.Section, entry.Definition.Key, (ConfigScope)2, (Func<string>)(() => Convert.ToString(entry.BoxedValue, CultureInfo.InvariantCulture)), 1)); } } } } namespace JG224.RegeneratingWorld.Runtime { [HarmonyPatch(typeof(Container), "Save")] internal static class LocationChestProtection { internal const string DepositKey = "jg224.rw.chest.deposit.v1"; internal static bool IsSensitive(ZDO zdo, GameObject prefab) { //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_007f: 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_00a7: Unknown result type (might be due to invalid IL or missing references) if (zdo == null || (Object)(object)prefab == (Object)null) { return true; } Container component = prefab.GetComponent<Container>(); if ((Object)(object)component == (Object)null) { return true; } try { ChestInventoryEntry[] array = Read(zdo.GetString(ZDOVars.s_items, "")); if (array.Length == 0) { return false; } if (zdo.GetBool("jg224.rw.chest.deposit.v1", false)) { return true; } Dictionary<string, ItemData> dictionary = new Dictionary<string, ItemData>(StringComparer.Ordinal); foreach (DropData drop in component.m_defaultItems.m_drops) { if (!((Object)(object)drop.m_item == (Object)null)) { ItemDrop component2 = drop.m_item.GetComponent<ItemDrop>(); if ((Object)(object)component2 != (Object)null) { dictionary[((Object)drop.m_item).name] = component2.m_itemData; } } } ChestInventoryEntry[] array2 = array; foreach (ChestInventoryEntry chestInventoryEntry in array2) { if (!dictionary.TryGetValue(chestInventoryEntry.Name, out var value) || chestInventoryEntry.HasPlayerMetadata || chestInventoryEntry.Quality != value.m_quality || chestInventoryEntry.Variant != value.m_variant) { return true; } } return false; } catch { return true; } } private static void Prefix(Container __instance) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown ZNetView val = (((Object)(object)__instance.m_rootObjectOverride != (Object)null) ? __instance.m_rootObjectOverride : ((Component)__instance).GetComponent<ZNetView>()); if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner()) { return; } ZDO zDO = val.GetZDO(); if (zDO.GetLong(ZDOVars.s_creator, 0L) != 0L || !zDO.GetBool(ZDOVars.s_addedDefaultItems, false)) { return; } try { ZPackage val2 = new ZPackage(); __instance.GetInventory().Save(val2); ChestInventoryEntry[] array = Read(val2); if (array.Length == 0) { if (zDO.GetBool("jg224.rw.chest.deposit.v1", false)) { zDO.Set("jg224.rw.chest.deposit.v1", false); } } else if (!zDO.GetBool("jg224.rw.chest.deposit.v1", false) && ChestInventoryCodec.HasAdditions(Read(zDO.GetString(ZDOVars.s_items, "")), array)) { zDO.Set("jg224.rw.chest.deposit.v1", true); } } catch { zDO.Set("jg224.rw.chest.deposit.v1", true); } } private static ChestInventoryEntry[] Read(string encoded) { if (string.IsNullOrEmpty(encoded)) { return Array.Empty<ChestInventoryEntry>(); } if (encoded.Length > 4194304) { throw new FormatException("Inventory payload exceeds limit."); } return ChestInventoryCodec.Decode(Convert.FromBase64String(encoded)); } private static ChestInventoryEntry[] Read(ZPackage package) { return ChestInventoryCodec.Decode(package.GetArray()); } } [HarmonyPatch(typeof(ZDOMan), "CreateNewZDO", new Type[] { typeof(Vector3), typeof(int) })] internal static class LocationCreationCapture { private sealed class Scope : IDisposable { public void Dispose() { _created = null; _transaction = null; _maximum = 0; _staged = null; _recording = false; } } private static List<ZDO> _created; private static string _transaction; private static int _maximum; private static HashSet<ZDOID> _staged; private static bool _recording; internal static IDisposable Begin(List<ZDO> created, string transaction, int maximum) { if (_created != null) { throw new InvalidOperationException("Location regeneration cannot be nested."); } _created = created; _transaction = transaction; _maximum = maximum; _staged = new HashSet<ZDOID>(); _recording = true; return new Scope(); } internal static bool IsStaged(ZDO zdo) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (zdo != null && _staged != null) { return _staged.Contains(zdo.m_uid); } return false; } internal static void FinishGeneration() { _recording = false; } private static void Postfix(ZDO __result) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (_recording && _created != null && __result != null) { _created.Add(__result); _staged.Add(__result.m_uid); __result.Set("jg224.rw.location.transaction.v1", _transaction); if (_created.Count > _maximum) { throw new InvalidOperationException("Location regeneration exceeded the network object limit."); } } } } internal static class LocationLookup { internal static ZoneLocation Find(IEnumerable<ZoneLocation> locations, int hash) { if (locations == null) { return null; } foreach (ZoneLocation location in locations) { if (location != null && location.m_prefab.IsValid && location.Hash == hash) { return location; } } return null; } } internal sealed class LocationRegenerator { private sealed class PrefabState { private readonly Transform _root; private readonly Vector3 _position; private readonly Quaternion _rotation; private readonly Transform _interior; private readonly Vector3 _interiorPosition; private readonly Quaternion _interiorRotation; private readonly Transform _generator; private readonly Vector3 _generatorPosition; private readonly Dictionary<GameObject, bool> _active = new Dictionary<GameObject, bool>(); private readonly bool _randomDamage; internal PrefabState(GameObject prefab) { //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_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_009e: 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_00af: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) _root = prefab.transform; _position = _root.position; _rotation = _root.rotation; Location component = prefab.GetComponent<Location>(); _interior = (((Object)(object)component == (Object)null) ? null : component.m_interiorTransform); _generator = (((Object)(object)component == (Object)null || (Object)(object)component.m_generator == (Object)null) ? null : ((Component)component.m_generator).transform); if ((Object)(object)_interior != (Object)null) { _interiorPosition = _interior.localPosition; _interiorRotation = _interior.localRotation; } if ((Object)(object)_generator != (Object)null) { _generatorPosition = _generator.localPosition; } Transform[] componentsInChildren = prefab.GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { _active[((Component)val).gameObject] = ((Component)val).gameObject.activeSelf; } RandomSpawn[] componentsInChildren2 = prefab.GetComponentsInChildren<RandomSpawn>(true); foreach (RandomSpawn val2 in componentsInChildren2) { if ((Object)(object)val2.m_OffObject != (Object)null) { _active[val2.m_OffObject] = val2.m_OffObject.activeSelf; } } _randomDamage = WearNTear.m_randomInitialDamage; } internal void Restore() { //IL_0007: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) _root.position = _position; _root.rotation = _rotation; if ((Object)(object)_interior != (Object)null) { _interior.localPosition = _interiorPosition; _interior.localRotation = _interiorRotation; } if ((Object)(object)_generator != (Object)null) { _generator.localPosition = _generatorPosition; } foreach (KeyValuePair<GameObject, bool> item in _active) { if ((Object)(object)item.Key != (Object)null) { item.Key.SetActive(item.Value); } } WearNTear.m_randomInitialDamage = _randomDamage; } } internal const string ClockKey = "jg224.rw.location.clock.v1"; internal const string OwnerKey = "jg224.rw.location.owner.v1"; internal const string TransactionKey = "jg224.rw.location.transaction.v1"; private const int MaximumObjects = 20000; private static readonly MethodInfo SpawnLocationMethod = AccessTools.Method(typeof(ZoneSystem), "SpawnLocation", new Type[7] { typeof(ZoneLocation), typeof(int), typeof(Vector3), typeof(Quaternion), typeof(SpawnMode), typeof(List<GameObject>), typeof(bool) }, (Type[])null); private static readonly MethodInfo SpawnZoneMethod = AccessTools.Method(typeof(ZoneSystem), "SpawnZone", new Type[3] { typeof(Vector2s), typeof(SpawnMode), typeof(GameObject).MakeByRefType() }, (Type[])null); private static readonly MethodInfo SendDestroyedMethod = AccessTools.Method(typeof(ZDOMan), "SendDestroyed", Type.EmptyTypes, (Type[])null); private readonly Func<Vector3, float, bool> _isProtected; private readonly Func<ZDO, bool> _isSensitive; private readonly Action<IReadOnlyList<ZDO>, string> _backup; private readonly Action<string> _log; private readonly List<ZDO> _discovered = new List<ZDO>(); private readonly Queue<ZDOID> _pending = new Queue<ZDOID>(); private readonly HashSet<ZDOID> _reportedIncomplete = new HashSet<ZDOID>(); private readonly Dictionary<int, bool> _supported = new Dictionary<int, bool>(); private int _scanIndex; private bool _blocked; internal LocationRegenerator(Func<Vector3, float, bool> isProtected, Func<ZDO, bool> isSensitive, Action<IReadOnlyList<ZDO>, string> backupBeforeMutation, Action<string> log) { _isProtected = isProtected ?? throw new ArgumentNullException("isProtected"); _isSensitive = isSensitive ?? throw new ArgumentNullException("isSensitive"); _backup = backupBeforeMutation ?? throw new ArgumentNullException("backupBeforeMutation"); _log = log ?? throw new ArgumentNullException("log"); if (SpawnLocationMethod == null) { throw new MissingMethodException("Valheim ZoneSystem.SpawnLocation signature changed."); } if (SpawnZoneMethod == null) { throw new MissingMethodException("Valheim ZoneSystem.SpawnZone signature changed."); } if (SendDestroyedMethod == null) { throw new MissingMethodException("Valheim ZDOMan.SendDestroyed signature changed."); } } internal void Tick(double now, double delay) { //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) if (_blocked || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || (Object)(object)ZoneSystem.instance == (Object)null || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null || !Finite(now) || !Finite(delay) || delay <= 0.0) { return; } if (_pending.Count == 0) { string prefabName = Utils.GetPrefabName(ZoneSystem.instance.m_locationProxyPrefab); if (!ZDOMan.instance.GetAllZDOsWithPrefabIterative(prefabName, _discovered, ref _scanIndex)) { return; } foreach (ZDO item in _discovered) { if (item.IsValid()) { _pending.Enqueue(item.m_uid); } } _discovered.Clear(); _scanIndex = 0; } for (int i = 0; i < 32; i++) { if (_pending.Count == 0) { break; } ZDO zDO = ZDOMan.instance.GetZDO(_pending.Dequeue()); if (zDO == null || !zDO.IsValid()) { continue; } ZoneLocation val = FindLocation(zDO.GetInt(ZDOVars.s_location, 0)); if (val == null || !Supports(val)) { continue; } string text = zDO.GetString("jg224.rw.location.transaction.v1", ""); if (!string.IsNullOrEmpty(text)) { if (_reportedIncomplete.Add(zDO.m_uid)) { _log("Location " + val.m_prefab.Name + " is paused after an interrupted transaction (" + text + "). Preserve the world and recovery snapshots before investigating."); } } else { long num = zDO.GetLong("jg224.rw.location.clock.v1", -1L); if (num < 0 || (double)num > now * 1000.0) { Own(zDO); zDO.Set("jg224.rw.location.clock.v1", Milliseconds(now)); } else if (!(now - (double)num / 1000.0 < delay) && TryRegenerate(zDO, val, now)) { break; } } } } private bool Supports(ZoneLocation location) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (_supported.TryGetValue(location.Hash, out var value)) { return value; } string name = location.m_prefab.Name; if (name.IndexOf("StartTemple", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Vendor", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Haldor", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Hildir_camp", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("BogWitch", StringComparison.OrdinalIgnoreCase) >= 0) { return _supported[location.Hash] = false; } location.m_prefab.Load(); try { GameObject asset = location.m_prefab.Asset; Location val = (((Object)(object)asset == (Object)null) ? null : asset.GetComponent<Location>()); value = (Object)(object)val != (Object)null && (val.m_hasInterior || (Object)(object)val.m_interiorTransform != (Object)null || (Object)(object)val.m_generator != (Object)null || (Object)(object)asset.GetComponentInChildren<DungeonGenerator>(true) != (Object)null); value |= name.StartsWith("GoblinCamp", StringComparison.OrdinalIgnoreCase) || name.StartsWith("FulingVillage", StringComparison.OrdinalIgnoreCase) || name.StartsWith("Dvergr", StringComparison.OrdinalIgnoreCase) || name.StartsWith("Fortress", StringComparison.OrdinalIgnoreCase); _supported[location.Hash] = value; return value; } finally { location.m_prefab.Release(); } } private bool TryRegenerate(ZDO proxy, ZoneLocation location, double now) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_05db: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_05ef: Unknown result type (might be due to invalid IL or missing references) //IL_05f4: 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_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_0664: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) using (ResourceRegenerator.SuppressCapture()) { location.m_prefab.Load(); List<GameObject> list = new List<GameObject>(); try { GameObject asset = location.m_prefab.Asset; if ((Object)(object)asset == (Object)null) { return false; } Vector3 position = proxy.GetPosition(); Quaternion rotation = proxy.GetRotation(); List<Bounds> footprint = BuildFootprint(asset, location, position, rotation); if (!SafeFootprint(footprint)) { return false; } if (!PrepareTerrain(footprint, list)) { return false; } List<ZDO> list2 = FindObjects(footprint); if (list2.Count > 20000 || HasSensitiveObject(list2, footprint)) { return false; } string text = proxy.GetString("jg224.rw.location.owner.v1", ""); if (string.IsNullOrEmpty(text)) { text = ((object)Unsafe.As<ZDOID, ZDOID>(ref proxy.m_uid)/*cast due to .constrained prefix*/).ToString(); } string text2 = text + ":" + Milliseconds(now); ZDOID uid = proxy.m_uid; _backup(list2, "location-intent:" + text2); Own(proxy); proxy.Set("jg224.rw.location.transaction.v1", text2); List<ZDO> list3 = new List<ZDO>(); List<GameObject> list4 = new List<GameObject>(); State state = Random.state; int forceSeed = DungeonGenerator.m_forceSeed; PrefabState prefabState = new PrefabState(asset); List<PrefabState> list5 = new List<PrefabState>(); List<SoftReference<GameObject>> list6 = new List<SoftReference<GameObject>>(); IDisposable disposable = null; bool flag = false; bool flag2 = false; try { CaptureRoomStates(asset, list5, list6); disposable = LocationCreationCapture.Begin(list3, text2, 20000); try { DungeonGenerator.m_forceSeed = int.MinValue; SpawnLocationMethod.Invoke(ZoneSystem.instance, new object[7] { location, proxy.GetInt(ZDOVars.s_seed, 0), position, rotation, (object)(SpawnMode)2, list4, false }); } finally { LocationCreationCapture.FinishGeneration(); } ZDO val = ValidateGenerated(list3, proxy, footprint); if (val == null || !SafeFootprint(footprint)) { throw new InvalidOperationException("Generated location failed its identity or footprint checks."); } list2 = FindObjects(footprint); HashSet<ZDOID> createdIds = new HashSet<ZDOID>(); foreach (ZDO item in list3) { createdIds.Add(item.m_uid); } list2.RemoveAll((ZDO zdo) => createdIds.Contains(zdo.m_uid)); if (list2.Count > 20000 || HasSensitiveObject(list2, footprint)) { throw new InvalidOperationException("A protected object is inside the generated location footprint."); } List<ZDO> list7 = SelectOldObjects(list2, list3, proxy, text, footprint); ValidateDungeonLayouts(list7, list3); if (!list7.Contains(proxy)) { throw new InvalidOperationException("Original location anchor was not selected."); } foreach (ZDO item2 in list3) { Own(item2); item2.Set("jg224.rw.location.owner.v1", text); item2.Set("jg224.rw.location.transaction.v1", text2); } val.Set("jg224.rw.location.clock.v1", Milliseconds(now)); _backup(list3, "location-created:" + text2); _backup(list7, "location-commit:" + text2); flag2 = true; foreach (ZDO item3 in list7) { Destroy(item3); } FlushDestroyed(); _backup(list3, "location-complete:" + text2); foreach (ZDO item4 in list3) { item4.Set("jg224.rw.location.transaction.v1", ""); } flag = true; _log("Regenerated " + location.m_prefab.Name + ": restored " + list3.Count + " native objects and replaced " + list7.Count + " old objects."); return true; } catch (Exception ex) { Exception ex2 = ((ex is TargetInvocationException { InnerException: not null } ex3) ? ex3.InnerException : ex); if (!flag2) { try { foreach (ZDO item5 in list3) { Destroy(item5); } FlushDestroyed(); _backup(Array.Empty<ZDO>(), "location-rollback:" + text2); proxy.Set("jg224.rw.location.transaction.v1", ""); proxy.Set("jg224.rw.location.clock.v1", Milliseconds(now)); } catch (Exception ex4) { _blocked = true; _log("Location rollback is incomplete for " + text2 + ": " + ex4.Message); } } else { _blocked = true; } _log("Location " + location.m_prefab.Name + " regeneration " + (flag2 ? "requires recovery" : "was rolled back") + ": " + ex2.Message); return true; } finally { disposable?.Dispose(); ZNetView.FinishGhostInit(); DungeonGenerator.m_forceSeed = forceSeed; foreach (PrefabState item6 in list5) { item6.Restore(); } prefabState.Restore(); Random.state = state; foreach (SoftReference<GameObject> item7 in list6) { item7.Release(); } foreach (GameObject item8 in list4) { if ((Object)(object)item8 != (Object)null) { Object.Destroy((Object)(object)item8); } } if (!flag && flag2) { _reportedIncomplete.Add(uid); } } } finally { foreach (GameObject item9 in list) { if ((Object)(object)item9 != (Object)null) { Object.Destroy((Object)(object)item9); } } location.m_prefab.Release(); } } } private static bool PrepareTerrain(List<Bounds> footprint, List<GameObject> temporary) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0100: 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_011a: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) HashSet<Vector2s> hashSet = new HashSet<Vector2s>(); foreach (Bounds item in footprint) { Bounds current = item; Vector2s zone = ZoneSystem.GetZone(((Bounds)(ref current)).min); Vector2s zone2 = ZoneSystem.GetZone(((Bounds)(ref current)).max); if (zone2.x < zone.x || zone2.y < zone.y || zone2.x - zone.x > 8 || zone2.y - zone.y > 8) { throw new InvalidOperationException("Location terrain footprint exceeds supported bounds."); } for (int i = zone.x; i <= zone2.x; i++) { for (int j = zone.y; j <= zone2.y; j++) { hashSet.Add(new Vector2s(i, j)); } } } bool flag = true; foreach (Vector2s item2 in hashSet) { if (!((Object)(object)Heightmap.FindHeightmap(ZoneSystem.GetZonePos(item2)) != (Object)null)) { object[] array = new object[3] { item2, (object)(SpawnMode)1, null }; bool num = (bool)SpawnZoneMethod.Invoke(ZoneSystem.instance, array); object obj = array[2]; GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (val != null) { temporary.Add(val); } if (!num) { flag = false; } } } if (flag) { Physics.SyncTransforms(); } return flag; } private static void CaptureRoomStates(GameObject prefab, List<PrefabState> states, List<SoftReference<GameObject>> held) { //IL_0023: 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_002b: 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) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) HashSet<AssetID> hashSet = new HashSet<AssetID>(); DungeonGenerator[] componentsInChildren = prefab.GetComponentsInChildren<DungeonGenerator>(true); for (int i = 0; i < componentsInChildren.Length; i++) { SoftReference<GameObject>[] availableRoomPrefabs = componentsInChildren[i].GetAvailableRoomPrefabs(); for (int j = 0; j < availableRoomPrefabs.Length; j++) { SoftReference<GameObject> item = availableRoomPrefabs[j]; if (hashSet.Add(item.m_assetID)) { item.Load(); held.Add(item); if ((Object)(object)item.Asset == (Object)null) { throw new InvalidOperationException("A dungeon room asset could not be loaded."); } states.Add(new PrefabState(item.Asset)); } } } } private ZDO ValidateGenerated(List<ZDO> created, ZDO oldProxy, List<Bounds> footprint) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) if (created.Count < 2 || created.Count > 20000) { return null; } ZDO val = null; foreach (ZDO item in created) { if (item == null || !item.IsValid() || item.GetPrefab() == 0 || !Finite(item.GetPosition().x) || !Finite(item.GetPosition().y) || !Finite(item.GetPosition().z)) { return null; } if (item.GetPrefab() == oldProxy.GetPrefab() && item.GetInt(ZDOVars.s_location, 0) == oldProxy.GetInt(ZDOVars.s_location, 0)) { if (val != null || Vector3.Distance(item.GetPosition(), oldProxy.GetPosition()) > 0.1f) { return null; } val = item; } if (!Inside(footprint, item.GetPosition())) { footprint.Add(new Bounds(item.GetPosition(), Vector3.one * 4f)); } } return val; } private static void ValidateDungeonLayouts(List<ZDO> removed, List<ZDO> created) { //IL_0057: 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) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014b: 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_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) foreach (ZDO item in created) { byte[] byteArray = item.GetByteArray(ZDOVars.s_roomData, (byte[])null); if (byteArray == null || byteArray.Length == 0) { continue; } foreach (ZDO item2 in removed) { if (item2.GetPrefab() != item.GetPrefab() || Vector3.SqrMagnitude(item2.GetPosition() - item.GetPosition()) > 0.01f) { continue; } byte[] array = item2.GetByteArray(ZDOVars.s_roomData, (byte[])null); if (array == null) { int num = item2.GetInt(ZDOVars.s_rooms, 0); if (num < 0 || num > 10000) { throw new InvalidOperationException("Invalid legacy dungeon room count."); } using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter binaryWriter = new BinaryWriter(memoryStream); binaryWriter.Write(num); for (int i = 0; i < num; i++) { string text = "room" + i; binaryWriter.Write(item2.GetInt(text, 0)); Vector3 vec = item2.GetVec3(text + "_pos", Vector3.zero); Quaternion quaternion = item2.GetQuaternion(text + "_rot", Quaternion.identity); binaryWriter.Write(vec.x); binaryWriter.Write(vec.y); binaryWriter.Write(vec.z); binaryWriter.Write(quaternion.x); binaryWriter.Write(quaternion.y); binaryWriter.Write(quaternion.z); binaryWriter.Write(quaternion.w); } array = memoryStream.ToArray(); } if (array.Length != byteArray.Length) { throw new InvalidOperationException("Native generation changed the saved dungeon layout; existing rooms were preserved."); } for (int j = 0; j < array.Length; j++) { if (array[j] != byteArray[j]) { throw new InvalidOperationException("Native generation changed the saved dungeon layout; existing rooms were preserved."); } } } } } private List<ZDO> SelectOldObjects(List<ZDO> nearby, List<ZDO> created, ZDO proxy, string token, List<Bounds> footprint) { //IL_004c: 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_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) Dictionary<int, List<Vector3>> dictionary = new Dictionary<int, List<Vector3>>(); HashSet<int> hashSet = new HashSet<int>(); foreach (ZDO item in created) { if (!dictionary.TryGetValue(item.GetPrefab(), out var value)) { value = (dictionary[item.GetPrefab()] = new List<Vector3>()); } value.Add(item.GetPosition()); GameObject prefab = ZNetScene.instance.GetPrefab(item.GetPrefab()); if ((Object)(object)prefab == (Object)null) { continue; } CreatureSpawner component = prefab.GetComponent<CreatureSpawner>(); if ((Object)(object)component != (Object)null && (Object)(object)component.m_creaturePrefab != (Object)null) { hashSet.Add(StringExtensionMethods.GetStableHashCode(Utils.GetPrefabName(component.m_creaturePrefab))); } SpawnArea component2 = prefab.GetComponent<SpawnArea>(); if (!((Object)(object)component2 != (Object)null)) { continue; } foreach (SpawnData prefab4 in component2.m_prefabs) { if ((Object)(object)prefab4.m_prefab != (Object)null) { hashSet.Add(StringExtensionMethods.GetStableHashCode(Utils.GetPrefabName(prefab4.m_prefab))); } } } List<ZDO> list2 = new List<ZDO>(); HashSet<ZDOID> hashSet2 = new HashSet<ZDOID>(); foreach (ZDO item2 in nearby) { if (!Inside(footprint, item2.GetPosition())) { continue; } bool flag = item2 == proxy || item2.GetString("jg224.rw.location.owner.v1", "") == token || hashSet.Contains(item2.GetPrefab()); GameObject prefab2 = ZNetScene.instance.GetPrefab(item2.GetPrefab()); if ((Object)(object)prefab2 == (Object)null) { throw new InvalidOperationException("An unknown network prefab is inside the location."); } if (!flag && dictionary.TryGetValue(item2.GetPrefab(), out var value2)) { flag = (Object)(object)prefab2.GetComponent<Character>() != (Object)null; int num = 0; while (!flag && num < value2.Count) { flag = Vector3.SqrMagnitude(item2.GetPosition() - value2[num]) <= 0.5625f; num++; } } if (flag && hashSet2.Add(item2.m_uid)) { list2.Add(item2); } } for (int i = 0; i < list2.Count; i++) { ZDO zDO = ZDOMan.instance.GetZDO(list2[i].GetConnectionZDOID((ConnectionType)3)); if (zDO != null && zDO.IsValid() && !hashSet2.Contains(zDO.m_uid)) { GameObject prefab3 = ZNetScene.instance.GetPrefab(zDO.GetPrefab()); if ((Object)(object)prefab3 == (Object)null || (Object)(object)prefab3.GetComponent<Character>() == (Object)null || _isSensitive(zDO) || _isProtected(zDO.GetPosition(), 2f)) { throw new InvalidOperationException("A linked spawned creature is protected or no longer recognized."); } hashSet2.Add(zDO.m_uid); list2.Add(zDO); } } return list2; } private bool HasSensitiveObject(List<ZDO> nearby, List<Bounds> footprint) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) foreach (ZDO item in nearby) { if (Inside(footprint, item.GetPosition()) && _isSensitive(item)) { return true; } } return false; } private bool SafeFootprint(List<Bounds> footprint) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) foreach (Bounds item in footprint) { Bounds current = item; Func<Vector3, float, bool> isProtected = _isProtected; Vector3 center = ((Bounds)(ref current)).center; Vector3 extents = ((Bounds)(ref current)).extents; if (isProtected(center, ((Vector3)(ref extents)).magnitude)) { return false; } } return true; } private static List<Bounds> BuildFootprint(GameObject prefab, ZoneLocation location, Vector3 position, Quaternion rotation) { //IL_0017: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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_0076: 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_008f: 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) //IL_00a9: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015d: 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_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01af: 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_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(8f, location.m_exteriorRadius); List<Bounds> list = new List<Bounds> { new Bounds(position, Vector3.one * (num * 2f + 4f)) }; PrefabState prefabState = new PrefabState(prefab); try { Location component = prefab.GetComponent<Location>(); Vector3 val = (((Object)(object)component != (Object)null && (Object)(object)component.m_generator != (Object)null) ? ((Component)component.m_generator).transform.localPosition : Vector3.zero); Vector3 val2 = (((Object)(object)component != (Object)null && (Object)(object)component.m_interiorTransform != (Object)null) ? component.m_interiorTransform.localPosition : Vector3.zero); prefab.transform.position = Vector3.zero; prefab.transform.rotation = Quaternion.identity; bool flag = (Object)(object)component != (Object)null && component.m_useCustomInteriorTransform && (Object)(object)component.m_generator != (Object)null && (Object)(object)component.m_interiorTransform != (Object)null; if (flag) { ((Component)component.m_generator).transform.localPosition = Vector3.zero; Vector3 val3 = ZoneSystem.GetZonePos(ZoneSystem.GetZone(position)) + val2 + val - position; Vector3 localPosition = Quaternion.Inverse(rotation) * val3; localPosition.y = val2.y; component.m_interiorTransform.localPosition = localPosition; component.m_interiorTransform.localRotation = Quaternion.Inverse(rotation); } ZNetView[] componentsInChildren = prefab.GetComponentsInChildren<ZNetView>(true); foreach (ZNetView val4 in componentsInChildren) { Vector3 val5 = position + rotation * ((Component)val4).transform.position; DungeonGenerator component2 = ((Component)val4).GetComponent<DungeonGenerator>(); if ((Object)(object)component2 != (Object)null) { Vector3 zonePos = ZoneSystem.GetZonePos(ZoneSystem.GetZone(val5)); zonePos.y = val5.y - (flag ? val.y : 0f); list.Add(new Bounds(zonePos, component2.m_zoneSize + Vector3.one * 4f)); } else if (!Inside(list, val5)) { list.Add(new Bounds(val5, Vector3.one * 4f)); } } return list; } finally { prefabState.Restore(); } } private static List<ZDO> FindObjects(List<Bounds> footprint) { //IL_0027: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_00cf: 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) List<ZDO> list = new List<ZDO>(); HashSet<ZDOID> hashSet = new HashSet<ZDOID>(); HashSet<Vector2s> hashSet2 = new HashSet<Vector2s>(); List<ZDO> list2 = new List<ZDO>(); Vector2s val = default(Vector2s); foreach (Bounds item in footprint) { Bounds current = item; Vector2s zone = ZoneSystem.GetZone(((Bounds)(ref current)).min); Vector2s zone2 = ZoneSystem.GetZone(((Bounds)(ref current)).max); if (zone2.x < zone.x || zone2.y < zone.y || zone2.x - zone.x > 32 || zone2.y - zone.y > 32) { throw new InvalidOperationException("Location footprint exceeds supported bounds."); } for (int i = zone.x; i <= zone2.x; i++) { for (int j = zone.y; j <= zone2.y; j++) { ((Vector2s)(ref val))..ctor(i, j); if (!hashSet2.Add(val)) { continue; } list2.Clear(); WorldAccess.FindSectorObjects(val, 0, list2); foreach (ZDO item2 in list2) { if (item2.IsValid() && hashSet.Add(item2.m_uid)) { list.Add(item2); } } } } } return list; } private static bool Inside(List<Bounds> bounds, Vector3 position) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) foreach (Bounds bound in bounds) { Bounds current = bound; if (((Bounds)(ref current)).Contains(position)) { return true; } } return false; } private static ZoneLocation FindLocation(int hash) { return LocationLookup.Find(ZoneSystem.instance.m_locations, hash); } private static void Own(ZDO zdo) { zdo.SetOwner(ZDOMan.GetSessionID()); } private static long Milliseconds(double seconds) { return checked((long)(seconds * 1000.0)); } private static bool Finite(double value) { if (!double.IsNaN(value)) { return !double.IsInfinity(value); } return false; } private static void Destroy(ZDO zdo) { if (zdo != null && zdo.IsValid()) { Own(zdo); ZNetView val = ZNetScene.instance.FindInstance(zdo); if ((Object)(object)val != (Object)null) { ZNetScene.instance.Destroy(((Component)val).gameObject); } else { ZDOMan.instance.DestroyZDO(zdo); } } } private static void FlushDestroyed() { SendDestroyedMethod.Invoke(ZDOMan.instance, null); } } internal sealed class RegenerationRuntime { private readonly Settings _settings; private readonly ICoreServices _core; private readonly Action<string> _log; private long _world; private bool _started; private bool _faulted; private double _nextScan; private WorldAccess _access; private TerrainRegenerator _terrain; private ResourceRegenerator _resources; private LocationRegenerator _locations; private ZDOID[] _scan; private int _cursor; internal RegenerationRuntime(Settings settings, ICoreServices core, Action<string> log) { _settings = settings; _core = core; _log = log; } internal void Tick() { //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) if (!WorldAccess.Server) { if (_started) { Stop(); } return; } try { long worldUID = ZNet.instance.GetWorldUID(); if (_started && worldUID != _world) { Stop(); } if (!_started) { _world = worldUID; _started = true; _faulted = false; _access = new WorldAccess(_settings, _core, worldUID, _log); _terrain = new TerrainRegenerator(_access, _log); _resources = new ResourceRegenerator(_access, worldUID, _log, () => !_faulted && _settings.Enabled.Value && _settings.Resources.Value); _locations = new LocationRegenerator(_access.Protected, _access.Sensitive, _access.Backup, _log); _resources.Load(); _core.Modules.SetState(Plugin.ModuleId, (ModuleRuntimeState)2, "World restoration records loaded."); _log("Regeneration records loaded for world " + worldUID + ". Default terrain/location cycle: 30 in-game days."); } if (_faulted || !_settings.Enabled.Value) { return; } double now = WorldAccess.Now; if (_resources.HasPendingWork) { if (_settings.Resources.Value) { _resources.RunPending(now, (double)_settings.ResourceDays.Value * WorldAccess.DaySeconds); } else { _resources.CancelPendingWork(); } return; } if (_scan == null) { if (Time.unscaledTimeAsDouble < _nextScan) { return; } _scan = WorldAccess.Objects.Keys.ToArray(); _cursor = 0; if (_settings.Resources.Value) { _resources.PrepareScan(); } } int num = Math.Min(_scan.Length, _cursor + 128); while (_cursor < num) { ZDO zDO = ZDOMan.instance.GetZDO(_scan[_cursor]); if (zDO != null) { if (_settings.Terrain.Value) { _terrain.Visit(zDO, now, (double)_settings.TerrainDays.Value * WorldAccess.DaySeconds); } if (_settings.Resources.Value) { _resources.Observe(zDO); } } _cursor++; } if (_cursor >= _scan.Length) { _scan = null; _nextScan = Time.unscaledTimeAsDouble + (double)_settings.ScanSeconds.Value; if (_settings.Resources.Value) { _resources.Tick(now, (double)_settings.ResourceDays.Value * WorldAccess.DaySeconds); } if (_settings.Locations.Value) { _locations.Tick(now, (double)_settings.LocationDays.Value * WorldAccess.DaySeconds); } } } catch (Exception ex) { _faulted = true; _core.Modules.SetState(Plugin.ModuleId, (ModuleRuntimeState)5, ex.Message); _log("Regeneration paused to preserve world state: " + ex); } } internal void Stop() { try { if (_started && !_faulted) { _resources?.Save(); } } catch (Exception ex) { _log("Could not save regeneration records: " + ex.Message); } _resources?.Dispose(); _scan = null; _terrain = null; _resources = null; _locations = null; _access = null; _started = false; _nextScan = 0.0; } } internal sealed class ResourceRegenerator : IDisposable { private sealed class CaptureScope : IDisposable { private bool _ended; public void Dispose() { if (!_ended) { _ended = true; _suppression--; } } } internal const string PlantedKey = "jg224.rw.player-planted.v1"; internal const string ResourceKey = "jg224.rw.resource.v1"; private readonly WorldAccess _access; private readonly long _world; private readonly Action<string> _log; private readonly Func<bool> _trackingEnabled; private static readonly HashSet<ResourceRegenerator> Active = new HashSet<ResourceRegenerator>(); private static readonly HashSet<ZDOID> MutationIds = new HashSet<ZDOID>(); private static readonly MethodInfo SendDestroyed = AccessTools.Method(typeof(ZDOMan), "SendDestroyed", Type.EmptyTypes, (Type[])null) ?? throw new MissingMethodException("ZDOMan.SendDestroyed"); private static int _suppression; private ZDOMan _manager; private Exception _captureFailure; private bool _scanComplete; private bool _disposed; private bool _limitReported; private int _restoredThisCycle; private readonly Dictionary<string, ResourceRecord> _records = new Dictionary<string, ResourceRecord>(StringComparer.Ordinal); private readonly Queue<string> _capacityCandidates = new Queue<string>(); private readonly HashSet<string> _untouchedOriginals = new HashSet<string>(StringComparer.Ordinal); private readonly Dictionary<ZDOID, ResourceRecord> _byId = new Dictionary<ZDOID, ResourceRecord>(); private readonly HashSet<int> _natural = new HashSet<int>(); private readonly Dictionary<int, Plant> _plants = new Dictionary<int, Plant>(); private readonly Dictionary<int, int> _rockAreas = new Dictionary<int, int>(); private readonly Dictionary<string, ResourceRecord> _byPosition = new Dictionary<string, ResourceRecord>(StringComparer.Ordinal); private IAtomicStore _store; private bool _dirty; private bool _catalogued; private string[] _pendingScan; private int _pendingCursor; internal bool HasPendingWork => _pendingScan != null; internal ResourceRegenerator(WorldAccess access, long world, Action<string> log, Func<bool> trackingEnabled = null) { _access = access; _world = world; _log = log; _trackingEnabled = trackingEnabled ?? ((Func<bool>)(() => true)); } internal void Load() { //IL_00a5: 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) _store = _access.OpenStore("resources.bin", 33554432); AtomicStoreRecord val = default(AtomicStoreRecord); string error = default(string); if (_store.TryLoad(ref val, ref error)) { if (val.OwnerId != _world || val.SchemaVersion != 1 || !ResourceRecordCodec.TryDecode(val.Payload, out var records, out error)) { throw new InvalidDataException("Resource ledger rejected: " + error); } foreach (ResourceRecord item in records) { _records.Add(item.Key, item); _byId[new ZDOID(item.UserId, item.ObjectId)] = item; _byPosition[PositionKey(item.Prefab, Position(item))] = item; if (ResourceStateRules.IsUntouchedOriginal(item)) { _capacityCandidates.Enqueue(item.Key); _untouchedOriginals.Add(item.Key); } } if (val.RecoveredFromBackup) { _log("Resource records recovered from bounded backup; pending spawns remain guarded."); } } else if (File.Exists(_store.Path) || File.Exists(_store.Path + ".bak")) { throw new InvalidDataException("Resource ledger could not be loaded: " + error); } Catalog(); _manager = ZDOMan.instance; ZDOMan manager = _manager; manager.m_onZDODestroyed = (Action<ZDO>)Delegate.Combine(manager.m_onZDODestroyed, new Action<ZDO>(OnNativeDestroyed)); Active.Add(this); } internal void PrepareScan() { if (_captureFailure != null) { throw new InvalidDataException("Resource capture failed; regeneration is paused.", _captureFailure); } _scanComplete = false; Catalog(); } private void Catalog() { if (_catalogued) { return; } foreach (ZoneVegetation item in ZoneSystem.instance.m_vegetation) { if (Object.op_Implicit((Object)(object)item.m_prefab) && Object.op_Implicit((Object)(object)item.m_prefab.GetComponent<ZNetView>())) { _natural.Add(StringExtensionMethods.GetStableHashCode(((Object)item.m_prefab).name)); } } foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { Plant val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<Plant>() : null); if (!Object.op_Implicit((Object)(object)val)) { continue; } GameObject[] grownPrefabs = val.m_grownPrefabs; foreach (GameObject val2 in grownPrefabs) { if (Object.op_Implicit((Object)(object)val2) && val.m_growTime > 0f && val.m_growTimeMax >= val.m_growTime) { _plants[StringExtensionMethods.GetStableHashCode(((Object)val2).name)] = val; } } } _catalogued = true; } internal void Observe(ZDO zdo, bool destroying = false) { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: 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_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02e4: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0318: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) if (!_natural.Contains(zdo.GetPrefab())) { return; } PrefabInfo prefabInfo = _access.Info(zdo.GetPrefab()); if (!Object.op_Implicit((Object)(object)prefabInfo.Prefab) || (!prefabInfo.Tree && !prefabInfo.Rock && !Object.op_Implicit((Object)(object)prefabInfo.Pickable) && !Object.op_Implicit((Object)(object)prefabInfo.Prefab.GetComponent<Destructible>())) || prefabInfo.Piece || prefabInfo.Character || prefabInfo.Container || prefabInfo.Item || prefabInfo.Terrain || zdo.GetBool("jg224.rw.player-planted.v1", false) || zdo.GetLong(ZDOVars.s_creator, 0L) != 0L || zdo.GetString("jg224.rw.location.owner.v1", "").Length != 0 || zdo.GetString("jg224.rw.location.transaction.v1", "").Length != 0) { return; } if (_byId.TryGetValue(zdo.m_uid, out var value)) { if (destroying) { _untouchedOriginals.Remove(value.Key); } if (!destroying && ResourceStateRules.CanRetireIntact(value, VerifiedPresence(value))) { RetireIntact(value); } return; } string text = zdo.GetString("jg224.rw.resource.v1", ""); ResourceRecord value3; if (text.Length > 0 && _records.TryGetValue(text, out var value2)) { if (!value2.Pending && ZDOMan.instance.GetZDO(new ZDOID(value2.UserId, value2.ObjectId)) == null && value2.Prefab == zdo.GetPrefab() && PositionKey(value2.Prefab, Position(value2)) == PositionKey(zdo.GetPrefab(), zdo.GetPosition())) { Attach(value2, zdo); } } else if (_byPosition.TryGetValue(PositionKey(zdo.GetPrefab(), zdo.GetPosition()), out value3)) { if (!value3.Pending && ZDOMan.instance.GetZDO(new ZDOID(value3.UserId, value3.ObjectId)) == null) { Attach(value3, zdo); } } else { if (!ResourceStateRules.ShouldTrackObservation(destroying ? ResourcePresence.Missing : Presence(zdo), destroying)) { return; } if (!EnsureCapacity()) { if (!_limitReported) { _limitReported = true; _log("Resource ledger holds 100,000 harvested or protected records after intact-original reclamation; additional depleted resources cannot be tracked until capacity is available. Existing records are preserved."); } return; } Vector3 position = zdo.GetPosition(); Quaternion rotation = zdo.GetRotation(); Vector3 vec = zdo.GetVec3(ZDOVars.s_scaleHash, Vector3.one * zdo.GetFloat(ZDOVars.s_scaleScalarHash, 1f)); text = OriginalKey(((ZDOID)(ref zdo.m_uid)).UserID, ((ZDOID)(ref zdo.m_uid)).ID); ResourceRecord resourceRecord = new ResourceRecord { Key = text, UserId = ((ZDOID)(ref zdo.m_uid)).UserID, ObjectId = ((ZDOID)(ref zdo.m_uid)).ID, Prefab = zdo.GetPrefab(), X = position.x, Y = position.y, Z = position.z, RotX = rotation.x, RotY = rotation.y, RotZ = rotation.z, RotW = rotation.w, ScaleX = vec.x, ScaleY = vec.y, ScaleZ = vec.z, GrowSeconds = GrowthTime(zdo), MissingSince = -1.0 }; _records.Add(text, resourceRecord); _byId[zdo.m_uid] = resourceRecord; _byPosition[PositionKey(resourceRecord.Prefab, position)] = resourceRecord; _dirty = true; } } private ResourcePresence VerifiedPresence(ResourceRecord record) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (!_untouchedOriginals.Contains(record.Key)) { return ResourcePresence.Unknown; } ZDO zDO = ZDOMan.instance.GetZDO(new ZDOID(record.UserId, record.ObjectId)); if (zDO == null) { return ResourcePresence.Missing; } if (zDO.GetPrefab() != record.Prefab || zDO.GetString("jg224.rw.resource.v1", "").Length != 0 || Vector3.SqrMagnitude(zDO.GetPosition() - Position(record)) > 0.25f) { return ResourcePresence.Unknown; } return Presence(zDO); } private bool EnsureCapacity() { if (_records.Count < 100000) { return true; } if (!ResourceStateRules.TryTakeIntactCandidate(_records, _capacityCandidates, VerifiedPresence, out var retired)) { return false; } RetireIntact(retired); return true; } private void RetireIntact(ResourceRecord record) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) _records.Remove(record.Key); _untouchedOriginals.Remove(record.Key); _byId.Remove(new ZDOID(record.UserId, record.ObjectId)); _byPosition.Remove(PositionKey(record.Prefab, Position(record))); _dirty = true; _limitReported = false; } private double GrowthTime(ZDO zdo) { //IL_005d: 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_0024: Unknown result type (might be due to invalid IL or missing references) if (!_plants.TryGetValue(zdo.GetPrefab(), out var value)) { return 0.0; } State state = Random.state; try { Random.InitState((int)(((ZDOID)(ref zdo.m_uid)).UserID + ((ZDOID)(ref zdo.m_uid)).ID)); return Mathf.Lerp(value.m_growTime, value.m_growTimeMax, Random.value); } finally { Random.state = state; } } private void Attach(ResourceRecord record, ZDO zdo) { //IL_0024: 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) _untouchedOriginals.Remove(record.Key); _byId.Remove(new ZDOID(record.UserId, record.ObjectId)); record.UserId = ((ZDOID)(ref zdo.m_uid)).UserID; record.ObjectId = ((ZDOID)(ref zdo.m_uid)).ID; record.Pending = false; record.MissingSince = -1.0; _byId[zdo.m_uid] = record; _dirty = true; } internal void Tick(double now, double fallbackDelay) { _scanComplete = true; if (_pendingScan != null) { throw new InvalidOperationException("Resource scan cycles cannot overlap."); } _pendingScan = _records.Keys.ToArray(); _pendingCursor = 0; _restoredThisCycle = 0; RunPending(now, fallbackDelay); } internal void CancelPendingWork() { _pendingScan = null; _scanComplete = false; } internal void RunPending(double now, double fallbackDelay) { //IL_0080: 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_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_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) if (_captureFailure != null) { throw new InvalidDataException("Resource capture failed; regeneration is paused.", _captureFailure); } if (_pendingScan == null || !_scanComplete || !WorldAccess.Server) { return; } int num = Math.Min(_pendingScan.Length, _pendingCursor + 256); ZDOID key = default(ZDOID); while (_pendingCursor < num) { if (_records.TryGetValue(_pendingScan[_pendingCursor], out var value)) { ZDO val = ZDOMan.instance.GetZDO(new ZDOID(value.UserId, value.ObjectId)); if (val != null && (val.GetPrefab() != value.Prefab || Vector3.SqrMagnitude(val.GetPosition() - Position(value)) > 0.25f)) { val = null; } if (val == null || (!val.GetBool("jg224.rw.player-planted.v1", false) && !_access.Sensitive(val))) { ResourcePresence resourcePresence = Presence(val); if (resourcePresence != ResourcePresence.Unknown) { if (resourcePresence != ResourcePresence.Intact) { _untouchedOriginals.Remove(value.Key); } if (value.Pending) { ReconcilePending(value, val, resourcePresence); } else { if (ResourceStateRules.ObservePresence(value, resourcePresence, now)) { _dirty = true; } double delaySeconds; if (ResourceStateRules.CanRetireIntact(value, VerifiedPresence(value))) { RetireIntact(value); } else if (resourcePresence != ResourcePresence.Intact && _restoredThisCycle < 8 && ResetRules.TryGetResourceDelaySeconds((value.GrowSeconds > 0.0) ? new double?(value.GrowSeconds) : ((double?)null), fallbackDelay, out delaySeconds) && ResetRules.IsDue(now, value.MissingSince, delaySeconds) && !_access.Protected(Position(value), 8f) && (val == null || !val.HasOwner() || val.IsOwner())) { if (FindReplacements(value, val).Count != 0) { value.Pending = true; _dirty = true; Save(); } else { PrefabInfo prefabInfo = _access.Info(value.Prefab); if (Object.op_Implicit((Object)(object)prefabInfo.Prefab)) { List<ZDO> list = OriginalObjects(value, val, prefabInfo); ZDOID[] array = list.Select((ZDO z) => z.m_uid).ToArray(); if (list.Count != 0) { _access.Backup(list, "resource"); } value.Pending = true; _dirty = true; Save(); ZDO val2 = ZDOMan.instance.CreateNewZDO(Position(value), value.Prefab); val2.SetPrefab(value.Prefab); WorldAccess.Own(val2); val2.Persistent = true; ZNetView component = prefabInfo.Prefab.GetComponent<ZNetView>(); val2.Type = component.m_type; val2.Distant = component.m_distant; val2.SetRotation(new Quaternion(value.RotX, value.RotY, value.RotZ, value.RotW)); val2.Set(ZDOVars.s_scaleHash, new Vector3(value.ScaleX, value.ScaleY, value.ScaleZ)); val2.Set("jg224.rw.resource.v1", value.Key); DeleteOriginals(list, array); ((ZDOID)(ref key))..ctor(value.UserId, value.ObjectId); if (!ResourceStateRules.TryCompleteReplacement(value, val2.IsValid() && val2.GetPrefab() == value.Prefab && val2.GetString("jg224.rw.resource.v1", "") == value.Key, array.All((ZDOID id) => ZDOMan.instance.GetZDO(id) == null), ((ZDOID)(ref val2.m_uid)).UserID, ((ZDOID)(ref val2.m_uid)).ID)) { throw new InvalidOperationException("Resource replacement could not be verified; reservation retained."); } ZDOID[] array2 = array; foreach (ZDOID key2 in array2) { _byId.Remove(key2); } _byId.Remove(key); _byId[val2.m_uid] = value; _dirty = true; Save(); _restoredThisCycle++; } } } } } } } _pendingCursor++; } if (_pendingCursor >= _pendingScan.Length) { _pendingScan = null; Save(); if (_restoredThisCycle > 0) { _log("Regrew " + _restoredThisCycle + " natural resources."); } } } private List<ZDO> FindReplacements(ResourceRecord record, ZDO current) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) List<ZDO> list = new List<ZDO>(); WorldAccess.FindSectorObjects(ZoneSystem.GetZone(Position(record)), 1, list); return list.Where((ZDO zdo) => zdo != current && zdo.GetPrefab() == record.Prefab && Vector3.SqrMagnitude(zdo.GetPosition() - Position(record)) < 0.25f).ToList(); } private void ReconcilePending(ResourceRecord record, ZDO current, ResourcePresence presence) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) if (_restoredThisCycle >= 8 || _access.Protected(Position(record), 8f) || (current != null && current.HasOwner() && !current.IsOwner())) { return; } List<ZDO> list = FindReplacements(record, current); bool conflictingIdentity = list.Any((ZDO z) => _access.Sensitive(z) || Presence(z) != ResourcePresence.Intact || (z.GetString("jg224.rw.resource.v1", "").Length > 0 && z.GetString("jg224.rw.resource.v1", "") != record.Key) || z.GetString("jg224.rw.location.owner.v1", "").Length > 0 || z.GetString("jg224.rw.location.transaction.v1", "").Length > 0); ResourceRecoveryAction resourceRecoveryAction = ResourceStateRules.PlanPendingRecovery(_scanComplete, presence, list.Count, conflictingIdentity); switch (resourceRecoveryAction) { case ResourceRecoveryAction.Wait: return; case ResourceRecoveryAction.KeepIntactOriginal: case ResourceRecoveryAction.RetryCreation: record.Pending = false; if (resourceRecoveryAction == ResourceRecoveryAction.KeepIntactOriginal) { record.MissingSince = -1.0; } _dirty = true; Save(); return; } ZDO val = list[0]; List<ZDO> list2 = OriginalObjects(record, current, _access.Info(record.Prefab)); ZDOID[] array = list2.Select((ZDO z) => z.m_uid).ToArray(); if (list2.Count > 0) { _access.Backup(list2, "resource-recovery"); } ZDOID key = default(ZDOID); ((ZDOID)(ref key))..ctor(record.UserId, record.ObjectId); DeleteOriginals(list2, array); if (!ResourceStateRules.TryCompleteReplacement(record, val.IsValid() && val.GetPrefab() == record.Prefab, array.All((ZDOID id) => ZDOMan.instance.GetZDO(id) == null), ((ZDOID)(ref val.m_uid)).UserID, ((ZDOID)(ref val.m_uid)).ID)) { throw new InvalidOperationException("Resource recovery could not verify replacement; reservation retained."); } _byId.Remove(key); _byId[val.m_uid] = record; _dirty = true; Save(); _restoredThisCycle++; } private List<ZDO> OriginalObjects(ResourceRecord record, ZDO current, PrefabInfo info) { //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_008a: 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) List<ZDO> list = new List<ZDO>(); if (current != null) { list.Add(current); } if (!Object.op_Implicit((Object)(object)info.Prefab)) { return list; } TreeBase component = info.Prefab.GetComponent<TreeBase>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.m_stubPrefab)) { return list; } int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)component.m_stubPrefab).name); List<ZDO> list2 = new List<ZDO>(); WorldAccess.FindSectorObjects(ZoneSystem.GetZone(Position(record)), 1, list2); foreach (ZDO item in list2) { if (item.GetPrefab() == stableHashCode && Vector3.SqrMagnitude(item.GetPosition() - Position(record)) < 0.25f && !_access.Sensitive(item)) { if (item.HasOwner() && !item.IsOwner()) { throw new InvalidOperationException("A stump changed ownership during resource restoration."); } list.Add(item); } } return list; } private static void DeleteOriginals(List<ZDO> originals, ZDOID[] originalIds) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) ZDOID[] array = originalIds; foreach (ZDOID item in array) { MutationIds.Add(item); } try { foreach (ZDO original in originals) { WorldAccess.Destroy(original); } SendDestroyed.Invoke(ZDOMan.instance, null); if (originalIds.Any((ZDOID id) => ZDOMan.instance.GetZDO(id) != null)) { throw new InvalidOperationException("Native resource deletion did not complete; reservation retained."); } } finally { array = originalIds; foreach (ZDOID item2 in array) { MutationIds.Remove(item2); } } } private ResourcePresence Presence(ZDO zdo) { if (zdo == null) { return ResourcePresence.Missing; } PrefabInfo prefabInfo = _access.Info(zdo.GetPrefab()); if (!Object.op_Implicit((Object)(object)prefabInfo.Prefab)) { return ResourcePresence.Unknown; } if (Object.op_Implicit((Object)(object)prefabInfo.Pickable)) { if (!(prefabInfo.Pickable.m_respawnTimeMinutes <= 0f) || !zdo.GetBool(ZDOVars.s_picked, false)) { return ResourcePresence.Intact; } return ResourcePresence.Depleted; } MineRock5 component = prefabInfo.Prefab.GetComponent<MineRock5>(); MineRock component2 = prefabInfo.Prefab.GetComponent<MineRock>(); if (!Object.op_Implicit((Object)(object)component) && !Object.op_Implicit((Object)(object)component2)) { return ResourcePresence.Intact; } if (!_rockAreas.TryGetValue(zdo.GetPrefab(), out var value)) { value = ((Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)component2.m_areaRoot)) ? component2.m_areaRoot : prefabInfo.Prefab).GetComponentsInChildren<Collider>().Length; _rockAreas.Add(zdo.GetPrefab(), value); } if (value < 1 || value > 10000) { return ResourcePresence.Unknown; } bool depleted; if (Object.op_Implicit((Object)(object)component)) { string text = zdo.GetString(ZDOVars.s_health, ""); if (text.Length == 0) { return ResourcePresence.Intact; } if (text.Length > 53340) { return ResourcePresence.Unknown; } try { if (!NativeRockHealth.TryReadMineRock5(Convert.FromBase64String(text), value, out depleted)) { return ResourcePresence.Unknown; } } catch (FormatException) { return ResourcePresence.Unknown; } } else { float[] array = new float[value]; for (int i = 0; i < value; i++) { array[i] = zdo.GetFloat("Health" + i, 1f); } if (!NativeRockHealth.TryGetDepletion(array, out depleted)) { return ResourcePresence.Unknown; } } if (!depleted) { return ResourcePresence.Intact; } return ResourcePresence.Depleted; } internal void Save() { if (_captureFailure != null) { throw new InvalidDataException("Resource capture failed; records preserved for recovery.", _captureFailure); } if (_dirty && _store != null) { _store.Save(1, _world, ResourceRecordCodec.Encode(_records.Values)); _dirty = false; } } private void OnNativeDestroyed(ZDO zdo) { //IL_0015: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) if (_disposed || !WorldAccess.Server || MutationIds.Contains(zdo.m_uid)) { return; } try { if (_suppression > 0) { if (_byId.TryGetValue(zdo.m_uid, out var value)) { _untouchedOriginals.Remove(value.Key); _byId.Remove(zdo.m_uid); _records.Remove(value.Key); _byPosition.Remove(PositionKey(value.Prefab, Position(value))); _dirty = true; } } else if (_trackingEnabled()) { Observe(zdo, destroying: true); if (_byId.TryGetValue(zdo.m_uid, out var value2) && !value2.Pending) { value2.MissingSince = WorldAccess.Now; _dirty = true; } } } catch (Exception error) { CaptureFailure(error); } } private void CaptureFailure(Exception error) { if (_captureFailure == null) { _captureFailure = error; _log("Resource capture failed; automatic restoration will pause: " + error.Message); } } internal static void FlushCaptured() { ResourceRegenerator[] array = Active.ToArray(); foreach (ResourceRegenerator resourceRegenerator in array) { if (resourceRegenerator._captureFailure == null) { try { resourceRegenerator.Save(); } catch (Exception error) { resourceRegenerator.CaptureFailure(error); } } } } internal static IDisposable SuppressCapture() { if (_suppression == 0 && WorldAccess.Server) { SendDestroyed.Invoke(ZDOMan.instance, null); } _suppression++; return new CaptureScope(); } public void Dispose() { if (!_disposed) { _disposed = true; if (_manager != null) { ZDOMan manager = _manager; manager.m_onZDODestroyed = (Action<ZDO>)Delegate.Remove(manager.m_onZDODestroyed, new Action<ZDO>(OnNativeDestroyed)); } Active.Remove(this); _pendingScan = null; } } private static Vector3 Position(ResourceRecord record) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(record.X, record.Y, record.Z); } private static string OriginalKey(long userId, uint objectId) { return userId.ToString(CultureInfo.InvariantCulture) + ":" + objectId.ToString(CultureInfo.InvariantCulture); } private static string PositionKey(int prefab, Vector3 position) { return prefab.ToString(CultureInfo.InvariantCulture) + ":" + position.x.ToString("R", CultureInfo.InvariantCulture) + ":" + position.y.ToString("R", CultureInfo.InvariantCulture) + ":" + position.z.ToString("R", CultureInfo.InvariantCulture); } } [HarmonyPatch(typeof(ZDOMan), "RPC_DestroyZDO", new Type[] { typeof(long), typeof(ZPackage) })] internal static class ResourceDestructionCapture { private static Exception Finalizer(Exception __exception) { ResourceRegenerator.FlushCaptured(); return __exception; } } [HarmonyPatch(typeof(Plant), "Grow")] internal static class PlayerPlantOwnership { private static void Prefix(Plant __instance, out long __state) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); __state = ((Object.op_Implicit((Object)(object)component) && component.IsValid()) ? component.GetZDO().GetLong(ZDOVars.s_creator, 0L) : 0); } private static void Postfix(GameObject __result, long __state) { if (!Object.op_Implicit((Object)(object)__result)) { return; } ZNetView component = __result.GetComponent<ZNetView>(); if (Object.op_Implicit((Object)(object)component) && component.IsValid() && component.IsOwner()) { component.GetZDO().Set("jg224.rw.player-planted.v1", true); if (__state != 0L) { component.GetZDO().Set(ZDOVars.s_creator, __state); } } } } internal sealed class TerrainRegenerator { private const string Stamp = "jg224.rw.terrain.time"; private const string Fingerprint = "jg224.rw.terrain.hash"; private const string Schema = "jg224.rw.terrain.schema"; private readonly WorldAccess _access; private readonly Action<string> _log; private readonly HashSet<ZDOID> _reported = new HashSet<ZDOID>(); internal TerrainRegenerator(WorldAccess access, Action<string> log) { _access = access; _log = log; } internal unsafe void Visit(ZDO zdo, double now, double delay) { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: 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_0227: 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_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) PrefabInfo prefabInfo = _access.Info(zdo.GetPrefab()); if ((!prefabInfo.Terrain && (!Object.op_Implicit((Object)(object)prefabInfo.LegacyTerrain) || !prefabInfo.LegacyTerrain.m_playerModifiction || prefabInfo.LegacyTerrain.m_useTerrainCompiler)) || (zdo.HasOwner() && !zdo.IsOwner()) || zdo.GetInt("jg224.rw.terrain.schema", 0) > 1) { return; } if (!prefabInfo.Terrain) { if (!StartOrChanged(zdo, now, 1L)) { float num = Math.Max(prefabInfo.LegacyTerrain.m_levelRadius, Math.Max(prefabInfo.LegacyTerrain.m_smoothRadius, prefabInfo.LegacyTerrain.m_paintRadius)); if (prefabInfo.LegacyTerrain.m_square) { num *= (float)Math.Sqrt(2.0); } if (ResetRules.IsDue(now, zdo.GetFloat("jg224.rw.terrain.time", -1f), delay) && !_access.Protected(zdo.GetPosition(), num)) { _access.Backup((IReadOnlyList<ZDO>)(object)new ZDO[1] { zdo }, "legacy-terrain"); WorldAccess.Destroy(zdo); } } return; } byte[] byteArray = zdo.GetByteArray(ZDOVars.s_TCData, (byte[])null); if (byteArray == null || byteArray.Length == 0 || byteArray.Length > 1782842) { return; } long hash = Hash(byteArray); if (StartOrChanged(zdo, now, hash) || !ResetRules.IsDue(now, zdo.GetFloat("jg224.rw.terrain.time", -1f), delay)) { return; } Vector3 center = zdo.GetPosition(); if (!WorldAccess.Finite(center)) { return; } float scale; Func<Vector3, bool> protectedPoint; if (!TerrainPayload.TryInflate(byteArray, out var raw) || !TerrainData.TryDecode(raw, out var data, out var _)) { if (_reported.Add(zdo.m_uid)) { Action<string> log = _log; ZDOID uid = zdo.m_uid; log("Skipping unsupported/corrupt terrain compiler " + ((object)(*(ZDOID*)(&uid))/*cast due to .constrained prefix*/).ToString() + "."); } } else { if (data.PaintStride != data.Width + 1) { return; } if (!TryGetGeometry(center, data.Width, out scale, out var extent, out var cellMargin)) { if (_reported.Add(zdo.m_uid)) { Action<string> log2 = _log; ZDOID uid = zdo.m_uid; log2("Skipping terrain compiler whose geometry differs from the current zone prefab: " + ((object)(*(ZDOID*)(&uid))/*cast due to .constrained prefix*/).ToString() + "."); } } else if (!_access.PlayersNear(center, extent + cellMargin)) { protectedPoint = _access.PointProtection(center, extent, cellMargin); int num2 = data.ClearWhere((int i) => Allowed(i, data.Width + 1), (int i) => Allowed(i, data.PaintStride)); if (num2 != 0) { byte[] array = Utils.Compress(data.Encode()); _access.Backup((IReadOnlyList<ZDO>)(object)new ZDO[1] { zdo }, "terrain"); WorldAccess.Own(zdo); zdo.Set(ZDOVars.s_TCData, array); zdo.Set("jg224.rw.terrain.hash", Hash(array)); zdo.Set("jg224.rw.terrain.time", (float)now); ZDOMan.instance.ForceSendZDO(zdo.m_uid); Action<string> log3 = _log; string[] obj = new string[5] { "Restored ", num2.ToString(), " unprotected terrain cells at ", null, null }; Vector3 val = center; obj[3] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString(); obj[4] = "."; log3(string.Concat(obj)); } } } bool Allowed(int index, int stride) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) Vector3 arg = center + new Vector3(((float)(index % stride) - (float)data.Width / 2f) * scale, 0f, ((float)(index / stride) - (float)data.Width / 2f) * scale); return !protectedPoint(arg); } } private static bool StartOrChanged(ZDO zdo, double now, long hash) { if (zdo.GetInt("jg224.rw.terrain.schema", 0) == 1 && zdo.GetLong("jg224.rw.terrain.hash", 0L) == hash && zdo.GetFloat("jg224.rw.terrain.time", -1f) >= 0f && (double)zdo.GetFloat("jg224.rw.terrain.time", 0f) <= now) { return false; } WorldAccess.Own(zdo); zdo.Set("jg224.rw.terrain.schema", 1); zdo.Set("jg224.rw.terrain.hash", hash); zdo.Set("jg224.rw.terrain.time", (float)now); return true; } private static long Hash(byte[] bytes) { long num = 1469598103934665603L; foreach (byte b in bytes) { num = (num ^ b) * 1099511628211L; } return num; } private static bool TryGetGeometry(Vector3 center, int width, out float scale, out float extent, out float cellMargin) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) scale = 0f; extent = 0f; cellMargin = 0f; GameObject zonePrefab = ZoneSystem.instance.m_zonePrefab; if (!Object.op_Implicit((Object)(object)zonePrefab)) { return false; } Heightmap componentInChildren = zonePrefab.GetComponentInChildren<Heightmap>(); if (!Object.op_Implicit((Object)(object)componentInChildren) || componentInChildren.m_width != width || !WorldAccess.IsFinite(componentInChildr