using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using FalseGods.Application.ReadyGate; using FalseGods.Application.Replication; using FalseGods.Application.Wire; using FalseGods.Core.Arena; using FalseGods.Core.Arena.Events; using FalseGods.Core.Bosses; using FalseGods.Core.Bosses.Combat; using FalseGods.Core.Bosses.Events; using FalseGods.Core.Encounters; using FalseGods.Core.Simulation; using FalseGods.Protocol.Arena; using FalseGods.Protocol.Wire; using FalseGods.RuntimeContracts.Arena; using FalseGods.RuntimeContracts.Diagnostics; using FalseGods.RuntimeContracts.Multiplayer; using FalseGods.RuntimeContracts.Presentation; using FalseGods.RuntimeContracts.Transport; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("FalseGods.Application")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+6e5740a80f810ab422551028733810b527fb614d")] [assembly: AssemblyProduct("FalseGods.Application")] [assembly: AssemblyTitle("FalseGods.Application")] [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; } } internal static class IsExternalInit { } } namespace FalseGods.Application.Wire { public static class ArenaWireMapping { public static ArenaSnapshot ToSnapshot(ArenaSimulation arena, EncounterId encounter, string arenaId, int arenaVersion, SimulationTick tick, Sequence lastProcessedArenaEventSequence) { //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown if (arena == null) { throw new ArgumentNullException("arena"); } List list = new List(arena.ActiveMechanismGroups); return new ArenaSnapshot(encounter, arenaId, arenaVersion, ProtocolVersion.Current, tick, (IReadOnlyList)list, arena.IsExitUnlocked, lastProcessedArenaEventSequence); } public static IArenaWireEvent ToWireEvent(IArenaDomainEvent domainEvent, Sequence sequence, SimulationTick tick) { //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_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_0025: Expected O, but got Unknown //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_002d: Expected O, but got Unknown MechanismGroupActivated val = (MechanismGroupActivated)(object)((domainEvent is MechanismGroupActivated) ? domainEvent : null); if (val == null) { if (!(domainEvent is ArenaExitUnlocked)) { if (domainEvent == null) { throw new ArgumentNullException("domainEvent"); } throw new ArgumentOutOfRangeException("domainEvent", ((object)domainEvent).GetType().Name, "No wire mapping for this arena domain event."); } return (IArenaWireEvent)new ArenaExitUnlockedEvent(sequence, tick); } return (IArenaWireEvent)new ArenaMechanismGroupActivatedEvent(sequence, tick, val.Group); } } public static class BossWireMapping { public static BossSnapshot ToSnapshot(BossSimulation boss, EncounterId encounter, DefinitionId definition, SimulationTick tick, Sequence lastProcessedBossEventSequence) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected I4, but got Unknown //IL_0035: 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_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_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_005c: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected I4, but got Unknown //IL_0092: Expected I4, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown if (boss == null) { throw new ArgumentNullException("boss"); } AttackInstanceId? currentAttack = boss.CurrentAttack; int? num = (currentAttack.HasValue ? new int?((int)boss.CurrentAttackKind) : ((int?)null)); return new BossSnapshot(encounter, boss.Id, definition, ProtocolVersion.Current, tick, (int)boss.Phase, (int)boss.Activity, tick, currentAttack, num, (ParticipantId?)null, boss.Position, boss.PositionHeight, boss.Facing, boss.Health, boss.MaxHealth, boss.IsWeakPointExposed, boss.IsEnraged, boss.HasBegun, lastProcessedBossEventSequence); } public static IBossWireEvent ToWireEvent(IBossDomainEvent domainEvent, Sequence sequence, SimulationTick tick) { //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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected I4, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_00a7: 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_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_00c6: Expected I4, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00c7: 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_00ca: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected I4, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected I4, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_00fe: 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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_011b: 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_012d: 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_013f: Expected O, but got Unknown //IL_013f: 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_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown BossSpawned val = (BossSpawned)(object)((domainEvent is BossSpawned) ? domainEvent : null); if (val == null) { if (!(domainEvent is BossBegan)) { AttackTelegraphed val2 = (AttackTelegraphed)(object)((domainEvent is AttackTelegraphed) ? domainEvent : null); if (val2 == null) { AttackCommitted val3 = (AttackCommitted)(object)((domainEvent is AttackCommitted) ? domainEvent : null); if (val3 == null) { WeakPointExposed val4 = (WeakPointExposed)(object)((domainEvent is WeakPointExposed) ? domainEvent : null); if (val4 == null) { BossPhaseChanged val5 = (BossPhaseChanged)(object)((domainEvent is BossPhaseChanged) ? domainEvent : null); if (val5 == null) { BossDamaged val6 = (BossDamaged)(object)((domainEvent is BossDamaged) ? domainEvent : null); if (val6 == null) { BossRelocated val7 = (BossRelocated)(object)((domainEvent is BossRelocated) ? domainEvent : null); if (val7 == null) { BossEnraged val8 = (BossEnraged)(object)((domainEvent is BossEnraged) ? domainEvent : null); if (val8 == null) { if (!(domainEvent is BossDied)) { if (domainEvent == null) { throw new ArgumentNullException("domainEvent"); } throw new ArgumentOutOfRangeException("domainEvent", ((object)domainEvent).GetType().Name, "No wire mapping for this boss domain event."); } return (IBossWireEvent)new BossDefeatedEvent(sequence, tick); } return (IBossWireEvent)new BossEnragedEvent(sequence, tick, val8.Enraged); } return (IBossWireEvent)new BossRelocatedEvent(sequence, tick, val7.StationIndex, val7.AnchorIndex, val7.Position, val7.Height); } return (IBossWireEvent)new BossDamagedEvent(sequence, tick, val6.Amount, val6.RemainingHealth, val6.WeakPointHit); } return (IBossWireEvent)new BossPhaseChangedEvent(sequence, tick, (int)val5.Phase); } return (IBossWireEvent)new BossWeakPointChangedEvent(sequence, tick, val4.Exposed); } return (IBossWireEvent)new BossAttackCommittedEvent(sequence, tick, val3.Attack, (int)val3.Kind, val3.AimPoint); } return (IBossWireEvent)new BossAttackTelegraphedEvent(sequence, tick, val2.Attack, (int)val2.Kind, val2.AimPoint, val2.TelegraphSeconds); } return (IBossWireEvent)new BossBeganEvent(sequence, tick); } return (IBossWireEvent)new BossAppearedEvent(sequence, tick, (int)val.Phase); } } } namespace FalseGods.Application.Replication { public enum ReplicationKind : byte { BossSnapshot = 1, ArenaSnapshot, BossEvent, ArenaEvent, EncounterBaseline, EnterArena, ArenaReady, ArenaLoadFailed, EncounterAborted, EncounterEnded, ClientHitRequest, BossHitPlayer, ArenaLevelDeclared, ArenaLevelRequested, CrateDropped, CrateThrown, CrateVolleyFired, CratesTaken, CratesSetDown, CrateDestroyed, CrateDestroyRequested } public readonly struct DecodedMessage { public ReplicationKind Kind { get; } public object Value { get; } public DecodedMessage(ReplicationKind kind, object value) { Kind = kind; Value = value; } } public static class EncounterCodec { public static EncodedPayload Encode(BossSnapshot snapshot) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.BossSnapshot, WireCodec.Serialize(snapshot)); } public static EncodedPayload Encode(ArenaSnapshot snapshot) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.ArenaSnapshot, WireCodec.Serialize(snapshot)); } public static EncodedPayload Encode(IBossWireEvent bossEvent) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.BossEvent, WireCodec.Serialize(bossEvent)); } public static EncodedPayload Encode(IArenaWireEvent arenaEvent) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.ArenaEvent, WireCodec.Serialize(arenaEvent)); } public static EncodedPayload Encode(EncounterBaseline baseline) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.EncounterBaseline, WireCodec.Serialize(baseline)); } public static EncodedPayload Encode(EnterArena message) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.EnterArena, WireCodec.Serialize(message)); } public static EncodedPayload Encode(ArenaReady message) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.ArenaReady, WireCodec.Serialize(message)); } public static EncodedPayload Encode(ArenaLoadFailed message) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.ArenaLoadFailed, WireCodec.Serialize(message)); } public static EncodedPayload Encode(EncounterAborted message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.EncounterAborted, WireCodec.Serialize(message)); } public static EncodedPayload Encode(EncounterEnded message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.EncounterEnded, WireCodec.Serialize(message)); } public static EncodedPayload Encode(ClientHitRequest message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.ClientHitRequest, WireCodec.Serialize(message)); } public static EncodedPayload Encode(BossHitPlayer message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.BossHitPlayer, WireCodec.Serialize(message)); } public static EncodedPayload Encode(ArenaLevelDeclared message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.ArenaLevelDeclared, WireCodec.Serialize(message)); } public static EncodedPayload Encode(ArenaLevelRequested message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.ArenaLevelRequested, WireCodec.Serialize(message)); } public static EncodedPayload Encode(CrateDropped message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.CrateDropped, WireCodec.Serialize(message)); } public static EncodedPayload Encode(CrateThrown message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.CrateThrown, WireCodec.Serialize(message)); } public static EncodedPayload Encode(CrateVolleyFired message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.CrateVolleyFired, WireCodec.Serialize(message)); } public static EncodedPayload Encode(CratesTaken message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.CratesTaken, WireCodec.Serialize(message)); } public static EncodedPayload Encode(CratesSetDown message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.CratesSetDown, WireCodec.Serialize(message)); } public static EncodedPayload Encode(CrateDestroyed message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.CrateDestroyed, WireCodec.Serialize(message)); } public static EncodedPayload Encode(CrateDestroyRequested message) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) return Wrap(ReplicationKind.CrateDestroyRequested, WireCodec.Serialize(message)); } public static DecodedMessage Decode(EncodedPayload payload) { byte[] array = ((EncodedPayload)(ref payload)).ToArray(); if (array.Length == 0) { throw new InvalidDataException("Empty replication payload: no kind tag."); } ReplicationKind replicationKind = (ReplicationKind)array[0]; byte[] array2 = new byte[array.Length - 1]; Array.Copy(array, 1, array2, 0, array2.Length); return replicationKind switch { ReplicationKind.BossSnapshot => new DecodedMessage(replicationKind, WireCodec.DeserializeBossSnapshot(array2)), ReplicationKind.ArenaSnapshot => new DecodedMessage(replicationKind, WireCodec.DeserializeArenaSnapshot(array2)), ReplicationKind.BossEvent => new DecodedMessage(replicationKind, WireCodec.DeserializeBossEvent(array2)), ReplicationKind.ArenaEvent => new DecodedMessage(replicationKind, WireCodec.DeserializeArenaEvent(array2)), ReplicationKind.EncounterBaseline => new DecodedMessage(replicationKind, WireCodec.DeserializeBaseline(array2)), ReplicationKind.EnterArena => new DecodedMessage(replicationKind, WireCodec.DeserializeEnterArena(array2)), ReplicationKind.ArenaReady => new DecodedMessage(replicationKind, WireCodec.DeserializeArenaReady(array2)), ReplicationKind.ArenaLoadFailed => new DecodedMessage(replicationKind, WireCodec.DeserializeArenaLoadFailed(array2)), ReplicationKind.EncounterAborted => new DecodedMessage(replicationKind, WireCodec.DeserializeEncounterAborted(array2)), ReplicationKind.EncounterEnded => new DecodedMessage(replicationKind, WireCodec.DeserializeEncounterEnded(array2)), ReplicationKind.ClientHitRequest => new DecodedMessage(replicationKind, WireCodec.DeserializeClientHitRequest(array2)), ReplicationKind.BossHitPlayer => new DecodedMessage(replicationKind, WireCodec.DeserializeBossHitPlayer(array2)), ReplicationKind.ArenaLevelDeclared => new DecodedMessage(replicationKind, WireCodec.DeserializeArenaLevelDeclared(array2)), ReplicationKind.ArenaLevelRequested => new DecodedMessage(replicationKind, WireCodec.DeserializeArenaLevelRequested(array2)), ReplicationKind.CrateDropped => new DecodedMessage(replicationKind, WireCodec.DeserializeCrateDropped(array2)), ReplicationKind.CrateThrown => new DecodedMessage(replicationKind, WireCodec.DeserializeCrateThrown(array2)), ReplicationKind.CrateVolleyFired => new DecodedMessage(replicationKind, WireCodec.DeserializeCrateVolleyFired(array2)), ReplicationKind.CratesTaken => new DecodedMessage(replicationKind, WireCodec.DeserializeCratesTaken(array2)), ReplicationKind.CratesSetDown => new DecodedMessage(replicationKind, WireCodec.DeserializeCratesSetDown(array2)), ReplicationKind.CrateDestroyed => new DecodedMessage(replicationKind, WireCodec.DeserializeCrateDestroyed(array2)), ReplicationKind.CrateDestroyRequested => new DecodedMessage(replicationKind, WireCodec.DeserializeCrateDestroyRequested(array2)), _ => throw new InvalidDataException($"Unknown replication kind tag {array[0]}."), }; } private static EncodedPayload Wrap(ReplicationKind kind, byte[] wireBytes) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) byte[] array = new byte[wireBytes.Length + 1]; array[0] = (byte)kind; Array.Copy(wireBytes, 0, array, 1, wireBytes.Length); return new EncodedPayload(array); } } public sealed class EncounterHostReplication { private static readonly Sequence NoEvents = new Sequence(-1L); private readonly ReplicationSender _sender; private readonly IMultiplayerSession _session; private readonly IPlayerRoster _roster; private readonly EncounterId _encounter; private readonly DefinitionId _definition; private readonly ArenaManifest _manifest; private readonly WorldPosition _arenaOrigin; private readonly HashSet _baselinedPeers = new HashSet(); private Sequence _lastBossSequence = NoEvents; private Sequence _lastArenaSequence = NoEvents; public Sequence LastBossSequence => _lastBossSequence; public Sequence LastArenaSequence => _lastArenaSequence; public EncounterHostReplication(ReplicationSender sender, IMultiplayerSession session, IPlayerRoster roster, EncounterId encounter, DefinitionId definition, ArenaManifest manifest, WorldPosition arenaOrigin = default(WorldPosition)) { //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_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_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_0072: 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_0091: 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) _sender = sender ?? throw new ArgumentNullException("sender"); _session = session ?? throw new ArgumentNullException("session"); _roster = roster ?? throw new ArgumentNullException("roster"); _encounter = encounter; _definition = definition; _manifest = manifest ?? throw new ArgumentNullException("manifest"); _arenaOrigin = arenaOrigin; } public void Publish(BossSimulation boss, IReadOnlyList drainedEvents, SimulationTick tick) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) PublishCore(boss, drainedEvents, null, Array.Empty(), null, tick); } public void Publish(BossSimulation boss, IReadOnlyList drainedBossEvents, ArenaSimulation arena, IReadOnlyList drainedArenaEvents, EncounterPhase phase, SimulationTick tick) { //IL_0014: 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 (arena == null) { throw new ArgumentNullException("arena"); } PublishCore(boss, drainedBossEvents, arena, drainedArenaEvents, phase, tick); } private void PublishCore(BossSimulation boss, IReadOnlyList drainedBossEvents, ArenaSimulation? arena, IReadOnlyList drainedArenaEvents, EncounterPhase? phase, SimulationTick tick) { //IL_0030: 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_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_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_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_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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) if (boss == null) { throw new ArgumentNullException("boss"); } if (drainedBossEvents == null) { throw new ArgumentNullException("drainedBossEvents"); } if (drainedArenaEvents == null) { throw new ArgumentNullException("drainedArenaEvents"); } BaselineNewPeers(boss, arena, phase, tick); for (int i = 0; i < drainedBossEvents.Count; i++) { _lastBossSequence = ((Sequence)(ref _lastBossSequence)).Next(); _sender.BroadcastBossEvent(BossWireMapping.ToWireEvent(drainedBossEvents[i], _lastBossSequence, tick)); } for (int j = 0; j < drainedArenaEvents.Count; j++) { _lastArenaSequence = ((Sequence)(ref _lastArenaSequence)).Next(); _sender.BroadcastArenaEvent(ArenaWireMapping.ToWireEvent(drainedArenaEvents[j], _lastArenaSequence, tick)); } _sender.BroadcastBossSnapshot(BossWireMapping.ToSnapshot(boss, _encounter, _definition, tick, _lastBossSequence)); if (arena != null) { _sender.BroadcastArenaSnapshot(BuildArenaSnapshot(arena, tick)); } } private void BaselineNewPeers(BossSimulation boss, ArenaSimulation? arena, EncounterPhase? phase, SimulationTick tick) { //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_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_0059: 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_0072: 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) IReadOnlyList members = _roster.Members; _baselinedPeers.RemoveWhere((SessionPeerId peer) => !Contains(members, peer)); for (int num = 0; num < members.Count; num++) { SessionPeerId val = members[num]; if (!(val == _session.LocalPeer) && !_baselinedPeers.Contains(val)) { _sender.SendBaseline(BuildBaseline(boss, arena, phase, tick), val); _baselinedPeers.Add(val); } } } private EncounterBaseline BuildBaseline(BossSimulation boss, ArenaSimulation? arena, EncounterPhase? phase, SimulationTick tick) { //IL_003a: 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_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_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_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_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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected I4, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_0062: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected I4, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown ArenaSnapshot val = (ArenaSnapshot)((arena != null) ? ((object)BuildArenaSnapshot(arena, tick)) : ((object)new ArenaSnapshot(_encounter, _manifest.ArenaId, _manifest.ArenaVersion, ProtocolVersion.Current, tick, (IReadOnlyList)Array.Empty(), false, NoEvents))); EncounterPhase val2 = (EncounterPhase)(((int?)phase) ?? ((!boss.IsDead) ? 1 : 2)); return new EncounterBaseline(_encounter, ProtocolVersion.Current, _manifest.ArenaId, _manifest.ArenaVersion, _manifest.ContentHash, _arenaOrigin, tick, (int)val2, BossWireMapping.ToSnapshot(boss, _encounter, _definition, tick, _lastBossSequence), val, _lastBossSequence, _lastArenaSequence); } private ArenaSnapshot BuildArenaSnapshot(ArenaSimulation arena, SimulationTick tick) { //IL_0002: 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_001f: Unknown result type (might be due to invalid IL or missing references) return ArenaWireMapping.ToSnapshot(arena, _encounter, _manifest.ArenaId, _manifest.ArenaVersion, tick, _lastArenaSequence); } private static bool Contains(IReadOnlyList members, SessionPeerId peer) { //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) for (int i = 0; i < members.Count; i++) { if (members[i] == peer) { return true; } } return false; } } public sealed class ReplicationReceiver : IDisposable { private readonly IEncounterChannel _channel; private readonly IMultiplayerSession _session; private readonly HashSet _appliedBossSequences = new HashSet(); private readonly HashSet _appliedArenaSequences = new HashSet(); private readonly HashSet _committedAttacks = new HashSet(); private readonly List _appliedBossEvents = new List(); private readonly List _appliedArenaEvents = new List(); private long _bossFloor = -1L; private long _arenaFloor = -1L; private long _lastBossSnapshotTick = long.MinValue; private long _lastArenaSnapshotTick = long.MinValue; public int DroppedFromNonHost { get; private set; } public int DroppedMalformed { get; private set; } public int DroppedVersionMismatch { get; private set; } public IReadOnlyList AppliedBossEvents => _appliedBossEvents; public IReadOnlyList AppliedArenaEvents => _appliedArenaEvents; public int CommittedAttackCount => _committedAttacks.Count; public BossSnapshot? LatestBossSnapshot { get; private set; } public ArenaSnapshot? LatestArenaSnapshot { get; private set; } public bool HasBaseline { get; private set; } public EncounterBaseline? Baseline { get; private set; } public ReplicationReceiver(IEncounterChannel channel, IMultiplayerSession session) { _channel = channel ?? throw new ArgumentNullException("channel"); _session = session ?? throw new ArgumentNullException("session"); _channel.Received += OnReceived; } public void Dispose() { _channel.Received -= OnReceived; } public void Apply(EncodedPayload payload) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ApplyDecoded(EncounterCodec.Decode(payload)); } private void OnReceived(SessionPeerId sender, EncodedPayload payload) { //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_0025: Unknown result type (might be due to invalid IL or missing references) if (sender != _session.HostPeer) { DroppedFromNonHost++; return; } DecodedMessage message; try { message = EncounterCodec.Decode(payload); } catch (Exception) { DroppedMalformed++; return; } ApplyDecoded(message); } private void ApplyDecoded(DecodedMessage message) { //IL_0088: 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_00c7: Unknown result type (might be due to invalid IL or missing references) object value = message.Value; BossSnapshot val = (BossSnapshot)((value is BossSnapshot) ? value : null); if (val == null) { ArenaSnapshot val2 = (ArenaSnapshot)((value is ArenaSnapshot) ? value : null); if (val2 == null) { IBossWireEvent val3 = (IBossWireEvent)((value is IBossWireEvent) ? value : null); if (val3 == null) { IArenaWireEvent val4 = (IArenaWireEvent)((value is IArenaWireEvent) ? value : null); if (val4 == null) { EncounterBaseline val5 = (EncounterBaseline)((value is EncounterBaseline) ? value : null); if (val5 == null) { if (!(value is EnterArena) && !(value is ArenaReady) && !(value is ArenaLoadFailed) && !(value is EncounterAborted) && !(value is EncounterEnded)) { throw new InvalidOperationException("Unhandled replication value " + (message.Value?.GetType().Name ?? "null") + "."); } } else if (!RejectVersion(val5.ProtocolVersion)) { ApplyBaseline(val5); } } else { ApplyArenaEvent(val4); } } else { ApplyBossEvent(val3); } } else if (!RejectVersion(val2.ProtocolVersion)) { ApplyArenaSnapshot(val2); } } else if (!RejectVersion(val.ProtocolVersion)) { ApplyBossSnapshot(val); } } private bool RejectVersion(ProtocolVersion version) { //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 (version != ProtocolVersion.Current) { DroppedVersionMismatch++; return true; } return false; } private void ApplyBossSnapshot(BossSnapshot snapshot) { //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_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) SimulationTick tick = snapshot.Tick; if (((SimulationTick)(ref tick)).Value >= _lastBossSnapshotTick) { LatestBossSnapshot = snapshot; tick = snapshot.Tick; _lastBossSnapshotTick = ((SimulationTick)(ref tick)).Value; } } private void ApplyArenaSnapshot(ArenaSnapshot snapshot) { //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_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) SimulationTick tick = snapshot.Tick; if (((SimulationTick)(ref tick)).Value >= _lastArenaSnapshotTick) { LatestArenaSnapshot = snapshot; tick = snapshot.Tick; _lastArenaSnapshotTick = ((SimulationTick)(ref tick)).Value; } } private void ApplyBossEvent(IBossWireEvent bossEvent) { //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_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) Sequence sequence = bossEvent.Sequence; long value = ((Sequence)(ref sequence)).Value; if (value > _bossFloor && _appliedBossSequences.Add(value)) { BossAttackCommittedEvent val = (BossAttackCommittedEvent)(object)((bossEvent is BossAttackCommittedEvent) ? bossEvent : null); if (val != null) { HashSet committedAttacks = _committedAttacks; AttackInstanceId attack = val.Attack; committedAttacks.Add(((AttackInstanceId)(ref attack)).Value); } _appliedBossEvents.Add(bossEvent); } } private void ApplyArenaEvent(IArenaWireEvent arenaEvent) { //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) Sequence sequence = arenaEvent.Sequence; long value = ((Sequence)(ref sequence)).Value; if (value > _arenaFloor && _appliedArenaSequences.Add(value)) { _appliedArenaEvents.Add(arenaEvent); } } private void ApplyBaseline(EncounterBaseline baseline) { //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_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_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_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) if (!HasBaseline) { HasBaseline = true; Baseline = baseline; Sequence val = baseline.LastProcessedBossEventSequence; _bossFloor = ((Sequence)(ref val)).Value; val = baseline.LastProcessedArenaEventSequence; _arenaFloor = ((Sequence)(ref val)).Value; LatestBossSnapshot = baseline.Boss; LatestArenaSnapshot = baseline.Arena; SimulationTick tick = baseline.Boss.Tick; _lastBossSnapshotTick = ((SimulationTick)(ref tick)).Value; tick = baseline.Arena.Tick; _lastArenaSnapshotTick = ((SimulationTick)(ref tick)).Value; } } } public sealed class ReplicationSender { private readonly IEncounterChannel _channel; private readonly IMultiplayerSession _session; public ReplicationSender(IEncounterChannel channel, IMultiplayerSession session) { _channel = channel ?? throw new ArgumentNullException("channel"); _session = session ?? throw new ArgumentNullException("session"); } public void BroadcastBossSnapshot(BossSnapshot snapshot) { //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) Send(EncounterCodec.Encode(snapshot), (MessageDelivery)1, MessageTarget.AllClients); } public void BroadcastArenaSnapshot(ArenaSnapshot snapshot) { //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) Send(EncounterCodec.Encode(snapshot), (MessageDelivery)1, MessageTarget.AllClients); } public void BroadcastBossEvent(IBossWireEvent bossEvent) { //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) Send(EncounterCodec.Encode(bossEvent), (MessageDelivery)0, MessageTarget.AllClients); } public void BroadcastArenaEvent(IArenaWireEvent arenaEvent) { //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) Send(EncounterCodec.Encode(arenaEvent), (MessageDelivery)0, MessageTarget.AllClients); } public void SendBaseline(EncounterBaseline baseline, SessionPeerId peer) { //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) Send(EncounterCodec.Encode(baseline), (MessageDelivery)0, MessageTarget.ToPeer(peer)); } public void BroadcastEnterArena(EnterArena message) { //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) Send(EncounterCodec.Encode(message), (MessageDelivery)0, MessageTarget.AllClients); } public void BroadcastAborted(EncounterAborted message) { //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) Send(EncounterCodec.Encode(message), (MessageDelivery)0, MessageTarget.AllClients); } public void BroadcastEnded(EncounterEnded message) { //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) Send(EncounterCodec.Encode(message), (MessageDelivery)0, MessageTarget.AllClients); } public void SendBossHitPlayer(BossHitPlayer message, SessionPeerId peer) { //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) Send(EncounterCodec.Encode(message), (MessageDelivery)0, MessageTarget.ToPeer(peer)); } private void Send(EncodedPayload payload, MessageDelivery delivery, MessageTarget target) { //IL_0006: 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_0020: Unknown result type (might be due to invalid IL or missing references) if ((int)_session.Role != 0) { throw new InvalidOperationException("Only the host replicates encounter state; a client must not broadcast."); } _channel.Send(payload, delivery, target); } } } namespace FalseGods.Application.ReadyGate { public enum GateStatus { Waiting, Resolved, Aborted } public enum GateAbortReason { None, ContentHashSchemaMismatch, VersionMismatch, ContentMismatch, LoadFailed, Timeout } public sealed class EncounterReadyGate { private readonly ArenaManifest _hostManifest; private readonly IPlayerRoster _roster; private readonly HashSet _ready = new HashSet(); public GateStatus Status { get { if (AbortReason != GateAbortReason.None) { return GateStatus.Aborted; } if (!AllRequiredReady()) { return GateStatus.Waiting; } return GateStatus.Resolved; } } public GateAbortReason AbortReason { get; private set; } public IReadOnlyList Outstanding => _roster.Members.Where((SessionPeerId m) => !_ready.Contains(m)).ToList(); public EncounterReadyGate(ArenaManifest hostManifest, IPlayerRoster roster) { _hostManifest = hostManifest ?? throw new ArgumentNullException("hostManifest"); _roster = roster ?? throw new ArgumentNullException("roster"); } public GateStatus SubmitReady(SessionPeerId peer, ArenaManifest report) { //IL_0023: 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) //IL_00b3: 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_00d8: Unknown result type (might be due to invalid IL or missing references) if (report == null) { throw new ArgumentNullException("report"); } if (AbortReason != GateAbortReason.None) { return GateStatus.Aborted; } if (!_roster.Members.Contains(peer)) { return Status; } if (report.ContentHashSchemaVersion != _hostManifest.ContentHashSchemaVersion) { return Abort(GateAbortReason.ContentHashSchemaMismatch); } if (!string.Equals(report.ArenaId, _hostManifest.ArenaId, StringComparison.Ordinal) || report.ArenaVersion != _hostManifest.ArenaVersion || report.ProtocolVersion != _hostManifest.ProtocolVersion || !string.Equals(report.BundleVersion, _hostManifest.BundleVersion, StringComparison.Ordinal)) { return Abort(GateAbortReason.VersionMismatch); } if (report.ContentHash != _hostManifest.ContentHash) { return Abort(GateAbortReason.ContentMismatch); } _ready.Add(peer); return Status; } public GateStatus SubmitLoadFailed(SessionPeerId peer) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if (AbortReason != GateAbortReason.None) { return GateStatus.Aborted; } if (!_roster.Members.Contains(peer)) { return Status; } return Abort(GateAbortReason.LoadFailed); } public GateStatus OnTimeout() { if (Status == GateStatus.Waiting) { return Abort(GateAbortReason.Timeout); } return Status; } private bool AllRequiredReady() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) IReadOnlyList members = _roster.Members; if (members.Count == 0) { return false; } for (int i = 0; i < members.Count; i++) { if (!_ready.Contains(members[i])) { return false; } } return true; } private GateStatus Abort(GateAbortReason reason) { AbortReason = reason; return GateStatus.Aborted; } } } namespace FalseGods.Application.Presentation { public static class ArenaPresentationMapping { public static IPresentationEvent ToEvent(IArenaDomainEvent domainEvent) { //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_0023: 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 MechanismGroupActivated val = (MechanismGroupActivated)(object)((domainEvent is MechanismGroupActivated) ? domainEvent : null); if (val == null) { if (!(domainEvent is ArenaExitUnlocked)) { if (domainEvent == null) { throw new ArgumentNullException("domainEvent"); } throw new ArgumentOutOfRangeException("domainEvent", ((object)domainEvent).GetType().Name, "No presentation mapping for this arena domain event."); } return (IPresentationEvent)new ExitOpened(); } return (IPresentationEvent)new MechanismGroupEngaged(val.Group); } } public static class BossPresentationMapping { public static PresentationState ToState(BossSimulation boss) { //IL_0043: 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_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_0066: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown if (boss == null) { throw new ArgumentNullException("boss"); } float num = ((boss.MaxHealth > 0) ? Math.Max(0f, Math.Min(1f, (float)boss.Health / (float)boss.MaxHealth)) : 0f); return new PresentationState(boss.Id, boss.Position, boss.PositionHeight, boss.Facing, ToPhaseVisualId(boss.Phase), ToVisualActivity(boss.Activity), boss.IsWeakPointExposed, boss.IsEnraged, num); } public static IPresentationEvent ToEvent(IBossDomainEvent domainEvent) { //IL_009a: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //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_00bc: Expected O, but got Unknown //IL_00bd: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00e5: Expected O, but got Unknown //IL_00e6: 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_00f2: 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_00fd: 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_0108: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_011e: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown //IL_0137: 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_0150: Expected O, but got Unknown //IL_0152: 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_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_016d: 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_017f: Expected O, but got Unknown //IL_0181: 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_018c: Expected O, but got Unknown BossSpawned val = (BossSpawned)(object)((domainEvent is BossSpawned) ? domainEvent : null); if (val == null) { BossBegan val2 = (BossBegan)(object)((domainEvent is BossBegan) ? domainEvent : null); if (val2 == null) { AttackTelegraphed val3 = (AttackTelegraphed)(object)((domainEvent is AttackTelegraphed) ? domainEvent : null); if (val3 == null) { AttackCommitted val4 = (AttackCommitted)(object)((domainEvent is AttackCommitted) ? domainEvent : null); if (val4 == null) { WeakPointExposed val5 = (WeakPointExposed)(object)((domainEvent is WeakPointExposed) ? domainEvent : null); if (val5 == null) { BossPhaseChanged val6 = (BossPhaseChanged)(object)((domainEvent is BossPhaseChanged) ? domainEvent : null); if (val6 == null) { BossDamaged val7 = (BossDamaged)(object)((domainEvent is BossDamaged) ? domainEvent : null); if (val7 == null) { BossRelocated val8 = (BossRelocated)(object)((domainEvent is BossRelocated) ? domainEvent : null); if (val8 == null) { BossEnraged val9 = (BossEnraged)(object)((domainEvent is BossEnraged) ? domainEvent : null); if (val9 == null) { BossDied val10 = (BossDied)(object)((domainEvent is BossDied) ? domainEvent : null); if (val10 == null) { if (domainEvent == null) { throw new ArgumentNullException("domainEvent"); } throw new ArgumentOutOfRangeException("domainEvent", ((object)domainEvent).GetType().Name, "No presentation mapping is defined for this boss domain event."); } return (IPresentationEvent)new BossDefeated(val10.Boss); } return (IPresentationEvent)new RageChanged(val9.Boss, val9.Enraged); } return (IPresentationEvent)new BossMoved(val8.Boss, val8.Position, val8.Height); } return (IPresentationEvent)new BossHit(val7.Boss, val7.Amount, val7.WeakPointHit); } return (IPresentationEvent)new PhaseTransition(val6.Boss, ToPhaseVisualId(val6.Phase)); } return (IPresentationEvent)new WeakPointVisibilityChanged(val5.Boss, val5.Exposed); } return (IPresentationEvent)new AttackLanded(val4.Boss, val4.Attack, ToVisualKind(val4.Kind), val4.AimPoint); } return (IPresentationEvent)new AttackTelegraphStarted(val3.Boss, val3.Attack, ToVisualKind(val3.Kind), val3.AimPoint, val3.TelegraphSeconds); } return (IPresentationEvent)new BossRoared(val2.Boss); } return (IPresentationEvent)new BossAppeared(val.Boss, ToPhaseVisualId(val.Phase)); } private static int ToPhaseVisualId(BossPhase phase) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Expected I4, but got Unknown return (int)phase; } private static BossVisualActivity ToVisualActivity(BossActivity activity) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected I4, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) return (BossVisualActivity)((int)activity switch { 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, _ => throw new ArgumentOutOfRangeException("activity", activity, "Unknown boss activity."), }); } private static AttackVisualKind ToVisualKind(BossAttackKind kind) { //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 //IL_0013: Unknown result type (might be due to invalid IL or missing references) if ((int)kind != 1) { if ((int)kind == 2) { return (AttackVisualKind)2; } throw new ArgumentOutOfRangeException("kind", kind, "Unknown boss attack kind."); } return (AttackVisualKind)1; } } public sealed class BossPresenter { private readonly IEncounterPresentation _presentation; public BossPresenter(IEncounterPresentation presentation) { _presentation = presentation ?? throw new ArgumentNullException("presentation"); } public void Present(BossSimulation boss, IReadOnlyList domainEvents) { if (boss == null) { throw new ArgumentNullException("boss"); } if (domainEvents == null) { throw new ArgumentNullException("domainEvents"); } for (int i = 0; i < domainEvents.Count; i++) { _presentation.Handle(BossPresentationMapping.ToEvent(domainEvents[i])); } _presentation.Apply(BossPresentationMapping.ToState(boss)); } } public sealed class FalseGodTitle { private const string SpacedInterpunct = " · "; private const string ChineseInterpunct = "·"; private const string JapaneseInterpunct = "・"; private static readonly FalseGodTitle Fallback = new FalseGodTitle("False God", " · "); private static readonly Dictionary ByLanguageCode = new Dictionary(StringComparer.OrdinalIgnoreCase) { ["en"] = Fallback, ["sv"] = new FalseGodTitle("Falsk gud", " · "), ["fr"] = new FalseGodTitle("Faux Dieu", " · "), ["it"] = new FalseGodTitle("Falso Dio", " · "), ["de"] = new FalseGodTitle("Falscher Gott", " · "), ["es"] = new FalseGodTitle("Falso Dios", " · "), ["pt"] = new FalseGodTitle("Falso Deus", " · "), ["ru"] = new FalseGodTitle("Лжебог", " · "), ["pl"] = new FalseGodTitle("Fałszywy Bóg", " · "), ["ja"] = new FalseGodTitle("偽神", "・"), ["ko"] = new FalseGodTitle("거짓 신", " · "), ["zh-CN"] = new FalseGodTitle("伪神", "·"), ["tr"] = new FalseGodTitle("Sahte Tanrı", " · "), ["ar"] = new FalseGodTitle("إله زائف", " · ") }; public string Word { get; } public string Joiner { get; } private FalseGodTitle(string word, string joiner) { Word = word; Joiner = joiner; } public static FalseGodTitle For(string? languageCode) { if (string.IsNullOrEmpty(languageCode)) { return Fallback; } if (ByLanguageCode.TryGetValue(languageCode, out FalseGodTitle value)) { return value; } string text = LanguageOf(languageCode); if (ByLanguageCode.TryGetValue(text, out FalseGodTitle value2)) { return value2; } foreach (KeyValuePair item in ByLanguageCode) { if (string.Equals(LanguageOf(item.Key), text, StringComparison.OrdinalIgnoreCase)) { return item.Value; } } return Fallback; } private static string LanguageOf(string languageCode) { int num = languageCode.IndexOf('-'); if (num <= 0) { return languageCode; } return languageCode.Substring(0, num); } public static string Compose(string word, string joiner, string? creatureName, bool rightToLeft) { if (string.IsNullOrEmpty(creatureName)) { return word; } if (!rightToLeft) { return word + joiner + creatureName; } return creatureName + joiner + word; } public string Compose(string? creatureName, bool rightToLeft = false) { return Compose(Word, Joiner, creatureName, rightToLeft); } } public interface IArenaAtmospherePort : IDisposable { void Warm(); void SetRoomDepth(float startDistance, float endDistance, float afterSeconds = 0f, float overSeconds = 0f); void StartBattleMusic(); void StopBattleMusic(); } public static class ArenaDepth { public const float OpeningStart = 4f; public const float OpeningEnd = 10f; public const float FightStart = 10f; public const float FightEnd = 72f; public const float RevealHoldSeconds = 1f; public const float RevealSeconds = 3f; } public interface IBossVoicePort { void Roar(ArenaWorldPoint at); void Warm(); } public static class WirePresentationMapping { public static PresentationState ToState(BossSnapshot snapshot) { //IL_0043: 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_0055: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown if (snapshot == null) { throw new ArgumentNullException("snapshot"); } float num = ((snapshot.MaxHealth > 0) ? Math.Max(0f, Math.Min(1f, (float)snapshot.Health / (float)snapshot.MaxHealth)) : 0f); return new PresentationState(snapshot.Boss, snapshot.Position, snapshot.PositionHeight, snapshot.Facing, snapshot.PhaseId, ToVisualActivity(snapshot.StateId), snapshot.WeakPointExposed, snapshot.Enraged, num); } public static IPresentationEvent ToEvent(BossInstanceId boss, IBossWireEvent wireEvent) { //IL_0091: 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_009e: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00a5: 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_00b2: 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_00c9: Expected O, but got Unknown //IL_00c9: 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_00d6: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_00e7: 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_00f4: Expected O, but got Unknown //IL_00f4: 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_0102: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown //IL_0117: 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_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_012c: 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_013a: Expected O, but got Unknown //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_0141: Expected O, but got Unknown BossAppearedEvent val = (BossAppearedEvent)(object)((wireEvent is BossAppearedEvent) ? wireEvent : null); if (val == null) { if (!(wireEvent is BossBeganEvent)) { BossAttackTelegraphedEvent val2 = (BossAttackTelegraphedEvent)(object)((wireEvent is BossAttackTelegraphedEvent) ? wireEvent : null); if (val2 == null) { BossAttackCommittedEvent val3 = (BossAttackCommittedEvent)(object)((wireEvent is BossAttackCommittedEvent) ? wireEvent : null); if (val3 == null) { BossPhaseChangedEvent val4 = (BossPhaseChangedEvent)(object)((wireEvent is BossPhaseChangedEvent) ? wireEvent : null); if (val4 == null) { BossWeakPointChangedEvent val5 = (BossWeakPointChangedEvent)(object)((wireEvent is BossWeakPointChangedEvent) ? wireEvent : null); if (val5 == null) { BossDamagedEvent val6 = (BossDamagedEvent)(object)((wireEvent is BossDamagedEvent) ? wireEvent : null); if (val6 == null) { BossRelocatedEvent val7 = (BossRelocatedEvent)(object)((wireEvent is BossRelocatedEvent) ? wireEvent : null); if (val7 == null) { BossEnragedEvent val8 = (BossEnragedEvent)(object)((wireEvent is BossEnragedEvent) ? wireEvent : null); if (val8 == null) { if (!(wireEvent is BossDefeatedEvent)) { if (wireEvent == null) { throw new ArgumentNullException("wireEvent"); } throw new ArgumentOutOfRangeException("wireEvent", ((object)wireEvent).GetType().Name, "No presentation mapping for this boss wire event."); } return (IPresentationEvent)new BossDefeated(boss); } return (IPresentationEvent)new RageChanged(boss, val8.Enraged); } return (IPresentationEvent)new BossMoved(boss, val7.Position, val7.Height); } return (IPresentationEvent)new BossHit(boss, val6.Amount, val6.WeakPointHit); } return (IPresentationEvent)new WeakPointVisibilityChanged(boss, val5.Exposed); } return (IPresentationEvent)new PhaseTransition(boss, val4.PhaseId); } return (IPresentationEvent)new AttackLanded(boss, val3.Attack, ToVisualKind(val3.AttackDefinitionId), val3.AimPoint); } return (IPresentationEvent)new AttackTelegraphStarted(boss, val2.Attack, ToVisualKind(val2.AttackDefinitionId), val2.AimPoint, val2.TelegraphSeconds); } return (IPresentationEvent)new BossRoared(boss); } return (IPresentationEvent)new BossAppeared(boss, val.PhaseId); } public static IPresentationEvent ToEvent(IArenaWireEvent wireEvent) { //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_0023: 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 ArenaMechanismGroupActivatedEvent val = (ArenaMechanismGroupActivatedEvent)(object)((wireEvent is ArenaMechanismGroupActivatedEvent) ? wireEvent : null); if (val == null) { if (!(wireEvent is ArenaExitUnlockedEvent)) { if (wireEvent == null) { throw new ArgumentNullException("wireEvent"); } throw new ArgumentOutOfRangeException("wireEvent", ((object)wireEvent).GetType().Name, "No presentation mapping for this arena wire event."); } return (IPresentationEvent)new ExitOpened(); } return (IPresentationEvent)new MechanismGroupEngaged(val.Group); } public static IReadOnlyList ToEvents(ArenaSnapshot snapshot) { //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_003c: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown if (snapshot == null) { throw new ArgumentNullException("snapshot"); } List list = new List(snapshot.ActiveMechanismGroups.Count + 1); for (int i = 0; i < snapshot.ActiveMechanismGroups.Count; i++) { list.Add((IPresentationEvent)new MechanismGroupEngaged(snapshot.ActiveMechanismGroups[i])); } if (snapshot.ExitUnlocked) { list.Add((IPresentationEvent)new ExitOpened()); } return list; } private static BossVisualActivity ToVisualActivity(int stateId) { return (BossVisualActivity)(stateId switch { 0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5, 6 => 6, 7 => 7, _ => throw new ArgumentOutOfRangeException("stateId", stateId, "Unknown wire boss state id."), }); } private static AttackVisualKind ToVisualKind(int attackDefinitionId) { return (AttackVisualKind)(attackDefinitionId switch { 1 => 1, 2 => 2, _ => throw new ArgumentOutOfRangeException("attackDefinitionId", attackDefinitionId, "Unknown wire attack definition id."), }); } } } namespace FalseGods.Application.Combat { public sealed class ClientHitReporter { private readonly IEncounterChannel _channel; private readonly IMultiplayerSession _session; private readonly ILogger? _logger; private int _sequence; private EncounterId _announced; public ClientHitReporter(IEncounterChannel channel, IMultiplayerSession session, ILogger? logger = null) { _channel = channel ?? throw new ArgumentNullException("channel"); _session = session ?? throw new ArgumentNullException("session"); _logger = logger; } public void ReportHit(EncounterId encounter, float damageCandidate, WorldPosition? attackerPosition = null) { //IL_000e: 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: Expected O, but got Unknown //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_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_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_0064: Unknown result type (might be due to invalid IL or missing references) if (!_session.IsActive) { return; } ClientHitRequest message = new ClientHitRequest(encounter, ++_sequence, damageCandidate, attackerPosition); _channel.Send(EncounterCodec.Encode(message), (MessageDelivery)0, MessageTarget.Host); if (_announced != encounter) { _announced = encounter; ILogger? logger = _logger; if (logger != null) { logger.Log($"Reporting weapon hits to the host for {encounter}; the first is on its way."); } } } } public sealed class CrateCommandFlow : IDisposable { public const int MaxVolleyCount = 64; public const float MaxFireIntervalSeconds = 5f; public const int MaxLoad = 64; public const float MaxPickUpReach = 50f; public const int MaxVolleyTargets = 32; private readonly IEncounterChannel _channel; private readonly IMultiplayerSession _session; public Action? OnDropped { get; set; } public Action? OnThrown { get; set; } public Action, CrateVolleyShape>? OnVolleyFired { get; set; } public Action? OnTaken { get; set; } public Action? OnSetDown { get; set; } public Action? OnDestroyed { get; set; } public Action? OnDestroyRequested { get; set; } private bool IsHosting { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (_session.IsActive) { return (int)_session.Role == 0; } return false; } } public CrateCommandFlow(IEncounterChannel channel, IMultiplayerSession session) { _channel = channel ?? throw new ArgumentNullException("channel"); _session = session ?? throw new ArgumentNullException("session"); _channel.Received += OnReceived; } public void Dispose() { _channel.Received -= OnReceived; } public void BroadcastDropped(ArenaWorldPoint at, CratePileId pile, bool explosive) { //IL_0009: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected I4, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (IsHosting) { Broadcast(EncounterCodec.Encode(new CrateDropped(ToWire(at), (int)((CratePileId)(ref pile)).Kind, ((CratePileId)(ref pile)).Index, explosive))); } } public void BroadcastThrown(ArenaWorldPoint from, ArenaWorldPoint to, float flightSeconds, float apexHeight) { //IL_0009: 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_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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (IsHosting) { Broadcast(EncounterCodec.Encode(new CrateThrown(ToWire(from), ToWire(to), flightSeconds, apexHeight))); } } public void BroadcastVolley(CratePileId pile, IReadOnlyList aims, CrateVolleyShape shape) { //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_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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected I4, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) if (IsHosting) { List list = new List(aims.Count); for (int i = 0; i < aims.Count; i++) { list.Add(new CrateVolleyTarget(ToWire(aims[i].Current), ToWire(aims[i].Lead))); } Broadcast(EncounterCodec.Encode(new CrateVolleyFired((IReadOnlyList)list, (int)((CratePileId)(ref pile)).Kind, ((CratePileId)(ref pile)).Index, shape.Seed, shape.Count, shape.SpreadMinRadius, shape.SpreadMaxRadius, shape.LiftHeight, shape.LiftSeconds, shape.HoldSeconds, shape.FlightSeconds, shape.ApexHeight, shape.LeadShare, shape.FireIntervalSeconds))); } } public void BroadcastTaken(ArenaWorldPoint at, CratePileId pile, int count, float radius) { //IL_0009: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected I4, 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_0025: Unknown result type (might be due to invalid IL or missing references) if (IsHosting) { Broadcast(EncounterCodec.Encode(new CratesTaken(ToWire(at), (int)((CratePileId)(ref pile)).Kind, ((CratePileId)(ref pile)).Index, count, radius))); } } public void BroadcastSetDown(ArenaWorldPoint from, ArenaWorldPoint at, CratePileId pile, int count, int seed, int explosives) { //IL_0009: 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_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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected I4, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (IsHosting) { Broadcast(EncounterCodec.Encode(new CratesSetDown(ToWire(from), ToWire(at), (int)((CratePileId)(ref pile)).Kind, ((CratePileId)(ref pile)).Index, count, seed, explosives))); } } public void ReportDestroyed(int crateId, CrateDeath death) { //IL_0013: 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) if (IsHosting) { BroadcastDestroyed(crateId, death); } else { RequestDestroy(crateId, death); } } public void BroadcastDestroyed(int crateId, CrateDeath death) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected I4, but got Unknown //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (IsHosting) { Broadcast(EncounterCodec.Encode(new CrateDestroyed(crateId, (int)death))); } } public void RequestDestroy(int crateId, CrateDeath death) { //IL_0013: 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: Expected I4, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (_session.IsActive && (int)_session.Role != 0) { _channel.Send(EncounterCodec.Encode(new CrateDestroyRequested(crateId, (int)death)), (MessageDelivery)0, MessageTarget.Host); } } private void Broadcast(EncodedPayload payload) { //IL_0006: 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) _channel.Send(payload, (MessageDelivery)0, MessageTarget.AllClients); } private void OnReceived(SessionPeerId sender, EncodedPayload payload) { //IL_0000: 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_006b: 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_002e: 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_013b: 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_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: 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_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_0196: 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_036e: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) DecodedMessage decodedMessage; try { decodedMessage = EncounterCodec.Decode(payload); } catch (Exception) { return; } object value = decodedMessage.Value; CrateDestroyRequested val = (CrateDestroyRequested)((value is CrateDestroyRequested) ? value : null); if (val != null) { if (IsHosting && sender != _session.HostPeer && IsKnownDeath(val.Death)) { OnDestroyRequested?.Invoke(val.CrateId, (CrateDeath)val.Death); } } else { if (sender != _session.HostPeer || IsHosting) { return; } object value2 = decodedMessage.Value; CrateDropped val2 = (CrateDropped)((value2 is CrateDropped) ? value2 : null); if (val2 == null) { CrateThrown val3 = (CrateThrown)((value2 is CrateThrown) ? value2 : null); if (val3 == null) { CratesTaken val4 = (CratesTaken)((value2 is CratesTaken) ? value2 : null); if (val4 == null) { CrateDestroyed val5 = (CrateDestroyed)((value2 is CrateDestroyed) ? value2 : null); if (val5 == null) { CratesSetDown val6 = (CratesSetDown)((value2 is CratesSetDown) ? value2 : null); if (val6 == null) { CrateVolleyFired val7 = (CrateVolleyFired)((value2 is CrateVolleyFired) ? value2 : null); if (val7 != null) { CrateVolleyFired val8 = val7; CratePileId arg = default(CratePileId); if (IsSaneVolley(val8) && CratePileId.TryFrom(val8.PileKind, val8.PileIndex, ref arg)) { OnVolleyFired?.Invoke(arg, ToAims(val8.Targets), new CrateVolleyShape(val8.Seed, val8.Count, val8.SpreadMinRadius, val8.SpreadMaxRadius, val8.LiftHeight, val8.LiftSeconds, val8.HoldSeconds, val8.FlightSeconds, val8.ApexHeight, val8.LeadShare, val8.FireIntervalSeconds)); } } } else { CratesSetDown val9 = val6; CratePileId arg2 = default(CratePileId); if (IsFinite(val9.From) && IsFinite(val9.At) && val9.Count > 0 && val9.Count <= 64 && val9.Explosives >= 0 && val9.Explosives <= val9.Count && CratePileId.TryFrom(val9.PileKind, val9.PileIndex, ref arg2)) { OnSetDown?.Invoke(FromWire(val9.From), FromWire(val9.At), arg2, val9.Count, val9.Seed, val9.Explosives); } } } else { CrateDestroyed val10 = val5; if (IsKnownDeath(val10.Death)) { OnDestroyed?.Invoke(val10.CrateId, (CrateDeath)val10.Death); } } } else { CratesTaken val11 = val4; CratePileId arg3 = default(CratePileId); if (IsFinite(val11.At) && val11.Count > 0 && val11.Count <= 64 && IsPositive(val11.Radius) && val11.Radius <= 50f && CratePileId.TryFrom(val11.PileKind, val11.PileIndex, ref arg3)) { OnTaken?.Invoke(FromWire(val11.At), arg3, val11.Count, val11.Radius); } } } else { CrateThrown val12 = val3; if (IsFinite(val12.From) && IsFinite(val12.To) && IsPositive(val12.FlightSeconds) && IsFinite(val12.ApexHeight)) { OnThrown?.Invoke(FromWire(val12.From), FromWire(val12.To), val12.FlightSeconds, val12.ApexHeight); } } } else { CrateDropped val13 = val2; CratePileId arg4 = default(CratePileId); if (IsFinite(val13.At) && CratePileId.TryFrom(val13.PileKind, val13.PileIndex, ref arg4)) { OnDropped?.Invoke(FromWire(val13.At), arg4, val13.Explosive); } } } } private static IReadOnlyList ToAims(IReadOnlyList targets) { //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_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) List list = new List(targets.Count); for (int i = 0; i < targets.Count; i++) { list.Add(new CrateVolleyAim(FromWire(targets[i].Current), FromWire(targets[i].Lead))); } return list; } private static bool IsSaneVolley(CrateVolleyFired v) { if (HasSaneTargets(v.Targets) && v.Count > 0 && v.Count <= 64 && IsFinite(v.SpreadMinRadius) && IsFinite(v.SpreadMaxRadius) && v.SpreadMinRadius >= 0f && v.SpreadMaxRadius >= v.SpreadMinRadius && IsFinite(v.LiftHeight) && IsPositive(v.LiftSeconds) && IsFinite(v.HoldSeconds) && v.HoldSeconds >= 0f && IsPositive(v.FlightSeconds) && IsFinite(v.ApexHeight) && IsFinite(v.LeadShare) && v.LeadShare >= 0f && v.LeadShare <= 1f && IsFinite(v.FireIntervalSeconds) && v.FireIntervalSeconds >= 0f) { return v.FireIntervalSeconds <= 5f; } return false; } private static bool HasSaneTargets(IReadOnlyList targets) { //IL_0022: 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) if (targets == null || targets.Count == 0 || targets.Count > 32) { return false; } for (int i = 0; i < targets.Count; i++) { if (!IsFinite(targets[i].Current) || !IsFinite(targets[i].Lead)) { return false; } } return true; } private static bool IsKnownDeath(int death) { if (death != 0) { return death == 1; } return true; } private static bool IsPositive(float value) { if (IsFinite(value)) { return value > 0f; } return false; } private static bool IsFinite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static bool IsFinite(WorldPosition p) { if (IsFinite(((WorldPosition)(ref p)).X) && IsFinite(((WorldPosition)(ref p)).Y)) { return IsFinite(((WorldPosition)(ref p)).Z); } return false; } private static WorldPosition ToWire(ArenaWorldPoint p) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) return new WorldPosition(((ArenaWorldPoint)(ref p)).X, ((ArenaWorldPoint)(ref p)).Y, ((ArenaWorldPoint)(ref p)).Z); } private static ArenaWorldPoint FromWire(WorldPosition p) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) return new ArenaWorldPoint(((WorldPosition)(ref p)).X, ((WorldPosition)(ref p)).Y, ((WorldPosition)(ref p)).Z); } } public readonly struct CrateVolleyAim { public ArenaWorldPoint Current { get; } public ArenaWorldPoint Lead { get; } public CrateVolleyAim(ArenaWorldPoint current, ArenaWorldPoint lead) { //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) Current = current; Lead = lead; } } public readonly struct CrateVolleyShape { public int Seed { get; } public int Count { get; } public float SpreadMinRadius { get; } public float SpreadMaxRadius { get; } public float LiftHeight { get; } public float LiftSeconds { get; } public float HoldSeconds { get; } public float FlightSeconds { get; } public float ApexHeight { get; } public float LeadShare { get; } public float FireIntervalSeconds { get; } public CrateVolleyShape(int seed, int count, float spreadMinRadius, float spreadMaxRadius, float liftHeight, float liftSeconds, float holdSeconds, float flightSeconds, float apexHeight, float leadShare, float fireIntervalSeconds = 0f) { Seed = seed; Count = count; SpreadMinRadius = spreadMinRadius; SpreadMaxRadius = spreadMaxRadius; LiftHeight = liftHeight; LiftSeconds = liftSeconds; HoldSeconds = holdSeconds; FlightSeconds = flightSeconds; ApexHeight = apexHeight; LeadShare = leadShare; FireIntervalSeconds = fireIntervalSeconds; } } public sealed class HostHitIntake : IDisposable { private readonly IEncounterChannel _channel; private readonly IPlayerRoster _roster; private readonly EncounterId _encounter; private readonly float _maxDamagePerHit; private readonly Action _applyDamage; private readonly Action? _log; public HostHitIntake(IEncounterChannel channel, IPlayerRoster roster, EncounterId encounter, float maxDamagePerHit, Action applyDamage, Action? log = null) { //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) _channel = channel ?? throw new ArgumentNullException("channel"); _roster = roster ?? throw new ArgumentNullException("roster"); _applyDamage = applyDamage ?? throw new ArgumentNullException("applyDamage"); _encounter = encounter; _maxDamagePerHit = maxDamagePerHit; _log = log; _channel.Received += OnReceived; } public void Dispose() { _channel.Received -= OnReceived; } private void OnReceived(SessionPeerId sender, EncodedPayload payload) { //IL_0000: 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_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_004c: 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_00a6: Unknown result type (might be due to invalid IL or missing references) DecodedMessage decodedMessage; try { decodedMessage = EncounterCodec.Decode(payload); } catch (Exception) { return; } object value = decodedMessage.Value; ClientHitRequest val = (ClientHitRequest)((value is ClientHitRequest) ? value : null); if (val == null || val.Encounter != _encounter) { return; } if (!IsMember(sender)) { _log?.Invoke($"Dropped a hit request from non-member {sender} for {_encounter}."); return; } float damageCandidate = val.DamageCandidate; if (!float.IsNaN(damageCandidate) && !float.IsInfinity(damageCandidate) && !(damageCandidate <= 0f)) { float num = Math.Min(damageCandidate, _maxDamagePerHit); _log?.Invoke($"Client {sender} hit seq={val.RequestSequence}: candidate {damageCandidate:0.##} " + $"-> applying {num:0.##} (host clamps; the simulation decides the result)."); _applyDamage(num); } } private bool IsMember(SessionPeerId sender) { //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) IReadOnlyList members = _roster.Members; for (int i = 0; i < members.Count; i++) { if (members[i] == sender) { return true; } } return false; } } public interface IBattlefieldCleanupPort { int SweepCorpses(ArenaWorldPoint around, float radius); } public static class BattlefieldSweep { public const float ArenaReach = 120f; } public readonly record struct ArmPlacement(ArenaWorldPoint BossAt, SimVector2 BossFacing, float SideDistance, float ForwardOffset, float Lift, float Scale); public interface IBossArmPort { int Raised { get; } void Raise(int count, ArmPlacement placement); void Follow(ArmPlacement placement); void LowerAll(); void Adopt(int count); void Release(); } public static class RageArms { public const int Count = 2; public const float SideDistance = 3.1f; public const float ForwardOffset = 1f; public const float Lift = 1.5f; public const float Scale = 1.5f; } public interface IBossDamageSink { void ApplyWeaponDamage(float amount); } public interface IBossPresencePort { void Declare(); void Withdraw(); void ShowHealthBar(); void ReportHealth(float fraction); void HideHealthBar(); } public interface IBossRewardPort { void DropReward(ArenaWorldPoint at); } public interface ICarrierPort { int Working { get; } int Carried { get; } float ObservedWalkSpeed { get; } void Warm(ArenaWorldPoint at); void Advance(float deltaSeconds, int wanted, int loadPerCarrier, float replaceAfterSeconds, IReadOnlyList sources, ArenaWorldPoint deliverTo, CratePileId deliverPile); void DismissAll(); void Disband(); } public interface IDamagePort { void ApplyDamage(ParticipantId target, int amount); } public interface IMinionSpawnPort { int Alive { get; } int SizeOf(MinionBandId band); void Summon(MinionBandId band, IReadOnlyList places); void DespawnAll(); } public readonly struct PlayerAim { public int Index { get; } public SimVector2 Position { get; } public float Height { get; } public SimVector2 Velocity { get; } public bool VelocityKnown { get; } public PlayerAim(int index, SimVector2 position, float height, SimVector2 velocity, bool velocityKnown) { //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_0016: 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) Index = index; Position = position; Height = height; Velocity = velocity; VelocityKnown = velocityKnown; } } public readonly struct PlayerMotion { public SimVector2 Position { get; } public SimVector2 Velocity { get; } public bool Known { get; } public PlayerMotion(SimVector2 position, SimVector2 velocity) { //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) Position = position; Velocity = velocity; Known = true; } } public interface IPlayerMotionPort { PlayerMotion TryReadLocalPlayer(); void ReadPlayersToThrowAt(IList into); } public interface IThrownCrateImpact { bool Contact(ArenaWorldPoint at); bool Splash(ArenaWorldPoint at); } public interface IThrownCratePort { Action? Died { get; set; } int InFlight { get; } int Resting { get; } bool Prepare(); bool Throw(ArenaWorldPoint from, ArenaWorldPoint to, float flightSeconds, float apexHeight); bool ThrowExplosive(ArenaWorldPoint from, ArenaWorldPoint to, float flightSeconds, float apexHeight, Action whenItGoesOff); bool Drop(ArenaWorldPoint at, CratePileId pile, bool explosive = false); void Clear(); int LaunchVolley(CratePileId pile, IReadOnlyList aims, CrateVolleyShape shape); int TossRing(ArenaWorldPoint from, ArenaWorldPoint at, CratePileId pile, int count, int seed, int explosives); int RestingOn(CratePileId pile); int TakeFrom(CratePileId pile, int count, ArenaWorldPoint near, float radius); bool TryFindNearestResting(CratePileId pile, ArenaWorldPoint near, out ArenaWorldPoint at, IReadOnlyList spokenFor = null, float keepApart = 0f); bool Destroy(int crateId, CrateDeath death); void Advance(float deltaSeconds); void Release(); } public static class WeaponDamage { public static int ToSimAmount(float amount) { if (float.IsNaN(amount) || float.IsInfinity(amount) || amount <= 0f) { return 0; } if (amount >= 2.1474836E+09f) { return int.MaxValue; } return Math.Max(1, (int)Math.Round(amount, MidpointRounding.AwayFromZero)); } } } namespace FalseGods.Application.Arena { public sealed class ArenaLevelFlow : IDisposable { private readonly IEncounterChannel _channel; private readonly IMultiplayerSession _session; private readonly IPlayerRoster _roster; private readonly HashSet _informedPeers = new HashSet(); private ArenaLevelDeclared? _declaration; public Action? OnDeclared { get; set; } public Action? OnRequested { get; set; } public ArenaLevelDeclared? Declaration => _declaration; private bool IsHosting { get { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (_session.IsActive) { return (int)_session.Role == 0; } return false; } } public ArenaLevelFlow(IEncounterChannel channel, IMultiplayerSession session, IPlayerRoster roster) { _channel = channel ?? throw new ArgumentNullException("channel"); _session = session ?? throw new ArgumentNullException("session"); _roster = roster ?? throw new ArgumentNullException("roster"); _channel.Received += OnReceived; } public void Dispose() { _channel.Received -= OnReceived; } public void Declare(ArenaLevelId level, bool isBossArena = true) { //IL_0009: 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: Expected O, but got Unknown if (IsHosting) { ArenaLevelDeclared val = (_declaration = new ArenaLevelDeclared(level, isBossArena)); _informedPeers.Clear(); OnDeclared?.Invoke(val); Broadcast(val); } } public void Request(ArenaLevelId level) { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0027: 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 (_session.IsActive && (int)_session.Role != 0) { _channel.Send(EncounterCodec.Encode(new ArenaLevelRequested(level)), (MessageDelivery)0, MessageTarget.Host); } } public void Tick() { //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_0053: 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_006c: 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_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_0092: Unknown result type (might be due to invalid IL or missing references) ArenaLevelDeclared declaration = _declaration; if (declaration == null || !IsHosting) { return; } IReadOnlyList members = _roster.Members; _informedPeers.RemoveWhere((SessionPeerId peer) => !Contains(members, peer)); for (int num = 0; num < members.Count; num++) { SessionPeerId val = members[num]; if (!(val == _session.LocalPeer) && !_informedPeers.Contains(val)) { _channel.Send(EncounterCodec.Encode(declaration), (MessageDelivery)0, MessageTarget.ToPeer(val)); _informedPeers.Add(val); } } } private void Broadcast(ArenaLevelDeclared declaration) { //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) _channel.Send(EncounterCodec.Encode(declaration), (MessageDelivery)0, MessageTarget.AllClients); } private void OnReceived(SessionPeerId sender, EncodedPayload payload) { //IL_0000: 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_0030: 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) DecodedMessage decodedMessage; try { decodedMessage = EncounterCodec.Decode(payload); } catch (Exception) { return; } object value = decodedMessage.Value; ArenaLevelDeclared val = (ArenaLevelDeclared)((value is ArenaLevelDeclared) ? value : null); if (val == null) { ArenaLevelRequested val2 = (ArenaLevelRequested)((value is ArenaLevelRequested) ? value : null); if (val2 != null && IsHosting && IsMember(sender)) { OnRequested?.Invoke(val2); } } else if (sender == _session.HostPeer && !IsHosting) { _declaration = val; OnDeclared?.Invoke(val); } } private bool IsMember(SessionPeerId peer) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return Contains(_roster.Members, peer); } private static bool Contains(IReadOnlyList peers, SessionPeerId peer) { //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) for (int i = 0; i < peers.Count; i++) { if (peers[i] == peer) { return true; } } return false; } } public static class ArenaMarkerKinds { public const string Player = "Player"; public const string Boss = "Enemy"; } public static class BossRoomContent { public const string AnchorGroupPath = "GameplayRoot/BossAnchors"; public const string BodyPath = "GameplayRoot/BossBody"; public const string MinionSpawnGroupPath = "GameplayRoot/MinionSpawns"; public const string CrateSourceGroupPath = "GameplayRoot/CrateSources"; public const string StartTriggerPath = "GameplayRoot/StartTrigger"; public const string ExitBlastPath = "GameplayRoot/ExitBlast"; public const string RewardDropPath = "GameplayRoot/RewardDrop"; public const string CratePileGroupPath = "GameplayRoot/CratePiles"; } public static class RockDecoration { public const string ParentPath = "VisualRoot"; public const string ChildNamePrefix = "Rock_"; public const string MaterialName = "Rocks_Caves"; public const int SubMaterialIndex = 0; } public static class WallShellDecoration { public const string Path = "VisualRoot/CaveShell"; public const string WalkablePath = "VisualRoot/CaveWalkable"; public static readonly IReadOnlyList SurfaceRules = new SubmeshMaterialRule[5] { new SubmeshMaterialRule("FG_WallBot", "CaveWallBot"), new SubmeshMaterialRule("FG_WallMid", "CaveWallMid"), new SubmeshMaterialRule("FG_WallTop", "CaveWallTop"), new SubmeshMaterialRule("FG_Floor", "CaveFloor"), new SubmeshMaterialRule("FG_Ceiling", "CaveCeilingOther") }; } public static class VanillaPropDecoration { public const string ParentPath = "VisualRoot/VanillaProps"; public const string CaveBossRoomKey = "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveCousinNew.prefab"; public static readonly IReadOnlyList Props = new VanillaPropClone[9] { new VanillaPropClone("VisualRoot/VanillaProps", "Prop_MudPool", "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveCousinNew.prefab", "Enemies/CousinSludgePool", new string[1] { "CousinPosition" }, new string[2] { "CousinPool", "ApplyDamageInsideCollider" }, "GeometryNoNavMesh", new string[1] { "PoolBlocker" }), new VanillaPropClone("VisualRoot/VanillaProps", "Prop_Platshroom", "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveCousinNew.prefab", "Decorations/Mushrooms/Platshroom (2)", NoNames, NoNames, "", NoNames), new VanillaPropClone("VisualRoot/VanillaProps", "Prop_MushroomDecor", "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveCousinNew.prefab", "Decorations/Mushrooms/Platshroom (Decoration)", NoNames, NoNames, "", NoNames), new VanillaPropClone("VisualRoot/VanillaProps", "Prop_Tickshroom", "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveCousinNew.prefab", "Decorations/Mushrooms/Tickshroom 1 (1)", NoNames, NoNames, "GeometryNoNavMesh", NoNames), new VanillaPropClone("VisualRoot/VanillaProps", "Prop_CaveRock1", "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveCousinNew.prefab", "Decorations/Rocks/CaveRock1 (5)", NoNames, NoNames, "", NoNames), new VanillaPropClone("VisualRoot/VanillaProps", "Prop_CaveRock2", "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveCousinNew.prefab", "Decorations/Rocks/CaveRock2 (24)", NoNames, NoNames, "", NoNames), new VanillaPropClone("VisualRoot/VanillaProps", "Prop_CavePath", "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveCousinNew.prefab", "Decorations/Paths/CavePatch (30)", NoNames, NoNames, "", NoNames), new VanillaPropClone("VisualRoot/VanillaProps", "Prop_Stalagmite", "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveCousinNew.prefab", "Decorations/Stalagmites/Stalagmite", NoNames, NoNames, "", NoNames), new VanillaPropClone("VisualRoot/VanillaProps", "Prop_ExitRoom", "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveEndRoom1.prefab", "", new string[3] { "HiddenChest", "HayBase", "HayBase (1)" }, new string[1] { "Connector" }, "", NoNames, PointExitAtSafeArea: true) }; public const string CaveEndRoomKey = "Assets/_Core/Prefabs/LevelGeneration/Chunks/Caves/CaveEndRoom1.prefab"; public const string WholeRoom = ""; public const string OffTheNavigationLayers = "GeometryNoNavMesh"; public const string KeepTheDonorsLayer = ""; private static readonly IReadOnlyList NoNames = new string[0]; public const string MudPoolHazardVolumeName = "PoolBlocker"; public const int MudPoolHazardDamage = 5; public const float MudPoolHazardInterval = 0.25f; } public enum ArenaLoadStage { NotLoaded, Prepared, Realized } public sealed record ArenaPrepareResult(bool Success, string? FailureReason, ArenaContentArtifact? Artifact) { public static ArenaPrepareResult Failed(string reason) { return new ArenaPrepareResult(Success: false, reason, null); } } public sealed record LoadedArena(ArenaWorldPoint Origin, ArenaWorldPoint PlayerSpawn, ArenaWorldPoint BossSpawn, int NavWalkableNodes, IReadOnlyList BossAnchors, float BossSize, IReadOnlyList MinionSpawns, IReadOnlyList CrateSources, IReadOnlyList CratePiles, ArenaWorldPoint? StartTrigger, float StartTriggerRadius, ArenaWorldPoint? ExitBlast, ArenaWorldPoint? RewardDrop); public sealed record ArenaRealizeResult(bool Success, string? FailureReason, ArenaManifest? Manifest, LoadedArena? Arena) { public static ArenaRealizeResult Failed(string reason) { return new ArenaRealizeResult(Success: false, reason, null, null); } } public sealed class ArenaLoadFlow { private const float PositionEpsilon = 0.001f; private const float RotationEpsilonDegrees = 0.05f; private const float ScaleEpsilon = 0.001f; private readonly IArenaAssetProvider _assets; private readonly IArenaRealization _realization; private readonly INavigationPort _navigation; private readonly IVanillaAssetProvider _vanillaAssets; private ContentHash _contentHash; public ArenaLoadStage Stage { get; private set; } public ArenaContentArtifact? Artifact { get; private set; } public ArenaManifest? Manifest { get; private set; } public LoadedArena? Arena { get; private set; } public ArenaLoadFlow(IArenaAssetProvider assets, IArenaRealization realization, INavigationPort navigation, IVanillaAssetProvider vanillaAssets) { _assets = assets ?? throw new ArgumentNullException("assets"); _realization = realization ?? throw new ArgumentNullException("realization"); _navigation = navigation ?? throw new ArgumentNullException("navigation"); _vanillaAssets = vanillaAssets ?? throw new ArgumentNullException("vanillaAssets"); } public ArenaPrepareResult Prepare() { //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_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) if (Stage != ArenaLoadStage.NotLoaded) { throw new InvalidOperationException($"Prepare called at stage {Stage}; the flow loads once per encounter."); } ArenaAssetLoadResult val = _assets.Load(); if (!val.Success || val.ArtifactText == null) { _assets.Release(); return ArenaPrepareResult.Failed("arena content unavailable: " + (val.Error ?? "no artifact text")); } ArenaContentArtifact val2; ContentHash contentHash; try { val2 = ArenaContentArtifact.Parse(val.ArtifactText); contentHash = val2.ComputeContentHash(); } catch (Exception ex) { _assets.Release(); return ArenaPrepareResult.Failed("arena artifact invalid: " + ex.Message); } Artifact = val2; _contentHash = contentHash; Stage = ArenaLoadStage.Prepared; return new ArenaPrepareResult(Success: true, null, val2); } public ArenaRealizeResult Realize(ArenaWorldPoint origin) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Expected O, but got Unknown //IL_0316: 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_0320: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) if (Stage != ArenaLoadStage.Prepared) { throw new InvalidOperationException($"Realize called at stage {Stage}; call Prepare first, once."); } ArenaContentArtifact artifact = Artifact; string text = FindMarkerPath(artifact, "Player"); string text2 = FindMarkerPath(artifact, "Enemy"); if (text == null || text2 == null) { return Fail("authored parity map has no '" + ((text == null) ? "Player" : "Enemy") + "' marker"); } List list = new List(artifact.Parity.Count); foreach (ArenaParityNode item in artifact.Parity) { list.Add(item.Path); } ArenaRealizationResult val = _realization.Realize(origin, (IReadOnlyList)list, (IReadOnlyList)new string[6] { text, text2, "GameplayRoot/BossBody", "GameplayRoot/StartTrigger", "GameplayRoot/ExitBlast", "GameplayRoot/RewardDrop" }, (IReadOnlyList)new string[4] { "GameplayRoot/BossAnchors", "GameplayRoot/MinionSpawns", "GameplayRoot/CrateSources", "GameplayRoot/CratePiles" }); if (!val.Success) { return Fail("arena realization failed: " + (val.Error ?? "unknown")); } string text3 = CompareParity(artifact.Parity, val.ParityNodes); if (text3 != null) { return Fail("realized arena diverges from authored content: " + text3); } RealizedMarker val2 = FindMarker(val.Markers, text); RealizedMarker val3 = FindMarker(val.Markers, text2); if (val2 == null || val3 == null) { return Fail("realized arena is missing marker '" + ((val2 == null) ? text : text2) + "'"); } string error; IReadOnlyList readOnlyList = BuildMaterialBorrowRequests(artifact, out error); if (error != null) { return Fail(error); } MaterialBorrowResult materialBorrowResult = _vanillaAssets.Resolve(readOnlyList); if (!materialBorrowResult.Success) { return Fail("arena material borrow failed: " + (materialBorrowResult.Error ?? "unknown")); } MaterialBorrowResult materialBorrowResult2 = PaintDecorationRocks(readOnlyList); if (!materialBorrowResult2.Success) { return Fail("arena decoration paint failed: " + (materialBorrowResult2.Error ?? "unknown")); } MaterialBorrowResult materialBorrowResult3 = PaintWallShell(readOnlyList); if (!materialBorrowResult3.Success) { return Fail("arena wall-shell paint failed: " + (materialBorrowResult3.Error ?? "unknown")); } VanillaPropResult vanillaPropResult = CloneVanillaProps(); if (!vanillaPropResult.Success) { return Fail("arena vanilla scenery failed: " + (vanillaPropResult.Error ?? "unknown")); } NavigationApplyResult navigationApplyResult = _navigation.Apply(); if (!navigationApplyResult.Success) { return Fail("arena navigation failed: " + (navigationApplyResult.Error ?? "unknown")); } Manifest = new ArenaManifest(artifact.Definition.ArenaId, artifact.Definition.ArenaVersion, artifact.SchemaVersion, _contentHash, ((ProtocolVersion)(ref ProtocolVersion.Current)).Value, artifact.BundleVersion); ArenaWorldPoint worldPosition = val2.WorldPosition; ArenaWorldPoint worldPosition2 = val3.WorldPosition; int walkableNodesApplied = navigationApplyResult.WalkableNodesApplied; IReadOnlyList bossAnchors = CollectGroup(val.Markers, "GameplayRoot/BossAnchors"); float bossSize = ReadBossSize(val.Markers); IReadOnlyList minionSpawns = CollectGroup(val.Markers, "GameplayRoot/MinionSpawns"); IReadOnlyList crateSources = CollectGroup(val.Markers, "GameplayRoot/CrateSources"); IReadOnlyList cratePiles = CollectGroup(val.Markers, "GameplayRoot/CratePiles"); float radius; ArenaWorldPoint? startTrigger = ReadStartTrigger(val.Markers, out radius); float startTriggerRadius = radius; RealizedMarker? obj = FindMarker(val.Markers, "GameplayRoot/ExitBlast"); ArenaWorldPoint? exitBlast = ((obj != null) ? new ArenaWorldPoint?(obj.WorldPosition) : ((ArenaWorldPoint?)null)); RealizedMarker? obj2 = FindMarker(val.Markers, "GameplayRoot/RewardDrop"); Arena = new LoadedArena(origin, worldPosition, worldPosition2, walkableNodesApplied, bossAnchors, bossSize, minionSpawns, crateSources, cratePiles, startTrigger, startTriggerRadius, exitBlast, (obj2 != null) ? new ArenaWorldPoint?(obj2.WorldPosition) : ((ArenaWorldPoint?)null)); Stage = ArenaLoadStage.Realized; return new ArenaRealizeResult(Success: true, null, Manifest, Arena); } public void Teardown() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) _navigation.Remove(); _realization.Teardown(); _vanillaAssets.Release(); _assets.Release(); Artifact = null; Manifest = null; Arena = null; _contentHash = default(ContentHash); Stage = ArenaLoadStage.NotLoaded; } private ArenaRealizeResult Fail(string reason) { Teardown(); return ArenaRealizeResult.Failed(reason); } private MaterialBorrowResult PaintDecorationRocks(IReadOnlyList borrowRequests) { if (borrowRequests.Count == 0) { return MaterialBorrowResult.Resolved(0); } string carrierGuid = borrowRequests[0].CarrierGuid; return _vanillaAssets.PaintByConvention(new MaterialConventionPaint("VisualRoot", "Rock_", 0, carrierGuid, "Rocks_Caves")); } private VanillaPropResult CloneVanillaProps() { int num = 0; foreach (VanillaPropClone prop in VanillaPropDecoration.Props) { VanillaPropResult vanillaPropResult = _vanillaAssets.CloneProps(prop); if (!vanillaPropResult.Success) { return vanillaPropResult; } num += vanillaPropResult.Cloned; } return VanillaPropResult.Placed(num); } private MaterialBorrowResult PaintWallShell(IReadOnlyList borrowRequests) { if (borrowRequests.Count == 0) { return MaterialBorrowResult.Resolved(0); } string carrierGuid = borrowRequests[0].CarrierGuid; MaterialBorrowResult materialBorrowResult = _vanillaAssets.PaintSubmeshes(new SubmeshBorrow("VisualRoot/CaveShell", carrierGuid, WallShellDecoration.SurfaceRules)); if (!materialBorrowResult.Success) { return materialBorrowResult; } MaterialBorrowResult materialBorrowResult2 = _vanillaAssets.PaintSubmeshes(new SubmeshBorrow("VisualRoot/CaveWalkable", carrierGuid, WallShellDecoration.SurfaceRules)); if (!materialBorrowResult2.Success) { return materialBorrowResult2; } return MaterialBorrowResult.Resolved(materialBorrowResult.Applied + materialBorrowResult2.Applied); } private static IReadOnlyList BuildMaterialBorrowRequests(ArenaContentArtifact artifact, out string? error) { //IL_001d: 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_008d: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = new Dictionary(); foreach (MaterialBorrowPlacement materialBorrowPlacement in artifact.MaterialBorrowPlacements) { dictionary[materialBorrowPlacement.BorrowMarkerId] = materialBorrowPlacement.TargetPath; } List list = new List(artifact.Definition.MaterialBorrows.Count); foreach (MaterialBorrowDefinition materialBorrow in artifact.Definition.MaterialBorrows) { if (!dictionary.TryGetValue(materialBorrow.MarkerId, out var value)) { error = $"material borrow {materialBorrow.MarkerId} has no target-path placement in the artifact"; return Array.Empty(); } list.Add(new MaterialBorrowRequest(value, materialBorrow.TargetSubMaterialIndex, materialBorrow.CarrierGuid, materialBorrow.MaterialName)); } error = null; return list; } private static IReadOnlyList CollectGroup(IReadOnlyList markers, string groupPath) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) string value = groupPath + "/"; List list = new List(); for (int i = 0; i < markers.Count; i++) { if (markers[i].Path.StartsWith(value, StringComparison.Ordinal)) { list.Add(markers[i].WorldPosition); } } return list; } private static float ReadBossSize(IReadOnlyList markers) { //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) RealizedMarker val = FindMarker(markers, "GameplayRoot/BossBody"); if (val == null) { return 0f; } ArenaWorldPoint localScale = val.LocalScale; if (((ArenaWorldPoint)(ref localScale)).X <= 0f || Math.Abs(((ArenaWorldPoint)(ref localScale)).X - ((ArenaWorldPoint)(ref localScale)).Y) > 0.001f || Math.Abs(((ArenaWorldPoint)(ref localScale)).X - ((ArenaWorldPoint)(ref localScale)).Z) > 0.001f) { return 0f; } return ((ArenaWorldPoint)(ref localScale)).X; } private static ArenaWorldPoint? ReadStartTrigger(IReadOnlyList markers, out float radius) { //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_0085: Unknown result type (might be due to invalid IL or missing references) radius = 0f; RealizedMarker val = FindMarker(markers, "GameplayRoot/StartTrigger"); if (val == null) { return null; } ArenaWorldPoint localScale = val.LocalScale; if (((ArenaWorldPoint)(ref localScale)).X <= 0f || Math.Abs(((ArenaWorldPoint)(ref localScale)).X - ((ArenaWorldPoint)(ref localScale)).Y) > 0.001f || Math.Abs(((ArenaWorldPoint)(ref localScale)).X - ((ArenaWorldPoint)(ref localScale)).Z) > 0.001f) { return null; } radius = ((ArenaWorldPoint)(ref localScale)).X * 0.5f; return val.WorldPosition; } private static string? FindMarkerPath(ArenaContentArtifact artifact, string kind) { foreach (ArenaParityNode item in artifact.Parity) { if (string.Equals(item.Kind, kind, StringComparison.Ordinal)) { return item.Path; } } return null; } private static RealizedMarker? FindMarker(IReadOnlyList markers, string path) { foreach (RealizedMarker marker in markers) { if (string.Equals(marker.Path, path, StringComparison.Ordinal)) { return marker; } } return null; } private static string? CompareParity(IReadOnlyList authored, IReadOnlyList realized) { //IL_0085: 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_009f: 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_00b9: 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) Dictionary dictionary = new Dictionary(StringComparer.Ordinal); foreach (RealizedParityNode item in realized) { dictionary[item.Path] = item; } foreach (ArenaParityNode item2 in authored) { if (!dictionary.TryGetValue(item2.Path, out var value)) { return "'" + item2.Path + "' missing at runtime"; } float num = Distance(item2.LocalTransform.Position, value.LocalPosition); float num2 = AngleDegrees(item2.LocalTransform.Rotation, value.LocalRotation); float num3 = Distance(item2.LocalTransform.Scale, value.LocalScale); if (num > 0.001f || num2 > 0.05f || num3 > 0.001f) { return $"'{item2.Path}' off by pos {num:0.####} rot {num2:0.####}deg scale {num3:0.####}"; } } return null; } private static float Distance(Vector3 authored, ArenaWorldPoint actual) { float num = ((Vector3)(ref authored)).X - ((ArenaWorldPoint)(ref actual)).X; float num2 = ((Vector3)(ref authored)).Y - ((ArenaWorldPoint)(ref actual)).Y; float num3 = ((Vector3)(ref authored)).Z - ((ArenaWorldPoint)(ref actual)).Z; return (float)Math.Sqrt(num * num + num2 * num2 + num3 * num3); } private static float AngleDegrees(Quaternion authored, ArenaRotation actual) { float num = ((Quaternion)(ref authored)).X * ((ArenaRotation)(ref actual)).X + ((Quaternion)(ref authored)).Y * ((ArenaRotation)(ref actual)).Y + ((Quaternion)(ref authored)).Z * ((ArenaRotation)(ref actual)).Z + ((Quaternion)(ref authored)).W * ((ArenaRotation)(ref actual)).W; double d = Math.Min(1.0, Math.Abs((double)num)); return (float)(2.0 * Math.Acos(d) * (180.0 / Math.PI)); } } public static class ArenaPlacement { private const float IdentityEpsilon = 0.0001f; public static ArenaWorldPoint OriginForPlayerFoot(ArenaContentArtifact artifact, ArenaWorldPoint playerFoot) { //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_0047: Unknown result type (might be due to invalid IL or missing references) if (artifact == null) { throw new ArgumentNullException("artifact"); } ArenaWorldPoint val = RootRelativeMarkerOffset(artifact, "Player"); return new ArenaWorldPoint(((ArenaWorldPoint)(ref playerFoot)).X - ((ArenaWorldPoint)(ref val)).X, ((ArenaWorldPoint)(ref playerFoot)).Y - ((ArenaWorldPoint)(ref val)).Y, ((ArenaWorldPoint)(ref playerFoot)).Z - ((ArenaWorldPoint)(ref val)).Z); } private static ArenaWorldPoint RootRelativeMarkerOffset(ArenaContentArtifact artifact, string kind) { //IL_017f: 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_012d: 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_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) ArenaParityNode val = null; Dictionary dictionary = new Dictionary(StringComparer.Ordinal); foreach (ArenaParityNode item in artifact.Parity) { dictionary[item.Path] = item; if (val == null && string.Equals(item.Kind, kind, StringComparison.Ordinal)) { val = item; } } if (val == null) { throw new InvalidOperationException("The authored parity map has no '" + kind + "' marker to place the arena by."); } float num = 0f; float num2 = 0f; float num3 = 0f; string[] array = val.Path.Split(new char[1] { '/' }); string text = string.Empty; for (int i = 0; i < array.Length; i++) { text = ((i == 0) ? array[0] : (text + "/" + array[i])); if (!dictionary.TryGetValue(text, out var value)) { throw new InvalidOperationException("Cannot derive the '" + kind + "' marker offset: ancestor '" + text + "' is not in the parity map."); } if (i < array.Length - 1) { RequireIdentityOrientation(value); } float num4 = num; Vector3 position = value.LocalTransform.Position; num = num4 + ((Vector3)(ref position)).X; float num5 = num2; position = value.LocalTransform.Position; num2 = num5 + ((Vector3)(ref position)).Y; float num6 = num3; position = value.LocalTransform.Position; num3 = num6 + ((Vector3)(ref position)).Z; } return new ArenaWorldPoint(num, num2, num3); } private static void RequireIdentityOrientation(ArenaParityNode node) { //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_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) Quaternion rotation = node.LocalTransform.Rotation; bool num = Math.Abs(((Quaternion)(ref rotation)).X) <= 0.0001f && Math.Abs(((Quaternion)(ref rotation)).Y) <= 0.0001f && Math.Abs(((Quaternion)(ref rotation)).Z) <= 0.0001f && Math.Abs(Math.Abs(((Quaternion)(ref rotation)).W) - 1f) <= 0.0001f; Vector3 scale = node.LocalTransform.Scale; bool flag = Math.Abs(((Vector3)(ref scale)).X - 1f) <= 0.0001f && Math.Abs(((Vector3)(ref scale)).Y - 1f) <= 0.0001f && Math.Abs(((Vector3)(ref scale)).Z - 1f) <= 0.0001f; if (!num || !flag) { throw new InvalidOperationException("Cannot derive a marker offset by summing positions: '" + node.Path + "' has a non-identity rotation or non-unit scale. Extend ArenaPlacement with full transform composition first."); } } } public sealed record ClientLoadOutcome(ArenaManifest? Manifest, string? FailureReason, bool NotYet = false) { public static ClientLoadOutcome Ready(ArenaManifest manifest) { return new ClientLoadOutcome(manifest, null); } public static ClientLoadOutcome Failed(string reason) { return new ClientLoadOutcome(null, reason); } public static ClientLoadOutcome Deferred(string reason) { return new ClientLoadOutcome(null, reason, NotYet: true); } } public sealed class ClientEncounterFlow : IDisposable { private const float DeferralLimitSeconds = 25f; private readonly IEncounterChannel _channel; private readonly IMultiplayerSession _session; private EnterArena? _waiting; private float _waited; public Func? OnEnterArena { get; set; } public Action? OnAborted { get; set; } public Action? OnEnded { get; set; } public Action? OnBossHitPlayer { get; set; } public ClientEncounterFlow(IEncounterChannel channel, IMultiplayerSession session) { _channel = channel ?? throw new ArgumentNullException("channel"); _session = session ?? throw new ArgumentNullException("session"); _channel.Received += OnReceived; } public void Tick(float deltaSeconds) { EnterArena waiting = _waiting; if (waiting != null) { _waited += deltaSeconds; Answer(waiting, Load(waiting), _waited >= 25f); } } public void Dispose() { _channel.Received -= OnReceived; } private void OnReceived(SessionPeerId sender, EncodedPayload payload) { //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_0015: Unknown result type (might be due to invalid IL or missing references) if (sender != _session.HostPeer) { return; } DecodedMessage decodedMessage; try { decodedMessage = EncounterCodec.Decode(payload); } catch (Exception) { return; } object value = decodedMessage.Value; EnterArena val = (EnterArena)((value is EnterArena) ? value : null); if (val == null) { EncounterAborted val2 = (EncounterAborted)((value is EncounterAborted) ? value : null); if (val2 == null) { EncounterEnded val3 = (EncounterEnded)((value is EncounterEnded) ? value : null); if (val3 == null) { BossHitPlayer val4 = (BossHitPlayer)((value is BossHitPlayer) ? value : null); if (val4 != null) { OnBossHitPlayer?.Invoke(val4); } } else { OnEnded?.Invoke(val3); } } else { OnAborted?.Invoke(val2); } } else { HandleEnterArena(val); } } private void HandleEnterArena(EnterArena enter) { _waiting = null; _waited = 0f; Answer(enter, Load(enter), giveUp: false); } private ClientLoadOutcome Load(EnterArena enter) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (!IsFinite(enter.Origin)) { return ClientLoadOutcome.Failed("EnterArena carried a non-finite origin"); } if (OnEnterArena == null) { return ClientLoadOutcome.Failed("client has no arena composition to load with"); } return OnEnterArena(enter); } private void Answer(EnterArena enter, ClientLoadOutcome outcome, bool giveUp) { //IL_0052: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0045: 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_0070: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (outcome.NotYet && !giveUp) { _waiting = enter; return; } _waiting = null; _waited = 0f; if (outcome.Manifest != (ArenaManifest)null) { Reply(EncounterCodec.Encode(new ArenaReady(enter.Encounter, outcome.Manifest))); } else { Reply(EncounterCodec.Encode(new ArenaLoadFailed(enter.Encounter, outcome.FailureReason ?? "unspecified load failure"))); } } private void Reply(EncodedPayload payload) { //IL_0006: 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) _channel.Send(payload, (MessageDelivery)0, MessageTarget.Host); } private static bool IsFinite(WorldPosition p) { if (!float.IsNaN(((WorldPosition)(ref p)).X) && !float.IsInfinity(((WorldPosition)(ref p)).X) && !float.IsNaN(((WorldPosition)(ref p)).Y) && !float.IsInfinity(((WorldPosition)(ref p)).Y) && !float.IsNaN(((WorldPosition)(ref p)).Z)) { return !float.IsInfinity(((WorldPosition)(ref p)).Z); } return false; } } public sealed class HostEncounterGate : IDisposable { private readonly IEncounterChannel _channel; private readonly IMultiplayerSession _session; private readonly ReplicationSender _sender; private readonly EncounterReadyGate _gate; private readonly EncounterId _encounter; private readonly ArenaManifest _hostManifest; private readonly WorldPosition _origin; private readonly float _timeoutSeconds; private float _elapsedSeconds; private bool _opened; private bool _abortBroadcast; public GateStatus Status => _gate.Status; public GateAbortReason AbortReason => _gate.AbortReason; public HostEncounterGate(IEncounterChannel channel, IMultiplayerSession session, IPlayerRoster roster, ReplicationSender sender, EncounterId encounter, ArenaManifest hostManifest, WorldPosition origin, float timeoutSeconds) { //IL_006f: 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_0077: 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) _channel = channel ?? throw new ArgumentNullException("channel"); _session = session ?? throw new ArgumentNullException("session"); _sender = sender ?? throw new ArgumentNullException("sender"); _hostManifest = hostManifest ?? throw new ArgumentNullException("hostManifest"); _gate = new EncounterReadyGate(hostManifest, roster); _encounter = encounter; _origin = origin; _timeoutSeconds = timeoutSeconds; } public void Open() { //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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (_opened) { throw new InvalidOperationException("The gate is already open; one gate drives one encounter."); } _opened = true; _channel.Received += OnReceived; _sender.BroadcastEnterArena(new EnterArena(_encounter, _hostManifest, _origin)); _gate.SubmitReady(_session.LocalPeer, _hostManifest); } public void Tick(float deltaSeconds) { //IL_0062: 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_0081: Expected O, but got Unknown if (!_opened) { return; } if (_gate.Status == GateStatus.Waiting) { _elapsedSeconds += deltaSeconds; if (_elapsedSeconds >= _timeoutSeconds) { _gate.OnTimeout(); } } if (_gate.Status == GateStatus.Aborted && !_abortBroadcast) { _abortBroadcast = true; _sender.BroadcastAborted(new EncounterAborted(_encounter, ToWireReason(_gate.AbortReason))); } } public string DescribeOutstanding() { return string.Join(", ", _gate.Outstanding); } public void Dispose() { _channel.Received -= OnReceived; } private void OnReceived(SessionPeerId sender, EncodedPayload payload) { //IL_0000: 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_0030: 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_0051: 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_0069: Unknown result type (might be due to invalid IL or missing references) DecodedMessage decodedMessage; try { decodedMessage = EncounterCodec.Decode(payload); } catch (Exception) { return; } object value = decodedMessage.Value; ArenaReady val = (ArenaReady)((value is ArenaReady) ? value : null); if (val == null) { ArenaLoadFailed val2 = (ArenaLoadFailed)((value is ArenaLoadFailed) ? value : null); if (val2 != null && val2.Encounter == _encounter) { _gate.SubmitLoadFailed(sender); } } else if (val.Encounter == _encounter) { _gate.SubmitReady(sender, val.Manifest); } } private static EncounterAbortReason ToWireReason(GateAbortReason reason) { return (EncounterAbortReason)(reason switch { GateAbortReason.ContentHashSchemaMismatch => 1, GateAbortReason.VersionMismatch => 2, GateAbortReason.ContentMismatch => 3, GateAbortReason.LoadFailed => 4, GateAbortReason.Timeout => 5, _ => 0, }); } } public interface IArenaHijackPort { ArenaLevelId ArenaLevel { get; } bool IsArenaModeOn { get; } bool DeclareArenaLevel(ArenaLevelId level); void LeaveArenaMode(); void LoadHijackedArena(); } public sealed record NavigationApplyResult(bool Success, string? Error, int WalkableNodesApplied) { public static NavigationApplyResult Applied(int walkableNodes) { return new NavigationApplyResult(Success: true, null, walkableNodes); } public static NavigationApplyResult Failed(string error) { return new NavigationApplyResult(Success: false, error, 0); } } public interface INavigationPort { NavigationApplyResult Apply(); void Remove(); } public sealed record MaterialBorrowRequest(string TargetPath, int TargetSubMaterialIndex, string CarrierGuid, string MaterialName); public sealed record MaterialConventionPaint(string ParentPath, string ChildNamePrefix, int SubMaterialIndex, string CarrierGuid, string MaterialName); public sealed record SubmeshMaterialRule(string PlaceholderName, string VanillaMaterialName); public sealed record SubmeshBorrow(string TargetPath, string CarrierGuid, IReadOnlyList Rules); public sealed record VanillaPropClone(string ParentPath, string MarkerNamePrefix, string RoomKey, string PropPath, IReadOnlyList StripChildNames, IReadOnlyList StripComponentNames, string LayerName, IReadOnlyList VolumeChildNames, bool PointExitAtSafeArea = false); public sealed record VanillaPropResult(bool Success, string? Error, int Cloned) { public static VanillaPropResult Placed(int cloned) { return new VanillaPropResult(Success: true, null, cloned); } public static VanillaPropResult Failed(string error) { return new VanillaPropResult(Success: false, error, 0); } } public sealed record MaterialBorrowResult(bool Success, string? Error, int Applied) { public static MaterialBorrowResult Resolved(int applied) { return new MaterialBorrowResult(Success: true, null, applied); } public static MaterialBorrowResult Failed(string error) { return new MaterialBorrowResult(Success: false, error, 0); } } public interface IVanillaAssetProvider { MaterialBorrowResult Resolve(IReadOnlyList requests); MaterialBorrowResult PaintByConvention(MaterialConventionPaint paint); MaterialBorrowResult PaintSubmeshes(SubmeshBorrow borrow); VanillaPropResult CloneProps(VanillaPropClone request); void Release(); } }