using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ChaosSuite.Core")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a3464fa3098fa6be253d588a5b7ca9ba01bef4dd")] [assembly: AssemblyProduct("ChaosSuite.Core")] [assembly: AssemblyTitle("ChaosSuite.Core")] [assembly: AssemblyVersion("1.0.0.0")] [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 ChaosSuite.Core { public readonly record struct EntityId(ulong Value) { public bool IsValid => Value != 0; public static readonly EntityId None = new EntityId(0uL); } public readonly record struct ActionReceipt(EntityId Entity, ulong Sequence, bool Accepted, string Reason) { public static ActionReceipt Reject(EntityId entity, ulong sequence, string reason) { return new ActionReceipt(entity, sequence, Accepted: false, reason); } public static ActionReceipt Accept(EntityId entity, ulong sequence) { return new ActionReceipt(entity, sequence, Accepted: true, string.Empty); } } public static class TargetedClientOutcome { public static bool IsRecipient(ulong localClientId, ulong targetClientId) { return localClientId == targetClientId; } } public sealed class MonotonicActionGuard { private readonly Dictionary lastSequenceBySender = new Dictionary(); public bool TryAccept(ulong senderId, ulong sequence) { if (lastSequenceBySender.TryGetValue(senderId, out var value) && sequence <= value) { return false; } lastSequenceBySender[senderId] = sequence; return true; } public void Forget(ulong senderId) { lastSequenceBySender.Remove(senderId); } } public sealed class IdempotentCleanup { private readonly List actions = new List(); private bool completed; public bool IsCompleted => completed; public void Register(Action action) { if (action == null) { throw new ArgumentNullException("action"); } if (completed) { action(); } else { actions.Add(action); } } public void Complete() { if (completed) { return; } completed = true; List list = null; for (int num = actions.Count - 1; num >= 0; num--) { try { actions[num](); } catch (Exception item) { (list ?? (list = new List())).Add(item); } } actions.Clear(); if (list == null || list.Count <= 0) { return; } throw new AggregateException(list); } } public sealed class PersistentCleanupCycle { private readonly List persistentActions = new List(); private IdempotentCleanup current = new IdempotentCleanup(); private bool terminallyCompleted; public IdempotentCleanup Current => current; public bool IsTerminallyCompleted => terminallyCompleted; public void RegisterPersistent(Action action) { if (action == null) { throw new ArgumentNullException("action"); } if (terminallyCompleted) { action(); } else if (!persistentActions.Contains(action)) { persistentActions.Add(action); current.Register(action); } } public void Reset() { if (terminallyCompleted) { return; } try { current.Complete(); } finally { current = new IdempotentCleanup(); for (int i = 0; i < persistentActions.Count; i++) { current.Register(persistentActions[i]); } } } public void Complete() { if (terminallyCompleted) { return; } terminallyCompleted = true; try { current.Complete(); } finally { persistentActions.Clear(); } } } public readonly record struct BoundedSetting(T Value, T Minimum, T Maximum) where T : IComparable { public T Clamp() { if (Value.CompareTo(Minimum) >= 0) { if (Value.CompareTo(Maximum) <= 0) { return Value; } return Maximum; } return Minimum; } } public readonly record struct GameplaySettings(bool Enabled, bool AllowIndoor, bool AllowOutdoor, int SpawnWeight, int PowerLevel, int MaximumCount, int Health, float StunSeconds, float CooldownSeconds, int Damage, float EffectSeconds, float NoiseRange, float NoiseLoudness, bool DebugLogging) { public GameplaySettings Validated() { return this with { SpawnWeight = Math.Clamp(SpawnWeight, 0, 100), PowerLevel = Math.Clamp(PowerLevel, 0, 100), MaximumCount = Math.Clamp(MaximumCount, 0, 8), Health = Math.Clamp(Health, 1, 1000), StunSeconds = Math.Clamp(StunSeconds, 0f, 60f), CooldownSeconds = Math.Clamp(CooldownSeconds, 0f, 300f), Damage = Math.Clamp(Damage, 0, 100), EffectSeconds = Math.Clamp(EffectSeconds, 0.1f, 300f), NoiseRange = Math.Clamp(NoiseRange, 0f, 200f), NoiseLoudness = Math.Clamp(NoiseLoudness, 0f, 1f) }; } } public readonly record struct AccessibilitySettings(float ScreenShake, float CameraRoll, float Flash, float MotionTrail, bool Subtitles, float SubtitleScale, float Volume, bool ReducedMotion) { public AccessibilitySettings Validated() { return this with { ScreenShake = Math.Clamp(ScreenShake, 0f, 1f), CameraRoll = Math.Clamp(CameraRoll, 0f, 1f), Flash = Math.Clamp(Flash, 0f, 1f), MotionTrail = Math.Clamp(MotionTrail, 0f, 1f), SubtitleScale = Math.Clamp(SubtitleScale, 0.75f, 2f), Volume = Math.Clamp(Volume, 0f, 1f) }; } } public readonly record struct Seed(ulong Value) { public Seed Combine(ulong value) { return new Seed(Mix(Value ^ value)); } public static Seed From(params ulong[] values) { Seed result = new Seed(11400714819323198485uL); foreach (ulong value in values) { result = result.Combine(value); } return result; } private static ulong Mix(ulong value) { value ^= value >> 30; value *= 13787848793156543929uL; value ^= value >> 27; value *= 10723151780598845931uL; return value ^ (value >> 31); } } public sealed class DeterministicRandom { private ulong state; public DeterministicRandom(Seed seed) { state = ((seed.Value == 0L) ? 11562461410679940143uL : seed.Value); } public ulong NextUInt64() { state += 11400714819323198485uL; ulong num = state; long num2 = (long)(num ^ (num >> 30)) * -4658895280553007687L; long num3 = (num2 ^ (num2 >>> 27)) * -7723592293110705685L; return (ulong)(num3 ^ (num3 >>> 31)); } public int NextInt(int exclusiveMax) { if (exclusiveMax <= 0) { throw new ArgumentOutOfRangeException("exclusiveMax"); } return (int)(NextUInt64() % (uint)exclusiveMax); } public double NextUnit() { return (double)(NextUInt64() >> 11) * 1.1102230246251565E-16; } } public readonly record struct Weighted(T Value, int Weight); public static class WeightedPicker { public static T Pick(IReadOnlyList> options, DeterministicRandom random) { if (options.Count == 0) { throw new ArgumentException("At least one option is required.", "options"); } int num = 0; foreach (Weighted option in options) { if (option.Weight < 0) { throw new ArgumentOutOfRangeException("options", "Weights cannot be negative."); } num = checked(num + option.Weight); } if (num == 0) { throw new ArgumentException("At least one option must have positive weight.", "options"); } int num2 = random.NextInt(num); foreach (Weighted option2 in options) { if (num2 < option2.Weight) { return option2.Value; } num2 -= option2.Weight; } throw new InvalidOperationException("Weighted selection exhausted unexpectedly."); } } public sealed class EffectOwnerLedger { private sealed class Entry { internal ulong LifetimeOwner { get; set; } internal HashSet AffectedOwners { get; } = new HashSet(); internal Entry(ulong lifetimeOwner) { LifetimeOwner = lifetimeOwner; } } private readonly Dictionary entries = new Dictionary(); public int Count => entries.Count; public void Track(EntityId effectId, ulong lifetimeOwner = ulong.MaxValue) { if (!effectId.IsValid) { throw new ArgumentException("A valid effect id is required.", "effectId"); } if (entries.TryGetValue(effectId, out Entry value)) { if (value.LifetimeOwner == ulong.MaxValue && lifetimeOwner != ulong.MaxValue) { value.LifetimeOwner = lifetimeOwner; } } else { entries.Add(effectId, new Entry(lifetimeOwner)); } } public bool Associate(EntityId effectId, ulong affectedOwner) { if (effectId.IsValid && affectedOwner != ulong.MaxValue && entries.TryGetValue(effectId, out Entry value)) { return value.AffectedOwners.Add(affectedOwner); } return false; } public bool Disassociate(EntityId effectId, ulong affectedOwner) { if (effectId.IsValid && affectedOwner != ulong.MaxValue && entries.TryGetValue(effectId, out Entry value)) { return value.AffectedOwners.Remove(affectedOwner); } return false; } public bool Forget(EntityId effectId) { return entries.Remove(effectId); } public void Clear() { entries.Clear(); } public IReadOnlyList OwnedOrAffectedBy(ulong owner) { return Collect(owner, includeLifetimeOwner: true); } public IReadOnlyList AffectedBy(ulong owner) { return Collect(owner, includeLifetimeOwner: false); } private IReadOnlyList Collect(ulong owner, bool includeLifetimeOwner) { List list = new List(); foreach (KeyValuePair entry in entries) { if ((includeLifetimeOwner && entry.Value.LifetimeOwner == owner) || entry.Value.AffectedOwners.Contains(owner)) { list.Add(entry.Key); } } return list; } } public readonly record struct DestinationCandidate(EntityId Id, bool PathComplete, bool InInterior, bool IsShip, bool IsCompany, bool NearPit, bool NearMine, bool LockedRegion, bool UnderMap, float DangerScore, float Distance); public static class DestinationSafety { public static bool IsSafe(in DestinationCandidate candidate, float maximumDanger, float minimumDistance, bool allowShip = false, bool allowCompany = false) { if (candidate.Id.IsValid && candidate.PathComplete && candidate.InInterior && !candidate.UnderMap && !candidate.NearPit && !candidate.NearMine && !candidate.LockedRegion && (allowShip || !candidate.IsShip) && (allowCompany || !candidate.IsCompany) && candidate.DangerScore <= maximumDanger) { return candidate.Distance >= minimumDistance; } return false; } public static DestinationCandidate? Choose(IReadOnlyList candidates, DeterministicRandom random, float maximumDanger, float minimumDistance) { List list = new List(); foreach (DestinationCandidate candidate2 in candidates) { DestinationCandidate candidate = candidate2; if (IsSafe(in candidate, maximumDanger, minimumDistance)) { list.Add(candidate); } } if (list.Count == 0) { return null; } return list[random.NextInt(list.Count)]; } } public sealed class RateLimiter { private readonly Dictionary nextAllowedAt = new Dictionary(); public bool TryAcquire(EntityId key, double now, double minimumInterval) { if (minimumInterval < 0.0) { throw new ArgumentOutOfRangeException("minimumInterval"); } if (nextAllowedAt.TryGetValue(key, out var value) && now < value) { return false; } nextAllowedAt[key] = now + minimumInterval; return true; } public void Clear(EntityId key) { nextAllowedAt.Remove(key); } public void ClearAll() { nextAllowedAt.Clear(); } } public enum SystemicThreatKind : byte { RestraintOrDisplacement, RoomScaleEnvironmental, PersistentCurse } public sealed class SystemicThreatBudget { private readonly int[] capacities = new int[3] { 1, 1, 1 }; private readonly HashSet[] leases = new HashSet[3] { new HashSet(), new HashSet(), new HashSet() }; public void SetCapacity(SystemicThreatKind kind, int capacity) { capacities[Index(kind)] = Math.Clamp(capacity, 0, 8); } public int Capacity(SystemicThreatKind kind) { return capacities[Index(kind)]; } public int Active(SystemicThreatKind kind) { return leases[Index(kind)].Count; } public bool TryAcquire(SystemicThreatKind kind, EntityId entity) { if (!entity.IsValid) { return false; } HashSet hashSet = leases[Index(kind)]; if (hashSet.Contains(entity)) { return true; } if (hashSet.Count >= capacities[Index(kind)]) { return false; } hashSet.Add(entity); return true; } public bool Release(SystemicThreatKind kind, EntityId entity) { if (entity.IsValid) { return leases[Index(kind)].Remove(entity); } return false; } public int Release(EntityId entity) { if (!entity.IsValid) { return 0; } int num = 0; for (int i = 0; i < leases.Length; i++) { if (leases[i].Remove(entity)) { num++; } } return num; } public void Clear() { for (int i = 0; i < leases.Length; i++) { leases[i].Clear(); } } private static int Index(SystemicThreatKind kind) { if (kind < (SystemicThreatKind)3) { return (int)kind; } throw new ArgumentOutOfRangeException("kind"); } } } namespace System.Runtime.CompilerServices { internal static class IsExternalInit { } }