Decompiled source of IamScoutmaster v0.7.3
plugins/Thanks.I_am_Scoutmaster.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Thanks.I_am_Scoutmaster")] [assembly: AssemblyDescription("Control the PEAK Scoutmaster as the local player.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Thanks")] [assembly: AssemblyProduct("I'm Scoutmaster")] [assembly: AssemblyCopyright("Copyright 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("0ee091f4-9b49-4593-a95d-af67533313c8")] [assembly: AssemblyFileVersion("0.7.14.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.7.14.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ImScoutmaster { public sealed class ControlledScoutmasterVisualSync : MonoBehaviour { private Character _character; private PhotonView _view; public void Initialize(Character character, PhotonView view) { _character = (((Object)(object)character != (Object)null) ? character : ((Component)this).GetComponent<Character>()); _view = (((Object)(object)view != (Object)null) ? view : ((Component)this).GetComponent<PhotonView>()); } private void Awake() { Initialize(_character, _view); } private void Update() { if ((Object)(object)_character == (Object)null) { _character = ((Component)this).GetComponent<Character>(); } if ((Object)(object)_character != (Object)null) { Plugin.EnsureControlledScoutmasterRegistered(_character); } } private void OnDestroy() { Plugin.UnregisterControlledScoutmasterInstance(_character, _view); } } [BepInPlugin("com.github.Thanks.ImScoutmaster", "I'm Scoutmaster", "0.7.14")] public sealed class Plugin : BaseUnityPlugin, IInRoomCallbacks { private enum ConfigKey { ToggleKey, StaminaRefill, ThrowForce, ThrowUpBias, ThrowFallSeconds, ThrowMaxDistance, ThirdPersonHeightOffset, ThirdPersonDistance, SourceStashDistance, RestoreAtScoutmasterPosition, RestoreGroundOffset, HideHudWhileTransformed, VerboseLogs } private readonly struct RendererVisualState { public readonly bool Enabled; public readonly bool ForceRenderingOff; public RendererVisualState(bool enabled, bool forceRenderingOff) { Enabled = enabled; ForceRenderingOff = forceRenderingOff; } } private sealed class ActiveScoutmasterSession { private readonly struct BodypartPhysicsState { public readonly Rigidbody Rig; public readonly bool IsKinematic; public readonly bool DetectCollisions; public readonly bool UseGravity; public BodypartPhysicsState(Rigidbody rig) { Rig = rig; IsKinematic = (Object)(object)rig != (Object)null && rig.isKinematic; DetectCollisions = (Object)(object)rig != (Object)null && rig.detectCollisions; UseGravity = (Object)(object)rig != (Object)null && rig.useGravity; } } private Character _sourceCharacter; private readonly GameObject _scoutmasterObject; private readonly Scoutmaster _scoutmaster; private readonly Character _scoutmasterCharacter; private readonly Vector3 _sourceStartPosition; private readonly Vector3 _sourceStashPosition; private readonly Quaternion _sourceStartRotation; private readonly bool _sourceWasActive; private readonly List<BodypartPhysicsState> _sourceBodypartPhysicsStates = new List<BodypartPhysicsState>(); private PlayerScoutmasterController _controller; private bool _sourcePhysicsSuspended; private bool _sourceViewDisabledByMod; private bool _sourceViewSyncFrozenByMod; private ViewSynchronization _sourceViewSynchronizationBackup; private bool _sourceSyncerDisabledByMod; private bool _sourceStashBroadcastPending; private float _nextSourceStashReaffirmTime; private const float MaxUnsafeRestoreFallbackVerticalDrift = 10f; private const float MaxRestoreAnchorHorizontalDrift = 4f; private const float MaxRestoreVerticalError = 8f; public bool IsActive { get { if ((Object)(object)_sourceCharacter != (Object)null && (Object)(object)_scoutmasterObject != (Object)null && (Object)(object)_scoutmaster != (Object)null) { return (Object)(object)_scoutmasterCharacter != (Object)null; } return false; } } public ActiveScoutmasterSession(Character sourceCharacter, GameObject scoutmasterObject, Scoutmaster scoutmaster, Character scoutmasterCharacter, bool sourceWasActive, Vector3 transformAnchor) { //IL_002f: 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_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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) _sourceCharacter = sourceCharacter; _scoutmasterObject = scoutmasterObject; _scoutmaster = scoutmaster; _scoutmasterCharacter = scoutmasterCharacter; _sourceStartPosition = transformAnchor; _sourceStashPosition = ResolveSourceStashPosition(_sourceStartPosition); _sourceStartRotation = GetSpawnRotation(sourceCharacter); _sourceWasActive = sourceWasActive; } private static Vector3 ResolveSourceStashPosition(Vector3 startPosition) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(SourceStashDistance.Value, 10f); if (TryFindStandingGroundBelow(startPosition, 600f, out var groundHit)) { return ((RaycastHit)(ref groundHit)).point + Vector3.down * Mathf.Max(num, 25f); } return startPosition + Vector3.down * (num + 400f); } public IEnumerator Enter() { PreconfigureScoutmasterForLocalControl(); _controller = _scoutmasterObject.GetComponent<PlayerScoutmasterController>() ?? _scoutmasterObject.AddComponent<PlayerScoutmasterController>(); _controller.Initialize(_sourceCharacter, _scoutmaster, _scoutmasterCharacter); RegisterControlledScoutmaster(_scoutmaster); Character.localCharacter = _scoutmasterCharacter; SetGameObjectActive(_scoutmasterObject, active: true); AlignScoutmasterBodyToSource(); yield return null; AlignScoutmasterBodyToSource(); PrepareScoutmaster(); CopyLookStateForRestore(_sourceCharacter, _scoutmasterCharacter, _sourceStartRotation); SetCameraOverride(_scoutmasterCharacter); _viewScoutmasterObject = _scoutmasterObject; UpdateScoutmasterHudState(); RestoreRendererVisibility(_scoutmasterObject); if (!_scoutmasterPhysicsWarmedUp) { yield return (object)new WaitForSecondsRealtime(0.25f); EnableScoutmasterPhysics(); _scoutmasterPhysicsWarmedUp = true; } _controller.ActivateDynamicRagdollControl(); HideSourceCharacter(); yield return (object)new WaitForSecondsRealtime(0.1f); if (PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode) { try { PhotonNetwork.SendAllOutgoingCommands(); } catch (Exception ex) { LogVerbose("Failed to flush source stash position over network: " + ex.Message); } } FreezeSourceNetworkSync(); _sourceStashBroadcastPending = false; Character.localCharacter = _scoutmasterCharacter; LogVerbose("Entered Scoutmaster form."); LogPhotonViewDuplicateScan("entered-scoutmaster-form"); } private void PreconfigureScoutmasterForLocalControl() { _scoutmasterCharacter.isScoutmaster = true; _scoutmasterCharacter.isZombie = false; } private void AlignScoutmasterBodyToSource() { //IL_002d: 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_003f: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_013c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)_scoutmasterCharacter == (Object)null || (Object)(object)_scoutmasterObject == (Object)null) { return; } try { Vector3 val = (IsFiniteVector(_sourceStartPosition) ? _sourceStartPosition : _sourceCharacter.Center); SetCharacterPositionImmediate(_scoutmasterCharacter, val, _sourceStartRotation); Vector3 center = _scoutmasterCharacter.Center; if (!IsFiniteVector(center) || !IsFiniteVector(val) || Vector3.Distance(center, val) > 3f) { ReanchorScoutmasterBodyToSource(val); } AlignCharacterFeetToGround(_scoutmasterCharacter, _sourceCharacter); _scoutmasterCharacter.data.currentRagdollControll = 1f; _scoutmasterCharacter.data.fallSeconds = 0f; _scoutmasterCharacter.data.isGrounded = (Object)(object)_sourceCharacter.data != (Object)null && _sourceCharacter.data.isGrounded; _scoutmasterCharacter.data.groundPos = (((Object)(object)_sourceCharacter.data != (Object)null) ? _sourceCharacter.data.groundPos : _sourceCharacter.Center); Physics.SyncTransforms(); if (_scoutmasterPhysicsWarmedUp) { EnableScoutmasterPhysics(); } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to align controlled body: " + ex.Message)); } } } private void ReanchorScoutmasterBodyToSource(Vector3 sourceCenter) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) if (_scoutmasterCharacter?.refs?.ragdoll?.partList == null || _sourceCharacter?.refs?.ragdoll?.partList == null) { return; } try { ((Component)_scoutmasterCharacter).transform.SetPositionAndRotation(sourceCenter, _sourceStartRotation); List<Bodypart> partList = _sourceCharacter.refs.ragdoll.partList; List<Bodypart> partList2 = _scoutmasterCharacter.refs.ragdoll.partList; for (int i = 0; i < partList2.Count; i++) { Bodypart val = partList2[i]; if ((Object)(object)val == (Object)null) { continue; } Vector3 position = sourceCenter; if (i < partList.Count && (Object)(object)partList[i] != (Object)null) { Bodypart val2 = partList[i]; Vector3 val3 = (((Object)(object)val2.Rig != (Object)null) ? val2.Rig.position : val2.transform.position); if (IsFiniteVector(val3)) { position = val3; } } if ((Object)(object)val.Rig != (Object)null) { val.Rig.position = position; if (!val.Rig.isKinematic) { val.Rig.linearVelocity = Vector3.zero; val.Rig.angularVelocity = Vector3.zero; } } else if ((Object)(object)val.transform != (Object)null) { val.transform.position = position; } } } catch { } } private void EnableScoutmasterPhysics() { if ((Object)(object)_scoutmasterCharacter == (Object)null || _scoutmasterCharacter.refs?.ragdoll?.partList == null) { return; } try { foreach (Bodypart part in _scoutmasterCharacter.refs.ragdoll.partList) { Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null); if (!((Object)(object)val == (Object)null)) { val.isKinematic = false; val.detectCollisions = true; val.useGravity = true; val.WakeUp(); } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to enable controlled physics: " + ex.Message)); } } } public void Tick() { if (!IsActive) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"[I'm Scoutmaster] Session became inactive."); } Instance?.ExitScoutmasterForm(restorePlayer: true); return; } Character.localCharacter = _scoutmasterCharacter; KeepScoutmasterAwake(); if (!_sourceStashBroadcastPending) { KeepSourceOutOfPlay(); FollowSourceCharacterToControlledBodySafely(); } } private void FollowSourceCharacterToControlledBody() { //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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)_scoutmasterCharacter == (Object)null) { return; } try { Vector3 center = _scoutmasterCharacter.Center; if (!IsFiniteVector(center)) { return; } Vector3 val = center - _sourceCharacter.Center; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return; } Transform transform = ((Component)_sourceCharacter).transform; transform.position += val; if (_sourceCharacter.refs?.ragdoll?.partList == null) { return; } foreach (Bodypart part in _sourceCharacter.refs.ragdoll.partList) { if (!((Object)(object)part == (Object)null)) { if ((Object)(object)part.Rig != (Object)null) { Rigidbody rig = part.Rig; rig.position += val; } else if ((Object)(object)part.transform != (Object)null) { Transform transform2 = part.transform; transform2.position += val; } } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to follow source character to controlled body: " + ex.Message)); } } } private void FollowSourceCharacterToControlledBodySafely() { //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_002a: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)_scoutmasterCharacter == (Object)null) { return; } try { Vector3 center = _scoutmasterCharacter.Center; if (!IsFiniteVector(center)) { return; } Vector3 center2 = _sourceCharacter.Center; if (IsFiniteVector(center2)) { Vector3 val = center - center2; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return; } } Quaternion val2 = ((Component)_scoutmasterCharacter).transform.rotation; if (!IsFiniteQuaternion(val2)) { val2 = _sourceStartRotation; } SetCharacterPositionImmediate(_sourceCharacter, center, val2); SanitizeCharacterBodyparts(_sourceCharacter, center, val2); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to safely follow source character to controlled body: " + ex.Message)); } } } public void Exit(bool restorePlayer) { //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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00b4: Unknown result type (might be due to invalid IL or missing references) if (restorePlayer && (Object)(object)_sourceCharacter == (Object)null) { Character val = TryRecoverOriginalLocalCharacter(); if ((Object)(object)val != (Object)null) { _sourceCharacter = val; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("[I'm Scoutmaster] Recovered source character reference during exit: " + ((Object)val).name + ".")); } } } Vector3 position = ResolveRestorePosition(); Quaternion val2 = ResolveRestoreRotation(); if ((Object)(object)_controller != (Object)null) { ((Behaviour)_controller).enabled = false; } RestoreRendererVisibility(_scoutmasterObject); ClearCameraOverride(); _viewScoutmasterObject = null; RestoreHudAfterScoutmaster(); if (restorePlayer && (Object)(object)_sourceCharacter != (Object)null) { CopyLookStateForRestore(_scoutmasterCharacter, _sourceCharacter, val2); RestoreSourceCharacter(position, val2); SanitizeCharacterLookState(_sourceCharacter); ForcePlayerCharacterLookup(_sourceCharacter); Character.localCharacter = _sourceCharacter; BeginCameraRestoreAssist(_sourceCharacter); } UnregisterStashedSourceCharacter(_sourceCharacter); ResumeSourceNetworkSync(); UnregisterControlledScoutmaster(_scoutmaster); BeginPeakStatsCleanupGraceWindow(); CleanupPeakStatsUi(aggressive: true); DestroyScoutmasterObject(_scoutmasterObject); LogVerbose("Exited Scoutmaster form."); LogPhotonViewDuplicateScan("exited-scoutmaster-form"); } private Vector3 ResolveRestorePosition() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) bool num = RestoreAtScoutmasterPosition == null || RestoreAtScoutmasterPosition.Value; Vector3 requestedPosition = _sourceStartPosition; if (num && (Object)(object)_scoutmasterCharacter != (Object)null) { Vector3 center = _scoutmasterCharacter.Center; if (IsFiniteVector(center)) { requestedPosition = center; } else { Vector3 position = ((Component)_scoutmasterCharacter).transform.position; if (IsFiniteVector(position)) { requestedPosition = position; } } } return ResolveSafeRestorePosition(requestedPosition, _scoutmasterCharacter, _sourceCharacter, _sourceStartPosition); } private Quaternion ResolveRestoreRotation() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_scoutmasterCharacter == (Object)null) { return _sourceStartRotation; } Vector3 val = Vector3.ProjectOnPlane(((Component)_scoutmasterCharacter).transform.rotation * Vector3.forward, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && (Object)(object)_scoutmasterCharacter.data != (Object)null) { val = _scoutmasterCharacter.data.lookDirection_Flat; } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && (Object)(object)_scoutmasterCharacter.data != (Object)null) { val = Vector3.ProjectOnPlane(_scoutmasterCharacter.data.lookDirection, Vector3.up); } if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return _sourceStartRotation; } return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); } private static Character TryRecoverOriginalLocalCharacter() { try { Player localPlayer = Player.localPlayer; object obj; if (localPlayer == null) { obj = null; } else { PhotonView photonView = ((MonoBehaviourPun)localPlayer).photonView; obj = ((photonView != null) ? photonView.Owner : null); } Player val = (Player)obj; if (val == null || Character.AllCharacters == null) { return null; } foreach (Character allCharacter in Character.AllCharacters) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter.data == (Object)null) && !((Object)(object)((MonoBehaviourPun)allCharacter).photonView == (Object)null) && ((MonoBehaviourPun)allCharacter).photonView.Owner == val && !IsControlledScoutmasterCharacter(allCharacter) && !allCharacter.isZombie && !allCharacter.isScoutmaster) { return allCharacter; } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to recover original local character: " + ex.Message)); } } return null; } private static Vector3 GetRestoreAnchor(Character character) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_0062: 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_007b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null) { return Vector3.zero; } Vector3 center = character.Center; if ((Object)(object)character.data != (Object)null && IsFiniteVector(character.data.groundPos)) { Vector3 groundPos = character.data.groundPos; Vector3 val = Vector3.ProjectOnPlane(groundPos - center, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude <= 64f && Mathf.Abs(groundPos.y - center.y) <= 12f) { return groundPos; } } if (IsFiniteVector(center)) { return center; } Vector3 head = character.Head; if (!IsFiniteVector(head)) { return ((Component)character).transform.position; } return head; } private static void AlignCharacterFeetToGround(Character controlledCharacter, Character sourceCharacter) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)controlledCharacter == (Object)null) && !((Object)(object)sourceCharacter == (Object)null) && TryGetCharacterGroundY(sourceCharacter, out var groundY) && TryGetCharacterGroundY(controlledCharacter, out var groundY2)) { float num = groundY - groundY2; if (!float.IsNaN(num) && !float.IsInfinity(num) && !(num <= 0.001f) && !(num > 2f)) { SetCharacterPositionImmediate(controlledCharacter, controlledCharacter.Center + Vector3.up * num, ((Component)controlledCharacter).transform.rotation); } } } private static bool TryGetCharacterGroundY(Character character, out float groundY) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) groundY = 0f; if ((Object)(object)character == (Object)null) { return false; } Vector3 center = character.Center; if ((Object)(object)character.data != (Object)null && IsFiniteVector(character.data.groundPos)) { Vector3 groundPos = character.data.groundPos; Vector3 val = Vector3.ProjectOnPlane(groundPos - center, Vector3.up); if (((Vector3)(ref val)).sqrMagnitude <= 64f && Mathf.Abs(groundPos.y - center.y) <= 12f) { groundY = groundPos.y; return true; } } if (TryGetCharacterColliderBottomY(character, out groundY)) { return true; } if (IsFiniteVector(center)) { groundY = center.y; return true; } Vector3 position = ((Component)character).transform.position; if (!IsFiniteVector(position)) { return false; } groundY = position.y; return true; } private static bool TryGetCharacterColliderBottomY(Character character, out float bottomY) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) bottomY = 0f; if (character?.refs?.ragdoll?.partList == null) { return false; } bool flag = false; foreach (Bodypart part in character.refs.ragdoll.partList) { if ((Object)(object)part == (Object)null) { continue; } Collider[] componentsInChildren = ((Component)part).GetComponentsInChildren<Collider>(true); if (componentsInChildren != null) { Collider[] array = componentsInChildren; foreach (Collider val in array) { if (!((Object)(object)val == (Object)null) && val.enabled) { Bounds bounds = val.bounds; Vector3 min = ((Bounds)(ref bounds)).min; if (IsFiniteVector(min) && (!flag || min.y < bottomY)) { bottomY = min.y; flag = true; } } } } Vector3 val2 = (((Object)(object)part.Rig != (Object)null) ? part.Rig.position : part.transform.position); if (IsFiniteVector(val2) && (!flag || val2.y < bottomY)) { bottomY = val2.y; flag = true; } } return flag; } private unsafe static Vector3 ResolveSafeRestorePosition(Vector3 requestedPosition, Character scoutmasterCharacter, Character sourceCharacter, Vector3 fallbackPosition) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0098: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(RestoreGroundOffset.Value, 0.2f, 5f); Vector3 val = (IsFiniteVector(requestedPosition) ? requestedPosition : fallbackPosition); if (!IsFiniteVector(val)) { val = (((Object)(object)sourceCharacter != (Object)null) ? ((Component)sourceCharacter).transform.position : Vector3.zero); } if (TryFindRestoreGround(val + Vector3.up * 5f, 30f, scoutmasterCharacter, sourceCharacter, out var groundHit) || TryFindRestoreGround(val + Vector3.up * 12f, 80f, scoutmasterCharacter, sourceCharacter, out groundHit) || TryFindRestoreGroundUpward(val, 80f, scoutmasterCharacter, sourceCharacter, out groundHit) || TryFindRestoreGround(fallbackPosition + Vector3.up * 5f, 60f, scoutmasterCharacter, sourceCharacter, out groundHit) || TryFindRestoreGround(fallbackPosition + Vector3.up * 60f, 200f, scoutmasterCharacter, sourceCharacter, out groundHit)) { return ((RaycastHit)(ref groundHit)).point + Vector3.up * num; } Vector3 val2 = (IsFiniteVector(fallbackPosition) ? fallbackPosition : val); if ((Object)(object)sourceCharacter != (Object)null && !IsFiniteVector(val2)) { val2 = ((Component)sourceCharacter).transform.position; } ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] No restore ground found below or above anchor " + ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString() + "; restoring at safe fallback " + ((object)(*(Vector3*)(&val2))/*cast due to .constrained prefix*/).ToString() + " instead.")); } return val2 + Vector3.up * num; } private static bool TryFindRestoreGroundUpward(Vector3 origin, float distance, Character scoutmasterCharacter, Character sourceCharacter, out RaycastHit groundHit) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) groundHit = default(RaycastHit); if (!IsFiniteVector(origin)) { return false; } RaycastHit[] array; try { array = Physics.RaycastAll(origin, Vector3.up, distance, -1, (QueryTriggerInteraction)1); } catch { return false; } Array.Sort(array, (RaycastHit left, RaycastHit right) => ((RaycastHit)(ref left)).distance.CompareTo(((RaycastHit)(ref right)).distance)); RaycastHit[] array2 = array; for (int num = 0; num < array2.Length; num++) { RaycastHit val = array2[num]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((RaycastHit)(ref val)).collider.isTrigger && !(Vector3.Dot(((RaycastHit)(ref val)).normal, Vector3.up) > 0.2f) && !IsRestoreIgnoredCollider(((RaycastHit)(ref val)).collider, scoutmasterCharacter, sourceCharacter)) { if (TryFindRestoreGround(((RaycastHit)(ref val)).point + Vector3.up * 12f, 30f, scoutmasterCharacter, sourceCharacter, out var groundHit2)) { groundHit = groundHit2; } else { groundHit = val; } return true; } } return false; } private static bool TryFindRestoreGround(Vector3 origin, float distance, Character scoutmasterCharacter, Character sourceCharacter, out RaycastHit groundHit) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) groundHit = default(RaycastHit); if (!IsFiniteVector(origin)) { return false; } RaycastHit[] array; try { array = Physics.RaycastAll(origin, Vector3.down, distance, -1, (QueryTriggerInteraction)1); } catch { return false; } Array.Sort(array, (RaycastHit left, RaycastHit right) => ((RaycastHit)(ref left)).distance.CompareTo(((RaycastHit)(ref right)).distance)); RaycastHit[] array2 = array; for (int num = 0; num < array2.Length; num++) { RaycastHit val = array2[num]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((RaycastHit)(ref val)).collider.isTrigger && !(Vector3.Dot(((RaycastHit)(ref val)).normal, Vector3.up) < -0.2f) && !IsRestoreIgnoredCollider(((RaycastHit)(ref val)).collider, scoutmasterCharacter, sourceCharacter)) { groundHit = val; return true; } } return false; } private static bool IsRestoreIgnoredCollider(Collider collider, Character scoutmasterCharacter, Character sourceCharacter) { if ((Object)(object)collider == (Object)null) { return true; } Transform transform = ((Component)collider).transform; if (!IsColliderOwnedBy(transform, scoutmasterCharacter)) { return IsColliderOwnedBy(transform, sourceCharacter); } return true; } private static bool IsColliderOwnedBy(Transform colliderTransform, Character character) { if ((Object)(object)colliderTransform == (Object)null || (Object)(object)character == (Object)null) { return false; } Transform transform = ((Component)character).transform; if (!((Object)(object)colliderTransform == (Object)(object)transform)) { return colliderTransform.IsChildOf(transform); } return true; } private static bool IsFiniteVector(Vector3 value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (IsFiniteFloat(value.x) && IsFiniteFloat(value.y)) { return IsFiniteFloat(value.z); } return false; } private static bool IsFiniteFloat(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private void PrepareScoutmaster() { ClearScoutmasterAiState(_scoutmaster); _scoutmasterCharacter.isScoutmaster = true; _scoutmasterCharacter.isZombie = false; _scoutmasterCharacter.data.isScoutmaster = true; SetCharacterDeadWithoutReconnect(_scoutmasterCharacter, dead: false); _scoutmasterCharacter.data.zombified = false; _scoutmasterCharacter.data.passedOut = false; _scoutmasterCharacter.data.fullyPassedOut = false; _scoutmasterCharacter.data.fallSeconds = 0f; _scoutmasterCharacter.data.currentRagdollControll = 1f; _scoutmasterCharacter.data.currentStamina = Mathf.Max(_scoutmasterCharacter.data.currentStamina, GetControlledStaminaFill()); _scoutmasterCharacter.data.extraStamina = 0f; ClearAssistJumpState(_scoutmasterCharacter); } private void HideSourceCharacter() { //IL_00a6: 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_00c8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sourceCharacter == (Object)null) { return; } try { _sourceStashBroadcastPending = true; RegisterStashedSourceCharacter(_sourceCharacter); _sourceCharacter.data.fallSeconds = 0f; _sourceCharacter.data.passedOut = false; _sourceCharacter.data.fullyPassedOut = false; ClearAssistJumpState(_sourceCharacter); if (_sourceWasActive && !((Component)_sourceCharacter).gameObject.activeSelf) { ((Component)_sourceCharacter).gameObject.SetActive(true); } HideSourceRenderers(((Component)_sourceCharacter).gameObject); SetCharacterPositionImmediate(_sourceCharacter, _sourceStashPosition, ((Component)_sourceCharacter).transform.rotation); SuspendSourcePhysics(); SendSourceCharacterOutOfPlay(_sourceStashPosition); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to stash source character: " + ex.Message)); } } } private void RestoreSourceCharacter(Vector3 position, Quaternion rotation) { //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) try { _sourceStashBroadcastPending = false; if (_sourceWasActive && !((Component)_sourceCharacter).gameObject.activeSelf) { ((Component)_sourceCharacter).gameObject.SetActive(true); } SetCharacterDeadWithoutReconnect(_sourceCharacter, dead: false); _sourceCharacter.data.zombified = false; _sourceCharacter.isZombie = false; _sourceCharacter.data.passedOut = false; _sourceCharacter.data.fullyPassedOut = false; _sourceCharacter.data.fallSeconds = 0f; _sourceCharacter.data.deathTimer = 0f; _sourceCharacter.data.currentRagdollControll = 1f; _sourceCharacter.data.isGrounded = false; _sourceCharacter.data.sinceGrounded = 0f; _sourceCharacter.data.groundedFor = 0f; _sourceCharacter.data.groundPos = position; _sourceCharacter.data.avarageVelocity = Vector3.zero; _sourceCharacter.data.avarageLastFrameVelocity = Vector3.zero; ClearAssistJumpState(_sourceCharacter); SetCharacterPositionImmediate(_sourceCharacter, position, rotation); SanitizeCharacterBodyparts(_sourceCharacter, position, rotation); ResumeSourceNetworkSync(); SendSourceCharacterRestore(position); SetCharacterPositionImmediate(_sourceCharacter, position, rotation); SanitizeCharacterBodyparts(_sourceCharacter, position, rotation); RestoreSourcePhysics(); RestoreSourceRenderers(((Component)_sourceCharacter).gameObject); UnregisterStashedSourceCharacter(_sourceCharacter); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to restore source character: " + ex.Message)); } } } private void SendSourceCharacterOutOfPlay(Vector3 stashPosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendSourceCharacterStateRpc(stashPosition, "[I'm Scoutmaster] Failed to move source character out of play: "); } private void FreezeSourceNetworkSync() { //IL_0077: 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) if ((Object)(object)_sourceCharacter == (Object)null) { return; } try { PhotonView photonView = ((MonoBehaviourPun)_sourceCharacter).photonView; if ((Object)(object)photonView != (Object)null) { if (((Behaviour)photonView).enabled) { ((Behaviour)photonView).enabled = false; _sourceViewDisabledByMod = true; LogVerbose("Froze source character network sync while stashed."); LogObjectPhotonViewState("freeze-source", ((Component)_sourceCharacter).gameObject); } if (!_sourceViewSyncFrozenByMod) { _sourceViewSynchronizationBackup = photonView.Synchronization; _sourceViewSyncFrozenByMod = true; } photonView.Synchronization = (ViewSynchronization)0; } CharacterSyncer component = ((Component)_sourceCharacter).GetComponent<CharacterSyncer>(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { ((Behaviour)component).enabled = false; _sourceSyncerDisabledByMod = true; LogVerbose("Disabled source CharacterSyncer while stashed."); } } catch (Exception ex) { LogVerbose("Failed to freeze source character network sync: " + ex.Message); } } private void ResumeSourceNetworkSync() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if ((!_sourceViewDisabledByMod && !_sourceViewSyncFrozenByMod && !_sourceSyncerDisabledByMod) || (Object)(object)_sourceCharacter == (Object)null) { return; } try { PhotonView photonView = ((MonoBehaviourPun)_sourceCharacter).photonView; if ((Object)(object)photonView != (Object)null) { if (_sourceViewDisabledByMod && !((Behaviour)photonView).enabled) { ((Behaviour)photonView).enabled = true; LogVerbose("Resumed source character network sync for restore."); } if (_sourceViewSyncFrozenByMod) { photonView.Synchronization = _sourceViewSynchronizationBackup; _sourceViewSyncFrozenByMod = false; } } if (_sourceSyncerDisabledByMod) { CharacterSyncer component = ((Component)_sourceCharacter).GetComponent<CharacterSyncer>(); if ((Object)(object)component != (Object)null && !((Behaviour)component).enabled) { ((Behaviour)component).enabled = true; LogVerbose("Re-enabled source CharacterSyncer for restore."); } _sourceSyncerDisabledByMod = false; } LogObjectPhotonViewState("resume-source", ((Component)_sourceCharacter).gameObject); LogPhotonViewDuplicateScan("after-resume-source"); _sourceViewDisabledByMod = false; } catch (Exception ex) { LogVerbose("Failed to resume source character network sync: " + ex.Message); } } private void ReaffirmSourceStashOverNetworkThrottled() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < _nextSourceStashReaffirmTime) { return; } _nextSourceStashReaffirmTime = Time.unscaledTime + 10f; if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)_sourceCharacter).photonView == (Object)null || (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode)) { return; } try { ((MonoBehaviourPun)_sourceCharacter).photonView.RPC("WarpPlayerRPC", (RpcTarget)1, new object[2] { _sourceStashPosition, false }); } catch (Exception ex) { LogVerbose("Failed to reaffirm source stash position: " + ex.Message); } } internal void PushSourceStashPositionToPlayer(Player player) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (player == null || (Object)(object)_sourceCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)_sourceCharacter).photonView == (Object)null || (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode)) { return; } try { ((MonoBehaviourPun)_sourceCharacter).photonView.RPC("WarpPlayerRPC", player, new object[2] { _sourceStashPosition, false }); _nextSourceStashReaffirmTime = Time.unscaledTime + 10f; LogVerbose("Pushed source stash position to joining player " + player.ActorNumber + "."); } catch (Exception ex) { LogVerbose("Failed to push source stash position to joining player: " + ex.Message); } } private void SendSourceCharacterRestore(Vector3 restorePosition) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendSourceCharacterStateRpc(restorePosition, "[I'm Scoutmaster] Failed to restore source character over network: "); } private void SendSourceCharacterStateRpc(Vector3 position, string warningPrefix) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)_sourceCharacter).photonView == (Object)null || (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode)) { return; } try { PhotonView photonView = ((MonoBehaviourPun)_sourceCharacter).photonView; photonView.RPC("RPCA_UnFall", (RpcTarget)1, Array.Empty<object>()); photonView.RPC("ReviveCharacter", (RpcTarget)1, new object[1] { false }); photonView.RPC("WarpPlayerRPC", (RpcTarget)1, new object[2] { position, false }); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)(warningPrefix + ex.Message)); } } } private void SuspendSourcePhysics() { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sourceCharacter == (Object)null || _sourceCharacter.refs?.ragdoll?.partList == null) { return; } try { if (!_sourcePhysicsSuspended) { _sourceBodypartPhysicsStates.Clear(); } foreach (Bodypart part in _sourceCharacter.refs.ragdoll.partList) { Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null); if (!((Object)(object)val == (Object)null)) { if (!_sourcePhysicsSuspended) { _sourceBodypartPhysicsStates.Add(new BodypartPhysicsState(val)); } if (!val.isKinematic) { val.linearVelocity = Vector3.zero; val.angularVelocity = Vector3.zero; } val.detectCollisions = false; val.useGravity = false; val.isKinematic = true; } } _sourcePhysicsSuspended = true; } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to suspend source physics: " + ex.Message)); } } } private void RestoreSourcePhysics() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (!_sourcePhysicsSuspended) { return; } try { foreach (BodypartPhysicsState sourceBodypartPhysicsState in _sourceBodypartPhysicsStates) { Rigidbody rig = sourceBodypartPhysicsState.Rig; if (!((Object)(object)rig == (Object)null)) { rig.isKinematic = sourceBodypartPhysicsState.IsKinematic; if (!rig.isKinematic) { rig.linearVelocity = Vector3.zero; rig.angularVelocity = Vector3.zero; } rig.detectCollisions = sourceBodypartPhysicsState.DetectCollisions; rig.useGravity = sourceBodypartPhysicsState.UseGravity; } } } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Failed to restore source physics: " + ex.Message)); } } finally { _sourceBodypartPhysicsStates.Clear(); _sourcePhysicsSuspended = false; } } private void KeepScoutmasterAwake() { if (!((Object)(object)_scoutmasterCharacter?.data == (Object)null)) { ClearScoutmasterAiState(_scoutmaster); SetCharacterDeadWithoutReconnect(_scoutmasterCharacter, dead: false); _scoutmasterCharacter.isScoutmaster = true; _scoutmasterCharacter.isZombie = false; _scoutmasterCharacter.data.isScoutmaster = true; _scoutmasterCharacter.data.zombified = false; if (!IsControlledScoutmasterIncapacitated(_scoutmasterCharacter)) { _scoutmasterCharacter.data.passedOut = false; _scoutmasterCharacter.data.fullyPassedOut = false; _scoutmasterCharacter.data.fallSeconds = 0f; _scoutmasterCharacter.data.currentRagdollControll = 1f; _scoutmasterCharacter.data.currentStamina = Mathf.Max(_scoutmasterCharacter.data.currentStamina, GetControlledStaminaFill()); _scoutmasterCharacter.data.extraStamina = 0f; ClearAssistJumpState(_scoutmasterCharacter); } } } private void KeepSourceOutOfPlay() { if (!((Object)(object)_sourceCharacter == (Object)null) && !((Object)(object)_sourceCharacter.data == (Object)null)) { if ((Object)(object)_sourceCharacter == (Object)(object)Character.localCharacter && (Object)(object)_scoutmasterCharacter != (Object)null) { Character.localCharacter = _scoutmasterCharacter; } SetCharacterDeadWithoutReconnect(_sourceCharacter, dead: false); _sourceCharacter.data.zombified = false; _sourceCharacter.data.passedOut = false; _sourceCharacter.data.fullyPassedOut = false; _sourceCharacter.data.fallSeconds = 0f; ClearAssistJumpState(_sourceCharacter); HideSourceRenderers(((Component)_sourceCharacter).gameObject); SuspendSourcePhysics(); ReaffirmSourceStashOverNetworkThrottled(); } } } private sealed class ImScoutmasterPrefabPool : IPunPrefabPool { private readonly IPunPrefabPool _inner; private static GameObject _cachedScoutmasterPrefab; private static GameObject _runtimePrefabRoot; private static bool _loggedMissingScoutmasterPrefab; private static GameObject _cachedCharacterPrefab; private static GameObject _runtimeCharacterPrefabRoot; private static bool _loggedMissingCharacterPrefab; public IPunPrefabPool Inner => _inner; public ImScoutmasterPrefabPool(IPunPrefabPool inner) { _inner = inner; } private static bool PruneStaleDefaultPoolResourceCache() { bool flag = false; try { Type typeFromHandle = typeof(DefaultPool); FieldInfo field = typeFromHandle.GetField("ResourceCache", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return false; } HashSet<object> hashSet = new HashSet<object>(); Queue<object> queue = new Queue<object>(); IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool; if (prefabPool != null) { queue.Enqueue(prefabPool); } while (queue.Count > 0) { object obj = queue.Dequeue(); if (obj == null || !hashSet.Add(obj)) { continue; } if (typeFromHandle.IsInstanceOfType(obj)) { flag |= PruneSingleDefaultPoolCache(field, obj); } Type type = obj.GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { object obj2 = null; try { obj2 = fieldInfo.GetValue(obj); } catch { } if (obj2 == null) { continue; } if (typeFromHandle.IsInstanceOfType(obj2)) { flag |= PruneSingleDefaultPoolCache(field, obj2); continue; } IPunPrefabPool val = (IPunPrefabPool)((obj2 is IPunPrefabPool) ? obj2 : null); if (val != null) { queue.Enqueue(val); } } PropertyInfo property = type.GetProperty("Inner", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(property != null)) { continue; } try { object? value = property.GetValue(obj); IPunPrefabPool val2 = (IPunPrefabPool)((value is IPunPrefabPool) ? value : null); if (val2 != null) { queue.Enqueue(val2); } } catch { } } } catch { } return flag; } private static bool PruneSingleDefaultPoolCache(FieldInfo resourceCacheField, object defaultPoolInstance) { try { if (resourceCacheField.GetValue(defaultPoolInstance) is IDictionary dictionary) { List<object> list = new List<object>(); foreach (DictionaryEntry item in dictionary) { object? value = item.Value; Object val = (Object)((value is Object) ? value : null); if (val != null && val == (Object)null) { list.Add(item.Key); } } foreach (object item2 in list) { dictionary.Remove(item2); } return list.Count > 0; } } catch { } return false; } public GameObject Instantiate(string prefabId, Vector3 position, Quaternion rotation) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) bool flag = string.Equals(prefabId, "Character", StringComparison.Ordinal); bool flag2 = string.Equals(prefabId, "Character_Scoutmaster", StringComparison.Ordinal); if (!flag && !flag2) { try { IPunPrefabPool inner = _inner; return (inner != null) ? inner.Instantiate(prefabId, position, rotation) : null; } catch (Exception ex) { if (!PruneStaleDefaultPoolResourceCache()) { throw; } ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("[I'm Scoutmaster] Pruned stale Photon prefab cache for '" + prefabId + "' after instantiate failure (" + ex.Message + "); retrying.")); } IPunPrefabPool inner2 = _inner; return (inner2 != null) ? inner2.Instantiate(prefabId, position, rotation) : null; } } GameObject val = null; try { IPunPrefabPool inner3 = _inner; val = ((inner3 != null) ? inner3.Instantiate(prefabId, position, rotation) : null); } catch (Exception ex2) { LogVerbose("Inner prefab pool failed to instantiate " + prefabId + ": " + ex2.Message); if (PruneStaleDefaultPoolResourceCache()) { try { IPunPrefabPool inner4 = _inner; val = ((inner4 != null) ? inner4.Instantiate(prefabId, position, rotation) : null); } catch (Exception ex3) { LogVerbose("Retry failed for " + prefabId + ": " + ex3.Message); } } } if ((Object)(object)val != (Object)null) { if (flag) { CacheCharacterPrefabBackup(val, "successful Character instantiation"); } else { CacheScoutmasterPrefabBackup(val, "successful Scoutmaster instantiation"); } LogObjectPhotonViewState("pool-instantiate(" + prefabId + ")", val); return val; } if (flag) { GameObject val2 = TryInstantiateCachedCharacterPrefab(position, rotation); if ((Object)(object)val2 != (Object)null) { return val2; } if (!_loggedMissingCharacterPrefab) { _loggedMissingCharacterPrefab = true; ManualLogSource log2 = Log; if (log2 != null) { log2.LogWarning((object)"[I'm Scoutmaster] Could not instantiate Character from any pool, Resources, or cached runtime backup."); } } return null; } GameObject val3 = ResolveScoutmasterPrefab(); if ((Object)(object)val3 == (Object)null) { if (!_loggedMissingScoutmasterPrefab) { _loggedMissingScoutmasterPrefab = true; ManualLogSource log3 = Log; if (log3 != null) { log3.LogWarning((object)"[I'm Scoutmaster] Could not resolve Character_Scoutmaster from the active prefab pool, Resources, or loaded Scoutmaster objects."); } } return null; } return InstantiatePrefabAsRuntimeObject(val3, position, rotation); } internal static GameObject ResolveScoutmasterPrefab() { if ((Object)(object)_cachedScoutmasterPrefab != (Object)null) { return _cachedScoutmasterPrefab; } _cachedScoutmasterPrefab = Resources.Load<GameObject>("Character_Scoutmaster"); if ((Object)(object)_cachedScoutmasterPrefab != (Object)null) { return _cachedScoutmasterPrefab; } try { Scoutmaster val = FindLoadedScoutmasterPrefabSource(); if ((Object)(object)val == (Object)null) { return null; } CacheScoutmasterPrefabBackup(((Component)val).gameObject, "loaded Scoutmaster object"); return _cachedScoutmasterPrefab; } catch (Exception ex) { LogVerbose("Failed to build Character_Scoutmaster runtime prefab backup: " + ex.Message); return null; } } internal static void CacheScoutmasterPrefabBackup(GameObject sourceObject, string reason) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown if ((Object)(object)_cachedScoutmasterPrefab != (Object)null || (Object)(object)sourceObject == (Object)null) { return; } try { if (IsRuntimeScoutmasterPrefabBackup(sourceObject)) { return; } Scoutmaster component = sourceObject.GetComponent<Scoutmaster>(); Character component2 = sourceObject.GetComponent<Character>(); PhotonView component3 = sourceObject.GetComponent<PhotonView>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null) && !((Object)(object)component3 == (Object)null)) { if ((Object)(object)_runtimePrefabRoot == (Object)null) { _runtimePrefabRoot = new GameObject("ImScoutmaster_RuntimePrefabRoot"); _runtimePrefabRoot.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_runtimePrefabRoot); } _cachedScoutmasterPrefab = Object.Instantiate<GameObject>(sourceObject, _runtimePrefabRoot.transform); ((Object)_cachedScoutmasterPrefab).name = "Character_Scoutmaster"; _cachedScoutmasterPrefab.SetActive(false); ResetPhotonViewsForPrefabBackup(_cachedScoutmasterPrefab); _loggedMissingScoutmasterPrefab = false; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("[I'm Scoutmaster] Registered runtime network prefab backup for Character_Scoutmaster from " + reason + ".")); } } } catch (Exception ex) { _cachedScoutmasterPrefab = null; LogVerbose("Failed to cache Character_Scoutmaster runtime prefab backup: " + ex.Message); } } private static Scoutmaster FindLoadedScoutmasterPrefabSource() { try { if (ScoutmasterAllScoutmastersField?.GetValue(null) is IEnumerable enumerable) { foreach (object item in enumerable) { Scoutmaster val = (Scoutmaster)((item is Scoutmaster) ? item : null); if (IsUsableScoutmasterPrefabSource(val, exactName: true)) { return val; } } foreach (object item2 in enumerable) { Scoutmaster val2 = (Scoutmaster)((item2 is Scoutmaster) ? item2 : null); if (IsUsableScoutmasterPrefabSource(val2, exactName: false)) { return val2; } } } } catch { } Scoutmaster[] array = Resources.FindObjectsOfTypeAll<Scoutmaster>(); Scoutmaster[] array2 = array; foreach (Scoutmaster val3 in array2) { if (IsUsableScoutmasterPrefabSource(val3, exactName: true)) { return val3; } } array2 = array; foreach (Scoutmaster val4 in array2) { if (IsUsableScoutmasterPrefabSource(val4, exactName: false)) { return val4; } } try { GameObject[] array3 = Resources.FindObjectsOfTypeAll<GameObject>(); foreach (GameObject val5 in array3) { if (!((Object)(object)val5 == (Object)null) && !IsRuntimeScoutmasterPrefabBackup(val5) && string.Equals(((Object)val5).name, "Character_Scoutmaster", StringComparison.Ordinal)) { Scoutmaster component = val5.GetComponent<Scoutmaster>(); if ((Object)(object)component != (Object)null && (Object)(object)val5.GetComponent<Character>() != (Object)null && (Object)(object)val5.GetComponent<PhotonView>() != (Object)null) { return component; } } } } catch { } return null; } private static bool IsUsableScoutmasterPrefabSource(Scoutmaster candidate, bool exactName) { if ((Object)(object)candidate == (Object)null || (Object)(object)((Component)candidate).gameObject == (Object)null || IsRuntimeScoutmasterPrefabBackup(((Component)candidate).gameObject)) { return false; } if (exactName && !string.Equals(((Object)((Component)candidate).gameObject).name, "Character_Scoutmaster", StringComparison.Ordinal) && !string.Equals(((Object)((Component)candidate).gameObject).name, "Character_Scoutmaster(Clone)", StringComparison.Ordinal)) { return false; } if ((Object)(object)((Component)candidate).GetComponent<Character>() != (Object)null) { return (Object)(object)((Component)candidate).GetComponent<PhotonView>() != (Object)null; } return false; } private static bool IsRuntimeScoutmasterPrefabBackup(GameObject obj) { if ((Object)(object)obj == (Object)null) { return false; } if ((Object)(object)_cachedScoutmasterPrefab != (Object)null && (Object)(object)obj == (Object)(object)_cachedScoutmasterPrefab) { return true; } Transform transform = obj.transform; if ((Object)(object)_runtimePrefabRoot != (Object)null && (Object)(object)transform != (Object)null) { if (!((Object)(object)transform == (Object)(object)_runtimePrefabRoot.transform)) { return transform.IsChildOf(_runtimePrefabRoot.transform); } return true; } return false; } private static void ResetPhotonViewsForPrefabBackup(GameObject backup) { PhotonView[] componentsInChildren = backup.GetComponentsInChildren<PhotonView>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].ViewID = 0; componentsInChildren[i].sceneViewId = 0; } } private static void CacheCharacterPrefabBackup(GameObject sourceInstance, string reason) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown if ((Object)(object)_cachedCharacterPrefab != (Object)null || (Object)(object)sourceInstance == (Object)null) { return; } try { if (!IsRuntimeCharacterPrefabBackup(sourceInstance) && !((Object)(object)sourceInstance.GetComponent<Character>() == (Object)null)) { if ((Object)(object)_runtimeCharacterPrefabRoot == (Object)null) { _runtimeCharacterPrefabRoot = new GameObject("ImScoutmaster_RuntimeCharacterPrefabRoot"); _runtimeCharacterPrefabRoot.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_runtimeCharacterPrefabRoot); } _cachedCharacterPrefab = Object.Instantiate<GameObject>(sourceInstance, _runtimeCharacterPrefabRoot.transform); ((Object)_cachedCharacterPrefab).name = "Character"; _cachedCharacterPrefab.SetActive(false); ResetPhotonViewsForPrefabBackup(_cachedCharacterPrefab); _loggedMissingCharacterPrefab = false; ManualLogSource log = Log; if (log != null) { log.LogInfo((object)("[I'm Scoutmaster] Cached runtime Character prefab backup from " + reason + ".")); } } } catch (Exception ex) { _cachedCharacterPrefab = null; LogVerbose("Failed to cache Character runtime prefab backup: " + ex.Message); } } private static bool IsRuntimeCharacterPrefabBackup(GameObject obj) { if ((Object)(object)obj == (Object)null) { return false; } if ((Object)(object)_cachedCharacterPrefab != (Object)null && (Object)(object)obj == (Object)(object)_cachedCharacterPrefab) { return true; } Transform transform = obj.transform; if ((Object)(object)_runtimeCharacterPrefabRoot != (Object)null && (Object)(object)transform != (Object)null) { if (!((Object)(object)transform == (Object)(object)_runtimeCharacterPrefabRoot.transform)) { return transform.IsChildOf(_runtimeCharacterPrefabRoot.transform); } return true; } return false; } internal static bool IsRuntimePrefabBackupObject(GameObject obj) { if (!IsRuntimeScoutmasterPrefabBackup(obj)) { return IsRuntimeCharacterPrefabBackup(obj); } return true; } private static GameObject TryInstantiateCachedCharacterPrefab(Vector3 position, Quaternion rotation) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_cachedCharacterPrefab != (Object)null) { GameObject val = InstantiatePrefabAsRuntimeObject(_cachedCharacterPrefab, position, rotation); if ((Object)(object)val != (Object)null) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)"[I'm Scoutmaster] Instantiated Character from cached runtime backup (small-exit recovery)."); } return val; } } GameObject val2 = Resources.Load<GameObject>("Character"); if ((Object)(object)val2 != (Object)null) { CacheCharacterPrefabBackup(val2, "Resources"); return InstantiatePrefabAsRuntimeObject(val2, position, rotation); } if (TryCaptureCharacterPrefabFromChain(out var prefab)) { CacheCharacterPrefabBackup(prefab, "prefab pool chain"); return InstantiatePrefabAsRuntimeObject(prefab, position, rotation); } return null; } private static bool TryCaptureCharacterPrefabFromChain(out GameObject prefab) { prefab = null; try { HashSet<object> hashSet = new HashSet<object>(); Queue<object> queue = new Queue<object>(); IPunPrefabPool prefabPool = PhotonNetwork.PrefabPool; if (prefabPool != null) { queue.Enqueue(prefabPool); } while (queue.Count > 0) { object obj = queue.Dequeue(); if (obj == null || !hashSet.Add(obj)) { continue; } Type type = obj.GetType(); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo fieldInfo in fields) { object value = null; try { value = fieldInfo.GetValue(fieldInfo.IsStatic ? null : obj); } catch { } if (TryUseCharacterPrefabPoolValue(value, queue, out prefab)) { return true; } } PropertyInfo[] properties = type.GetProperties(bindingAttr); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.GetIndexParameters().Length == 0 && propertyInfo.CanRead) { object value2 = null; try { MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true); value2 = propertyInfo.GetValue((getMethod != null && getMethod.IsStatic) ? null : obj); } catch { } if (TryUseCharacterPrefabPoolValue(value2, queue, out prefab)) { return true; } } } } } catch { } return false; } private static bool TryUseCharacterPrefabPoolValue(object value, Queue<object> pendingPools, out GameObject prefab) { prefab = null; if (value == null) { return false; } if (value is Dictionary<string, GameObject> dictionary && dictionary.TryGetValue("Character", out var value2) && IsUsableCharacterPrefabCandidate(value2)) { prefab = value2; return true; } if (value is IDictionary dictionary2 && dictionary2.Contains("Character") && IsUsableCharacterPrefabCandidate((GameObject)/*isinst with value type is only supported in some contexts*/)) { object? obj = dictionary2["Character"]; prefab = (GameObject)((obj is GameObject) ? obj : null); return true; } GameObject val = (GameObject)((value is GameObject) ? value : null); if (val != null && IsUsableCharacterPrefabCandidate(val)) { prefab = val; return true; } IPunPrefabPool val2 = (IPunPrefabPool)((value is IPunPrefabPool) ? value : null); if (val2 != null) { pendingPools.Enqueue(val2); } return false; } private static bool IsUsableCharacterPrefabCandidate(GameObject candidate) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)candidate == (Object)null || (Object)(object)candidate.GetComponent<Character>() == (Object)null) { return false; } if (IsRuntimeCharacterPrefabBackup(candidate)) { return true; } PhotonView component = candidate.GetComponent<PhotonView>(); bool flag = (Object)(object)component != (Object)null && component.ViewID > 0; Scene scene = candidate.scene; bool num = !((Scene)(ref scene)).IsValid(); bool flag2 = ((Object)candidate).name != null && ((Object)candidate).name.IndexOf("Backup", StringComparison.OrdinalIgnoreCase) >= 0; bool flag3 = !candidate.activeInHierarchy && !flag; return num || flag2 || flag3; } private static GameObject InstantiatePrefabAsRuntimeObject(GameObject prefab, Vector3 position, Quaternion rotation) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { return null; } bool activeSelf = prefab.activeSelf; if (activeSelf) { prefab.SetActive(false); } GameObject result = Object.Instantiate<GameObject>(prefab, position, rotation); if (activeSelf) { prefab.SetActive(true); } return result; } public void Destroy(GameObject gameObject) { IPunPrefabPool inner = _inner; if (inner != null) { inner.Destroy(gameObject); } } } public const string Id = "com.github.Thanks.ImScoutmaster"; public const string Name = "I'm Scoutmaster"; public const string Version = "0.7.14"; private const string ScoutmasterResourceName = "Character_Scoutmaster"; private const string CharacterResourceName = "Character"; private const float ToggleHoldSeconds = 1f; private const float ManualFallShortPressMaxSeconds = 0.3f; private const float ToggleDebounceSeconds = 0.35f; private const int SimplifiedChineseLanguageIndex = 9; private const string ControlsConfigSectionName = "Controls"; private const string ScoutmasterControlConfigSectionName = "Scoutmaster Control"; private const string CameraConfigSectionName = "Camera"; private const string PlayerRestoreConfigSectionName = "Player Restore"; private const string HudConfigSectionName = "HUD"; private const string DiagnosticsConfigSectionName = "Diagnostics"; private const string ModConfigPluginGuid = "com.github.PEAKModding.PEAKLib.ModConfig"; private const float ModConfigUiLocalizationIntervalSeconds = 0.25f; private const float CameraRestoreAssistSeconds = 0.4f; private const float CameraHealSeconds = 8f; private const float CameraHealMaxDistance = 100f; private const float CameraHealDefaultFieldOfView = 70f; private const float CameraPatrolIntervalSeconds = 0.5f; private const float CameraPatrolBackoffSeconds = 10f; private const int CameraPatrolMaxConsecutiveRepairs = 4; private const float ThirdPersonHeadTargetLiftMin = 0.35f; private const float ThirdPersonHeadTargetLiftMax = 1.35f; private const float ThirdPersonConfiguredTargetBlend = 0.25f; private const float ThirdPersonGroundMinHeight = 1.55f; private const float ThirdPersonCrouchGroundMinHeight = 1.15f; private const float ThirdPersonBodyFrameBlendStart = 0.45f; private const float ThirdPersonBodyFrameBlendFull = 0.95f; private const float ThirdPersonBodyFrameDownMaxBlend = 0.42f; private const float ThirdPersonBodyFrameUpMaxBlend = 0.3f; private const float ThirdPersonFocusForwardMin = 1.75f; private const float ThirdPersonFocusForwardMax = 4.25f; private const float ThirdPersonDownFocusDropMax = 1.15f; private const float ThirdPersonUpFocusLiftMax = 0.8f; private const float ThirdPartyCompatibilityRetryIntervalSeconds = 1f; private const float ClearBoostReticleTimer = 10f; private const float ControlledScoutmasterJumpVelocity = 10.5f; private const float ControlledScoutmasterJumpGroundClearance = 0.12f; private const float ControlledScoutmasterManualFallSeconds = 1.25f; private const float ControlledGrabAttachPointMaxHandDistance = 3.5f; private const string ControlledScoutmasterInstantiationMarker = "ImScoutmaster.ControlledScoutmaster"; private const int ControlledScoutmasterNetworkProtocol = 1; private const float PrefabPoolWrapperRetryIntervalSeconds = 0.5f; private const float ScoutmasterPrefabRetrySeconds = 8f; private const float ScoutmasterPrefabWarmIntervalSeconds = 2f; private static readonly BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly BindingFlags StaticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly PropertyInfo ConfigFileEntriesProperty = typeof(ConfigFile).GetProperty("Entries", InstanceFlags); private static readonly FieldInfo CharacterViewField = typeof(Character).GetField("view", InstanceFlags); private static readonly FieldInfo CharacterStartedField = typeof(Character).GetField("started", InstanceFlags); private static readonly FieldInfo CharacterSmoothedCamPosField = typeof(Character).GetField("smoothedCamPos", InstanceFlags); private static readonly MethodInfo CharacterGetBodypartMethod = typeof(Character).GetMethod("GetBodypart", InstanceFlags); private static readonly MethodInfo CharacterGetPartTypeMethod = typeof(Character).GetMethod("GetPartType", InstanceFlags); private static readonly FieldInfo CharacterDataCharacterField = typeof(CharacterData).GetField("character", InstanceFlags); private static readonly FieldInfo CharacterDataDeadField = typeof(CharacterData).GetField("_dead", InstanceFlags); private static readonly FieldInfo CharacterDataGrabbedPlayerField = typeof(CharacterData).GetField("grabbedPlayer", InstanceFlags); private static readonly MethodInfo CharacterFallMethod = typeof(Character).GetMethod("Fall", InstanceFlags, null, new Type[2] { typeof(float), typeof(float) }, null); private static readonly FieldInfo CharacterCustomizationCharacterField = typeof(CharacterCustomization).GetField("_character", InstanceFlags); private static readonly FieldInfo BodypartCharacterField = typeof(Bodypart).GetField("character", InstanceFlags); private static readonly FieldInfo ScoutmasterCurrentTargetField = typeof(Scoutmaster).GetField("_currentTarget", InstanceFlags); private static readonly FieldInfo ScoutmasterTargetForcedUntilField = typeof(Scoutmaster).GetField("targetForcedUntil", InstanceFlags); private static readonly FieldInfo ScoutmasterChillForSecondsField = typeof(Scoutmaster).GetField("chillForSeconds", InstanceFlags); private static readonly FieldInfo ScoutmasterIsThrowingField = typeof(Scoutmaster).GetField("isThrowing", InstanceFlags); private static readonly FieldInfo ScoutmasterAllScoutmastersField = typeof(Scoutmaster).GetField("AllScoutmasters", StaticFlags); private static readonly PropertyInfo MainCameraSpecCharacterProperty = typeof(MainCameraMovement).GetProperty("specCharacter", StaticFlags); private static readonly FieldInfo MainCameraIsSpectatingField = typeof(MainCameraMovement).GetField("isSpectating", InstanceFlags); private static readonly FieldInfo MainCameraRagdollCamField = typeof(MainCameraMovement).GetField("ragdollCam", InstanceFlags); private static readonly FieldInfo MainCameraCurrentForwardOffsetField = typeof(MainCameraMovement).GetField("currentForwardOffset", InstanceFlags); private static readonly FieldInfo MainCameraTargetPlayerPovPositionField = typeof(MainCameraMovement).GetField("targetPlayerPovPosition", InstanceFlags); private static readonly FieldInfo MainCameraPhysicsRotField = typeof(MainCameraMovement).GetField("physicsRot", InstanceFlags); private static readonly MethodInfo FindObjectsOfTypeByTypeMethod = typeof(Object).GetMethod("FindObjectsOfType", new Type[1] { typeof(Type) }); private static readonly MethodInfo CharacterClimbingCanClimbMethod = typeof(CharacterClimbing).GetMethod("CanClimb", InstanceFlags, null, Type.EmptyTypes, null); private static readonly MethodInfo CharacterClimbingStartClimbRpcMethod = FindCharacterClimbingStartClimbRpcMethod(); private static readonly FieldInfo CharacterClimbingClimbToggledOnField = typeof(CharacterClimbing).GetField("climbToggledOn", InstanceFlags); private static readonly FieldInfo CharacterClimbingSinceLastClimbStartedField = typeof(CharacterClimbing).GetField("sinceLastClimbStarted", InstanceFlags); private static readonly FieldInfo CharacterClimbingPlayerSlideField = typeof(CharacterClimbing).GetField("playerSlide", InstanceFlags); private static readonly FieldInfo CharacterClimbingPlayerSlideFieldRenamed = typeof(CharacterClimbing).GetField("_playerSlide", InstanceFlags); private static readonly PropertyInfo CharacterClimbingPlayerSlideProperty = typeof(CharacterClimbing).GetProperty("playerSlide", InstanceFlags); private static readonly MethodInfo CharacterGrabbingGrabAttachMethod = typeof(CharacterGrabbing).GetMethod("RPCA_GrabAttach", InstanceFlags); private static readonly PropertyInfo PlayerHandlerInstanceProperty = typeof(PlayerHandler).GetProperty("Instance", StaticFlags); private static readonly FieldInfo PlayerHandlerCharacterLookupField = typeof(PlayerHandler).GetField("m_playerCharacterLookup", InstanceFlags); private static readonly FieldInfo CharacterItemsCurrentSelectedSlotField = typeof(CharacterItems).GetField("currentSelectedSlot", InstanceFlags); private static readonly FieldInfo CharacterItemsLastSelectedSlotField = typeof(CharacterItems).GetField("lastSelectedSlot", InstanceFlags); private static readonly FieldInfo CharacterAfflictionsCharacterField = typeof(CharacterAfflictions).GetField("character", InstanceFlags); private static readonly object CharacterItemsNoneSlotValue = CreateOptionableNoneValue(CharacterItemsCurrentSelectedSlotField?.FieldType); private static FieldInfo PeakStatsStaminaBarsField; private static FieldInfo PeakStatsObservedCharacterField; private static FieldInfo PeakStatsAfflictionBarField; private static Type PeakStatsStaminaBarType; private static Type PeakStatsAfflictionType; private static float _peakStatsCleanupGraceUntil; private static bool _skipControlledCharacterFixedUpdate; private bool _characterFixedUpdateCompatibilityConfigured; private bool _loggedWaitingForPeakerHook; private bool _loggedPeakStatsTypesMissing; private float _nextPeakerGuardAttemptTime; private bool _peakStatsCompatibilityConfigured; private float _nextThirdPartyCompatibilityAttemptTime; private static ImScoutmasterPrefabPool _prefabPoolWrapper; private static float _nextPrefabPoolWrapperEnsureTime; private static bool _scoutmasterPhysicsWarmedUp; private static float _nextScoutmasterPrefabWarmTime; private readonly Harmony _harmony = new Harmony("com.github.Thanks.ImScoutmaster"); private ActiveScoutmasterSession _session; private bool _switching; private float _lastToggleTime; private float _toggleHoldStartTime = -1f; private bool _toggleHoldTriggered; private bool _lastDetectedChineseLanguage; private bool _isRefreshingLanguage; private bool _pendingConfigFileLocalizationRefresh; private bool _pendingConfigFileLocalizationSave; private float _nextModConfigUiLocalizationTime; private static Transform _controlledScoutmasterCreationRoot; private static readonly HashSet<int> _controlledScoutmasterInstanceIds = new HashSet<int>(); private static readonly HashSet<int> _controlledScoutmasterViewIds = new HashSet<int>(); private static readonly HashSet<int> _controlledScoutmasterCharacterInstanceIds = new HashSet<int>(); private static readonly Dictionary<int, int> _controlledScoutmasterOwnerActorNumbersByViewId = new Dictionary<int, int>(); private static readonly Dictionary<int, Character> _controlledScoutmasterByOwnerActorNumber = new Dictionary<int, Character>(); private static readonly HashSet<int> _stashedSourceCharacterIds = new HashSet<int>(); private static readonly Dictionary<int, RendererVisualState> _rendererVisualStates = new Dictionary<int, RendererVisualState>(); private static readonly Dictionary<int, RendererVisualState> _sourceRendererVisualStates = new Dictionary<int, RendererVisualState>(); private static readonly Dictionary<int, bool> _sourceLightVisualStates = new Dictionary<int, bool>(); private static Character _cameraOverrideCharacter; private static Character _cameraRestoreCharacter; private static float _cameraRestoreUntil; private static float _cameraHealUntil; private static float _nextCameraPatrolTime; private static int _cameraPatrolConsecutiveRepairs; private static Character _lastCameraPatrolCharacter; private static GameObject _viewScoutmasterObject; private static bool _hasSmoothedThirdPersonCameraPose; private static Vector3 _smoothedThirdPersonCameraPosition; private static Quaternion _smoothedThirdPersonCameraRotation = Quaternion.identity; private static GameObject _hudCanvasObject; private static GameObject _namesCanvasObject; private static bool _hudPreviousKnown; private static bool _namesPreviousKnown; private static bool _hudPreviousActive; private static bool _namesPreviousActive; private static bool _hudHiddenForScoutmaster; private const float MaxTransformGroundProbeDistance = 40f; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static ConfigEntry<KeyCode> ToggleKey { get; private set; } internal static ConfigEntry<float> StaminaRefill { get; private set; } internal static ConfigEntry<float> ThrowForce { get; private set; } internal static ConfigEntry<float> ThrowUpBias { get; private set; } internal static ConfigEntry<float> ThrowFallSeconds { get; private set; } internal static ConfigEntry<float> ThrowMaxDistance { get; private set; } internal static ConfigEntry<float> ThirdPersonHeightOffset { get; private set; } internal static ConfigEntry<float> ThirdPersonDistance { get; private set; } internal static ConfigEntry<float> SourceStashDistance { get; private set; } internal static ConfigEntry<bool> RestoreAtScoutmasterPosition { get; private set; } internal static ConfigEntry<float> RestoreGroundOffset { get; private set; } internal static ConfigEntry<bool> HideHudWhileTransformed { get; private set; } internal static ConfigEntry<bool> VerboseLogs { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; _lastDetectedChineseLanguage = DetectChineseLanguage(); BindConfig(_lastDetectedChineseLanguage); RegisterConfigChangeHandlers(); MarkConfigFileLocalizationDirty(saveConfigFile: true); PatchHarmonyTolerantly(); ConfigureCharacterFixedUpdateCompatibility(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm Scoutmaster] Loaded version 0.7.14."); ((BaseUnityPlugin)this).Logger.LogInfo((object)("[I'm Scoutmaster] Config language: " + BuildLanguageDetectionSummary(_lastDetectedChineseLanguage))); ValidateReflectionMembers(); PhotonNetwork.AddCallbackTarget((object)this); } private void PatchHarmonyTolerantly() { int num = 0; int num2 = 0; Type[] types = typeof(ScoutmasterHarmonyPatches).Assembly.GetTypes(); foreach (Type type in types) { if (type == null || !type.IsClass || (type.IsAbstract && !type.IsSealed) || !type.IsDefined(typeof(HarmonyPatch), inherit: false)) { continue; } try { _harmony.CreateClassProcessor(type).Patch(); num++; } catch (Exception ex) { num2++; ManualLogSource logger = ((BaseUnityPlugin)