Decompiled source of VAutomationCore v1.0.1
VAutomationCore.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; 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.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using ProjectM; using ProjectM.Network; using ProjectM.Shared; using Stunlock.Core; using Unity.Collections; using Unity.Entities; using Unity.Mathematics; using Unity.Transforms; using VAutomationCore; using VAutomationCore.Core; using VAutomationCore.Core.Api; using VAutomationCore.Core.Data; using VAutomationCore.Core.Events; using VAutomationCore.Core.Logging; using VAutomationCore.Core.Services; using VAutomationCore.Models; using VAutomationCore.Services; using VampireCommandFramework; using VampireCommandFramework.Breadstone; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("Bluelock.Tests")] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("VAutomation")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (c) Coyoteq1 2026")] [assembly: AssemblyDescription("Core library for V Rising automation mods providing shared utilities, ECS helpers, and configuration management.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1-beta.2+5cc4ae7758094d55742ad80b60693af3234305f4")] [assembly: AssemblyProduct("VAutomationCore")] [assembly: AssemblyTitle("VAutomationCore")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Coyoteq1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace VAutomation.Core.Json { public static class VAutoJsonOptions { public static JsonSerializerOptions Default { get; } = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true, IgnoreReadOnlyProperties = false, AllowTrailingCommas = true, ReadCommentHandling = JsonCommentHandling.Skip }; public static JsonSerializerOptions WithConverters(params JsonConverter[] converters) { JsonSerializerOptions jsonSerializerOptions = new JsonSerializerOptions(Default); foreach (JsonConverter item in converters) { jsonSerializerOptions.Converters.Add(item); } return jsonSerializerOptions; } } } namespace VAuto.Services.Interfaces { public interface IService { bool IsInitialized { get; } ManualLogSource Log { get; } void Initialize(); void Cleanup(); } public interface IEntityService : IService { bool RegisterEntity(Entity entity); bool UnregisterEntity(Entity entity); int GetEntityCount(); } public interface IArenaService : IEntityService, IService { bool CreateArena(string arenaId, float3 center, float radius); bool DeleteArena(string arenaId); List<string> GetArenaIds(); int GetArenaCount(); } public interface IPlayerService : IService { bool AddPlayer(ulong platformId, string characterName); bool RemovePlayer(ulong platformId); List<ulong> GetPlayerIds(); int GetPlayerCount(); bool PlayerExists(ulong platformId); } public interface IDataPersistenceService : IService { bool SaveData(string key, object data); object LoadData(string key, Type dataType); bool DeleteData(string key); bool DataExists(string key); } public interface IComponentService : IService { bool SaveComponents(Entity entity, string saveId = null); bool RestoreComponents(Entity entity, string saveId = null); bool DeleteComponents(Entity entity); } public interface IBuildService : IService { bool BuildStructure(Entity user, string structureName, float3 position, quaternion? rotation = null); bool RemoveStructure(string structureName); List<string> GetAvailableStructures(); void SetBuildPermission(ulong platformId, bool canBuild); } public interface IVisualEffectService : IService { bool CreateEffect(string name, float3 position, object type, float4 color); bool RemoveEffect(string name); bool UpdateEffect(string name, float3? position = null, float4? color = null); int GetActiveEffectCount(); } public interface IDatabaseService : IDataPersistenceService, IService { bool SaveArenaState(string arenaId, object arenaState); object LoadArenaState(string arenaId); bool SavePlayerData(ulong platformId, object playerData); object LoadPlayerData(ulong platformId); } public interface IServiceHealthMonitor { ServiceHealthStatus GetHealthStatus(); ServicePerformanceMetrics GetPerformanceMetrics(); int GetErrorCount(); string GetLastError(); } public class ServiceHealthStatus { public string ServiceName { get; set; } public bool IsHealthy { get; set; } public string Status { get; set; } public DateTime LastCheck { get; set; } public List<string> Issues { get; set; } = new List<string>(); } public class ServicePerformanceMetrics { public string ServiceName { get; set; } public double AverageResponseTime { get; set; } public int RequestsPerSecond { get; set; } public long MemoryUsage { get; set; } public int ActiveOperations { get; set; } public DateTime MeasuredAt { get; set; } } public interface ILifecycleService : IService { bool EnterArena(Entity user, Entity character); bool ExitArena(Entity user, Entity character); bool IsPlayerInArena(ulong platformId); } public interface IZoneService : IService { float3 Center { get; set; } float Radius { get; set; } float3 SpawnPoint { get; set; } float ExitRadius { get; set; } bool IsInZone(Entity user, string zoneName); void EnterZone(Entity user, string zoneName); void ExitZone(Entity user, string zoneName); bool IsInArena(float3 position); float GetDistanceToCenter(float3 position); bool IsInTransitionZone(float3 position); void SetArenaZone(float3 center, float radius); void SetSpawn(float3 spawn); bool CreateZone(string name, float3 center, float radius); } public interface IHealingService : IService { void ApplyHeal(Entity character); void HealPlayer(Entity user, float amount); void SetHealth(Entity user, float health); } public interface ITeleportService : IService { bool Teleport(Entity characterEntity, float3 position); void TeleportTo(Entity user, float3 position); bool CanTeleport(Entity user, float3 position); } } namespace VAuto.Core { public static class PrefabGuidConverter { public static bool TryGetGuid(string prefabName, out PrefabGUID guid) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) guid = default(PrefabGUID); if (string.IsNullOrWhiteSpace(prefabName)) { return false; } if (UnifiedCore.Server == null) { return false; } PrefabCollectionSystem existingSystemManaged = UnifiedCore.Server.GetExistingSystemManaged<PrefabCollectionSystem>(); if (existingSystemManaged == null) { return false; } MemberInfo[] members = ((object)existingSystemManaged).GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MemberInfo memberInfo in members) { object obj = ((memberInfo is FieldInfo fieldInfo) ? fieldInfo.GetValue(existingSystemManaged) : ((!(memberInfo is PropertyInfo propertyInfo)) ? null : propertyInfo.GetValue(existingSystemManaged))); object obj2 = obj; if (obj2 != null && TryGetGuidFromDictionary(obj2, prefabName, out guid)) { return true; } } return false; } public static bool TryGetName(PrefabGUID guid, out string prefabName) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) prefabName = string.Empty; if (((PrefabGUID)(ref guid)).GuidHash == 0L) { return false; } if (UnifiedCore.Server == null) { return false; } PrefabCollectionSystem existingSystemManaged = UnifiedCore.Server.GetExistingSystemManaged<PrefabCollectionSystem>(); if (existingSystemManaged == null) { return false; } MemberInfo[] members = ((object)existingSystemManaged).GetType().GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MemberInfo memberInfo in members) { object obj = ((memberInfo is FieldInfo fieldInfo) ? fieldInfo.GetValue(existingSystemManaged) : ((!(memberInfo is PropertyInfo propertyInfo)) ? null : propertyInfo.GetValue(existingSystemManaged))); object obj2 = obj; if (obj2 != null && TryGetNameFromDictionary(obj2, guid, out prefabName)) { return true; } } return false; } private static bool TryGetGuidFromDictionary(object value, string prefabName, out PrefabGUID guid) { //IL_0001: 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_0032: 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_0035: Unknown result type (might be due to invalid IL or missing references) guid = default(PrefabGUID); if (!(value is IDictionary dictionary)) { return false; } if (dictionary.Contains(prefabName) && dictionary[prefabName] is PrefabGUID val) { guid = val; return true; } return false; } private static bool TryGetNameFromDictionary(object value, PrefabGUID guid, out string prefabName) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) prefabName = string.Empty; if (!(value is IDictionary dictionary)) { return false; } foreach (object key in dictionary.Keys) { if (dictionary[key] is PrefabGUID val && ((PrefabGUID)(ref val)).GuidHash == ((PrefabGUID)(ref guid)).GuidHash) { prefabName = key.ToString() ?? string.Empty; return true; } } return false; } } } namespace VAuto.Core.Json { public sealed class PrefabGuidJsonConverter : JsonConverter<PrefabGUID> { public override PrefabGUID Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0073: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) try { if (reader.TokenType == JsonTokenType.Number) { return new PrefabGUID(reader.GetInt32()); } if (reader.TokenType == JsonTokenType.String) { string @string = reader.GetString(); if (string.IsNullOrWhiteSpace(@string)) { return default(PrefabGUID); } if (int.TryParse(@string, out var result)) { return new PrefabGUID(result); } if (PrefabGuidConverter.TryGetGuid(@string, out var guid)) { return guid; } return default(PrefabGUID); } if (reader.TokenType == JsonTokenType.StartObject) { using (JsonDocument jsonDocument = JsonDocument.ParseValue(ref reader)) { JsonElement rootElement = jsonDocument.RootElement; if (TryReadGuidHash(rootElement, "guidHash", out var guidHash) || TryReadGuidHash(rootElement, "GuidHash", out guidHash)) { return new PrefabGUID((int)guidHash); } if (rootElement.TryGetProperty("name", out var value) && value.ValueKind == JsonValueKind.String) { string string2 = value.GetString(); if (!string.IsNullOrWhiteSpace(string2) && PrefabGuidConverter.TryGetGuid(string2, out var guid2)) { return guid2; } } return default(PrefabGUID); } } } catch { } reader.Skip(); return default(PrefabGUID); } public override void Write(Utf8JsonWriter writer, PrefabGUID value, JsonSerializerOptions options) { writer.WriteNumberValue(((PrefabGUID)(ref value)).GuidHash); } private static bool TryReadGuidHash(JsonElement root, string property, out long guidHash) { guidHash = 0L; if (!root.TryGetProperty(property, out var value)) { return false; } if (value.ValueKind == JsonValueKind.Number && value.TryGetInt64(out guidHash)) { return true; } if (value.ValueKind == JsonValueKind.String && long.TryParse(value.GetString(), out guidHash)) { return true; } return false; } } } namespace VAuto.Core.Configuration { public enum PluginKey { Core, Arena, Lifecycle, Announcement, Traps, Zone } public sealed class PluginManifest { public PluginKey Key { get; } public string Guid { get; } public string Name { get; } public string Version { get; } public bool EnableHarmony { get; } public string HarmonyId { get; } public PluginManifest(PluginKey key, string guid, string name, string version, bool enableHarmony, string harmonyId = null) { if (string.IsNullOrWhiteSpace(guid)) { throw new ArgumentException("GUID cannot be null or empty.", "guid"); } if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Name cannot be null or empty.", "name"); } if (string.IsNullOrWhiteSpace(version)) { throw new ArgumentException("Version cannot be null or empty.", "version"); } Key = key; Guid = guid; Name = name; Version = version; EnableHarmony = enableHarmony; HarmonyId = (string.IsNullOrWhiteSpace(harmonyId) ? guid : harmonyId); } public override string ToString() { return $"{Name} ({Guid}) v{Version}"; } } } namespace VAuto.Core.Chat { public static class ChatService { public static bool TryBroadcastSystemMessage(string message, out string error) { error = string.Empty; try { if (!GameActionService.TrySendSystemMessageToAll(TrimForFixedString(message))) { error = "Failed to broadcast system message"; return false; } return true; } catch (Exception ex) { error = ex.Message; return false; } } public static bool TrySendSystemMessage(ulong platformId, string message, out string error) { error = string.Empty; try { if (!GameActionService.TrySendSystemMessageToPlatformId(platformId, TrimForFixedString(message))) { error = $"User not connected: {platformId}"; return false; } return true; } catch (Exception ex) { error = ex.Message; return false; } } private static string TrimForFixedString(string message) { if (string.IsNullOrEmpty(message)) { return string.Empty; } return ((message.Length > 512) ? message.Substring(0, 512) : message).Replace("\n", " ").Replace("\r", " "); } } } namespace VAuto.Core.Services { public static class DebugEventBridge { private sealed class SnapshotEnvelope { public int Version { get; set; } = 1; public Dictionary<string, SandboxProgressionSnapshot> Players { get; set; } = new Dictionary<string, SandboxProgressionSnapshot>(StringComparer.Ordinal); } private static readonly string[] ProgressionKeywords = new string[7] { "Research", "VBlood", "Achievement", "Unlock", "Tech", "Recipe", "Progress" }; private static readonly JsonSerializerOptions JsonOpts = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, WriteIndented = true }; private static readonly ISnapshotCaptureService SnapshotCaptureService = new SnapshotCaptureService(); private static readonly ISnapshotDiffService SnapshotDiffService = new SnapshotDiffService(); private static readonly ISnapshotPersistenceService SnapshotPersistenceService = new SnapshotPersistenceService(); private static readonly IProgressionRestoreService ProgressionRestoreService = new ProgressionRestoreService(); private static bool _enabled = true; private static bool _persistSnapshots = true; private static string _snapshotPath = string.Empty; private static bool _verboseLogs; private const string BaselineCsvFileName = "sandbox_progression_baseline.csv.gz"; private const string DeltaCsvFileName = "sandbox_progression_delta.csv.gz"; private const string ProgressionJournalJsonlFileName = "sandbox_progression_journal.jsonl"; private const string LegacyJsonFileName = "sandbox_progression_snapshots.json"; private const string BlueLockAssemblyName = "BlueLock"; private static readonly HashSet<ulong> _unlockAppliedThisSession = new HashSet<ulong>(); private static readonly object _snapshotFileLock = new object(); private static readonly object _stateLock = new object(); private static bool _snapshotsLoaded; private static readonly MethodInfo? GetComponentDataGeneric = typeof(EntityManager).GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "GetComponentData" && m.IsGenericMethodDefinition && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Entity)); private static readonly MethodInfo? SetComponentDataGeneric = typeof(EntityManager).GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "SetComponentData" && m.IsGenericMethodDefinition && m.GetParameters().Length == 2 && m.GetParameters()[0].ParameterType == typeof(Entity)); private static readonly MethodInfo? HasComponentGeneric = typeof(EntityManager).GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "HasComponent" && m.IsGenericMethodDefinition && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Entity)); private static readonly MethodInfo? AddComponentGeneric = typeof(EntityManager).GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "AddComponent" && m.IsGenericMethodDefinition && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Entity)); private static readonly MethodInfo? RemoveComponentGeneric = typeof(EntityManager).GetMethods(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault((MethodInfo m) => m.Name == "RemoveComponent" && m.IsGenericMethodDefinition && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(Entity)); private static readonly MethodInfo[] GetComponentTypesMethods = (from m in typeof(EntityManager).GetMethods(BindingFlags.Instance | BindingFlags.Public) where m.Name == "GetComponentTypes" && !m.IsGenericMethod select m).ToArray(); public static void ConfigureSandboxProgression(bool enabled, bool persistSnapshots, string snapshotPath, bool verboseLogs) { _enabled = enabled; _persistSnapshots = persistSnapshots; _snapshotPath = snapshotPath ?? string.Empty; _verboseLogs = verboseLogs; _snapshotsLoaded = false; EnsureSnapshotsLoaded(); LogInfo($"Configured sandbox progression: enabled={_enabled}, persist={_persistSnapshots}, path='{_snapshotPath}'."); } public static void OnZoneEnterStart(Entity character, string zoneId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) OnZoneEnterStart(character, zoneId, enableUnlock: true); } public static void OnPlayerEnter(Entity character, string zoneId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) OnPlayerEnter(character, zoneId, enableUnlock: true); } public static void OnPlayerExit(Entity character, string zoneId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) OnPlayerExit(character, zoneId, enableUnlock: true); } public static void OnPlayerIsInZone(Entity character, string zoneId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) OnPlayerIsInZone(character, zoneId, enableUnlock: true); } public static void OnPlayerEnterZone(Entity character) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) OnPlayerEnterZone(character, enableUnlock: true); } public static void OnPlayerIsInZone(Entity character) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) OnPlayerIsInZone(character, enableUnlock: true); } public static void OnPlayerExitZone(Entity character) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) OnPlayerExitZone(character, enableUnlock: true); } public static void FlushSnapshotsToDisk() { PersistSnapshotsToDisk(); } public static (int activeBaselines, int pendingContexts, int activeDeltas, bool isDirty) GetSnapshotCounts() { return SandboxSnapshotStore.GetSnapshotCounts(); } public static (string? zoneId, int rowCount, DateTime? capturedUtc) GetBaselineInfo(ulong platformId) { return SandboxSnapshotStore.GetBaselineInfo(platformId); } public static bool HasActiveBaseline(ulong platformId) { return SandboxSnapshotStore.HasActiveBaseline(platformId); } public static void OnPlayerEnter(Entity character, string zoneId, bool enableUnlock) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) OnZoneEnterStart(character, zoneId, enableUnlock); OnPlayerEnterZone(character, enableUnlock); } public static void OnPlayerExit(Entity character, string zoneId, bool enableUnlock) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) OnPlayerExitZone(character, enableUnlock); } public static void OnPlayerIsInZone(Entity character, string zoneId, bool enableUnlock) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) OnPlayerIsInZone(character, enableUnlock); } public static void OnZoneEnterStart(Entity character, string zoneId, bool enableUnlock) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (_enabled && enableUnlock) { EnsureSnapshotsLoaded(); if (TryResolvePlayerIdentity(character, out ulong platformId, out string characterName, out Entity _)) { string preferredPlayerKey = SandboxSnapshotStore.GetPreferredPlayerKey(characterName, platformId); DateTime utcNow = DateTime.UtcNow; string snapshotId = SnapshotCaptureService.BuildSnapshotId(platformId, characterName, utcNow); SandboxProgressionSnapshot snapshot = SnapshotCaptureService.CaptureProgressionSnapshot(character); BaselineRow[] array = SnapshotCaptureService.BuildBaselineRows(snapshot, preferredPlayerKey, characterName, platformId, zoneId, snapshotId, utcNow); ZoneEntityEntry[] array2 = SnapshotCaptureService.CaptureZoneEntityMap(zoneId); SandboxSnapshotStore.UpsertPendingContext(new SandboxPendingContext { PlayerKey = preferredPlayerKey, CharacterName = characterName, PlatformId = platformId, ZoneId = (zoneId ?? string.Empty), SnapshotId = snapshotId, CapturedUtc = utcNow, ComponentRows = array, PreEnterZoneEntities = array2 }); LogDebug($"Captured sandbox baseline for key='{preferredPlayerKey}', zone='{zoneId}', components={array.Length}, entities={array2.Length}."); } } } public static void OnPlayerEnterZone(Entity character, bool enableUnlock) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_0102: Unknown result type (might be due to invalid IL or missing references) if (!_enabled || !enableUnlock) { return; } EnsureSnapshotsLoaded(); if (!TryResolvePlayerIdentity(character, out ulong platformId, out string characterName, out Entity _)) { return; } lock (_stateLock) { if (_unlockAppliedThisSession.Contains(platformId)) { return; } } if (!SandboxSnapshotStore.TryTakePendingContext(characterName, platformId, out string playerKey, out SandboxPendingContext context) || context == null) { DateTime utcNow = DateTime.UtcNow; string snapshotId = SnapshotCaptureService.BuildSnapshotId(platformId, characterName, utcNow); playerKey = SandboxSnapshotStore.GetPreferredPlayerKey(characterName, platformId); SandboxProgressionSnapshot snapshot = SnapshotCaptureService.CaptureProgressionSnapshot(character); context = new SandboxPendingContext { PlayerKey = playerKey, CharacterName = characterName, PlatformId = platformId, ZoneId = string.Empty, SnapshotId = snapshotId, CapturedUtc = utcNow, ComponentRows = SnapshotCaptureService.BuildBaselineRows(snapshot, playerKey, characterName, platformId, string.Empty, snapshotId, utcNow), PreEnterZoneEntities = Array.Empty<ZoneEntityEntry>() }; } ApplyFullUnlock(character); DateTime utcNow2 = DateTime.UtcNow; SandboxProgressionSnapshot snapshot2 = SnapshotCaptureService.CaptureProgressionSnapshot(character); BaselineRow[] array = SnapshotCaptureService.BuildBaselineRows(snapshot2, playerKey, characterName, platformId, context.ZoneId, context.SnapshotId, utcNow2); List<DeltaRow> list = new List<DeltaRow>(); list.AddRange(SnapshotDiffService.ComputeComponentDelta(context.ComponentRows, array)); list.AddRange(SnapshotDiffService.ExtractOpenedTech(context.ComponentRows, array)); list.AddRange(SnapshotDiffService.ComputeEntityDelta(context.PreEnterZoneEntities, SnapshotCaptureService.CaptureZoneEntityMap(context.ZoneId))); StampDeltaRows(list, playerKey, characterName, platformId, context.ZoneId, context.SnapshotId, utcNow2); SandboxBaselineSnapshot baseline = new SandboxBaselineSnapshot { PlayerKey = playerKey, CharacterName = characterName, PlatformId = platformId, ZoneId = context.ZoneId, SnapshotId = context.SnapshotId, CapturedUtc = context.CapturedUtc, Rows = context.ComponentRows }; SandboxDeltaSnapshot delta = new SandboxDeltaSnapshot { PlayerKey = playerKey, CharacterName = characterName, PlatformId = platformId, ZoneId = context.ZoneId, SnapshotId = context.SnapshotId, CapturedUtc = utcNow2, Rows = list.ToArray() }; SandboxSnapshotStore.PutActiveSnapshots(playerKey, baseline, delta); SandboxSnapshotStore.MarkDirty(); TryAppendProgressionJournal(playerKey, context, array, utcNow2); lock (_stateLock) { _unlockAppliedThisSession.Add(platformId); } LogDebug($"Finalized sandbox baseline+delta for key='{playerKey}', zone='{context.ZoneId}', deltaRows={list.Count}."); } public static void OnPlayerIsInZone(Entity character, bool enableUnlock) { } public static void OnPlayerExitZone(Entity character, bool enableUnlock) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if (!TryResolvePlayerIdentity(character, out ulong platformId, out string characterName, out Entity _)) { return; } if (!enableUnlock) { lock (_stateLock) { _unlockAppliedThisSession.Remove(platformId); return; } } if (!SandboxSnapshotStore.TryGetActiveSnapshots(characterName, platformId, out string playerKey, out SandboxBaselineSnapshot baseline, out SandboxDeltaSnapshot delta) || baseline == null) { lock (_stateLock) { _unlockAppliedThisSession.Remove(platformId); } LogDebug($"No active sandbox baseline found for character='{characterName}', platformId={platformId}."); return; } ProgressionRestoreService.TryApplyDeltaEntityCleanup(delta, baseline.ZoneId); SandboxProgressionSnapshot snapshot = BuildSnapshotFromBaselineRows(baseline.Rows, baseline.PlatformId, baseline.CapturedUtc); if (!ProgressionRestoreService.RestoreProgressionSnapshot(character, snapshot)) { LogWarning($"Restore failed for playerKey='{playerKey}', platformId={platformId}."); } ProgressionRestoreService.ValidateDeltaAfterRestore(delta, baseline.ZoneId); SandboxSnapshotStore.RemoveActiveSnapshots(playerKey); SandboxSnapshotStore.MarkDirty(); lock (_stateLock) { _unlockAppliedThisSession.Remove(platformId); } FlushSnapshotsToDisk(); } private static bool TryGetPlatformId(Entity character, out ulong platformId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) string characterName; Entity userEntity; return TryResolvePlayerIdentity(character, out platformId, out characterName, out userEntity); } private static bool TryGetUserEntity(Entity character, out Entity userEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) ulong platformId; string characterName; return TryResolvePlayerIdentity(character, out platformId, out characterName, out userEntity); } private static bool TryResolvePlayerIdentity(Entity character, out ulong platformId, out string characterName, out Entity userEntity) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0025: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0054: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_009f: 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) platformId = 0uL; characterName = string.Empty; userEntity = Entity.Null; try { EntityManager entityManager = UnifiedCore.EntityManager; if (entityManager == default(EntityManager) || !((EntityManager)(ref entityManager)).Exists(character) || !((EntityManager)(ref entityManager)).HasComponent<PlayerCharacter>(character)) { return false; } PlayerCharacter componentData = ((EntityManager)(ref entityManager)).GetComponentData<PlayerCharacter>(character); if (!((EntityManager)(ref entityManager)).Exists(componentData.UserEntity) || !((EntityManager)(ref entityManager)).HasComponent<User>(componentData.UserEntity)) { return false; } User componentData2 = ((EntityManager)(ref entityManager)).GetComponentData<User>(componentData.UserEntity); platformId = componentData2.PlatformId; if (platformId == 0L) { LogWarning("Sandbox progression skipped: platformId == 0."); return false; } userEntity = componentData.UserEntity; characterName = NormalizeCharacterName(((object)(FixedString64Bytes)(ref componentData2.CharacterName)).ToString(), platformId); return true; } catch (Exception ex) { LogWarning("TryResolvePlayerIdentity failed: " + ex.Message); return false; } } private static string NormalizeCharacterName(string? rawName, ulong platformId) { string text = (rawName ?? string.Empty).Trim(); if (text.Length == 0) { return platformId.ToString(CultureInfo.InvariantCulture); } return text; } private static void ApplyFullUnlock(Entity character) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0037: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_00a9: Unknown result type (might be due to invalid IL or missing references) try { if (!TryGetUserEntity(character, out var userEntity)) { return; } DebugEventsSystem existingSystemManaged = UnifiedCore.Server.GetExistingSystemManaged<DebugEventsSystem>(); if (existingSystemManaged == null) { LogWarning("ApplyFullUnlock skipped: DebugEventsSystem unavailable."); return; } FromCharacter val = default(FromCharacter); val.User = userEntity; val.Character = character; FromCharacter fromCharacter = val; Type type = ((object)existingSystemManaged).GetType(); bool flag = TryInvokeUnlock(type, existingSystemManaged, new string[2] { "UnlockAllResearch", "TriggerUnlockAllResearch" }, fromCharacter, userEntity); bool flag2 = TryInvokeUnlock(type, existingSystemManaged, new string[2] { "UnlockAllVBloods", "TriggerUnlockAllVBlood" }, fromCharacter, userEntity); bool flag3 = TryInvokeUnlock(type, existingSystemManaged, new string[2] { "CompleteAllAchievements", "TriggerCompleteAllAchievements" }, fromCharacter, userEntity); if (!flag || !flag2 || !flag3) { LogWarning($"ApplyFullUnlock partial failure: research={flag}, vblood={flag2}, achievements={flag3}."); } else { LogDebug("ApplyFullUnlock succeeded."); } } catch (Exception ex) { LogWarning("ApplyFullUnlock failed: " + ex.Message); } } private static bool TryInvokeUnlock(Type systemType, object instance, string[] methodNames, FromCharacter fromCharacter, Entity userEntity) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) foreach (string methodName in methodNames) { foreach (MethodInfo item in from m in systemType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where m.Name == methodName select m) { ParameterInfo[] parameters = item.GetParameters(); if (parameters.Length != 1) { continue; } try { if (parameters[0].ParameterType == typeof(FromCharacter)) { item.Invoke(instance, new object[1] { fromCharacter }); return true; } if (parameters[0].ParameterType == typeof(Entity)) { item.Invoke(instance, new object[1] { userEntity }); return true; } } catch { } } } return false; } internal static SandboxProgressionSnapshot CaptureProgressionSnapshotCore(Entity character) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0054: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00aa: Unknown result type (might be due to invalid IL or missing references) SandboxProgressionSnapshot sandboxProgressionSnapshot = new SandboxProgressionSnapshot { CapturedUtc = DateTime.UtcNow }; if (!TryGetPlatformId(character, out var platformId)) { return sandboxProgressionSnapshot; } sandboxProgressionSnapshot.PlatformId = platformId; if (!TryGetUserEntity(character, out var userEntity)) { return sandboxProgressionSnapshot; } EntityManager entityManager = UnifiedCore.EntityManager; if (entityManager == default(EntityManager) || !((EntityManager)(ref entityManager)).Exists(userEntity)) { return sandboxProgressionSnapshot; } if (!TryGetComponentTypeEnumerable(entityManager, userEntity, out IEnumerable componentTypes, out IDisposable disposable)) { return sandboxProgressionSnapshot; } try { foreach (object item in componentTypes) { if (!TryResolveManagedType(item, out Type managedType) || managedType == null || !IsProgressionComponentType(managedType) || !TryHasComponent(entityManager, userEntity, managedType) || !TryGetComponentData(entityManager, userEntity, managedType, out object value, out string _)) { continue; } string text = managedType.AssemblyQualifiedName ?? managedType.FullName ?? managedType.Name; if (!string.IsNullOrWhiteSpace(text)) { string jsonPayload; try { jsonPayload = JsonSerializer.Serialize(value, managedType, JsonOpts); } catch { continue; } sandboxProgressionSnapshot.Components[text] = new SnapshotComponentState { Existed = true, AssemblyQualifiedType = text, JsonPayload = jsonPayload }; } } return sandboxProgressionSnapshot; } finally { disposable?.Dispose(); } } internal static bool RestoreProgressionSnapshotCore(Entity character, SandboxProgressionSnapshot snapshot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0151: 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_0177: 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_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_01b3: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) if (!TryGetUserEntity(character, out var userEntity)) { return false; } EntityManager entityManager = UnifiedCore.EntityManager; if (entityManager == default(EntityManager) || !((EntityManager)(ref entityManager)).Exists(userEntity)) { return false; } bool flag = true; HashSet<string> hashSet = new HashSet<string>(snapshot.Components.Keys, StringComparer.Ordinal); string error; if (TryGetComponentTypeEnumerable(entityManager, userEntity, out IEnumerable componentTypes, out IDisposable disposable)) { try { foreach (object item2 in componentTypes) { if (TryResolveManagedType(item2, out Type managedType) && !(managedType == null) && IsProgressionComponentType(managedType)) { string item = managedType.AssemblyQualifiedName ?? managedType.FullName ?? managedType.Name; if (!hashSet.Contains(item) && TryHasComponent(entityManager, userEntity, managedType) && !TryRemoveComponent(entityManager, userEntity, managedType, out error)) { flag = false; } } } } finally { disposable?.Dispose(); } } foreach (KeyValuePair<string, SnapshotComponentState> component in snapshot.Components) { SnapshotComponentState value = component.Value; if (value == null) { continue; } Type type = ResolveTypeByName(value.AssemblyQualifiedType); if (type == null || !IsProgressionComponentType(type)) { continue; } try { if (!value.Existed) { if (TryHasComponent(entityManager, userEntity, type)) { flag &= TryRemoveComponent(entityManager, userEntity, type, out error); } continue; } if (!TryHasComponent(entityManager, userEntity, type) && !TryAddComponent(entityManager, userEntity, type, out error)) { flag = false; continue; } if (string.IsNullOrWhiteSpace(value.JsonPayload)) { flag = false; continue; } object obj = JsonSerializer.Deserialize(value.JsonPayload, type, JsonOpts); if (obj == null || !TrySetComponentData(entityManager, userEntity, type, obj, out error)) { flag = false; } } catch { flag = false; } } return flag; } internal static string BuildSnapshotIdCore(ulong platformId, string characterName, DateTime capturedUtc) { string text = (characterName ?? string.Empty).Trim(); if (text.Length == 0) { text = platformId.ToString(CultureInfo.InvariantCulture); } text = text.Replace("|", "_", StringComparison.Ordinal); return $"{capturedUtc:yyyyMMddHHmmssfff}_{text}_{platformId.ToString(CultureInfo.InvariantCulture)}"; } internal static BaselineRow[] BuildBaselineRowsCore(SandboxProgressionSnapshot snapshot, string playerKey, string characterName, ulong platformId, string zoneId, string snapshotId, DateTime capturedUtc) { List<BaselineRow> list = new List<BaselineRow>(snapshot.Components.Count); foreach (KeyValuePair<string, SnapshotComponentState> component in snapshot.Components) { SnapshotComponentState value = component.Value; if (value != null) { string text = ((!string.IsNullOrWhiteSpace(value.AssemblyQualifiedType)) ? value.AssemblyQualifiedType : component.Key); if (!string.IsNullOrWhiteSpace(text)) { string payload = value.JsonPayload ?? string.Empty; list.Add(new BaselineRow { Version = 1, SnapshotId = snapshotId, PlayerKey = playerKey, CharacterName = characterName, PlatformId = platformId, ZoneId = (zoneId ?? string.Empty), CapturedUtc = capturedUtc, RowType = "component", ComponentType = ResolveComponentTypeName(text), AssemblyQualifiedType = text, Existed = value.Existed, PayloadBase64 = EncodePayload(payload), PayloadHash = ComputePayloadHash(payload) }); } } } return list.ToArray(); } private static SandboxProgressionSnapshot BuildSnapshotFromBaselineRows(IEnumerable<BaselineRow> rows, ulong platformId, DateTime capturedUtc) { SandboxProgressionSnapshot sandboxProgressionSnapshot = new SandboxProgressionSnapshot { PlatformId = platformId, CapturedUtc = capturedUtc }; foreach (BaselineRow item in rows ?? Array.Empty<BaselineRow>()) { if (item != null) { string text = ((!string.IsNullOrWhiteSpace(item.AssemblyQualifiedType)) ? item.AssemblyQualifiedType : item.ComponentType); if (!string.IsNullOrWhiteSpace(text)) { sandboxProgressionSnapshot.Components[text] = new SnapshotComponentState { Existed = item.Existed, AssemblyQualifiedType = text, JsonPayload = DecodePayload(item.PayloadBase64) }; } } } return sandboxProgressionSnapshot; } private static string ResolveComponentTypeName(string assemblyQualifiedType) { try { Type type = ResolveTypeByName(assemblyQualifiedType); if (type != null) { return type.Name; } } catch { } string text = assemblyQualifiedType.Split(',')[0]; int num = text.LastIndexOf('.'); if (num < 0 || num + 1 >= text.Length) { return text; } return text.Substring(num + 1); } private static string EncodePayload(string payload) { return Convert.ToBase64String(Encoding.UTF8.GetBytes(payload ?? string.Empty)); } private static string DecodePayload(string payloadBase64) { if (string.IsNullOrWhiteSpace(payloadBase64)) { return string.Empty; } try { return Encoding.UTF8.GetString(Convert.FromBase64String(payloadBase64)); } catch { return string.Empty; } } private static string ComputePayloadHash(string payload) { using SHA256 sHA = SHA256.Create(); return Convert.ToHexString(sHA.ComputeHash(Encoding.UTF8.GetBytes(payload ?? string.Empty))); } private static void StampDeltaRows(IEnumerable<DeltaRow> rows, string playerKey, string characterName, ulong platformId, string zoneId, string snapshotId, DateTime capturedUtc) { foreach (DeltaRow item in rows ?? Array.Empty<DeltaRow>()) { if (item != null) { item.Version = 1; item.SnapshotId = snapshotId; item.PlayerKey = playerKey; item.CharacterName = characterName; item.PlatformId = platformId; item.ZoneId = zoneId ?? string.Empty; item.CapturedUtc = capturedUtc; } } } internal static ZoneEntityEntry[] CaptureZoneEntityMapCore(string zoneId) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_002e: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrWhiteSpace(zoneId)) { return Array.Empty<ZoneEntityEntry>(); } Func<float, float, bool> func = ResolveZoneContainsPredicate(zoneId); if (func == null) { return Array.Empty<ZoneEntityEntry>(); } try { EntityManager entityManager = UnifiedCore.EntityManager; if (entityManager == default(EntityManager)) { return Array.Empty<ZoneEntityEntry>(); } EntityQuery val = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly<PrefabGUID>() }); NativeArray<Entity> val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); try { List<ZoneEntityEntry> list = new List<ZoneEntityEntry>(Math.Min(val2.Length, 2048)); for (int i = 0; i < val2.Length; i++) { Entity val3 = val2[i]; if (TryGetBestPosition(entityManager, val3, out var position) && func(position.x, position.z)) { PrefabGUID componentData = ((EntityManager)(ref entityManager)).GetComponentData<PrefabGUID>(val3); list.Add(new ZoneEntityEntry { EntityIndex = val3.Index, EntityVersion = val3.Version, PrefabGuidHash = ((PrefabGUID)(ref componentData)).GuidHash, PrefabName = ResolvePrefabName(componentData), PosX = position.x, PosY = position.y, PosZ = position.z }); } } return list.ToArray(); } finally { if (val2.IsCreated) { val2.Dispose(); } } } catch (Exception ex) { LogWarning("CaptureZoneEntityMap failed for zone '" + zoneId + "': " + ex.Message); return Array.Empty<ZoneEntityEntry>(); } } private static bool TryGetBestPosition(EntityManager em, Entity entity, out float3 position) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_004b: 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_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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) position = default(float3); try { if (((EntityManager)(ref em)).HasComponent<LocalTransform>(entity)) { position = ((EntityManager)(ref em)).GetComponentData<LocalTransform>(entity).Position; return true; } if (((EntityManager)(ref em)).HasComponent<Translation>(entity)) { position = ((EntityManager)(ref em)).GetComponentData<Translation>(entity).Value; return true; } if (((EntityManager)(ref em)).HasComponent<LastTranslation>(entity)) { position = ((EntityManager)(ref em)).GetComponentData<LastTranslation>(entity).Value; return true; } if (((EntityManager)(ref em)).HasComponent<SpawnTransform>(entity)) { position = ((EntityManager)(ref em)).GetComponentData<SpawnTransform>(entity).Position; return true; } } catch { } return false; } private static Func<float, float, bool>? ResolveZoneContainsPredicate(string zoneId) { if (string.IsNullOrWhiteSpace(zoneId)) { return null; } try { Type type = Type.GetType("VAuto.Zone.Services.ZoneConfigService, BlueLock", throwOnError: false) ?? Type.GetType("VAuto.Zone.Services.ZoneConfigService", throwOnError: false); if (type == null) { return null; } MethodInfo method = type.GetMethod("GetZoneById", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null); if (method == null) { return null; } object zone = method.Invoke(null, new object[1] { zoneId }); if (zone == null) { return null; } MethodInfo isInside = zone.GetType().GetMethod("IsInside", BindingFlags.Instance | BindingFlags.Public, null, new Type[2] { typeof(float), typeof(float) }, null); if (isInside == null) { return null; } return delegate(float x, float z) { try { object obj2 = isInside.Invoke(zone, new object[2] { x, z }); bool flag = default(bool); int num; if (obj2 is bool) { flag = (bool)obj2; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } }; } catch { return null; } } private static string ResolvePrefabName(PrefabGUID prefabGuid) { if (((PrefabGUID)(ref prefabGuid)).GuidHash == 0) { return string.Empty; } return "Prefab_" + ((PrefabGUID)(ref prefabGuid)).GuidHash.ToString(CultureInfo.InvariantCulture); } internal static void TryApplyDeltaEntityCleanupCore(SandboxDeltaSnapshot? deltaSnapshot, string zoneId) { //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_026d: 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) //IL_0025: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_020f: 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_0216: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if (deltaSnapshot?.Rows == null || deltaSnapshot.Rows.Length == 0) { return; } Func<float, float, bool> func = ResolveZoneContainsPredicate(zoneId); EntityManager entityManager = UnifiedCore.EntityManager; if (entityManager == default(EntityManager)) { return; } int num = 0; int num2 = 0; DeltaRow[] rows = deltaSnapshot.Rows; PrefabGUID componentData; foreach (DeltaRow deltaRow in rows) { if (deltaRow == null || !string.Equals(deltaRow.RowType, "entity_created", StringComparison.OrdinalIgnoreCase)) { continue; } Entity val = default(Entity); val.Index = deltaRow.EntityIndex; val.Version = deltaRow.EntityVersion; Entity val2 = val; if (!((EntityManager)(ref entityManager)).Exists(val2) || func == null || !TryGetBestPosition(entityManager, val2, out var position) || !func(position.x, position.z)) { continue; } if (deltaRow.PrefabGuid != 0L && ((EntityManager)(ref entityManager)).HasComponent<PrefabGUID>(val2)) { componentData = ((EntityManager)(ref entityManager)).GetComponentData<PrefabGUID>(val2); if (((PrefabGUID)(ref componentData)).GuidHash != (int)deltaRow.PrefabGuid) { continue; } } try { ((EntityManager)(ref entityManager)).DestroyEntity(val2); num++; } catch (Exception ex) { LogWarning($"Delta cleanup failed for entity {val2.Index}:{val2.Version}: {ex.Message}"); } } rows = deltaSnapshot.Rows; foreach (DeltaRow deltaRow2 in rows) { if (deltaRow2 == null || !string.Equals(deltaRow2.RowType, "entity_created", StringComparison.OrdinalIgnoreCase)) { continue; } Entity val = default(Entity); val.Index = deltaRow2.EntityIndex; val.Version = deltaRow2.EntityVersion; Entity val3 = val; if (!((EntityManager)(ref entityManager)).Exists(val3)) { continue; } if (deltaRow2.PrefabGuid != 0L && ((EntityManager)(ref entityManager)).HasComponent<PrefabGUID>(val3)) { componentData = ((EntityManager)(ref entityManager)).GetComponentData<PrefabGUID>(val3); if (((PrefabGUID)(ref componentData)).GuidHash != (int)deltaRow2.PrefabGuid) { continue; } } try { ((EntityManager)(ref entityManager)).DestroyEntity(val3); num2++; } catch (Exception ex2) { LogWarning($"Delta force-cleanup failed for entity {val3.Index}:{val3.Version}: {ex2.Message}"); } } int num3 = num + num2; if (num3 > 0) { LogDebug($"Delta cleanup removed {num3} created entities for zone '{zoneId}' (strict={num}, force={num2})."); } } internal static void ValidateDeltaAfterRestoreCore(SandboxDeltaSnapshot? deltaSnapshot, string zoneId) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) if (deltaSnapshot?.Rows == null || deltaSnapshot.Rows.Length == 0) { return; } EntityManager entityManager = UnifiedCore.EntityManager; if (entityManager == default(EntityManager)) { return; } int num = 0; DeltaRow[] rows = deltaSnapshot.Rows; foreach (DeltaRow deltaRow in rows) { if (deltaRow != null && string.Equals(deltaRow.RowType, "entity_created", StringComparison.OrdinalIgnoreCase)) { Entity val = default(Entity); val.Index = deltaRow.EntityIndex; val.Version = deltaRow.EntityVersion; Entity val2 = val; if (((EntityManager)(ref entityManager)).Exists(val2)) { num++; } } } if (num > 0) { LogWarning($"Delta validation found {num} unresolved created entities for zone '{zoneId}'."); } } private static bool TryGetComponentTypeEnumerable(EntityManager em, Entity userEntity, out IEnumerable componentTypes, out IDisposable? disposable) { //IL_0051: 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) componentTypes = Array.Empty<object>(); disposable = null; MethodInfo[] getComponentTypesMethods = GetComponentTypesMethods; foreach (MethodInfo methodInfo in getComponentTypesMethods) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length != 2 || parameters[0].ParameterType != typeof(Entity) || !TryGetAllocatorArgument(parameters[1].ParameterType, out object allocatorArgument)) { continue; } try { object obj = methodInfo.Invoke(em, new object[2] { userEntity, allocatorArgument }); if (TryConvertToEnumerable(obj, out componentTypes)) { disposable = obj as IDisposable; return true; } } catch { } } return false; } private static bool TryGetAllocatorArgument(Type allocatorParamType, out object allocatorArgument) { allocatorArgument = null; if (allocatorParamType == typeof(Allocator)) { allocatorArgument = (object)(Allocator)2; return true; } if (allocatorParamType.IsEnum) { allocatorArgument = Enum.ToObject(allocatorParamType, 2); return true; } return false; } private static bool TryConvertToEnumerable(object? value, out IEnumerable enumerable) { if (value is IEnumerable enumerable2) { enumerable = enumerable2; return true; } enumerable = Array.Empty<object>(); return false; } private static bool TryResolveManagedType(object componentTypeObj, out Type? managedType) { managedType = null; if (componentTypeObj == null) { return false; } Type type = componentTypeObj.GetType(); MethodInfo method = type.GetMethod("GetManagedType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method != null) { try { if (TryCoerceToManagedType(method.Invoke(componentTypeObj, null), out managedType)) { return true; } } catch { } } string[] array = new string[2] { "ManagedType", "Type" }; foreach (string name in array) { PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property == null) { continue; } try { if (TryCoerceToManagedType(property.GetValue(componentTypeObj), out managedType)) { return true; } } catch { } } return false; } private static bool TryCoerceToManagedType(object? rawType, out Type? managedType) { managedType = null; if (rawType == null) { return false; } if (rawType is Type type) { managedType = type; return true; } Type type2 = rawType.GetType(); string typeName = type2.GetProperty("AssemblyQualifiedName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(rawType) as string; managedType = ResolveTypeByName(typeName); if (managedType != null) { return true; } string typeName2 = type2.GetProperty("FullName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(rawType) as string; managedType = ResolveTypeByName(typeName2); return managedType != null; } private static bool IsProgressionComponentType(Type managedType) { string name = managedType.FullName ?? managedType.Name; return ProgressionKeywords.Any((string keyword) => name.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0); } private static Type? ResolveTypeByName(string? typeName) { if (string.IsNullOrWhiteSpace(typeName)) { return null; } Type type = Type.GetType(typeName, throwOnError: false); if (type != null) { return type; } string name = typeName.Split(',')[0].Trim(); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { type = assemblies[i].GetType(name, throwOnError: false); if (type != null) { return type; } } return null; } private static bool TryGetComponentData(EntityManager em, Entity entity, Type componentType, out object? value, out string error) { //IL_0038: 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) value = null; error = string.Empty; if (GetComponentDataGeneric == null) { error = "GetComponentData<T> method unavailable"; return false; } try { value = GetComponentDataGeneric.MakeGenericMethod(componentType).Invoke(em, new object[1] { entity }); return true; } catch (Exception ex) { error = ex.Message; return false; } } private static bool TrySetComponentData(EntityManager em, Entity entity, Type componentType, object value, out string error) { //IL_0034: 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) error = string.Empty; if (SetComponentDataGeneric == null) { error = "SetComponentData<T> method unavailable"; return false; } try { SetComponentDataGeneric.MakeGenericMethod(componentType).Invoke(em, new object[2] { entity, value }); return true; } catch (Exception ex) { error = ex.Message; return false; } } private static bool TryHasComponent(EntityManager em, Entity entity, Type componentType) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (HasComponentGeneric == null) { return false; } try { object obj = HasComponentGeneric.MakeGenericMethod(componentType).Invoke(em, new object[1] { entity }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } } private static bool TryAddComponent(EntityManager em, Entity entity, Type componentType, out string error) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) error = string.Empty; if (AddComponentGeneric == null) { error = "AddComponent<T> method unavailable"; return false; } try { AddComponentGeneric.MakeGenericMethod(componentType).Invoke(em, new object[1] { entity }); return true; } catch (Exception ex) { error = ex.Message; return false; } } private static bool TryRemoveComponent(EntityManager em, Entity entity, Type componentType, out string error) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) error = string.Empty; if (RemoveComponentGeneric == null) { error = "RemoveComponent<T> method unavailable"; return false; } try { RemoveComponentGeneric.MakeGenericMethod(componentType).Invoke(em, new object[1] { entity }); return true; } catch (Exception ex) { error = ex.Message; return false; } } private static void EnsureSnapshotsLoaded() { if (_snapshotsLoaded) { return; } lock (_snapshotFileLock) { if (_snapshotsLoaded) { return; } SandboxSnapshotStore.ClearAll(); if (!_persistSnapshots) { _snapshotsLoaded = true; return; } string text = ResolveSnapshotDirectory(); if (string.IsNullOrWhiteSpace(text)) { _snapshotsLoaded = true; return; } string path = Path.Combine(text, "sandbox_progression_baseline.csv.gz"); string path2 = Path.Combine(text, "sandbox_progression_delta.csv.gz"); string path3 = ResolveLegacyJsonPath(text); try { if (File.Exists(path) || File.Exists(path2)) { List<BaselineRow> rows = SnapshotPersistenceService.ReadBaseline(path); List<DeltaRow> rows2 = SnapshotPersistenceService.ReadDelta(path2); SandboxBaselineSnapshot[] array = BuildBaselineSnapshotsFromRows(rows); SandboxDeltaSnapshot[] array2 = BuildDeltaSnapshotsFromRows(rows2); SandboxSnapshotStore.ImportActiveSnapshots(array, array2, markDirty: false); LogDebug($"Loaded sandbox snapshots from CSV: baselines={array.Length}, deltas={array2.Length}."); _snapshotsLoaded = true; return; } if (File.Exists(path3)) { SandboxBaselineSnapshot[] array3 = ConvertLegacyEnvelopeToBaselines(JsonSerializer.Deserialize<SnapshotEnvelope>(File.ReadAllText(path3), JsonOpts)); if (array3.Length != 0) { SandboxSnapshotStore.ImportActiveSnapshots(array3, Array.Empty<SandboxDeltaSnapshot>(), markDirty: true); LogInfo($"Migrated {array3.Length} legacy sandbox snapshots to in-memory baseline format."); } } } catch (Exception ex) { LogWarning("Snapshot file load failed: " + ex.Message); } _snapshotsLoaded = true; } } private static void PersistSnapshotsToDisk() { if (!_persistSnapshots || !SandboxSnapshotStore.IsDirty) { return; } string text = ResolveSnapshotDirectory(); if (string.IsNullOrWhiteSpace(text)) { return; } string path = Path.Combine(text, "sandbox_progression_baseline.csv.gz"); string path2 = Path.Combine(text, "sandbox_progression_delta.csv.gz"); lock (_snapshotFileLock) { if (!SandboxSnapshotStore.IsDirty) { return; } try { Directory.CreateDirectory(text); BaselineRow[] array = SandboxSnapshotStore.GetActiveBaselines().SelectMany((SandboxBaselineSnapshot snapshot) => snapshot.Rows ?? Array.Empty<BaselineRow>()).ToArray(); DeltaRow[] array2 = SandboxSnapshotStore.GetActiveDeltas().SelectMany((SandboxDeltaSnapshot snapshot) => snapshot.Rows ?? Array.Empty<DeltaRow>()).ToArray(); if (array.Length == 0) { DeleteIfExists(path); } else { SnapshotPersistenceService.WriteBaseline(path, array); } if (array2.Length == 0) { DeleteIfExists(path2); } else { SnapshotPersistenceService.WriteDelta(path2, array2); } SandboxSnapshotStore.MarkClean(); } catch (Exception ex) { LogWarning("Snapshot persist failed: " + ex.Message); } } } private static void TryAppendProgressionJournal(string playerKey, SandboxPendingContext pending, BaselineRow[] postRows, DateTime capturedUtc) { if (!_persistSnapshots) { return; } string text = ResolveSnapshotDirectory(); if (string.IsNullOrWhiteSpace(text)) { return; } try { Directory.CreateDirectory(text); string path = Path.Combine(text, "sandbox_progression_journal.jsonl"); BaselineRow[] source = pending?.ComponentRows ?? Array.Empty<BaselineRow>(); if (postRows == null) { postRows = Array.Empty<BaselineRow>(); } Dictionary<string, BaselineRow> dictionary = source.Where((BaselineRow r) => r != null && string.Equals(r.RowType, "component", StringComparison.OrdinalIgnoreCase)).GroupBy<BaselineRow, string>((BaselineRow r) => r.AssemblyQualifiedType ?? string.Empty, StringComparer.Ordinal).ToDictionary<IGrouping<string, BaselineRow>, string, BaselineRow>((IGrouping<string, BaselineRow> g) => g.Key, (IGrouping<string, BaselineRow> g) => g.Last(), StringComparer.Ordinal); Dictionary<string, BaselineRow> dictionary2 = postRows.Where((BaselineRow r) => r != null && string.Equals(r.RowType, "component", StringComparison.OrdinalIgnoreCase)).GroupBy<BaselineRow, string>((BaselineRow r) => r.AssemblyQualifiedType ?? string.Empty, StringComparer.Ordinal).ToDictionary<IGrouping<string, BaselineRow>, string, BaselineRow>((IGrouping<string, BaselineRow> g) => g.Key, (IGrouping<string, BaselineRow> g) => g.Last(), StringComparer.Ordinal); HashSet<string> hashSet = new HashSet<string>(dictionary.Keys, StringComparer.Ordinal); hashSet.UnionWith(dictionary2.Keys); using FileStream stream = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read); using StreamWriter streamWriter = new StreamWriter(stream, Encoding.UTF8); foreach (string item in hashSet) { dictionary.TryGetValue(item, out var value); dictionary2.TryGetValue(item, out var value2); string text2 = DecodePayload(value?.PayloadBase64 ?? string.Empty); string text3 = DecodePayload(value2?.PayloadBase64 ?? string.Empty); if (!string.Equals(text2, text3, StringComparison.Ordinal)) { string operation = ((value == null) ? "add" : ((value2 == null) ? "remove" : "modify")); ProgressionJournalEvent value3 = new ProgressionJournalEvent { Version = 1, SnapshotId = (pending?.SnapshotId ?? string.Empty), PlayerKey = (playerKey ?? string.Empty), CharacterName = (pending?.CharacterName ?? string.Empty), PlatformId = (pending?.PlatformId ?? 0), ZoneId = (pending?.ZoneId ?? string.Empty), CapturedUtc = capturedUtc, Operation = operation, ComponentType = ResolveComponentTypeName(item), AssemblyQualifiedType = item, BeforeJson = text2, AfterJson = text3 }; streamWriter.WriteLine(JsonSerializer.Serialize(value3, JsonOpts)); } } } catch (Exception ex) { LogWarning("Progression journal append failed: " + ex.Message); } } private static string ResolveSnapshotDirectory() { if (string.IsNullOrWhiteSpace(_snapshotPath)) { return string.Empty; } string text = _snapshotPath.Trim(); if (Path.HasExtension(text)) { return Path.GetDirectoryName(text) ?? string.Empty; } return text; } private static string ResolveLegacyJsonPath(string snapshotDirectory) { if (!string.IsNullOrWhiteSpace(_snapshotPath) && string.Equals(Path.GetExtension(_snapshotPath), ".json", StringComparison.OrdinalIgnoreCase)) { return _snapshotPath; } return Path.Combine(snapshotDirectory, "sandbox_progression_snapshots.json"); } private static SandboxBaselineSnapshot[] BuildBaselineSnapshotsFromRows(IEnumerable<BaselineRow> rows) { return (rows ?? Array.Empty<BaselineRow>()).Where((BaselineRow row) => row != null).GroupBy<BaselineRow, string>((BaselineRow row) => ResolvePlayerKey(row.PlayerKey, row.CharacterName, row.PlatformId), StringComparer.Ordinal).Select(delegate(IGrouping<string, BaselineRow> group) { BaselineRow[] array = group.OrderBy((BaselineRow row) => row.CapturedUtc).ToArray(); BaselineRow baselineRow = array[0]; return new SandboxBaselineSnapshot { PlayerKey = group.Key, CharacterName = baselineRow.CharacterName, PlatformId = baselineRow.PlatformId, ZoneId = baselineRow.ZoneId, SnapshotId = baselineRow.SnapshotId, CapturedUtc = baselineRow.CapturedUtc, Rows = array }; }) .ToArray(); } private static SandboxDeltaSnapshot[] BuildDeltaSnapshotsFromRows(IEnumerable<DeltaRow> rows) { return (rows ?? Array.Empty<DeltaRow>()).Where((DeltaRow row) => row != null).GroupBy<DeltaRow, string>((DeltaRow row) => ResolvePlayerKey(row.PlayerKey, row.CharacterName, row.PlatformId), StringComparer.Ordinal).Select(delegate(IGrouping<string, DeltaRow> group) { DeltaRow[] array = group.OrderBy((DeltaRow row) => row.CapturedUtc).ToArray(); DeltaRow deltaRow = array[0]; return new SandboxDeltaSnapshot { PlayerKey = group.Key, CharacterName = deltaRow.CharacterName, PlatformId = deltaRow.PlatformId, ZoneId = deltaRow.ZoneId, SnapshotId = deltaRow.SnapshotId, CapturedUtc = deltaRow.CapturedUtc, Rows = array }; }) .ToArray(); } private static string ResolvePlayerKey(string? key, string characterName, ulong platformId) { if (!string.IsNullOrWhiteSpace(key)) { return key; } return SandboxSnapshotStore.GetPreferredPlayerKey(characterName, platformId); } private static SandboxBaselineSnapshot[] ConvertLegacyEnvelopeToBaselines(SnapshotEnvelope? envelope) { if (envelope?.Players == null || envelope.Players.Count == 0) { return Array.Empty<SandboxBaselineSnapshot>(); } List<SandboxBaselineSnapshot> list = new List<SandboxBaselineSnapshot>(); foreach (KeyValuePair<string, SandboxProgressionSnapshot> player in envelope.Players) { if (player.Value != null) { ulong result = player.Value.PlatformId; if (result != 0L || ulong.TryParse(player.Key, NumberStyles.Integer, CultureInfo.InvariantCulture, out result)) { DateTime capturedUtc = ((player.Value.CapturedUtc == default(DateTime)) ? DateTime.UtcNow : player.Value.CapturedUtc); string characterName = NormalizeCharacterName(string.Empty, result); string preferredPlayerKey = SandboxSnapshotStore.GetPreferredPlayerKey(characterName, result); string snapshotId = BuildSnapshotIdCore(result, characterName, capturedUtc); BaselineRow[] rows = BuildBaselineRowsCore(player.Value, preferredPlayerKey, characterName, result, string.Empty, snapshotId, capturedUtc); list.Add(new SandboxBaselineSnapshot { PlayerKey = preferredPlayerKey, CharacterName = characterName, PlatformId = result, ZoneId = string.Empty, SnapshotId = snapshotId, CapturedUtc = capturedUtc, Rows = rows }); } } } return list.ToArray(); } private static void DeleteIfExists(string path) { try { if (File.Exists(path)) { File.Delete(path); } } catch (Exception ex) { LogWarning("Failed deleting snapshot file '" + path + "': " + ex.Message); } } private static void LogInfo(string message) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown try { ManualLogSource coreLog = Plugin.CoreLog; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(19, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DebugEventBridge] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(message); } coreLog.LogInfo(val); } catch { } } private static void LogWarning(string message) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown try { ManualLogSource coreLog = Plugin.CoreLog; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(19, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[DebugEventBridge] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(message); } coreLog.LogWarning(val); } catch { } } private static void LogDebug(string message) { if (_verboseLogs) { LogInfo(message); } } } internal sealed class SandboxProgressionSnapshot { public ulong PlatformId { get; set; } public DateTime CapturedUtc { get; set; } public Dictionary<string, SnapshotComponentState> Components { get; set; } = new Dictionary<string, SnapshotComponentState>(StringComparer.Ordinal); } internal sealed class SnapshotComponentState { public bool Existed { get; set; } public string AssemblyQualifiedType { get; set; } = string.Empty; public string JsonPayload { get; set; } = string.Empty; } internal sealed class ProgressionJournalEvent { public int Version { get; set; } = 1; public string SnapshotId { get; set; } = string.Empty; public string PlayerKey { get; set; } = string.Empty; public string CharacterName { get; set; } = string.Empty; public ulong PlatformId { get; set; } public string ZoneId { get; set; } = string.Empty; public DateTime CapturedUtc { get; set; } public string Operation { get; set; } = string.Empty; public string ComponentType { get; set; } = string.Empty; public string AssemblyQualifiedType { get; set; } = string.Empty; public string BeforeJson { get; set; } = string.Empty; public string AfterJson { get; set; } = string.Empty; } internal sealed class SandboxPendingContext { public string PlayerKey { get; set; } = string.Empty; public string CharacterName { get; set; } = string.Empty; public ulong PlatformId { get; set; } public string ZoneId { get; set; } = string.Empty; public string SnapshotId { get; set; } = string.Empty; public DateTime CapturedUtc { get; set; } public BaselineRow[] ComponentRows { get; set; } = Array.Empty<BaselineRow>(); public ZoneEntityEntry[] PreEnterZoneEntities { get; set; } = Array.Empty<ZoneEntityEntry>(); } internal sealed class ZoneEntityEntry { public int EntityIndex { get; set; } public int EntityVersion { get; set; } public long PrefabGuidHash { get; set; } public string PrefabName { get; set; } = string.Empty; public float PosX { get; set; } public float PosY { get; set; } public float PosZ { get; set; } } internal sealed class BaselineRow { public int Version { get; set; } = 1; public string SnapshotId { get; set; } = string.Empty; public string PlayerKey { get; set; } = string.Empty; public string CharacterName { get; set; } = string.Empty; public ulong PlatformId { get; set; } public string ZoneId { get; set; } = string.Empty; public DateTime CapturedUtc { get; set; } public string RowType { get; set; } = "component"; public string ComponentType { get; set; } = string.Empty; public string AssemblyQualifiedType { get; set; } = string.Empty; public bool Existed { get; set; } public string PayloadBase64 { get; set; } = string.Empty; public string PayloadHash { get; set; } = string.Empty; } internal sealed class DeltaRow { public int Version { get; set; } = 1; public string SnapshotId { get; set; } = string.Empty; public string PlayerKey { get; set; } = string.Empty; public string CharacterName { get; set; } = string.Empty; public ulong PlatformId { get; set; } public string ZoneId { get; set; } = string.Empty; public DateTime CapturedUtc { get; set; } public string RowType { get; set; } = string.Empty; public string Operation { get; set; } = string.Empty; public string ComponentType { get; set; } = string.Empty; public string BeforePayloadBase64 { get; set; } = string.Empty; public string AfterPayloadBase64 { get; set; } = string.Empty; public long TechGuid { get; set; } public string TechName { get; set; } = string.Empty; public int EntityIndex { get; set; } public int EntityVersion { get; set; } public long PrefabGuid { get; set; } public string PrefabName { get; set; } = string.Empty; public float PosX { get; set; } public float PosY { get; set; } public float PosZ { get; set; } } internal sealed class SandboxBaselineSnapshot { public string PlayerKey { get; set; } = string.Empty; public string CharacterName { get; set; } = string.Empty; public ulong PlatformId { get; set; } public string ZoneId { get; set; } = string.Empty; public string SnapshotId { get; set; } = string.Empty; public DateTime CapturedUtc { get; set; } public BaselineRow[] Rows { get; set; } = Array.Empty<BaselineRow>(); } internal sealed class SandboxDeltaSnapshot { public string PlayerKey { get; set; } = string.Empty; public string CharacterName { get; set; } = string.Empty; public ulong PlatformId { get; set; } public string ZoneId { get; set; } = string.Empty; public string SnapshotId { get; set; } = string.Empty; public DateTime CapturedUtc { get; set; } public DeltaRow[] Rows { get; set; } = Array.Empty<DeltaRow>(); } internal static class SandboxSnapshotStore { private static readonly object Sync = new object(); private static readonly Dictionary<string, SandboxPendingContext> PendingContexts = new Dictionary<string, SandboxPendingContext>(StringComparer.Ordinal); private static readonly Dictionary<string, SandboxBaselineSnapshot> ActiveBaselines = new Dictionary<string, SandboxBaselineSnapshot>(StringComparer.Ordinal); private static readonly Dictionary<string, SandboxDeltaSnapshot> ActiveDeltas = new Dictionary<string, SandboxDeltaSnapshot>(StringComparer.Ordinal); private static bool _dirty; public static bool IsDirty { get { lock (Sync) { return _dirty; } } } public static (int activeBaselines, int pendingContexts, int activeDeltas, bool isDirty) GetSnapshotCounts() { lock (Sync) { return (ActiveBaselines.Count, PendingContexts.Count, ActiveDeltas.Count, _dirty); } } public static (string? zoneId, int rowCount, DateTime? capturedUtc) GetBaselineInfo(ulong platformId) { lock (Sync) { SandboxBaselineSnapshot sandboxBaselineSnapshot = ActiveBaselines.Values.FirstOrDefault((SandboxBaselineSnapshot b) => b.PlatformId == platformId); if (sandboxBaselineSnapshot != null) { string zoneId = sandboxBaselineSnapshot.ZoneId; BaselineRow[] rows = sandboxBaselineSnapshot.Rows; return (zoneId, (rows != null) ? rows.Length : 0, sandboxBaselineSnapshot.CapturedUtc); } return (null, 0, null); } } public static bool HasActiveBaseline(ulong platformId) { lock (Sync) { return ActiveBaselines.Values.Any((SandboxBaselineSnapshot b) => b.PlatformId == platformId); } } public static void ClearAll() { lock (Sync) { PendingContexts.Clear(); ActiveBaselines.Clear(); ActiveDeltas.Clear(); _dirty = false; } } public static string UpsertPendingContext(SandboxPendingContext context) { if (context == null) { throw new ArgumentNullException("context"); } lock (Sync) { string text2 = (context.PlayerKey = ResolvePlayerKeyNoLock(context.CharacterName, context.PlatformId, createIfMissing: true)); PendingContexts[text2] = context; return text2; } } public static bool TryTakePendingContext(string characterName, ulong platformId, out string playerKey, out SandboxPendingContext? context) { lock (Sync) { context = null; playerKey = string.Empty; if (!TryResolveExistingPlayerKeyNoLock(characterName, platformId, out string key)) { return false; } if (!PendingContexts.TryGetValue(key, out context) || context == null) { return false; } playerKey = key; PendingContexts.Remove(key); return true; } } public static bool TryGetActiveSnapshots(string characterName, ulong platformId, out string playerKey, out SandboxBaselineSnapshot? baseline, out SandboxDeltaSnapshot? delta) { lock (Sync) { baseline = null; delta = null; playerKey = string.Empty; if (!TryResolveExistingPlayerKeyNoLock(characterName, platformId, out string key)) { return false; } ActiveBaselines.TryGetValue(key, out baseline); ActiveDeltas.TryGetValue(key, out delta); playerKey = key; return baseline != null || delta != null; } } public static void PutActiveSnapshots(string playerKey, SandboxBaselineSnapshot baseline, SandboxDeltaSnapshot delta) { if (string.IsNullOrWhiteSpace(playerKey)) { throw new ArgumentException("Player key is required.", "playerKey"); } lock (Sync) { ActiveBaselines[playerKey] = baseline; ActiveDeltas[playerKey] = delta; } } public static void RemoveActiveSnapshots(string playerKey) { if (string.IsNullOrWhiteSpace(playerKey)) { return; } lock (Sync) { ActiveBaselines.Remove(playerKey); ActiveDeltas.Remove(playerKey); } } public static void ImportActiveSnapshots(IEnumerable<SandboxBaselineSnapshot> baselines, IEnumerable<SandboxDeltaSnapshot> deltas, bool markDirty) { lock (Sync) { ActiveBaselines.Clear(); ActiveDeltas.Clear(); PendingContexts.Clear(); foreach (SandboxBaselineSnapshot item in baselines ?? Array.Empty<SandboxBaselineSnapshot>()) { if (item != null && !string.IsNullOrWhiteSpace(item.PlayerKey)) { ActiveBaselines[item.PlayerKey] = item; } } foreach (SandboxDeltaSnapshot item2 in deltas ?? Array.Empty<SandboxDeltaSnapshot>()) { if (item2 != null && !string.IsNullOrWhiteSpace(item2.PlayerKey)) { ActiveDeltas[item2.PlayerKey] = item2; } } _dirty = markDirty; } } public static SandboxBaselineSnapshot[] GetActiveBaselines() { lock (Sync) { return ActiveBaselines.Values.ToArray(); } } public static SandboxDeltaSnapshot[] GetActiveDeltas() { lock (Sync) { return ActiveDeltas.Values.ToArray(); } } public static void MarkDirty() { lock (Sync) { _dirty = true; } } public static void MarkClean() { lock (Sync) { _dirty = false; } } public static string GetPreferredPlayerKey(string characterName, ulong platformId) { lock (Sync) { return ResolvePlayerKeyNoLock(characterName, platformId, createIfMissing: true); } } private static bool TryResolveExistingPlayerKeyNoLock(string characterName, ulong platformId, out string key) { key = ResolvePlayerKeyNoLock(characterName, platformId, createIfMissing: false); if (string.IsNullOrWhiteSpace(key)) { return false; } if (PendingContexts.ContainsKey(key) || ActiveBaselines.ContainsKey(key) || ActiveDeltas.ContainsKey(key)) { return true; } foreach (KeyValuePair<string, SandboxPendingContext> pendingContext in PendingContexts) { if (pendingContext.Value.PlatformId == platformId) { key = pendingContext.Key; return true; } } foreach (KeyValuePair<string, SandboxBaselineSnapshot> activeBaseline in ActiveBaselines) { if (activeBaseline.Value.PlatformId == platformId) { key = activeBaseline.Key; return true; } } foreach (KeyValuePair<string, SandboxDeltaSnapshot> activeDelta in ActiveDeltas) { if (activeDelta.Value.PlatformId == platformId) { key = activeDelta.Key; return true; } } return false; } private static string ResolvePlayerKeyNoLock(string characterName, ulong platformId, bool createIfMissing) { string text = NormalizeName(characterName, platformId); if (string.IsNullOrWhiteSpace(text)) { return platformId.ToString(CultureInfo.InvariantCulture); } if (TryTryUsePrimaryNoLock(text, platformId, out string key)) { return key; } if (!createIfMissing) { return key; } return text + "|" + platformId.ToString(CultureInfo.InvariantCulture); } private static bool TryTryUsePrimaryNoLock(string normalizedName, ulong platformId, out string key) { key = normalizedName; if (TryKeyMatchesPlatformNoLock(normalizedName, platformId)) { return true; } string text = normalizedName + "|" + platformId.ToString(CultureInfo.InvariantCulture); if (TryKeyExistsNoLock(text)) { key = text; return true; } if (!TryKeyExistsNoLock(normalizedName)) { key = normalizedName; return true; } return false; } private static bool TryKeyMatchesPlatformNoLock(string key, ulong platformId) { if (PendingContexts.TryGetValue(key, out SandboxPendingContext value)) { return value.PlatformId == platformId; } if (ActiveBaselines.TryGetValue(key, out SandboxBaselineSnapshot value2)) { return value2.PlatformId == platformId; } if (ActiveDeltas.TryGetValue(key, out SandboxDeltaSnapshot value3)) { return value3.PlatformId == platformId; } return false; } private static bool TryKeyExistsNoLock(string key) { if (!PendingContexts.ContainsKey(key) && !ActiveBaselines.ContainsKey(key)) { return ActiveDeltas.ContainsKey(key); } return true; } private static string NormalizeName(string characterName, ulong platformId) { string text = (characterName ?? string.Empty).Trim(); if (text.Length != 0) { return text; } return platformId.ToString(CultureInfo.InvariantCulture); } } internal static class SandboxCsvWriter { private static readonly string[] BaselineHeader = new string[13] { "version", "snapshot_id", "player_key", "character_name", "platform_id", "zone_id", "captured_utc", "row_type", "component_type", "assembly_qualified_type", "existed", "payload_base64", "payload_hash" }; private static readonly string[] DeltaHeader = new string[21] { "version", "snapshot_id", "player_key", "character_name", "platform_id", "zone_id", "captured_utc", "row_type", "operation", "component_type", "before_payload_base64", "after_payload_base64", "tech_guid", "tech_name", "entity_index", "entity_version", "prefab_guid", "prefab_name", "pos_x", "pos_y", "pos_z" }; public static void WriteBaseline(string path, IEnumerable<BaselineRow> rows) { WriteCsv(path, BaselineHeader, rows, (BaselineRow row) => new string[13] { row.Version.ToString(CultureInfo.InvariantCulture), row.SnapshotId, row.PlayerKey, row.CharacterName, row.PlatformId.ToString(CultureInfo.InvariantCulture), row.ZoneId, row.CapturedUtc.ToString("O", CultureInfo.InvariantCulture), row.RowType, row.ComponentType, row.AssemblyQualifiedType, row.Existed ? "true" : "false", row.PayloadBase64, row.PayloadHash }); } public static void WriteDelta(string path, IEnumerable<DeltaRow> rows) { WriteCsv(path, DeltaHeader, rows, (DeltaRow row) => new string[21] { row.Version.ToString(CultureInfo.InvariantCulture), row.SnapshotId, row.PlayerKey, row.CharacterName, row.PlatformId.ToString(CultureInfo.InvariantCulture), row.ZoneId, row.CapturedUtc.ToString("O", CultureInfo.InvariantCulture), row.RowType, row.Operation, row.ComponentType, row.BeforePayloadBase64, row.AfterPayloadBase64, row.TechGuid.ToString(CultureInfo.InvariantCulture), row.TechName, row.EntityIndex.ToString(CultureInfo.InvariantCulture), row.EntityVersion.ToString(CultureInfo.InvariantCulture), row.PrefabGuid.ToString(CultureInfo.InvariantCulture), row.Pref