using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using HarmonyLib; using HookDOTS.API; using HookDOTS.API.Attributes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using ProjectM; using ProjectM.CastleBuilding; using ProjectM.Gameplay.Clan; using ProjectM.Gameplay.Scripting; using ProjectM.Gameplay.Systems; using ProjectM.Network; using ProjectM.Scripting; using ProjectM.Shared; using RaidForge.Config; using RaidForge.Core; using RaidForge.Data; using RaidForge.Patches; using RaidForge.Services; using RaidForge.Systems; using RaidForge.Utils; using Stunlock.Core; using Stunlock.Network; using Unity.Collections; using Unity.Entities; using Unity.Mathematics; using Unity.Transforms; using VampireCommandFramework; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("RaidForge")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Allows for flexible control over raid mechanics.")] [assembly: AssemblyFileVersion("3.2.2.0")] [assembly: AssemblyInformationalVersion("3.2.2")] [assembly: AssemblyProduct("RaidForge")] [assembly: AssemblyTitle("RaidForge")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.2.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RaidForge { [BepInPlugin("raidforge", "RaidForge", "3.2.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { private Harmony _harmony; private HookDOTS _hookDOTS; private static ConfigFile _raidScheduleConfigFile; private static ConfigFile _golemSettingsConfigFile; private static ConfigFile _offlineProtectionConfigFile; private static ConfigFile _raidInterferenceConfigFile; private static ConfigFile _troubleshootingConfigFile; private static ConfigFile _optInRaidingConfigFile; private static ConfigFile _optInScheduleConfigFile; private static ConfigFile _weaponRaidingConfigFile; private static ConfigFile _tntRaidingConfigFile; private static ConfigFile _commandSettingsConfigFile; private static ConfigFile _shardConfigFile; private static ConfigFile _mapIconsConfigFile; private static ConfigFile _purchasedOrpConfigFile; private static ConfigFile _servantLimitsConfigFile; private static bool _onBootShardScanHasRun = false; public static Plugin Instance { get; private set; } public static ManualLogSource Logger { get; private set; } public static bool SystemsInitialized { get; private set; } = false; public static bool ServerHasJustBooted { get; private set; } = true; public static bool IsAutoRaidCurrentlyActive => RaidSchedulingSystem.IsAutoRaidActive; public static List GetSchedule() { if (RaidConfig.Schedule != null) { return new List(RaidConfig.Schedule); } return new List(); } public override void Load() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown Instance = this; ServerHasJustBooted = true; SystemsInitialized = false; _onBootShardScanHasRun = false; Logger = ((BasePlugin)this).Log; LoggingHelper.Initialize(Logger); ResetRuntimeStateForFreshLoad(); LoadConfigs(); bool flag = default(bool); try { _harmony = new Harmony("raidforge"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); RaidForgeScheduler.Initialize(); _hookDOTS = new HookDOTS("raidforge", Logger); _hookDOTS.RegisterAnnotatedHooks(); Logger.LogInfo((object)"[RaidForge] HookDOTS registered. Damage policy hook active."); } catch (Exception ex) { ManualLogSource logger = Logger; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RaidForge] Patching failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } logger.LogError(val); } RaidInterferenceService.Initialize(); try { CommandRegistry.RegisterAll(); CommandRegistryCustomizationService.ApplyStartupConfiguration(); } catch (Exception ex2) { ManualLogSource logger2 = Logger; BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RaidForge] Failed to register commands: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex2); } logger2.LogError(val); } Logger.LogInfo((object)"[RaidForge] Loaded. Waiting for server world update to initialize systems..."); } public static void AttemptInitializeCoreSystems() { //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) if (!SystemsInitialized && VWorld.IsServerWorldReady()) { Logger.LogInfo((object)"[RaidForge] Server world detected. Initializing systems..."); EntityManager entityManager = VWorld.EntityManager; PrefabGuidResolver.ValidateKnownPrefabs(); ServantLimitService.ReloadConfiguredLimits(entityManager); SystemsInitialized = true; bool value = OfflineRaidProtectionConfig.EnableOfflineRaidProtection.Value; bool num = OptInRaidingConfig.EnableOptInRaiding.Value && !value; bool flag = PurchasedOrpConfig.IsPurchasedOrpActive(); if (value) { OfflineGraceService.LoadOfflineStatesFromDisk(entityManager); } if (num) { OptInRaidService.LoadStateFromDisk(); } if (flag) { PurchasedOrpService.LoadStateFromDisk(); } if (value) { ShardVulnerabilityService.LoadStateFromDisk(); } int num2 = OwnershipCacheService.InitializeHeartOwnershipCache(entityManager); int num3 = OwnershipCacheService.InitializeUserToClanCache(entityManager); ManualLogSource logger = Logger; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(49, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RaidForge] World Scan Complete: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Hearts, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Users."); } logger.LogInfo(val); RaidMapIconService.ClearAllRaidForgeIconEntities(entityManager); RunOnBootShardScanIfNeeded(); if (ServerHasJustBooted) { OfflineGraceService.EstablishInitialGracePeriodsOnBoot(entityManager); ServerHasJustBooted = false; } PlayerRegistryService.RefreshFromWorld(entityManager); RaidSchedulingSystem.CheckScheduleAndToggleRaids(forceCheck: true); GolemAutomationSystem.CheckAutomation(); RegisterRecurringTask("raid schedule check", delegate { RaidSchedulingSystem.CheckScheduleAndToggleRaids(); }, 30.0); RegisterRecurringTask("Golem automation check", delegate { GolemAutomationSystem.CheckAutomation(); }, 3600.0); RegisterRecurringTask("raid interference check", RaidInterferenceService.ProcessInterference, 2.0); RegisterRecurringTask("raid map icon cleanup", RaidMapIconService.ProcessCleanup, 5.0); RegisterRecurringTask("opt-in cooldown check", ProcessOptInCooldowns, 300.0); RegisterRecurringTask("purchased ORP raid-day accounting", PurchasedOrpService.ProcessDueRaidDayConsumption, 300.0); Logger.LogInfo((object)"[RaidForge] Initialization Complete. Mod is Active."); } } private static void RegisterRecurringTask(string taskName, Action action, double intervalSeconds) { RaidForgeScheduler.RunEvery(delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown try { action(); } catch (Exception ex) { ManualLogSource logger = Logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RaidForge] Error in scheduled "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(taskName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } logger.LogError(val); } }, intervalSeconds); } private static void ProcessOptInCooldowns() { if (OptInRaidingConfig.EnableOptInRaiding.Value && !OfflineRaidProtectionConfig.EnableOfflineRaidProtection.Value && OptInRaidingConfig.AutoOptOutAfterCooldown.Value) { OptInRaidService.ProcessAutoOptOut(OptInRaidingConfig.OptInLockDurationHours.Value); } } public static void RunOnBootShardScanIfNeeded() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!_onBootShardScanHasRun && SystemsInitialized) { if (!OfflineRaidProtectionConfig.EnableOfflineRaidProtection.Value || !ShardConfig.DisableOrpForShardHolders.Value) { _onBootShardScanHasRun = true; } else if (!_onBootShardScanHasRun) { PerformOnBootShardVulnerabilityScan(VWorld.EntityManager); _onBootShardScanHasRun = true; } } } private static void PerformOnBootShardVulnerabilityScan(EntityManager em) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_006c: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) EntityQuery val = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); NativeArray val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); HashSet hashSet = new HashSet(); try { Enumerator enumerator = val2.GetEnumerator(); bool flag = default(bool); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (!OwnerIdentityHelper.TryResolveFromUserEntity(em, current, out var owner, out var error)) { ManualLogSource logger = Logger; if (logger != null) { BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(58, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[RaidForge] Skipping on-boot shard scan owner resolution: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(error); } logger.LogWarning(val3); } continue; } HashSet hashSet2 = new HashSet(); Entity entity = owner.UserData.LocalCharacter._Entity; if (entity.Exists() && UserHelper.TryGetSoulShardsOnPerson(em, entity, out var foundShards, out var locationSummary)) { foreach (PrefabGUID item in foundShards) { hashSet2.Add(item); } } if (!string.IsNullOrEmpty(owner.PersistentKey) && hashSet.Add(owner.PersistentKey) && UserHelper.TryGetSoulShardsInOwnedPedestals(em, current, out var foundShards2, out locationSummary)) { foreach (PrefabGUID item2 in foundShards2) { hashSet2.Add(item2); } } if (hashSet2.Count == 0) { continue; } int maxCopiesForThisShard = ShardConfig.MaxAllowedShardsPerType?.Value ?? 1; foreach (PrefabGUID item3 in hashSet2) { PrefabGUID current4 = item3; ShardVulnerabilityService.SetVulnerable(owner.PersistentKey, ((PrefabGUID)(ref current4)).GuidHash, owner.UserKey, owner.ContextualName, maxCopiesForThisShard, deferSave: true); } } ShardVulnerabilityService.Flush(); } catch (Exception ex) { LoggingHelper.Error("Error during on-boot shard scan", ex); } finally { if (val2.IsCreated) { val2.Dispose(); } ((EntityQuery)(ref val)).Dispose(); } } private void OnConfigSettingChanged(object sender, SettingChangedEventArgs e) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) if (sender == _raidScheduleConfigFile) { RaidConfig.ParseSchedule(); PurchasedOrpService.ProcessDueRaidDayConsumption(force: true); if (SystemsInitialized) { RaidSchedulingSystem.CheckScheduleAndToggleRaids(forceCheck: true); RaidMapIconService.MarkPersistentStateIconsDirty(); } } else if (sender == _golemSettingsConfigFile) { GolemAutomationConfig.ReloadAndParseAll(); if (SystemsInitialized) { GolemAutomationSystem.ResetAutomationState(); GolemAutomationSystem.CheckAutomation(); } } else if (sender == _mapIconsConfigFile) { if (SystemsInitialized) { RaidMapIconService.MarkPersistentStateIconsDirty(); RaidMapIconService.ClearAllRaidForgeIconEntities(VWorld.EntityManager); RaidMapIconService.ProcessCleanup(); } ManualLogSource logger = Logger; if (logger != null) { logger.LogInfo((object)"[RaidForge] MapIcons.cfg changed. New values will be used by map icon services."); } } else if (sender == _optInRaidingConfigFile) { if (SystemsInitialized) { OptInRaidService.ReloadStateFromDisk(); PurchasedOrpService.ReloadStateFromDisk(); RaidMapIconService.MarkPersistentStateIconsDirty(); RaidMapIconService.ClearAllRaidForgeIconEntities(VWorld.EntityManager); RaidMapIconService.ProcessCleanup(); } ManualLogSource logger2 = Logger; if (logger2 != null) { logger2.LogInfo((object)"[RaidForge] OptInRaiding.cfg changed. Opt-in mode and map icons were refreshed."); } } else if (sender == _purchasedOrpConfigFile) { if (SystemsInitialized) { PurchasedOrpService.ReloadStateFromDisk(); RaidMapIconService.MarkPersistentStateIconsDirty(); RaidMapIconService.ClearAllRaidForgeIconEntities(VWorld.EntityManager); RaidMapIconService.ProcessCleanup(); } ManualLogSource logger3 = Logger; if (logger3 != null) { logger3.LogInfo((object)"[RaidForge] PurchasedORP.cfg changed. Purchased ORP state and map icons were refreshed."); } } else if (sender == _raidInterferenceConfigFile) { RaidInterferenceService.ResetRuntimeState(); RaidInterferenceService.Initialize(); ManualLogSource logger4 = Logger; if (logger4 != null) { logger4.LogInfo((object)"[RaidForge] RaidInterference.cfg changed. Runtime raid interference state was refreshed."); } } else if (sender == _servantLimitsConfigFile) { if (SystemsInitialized) { ServantLimitService.ReloadConfiguredLimits(VWorld.EntityManager); } ManualLogSource logger5 = Logger; if (logger5 != null) { logger5.LogInfo((object)"[RaidForge] ServantLimits.cfg changed. Servant prefab limits were refreshed."); } } else if (sender == _weaponRaidingConfigFile) { ManualLogSource logger6 = Logger; if (logger6 != null) { logger6.LogInfo((object)"[RaidForge] WeaponRaiding.cfg changed. New weapon structure damage settings are active."); } } else if (sender == _tntRaidingConfigFile) { ManualLogSource logger7 = Logger; if (logger7 != null) { logger7.LogInfo((object)"[RaidForge] TntDamageAndRaiding.cfg changed. New TNT damage settings are active."); } } } public static void ReloadAllConfigsAndRefreshSystems() { //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Expected O, but got Unknown //IL_00f7: 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_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { if (_troubleshootingConfigFile != null) { _troubleshootingConfigFile.Reload(); } if (_raidScheduleConfigFile != null) { _raidScheduleConfigFile.Reload(); } if (_golemSettingsConfigFile != null) { _golemSettingsConfigFile.Reload(); } if (_offlineProtectionConfigFile != null) { _offlineProtectionConfigFile.Reload(); } if (_raidInterferenceConfigFile != null) { _raidInterferenceConfigFile.Reload(); } if (_optInRaidingConfigFile != null) { _optInRaidingConfigFile.Reload(); } if (_optInScheduleConfigFile != null) { _optInScheduleConfigFile.Reload(); } if (_weaponRaidingConfigFile != null) { _weaponRaidingConfigFile.Reload(); } if (_tntRaidingConfigFile != null) { _tntRaidingConfigFile.Reload(); } if (_shardConfigFile != null) { _shardConfigFile.Reload(); } if (_mapIconsConfigFile != null) { _mapIconsConfigFile.Reload(); } if (_purchasedOrpConfigFile != null) { _purchasedOrpConfigFile.Reload(); } if (_servantLimitsConfigFile != null) { _servantLimitsConfigFile.Reload(); } RaidConfig.ParseSchedule(); PurchasedOrpService.ProcessDueRaidDayConsumption(force: true); GolemAutomationConfig.ReloadAndParseAll(); if (SystemsInitialized) { OfflineGraceService.ReloadOfflineStatesFromDisk(VWorld.EntityManager); ShardVulnerabilityService.ReloadStateFromDisk(); OptInRaidService.ReloadStateFromDisk(); PurchasedOrpService.ReloadStateFromDisk(); ServantLimitService.ReloadConfiguredLimits(VWorld.EntityManager); EntityManager entityManager = VWorld.EntityManager; int num = OwnershipCacheService.InitializeHeartOwnershipCache(entityManager); int num2 = OwnershipCacheService.InitializeUserToClanCache(entityManager); ManualLogSource logger = Logger; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(42, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[Reload] Cache refreshed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Hearts, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Users."); } logger.LogInfo(val); PlayerRegistryService.RefreshFromWorld(entityManager); RaidSchedulingSystem.CheckScheduleAndToggleRaids(forceCheck: true); GolemAutomationSystem.ResetAutomationState(); GolemAutomationSystem.CheckAutomation(); RaidMapIconService.MarkPersistentStateIconsDirty(); RaidMapIconService.ClearAllRaidForgeIconEntities(entityManager); RaidMapIconService.ProcessCleanup(); RaidInterferenceService.ResetRuntimeState(); RaidInterferenceService.Initialize(); } ManualLogSource logger2 = Logger; if (logger2 != null) { logger2.LogInfo((object)"[RaidForge] All config files were reloaded."); } } catch (Exception ex) { ManualLogSource logger3 = Logger; if (logger3 != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[RaidForge] Error reloading configs: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger3.LogError(val2); } } } public static void TriggerReloadFromCommand() { ReloadAllConfigsAndRefreshSystems(); } private static void ResetRuntimeStateForFreshLoad() { ServerWorldReadyPatch.ResetRuntimeState(); DamageInterceptorPatch.ResetRuntimeState(); OfflineGraceService.ResetRuntimeState(); OptInRaidService.ResetRuntimeState(); PurchasedOrpService.ResetRuntimeState(); ShardVulnerabilityService.ResetRuntimeState(); RaidInterferenceService.ResetRuntimeState(); RaidMapIconService.ResetRuntimeState(); PlayerRegistryService.ResetRuntimeState(); ServantLimitService.ResetRuntimeState(); OwnershipCacheService.ClearAllCaches(); RaidSchedulingSystem.ResetRuntimeState(); GolemAutomationSystem.ResetRuntimeState(); } public static void TriggerGolemAutomationResetFromCommand() { if (SystemsInitialized) { GolemAutomationSystem.ResetAutomationState(); } } private void LoadConfigs() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown string text = Path.Combine(Paths.ConfigPath, "RaidForge"); Directory.CreateDirectory(text); string text2 = Path.Combine(text, "TntDamageAndRaiding.cfg"); bool tntConfigExistedBeforeLoad = File.Exists(text2); _troubleshootingConfigFile = new ConfigFile(Path.Combine(text, "Troubleshooting.cfg"), true); _raidScheduleConfigFile = new ConfigFile(Path.Combine(text, "RaidScheduleAndGeneral.cfg"), true); _golemSettingsConfigFile = new ConfigFile(Path.Combine(text, "GolemSettings.cfg"), true); _offlineProtectionConfigFile = new ConfigFile(Path.Combine(text, "OfflineProtection.cfg"), true); _raidInterferenceConfigFile = new ConfigFile(Path.Combine(text, "RaidInterference.cfg"), true); _optInRaidingConfigFile = new ConfigFile(Path.Combine(text, "OptInRaiding.cfg"), true); _optInScheduleConfigFile = new ConfigFile(Path.Combine(text, "OptInSchedule.cfg"), true); _weaponRaidingConfigFile = new ConfigFile(Path.Combine(text, "WeaponRaiding.cfg"), true); _tntRaidingConfigFile = new ConfigFile(text2, true); _commandSettingsConfigFile = new ConfigFile(Path.Combine(text, "CommandSettings.cfg"), true); _shardConfigFile = new ConfigFile(Path.Combine(text, "SoulShards.cfg"), true); _mapIconsConfigFile = new ConfigFile(Path.Combine(text, "MapIcons.cfg"), true); _purchasedOrpConfigFile = new ConfigFile(Path.Combine(text, "PurchasedORP.cfg"), true); _servantLimitsConfigFile = new ConfigFile(Path.Combine(text, "ServantLimits.cfg"), true); TroubleshootingConfig.Initialize(_troubleshootingConfigFile); RaidConfig.Initialize(_raidScheduleConfigFile, Logger); GolemAutomationConfig.Initialize(_golemSettingsConfigFile, Logger); OfflineRaidProtectionConfig.Initialize(_offlineProtectionConfigFile); RaidInterferenceConfig.Initialize(_raidInterferenceConfigFile); OptInRaidingConfig.Initialize(_optInRaidingConfigFile); OptInScheduleConfig.Initialize(_optInScheduleConfigFile); WeaponRaidingConfig.Initialize(_weaponRaidingConfigFile, Logger); TntRaidingConfig.Initialize(_tntRaidingConfigFile, Logger); TntRaidingConfig.MigrateLegacySettingsIfNeeded(_weaponRaidingConfigFile, tntConfigExistedBeforeLoad, Logger); CommandSettingsConfig.Initialize(_commandSettingsConfigFile, Logger); ShardConfig.Initialize(_shardConfigFile); MapIconsConfig.Initialize(_mapIconsConfigFile); PurchasedOrpConfig.Initialize(_purchasedOrpConfigFile); ServantLimitsConfig.Initialize(_servantLimitsConfigFile); RaidConfig.ParseSchedule(); GolemAutomationConfig.ReloadAndParseAll(); _troubleshootingConfigFile.SettingChanged += OnConfigSettingChanged; _raidScheduleConfigFile.SettingChanged += OnConfigSettingChanged; _golemSettingsConfigFile.SettingChanged += OnConfigSettingChanged; _offlineProtectionConfigFile.SettingChanged += OnConfigSettingChanged; _raidInterferenceConfigFile.SettingChanged += OnConfigSettingChanged; _optInRaidingConfigFile.SettingChanged += OnConfigSettingChanged; _optInScheduleConfigFile.SettingChanged += OnConfigSettingChanged; _weaponRaidingConfigFile.SettingChanged += OnConfigSettingChanged; _tntRaidingConfigFile.SettingChanged += OnConfigSettingChanged; _shardConfigFile.SettingChanged += OnConfigSettingChanged; _mapIconsConfigFile.SettingChanged += OnConfigSettingChanged; _purchasedOrpConfigFile.SettingChanged += OnConfigSettingChanged; _servantLimitsConfigFile.SettingChanged += OnConfigSettingChanged; ManualLogSource logger = Logger; if (logger != null) { logger.LogInfo((object)"[RaidForge] Config files loaded, including CommandSettings.cfg and separate weapon/TNT raiding files."); } } public override bool Unload() { //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Expected O, but got Unknown bool flag = default(bool); try { if (_troubleshootingConfigFile != null) { _troubleshootingConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_raidScheduleConfigFile != null) { _raidScheduleConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_golemSettingsConfigFile != null) { _golemSettingsConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_offlineProtectionConfigFile != null) { _offlineProtectionConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_raidInterferenceConfigFile != null) { _raidInterferenceConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_optInRaidingConfigFile != null) { _optInRaidingConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_optInScheduleConfigFile != null) { _optInScheduleConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_weaponRaidingConfigFile != null) { _weaponRaidingConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_tntRaidingConfigFile != null) { _tntRaidingConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_shardConfigFile != null) { _shardConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_mapIconsConfigFile != null) { _mapIconsConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_purchasedOrpConfigFile != null) { _purchasedOrpConfigFile.SettingChanged -= OnConfigSettingChanged; } if (_servantLimitsConfigFile != null) { _servantLimitsConfigFile.SettingChanged -= OnConfigSettingChanged; } RaidForgeScheduler.Dispose(); HookDOTS hookDOTS = _hookDOTS; if (hookDOTS != null) { hookDOTS.Dispose(); } try { CommandRegistry.UnregisterAssembly(); } catch (Exception ex) { ManualLogSource logger = Logger; if (logger != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RaidForge] Failed to unregister commands: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } logger.LogError(val); } } RaidInterferenceService.StopService(); SharedFileIO.FlushPendingWrites(); RaidMapIconService.ResetRuntimeState(); DamageInterceptorPatch.ResetRuntimeState(); ServerWorldReadyPatch.ResetRuntimeState(); OfflineGraceService.ResetRuntimeState(); OptInRaidService.ResetRuntimeState(); PurchasedOrpService.ResetRuntimeState(); ShardVulnerabilityService.ResetRuntimeState(); RaidSchedulingSystem.ResetRuntimeState(); GolemAutomationSystem.ResetRuntimeState(); OwnershipCacheService.ClearAllCaches(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } SystemsInitialized = false; ServerHasJustBooted = true; _onBootShardScanHasRun = false; ManualLogSource logger2 = Logger; if (logger2 != null) { logger2.LogInfo((object)"[RaidForge] Unloaded."); } } catch (Exception ex2) { ManualLogSource logger = Logger; if (logger != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RaidForge] Error during unload: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex2); } logger.LogError(val); } return false; } return true; } } public static class PluginInfo { public const string PLUGIN_GUID = "RaidForge"; public const string PLUGIN_NAME = "RaidForge"; public const string PLUGIN_VERSION = "3.2.2"; } } namespace RaidForge.Utils { public static class ChatColors { public const string Error = "#FF4136"; public const string Success = "#2ECC40"; public const string Info = "#FFFFFF"; public const string Warning = "#F00534"; public const string Highlight = "#7FDBFF"; public const string Accent = "#FFDC00"; public const string Muted = "#AAAAAA"; public static string Format(string message, string colorHex) { if (string.IsNullOrEmpty(colorHex)) { return message; } return $"{message}"; } public static string ErrorText(string message) { return Format(message, "#FF4136"); } public static string SuccessText(string message) { return Format(message, "#2ECC40"); } public static string InfoText(string message) { return Format(message, "#FFFFFF"); } public static string WarningText(string message) { return Format(message, "#F00534"); } public static string HighlightText(string message) { return Format(message, "#7FDBFF"); } public static string AccentText(string message) { return Format(message, "#FFDC00"); } public static string MutedText(string message) { return Format(message, "#AAAAAA"); } } internal static class DelimitedText { public static string Escape(string value, char delimiter) { if (string.IsNullOrEmpty(value)) { return string.Empty; } if (value.IndexOf(delimiter) < 0 && value.IndexOf('"') < 0 && value.IndexOf('\r') < 0 && value.IndexOf('\n') < 0) { return value; } return "\"" + value.Replace("\"", "\"\"") + "\""; } public static string[] ParseLine(string line, char delimiter) { List list = new List(); StringBuilder stringBuilder = new StringBuilder(); bool flag = false; for (int i = 0; i < line.Length; i++) { char c = line[i]; if (c == '"') { if (flag && i + 1 < line.Length && line[i + 1] == '"') { stringBuilder.Append('"'); i++; } else { flag = !flag; } } else if (c == delimiter && !flag) { list.Add(stringBuilder.ToString()); stringBuilder.Clear(); } else { stringBuilder.Append(c); } } list.Add(stringBuilder.ToString()); return list.ToArray(); } } internal static class EntityExtensions { private static EntityManager Em => VWorld.EntityManager; public static bool Exists(this Entity entity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (entity != Entity.Null) { EntityManager em = Em; return ((EntityManager)(ref em)).Exists(entity); } return false; } } public static class LoggingHelper { private static ManualLogSource _logger; private static bool IsVerboseLoggingGloballyEnabled => TroubleshootingConfig.EnableVerboseLogging?.Value ?? false; public static void Initialize(ManualLogSource logger) { _logger = logger; if (_logger == null) { Console.WriteLine("[RaidForge.LoggingHelper] CRITICAL: Logger passed to Initialize is null!"); } } public static void Info(string message) { ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)message); } } public static void Warning(string message, Exception ex = null) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown if (_logger == null) { return; } if (ex != null) { ManualLogSource logger = _logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(14, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(message); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" | Exception: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.ToString()); } logger.LogWarning(val); } else { _logger.LogWarning((object)message); } } public static void Error(string message, Exception ex = null) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown if (_logger == null) { Console.WriteLine("[RaidForge.LoggingHelper ERROR (logger not init)]: " + message + " " + ((ex != null) ? ex.ToString() : "")); } else if (ex != null) { ManualLogSource logger = _logger; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(14, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(message); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" | Exception: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.ToString()); } logger.LogError(val); } else { _logger.LogError((object)message); } } public static void Debug(string message) { if (IsVerboseLoggingGloballyEnabled && _logger != null) { _logger.LogDebug((object)message); } } } public readonly struct OwnerIdentity { public readonly Entity UserEntity; public readonly Entity ClanEntity; public readonly User UserData; public readonly string PersistentKey; public readonly string UserKey; public readonly string ContextualName; public readonly string CharacterName; public readonly string ClanName; public readonly ulong PlatformId; public readonly bool IsClan; public OwnerIdentity(Entity userEntity, Entity clanEntity, User userData, string persistentKey, string userKey, string contextualName, string characterName, string clanName, ulong platformId, bool isClan) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) UserEntity = userEntity; ClanEntity = clanEntity; UserData = userData; PersistentKey = persistentKey; UserKey = userKey; ContextualName = contextualName; CharacterName = characterName; ClanName = clanName; PlatformId = platformId; IsClan = isClan; } public string GetDisplayNameWithOwnerType() { if (!IsClan) { return ContextualName; } return ContextualName + " (Clan)"; } } public static class OwnerIdentityHelper { public static bool TryResolveFromUserEntity(EntityManager em, Entity userEntity, out OwnerIdentity owner, out string error) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0069: 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_006b: 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) owner = default(OwnerIdentity); error = string.Empty; try { if (em == default(EntityManager)) { error = "EntityManager is not available."; return false; } if (userEntity == Entity.Null || !((EntityManager)(ref em)).Exists(userEntity)) { error = "User entity does not exist."; return false; } if (!((EntityManager)(ref em)).HasComponent(userEntity)) { error = "Entity does not have a User component."; return false; } User componentData = ((EntityManager)(ref em)).GetComponentData(userEntity); return TryResolveFromUserData(em, userEntity, componentData, null, out owner, out error); } catch (Exception ex) { error = "Failed to resolve owner identity from user entity: " + ex.Message; return false; } } public unsafe static bool TryResolveFromUserData(EntityManager em, Entity userEntity, User userData, string fallbackCharacterName, out OwnerIdentity owner, 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) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) owner = default(OwnerIdentity); error = string.Empty; try { string text = ((!string.IsNullOrWhiteSpace(fallbackCharacterName)) ? fallbackCharacterName : SafeFixedStringToString(((object)(*(FixedString64Bytes*)(&userData.CharacterName))/*cast due to .constrained prefix*/).ToString(), "Unknown Player")); ulong platformId = userData.PlatformId; string userKey = PersistentKeyHelper.GetUserKey(platformId); Entity entity = userData.ClanEntity._Entity; if (entity != Entity.Null && entity.Exists() && ((EntityManager)(ref em)).Exists(entity) && ((EntityManager)(ref em)).HasComponent(entity)) { ClanTeam componentData = ((EntityManager)(ref em)).GetComponentData(entity); string text2 = SafeFixedStringToString(((object)(*(FixedString64Bytes*)(&componentData.Name))/*cast due to .constrained prefix*/).ToString(), "Unknown Clan"); string clanKey = PersistentKeyHelper.GetClanKey(em, entity); owner = new OwnerIdentity(userEntity, entity, userData, clanKey, userKey, text2, text, text2, platformId, isClan: true); return true; } owner = new OwnerIdentity(userEntity, Entity.Null, userData, userKey, userKey, text, text, string.Empty, platformId, isClan: false); return true; } catch (Exception ex) { error = "Failed to resolve owner identity from user data: " + ex.Message; return false; } } public static bool TryResolveFromPlayerName(EntityManager em, string playerName, out OwnerIdentity owner, out string error) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) owner = default(OwnerIdentity); error = string.Empty; try { if (string.IsNullOrWhiteSpace(playerName)) { error = "Player name cannot be empty."; return false; } if (!UserHelper.FindUserEntity(em, playerName, out var userEntity, out var userData, out var characterName)) { error = "Player '" + playerName + "' not found."; return false; } return TryResolveFromUserData(em, userEntity, userData, characterName, out owner, out error); } catch (Exception ex) { error = "Failed to resolve owner identity for player '" + playerName + "': " + ex.Message; return false; } } public static bool TryResolveFromCommandSender(EntityManager em, Entity senderUserEntity, out OwnerIdentity owner, out string error) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TryResolveFromUserEntity(em, senderUserEntity, out owner, out error); } private static string SafeFixedStringToString(string value, string fallback) { if (string.IsNullOrWhiteSpace(value)) { return fallback; } return value.Trim(); } } public static class OwnerIdentityQueries { public static List GetUniqueOwners(EntityManager em, string logContext) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); try { val = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref em)).Exists(current) && OwnerIdentityHelper.TryResolveFromUserEntity(em, current, out var owner, out var _) && !string.IsNullOrWhiteSpace(owner.PersistentKey) && !dictionary.ContainsKey(owner.PersistentKey)) { dictionary[owner.PersistentKey] = owner; } } } catch (Exception ex) { LoggingHelper.Error("[" + logContext + "] Error building unique owner list.", ex); } finally { if (val2.IsCreated) { val2.Dispose(); } if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } } return new List(dictionary.Values); } } public static class PrefabGuidResolver { private delegate bool TryResolveDelegate(string prefabNameOrHash, out PrefabGUID prefabGuid, out string resolvedName); public static bool TryResolve(string prefabNameOrHash, out PrefabGUID prefabGuid) { string resolvedName; return TryResolve(prefabNameOrHash, out prefabGuid, out resolvedName); } public static bool TryResolve(string prefabNameOrHash, out PrefabGUID prefabGuid, out string resolvedName) { //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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) prefabGuid = default(PrefabGUID); resolvedName = null; if (string.IsNullOrWhiteSpace(prefabNameOrHash)) { return false; } string text = prefabNameOrHash.Trim(); if (int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { prefabGuid = new PrefabGUID(result); if (!TryGetPrefabName(prefabGuid, out resolvedName)) { prefabGuid = default(PrefabGUID); return false; } return true; } if (!TryGetPrefabGuidByName(text, out prefabGuid)) { return false; } resolvedName = (TryGetPrefabName(prefabGuid, out var prefabName) ? prefabName : text); return true; } public static bool TryResolveMapIcon(string prefabNameOrHash, out PrefabGUID prefabGuid) { string resolvedName; return TryResolveMapIcon(prefabNameOrHash, out prefabGuid, out resolvedName); } public static bool TryResolveMapIcon(string prefabNameOrHash, out PrefabGUID prefabGuid, out string resolvedName) { //IL_0001: 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) prefabGuid = default(PrefabGUID); resolvedName = null; if (MapIconPrefabCatalog.TryResolve(prefabNameOrHash, out prefabGuid, out resolvedName)) { return true; } if (!TryResolve(prefabNameOrHash, out prefabGuid, out resolvedName) || string.IsNullOrWhiteSpace(resolvedName) || !resolvedName.StartsWith("MapIcon_", StringComparison.OrdinalIgnoreCase) || ((PrefabGUID)(ref prefabGuid)).GuidHash == MapIconPrefabCatalog.MapIconProxyPrefab.GuidHash) { prefabGuid = default(PrefabGUID); resolvedName = null; return false; } return true; } public static PrefabGUID ResolveMapIconOrDefault(string prefabNameOrHash, PrefabRef fallbackPrefab, string context) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) return ResolveOrDefault(prefabNameOrHash, fallbackPrefab.Name, fallbackPrefab.Guid, context, TryResolveMapIcon); } public static bool TryGetPrefabGuidByName(string prefabName, out PrefabGUID prefabGuid) { //IL_0001: 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_0041: Unknown result type (might be due to invalid IL or missing references) prefabGuid = default(PrefabGUID); if (string.IsNullOrWhiteSpace(prefabName)) { return false; } string text = prefabName.Trim(); if (TryGetPrefabLookup(out var prefabLookup) && ((PrefabLookupMap)(ref prefabLookup)).TryGetPrefabGuidWithName(text, ref prefabGuid, true)) { return true; } if (TryGetKnownPrefabByName(text, out var prefab)) { prefabGuid = prefab.Guid; return true; } return false; } public static bool TryGetPrefabName(PrefabGUID prefabGuid, out string prefabName) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) prefabName = null; if (TryGetPrefabLookup(out var prefabLookup) && ((PrefabLookupMap)(ref prefabLookup)).TryGetName(prefabGuid, ref prefabName) && !string.IsNullOrWhiteSpace(prefabName)) { return true; } if (TryGetKnownPrefabByHash(((PrefabGUID)(ref prefabGuid)).GuidHash, out var prefab)) { prefabName = prefab.Name; return true; } return false; } public static int ValidateKnownPrefabs() { try { return ValidateKnownPrefabsCore(); } catch (Exception ex) { LoggingHelper.Warning("[PrefabCatalog] Runtime name/hash validation failed unexpectedly.", ex); return -1; } } private static int ValidateKnownPrefabsCore() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (!TryGetPrefabLookup(out var prefabLookup)) { LoggingHelper.Warning("[PrefabCatalog] V Rising PrefabLookupMap is unavailable; runtime name/hash validation was skipped."); return -1; } HashSet seenHashes = new HashSet(); int validated = 0; int mismatches = 0; foreach (PrefabRef item in PrefabData.All) { ValidateKnownPrefab(prefabLookup, item, seenHashes, ref validated, ref mismatches); } foreach (PrefabRef knownPrefab in MapIconPrefabCatalog.KnownPrefabs) { ValidateKnownPrefab(prefabLookup, knownPrefab, seenHashes, ref validated, ref mismatches); } if (mismatches == 0) { LoggingHelper.Info($"[PrefabCatalog] Validated {validated} unique prefab name/hash pair(s) against V Rising."); } else { LoggingHelper.Error($"[PrefabCatalog] Found {mismatches} invalid prefab definition(s) while validating {validated} unique pair(s)."); } return mismatches; } private static PrefabGUID ResolveOrDefault(string prefabNameOrHash, string defaultPrefabName, PrefabGUID fallbackPrefabGuid, string context, TryResolveDelegate tryResolve) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (tryResolve(prefabNameOrHash, out var prefabGuid, out var resolvedName)) { return prefabGuid; } if (tryResolve(defaultPrefabName, out prefabGuid, out resolvedName)) { LogInvalidConfig(prefabNameOrHash, defaultPrefabName, context); return prefabGuid; } LogInvalidConfig(prefabNameOrHash, $"{defaultPrefabName} ({((PrefabGUID)(ref fallbackPrefabGuid)).GuidHash})", context); return fallbackPrefabGuid; } private static void ValidateKnownPrefab(PrefabLookupMap prefabLookup, PrefabRef prefab, HashSet seenHashes, ref int validated, ref int mismatches) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (seenHashes.Add(prefab.GuidHash)) { validated++; string text = default(string); bool num = ((PrefabLookupMap)(ref prefabLookup)).TryGetName(prefab.Guid, ref text) && string.Equals(text, prefab.Name, StringComparison.Ordinal); PrefabGUID val = default(PrefabGUID); bool flag = ((PrefabLookupMap)(ref prefabLookup)).TryGetPrefabGuidWithName(prefab.Name, ref val, false) && ((PrefabGUID)(ref val)).GuidHash == prefab.GuidHash; if (!(num && flag)) { mismatches++; LoggingHelper.Error($"[PrefabCatalog] Invalid definition {prefab}. Hash resolved to '{text ?? ""}'; name resolved to {((PrefabGUID)(ref val)).GuidHash}."); } } } private static bool TryGetPrefabLookup(out PrefabLookupMap prefabLookup) { //IL_0001: 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_0019: Unknown result type (might be due to invalid IL or missing references) prefabLookup = default(PrefabLookupMap); if (!TryGetPrefabCollectionSystem(out var prefabCollection)) { return false; } prefabLookup = prefabCollection._PrefabLookupMap; return ((PrefabLookupMap)(ref prefabLookup)).IsCreated; } private static bool TryGetPrefabCollectionSystem(out PrefabCollectionSystem prefabCollection) { prefabCollection = null; if (VWorld.Server == null || !VWorld.Server.IsCreated) { return false; } prefabCollection = VWorld.Server.GetExistingSystemManaged(); return prefabCollection != null; } private static bool TryGetKnownPrefabByName(string name, out PrefabRef prefab) { if (PrefabData.TryGetByName(name, out prefab)) { return true; } foreach (PrefabRef knownPrefab in MapIconPrefabCatalog.KnownPrefabs) { if (string.Equals(knownPrefab.Name, name, StringComparison.OrdinalIgnoreCase)) { prefab = knownPrefab; return true; } } prefab = default(PrefabRef); return false; } private static bool TryGetKnownPrefabByHash(int guidHash, out PrefabRef prefab) { if (!PrefabData.TryGetByHash(guidHash, out prefab)) { return MapIconPrefabCatalog.TryGetByHash(guidHash, out prefab); } return true; } private static void LogInvalidConfig(string configuredValue, string fallbackValue, string context) { ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { string value = (string.IsNullOrWhiteSpace(configuredValue) ? "" : configuredValue.Trim()); LoggingHelper.Warning($"[PrefabGuidResolver] Could not resolve '{value}' for {context}. Using {fallbackValue}."); } } } public static class ShapeshiftHelper { public static bool IsInBearForm(EntityManager em, Entity characterEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!BuffUtility.HasBuff(em, characterEntity, PrefabIdentifier.op_Implicit(PrefabData.BearBuff.Guid))) { return BuffUtility.HasBuff(em, characterEntity, PrefabIdentifier.op_Implicit(PrefabData.BearSkinBuff.Guid)); } return true; } } public static class SharedFileIO { private const int DefaultAttempts = 5; private const int DefaultDelayMilliseconds = 75; private static readonly object PendingWritesLock = new object(); private static readonly Dictionary PendingWritesByPath = new Dictionary(StringComparer.OrdinalIgnoreCase); private static Thread _writerThread; private static bool _isWriting; public static string[] ReadAllLinesShared(string path) { if (!File.Exists(path)) { return Array.Empty(); } Exception ex = null; for (int i = 1; i <= 5; i++) { try { using FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); using StreamReader streamReader = new StreamReader(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks: true); List list = new List(); while (!streamReader.EndOfStream) { list.Add(streamReader.ReadLine()); } return list.ToArray(); } catch (IOException ex2) { ex = ex2; Thread.Sleep(75 * i); } } throw ex ?? new IOException("Failed to read '" + path + "'."); } public static void WriteAllTextWithRetry(string path, string content) { string directoryName = Path.GetDirectoryName(path); if (!string.IsNullOrEmpty(directoryName)) { Directory.CreateDirectory(directoryName); } Exception ex = null; for (int i = 1; i <= 5; i++) { try { using FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read); using StreamWriter streamWriter = new StreamWriter(stream, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); streamWriter.Write(content); return; } catch (IOException ex2) { ex = ex2; Thread.Sleep(75 * i); } } throw ex ?? new IOException("Failed to write '" + path + "'."); } public static void QueueWriteAllTextWithRetry(string path, string content) { if (string.IsNullOrWhiteSpace(path)) { return; } lock (PendingWritesLock) { PendingWritesByPath[path] = content ?? string.Empty; EnsureWriterThreadStarted(); Monitor.PulseAll(PendingWritesLock); } } public static void FlushPendingWrites() { while (true) { Dictionary batch; lock (PendingWritesLock) { while (_isWriting) { Monitor.Wait(PendingWritesLock, 50); } if (PendingWritesByPath.Count == 0) { break; } batch = TakePendingWritesForCurrentThread(); } WriteBatch(batch); } } private static void EnsureWriterThreadStarted() { if (_writerThread == null || !_writerThread.IsAlive) { _writerThread = new Thread(BackgroundWriterLoop) { IsBackground = true, Name = "RaidForge CSV Writer" }; _writerThread.Start(); } } private static void BackgroundWriterLoop() { while (true) { Dictionary batch; lock (PendingWritesLock) { while (PendingWritesByPath.Count == 0 || _isWriting) { Monitor.Wait(PendingWritesLock); } batch = TakePendingWritesForCurrentThread(); } WriteBatch(batch); } } private static Dictionary TakePendingWritesForCurrentThread() { Dictionary result = new Dictionary(PendingWritesByPath, StringComparer.OrdinalIgnoreCase); PendingWritesByPath.Clear(); _isWriting = true; return result; } private static void WriteBatch(Dictionary batch) { try { foreach (KeyValuePair item in batch) { try { WriteAllTextWithRetry(item.Key, item.Value); } catch (Exception ex) { LoggingHelper.Error("[SharedFileIO] CSV write failed for '" + item.Key + "'.", ex); } } } finally { lock (PendingWritesLock) { _isWriting = false; Monitor.PulseAll(PendingWritesLock); } } } } public static class UserHelper { private const int MaxSourceOwnerDepth = 6; public static bool TryGetShardPrefabsForUserOrClan(EntityManager em, Entity userEntity, out HashSet foundShards, out string reason) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) foundShards = new HashSet(); List list = new List(); User val = default(User); if (!((EntityManager)(ref em)).Exists(userEntity) || !((EntityManager)(ref em)).TryGetComponentData(userEntity, ref val)) { reason = "Invalid User Entity"; return false; } Entity entity = val.LocalCharacter._Entity; if (entity.Exists() && TryGetSoulShardsOnPerson(em, entity, out var foundShards2, out var locationSummary)) { foreach (PrefabGUID item in foundShards2) { foundShards.Add(item); } list.Add("shard(s) found in " + locationSummary); } if (TryGetSoulShardsInOwnedPedestals(em, userEntity, out var foundShards3, out var reason2)) { foreach (PrefabGUID item2 in foundShards3) { foundShards.Add(item2); } list.Add(reason2); } if (foundShards.Count > 0) { reason = string.Join(" | ", list); return true; } reason = "No shards found."; return false; } public static bool TryGetSoulShardsOnPerson(EntityManager em, Entity characterEntity, out HashSet foundShards, out string locationSummary) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_003a: 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_0162: 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_0172: 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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0199: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00af: 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) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) foundShards = new HashSet(); List list = new List(); if (characterEntity == Entity.Null || !((EntityManager)(ref em)).Exists(characterEntity)) { locationSummary = "none"; return false; } NativeList val = default(NativeList); val..ctor(AllocatorHandle.op_Implicit((Allocator)2)); try { if (InventoryUtilities.TryGetInventoryEntities(em, characterEntity, ref val)) { PrefabGUID item = default(PrefabGUID); for (int i = 0; i < val.Length; i++) { Entity val2 = val[i]; if (!((EntityManager)(ref em)).Exists(val2) || !((EntityManager)(ref em)).HasBuffer(val2)) { continue; } Enumerator enumerator = ((EntityManager)(ref em)).GetBuffer(val2, false).GetEnumerator(); while (enumerator.MoveNext()) { InventoryBuffer current = enumerator.Current; if (PrefabData.SoulShardPrefabGUIDs.Contains(current.ItemType)) { foundShards.Add(current.ItemType); if (!list.Contains("inventory")) { list.Add("inventory"); } } else if (((EntityManager)(ref em)).Exists(current.ItemEntity._Entity) && ((EntityManager)(ref em)).TryGetComponentData(current.ItemEntity._Entity, ref item) && PrefabData.SoulShardPrefabGUIDs.Contains(item)) { foundShards.Add(item); if (!list.Contains("inventory")) { list.Add("inventory"); } } } } } } finally { if (val.IsCreated) { val.Dispose(); } } Equipment val3 = default(Equipment); if (((EntityManager)(ref em)).TryGetComponentData(characterEntity, ref val3)) { Entity entity = val3.GrimoireSlot.SlotEntity._Entity; PrefabGUID item2 = default(PrefabGUID); if (entity.Exists() && ((EntityManager)(ref em)).TryGetComponentData(entity, ref item2) && PrefabData.SoulShardPrefabGUIDs.Contains(item2)) { foundShards.Add(item2); if (!list.Contains("equipped Grimoire")) { list.Add("equipped Grimoire"); } } } locationSummary = ((list.Count > 0) ? string.Join(" and ", list) : "none"); return foundShards.Count > 0; } public static bool TryGetSoulShardsInOwnedPedestals(EntityManager em, Entity userEntity, out HashSet foundShards, out string reason) { //IL_0010: 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_0026: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) foundShards = new HashSet(); reason = string.Empty; User val = default(User); if (!((EntityManager)(ref em)).Exists(userEntity) || !((EntityManager)(ref em)).TryGetComponentData(userEntity, ref val)) { return false; } Entity entity = val.ClanEntity._Entity; HashSet hashSet = new HashSet(); foreach (KeyValuePair item in OwnershipCacheService.GetHeartToOwnerCacheView()) { if (((EntityManager)(ref em)).Exists(item.Key) && ((EntityManager)(ref em)).Exists(item.Value)) { bool flag = false; if (item.Value == userEntity) { flag = true; } if (!flag && entity.Exists() && OwnershipCacheService.TryGetUserClan(item.Value, out var clanEntity) && clanEntity == entity) { flag = true; } if (flag) { hashSet.Add(item.Key); } } } if (!hashSet.Any()) { return false; } HashSet soulShardPedestalPrefabGUIDs = PrefabData.SoulShardPedestalPrefabGUIDs; EntityQuery val2 = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[2] { ComponentType.ReadOnly(), ComponentType.ReadOnly() }); NativeArray val3 = ((EntityQuery)(ref val2)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); try { Enumerator enumerator2 = val3.GetEnumerator(); DynamicBuffer val4 = default(DynamicBuffer); PrefabGUID val5 = default(PrefabGUID); DynamicBuffer val6 = default(DynamicBuffer); while (enumerator2.MoveNext()) { Entity current2 = enumerator2.Current; if (!hashSet.Contains(((EntityManager)(ref em)).GetComponentData(current2).CastleHeartEntity._Entity) || !soulShardPedestalPrefabGUIDs.Contains(((EntityManager)(ref em)).GetComponentData(current2)) || !((EntityManager)(ref em)).TryGetBuffer(current2, ref val4)) { continue; } Enumerator enumerator3 = val4.GetEnumerator(); while (enumerator3.MoveNext()) { Entity entity2 = enumerator3.Current.Entity; if (!entity2.Exists() || !((EntityManager)(ref em)).TryGetComponentData(entity2, ref val5) || !(val5 == PrefabData.ExternalInventoryPrefab.Guid) || !((EntityManager)(ref em)).TryGetBuffer(entity2, ref val6)) { continue; } Enumerator enumerator4 = val6.GetEnumerator(); while (enumerator4.MoveNext()) { InventoryBuffer current3 = enumerator4.Current; if (PrefabData.SoulShardPrefabGUIDs.Contains(current3.ItemType)) { foundShards.Add(current3.ItemType); } } } } } finally { if (val3.IsCreated) { val3.Dispose(); } ((EntityQuery)(ref val2)).Dispose(); } if (foundShards.Count > 0) { reason = $"Found {foundShards.Count} unique shard type(s) inside pedestal inventories."; return true; } return false; } public unsafe static bool FindUserEntity(EntityManager em, string identifier, out Entity userEntity, out User userData, out string characterName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: 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_0101: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) userEntity = Entity.Null; userData = default(User); characterName = string.Empty; if (string.IsNullOrWhiteSpace(identifier)) { return false; } EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); try { val = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); ulong result; bool flag = ulong.TryParse(identifier, out result); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (!((EntityManager)(ref em)).Exists(current) || !((EntityManager)(ref em)).HasComponent(current)) { continue; } User componentData = ((EntityManager)(ref em)).GetComponentData(current); if (flag) { if (componentData.PlatformId == result) { userEntity = current; userData = componentData; characterName = ((object)(*(FixedString64Bytes*)(&componentData.CharacterName))/*cast due to .constrained prefix*/).ToString(); return true; } continue; } string text = ((object)(*(FixedString64Bytes*)(&componentData.CharacterName))/*cast due to .constrained prefix*/).ToString(); if (text.Equals(identifier, StringComparison.OrdinalIgnoreCase)) { userEntity = current; userData = componentData; characterName = text; return true; } } } finally { if (val2.IsCreated) { val2.Dispose(); } if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } } return false; } public static bool TryGetPlayerOwnerFromSource(EntityManager em, Entity sourceEntity, out Entity playerCharacterEntity, out Entity userEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return TryGetPlayerOwnerFromSource(em, sourceEntity, 0, out playerCharacterEntity, out userEntity); } private static bool TryGetPlayerOwnerFromSource(EntityManager em, Entity sourceEntity, int depth, out Entity playerCharacterEntity, out Entity userEntity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_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_002a: 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_0075: 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_0041: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_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_006a: 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_012a: 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_010c: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) playerCharacterEntity = Entity.Null; userEntity = Entity.Null; if (depth > 6 || sourceEntity == Entity.Null || !((EntityManager)(ref em)).Exists(sourceEntity)) { return false; } PlayerCharacter val = default(PlayerCharacter); if (((EntityManager)(ref em)).TryGetComponentData(sourceEntity, ref val)) { Entity userEntity2 = val.UserEntity; if (userEntity2 != Entity.Null && ((EntityManager)(ref em)).Exists(userEntity2)) { playerCharacterEntity = sourceEntity; userEntity = userEntity2; return true; } } User val2 = default(User); if (((EntityManager)(ref em)).TryGetComponentData(sourceEntity, ref val2)) { userEntity = sourceEntity; Entity entity = val2.LocalCharacter._Entity; if (entity != Entity.Null && ((EntityManager)(ref em)).Exists(entity) && ((EntityManager)(ref em)).HasComponent(entity)) { playerCharacterEntity = entity; } return true; } int depth2 = depth + 1; UserOwner val3 = default(UserOwner); if (((EntityManager)(ref em)).TryGetComponentData(sourceEntity, ref val3)) { Entity entity2 = val3.Owner._Entity; if (entity2 != sourceEntity && TryGetPlayerOwnerFromSource(em, entity2, depth2, out playerCharacterEntity, out userEntity)) { return true; } } EntityOwner val4 = default(EntityOwner); if (((EntityManager)(ref em)).TryGetComponentData(sourceEntity, ref val4)) { Entity owner = val4.Owner; if (owner != sourceEntity && TryGetPlayerOwnerFromSource(em, owner, depth2, out playerCharacterEntity, out userEntity)) { return true; } } EntityCreator val5 = default(EntityCreator); if (((EntityManager)(ref em)).TryGetComponentData(sourceEntity, ref val5)) { Entity entity3 = val5.Creator._Entity; if (entity3 != sourceEntity && TryGetPlayerOwnerFromSource(em, entity3, depth2, out playerCharacterEntity, out userEntity)) { return true; } } return false; } public static bool IsAnyClanMemberOnline(EntityManager em, Entity clanEntity, Entity excludingUserEntity = default(Entity)) { //IL_0002: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (!((EntityManager)(ref em)).Exists(clanEntity) || !((EntityManager)(ref em)).HasComponent(clanEntity)) { return false; } NativeList val = default(NativeList); val..ctor(AllocatorHandle.op_Implicit((Allocator)2)); try { TeamUtility.GetClanMembers(em, clanEntity, val); Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if ((!(excludingUserEntity != default(Entity)) || !(current == excludingUserEntity)) && ((EntityManager)(ref em)).Exists(current) && ((EntityManager)(ref em)).HasComponent(current) && ((EntityManager)(ref em)).GetComponentData(current).IsConnected) { return true; } } } catch (Exception ex) { LoggingHelper.Error("[UserHelper] Error in IsAnyClanMemberOnline", ex); } finally { if (val.IsCreated) { val.Dispose(); } } return false; } } internal static class VWorld { private static World _serverWorld; private static EntityManager _entityManager; public static World Server { get { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (_serverWorld != null && _serverWorld.IsCreated) { return _serverWorld; } _serverWorld = GetWorld("Server"); if (_serverWorld == null || !_serverWorld.IsCreated) { _entityManager = default(EntityManager); LoggingHelper.Error("VWorld: Server world is not available or not created. Subsequent calls may fail."); return null; } _entityManager = _serverWorld.EntityManager; return _serverWorld; } } public static EntityManager EntityManager { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_005b: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0032: Unknown result type (might be due to invalid IL or missing references) if ((_entityManager == default(EntityManager) || (_serverWorld != null && _serverWorld.IsCreated && _entityManager != _serverWorld.EntityManager)) && Server != null) { _entityManager = _serverWorld.EntityManager; } if (_entityManager == default(EntityManager)) { LoggingHelper.Error("VWorld: EntityManager is not available. Ensure Server world is initialized."); } return _entityManager; } } private static World GetWorld(string name) { if (World.s_AllWorlds == null) { return null; } Enumerator enumerator = World.s_AllWorlds.GetEnumerator(); while (enumerator.MoveNext()) { World current = enumerator.Current; if (current.Name == name && current.IsCreated) { return current; } } return null; } public static bool IsServerWorldReady() { //IL_0013: 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_0020: Unknown result type (might be due to invalid IL or missing references) if (Server != null && Server.IsCreated) { return EntityManager != default(EntityManager); } return false; } public static bool GameBalanceSettings(out ServerGameBalanceSettings settings, Func modify = null) { //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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_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) settings = default(ServerGameBalanceSettings); EntityQuery val = default(EntityQuery); try { if (!IsServerWorldReady()) { LoggingHelper.Error("VWorld.GameBalanceSettings: Server world or EntityManager not ready."); return false; } EntityManager entityManager = EntityManager; val = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadWrite() }); if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { LoggingHelper.Error("VWorld.GameBalanceSettings: Could not find ServerGameBalanceSettings entity."); return false; } Entity singletonEntity = ((EntityQuery)(ref val)).GetSingletonEntity(); ServerGameBalanceSettings componentData = ((EntityManager)(ref entityManager)).GetComponentData(singletonEntity); if (modify == null) { settings = componentData; return true; } ServerGameBalanceSettings val2 = modify(componentData); ((EntityManager)(ref entityManager)).SetComponentData(singletonEntity, val2); settings = val2; return true; } catch (Exception ex) { LoggingHelper.Error("VWorld.GameBalanceSettings: Exception while accessing/modifying ServerGameBalanceSettings.", ex); return false; } finally { if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } } } } } namespace RaidForge.Systems { public static class GolemAutomationSystem { private static int _lastDayCheckedForSchedule = -1; private static SiegeWeaponHealth? _lastHealthSuccessfullySet = null; public static void ResetRuntimeState() { _lastDayCheckedForSchedule = -1; _lastHealthSuccessfullySet = null; } public static bool CheckAutomation() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) if (!VWorld.IsServerWorldReady()) { ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Debug("GolemAutomationSystem: Server world not ready. Golem automation check skipped."); } return false; } SiegeWeaponHealth? val = null; string value = "None"; string text = GolemAutomationConfig.ManualSiegeWeaponHealthOverride?.Value; if (!string.IsNullOrEmpty(text)) { if (Enum.TryParse(text, ignoreCase: true, out SiegeWeaponHealth result)) { val = result; value = "Manual Level Override ('" + text + "')"; LoggingHelper.Debug("[GolemAutomationSystem] Manual SiegeWeaponHealth level override active: " + text + "."); } else { LoggingHelper.Warning("[GolemAutomationSystem] Invalid ManualSiegeWeaponHealthOverride value in config: '" + text + "'. It will be ignored."); } } if (!val.HasValue) { ConfigEntry enableDayBasedAutomation = GolemAutomationConfig.EnableDayBasedAutomation; if (enableDayBasedAutomation != null && enableDayBasedAutomation.Value) { if (!GolemAutomationConfig.ParsedStartDate.HasValue) { ConfigEntry enableVerboseLogging2 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging2 != null && enableVerboseLogging2.Value) { LoggingHelper.Debug("GolemAutomationSystem: Day-based automation enabled, but ServerStartDateForAutomation not parsed. Schedule skipped."); } } else { DateTime now = DateTime.Now; DateTime value2 = GolemAutomationConfig.ParsedStartDate.Value; int num = (int)Math.Floor((now - value2).TotalDays); if (num < 0) { num = 0; } LoggingHelper.Debug($"[GolemAutomationSystem] Evaluating day-based schedule for Day {num}. Last schedule check day: {_lastDayCheckedForSchedule}."); val = GolemAutomationConfig.GetScheduledHealthForDay(num); if (val.HasValue) { value = $"Day-Based Schedule (Day {num} -> Level {val.Value})"; LoggingHelper.Debug($"[GolemAutomationSystem] Day-based schedule determined target: {val.Value}."); } else { LoggingHelper.Debug($"[GolemAutomationSystem] No day-based schedule entry found for Day {num}."); } _lastDayCheckedForSchedule = num; } goto IL_026c; } } if (!val.HasValue) { LoggingHelper.Debug("[GolemAutomationSystem] No manual override set and day-based automation is disabled."); } goto IL_026c; IL_026c: if (val.HasValue) { if (!_lastHealthSuccessfullySet.HasValue || _lastHealthSuccessfullySet.Value != val.Value) { LoggingHelper.Info($"[GolemAutomationSystem] Attempting to set Golem Health to {val.Value} (Source: {value})."); if (SiegeWeaponSystem.SetSiegeWeaponHealth(val.Value)) { _lastHealthSuccessfullySet = val.Value; LoggingHelper.Info($"[GolemAutomationSystem] Successfully set Golem Health to {val.Value}."); } else { LoggingHelper.Error($"[GolemAutomationSystem] FAILED to set Golem Health to {val.Value}."); } } else { LoggingHelper.Debug($"[GolemAutomationSystem] Golem Health {val.Value} (Source: {value}) is already what was last successfully set. No change needed."); } } else { LoggingHelper.Debug("[GolemAutomationSystem] No golem health change determined by overrides or active day-based schedule for today."); } return true; } public static void ResetAutomationState() { ResetRuntimeState(); LoggingHelper.Info("GolemAutomationSystem: State (last check day and last applied health) has been reset."); } } public static class RaidSchedulingSystem { private static bool _initialCheckPerformed; private static bool? _manualRaidOverride; public static bool IsAutoRaidActive { get; private set; } public static bool HasManualOverride => _manualRaidOverride.HasValue; public static bool? ManualOverrideValue => _manualRaidOverride; public static void ResetRuntimeState() { IsAutoRaidActive = false; _initialCheckPerformed = false; _manualRaidOverride = null; } public static bool SetManualOverride(bool raidsEnabled) { if (!VWorld.IsServerWorldReady()) { LoggingHelper.Warning($"RaidSchedulingSystem: Could not set manual raid override to {raidsEnabled}; server world is not ready."); return false; } _manualRaidOverride = raidsEnabled; LoggingHelper.Info("RaidSchedulingSystem: Manual raid override set to " + (raidsEnabled ? "ON" : "OFF") + ". Schedule automation will not change raids until the override is cleared."); return ApplyDesiredRaidState(raidsEnabled, "Manual override"); } public static bool ClearManualOverride() { _manualRaidOverride = null; LoggingHelper.Info("RaidSchedulingSystem: Manual raid override cleared. Resuming schedule control."); return CheckScheduleAndToggleRaids(forceCheck: true); } public static bool CheckScheduleAndToggleRaids(bool forceCheck = false) { bool flag = forceCheck || !_initialCheckPerformed; if (!VWorld.IsServerWorldReady()) { if (flag) { ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Warning("RaidSchedulingSystem: Server world not ready yet for schedule check."); } } return false; } bool value; bool flag2; bool flag3; if (_manualRaidOverride.HasValue) { value = _manualRaidOverride.Value; flag2 = RaidToggleSystem.AreRaidsEnabled(); flag3 = value != flag2; if (flag3) { goto IL_0080; } if (flag) { ConfigEntry enableVerboseLogging2 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging2 != null && enableVerboseLogging2.Value) { goto IL_0080; } } goto IL_00e3; } DateTime now = DateTime.Now; DateTime raidScheduleNow = RaidConfig.GetRaidScheduleNow(); List schedule = RaidConfig.Schedule; if (schedule == null) { LoggingHelper.Error("RaidSchedulingSystem: Check FAILED - RaidConfig.Schedule is null. Raids will be treated as OFF by default."); if (RaidToggleSystem.AreRaidsEnabled()) { LoggingHelper.Info("RaidSchedulingSystem: Turning raids OFF due to null schedule."); RaidToggleSystem.DisableRaids(); } IsAutoRaidActive = false; return true; } bool flag4 = false; string value2 = "No matching schedule entry found."; foreach (RaidScheduleEntry item in schedule) { if (item.Day == raidScheduleNow.DayOfWeek) { DateTime dateTime = raidScheduleNow.Date + item.StartTime; DateTime dateTime2 = ((!(item.EndTime == TimeSpan.Zero) || !item.SpansMidnight) ? (item.SpansMidnight ? (raidScheduleNow.Date.AddDays(1.0) + item.EndTime) : (raidScheduleNow.Date + item.EndTime)) : raidScheduleNow.Date.AddDays(1.0)); if (raidScheduleNow >= dateTime && raidScheduleNow < dateTime2) { flag4 = true; string value3 = ((item.EndTime == TimeSpan.Zero && item.SpansMidnight) ? "24:00" : item.EndTime.ToString("hh\\:mm")); value2 = $"Active window: {item.Day} {item.StartTime:hh\\:mm} - {value3}"; break; } } else if (item.SpansMidnight && item.Day == (DayOfWeek)((int)(raidScheduleNow.DayOfWeek - 1 + 7) % 7)) { DateTime dateTime = raidScheduleNow.Date.AddDays(-1.0) + item.StartTime; DateTime dateTime2 = raidScheduleNow.Date + item.EndTime; if (raidScheduleNow >= dateTime && raidScheduleNow < dateTime2) { flag4 = true; value2 = $"Active window (spanned from yesterday): {item.Day} {item.StartTime:hh\\:mm} - {item.EndTime:hh\\:mm}"; break; } } } bool flag5 = RaidToggleSystem.AreRaidsEnabled(); bool flag6 = flag4 != flag5; if (flag6) { goto IL_03f5; } if (flag) { ConfigEntry enableVerboseLogging3 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging3 != null && enableVerboseLogging3.Value) { goto IL_03f5; } } goto IL_04ba; IL_0080: LoggingHelper.Info($"RaidSchedulingSystem: Manual override active - Should be {(value ? "ON" : "OFF")}. Current live state: {flag2}. Change needed: {flag3}"); goto IL_00e3; IL_03f5: LoggingHelper.Info($"RaidSchedulingSystem: Schedule check - Should be {(flag4 ? "ON" : "OFF")}. Reason: {value2}. Schedule clock: {raidScheduleNow:ddd HH:mm}. Server clock: {now:ddd HH:mm}. Current live state: {flag5}. Internal state: {IsAutoRaidActive}. Change needed: {flag6}"); goto IL_04ba; IL_04ba: if (flag6) { ApplyDesiredRaidState(flag4, "Scheduled"); } else if (flag) { ConfigEntry enableVerboseLogging4 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging4 != null && enableVerboseLogging4.Value) { IsAutoRaidActive = flag4; LoggingHelper.Info($"RaidSchedulingSystem: Raid state ({IsAutoRaidActive}) matches desired state. No action needed."); } } MarkInitialCheckPerformed(); return true; IL_00e3: if (flag3) { ApplyDesiredRaidState(value, "Manual override"); } else { IsAutoRaidActive = value; } MarkInitialCheckPerformed(); return true; } private static bool ApplyDesiredRaidState(bool shouldBeActive, string source) { LoggingHelper.Info(shouldBeActive ? ("RaidSchedulingSystem: Enabling raids (" + source + ")...") : ("RaidSchedulingSystem: Disabling raids (" + source + ")...")); if (shouldBeActive ? RaidToggleSystem.EnableRaids() : RaidToggleSystem.DisableRaids()) { IsAutoRaidActive = shouldBeActive; LoggingHelper.Info($"RaidSchedulingSystem: Raid state successfully changed to: {IsAutoRaidActive} ({source})"); return true; } LoggingHelper.Error($"RaidSchedulingSystem: FAILED to set CastleDamageMode via {source}. Raid state remains {IsAutoRaidActive}."); return false; } private static void MarkInitialCheckPerformed() { if (!_initialCheckPerformed && VWorld.IsServerWorldReady()) { _initialCheckPerformed = true; ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Info("RaidSchedulingSystem: Initial raid schedule check performed."); } } } } public static class RaidToggleSystem { private static readonly TimeSpan RaidStateCacheDuration = TimeSpan.FromSeconds(1.0); private static bool _cachedRaidsEnabled = false; private static DateTime _raidStateCacheExpiresUtc = DateTime.MinValue; public static bool AreRaidsEnabled() { DateTime utcNow = DateTime.UtcNow; if (utcNow < _raidStateCacheExpiresUtc) { return _cachedRaidsEnabled; } RefreshRaidStateCache(utcNow); return _cachedRaidsEnabled; } public static bool AreRaidsEnabledLive() { RefreshRaidStateCache(DateTime.UtcNow); return _cachedRaidsEnabled; } public static bool EnableRaids() { return SetCastleDamageMode((CastleDamageMode)1); } public static bool DisableRaids() { return SetCastleDamageMode((CastleDamageMode)2); } private static bool SetCastleDamageMode(CastleDamageMode newMode) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) try { if (!SetServerGameSettingsCastleDamageMode(newMode, out var previousMode)) { return false; } CastleDamageMode balancePreviousMode = (CastleDamageMode)0; if (VWorld.GameBalanceSettings(out var settings, delegate(ServerGameBalanceSettings val) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_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_0029: 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) balancePreviousMode = val.CastleDamageMode; if (val.CastleDamageMode == newMode) { return val; } val.CastleDamageMode = newMode; return val; })) { SetRaidStateCache((int)newMode == 1); RaidMapIconService.MarkPersistentStateIconsDirty(); RaidMapIconService.ProcessCleanup(); LoggingHelper.Info($"[RaidToggleSystem] CastleDamageMode set to {newMode} (ServerGameSettings: {previousMode} -> {newMode}, BalanceSettings: {balancePreviousMode} -> {settings.CastleDamageMode})."); return true; } return false; } catch (Exception ex) { LoggingHelper.Error($"[RaidToggleSystem] Failed to set CastleDamageMode to {newMode}.", ex); return false; } } private static bool SetServerGameSettingsCastleDamageMode(CastleDamageMode newMode, out CastleDamageMode previousMode) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected I4, but got Unknown //IL_0046: 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_004f: Unknown result type (might be due to invalid IL or missing references) previousMode = (CastleDamageMode)0; try { if (!VWorld.IsServerWorldReady()) { LoggingHelper.Error("[RaidToggleSystem] Server world not ready while setting ServerGameSettings CastleDamageMode."); return false; } ServerGameSettingsSystem existingSystemManaged = VWorld.Server.GetExistingSystemManaged(); if (existingSystemManaged == null) { LoggingHelper.Error("[RaidToggleSystem] ServerGameSettingsSystem not found while setting CastleDamageMode."); return false; } ServerGameSettings settings = existingSystemManaged._Settings; previousMode = (CastleDamageMode)(int)settings.CastleDamageMode; if (settings.CastleDamageMode != newMode) { settings.CastleDamageMode = newMode; existingSystemManaged._Settings = settings; } return true; } catch (Exception ex) { LoggingHelper.Error("[RaidToggleSystem] Failed to set ServerGameSettings CastleDamageMode.", ex); return false; } } private static void RefreshRaidStateCache(DateTime nowUtc) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 if (VWorld.GameBalanceSettings(out var settings)) { _cachedRaidsEnabled = (int)settings.CastleDamageMode == 1; } _raidStateCacheExpiresUtc = nowUtc.Add(RaidStateCacheDuration); } private static void SetRaidStateCache(bool raidsEnabled) { _cachedRaidsEnabled = raidsEnabled; _raidStateCacheExpiresUtc = DateTime.UtcNow.Add(RaidStateCacheDuration); } } public static class SiegeWeaponSystem { public static bool SetSiegeWeaponHealth(SiegeWeaponHealth newValue) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) try { if (VWorld.GameBalanceSettings(out var _, delegate(ServerGameBalanceSettings val) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (val.SiegeWeaponHealth == newValue) { return val; } val.SiegeWeaponHealth = newValue; return val; })) { return true; } return false; } catch (Exception ex) { LoggingHelper.Error($"[SiegeWeaponSystem] Failed to set SiegeWeaponHealth to {newValue}.", ex); return false; } } public static SiegeWeaponHealth? GetSiegeWeaponHealth() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) try { if (VWorld.GameBalanceSettings(out var settings)) { return settings.SiegeWeaponHealth; } return null; } catch (Exception ex) { LoggingHelper.Error("[SiegeWeaponSystem] Failed to read SiegeWeaponHealth.", ex); return null; } } } } namespace RaidForge.Services { internal static class CommandRegistryCustomizationService { private sealed class PreparedCommand { public object Metadata { get; } public ParameterInfo[] Parameters { get; } public IReadOnlyList CommandNames { get; } public PreparedCommand(object metadata, ParameterInfo[] parameters, IReadOnlyList commandNames) { Metadata = metadata; Parameters = parameters; CommandNames = commandNames; } } public static void ApplyStartupConfiguration() { //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Expected O, but got Unknown //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown if (!CommandSettingsConfig.CustomSettingsEnabled) { ManualLogSource logger = Plugin.Logger; if (logger != null) { logger.LogInfo((object)"[CommandSettings] Custom command settings are disabled. VCF is using RaidForge's built-in commands and normal help registration."); } return; } Assembly assembly = typeof(Plugin).Assembly; bool flag = false; try { IDictionary assemblyCommandMap = GetAssemblyCommandMap(); if (!assemblyCommandMap.Contains(assembly) || !(assemblyCommandMap[assembly] is IDictionary dictionary)) { throw new InvalidOperationException("VCF did not expose RaidForge's registered command map."); } List list = PrepareCommands(dictionary); Type type = dictionary.GetType(); ValidateCommandKeysAvailable(assemblyCommandMap, assembly, list); CommandRegistry.UnregisterAssembly(assembly); flag = true; object commandCache = GetCommandCache(); MethodInfo method = commandCache.GetType().GetMethod("AddCommand", BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { throw new MissingMethodException(commandCache.GetType().FullName, "AddCommand"); } IDictionary dictionary2 = (IDictionary)(assemblyCommandMap[assembly] = (IDictionary)Activator.CreateInstance(type)); foreach (PreparedCommand item in list) { List list2 = new List(); dictionary2.Add(item.Metadata, list2); foreach (string commandName in item.CommandNames) { string text = "." + commandName; method.Invoke(commandCache, new object[3] { text, item.Parameters, item.Metadata }); list2.Add(text); } } int count = list.Count; int value = CommandSettingsConfig.RuntimeCommands.Count - count; ManualLogSource logger2 = Plugin.Logger; if (logger2 != null) { logger2.LogInfo((object)($"[CommandSettings] Applied startup-only VCF registration: enabled={count}, disabled={value}. " + "Configured names and shorthands now appear through normal .help.")); } } catch (Exception ex) { ManualLogSource logger3 = Plugin.Logger; bool flag2 = default(bool); if (logger3 != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(98, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[CommandSettings] Could not apply custom VCF registration. Restoring built-in RaidForge commands: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } logger3.LogError(val); } try { if (!flag) { ManualLogSource logger4 = Plugin.Logger; if (logger4 != null) { logger4.LogWarning((object)"[CommandSettings] Built-in RaidForge commands remain registered because customization failed before the registry was changed."); } } else { CommandRegistry.UnregisterAssembly(assembly); CommandRegistry.RegisterAll(assembly); } } catch (Exception ex2) { logger3 = Plugin.Logger; if (logger3 != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(59, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[CommandSettings] Failed to restore built-in VCF commands: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex2); } logger3.LogError(val); } } } } private static void ValidateCommandKeysAvailable(IDictionary assemblyCommandMap, Assembly raidForgeAssembly, IReadOnlyList preparedCommands) { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (DictionaryEntry item2 in assemblyCommandMap) { if (object.Equals(item2.Key, raidForgeAssembly) || !(item2.Value is IDictionary dictionary)) { continue; } foreach (DictionaryEntry item3 in dictionary) { if (!(item3.Value is IEnumerable enumerable) || item3.Value is string) { continue; } foreach (object item4 in enumerable) { if (item4 is string item) { hashSet.Add(item); } } } } foreach (PreparedCommand preparedCommand in preparedCommands) { foreach (string commandName in preparedCommand.CommandNames) { string text = "." + commandName; if (hashSet.Contains(text)) { throw new InvalidOperationException("Configured command '" + text + "' is already registered by VCF or another mod."); } } } } internal static bool TryGetRaidForgeCommandMap(out IDictionary commandMap) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown commandMap = null; try { IDictionary assemblyCommandMap = GetAssemblyCommandMap(); Assembly assembly = typeof(Plugin).Assembly; if (assemblyCommandMap.Contains(assembly) && assemblyCommandMap[assembly] is IDictionary dictionary) { commandMap = dictionary; return true; } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; if (logger != null) { bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(49, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[CommandSettings] VCF command-map lookup failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } logger.LogDebug(val); } } return false; } internal static string GetRegisteredCommandName(object metadata) { if (metadata == null) { return null; } object? obj = metadata.GetType().GetProperty("Attribute", BindingFlags.Instance | BindingFlags.Public)?.GetValue(metadata); CommandAttribute val = (CommandAttribute)((obj is CommandAttribute) ? obj : null); if (val == null) { return null; } return val.Name; } private static List PrepareCommands(IDictionary originalCommandMap) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown List list = new List(); bool flag = default(bool); foreach (DictionaryEntry item in originalCommandMap) { object key = item.Key; Type type = key.GetType(); CommandAttribute val = (CommandAttribute)GetRequiredProperty(type, "Attribute").GetValue(key); if (!CommandSettingsConfig.TryGetCommand(val.Name, out var command)) { ManualLogSource logger = Plugin.Logger; if (logger != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(112, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[CommandSettings] Registered command '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(val.Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' has no configuration definition and will keep its built-in registration."); } logger.LogWarning(val2); } command = CreateDefaultRuntime(val); } if (command.Enabled) { string text = (string.IsNullOrWhiteSpace(command.ShortHand) ? null : command.ShortHand); CommandAttribute customizedAttribute = new CommandAttribute(command.PrimaryName, text, val.Usage, val.Description, val.Id, val.AdminOnly); object metadata = CreateMetadataClone(type, key, customizedAttribute); List list2 = new List { command.PrimaryName }; if (!string.IsNullOrEmpty(text)) { list2.Add(text); } list.Add(new PreparedCommand(metadata, (ParameterInfo[])GetRequiredProperty(type, "Parameters").GetValue(key), list2)); } } return list; } private static object CreateMetadataClone(Type metadataType, object originalMetadata, CommandAttribute customizedAttribute) { ConstructorInfo? constructorInfo = metadataType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault(delegate(ConstructorInfo constructor) { ParameterInfo[] parameters = constructor.GetParameters(); return parameters.Length == 8 && parameters[0].ParameterType == typeof(CommandAttribute); }); if (constructorInfo == null) { throw new MissingMethodException(metadataType.FullName, ".ctor(CommandAttribute, ...)"); } return constructorInfo.Invoke(new object[8] { customizedAttribute, GetRequiredProperty(metadataType, "Assembly").GetValue(originalMetadata), GetRequiredProperty(metadataType, "Method").GetValue(originalMetadata), GetRequiredProperty(metadataType, "Constructor").GetValue(originalMetadata), GetRequiredProperty(metadataType, "Parameters").GetValue(originalMetadata), GetRequiredProperty(metadataType, "ContextType").GetValue(originalMetadata), GetRequiredProperty(metadataType, "ConstructorType").GetValue(originalMetadata), GetRequiredProperty(metadataType, "GroupAttribute").GetValue(originalMetadata) }); } private static CommandSettingsConfig.RuntimeCommand CreateDefaultRuntime(CommandAttribute attribute) { return new CommandSettingsConfig.RuntimeCommand(new CommandSettingsConfig.CommandDefinition(attribute.Name, attribute.ShortHand, attribute.Description, attribute.Usage, attribute.AdminOnly), enabled: true, attribute.Name, attribute.ShortHand ?? string.Empty, !attribute.AdminOnly, showInAdminList: true); } private static IDictionary GetAssemblyCommandMap() { return (typeof(CommandRegistry).GetProperty("AssemblyCommandMap", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) as IDictionary) ?? throw new MissingMemberException(typeof(CommandRegistry).FullName, "AssemblyCommandMap"); } private static object GetCommandCache() { return typeof(CommandRegistry).GetField("_cache", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) ?? throw new MissingFieldException(typeof(CommandRegistry).FullName, "_cache"); } private static PropertyInfo GetRequiredProperty(Type type, string name) { return type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public) ?? throw new MissingMemberException(type.FullName, name); } } public static class InventoryPaymentService { public static int GetItemAmount(EntityManager em, Entity characterEntity, PrefabGUID itemPrefab) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_001b: Unknown result type (might be due to invalid IL or missing references) if (characterEntity == Entity.Null || !((EntityManager)(ref em)).Exists(characterEntity)) { return 0; } return InventoryUtilities.GetItemAmountInInventories(em, characterEntity, itemPrefab); } public static bool TryRemoveItems(EntityManager em, Entity characterEntity, PrefabGUID itemPrefab, int amount) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_001f: Unknown result type (might be due to invalid IL or missing references) if (amount <= 0 || characterEntity == Entity.Null || !((EntityManager)(ref em)).Exists(characterEntity)) { return false; } return InventoryUtilitiesServer.TryRemoveItem(em, characterEntity, itemPrefab, amount); } } public class PersistedOfflineStateEntry { public string PersistentKey { get; set; } public long OfflineStartTimeTicks { get; set; } public string ContextualName { get; set; } } public static class PersistentKeyHelper { public static string GetUserKey(ulong platformId) { return $"user_{platformId}"; } public unsafe static string GetClanKey(EntityManager em, Entity clanEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0036: Unknown result type (might be due to invalid IL or missing references) if (clanEntity == Entity.Null || !((EntityManager)(ref em)).Exists(clanEntity)) { return null; } if (((EntityManager)(ref em)).HasComponent(clanEntity)) { NetworkId componentData = ((EntityManager)(ref em)).GetComponentData(clanEntity); if (!((NetworkId)(ref componentData)).Equals(default(NetworkId))) { string text = ((object)(*(NetworkId*)(&componentData))/*cast due to .constrained prefix*/).ToString(); return "clan_nid_" + text; } } return null; } } public static class OfflineGraceService { private static Dictionary _persistedOfflineStartTimes = new Dictionary(); private static Dictionary _persistedOfflineEntityNames = new Dictionary(); private static readonly string DataSubfolder = "Data"; private static readonly string OfflineStatesSaveFileName = "RaidForge_OfflineStates.csv"; private static bool _dataLoadedFromDisk = false; private static readonly object _saveLock = new object(); private static string GetSaveFilePath() { string text = Path.Combine(Paths.ConfigPath, "RaidForge", DataSubfolder); Directory.CreateDirectory(text); return Path.Combine(text, OfflineStatesSaveFileName); } public static void ResetRuntimeState() { lock (_saveLock) { _persistedOfflineStartTimes.Clear(); _persistedOfflineEntityNames.Clear(); _dataLoadedFromDisk = false; } } public static void ReloadOfflineStatesFromDisk(EntityManager entityManager) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) LoadOfflineStatesFromDisk(entityManager, forceReload: true); } public static void LoadOfflineStatesFromDisk(EntityManager entityManager, bool forceReload = false) { if (_dataLoadedFromDisk && !forceReload) { return; } lock (_saveLock) { string saveFilePath = GetSaveFilePath(); if (_dataLoadedFromDisk && !forceReload) { return; } _persistedOfflineStartTimes.Clear(); _persistedOfflineEntityNames.Clear(); if (!File.Exists(saveFilePath)) { _dataLoadedFromDisk = true; return; } try { foreach (string item in SharedFileIO.ReadAllLinesShared(saveFilePath).Skip(1)) { if (string.IsNullOrWhiteSpace(item)) { continue; } string[] array = DelimitedText.ParseLine(item, ','); if (array.Length >= 3) { string text = array[0].Trim(); string value = array[2].Trim(); if (!string.IsNullOrEmpty(text) && long.TryParse(array[1], out var result)) { _persistedOfflineStartTimes[text] = new DateTime(result, DateTimeKind.Utc); _persistedOfflineEntityNames[text] = value; } } } } catch (Exception ex) { LoggingHelper.Error("Failed to load offline states from CSV.", ex); } _dataLoadedFromDisk = true; } } private static void SaveTimedOfflineStatesToDiskInternal() { if (!Plugin.SystemsInitialized && !_dataLoadedFromDisk) { return; } lock (_saveLock) { string saveFilePath = GetSaveFilePath(); try { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("PersistentKey,OfflineStartTimeTicks,ContextualName"); foreach (KeyValuePair persistedOfflineStartTime in _persistedOfflineStartTimes) { string key = persistedOfflineStartTime.Key; long ticks = persistedOfflineStartTime.Value.Ticks; string value2; string value = (_persistedOfflineEntityNames.TryGetValue(key, out value2) ? value2 : "NameNotFoundOnSave"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 3, stringBuilder2); handler.AppendFormatted(DelimitedText.Escape(key, ',')); handler.AppendLiteral(","); handler.AppendFormatted(ticks); handler.AppendLiteral(","); handler.AppendFormatted(DelimitedText.Escape(value, ',')); stringBuilder2.AppendLine(ref handler); } SharedFileIO.QueueWriteAllTextWithRetry(saveFilePath, stringBuilder.ToString()); } catch (Exception ex) { LoggingHelper.Error("Failed to save offline states to CSV.", ex); } } } public static void MarkAsOffline(string persistentKey, DateTime offlineTimeUtc, string contextualName) { if (!string.IsNullOrEmpty(persistentKey)) { SetOfflineStateInMemory(persistentKey, offlineTimeUtc, contextualName); SaveTimedOfflineStatesToDiskInternal(); } } public static void MarkAsOnline(string persistentKey, string contextualName) { if (!string.IsNullOrEmpty(persistentKey)) { bool flag; lock (_saveLock) { flag = _persistedOfflineStartTimes.Remove(persistentKey); _persistedOfflineEntityNames.Remove(persistentKey); } if (flag) { SaveTimedOfflineStatesToDiskInternal(); } } } public static bool AdminForceRemoveProtection(string persistentKey) { if (string.IsNullOrEmpty(persistentKey)) { return false; } bool flag; lock (_saveLock) { flag = _persistedOfflineStartTimes.Remove(persistentKey); _persistedOfflineEntityNames.Remove(persistentKey); } if (flag) { SaveTimedOfflineStatesToDiskInternal(); LoggingHelper.Info("[Admin] Forced removal of ORP for key: " + persistentKey); return true; } return false; } private static void SetOfflineStateInMemory(string persistentKey, DateTime offlineTimeUtc, string contextualName) { lock (_saveLock) { _persistedOfflineStartTimes[persistentKey] = offlineTimeUtc; _persistedOfflineEntityNames[persistentKey] = contextualName; } } private static bool ClearOfflineStateInMemory(string persistentKey) { lock (_saveLock) { bool num = _persistedOfflineStartTimes.Remove(persistentKey); bool flag = _persistedOfflineEntityNames.Remove(persistentKey); return num || flag; } } public static bool TryGetOfflineStartTime(string persistentKey, out DateTime offlineStartTimeUtc) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) offlineStartTimeUtc = default(DateTime); if (string.IsNullOrEmpty(persistentKey)) { return false; } if (!_dataLoadedFromDisk && Plugin.SystemsInitialized && VWorld.IsServerWorldReady()) { LoadOfflineStatesFromDisk(VWorld.EntityManager); } lock (_saveLock) { return _persistedOfflineStartTimes.TryGetValue(persistentKey, out offlineStartTimeUtc); } } public static void HandleUserDisconnected(EntityManager entityManager, Entity disconnectedUserEntity) { //IL_001c: 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_002b: 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) //IL_009b: 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_00af: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.SystemsInitialized) { return; } ConfigEntry enableOfflineRaidProtection = OfflineRaidProtectionConfig.EnableOfflineRaidProtection; if (enableOfflineRaidProtection == null || !enableOfflineRaidProtection.Value || disconnectedUserEntity == Entity.Null || !((EntityManager)(ref entityManager)).Exists(disconnectedUserEntity)) { return; } if (!OwnerIdentityHelper.TryResolveFromUserEntity(entityManager, disconnectedUserEntity, out var owner, out var error)) { LoggingHelper.Debug("[OfflineGraceService] Failed to resolve disconnected owner: " + error); return; } string characterName = owner.CharacterName; string text = ((!string.IsNullOrEmpty(owner.PersistentKey)) ? owner.PersistentKey : owner.UserKey); string userKey = owner.UserKey; string contextualName = owner.ContextualName; bool flag = owner.IsClan && !string.IsNullOrEmpty(owner.PersistentKey) && owner.ClanEntity != Entity.Null && ((EntityManager)(ref entityManager)).Exists(owner.ClanEntity); HashSet foundShards; string reason; if (string.IsNullOrEmpty(text)) { LoggingHelper.Debug("[OfflineGraceService] Skipping disconnect handling for '" + characterName + "' because owner key could not be resolved."); } else if (ShardConfig.DisableOrpForShardHolders.Value && UserHelper.TryGetShardPrefabsForUserOrClan(entityManager, disconnectedUserEntity, out foundShards, out reason)) { LoggingHelper.Debug($"[ShardVulnerability] {reason} | Flagging '{contextualName}' as vulnerable, latched by '{characterName}'."); int maxCopiesForThisShard = ShardConfig.MaxAllowedShardsPerType?.Value ?? 1; foreach (PrefabGUID item in foundShards) { PrefabGUID current = item; ShardVulnerabilityService.SetVulnerable(text, ((PrefabGUID)(ref current)).GuidHash, userKey, contextualName, maxCopiesForThisShard, deferSave: true); } ShardVulnerabilityService.Flush(); } else if (flag) { ShardVulnerabilityService.ClearAllShardsForOwnerIfLatchedBy(text, userKey); if (ShardVulnerabilityService.IsVulnerable(text)) { LoggingHelper.Debug("[OfflineGraceService] Clan '" + contextualName + "' still has an active shard vulnerability from another member. Skipping ORP."); } else if (!UserHelper.IsAnyClanMemberOnline(entityManager, owner.ClanEntity, disconnectedUserEntity)) { LoggingHelper.Debug("[OfflineGraceService] All members offline for Clan '" + contextualName + "'. Applying ORP."); MarkAsOffline(text, DateTime.UtcNow, contextualName + " (last online: " + characterName + ")"); } else { LoggingHelper.Debug("[OfflineGraceService] Clan '" + contextualName + "' still has members online. No ORP applied yet."); } } else { ShardVulnerabilityService.ClearAllForOwner(text); LoggingHelper.Debug("[OfflineGraceService] Solo player '" + characterName + "' offline. Applying ORP."); MarkAsOffline(text, DateTime.UtcNow, characterName); } } public unsafe static void HandleClanMemberDeparted(EntityManager entityManager, Entity userWhoLeft, Entity clanThatWasLeft, FixedString64Bytes userWhoLeftCharacterNameFs) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_005d: 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_0061: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) string text = ((object)(*(FixedString64Bytes*)(&userWhoLeftCharacterNameFs))/*cast due to .constrained prefix*/).ToString(); if (!Plugin.SystemsInitialized) { return; } ConfigEntry enableOfflineRaidProtection = OfflineRaidProtectionConfig.EnableOfflineRaidProtection; if (enableOfflineRaidProtection != null && enableOfflineRaidProtection.Value && !(clanThatWasLeft == Entity.Null) && ((EntityManager)(ref entityManager)).Exists(clanThatWasLeft) && ((EntityManager)(ref entityManager)).HasComponent(clanThatWasLeft)) { string clanKey = PersistentKeyHelper.GetClanKey(entityManager, clanThatWasLeft); if (!string.IsNullOrEmpty(clanKey) && !UserHelper.IsAnyClanMemberOnline(entityManager, clanThatWasLeft)) { ClanTeam componentData = ((EntityManager)(ref entityManager)).GetComponentData(clanThatWasLeft); string text2 = ((object)(*(FixedString64Bytes*)(&componentData.Name))/*cast due to .constrained prefix*/).ToString(); MarkAsOffline(clanKey, DateTime.UtcNow, text2 + " (after " + text + " departed)"); } } } public static void EstablishInitialGracePeriodsOnBoot(EntityManager entityManager) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.SystemsInitialized || !Plugin.ServerHasJustBooted) { return; } ConfigEntry enableOfflineRaidProtection = OfflineRaidProtectionConfig.EnableOfflineRaidProtection; if (enableOfflineRaidProtection == null || !enableOfflineRaidProtection.Value) { return; } if (!_dataLoadedFromDisk) { LoadOfflineStatesFromDisk(entityManager); } DateTime utcNow = DateTime.UtcNow; HashSet hashSet = new HashSet(); int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; bool flag = false; HashSet verifiedConnectedOwnerKeysAtLastSave = PlayerRegistryService.GetVerifiedConnectedOwnerKeysAtLastSave(entityManager); foreach (KeyValuePair item in OwnershipCacheService.GetHeartToOwnerCacheView().ToList()) { Entity key = item.Key; Entity value = item.Value; if (key == Entity.Null || value == Entity.Null || !((EntityManager)(ref entityManager)).Exists(key) || !((EntityManager)(ref entityManager)).Exists(value)) { continue; } if (!OwnerIdentityHelper.TryResolveFromUserEntity(entityManager, value, out var owner, out var error)) { LoggingHelper.Debug("[OfflineGraceService] Boot ORP skipped owner resolution: " + error); } else { if (string.IsNullOrEmpty(owner.PersistentKey) || !hashSet.Add(owner.PersistentKey)) { continue; } if (ShardConfig.DisableOrpForShardHolders.Value && ShardVulnerabilityService.IsVulnerable(owner.PersistentKey)) { if (ClearOfflineStateInMemory(owner.PersistentKey)) { flag = true; } num5++; continue; } bool num6 = OfflineProtectionService.AreAllDefendersActuallyOffline(key, entityManager); bool flag2 = verifiedConnectedOwnerKeysAtLastSave.Contains(owner.PersistentKey); bool flag3 = _persistedOfflineStartTimes.ContainsKey(owner.PersistentKey); if (num6) { if (flag2) { SetOfflineStateInMemory(owner.PersistentKey, utcNow, owner.ContextualName + " (server boot grace)"); PlayerRegistryService.MarkOwnerDisconnected(owner.PersistentKey); num++; flag = true; } else if (!flag3) { SetOfflineStateInMemory(owner.PersistentKey, utcNow, owner.ContextualName + " (server boot initial grace)"); PlayerRegistryService.MarkOwnerDisconnected(owner.PersistentKey); num2++; flag = true; } else { num3++; } } else if (ClearOfflineStateInMemory(owner.PersistentKey)) { num4++; flag = true; } } } if (flag) { SaveTimedOfflineStatesToDiskInternal(); } LoggingHelper.Info($"[OfflineGraceService] Boot ORP grace refresh complete. Restamped {num} previously connected owner(s), initialized {num2} unknown offline owner(s), preserved {num3} existing offline owner(s), cleared {num4} online owner(s), skipped {num5} shard-vulnerable owner(s)."); } } public static class OfflineProtectionService { public readonly struct OfflineProtectionEvaluation { public readonly bool IsProtected; public readonly bool IsInGracePeriod; public readonly bool AllDefendersOffline; public readonly bool CheckedAllDefendersOffline; public readonly string PersistentKey; public readonly string Reason; public OfflineProtectionEvaluation(bool isProtected, bool isInGracePeriod, bool allDefendersOffline, bool checkedAllDefendersOffline, string persistentKey, string reason) { IsProtected = isProtected; IsInGracePeriod = isInGracePeriod; AllDefendersOffline = allDefendersOffline; CheckedAllDefendersOffline = checkedAllDefendersOffline; PersistentKey = persistentKey; Reason = reason; } } public static bool IsHeartCurrentlyOfflineProtected(Entity castleHeartEntity, EntityManager entityManager) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) return EvaluateHeartOfflineProtection(castleHeartEntity, entityManager).IsProtected; } public static OfflineProtectionEvaluation EvaluateHeartOfflineProtection(Entity castleHeartEntity, EntityManager entityManager, string persistentKey = null, DateTime? nowUtc = null, float? configuredGraceMinutes = null, bool? offlineProtectionAllowed = null) { //IL_0013: 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_001c: 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_0026: 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_003e: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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) if (!Plugin.SystemsInitialized) { return NotProtected(persistentKey, "RaidForge systems are not initialized."); } if (entityManager == default(EntityManager) || castleHeartEntity == Entity.Null || !((EntityManager)(ref entityManager)).Exists(castleHeartEntity) || !((EntityManager)(ref entityManager)).HasComponent(castleHeartEntity)) { return NotProtected(persistentKey, "Castle Heart does not exist."); } if (!(offlineProtectionAllowed ?? OfflineRaidProtectionConfig.IsOfflineProtectionAllowedToday())) { return NotProtected(persistentKey, "Offline Raid Protection is disabled or not allowed today."); } CastleHeart componentData = ((EntityManager)(ref entityManager)).GetComponentData(castleHeartEntity); if (((CastleHeart)(ref componentData)).IsSieged()) { return NotProtected(persistentKey, "Castle Heart is already breached/sieged."); } if (IsBaseDecaying(castleHeartEntity, entityManager)) { return NotProtected(persistentKey, "Castle Heart is decaying."); } string persistentKey2 = persistentKey; if (string.IsNullOrWhiteSpace(persistentKey2) && !TryResolvePersistentOwnerKey(castleHeartEntity, entityManager, out persistentKey2, out var error)) { return NotProtected(persistentKey2, error); } if (ShardConfig.DisableOrpForShardHolders.Value && ShardVulnerabilityService.IsVulnerable(persistentKey2)) { return NotProtected(persistentKey2, "Owner is shard-vulnerable."); } if (!OfflineGraceService.TryGetOfflineStartTime(persistentKey2, out var offlineStartTimeUtc)) { return NotProtected(persistentKey2, "No offline timestamp exists."); } DateTime dateTime = nowUtc ?? DateTime.UtcNow; float num = configuredGraceMinutes ?? OfflineRaidProtectionConfig.GracePeriodDurationMinutes?.Value ?? 0f; if (num > 0f && (dateTime - offlineStartTimeUtc).TotalMinutes < (double)num) { bool allDefendersOffline = AreAllDefendersActuallyOffline(castleHeartEntity, entityManager); return new OfflineProtectionEvaluation(isProtected: false, isInGracePeriod: true, allDefendersOffline, checkedAllDefendersOffline: true, persistentKey2, "Offline timestamp exists, but grace has not elapsed."); } if (!AreAllDefendersActuallyOffline(castleHeartEntity, entityManager)) { return new OfflineProtectionEvaluation(isProtected: false, isInGracePeriod: false, allDefendersOffline: false, checkedAllDefendersOffline: true, persistentKey2, "At least one defender is online."); } return new OfflineProtectionEvaluation(isProtected: true, isInGracePeriod: false, allDefendersOffline: true, checkedAllDefendersOffline: true, persistentKey2, "Offline timestamp is past grace and all defenders are offline."); } private static OfflineProtectionEvaluation NotProtected(string persistentKey, string reason) { return new OfflineProtectionEvaluation(isProtected: false, isInGracePeriod: false, allDefendersOffline: false, checkedAllDefendersOffline: false, persistentKey, reason); } private static bool TryResolvePersistentOwnerKey(Entity castleHeartEntity, EntityManager entityManager, out string persistentKey, out string error) { //IL_000a: 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_0023: 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) persistentKey = null; error = string.Empty; if (!OwnershipCacheService.TryGetHeartOwner(castleHeartEntity, out var ownerUserEntity) || ownerUserEntity == Entity.Null || !((EntityManager)(ref entityManager)).Exists(ownerUserEntity)) { error = "Castle Heart owner is not in the ownership cache."; return false; } if (!OwnerIdentityHelper.TryResolveFromUserEntity(entityManager, ownerUserEntity, out var owner, out error)) { return false; } persistentKey = owner.PersistentKey; return !string.IsNullOrWhiteSpace(persistentKey); } public static bool AreAllDefendersActuallyOffline(Entity castleHeartEntity, EntityManager entityManager) { //IL_000b: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_003e: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0061: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.SystemsInitialized) { return false; } if (!((EntityManager)(ref entityManager)).Exists(castleHeartEntity) || !((EntityManager)(ref entityManager)).HasComponent(castleHeartEntity)) { return false; } Entity entity = ((EntityManager)(ref entityManager)).GetComponentData(castleHeartEntity).Owner._Entity; if (!((EntityManager)(ref entityManager)).Exists(entity) || !((EntityManager)(ref entityManager)).HasComponent(entity)) { return false; } User componentData = ((EntityManager)(ref entityManager)).GetComponentData(entity); Entity clanEntity = Entity.Null; OwnershipCacheService.TryGetUserClan(entity, out clanEntity); if (clanEntity != Entity.Null && ((EntityManager)(ref entityManager)).Exists(clanEntity) && ((EntityManager)(ref entityManager)).HasComponent(clanEntity)) { return !UserHelper.IsAnyClanMemberOnline(entityManager, clanEntity); } return !componentData.IsConnected; } public static bool IsBaseDecaying(Entity castleHeartEntity, EntityManager entityManager) { //IL_0002: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) if (!((EntityManager)(ref entityManager)).Exists(castleHeartEntity) || !((EntityManager)(ref entityManager)).HasComponent(castleHeartEntity)) { return true; } CastleHeart componentData = ((EntityManager)(ref entityManager)).GetComponentData(castleHeartEntity); if (componentData.FuelQuantity <= 0 || ((CastleHeart)(ref componentData)).IsDecaying()) { return true; } return false; } } public static class OptInRaidService { private static Dictionary _manualStateTimes = new Dictionary(); private static Dictionary _manualStateNames = new Dictionary(); private static readonly string DataSubfolder = "Data"; private static readonly string OptInSaveFileName = "RaidForge_OptInState.csv"; private static readonly string OptOutSaveFileName = "RaidForge_OptOutState.csv"; private static readonly object _saveLock = new object(); private static bool _dataLoaded = false; private static bool _loadedDefaultOptInMode = false; private static bool DefaultOptInMode => OptInRaidingConfig.UseDefaultOptInMode; private static string GetSaveFilePath() { string text = Path.Combine(Paths.ConfigPath, "RaidForge", DataSubfolder); Directory.CreateDirectory(text); return Path.Combine(text, DefaultOptInMode ? OptOutSaveFileName : OptInSaveFileName); } public static void ResetRuntimeState() { lock (_saveLock) { _manualStateTimes.Clear(); _manualStateNames.Clear(); _dataLoaded = false; _loadedDefaultOptInMode = false; } } public static void ReloadStateFromDisk() { LoadStateFromDisk(forceReload: true); } public static void LoadStateFromDisk(bool forceReload = false) { bool defaultOptInMode = DefaultOptInMode; if (_dataLoaded && !forceReload && _loadedDefaultOptInMode == defaultOptInMode) { return; } lock (_saveLock) { defaultOptInMode = DefaultOptInMode; if (_dataLoaded && !forceReload && _loadedDefaultOptInMode == defaultOptInMode) { return; } string saveFilePath = GetSaveFilePath(); _manualStateTimes.Clear(); _manualStateNames.Clear(); _loadedDefaultOptInMode = defaultOptInMode; if (!File.Exists(saveFilePath)) { _dataLoaded = true; return; } try { foreach (string item in SharedFileIO.ReadAllLinesShared(saveFilePath).Skip(1)) { if (string.IsNullOrWhiteSpace(item)) { continue; } string[] array = DelimitedText.ParseLine(item, ','); if (array.Length < 3) { continue; } string text = array[0]; if (long.TryParse(array[1], out var result)) { string value = array[2]; if (!string.IsNullOrEmpty(text)) { _manualStateTimes[text] = new DateTime(result, DateTimeKind.Utc); _manualStateNames[text] = value; } } } } catch (Exception ex) { LoggingHelper.Error("[OptIn] Failed to load opt-in/opt-out state from disk.", ex); } _dataLoaded = true; } } public static void ProcessAutoOptOut(int lockDurationHours) { EnsureLoadedForCurrentMode(); if (DefaultOptInMode) { return; } List list = new List(); DateTime utcNow = DateTime.UtcNow; TimeSpan timeSpan = TimeSpan.FromHours(lockDurationHours); lock (_saveLock) { if (_manualStateTimes.Count == 0) { return; } foreach (KeyValuePair manualStateTime in _manualStateTimes) { if (utcNow - manualStateTime.Value >= timeSpan) { list.Add(manualStateTime.Key); } } if (list.Count <= 0) { return; } foreach (string item in list) { _manualStateTimes.Remove(item); string value2; string value = (_manualStateNames.TryGetValue(item, out value2) ? value2 : item); _manualStateNames.Remove(item); LoggingHelper.Info($"[OptIn] Auto-opted out '{value}' because their {lockDurationHours}h cooldown expired."); } RaidMapIconService.MarkPersistentStateIconsDirty(); SaveStateToDisk(); } } public static void OptIn(string persistentKey, string contextualName) { if (string.IsNullOrEmpty(persistentKey)) { return; } EnsureLoadedForCurrentMode(); lock (_saveLock) { if (DefaultOptInMode) { _manualStateTimes.Remove(persistentKey); _manualStateNames.Remove(persistentKey); } else { _manualStateTimes[persistentKey] = DateTime.UtcNow; _manualStateNames[persistentKey] = contextualName; } _dataLoaded = true; _loadedDefaultOptInMode = DefaultOptInMode; } RaidMapIconService.MarkPersistentStateIconsDirty(); SaveStateToDisk(); } public static void OptOut(string persistentKey, string contextualName) { if (string.IsNullOrEmpty(persistentKey)) { return; } EnsureLoadedForCurrentMode(); lock (_saveLock) { if (DefaultOptInMode) { _manualStateTimes[persistentKey] = DateTime.UtcNow; _manualStateNames[persistentKey] = contextualName; } else { _manualStateTimes.Remove(persistentKey); _manualStateNames.Remove(persistentKey); } _dataLoaded = true; _loadedDefaultOptInMode = DefaultOptInMode; } RaidMapIconService.MarkPersistentStateIconsDirty(); SaveStateToDisk(); } public static bool IsOptedIn(string persistentKey) { EnsureLoadedForCurrentMode(); if (string.IsNullOrEmpty(persistentKey)) { return false; } lock (_saveLock) { bool flag = _manualStateTimes.ContainsKey(persistentKey); return DefaultOptInMode ? (!flag) : flag; } } public static bool IsManuallyOptedOut(string persistentKey) { EnsureLoadedForCurrentMode(); if (string.IsNullOrEmpty(persistentKey) || !DefaultOptInMode) { return false; } lock (_saveLock) { return _manualStateTimes.ContainsKey(persistentKey); } } public static bool TryGetOptInTime(string persistentKey, out DateTime optInTime) { optInTime = default(DateTime); EnsureLoadedForCurrentMode(); if (string.IsNullOrEmpty(persistentKey)) { return false; } lock (_saveLock) { if (DefaultOptInMode) { if (_manualStateTimes.ContainsKey(persistentKey)) { return false; } optInTime = DateTime.MinValue; return true; } return _manualStateTimes.TryGetValue(persistentKey, out optInTime); } } public static bool TryGetManualStateTime(string persistentKey, out DateTime stateTime) { stateTime = default(DateTime); EnsureLoadedForCurrentMode(); if (string.IsNullOrEmpty(persistentKey)) { return false; } lock (_saveLock) { return _manualStateTimes.TryGetValue(persistentKey, out stateTime); } } private static void EnsureLoadedForCurrentMode() { if (!_dataLoaded || _loadedDefaultOptInMode != DefaultOptInMode) { LoadStateFromDisk(_loadedDefaultOptInMode != DefaultOptInMode); } } private static void SaveStateToDisk() { lock (_saveLock) { string saveFilePath = GetSaveFilePath(); try { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(DefaultOptInMode ? "PersistentKey,OptOutTimestampTicks,ContextualName" : "PersistentKey,OptInTimestampTicks,ContextualName"); foreach (KeyValuePair manualStateTime in _manualStateTimes) { string key = manualStateTime.Key; long ticks = manualStateTime.Value.Ticks; string value2; string value = (_manualStateNames.TryGetValue(key, out value2) ? value2 : "Unknown"); StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(2, 3, stringBuilder2); handler.AppendFormatted(DelimitedText.Escape(key, ',')); handler.AppendLiteral(","); handler.AppendFormatted(ticks); handler.AppendLiteral(","); handler.AppendFormatted(DelimitedText.Escape(value, ',')); stringBuilder2.AppendLine(ref handler); } SharedFileIO.QueueWriteAllTextWithRetry(saveFilePath, stringBuilder.ToString()); } catch (Exception ex) { LoggingHelper.Error("[OptIn] Failed to save opt-in/opt-out state to disk.", ex); } } } } public static class OwnershipCacheService { private static Dictionary _heartToOwnerUserCache = new Dictionary(); private static bool _isHeartCachePopulatedFromInitialScan = false; private static Dictionary _userToClanCache = new Dictionary(); private static bool _isClanCachePopulatedFromInitialScan = false; public static void AddHeartToCache(Entity heartEntity, EntityManager em) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0032: 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_0040: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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) UserOwner val = default(UserOwner); if (!((EntityManager)(ref em)).Exists(heartEntity) || !((EntityManager)(ref em)).TryGetComponentData(heartEntity, ref val)) { return; } Entity entity = val.Owner._Entity; if (entity != Entity.Null && ((EntityManager)(ref em)).Exists(entity)) { _heartToOwnerUserCache[heartEntity] = entity; RaidMapIconService.MarkPersistentStateIconsDirty(); User val2 = default(User); if (((EntityManager)(ref em)).TryGetComponentData(entity, ref val2)) { _userToClanCache[entity] = val2.ClanEntity._Entity; } } } public static int InitializeHeartOwnershipCache(EntityManager entityManager) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_0031: Expected O, but got Unknown //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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_0092: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00b1: Unknown result type (might be due to invalid IL or missing references) if (entityManager == default(EntityManager)) { _isHeartCachePopulatedFromInitialScan = false; return 0; } _heartToOwnerUserCache.Clear(); _isHeartCachePopulatedFromInitialScan = false; EntityQueryDesc val = new EntityQueryDesc(); val.All = Il2CppStructArray.op_Implicit((ComponentType[])(object)new ComponentType[2] { ComponentType.ReadOnly(), ComponentType.ReadOnly() }); EntityQueryDesc val2 = val; EntityQuery val3 = default(EntityQuery); NativeArray val4 = default(NativeArray); int num = 0; try { val3 = ((EntityManager)(ref entityManager)).CreateEntityQuery((EntityQueryDesc[])(object)new EntityQueryDesc[1] { val2 }); val4 = ((EntityQuery)(ref val3)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)3)); Enumerator enumerator = val4.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; AddHeartToCache(current, entityManager); if (_heartToOwnerUserCache.ContainsKey(current)) { num++; } } } catch (Exception ex) { _isHeartCachePopulatedFromInitialScan = false; LoggingHelper.Error("[OwnershipCache] Failed while initializing heart ownership cache.", ex); return num; } finally { if (val4.IsCreated) { val4.Dispose(); } if (val3 != default(EntityQuery)) { ((EntityQuery)(ref val3)).Dispose(); } } _isHeartCachePopulatedFromInitialScan = true; return num; } public static int InitializeUserToClanCache(EntityManager entityManager) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_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_009b: Unknown result type (might be due to invalid IL or missing references) if (entityManager == default(EntityManager)) { _isClanCachePopulatedFromInitialScan = false; return 0; } _userToClanCache.Clear(); _isClanCachePopulatedFromInitialScan = false; EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); int num = 0; try { val = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)3)); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref entityManager)).Exists(current)) { User componentData = ((EntityManager)(ref entityManager)).GetComponentData(current); _userToClanCache[current] = componentData.ClanEntity._Entity; num++; } } } catch (Exception ex) { _isClanCachePopulatedFromInitialScan = false; LoggingHelper.Error("[OwnershipCache] Failed while initializing user clan cache.", ex); return num; } finally { if (val2.IsCreated) { val2.Dispose(); } if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } } _isClanCachePopulatedFromInitialScan = true; return num; } public static bool IsInitialScanAttemptedAndConsideredPopulated() { if (_isHeartCachePopulatedFromInitialScan) { return _isClanCachePopulatedFromInitialScan; } return false; } public static bool UpdateUserClan(Entity userEntity, Entity clanEntity, EntityManager em) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_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_0020: 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_002b: 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_0039: 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_0066: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (em == default(EntityManager) || userEntity == Entity.Null || !((EntityManager)(ref em)).Exists(userEntity)) { return false; } if (clanEntity != Entity.Null && !((EntityManager)(ref em)).Exists(clanEntity)) { clanEntity = Entity.Null; } if (!_userToClanCache.TryGetValue(userEntity, out var value) || value != clanEntity) { _userToClanCache[userEntity] = clanEntity; RaidMapIconService.MarkPersistentStateIconsDirty(); return true; } return false; } public static bool TryGetUserClan(Entity userEntity, out Entity clanEntity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_001f: Unknown result type (might be due to invalid IL or missing references) clanEntity = Entity.Null; if (userEntity == Entity.Null) { return false; } return _userToClanCache.TryGetValue(userEntity, out clanEntity); } public static bool TryGetHeartOwner(Entity heartEntity, out Entity ownerUserEntity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_001f: Unknown result type (might be due to invalid IL or missing references) ownerUserEntity = Entity.Null; if (heartEntity == Entity.Null) { return false; } return _heartToOwnerUserCache.TryGetValue(heartEntity, out ownerUserEntity); } public static void UpdateHeartOwner(Entity heartEntity, Entity ownerUserEntity, EntityManager em) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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) if (em == default(EntityManager) || heartEntity == Entity.Null || !((EntityManager)(ref em)).Exists(heartEntity)) { return; } if (ownerUserEntity != Entity.Null && !((EntityManager)(ref em)).Exists(ownerUserEntity)) { ownerUserEntity = Entity.Null; } Entity value; if (ownerUserEntity == Entity.Null) { if (_heartToOwnerUserCache.Remove(heartEntity)) { RaidMapIconService.MarkPersistentStateIconsDirty(); } } else if (!_heartToOwnerUserCache.TryGetValue(heartEntity, out value) || value != ownerUserEntity) { _heartToOwnerUserCache[heartEntity] = ownerUserEntity; RaidMapIconService.MarkPersistentStateIconsDirty(); } } public static void RemoveHeart(Entity heartEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!(heartEntity == Entity.Null) && _heartToOwnerUserCache.Remove(heartEntity)) { RaidMapIconService.MarkPersistentStateIconsDirty(); } } public static void HandlePlayerConnected(Entity userEntity, EntityManager entityManager) { //IL_000a: 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_001e: 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_0026: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (IsInitialScanAttemptedAndConsideredPopulated() && ((EntityManager)(ref entityManager)).Exists(userEntity) && ((EntityManager)(ref entityManager)).HasComponent(userEntity)) { User componentData = ((EntityManager)(ref entityManager)).GetComponentData(userEntity); UpdateUserClan(userEntity, componentData.ClanEntity._Entity, entityManager); } } public static IReadOnlyDictionary GetHeartToOwnerCacheView() { return _heartToOwnerUserCache; } public static IReadOnlyDictionary GetUserToClanCacheView() { return _userToClanCache; } public static void ClearAllCaches() { _heartToOwnerUserCache.Clear(); _userToClanCache.Clear(); _isHeartCachePopulatedFromInitialScan = false; _isClanCachePopulatedFromInitialScan = false; RaidMapIconService.MarkPersistentStateIconsDirty(); } } public sealed class PlayerRegistryEntry { public string UserKey { get; set; } public ulong PlatformId { get; set; } public string CharacterName { get; set; } public string OwnerPersistentKey { get; set; } public string OwnerType { get; set; } public string ClanName { get; set; } public long LastSeenUtcTicks { get; set; } public bool IsConnected { get; set; } } public static class PlayerRegistryService { private static readonly object RegistryLock = new object(); private static readonly Dictionary EntriesByUserKey = new Dictionary(); private static bool _loadedFromDisk = false; private static bool _dirty = false; private static DateTime _nextLockedRegistryWarningUtc = DateTime.MinValue; private const string DataSubfolder = "Data"; private const string SaveFileName = "RaidForge_PlayerRegistry.csv"; private const string PendingSaveFileName = "RaidForge_PlayerRegistry.pending.csv"; private static string GetSaveFilePath() { string text = Path.Combine(Paths.ConfigPath, "RaidForge", "Data"); Directory.CreateDirectory(text); return Path.Combine(text, "RaidForge_PlayerRegistry.csv"); } private static string GetPendingSaveFilePath() { string text = Path.Combine(Paths.ConfigPath, "RaidForge", "Data"); Directory.CreateDirectory(text); return Path.Combine(text, "RaidForge_PlayerRegistry.pending.csv"); } public static void ResetRuntimeState() { lock (RegistryLock) { EntriesByUserKey.Clear(); _loadedFromDisk = false; _dirty = false; _nextLockedRegistryWarningUtc = DateTime.MinValue; } } public static void RefreshFromWorld(EntityManager em) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0169: 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_0172: 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_0045: 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_007c: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (em == default(EntityManager)) { return; } LoadFromDisk(); EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); int num = 0; int num2 = 0; try { val = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { return; } val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); lock (RegistryLock) { Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; num++; if (TryBuildEntry(em, current, out var entry) && UpsertEntryInMemory(entry)) { num2++; } } } ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Info($"[PlayerRegistry] World refresh scanned {num} user entr{((num == 1) ? "y" : "ies")}; changed {num2}."); } } catch (Exception ex) { LoggingHelper.Error("[PlayerRegistry] Failed to refresh player registry from world.", ex); } finally { if (val2.IsCreated) { val2.Dispose(); } if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } } } public static void UpsertUser(EntityManager em, Entity userEntity, bool? connectedOverride = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_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_0020: 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_002f: Unknown result type (might be due to invalid IL or missing references) if (em == default(EntityManager) || userEntity == Entity.Null || !((EntityManager)(ref em)).Exists(userEntity)) { return; } LoadFromDisk(); if (!TryBuildEntry(em, userEntity, out var entry, connectedOverride)) { return; } lock (RegistryLock) { UpsertEntryInMemory(entry); } } public static HashSet GetVerifiedConnectedOwnerKeysAtLastSave(EntityManager em) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) LoadFromDisk(); Dictionary dictionary = BuildCurrentOwnerByUserKey(em); HashSet hashSet = new HashSet(); lock (RegistryLock) { foreach (PlayerRegistryEntry value2 in EntriesByUserKey.Values) { if (value2.IsConnected && !string.IsNullOrEmpty(value2.OwnerPersistentKey) && dictionary.TryGetValue(value2.UserKey, out var value) && !(value != value2.OwnerPersistentKey)) { hashSet.Add(value2.OwnerPersistentKey); } } return hashSet; } } public static bool TryGetEntryByUserKey(string userKey, out PlayerRegistryEntry entry) { entry = null; if (string.IsNullOrWhiteSpace(userKey)) { return false; } LoadFromDisk(); lock (RegistryLock) { if (!EntriesByUserKey.TryGetValue(userKey, out var value)) { return false; } entry = CloneEntry(value); return true; } } public static List FindEntriesByCharacterName(string characterName) { LoadFromDisk(); if (string.IsNullOrWhiteSpace(characterName)) { return new List(); } string normalizedName = characterName.Trim(); lock (RegistryLock) { List list = EntriesByUserKey.Values.Where((PlayerRegistryEntry entry) => string.Equals(entry.CharacterName, normalizedName, StringComparison.OrdinalIgnoreCase)).Select(CloneEntry).OrderBy((PlayerRegistryEntry entry) => entry.CharacterName, StringComparer.OrdinalIgnoreCase) .ToList(); if (list.Count > 0) { return list; } return EntriesByUserKey.Values.Where((PlayerRegistryEntry entry) => (entry.CharacterName ?? string.Empty).IndexOf(normalizedName, StringComparison.OrdinalIgnoreCase) >= 0).Select(CloneEntry).OrderBy((PlayerRegistryEntry entry) => entry.CharacterName, StringComparer.OrdinalIgnoreCase) .Take(8) .ToList(); } } public static void MarkOwnerDisconnected(string ownerPersistentKey) { if (string.IsNullOrEmpty(ownerPersistentKey)) { return; } LoadFromDisk(); long ticks = DateTime.UtcNow.Ticks; lock (RegistryLock) { foreach (PlayerRegistryEntry item in EntriesByUserKey.Values.Where((PlayerRegistryEntry entry) => entry.OwnerPersistentKey == ownerPersistentKey)) { if (item.IsConnected) { item.IsConnected = false; item.LastSeenUtcTicks = ticks; _dirty = true; } } } } private static bool TryBuildEntry(EntityManager em, Entity userEntity, out PlayerRegistryEntry entry, bool? connectedOverride = null) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: 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) entry = null; if (!OwnerIdentityHelper.TryResolveFromUserEntity(em, userEntity, out var owner, out var _)) { return false; } entry = new PlayerRegistryEntry { UserKey = owner.UserKey, PlatformId = owner.PlatformId, CharacterName = owner.CharacterName, OwnerPersistentKey = owner.PersistentKey, OwnerType = (owner.IsClan ? "Clan" : "Player"), ClanName = (owner.ClanName ?? string.Empty), LastSeenUtcTicks = DateTime.UtcNow.Ticks, IsConnected = (connectedOverride ?? owner.UserData.IsConnected) }; return !string.IsNullOrEmpty(entry.UserKey); } private static Dictionary BuildCurrentOwnerByUserKey(EntityManager em) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); try { val = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { return dictionary; } val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref em)).Exists(current) && ((EntityManager)(ref em)).HasComponent(current) && OwnerIdentityHelper.TryResolveFromUserEntity(em, current, out var owner, out var _) && !string.IsNullOrEmpty(owner.UserKey) && !string.IsNullOrEmpty(owner.PersistentKey)) { dictionary[owner.UserKey] = owner.PersistentKey; } } return dictionary; } finally { if (val2.IsCreated) { val2.Dispose(); } if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } } } public static void SaveIfDirty() { bool dirty; lock (RegistryLock) { dirty = _dirty; } if (dirty) { SaveToDisk(); } } private static bool UpsertEntryInMemory(PlayerRegistryEntry entry) { if (entry == null || string.IsNullOrEmpty(entry.UserKey)) { return false; } if (EntriesByUserKey.TryGetValue(entry.UserKey, out var value) && EntryMateriallyEquals(value, entry)) { return false; } EntriesByUserKey[entry.UserKey] = entry; _dirty = true; return true; } private static bool EntryMateriallyEquals(PlayerRegistryEntry left, PlayerRegistryEntry right) { if (left.PlatformId == right.PlatformId && left.CharacterName == right.CharacterName && left.OwnerPersistentKey == right.OwnerPersistentKey && left.OwnerType == right.OwnerType && left.ClanName == right.ClanName) { return left.IsConnected == right.IsConnected; } return false; } private static PlayerRegistryEntry CloneEntry(PlayerRegistryEntry entry) { if (entry == null) { return null; } return new PlayerRegistryEntry { UserKey = entry.UserKey, PlatformId = entry.PlatformId, CharacterName = entry.CharacterName, OwnerPersistentKey = entry.OwnerPersistentKey, OwnerType = entry.OwnerType, ClanName = entry.ClanName, LastSeenUtcTicks = entry.LastSeenUtcTicks, IsConnected = entry.IsConnected }; } private static void LoadFromDisk() { if (_loadedFromDisk) { return; } string saveFilePath = GetSaveFilePath(); string pendingSaveFilePath = GetPendingSaveFilePath(); string newestExistingRegistryFile = GetNewestExistingRegistryFile(saveFilePath, pendingSaveFilePath); if (string.IsNullOrEmpty(newestExistingRegistryFile)) { _loadedFromDisk = true; return; } try { string[] source = SharedFileIO.ReadAllLinesShared(newestExistingRegistryFile); lock (RegistryLock) { foreach (string item in source.Skip(1)) { if (string.IsNullOrWhiteSpace(item)) { continue; } string[] array = DelimitedText.ParseLine(item, ','); if (array.Length >= 8 && ulong.TryParse(array[1], out var result) && long.TryParse(array[6], out var result2) && bool.TryParse(array[7], out var result3)) { string text = array[0].Trim(); if (!string.IsNullOrEmpty(text)) { EntriesByUserKey[text] = new PlayerRegistryEntry { UserKey = text, PlatformId = result, CharacterName = array[2].Trim(), OwnerPersistentKey = array[3].Trim(), OwnerType = array[4].Trim(), ClanName = array[5].Trim(), LastSeenUtcTicks = result2, IsConnected = result3 }; } } } _loadedFromDisk = true; } } catch (Exception ex) { LoggingHelper.Error("[PlayerRegistry] Failed to load player registry from disk.", ex); } } private static void SaveToDisk() { string content = BuildRegistryCsv(); try { SharedFileIO.WriteAllTextWithRetry(GetSaveFilePath(), content); TryDeletePendingFile(); lock (RegistryLock) { _loadedFromDisk = true; _dirty = false; } } catch (IOException ex) { if (WritePendingRegistrySnapshot(content)) { LogRegistryLockWarning("[PlayerRegistry] Main registry CSV is locked. Wrote pending registry snapshot and will retry later."); } else { LogRegistryLockWarning("[PlayerRegistry] Main registry CSV is locked and pending snapshot could not be written. Registry changes remain queued.", ex); } } catch (Exception ex2) { LoggingHelper.Warning("[PlayerRegistry] Failed to save player registry to disk. Registry changes remain queued.", ex2); } } private static string BuildRegistryCsv() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("UserKey,PlatformId,CharacterName,OwnerPersistentKey,OwnerType,ClanName,LastSeenUtcTicks,IsConnected"); List list; lock (RegistryLock) { list = EntriesByUserKey.Values.OrderBy((PlayerRegistryEntry entry) => entry.CharacterName, StringComparer.OrdinalIgnoreCase).ToList(); } foreach (PlayerRegistryEntry item in list) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(7, 8, stringBuilder2); handler.AppendFormatted(DelimitedText.Escape(item.UserKey, ',')); handler.AppendLiteral(","); handler.AppendFormatted(item.PlatformId); handler.AppendLiteral(","); handler.AppendFormatted(DelimitedText.Escape(item.CharacterName ?? string.Empty, ',')); handler.AppendLiteral(","); handler.AppendFormatted(DelimitedText.Escape(item.OwnerPersistentKey ?? string.Empty, ',')); handler.AppendLiteral(","); handler.AppendFormatted(DelimitedText.Escape(item.OwnerType ?? string.Empty, ',')); handler.AppendLiteral(","); handler.AppendFormatted(DelimitedText.Escape(item.ClanName ?? string.Empty, ',')); handler.AppendLiteral(","); handler.AppendFormatted(item.LastSeenUtcTicks); handler.AppendLiteral(","); handler.AppendFormatted(item.IsConnected); stringBuilder2.AppendLine(ref handler); } return stringBuilder.ToString(); } private static string GetNewestExistingRegistryFile(string mainFilePath, string pendingFilePath) { bool flag = File.Exists(mainFilePath); bool flag2 = File.Exists(pendingFilePath); if (!flag && !flag2) { return null; } if (!flag) { return pendingFilePath; } if (!flag2) { return mainFilePath; } if (!(File.GetLastWriteTimeUtc(pendingFilePath) > File.GetLastWriteTimeUtc(mainFilePath))) { return mainFilePath; } return pendingFilePath; } private static bool WritePendingRegistrySnapshot(string content) { try { SharedFileIO.WriteAllTextWithRetry(GetPendingSaveFilePath(), content); lock (RegistryLock) { _loadedFromDisk = true; _dirty = true; } return true; } catch (Exception ex) { LoggingHelper.Debug("[PlayerRegistry] Pending registry write failed: " + ex.Message); return false; } } private static void LogRegistryLockWarning(string message, Exception ex = null) { DateTime utcNow = DateTime.UtcNow; if (utcNow < _nextLockedRegistryWarningUtc) { LoggingHelper.Debug(message + " " + ex?.Message); return; } _nextLockedRegistryWarningUtc = utcNow.AddMinutes(1.0); LoggingHelper.Warning(message, ex); } private static void TryDeletePendingFile() { try { string pendingSaveFilePath = GetPendingSaveFilePath(); if (File.Exists(pendingSaveFilePath)) { File.Delete(pendingSaveFilePath); } } catch (Exception ex) { LoggingHelper.Debug("[PlayerRegistry] Could not delete pending registry file: " + ex.Message); } } } public sealed class PurchasedOrpEntry { public string PersistentKey { get; set; } public string ContextualName { get; set; } public int RemainingRaidDays { get; set; } public DateTime LastProcessedLocalDate { get; set; } public DateTime LastPurchaseUtc { get; set; } } public static class PurchasedOrpService { private const string DataSubfolder = "Data"; private const string SaveFileName = "RaidForge_PurchasedOrp.csv"; private const string DateFormat = "yyyy-MM-dd"; private static readonly Dictionary _entriesByKey = new Dictionary(); private static readonly object _saveLock = new object(); private static bool _dataLoaded; private static DateTime _lastConsumptionProcessedDate = DateTime.MinValue; private static string GetSaveFilePath() { string text = Path.Combine(Paths.ConfigPath, "RaidForge", "Data"); Directory.CreateDirectory(text); return Path.Combine(text, "RaidForge_PurchasedOrp.csv"); } public static DateTime GetCurrentRaidDate() { return RaidConfig.GetRaidScheduleNow().Date; } public static void ResetRuntimeState() { lock (_saveLock) { _entriesByKey.Clear(); _dataLoaded = false; _lastConsumptionProcessedDate = DateTime.MinValue; } } public static void ReloadStateFromDisk() { LoadStateFromDisk(forceReload: true); } public static void LoadStateFromDisk(bool forceReload = false) { if (_dataLoaded && !forceReload) { return; } lock (_saveLock) { if (_dataLoaded && !forceReload) { return; } _entriesByKey.Clear(); string saveFilePath = GetSaveFilePath(); if (!File.Exists(saveFilePath)) { _dataLoaded = true; return; } try { foreach (string item in SharedFileIO.ReadAllLinesShared(saveFilePath).Skip(1)) { if (string.IsNullOrWhiteSpace(item)) { continue; } string[] array = DelimitedText.ParseLine(item, ','); if (array.Length < 4) { continue; } string text = array[0].Trim(); if (!string.IsNullOrWhiteSpace(text)) { PurchasedOrpEntry purchasedOrpEntry = TryLoadCurrentFormat(array); if (purchasedOrpEntry == null) { purchasedOrpEntry = TryLoadLegacyDateFormat(array); } if (purchasedOrpEntry != null && purchasedOrpEntry.RemainingRaidDays > 0) { purchasedOrpEntry.PersistentKey = text; _entriesByKey[text] = purchasedOrpEntry; } } } } catch (Exception ex) { LoggingHelper.Error("[PurchasedORP] Failed to load purchased ORP state from disk.", ex); } _dataLoaded = true; ProcessDueRaidDayConsumptionInternal(GetCurrentRaidDate(), saveIfChanged: true, force: true); } } public static void ProcessDueRaidDayConsumption() { ProcessDueRaidDayConsumption(force: false); } public static void ProcessDueRaidDayConsumption(bool force) { EnsureLoaded(); lock (_saveLock) { ProcessDueRaidDayConsumptionInternal(GetCurrentRaidDate(), saveIfChanged: true, force); } } public static bool HasProtectionForToday(string persistentKey) { if (string.IsNullOrWhiteSpace(persistentKey) || !IsRaidDate(GetCurrentRaidDate())) { return false; } EnsureLoaded(); lock (_saveLock) { ProcessDueRaidDayConsumptionInternal(GetCurrentRaidDate(), saveIfChanged: true); PurchasedOrpEntry value; return _entriesByKey.TryGetValue(persistentKey, out value) && value.RemainingRaidDays > 0; } } public static int GetRemainingRaidDays(string persistentKey) { if (string.IsNullOrWhiteSpace(persistentKey)) { return 0; } EnsureLoaded(); lock (_saveLock) { ProcessDueRaidDayConsumptionInternal(GetCurrentRaidDate(), saveIfChanged: true); PurchasedOrpEntry value; return _entriesByKey.TryGetValue(persistentKey, out value) ? Math.Max(0, value.RemainingRaidDays) : 0; } } public static bool TryGetEntry(string persistentKey, out PurchasedOrpEntry entry) { entry = null; if (string.IsNullOrWhiteSpace(persistentKey)) { return false; } EnsureLoaded(); lock (_saveLock) { ProcessDueRaidDayConsumptionInternal(GetCurrentRaidDate(), saveIfChanged: true); if (!_entriesByKey.TryGetValue(persistentKey, out var value)) { return false; } entry = new PurchasedOrpEntry { PersistentKey = value.PersistentKey, ContextualName = value.ContextualName, RemainingRaidDays = value.RemainingRaidDays, LastProcessedLocalDate = value.LastProcessedLocalDate, LastPurchaseUtc = value.LastPurchaseUtc }; return true; } } public static void AddRaidDays(string persistentKey, string contextualName, int raidDays) { if (string.IsNullOrWhiteSpace(persistentKey) || raidDays <= 0) { return; } EnsureLoaded(); checked { lock (_saveLock) { DateTime currentRaidDate = GetCurrentRaidDate(); ProcessDueRaidDayConsumptionInternal(currentRaidDate, saveIfChanged: false); if (!_entriesByKey.TryGetValue(persistentKey, out var value)) { value = new PurchasedOrpEntry { PersistentKey = persistentKey, LastProcessedLocalDate = currentRaidDate }; _entriesByKey[persistentKey] = value; } value.ContextualName = contextualName; value.RemainingRaidDays += raidDays; value.LastPurchaseUtc = DateTime.UtcNow; if (value.LastProcessedLocalDate == default(DateTime)) { value.LastProcessedLocalDate = currentRaidDate; } SaveStateToDiskInternal(); } } } public static int RemoveRaidDays(string persistentKey, int raidDays) { if (string.IsNullOrWhiteSpace(persistentKey) || raidDays <= 0) { return 0; } EnsureLoaded(); lock (_saveLock) { ProcessDueRaidDayConsumptionInternal(GetCurrentRaidDate(), saveIfChanged: false); if (!_entriesByKey.TryGetValue(persistentKey, out var value)) { return 0; } int num = Math.Min(raidDays, Math.Max(0, value.RemainingRaidDays)); value.RemainingRaidDays -= num; if (value.RemainingRaidDays <= 0) { _entriesByKey.Remove(persistentKey); } SaveStateToDiskInternal(); return num; } } public static bool IsRaidDate(DateTime date) { List schedule = RaidConfig.Schedule; if (schedule == null || schedule.Count == 0) { return false; } DayOfWeek dayOfWeek = date.Date.DayOfWeek; foreach (RaidScheduleEntry item in schedule) { if (item.Day == dayOfWeek) { return true; } DayOfWeek dayOfWeek2 = (DayOfWeek)((int)(item.Day + 1) % 7); if (item.SpansMidnight && item.EndTime != TimeSpan.Zero && dayOfWeek2 == dayOfWeek) { return true; } } return false; } private static PurchasedOrpEntry TryLoadCurrentFormat(string[] parts) { if (!int.TryParse(parts[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return null; } DateTime lastProcessedLocalDate = GetCurrentRaidDate(); if (parts.Length >= 4 && DateTime.TryParseExact(parts[3].Trim(), "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var result2)) { lastProcessedLocalDate = result2.Date; } DateTime lastPurchaseUtc = DateTime.MinValue; if (parts.Length >= 5 && long.TryParse(parts[4], out var result3)) { lastPurchaseUtc = new DateTime(result3, DateTimeKind.Utc); } return new PurchasedOrpEntry { ContextualName = parts[1].Trim(), RemainingRaidDays = Math.Max(0, result), LastProcessedLocalDate = lastProcessedLocalDate, LastPurchaseUtc = lastPurchaseUtc }; } private static PurchasedOrpEntry TryLoadLegacyDateFormat(string[] parts) { int num = 0; string[] array = parts[2].Split('|'); for (int i = 0; i < array.Length; i++) { if (DateTime.TryParseExact(array[i].Trim(), "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var result) && result.Date >= GetCurrentRaidDate()) { num++; } } if (num <= 0) { return null; } DateTime lastPurchaseUtc = DateTime.MinValue; if (parts.Length >= 4 && long.TryParse(parts[3], out var result2)) { lastPurchaseUtc = new DateTime(result2, DateTimeKind.Utc); } return new PurchasedOrpEntry { ContextualName = parts[1].Trim(), RemainingRaidDays = num, LastProcessedLocalDate = GetCurrentRaidDate(), LastPurchaseUtc = lastPurchaseUtc }; } private static void EnsureLoaded() { if (!_dataLoaded) { LoadStateFromDisk(); } } private static void ProcessDueRaidDayConsumptionInternal(DateTime today, bool saveIfChanged, bool force = false) { today = today.Date; if (!force && _lastConsumptionProcessedDate >= today) { return; } bool flag = false; DateTime dateTime = today.AddDays(-1.0); foreach (string item in _entriesByKey.Keys.ToList()) { PurchasedOrpEntry purchasedOrpEntry = _entriesByKey[item]; if (purchasedOrpEntry.LastProcessedLocalDate == default(DateTime)) { purchasedOrpEntry.LastProcessedLocalDate = today; flag = true; continue; } DateTime dateTime2 = purchasedOrpEntry.LastProcessedLocalDate.Date.AddDays(1.0); while (dateTime2 <= dateTime && purchasedOrpEntry.RemainingRaidDays > 0) { if (IsRaidDate(dateTime2)) { purchasedOrpEntry.RemainingRaidDays--; flag = true; } dateTime2 = dateTime2.AddDays(1.0); } if (purchasedOrpEntry.LastProcessedLocalDate.Date < today) { purchasedOrpEntry.LastProcessedLocalDate = today; flag = true; } if (purchasedOrpEntry.RemainingRaidDays <= 0) { _entriesByKey.Remove(item); flag = true; } } if (flag && saveIfChanged) { SaveStateToDiskInternal(); } _lastConsumptionProcessedDate = today; } private static void SaveStateToDiskInternal() { string saveFilePath = GetSaveFilePath(); try { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("PersistentKey,ContextualName,RemainingRaidDays,LastProcessedLocalDate,LastPurchaseUtcTicks"); foreach (PurchasedOrpEntry item in _entriesByKey.Values.OrderBy((PurchasedOrpEntry e) => e.ContextualName, StringComparer.OrdinalIgnoreCase)) { if (item.RemainingRaidDays > 0) { StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(4, 5, stringBuilder2); handler.AppendFormatted(DelimitedText.Escape(item.PersistentKey, ',')); handler.AppendLiteral(","); handler.AppendFormatted(DelimitedText.Escape(item.ContextualName ?? "Unknown", ',')); handler.AppendLiteral(","); handler.AppendFormatted(item.RemainingRaidDays.ToString(CultureInfo.InvariantCulture)); handler.AppendLiteral(","); handler.AppendFormatted(item.LastProcessedLocalDate.Date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)); handler.AppendLiteral(","); handler.AppendFormatted(item.LastPurchaseUtc.Ticks); stringBuilder2.AppendLine(ref handler); } } SharedFileIO.QueueWriteAllTextWithRetry(saveFilePath, stringBuilder.ToString()); } catch (Exception ex) { LoggingHelper.Error("[PurchasedORP] Failed to save purchased ORP state to disk.", ex); } } } public static class RaidInterferenceService { private static EntityManager _entityManager; private static DebugEventsSystem _debugEventsSystem_instance; private static ServerScriptMapper _serverScriptMapper_instance; private static ServerGameManager _serverGameManager_instance; private static bool _serverGameManager_found = false; private static readonly Dictionary _activeSieges = new Dictionary(); private static bool _isServiceLogicInitialized = false; private static Dictionary _lastDebuffMessageTimes = new Dictionary(); public static void Initialize() { _isServiceLogicInitialized = true; } private static bool EnsureSystemsInitialized() { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (!_isServiceLogicInitialized) { return false; } World server = VWorld.Server; if (server == null || !server.IsCreated) { return false; } if (_entityManager == default(EntityManager)) { _entityManager = VWorld.EntityManager; } if (_entityManager != default(EntityManager) && _debugEventsSystem_instance != null && _serverScriptMapper_instance != null && _serverGameManager_found) { return true; } if (_debugEventsSystem_instance == null) { try { _debugEventsSystem_instance = server.GetExistingSystemManaged(); } catch (Exception ex) { _debugEventsSystem_instance = null; LoggingHelper.Debug("[RaidInterference] DebugEventsSystem not ready: " + ex.Message); } } if (_serverScriptMapper_instance == null) { try { _serverScriptMapper_instance = server.GetExistingSystemManaged(); } catch (Exception ex2) { _serverScriptMapper_instance = null; LoggingHelper.Debug("[RaidInterference] ServerScriptMapper not ready: " + ex2.Message); } } if (_serverScriptMapper_instance != null) { try { _serverGameManager_instance = _serverScriptMapper_instance.GetServerGameManager(); _serverGameManager_found = true; } catch (Exception ex3) { _serverGameManager_found = false; LoggingHelper.Debug("[RaidInterference] ServerGameManager not ready: " + ex3.Message); } } else { _serverGameManager_found = false; } if (_entityManager != default(EntityManager) && _debugEventsSystem_instance != null) { return _serverGameManager_found; } return false; } public static void StartSiege(Entity castleHeartEntity, Entity attackerUserEntity) { //IL_001d: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0059: 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_0064: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_008e: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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_010f: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) if (!RaidInterferenceConfig.EnableRaidInterference.Value || !_isServiceLogicInitialized || !EnsureSystemsInitialized()) { return; } try { if (ShouldSkipInterference(castleHeartEntity)) { EndSiege(castleHeartEntity); return; } Entity val = Entity.Null; Entity val2 = Entity.Null; if (!((EntityManager)(ref _entityManager)).HasComponent(castleHeartEntity)) { return; } Entity entity = ((EntityManager)(ref _entityManager)).GetComponentData(castleHeartEntity).Owner._Entity; if (!((EntityManager)(ref _entityManager)).Exists(entity) || !((EntityManager)(ref _entityManager)).HasComponent(entity)) { return; } Entity entity2 = ((EntityManager)(ref _entityManager)).GetComponentData(entity).ClanEntity._Entity; val = ((((EntityManager)(ref _entityManager)).Exists(entity2) && ((EntityManager)(ref _entityManager)).HasComponent(entity2)) ? entity2 : entity); if (!((EntityManager)(ref _entityManager)).Exists(attackerUserEntity) || !((EntityManager)(ref _entityManager)).HasComponent(attackerUserEntity)) { return; } Entity entity3 = ((EntityManager)(ref _entityManager)).GetComponentData(attackerUserEntity).ClanEntity._Entity; val2 = ((((EntityManager)(ref _entityManager)).Exists(entity3) && ((EntityManager)(ref _entityManager)).HasComponent(entity3)) ? entity3 : attackerUserEntity); if (!(val == Entity.Null) && !(val2 == Entity.Null)) { _activeSieges[castleHeartEntity] = (val2, val); if (TroubleshootingConfig.EnableVerboseLogging.Value) { LoggingHelper.Debug($"[RaidInterference] Siege Started on Heart {castleHeartEntity.Index}. Attacker: {val2.Index}, Defender: {val.Index}"); } } } catch (Exception ex) { LoggingHelper.Error("[RaidInterference] Error starting siege logic", ex); } } public static void EndSiege(Entity castleHeartEntity) { //IL_000d: 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) if (_isServiceLogicInitialized && _activeSieges.Remove(castleHeartEntity) && TroubleshootingConfig.EnableVerboseLogging.Value) { LoggingHelper.Debug($"[RaidInterference] Siege Ended on Heart {castleHeartEntity.Index}."); } } public static void StopService() { ResetRuntimeState(); } public static void ResetRuntimeState() { //IL_0019: 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) _activeSieges.Clear(); _lastDebuffMessageTimes.Clear(); _entityManager = default(EntityManager); _debugEventsSystem_instance = null; _serverScriptMapper_instance = null; _serverGameManager_instance = default(ServerGameManager); _serverGameManager_found = false; _isServiceLogicInitialized = false; } public static void ProcessInterference() { //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00cc: Unknown result type (might be due to invalid IL or missing references) if (!RaidInterferenceConfig.EnableRaidInterference.Value || !_isServiceLogicInitialized || _activeSieges.Count == 0 || !EnsureSystemsInitialized()) { return; } PruneInvalidRuntimeEntities(); List list = new List(); List list2 = _activeSieges.Keys.ToList(); EntityQuery val = default(EntityQuery); NativeArray users = default(NativeArray); try { val = ((EntityManager)(ref _entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[2] { ComponentType.ReadOnly(), ComponentType.ReadOnly() }); if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { return; } users = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)3)); foreach (Entity item in list2) { if (!TryGetActiveSiege(item, out (Entity, Entity) siegeParticipants, out CastleHeart castleHeart)) { list.Add(item); } else if (ShouldSkipInterference(item)) { list.Add(item); } else { ProcessUsersForSiege(item, castleHeart, siegeParticipants, users); } } } finally { if (users.IsCreated) { users.Dispose(); } if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } foreach (Entity item2 in list) { EndSiege(item2); } } } private static bool TryGetActiveSiege(Entity castleHeartEntity, out (Entity AttackerInfo, Entity DefenderInfo) siegeParticipants, out CastleHeart castleHeart) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) siegeParticipants = default((Entity, Entity)); castleHeart = default(CastleHeart); if (!_activeSieges.TryGetValue(castleHeartEntity, out siegeParticipants) || !((EntityManager)(ref _entityManager)).Exists(castleHeartEntity) || !((EntityManager)(ref _entityManager)).HasComponent(castleHeartEntity)) { return false; } castleHeart = ((EntityManager)(ref _entityManager)).GetComponentData(castleHeartEntity); if (IsCastleHeartInActiveRaidEvent(castleHeart)) { return true; } if (TroubleshootingConfig.EnableVerboseLogging.Value) { LoggingHelper.Debug($"[RaidInterference] Heart {castleHeartEntity.Index} no longer reports an active raid event. Removing."); } return false; } private static bool IsCastleHeartInActiveRaidEvent(CastleHeart castleHeart) { //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_0022: Invalid comparison between Unknown and I4 //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_002b: Invalid comparison between Unknown and I4 //IL_002d: 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_0034: Invalid comparison between Unknown and I4 if (!((CastleHeart)(ref castleHeart)).IsSieged() && !((CastleHeart)(ref castleHeart)).IsAttacked() && !((CastleHeart)(ref castleHeart)).IsRaided() && (int)castleHeart.ActiveEvent != 2 && (int)castleHeart.ActiveEvent != 3) { return (int)castleHeart.ActiveEvent == 4; } return true; } private static void PruneInvalidRuntimeEntities() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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_00b2: 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) if (_entityManager == default(EntityManager)) { return; } foreach (Entity item in _activeSieges.Keys.ToList()) { if (item == Entity.Null || !((EntityManager)(ref _entityManager)).Exists(item)) { _activeSieges.Remove(item); } } foreach (Entity item2 in _lastDebuffMessageTimes.Keys.ToList()) { if (item2 == Entity.Null || !((EntityManager)(ref _entityManager)).Exists(item2)) { _lastDebuffMessageTimes.Remove(item2); } } } private static bool ShouldSkipInterference(Entity castleHeartEntity) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) if (RaidInterferenceConfig.DisableInterferenceForDecayingBases.Value && OfflineProtectionService.IsBaseDecaying(castleHeartEntity, _entityManager)) { return true; } if (RaidInterferenceConfig.DisableInterferenceForOfflineRaids.Value && OfflineProtectionService.AreAllDefendersActuallyOffline(castleHeartEntity, _entityManager)) { return true; } return false; } private static void ProcessUsersForSiege(Entity castleHeartEntity, CastleHeart castleHeart, (Entity AttackerInfo, Entity DefenderInfo) siegeParticipants, NativeArray users) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_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_0015: 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_0027: 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_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) //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_0041: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) Enumerator enumerator = users.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (!TryGetConnectedPlayer(current, out var user, out var characterEntity, out var tilePosition) || !IsCharacterInSiegeTerritory(castleHeartEntity, castleHeart, tilePosition)) { continue; } bool flag = IsParticipant(current, user.ClanEntity._Entity, siegeParticipants.AttackerInfo); bool flag2 = IsParticipant(current, user.ClanEntity._Entity, siegeParticipants.DefenderInfo); if (TroubleshootingConfig.EnableVerboseLogging.Value) { LoggingHelper.Debug($"[RaidInterference] Player '{user.CharacterName}' is in sieged territory."); LoggingHelper.Debug($" -> IsAttacker: {flag}"); LoggingHelper.Debug($" -> IsDefender: {flag2}"); } if (!(flag || flag2) && ShouldApplyInterferenceBurn(user, characterEntity)) { if (TroubleshootingConfig.EnableVerboseLogging.Value) { LoggingHelper.Debug($" -> APPLYING BURN to '{user.CharacterName}'."); } ApplyInterloperDebuff(characterEntity, current); } } } private static bool TryGetConnectedPlayer(Entity userEntity, out User user, out Entity characterEntity, out TilePosition tilePosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0041: 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_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_0077: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) user = default(User); characterEntity = Entity.Null; tilePosition = default(TilePosition); if (!((EntityManager)(ref _entityManager)).Exists(userEntity) || !((EntityManager)(ref _entityManager)).HasComponent(userEntity)) { return false; } user = ((EntityManager)(ref _entityManager)).GetComponentData(userEntity); characterEntity = user.LocalCharacter._Entity; if (!user.IsConnected || characterEntity == Entity.Null || !((EntityManager)(ref _entityManager)).Exists(characterEntity) || !((EntityManager)(ref _entityManager)).HasComponent(characterEntity)) { return false; } tilePosition = ((EntityManager)(ref _entityManager)).GetComponentData(characterEntity); return true; } private static bool IsCharacterInSiegeTerritory(Entity castleHeartEntity, CastleHeart castleHeart, TilePosition tilePosition) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_003b: 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_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_0052: Unknown result type (might be due to invalid IL or missing references) Entity entity = NetworkedEntity.op_Implicit(castleHeart.CastleTerritoryEntity)._Entity; if (!((EntityManager)(ref _entityManager)).Exists(entity)) { return false; } try { CastleTerritory val = default(CastleTerritory); if (!((EntityManager)(ref _entityManager)).TryGetComponentData(entity, ref val)) { return false; } if (!((BoundsMinMax)(ref val.WorldBounds)).Contains(tilePosition.Tile)) { return false; } return CastleTerritoryExtensions.IsTileInTerritory(_entityManager, tilePosition.Tile, ref entity, ref val); } catch (Exception ex) { LoggingHelper.Debug($"[RaidInterference] Failed territory check for Heart {castleHeartEntity.Index}: {ex.Message}"); return false; } } private static bool IsParticipant(Entity userEntity, Entity playerClanEntity, Entity participantInfo) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_001b: Unknown result type (might be due to invalid IL or missing references) if (participantInfo != Entity.Null) { if (!(playerClanEntity != Entity.Null) || !(playerClanEntity == participantInfo)) { return participantInfo == userEntity; } return true; } return false; } private static bool ShouldApplyInterferenceBurn(User user, Entity characterEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if (user.IsAdmin) { if (TroubleshootingConfig.EnableVerboseLogging.Value) { LoggingHelper.Debug($" -> Skipping burn for '{user.CharacterName}' (Admin Detected)."); } return false; } bool flag = ShapeshiftHelper.IsInBearForm(_entityManager, characterEntity); if (TroubleshootingConfig.EnableVerboseLogging.Value) { LoggingHelper.Debug($" -> BearBuffDetected: {flag}"); LoggingHelper.Debug($" -> BearFormExemptEnabled: {RaidInterferenceConfig.ExemptBearFormUsers.Value}"); } if (RaidInterferenceConfig.ExemptBearFormUsers.Value && flag) { if (TroubleshootingConfig.EnableVerboseLogging.Value) { LoggingHelper.Debug($" -> Skipping burn for '{user.CharacterName}' (Bear Buff Detected)."); } return false; } return true; } private static void ApplyInterloperDebuff(Entity characterEntity, Entity userEntity) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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_0158: 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_00b5: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) if (!EnsureSystemsInitialized()) { return; } Entity val = default(Entity); if (((ServerGameManager)(ref _serverGameManager_instance)).TryGetBuff(characterEntity, PrefabIdentifier.op_Implicit(PrefabData.InterloperDebuff.Guid), ref val)) { if (TroubleshootingConfig.EnableVerboseLogging.Value) { LoggingHelper.Debug($"[RaidInterference] Refreshing existing InterloperDebuff on character {characterEntity.Index}."); } if (((EntityManager)(ref _entityManager)).HasComponent(val)) { ((EntityManager)(ref _entityManager)).SetComponentData(val, new Age { Value = 0f }); } LifeTime val2 = new LifeTime { Duration = 5f, EndAction = (LifeTimeEndAction)2 }; if (((EntityManager)(ref _entityManager)).HasComponent(val)) { ((EntityManager)(ref _entityManager)).SetComponentData(val, val2); } else { ((EntityManager)(ref _entityManager)).AddComponentData(val, val2); } } else { FromCharacter val3 = new FromCharacter { Character = characterEntity, User = userEntity }; ApplyBuffDebugEvent val4 = new ApplyBuffDebugEvent { BuffPrefabGUID = PrefabData.InterloperDebuff.Guid }; try { _debugEventsSystem_instance.ApplyBuff(val3, val4); if (TroubleshootingConfig.EnableVerboseLogging.Value) { LoggingHelper.Debug($"[RaidInterference] Applied InterloperDebuff to character {characterEntity.Index}."); } } catch (Exception ex) { LoggingHelper.Error("[RaidInterference] Failed to apply debug buff event: " + ex.Message); } } bool flag = false; if (!_lastDebuffMessageTimes.TryGetValue(userEntity, out var value)) { flag = true; } else if ((DateTime.UtcNow - value).TotalSeconds > 10.0) { flag = true; } if (flag && ((EntityManager)(ref _entityManager)).Exists(userEntity) && ((EntityManager)(ref _entityManager)).HasComponent(userEntity)) { FixedString512Bytes val5 = default(FixedString512Bytes); ((FixedString512Bytes)(ref val5))..ctor(ChatColors.WarningText("You are interfering in an active siege, leave now!")); ServerChatUtils.SendSystemMessageToClient(_entityManager, ((EntityManager)(ref _entityManager)).GetComponentData(userEntity), ref val5); _lastDebuffMessageTimes[userEntity] = DateTime.UtcNow; } } } public static class RaidMapIconService { private enum RaidMapIconKind { OfflineRaid, DecayRaid, OptIn, OptOut } private readonly struct ActiveRaidIcon { public readonly Entity IconProxy; public readonly DateTime LastHit; public readonly RaidMapIconKind Kind; public ActiveRaidIcon(Entity iconProxy, DateTime lastHit, RaidMapIconKind kind) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) IconProxy = iconProxy; LastHit = lastHit; Kind = kind; } } private const double AttackStateUpdateGraceSeconds = 2.0; private const double PassiveIconFailureLogCooldownSeconds = 30.0; private static readonly Dictionary _activeRaidIcons = new Dictionary(); private static readonly HashSet _activeIconProxies = new HashSet(); private static readonly Dictionary _passiveIconFailureLogTimes = new Dictionary(); private static EntityQuery _mapIconAttachQuery; private static EntityManager _cachedMapIconAttachQueryEntityManager; private static bool _mapIconAttachQueryInitialized; private static bool _persistentStateIconsDirty = true; public static bool HasActiveIcons => _activeRaidIcons.Count > 0; public static bool IsRaidIconProxy(Entity iconProxy) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return _activeIconProxies.Contains(iconProxy); } public static void ResetRuntimeState() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) RemoveAllIcons(); _activeRaidIcons.Clear(); _activeIconProxies.Clear(); _passiveIconFailureLogTimes.Clear(); _mapIconAttachQuery = default(EntityQuery); _cachedMapIconAttachQueryEntityManager = default(EntityManager); _mapIconAttachQueryInitialized = false; _persistentStateIconsDirty = true; } public static void MarkPersistentStateIconsDirty() { _persistentStateIconsDirty = true; } public static void AddRaidIcon(Entity castleHeartEntity, bool isOfflineRaid, bool isDecayRaid) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (isOfflineRaid) { AddRaidIconInternal(castleHeartEntity, RaidMapIconKind.OfflineRaid); } else if (isDecayRaid) { AddRaidIconInternal(castleHeartEntity, RaidMapIconKind.DecayRaid); } } public static void ClearAllRaidForgeIconEntities(EntityManager em) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_012d: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) RemoveAllIcons(); if (em == default(EntityManager)) { return; } HashSet knownRaidForgeIconGuidHashes = GetKnownRaidForgeIconGuidHashes(); HashSet hashSet = new HashSet(); HashSet hashSet2 = new HashSet(); EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); int num = 0; try { PrefabGUID proxyPrefabGuid; bool flag = TryGetMapIconProxyPrefabGuid(out proxyPrefabGuid); val = GetMapIconAttachQuery(em); if (!((EntityQuery)(ref val)).IsEmptyIgnoreFilter && flag) { val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref em)).Exists(current) && ((EntityManager)(ref em)).HasComponent(current)) { Entity parent = ((EntityManager)(ref em)).GetComponentData(current).Parent; if (!(parent == Entity.Null) && ((EntityManager)(ref em)).Exists(parent) && IsRaidForgeMapIconProxyEntity(em, parent, proxyPrefabGuid) && IsKnownRaidForgeIconEntity(em, current, knownRaidForgeIconGuidHashes)) { hashSet2.Add(current); hashSet.Add(parent); } } } } num = DestroyStandaloneRaidForgeIconEntities(em, knownRaidForgeIconGuidHashes, Entity.Null, Entity.Null); } finally { if (val2.IsCreated) { val2.Dispose(); } } foreach (Entity item in hashSet2) { DestroyEntityIfAlive(em, item); } foreach (Entity item2 in hashSet) { DestroyAttachedIconEntities(em, item2); DestroyEntityIfAlive(em, item2); } ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value && (hashSet2.Count > 0 || hashSet.Count > 0 || num > 0)) { LoggingHelper.Info($"[RaidMapIconService] Cleared {hashSet.Count} stale RaidForge map icon proxy/proxies and {num} targeted icon(s)."); } } private static void RemoveRaidIcon(Entity castleHeartEntity) { //IL_0005: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) if (!_activeRaidIcons.TryGetValue(castleHeartEntity, out var value)) { return; } if (VWorld.IsServerWorldReady()) { EntityManager entityManager = VWorld.EntityManager; if (((EntityManager)(ref entityManager)).Exists(value.IconProxy)) { EntityManager entityManager2 = VWorld.EntityManager; DestroyAttachedIconEntities(entityManager2, value.IconProxy); DestroyEntityIfAlive(entityManager2, value.IconProxy); } } _activeRaidIcons.Remove(castleHeartEntity); _activeIconProxies.Remove(value.IconProxy); } public static void RemoveOfflineRaidIconsForOwner(string ownerPersistentKey, EntityManager em) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(ownerPersistentKey) || _activeRaidIcons.Count == 0 || em == default(EntityManager)) { return; } List list = new List(); foreach (KeyValuePair activeRaidIcon in _activeRaidIcons) { if (activeRaidIcon.Value.Kind == RaidMapIconKind.OfflineRaid && TryGetOwnerPersistentKey(activeRaidIcon.Key, em, out var ownerPersistentKey2) && ownerPersistentKey2 == ownerPersistentKey) { list.Add(activeRaidIcon.Key); } } foreach (Entity item in list) { RemoveRaidIcon(item); } if (!_persistentStateIconsDirty) { return; } try { SyncPersistentStateIcons(em); } finally { _persistentStateIconsDirty = false; } } public static void RemoveDecayRaidIconsForReclaimedPlot(Entity newCastleHeartEntity, EntityManager em) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0047: 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_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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) if (em == default(EntityManager) || newCastleHeartEntity == Entity.Null || !((EntityManager)(ref em)).Exists(newCastleHeartEntity) || !((EntityManager)(ref em)).HasComponent(newCastleHeartEntity) || !TryGetMapIconPosition(em, newCastleHeartEntity, out var position)) { return; } float num = 324f; Entity castleTerritoryEntity = ((EntityManager)(ref em)).GetComponentData(newCastleHeartEntity).CastleTerritoryEntity; List list = new List(); foreach (KeyValuePair item in _activeRaidIcons.ToList()) { if (item.Value.Kind == RaidMapIconKind.DecayRaid) { Entity key = item.Key; Entity iconProxy = item.Value.IconProxy; bool flag = key == newCastleHeartEntity; if (!flag && (key == Entity.Null || !((EntityManager)(ref em)).Exists(key) || !((EntityManager)(ref em)).HasComponent(key))) { flag = true; } if (!flag && castleTerritoryEntity != Entity.Null) { flag = ((EntityManager)(ref em)).GetComponentData(key).CastleTerritoryEntity == castleTerritoryEntity; } if (!flag && TryGetMapIconPosition(em, key, out var position2)) { flag = math.distancesq(position, position2) <= num; } if (!flag && iconProxy != Entity.Null && ((EntityManager)(ref em)).Exists(iconProxy) && TryGetMapIconPosition(em, iconProxy, out var position3)) { flag = math.distancesq(position, position3) <= num; } if (flag) { list.Add(key); } } } foreach (Entity item2 in list) { RemoveRaidIcon(item2); } ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value && list.Count > 0) { LoggingHelper.Debug($"[RaidMapIconService] Removed {list.Count} decay raid icon(s) after castle heart placement reclaimed a plot."); } } public static void ProcessCleanup() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0176: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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) //IL_00cc: 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_0127: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) if (!VWorld.IsServerWorldReady()) { return; } EntityManager entityManager = VWorld.EntityManager; if (!AnyIconKindEnabled()) { RemoveAllIcons(); return; } int value = MapIconsConfig.RaidMapIconTimeoutSeconds.Value; DateTime utcNow = DateTime.UtcNow; foreach (Entity item in _activeRaidIcons.Keys.ToList()) { ActiveRaidIcon activeRaidIcon = _activeRaidIcons[item]; if (!((EntityManager)(ref entityManager)).Exists(item) || !((EntityManager)(ref entityManager)).HasComponent(item)) { RemoveRaidIcon(item); continue; } if (!IsIconKindEnabled(activeRaidIcon.Kind)) { RemoveRaidIcon(item); continue; } CastleHeart componentData = ((EntityManager)(ref entityManager)).GetComponentData(item); double totalSeconds = (utcNow - activeRaidIcon.LastHit).TotalSeconds; if (activeRaidIcon.Kind == RaidMapIconKind.OfflineRaid) { if (!RaidToggleSystem.AreRaidsEnabled() || !OfflineProtectionService.AreAllDefendersActuallyOffline(item, entityManager) || (!((CastleHeart)(ref componentData)).IsAttacked() && totalSeconds > 2.0) || totalSeconds > (double)value) { RemoveRaidIcon(item); } continue; } if (activeRaidIcon.Kind == RaidMapIconKind.DecayRaid) { if (!((CastleHeart)(ref componentData)).IsDecaying() || totalSeconds > (double)value) { RemoveRaidIcon(item); } continue; } if (activeRaidIcon.Kind == RaidMapIconKind.OptIn && !ShouldShowOptInIcon(item, entityManager)) { RemoveRaidIcon(item); } if (activeRaidIcon.Kind == RaidMapIconKind.OptOut && !ShouldShowOptOutIcon(item, entityManager)) { RemoveRaidIcon(item); } } if (!_persistentStateIconsDirty) { return; } try { SyncPersistentStateIcons(entityManager); } finally { _persistentStateIconsDirty = false; } } public static void RemoveAllIcons() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) foreach (Entity item in _activeRaidIcons.Keys.ToList()) { RemoveRaidIcon(item); } } private static void SyncPersistentStateIcons(EntityManager em) { //IL_0048: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) if (!ShouldShowOptInIcons()) { RemoveIconsOfKind(RaidMapIconKind.OptIn); } if (!ShouldShowOptOutIcons()) { RemoveIconsOfKind(RaidMapIconKind.OptOut); } if (!ShouldShowOptInIcons() && !ShouldShowOptOutIcons()) { return; } foreach (KeyValuePair item in OwnershipCacheService.GetHeartToOwnerCacheView().ToList()) { Entity key = item.Key; ActiveRaidIcon value3; if (ShouldShowOptInIcon(key, em)) { if (!_activeRaidIcons.TryGetValue(key, out var value) || GetIconPriority(value.Kind) <= GetIconPriority(RaidMapIconKind.OptIn)) { if (_activeRaidIcons.TryGetValue(key, out value) && value.Kind == RaidMapIconKind.OptOut) { RemoveRaidIcon(key); } AddRaidIconInternal(key, RaidMapIconKind.OptIn); } } else if (ShouldShowOptOutIcon(key, em)) { if (!_activeRaidIcons.TryGetValue(key, out var value2) || GetIconPriority(value2.Kind) <= GetIconPriority(RaidMapIconKind.OptOut)) { if (_activeRaidIcons.TryGetValue(key, out value2) && value2.Kind == RaidMapIconKind.OptIn) { RemoveRaidIcon(key); } AddRaidIconInternal(key, RaidMapIconKind.OptOut); } } else if (_activeRaidIcons.TryGetValue(key, out value3) && (value3.Kind == RaidMapIconKind.OptIn || value3.Kind == RaidMapIconKind.OptOut)) { RemoveRaidIcon(key); } } } private static void RemoveIconsOfKind(RaidMapIconKind kind) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) foreach (Entity item in (from entry in _activeRaidIcons where entry.Value.Kind == kind select entry.Key).ToList()) { RemoveRaidIcon(item); } } private static void AddRaidIconInternal(Entity castleHeartEntity, RaidMapIconKind kind) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_001a: 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_0047: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020b: 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_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) if (!VWorld.IsServerWorldReady()) { return; } EntityManager entityManager = VWorld.EntityManager; if (!((EntityManager)(ref entityManager)).Exists(castleHeartEntity) || (!((EntityManager)(ref entityManager)).HasComponent(castleHeartEntity) && !((EntityManager)(ref entityManager)).HasComponent(castleHeartEntity))) { LogPassiveIconFailure(kind, castleHeartEntity, "castle heart is missing Translation/LocalToWorld position data"); } else { if (!IsIconKindEnabled(kind)) { return; } if (_activeRaidIcons.TryGetValue(castleHeartEntity, out var value) && ((EntityManager)(ref entityManager)).Exists(value.IconProxy)) { if (value.Kind == kind) { _activeRaidIcons[castleHeartEntity] = new ActiveRaidIcon(value.IconProxy, DateTime.UtcNow, value.Kind); _activeIconProxies.Add(value.IconProxy); return; } if (GetIconPriority(value.Kind) > GetIconPriority(kind)) { _activeIconProxies.Add(value.IconProxy); return; } RemoveRaidIcon(castleHeartEntity); } else if (_activeRaidIcons.TryGetValue(castleHeartEntity, out value)) { _activeRaidIcons.Remove(castleHeartEntity); _activeIconProxies.Remove(value.IconProxy); } RemoveStaleIconEntitiesForHeart(entityManager, castleHeartEntity, Entity.Null); if (!TryGetIconPrefabGuid(kind, out var iconPrefabGuid)) { ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Warning($"[RaidMapIconService] Could not resolve map icon prefab for {kind}. Icon was not spawned."); } return; } if (IsPassiveStateIconKind(kind)) { if (TrySpawnTargetedMapIcon(entityManager, castleHeartEntity, iconPrefabGuid, kind, out var mapIconEntity)) { _activeRaidIcons[castleHeartEntity] = new ActiveRaidIcon(mapIconEntity, DateTime.UtcNow, kind); _activeIconProxies.Add(mapIconEntity); } else { LogPassiveIconFailure(kind, castleHeartEntity, $"targeted icon spawn failed for prefab {((PrefabGUID)(ref iconPrefabGuid)).GuidHash}"); } return; } PrefabCollectionSystem existingSystemManaged = VWorld.Server.GetExistingSystemManaged(); Entity val = default(Entity); if (TryGetMapIconProxyPrefabGuid(out var proxyPrefabGuid) && existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(proxyPrefabGuid, ref val)) { float3 value2 = ((EntityManager)(ref entityManager)).GetComponentData(castleHeartEntity).Value; Entity val2 = ((EntityManager)(ref entityManager)).Instantiate(val); ((EntityManager)(ref entityManager)).SetComponentData(val2, new Translation { Value = value2 }); ((EntityManager)(ref entityManager)).AddComponentData(val2, new SpawnedBy { Value = castleHeartEntity }); if (((EntityManager)(ref entityManager)).HasComponent(val2)) { ((EntityManager)(ref entityManager)).RemoveComponent(val2); } if (((EntityManager)(ref entityManager)).HasBuffer(val2)) { ((EntityManager)(ref entityManager)).GetBuffer(val2, false).Clear(); } if (((EntityManager)(ref entityManager)).HasComponent(val2)) { ((EntityManager)(ref entityManager)).RemoveComponent(val2); } DynamicBuffer buffer = ((EntityManager)(ref entityManager)).GetBuffer(val2, false); buffer.Clear(); buffer.Add(new AttachMapIconsToEntity { Prefab = iconPrefabGuid }); _activeRaidIcons[castleHeartEntity] = new ActiveRaidIcon(val2, DateTime.UtcNow, kind); _activeIconProxies.Add(val2); } } } private static bool TrySpawnTargetedMapIcon(EntityManager em, Entity castleHeartEntity, PrefabGUID iconPrefab, RaidMapIconKind kind, out Entity mapIconEntity) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_005e: 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_004b: 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_009b: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) mapIconEntity = Entity.Null; if (castleHeartEntity == Entity.Null || !((EntityManager)(ref em)).Exists(castleHeartEntity) || !((EntityManager)(ref em)).HasComponent(castleHeartEntity)) { LogPassiveIconFailure(kind, castleHeartEntity, "castle heart is missing NetworkId or no longer exists"); return false; } PrefabCollectionSystem existingSystemManaged = VWorld.Server.GetExistingSystemManaged(); if (existingSystemManaged == null) { LogPassiveIconFailure(kind, castleHeartEntity, "PrefabCollectionSystem is unavailable"); return false; } Entity val = default(Entity); if (!existingSystemManaged._PrefabGuidToEntityMap.TryGetValue(iconPrefab, ref val)) { LogPassiveIconFailure(kind, castleHeartEntity, $"map icon prefab {((PrefabGUID)(ref iconPrefab)).GuidHash} was not found in _PrefabGuidToEntityMap"); return false; } if (!TryGetMapIconPosition(em, castleHeartEntity, out var position)) { LogPassiveIconFailure(kind, castleHeartEntity, "could not resolve castle heart position"); return false; } mapIconEntity = ((EntityManager)(ref em)).Instantiate(val); ConfigureSpawnedMapIconTransformLikeModCore(em, mapIconEntity, position); AddOrUpdateSpawnedBy(em, mapIconEntity, castleHeartEntity); Entity spawnedMapIcon = mapIconEntity; RaidForgeScheduler.RunAfterFrames(delegate { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (VWorld.IsServerWorldReady()) { EntityManager entityManager = VWorld.EntityManager; if (!ConfigureTargetedMapIconLikeModCore(entityManager, spawnedMapIcon, castleHeartEntity)) { LogPassiveIconFailure(kind, castleHeartEntity, $"failed to configure spawned icon entity {spawnedMapIcon.Index}:{spawnedMapIcon.Version}"); DestroyEntityIfAlive(entityManager, spawnedMapIcon); if (_activeRaidIcons.TryGetValue(castleHeartEntity, out var value) && value.IconProxy == spawnedMapIcon) { _activeRaidIcons.Remove(castleHeartEntity); } _activeIconProxies.Remove(spawnedMapIcon); } else { AttachMapIconAsChild(entityManager, spawnedMapIcon, castleHeartEntity, iconPrefab); } } }, 1); RaidForgeScheduler.RunAfterFrames(delegate { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (VWorld.IsServerWorldReady()) { EntityManager entityManager = VWorld.EntityManager; if (ConfigureTargetedMapIconLikeModCore(entityManager, spawnedMapIcon, castleHeartEntity)) { AttachMapIconAsChild(entityManager, spawnedMapIcon, castleHeartEntity, iconPrefab); } } }, 5); return true; } private static bool TryGetMapIconPosition(EntityManager em, Entity targetEntity, 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_002b: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_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_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) position = default(float3); if (((EntityManager)(ref em)).HasComponent(targetEntity)) { LocalToWorld componentData = ((EntityManager)(ref em)).GetComponentData(targetEntity); position = ((LocalToWorld)(ref componentData)).Position; return true; } if (((EntityManager)(ref em)).HasComponent(targetEntity)) { position = ((EntityManager)(ref em)).GetComponentData(targetEntity).Value; return true; } return false; } private static void ConfigureSpawnedMapIconTransformLikeModCore(EntityManager em, Entity mapIconEntity, float3 position) { //IL_0002: 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_000c: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0087: 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_005f: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00b3: 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) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) if (!((EntityManager)(ref em)).HasComponent(mapIconEntity)) { ((EntityManager)(ref em)).AddComponent(mapIconEntity); } if (((EntityManager)(ref em)).HasComponent(mapIconEntity)) { ((EntityManager)(ref em)).SetComponentData(mapIconEntity, new Translation { Value = position }); } else { ((EntityManager)(ref em)).AddComponentData(mapIconEntity, new Translation { Value = position }); } if (((EntityManager)(ref em)).HasComponent(mapIconEntity)) { LocalToWorld componentData = ((EntityManager)(ref em)).GetComponentData(mapIconEntity); componentData.Value.c3 = new float4(position, 1f); ((EntityManager)(ref em)).SetComponentData(mapIconEntity, componentData); } if (((EntityManager)(ref em)).HasComponent(mapIconEntity)) { ((EntityManager)(ref em)).SetComponentData(mapIconEntity, new Rotation { Value = quaternion.identity }); } else { ((EntityManager)(ref em)).AddComponentData(mapIconEntity, new Rotation { Value = quaternion.identity }); } if (((EntityManager)(ref em)).HasComponent(mapIconEntity)) { ((EntityManager)(ref em)).SetComponentData(mapIconEntity, new SpawnTransform { Position = position, Rotation = quaternion.identity }); } if (((EntityManager)(ref em)).HasComponent(mapIconEntity)) { ((EntityManager)(ref em)).SetComponentData(mapIconEntity, new LastTranslation { Value = position }); } } private static void AddOrUpdateSpawnedBy(EntityManager em, Entity mapIconEntity, Entity sourceEntity) { //IL_0002: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (((EntityManager)(ref em)).HasComponent(mapIconEntity)) { ((EntityManager)(ref em)).SetComponentData(mapIconEntity, new SpawnedBy { Value = sourceEntity }); } else { ((EntityManager)(ref em)).AddComponentData(mapIconEntity, new SpawnedBy { Value = sourceEntity }); } } private static bool ConfigureTargetedMapIconLikeModCore(EntityManager em, Entity mapIconEntity, Entity targetEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_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_001e: 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_002d: 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_0041: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if (em == default(EntityManager) || mapIconEntity == Entity.Null || targetEntity == Entity.Null || !((EntityManager)(ref em)).Exists(mapIconEntity) || !((EntityManager)(ref em)).Exists(targetEntity) || !((EntityManager)(ref em)).HasComponent(targetEntity)) { return false; } if (!((EntityManager)(ref em)).HasComponent(mapIconEntity)) { ((EntityManager)(ref em)).AddComponent(mapIconEntity); } MapIconData componentData = ((EntityManager)(ref em)).GetComponentData(mapIconEntity); componentData.RequiresReveal = false; componentData.ShowOutsideVision = true; componentData.ShowOnMinimap = true; componentData.AllySetting = (MapIconShowSettings)2; componentData.EnemySetting = (MapIconShowSettings)2; ((EntityManager)(ref em)).SetComponentData(mapIconEntity, componentData); if (!((EntityManager)(ref em)).HasComponent(mapIconEntity)) { ((EntityManager)(ref em)).AddComponent(mapIconEntity); } MapIconTargetEntity componentData2 = ((EntityManager)(ref em)).GetComponentData(mapIconEntity); componentData2.TargetEntity = NetworkedEntity.ServerEntity(targetEntity); componentData2.TargetNetworkId = ((EntityManager)(ref em)).GetComponentData(targetEntity); ((EntityManager)(ref em)).SetComponentData(mapIconEntity, componentData2); return true; } private static void AttachMapIconAsChild(EntityManager em, Entity mapIconEntity, Entity parentEntity, PrefabGUID iconPrefab) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_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_004d: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_009a: 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_00a3: Unknown result type (might be due to invalid IL or missing references) if (mapIconEntity == Entity.Null || parentEntity == Entity.Null || !((EntityManager)(ref em)).Exists(mapIconEntity) || !((EntityManager)(ref em)).Exists(parentEntity)) { return; } if (((EntityManager)(ref em)).HasComponent(mapIconEntity)) { ((EntityManager)(ref em)).SetComponentData(mapIconEntity, new Attach(parentEntity)); } else { ((EntityManager)(ref em)).AddComponentData(mapIconEntity, new Attach(parentEntity)); } DynamicBuffer val = (((EntityManager)(ref em)).HasBuffer(parentEntity) ? ((EntityManager)(ref em)).GetBuffer(parentEntity, false) : ((EntityManager)(ref em)).AddBuffer(parentEntity)); for (int i = 0; i < val.Length; i++) { if (val[i].Entity == mapIconEntity) { AttachedBuffer val2 = val[i]; val2.PrefabGuid = iconPrefab; val[i] = val2; return; } } val.Add(new AttachedBuffer { PrefabGuid = iconPrefab, Entity = mapIconEntity }); } private static void LogPassiveIconFailure(RaidMapIconKind kind, Entity heart, string reason) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00df: 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) ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { string key = $"{kind}:{heart.Index}:{heart.Version}:{reason}"; DateTime utcNow = DateTime.UtcNow; if (!_passiveIconFailureLogTimes.TryGetValue(key, out var value) || !((utcNow - value).TotalSeconds < 30.0)) { _passiveIconFailureLogTimes[key] = utcNow; LoggingHelper.Debug($"[RaidMapIconService] Passive {kind} icon skipped for heart {heart.Index}:{heart.Version}: {reason}."); } } } private static bool ShouldShowOptInIcons() { if (!OptInRaidingConfig.UseDefaultOptInMode && MapIconsConfig.EnableOptInRaidMapIcon.Value && OptInRaidingConfig.EnableOptInRaiding.Value && !OfflineRaidProtectionConfig.EnableOfflineRaidProtection.Value) { return RaidToggleSystem.AreRaidsEnabled(); } return false; } private static bool ShouldShowOptOutIcons() { if (OptInRaidingConfig.UseDefaultOptInMode && MapIconsConfig.EnableOptOutRaidMapIcon.Value && OptInRaidingConfig.EnableOptInRaiding.Value && !OfflineRaidProtectionConfig.EnableOfflineRaidProtection.Value) { return RaidToggleSystem.AreRaidsEnabled(); } return false; } private static bool ShouldShowOptInIcon(Entity castleHeartEntity, EntityManager em) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!ShouldShowOptInIcons() || castleHeartEntity == Entity.Null || !((EntityManager)(ref em)).Exists(castleHeartEntity) || !((EntityManager)(ref em)).HasComponent(castleHeartEntity)) { return false; } if (!TryGetOwnerPersistentKey(castleHeartEntity, em, out var ownerPersistentKey)) { return false; } return OptInRaidService.IsOptedIn(ownerPersistentKey); } private static bool ShouldShowOptOutIcon(Entity castleHeartEntity, EntityManager em) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!ShouldShowOptOutIcons() || castleHeartEntity == Entity.Null || !((EntityManager)(ref em)).Exists(castleHeartEntity) || !((EntityManager)(ref em)).HasComponent(castleHeartEntity)) { return false; } if (!TryGetOwnerPersistentKey(castleHeartEntity, em, out var ownerPersistentKey)) { return false; } return OptInRaidService.IsManuallyOptedOut(ownerPersistentKey); } private static bool TryGetOwnerPersistentKey(Entity castleHeartEntity, EntityManager em, out string ownerPersistentKey) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0026: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_003b: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) ownerPersistentKey = null; if (!OwnershipCacheService.TryGetHeartOwner(castleHeartEntity, out var ownerUserEntity) || ownerUserEntity == Entity.Null || !((EntityManager)(ref em)).Exists(ownerUserEntity) || !((EntityManager)(ref em)).HasComponent(ownerUserEntity)) { return false; } if (OwnershipCacheService.TryGetUserClan(ownerUserEntity, out var clanEntity) && clanEntity != Entity.Null && ((EntityManager)(ref em)).Exists(clanEntity)) { ownerPersistentKey = PersistentKeyHelper.GetClanKey(em, clanEntity); return !string.IsNullOrEmpty(ownerPersistentKey); } User componentData = ((EntityManager)(ref em)).GetComponentData(ownerUserEntity); ownerPersistentKey = PersistentKeyHelper.GetUserKey(componentData.PlatformId); return !string.IsNullOrEmpty(ownerPersistentKey); } private static bool AnyIconKindEnabled() { if (!MapIconsConfig.EnableOfflineRaidMapIcon.Value && !MapIconsConfig.EnableDecayRaidMapIcon.Value && !MapIconsConfig.EnableOptInRaidMapIcon.Value) { return MapIconsConfig.EnableOptOutRaidMapIcon.Value; } return true; } private static bool IsIconKindEnabled(RaidMapIconKind kind) { return kind switch { RaidMapIconKind.OfflineRaid => MapIconsConfig.EnableOfflineRaidMapIcon.Value, RaidMapIconKind.DecayRaid => MapIconsConfig.EnableDecayRaidMapIcon.Value, RaidMapIconKind.OptIn => MapIconsConfig.EnableOptInRaidMapIcon.Value, RaidMapIconKind.OptOut => MapIconsConfig.EnableOptOutRaidMapIcon.Value, _ => false, }; } private static bool TryGetIconPrefabGuid(RaidMapIconKind kind, out PrefabGUID iconPrefabGuid) { //IL_0001: 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_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) iconPrefabGuid = default(PrefabGUID); if (IsPassiveStateIconKind(kind)) { iconPrefabGuid = MapIconPrefabCatalog.PassiveRaidStateMapIcon.Guid; return true; } iconPrefabGuid = PrefabGuidResolver.ResolveMapIconOrDefault(kind switch { RaidMapIconKind.OfflineRaid => MapIconsConfig.OfflineRaidMapIconPrefab.Value, RaidMapIconKind.DecayRaid => MapIconsConfig.DecayRaidMapIconPrefab.Value, _ => MapIconPrefabCatalog.DefaultRaidForgeMapIcon.Name, }, MapIconPrefabCatalog.DefaultRaidForgeMapIcon, $"{kind} map icon"); return true; } private static int GetIconPriority(RaidMapIconKind kind) { if (kind != RaidMapIconKind.OfflineRaid && kind != RaidMapIconKind.DecayRaid) { return 1; } return 2; } private static HashSet GetKnownRaidForgeIconGuidHashes() { HashSet hashSet = new HashSet { MapIconPrefabCatalog.DefaultRaidForgeMapIcon.GuidHash, MapIconPrefabCatalog.PassiveRaidStateMapIcon.GuidHash, MapIconPrefabCatalog.RecommendedTerritoryMapIcon.GuidHash, MapIconPrefabCatalog.HistoricalRelicSpawnBaseMapIcon.GuidHash, MapIconPrefabCatalog.HistoricalRelicBaseMapIcon.GuidHash, MapIconPrefabCatalog.HistoricalCastleHeartMapIcon.GuidHash }; if (TryGetPrefabGuidByName(MapIconPrefabCatalog.PassiveRaidStateMapIcon.Name, out var prefabGuid)) { hashSet.Add(((PrefabGUID)(ref prefabGuid)).GuidHash); } if (MapIconsConfig.OfflineRaidMapIconPrefab != null && PrefabGuidResolver.TryResolveMapIcon(MapIconsConfig.OfflineRaidMapIconPrefab.Value, out var prefabGuid2)) { hashSet.Add(((PrefabGUID)(ref prefabGuid2)).GuidHash); } if (MapIconsConfig.DecayRaidMapIconPrefab != null && PrefabGuidResolver.TryResolveMapIcon(MapIconsConfig.DecayRaidMapIconPrefab.Value, out var prefabGuid3)) { hashSet.Add(((PrefabGUID)(ref prefabGuid3)).GuidHash); } return hashSet; } private static bool IsPassiveStateIconKind(RaidMapIconKind kind) { if (kind != RaidMapIconKind.OptIn) { return kind == RaidMapIconKind.OptOut; } return true; } private static void RemoveStaleIconEntitiesForHeart(EntityManager em, Entity castleHeartEntity, Entity keepProxy) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0150: 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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) if (em == default(EntityManager) || castleHeartEntity == Entity.Null || !((EntityManager)(ref em)).Exists(castleHeartEntity)) { return; } PrefabGUID proxyPrefabGuid; bool flag = TryGetMapIconProxyPrefabGuid(out proxyPrefabGuid); HashSet knownRaidForgeIconGuidHashes = GetKnownRaidForgeIconGuidHashes(); HashSet hashSet = new HashSet(); HashSet hashSet2 = new HashSet(); EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); try { val = GetMapIconAttachQuery(em); if (!((EntityQuery)(ref val)).IsEmptyIgnoreFilter && flag) { val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref em)).Exists(current) && ((EntityManager)(ref em)).HasComponent(current) && IsKnownRaidForgeIconEntity(em, current, knownRaidForgeIconGuidHashes)) { Entity parent = ((EntityManager)(ref em)).GetComponentData(current).Parent; if (!(parent == Entity.Null) && !(parent == keepProxy) && ((EntityManager)(ref em)).Exists(parent) && IsRaidForgeMapIconProxyEntity(em, parent, proxyPrefabGuid) && !(((EntityManager)(ref em)).GetComponentData(parent).Value != castleHeartEntity)) { hashSet2.Add(current); hashSet.Add(parent); } } } } } finally { if (val2.IsCreated) { val2.Dispose(); } } foreach (Entity item in hashSet2) { DestroyEntityIfAlive(em, item); } foreach (Entity item2 in hashSet) { DestroyAttachedIconEntities(em, item2); DestroyEntityIfAlive(em, item2); _activeIconProxies.Remove(item2); } DestroyStandaloneRaidForgeIconEntities(em, knownRaidForgeIconGuidHashes, castleHeartEntity, keepProxy); } private static int DestroyStandaloneRaidForgeIconEntities(EntityManager em, HashSet knownIconGuidHashes, Entity heartToMatch, Entity keepIcon) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); HashSet hashSet = new HashSet(); try { val = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[2] { ComponentType.ReadOnly(), ComponentType.ReadOnly() }); if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { return 0; } val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (!(current == keepIcon) && ((EntityManager)(ref em)).Exists(current) && !((EntityManager)(ref em)).HasComponent(current) && IsKnownRaidForgeIconEntity(em, current, knownIconGuidHashes)) { SpawnedBy componentData = ((EntityManager)(ref em)).GetComponentData(current); if (!(componentData.Value == Entity.Null) && (!(heartToMatch != Entity.Null) || !(componentData.Value != heartToMatch))) { hashSet.Add(current); } } } } finally { if (val2.IsCreated) { val2.Dispose(); } if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } } foreach (Entity item in hashSet) { DestroyEntityIfAlive(em, item); _activeIconProxies.Remove(item); } return hashSet.Count; } private static bool TryGetMapIconProxyPrefabGuid(out PrefabGUID proxyPrefabGuid) { //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) if (TryGetPrefabGuidByName(MapIconPrefabCatalog.MapIconProxyPrefab.Name, out proxyPrefabGuid)) { return true; } proxyPrefabGuid = MapIconPrefabCatalog.MapIconProxyPrefab.Guid; return true; } private static bool TryGetPrefabGuidByName(string prefabName, out PrefabGUID prefabGuid) { return PrefabGuidResolver.TryGetPrefabGuidByName(prefabName, out prefabGuid); } private static bool IsRaidForgeMapIconProxyEntity(EntityManager em, Entity entity, PrefabGUID proxyPrefabGuid) { //IL_0002: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (((EntityManager)(ref em)).Exists(entity) && ((EntityManager)(ref em)).HasComponent(entity) && ((EntityManager)(ref em)).HasComponent(entity)) { PrefabGUID componentData = ((EntityManager)(ref em)).GetComponentData(entity); return ((PrefabGUID)(ref componentData)).GuidHash == ((PrefabGUID)(ref proxyPrefabGuid)).GuidHash; } return false; } private static bool IsKnownRaidForgeIconEntity(EntityManager em, Entity entity, HashSet knownIconGuidHashes) { //IL_0002: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!((EntityManager)(ref em)).Exists(entity) || !((EntityManager)(ref em)).HasComponent(entity)) { return false; } PrefabGUID componentData = ((EntityManager)(ref em)).GetComponentData(entity); return knownIconGuidHashes.Contains(((PrefabGUID)(ref componentData)).GuidHash); } private static void DestroyEntityIfAlive(EntityManager em, Entity entity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (entity == Entity.Null || !((EntityManager)(ref em)).Exists(entity)) { return; } try { DestroyUtility.Destroy(em, entity, (DestroyDebugReason)0, (string)null, 0); } catch (Exception ex) { LoggingHelper.Debug($"[RaidMapIconService] DestroyUtility failed for icon entity {entity.Index}: {ex.Message}. Falling back to EntityManager.DestroyEntity."); if (((EntityManager)(ref em)).Exists(entity)) { ((EntityManager)(ref em)).DestroyEntity(entity); } } } private static void DestroyAttachedIconEntities(EntityManager em, Entity iconProxy) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (iconProxy == Entity.Null || !((EntityManager)(ref em)).Exists(iconProxy)) { return; } if (((EntityManager)(ref em)).HasBuffer(iconProxy)) { DynamicBuffer buffer = ((EntityManager)(ref em)).GetBuffer(iconProxy, false); for (int i = 0; i < buffer.Length; i++) { DestroyEntityIfAlive(em, buffer[i].Entity); } } EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); try { val = GetMapIconAttachQuery(em); if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { return; } val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref em)).Exists(current) && ((EntityManager)(ref em)).HasComponent(current) && ((EntityManager)(ref em)).GetComponentData(current).Parent == iconProxy) { DestroyEntityIfAlive(em, current); } } } finally { if (val2.IsCreated) { val2.Dispose(); } } } private static EntityQuery GetMapIconAttachQuery(EntityManager em) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) if (!_mapIconAttachQueryInitialized || _cachedMapIconAttachQueryEntityManager != em) { _mapIconAttachQuery = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[2] { ComponentType.ReadOnly(), ComponentType.ReadOnly() }); _cachedMapIconAttachQueryEntityManager = em; _mapIconAttachQueryInitialized = true; } return _mapIconAttachQuery; } } public static class ServantLimitService { private readonly struct ConvertibleCharacter { public string SourcePrefabName { get; } public string ServantPrefabName { get; } public PrefabGUID ServantPrefabGuid { get; } public ConvertibleCharacter(string sourcePrefabName, string servantPrefabName, PrefabGUID servantPrefabGuid) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) SourcePrefabName = sourcePrefabName; ServantPrefabName = servantPrefabName; ServantPrefabGuid = servantPrefabGuid; } } private readonly struct ServantLimit { public string ServantPrefabName { get; } public int MaximumPerCastle { get; } public ServantLimit(string servantPrefabName, int maximumPerCastle) { ServantPrefabName = servantPrefabName; MaximumPerCastle = maximumPerCastle; } } private readonly struct PendingReservation { public Entity CastleHeartEntity { get; } public int ServantPrefabHash { get; } public DateTime ExpiresUtc { get; } public PendingReservation(Entity castleHeartEntity, int servantPrefabHash, DateTime expiresUtc) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) CastleHeartEntity = castleHeartEntity; ServantPrefabHash = servantPrefabHash; ExpiresUtc = expiresUtc; } } private static readonly Dictionary _charactersBySourceName = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary _limitsByServantHash = new Dictionary(); private static readonly Dictionary _pendingReservations = new Dictionary(); private static readonly Dictionary _nextRejectionNoticeUtc = new Dictionary(); private static readonly List _expiredReservationCoffins = new List(); private static readonly List _expiredRejectionNoticeUsers = new List(); private static readonly TimeSpan ReservationLifetime = TimeSpan.FromSeconds(2.0); private static readonly TimeSpan RejectionNoticeCooldown = TimeSpan.FromSeconds(5.0); private static bool _catalogInitialized; public static bool HasActiveLimits { get { ConfigEntry enableServantLimits = ServantLimitsConfig.EnableServantLimits; if (enableServantLimits != null && enableServantLimits.Value) { return _limitsByServantHash.Count > 0; } return false; } } public static void ResetRuntimeState() { _charactersBySourceName.Clear(); _limitsByServantHash.Clear(); _pendingReservations.Clear(); _nextRejectionNoticeUtc.Clear(); _expiredReservationCoffins.Clear(); _expiredRejectionNoticeUsers.Clear(); _catalogInitialized = false; } public static int ReloadConfiguredLimits(EntityManager entityManager) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) _limitsByServantHash.Clear(); _pendingReservations.Clear(); _nextRejectionNoticeUtc.Clear(); if (!_catalogInitialized && !TryInitializeCharacterCatalog(entityManager)) { LoggingHelper.Warning("[ServantLimits] Convertible character catalog is unavailable; no servant limits were loaded."); return 0; } ConfigEntry enableServantLimits = ServantLimitsConfig.EnableServantLimits; if (enableServantLimits == null || !enableServantLimits.Value) { LoggingHelper.Info("[ServantLimits] Disabled."); return 0; } foreach (KeyValuePair> characterLimitEntry in ServantLimitsConfig.CharacterLimitEntries) { string text = characterLimitEntry.Value?.Value?.Trim(); if (!string.IsNullOrWhiteSpace(text)) { ConvertibleCharacter value; if (!int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result < 0) { LoggingHelper.Warning($"[ServantLimits] Ignoring {characterLimitEntry.Key}='{text}': " + "the value must be blank or a non-negative integer."); } else if (!_charactersBySourceName.TryGetValue(characterLimitEntry.Key, out value)) { LoggingHelper.Warning("[ServantLimits] Ignoring unknown convertible character '" + characterLimitEntry.Key + "'."); } else { AddActiveLimit(value, result); } } } LoggingHelper.Info($"[ServantLimits] Loaded {_limitsByServantHash.Count} active limit(s) from {_charactersBySourceName.Count} convertible character prefab(s)."); return _limitsByServantHash.Count; } public static bool TryAllowInsert(EntityManager entityManager, Entity coffinEntity, Entity userEntity, PrefabGUID servantPrefab, out int currentCount, out int limit, out string servantPrefabName) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) currentCount = 0; limit = 0; servantPrefabName = null; ConfigEntry enableServantLimits = ServantLimitsConfig.EnableServantLimits; if (enableServantLimits == null || !enableServantLimits.Value || !_limitsByServantHash.TryGetValue(((PrefabGUID)(ref servantPrefab)).GuidHash, out var value)) { return true; } limit = value.MaximumPerCastle; servantPrefabName = value.ServantPrefabName; if (!TryGetConnectedCastleHeart(entityManager, coffinEntity, out var castleHeartEntity)) { LoggingHelper.Warning($"[ServantLimits] Could not resolve a castle heart for coffin {DescribeEntity(coffinEntity)}; the {servantPrefabName} insertion was blocked."); NotifyMissingCastleHeart(entityManager, userEntity); return false; } Trace($"Evaluating user={DescribeEntity(userEntity)}, coffin={DescribeEntity(coffinEntity)}, heart={DescribeEntity(castleHeartEntity)}, servant={servantPrefabName} ({((PrefabGUID)(ref servantPrefab)).GuidHash}), maximum={limit}."); CleanupPendingReservations(entityManager); currentCount = CountExistingServants(entityManager, castleHeartEntity, ((PrefabGUID)(ref servantPrefab)).GuidHash, coffinEntity); currentCount += CountPendingReservations(castleHeartEntity, ((PrefabGUID)(ref servantPrefab)).GuidHash, coffinEntity); if (currentCount >= limit) { NotifyLimitReached(entityManager, userEntity, servantPrefabName); Trace($"BLOCK servant={servantPrefabName}, heart={DescribeEntity(castleHeartEntity)}, otherMatchingCoffins={currentCount}, maximum={limit}, interactedCoffin={DescribeEntity(coffinEntity)}."); return false; } _pendingReservations[coffinEntity] = new PendingReservation(castleHeartEntity, ((PrefabGUID)(ref servantPrefab)).GuidHash, DateTime.UtcNow + ReservationLifetime); Trace($"ALLOW servant={servantPrefabName}, heart={DescribeEntity(castleHeartEntity)}, otherMatchingCoffins={currentCount}, maximum={limit}; reserved coffin={DescribeEntity(coffinEntity)} for {ReservationLifetime.TotalSeconds:0.#}s."); return true; } public static void LogCountSnapshot(EntityManager entityManager, Entity coffinEntity, Entity userEntity, PrefabGUID servantPrefab, string action) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0171: 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_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) ConfigEntry enableDetailedLogging = ServantLimitsConfig.EnableDetailedLogging; if (enableDetailedLogging != null && enableDetailedLogging.Value) { if (!_limitsByServantHash.TryGetValue(((PrefabGUID)(ref servantPrefab)).GuidHash, out var value)) { Trace($"ACTION action={action}, user={DescribeEntity(userEntity)}, coffin={DescribeEntity(coffinEntity)}, targetHash={((PrefabGUID)(ref servantPrefab)).GuidHash}; " + "no active limit exists for this final servant prefab."); return; } if (!TryGetConnectedCastleHeart(entityManager, coffinEntity, out var castleHeartEntity)) { Trace($"ACTION action={action}, user={DescribeEntity(userEntity)}, coffin={DescribeEntity(coffinEntity)}, servant={value.ServantPrefabName}; " + "the coffin has no valid castle-heart connection."); return; } CleanupPendingReservations(entityManager); int num = CountExistingServants(entityManager, castleHeartEntity, ((PrefabGUID)(ref servantPrefab)).GuidHash, coffinEntity); int num2 = CountPendingReservations(castleHeartEntity, ((PrefabGUID)(ref servantPrefab)).GuidHash, coffinEntity); Trace($"ACTION action={action}, user={DescribeEntity(userEntity)}, coffin={DescribeEntity(coffinEntity)}, heart={DescribeEntity(castleHeartEntity)}, servant={value.ServantPrefabName} ({((PrefabGUID)(ref servantPrefab)).GuidHash}), existing={num}, pending={num2}, total={num + num2}, maximum={value.MaximumPerCastle}."); } } private static bool TryInitializeCharacterCatalog(EntityManager entityManager) { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_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_0028: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_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) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) World server = VWorld.Server; PrefabCollectionSystem val = ((server != null) ? server.GetExistingSystemManaged() : null); if (entityManager == default(EntityManager) || val == null || !val._PrefabGuidToEntityMap.IsCreated) { return false; } _charactersBySourceName.Clear(); EntityQuery val2 = default(EntityQuery); NativeArray val3 = default(NativeArray); try { EntityQueryDesc[] array = new EntityQueryDesc[1]; EntityQueryDesc val4 = new EntityQueryDesc(); val4.All = Il2CppStructArray.op_Implicit((ComponentType[])(object)new ComponentType[3] { ComponentType.ReadOnly(), ComponentType.ReadOnly(), ComponentType.ReadOnly() }); val4.Options = (EntityQueryOptions)3; array[0] = val4; val2 = ((EntityManager)(ref entityManager)).CreateEntityQuery((EntityQueryDesc[])(object)array); val3 = ((EntityQuery)(ref val2)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Enumerator enumerator = val3.GetEnumerator(); PrefabGUID sourcePrefabGuid = default(PrefabGUID); ServantConvertable val5 = default(ServantConvertable); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref entityManager)).TryGetComponentData(current, ref sourcePrefabGuid) && ((EntityManager)(ref entityManager)).TryGetComponentData(current, ref val5) && ((PrefabGUID)(ref val5.ConvertToUnit)).GuidHash != 0 && TryCreateConvertibleCharacter(entityManager, val, sourcePrefabGuid, val5.ConvertToUnit, out var character)) { _charactersBySourceName[character.SourcePrefabName] = character; } } } catch (Exception ex) { _charactersBySourceName.Clear(); LoggingHelper.Warning("[ServantLimits] Failed while discovering convertible character prefabs.", ex); return false; } finally { if (val3.IsCreated) { val3.Dispose(); } if (val2 != default(EntityQuery)) { ((EntityQuery)(ref val2)).Dispose(); } } List> list = new List>(_charactersBySourceName.Count); foreach (ConvertibleCharacter value in _charactersBySourceName.Values) { list.Add(new KeyValuePair(value.SourcePrefabName, value.ServantPrefabName)); } list.Sort((KeyValuePair left, KeyValuePair right) => StringComparer.Ordinal.Compare(left.Key, right.Key)); ServantLimitsConfig.RegisterCharacterLimits(list); _catalogInitialized = true; LoggingHelper.Info($"[ServantLimits] Generated {_charactersBySourceName.Count} regular CHAR_ to servant prefab entries."); Trace($"Character catalog registration complete with {_charactersBySourceName.Count} convertible source prefab(s)."); return true; } private static bool TryCreateConvertibleCharacter(EntityManager entityManager, PrefabCollectionSystem prefabCollection, PrefabGUID sourcePrefabGuid, PrefabGUID servantPrefabGuid, out ConvertibleCharacter character) { //IL_0008: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) character = default(ConvertibleCharacter); Entity val = default(Entity); if (!PrefabGuidResolver.TryGetPrefabName(sourcePrefabGuid, out var prefabName) || !prefabName.StartsWith("CHAR_", StringComparison.Ordinal) || prefabName.EndsWith("_Servant", StringComparison.OrdinalIgnoreCase) || !PrefabGuidResolver.TryGetPrefabName(servantPrefabGuid, out var prefabName2) || !prefabName2.StartsWith("CHAR_", StringComparison.Ordinal) || !prefabName2.EndsWith("_Servant", StringComparison.OrdinalIgnoreCase) || !prefabCollection._PrefabGuidToEntityMap.TryGetValue(servantPrefabGuid, ref val) || !((EntityManager)(ref entityManager)).Exists(val) || !((EntityManager)(ref entityManager)).HasComponent(val)) { return false; } character = new ConvertibleCharacter(prefabName, prefabName2, servantPrefabGuid); return true; } private static void AddActiveLimit(ConvertibleCharacter character, int maximumPerCastle) { //IL_0007: 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_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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) Dictionary limitsByServantHash = _limitsByServantHash; PrefabGUID servantPrefabGuid = character.ServantPrefabGuid; if (limitsByServantHash.TryGetValue(((PrefabGUID)(ref servantPrefabGuid)).GuidHash, out var value)) { int num = Math.Min(value.MaximumPerCastle, maximumPerCastle); Dictionary limitsByServantHash2 = _limitsByServantHash; servantPrefabGuid = character.ServantPrefabGuid; limitsByServantHash2[((PrefabGUID)(ref servantPrefabGuid)).GuidHash] = new ServantLimit(character.ServantPrefabName, num); LoggingHelper.Warning($"[ServantLimits] Multiple regular characters resolve to {character.ServantPrefabName}; using the strictest configured limit ({num})."); return; } Dictionary limitsByServantHash3 = _limitsByServantHash; servantPrefabGuid = character.ServantPrefabGuid; limitsByServantHash3.Add(((PrefabGUID)(ref servantPrefabGuid)).GuidHash, new ServantLimit(character.ServantPrefabName, maximumPerCastle)); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(45, 4); defaultInterpolatedStringHandler.AppendLiteral("[ServantLimits] "); defaultInterpolatedStringHandler.AppendFormatted(character.SourcePrefabName); defaultInterpolatedStringHandler.AppendLiteral(" -> "); defaultInterpolatedStringHandler.AppendFormatted(character.ServantPrefabName); defaultInterpolatedStringHandler.AppendLiteral(" "); defaultInterpolatedStringHandler.AppendLiteral("("); servantPrefabGuid = character.ServantPrefabGuid; defaultInterpolatedStringHandler.AppendFormatted(((PrefabGUID)(ref servantPrefabGuid)).GuidHash); defaultInterpolatedStringHandler.AppendLiteral("), maximum "); defaultInterpolatedStringHandler.AppendFormatted(maximumPerCastle); defaultInterpolatedStringHandler.AppendLiteral(" per castle."); LoggingHelper.Info(defaultInterpolatedStringHandler.ToStringAndClear()); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler2 = new DefaultInterpolatedStringHandler(50, 4); defaultInterpolatedStringHandler2.AppendLiteral("Activated source="); defaultInterpolatedStringHandler2.AppendFormatted(character.SourcePrefabName); defaultInterpolatedStringHandler2.AppendLiteral(", target="); defaultInterpolatedStringHandler2.AppendFormatted(character.ServantPrefabName); defaultInterpolatedStringHandler2.AppendLiteral(", "); defaultInterpolatedStringHandler2.AppendLiteral("targetHash="); servantPrefabGuid = character.ServantPrefabGuid; defaultInterpolatedStringHandler2.AppendFormatted(((PrefabGUID)(ref servantPrefabGuid)).GuidHash); defaultInterpolatedStringHandler2.AppendLiteral(", maximum="); defaultInterpolatedStringHandler2.AppendFormatted(maximumPerCastle); defaultInterpolatedStringHandler2.AppendLiteral("."); Trace(defaultInterpolatedStringHandler2.ToStringAndClear()); } private static bool TryGetConnectedCastleHeart(EntityManager entityManager, Entity coffinEntity, out Entity castleHeartEntity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0029: 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_002f: 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_003e: 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_0053: 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) castleHeartEntity = Entity.Null; CastleHeartConnection val = default(CastleHeartConnection); if (!((EntityManager)(ref entityManager)).Exists(coffinEntity) || !((EntityManager)(ref entityManager)).TryGetComponentData(coffinEntity, ref val)) { return false; } Entity entity = val.CastleHeartEntity._Entity; if (entity == Entity.Null || !((EntityManager)(ref entityManager)).Exists(entity) || !((EntityManager)(ref entityManager)).HasComponent(entity)) { return false; } castleHeartEntity = entity; return true; } private static int CountExistingServants(EntityManager entityManager, Entity castleHeartEntity, int servantPrefabHash, Entity coffinToExclude) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0022: Expected O, but got Unknown //IL_002b: 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_0037: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: 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_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_0216: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); int num = 0; try { EntityQueryDesc[] array = new EntityQueryDesc[1]; EntityQueryDesc val3 = new EntityQueryDesc(); val3.All = Il2CppStructArray.op_Implicit((ComponentType[])(object)new ComponentType[2] { ComponentType.ReadOnly(), ComponentType.ReadOnly() }); val3.Options = (EntityQueryOptions)2; array[0] = val3; val = ((EntityManager)(ref entityManager)).CreateEntityQuery((EntityQueryDesc[])(object)array); if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { return 0; } val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (current == coffinToExclude) { Trace("Ignoring interacted coffin=" + DescribeEntity(current) + " while counting existing servants."); continue; } ServantCoffinstation componentData = ((EntityManager)(ref entityManager)).GetComponentData(current); if ((int)componentData.State != 0 && ((PrefabGUID)(ref componentData.ConvertToUnit)).GuidHash == servantPrefabHash) { Entity entity = ((EntityManager)(ref entityManager)).GetComponentData(current).CastleHeartEntity._Entity; bool flag = entity == castleHeartEntity; Trace($"Matching occupied coffin={DescribeEntity(current)}, state={componentData.State}, targetHash={((PrefabGUID)(ref componentData.ConvertToUnit)).GuidHash}, heart={DescribeEntity(entity)}, matchesInteractedHeart={flag}."); if (flag) { num++; } } } } finally { if (val2.IsCreated) { val2.Dispose(); } if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } } Trace($"Existing count for heart={DescribeEntity(castleHeartEntity)}, targetHash={servantPrefabHash}, excluding={DescribeEntity(coffinToExclude)} is {num}."); return num; } private static void CleanupPendingReservations(EntityManager entityManager) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) if (_pendingReservations.Count == 0) { return; } DateTime utcNow = DateTime.UtcNow; _expiredReservationCoffins.Clear(); ServantCoffinstation val = default(ServantCoffinstation); foreach (KeyValuePair pendingReservation in _pendingReservations) { bool flag = pendingReservation.Value.ExpiresUtc <= utcNow; bool flag2 = !((EntityManager)(ref entityManager)).Exists(pendingReservation.Key); bool value = false; bool flag3 = flag || flag2; if (!flag3 && ((EntityManager)(ref entityManager)).TryGetComponentData(pendingReservation.Key, ref val) && (int)val.State != 0) { value = true; flag3 = true; } if (flag3) { Trace($"Removing reservation coffin={DescribeEntity(pendingReservation.Key)}, expired={flag}, missing={flag2}, representedByCoffinState={value}."); _expiredReservationCoffins.Add(pendingReservation.Key); } } foreach (Entity expiredReservationCoffin in _expiredReservationCoffins) { _pendingReservations.Remove(expiredReservationCoffin); } _expiredReservationCoffins.Clear(); } private static int CountPendingReservations(Entity castleHeartEntity, int servantPrefabHash, Entity coffinToExclude) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_0197: 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_00ba: Unknown result type (might be due to invalid IL or missing references) int num = 0; foreach (KeyValuePair pendingReservation in _pendingReservations) { if (pendingReservation.Key == coffinToExclude) { Trace("Ignoring the interacted coffin's own pending reservation: " + DescribeEntity(pendingReservation.Key) + "."); continue; } PendingReservation value = pendingReservation.Value; if (value.CastleHeartEntity == castleHeartEntity && value.ServantPrefabHash == servantPrefabHash) { Trace($"Counting pending reservation coffin={DescribeEntity(pendingReservation.Key)}, heart={DescribeEntity(value.CastleHeartEntity)}, targetHash={value.ServantPrefabHash}, expiresUtc={value.ExpiresUtc:O}."); num++; } } Trace($"Pending count for heart={DescribeEntity(castleHeartEntity)}, targetHash={servantPrefabHash}, excluding={DescribeEntity(coffinToExclude)} is {num}."); return num; } private static void NotifyLimitReached(EntityManager entityManager, Entity userEntity, string servantPrefabName) { //IL_0002: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) User val = default(User); if (((EntityManager)(ref entityManager)).Exists(userEntity) && ((EntityManager)(ref entityManager)).TryGetComponentData(userEntity, ref val) && ShouldSendRejectionNotice(userEntity)) { string servantDisplayName = GetServantDisplayName(servantPrefabName); FixedString512Bytes val2 = default(FixedString512Bytes); ((FixedString512Bytes)(ref val2))..ctor(ChatColors.WarningText("This castle has reached the maximum number of " + servantDisplayName + " servants.")); ServerChatUtils.SendSystemMessageToClient(entityManager, val, ref val2); } } private static void NotifyMissingCastleHeart(EntityManager entityManager, Entity userEntity) { //IL_0002: 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_0016: 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_0031: Unknown result type (might be due to invalid IL or missing references) User val = default(User); if (((EntityManager)(ref entityManager)).Exists(userEntity) && ((EntityManager)(ref entityManager)).TryGetComponentData(userEntity, ref val) && ShouldSendRejectionNotice(userEntity)) { FixedString512Bytes val2 = default(FixedString512Bytes); ((FixedString512Bytes)(ref val2))..ctor(ChatColors.WarningText("This servant cannot be converted because the coffin is not connected to a valid castle heart.")); ServerChatUtils.SendSystemMessageToClient(entityManager, val, ref val2); } } private static bool ShouldSendRejectionNotice(Entity userEntity) { //IL_000b: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) DateTime utcNow = DateTime.UtcNow; if (_nextRejectionNoticeUtc.TryGetValue(userEntity, out var value) && value > utcNow) { return false; } _nextRejectionNoticeUtc[userEntity] = utcNow + RejectionNoticeCooldown; if (_nextRejectionNoticeUtc.Count <= 256) { return true; } _expiredRejectionNoticeUsers.Clear(); foreach (KeyValuePair item in _nextRejectionNoticeUtc) { if (item.Value <= utcNow) { _expiredRejectionNoticeUsers.Add(item.Key); } } foreach (Entity expiredRejectionNoticeUser in _expiredRejectionNoticeUsers) { _nextRejectionNoticeUtc.Remove(expiredRejectionNoticeUser); } _expiredRejectionNoticeUsers.Clear(); return true; } private static string GetServantDisplayName(string servantPrefabName) { if (string.IsNullOrWhiteSpace(servantPrefabName)) { return "this type of"; } string text = servantPrefabName; if (text.StartsWith("CHAR_", StringComparison.OrdinalIgnoreCase)) { text = text.Substring("CHAR_".Length); } if (text.EndsWith("_Servant", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(0, text.Length - "_Servant".Length); } return text.Replace('_', ' '); } private static string DescribeEntity(Entity entity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!(entity == Entity.Null)) { return $"{entity.Index}:{entity.Version}"; } return "null"; } private static void Trace(string message) { ConfigEntry enableDetailedLogging = ServantLimitsConfig.EnableDetailedLogging; if (enableDetailedLogging != null && enableDetailedLogging.Value) { LoggingHelper.Info("[ServantLimits:Trace] " + message); } } } public class ShardVulnerabilityEntry { public string OwnerKey { get; set; } public int ShardPrefabGuid { get; set; } public string LatchedByUserKey { get; set; } public string ContextualName { get; set; } public long LatchedAtTicks { get; set; } } public static class ShardVulnerabilityService { private static Dictionary> _vulnerabilityByOwnerKey = new Dictionary>(); private static readonly object _stateLock = new object(); private static bool _dataLoaded = false; private static readonly string DataSubfolder = "Data"; private static readonly string SaveFileName = "RaidForge_ShardVulnerability.csv"; private static string GetSaveFilePath() { string text = Path.Combine(Paths.ConfigPath, "RaidForge", DataSubfolder); Directory.CreateDirectory(text); return Path.Combine(text, SaveFileName); } public static void ResetRuntimeState() { lock (_stateLock) { _vulnerabilityByOwnerKey.Clear(); _dataLoaded = false; ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Info("[ShardVulnerabilityService] Runtime state reset."); } } } public static void ReloadStateFromDisk() { LoadStateFromDisk(forceReload: true); } public static void LoadStateFromDisk(bool forceReload = false) { if (_dataLoaded && !forceReload) { return; } lock (_stateLock) { if (_dataLoaded && !forceReload) { return; } string saveFilePath = GetSaveFilePath(); if (!File.Exists(saveFilePath)) { _vulnerabilityByOwnerKey.Clear(); _dataLoaded = true; return; } try { Dictionary> dictionary = new Dictionary>(); int num = 0; foreach (string item2 in SharedFileIO.ReadAllLinesShared(saveFilePath).Skip(1)) { if (string.IsNullOrWhiteSpace(item2)) { continue; } string[] array = DelimitedText.ParseLine(item2, '|'); if (array.Length < 5) { continue; } string text = array[0].Trim(); if (int.TryParse(array[1].Trim(), out var shardGuid) && long.TryParse(array[4].Trim(), out var result)) { ShardVulnerabilityEntry item = new ShardVulnerabilityEntry { OwnerKey = text, ShardPrefabGuid = shardGuid, LatchedByUserKey = array[2].Trim(), ContextualName = array[3].Trim(), LatchedAtTicks = result }; if (!dictionary.ContainsKey(text)) { dictionary[text] = new List(); } dictionary[text].RemoveAll((ShardVulnerabilityEntry e) => e.ShardPrefabGuid == shardGuid); dictionary[text].Add(item); num++; } } _vulnerabilityByOwnerKey = dictionary; _dataLoaded = true; ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Info($"[ShardVulnerabilityService] Loaded {_vulnerabilityByOwnerKey.Count} owners with {num} total shard vulnerabilities."); } } catch (Exception ex) { LoggingHelper.Error("[ShardVulnerabilityService] Critical failure loading state from disk. Runtime state will remain empty to prevent data corruption.", ex); } } } private static void SaveStateToDisk() { string content = string.Empty; lock (_stateLock) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("OwnerKey|ShardPrefabGuid|LatchedByUserKey|ContextualName|LatchedAtTicks"); foreach (List value4 in _vulnerabilityByOwnerKey.Values) { foreach (ShardVulnerabilityEntry item in value4) { string value = DelimitedText.Escape(item.OwnerKey, '|'); string value2 = DelimitedText.Escape(item.LatchedByUserKey, '|'); string value3 = DelimitedText.Escape(item.ContextualName ?? "Unknown", '|'); StringBuilder stringBuilder2 = stringBuilder; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(4, 5, stringBuilder2); handler.AppendFormatted(value); handler.AppendLiteral("|"); handler.AppendFormatted(item.ShardPrefabGuid); handler.AppendLiteral("|"); handler.AppendFormatted(value2); handler.AppendLiteral("|"); handler.AppendFormatted(value3); handler.AppendLiteral("|"); handler.AppendFormatted(item.LatchedAtTicks); stringBuilder2.AppendLine(ref handler); } } content = stringBuilder.ToString(); } try { SharedFileIO.QueueWriteAllTextWithRetry(GetSaveFilePath(), content); } catch (Exception ex) { LoggingHelper.Error("[ShardVulnerabilityService] Failed to save state to disk.", ex); } } public static void Flush() { SaveStateToDisk(); } public static void SetVulnerable(string ownerKey, int shardPrefabGuid, string latchedByUserKey, string contextualName, int maxCopiesForThisShard = 1, bool deferSave = false) { if (!_dataLoaded) { LoadStateFromDisk(); } if (string.IsNullOrEmpty(ownerKey) || string.IsNullOrEmpty(latchedByUserKey)) { return; } lock (_stateLock) { if (!_vulnerabilityByOwnerKey.ContainsKey(ownerKey)) { _vulnerabilityByOwnerKey[ownerKey] = new List(); } List list = _vulnerabilityByOwnerKey[ownerKey]; ShardVulnerabilityEntry shardVulnerabilityEntry = list.FirstOrDefault((ShardVulnerabilityEntry e) => e.ShardPrefabGuid == shardPrefabGuid); if (shardVulnerabilityEntry != null) { shardVulnerabilityEntry.LatchedByUserKey = latchedByUserKey; shardVulnerabilityEntry.ContextualName = contextualName; shardVulnerabilityEntry.LatchedAtTicks = DateTime.UtcNow.Ticks; ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Info($"[ShardVulnerabilityService] Updated vulnerability for {contextualName} (Shard: {shardPrefabGuid}) latched by {latchedByUserKey}."); } } else { list.Add(new ShardVulnerabilityEntry { OwnerKey = ownerKey, ShardPrefabGuid = shardPrefabGuid, LatchedByUserKey = latchedByUserKey, ContextualName = contextualName, LatchedAtTicks = DateTime.UtcNow.Ticks }); ConfigEntry enableVerboseLogging2 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging2 != null && enableVerboseLogging2.Value) { LoggingHelper.Info($"[ShardVulnerabilityService] Added NEW vulnerability for {contextualName} (Shard: {shardPrefabGuid}) latched by {latchedByUserKey}."); } } if (maxCopiesForThisShard > 0) { List list2 = (from e in _vulnerabilityByOwnerKey.Values.SelectMany((List x) => x) where e.ShardPrefabGuid == shardPrefabGuid orderby e.LatchedAtTicks descending select e).ToList(); if (list2.Count > maxCopiesForThisShard) { foreach (ShardVulnerabilityEntry item in list2.Skip(maxCopiesForThisShard)) { _vulnerabilityByOwnerKey[item.OwnerKey].Remove(item); if (_vulnerabilityByOwnerKey[item.OwnerKey].Count == 0) { _vulnerabilityByOwnerKey.Remove(item.OwnerKey); } ConfigEntry enableVerboseLogging3 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging3 != null && enableVerboseLogging3.Value) { LoggingHelper.Info($"[ShardVulnerabilityService] Uniqueness enforced: Removed old vulnerability for {item.ContextualName} holding Shard {shardPrefabGuid}."); } } } } } if (!deferSave) { SaveStateToDisk(); } } public static void ClearAllForOwner(string ownerKey) { if (!_dataLoaded) { LoadStateFromDisk(); } if (string.IsNullOrEmpty(ownerKey)) { return; } bool flag = false; lock (_stateLock) { flag = _vulnerabilityByOwnerKey.Remove(ownerKey); } if (flag) { ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Info("[ShardVulnerabilityService] Cleared ALL vulnerabilities for OwnerKey: " + ownerKey + "."); } SaveStateToDisk(); } } public static bool ClearAllShardsForOwnerIfLatchedBy(string ownerKey, string latchedByUserKey) { if (!_dataLoaded) { LoadStateFromDisk(); } if (string.IsNullOrEmpty(ownerKey) || string.IsNullOrEmpty(latchedByUserKey)) { return false; } bool flag = false; lock (_stateLock) { if (_vulnerabilityByOwnerKey.TryGetValue(ownerKey, out var value) && value.RemoveAll((ShardVulnerabilityEntry e) => e.LatchedByUserKey == latchedByUserKey) > 0) { if (value.Count == 0) { _vulnerabilityByOwnerKey.Remove(ownerKey); } flag = true; } } if (flag) { ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Info($"[ShardVulnerabilityService] Cleared ALL shards for OwnerKey: {ownerKey} that were latched by {latchedByUserKey}."); } SaveStateToDisk(); return true; } return false; } public static bool IsVulnerable(string ownerKey) { if (!_dataLoaded) { LoadStateFromDisk(); } if (string.IsNullOrEmpty(ownerKey)) { return false; } lock (_stateLock) { return _vulnerabilityByOwnerKey.ContainsKey(ownerKey) && _vulnerabilityByOwnerKey[ownerKey].Count > 0; } } public static List GetEntriesForOwner(string ownerKey) { if (!_dataLoaded) { LoadStateFromDisk(); } if (string.IsNullOrEmpty(ownerKey)) { return new List(); } lock (_stateLock) { if (_vulnerabilityByOwnerKey.TryGetValue(ownerKey, out var value)) { return value.ToList(); } return new List(); } } } internal static class TntDamageDiagnosticService { private readonly struct GraphNode { public Entity Entity { get; } public int Depth { get; } public string Relation { get; } public GraphNode(Entity entity, int depth, string relation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) Entity = entity; Depth = depth; Relation = relation; } } private static readonly TimeSpan SourceLogCooldown = TimeSpan.FromSeconds(2.0); private const int MaxTrackedSources = 256; private const int MaxGraphDepth = 4; private const int MaxGraphNodes = 16; private static readonly Dictionary _lastLogBySource = new Dictionary(); public static void ResetRuntimeState() { _lastLogBySource.Clear(); } public static void TryLogCastleDamageEvent(EntityManager entityManager, Entity damageEventEntity, DealDamageEvent damageEvent, DateTime nowUtc) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_001f: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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_010d: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) try { Entity val = (((EntityManager)(ref entityManager)).Exists(damageEvent.SpellSource) ? damageEvent.SpellSource : damageEvent.Target); if (!(val != Entity.Null) || !_lastLogBySource.TryGetValue(val, out var value) || !(nowUtc - value < SourceLogCooldown)) { if (_lastLogBySource.Count >= 256) { _lastLogBySource.Clear(); } if (val != Entity.Null) { _lastLogBySource[val] = nowUtc; } EntityTypeModifiers materialModifiers = damageEvent.MaterialModifiers; StringBuilder stringBuilder = new StringBuilder(1024); stringBuilder.Append("[TNT-DIAG] Castle DealDamage event "); stringBuilder.Append(FormatEntityId(damageEventEntity)); stringBuilder.Append(" target="); AppendEntityDescription(stringBuilder, entityManager, damageEvent.Target); stringBuilder.Append(" source="); AppendEntityDescription(stringBuilder, entityManager, damageEvent.SpellSource); stringBuilder.Append(" damage={type="); stringBuilder.Append(damageEvent.MainType); stringBuilder.Append(", main="); stringBuilder.Append(FormatFloat(damageEvent.MainFactor)); stringBuilder.Append(", raw="); stringBuilder.Append(FormatFloat(damageEvent.RawDamage)); stringBuilder.Append(", rawPercent="); stringBuilder.Append(FormatFloat(damageEvent.RawDamagePercent)); stringBuilder.Append(", modifier="); stringBuilder.Append(FormatFloat(damageEvent.Modifier)); stringBuilder.Append(", flags="); stringBuilder.Append(damageEvent.DealDamageFlags.ToString(CultureInfo.InvariantCulture)); stringBuilder.Append("} materials={castle="); stringBuilder.Append(FormatFloat(materialModifiers.CastleObject)); stringBuilder.Append(", basic="); stringBuilder.Append(FormatFloat(materialModifiers.BasicStructure)); stringBuilder.Append(", reinforced="); stringBuilder.Append(FormatFloat(materialModifiers.ReinforcedStructure)); stringBuilder.Append(", fortified="); stringBuilder.Append(FormatFloat(materialModifiers.FortifiedStructure)); stringBuilder.Append(", stone="); stringBuilder.Append(FormatFloat(materialModifiers.StoneStructure)); stringBuilder.Append(", explosives="); stringBuilder.Append(FormatFloat(materialModifiers.Explosives)); stringBuilder.Append(", siegeAltar="); stringBuilder.Append(FormatFloat(materialModifiers.SiegeAltar)); stringBuilder.Append("} sourceGraph="); AppendSourceGraph(stringBuilder, entityManager, damageEvent.SpellSource); LoggingHelper.Info(stringBuilder.ToString()); } } catch (Exception ex) { LoggingHelper.Warning("[TNT-DIAG] Failed to describe a castle damage event.", ex); } } private static void AppendSourceGraph(StringBuilder message, EntityManager entityManager, Entity rootEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) if (rootEntity == Entity.Null || !((EntityManager)(ref entityManager)).Exists(rootEntity)) { message.Append("[unavailable]"); return; } Queue queue = new Queue(); HashSet hashSet = new HashSet(); queue.Enqueue(new GraphNode(rootEntity, 0, "root")); int num = 0; EntityOwner val = default(EntityOwner); EntityCreator val2 = default(EntityCreator); UserOwner val3 = default(UserOwner); AbilityOwner val4 = default(AbilityOwner); while (queue.Count > 0 && num < 16) { GraphNode graphNode = queue.Dequeue(); if (graphNode.Entity == Entity.Null || !((EntityManager)(ref entityManager)).Exists(graphNode.Entity) || !hashSet.Add(graphNode.Entity)) { continue; } if (num > 0) { message.Append(" -> "); } message.Append('['); message.Append(graphNode.Relation); message.Append(':'); AppendEntityDescription(message, entityManager, graphNode.Entity); message.Append(']'); num++; if (graphNode.Depth < 4) { int depth = graphNode.Depth + 1; if (((EntityManager)(ref entityManager)).TryGetComponentData(graphNode.Entity, ref val)) { EnqueueIfValid(queue, val.Owner, depth, "EntityOwner"); } if (((EntityManager)(ref entityManager)).TryGetComponentData(graphNode.Entity, ref val2)) { EnqueueIfValid(queue, val2.Creator._Entity, depth, "EntityCreator"); } if (((EntityManager)(ref entityManager)).TryGetComponentData(graphNode.Entity, ref val3)) { EnqueueIfValid(queue, val3.Owner._Entity, depth, "UserOwner"); } if (((EntityManager)(ref entityManager)).TryGetComponentData(graphNode.Entity, ref val4)) { EnqueueIfValid(queue, val4.AbilityGroup._Entity, depth, "AbilityGroup"); EnqueueIfValid(queue, val4.Ability._Entity, depth, "Ability"); } } } if (num == 0) { message.Append("[no live source nodes]"); } else if (queue.Count > 0) { message.Append(" -> [truncated]"); } } private static void EnqueueIfValid(Queue pending, Entity entity, int depth, string relation) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (entity != Entity.Null) { pending.Enqueue(new GraphNode(entity, depth, relation)); } } private static void AppendEntityDescription(StringBuilder message, EntityManager entityManager, Entity entity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0033: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) message.Append(FormatEntityId(entity)); if (entity == Entity.Null || !((EntityManager)(ref entityManager)).Exists(entity)) { message.Append("(missing)"); return; } PrefabGUID prefabGuid = default(PrefabGUID); if (((EntityManager)(ref entityManager)).TryGetComponentData(entity, ref prefabGuid)) { message.Append('('); if (PrefabGuidResolver.TryGetPrefabName(prefabGuid, out var prefabName)) { message.Append(prefabName); } else { message.Append("unknown-prefab"); } message.Append('#'); message.Append(((PrefabGUID)(ref prefabGuid)).GuidHash.ToString(CultureInfo.InvariantCulture)); if (PrefabData.IsTntItemPrefab(prefabGuid)) { message.Append(",tnt-item"); } else if (PrefabData.IsTntPlaceablePrefab(prefabGuid)) { message.Append(",tnt-placeable"); } message.Append(')'); } else { message.Append("(no-prefab)"); } message.Append('{'); bool needsSeparator = false; AppendTag(message, ((EntityManager)(ref entityManager)).HasComponent(entity), "Explosive", ref needsSeparator); AppendTag(message, ((EntityManager)(ref entityManager)).HasComponent(entity), "EntityOwner", ref needsSeparator); AppendTag(message, ((EntityManager)(ref entityManager)).HasComponent(entity), "EntityCreator", ref needsSeparator); AppendTag(message, ((EntityManager)(ref entityManager)).HasComponent(entity), "UserOwner", ref needsSeparator); AppendTag(message, ((EntityManager)(ref entityManager)).HasComponent(entity), "AbilityOwner", ref needsSeparator); AppendTag(message, ((EntityManager)(ref entityManager)).HasComponent(entity), "PlayerCharacter", ref needsSeparator); AppendTag(message, ((EntityManager)(ref entityManager)).HasComponent(entity), "User", ref needsSeparator); message.Append('}'); } private static void AppendTag(StringBuilder message, bool include, string tag, ref bool needsSeparator) { if (include) { if (needsSeparator) { message.Append(','); } message.Append(tag); needsSeparator = true; } } private static string FormatEntityId(Entity entity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (!(entity == Entity.Null)) { return entity.Index.ToString(CultureInfo.InvariantCulture) + ":" + entity.Version.ToString(CultureInfo.InvariantCulture); } return "null"; } private static string FormatFloat(float value) { return value.ToString("0.###", CultureInfo.InvariantCulture); } } } namespace RaidForge.Patches { [HarmonyPatch(typeof(SpawnCastleTeamSystem), "OnUpdate")] public static class CastleHeartSpawnPatch { public static void Prefix(SpawnCastleTeamSystem __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) EntityQuery mainQuery = __instance._MainQuery; if (((EntityQuery)(ref mainQuery)).IsEmptyIgnoreFilter) { return; } mainQuery = __instance._MainQuery; NativeArray val = ((EntityQuery)(ref mainQuery)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); try { EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { OwnershipCacheService.AddHeartToCache(enumerator.Current, entityManager); } } finally { if (val.IsCreated) { val.Dispose(); } } } } [HarmonyPatch(typeof(ClanSystem_Server), "OnUpdate")] public static class ClanCacheSyncPatch { private static readonly Dictionary _preClanSnapshot = new Dictionary(); public static void Prefix(ClanSystem_Server __instance) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0046: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.SystemsInitialized || !HasRelevantClanEvents(__instance)) { return; } _preClanSnapshot.Clear(); EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); try { val = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { return; } val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)3)); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref entityManager)).Exists(current)) { User componentData = ((EntityManager)(ref entityManager)).GetComponentData(current); _preClanSnapshot[current] = componentData.ClanEntity._Entity; } } } finally { if (val2.IsCreated) { val2.Dispose(); } if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } } } public static void Postfix(ClanSystem_Server __instance) { //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: 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_001d: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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) if (!Plugin.SystemsInitialized || _preClanSnapshot.Count == 0) { return; } EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; EntityQuery val = default(EntityQuery); NativeArray val2 = default(NativeArray); try { val = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { return; } val2 = ((EntityQuery)(ref val)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)3)); Enumerator enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref entityManager)).Exists(current)) { User componentData = ((EntityManager)(ref entityManager)).GetComponentData(current); Entity entity = componentData.ClanEntity._Entity; if (_preClanSnapshot.TryGetValue(current, out var value) && !(value == entity)) { LoggingHelper.Info($"[ClanCacheSync] Clan membership change detected for '{componentData.CharacterName}'. Updating cache."); OwnershipCacheService.UpdateUserClan(current, entity, entityManager); PlayerRegistryService.UpsertUser(entityManager, current, componentData.IsConnected); } } } } finally { if (val2.IsCreated) { val2.Dispose(); } if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } _preClanSnapshot.Clear(); } } private static bool HasRelevantClanEvents(ClanSystem_Server clanSystem) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0041: 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) EntityQuery val = clanSystem._ClanInviteResponseQuery; if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { val = clanSystem._LeaveClanEventQuery; if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { val = clanSystem._KickRequestQuery; if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { val = clanSystem._CreateClanEventQuery; if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { val = clanSystem._EditClanEventQuery; return !((EntityQuery)(ref val)).IsEmptyIgnoreFilter; } } } } return true; } } [HarmonyPatch(typeof(ClanSystem_Server), "LeaveClan")] public static class ClanLeaveHookPatch { private static void Postfix(ClanSystem_Server __instance, EntityCommandBuffer commandBuffer, ModificationsRegistry modificationsRegistry, Entity clanEntity, Entity userToLeave, LeaveReason reason, CastleHeartLimitType castleHeartLimitType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; if (entityManager == default(EntityManager) || userToLeave == Entity.Null) { return; } try { FixedString64Bytes characterName = default(FixedString64Bytes); ((FixedString64Bytes)(ref characterName))..ctor("Unknown (User Data N/A)"); if (((EntityManager)(ref entityManager)).Exists(userToLeave) && ((EntityManager)(ref entityManager)).HasComponent(userToLeave)) { characterName = ((EntityManager)(ref entityManager)).GetComponentData(userToLeave).CharacterName; } if (((EntityManager)(ref entityManager)).Exists(clanEntity)) { OfflineGraceService.HandleClanMemberDeparted(entityManager, userToLeave, clanEntity, characterName); } OwnershipCacheService.UpdateUserClan(userToLeave, Entity.Null, entityManager); PlayerRegistryService.UpsertUser(entityManager, userToLeave); } catch (Exception ex) { LoggingHelper.Error("[ClanLeaveHook] Error while updating ORP and ownership cache after clan leave.", ex); } } } [HarmonyPatch] internal static class RaidForgeVcfHelpVisibilityPatch { private sealed class HiddenHelpState { private bool _restored; public IDictionary CommandMap { get; } public List RemovedEntries { get; } = new List(); public HiddenHelpState(IDictionary commandMap) { CommandMap = commandMap; } public void Restore() { if (_restored) { return; } foreach (DictionaryEntry removedEntry in RemovedEntries) { if (!CommandMap.Contains(removedEntry.Key)) { CommandMap.Add(removedEntry.Key, removedEntry.Value); } } _restored = true; } } private static IEnumerable TargetMethods() { Type type = AccessTools.TypeByName("VampireCommandFramework.Basics.HelpCommands"); if (type == null) { return Array.Empty(); } return (from method in type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where method.Name == "HelpCommand" || method.Name == "HelpAllCommand" select method).Cast(); } private static void Prefix(ICommandContext __0, out HiddenHelpState __state) { __state = null; if (!CommandSettingsConfig.CustomSettingsEnabled || !CommandRegistryCustomizationService.TryGetRaidForgeCommandMap(out var commandMap)) { return; } HiddenHelpState hiddenHelpState = (__state = new HiddenHelpState(commandMap)); foreach (DictionaryEntry item in commandMap) { if (!CommandSettingsConfig.ShouldShowInVcfHelp(CommandRegistryCustomizationService.GetRegisteredCommandName(item.Key), __0.IsAdmin)) { hiddenHelpState.RemovedEntries.Add(item); } } foreach (DictionaryEntry removedEntry in hiddenHelpState.RemovedEntries) { commandMap.Remove(removedEntry.Key); } } private static void Postfix(HiddenHelpState __state) { __state?.Restore(); } private static Exception Finalizer(Exception __exception, HiddenHelpState __state) { __state?.Restore(); return __exception; } } public static class DamageInterceptorPatch { private sealed class DamageContext { public readonly EntityManager Em; public readonly Entity DamageEventEntity; public readonly Entity CastleHeartEntity; public readonly Entity SourceEntity; public readonly string PersistentKey; public readonly DateTime NowUtc; public readonly bool LogDebug; public readonly bool OptInEnabled; public readonly bool PurchasedOrpEnabled; public readonly bool OrpEnabled; public readonly bool AnnounceOfflineRaid; public readonly bool ShowOfflineRaidIcon; public readonly bool AnnounceDecayed; public readonly bool ForcedRaidDay; public readonly float ConfiguredGraceMinutes; public readonly bool WeaponRaidingEnabled; public readonly bool TntRaidingEnabled; public readonly float WeaponDamageMultiplier; public readonly TntTier TntTier; public readonly EntityTypeModifiers NativeTntModifiers; public readonly float TntNormalDamagePercent; public readonly float TntCastleWallDamagePercent; public readonly bool UseNormalTntDamageAfterBreach; public DealDamageEvent DamageEvent; public string CachedDefenderBaseName; public bool IsFastTrackApproved; public bool AttackerResolved; public Entity AttackerCharEntity = Entity.Null; public Entity AttackerUserEntity = Entity.Null; public string AttackerName; public string AttackerKey; public bool AllDefendersOffline; public bool CheckedAllDefendersOffline; public bool IsInGracePeriod; public bool WillBeFullyProtected; public bool IsBreached; public bool IsDecaying; public bool IsTntDamage => TntTier != TntTier.None; public DamageContext(EntityManager em, Entity damageEventEntity, Entity castleHeartEntity, Entity sourceEntity, string persistentKey, DealDamageEvent damageEvent, DateTime nowUtc, bool logDebug, bool optInEnabled, bool purchasedOrpEnabled, bool orpEnabled, bool announceOfflineRaid, bool showOfflineRaidIcon, bool announceDecayed, bool forcedRaidDay, float configuredGraceMinutes, bool weaponRaidingEnabled, bool tntRaidingEnabled, float weaponDamageMultiplier, TntTier tntTier, EntityTypeModifiers nativeTntModifiers, float tntNormalDamagePercent, float tntCastleWallDamagePercent, bool useNormalTntDamageAfterBreach) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0042: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) Em = em; DamageEventEntity = damageEventEntity; CastleHeartEntity = castleHeartEntity; SourceEntity = sourceEntity; PersistentKey = persistentKey; DamageEvent = damageEvent; NowUtc = nowUtc; LogDebug = logDebug; OptInEnabled = optInEnabled; PurchasedOrpEnabled = purchasedOrpEnabled; OrpEnabled = orpEnabled; AnnounceOfflineRaid = announceOfflineRaid; ShowOfflineRaidIcon = showOfflineRaidIcon; AnnounceDecayed = announceDecayed; ForcedRaidDay = forcedRaidDay; ConfiguredGraceMinutes = configuredGraceMinutes; WeaponRaidingEnabled = weaponRaidingEnabled; TntRaidingEnabled = tntRaidingEnabled; WeaponDamageMultiplier = weaponDamageMultiplier; TntTier = tntTier; NativeTntModifiers = nativeTntModifiers; TntNormalDamagePercent = tntNormalDamagePercent; TntCastleWallDamagePercent = tntCastleWallDamagePercent; UseNormalTntDamageAfterBreach = useNormalTntDamageAfterBreach; } } private static readonly TimeSpan OfflineProtectedMessageCooldown = TimeSpan.FromSeconds(10.0); private static Dictionary _lastProtectedMessageTimes = new Dictionary(); private static readonly TimeSpan OfflineSiegeAnnouncementCooldown = TimeSpan.FromSeconds(30.0); private static Dictionary _lastOfflineSiegeAnnouncementTimes = new Dictionary(); private static readonly TimeSpan DecayedRaidAnnouncementCooldown = TimeSpan.FromMinutes(5.0); private static Dictionary _lastDecayedRaidAnnouncementTimes = new Dictionary(); private static DateTime _nextCooldownPruneUtc = DateTime.MinValue; private static EntityQuery _damageQuery; private static EntityManager _cachedEntityManager; private static bool _queryInitialized = false; private static ServerScriptMapper _serverScriptMapper; private static ServerGameManager _serverGameManager; private static bool _sgmCached = false; private const int MaxTntSourceDepth = 4; private const int MaxCachedTntSources = 512; private static readonly Dictionary _tntTierBySource = new Dictionary(); public static void ResetRuntimeState() { //IL_000b: 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_002d: Unknown result type (might be due to invalid IL or missing references) _queryInitialized = false; _damageQuery = default(EntityQuery); _cachedEntityManager = default(EntityManager); _sgmCached = false; _serverScriptMapper = null; _serverGameManager = default(ServerGameManager); _lastProtectedMessageTimes.Clear(); _lastOfflineSiegeAnnouncementTimes.Clear(); _lastDecayedRaidAnnouncementTimes.Clear(); _tntTierBySource.Clear(); _nextCooldownPruneUtc = DateTime.MinValue; TntDamageDiagnosticService.ResetRuntimeState(); } [EcsSystemUpdatePrefix(typeof(DealDamageSystem), true)] public unsafe static void Prefix(SystemState* systemState) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_042d: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03d3: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_0460: Unknown result type (might be due to invalid IL or missing references) //IL_0462: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager = ((SystemState)systemState).EntityManager; if (!_queryInitialized || _cachedEntityManager != entityManager) { _damageQuery = ((EntityManager)(ref entityManager)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadWrite() }); _cachedEntityManager = entityManager; _queryInitialized = true; } if (((EntityQuery)(ref _damageQuery)).IsEmptyIgnoreFilter) { return; } bool value = TroubleshootingConfig.EnableVerboseLogging.Value; bool flag = TroubleshootingConfig.EnableTntDamageLogging?.Value ?? false; bool value2 = OfflineRaidProtectionConfig.EnableOfflineRaidProtection.Value; bool flag2 = OfflineRaidProtectionConfig.IsOfflineProtectionAllowedToday(); bool flag3 = OptInRaidingConfig.EnableOptInRaiding.Value && !value2; bool flag4 = PurchasedOrpConfig.IsPurchasedOrpActive(); bool value3 = OfflineRaidProtectionConfig.AnnounceOfflineRaid.Value; bool value4 = MapIconsConfig.EnableOfflineRaidMapIcon.Value; bool value5 = OfflineRaidProtectionConfig.AnnounceDecayedBaseRaid.Value; bool forcedRaidDay = OptInScheduleConfig.EnableOptInSchedule.Value && !OptInScheduleConfig.IsOptInSystemAllowedToday(); float value6 = OfflineRaidProtectionConfig.GracePeriodDurationMinutes.Value; bool value7 = WeaponRaidingConfig.EnableWeaponRaiding.Value; bool flag5 = TntRaidingConfig.EnableTntRaiding?.Value ?? false; float num = ClampTntPercent(TntRaidingConfig.T01NormalDamagePercent?.Value ?? 100f); float num2 = ClampTntPercent(TntRaidingConfig.T02NormalDamagePercent?.Value ?? 100f); float num3 = ClampTntPercent(TntRaidingConfig.T01CastleWallDamagePercent?.Value ?? 100f); float num4 = ClampTntPercent(TntRaidingConfig.T02CastleWallDamagePercent?.Value ?? 100f); bool useNormalTntDamageAfterBreach = TntRaidingConfig.UseNormalTntDamageAfterBreach?.Value ?? true; bool flag6 = Math.Abs(num - 100f) > 0.001f || Math.Abs(num2 - 100f) > 0.001f; float value8 = WeaponRaidingConfig.WeaponDamageVsStoneMultiplier.Value; bool value9 = MapIconsConfig.EnableDecayRaidMapIcon.Value; if (!flag3 && !flag4 && !flag2 && !value7 && !flag5 && !value3 && !value4 && !value5 && !value9 && !flag && !flag6) { return; } NativeArray val = ((EntityQuery)(ref _damageQuery)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); DateTime utcNow = DateTime.UtcNow; PruneInvalidCooldownEntries(entityManager, utcNow); if (!_sgmCached && VWorld.Server != null && VWorld.Server.IsCreated) { try { _serverScriptMapper = VWorld.Server.GetExistingSystemManaged(); if (_serverScriptMapper != null) { _serverGameManager = _serverScriptMapper.GetServerGameManager(); _sgmCached = true; } } catch (Exception ex) { LoggingHelper.Debug("[DamageInterceptorPatch] ServerGameManager not ready: " + ex.Message); } } try { Enumerator enumerator = val.GetEnumerator(); User val2 = default(User); while (enumerator.MoveNext()) { Entity current = enumerator.Current; try { if (!((EntityManager)(ref entityManager)).Exists(current)) { continue; } DealDamageEvent componentData = ((EntityManager)(ref entityManager)).GetComponentData(current); if (componentData.MainFactor <= 0f && componentData.RawDamage <= 0f) { continue; } Entity target = componentData.Target; Entity spellSource = componentData.SpellSource; EntityTypeModifiers materialModifiers = componentData.MaterialModifiers; TntTier tntTier = TntTier.None; float num5 = 100f; if (flag6 && materialModifiers.Explosives > 0f) { tntTier = TryGetTntTier(entityManager, spellSource); if (tntTier != TntTier.None) { num5 = ((tntTier == TntTier.T01) ? num : num2); if (Math.Abs(num5 - 100f) > 0.001f) { componentData.MaterialModifiers = ScaleMaterialModifiers(materialModifiers, num5 / 100f); ((EntityManager)(ref entityManager)).SetComponentData(current, componentData); } } } bool num6 = ((EntityManager)(ref entityManager)).HasComponent(target); bool flag7 = ((EntityManager)(ref entityManager)).HasComponent(target); if (!num6 && !flag7) { continue; } if (tntTier == TntTier.None) { tntTier = TryGetTntTier(entityManager, spellSource); if (tntTier != TntTier.None) { num5 = ((tntTier == TntTier.T01) ? num : num2); } } if (flag) { TntDamageDiagnosticService.TryLogCastleDamageEvent(entityManager, current, componentData, utcNow); } if (!TryGetDefenderKeyFromDamagedEntity(entityManager, target, out var castleHeartEntity, out var defenderKeyEntity)) { continue; } string text = null; if (defenderKeyEntity != Entity.Null) { if (((EntityManager)(ref entityManager)).HasComponent(defenderKeyEntity)) { text = PersistentKeyHelper.GetClanKey(entityManager, defenderKeyEntity); } else if (((EntityManager)(ref entityManager)).TryGetComponentData(defenderKeyEntity, ref val2)) { text = PersistentKeyHelper.GetUserKey(val2.PlatformId); } } if (!string.IsNullOrEmpty(text)) { DamageContext damageContext = new DamageContext(entityManager, current, castleHeartEntity, spellSource, text, componentData, utcNow, value, flag3, flag4, flag2, value3, value4, value5, forcedRaidDay, value6, value7, flag5, value8, tntTier, materialModifiers, num5, (tntTier == TntTier.T01) ? num3 : num4, useNormalTntDamageAfterBreach); CastleHeart componentData2 = ((EntityManager)(ref entityManager)).GetComponentData(castleHeartEntity); damageContext.IsBreached = ((CastleHeart)(ref componentData2)).IsSieged(); damageContext.IsDecaying = OfflineProtectionService.IsBaseDecaying(castleHeartEntity, entityManager); EvaluateFastTrackRules(damageContext); if (damageContext.IsFastTrackApproved || (!TryBlockByOptInRules(damageContext) && !TryBlockByPurchasedOrpRules(damageContext) && !TryBlockByOfflineProtection(damageContext))) { HandleAllowedRaidSignals(damageContext); ApplyConfiguredStructureDamage(damageContext); } } } catch (Exception ex2) { LoggingHelper.Warning("[DamageInterceptorPatch] Error processing specific damage event.", ex2); } } } finally { if (val.IsCreated) { val.Dispose(); } } } private static void EvaluateFastTrackRules(DamageContext context) { //IL_002b: 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_0053: Unknown result type (might be due to invalid IL or missing references) if (context.IsDecaying) { EnsureAttackerResolved(context); if (!IsVampireDamage(context)) { if (context.LogDebug) { LoggingHelper.Debug("[Damage] Decay raid announcement/icon skipped because damage source did not resolve to a vampire player."); } } else { RaidMapIconService.AddRaidIcon(context.CastleHeartEntity, isOfflineRaid: false, isDecayRaid: true); if (context.AnnounceDecayed && !string.IsNullOrEmpty(context.AttackerName)) { AnnounceDecayedBaseDamage(context.Em, context.CastleHeartEntity, context.AttackerName, EnsureDefenderBaseName(context), context.NowUtc); } } } if (context.IsBreached || context.IsDecaying) { if (context.LogDebug) { LoggingHelper.Debug($"[Damage] Allowed: Base {EnsureDefenderBaseName(context)} is Breached({context.IsBreached}) or Decaying({context.IsDecaying})."); } context.IsFastTrackApproved = true; } if (context.IsFastTrackApproved || !ShardConfig.DisableOrpForShardHolders.Value || !ShardVulnerabilityService.IsVulnerable(context.PersistentKey)) { return; } if (context.LogDebug) { List entriesForOwner = ShardVulnerabilityService.GetEntriesForOwner(context.PersistentKey); string text = string.Join(" | ", entriesForOwner.Select((ShardVulnerabilityEntry e) => $"Shard: {e.ShardPrefabGuid} (Latched By: {e.LatchedByUserKey})")); LoggingHelper.Debug("[Damage] Allowed: Owner '" + context.PersistentKey + "' is vulnerable. Details: " + text); } context.IsFastTrackApproved = true; } private static bool IsVampireDamage(DamageContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_002e: 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_0044: Unknown result type (might be due to invalid IL or missing references) if (context.AttackerUserEntity != Entity.Null && context.AttackerCharEntity != Entity.Null) { EntityManager em = context.Em; if (((EntityManager)(ref em)).Exists(context.AttackerCharEntity)) { em = context.Em; return ((EntityManager)(ref em)).HasComponent(context.AttackerCharEntity); } } return false; } private static bool TryBlockByOptInRules(DamageContext context) { //IL_0029: 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_0035: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) if (!context.OptInEnabled) { return false; } if (!context.ForcedRaidDay && !OptInRaidService.IsOptedIn(context.PersistentKey)) { EnsureAttackerResolved(context); BlockDamageAndNotify(context.Em, context.DamageEventEntity, context.AttackerUserEntity, EnsureDefenderBaseName(context), "PROTECTED", OptInRaidingConfig.UseDefaultOptInMode ? "(Opted-Out)" : "(Not Opted-In)", context.NowUtc); return true; } EnsureAttackerResolved(context); if (context.ForcedRaidDay || (!string.IsNullOrEmpty(context.AttackerKey) && OptInRaidService.IsOptedIn(context.AttackerKey))) { return false; } BlockDamageAndNotify(context.Em, context.DamageEventEntity, context.AttackerUserEntity, EnsureDefenderBaseName(context), "PROTECTED", "(Attacker " + (context.AttackerName ?? "Unknown") + " is not Opted-In)", context.NowUtc); return true; } private static bool TryBlockByPurchasedOrpRules(DamageContext context) { //IL_004f: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!context.PurchasedOrpEnabled) { return false; } if (!PurchasedOrpService.HasProtectionForToday(context.PersistentKey)) { return false; } if (!RaidToggleSystem.AreRaidsEnabled()) { EntityManager em = context.Em; ((EntityManager)(ref em)).DestroyEntity(context.DamageEventEntity); if (context.LogDebug) { LoggingHelper.Debug("[Damage] Purchased ORP blocked damage quietly because raids are not currently enabled."); } return true; } EnsureAttackerResolved(context); BlockDamageAndNotify(context.Em, context.DamageEventEntity, context.AttackerUserEntity, EnsureDefenderBaseName(context), "PURCHASE PROTECTED", "(Purchased ORP)", context.NowUtc); return true; } private static bool TryBlockByOfflineProtection(DamageContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) OfflineProtectionService.OfflineProtectionEvaluation offlineProtectionEvaluation = OfflineProtectionService.EvaluateHeartOfflineProtection(context.CastleHeartEntity, context.Em, context.PersistentKey, context.NowUtc, context.ConfiguredGraceMinutes, context.OrpEnabled); context.IsInGracePeriod = offlineProtectionEvaluation.IsInGracePeriod; context.AllDefendersOffline = offlineProtectionEvaluation.AllDefendersOffline; context.CheckedAllDefendersOffline = offlineProtectionEvaluation.CheckedAllDefendersOffline; context.WillBeFullyProtected = offlineProtectionEvaluation.IsProtected; if (!context.WillBeFullyProtected) { return false; } if (!RaidToggleSystem.AreRaidsEnabled()) { EntityManager em = context.Em; ((EntityManager)(ref em)).DestroyEntity(context.DamageEventEntity); if (context.LogDebug) { LoggingHelper.Debug("[Damage] ORP blocked damage quietly because raids are not currently enabled."); } return true; } EnsureAttackerResolved(context); BlockDamageAndNotify(context.Em, context.DamageEventEntity, context.AttackerUserEntity, EnsureDefenderBaseName(context), "OFFLINE PROTECTED", string.Empty, context.NowUtc); return true; } private static void HandleAllowedRaidSignals(DamageContext context) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if ((!context.AnnounceOfflineRaid && !context.ShowOfflineRaidIcon) || context.IsDecaying) { return; } if (!RaidToggleSystem.AreRaidsEnabled()) { if (context.LogDebug) { LoggingHelper.Debug("[Damage] Offline raid announcement/icon skipped because raids are not currently enabled."); } } else { if (!IsEligibleOfflineRaidSignal(context)) { return; } EnsureAttackerResolved(context); if (IsSiegeWeaponDamage(context)) { if (context.ShowOfflineRaidIcon) { RaidMapIconService.AddRaidIcon(context.CastleHeartEntity, isOfflineRaid: true, isDecayRaid: false); } if (context.AnnounceOfflineRaid) { MakeOfflineSiegeAnnouncement(context.Em, context.CastleHeartEntity, context.AttackerName, EnsureDefenderBaseName(context), context.NowUtc); } } } } private static bool IsEligibleOfflineRaidSignal(DamageContext context) { if (context.IsBreached) { if (context.LogDebug) { LoggingHelper.Debug("[Damage] Offline raid announcement/icon skipped because the base is already breached."); } return false; } EnsureAllDefendersOfflineChecked(context); if (!context.AllDefendersOffline) { if (context.LogDebug) { LoggingHelper.Debug("[Damage] Offline raid announcement/icon skipped because at least one defender is online."); } return false; } if (OfflineGraceService.TryGetOfflineStartTime(context.PersistentKey, out var offlineStartTimeUtc)) { TimeSpan timeSpan = context.NowUtc - offlineStartTimeUtc; if (context.ConfiguredGraceMinutes > 0f && timeSpan.TotalMinutes < (double)context.ConfiguredGraceMinutes) { context.IsInGracePeriod = true; if (context.LogDebug) { LoggingHelper.Debug("[Damage] Offline raid announcement/icon skipped because defenders are still in ORP grace."); } return false; } } return true; } private static void ApplyConfiguredStructureDamage(DamageContext context) { //IL_0041: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) if (!context.IsTntDamage && context.DamageEvent.MaterialModifiers.StoneStructure > 0f) { return; } if (context.IsTntDamage) { if (!context.TntRaidingEnabled) { return; } } else if (!context.WeaponRaidingEnabled) { return; } EnsureAttackerResolved(context); if (context.AttackerUserEntity == Entity.Null) { if (context.LogDebug && context.IsTntDamage) { LoggingHelper.Debug("[TNT Raiding] Stone damage was not enabled because the placing player could not be resolved."); } return; } EntityTypeModifiers materialModifiers = context.DamageEvent.MaterialModifiers; if (context.IsTntDamage) { float explosives = context.NativeTntModifiers.Explosives; if (explosives <= 0f) { if (context.LogDebug) { LoggingHelper.Debug("[TNT Raiding] Stone damage was not enabled because the native Explosives modifier was not positive."); } return; } float num = ((context.IsBreached && context.UseNormalTntDamageAfterBreach) ? context.TntNormalDamagePercent : context.TntCastleWallDamagePercent); materialModifiers.StoneStructure = explosives * (num / 100f); if (materialModifiers.StoneStructure <= 0f) { if (context.LogDebug) { LoggingHelper.Debug($"[TNT Raiding] Stone damage is disabled at {num}% while breached={context.IsBreached}."); } return; } } else { materialModifiers.StoneStructure = context.WeaponDamageMultiplier; } context.DamageEvent.MaterialModifiers = materialModifiers; EntityManager em = context.Em; ((EntityManager)(ref em)).SetComponentData(context.DamageEventEntity, context.DamageEvent); if (context.LogDebug) { if (context.IsTntDamage) { float value = ((context.IsBreached && context.UseNormalTntDamageAfterBreach) ? context.TntNormalDamagePercent : context.TntCastleWallDamagePercent); string value2 = ((context.IsBreached && context.UseNormalTntDamageAfterBreach) ? "normal-after-breach" : "castle-raid"); LoggingHelper.Debug($"[TNT Raiding] tier={context.TntTier}, StoneStructure={materialModifiers.StoneStructure} (native={context.NativeTntModifiers.Explosives}, percent={value}, mode={value2}, breached={context.IsBreached})."); } else { LoggingHelper.Debug($"[Weapon Raiding] Overwrote StoneStructure modifier to {materialModifiers.StoneStructure}."); } } } private static void EnsureAttackerResolved(DamageContext context) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (!context.AttackerResolved) { ResolveAttacker(context.Em, context.SourceEntity, ref context.AttackerResolved, ref context.AttackerCharEntity, ref context.AttackerUserEntity, ref context.AttackerName, ref context.AttackerKey); } } private static string EnsureDefenderBaseName(DamageContext context) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (context.CachedDefenderBaseName == null) { context.CachedDefenderBaseName = GetDefenderBaseName(context.Em, context.CastleHeartEntity); } return context.CachedDefenderBaseName; } private static void EnsureAllDefendersOfflineChecked(DamageContext context) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (!context.CheckedAllDefendersOffline) { context.AllDefendersOffline = OfflineProtectionService.AreAllDefendersActuallyOffline(context.CastleHeartEntity, context.Em); context.CheckedAllDefendersOffline = true; } } private static void PruneInvalidCooldownEntries(EntityManager em, DateTime nowUtc) { //IL_0024: 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_003a: Unknown result type (might be due to invalid IL or missing references) try { if (!(nowUtc < _nextCooldownPruneUtc)) { _nextCooldownPruneUtc = nowUtc.AddMinutes(1.0); PruneMissingEntityKeys(em, _lastProtectedMessageTimes); PruneMissingEntityKeys(em, _lastOfflineSiegeAnnouncementTimes); PruneMissingEntityKeys(em, _lastDecayedRaidAnnouncementTimes); } } catch (Exception ex) { LoggingHelper.Debug("[DamageInterceptorPatch] Cooldown prune failed: " + ex.Message); } } private static void PruneMissingEntityKeys(EntityManager em, Dictionary timestampsByEntity) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (timestampsByEntity.Count == 0) { return; } foreach (Entity item in timestampsByEntity.Keys.Where((Entity entity) => entity == Entity.Null || !((EntityManager)(ref em)).Exists(entity)).ToList()) { timestampsByEntity.Remove(item); } } private static void ResolveAttacker(EntityManager em, Entity sourceEntity, ref bool resolved, ref Entity charEntity, ref Entity userEntity, ref string name, ref string key) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: 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_0017: 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_0034: 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) resolved = true; if (UserHelper.TryGetPlayerOwnerFromSource(em, sourceEntity, out charEntity, out userEntity) && !(userEntity == Entity.Null) && ((EntityManager)(ref em)).Exists(userEntity)) { if (!OwnerIdentityHelper.TryResolveFromUserEntity(em, userEntity, out var owner, out var error)) { LoggingHelper.Debug("[DamageInterceptorPatch] Failed to resolve attacker owner identity: " + error); return; } name = owner.CharacterName; key = owner.PersistentKey; } } private static void BlockDamageAndNotify(EntityManager em, Entity eventEntity, Entity attackerUserEntity, string defenderBaseName, string protectionStatusKeyword, string protectionContext, DateTime nowUtc) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) ((EntityManager)(ref em)).DestroyEntity(eventEntity); if (!(attackerUserEntity == Entity.Null) && (!_lastProtectedMessageTimes.TryGetValue(attackerUserEntity, out var value) || !(nowUtc - value <= OfflineProtectedMessageCooldown))) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(ChatColors.InfoText(defenderBaseName + " is ")); stringBuilder.Append(ChatColors.AccentText(protectionStatusKeyword)); if (!string.IsNullOrEmpty(protectionContext)) { stringBuilder.Append(ChatColors.InfoText(" " + protectionContext + ".")); } else { stringBuilder.Append(ChatColors.InfoText(".")); } User val = default(User); if (((EntityManager)(ref em)).TryGetComponentData(attackerUserEntity, ref val)) { FixedString512Bytes val2 = default(FixedString512Bytes); ((FixedString512Bytes)(ref val2))..ctor(stringBuilder.ToString()); ServerChatUtils.SendSystemMessageToClient(em, val, ref val2); _lastProtectedMessageTimes[attackerUserEntity] = nowUtc; } } } private static bool TryGetDefenderKeyFromDamagedEntity(EntityManager em, Entity damagedEntity, out Entity castleHeartEntity, out Entity defenderKeyEntity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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_0018: 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_0023: 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_0029: 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_0033: 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_0045: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) castleHeartEntity = Entity.Null; defenderKeyEntity = Entity.Null; if (((EntityManager)(ref em)).HasComponent(damagedEntity)) { castleHeartEntity = ((EntityManager)(ref em)).GetComponentData(damagedEntity).CastleHeartEntity._Entity; } else if (((EntityManager)(ref em)).HasComponent(damagedEntity)) { castleHeartEntity = damagedEntity; } if (castleHeartEntity == Entity.Null || !((EntityManager)(ref em)).Exists(castleHeartEntity) || !((EntityManager)(ref em)).HasComponent(castleHeartEntity)) { return false; } if (!OwnershipCacheService.TryGetHeartOwner(castleHeartEntity, out var ownerUserEntity) || ownerUserEntity == Entity.Null) { return false; } if (!((EntityManager)(ref em)).Exists(ownerUserEntity) || !((EntityManager)(ref em)).HasComponent(ownerUserEntity)) { return false; } if (OwnershipCacheService.TryGetUserClan(ownerUserEntity, out var clanEntity) && clanEntity != Entity.Null && ((EntityManager)(ref em)).Exists(clanEntity)) { defenderKeyEntity = clanEntity; } else { defenderKeyEntity = ownerUserEntity; } return true; } private unsafe static string GetDefenderBaseName(EntityManager em, Entity castleHeartEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_004b: Unknown result type (might be due to invalid IL or missing references) UserOwner val = default(UserOwner); User val2 = default(User); if (castleHeartEntity != Entity.Null && ((EntityManager)(ref em)).TryGetComponentData(castleHeartEntity, ref val) && ((EntityManager)(ref em)).Exists(val.Owner._Entity) && ((EntityManager)(ref em)).TryGetComponentData(val.Owner._Entity, ref val2)) { NameableInteractable val3 = default(NameableInteractable); if (((EntityManager)(ref em)).TryGetComponentData(castleHeartEntity, ref val3) && !string.IsNullOrWhiteSpace(((object)(*(FixedString64Bytes*)(&val3.Name))/*cast due to .constrained prefix*/).ToString())) { return "'" + ((object)(*(FixedString64Bytes*)(&val3.Name))/*cast due to .constrained prefix*/).ToString() + "'"; } return ((object)(*(FixedString64Bytes*)(&val2.CharacterName))/*cast due to .constrained prefix*/).ToString() + "'s base"; } return "A base"; } private static bool IsSiegeWeaponDamage(DamageContext context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (context.AttackerCharEntity != Entity.Null && HasSiegeGolemBuff(context.Em, context.AttackerCharEntity)) { return true; } if (context.IsTntDamage) { if (string.IsNullOrEmpty(context.AttackerName)) { context.AttackerName = "Explosives"; } return true; } return false; } private static TntTier TryGetTntTier(EntityManager em, Entity sourceEntity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (sourceEntity == Entity.Null || !((EntityManager)(ref em)).Exists(sourceEntity)) { return TntTier.None; } if (_tntTierBySource.TryGetValue(sourceEntity, out var value)) { return value; } TntTier tntTier = ResolveTntTier(em, sourceEntity, 0); if (_tntTierBySource.Count >= 512) { _tntTierBySource.Clear(); } _tntTierBySource[sourceEntity] = tntTier; return tntTier; } private static TntTier ResolveTntTier(EntityManager em, Entity sourceEntity, int depth) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_004e: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_0058: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (depth > 4 || sourceEntity == Entity.Null || !((EntityManager)(ref em)).Exists(sourceEntity)) { return TntTier.None; } PrefabGUID prefabGuid = default(PrefabGUID); if (((EntityManager)(ref em)).TryGetComponentData(sourceEntity, ref prefabGuid)) { TntTier tntTier = PrefabData.GetTntTier(prefabGuid); if (tntTier != TntTier.None) { return tntTier; } } int depth2 = depth + 1; EntityOwner val = default(EntityOwner); if (((EntityManager)(ref em)).TryGetComponentData(sourceEntity, ref val) && val.Owner != sourceEntity) { TntTier tntTier2 = ResolveTntTier(em, val.Owner, depth2); if (tntTier2 != TntTier.None) { return tntTier2; } } EntityCreator val2 = default(EntityCreator); if (((EntityManager)(ref em)).TryGetComponentData(sourceEntity, ref val2)) { Entity entity = val2.Creator._Entity; if (entity != sourceEntity && entity != Entity.Null) { TntTier tntTier3 = ResolveTntTier(em, entity, depth2); if (tntTier3 != TntTier.None) { return tntTier3; } } } return TntTier.None; } private static float ClampTntPercent(float value) { return Math.Clamp(value, 0f, 1000f); } private static EntityTypeModifiers ScaleMaterialModifiers(EntityTypeModifiers modifiers, float multiplier) { //IL_0114: Unknown result type (might be due to invalid IL or missing references) modifiers.Human *= multiplier; modifiers.Undead *= multiplier; modifiers.Demon *= multiplier; modifiers.Mechanical *= multiplier; modifiers.Beast *= multiplier; modifiers.CastleObject *= multiplier; modifiers.PlayerVampire *= multiplier; modifiers.PvEVampire *= multiplier; modifiers.ShadowVBlood *= multiplier; modifiers.BasicStructure *= multiplier; modifiers.ReinforcedStructure *= multiplier; modifiers.FortifiedStructure *= multiplier; modifiers.StoneStructure *= multiplier; modifiers.SiegeAltar *= multiplier; modifiers.Wood *= multiplier; modifiers.Minerals *= multiplier; modifiers.Vegetation *= multiplier; modifiers.LightArmor *= multiplier; modifiers.VBlood *= multiplier; modifiers.Magic *= multiplier; modifiers.Explosives *= multiplier; modifiers.MassiveResource *= multiplier; modifiers.MonsterGate *= multiplier; return modifiers; } private static void MakeOfflineSiegeAnnouncement(EntityManager em, Entity castleHeartEntity, string attackerName, string defenderBaseName, DateTime nowUtc) { //IL_0005: 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_00b6: Unknown result type (might be due to invalid IL or missing references) if (!_lastOfflineSiegeAnnouncementTimes.TryGetValue(castleHeartEntity, out var value) || nowUtc - value > OfflineSiegeAnnouncementCooldown) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(ChatColors.HighlightText(defenderBaseName ?? "Unknown")); stringBuilder.Append(ChatColors.InfoText(" is being ")); stringBuilder.Append(ChatColors.WarningText("offline raided")); stringBuilder.Append(ChatColors.InfoText(" by ")); stringBuilder.Append(ChatColors.HighlightText(attackerName ?? "Unknown")); stringBuilder.Append(ChatColors.InfoText("!")); FixedString512Bytes val = default(FixedString512Bytes); ((FixedString512Bytes)(ref val))..ctor(stringBuilder.ToString()); ServerChatUtils.SendSystemMessageToAllClients(em, ref val); _lastOfflineSiegeAnnouncementTimes[castleHeartEntity] = nowUtc; } } private static void AnnounceDecayedBaseDamage(EntityManager em, Entity castleHeartEntity, string attackerName, string defenderBaseName, DateTime nowUtc) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) if (!_lastDecayedRaidAnnouncementTimes.TryGetValue(castleHeartEntity, out var value) || nowUtc - value > DecayedRaidAnnouncementCooldown) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(ChatColors.InfoText(defenderBaseName + " ")); stringBuilder.Append(ChatColors.WarningText("is DECAYED")); stringBuilder.Append(ChatColors.InfoText(" and being raided by ")); stringBuilder.Append(ChatColors.HighlightText(attackerName ?? "Unknown")); stringBuilder.Append(ChatColors.InfoText("!")); FixedString512Bytes val = default(FixedString512Bytes); ((FixedString512Bytes)(ref val))..ctor(stringBuilder.ToString()); ServerChatUtils.SendSystemMessageToAllClients(em, ref val); _lastDecayedRaidAnnouncementTimes[castleHeartEntity] = nowUtc; } } private static bool HasSiegeGolemBuff(EntityManager em, Entity playerCharacterEntity) { //IL_0002: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!((EntityManager)(ref em)).Exists(playerCharacterEntity) || !((EntityManager)(ref em)).HasComponent(playerCharacterEntity)) { return false; } if (!_sgmCached) { return false; } try { Entity val = default(Entity); return ((ServerGameManager)(ref _serverGameManager)).TryGetBuff(playerCharacterEntity, PrefabIdentifier.op_Implicit(PrefabData.SiegeGolemBuff.Guid), ref val); } catch (Exception ex) { LoggingHelper.Debug("[DamageInterceptorPatch] Siege golem buff check failed: " + ex.Message); return false; } } } [HarmonyPatch(typeof(TeamUtility), "ClaimCastle")] public static class TeamUtility_ClaimCastle_Patch { private static void Postfix(EntityManager entityManager, Entity userEntity, Entity castleHeartEntity, CastleHeartLimitType limitType) { //IL_0008: 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_0015: 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_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_003a: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0059: 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_005f: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (!VWorld.IsServerWorldReady() || userEntity == Entity.Null || castleHeartEntity == Entity.Null || !((EntityManager)(ref entityManager)).Exists(userEntity) || !((EntityManager)(ref entityManager)).Exists(castleHeartEntity)) { return; } if (((EntityManager)(ref entityManager)).HasComponent(castleHeartEntity) && ((EntityManager)(ref entityManager)).HasComponent(castleHeartEntity)) { Entity entity = ((EntityManager)(ref entityManager)).GetComponentData(castleHeartEntity).Owner._Entity; if (entity == userEntity) { OwnershipCacheService.UpdateHeartOwner(castleHeartEntity, userEntity, entityManager); } else if (entity != Entity.Null && ((EntityManager)(ref entityManager)).Exists(entity)) { OwnershipCacheService.UpdateHeartOwner(castleHeartEntity, entity, entityManager); } else { OwnershipCacheService.UpdateHeartOwner(castleHeartEntity, Entity.Null, entityManager); } } RaidMapIconService.RemoveDecayRaidIconsForReclaimedPlot(castleHeartEntity, entityManager); } } [HarmonyPatch(typeof(MapIconSpawnSystem), "OnUpdate")] public static class MapIconSpawnPatch { private static EntityQuery _mapIconPositionQuery; private static EntityManager _cachedEntityManager; private static bool _queryInitialized; public static void Prefix(MapIconSpawnSystem __instance) { //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) //IL_0042: Unknown result type (might be due to invalid IL or missing references) try { if ((MapIconsConfig.EnableDecayRaidMapIcon.Value || MapIconsConfig.EnableOfflineRaidMapIcon.Value || MapIconsConfig.EnableOptInRaidMapIcon.Value || MapIconsConfig.EnableOptOutRaidMapIcon.Value) && RaidMapIconService.HasActiveIcons) { EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; ApplyRaidForgeIconData(entityManager, GetMapIconPositionQuery(entityManager)); } } catch (Exception ex) { LoggingHelper.Warning("[MapIconSpawnPatch] Failed to apply RaidForge map icon visibility settings.", ex); } } private static EntityQuery GetMapIconPositionQuery(EntityManager em) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) if (!_queryInitialized || _cachedEntityManager != em) { _mapIconPositionQuery = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[2] { ComponentType.ReadWrite(), ComponentType.ReadOnly() }); _cachedEntityManager = em; _queryInitialized = true; } return _mapIconPositionQuery; } private static void ApplyRaidForgeIconData(EntityManager em, EntityQuery mapIconQuery) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0048: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_007f: 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_0093: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) NativeArray val = default(NativeArray); try { if (((EntityQuery)(ref mapIconQuery)).IsEmptyIgnoreFilter) { return; } val = ((EntityQuery)(ref mapIconQuery)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref em)).Exists(current) && ((EntityManager)(ref em)).HasComponent(current) && ((EntityManager)(ref em)).HasComponent(current)) { Entity parent = ((EntityManager)(ref em)).GetComponentData(current).Parent; if (!(parent == Entity.Null) && ((EntityManager)(ref em)).Exists(parent) && RaidMapIconService.IsRaidIconProxy(parent) && ((EntityManager)(ref em)).HasComponent(parent)) { MapIconData componentData = ((EntityManager)(ref em)).GetComponentData(current); componentData.RequiresReveal = false; componentData.ShowOutsideVision = true; componentData.ShowOnMinimap = true; componentData.AllySetting = (MapIconShowSettings)2; componentData.EnemySetting = (MapIconShowSettings)2; ((EntityManager)(ref em)).SetComponentData(current, componentData); } } } } finally { if (val.IsCreated) { val.Dispose(); } } } } [HarmonyPatch(typeof(ServerBootstrapSystem), "OnUserDisconnected")] public static class OnUserDisconnectedHookPatch { private static void Prefix(ServerBootstrapSystem __instance, NetConnectionId netConnectionId) { //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) try { if (__instance == null) { LogVerboseWarning("[RaidForge] OnUserDisconnectedHookPatch skipped: ServerBootstrapSystem instance was null."); } else { int num = default(int); if (!Plugin.SystemsInitialized || !__instance._NetEndPointToApprovedUserIndex.TryGetValue(netConnectionId, ref num)) { return; } if (__instance._ApprovedUsersLookup == null) { LogVerboseWarning("[RaidForge] OnUserDisconnectedHookPatch skipped: Approved users lookup was null."); return; } if (num < 0 || num >= ((Il2CppArrayBase)(object)__instance._ApprovedUsersLookup).Length) { LogVerboseWarning($"[RaidForge] OnUserDisconnectedHookPatch skipped: Approved user index out of range. Index: {num}, Length: {((Il2CppArrayBase)(object)__instance._ApprovedUsersLookup).Length}"); return; } ServerClient val = ((Il2CppArrayBase)(object)__instance._ApprovedUsersLookup)[num]; if (val == null) { LogVerboseWarning($"[RaidForge] OnUserDisconnectedHookPatch skipped: ServerClient was null for index {num}."); return; } Entity userEntity = val.UserEntity; EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; if (userEntity == Entity.Null) { LogVerboseWarning("[RaidForge] OnUserDisconnectedHookPatch skipped: UserEntity was null."); } else if (!((EntityManager)(ref entityManager)).Exists(userEntity)) { LogVerboseWarning($"[RaidForge] OnUserDisconnectedHookPatch skipped: UserEntity no longer exists. Entity: {userEntity}"); } else { OfflineGraceService.HandleUserDisconnected(entityManager, userEntity); PlayerRegistryService.UpsertUser(entityManager, userEntity, false); RaidMapIconService.MarkPersistentStateIconsDirty(); RaidMapIconService.ProcessCleanup(); } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; if (logger != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(57, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[RaidForge] Error in OnUserDisconnectedHookPatch Prefix: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger.LogError(val2); } } } private static void LogVerboseWarning(string message) { ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { ManualLogSource logger = Plugin.Logger; if (logger != null) { logger.LogWarning((object)message); } } } } [HarmonyPatch(typeof(TriggerPersistenceSaveSystem), "TriggerSave")] public static class PersistenceSavePatch { private static void Postfix(bool __result, SaveReason reason, FixedString128Bytes saveName, ServerRuntimeSettings saveConfig) { if (!__result || !Plugin.SystemsInitialized || !VWorld.IsServerWorldReady()) { return; } try { PlayerRegistryService.SaveIfDirty(); SharedFileIO.FlushPendingWrites(); } catch (Exception ex) { LoggingHelper.Warning("[PersistenceSavePatch] Post-save state flush failed.", ex); } } } [HarmonyPatch] public static class RaidEventDetectorPatch { private static Entity GetCastleHeartFromBreachedStructure(Entity breachedStructureEntity, EntityManager em) { //IL_0002: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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) if (((EntityManager)(ref em)).HasComponent(breachedStructureEntity)) { return ((EntityManager)(ref em)).GetComponentData(breachedStructureEntity).CastleHeartEntity._Entity; } if (((EntityManager)(ref em)).HasComponent(breachedStructureEntity)) { return breachedStructureEntity; } return Entity.Null; } [HarmonyPatch(typeof(DeathEventListenerSystem), "OnUpdate")] [HarmonyPostfix] private unsafe static void OnUpdatePostfix(DeathEventListenerSystem __instance) { //IL_000f: 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_002b: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if (!RaidInterferenceConfig.EnableRaidInterference.Value) { return; } NativeArray val = default(NativeArray); try { EntityQuery deathEventQuery = __instance._DeathEventQuery; if (((EntityQuery)(ref deathEventQuery)).IsEmptyIgnoreFilter) { return; } deathEventQuery = __instance._DeathEventQuery; val = ((EntityQuery)(ref deathEventQuery)).ToComponentDataArray(AllocatorHandle.op_Implicit((Allocator)3)); if (val.Length == 0) { return; } EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { DeathEvent current = enumerator.Current; if (!((EntityManager)(ref entityManager)).Exists(current.Died) || !((EntityManager)(ref entityManager)).Exists(current.Killer) || !((EntityManager)(ref entityManager)).HasComponent(current.Died)) { continue; } StatChangeReason statChangeReason = current.StatChangeReason; if (((object)(*(StatChangeReason*)(&statChangeReason))/*cast due to .constrained prefix*/).Equals((object)(StatChangeReason)15) && UserHelper.TryGetPlayerOwnerFromSource(entityManager, current.Killer, out var _, out var userEntity)) { Entity castleHeartFromBreachedStructure = GetCastleHeartFromBreachedStructure(current.Died, entityManager); if (castleHeartFromBreachedStructure != Entity.Null && ((EntityManager)(ref entityManager)).Exists(castleHeartFromBreachedStructure)) { RaidInterferenceService.StartSiege(castleHeartFromBreachedStructure, userEntity); } } } } catch (Exception ex) { LoggingHelper.Error("[RaidEventDetector] Error while detecting breached castle structures.", ex); } finally { if (val.IsCreated) { val.Dispose(); } } } } [HarmonyPatch(typeof(ServerBootstrapSystem), "OnUpdate")] public static class RaidForgeSchedulerPatch { [HarmonyPostfix] public static void OnUpdate_Postfix() { RaidForgeScheduler.DrainMainThreadActions(); } } [HarmonyPatch(typeof(ServantCoffinstationActionSystem), "OnUpdate")] public static class ServantCoffinLimitPatch { private static void Prefix(ServantCoffinstationActionSystem __instance) { try { ProcessCoffinActionEvents(__instance); } catch (Exception ex) { LoggingHelper.Warning("[ServantLimits] Failed while inspecting servant coffin action events; the original game actions were left intact.", ex); } } private static void ProcessCoffinActionEvents(ServantCoffinstationActionSystem system) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_0058: 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_00b5: 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) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) bool flag = ServantLimitsConfig.EnableDetailedLogging?.Value ?? false; if (!Plugin.SystemsInitialized || (!flag && !ServantLimitService.HasActiveLimits)) { return; } EntityQuery eventQuery = system._EventQuery; if (((EntityQuery)(ref eventQuery)).IsEmptyIgnoreFilter) { return; } EntityManager entityManager = ((ComponentSystemBase)system).EntityManager; NativeArray val = default(NativeArray); try { eventQuery = system._EventQuery; val = ((EntityQuery)(ref eventQuery)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)2)); if (!TryGetNetworkIdLookup(entityManager, out var networkLookup)) { if (flag) { LoggingHelper.Warning($"[ServantLimits:Action] Found {val.Length} coffin action event(s), " + "but the NetworkId lookup was unavailable."); } } else { Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; ProcessCoffinActionEvent(entityManager, current, networkLookup, flag); } } } finally { if (val.IsCreated) { val.Dispose(); } } } private unsafe static void ProcessCoffinActionEvent(EntityManager entityManager, Entity actionEntity, NetworkIdLookupMap networkLookup, bool detailedLogging) { //IL_0002: 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_0018: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: 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_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) ServantCoffinActionEvent val = default(ServantCoffinActionEvent); FromCharacter val2 = default(FromCharacter); if (!((EntityManager)(ref entityManager)).Exists(actionEntity) || !((EntityManager)(ref entityManager)).TryGetComponentData(actionEntity, ref val) || !((EntityManager)(ref entityManager)).TryGetComponentData(actionEntity, ref val2)) { return; } Entity val3 = default(Entity); bool flag = ((NetworkIdLookupMap)(ref networkLookup)).TryGetValue(val.Workstation, ref val3) && ((EntityManager)(ref entityManager)).Exists(val3); Entity conversionTarget; ServantConvertable convertable; bool flag2 = TryGetConversionTarget(entityManager, val2, out conversionTarget, out convertable); if (detailedLogging) { string value = (flag2 ? DescribeConversionTarget(entityManager, conversionTarget, convertable.ConvertToUnit) : "none"); LoggingHelper.Info($"[ServantLimits:Action] event={DescribeEntity(actionEntity)}, action={val.Action}, user={DescribeEntity(val2.User)}, character={DescribeEntity(val2.Character)}, workstationNetworkId={val.Workstation}, coffin={(flag ? DescribeEntity(val3) : "unresolved")}, dominatedTarget={value}, activeLimits={ServantLimitService.HasActiveLimits}."); } if (!flag || !flag2) { return; } int currentCount; int limit; string servantPrefabName; if ((int)val.Action != 0) { ServantLimitService.LogCountSnapshot(entityManager, val3, val2.User, convertable.ConvertToUnit, ((object)(*(ServantCoffinAction*)(&val.Action))/*cast due to .constrained prefix*/).ToString()); } else if (!ServantLimitService.TryAllowInsert(entityManager, val3, val2.User, convertable.ConvertToUnit, out currentCount, out limit, out servantPrefabName)) { ((EntityManager)(ref entityManager)).DestroyEntity(actionEntity); if (detailedLogging) { LoggingHelper.Info($"[ServantLimits:Action] Destroyed blocked Insert event={DescribeEntity(actionEntity)} for coffin={DescribeEntity(val3)}."); } } } private static bool TryGetNetworkIdLookup(EntityManager entityManager, out NetworkIdLookupMap networkLookup) { //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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0028: 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_0046: 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_005b: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) networkLookup = default(NetworkIdLookupMap); EntityQuery val = default(EntityQuery); try { EntityQueryDesc[] array = new EntityQueryDesc[1]; EntityQueryDesc val2 = new EntityQueryDesc(); val2.All = Il2CppStructArray.op_Implicit((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); val2.Options = (EntityQueryOptions)16; array[0] = val2; val = ((EntityManager)(ref entityManager)).CreateEntityQuery((EntityQueryDesc[])(object)array); if (((EntityQuery)(ref val)).IsEmptyIgnoreFilter) { return false; } Singleton singleton = ((EntityQuery)(ref val)).GetSingleton(); networkLookup = ((Singleton)(ref singleton)).GetNetworkIdLookupRO(); return networkLookup._NetworkIdToEntityMap.IsCreated; } finally { if (val != default(EntityQuery)) { ((EntityQuery)(ref val)).Dispose(); } } } private static bool TryGetConversionTarget(EntityManager entityManager, FromCharacter fromCharacter, out Entity conversionTarget, out ServantConvertable convertable) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0023: 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_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) //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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_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_005d: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0088: 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) conversionTarget = Entity.Null; convertable = default(ServantConvertable); if (!((EntityManager)(ref entityManager)).Exists(fromCharacter.Character) || !((EntityManager)(ref entityManager)).HasBuffer(fromCharacter.Character)) { return false; } Enumerator enumerator = ((EntityManager)(ref entityManager)).GetBuffer(fromCharacter.Character, false).GetEnumerator(); ServantConvertable val = default(ServantConvertable); while (enumerator.MoveNext()) { Entity entity = enumerator.Current.Entity._Entity; if (!(entity == Entity.Null) && ((EntityManager)(ref entityManager)).Exists(entity) && ((EntityManager)(ref entityManager)).TryGetComponentData(entity, ref val)) { conversionTarget = entity; convertable = val; return true; } } return false; } private static string DescribeConversionTarget(EntityManager entityManager, Entity conversionTarget, PrefabGUID servantPrefab) { //IL_0008: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) string value = "unknown"; PrefabGUID prefabGuid = default(PrefabGUID); if (((EntityManager)(ref entityManager)).TryGetComponentData(conversionTarget, ref prefabGuid) && PrefabGuidResolver.TryGetPrefabName(prefabGuid, out var prefabName)) { value = prefabName; } string prefabName2; string value2 = (PrefabGuidResolver.TryGetPrefabName(servantPrefab, out prefabName2) ? prefabName2 : "unknown"); return $"{DescribeEntity(conversionTarget)} {value} -> {value2} ({((PrefabGUID)(ref servantPrefab)).GuidHash})"; } private static string DescribeEntity(Entity entity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!(entity == Entity.Null)) { return $"{entity.Index}:{entity.Version}"; } return "null"; } } [HarmonyPatch(typeof(LoadPersistenceSystemV2), "SetLoadState")] public static class ServerWorldReadyPatch { private static bool _initRetryRegistered; private static bool _errorLogged; private static Timer _initRetryTimer; public static void ResetRuntimeState() { CancelInitializationRetry(); _initRetryRegistered = false; _errorLogged = false; } private static void Postfix(EntityManager entityManager, State loadState) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown try { if (!Plugin.SystemsInitialized && (int)loadState == 4) { RegisterInitializationRetry(); } } catch (Exception ex) { if (_errorLogged) { return; } ManualLogSource logger = Plugin.Logger; if (logger != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(52, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RaidForge] Error in persistence-load startup hook: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } logger.LogError(val); } _errorLogged = true; } } private static void RegisterInitializationRetry() { if (_initRetryRegistered) { return; } _initRetryRegistered = true; ManualLogSource logger = Plugin.Logger; if (logger != null) { logger.LogInfo((object)"[RaidForge] Persistence load completed. Waiting for final server readiness..."); } TryInitialize(); if (Plugin.SystemsInitialized) { CancelInitializationRetry(); return; } _initRetryTimer = RaidForgeScheduler.RunEvery(delegate { if (Plugin.SystemsInitialized) { CancelInitializationRetry(); } else { TryInitialize(); if (Plugin.SystemsInitialized) { CancelInitializationRetry(); } } }, 5.0); } private static void TryInitialize() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown try { if (!Plugin.SystemsInitialized) { Plugin.AttemptInitializeCoreSystems(); } } catch (Exception ex) { if (_errorLogged) { return; } ManualLogSource logger = Plugin.Logger; if (logger != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(64, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RaidForge] Error while attempting delayed core initialization: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex); } logger.LogError(val); } _errorLogged = true; } } private static void CancelInitializationRetry() { _initRetryTimer?.Dispose(); _initRetryTimer = null; } } [HarmonyPatch(typeof(TeleportationRequestSystem), "OnUpdate")] public static class TeleportationRestrictionsPatch { private static void Prefix(TeleportationRequestSystem __instance) { try { PrefixCore(__instance); } catch (Exception ex) { LoggingHelper.Warning("[Teleport] Error while applying waygate raid-hour restrictions.", ex); } } private static void PrefixCore(TeleportationRequestSystem __instance) { //IL_0025: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.SystemsInitialized) { return; } ConfigEntry allowWaygateTeleports = RaidConfig.AllowWaygateTeleports; if (allowWaygateTeleports == null || allowWaygateTeleports.Value || !VWorld.IsServerWorldReady()) { return; } EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; EntityQuery teleportRequestQuery = __instance._TeleportRequestQuery; if (((EntityQuery)(ref teleportRequestQuery)).IsEmptyIgnoreFilter || !RaidToggleSystem.AreRaidsEnabledLive()) { return; } teleportRequestQuery = __instance._TeleportRequestQuery; NativeArray val = ((EntityQuery)(ref teleportRequestQuery)).ToEntityArray(AllocatorHandle.op_Implicit((Allocator)3)); try { Enumerator enumerator = val.GetEnumerator(); FixedString512Bytes val2 = default(FixedString512Bytes); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (!((EntityManager)(ref entityManager)).Exists(current) || !((EntityManager)(ref entityManager)).HasComponent(current)) { continue; } TeleportationRequest componentData = ((EntityManager)(ref entityManager)).GetComponentData(current); Entity playerEntity = componentData.PlayerEntity; if (!((EntityManager)(ref entityManager)).Exists(playerEntity) || !((EntityManager)(ref entityManager)).HasComponent(playerEntity)) { continue; } Entity userEntity = ((EntityManager)(ref entityManager)).GetComponentData(playerEntity).UserEntity; if (((EntityManager)(ref entityManager)).Exists(userEntity) && ((EntityManager)(ref entityManager)).HasComponent(userEntity)) { Entity activeReturnToNetherWaypoint = GetActiveReturnToNetherWaypoint(entityManager, playerEntity); bool hasActiveNetherReturn = activeReturnToNetherWaypoint != Entity.Null; bool flag = IsActiveNetherReturnTeleport(entityManager, componentData, activeReturnToNetherWaypoint); User componentData2 = ((EntityManager)(ref entityManager)).GetComponentData(userEntity); bool isAdmin = componentData2.IsAdmin; bool flag2 = ShouldBlockTeleportType(componentData.TeleportationType); bool flag3 = IsAllowedSpecialTeleportTarget(entityManager, componentData.FromTarget) || IsAllowedSpecialTeleportTarget(entityManager, componentData.ToTarget); LogTeleportRequest(entityManager, componentData, hasActiveNetherReturn, flag, activeReturnToNetherWaypoint, isAdmin, flag2, flag3); if (flag2 && !(isAdmin || flag || flag3)) { ((EntityManager)(ref entityManager)).DestroyEntity(current); ((FixedString512Bytes)(ref val2))..ctor(ChatColors.WarningText("You cannot use waygates during raid hours!")); ServerChatUtils.SendSystemMessageToClient(entityManager, componentData2, ref val2); } } } } finally { if (val.IsCreated) { val.Dispose(); } } } private static bool ShouldBlockTeleportType(TeleportationType teleportationType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)teleportationType != 1) { return (int)teleportationType == 2; } return true; } private static Entity GetActiveReturnToNetherWaypoint(EntityManager em, Entity playerCharacterEntity) { //IL_0002: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_000c: 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_0028: 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) ReturnToNetherWaypoint val = default(ReturnToNetherWaypoint); if (!((EntityManager)(ref em)).TryGetComponentData(playerCharacterEntity, ref val)) { return Entity.Null; } Entity waypointEntity = val.WaypointEntity; if (!(waypointEntity != Entity.Null) || !((EntityManager)(ref em)).Exists(waypointEntity)) { return Entity.Null; } return waypointEntity; } private static bool IsActiveNetherReturnTeleport(EntityManager em, TeleportationRequest requestData, Entity activeNetherReturnWaypoint) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0027: 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_002d: Unknown result type (might be due to invalid IL or missing references) if (activeNetherReturnWaypoint == Entity.Null || !((EntityManager)(ref em)).Exists(activeNetherReturnWaypoint)) { return false; } if (!(requestData.FromTarget == activeNetherReturnWaypoint)) { return requestData.ToTarget == activeNetherReturnWaypoint; } return true; } private static bool IsAllowedSpecialTeleportTarget(EntityManager em, Entity target) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (target == Entity.Null || !((EntityManager)(ref em)).Exists(target)) { return false; } if (((EntityManager)(ref em)).HasComponent(target) || ((EntityManager)(ref em)).HasComponent(target) || ((EntityManager)(ref em)).HasComponent(target) || ((EntityManager)(ref em)).HasComponent(target)) { return true; } PrefabGUID prefabGuid = default(PrefabGUID); if (!((EntityManager)(ref em)).TryGetComponentData(target, ref prefabGuid) || !PrefabGuidResolver.TryGetPrefabName(prefabGuid, out var prefabName)) { return false; } if (prefabName.IndexOf("Nether", StringComparison.OrdinalIgnoreCase) < 0 && prefabName.IndexOf("Dracula", StringComparison.OrdinalIgnoreCase) < 0) { return prefabName.IndexOf("WarpRift", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static void LogTeleportRequest(EntityManager em, TeleportationRequest requestData, bool hasActiveNetherReturn, bool isActiveNetherReturnTeleport, Entity activeNetherReturnWaypoint, bool isAdmin, bool isBlockableType, bool isAllowedSpecialTeleport) { //IL_003f: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { LoggingHelper.Info("[Teleport] Request " + $"type={requestData.TeleportationType}, " + "from=" + DescribeTeleportTarget(em, requestData.FromTarget) + ", to=" + DescribeTeleportTarget(em, requestData.ToTarget) + ", " + $"admin={isAdmin}, " + $"activeNetherReturn={hasActiveNetherReturn}, " + $"netherReturnTeleport={isActiveNetherReturnTeleport}, " + "netherReturnWaypoint=" + DescribeTeleportTarget(em, activeNetherReturnWaypoint) + ", " + $"allowedSpecial={isAllowedSpecialTeleport}, " + $"blockedType={isBlockableType}"); } } private static string DescribeTeleportTarget(EntityManager em, Entity target) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) if (target == Entity.Null) { return "null"; } if (((EntityManager)(ref em)).Exists(target)) { PrefabGUID prefabGuid = default(PrefabGUID); if (((EntityManager)(ref em)).TryGetComponentData(target, ref prefabGuid)) { string prefabName; string value = (PrefabGuidResolver.TryGetPrefabName(prefabGuid, out prefabName) ? prefabName : "unknown"); return $"{target.Index}:{target.Version} {value} ({((PrefabGUID)(ref prefabGuid)).GuidHash})"; } return $"{target.Index}:{target.Version} no PrefabGUID"; } return $"{target.Index}:{target.Version} missing"; } } [HarmonyPatch(typeof(ServerBootstrapSystem), "OnUserConnected")] public static class UserConnectHookPatch { private unsafe static void Postfix(ServerBootstrapSystem __instance, NetConnectionId netConnectionId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00e9: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager = ((ComponentSystemBase)__instance).EntityManager; Entity val = Entity.Null; string text = "UnknownOnConnect"; User val2 = default(User); try { int num = default(int); if (__instance._NetEndPointToApprovedUserIndex.TryGetValue(netConnectionId, ref num) && num >= 0 && num < ((Il2CppArrayBase)(object)__instance._ApprovedUsersLookup).Length) { val = ((Il2CppArrayBase)(object)__instance._ApprovedUsersLookup)[num].UserEntity; if (((EntityManager)(ref entityManager)).Exists(val) && ((EntityManager)(ref entityManager)).TryGetComponentData(val, ref val2)) { text = ((object)(*(FixedString64Bytes*)(&val2.CharacterName))/*cast due to .constrained prefix*/).ToString(); } } if (val == Entity.Null || ((User)(ref val2)).Equals(default(User))) { return; } PlayerRegistryService.UpsertUser(entityManager, val, true); string userKey = PersistentKeyHelper.GetUserKey(val2.PlatformId); OfflineGraceService.MarkAsOnline(userKey, text); RaidMapIconService.RemoveOfflineRaidIconsForOwner(userKey, entityManager); OwnershipCacheService.HandlePlayerConnected(val, entityManager); Entity entity = val2.ClanEntity._Entity; if (entity != Entity.Null && ((EntityManager)(ref entityManager)).Exists(entity)) { string clanKey = PersistentKeyHelper.GetClanKey(entityManager, entity); if (!string.IsNullOrEmpty(clanKey)) { string text2 = "Clan"; if (((EntityManager)(ref entityManager)).HasComponent(entity)) { ClanTeam componentData = ((EntityManager)(ref entityManager)).GetComponentData(entity); text2 = ((object)(*(FixedString64Bytes*)(&componentData.Name))/*cast due to .constrained prefix*/).ToString(); } OfflineGraceService.MarkAsOnline(clanKey, text2 + " (member " + text + " connected)"); RaidMapIconService.RemoveOfflineRaidIconsForOwner(clanKey, entityManager); } } RaidMapIconService.MarkPersistentStateIconsDirty(); RaidMapIconService.ProcessCleanup(); Plugin.RunOnBootShardScanIfNeeded(); } catch (Exception ex) { LoggingHelper.Error("Error in UserConnectHookPatch Postfix", ex); } } } } namespace RaidForge.Data { public readonly struct MapIconPrefabOption { public readonly string ShortName; public readonly PrefabRef Prefab; public string PrefabName => Prefab.Name; public int GuidHash => Prefab.GuidHash; public MapIconPrefabOption(string shortName, PrefabRef prefab) { ShortName = shortName; Prefab = prefab; } public MapIconPrefabOption(string shortName, string prefabName, int guidHash) : this(shortName, new PrefabRef(prefabName, guidHash)) { } } public static class MapIconPrefabCatalog { public static readonly PrefabRef DefaultRaidForgeMapIcon = new PrefabRef("MapIcon_CastleObject_Tailor", -1060998155); public static readonly PrefabRef MapIconProxyPrefab = new PrefabRef("MapIcon_ProxyObject_POI_Unknown", 636813227); public static readonly PrefabRef PassiveRaidStateMapIcon = new PrefabRef("MapIcon_Exit", -1527777594); public static readonly PrefabRef RecommendedTerritoryMapIcon = new PrefabRef("MapIcon_RecommendedTerritoryIcon", 906269163); public static readonly PrefabRef HistoricalRelicSpawnBaseMapIcon = new PrefabRef("MapIcon_Relic_Spawn_Base", -1305965860); public static readonly PrefabRef HistoricalRelicBaseMapIcon = new PrefabRef("MapIcon_Relic_Base", 638227411); public static readonly PrefabRef HistoricalCastleHeartMapIcon = new PrefabRef("MapIcon_CastleObject_CastleHeart", 652170644); private static readonly MapIconPrefabOption[] _options = new MapIconPrefabOption[98] { new MapIconPrefabOption("CastleObject_Anvil", "MapIcon_CastleObject_Anvil", 880725011), new MapIconPrefabOption("CastleObject_BloodAltar", "MapIcon_CastleObject_BloodAltar", -1639620581), new MapIconPrefabOption("CastleObject_CastleHeart", HistoricalCastleHeartMapIcon), new MapIconPrefabOption("CastleObject_CraftingBench", "MapIcon_CastleObject_CraftingBench", -2136859183), new MapIconPrefabOption("CastleObject_Default", "MapIcon_CastleObject_Default", -1511010205), new MapIconPrefabOption("CastleObject_JewelCrafting", "MapIcon_CastleObject_JewelCrafting", 268696952), new MapIconPrefabOption("CastleObject_ResearchStation", "MapIcon_CastleObject_ResearchStation", -623144025), new MapIconPrefabOption("CastleObject_Tailor", DefaultRaidForgeMapIcon), new MapIconPrefabOption("CastleWaypoint_Active", "MapIcon_CastleWaypoint_Active", 404272564), new MapIconPrefabOption("Cave_Entryway", "MapIcon_Cave_Entryway", 743889990), new MapIconPrefabOption("CharmedUnit", "MapIcon_CharmedUnit", -1491648886), new MapIconPrefabOption("Crypt", "MapIcon_Crypt", -2078904014), new MapIconPrefabOption("DeathContainer", "MapIcon_DeathContainer", -1597024018), new MapIconPrefabOption("DraculasCastle", "MapIcon_DraculasCastle", -2066471106), new MapIconPrefabOption("Exit", PassiveRaidStateMapIcon), new MapIconPrefabOption("LocalPlayer", "MapIcon_LocalPlayer", -1323817571), new MapIconPrefabOption("Mount", "MapIcon_Mount", 1495684919), new MapIconPrefabOption("Player", "MapIcon_Player", -892362184), new MapIconPrefabOption("PlayerCustomMarker", "MapIcon_PlayerCustomMarker", 1716771727), new MapIconPrefabOption("PlayerCustomMarkerPathfindDot", "MapIcon_PlayerCustomMarkerPathfindDot", -438821425), new MapIconPrefabOption("PlayerPathDot", "MapIcon_PlayerPathDot", 467133242), new MapIconPrefabOption("POI_Discover_BanditCamp", "MapIcon_POI_Discover_BanditCamp", 2043384709), new MapIconPrefabOption("POI_Discover_BanditEncampment", "MapIcon_POI_Discover_BanditEncampment", 1519700716), new MapIconPrefabOption("POI_Discover_BanditFortification", "MapIcon_POI_Discover_BanditFortification", 1092950571), new MapIconPrefabOption("POI_Discover_BanditHideout", "MapIcon_POI_Discover_BanditHideout", 1210453814), new MapIconPrefabOption("POI_Discover_BanditOutpost", "MapIcon_POI_Discover_BanditOutpost", 1957543975), new MapIconPrefabOption("POI_Discover_Boss_Bandit", "MapIcon_POI_Discover_Boss_Bandit", 1501929529), new MapIconPrefabOption("POI_Discover_Boss_GrizzlyBear", "MapIcon_POI_Discover_Boss_GrizzlyBear", 400428420), new MapIconPrefabOption("POI_Discover_Boss_Militia", "MapIcon_POI_Discover_Boss_Militia", 216024887), new MapIconPrefabOption("POI_Discover_Boss_SpiderQueen", "MapIcon_POI_Discover_Boss_SpiderQueen", -1798124394), new MapIconPrefabOption("POI_Discover_Boss_Undead", "MapIcon_POI_Discover_Boss_Undead", -1887784669), new MapIconPrefabOption("POI_Discover_ChurchFarmlands", "MapIcon_POI_Discover_ChurchFarmlands", -1893591910), new MapIconPrefabOption("POI_Discover_CottonPlantation", "MapIcon_POI_Discover_CottonPlantation", -768444788), new MapIconPrefabOption("POI_Discover_CryptVault", "MapIcon_POI_Discover_CryptVault", 603697502), new MapIconPrefabOption("POI_Discover_CultistSite", "MapIcon_POI_Discover_CultistSite", 931669506), new MapIconPrefabOption("POI_Discover_DunleyChurch", "MapIcon_POI_Discover_DunleyChurch", 632395128), new MapIconPrefabOption("POI_Discover_FarmlandsChurch", "MapIcon_POI_Discover_FarmlandsChurch", -1256336496), new MapIconPrefabOption("POI_Discover_FarmlandsFarm", "MapIcon_POI_Discover_FarmlandsFarm", 239387799), new MapIconPrefabOption("POI_Discover_FarmlandsGarlicFarm", "MapIcon_POI_Discover_FarmlandsGarlicFarm", 297452363), new MapIconPrefabOption("POI_Discover_FarmlandsHorseFarm", "MapIcon_POI_Discover_FarmlandsHorseFarm", -948983333), new MapIconPrefabOption("POI_Discover_FarmlandsTown", "MapIcon_POI_Discover_FarmlandsTown", -1426507977), new MapIconPrefabOption("POI_Discover_ForgottenCemetery", "MapIcon_POI_Discover_ForgottenCemetery", -2040967389), new MapIconPrefabOption("POI_Discover_GhostTown", "MapIcon_POI_Discover_GhostTown", -1276819284), new MapIconPrefabOption("POI_Discover_Graveyard", "MapIcon_POI_Discover_Graveyard", 698241041), new MapIconPrefabOption("POI_Discover_InfestedMines", "MapIcon_POI_Discover_InfestedMines", 1904546641), new MapIconPrefabOption("POI_Discover_IronMines", "MapIcon_POI_Discover_IronMines", 1903833803), new MapIconPrefabOption("POI_Discover_LumberjackCamp", "MapIcon_POI_Discover_LumberjackCamp", 1148857439), new MapIconPrefabOption("POI_Discover_Merchant", "MapIcon_POI_Discover_Merchant", -360752412), new MapIconPrefabOption("POI_Discover_MilitiaCommandPost", "MapIcon_POI_Discover_MilitiaCommandPost", 105682385), new MapIconPrefabOption("POI_Discover_MilitiaEncampment", "MapIcon_POI_Discover_MilitiaEncampment", -605145652), new MapIconPrefabOption("POI_Discover_MilitiaFortification", "MapIcon_POI_Discover_MilitiaFortification", 1115067066), new MapIconPrefabOption("POI_Discover_MilitiaWatchTower", "MapIcon_POI_Discover_MilitiaWatchTower", -1768623961), new MapIconPrefabOption("POI_Discover_SpiderForest", "MapIcon_POI_Discover_SpiderForest", -680026394), new MapIconPrefabOption("POI_Discover_TerokiMeadows", "MapIcon_POI_Discover_TerokiMeadows", -1379366510), new MapIconPrefabOption("POI_Discover_TownFarmlands", "MapIcon_POI_Discover_TownFarmlands", 563819869), new MapIconPrefabOption("POI_Discover_Unknown", "MapIcon_POI_Discover_Unknown", -1443504104), new MapIconPrefabOption("POI_Discover_WolfDen", "MapIcon_POI_Discover_WolfDen", -1443808553), new MapIconPrefabOption("POI_Knowledge_Church", "MapIcon_POI_Knowledge_Church", -1571811509), new MapIconPrefabOption("POI_Knowledge_LumberjackCamp", "MapIcon_POI_Knowledge_LumberjackCamp", 351553164), new MapIconPrefabOption("POI_Knowledge_Settlement", "MapIcon_POI_Knowledge_Settlement", 138663934), new MapIconPrefabOption("POI_Knowledge_Town", "MapIcon_POI_Knowledge_Town", -221292597), new MapIconPrefabOption("POI_Resource_CoalMine", "MapIcon_POI_Resource_CoalMine", 1992891574), new MapIconPrefabOption("POI_Resource_CopperQuarry", "MapIcon_POI_Resource_CopperQuarry", 419555810), new MapIconPrefabOption("POI_Resource_CottonPlantation", "MapIcon_POI_Resource_CottonPlantation", 468675810), new MapIconPrefabOption("POI_Resource_DuskbarkForest", "MapIcon_POI_Resource_DuskbarkForest", -1989680779), new MapIconPrefabOption("POI_Resource_ForgottenCemetery", "MapIcon_POI_Resource_ForgottenCemetery", -1405787520), new MapIconPrefabOption("POI_Resource_GrizzlyBearDen", "MapIcon_POI_Resource_GrizzlyBearDen", -107944115), new MapIconPrefabOption("POI_Resource_IronMine", "MapIcon_POI_Resource_IronMine", -1725105796), new MapIconPrefabOption("POI_Resource_IronVein", "MapIcon_POI_Resource_IronVein", -1132008653), new MapIconPrefabOption("POI_Resource_Permanent_CopperQuarry", "MapIcon_POI_Resource_Permanent_CopperQuarry", 701513285), new MapIconPrefabOption("POI_Resource_QuartzMine", "MapIcon_POI_Resource_QuartzMine", -853022254), new MapIconPrefabOption("POI_Resource_QuartzQuarry", "MapIcon_POI_Resource_QuartzQuarry", -426591728), new MapIconPrefabOption("POI_Resource_SaintLilyCemetery", "MapIcon_POI_Resource_SaintLilyCemetery", -1766751566), new MapIconPrefabOption("POI_Resource_SnowBlossomForest", "MapIcon_POI_Resource_SnowBlossomForest", 643012707), new MapIconPrefabOption("POI_Spawn_CoffinSelect", "MapIcon_POI_Spawn_CoffinSelect", 1454830975), new MapIconPrefabOption("POI_Spawn_CryptSelect", "MapIcon_POI_Spawn_CryptSelect", -1938049417), new MapIconPrefabOption("POI_Spawn_WaypointSelect", "MapIcon_POI_Spawn_WaypointSelect", -2098609826), new MapIconPrefabOption("POI_VBloodSource", "MapIcon_POI_VBloodSource", 139106998), new MapIconPrefabOption("RecommendedTerritoryIcon", RecommendedTerritoryMapIcon), new MapIconPrefabOption("Relic_Base", HistoricalRelicBaseMapIcon), new MapIconPrefabOption("Relic_Spawn_Base", HistoricalRelicSpawnBaseMapIcon), new MapIconPrefabOption("Relic_Spawn_Dracula", "MapIcon_Relic_Spawn_Dracula", -834249437), new MapIconPrefabOption("Relic_Spawn_Morgana", "MapIcon_Relic_Spawn_Morgana", 1621891122), new MapIconPrefabOption("Relic_Spawn_Solarus", "MapIcon_Relic_Spawn_Solarus", -52304021), new MapIconPrefabOption("Relic_Spawn_TheMonster", "MapIcon_Relic_Spawn_TheMonster", 1570562186), new MapIconPrefabOption("Relic_Spawn_WingedHorror", "MapIcon_Relic_Spawn_WingedHorror", -199298876), new MapIconPrefabOption("Relic_Standard_Dracula", "MapIcon_Relic_Standard_Dracula", 1082059027), new MapIconPrefabOption("Relic_Standard_Morgana", "MapIcon_Relic_Standard_Morgana", 1172401273), new MapIconPrefabOption("Relic_Standard_Solarus", "MapIcon_Relic_Standard_Solarus", 2133172828), new MapIconPrefabOption("Relic_Standard_TheMonster", "MapIcon_Relic_Standard_TheMonster", 1204693597), new MapIconPrefabOption("Relic_Standard_WingedHorror", "MapIcon_Relic_Standard_WingedHorror", 622223699), new MapIconPrefabOption("Siege_Summon_T02", "MapIcon_Siege_Summon_T02", -1769480952), new MapIconPrefabOption("Siege_Summon_T02_Complete", "MapIcon_Siege_Summon_T02_Complete", 1358914922), new MapIconPrefabOption("StartGraveyardExit", "MapIcon_StartGraveyardExit", -37003475), new MapIconPrefabOption("StoneCoffin", "MapIcon_StoneCoffin", 985620050), new MapIconPrefabOption("UnclaimedCastle", "MapIcon_UnclaimedCastle", 1556395508), new MapIconPrefabOption("WoodenCoffin", "MapIcon_WoodenCoffin", 1636226671), new MapIconPrefabOption("WorldWaypoint_Active", "MapIcon_WorldWaypoint_Active", -1510127174) }; private static readonly PrefabRef[] _knownPrefabs = BuildKnownPrefabs(); private static readonly Dictionary _aliases = BuildAliases(); private static readonly Dictionary _namesByHash = (from prefab in _knownPrefabs group prefab by prefab.GuidHash).ToDictionary((IGrouping group) => group.Key, (IGrouping group) => group.First().Name); public static IReadOnlyList Options => _options; public static IReadOnlyList KnownPrefabs => _knownPrefabs; public static bool TryResolve(string value, out PrefabGUID prefabGuid, out string prefabName) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) prefabGuid = default(PrefabGUID); prefabName = null; if (string.IsNullOrWhiteSpace(value)) { return false; } if (!_aliases.TryGetValue(value.Trim(), out var value2)) { return false; } prefabGuid = new PrefabGUID(value2.GuidHash); prefabName = value2.PrefabName; return true; } public static bool TryGetName(int guidHash, out string prefabName) { return _namesByHash.TryGetValue(guidHash, out prefabName); } public static bool TryGetByHash(int guidHash, out PrefabRef prefab) { PrefabRef[] knownPrefabs = _knownPrefabs; for (int i = 0; i < knownPrefabs.Length; i++) { PrefabRef prefabRef = knownPrefabs[i]; if (prefabRef.GuidHash == guidHash) { prefab = prefabRef; return true; } } prefab = default(PrefabRef); return false; } public static string GetShortNameExamples() { return "Examples: CastleObject_Tailor, CastleObject_CastleHeart, Exit, Relic_Base, Siege_Summon_T02."; } private static Dictionary BuildAliases() { Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); MapIconPrefabOption[] options = _options; for (int i = 0; i < options.Length; i++) { MapIconPrefabOption value = options[i]; dictionary[value.ShortName] = value; dictionary[value.PrefabName] = value; if (value.PrefabName.StartsWith("MapIcon_", StringComparison.OrdinalIgnoreCase)) { dictionary[value.PrefabName.Substring("MapIcon_".Length)] = value; } } dictionary["Relic_Spawn_Ssolarus"] = dictionary["Relic_Spawn_Solarus"]; dictionary["MapIcon_Relic_Spawn_Ssolarus"] = dictionary["Relic_Spawn_Solarus"]; return dictionary; } private static PrefabRef[] BuildKnownPrefabs() { return (from prefab in _options.Select((MapIconPrefabOption option) => option.Prefab).Append(MapIconProxyPrefab) group prefab by prefab.GuidHash into @group select @group.First()).ToArray(); } } public enum TntTier { None, T01, T02 } public static class PrefabData { public static readonly PrefabRef SiegeGolemBuff = new PrefabRef("AB_Shapeshift_Golem_T02_Buff", 914043867); public static readonly PrefabRef TntItemT01 = new PrefabRef("Item_Building_Explosives_T01", 1779299585); public static readonly PrefabRef TntItemT02 = new PrefabRef("Item_Building_Explosives_T02", -1021407417); public static readonly PrefabRef TntPlaceableT01 = new PrefabRef("TM_EH_Mines_ExplosiveBarrel_Placeable_T01", -1401715476); public static readonly PrefabRef TntPlaceableT02 = new PrefabRef("TM_EH_Mines_ExplosiveBarrel_Placeable_T02", 2036168659); public static readonly PrefabRef InterloperDebuff = new PrefabRef("AB_Lucie_CripplingGoo_PoisonDebuff", 1382025211); public static readonly PrefabRef BearBuff = new PrefabRef("AB_Shapeshift_Bear_Buff", -1569370346); public static readonly PrefabRef BearSkinBuff = new PrefabRef("AB_Shapeshift_Bear_Skin01_Buff", -858273386); public static readonly PrefabRef ExternalInventoryPrefab = new PrefabRef("External_Inventory", 1183666186); public static readonly PrefabRef SolarusContainer = new PrefabRef("TM_Castle_Container_Specialized_Soulshards_Solarus", -824445631); public static readonly PrefabRef MonsterContainer = new PrefabRef("TM_Castle_Container_Specialized_Soulshards_Monster", -1996942061); public static readonly PrefabRef ManticoreContainer = new PrefabRef("TM_Castle_Container_Specialized_Soulshards_Manticore", 653759442); public static readonly PrefabRef DraculaContainer = new PrefabRef("TM_Castle_Container_Specialized_Soulshards_Dracula", 1495743889); public static readonly PrefabRef MorganaContainer = new PrefabRef("TM_Castle_Container_Specialized_Soulshards_Morgana", 1724128982); public static readonly PrefabRef SolarusShard = new PrefabRef("Item_MagicSource_SoulShard_Solarus", -21943750); public static readonly PrefabRef MorganaShard = new PrefabRef("Item_MagicSource_SoulShard_Morgana", 1286615355); public static readonly PrefabRef DraculaShard = new PrefabRef("Item_MagicSource_SoulShard_Dracula", 666638454); public static readonly PrefabRef MonsterShard = new PrefabRef("Item_MagicSource_SoulShard_Monster", -1581189572); public static readonly PrefabRef ManticoreShard = new PrefabRef("Item_MagicSource_SoulShard_Manticore", -1260254082); private static readonly PrefabRef[] _all = new PrefabRef[19] { SiegeGolemBuff, TntItemT01, TntItemT02, TntPlaceableT01, TntPlaceableT02, InterloperDebuff, BearBuff, BearSkinBuff, ExternalInventoryPrefab, SolarusContainer, MonsterContainer, ManticoreContainer, DraculaContainer, MorganaContainer, SolarusShard, MorganaShard, DraculaShard, MonsterShard, ManticoreShard }; public static readonly HashSet SoulShardPrefabGUIDs = new HashSet { SolarusShard.Guid, MorganaShard.Guid, DraculaShard.Guid, MonsterShard.Guid, ManticoreShard.Guid }; public static readonly HashSet TntItemPrefabGUIDs = new HashSet { TntItemT01.Guid, TntItemT02.Guid }; public static readonly HashSet TntPlaceablePrefabGUIDs = new HashSet { TntPlaceableT01.Guid, TntPlaceableT02.Guid }; public static readonly HashSet SoulShardPedestalPrefabGUIDs = new HashSet { SolarusContainer.Guid, MonsterContainer.Guid, ManticoreContainer.Guid, DraculaContainer.Guid, MorganaContainer.Guid }; public static IReadOnlyList All => _all; public static bool TryGetByName(string name, out PrefabRef prefab) { if (!string.IsNullOrWhiteSpace(name)) { string b = name.Trim(); PrefabRef[] all = _all; for (int i = 0; i < all.Length; i++) { PrefabRef prefabRef = all[i]; if (string.Equals(prefabRef.Name, b, StringComparison.OrdinalIgnoreCase)) { prefab = prefabRef; return true; } } } prefab = default(PrefabRef); return false; } public static bool TryGetByHash(int guidHash, out PrefabRef prefab) { PrefabRef[] all = _all; for (int i = 0; i < all.Length; i++) { PrefabRef prefabRef = all[i]; if (prefabRef.GuidHash == guidHash) { prefab = prefabRef; return true; } } prefab = default(PrefabRef); return false; } public static bool IsTntPrefab(PrefabGUID prefabGuid) { //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) if (!IsTntItemPrefab(prefabGuid)) { return IsTntPlaceablePrefab(prefabGuid); } return true; } public static bool IsTntItemPrefab(PrefabGUID prefabGuid) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return TntItemPrefabGUIDs.Contains(prefabGuid); } public static bool IsTntPlaceablePrefab(PrefabGUID prefabGuid) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return TntPlaceablePrefabGUIDs.Contains(prefabGuid); } public static TntTier GetTntTier(PrefabGUID prefabGuid) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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) if (prefabGuid == TntItemT01.Guid || prefabGuid == TntPlaceableT01.Guid) { return TntTier.T01; } if (prefabGuid == TntItemT02.Guid || prefabGuid == TntPlaceableT02.Guid) { return TntTier.T02; } return TntTier.None; } } public readonly struct PrefabRef { public string Name { get; } public PrefabGUID Guid { get; } public int GuidHash { get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) PrefabGUID guid = Guid; return ((PrefabGUID)(ref guid)).GuidHash; } } public PrefabRef(string name, int guidHash) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) Name = name; Guid = new PrefabGUID(guidHash); } public override string ToString() { return $"{Name} ({GuidHash})"; } } } namespace RaidForge.Core { public static class RaidForgeScheduler { private sealed class FrameDelayedAction { public readonly Action Action; public int FramesRemaining; public FrameDelayedAction(Action action, int framesRemaining) { Action = action; FramesRemaining = framesRemaining; } } private static readonly ConcurrentQueue _mainThreadActions = new ConcurrentQueue(); private static readonly List _frameDelayedActions = new List(); private static readonly List _activeTimers = new List(); private static readonly object _frameDelayedActionsLock = new object(); private static bool _isInitialized = false; public static void DrainMainThreadActions() { DrainFrameDelayedActions(); Action result; while (_mainThreadActions.TryDequeue(out result)) { try { result?.Invoke(); } catch (Exception value) { LoggingHelper.Error($"[RaidForgeScheduler] Error executing action: {value}"); } } } private static void DrainFrameDelayedActions() { List list = null; lock (_frameDelayedActionsLock) { for (int num = _frameDelayedActions.Count - 1; num >= 0; num--) { FrameDelayedAction frameDelayedAction = _frameDelayedActions[num]; frameDelayedAction.FramesRemaining--; if (frameDelayedAction.FramesRemaining <= 0) { if (list == null) { list = new List(); } list.Add(frameDelayedAction.Action); _frameDelayedActions.RemoveAt(num); } } } if (list == null) { return; } foreach (Action item in list) { try { item?.Invoke(); } catch (Exception value) { LoggingHelper.Error($"[RaidForgeScheduler] Error executing frame-delayed action: {value}"); } } } public static void Initialize() { if (!_isInitialized) { _isInitialized = true; LoggingHelper.Info("[RaidForgeScheduler] Scheduler Initialized."); } } public static void Dispose() { lock (_activeTimers) { foreach (Timer activeTimer in _activeTimers) { activeTimer?.Dispose(); } _activeTimers.Clear(); } lock (_frameDelayedActionsLock) { _frameDelayedActions.Clear(); } Action result; while (_mainThreadActions.TryDequeue(out result)) { } _isInitialized = false; } private static void EnqueueMainThreadAction(Action action) { _mainThreadActions.Enqueue(action); } public static void RunAfterFrames(Action action, int frames) { if (frames <= 0) { EnqueueMainThreadAction(action); return; } lock (_frameDelayedActionsLock) { _frameDelayedActions.Add(new FrameDelayedAction(action, frames)); } } public static void RunOnce(Action action, double delaySeconds) { if (delaySeconds < 0.0) { delaySeconds = 0.0; } Timer timer = null; timer = new Timer(delegate { EnqueueMainThreadAction(delegate { try { action?.Invoke(); } finally { lock (_activeTimers) { _activeTimers.Remove(timer); } timer?.Dispose(); } }); }, null, TimeSpan.FromSeconds(delaySeconds), Timeout.InfiniteTimeSpan); lock (_activeTimers) { _activeTimers.Add(timer); } } public static Timer RunEvery(Action action, double intervalSeconds, double initialDelaySeconds = 0.0) { if (intervalSeconds <= 0.0) { return null; } int queuedOrRunning = 0; Timer timer = new Timer(delegate { if (Interlocked.Exchange(ref queuedOrRunning, 1) != 1) { EnqueueMainThreadAction(delegate { try { action?.Invoke(); } finally { Interlocked.Exchange(ref queuedOrRunning, 0); } }); } }, null, TimeSpan.FromSeconds(initialDelaySeconds), TimeSpan.FromSeconds(intervalSeconds)); lock (_activeTimers) { _activeTimers.Add(timer); return timer; } } } } namespace RaidForge.Config { public static class CommandSettingsConfig { public sealed class RuntimeCommand { public CommandDefinition Definition { get; } public bool Enabled { get; } public string PrimaryName { get; } public string ShortHand { get; } public bool ShowInPlayerList { get; } public bool ShowInAdminList { get; } internal RuntimeCommand(CommandDefinition definition, bool enabled, string primaryName, string shortHand, bool showInPlayerList, bool showInAdminList) { Definition = definition; Enabled = enabled; PrimaryName = primaryName; ShortHand = shortHand; ShowInPlayerList = showInPlayerList; ShowInAdminList = showInAdminList; } } public sealed class CommandDefinition { public string CanonicalName { get; } public string DefaultShortHand { get; } public string Description { get; } public string Usage { get; } public bool AdminOnly { get; } internal ConfigEntry Enabled { get; set; } internal ConfigEntry Name { get; set; } internal ConfigEntry ShortHand { get; set; } internal ConfigEntry ShowInPlayerList { get; set; } internal ConfigEntry ShowInAdminList { get; set; } internal CommandDefinition(string canonicalName, string defaultShortHand, string description, string usage, bool adminOnly) { CanonicalName = canonicalName; DefaultShortHand = defaultShortHand; Description = description; Usage = usage; AdminOnly = adminOnly; } } private sealed class RuntimeSnapshot { public static readonly RuntimeSnapshot Empty = new RuntimeSnapshot(customSettingsEnabled: false, showPlayerCommandList: true, showAdminCommandList: true, Array.Empty(), new Dictionary(StringComparer.OrdinalIgnoreCase)); public bool CustomSettingsEnabled { get; } public bool ShowPlayerCommandList { get; } public bool ShowAdminCommandList { get; } public RuntimeCommand[] Commands { get; } public Dictionary TokenLookup { get; } public RuntimeSnapshot(bool customSettingsEnabled, bool showPlayerCommandList, bool showAdminCommandList, RuntimeCommand[] commands, Dictionary tokenLookup) { CustomSettingsEnabled = customSettingsEnabled; ShowPlayerCommandList = showPlayerCommandList; ShowAdminCommandList = showAdminCommandList; Commands = commands; TokenLookup = tokenLookup; } } private readonly struct LegacyGlobalSettings { public bool EnableCustomCommandSettings { get; } public bool ShowPlayerCommandList { get; } public bool ShowAdminCommandList { get; } public LegacyGlobalSettings(bool enableCustomCommandSettings, bool showPlayerCommandList, bool showAdminCommandList) { EnableCustomCommandSettings = enableCustomCommandSettings; ShowPlayerCommandList = showPlayerCommandList; ShowAdminCommandList = showAdminCommandList; } } private readonly struct LegacyCommandSettings { public bool Enabled { get; } public string Name { get; } public string ShortHand { get; } public bool ShowInPlayerList { get; } public bool ShowInAdminList { get; } public LegacyCommandSettings(bool enabled, string name, string shortHand, bool showInPlayerList, bool showInAdminList) { Enabled = enabled; Name = name; ShortHand = shortHand; ShowInPlayerList = showInPlayerList; ShowInAdminList = showInAdminList; } } private const string MasterSection = "00 - Enable Custom Commands"; private const string VisibilitySection = "01 - VCF Help Visibility"; private const string LegacyListsSection = "00 - Command Lists"; private const string LegacyGlobalSection = "00 - Custom Command Settings"; private const string ObsoleteListSection = "01 - raidcommands"; private static readonly CommandDefinition[] Definitions = new CommandDefinition[29] { Admin("raidrefreshcache", null, "Clears and rebuilds the RaidForge ownership caches."), Admin("raidforge", null, "Shows RaidForge status, help, and cache information.", "[?|status|cache]"), Public("raidoptin", null, "Opts you and your clan into being raidable."), Public("raidoptout", null, "Opts you and your clan out of being raidable when the lock permits."), Public("raidoptstatus", null, "Checks your current opt-in raiding status."), Public("raidoptlist", null, "Lists manually opted-in raidable players and clans.", "[page]"), Admin("forceopt", null, "Forces a player or clan's opt-in status.", " "), Admin("reloadraidforge", null, "Reloads RaidForge configuration files except startup-only command settings."), Admin("raidon", null, "Manually turns raids on."), Admin("raidoff", null, "Manually turns raids off."), Admin("raidauto", null, "Clears the manual raid override and resumes the schedule."), Admin("removeorp", null, "Removes offline protection from a player or clan until they reconnect.", ""), Public("raidtime", "raidt", "Shows the time until the next scheduled raid window."), Public("raiddays", "raidd", "Shows the raid schedule for the week."), Public("raidstatus", "raids", "Shows a player or clan's raid vulnerability status.", ""), Admin("raidstatusreason", null, "Shows the detailed reason for a player or clan's ORP status.", ""), Admin("golemstartdate", null, "Sets the golem automation start date to the current time."), Admin("golemcurrent", null, "Shows the current golem health settings."), Admin("golemsethp", null, "Sets and persists a siege golem health level.", ""), Admin("golemauto", null, "Clears the manual golem health override."), Admin("golemlist", null, "Lists available siege golem health levels."), Admin("golem", null, "Transforms the target player into a siege golem.", "[PlayerName]"), Admin("clearraidforgeicons", null, "Clears all active RaidForge map icons."), Public("buyorp", null, "Buys raid-day ORP protection for you or your clan.", ""), Public("buyorpstatus", "orpamount", "Shows your purchased ORP protection days."), Admin("givebuyorp", null, "Gives purchased ORP raid days to a player or clan.", " "), Admin("removebuyorp", null, "Removes purchased ORP raid days from a player or clan.", " "), Admin("raidconfigview", null, "Shows a specific RaidForge configuration section.", ""), Admin("raidconfigviewall", null, "Shows all currently loaded RaidForge configuration values.") }; private static volatile RuntimeSnapshot _snapshot = RuntimeSnapshot.Empty; public static ConfigFile ConfigFileInstance { get; private set; } public static ConfigEntry EnableCustomCommandSettings { get; private set; } public static ConfigEntry ShowPlayerCommandList { get; private set; } public static ConfigEntry ShowAdminCommandList { get; private set; } public static bool CustomSettingsEnabled => _snapshot.CustomSettingsEnabled; public static IReadOnlyList RuntimeCommands => _snapshot.Commands; public static void Initialize(ConfigFile configFile, ManualLogSource logger = null) { //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown ConfigFileInstance = configFile; LegacyGlobalSettings legacyGlobalSettings = ReadAndRemoveObsoleteCommandSettings(configFile); LegacyCommandSettings legacyCommandSettings = ReadAndRemoveLegacyRaidTimerSettings(configFile); EnableCustomCommandSettings = configFile.Bind("00 - Enable Custom Commands", "EnableCustomCommandSettings", legacyGlobalSettings.EnableCustomCommandSettings, "Master switch for all command customization below. Changes only take effect after a full server restart. If false, RaidForge uses its built-in command names, shorthands, enabled states, and normal VCF help behavior."); ShowPlayerCommandList = configFile.Bind("01 - VCF Help Visibility", "ShowPlayerCommandList", legacyGlobalSettings.ShowPlayerCommandList, "When custom command settings are enabled, controls whether RaidForge appears in normal VCF help for non-admin players. Requires a server restart."); ShowAdminCommandList = configFile.Bind("01 - VCF Help Visibility", "ShowAdminCommandList", legacyGlobalSettings.ShowAdminCommandList, "When custom command settings are enabled, controls whether RaidForge appears in normal VCF help for admins. Requires a server restart."); for (int i = 0; i < Definitions.Length; i++) { CommandDefinition commandDefinition = Definitions[i]; string text = $"{i + 2:00} - {commandDefinition.CanonicalName}"; bool flag = string.Equals(commandDefinition.CanonicalName, "raidtime", StringComparison.OrdinalIgnoreCase); commandDefinition.Enabled = configFile.Bind(text, "Enabled", !flag || legacyCommandSettings.Enabled, "If custom command settings are enabled, false removes this command and its shorthand from VCF until the next server restart."); commandDefinition.Name = configFile.Bind(text, "Name", flag ? legacyCommandSettings.Name : commandDefinition.CanonicalName, "Primary command name without the leading period. Requires EnableCustomCommandSettings=true and a server restart."); commandDefinition.ShortHand = configFile.Bind(text, "ShortHand", flag ? legacyCommandSettings.ShortHand : (commandDefinition.DefaultShortHand ?? string.Empty), "Optional shorthand without the leading period. Leave blank to disable it. Requires EnableCustomCommandSettings=true and a server restart."); commandDefinition.ShowInPlayerList = configFile.Bind(text, "ShowInPlayerList", flag ? legacyCommandSettings.ShowInPlayerList : (!commandDefinition.AdminOnly), "If custom command settings are enabled, controls visibility in normal VCF help for non-admin players. VCF still hides commands the player cannot execute. Requires a server restart."); commandDefinition.ShowInAdminList = configFile.Bind(text, "ShowInAdminList", !flag || legacyCommandSettings.ShowInAdminList, "If custom command settings are enabled, controls visibility in normal VCF help for admins. Requires a server restart."); } BuildStartupSnapshot(logger); if (logger != null) { bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(121, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[CommandSettings] Loaded "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(Definitions.Length); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" RaidForge command definitions. "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Custom settings enabled="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(CustomSettingsEnabled); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; changes require a full server restart."); } logger.LogInfo(val); } } public static bool TryGetCommand(string token, out RuntimeCommand command) { command = null; if (string.IsNullOrWhiteSpace(token)) { return false; } string key = token.Trim().TrimStart('.'); return _snapshot.TokenLookup.TryGetValue(key, out command); } public static string GetInvocation(string canonicalName) { if (!TryGetCommand(canonicalName, out var command)) { return "." + canonicalName; } return "." + command.PrimaryName; } public static bool ShouldShowInVcfHelp(string commandName, bool isAdmin) { RuntimeSnapshot snapshot = _snapshot; if (!snapshot.CustomSettingsEnabled) { return true; } if (!snapshot.TokenLookup.TryGetValue(commandName, out var value)) { return true; } if (!value.Enabled) { return false; } if (isAdmin ? snapshot.ShowAdminCommandList : snapshot.ShowPlayerCommandList) { if (!isAdmin) { return value.ShowInPlayerList; } return value.ShowInAdminList; } return false; } private static void BuildStartupSnapshot(ManualLogSource logger) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Expected O, but got Unknown bool flag = EnableCustomCommandSettings?.Value ?? false; Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); List list = new List(Definitions.Length); CommandDefinition[] definitions = Definitions; bool flag2 = default(bool); foreach (CommandDefinition commandDefinition in definitions) { string text = commandDefinition.CanonicalName; string text2 = commandDefinition.DefaultShortHand ?? string.Empty; bool enabled = true; bool showInPlayerList = !commandDefinition.AdminOnly; bool showInAdminList = true; if (flag) { text = NormalizeConfiguredName(commandDefinition.Name?.Value, commandDefinition.CanonicalName, allowBlank: false, logger, commandDefinition.CanonicalName, "Name"); if (IsReservedByAnotherDefinition(text, commandDefinition)) { ManualLogSource val = logger; if (val != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(101, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[CommandSettings] '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' is a built-in name for another RaidForge command. "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(commandDefinition.CanonicalName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' will keep its default name."); } val.LogWarning(val2); } text = commandDefinition.CanonicalName; } if (dictionary.TryGetValue(text, out var value)) { ManualLogSource val = logger; if (val != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(74, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[CommandSettings] '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' is already used by '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(value.CanonicalName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'. "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(commandDefinition.CanonicalName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' will keep its default name."); } val.LogWarning(val2); } text = commandDefinition.CanonicalName; } text2 = NormalizeConfiguredName(commandDefinition.ShortHand?.Value, string.Empty, allowBlank: true, logger, commandDefinition.CanonicalName, "ShortHand"); if (!string.IsNullOrEmpty(text2) && (string.Equals(text2, text, StringComparison.OrdinalIgnoreCase) || IsReservedByAnotherDefinition(text2, commandDefinition) || dictionary.ContainsKey(text2))) { ManualLogSource val = logger; if (val != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(86, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[CommandSettings] Shorthand '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' for '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(commandDefinition.CanonicalName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' conflicts with another command and was disabled."); } val.LogWarning(val2); } text2 = string.Empty; } enabled = commandDefinition.Enabled?.Value ?? true; showInPlayerList = commandDefinition.ShowInPlayerList?.Value ?? (!commandDefinition.AdminOnly); showInAdminList = commandDefinition.ShowInAdminList?.Value ?? true; } dictionary[text] = commandDefinition; if (!string.IsNullOrEmpty(text2)) { dictionary[text2] = commandDefinition; } list.Add(new RuntimeCommand(commandDefinition, enabled, text, text2, showInPlayerList, showInAdminList)); } Dictionary dictionary2 = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (RuntimeCommand item in list) { AddToken(dictionary2, item.Definition.CanonicalName, item); AddToken(dictionary2, item.Definition.DefaultShortHand, item); AddToken(dictionary2, item.PrimaryName, item); AddToken(dictionary2, item.ShortHand, item); } _snapshot = new RuntimeSnapshot(flag, ShowPlayerCommandList?.Value ?? true, ShowAdminCommandList?.Value ?? true, list.ToArray(), dictionary2); } private static LegacyGlobalSettings ReadAndRemoveObsoleteCommandSettings(ConfigFile configFile) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown ConfigDefinition val = new ConfigDefinition("00 - Custom Command Settings", "EnableCustomCommandSettings"); ConfigDefinition val2 = new ConfigDefinition("00 - Custom Command Settings", "ShowPlayerCommandList"); ConfigDefinition val3 = new ConfigDefinition("00 - Custom Command Settings", "ShowAdminCommandList"); ConfigDefinition val4 = new ConfigDefinition("00 - Command Lists", "ShowPlayerCommandList"); ConfigDefinition val5 = new ConfigDefinition("00 - Command Lists", "ShowAdminCommandList"); ConfigDefinition val6 = new ConfigDefinition("01 - raidcommands", "Enabled"); ConfigDefinition val7 = new ConfigDefinition("01 - raidcommands", "Name"); ConfigDefinition val8 = new ConfigDefinition("01 - raidcommands", "ShortHand"); ConfigDefinition val9 = new ConfigDefinition("01 - raidcommands", "ShowInPlayerList"); ConfigDefinition val10 = new ConfigDefinition("01 - raidcommands", "ShowInAdminList"); ConfigEntry val11 = configFile.Bind(val, false, new ConfigDescription("Legacy RaidForge custom-command master switch.", (AcceptableValueBase)null, Array.Empty())); ConfigEntry val12 = configFile.Bind(val2, true, new ConfigDescription("Legacy RaidForge VCF help setting.", (AcceptableValueBase)null, Array.Empty())); ConfigEntry val13 = configFile.Bind(val3, true, new ConfigDescription("Legacy RaidForge VCF help setting.", (AcceptableValueBase)null, Array.Empty())); configFile.Bind(val4, true, new ConfigDescription("Obsolete RaidForge command-list setting.", (AcceptableValueBase)null, Array.Empty())); configFile.Bind(val5, true, new ConfigDescription("Obsolete RaidForge command-list setting.", (AcceptableValueBase)null, Array.Empty())); configFile.Bind(val6, true, new ConfigDescription("Obsolete RaidForge command-list setting.", (AcceptableValueBase)null, Array.Empty())); configFile.Bind(val7, "raidcommands", new ConfigDescription("Obsolete RaidForge command-list setting.", (AcceptableValueBase)null, Array.Empty())); configFile.Bind(val8, "rc", new ConfigDescription("Obsolete RaidForge command-list setting.", (AcceptableValueBase)null, Array.Empty())); configFile.Bind(val9, true, new ConfigDescription("Obsolete RaidForge command-list setting.", (AcceptableValueBase)null, Array.Empty())); configFile.Bind(val10, true, new ConfigDescription("Obsolete RaidForge command-list setting.", (AcceptableValueBase)null, Array.Empty())); LegacyGlobalSettings result = new LegacyGlobalSettings(val11.Value, val12.Value, val13.Value); configFile.Remove(val); configFile.Remove(val2); configFile.Remove(val3); configFile.Remove(val4); configFile.Remove(val5); configFile.Remove(val6); configFile.Remove(val7); configFile.Remove(val8); configFile.Remove(val9); configFile.Remove(val10); configFile.Save(); return result; } private static LegacyCommandSettings ReadAndRemoveLegacyRaidTimerSettings(ConfigFile configFile) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown ConfigDefinition val = new ConfigDefinition("14 - raidtimer", "Enabled"); ConfigDefinition val2 = new ConfigDefinition("14 - raidtimer", "Name"); ConfigDefinition val3 = new ConfigDefinition("14 - raidtimer", "ShortHand"); ConfigDefinition val4 = new ConfigDefinition("14 - raidtimer", "ShowInPlayerList"); ConfigDefinition val5 = new ConfigDefinition("14 - raidtimer", "ShowInAdminList"); ConfigEntry val6 = configFile.Bind(val, true, new ConfigDescription("Legacy RaidForge raidtimer setting.", (AcceptableValueBase)null, Array.Empty())); ConfigEntry val7 = configFile.Bind(val2, "raidtimer", new ConfigDescription("Legacy RaidForge raidtimer setting.", (AcceptableValueBase)null, Array.Empty())); ConfigEntry val8 = configFile.Bind(val3, "raidt", new ConfigDescription("Legacy RaidForge raidtimer setting.", (AcceptableValueBase)null, Array.Empty())); ConfigEntry val9 = configFile.Bind(val4, true, new ConfigDescription("Legacy RaidForge raidtimer setting.", (AcceptableValueBase)null, Array.Empty())); ConfigEntry val10 = configFile.Bind(val5, true, new ConfigDescription("Legacy RaidForge raidtimer setting.", (AcceptableValueBase)null, Array.Empty())); string name = (string.Equals(val7.Value, "raidtimer", StringComparison.OrdinalIgnoreCase) ? "raidtime" : val7.Value); LegacyCommandSettings result = new LegacyCommandSettings(val6.Value, name, val8.Value, val9.Value, val10.Value); configFile.Remove(val); configFile.Remove(val2); configFile.Remove(val3); configFile.Remove(val4); configFile.Remove(val5); configFile.Save(); return result; } private static void AddToken(Dictionary lookup, string token, RuntimeCommand runtime) { if (!string.IsNullOrWhiteSpace(token) && !lookup.ContainsKey(token)) { lookup[token] = runtime; } } private static bool IsReservedByAnotherDefinition(string token, CommandDefinition owner) { if (string.IsNullOrEmpty(token)) { return false; } CommandDefinition[] definitions = Definitions; foreach (CommandDefinition commandDefinition in definitions) { if (commandDefinition != owner && (string.Equals(token, commandDefinition.CanonicalName, StringComparison.OrdinalIgnoreCase) || string.Equals(token, commandDefinition.DefaultShortHand, StringComparison.OrdinalIgnoreCase))) { return true; } } return false; } private static string NormalizeConfiguredName(string configuredValue, string fallback, bool allowBlank, ManualLogSource logger, string canonicalName, string settingName) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown string text = (configuredValue ?? string.Empty).Trim().TrimStart('.'); if (allowBlank && text.Length == 0) { return string.Empty; } if (!IsValidCommandToken(text)) { if (logger != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(47, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[CommandSettings] Invalid "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(settingName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(configuredValue); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' for '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(canonicalName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'. Using '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(fallback); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } logger.LogWarning(val); } return fallback; } return text; } private static bool IsValidCommandToken(string value) { if (string.IsNullOrEmpty(value) || value.Length > 32 || !char.IsLetter(value[0])) { return false; } for (int i = 1; i < value.Length; i++) { char c = value[i]; if (!char.IsLetterOrDigit(c) && c != '_' && c != '-') { return false; } } return true; } private static CommandDefinition Public(string canonicalName, string defaultShortHand, string description, string usage = null) { return new CommandDefinition(canonicalName, defaultShortHand, description, usage, adminOnly: false); } private static CommandDefinition Admin(string canonicalName, string defaultShortHand, string description, string usage = null) { return new CommandDefinition(canonicalName, defaultShortHand, description, usage, adminOnly: true); } } public static class GolemAutomationConfig { private static Dictionary Enabled, ConfigEntry Day)> _healthLevelConfigs = new Dictionary, ConfigEntry)>(); private static ManualLogSource _logger; public const string CONFIG_SECTION_MAIN_CONTROLS = "GolemMainControls"; public const string CONFIG_SECTION_AUTOMATION_SCHEDULE = "GolemDayBasedAutomationSchedule"; public static readonly Dictionary GolemHpEstimates = new Dictionary { { (SiegeWeaponHealth)0, 750 }, { (SiegeWeaponHealth)1, 1000 }, { (SiegeWeaponHealth)2, 1250 }, { (SiegeWeaponHealth)3, 1750 }, { (SiegeWeaponHealth)4, 2500 }, { (SiegeWeaponHealth)5, 3250 }, { (SiegeWeaponHealth)6, 4000 }, { (SiegeWeaponHealth)7, 5000 }, { (SiegeWeaponHealth)8, 7500 } }; public static ConfigFile ConfigFileInstance { get; private set; } public static ConfigEntry EnableDayBasedAutomation { get; private set; } public static ConfigEntry ServerStartDateForAutomation { get; private set; } public static ConfigEntry ManualSiegeWeaponHealthOverride { get; private set; } public static SortedDictionary ParsedDayBasedSchedule { get; private set; } = new SortedDictionary(); public static DateTime? ParsedStartDate { get; private set; } = null; public static void Initialize(ConfigFile configFile, ManualLogSource logger) { //IL_0017: 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_0032: Expected O, but got Unknown //IL_0032: Expected O, but got Unknown //IL_0042: 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_0061: Expected O, but got Unknown //IL_0061: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_0090: Expected O, but got Unknown //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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Invalid comparison between Unknown and I4 //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Invalid comparison between Unknown and I4 //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Expected O, but got Unknown //IL_01d0: Unknown result type (might be due to invalid IL or missing references) ConfigFileInstance = configFile; _logger = logger; EnableDayBasedAutomation = configFile.Bind(new ConfigDefinition("GolemMainControls", "EnableDayBasedAutomation"), true, new ConfigDescription("Enable automatic adjustment of Siege Golem health based on server days passed. This is overridden if a ManualSiegeWeaponHealthOverride is set.", (AcceptableValueBase)null, Array.Empty())); ServerStartDateForAutomation = configFile.Bind(new ConfigDefinition("GolemMainControls", "ServerStartDateForAutomation"), string.Empty, new ConfigDescription("The date/time the server 'started' for day-based automation. Format: yyyy-MM-dd HH:mm:ss. Required if DayBasedAutomation is enabled.", (AcceptableValueBase)null, Array.Empty())); ManualSiegeWeaponHealthOverride = configFile.Bind(new ConfigDefinition("GolemMainControls", "ManualOverrideSiegeLevel"), string.Empty, new ConfigDescription("Manually set a specific SiegeWeaponHealth level (e.g., 'Normal', 'High', 'Max'). If set to a valid level name, this overrides day-based automation. Set to empty string to disable this manual override and use day-based automation (if enabled).", (AcceptableValueBase)null, Array.Empty())); _healthLevelConfigs.Clear(); foreach (SiegeWeaponHealth value in Enum.GetValues(typeof(SiegeWeaponHealth))) { int num = (((int)value != 2) ? (-1) : 0); bool flag = (int)value == 2; ConfigDefinition val2 = new ConfigDefinition("GolemDayBasedAutomationSchedule", $"{value}_EnableInSchedule"); ConfigDescription val3 = new ConfigDescription($"Enable {value} Golem health for the day-based schedule.", (AcceptableValueBase)null, Array.Empty()); ConfigEntry item = configFile.Bind(val2, flag, val3); ConfigDefinition val4 = new ConfigDefinition("GolemDayBasedAutomationSchedule", $"{value}_DayToActivateInSchedule"); ConfigDescription val5 = new ConfigDescription($"Day number (from 0) for {value} health in the day-based schedule if enabled.", (AcceptableValueBase)null, Array.Empty()); ConfigEntry item2 = configFile.Bind(val4, num, val5); _healthLevelConfigs[value] = (item, item2); } ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value && _logger != null) { _logger.LogInfo((object)"[GolemAutomationConfig] Initialized."); } } public static bool SetServerStartDateAndSave(string dateString) { if (ServerStartDateForAutomation == null || ConfigFileInstance == null) { ManualLogSource logger = _logger; if (logger != null) { logger.LogError((object)"[GolemAutomationConfig] Cannot set start date: Config not fully initialized."); } return false; } ServerStartDateForAutomation.Value = dateString; ConfigFileInstance.Save(); ReloadAndParseAll(); LoggingHelper.Info("[GolemAutomationConfig] Server start date for automation set to '" + dateString + "' and saved."); return true; } public static void SetManualSiegeWeaponHealthOverrideAndSave(SiegeWeaponHealth? level) { //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) if (ManualSiegeWeaponHealthOverride == null || ConfigFileInstance == null) { ManualLogSource logger = _logger; if (logger != null) { logger.LogError((object)"[GolemAutomationConfig] Cannot set manual level override: Config not fully initialized."); } } else { ManualSiegeWeaponHealthOverride.Value = (level.HasValue ? ((object)level.GetValueOrDefault()/*cast due to .constrained prefix*/).ToString() : null) ?? string.Empty; ConfigFileInstance.Save(); LoggingHelper.Info("[GolemAutomationConfig] Manual Golem SiegeWeaponHealth override set to '" + ManualSiegeWeaponHealthOverride.Value + "' and saved."); } } public static void ClearManualSiegeWeaponHealthOverrideAndSave() { if (ManualSiegeWeaponHealthOverride == null || ConfigFileInstance == null) { ManualLogSource logger = _logger; if (logger != null) { logger.LogError((object)"[GolemAutomationConfig] Cannot clear manual level override: Config not fully initialized."); } } else { ManualSiegeWeaponHealthOverride.Value = string.Empty; ConfigFileInstance.Save(); LoggingHelper.Info("[GolemAutomationConfig] Manual Golem SiegeWeaponHealth override cleared."); } } public static void ReloadAndParseAll() { if (_logger != null) { ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { _logger.LogInfo((object)"[GolemAutomationConfig] Reloading and parsing Golem settings..."); } ParseStartDate(); ParseDayBasedSchedule(); } } private static void ParseStartDate() { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown ParsedStartDate = null; string text = ServerStartDateForAutomation.Value?.Trim() ?? ""; if (string.IsNullOrWhiteSpace(text)) { return; } bool flag = default(bool); ManualLogSource logger; if (DateTime.TryParseExact(text, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var result)) { ParsedStartDate = result; ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging == null || !enableVerboseLogging.Value) { return; } logger = _logger; if (logger != null) { BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(61, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GolemAutomationConfig] Parsed ServerStartDateForAutomation: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ParsedStartDate.Value, "yyyy-MM-dd HH:mm:ss"); } logger.LogInfo(val); } return; } logger = _logger; if (logger != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(72, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[GolemAutomationConfig] Invalid ServerStartDateForAutomation format: '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'."); } logger.LogError(val2); } } private static void ParseDayBasedSchedule() { //IL_0142: 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_00ae: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Expected O, but got Unknown ParsedDayBasedSchedule.Clear(); ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)"[GolemAutomationConfig] Parsing Golem Health Day-Based Schedule..."); } } bool flag = default(bool); ManualLogSource logger2; foreach (KeyValuePair, ConfigEntry)> healthLevelConfig in _healthLevelConfigs) { if (!healthLevelConfig.Value.Item1.Value || healthLevelConfig.Value.Item2.Value < 0) { continue; } if (ParsedDayBasedSchedule.ContainsKey(healthLevelConfig.Value.Item2.Value)) { logger2 = _logger; if (logger2 != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(73, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[GolemAutomationConfig] Day "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(healthLevelConfig.Value.Item2.Value); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" in schedule already has "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ParsedDayBasedSchedule[healthLevelConfig.Value.Item2.Value]); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", overwriting with "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(healthLevelConfig.Key); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } logger2.LogWarning(val); } } ParsedDayBasedSchedule[healthLevelConfig.Value.Item2.Value] = healthLevelConfig.Key; } ConfigEntry enableVerboseLogging2 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging2 == null || !enableVerboseLogging2.Value) { return; } logger2 = _logger; if (logger2 != null) { BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(59, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[GolemAutomationConfig] Parsed "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ParsedDayBasedSchedule.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" day-based schedule entries."); } logger2.LogInfo(val2); } } public static SiegeWeaponHealth? GetScheduledHealthForDay(int dayCount) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (ParsedDayBasedSchedule.Count == 0) { return null; } KeyValuePair keyValuePair = (from kvp in ParsedDayBasedSchedule where kvp.Key <= dayCount orderby kvp.Key descending select kvp).FirstOrDefault(); if (ParsedDayBasedSchedule.Any((KeyValuePair kvp) => kvp.Key <= dayCount)) { return keyValuePair.Value; } return null; } } public static class MapIconsConfig { public static ConfigEntry EnableOfflineRaidMapIcon; public static ConfigEntry OfflineRaidMapIconPrefab; public static ConfigEntry EnableDecayRaidMapIcon; public static ConfigEntry DecayRaidMapIconPrefab; public static ConfigEntry EnableOptInRaidMapIcon; public static ConfigEntry EnableOptOutRaidMapIcon; public static ConfigEntry RaidMapIconTimeoutSeconds; public static void Initialize(ConfigFile config) { EnableOfflineRaidMapIcon = config.Bind("MapIcons", "EnableOfflineRaidMapIcon", true, "Display a map icon on the map when an offline base is being raided."); OfflineRaidMapIconPrefab = config.Bind("MapIcons", "OfflineRaidMapIconPrefab", GetLegacyMapIconPrefabValue(config, "OfflineRaidMapIconPrefabGuid", MapIconPrefabCatalog.DefaultRaidForgeMapIcon.Name, MapIconPrefabCatalog.DefaultRaidForgeMapIcon.GuidHash), "Prefab name, short map icon name, or GUID hash for the map icon to display for offline raids. " + MapIconPrefabCatalog.GetShortNameExamples() + " Default: MapIcon_CastleObject_Tailor."); EnableDecayRaidMapIcon = config.Bind("MapIcons", "EnableDecayRaidMapIcon", true, "Display a map icon on the map when a decayed base is being raided."); DecayRaidMapIconPrefab = config.Bind("MapIcons", "DecayRaidMapIconPrefab", GetLegacyMapIconPrefabValue(config, "DecayRaidMapIconPrefabGuid", MapIconPrefabCatalog.DefaultRaidForgeMapIcon.Name, MapIconPrefabCatalog.DefaultRaidForgeMapIcon.GuidHash), "Prefab name, short map icon name, or GUID hash for the map icon to display for decay raids. " + MapIconPrefabCatalog.GetShortNameExamples() + " Default: MapIcon_CastleObject_Tailor."); EnableOptInRaidMapIcon = config.Bind("MapIcons", "EnableOptInRaidMapIcon", true, "Display a map icon on opted-in bases while raids are enabled."); EnableOptOutRaidMapIcon = config.Bind("MapIcons", "EnableOptOutRaidMapIcon", true, "Display a map icon on opted-out bases while DefaultEveryoneOptedIn is enabled, DefaultEveryoneOptedOut is disabled, and raids are enabled."); RaidMapIconTimeoutSeconds = config.Bind("MapIcons", "RaidMapIconTimeoutSeconds", 300, "How many seconds (default 300 = 5 mins) the map icon remains after the last hit."); RemoveLegacyPassiveIconEntries(config); } private static string GetLegacyMapIconPrefabValue(ConfigFile config, string legacyKey, string defaultPrefabName, int defaultGuidHash) { ConfigEntry val = default(ConfigEntry); if (!config.TryGetEntry("MapIcons", legacyKey, ref val)) { return defaultPrefabName; } if (val.Value != defaultGuidHash) { return val.Value.ToString(CultureInfo.InvariantCulture); } return defaultPrefabName; } private static void RemoveLegacyPassiveIconEntries(ConfigFile config) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown if (config.Remove(new ConfigDefinition("MapIcons", "EnableOfflineProtectIcons")) | config.Remove(new ConfigDefinition("MapIcons", "RefreshClientMapDataAfterIconSpawn")) | config.Remove(new ConfigDefinition("MapIcons", "OfflineProtectIconPrefabGuid")) | config.Remove(new ConfigDefinition("MapIcons", "OfflineRaidMapIconPrefabGuid")) | config.Remove(new ConfigDefinition("MapIcons", "DecayRaidMapIconPrefabGuid")) | config.Remove(new ConfigDefinition("MapIcons", "OptInRaidMapIconPrefabGuid")) | config.Remove(new ConfigDefinition("MapIcons", "OptOutRaidMapIconPrefabGuid"))) { config.Save(); } } } public static class OfflineRaidProtectionConfig { public static ConfigEntry EnableOfflineRaidProtection; public static ConfigEntry EnableOfflineProtectionDaySchedule; public static ConfigEntry GracePeriodDurationMinutes; public static ConfigEntry AnnounceOfflineRaid; public static ConfigEntry AnnounceDecayedBaseRaid; public static Dictionary> DayProtectionToggles { get; private set; } public static void Initialize(ConfigFile config) { DayProtectionToggles = new Dictionary>(); EnableOfflineRaidProtection = config.Bind("OfflineRaidProtection", "EnableOfflineProtection", true, "Enable or disable the offline raid protection system."); EnableOfflineProtectionDaySchedule = config.Bind("OfflineRaidProtection", "EnableOfflineProtectionDaySchedule", false, "If true, Offline Raid Protection only blocks damage on the enabled days below. Offline timestamps are still tracked on disabled days."); foreach (DayOfWeek value in Enum.GetValues(typeof(DayOfWeek))) { DayProtectionToggles[value] = config.Bind("OfflineProtectionDays", $"{value}EnableOfflineProtection", true, $"If EnableOfflineProtectionDaySchedule is true, this controls whether Offline Raid Protection blocks damage on {value}."); } GracePeriodDurationMinutes = config.Bind("OfflineRaidProtection", "GracePeriodMinutes", 15f, "The duration, in minutes, of the grace period after all relevant defenders log off. During this period, their base is still considered vulnerable and can be raided. Set to 0 for instant offline protection when players log off."); AnnounceOfflineRaid = config.Bind("OfflineRaidProtection", "AnnounceOfflineRaid", true, "If true, a global announcement will be made when a base whose defenders are all offline is attacked with siege damage. This can work even when Offline Raid Protection is disabled, allowing normal scheduled raiding servers to still announce offline raids."); AnnounceDecayedBaseRaid = config.Bind("OfflineRaidProtection", "AnnounceDecayedBaseRaid", true, "If true, a global announcement will be made when a decayed base is being damaged by a player."); } public static bool IsOfflineProtectionAllowedToday() { return IsOfflineProtectionAllowedOn(DateTime.Now.DayOfWeek); } public static bool IsOfflineProtectionAllowedOn(DayOfWeek day) { ConfigEntry enableOfflineRaidProtection = EnableOfflineRaidProtection; if (enableOfflineRaidProtection == null || !enableOfflineRaidProtection.Value) { return false; } ConfigEntry enableOfflineProtectionDaySchedule = EnableOfflineProtectionDaySchedule; if (enableOfflineProtectionDaySchedule == null || !enableOfflineProtectionDaySchedule.Value) { return true; } if (DayProtectionToggles == null || !DayProtectionToggles.TryGetValue(day, out var value)) { return true; } return value.Value; } } public static class OptInRaidingConfig { private const string SECTION_MAIN = "Opt-In Raiding"; public static ConfigFile ConfigFileInstance { get; private set; } public static ConfigEntry EnableOptInRaiding { get; private set; } public static ConfigEntry DefaultEveryoneOptedOut { get; private set; } public static ConfigEntry DefaultEveryoneOptedIn { get; private set; } public static ConfigEntry OptInLockDurationHours { get; private set; } public static ConfigEntry BlockOptInChangesDuringRaidHours { get; private set; } public static ConfigEntry AutoOptOutAfterCooldown { get; private set; } public static ConfigEntry AutoOptInShardHolders { get; private set; } public static bool UseDefaultOptInMode { get { ConfigEntry defaultEveryoneOptedIn = DefaultEveryoneOptedIn; if (defaultEveryoneOptedIn != null && defaultEveryoneOptedIn.Value) { ConfigEntry defaultEveryoneOptedOut = DefaultEveryoneOptedOut; if (defaultEveryoneOptedOut == null) { return true; } return !defaultEveryoneOptedOut.Value; } return false; } } public static void Initialize(ConfigFile configFile) { ConfigFileInstance = configFile; EnableOptInRaiding = configFile.Bind("Opt-In Raiding", "EnableOptInRaiding", false, "If true, this system is active only when Offline Raid Protection is disabled. By default, all bases are protected unless players/clans use the .raidoptin command.\nIMPORTANT: Offline Raid Protection takes priority if both systems are enabled."); DefaultEveryoneOptedOut = configFile.Bind("Opt-In Raiding", "DefaultEveryoneOptedOut", true, "If true, everyone starts opted-out/protected and only .raidoptin entries are saved. This is the normal/default mode."); DefaultEveryoneOptedIn = configFile.Bind("Opt-In Raiding", "DefaultEveryoneOptedIn", false, "If true and DefaultEveryoneOptedOut is false, everyone starts opted-in/raidable and only .raidoptout entries are saved."); OptInLockDurationHours = configFile.Bind("Opt-In Raiding", "OptInLockDurationHours", 24, "The number of hours a player/clan must wait before switching back after choosing a manual raid status."); BlockOptInChangesDuringRaidHours = configFile.Bind("Opt-In Raiding", "BlockOptInChangesDuringRaidHours", true, "If true, players/clans cannot use .raidoptin or .raidoptout while a raid window is active."); AutoOptOutAfterCooldown = configFile.Bind("Opt-In Raiding", "AutoOptOutAfterCooldown", false, "If true, players/clans are automatically opted-out the moment their lock duration expires."); AutoOptInShardHolders = configFile.Bind("Opt-In Raiding", "AutoOptInShardHolders", true, "If true, holding a soul shard automatically treats you as opted-in during raid windows."); NormalizeDefaultMode(); } private static void NormalizeDefaultMode() { if (DefaultEveryoneOptedOut.Value && DefaultEveryoneOptedIn.Value) { DefaultEveryoneOptedIn.Value = false; ConfigFileInstance.Save(); LoggingHelper.Warning("[OptInRaidingConfig] DefaultEveryoneOptedOut and DefaultEveryoneOptedIn were both enabled. DefaultEveryoneOptedOut wins, so DefaultEveryoneOptedIn was disabled."); } } } public static class OptInScheduleConfig { private const string SECTION_MAIN = "Opt-In Schedule"; public static ConfigFile ConfigFileInstance { get; private set; } public static ConfigEntry EnableOptInSchedule { get; private set; } public static Dictionary> DayToggles { get; private set; } public static void Initialize(ConfigFile configFile) { ConfigFileInstance = configFile; DayToggles = new Dictionary>(); EnableOptInSchedule = configFile.Bind("Opt-In Schedule", "EnableOptInSchedule", false, "If true, the daily schedule below is used. If false, the standard opt-in system is used. Good for if you want to allow teams to raid on weekdays an allow others to not be raided, while still making everyone raidable on weekends."); foreach (DayOfWeek value in Enum.GetValues(typeof(DayOfWeek))) { bool flag = value >= DayOfWeek.Monday && value <= DayOfWeek.Friday; DayToggles[value] = configFile.Bind("Opt-In Schedule", $"{value}AllowOptInSystem", flag, $"If true, the opt-in/opt-out system works normally on {value}. If false, everyone is raidable on {value}."); } } public static bool IsOptInSystemAllowedToday() { DayOfWeek dayOfWeek = DateTime.Now.DayOfWeek; if (DayToggles.TryGetValue(dayOfWeek, out var value)) { return value.Value; } return true; } } public static class PurchasedOrpConfig { private const string SECTION_MAIN = "Purchased ORP"; public static ConfigEntry EnablePurchasedOrp { get; private set; } public static ConfigEntry CurrencyPrefab { get; private set; } public static ConfigEntry CurrencyDisplayName { get; private set; } public static ConfigEntry CurrencyAmountPerRaidDay { get; private set; } public static ConfigEntry MaxPurchaseRaidDays { get; private set; } public static void Initialize(ConfigFile configFile) { EnablePurchasedOrp = configFile.Bind("Purchased ORP", "EnablePurchasedOrp", false, "If true, players can use .buyorp to buy raid-day protection. This mode only works when normal Offline Raid Protection and Opt-In Raiding are both disabled."); CurrencyPrefab = configFile.Bind("Purchased ORP", "CurrencyPrefab", "Item_Ingredient_Coin_Silver", "Prefab name or GUID hash for the item spent by .buyorp. Default: Item_Ingredient_Coin_Silver."); CurrencyDisplayName = configFile.Bind("Purchased ORP", "CurrencyDisplayName", "Silver Coins", "Player-facing item name shown in .buyorp messages. This does not affect which prefab is removed from inventory."); CurrencyAmountPerRaidDay = configFile.Bind("Purchased ORP", "CurrencyAmountPerRaidDay", 100, "How many of CurrencyPrefab are required per purchased raid day."); MaxPurchaseRaidDays = configFile.Bind("Purchased ORP", "MaxPurchaseRaidDays", 30, "Maximum number of raid days a player can buy in one .buyorp command."); } public static bool IsPurchasedOrpActive() { ConfigEntry enablePurchasedOrp = EnablePurchasedOrp; if (enablePurchasedOrp != null && enablePurchasedOrp.Value) { ConfigEntry enableOfflineRaidProtection = OfflineRaidProtectionConfig.EnableOfflineRaidProtection; if (enableOfflineRaidProtection == null || !enableOfflineRaidProtection.Value) { ConfigEntry enableOptInRaiding = OptInRaidingConfig.EnableOptInRaiding; if (enableOptInRaiding == null) { return true; } return !enableOptInRaiding.Value; } } return false; } } public struct RaidScheduleEntry { public DayOfWeek Day; public TimeSpan StartTime; public TimeSpan EndTime; public bool SpansMidnight; } public static class RaidConfig { private static ManualLogSource _logger; private static Dictionary Start, ConfigEntry End)> _dailyConfigs; public const string SECTION_GENERAL = "General"; public const string SECTION_SCHEDULE = "DailyRaidSchedule"; public static ConfigFile ConfigFileInstance { get; private set; } public static List Schedule { get; private set; } public static ConfigEntry AllowWaygateTeleports { get; private set; } public static ConfigEntry ShowCurrentRaidingStatusInRaidStatus { get; private set; } public static ConfigEntry RaidScheduleTimeZoneDisplayString { get; private set; } public static ConfigEntry RaidScheduleDisplayOffsetHours { get; private set; } public static void Initialize(ConfigFile configFile, ManualLogSource logger) { ConfigFileInstance = configFile; _logger = logger; Schedule = new List(); _dailyConfigs = new Dictionary, ConfigEntry)>(); AllowWaygateTeleports = configFile.Bind("General", "AllowWaygateTeleportsDuringRaid", true, "Allow teleportation via Waygates during an active raid window (if global raids are ON)."); ShowCurrentRaidingStatusInRaidStatus = configFile.Bind("General", "ShowCurrentRaidingStatusInRaidStatus", false, "If true, .raidstatus/.raids adds a second line per base showing whether that base is currently being raided/breached."); RaidScheduleTimeZoneDisplayString = configFile.Bind("General", "RaidScheduleTimeZoneForDisplay", "Server Time", "Text label shown next to raid times in .raidtime/.raidt/.raiddays/.raidd. This label does not convert time; use RaidScheduleDisplayOffsetHours for a fixed adjustment."); RaidScheduleDisplayOffsetHours = configFile.Bind("General", "RaidScheduleDisplayOffsetHours", 0.0, "Fixed schedule offset, in hours, added to the dedicated server's local clock for raid checks and command output. The server clock remains authoritative. Positive values move RaidForge time later; negative values move it earlier. Example: server 08:00 with offset 2 is treated as 10:00. This does not adjust automatically for daylight saving time."); string defaultValue = "00:00"; string defaultValue2 = "20:00"; string defaultValue3 = "22:00"; _dailyConfigs[DayOfWeek.Monday] = (BindDailyRaidTime(configFile, DayOfWeek.Monday, "StartTime", defaultValue), BindDailyRaidTime(configFile, DayOfWeek.Monday, "EndTime", defaultValue)); _dailyConfigs[DayOfWeek.Tuesday] = (BindDailyRaidTime(configFile, DayOfWeek.Tuesday, "StartTime", defaultValue), BindDailyRaidTime(configFile, DayOfWeek.Tuesday, "EndTime", defaultValue)); _dailyConfigs[DayOfWeek.Wednesday] = (BindDailyRaidTime(configFile, DayOfWeek.Wednesday, "StartTime", defaultValue), BindDailyRaidTime(configFile, DayOfWeek.Wednesday, "EndTime", defaultValue)); _dailyConfigs[DayOfWeek.Thursday] = (BindDailyRaidTime(configFile, DayOfWeek.Thursday, "StartTime", defaultValue), BindDailyRaidTime(configFile, DayOfWeek.Thursday, "EndTime", defaultValue)); _dailyConfigs[DayOfWeek.Friday] = (BindDailyRaidTime(configFile, DayOfWeek.Friday, "StartTime", defaultValue2), BindDailyRaidTime(configFile, DayOfWeek.Friday, "EndTime", defaultValue3)); _dailyConfigs[DayOfWeek.Saturday] = (BindDailyRaidTime(configFile, DayOfWeek.Saturday, "StartTime", defaultValue2), BindDailyRaidTime(configFile, DayOfWeek.Saturday, "EndTime", defaultValue3)); _dailyConfigs[DayOfWeek.Sunday] = (BindDailyRaidTime(configFile, DayOfWeek.Sunday, "StartTime", defaultValue2), BindDailyRaidTime(configFile, DayOfWeek.Sunday, "EndTime", defaultValue3)); ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value && _logger != null) { _logger.LogInfo((object)"[RaidConfig] Initialized."); } } public static DateTime GetRaidScheduleNow() { return DateTime.Now + GetRaidScheduleOffset(); } public static TimeSpan GetRaidScheduleOffset() { double num = RaidScheduleDisplayOffsetHours?.Value ?? 0.0; if (double.IsNaN(num) || double.IsInfinity(num)) { return TimeSpan.Zero; } return TimeSpan.FromHours(num); } private static ConfigEntry BindDailyRaidTime(ConfigFile configFile, DayOfWeek day, string suffix, string defaultValue) { string value = ((suffix == "StartTime") ? "start" : "end"); return configFile.Bind("DailyRaidSchedule", $"{day}{suffix}", defaultValue, $"Raid window {value} time for {day} in HH:mm server-local time. Set both start and end to 00:00 for no raids. Use EndTime=24:00 to allow a full-day 00:00-24:00 raid window."); } public static void ParseSchedule() { //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Expected O, but got Unknown //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Expected O, but got Unknown if (_logger == null || _dailyConfigs == null) { Console.WriteLine("[RaidConfig] CRITICAL: RaidConfig not properly initialized before parsing schedule."); Schedule = new List(); return; } ConfigEntry enableVerboseLogging = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging != null && enableVerboseLogging.Value) { _logger.LogInfo((object)"[RaidConfig] Parsing raid schedule from configuration..."); } List list = new List(); bool flag = default(bool); foreach (DayOfWeek item in Enum.GetValues(typeof(DayOfWeek)).Cast()) { if (!_dailyConfigs.TryGetValue(item, out (ConfigEntry, ConfigEntry) value)) { continue; } string text = value.Item1.Value?.Trim() ?? "00:00"; string text2 = value.Item2.Value?.Trim() ?? "00:00"; if (text == "00:00" && (text2 == "00:00" || string.IsNullOrEmpty(text2))) { continue; } if (!TimeSpan.TryParseExact(text, "h\\:mm", CultureInfo.InvariantCulture, out var result) && !TimeSpan.TryParseExact(text, "hh\\:mm", CultureInfo.InvariantCulture, out result)) { ConfigEntry enableVerboseLogging2 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging2 != null && enableVerboseLogging2.Value) { ManualLogSource logger = _logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(64, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RaidConfig] Could not parse start time '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Skipping entry."); } logger.LogWarning(val); } continue; } bool flag2 = string.Equals(text2, "24:00", StringComparison.Ordinal); TimeSpan result2; if (flag2 || text2 == "00:00" || string.IsNullOrEmpty(text2)) { result2 = TimeSpan.Zero; } else if (!TimeSpan.TryParseExact(text2, "h\\:mm", CultureInfo.InvariantCulture, out result2) && !TimeSpan.TryParseExact(text2, "hh\\:mm", CultureInfo.InvariantCulture, out result2)) { ConfigEntry enableVerboseLogging3 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging3 != null && enableVerboseLogging3.Value) { ManualLogSource logger2 = _logger; BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(62, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[RaidConfig] Could not parse end time '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Skipping entry."); } logger2.LogWarning(val); } continue; } bool flag3 = flag2 || (result2 < result && result2 != TimeSpan.Zero) || (result != TimeSpan.Zero && result2 == TimeSpan.Zero); list.Add(new RaidScheduleEntry { Day = item, StartTime = result, EndTime = result2, SpansMidnight = flag3 }); ConfigEntry enableVerboseLogging4 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging4 != null && enableVerboseLogging4.Value) { string text3 = ((result2 == TimeSpan.Zero && flag3) ? "Midnight" : result2.ToString("hh\\:mm")); ManualLogSource logger3 = _logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(40, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[RaidConfig] Parsed schedule entry: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(result, "hh\\:mm"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" - "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text3); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(flag3 ? " (spans midnight)" : ""); } logger3.LogInfo(val2); } } Schedule = list; ConfigEntry enableVerboseLogging5 = TroubleshootingConfig.EnableVerboseLogging; if (enableVerboseLogging5 != null && enableVerboseLogging5.Value) { ManualLogSource logger4 = _logger; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(49, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[RaidConfig] Total raid schedule entries parsed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(Schedule.Count); } logger4.LogInfo(val2); } } } public static class RaidInterferenceConfig { private const string SECTION_MAIN = "Raid Interference"; public static ConfigFile ConfigFileInstance { get; private set; } public static ConfigEntry EnableRaidInterference { get; private set; } public static ConfigEntry DisableInterferenceForOfflineRaids { get; private set; } public static ConfigEntry DisableInterferenceForDecayingBases { get; private set; } public static ConfigEntry ExemptBearFormUsers { get; private set; } public static void Initialize(ConfigFile configFile, ManualLogSource logger = null) { ConfigFileInstance = configFile; EnableRaidInterference = configFile.Bind("Raid Interference", "EnableRaidInterference", false, "If true, vampires trying to interfer will be burned til their hp hits 0 or until they leave the base.(base must be breached first) "); DisableInterferenceForOfflineRaids = configFile.Bind("Raid Interference", "DisableInterferenceForOfflineRaids", true, "If true, third parties will NOT get burned if the base being raided is offline (all defenders offline)."); DisableInterferenceForDecayingBases = configFile.Bind("Raid Interference", "DisableInterferenceForDecayingBases", true, "If true, third parties will NOT get burned if the base being raided is in a decaying state (castle heart is out of blood)."); ExemptBearFormUsers = configFile.Bind("Raid Interference", "ExemptBearFormUsers", true, "If true, players in Bear Form are immune to the burn. Good for spectators."); if (logger != null) { logger.LogInfo((object)"[RaidInterferenceConfig] Initialized."); } } } public static class ServantLimitsConfig { private const string SectionGeneral = "00 - General"; private const string LegacySectionGeneral = "General"; private const string SectionCharacterLimits = "Character Limits"; private static readonly Dictionary> _characterLimitEntries = new Dictionary>(StringComparer.OrdinalIgnoreCase); public static ConfigFile ConfigFileInstance { get; private set; } public static ConfigEntry EnableServantLimits { get; private set; } public static ConfigEntry EnableDetailedLogging { get; private set; } public static IReadOnlyDictionary> CharacterLimitEntries => _characterLimitEntries; public static void Initialize(ConfigFile configFile) { ConfigFileInstance = configFile; _characterLimitEntries.Clear(); bool hasCurrentGeneralSection = ContainsSection(configFile.ConfigFilePath, "00 - General"); bool hasLegacyGeneralSection = ContainsSection(configFile.ConfigFilePath, "General"); bool saveOnConfigSet = configFile.SaveOnConfigSet; try { configFile.SaveOnConfigSet = false; EnableServantLimits = configFile.Bind("00 - General", "EnableServantLimits", false, "Enforces nonblank entries under Character Limits. Blank character entries are unlimited."); EnableDetailedLogging = configFile.Bind("00 - General", "EnableDetailedLogging", false, "Logs servant-limit mappings, matching coffin states, castle-heart connections, reservations, and allow/block decisions. Enable only while diagnosing."); MigrateLegacyGeneralSection(configFile, hasCurrentGeneralSection, hasLegacyGeneralSection); } finally { configFile.SaveOnConfigSet = saveOnConfigSet; } configFile.Save(); } public static void RegisterCharacterLimits(IReadOnlyList> convertibleCharacters) { if (ConfigFileInstance == null || convertibleCharacters == null) { return; } bool saveOnConfigSet = ConfigFileInstance.SaveOnConfigSet; try { ConfigFileInstance.SaveOnConfigSet = false; foreach (KeyValuePair convertibleCharacter in convertibleCharacters) { if (!_characterLimitEntries.ContainsKey(convertibleCharacter.Key)) { ConfigEntry value = ConfigFileInstance.Bind("Character Limits", convertibleCharacter.Key, string.Empty, "Maximum per castle after conversion to " + convertibleCharacter.Value + ". Leave blank for unlimited; use 0 to block this character completely."); _characterLimitEntries.Add(convertibleCharacter.Key, value); } } } finally { ConfigFileInstance.SaveOnConfigSet = saveOnConfigSet; } ConfigFileInstance.Save(); } private static void MigrateLegacyGeneralSection(ConfigFile configFile, bool hasCurrentGeneralSection, bool hasLegacyGeneralSection) { if (hasLegacyGeneralSection) { ConfigEntry val = configFile.Bind("General", "EnableServantLimits", false, string.Empty); ConfigEntry val2 = configFile.Bind("General", "EnableDetailedLogging", false, string.Empty); if (!hasCurrentGeneralSection) { EnableServantLimits.Value = val.Value; EnableDetailedLogging.Value = val2.Value; } configFile.Remove(((ConfigEntryBase)val).Definition); configFile.Remove(((ConfigEntryBase)val2).Definition); } } private static bool ContainsSection(string configFilePath, string section) { if (string.IsNullOrWhiteSpace(configFilePath) || string.IsNullOrWhiteSpace(section) || !File.Exists(configFilePath)) { return false; } try { string b = "[" + section + "]"; foreach (string item in File.ReadLines(configFilePath)) { if (string.Equals(item.Trim(), b, StringComparison.OrdinalIgnoreCase)) { return true; } } } catch (IOException) { return false; } catch (UnauthorizedAccessException) { return false; } return false; } } public static class ShardConfig { public static ConfigEntry MaxAllowedShardsPerType { get; private set; } public static ConfigEntry DisableOrpForShardHolders { get; private set; } public static void Initialize(ConfigFile config) { MaxAllowedShardsPerType = config.Bind("Soul Shards", "MaxAllowedShardsPerType", 1, "The maximum unique number of the same soul shard type allowed on the server. You must change this if you allow more than one type of the same soul shard."); DisableOrpForShardHolders = config.Bind("Soul Shards", "DisableOrpForShardHolders", true, "If true, players or clans holding a soul shard will NOT receive Offline Raid Protection. If false, they get ORP like everyone else."); } } public static class TntRaidingConfig { private const string RaidingSection = "01 - TNT Castle Raiding"; private const string NormalDamageSection = "02 - Normal TNT Damage"; private const string CastleDamageSection = "03 - Castle Wall Damage"; public static ConfigFile ConfigFileInstance { get; private set; } public static ConfigEntry EnableTntRaiding { get; private set; } public static ConfigEntry T01NormalDamagePercent { get; private set; } public static ConfigEntry T02NormalDamagePercent { get; private set; } public static ConfigEntry T01CastleWallDamagePercent { get; private set; } public static ConfigEntry T02CastleWallDamagePercent { get; private set; } public static ConfigEntry UseNormalTntDamageAfterBreach { get; private set; } public static void Initialize(ConfigFile configFile, ManualLogSource logger = null) { ConfigFileInstance = configFile; EnableTntRaiding = configFile.Bind("01 - TNT Castle Raiding", "EnableTntRaiding", false, "If true, player-placed T01/T02 explosives can damage connected stone castle structures. Raid schedules, ORP, purchased protection, and opt-in rules still apply."); T01NormalDamagePercent = BindPercent(configFile, "02 - Normal TNT Damage", "T01NormalDamagePercent", "Scales all ordinary T01 explosive damage. 100 = native damage, 10 = 10% of native damage, and 110 = 10% above native damage."); T02NormalDamagePercent = BindPercent(configFile, "02 - Normal TNT Damage", "T02NormalDamagePercent", "Scales all ordinary T02 explosive damage. 100 = native damage, 10 = 10% of native damage, and 110 = 10% above native damage."); T01CastleWallDamagePercent = BindPercent(configFile, "03 - Castle Wall Damage", "T01CastleWallDamagePercent", "T01 damage against non-breached stone castle structures when TNT raiding is enabled. This is a percentage of native T01 explosive damage and does not multiply the normal-damage percentage."); T02CastleWallDamagePercent = BindPercent(configFile, "03 - Castle Wall Damage", "T02CastleWallDamagePercent", "T02 damage against non-breached stone castle structures when TNT raiding is enabled. This is a percentage of native T02 explosive damage and does not multiply the normal-damage percentage."); UseNormalTntDamageAfterBreach = configFile.Bind("03 - Castle Wall Damage", "UseNormalTntDamageAfterBreach", true, "If true, breached castle structures use that TNT tier's NormalDamagePercent. If false, they continue using that tier's CastleWallDamagePercent."); if (logger != null) { logger.LogInfo((object)"[TntRaidingConfig] TNT normal-damage and castle-raiding settings initialized."); } } public static float GetNormalDamagePercent(TntTier tier) { if (tier != TntTier.T01) { return T02NormalDamagePercent?.Value ?? 100f; } return T01NormalDamagePercent?.Value ?? 100f; } public static float GetCastleWallDamagePercent(TntTier tier) { if (tier != TntTier.T01) { return T02CastleWallDamagePercent?.Value ?? 100f; } return T01CastleWallDamagePercent?.Value ?? 100f; } public static void MigrateLegacySettingsIfNeeded(ConfigFile legacyWeaponConfig, bool tntConfigExistedBeforeLoad, ManualLogSource logger = null) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown if (legacyWeaponConfig == null || tntConfigExistedBeforeLoad) { return; } ConfigDefinition val = new ConfigDefinition("Weapon Raiding", "EnableTntRaiding"); ConfigDefinition val2 = new ConfigDefinition("Weapon Raiding", "TntPreBreachDamagePercent"); ConfigEntry val3 = legacyWeaponConfig.Bind(val, false, new ConfigDescription("Legacy RaidForge TNT setting. Migrated automatically to TntDamageAndRaiding.cfg.", (AcceptableValueBase)null, Array.Empty())); ConfigEntry val4 = legacyWeaponConfig.Bind(val2, 100f, new ConfigDescription("Legacy RaidForge TNT setting. Migrated automatically to TntDamageAndRaiding.cfg.", (AcceptableValueBase)null, Array.Empty())); EnableTntRaiding.Value = val3.Value; T01CastleWallDamagePercent.Value = val4.Value; T02CastleWallDamagePercent.Value = val4.Value; legacyWeaponConfig.Remove(val); legacyWeaponConfig.Remove(val2); legacyWeaponConfig.Save(); ConfigFileInstance.Save(); if (logger != null) { bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(83, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[TntRaidingConfig] Migrated legacy TNT settings: enabled="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(EnableTntRaiding.Value); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("T01/T02 castle damage="); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted(val4.Value); ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("%."); } logger.LogInfo(val5); } } private static ConfigEntry BindPercent(ConfigFile configFile, string section, string key, string description) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown return configFile.Bind(section, key, 100f, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1000f), Array.Empty())); } } public static class TroubleshootingConfig { private const string SECTION_LOGGING = "Logging"; public static ConfigFile ConfigFileInstance { get; private set; } public static ConfigEntry EnableTntDamageLogging { get; private set; } public static ConfigEntry EnableVerboseLogging { get; private set; } public static void Initialize(ConfigFile configFile, ManualLogSource logger = null) { ConfigFileInstance = configFile; EnableTntDamageLogging = configFile.Bind("Logging", "EnableTntDamageLogging", false, "Temporarily logs throttled castle-structure DealDamage events at Info level, including damage modifiers and the source ownership graph. Use this to identify TNT damage sources, then turn it off."); EnableVerboseLogging = configFile.Bind("Logging", "EnableVerboseLogging", false, "Set to true to enable detailed informational logs from RaidForge for debugging various features. This can be performance intensive and should be off, unless you are troubleshooting something."); if (logger != null) { logger.LogInfo((object)"[TroubleshootingConfig] Initialized."); } } } public static class WeaponRaidingConfig { private const string SECTION_MAIN = "Weapon Raiding"; public static ConfigFile ConfigFileInstance { get; private set; } public static ConfigEntry EnableWeaponRaiding { get; private set; } public static ConfigEntry WeaponDamageVsStoneMultiplier { get; private set; } public static void Initialize(ConfigFile configFile, ManualLogSource logger = null) { ConfigFileInstance = configFile; EnableWeaponRaiding = configFile.Bind("Weapon Raiding", "EnableWeaponRaiding", false, "If true, players can damage castle walls/structures with regular weapons."); WeaponDamageVsStoneMultiplier = configFile.Bind("Weapon Raiding", "WeaponDamageVsStoneMultiplier", 0.5f, "The damage multiplier against Stone Structures (Walls, Doors). \n0.0 = No Damage .\n1.0 = Full Weapon Damage.\n0.5 = Half Damage (Recommended to keep Golems relevant)."); if (logger != null) { logger.LogInfo((object)"[WeaponRaidingConfig] Weapon structure raiding settings initialized."); } } } } namespace RaidForge.Commands { internal static class CommandText { public static string ConfigLine(string key, string value) { return ChatColors.InfoText(key + ": ") + value; } public static string StatusLine(string key, string value) { return ConfigLine(key, value); } public static string CountText(int count) { return ChatColors.AccentText(count.ToString(CultureInfo.InvariantCulture)); } public static string EnabledText(bool value) { if (!value) { return ChatColors.WarningText("Disabled"); } return ChatColors.SuccessText("Enabled"); } public static string YesNoText(bool value) { if (!value) { return ChatColors.WarningText("No"); } return ChatColors.SuccessText("Yes"); } public static string FormatDuration(TimeSpan duration) { if (duration < TimeSpan.Zero) { duration = TimeSpan.Zero; } if (!(duration.TotalHours >= 1.0)) { if (!(duration.TotalMinutes >= 1.0)) { return $"{Math.Max(0, duration.Seconds)}s"; } return $"{duration.Minutes}m {duration.Seconds}s"; } return $"{(int)duration.TotalHours}h {duration.Minutes}m"; } public static string FormatTime(TimeSpan time) { return (DateTime.MinValue + time).ToString("h:mm tt", CultureInfo.InvariantCulture); } } public class GolemCommands { [Command("golemstartdate", null, null, "Sets the Golem Automation start date to the current time.", null, true)] public void SetGolemStartDate(ChatCommandContext ctx) { if (Plugin.Instance == null) { ctx.Reply(ChatColors.ErrorText("Error: Plugin instance not found.")); return; } try { string text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); if (!GolemAutomationConfig.SetServerStartDateAndSave(text)) { ctx.Reply(ChatColors.ErrorText("Failed to set and save Golem start date. Config may not be initialized.")); return; } Plugin.TriggerGolemAutomationResetFromCommand(); GolemAutomationSystem.CheckAutomation(); ctx.Reply(ChatColors.SuccessText("Golem Automation start date set to: ") + ChatColors.InfoText(text)); } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("An error occurred while setting the Golem start date. Check server logs.")); LoggingHelper.Error("Error executing .golemstartdate", ex); } } [Command("golemcurrent", null, null, "Shows the current Golem health settings.", null, true)] public void GolemCurrent(ChatCommandContext ctx) { //IL_001c: 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_0087: 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) try { SiegeWeaponHealth? siegeWeaponHealth = SiegeWeaponSystem.GetSiegeWeaponHealth(); string message = "N/A"; if (siegeWeaponHealth.HasValue && GolemAutomationConfig.GolemHpEstimates.TryGetValue(siegeWeaponHealth.Value, out var value)) { message = $"~{value} HP ({siegeWeaponHealth.Value})"; } else if (siegeWeaponHealth.HasValue) { message = ((object)siegeWeaponHealth.Value/*cast due to .constrained prefix*/).ToString(); } ctx.Reply(ChatColors.InfoText("Current Live Golem Health Setting: " + ChatColors.AccentText(message))); string text = (string.IsNullOrWhiteSpace(GolemAutomationConfig.ManualSiegeWeaponHealthOverride?.Value) ? "Not set" : GolemAutomationConfig.ManualSiegeWeaponHealthOverride.Value.Trim()); bool flag = GolemAutomationConfig.EnableDayBasedAutomation?.Value ?? false; ctx.Reply(ChatColors.InfoText("Config - Manual Level Override: " + ChatColors.HighlightText(text))); ctx.Reply(ChatColors.InfoText("Config - Day-Based Automation Enabled: " + ChatColors.HighlightText(flag.ToString()))); if (!string.Equals(text, "Not set", StringComparison.OrdinalIgnoreCase)) { ctx.Reply(ChatColors.WarningText("Manual Level Override is active and takes precedence over day-based automation. Use '" + CommandSettingsConfig.GetInvocation("golemauto") + "' to clear.")); } else if (!flag) { ctx.Reply(ChatColors.WarningText("Day-based automation is disabled and no manual level is set. Golem HP may use server default or last known setting.")); } } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("An error occurred while checking Golem health settings. Check server logs.")); LoggingHelper.Error("Error executing .golemcurrent", ex); } } [Command("golemsethp", null, null, "Manually sets and persists a Siege Golem health level. Usage: .golemsethp ", null, true)] public unsafe void GolemSetHpByLevelName(ChatCommandContext ctx, string levelName) { //IL_008d: 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) try { if (string.IsNullOrWhiteSpace(levelName)) { string text = string.Join(", ", Enum.GetNames(typeof(SiegeWeaponHealth))); ctx.Reply(ChatColors.ErrorText("Missing health level name. Valid levels are: " + text)); return; } levelName = levelName.Trim(); if (!Enum.TryParse(levelName, ignoreCase: true, out SiegeWeaponHealth result)) { string text2 = string.Join(", ", Enum.GetNames(typeof(SiegeWeaponHealth))); ctx.Reply(ChatColors.ErrorText("Invalid health level name '" + levelName + "'. Valid levels are: " + text2)); return; } GolemAutomationConfig.SetManualSiegeWeaponHealthOverrideAndSave(result); Plugin.TriggerGolemAutomationResetFromCommand(); GolemAutomationSystem.CheckAutomation(); string value = string.Empty; if (GolemAutomationConfig.GolemHpEstimates.TryGetValue(result, out var value2)) { value = $" (~{value2} HP)"; } ctx.Reply(ChatColors.SuccessText($"Persistent Golem health override set to Level: {ChatColors.AccentText(((object)(*(SiegeWeaponHealth*)(&result))/*cast due to .constrained prefix*/).ToString())}{value}. Day-based automation is now overridden. Use '{CommandSettingsConfig.GetInvocation("golemauto")}' to clear.")); } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("An error occurred while setting Golem HP. Check server logs.")); LoggingHelper.Error("Error executing .golemsethp", ex); } } [Command("golemauto", null, null, "Clears manual Golem health override. Day-based automation will apply if enabled.", null, true)] public void GolemSetAuto(ChatCommandContext ctx) { try { GolemAutomationConfig.ClearManualSiegeWeaponHealthOverrideAndSave(); Plugin.TriggerGolemAutomationResetFromCommand(); GolemAutomationSystem.CheckAutomation(); ctx.Reply(ChatColors.SuccessText("Manual Golem health override cleared. Automation will now apply if enabled.")); } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("An error occurred while clearing the Golem manual override. Check server logs.")); LoggingHelper.Error("Error executing .golemauto", ex); } } [Command("golemlist", null, null, "Lists available Siege Golem health levels and estimated HP.", null, true)] public void GolemList(ChatCommandContext ctx) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) try { ctx.Reply(ChatColors.HighlightText("Siege Golem Health Levels (Estimates from Config):")); if (GolemAutomationConfig.GolemHpEstimates == null || !GolemAutomationConfig.GolemHpEstimates.Any()) { ctx.Reply(ChatColors.WarningText("HP estimates not available in GolemAutomationConfig.")); return; } foreach (KeyValuePair item in GolemAutomationConfig.GolemHpEstimates.OrderBy((KeyValuePair kv) => kv.Value)) { ctx.Reply(ChatColors.InfoText($"{item.Key}") + " = " + ChatColors.SuccessText($"~{item.Value} HP")); } } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("An error occurred while listing Golem health levels. Check server logs.")); LoggingHelper.Error("Error executing .golemlist", ex); } } [Command("golem", null, null, "Transforms the target player into a Siege Golem. Usage: .golem [PlayerName]", null, true)] public void GolemTransformCommand(ChatCommandContext ctx, string playerName = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0068: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) try { Entity val = Entity.Null; string text; if (string.IsNullOrWhiteSpace(playerName)) { val = ctx.Event.SenderCharacterEntity; text = "yourself"; } else { playerName = playerName.Trim(); if (!UserHelper.FindUserEntity(VWorld.EntityManager, playerName, out var _, out var userData, out var characterName)) { ctx.Reply(ChatColors.ErrorText("Player '" + playerName + "' not found.")); return; } val = userData.LocalCharacter._Entity; text = characterName; } if (val == Entity.Null) { ctx.Reply(ChatColors.ErrorText("Could not find a valid character entity for the target.")); return; } EntityManager entityManager = VWorld.EntityManager; if (!((EntityManager)(ref entityManager)).Exists(val)) { ctx.Reply(ChatColors.ErrorText("Target character entity no longer exists.")); return; } ApplyBuff(val, PrefabData.SiegeGolemBuff.Guid); ctx.Reply(ChatColors.SuccessText("Applied Siege Golem form to " + text + ".")); } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Failed to apply golem buff. Check server logs.")); LoggingHelper.Error("Error executing .golem", ex); } } private static void ApplyBuff(Entity target, PrefabGUID buffGuid) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0029: 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_002f: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager = VWorld.EntityManager; DebugEventsSystem obj = VWorld.Server.GetExistingSystemManaged() ?? throw new InvalidOperationException("DebugEventsSystem could not be found."); FromCharacter val = new FromCharacter { Character = target }; if (((EntityManager)(ref entityManager)).HasComponent(target)) { PlayerCharacter componentData = ((EntityManager)(ref entityManager)).GetComponentData(target); if (componentData.UserEntity != Entity.Null && ((EntityManager)(ref entityManager)).Exists(componentData.UserEntity)) { val.User = componentData.UserEntity; } } ApplyBuffDebugEvent val2 = new ApplyBuffDebugEvent { BuffPrefabGUID = buffGuid }; obj.ApplyBuff(val, val2); } } public class IconCommands { [Command("clearraidforgeicons", null, null, "Manually clears all active raid map icons.", null, true)] public void ClearIconsCommand(ChatCommandContext ctx) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) try { ctx.Reply(ChatColors.InfoText("Status: ") + ChatColors.HighlightText("Clearing active raid map icons...")); RaidMapIconService.RemoveAllIcons(); RaidMapIconService.ClearAllRaidForgeIconEntities(VWorld.EntityManager); ctx.Reply(ChatColors.SuccessText("All raid map icons have been successfully removed.")); LoggingHelper.Info($"[Command] Admin '{ctx.Event.User.CharacterName}' forcefully cleared all raid map icons."); } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Critical error during icon cleanup. Check server logs.")); LoggingHelper.Error("Error executing .clearraidforgeicons", ex); } } } public class OptInCommands { private readonly struct OptInListEntry { public readonly string OwnerKey; public readonly string DisplayName; public readonly bool IsClan; public readonly DateTime StateTimeUtc; public OptInListEntry(string ownerKey, string displayName, bool isClan, DateTime stateTimeUtc) { OwnerKey = ownerKey; DisplayName = displayName; IsClan = isClan; StateTimeUtc = stateTimeUtc; } } private const int OptListPageSize = 10; [Command("raidoptin", null, null, "Opts you and your clan into being raidable.", null, false)] public void OptInCommand(ChatCommandContext ctx) { //IL_0012: 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) if (TryRejectOptInSystemUnavailable(ctx) || TryRejectRaidWindowStatusChange(ctx)) { return; } if (!OwnerIdentityHelper.TryResolveFromCommandSender(VWorld.EntityManager, ctx.Event.SenderUserEntity, out var owner, out var error)) { ctx.Reply(ChatColors.ErrorText(error)); return; } bool useDefaultOptInMode = OptInRaidingConfig.UseDefaultOptInMode; bool desiredOptIn = true; if (OptInRaidService.IsOptedIn(owner.PersistentKey)) { ctx.Reply(ChatColors.WarningText("You are already opted in to raiding.")); } else if (!TryRejectLockedStatusSwitch(ctx, owner.PersistentKey, desiredOptIn)) { OptInRaidService.OptIn(owner.PersistentKey, owner.ContextualName); RaidMapIconService.ProcessCleanup(); int value = OptInRaidingConfig.OptInLockDurationHours.Value; ctx.Reply(ChatColors.SuccessText("You have opted IN to raiding!")); if (useDefaultOptInMode) { ctx.Reply(ChatColors.InfoText("Your opt-out exception was removed. Your base(s) are now raidable by the default server rule.")); return; } ctx.Reply(ChatColors.InfoText($"Your base(s) are now raidable. You cannot opt-out for {value} hour(s).")); } } [Command("raidoptout", null, null, "Opts you and your clan out of being raidable, if the time lock has expired.", null, false)] public void OptOutCommand(ChatCommandContext ctx) { //IL_0012: 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) if (TryRejectOptInSystemUnavailable(ctx) || TryRejectRaidWindowStatusChange(ctx)) { return; } if (!OwnerIdentityHelper.TryResolveFromCommandSender(VWorld.EntityManager, ctx.Event.SenderUserEntity, out var owner, out var error)) { ctx.Reply(ChatColors.ErrorText(error)); return; } _ = OptInRaidingConfig.UseDefaultOptInMode; bool desiredOptIn = false; if (!OptInRaidService.IsOptedIn(owner.PersistentKey)) { ctx.Reply(ChatColors.WarningText("You are already opted out of raiding.")); } else if (!TryRejectLockedStatusSwitch(ctx, owner.PersistentKey, desiredOptIn)) { OptInRaidService.OptOut(owner.PersistentKey, owner.ContextualName); RaidMapIconService.ProcessCleanup(); ctx.Reply(ChatColors.SuccessText("You have opted OUT of raiding. Your base(s) are now protected.")); } } [Command("raidoptstatus", null, null, "Checks your current opt-in raiding status.", null, false)] public void StatusCommand(ChatCommandContext ctx) { //IL_0009: 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) if (TryRejectOptInSystemUnavailable(ctx)) { return; } if (!OwnerIdentityHelper.TryResolveFromCommandSender(VWorld.EntityManager, ctx.Event.SenderUserEntity, out var owner, out var error)) { ctx.Reply(ChatColors.ErrorText(error)); return; } bool useDefaultOptInMode = OptInRaidingConfig.UseDefaultOptInMode; bool flag = OptInRaidService.IsOptedIn(owner.PersistentKey); DateTime stateTime; bool flag2 = OptInRaidService.TryGetManualStateTime(owner.PersistentKey, out stateTime); if (OptInScheduleConfig.EnableOptInSchedule.Value && !OptInScheduleConfig.IsOptInSystemAllowedToday()) { ctx.Reply(ChatColors.WarningText("Your raiding status is: RAIDABLE (Forced Raid Day)")); string text = (flag ? "Opted-In" : "Opted-Out"); ctx.Reply(ChatColors.MutedText("(Your saved status is " + text + ", but the server schedule is overriding it today.)")); return; } if (flag) { ctx.Reply(ChatColors.WarningText(useDefaultOptInMode ? "Your raiding status is: OPTED-IN (Default Vulnerable)" : "Your raiding status is: OPTED-IN (Vulnerable)")); if (!useDefaultOptInMode && flag2) { TimeSpan timeSpan = TimeSpan.FromHours(OptInRaidingConfig.OptInLockDurationHours.Value); TimeSpan timeSpan2 = DateTime.UtcNow - stateTime; if (timeSpan2 < timeSpan) { TimeSpan duration = timeSpan - timeSpan2; ctx.Reply(ChatColors.InfoText("You can opt-out in: " + CommandText.FormatDuration(duration))); } else { ctx.Reply(ChatColors.SuccessText("Your time lock has expired. You can use " + CommandSettingsConfig.GetInvocation("raidoptout") + " at any time.")); } } return; } ctx.Reply(ChatColors.SuccessText(useDefaultOptInMode ? "Your raiding status is: OPTED-OUT (Manual Exception / Protected)" : "Your raiding status is: OPTED-OUT (Protected)")); if (useDefaultOptInMode && flag2) { TimeSpan timeSpan3 = TimeSpan.FromHours(OptInRaidingConfig.OptInLockDurationHours.Value); TimeSpan timeSpan4 = DateTime.UtcNow - stateTime; if (timeSpan4 < timeSpan3) { TimeSpan duration2 = timeSpan3 - timeSpan4; ctx.Reply(ChatColors.InfoText("You can opt-in again in: " + CommandText.FormatDuration(duration2))); } else { ctx.Reply(ChatColors.SuccessText("Your time lock has expired. You can use " + CommandSettingsConfig.GetInvocation("raidoptin") + " at any time.")); } } } [Command("raidoptlist", null, null, "Lists manually opted-in raidable players/clans. Usage: .raidoptlist [page]", null, false)] public void OptListCommand(ChatCommandContext ctx, int page = 1) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (TryRejectOptInSystemUnavailable(ctx)) { return; } if (page < 1) { ctx.Reply(ChatColors.ErrorText("Invalid page number. Usage: " + CommandSettingsConfig.GetInvocation("raidoptlist") + " 1")); return; } try { List list = BuildManualOptInEntries(VWorld.EntityManager).OrderBy((OptInListEntry e) => e.DisplayName, StringComparer.OrdinalIgnoreCase).ToList(); int count = list.Count; int num = Math.Max(1, (int)Math.Ceiling((double)count / 10.0)); if (page > num) { ctx.Reply(ChatColors.WarningText($"Page {page} does not exist. There are only {num} page(s).")); return; } bool useDefaultOptInMode = OptInRaidingConfig.UseDefaultOptInMode; string text = (useDefaultOptInMode ? "Opt-Out" : "Opt-In"); ctx.Reply(ChatColors.HighlightText($"=== Manual Raid {text} List | Page {page}/{num} ===")); ctx.Reply(ChatColors.InfoText("Total manually opted-" + (useDefaultOptInMode ? "out" : "in") + " owners: ") + ChatColors.AccentText(count.ToString())); if (count == 0) { ctx.Reply(ChatColors.WarningText("No players or clans are manually opted " + (useDefaultOptInMode ? "out" : "in") + ".")); ctx.Reply(ChatColors.HighlightText("=== End " + text + " List ===")); return; } int num2 = (page - 1) * 10; List list2 = list.Skip(num2).Take(10).ToList(); for (int num3 = 0; num3 < list2.Count; num3++) { OptInListEntry optInListEntry = list2[num3]; int value = num2 + num3 + 1; string text2 = (optInListEntry.IsClan ? "Clan" : "Player"); string text3 = optInListEntry.StateTimeUtc.ToString("yyyy-MM-dd HH:mm 'UTC'"); ctx.Reply(ChatColors.MutedText($"{value}. ") + ChatColors.HighlightText(optInListEntry.DisplayName) + ChatColors.MutedText(" (" + text2 + ") ") + ChatColors.InfoText("- Opted " + (useDefaultOptInMode ? "out" : "in") + ": " + text3)); } if (page < num) { ctx.Reply(ChatColors.InfoText("Next page: ") + ChatColors.AccentText($"{CommandSettingsConfig.GetInvocation("raidoptlist")} {page + 1}")); } ctx.Reply(ChatColors.HighlightText("=== End " + text + " List ===")); } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Error reading opt-in list. Check server logs.")); LoggingHelper.Error("Error executing .raidoptlist", ex); } } [Command("forceopt", null, null, "Admin command to force a player/clan's raiding status. Usage: .forceopt ", null, true)] public void ForceOptCommand(ChatCommandContext ctx, string playerName, string status) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (TryRejectOptInSystemUnavailable(ctx)) { return; } if (string.IsNullOrWhiteSpace(status)) { ctx.Reply(ChatColors.ErrorText("Invalid status. Use 'in' or 'out'.")); return; } if (!OwnerIdentityHelper.TryResolveFromPlayerName(VWorld.EntityManager, playerName, out var owner, out var error)) { ctx.Reply(ChatColors.ErrorText(error)); return; } status = status.Trim().ToLowerInvariant(); if (status == "in") { OptInRaidService.OptIn(owner.PersistentKey, owner.ContextualName); RaidMapIconService.ProcessCleanup(); ctx.Reply(ChatColors.SuccessText("Successfully forced '" + owner.ContextualName + "' to OPT-IN status.")); } else if (status == "out") { OptInRaidService.OptOut(owner.PersistentKey, owner.ContextualName); RaidMapIconService.ProcessCleanup(); ctx.Reply(ChatColors.SuccessText("Successfully forced '" + owner.ContextualName + "' to OPT-OUT status. This bypasses any time locks.")); } else { ctx.Reply(ChatColors.ErrorText("Invalid status. Use 'in' or 'out'.")); } } private static List BuildManualOptInEntries(EntityManager em) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (OwnerIdentity uniqueOwner in OwnerIdentityQueries.GetUniqueOwners(em, "OptCommands")) { if (OptInRaidService.TryGetManualStateTime(uniqueOwner.PersistentKey, out var stateTime)) { list.Add(new OptInListEntry(uniqueOwner.PersistentKey, uniqueOwner.GetDisplayNameWithOwnerType(), uniqueOwner.IsClan, stateTime)); } } return list; } private static bool TryRejectRaidWindowStatusChange(ChatCommandContext ctx) { ConfigEntry blockOptInChangesDuringRaidHours = OptInRaidingConfig.BlockOptInChangesDuringRaidHours; if (blockOptInChangesDuringRaidHours != null && blockOptInChangesDuringRaidHours.Value && Plugin.IsAutoRaidCurrentlyActive) { ctx.Reply(ChatColors.ErrorText("You cannot change your raid opt status while a raid window is active.")); return true; } return false; } private static bool TryRejectOptInSystemUnavailable(ChatCommandContext ctx) { if (!Plugin.SystemsInitialized || !VWorld.IsServerWorldReady()) { ctx.Reply(ChatColors.ErrorText("Systems not fully initialized. Please try again shortly.")); return true; } if (!OptInRaidingConfig.EnableOptInRaiding.Value) { ctx.Reply(ChatColors.ErrorText("The opt-in raiding system is not enabled on this server.")); return true; } if (OfflineRaidProtectionConfig.EnableOfflineRaidProtection.Value) { ctx.Reply(ChatColors.ErrorText("The opt-in raiding system is disabled because Offline Raid Protection is enabled. Use one system or the other.")); return true; } return false; } private static bool TryRejectLockedStatusSwitch(ChatCommandContext ctx, string ownerPersistentKey, bool desiredOptIn) { int num = Math.Max(0, OptInRaidingConfig.OptInLockDurationHours?.Value ?? 0); if (num <= 0) { return false; } bool useDefaultOptInMode = OptInRaidingConfig.UseDefaultOptInMode; if (useDefaultOptInMode == desiredOptIn) { if (!OptInRaidService.TryGetManualStateTime(ownerPersistentKey, out var stateTime)) { return false; } TimeSpan timeSpan = DateTime.UtcNow - stateTime; TimeSpan timeSpan2 = TimeSpan.FromHours(num); if (timeSpan < timeSpan2) { TimeSpan duration = timeSpan2 - timeSpan; string text = (desiredOptIn ? "opt-in" : "opt-out"); ctx.Reply(ChatColors.ErrorText("You cannot " + text + " yet. Time remaining: " + CommandText.FormatDuration(duration))); return true; } } if (!useDefaultOptInMode && !desiredOptIn) { if (!OptInRaidService.TryGetManualStateTime(ownerPersistentKey, out var stateTime2)) { ctx.Reply(ChatColors.WarningText("You are not opted in to raiding.")); return true; } TimeSpan timeSpan3 = DateTime.UtcNow - stateTime2; TimeSpan timeSpan4 = TimeSpan.FromHours(num); if (timeSpan3 < timeSpan4) { TimeSpan duration2 = timeSpan4 - timeSpan3; ctx.Reply(ChatColors.ErrorText("You cannot opt-out yet. Time remaining: " + CommandText.FormatDuration(duration2))); return true; } } return false; } } public class PurchasedOrpCommands { [Command("buyorp", null, null, "Buys raid-day ORP protection for you or your clan. Usage: .buyorp ", null, false)] public void BuyOrp(ChatCommandContext ctx, int days) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) try { if (TryRejectPurchasedOrpUnavailable(ctx)) { return; } int num = Math.Max(1, PurchasedOrpConfig.MaxPurchaseRaidDays?.Value ?? 30); if (days <= 0 || days > num) { ctx.Reply(ChatColors.ErrorText($"Usage: {CommandSettingsConfig.GetInvocation("buyorp")} where days is between 1 and {num}.")); return; } int num2 = PurchasedOrpConfig.CurrencyAmountPerRaidDay?.Value ?? 0; if (num2 <= 0) { ctx.Reply(ChatColors.ErrorText("Purchased ORP cost is not configured correctly. CurrencyAmountPerRaidDay must be greater than 0.")); return; } EntityManager entityManager = VWorld.EntityManager; if (!OwnerIdentityHelper.TryResolveFromCommandSender(entityManager, ctx.Event.SenderUserEntity, out var owner, out var error)) { ctx.Reply(ChatColors.ErrorText(error)); return; } if (!TryResolveCurrency(out var currencyPrefab, out var currencyDisplayName, out var error2)) { ctx.Reply(ChatColors.ErrorText(error2)); return; } int num3; try { num3 = checked(days * num2); } catch (OverflowException) { ctx.Reply(ChatColors.ErrorText("The configured ORP purchase cost is too large.")); return; } Entity senderCharacterEntity = ctx.Event.SenderCharacterEntity; int itemAmount = InventoryPaymentService.GetItemAmount(entityManager, senderCharacterEntity, currencyPrefab); if (itemAmount < num3) { int num4 = num3 - itemAmount; ctx.Reply(ChatColors.WarningText($"You are missing {num4.ToString(CultureInfo.InvariantCulture)} {currencyDisplayName}.")); ctx.Reply(ChatColors.InfoText($"Required: {num3.ToString(CultureInfo.InvariantCulture)} for {days} raid day(s). You have: {itemAmount.ToString(CultureInfo.InvariantCulture)}.")); } else if (!InventoryPaymentService.TryRemoveItems(entityManager, senderCharacterEntity, currencyPrefab, num3)) { ctx.Reply(ChatColors.ErrorText("Could not remove the required currency from your inventory. Please try again.")); } else { PurchasedOrpService.AddRaidDays(owner.PersistentKey, owner.ContextualName, days); RaidMapIconService.ProcessCleanup(); int remainingRaidDays = PurchasedOrpService.GetRemainingRaidDays(owner.PersistentKey); ctx.Reply(ChatColors.SuccessText($"Purchased ORP for {days} raid day(s) for {owner.GetDisplayNameWithOwnerType()}.")); ctx.Reply(ChatColors.InfoText("You are protected for " + remainingRaidDays.ToString(CultureInfo.InvariantCulture) + " raid day(s).")); ctx.Reply(ChatColors.InfoText($"Spent {num3.ToString(CultureInfo.InvariantCulture)} {currencyDisplayName}.")); } } catch (Exception ex2) { ctx.Reply(ChatColors.ErrorText("Error buying ORP protection. Check server logs.")); LoggingHelper.Error("Error executing .buyorp", ex2); } } [Command("buyorpstatus", "orpamount", null, "Shows your purchased ORP protection days.", null, false)] public void BuyOrpStatus(ChatCommandContext ctx) { ShowOrpAmount(ctx); } [Command("givebuyorp", null, null, "Admin: gives purchased ORP raid days to a player/clan. Usage: .givebuyorp ", null, true)] public void GiveBuyOrp(ChatCommandContext ctx, string playerName, int amount) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) try { if (TryRejectPurchasedOrpUnavailable(ctx)) { return; } if (amount <= 0) { ctx.Reply(ChatColors.ErrorText("Usage: " + CommandSettingsConfig.GetInvocation("givebuyorp") + " where amount is greater than 0.")); return; } if (!OwnerIdentityHelper.TryResolveFromPlayerName(VWorld.EntityManager, playerName, out var owner, out var error)) { ctx.Reply(ChatColors.ErrorText(error)); return; } try { PurchasedOrpService.AddRaidDays(owner.PersistentKey, owner.ContextualName, amount); } catch (OverflowException) { ctx.Reply(ChatColors.ErrorText("That ORP amount is too large to add.")); return; } RaidMapIconService.ProcessCleanup(); int remainingRaidDays = PurchasedOrpService.GetRemainingRaidDays(owner.PersistentKey); ctx.Reply(ChatColors.SuccessText($"Gave {amount.ToString(CultureInfo.InvariantCulture)} purchased ORP raid day(s) to {owner.GetDisplayNameWithOwnerType()}.")); ctx.Reply(ChatColors.InfoText(owner.GetDisplayNameWithOwnerType() + " now has " + remainingRaidDays.ToString(CultureInfo.InvariantCulture) + " raid day(s) of protection.")); } catch (Exception ex2) { ctx.Reply(ChatColors.ErrorText("Error giving purchased ORP. Check server logs.")); LoggingHelper.Error("Error executing .givebuyorp", ex2); } } [Command("removebuyorp", null, null, "Admin: removes purchased ORP raid days from a player/clan. Usage: .removebuyorp ", null, true)] public void RemoveBuyOrp(ChatCommandContext ctx, string playerName, int amount) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) try { if (TryRejectPurchasedOrpUnavailable(ctx)) { return; } if (amount <= 0) { ctx.Reply(ChatColors.ErrorText("Usage: .removebuyorp where amount is greater than 0.")); return; } if (!OwnerIdentityHelper.TryResolveFromPlayerName(VWorld.EntityManager, playerName, out var owner, out var error)) { ctx.Reply(ChatColors.ErrorText(error)); return; } int remainingRaidDays = PurchasedOrpService.GetRemainingRaidDays(owner.PersistentKey); int num = PurchasedOrpService.RemoveRaidDays(owner.PersistentKey, amount); RaidMapIconService.ProcessCleanup(); int remainingRaidDays2 = PurchasedOrpService.GetRemainingRaidDays(owner.PersistentKey); if (remainingRaidDays <= 0 || num <= 0) { ctx.Reply(ChatColors.WarningText(owner.GetDisplayNameWithOwnerType() + " has no purchased ORP raid days to remove.")); return; } ctx.Reply(ChatColors.SuccessText($"Removed {num.ToString(CultureInfo.InvariantCulture)} purchased ORP raid day(s) from {owner.GetDisplayNameWithOwnerType()}.")); ctx.Reply(ChatColors.InfoText(owner.GetDisplayNameWithOwnerType() + " now has " + remainingRaidDays2.ToString(CultureInfo.InvariantCulture) + " raid day(s) of protection.")); if (remainingRaidDays2 <= 0 && PurchasedOrpService.IsRaidDate(PurchasedOrpService.GetCurrentRaidDate())) { ctx.Reply(ChatColors.WarningText("Their purchased ORP protection for today is now removed.")); } } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Error removing purchased ORP. Check server logs.")); LoggingHelper.Error("Error executing .removebuyorp", ex); } } private static void ShowOrpAmount(ChatCommandContext ctx) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) try { if (TryRejectPurchasedOrpUnavailable(ctx)) { return; } if (!OwnerIdentityHelper.TryResolveFromCommandSender(VWorld.EntityManager, ctx.Event.SenderUserEntity, out var owner, out var error)) { ctx.Reply(ChatColors.ErrorText(error)); return; } int remainingRaidDays = PurchasedOrpService.GetRemainingRaidDays(owner.PersistentKey); if (remainingRaidDays <= 0) { ctx.Reply(ChatColors.WarningText("You do not have any purchased ORP raid days.")); } else { ctx.Reply(ChatColors.InfoText("You are protected for " + remainingRaidDays.ToString(CultureInfo.InvariantCulture) + " raid day(s).")); } } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Error reading purchased ORP status. Check server logs.")); LoggingHelper.Error("Error executing purchased ORP amount command", ex); } } private static bool TryRejectPurchasedOrpUnavailable(ChatCommandContext ctx) { ConfigEntry enablePurchasedOrp = PurchasedOrpConfig.EnablePurchasedOrp; if (enablePurchasedOrp == null || !enablePurchasedOrp.Value) { ctx.Reply(ChatColors.ErrorText("Purchased ORP is not enabled on this server.")); return true; } ConfigEntry enableOfflineRaidProtection = OfflineRaidProtectionConfig.EnableOfflineRaidProtection; if (enableOfflineRaidProtection != null && enableOfflineRaidProtection.Value) { ctx.Reply(ChatColors.ErrorText("Purchased ORP is disabled because normal Offline Raid Protection is enabled. Use one ORP mode at a time.")); return true; } ConfigEntry enableOptInRaiding = OptInRaidingConfig.EnableOptInRaiding; if (enableOptInRaiding != null && enableOptInRaiding.Value) { ctx.Reply(ChatColors.ErrorText("Purchased ORP is disabled because Opt-In Raiding is enabled. Use one raid-protection mode at a time.")); return true; } return false; } private static bool TryResolveCurrency(out PrefabGUID currencyPrefab, out string currencyDisplayName, out string error) { //IL_0001: 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) currencyPrefab = default(PrefabGUID); currencyDisplayName = null; error = string.Empty; string text = PurchasedOrpConfig.CurrencyPrefab?.Value; if (!PrefabGuidResolver.TryResolve(text, out currencyPrefab, out var resolvedName)) { error = "Could not resolve Purchased ORP CurrencyPrefab '" + text + "'. Use a valid prefab name or GUID hash."; return false; } currencyDisplayName = PurchasedOrpConfig.CurrencyDisplayName?.Value?.Trim(); if (string.IsNullOrWhiteSpace(currencyDisplayName)) { currencyDisplayName = resolvedName; } if (string.IsNullOrWhiteSpace(currencyDisplayName) && !PrefabGuidResolver.TryGetPrefabName(currencyPrefab, out currencyDisplayName)) { currencyDisplayName = ((PrefabGUID)(ref currencyPrefab)).GuidHash.ToString(CultureInfo.InvariantCulture); } return true; } } public class RaidCommands { private readonly struct DisplayRaidScheduleEntry { public readonly DateTime DisplayStart; public readonly DateTime DisplayEnd; public DisplayRaidScheduleEntry(DateTime displayStart, DateTime displayEnd) { DisplayStart = displayStart; DisplayEnd = displayEnd; } } [Command("reloadraidforge", null, null, "Reloads RaidForge configuration files except startup-only command settings.", null, true)] public void ReloadConfig(ChatCommandContext ctx) { if (Plugin.Instance == null) { ctx.Reply(ChatColors.ErrorText("Error: Plugin instance not found.")); return; } Plugin.TriggerReloadFromCommand(); ctx.Reply(ChatColors.SuccessText("RaidForge runtime configuration reload requested. Command settings require a full server restart.")); } [Command("raidon", null, null, "Manually turn raids ON.", null, true)] public void RaidOn(ChatCommandContext ctx) { try { if (RaidSchedulingSystem.SetManualOverride(raidsEnabled: true)) { ctx.Reply(ChatColors.SuccessText("Raids manually forced ON.")); ctx.Reply(ChatColors.InfoText("RaidForge schedule automation is paused until " + CommandSettingsConfig.GetInvocation("raidauto") + " or restart/reload.")); } else { ctx.Reply(ChatColors.ErrorText("Error enabling raids! Check server logs.")); } } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Error enabling raids!")); LoggingHelper.Error("Error executing .raidon", ex); } } [Command("raidoff", null, null, "Manually turn raids OFF.", null, true)] public void Raidoff(ChatCommandContext ctx) { try { if (RaidSchedulingSystem.SetManualOverride(raidsEnabled: false)) { ctx.Reply(ChatColors.WarningText("Raids manually forced OFF.")); ctx.Reply(ChatColors.InfoText("RaidForge schedule automation is paused until " + CommandSettingsConfig.GetInvocation("raidauto") + " or restart/reload.")); } else { ctx.Reply(ChatColors.ErrorText("Error disabling raids! Check server logs.")); } } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Error disabling raids!")); LoggingHelper.Error("Error executing .raidoff", ex); } } [Command("raidauto", null, null, "Clears the manual raid override and resumes the RaidForge schedule.", null, true)] public void RaidAuto(ChatCommandContext ctx) { try { if (RaidSchedulingSystem.ClearManualOverride()) { ctx.Reply(ChatColors.SuccessText("Manual raid override cleared. RaidForge schedule automation resumed.")); } else { ctx.Reply(ChatColors.ErrorText("Error resuming RaidForge schedule automation! Check server logs.")); } } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Error resuming RaidForge schedule automation!")); LoggingHelper.Error("Error executing .raidauto", ex); } } [Command("removeorp", null, null, "Removes offline protection from a player/clan until they log back in.", null, true)] public void RemoveOrp(ChatCommandContext ctx, string playerName) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.SystemsInitialized || !VWorld.IsServerWorldReady()) { ctx.Reply(ChatColors.ErrorText("Systems not fully initialized. Please try again shortly.")); return; } if (!OwnerIdentityHelper.TryResolveFromPlayerName(VWorld.EntityManager, playerName, out var owner, out var error)) { ctx.Reply(ChatColors.ErrorText(error)); return; } string displayNameWithOwnerType = owner.GetDisplayNameWithOwnerType(); if (OfflineGraceService.AdminForceRemoveProtection(owner.PersistentKey)) { ctx.Reply(ChatColors.SuccessText("Offline Protection REMOVED for: " + ChatColors.HighlightText(displayNameWithOwnerType))); ctx.Reply(ChatColors.InfoText("They are now vulnerable until they log in and log back out.")); } else { ctx.Reply(ChatColors.WarningText("Could not find active offline protection for: " + displayNameWithOwnerType + ". They may already be online or unprotected.")); } } [Command("raidtime", "raidt", null, "Shows time until the next scheduled raid window starts.", null, false)] public void RaidTimer(ChatCommandContext ctx) { ShowRaidTime(ctx); } private static void ShowRaidTime(ChatCommandContext ctx) { List schedule = Plugin.GetSchedule(); if (schedule == null) { ctx.Reply(ChatColors.ErrorText("Error retrieving schedule configuration.")); return; } if (!schedule.Any()) { ctx.Reply(ChatColors.InfoText("No raid schedule is configured.")); return; } DateTime raidScheduleNow = RaidConfig.GetRaidScheduleNow(); DateTime dateTime = DateTime.MaxValue; if (Plugin.IsAutoRaidCurrentlyActive) { ctx.Reply(ChatColors.SuccessText("Castle Raiding is currently ACTIVE.")); } for (int i = 0; i <= 7; i++) { DateTime dateTime2 = raidScheduleNow.AddDays(i); DayOfWeek dayOfWeek = dateTime2.DayOfWeek; foreach (RaidScheduleEntry item in schedule) { if (item.Day == dayOfWeek) { DateTime dateTime3 = dateTime2.Date + item.StartTime; if (dateTime3 > raidScheduleNow && dateTime3 < dateTime) { dateTime = dateTime3; } } else if (item.SpansMidnight && (int)(item.Day + 1) % 7 == (int)dayOfWeek) { DateTime dateTime3 = dateTime2.Date.AddDays(-1.0) + item.StartTime; if (dateTime3 > raidScheduleNow && dateTime3 < dateTime) { dateTime = dateTime3; } } } } if (dateTime != DateTime.MaxValue) { TimeSpan timeSpan = dateTime - raidScheduleNow; string message = ((timeSpan.TotalSeconds < 1.0 && timeSpan.TotalSeconds > -60.0) ? "imminently (within the minute)" : ((timeSpan.TotalSeconds < 60.0) ? $"{(int)timeSpan.TotalSeconds} second{((timeSpan.TotalSeconds != 1.0) ? "s" : "")}" : ((timeSpan.TotalMinutes < 60.0) ? $"{(int)timeSpan.TotalMinutes} minute{(((int)timeSpan.TotalMinutes != 1) ? "s" : "")}" : ((!(timeSpan.TotalHours < 24.0)) ? $"{(int)timeSpan.TotalDays} day{(((int)timeSpan.TotalDays != 1) ? "s" : "")}, {timeSpan.Hours} hour{((timeSpan.Hours != 1) ? "s" : "")} and {timeSpan.Minutes} minute{((timeSpan.Minutes != 1) ? "s" : "")}" : $"{(int)timeSpan.TotalHours} hour{(((int)timeSpan.TotalHours != 1) ? "s" : "")} and {timeSpan.Minutes} minute{((timeSpan.Minutes != 1) ? "s" : "")}")))); ctx.Reply(ChatColors.InfoText("Next scheduled raid window starts in: " + ChatColors.AccentText(message))); ctx.Reply(ChatColors.InfoText(FormatRaidDisplayDateTime(dateTime))); } else if (!Plugin.IsAutoRaidCurrentlyActive) { ctx.Reply(ChatColors.InfoText("No upcoming raids found in the schedule.")); } } [Command("raiddays", "raidd", null, "Shows the raid schedule for the week.", null, false)] public void RaidDays(ChatCommandContext ctx) { ShowRaidDays(ctx); } private static void ShowRaidDays(ChatCommandContext ctx) { List schedule = Plugin.GetSchedule(); if (schedule == null) { ctx.Reply(ChatColors.ErrorText("Error retrieving schedule.")); return; } string raidDisplaySuffix = GetRaidDisplaySuffix(); ctx.Reply(ChatColors.HighlightText("Raid Schedule" + raidDisplaySuffix + ":")); CultureInfo invariantCulture = CultureInfo.InvariantCulture; TimeSpan displayOffset = TimeSpan.Zero; Dictionary> dictionary = (from entry in schedule select BuildDisplayRaidScheduleEntry(entry, displayOffset) into e group e by e.DisplayStart.DayOfWeek).ToDictionary((IGrouping g) => g.Key, (IGrouping g) => g.OrderBy((DisplayRaidScheduleEntry e) => e.DisplayStart.TimeOfDay).ToList()); foreach (DayOfWeek item in (from DayOfWeek d in Enum.GetValues(typeof(DayOfWeek)) orderby (int)((d != DayOfWeek.Sunday) ? d : ((DayOfWeek)7)) select d).ToList()) { string text2; if (dictionary.TryGetValue(item, out var value) && value.Any()) { List list = new List(); foreach (DisplayRaidScheduleEntry item2 in value) { string message = item2.DisplayStart.ToString("h:mm tt", invariantCulture); string text = ChatColors.SuccessText(item2.DisplayEnd.ToString("h:mm tt", invariantCulture)); if (item2.DisplayEnd.DayOfWeek != item2.DisplayStart.DayOfWeek) { text += ChatColors.MutedText(" (" + item2.DisplayEnd.DayOfWeek.ToString().Substring(0, 3) + ")"); } list.Add(ChatColors.SuccessText(message) + ChatColors.MutedText(" - ") + text); } text2 = string.Join(ChatColors.MutedText(", "), list); } else { text2 = ChatColors.WarningText("No Raids Scheduled"); } ctx.Reply(ChatColors.InfoText(item.ToString()) + ": " + text2); } } private static DisplayRaidScheduleEntry BuildDisplayRaidScheduleEntry(RaidScheduleEntry entry, TimeSpan displayOffset) { DateTime dateTime = new DateTime(2024, 1, 7).AddDays((double)entry.Day).Date + entry.StartTime; DateTime dateTime2 = (entry.SpansMidnight ? (dateTime.Date.AddDays(1.0) + entry.EndTime) : (dateTime.Date + entry.EndTime)); if (entry.EndTime == TimeSpan.Zero && entry.SpansMidnight) { dateTime2 = dateTime.Date.AddDays(1.0); } return new DisplayRaidScheduleEntry(dateTime + displayOffset, dateTime2 + displayOffset); } private static string FormatRaidDisplayDateTime(DateTime scheduleDateTime) { return $"{scheduleDateTime:f}{GetRaidDisplaySuffix()}"; } private static TimeSpan GetRaidDisplayOffset() { return RaidConfig.GetRaidScheduleOffset(); } private static string GetRaidDisplaySuffix() { string text = RaidConfig.RaidScheduleTimeZoneDisplayString?.Value?.Trim() ?? string.Empty; double num = RaidConfig.RaidScheduleDisplayOffsetHours?.Value ?? 0.0; if (double.IsNaN(num) || double.IsInfinity(num) || !(Math.Abs(num) > 0.0001)) { if (string.IsNullOrWhiteSpace(text)) { return ""; } return " (" + text + ")"; } string text2 = $"offset {num:+0.##;-0.##;0}h"; if (string.IsNullOrWhiteSpace(text)) { return " (" + text2 + ")"; } return $" ({text}, {text2})"; } [Command("raidstatus", "raids", null, "Shows raid vulnerability status of the player/clan. Usage: .raidstatus ", null, false)] public void DisplayRaidStatus(ChatCommandContext ctx, string playerName) { ShowRaidStatus(ctx, playerName); } private void ShowRaidStatus(ChatCommandContext ctx, string playerName) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_00b5: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) try { EntityManager entityManager = VWorld.EntityManager; if (!Plugin.SystemsInitialized) { ctx.Reply(ChatColors.ErrorText("Systems not fully initialized. Please try again shortly.")); return; } if (!OwnerIdentityHelper.TryResolveFromPlayerName(entityManager, playerName, out var owner, out var error)) { ctx.Reply(ChatColors.Format(error, "#F00534")); return; } string displayNameWithOwnerType = owner.GetDisplayNameWithOwnerType(); List<(Entity, string)> ownedHearts = GetOwnedHearts(entityManager, owner.UserEntity, owner.ClanEntity, displayNameWithOwnerType); if (!ownedHearts.Any()) { ctx.Reply(ChatColors.InfoText("No Castle Hearts found for " + displayNameWithOwnerType + ".")); return; } bool flag = PurchasedOrpConfig.IsPurchasedOrpActive(); bool flag2 = PurchasedOrpService.IsRaidDate(PurchasedOrpService.GetCurrentRaidDate()); foreach (var item3 in ownedHearts) { Entity item = item3.Item1; string item2 = item3.Item2; CastleHeart componentData = ((EntityManager)(ref entityManager)).GetComponentData(item); bool flag3 = ((CastleHeart)(ref componentData)).IsSieged(); bool flag4 = OfflineProtectionService.IsBaseDecaying(item, entityManager); bool showRaidingStatusWhenEnabled = HasOnlineDefender(entityManager, item); if (flag3) { ReplyRaidStatusLine(ctx, item2, ChatColors.WarningText("BREACHED"), flag3, null, showRaidingStatusWhenEnabled); } else if (flag4) { ReplyRaidStatusLine(ctx, item2, ChatColors.WarningText("RAIDABLE"), flag3, null, showRaidingStatusWhenEnabled); } else if (OptInRaidingConfig.EnableOptInRaiding.Value && !OfflineRaidProtectionConfig.EnableOfflineRaidProtection.Value) { if (OptInRaidService.IsOptedIn(owner.PersistentKey)) { ReplyRaidStatusLine(ctx, item2, ChatColors.WarningText("RAIDABLE"), flag3, null, showRaidingStatusWhenEnabled); } else { ReplyRaidStatusLine(ctx, item2, ChatColors.SuccessText("PROTECTED"), flag3, null, showRaidingStatusWhenEnabled: false); } } else if (flag) { bool flag5 = flag2 && PurchasedOrpService.HasProtectionForToday(owner.PersistentKey); if (!flag2 || flag5) { ReplyRaidStatusLine(ctx, item2, ChatColors.SuccessText("PROTECTED"), flag3, null, showRaidingStatusWhenEnabled: false); } else { ReplyRaidStatusLine(ctx, item2, ChatColors.WarningText("RAIDABLE"), flag3, null, showRaidingStatusWhenEnabled); } } else if (OfflineRaidProtectionConfig.EnableOfflineRaidProtection.Value) { DateTime offlineStartTimeUtc; if (!OfflineRaidProtectionConfig.IsOfflineProtectionAllowedToday()) { ReplyRaidStatusLine(ctx, item2, ChatColors.WarningText("RAIDABLE"), flag3, ChatColors.InfoText("ORP disabled for today"), showRaidingStatusWhenEnabled); } else if (OfflineGraceService.TryGetOfflineStartTime(owner.PersistentKey, out offlineStartTimeUtc)) { TimeSpan timeSpan = DateTime.UtcNow - offlineStartTimeUtc; float value = OfflineRaidProtectionConfig.GracePeriodDurationMinutes.Value; if (value > 0f && timeSpan.TotalMinutes < (double)value) { TimeSpan timeSpan2 = TimeSpan.FromMinutes(value) - timeSpan; string message = $"{timeSpan2.Minutes}m {timeSpan2.Seconds}s"; ReplyRaidStatusLine(ctx, item2, ChatColors.WarningText("RAIDABLE"), flag3, $"{ChatColors.InfoText("Vulnerability Period:")} {ChatColors.WarningText(message)} {ChatColors.InfoText("remaining")}", showRaidingStatusWhenEnabled); } else if (OfflineProtectionService.AreAllDefendersActuallyOffline(item, entityManager)) { ReplyRaidStatusLine(ctx, item2, ChatColors.SuccessText("PROTECTED"), flag3, null, showRaidingStatusWhenEnabled: false); } else { ReplyRaidStatusLine(ctx, item2, ChatColors.WarningText("RAIDABLE"), flag3, null, showRaidingStatusWhenEnabled); } } else { ReplyRaidStatusLine(ctx, item2, ChatColors.WarningText("RAIDABLE"), flag3, null, showRaidingStatusWhenEnabled); } } else { ReplyRaidStatusLine(ctx, item2, ChatColors.WarningText("RAIDABLE"), flag3, null, showRaidingStatusWhenEnabled); } } } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("An error occurred processing the command. Check server logs.")); LoggingHelper.Error("Error executing .raidstatus", ex); } } private static void ReplyRaidStatusLine(ChatCommandContext ctx, string baseName, string protectionStatus, bool isCurrentlyRaiding, string extraDetail = null, bool showRaidingStatusWhenEnabled = true) { string text = ChatColors.InfoText(baseName) + ": " + protectionStatus; if (!string.IsNullOrWhiteSpace(extraDetail)) { text = text + " " + extraDetail; } ctx.Reply(text); if (showRaidingStatusWhenEnabled) { ConfigEntry showCurrentRaidingStatusInRaidStatus = RaidConfig.ShowCurrentRaidingStatusInRaidStatus; if (showCurrentRaidingStatusInRaidStatus != null && showCurrentRaidingStatusInRaidStatus.Value) { ctx.Reply(isCurrentlyRaiding ? ChatColors.ErrorText("Raiding") : ChatColors.SuccessText("Not Raiding")); } } } [Command("raidstatusreason", null, null, "Shows why a player/clan is or is not Offline Raid Protected. Usage: .raidstatusreason ", null, true)] public void DisplayRaidStatusReason(ChatCommandContext ctx, string playerName) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) try { EntityManager entityManager = VWorld.EntityManager; if (!Plugin.SystemsInitialized || !VWorld.IsServerWorldReady()) { ctx.Reply(ChatColors.ErrorText("Systems not fully initialized. Please try again shortly.")); return; } OwnerIdentity owner = default(OwnerIdentity); string error; bool flag = OwnerIdentityHelper.TryResolveFromPlayerName(entityManager, playerName, out owner, out error); PlayerRegistryEntry entry = null; string text; string text2; if (flag) { text = owner.PersistentKey; text2 = owner.GetDisplayNameWithOwnerType(); PlayerRegistryService.TryGetEntryByUserKey(owner.UserKey, out entry); } else { List list = PlayerRegistryService.FindEntriesByCharacterName(playerName); if (list.Count == 0) { ctx.Reply(ChatColors.ErrorText(error)); ctx.Reply(ChatColors.WarningText("Player was also not found in RaidForge_PlayerRegistry.csv.")); return; } if (list.Count > 1) { ctx.Reply(ChatColors.WarningText("Live player lookup failed: " + error)); ctx.Reply(ChatColors.WarningText("Multiple registry matches found. Use a more exact name:")); { foreach (PlayerRegistryEntry item in list.Take(5)) { ctx.Reply(ChatColors.InfoText($"- {item.CharacterName} ({item.PlatformId}) owner={item.OwnerPersistentKey}")); } return; } } entry = list[0]; text = entry.OwnerPersistentKey; text2 = ((!string.IsNullOrWhiteSpace(entry.ClanName) && entry.OwnerType == "Clan") ? (entry.ClanName + " (Clan)") : entry.CharacterName); if (string.IsNullOrWhiteSpace(text)) { ctx.Reply(ChatColors.WarningText("Registry entry for '" + entry.CharacterName + "' has no owner key, so ORP cannot be evaluated.")); return; } } ctx.Reply(ChatColors.HighlightText("Raid Status Reason: " + text2)); ctx.Reply(CommandText.StatusLine("Live user found", CommandText.YesNoText(flag))); ctx.Reply(CommandText.StatusLine("Owner key", ChatColors.AccentText(text ?? "missing"))); ctx.Reply(CommandText.StatusLine("ORP enabled", CommandText.YesNoText(OfflineRaidProtectionConfig.EnableOfflineRaidProtection?.Value ?? false))); ctx.Reply(CommandText.StatusLine("Purchased ORP active", CommandText.YesNoText(PurchasedOrpConfig.IsPurchasedOrpActive()))); ctx.Reply(CommandText.StatusLine("ORP active today", CommandText.YesNoText(OfflineRaidProtectionConfig.IsOfflineProtectionAllowedToday()))); ctx.Reply(CommandText.StatusLine("Raids currently enabled", CommandText.YesNoText(RaidToggleSystem.AreRaidsEnabled()))); ReplyRegistryStatus(ctx, entry, text, flag ? new bool?(owner.UserData.IsConnected) : ((bool?)null)); DateTime offlineStartTimeUtc; bool hasOfflineState = OfflineGraceService.TryGetOfflineStartTime(text, out offlineStartTimeUtc); ReplyOfflineStateStatus(ctx, hasOfflineState, offlineStartTimeUtc); bool flag2 = ShardConfig.DisableOrpForShardHolders?.Value ?? false; bool ownerShardVulnerable = flag2 && ShardVulnerabilityService.IsVulnerable(text); ReplyShardStatus(ctx, flag2, ownerShardVulnerable, text); List<(Entity, string)> ownedHeartsByPersistentKey = GetOwnedHeartsByPersistentKey(entityManager, text, text2); if (!ownedHeartsByPersistentKey.Any()) { ctx.Reply(ChatColors.WarningText("No Castle Hearts found for this owner in the ownership cache.")); ctx.Reply(ChatColors.InfoText("Run " + CommandSettingsConfig.GetInvocation("raidrefreshcache") + " if you expected hearts here.")); return; } foreach (var (heartEntity, baseName) in ownedHeartsByPersistentKey) { ReplyHeartProtectionReason(ctx, entityManager, heartEntity, baseName, text, hasOfflineState, offlineStartTimeUtc, ownerShardVulnerable); } } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("An error occurred processing the command. Check server logs.")); LoggingHelper.Error("Error executing .raidstatusreason", ex); } } private List<(Entity HeartEntity, string CastleName)> GetOwnedHearts(EntityManager em, Entity user, Entity clan, string ownerName) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_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_00e6: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) List<(Entity, string)> list = new List<(Entity, string)>(); foreach (KeyValuePair item in OwnershipCacheService.GetHeartToOwnerCacheView()) { if (((EntityManager)(ref em)).Exists(item.Key) && ((EntityManager)(ref em)).Exists(item.Value)) { bool flag = false; if (item.Value == user) { flag = true; } if (!flag && clan != Entity.Null && clan.Exists() && ((EntityManager)(ref em)).Exists(clan) && OwnershipCacheService.TryGetUserClan(item.Value, out var clanEntity) && clanEntity == clan) { flag = true; } if (flag) { list.Add((item.Key, ownerName + "'s base")); } } } if (list.Count > 1) { for (int i = 0; i < list.Count; i++) { (Entity, string) tuple = list[i]; list[i] = (tuple.Item1, $"{tuple.Item2} #{i + 1}"); } } return list; } private static List<(Entity HeartEntity, string CastleName)> GetOwnedHeartsByPersistentKey(EntityManager em, string ownerPersistentKey, string ownerName) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) List<(Entity, string)> list = new List<(Entity, string)>(); if (string.IsNullOrWhiteSpace(ownerPersistentKey)) { return list; } foreach (KeyValuePair item in OwnershipCacheService.GetHeartToOwnerCacheView()) { if (((EntityManager)(ref em)).Exists(item.Key) && ((EntityManager)(ref em)).Exists(item.Value) && OwnerIdentityHelper.TryResolveFromUserEntity(em, item.Value, out var owner, out var _) && owner.PersistentKey == ownerPersistentKey) { list.Add((item.Key, ownerName + "'s base")); } } if (list.Count > 1) { for (int i = 0; i < list.Count; i++) { (Entity, string) tuple = list[i]; list[i] = (tuple.Item1, $"{tuple.Item2} #{i + 1}"); } } return list; } private static void ReplyHeartProtectionReason(ChatCommandContext ctx, EntityManager em, Entity heartEntity, string baseName, string ownerPersistentKey, bool hasOfflineState, DateTime offlineStartTimeUtc, bool ownerShardVulnerable) { //IL_0047: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) DateTime utcNow = DateTime.UtcNow; bool flag = OfflineRaidProtectionConfig.EnableOfflineRaidProtection?.Value ?? false; bool flag2 = PurchasedOrpConfig.IsPurchasedOrpActive(); bool flag3 = flag2 && PurchasedOrpService.HasProtectionForToday(ownerPersistentKey); int value = (flag2 ? PurchasedOrpService.GetRemainingRaidDays(ownerPersistentKey) : 0); bool flag4 = PurchasedOrpService.IsRaidDate(PurchasedOrpService.GetCurrentRaidDate()); bool num = OfflineProtectionService.IsBaseDecaying(heartEntity, em); int num2; if (((EntityManager)(ref em)).Exists(heartEntity) && ((EntityManager)(ref em)).HasComponent(heartEntity)) { CastleHeart componentData = ((EntityManager)(ref em)).GetComponentData(heartEntity); num2 = (((CastleHeart)(ref componentData)).IsSieged() ? 1 : 0); } else { num2 = 0; } bool flag5 = (byte)num2 != 0; bool flag6 = OfflineProtectionService.AreAllDefendersActuallyOffline(heartEntity, em); float num3 = OfflineRaidProtectionConfig.GracePeriodDurationMinutes?.Value ?? 0f; bool flag7 = hasOfflineState && num3 > 0f && (utcNow - offlineStartTimeUtc).TotalMinutes < (double)num3; string text; string text2; if (num) { text = ChatColors.WarningText("NOT PROTECTED"); text2 = "Castle Heart is decaying or has no fuel; decayed bases bypass ORP."; } else if (flag5) { text = ChatColors.WarningText("NOT PROTECTED"); text2 = "Castle Heart is already breached/sieged; breached bases bypass ORP."; } else if (ownerShardVulnerable) { text = ChatColors.WarningText("NOT PROTECTED"); text2 = "Owner is shard-vulnerable and shard ORP bypass is enabled."; } else if (!flag) { if (flag3) { text = ChatColors.SuccessText("PROTECTED"); text2 = $"Purchased ORP is active. This owner has {value} raid day(s) of protection."; } else if (flag2) { if (!flag4) { text = ChatColors.InfoText("NO RAIDS TODAY"); text2 = $"Today is not a configured raid date. This owner has {value} raid day(s) of protection."; } else { text = ChatColors.WarningText("NOT PROTECTED"); text2 = "Purchased ORP is active, but this owner has no purchased protection remaining."; } } else { text = ChatColors.WarningText("NOT PROTECTED"); text2 = "Offline Raid Protection is disabled in config."; } } else if (!OfflineRaidProtectionConfig.IsOfflineProtectionAllowedToday()) { text = ChatColors.WarningText("NOT PROTECTED"); text2 = $"Offline Raid Protection is disabled for {DateTime.Now.DayOfWeek} in OfflineProtection.cfg."; } else if (!hasOfflineState) { text = ChatColors.WarningText("NOT PROTECTED"); text2 = "No offline timestamp exists for this owner. They may be online, never fully logged out after boot, or the boot registry did not restamp them."; } else if (flag7) { TimeSpan duration = TimeSpan.FromMinutes(num3) - (utcNow - offlineStartTimeUtc); text = ChatColors.WarningText("GRACE PERIOD"); text2 = "Offline timestamp exists, but ORP grace has " + CommandText.FormatDuration(duration) + " remaining."; } else if (!flag6) { text = ChatColors.WarningText("NOT PROTECTED"); text2 = "At least one defender is online: " + BuildOnlineDefenderSummary(em, heartEntity) + "."; } else { text = ChatColors.SuccessText("PROTECTED"); text2 = "Offline timestamp is past grace and all defenders are offline."; } ctx.Reply(ChatColors.InfoText(baseName) + ": " + text); ctx.Reply(ChatColors.MutedText("Reason: " + text2)); ctx.Reply(ChatColors.MutedText("Defenders offline: " + (flag6 ? "Yes" : "No"))); } private static void ReplyRegistryStatus(ChatCommandContext ctx, PlayerRegistryEntry registryEntry, string ownerPersistentKey, bool? liveConnected) { if (registryEntry == null) { ctx.Reply(ChatColors.WarningText("Registry: no entry found for this live user's UserKey.")); return; } string value = ((registryEntry.LastSeenUtcTicks > 0) ? new DateTime(registryEntry.LastSeenUtcTicks, DateTimeKind.Utc).ToString("u", CultureInfo.InvariantCulture) : "unknown"); string value2 = ((registryEntry.OwnerPersistentKey == ownerPersistentKey) ? "matches" : ("MISMATCH (" + registryEntry.OwnerPersistentKey + ")")); string value3 = (liveConnected.HasValue ? $", LiveConnected={liveConnected.Value}" : string.Empty); ctx.Reply(ChatColors.InfoText($"Registry: {registryEntry.CharacterName}, IsConnected={registryEntry.IsConnected}{value3}, LastSeen={value}, OwnerKey={value2}")); } private static void ReplyOfflineStateStatus(ChatCommandContext ctx, bool hasOfflineState, DateTime offlineStartTimeUtc) { if (!hasOfflineState) { ctx.Reply(ChatColors.WarningText("Offline state: missing")); return; } TimeSpan duration = DateTime.UtcNow - offlineStartTimeUtc; ctx.Reply(ChatColors.InfoText($"Offline state: since {offlineStartTimeUtc.ToString("u", CultureInfo.InvariantCulture)} ({CommandText.FormatDuration(duration)} ago)")); } private static void ReplyShardStatus(ChatCommandContext ctx, bool shardBypassEnabled, bool ownerShardVulnerable, string ownerPersistentKey) { if (!shardBypassEnabled) { ctx.Reply(ChatColors.InfoText("Shard ORP bypass: disabled")); return; } if (!ownerShardVulnerable) { ctx.Reply(ChatColors.InfoText("Shard ORP bypass: enabled, no active shard vulnerability for owner")); return; } List entriesForOwner = ShardVulnerabilityService.GetEntriesForOwner(ownerPersistentKey); string text = ((entriesForOwner.Count == 0) ? "active vulnerability present" : string.Join(", ", entriesForOwner.Select((ShardVulnerabilityEntry entry) => entry.ShardPrefabGuid.ToString(CultureInfo.InvariantCulture)))); ctx.Reply(ChatColors.WarningText("Shard ORP bypass: owner is vulnerable (" + text + ")")); } private static bool HasOnlineDefender(EntityManager em, Entity heartEntity) { //IL_0002: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_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_0086: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (!((EntityManager)(ref em)).Exists(heartEntity) || !((EntityManager)(ref em)).HasComponent(heartEntity)) { return false; } Entity entity = ((EntityManager)(ref em)).GetComponentData(heartEntity).Owner._Entity; if (!((EntityManager)(ref em)).Exists(entity) || !((EntityManager)(ref em)).HasComponent(entity)) { return false; } User componentData = ((EntityManager)(ref em)).GetComponentData(entity); Entity entity2 = componentData.ClanEntity._Entity; if (entity2 != Entity.Null && ((EntityManager)(ref em)).Exists(entity2) && ((EntityManager)(ref em)).HasComponent(entity2)) { return UserHelper.IsAnyClanMemberOnline(em, entity2); } return componentData.IsConnected; } private unsafe static string BuildOnlineDefenderSummary(EntityManager em, Entity heartEntity) { //IL_0002: 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_001c: 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_0022: 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_002c: 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_0049: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if (!((EntityManager)(ref em)).Exists(heartEntity) || !((EntityManager)(ref em)).HasComponent(heartEntity)) { return "owner not found"; } Entity entity = ((EntityManager)(ref em)).GetComponentData(heartEntity).Owner._Entity; if (!((EntityManager)(ref em)).Exists(entity) || !((EntityManager)(ref em)).HasComponent(entity)) { return "owner user not found"; } User componentData = ((EntityManager)(ref em)).GetComponentData(entity); Entity entity2 = componentData.ClanEntity._Entity; if (entity2 != Entity.Null && ((EntityManager)(ref em)).Exists(entity2) && ((EntityManager)(ref em)).HasComponent(entity2)) { List list = new List(); NativeList val = default(NativeList); val..ctor(AllocatorHandle.op_Implicit((Allocator)2)); try { TeamUtility.GetClanMembers(em, entity2, val); Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Entity current = enumerator.Current; if (((EntityManager)(ref em)).Exists(current) && ((EntityManager)(ref em)).HasComponent(current)) { User componentData2 = ((EntityManager)(ref em)).GetComponentData(current); if (componentData2.IsConnected) { list.Add(((object)(*(FixedString64Bytes*)(&componentData2.CharacterName))/*cast due to .constrained prefix*/).ToString()); } } } } finally { if (val.IsCreated) { val.Dispose(); } } if (list.Count <= 0) { return "none"; } return string.Join(", ", list); } if (!componentData.IsConnected) { return "none"; } return ((object)(*(FixedString64Bytes*)(&componentData.CharacterName))/*cast due to .constrained prefix*/).ToString(); } } public class RaidConfigViewCommands { private const int CONFIG_RAID_GENERAL = 1; private const int CONFIG_OFFLINE_PROTECTION = 2; private const int CONFIG_OPT_IN_RAIDING = 3; private const int CONFIG_OPT_IN_SCHEDULE = 4; private const int CONFIG_SOUL_SHARDS = 5; private const int CONFIG_MAP_ICONS = 6; private const int CONFIG_WEAPON_RAIDING = 7; private const int CONFIG_GOLEM_SETTINGS = 8; private const int CONFIG_RAID_INTERFERENCE = 9; private const int CONFIG_TROUBLESHOOTING = 10; [Command("raidconfigview", null, null, "Shows a specific RaidForge config section. Usage: .raidconfigview ? OR .raidconfigview ", null, true)] public void RaidConfigView(ChatCommandContext ctx, string selection = null) { try { if (string.IsNullOrWhiteSpace(selection) || selection.Trim() == "?") { ShowConfigMenu(ctx); return; } selection = selection.Trim(); int result; if (selection.Equals("all", StringComparison.OrdinalIgnoreCase)) { ShowAllConfigs(ctx); } else if (!int.TryParse(selection, out result)) { ctx.Reply(ChatColors.ErrorText($"Invalid config selection '{selection}'. Use '{CommandSettingsConfig.GetInvocation("raidconfigview")} ?' to see valid options.")); } else { ShowConfigByNumber(ctx, result); } } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Error reading RaidForge config values. Check server logs.")); LoggingHelper.Error("Error executing .raidconfigview", ex); } } [Command("raidconfigviewall", null, null, "Shows all currently loaded RaidForge configuration values.", null, true)] public void RaidConfigViewAll(ChatCommandContext ctx) { try { ShowAllConfigs(ctx); } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Error reading all RaidForge config values. Check server logs.")); LoggingHelper.Error("Error executing .raidconfigviewall", ex); } } private static void ShowConfigMenu(ChatCommandContext ctx) { ctx.Reply(ChatColors.HighlightText(" RaidForge Config View Menu ")); ctx.Reply(ChatColors.InfoText("Use ") + ChatColors.AccentText(CommandSettingsConfig.GetInvocation("raidconfigview") + " ") + ChatColors.InfoText(" to view one config section.")); ctx.Reply(ChatColors.InfoText("Use ") + ChatColors.AccentText(CommandSettingsConfig.GetInvocation("raidconfigviewall")) + ChatColors.InfoText(" to view everything.")); ctx.Reply(ChatColors.MutedText($"{1}. ") + ChatColors.SuccessText("Raid Schedule / General")); ctx.Reply(ChatColors.MutedText($"{2}. ") + ChatColors.SuccessText("Offline Raid Protection")); ctx.Reply(ChatColors.MutedText($"{3}. ") + ChatColors.SuccessText("Opt-In Raiding")); ctx.Reply(ChatColors.MutedText($"{4}. ") + ChatColors.SuccessText("Opt-In Schedule")); ctx.Reply(ChatColors.MutedText($"{5}. ") + ChatColors.SuccessText("Soul Shards")); ctx.Reply(ChatColors.MutedText($"{6}. ") + ChatColors.SuccessText("Map Icons")); ctx.Reply(ChatColors.MutedText($"{7}. ") + ChatColors.SuccessText("Weapon and TNT Raiding")); ctx.Reply(ChatColors.MutedText($"{8}. ") + ChatColors.SuccessText("Golem Settings")); ctx.Reply(ChatColors.MutedText($"{9}. ") + ChatColors.SuccessText("Raid Interference")); ctx.Reply(ChatColors.MutedText($"{10}. ") + ChatColors.SuccessText("Troubleshooting")); ctx.Reply(ChatColors.HighlightText(" End Config View Menu ")); } private static void ShowAllConfigs(ChatCommandContext ctx) { ctx.Reply(ChatColors.HighlightText(" RaidForge Loaded Config View: ALL ")); ShowGeneralRaidConfig(ctx); ShowOfflineProtectionConfig(ctx); ShowOptInRaidingConfig(ctx); ShowOptInScheduleConfig(ctx); ShowShardConfig(ctx); ShowMapIconConfig(ctx); ShowWeaponAndTntRaidingConfig(ctx); ShowGolemConfig(ctx); ShowRaidInterferenceConfig(ctx); ShowTroubleshootingConfig(ctx); ctx.Reply(ChatColors.HighlightText(" End RaidForge Loaded Config View ")); } private static void ShowConfigByNumber(ChatCommandContext ctx, int configNumber) { switch (configNumber) { case 1: ShowGeneralRaidConfig(ctx); return; case 2: ShowOfflineProtectionConfig(ctx); return; case 3: ShowOptInRaidingConfig(ctx); return; case 4: ShowOptInScheduleConfig(ctx); return; case 5: ShowShardConfig(ctx); return; case 6: ShowMapIconConfig(ctx); return; case 7: ShowWeaponAndTntRaidingConfig(ctx); return; case 8: ShowGolemConfig(ctx); return; case 9: ShowRaidInterferenceConfig(ctx); return; case 10: ShowTroubleshootingConfig(ctx); return; } ctx.Reply(ChatColors.ErrorText($"Invalid config number '{configNumber}'. Use '{CommandSettingsConfig.GetInvocation("raidconfigview")} ?' to see valid options.")); } private static void ShowGeneralRaidConfig(ChatCommandContext ctx) { ctx.Reply(ChatColors.AccentText("[1] Raid Schedule / General")); ctx.Reply(CommandText.ConfigLine("AllowWaygateTeleportsDuringRaid", CommandText.EnabledText(RaidConfig.AllowWaygateTeleports?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("ShowCurrentRaidingStatusInRaidStatus", CommandText.EnabledText(RaidConfig.ShowCurrentRaidingStatusInRaidStatus?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("RaidScheduleTimeZoneForDisplay", ChatColors.HighlightText(RaidConfig.RaidScheduleTimeZoneDisplayString?.Value ?? "Not Set"))); ctx.Reply(CommandText.ConfigLine("RaidScheduleDisplayOffsetHours", ChatColors.HighlightText((RaidConfig.RaidScheduleDisplayOffsetHours?.Value ?? 0.0).ToString("0.##", CultureInfo.InvariantCulture)))); ctx.Reply(CommandText.ConfigLine("Current Raid Schedule Clock", ChatColors.HighlightText(RaidConfig.GetRaidScheduleNow().ToString("ddd HH:mm", CultureInfo.InvariantCulture)))); List schedule = RaidConfig.Schedule; if (schedule == null || schedule.Count == 0) { ctx.Reply(ChatColors.WarningText("Parsed Raid Schedule: No raid windows configured.")); return; } ctx.Reply(CommandText.ConfigLine("Parsed Schedule Entries", ChatColors.HighlightText(schedule.Count.ToString()))); foreach (RaidScheduleEntry item in from e in schedule orderby DaySortValue(e.Day), e.StartTime select e) { string text = CommandText.FormatTime(item.StartTime); string text2 = ((item.EndTime == TimeSpan.Zero && item.SpansMidnight) ? "Midnight" : CommandText.FormatTime(item.EndTime)); string text3 = (item.SpansMidnight ? " (spans midnight)" : string.Empty); ctx.Reply(ChatColors.MutedText($"- {item.Day}: ") + ChatColors.SuccessText(text + " - " + text2 + text3)); } } private static void ShowOfflineProtectionConfig(ChatCommandContext ctx) { ctx.Reply(ChatColors.AccentText("[2] Offline Raid Protection")); ctx.Reply(CommandText.ConfigLine("EnableOfflineProtection", CommandText.EnabledText(OfflineRaidProtectionConfig.EnableOfflineRaidProtection?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("EnableOfflineProtectionDaySchedule", CommandText.EnabledText(OfflineRaidProtectionConfig.EnableOfflineProtectionDaySchedule?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("OfflineProtectionActiveToday", CommandText.EnabledText(OfflineRaidProtectionConfig.IsOfflineProtectionAllowedToday()))); ctx.Reply(CommandText.ConfigLine("GracePeriodMinutes", ChatColors.HighlightText((OfflineRaidProtectionConfig.GracePeriodDurationMinutes?.Value ?? 0f).ToString(CultureInfo.InvariantCulture)))); ctx.Reply(CommandText.ConfigLine("AnnounceOfflineRaid", CommandText.EnabledText(OfflineRaidProtectionConfig.AnnounceOfflineRaid?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("AnnounceDecayedBaseRaid", CommandText.EnabledText(OfflineRaidProtectionConfig.AnnounceDecayedBaseRaid?.Value ?? false))); ConfigEntry enableOfflineProtectionDaySchedule = OfflineRaidProtectionConfig.EnableOfflineProtectionDaySchedule; if (enableOfflineProtectionDaySchedule == null || !enableOfflineProtectionDaySchedule.Value || OfflineRaidProtectionConfig.DayProtectionToggles == null) { return; } foreach (DayOfWeek item in Enum.GetValues(typeof(DayOfWeek)).Cast().OrderBy(DaySortValue)) { if (OfflineRaidProtectionConfig.DayProtectionToggles.TryGetValue(item, out var value)) { string text = (value.Value ? "ORP blocks damage" : "ORP tracking only"); ctx.Reply(ChatColors.MutedText($"- {item}: ") + CommandText.EnabledText(value.Value) + ChatColors.InfoText(" (" + text + ")")); } } } private static void ShowOptInRaidingConfig(ChatCommandContext ctx) { ctx.Reply(ChatColors.AccentText("[3] Opt-In Raiding")); ctx.Reply(CommandText.ConfigLine("EnableOptInRaiding", CommandText.EnabledText(OptInRaidingConfig.EnableOptInRaiding?.Value ?? false))); ConfigEntry enableOptInRaiding = OptInRaidingConfig.EnableOptInRaiding; ctx.Reply(CommandText.ConfigLine("OptInRaidingActive", CommandText.EnabledText(enableOptInRaiding != null && enableOptInRaiding.Value && !(OfflineRaidProtectionConfig.EnableOfflineRaidProtection?.Value ?? false)))); ctx.Reply(CommandText.ConfigLine("DefaultEveryoneOptedOut", CommandText.EnabledText(OptInRaidingConfig.DefaultEveryoneOptedOut?.Value ?? true))); ctx.Reply(CommandText.ConfigLine("DefaultEveryoneOptedIn", CommandText.EnabledText(OptInRaidingConfig.DefaultEveryoneOptedIn?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("OptInLockDurationHours", ChatColors.HighlightText((OptInRaidingConfig.OptInLockDurationHours?.Value ?? 0).ToString()))); ctx.Reply(CommandText.ConfigLine("BlockOptInChangesDuringRaidHours", CommandText.EnabledText(OptInRaidingConfig.BlockOptInChangesDuringRaidHours?.Value ?? true))); ctx.Reply(CommandText.ConfigLine("AutoOptOutAfterCooldown", CommandText.EnabledText(OptInRaidingConfig.AutoOptOutAfterCooldown?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("AutoOptInShardHolders", CommandText.EnabledText(OptInRaidingConfig.AutoOptInShardHolders?.Value ?? false))); } private static void ShowOptInScheduleConfig(ChatCommandContext ctx) { ctx.Reply(ChatColors.AccentText("[4] Opt-In Schedule")); ctx.Reply(CommandText.ConfigLine("EnableOptInSchedule", CommandText.EnabledText(OptInScheduleConfig.EnableOptInSchedule?.Value ?? false))); if (OptInScheduleConfig.DayToggles == null || OptInScheduleConfig.DayToggles.Count == 0) { ctx.Reply(ChatColors.WarningText("Opt-In day toggles are not loaded.")); return; } foreach (DayOfWeek item in Enum.GetValues(typeof(DayOfWeek)).Cast().OrderBy(DaySortValue)) { if (OptInScheduleConfig.DayToggles.TryGetValue(item, out var value)) { string text = (value.Value ? "Opt-In system allowed" : "Forced raid day"); ctx.Reply(ChatColors.MutedText($"- {item}: ") + CommandText.EnabledText(value.Value) + ChatColors.InfoText(" (" + text + ")")); } } } private static void ShowShardConfig(ChatCommandContext ctx) { ctx.Reply(ChatColors.AccentText("[5] Soul Shards")); ctx.Reply(CommandText.ConfigLine("MaxAllowedShardsPerType", ChatColors.HighlightText((ShardConfig.MaxAllowedShardsPerType?.Value ?? 1).ToString()))); ctx.Reply(CommandText.ConfigLine("DisableOrpForShardHolders", CommandText.EnabledText(ShardConfig.DisableOrpForShardHolders?.Value ?? false))); } private static void ShowMapIconConfig(ChatCommandContext ctx) { ctx.Reply(ChatColors.AccentText("[6] Map Icons")); ctx.Reply(CommandText.ConfigLine("EnableOfflineRaidMapIcon", CommandText.EnabledText(MapIconsConfig.EnableOfflineRaidMapIcon?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("OfflineRaidMapIconPrefab", ChatColors.HighlightText(MapIconsConfig.OfflineRaidMapIconPrefab?.Value ?? string.Empty))); ctx.Reply(CommandText.ConfigLine("EnableDecayRaidMapIcon", CommandText.EnabledText(MapIconsConfig.EnableDecayRaidMapIcon?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("DecayRaidMapIconPrefab", ChatColors.HighlightText(MapIconsConfig.DecayRaidMapIconPrefab?.Value ?? string.Empty))); ctx.Reply(CommandText.ConfigLine("EnableOptInRaidMapIcon", CommandText.EnabledText(MapIconsConfig.EnableOptInRaidMapIcon?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("EnableOptOutRaidMapIcon", CommandText.EnabledText(MapIconsConfig.EnableOptOutRaidMapIcon?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("RaidMapIconTimeoutSeconds", ChatColors.HighlightText((MapIconsConfig.RaidMapIconTimeoutSeconds?.Value ?? 0).ToString()))); } private static void ShowWeaponAndTntRaidingConfig(ChatCommandContext ctx) { ctx.Reply(ChatColors.AccentText("[7] Weapon and TNT Raiding")); ctx.Reply(CommandText.ConfigLine("EnableWeaponRaiding", CommandText.EnabledText(WeaponRaidingConfig.EnableWeaponRaiding?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("EnableTntRaiding", CommandText.EnabledText(TntRaidingConfig.EnableTntRaiding?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("T01NormalDamagePercent", ChatColors.HighlightText((TntRaidingConfig.T01NormalDamagePercent?.Value ?? 100f).ToString(CultureInfo.InvariantCulture)))); ctx.Reply(CommandText.ConfigLine("T02NormalDamagePercent", ChatColors.HighlightText((TntRaidingConfig.T02NormalDamagePercent?.Value ?? 100f).ToString(CultureInfo.InvariantCulture)))); ctx.Reply(CommandText.ConfigLine("T01CastleWallDamagePercent", ChatColors.HighlightText((TntRaidingConfig.T01CastleWallDamagePercent?.Value ?? 100f).ToString(CultureInfo.InvariantCulture)))); ctx.Reply(CommandText.ConfigLine("T02CastleWallDamagePercent", ChatColors.HighlightText((TntRaidingConfig.T02CastleWallDamagePercent?.Value ?? 100f).ToString(CultureInfo.InvariantCulture)))); ctx.Reply(CommandText.ConfigLine("UseNormalTntDamageAfterBreach", CommandText.EnabledText(TntRaidingConfig.UseNormalTntDamageAfterBreach?.Value ?? true))); ctx.Reply(CommandText.ConfigLine("WeaponDamageVsStoneMultiplier", ChatColors.HighlightText((WeaponRaidingConfig.WeaponDamageVsStoneMultiplier?.Value ?? 0f).ToString(CultureInfo.InvariantCulture)))); } private static void ShowGolemConfig(ChatCommandContext ctx) { //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) ctx.Reply(ChatColors.AccentText("[8] Golem Settings")); ctx.Reply(CommandText.ConfigLine("EnableDayBasedAutomation", CommandText.EnabledText(GolemAutomationConfig.EnableDayBasedAutomation?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("ServerStartDateForAutomation", ChatColors.HighlightText(string.IsNullOrWhiteSpace(GolemAutomationConfig.ServerStartDateForAutomation?.Value) ? "Not Set" : GolemAutomationConfig.ServerStartDateForAutomation.Value))); ctx.Reply(CommandText.ConfigLine("ManualOverrideSiegeLevel", ChatColors.HighlightText(string.IsNullOrWhiteSpace(GolemAutomationConfig.ManualSiegeWeaponHealthOverride?.Value) ? "Not Set" : GolemAutomationConfig.ManualSiegeWeaponHealthOverride.Value))); if (GolemAutomationConfig.ParsedStartDate.HasValue) { ctx.Reply(CommandText.ConfigLine("ParsedStartDate", ChatColors.HighlightText(GolemAutomationConfig.ParsedStartDate.Value.ToString("yyyy-MM-dd HH:mm:ss")))); } else { ctx.Reply(CommandText.ConfigLine("ParsedStartDate", ChatColors.WarningText("Not Set / Invalid"))); } if (GolemAutomationConfig.ParsedDayBasedSchedule == null || GolemAutomationConfig.ParsedDayBasedSchedule.Count == 0) { ctx.Reply(ChatColors.WarningText("Parsed Golem Day Schedule: Empty")); return; } ctx.Reply(CommandText.ConfigLine("ParsedDayBasedScheduleEntries", ChatColors.HighlightText(GolemAutomationConfig.ParsedDayBasedSchedule.Count.ToString()))); foreach (KeyValuePair item in GolemAutomationConfig.ParsedDayBasedSchedule) { ctx.Reply(ChatColors.MutedText($"- Day {item.Key}: ") + ChatColors.SuccessText(((object)item.Value/*cast due to .constrained prefix*/).ToString())); } } private static void ShowRaidInterferenceConfig(ChatCommandContext ctx) { ctx.Reply(ChatColors.AccentText("[9] Raid Interference")); ctx.Reply(CommandText.ConfigLine("EnableRaidInterference", CommandText.EnabledText(RaidInterferenceConfig.EnableRaidInterference?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("DisableInterferenceForOfflineRaids", CommandText.EnabledText(RaidInterferenceConfig.DisableInterferenceForOfflineRaids?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("DisableInterferenceForDecayingBases", CommandText.EnabledText(RaidInterferenceConfig.DisableInterferenceForDecayingBases?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("ExemptBearFormUsers", CommandText.EnabledText(RaidInterferenceConfig.ExemptBearFormUsers?.Value ?? false))); } private static void ShowTroubleshootingConfig(ChatCommandContext ctx) { ctx.Reply(ChatColors.AccentText("[10] Troubleshooting")); ctx.Reply(CommandText.ConfigLine("EnableTntDamageLogging", CommandText.EnabledText(TroubleshootingConfig.EnableTntDamageLogging?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("EnableVerboseLogging", CommandText.EnabledText(TroubleshootingConfig.EnableVerboseLogging?.Value ?? false))); } private static int DaySortValue(DayOfWeek day) { if (day != DayOfWeek.Sunday) { return (int)day; } return 7; } } public class RaidForgeInfoCommands { private readonly struct CacheCountSnapshot { public readonly int UserCount; public readonly int ClanCount; public readonly int CastleHeartCount; public readonly int HeartOwnerCacheCount; public CacheCountSnapshot(int userCount, int clanCount, int castleHeartCount, int heartOwnerCacheCount) { UserCount = userCount; ClanCount = clanCount; CastleHeartCount = castleHeartCount; HeartOwnerCacheCount = heartOwnerCacheCount; } } private readonly struct OptInListEntry { public readonly string OwnerKey; public readonly string DisplayName; public readonly bool IsClan; public readonly DateTime? OptInTimeUtc; public OptInListEntry(string ownerKey, string displayName, bool isClan, DateTime? optInTimeUtc) { OwnerKey = ownerKey; DisplayName = displayName; IsClan = isClan; OptInTimeUtc = optInTimeUtc; } } private readonly struct OrpListEntry { public readonly string OwnerKey; public readonly string DisplayName; public readonly bool IsClan; public readonly bool HasTimedOfflineState; public readonly DateTime? OfflineStartTimeUtc; public OrpListEntry(string ownerKey, string displayName, bool isClan, bool hasTimedOfflineState, DateTime? offlineStartTimeUtc) { OwnerKey = ownerKey; DisplayName = displayName; IsClan = isClan; HasTimedOfflineState = hasTimedOfflineState; OfflineStartTimeUtc = offlineStartTimeUtc; } } [Command("raidforge", null, null, "RaidForge admin tools. Usage: .raidforge ?, .raidforge status, .raidforge cache", null, true)] public void RaidForgeCommand(ChatCommandContext ctx, string action = null) { try { if (string.IsNullOrWhiteSpace(action) || action.Trim() == "?") { ShowHelp(ctx); return; } action = action.Trim().ToLowerInvariant(); switch (action) { case "status": case "stats": ShowStatus(ctx); return; case "cache": case "counts": ShowCacheCounts(ctx); return; } ctx.Reply(ChatColors.ErrorText($"Unknown RaidForge action '{action}'. Use '{CommandSettingsConfig.GetInvocation("raidforge")} ?' for options.")); } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Error running RaidForge admin command. Check server logs.")); LoggingHelper.Error("Error executing .raidforge command.", ex); } } private static void ShowHelp(ChatCommandContext ctx) { ctx.Reply(ChatColors.HighlightText("RaidForge Admin Command Help")); ctx.Reply(ChatColors.InfoText(CommandSettingsConfig.GetInvocation("raidforge") + " status") + ChatColors.MutedText(" - Shows current RaidForge system status and key counts.")); ctx.Reply(ChatColors.InfoText(CommandSettingsConfig.GetInvocation("raidforge") + " cache") + ChatColors.MutedText(" - Shows cache/world count details.")); ctx.Reply(ChatColors.InfoText(CommandSettingsConfig.GetInvocation("raidrefreshcache")) + ChatColors.MutedText(" - Rebuilds ownership cache.")); ctx.Reply(ChatColors.InfoText(CommandSettingsConfig.GetInvocation("raidauto")) + ChatColors.MutedText(" - Clears manual raid override and resumes the schedule.")); ctx.Reply(ChatColors.InfoText(CommandSettingsConfig.GetInvocation("raidconfigview") + " ?") + ChatColors.MutedText(" - Shows numbered config sections.")); ctx.Reply(ChatColors.InfoText(CommandSettingsConfig.GetInvocation("raidconfigviewall")) + ChatColors.MutedText(" - Shows all loaded config sections.")); ctx.Reply(ChatColors.HighlightText("End RaidForge Help")); } private static void ShowStatus(ChatCommandContext ctx) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager = VWorld.EntityManager; CacheCountSnapshot cacheCountSnapshot = BuildCacheCounts(entityManager); List list = BuildOptInEntries(entityManager); List list2 = BuildOrpEntries(entityManager); ctx.Reply(ChatColors.HighlightText("RaidForge Status")); ctx.Reply(CommandText.ConfigLine("Systems Initialized", CommandText.YesNoText(Plugin.SystemsInitialized))); ctx.Reply(CommandText.ConfigLine("Server Has Just Booted", CommandText.YesNoText(Plugin.ServerHasJustBooted))); ctx.Reply(CommandText.ConfigLine("Raid Control Mode", GetRaidControlModeText())); ctx.Reply(CommandText.ConfigLine("Raids Currently Enabled", CommandText.YesNoText(RaidToggleSystem.AreRaidsEnabled()))); ctx.Reply(CommandText.ConfigLine("Effective Raid State", CommandText.YesNoText(Plugin.IsAutoRaidCurrentlyActive))); ctx.Reply(CommandText.ConfigLine("Offline Protection Enabled", CommandText.YesNoText(OfflineRaidProtectionConfig.EnableOfflineRaidProtection?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("Offline Protection Active Today", CommandText.YesNoText(OfflineRaidProtectionConfig.IsOfflineProtectionAllowedToday()))); ctx.Reply(CommandText.ConfigLine("Opt-In Raiding Enabled", CommandText.YesNoText(OptInRaidingConfig.EnableOptInRaiding?.Value ?? false))); ConfigEntry enableOptInRaiding = OptInRaidingConfig.EnableOptInRaiding; ctx.Reply(CommandText.ConfigLine("Opt-In Raiding Active", CommandText.YesNoText(enableOptInRaiding != null && enableOptInRaiding.Value && !(OfflineRaidProtectionConfig.EnableOfflineRaidProtection?.Value ?? false)))); ctx.Reply(CommandText.ConfigLine("Shard ORP Bypass Enabled", CommandText.YesNoText(ShardConfig.DisableOrpForShardHolders?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("Weapon Raiding Enabled", CommandText.YesNoText(WeaponRaidingConfig.EnableWeaponRaiding?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("TNT Raiding Enabled", CommandText.YesNoText(TntRaidingConfig.EnableTntRaiding?.Value ?? false))); ctx.Reply(CommandText.ConfigLine("TNT Normal Damage (T01 / T02)", (TntRaidingConfig.T01NormalDamagePercent?.Value ?? 100f).ToString(CultureInfo.InvariantCulture) + "% / " + (TntRaidingConfig.T02NormalDamagePercent?.Value ?? 100f).ToString(CultureInfo.InvariantCulture) + "%")); ctx.Reply(CommandText.ConfigLine("TNT Castle Damage (T01 / T02)", (TntRaidingConfig.T01CastleWallDamagePercent?.Value ?? 100f).ToString(CultureInfo.InvariantCulture) + "% / " + (TntRaidingConfig.T02CastleWallDamagePercent?.Value ?? 100f).ToString(CultureInfo.InvariantCulture) + "%")); ctx.Reply(ChatColors.AccentText("[World / Cache Counts]")); ctx.Reply(CommandText.ConfigLine("Users In World", CommandText.CountText(cacheCountSnapshot.UserCount))); ctx.Reply(CommandText.ConfigLine("Clans In World", CommandText.CountText(cacheCountSnapshot.ClanCount))); ctx.Reply(CommandText.ConfigLine("Castle Hearts In World", CommandText.CountText(cacheCountSnapshot.CastleHeartCount))); ctx.Reply(CommandText.ConfigLine("Heart Ownership Cache Entries", CommandText.CountText(cacheCountSnapshot.HeartOwnerCacheCount))); ctx.Reply(ChatColors.AccentText("[RaidForge State Counts]")); ctx.Reply(CommandText.ConfigLine("Manual Opt-In Owners", CommandText.CountText(list.Count))); ctx.Reply(CommandText.ConfigLine("ORP Owners Known", CommandText.CountText(list2.Count))); ctx.Reply(CommandText.ConfigLine("Timed ORP Owners", CommandText.CountText(list2.Count((OrpListEntry e) => e.HasTimedOfflineState)))); ctx.Reply(ChatColors.HighlightText("End RaidForge Status")); } private static string GetRaidControlModeText() { if (!RaidSchedulingSystem.HasManualOverride) { return ChatColors.SuccessText("Schedule"); } if (RaidSchedulingSystem.ManualOverrideValue != true) { return ChatColors.WarningText("Manual OFF"); } return ChatColors.WarningText("Manual ON"); } private static void ShowCacheCounts(ChatCommandContext ctx) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) EntityManager entityManager = VWorld.EntityManager; CacheCountSnapshot cacheCountSnapshot = BuildCacheCounts(entityManager); List list = BuildOptInEntries(entityManager); List list2 = BuildOrpEntries(entityManager); ctx.Reply(ChatColors.HighlightText("RaidForge Cache / Count View ")); ctx.Reply(CommandText.ConfigLine("Users In World", CommandText.CountText(cacheCountSnapshot.UserCount))); ctx.Reply(CommandText.ConfigLine("Clans In World", CommandText.CountText(cacheCountSnapshot.ClanCount))); ctx.Reply(CommandText.ConfigLine("Castle Hearts In World", CommandText.CountText(cacheCountSnapshot.CastleHeartCount))); ctx.Reply(CommandText.ConfigLine("Heart Ownership Cache Entries", CommandText.CountText(cacheCountSnapshot.HeartOwnerCacheCount))); ctx.Reply(CommandText.ConfigLine("Manual Opt-In Owners", CommandText.CountText(list.Count))); ctx.Reply(CommandText.ConfigLine("ORP Owners Known", CommandText.CountText(list2.Count))); ctx.Reply(CommandText.ConfigLine("Timed ORP Owners", CommandText.CountText(list2.Count((OrpListEntry e) => e.HasTimedOfflineState)))); ctx.Reply(ChatColors.InfoText("Tip: use ") + ChatColors.AccentText(CommandSettingsConfig.GetInvocation("raidrefreshcache")) + ChatColors.InfoText(" to rebuild ownership cache.")); ctx.Reply(ChatColors.HighlightText("End Cache / Count View")); } private static CacheCountSnapshot BuildCacheCounts(EntityManager em) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) int userCount = CountEntitiesWithComponent(em); int clanCount = CountEntitiesWithComponent(em); int castleHeartCount = CountEntitiesWithComponent(em); int heartOwnerCacheCount = 0; try { IReadOnlyDictionary heartToOwnerCacheView = OwnershipCacheService.GetHeartToOwnerCacheView(); if (heartToOwnerCacheView != null) { heartOwnerCacheCount = heartToOwnerCacheView.Count; } } catch (Exception ex) { LoggingHelper.Debug("[RaidForgeInfoCommands] Could not read heart ownership cache count: " + ex.Message); } return new CacheCountSnapshot(userCount, clanCount, castleHeartCount, heartOwnerCacheCount); } private static List BuildOptInEntries(EntityManager em) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (OwnerIdentity uniqueOwner in OwnerIdentityQueries.GetUniqueOwners(em, "RaidForgeInfoCommands")) { if (OptInRaidService.TryGetOptInTime(uniqueOwner.PersistentKey, out var optInTime)) { list.Add(new OptInListEntry(uniqueOwner.PersistentKey, uniqueOwner.GetDisplayNameWithOwnerType(), uniqueOwner.IsClan, optInTime)); } } return list; } private static List BuildOrpEntries(EntityManager em) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (OwnerIdentity uniqueOwner in OwnerIdentityQueries.GetUniqueOwners(em, "RaidForgeInfoCommands")) { DateTime offlineStartTimeUtc; bool flag = OfflineGraceService.TryGetOfflineStartTime(uniqueOwner.PersistentKey, out offlineStartTimeUtc); if (flag) { list.Add(new OrpListEntry(uniqueOwner.PersistentKey, uniqueOwner.GetDisplayNameWithOwnerType(), uniqueOwner.IsClan, flag, flag ? new DateTime?(offlineStartTimeUtc) : ((DateTime?)null))); } } return list; } private static int CountEntitiesWithComponent(EntityManager em) where T : struct { //IL_0002: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) EntityQuery val = default(EntityQuery); try { val = ((EntityManager)(ref em)).CreateEntityQuery((ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly() }); return ((EntityQuery)(ref val)).CalculateEntityCount(); } catch (Exception ex) { LoggingHelper.Debug("[RaidForgeInfoCommands] Failed to count component " + typeof(T).Name + ": " + ex.Message); return 0; } finally { ((EntityQuery)(ref val)).Dispose(); } } } public class RefreshCommands { [Command("raidrefreshcache", null, null, "Forcefully clears and rebuilds the entire RaidForge cache. Use if the server is not detecting players or bases correctly.", null, true)] public void RefreshCacheCommand(ChatCommandContext ctx) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (Plugin.Instance == null) { ctx.Reply(ChatColors.ErrorText("Error: Plugin instance not found.")); return; } try { ctx.Reply(ChatColors.InfoText("Status: ") + ChatColors.HighlightText("Clearing and rebuilding RaidForge cache...")); EntityManager entityManager = VWorld.Server.EntityManager; OwnershipCacheService.ClearAllCaches(); int value = OwnershipCacheService.InitializeHeartOwnershipCache(entityManager); int value2 = OwnershipCacheService.InitializeUserToClanCache(entityManager); OfflineGraceService.EstablishInitialGracePeriodsOnBoot(entityManager); ctx.Reply(ChatColors.SuccessText("Cache Refresh Complete.")); ctx.Reply(ChatColors.InfoText("Found & Cached: " + ChatColors.AccentText(value.ToString()) + " Castle Hearts")); ctx.Reply(ChatColors.InfoText("Found & Cached: " + ChatColors.AccentText(value2.ToString()) + " Users/Clans")); LoggingHelper.Info($"[Command] Cache refresh triggered by admin. Cached {value} hearts and {value2} users."); } catch (Exception ex) { ctx.Reply(ChatColors.ErrorText("Critical error during cache refresh. Check server logs.")); LoggingHelper.Error("Error executing .raidrefreshcache", ex); } } } }