using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Rewired; using RoR2.CameraModes; using RoR2.UI; using Unity; using UnityEngine; using UnityEngine.Networking; namespace RoR2; [RequireComponent(typeof(CharacterMaster))] [RequireComponent(typeof(PingerController))] public class PlayerCharacterMasterController : NetworkBehaviour { private static List _instances; private static ReadOnlyCollection _instancesReadOnly; private CharacterBody body; private InputBankTest bodyInputs; private CharacterMotor bodyMotor; private GameObject previousBodyObject; [CompilerGenerated] private string _003CfinalMessageTokenServer_003Ek__BackingField; private PingerController pingerController; [SyncVar(hook = "OnSyncNetworkUserInstanceId")] private NetworkInstanceId networkUserInstanceId; private GameObject resolvedNetworkUserGameObjectInstance; private bool networkUserResolved; private NetworkUser resolvedNetworkUserInstance; private bool alreadyLinkedToNetworkUserOnce; public float cameraMinPitch = -70f; public float cameraMaxPitch = 70f; public GameObject crosshair; public Vector3 crosshairPosition; private NetworkIdentity netid; private static readonly float sprintMinAimMoveDot; private bool sprintInputPressReceived; private bool wasClaimed; private float lunarCoinChanceMultiplier = 0.5f; private static int kRpcRpcOnLinkedToNetworkUser; private static int kRpcRpcIncrementRunCount; public static ReadOnlyCollection instances => _instancesReadOnly; private bool bodyIsFlier { get { if ((bool)bodyMotor) { return bodyMotor.isFlying; } return true; } } public CharacterMaster master { get; private set; } private NetworkIdentity networkIdentity => master.networkIdentity; public string finalMessageTokenServer { [Server] [CompilerGenerated] get { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.String RoR2.PlayerCharacterMasterController::get_finalMessageTokenServer()' called on client"); return null; } return _003CfinalMessageTokenServer_003Ek__BackingField; } [Server] [CompilerGenerated] set { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.PlayerCharacterMasterController::set_finalMessageTokenServer(System.String)' called on client"); } else { _003CfinalMessageTokenServer_003Ek__BackingField = value; } } } = string.Empty; public bool hasEffectiveAuthority => master.hasEffectiveAuthority; public GameObject networkUserObject { get { if (!networkUserResolved) { resolvedNetworkUserGameObjectInstance = Util.FindNetworkObject(networkUserInstanceId); resolvedNetworkUserInstance = null; if ((bool)resolvedNetworkUserGameObjectInstance) { resolvedNetworkUserInstance = resolvedNetworkUserGameObjectInstance.GetComponent(); networkUserResolved = true; SetBodyPrefabToPreference(); } } return resolvedNetworkUserGameObjectInstance; } private set { NetworkInstanceId invalid = NetworkInstanceId.Invalid; resolvedNetworkUserGameObjectInstance = null; resolvedNetworkUserInstance = null; networkUserResolved = true; if ((bool)value) { NetworkIdentity component = value.GetComponent(); if ((bool)component) { invalid = component.netId; resolvedNetworkUserGameObjectInstance = value; resolvedNetworkUserInstance = value.GetComponent(); SetBodyPrefabToPreference(); } } NetworknetworkUserInstanceId = invalid; } } public NetworkUser networkUser { get { if (!networkUserObject) { return null; } return resolvedNetworkUserInstance; } } public bool isConnected => networkUserObject; public bool preventGameOver => master.preventGameOver; public NetworkInstanceId NetworknetworkUserInstanceId { get { return networkUserInstanceId; } [param: In] set { if (NetworkServer.localClientActive && !base.syncVarHookGuard) { base.syncVarHookGuard = true; OnSyncNetworkUserInstanceId(value); base.syncVarHookGuard = false; } SetSyncVar(value, ref networkUserInstanceId, 1u); } } public event Action onLinkedToNetworkUserServer; public static event Action onPlayerAdded; public static event Action onPlayerRemoved; public static event Action onLinkedToNetworkUserServerGlobal; public static event Action onLinkedToNetworkUserLocal; private void OnSyncNetworkUserInstanceId(NetworkInstanceId value) { resolvedNetworkUserGameObjectInstance = null; resolvedNetworkUserInstance = null; networkUserResolved = value == NetworkInstanceId.Invalid; NetworknetworkUserInstanceId = value; } [Server] public void LinkToNetworkUserServer(NetworkUser networkUser) { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.PlayerCharacterMasterController::LinkToNetworkUserServer(RoR2.NetworkUser)' called on client"); return; } networkUser.masterObject = base.gameObject; networkUserObject = networkUser.gameObject; networkIdentity.AssignClientAuthority(networkUser.connectionToClient); if (!alreadyLinkedToNetworkUserOnce) { networkUser.CopyLoadoutToMaster(); alreadyLinkedToNetworkUserOnce = true; } else { networkUser.CopyLoadoutFromMaster(); } SetBodyPrefabToPreference(); this.onLinkedToNetworkUserServer?.Invoke(); PlayerCharacterMasterController.onLinkedToNetworkUserServerGlobal?.Invoke(this); HandleLinkedToNetworkUser(networkUser.id); CallRpcOnLinkedToNetworkUser(networkUser.id); } [ClientRpc] private void RpcOnLinkedToNetworkUser(NetworkUserId id) { HandleLinkedToNetworkUser(id); } private void HandleLinkedToNetworkUser(NetworkUserId id) { foreach (LocalUser readOnlyLocalUsers in LocalUserManager.readOnlyLocalUsersList) { if ((bool)readOnlyLocalUsers.currentNetworkUser && readOnlyLocalUsers.currentNetworkUser.id.Equals(id)) { PlayerCharacterMasterController.onLinkedToNetworkUserLocal?.Invoke(this); break; } } } private void Awake() { master = GetComponent(); netid = GetComponent(); pingerController = GetComponent(); } private void OnEnable() { _instances.Add(this); if (PlayerCharacterMasterController.onPlayerAdded != null) { PlayerCharacterMasterController.onPlayerAdded(this); } NetworkUser.onNetworkUserBodyPreferenceChanged += OnNetworkUserBodyPreferenceChanged; } private void OnDisable() { _instances.Remove(this); if (PlayerCharacterMasterController.onPlayerRemoved != null) { PlayerCharacterMasterController.onPlayerRemoved(this); } NetworkUser.onNetworkUserBodyPreferenceChanged -= OnNetworkUserBodyPreferenceChanged; } private void Start() { if (NetworkServer.active && (bool)networkUser) { CallRpcIncrementRunCount(); } } [ClientRpc] private void RpcIncrementRunCount() { if ((bool)networkUser) { LocalUser localUser = networkUser.localUser; if (localUser != null) { localUser.userProfile.totalRunCount++; } } } private static bool CanSendBodyInput(NetworkUser networkUser, out LocalUser localUser, out Player inputPlayer, out CameraRigController cameraRigController, out bool onlyAllowMovement) { if (!networkUser) { localUser = null; inputPlayer = null; cameraRigController = null; onlyAllowMovement = false; return false; } localUser = networkUser.localUser; inputPlayer = networkUser.inputPlayer; cameraRigController = networkUser.cameraRigController; onlyAllowMovement = false; if (localUser == null || inputPlayer == null || !cameraRigController) { return false; } if (localUser.isUIFocused) { UIInputPassthrough uIPassthrough = localUser.GetUIPassthrough(); if (!uIPassthrough) { return false; } onlyAllowMovement = uIPassthrough.OnlyAllowMovement; } if (!cameraRigController.isControlAllowed) { return false; } return true; } private void Update() { if (!hasEffectiveAuthority) { return; } SetBody(master.GetBodyObject()); if (!bodyInputs) { return; } Vector3 moveVector = Vector3.zero; Vector3 aimDirection = bodyInputs.aimDirection; if (CanSendBodyInput(networkUser, out var _, out var inputPlayer, out var cameraRigController, out var _)) { Transform transform = cameraRigController.transform; sprintInputPressReceived |= inputPlayer.GetButtonDown(18); Vector2 vector = new Vector2(inputPlayer.GetAxis(0), inputPlayer.GetAxis(1)); Vector2 vector2 = new Vector2(inputPlayer.GetAxis(12), inputPlayer.GetAxis(13)); bodyInputs.SetRawMoveStates(vector + vector2); float sqrMagnitude = vector.sqrMagnitude; if (sqrMagnitude > 1f) { vector /= Mathf.Sqrt(sqrMagnitude); } if (bodyIsFlier) { moveVector = transform.right * vector.x + transform.forward * vector.y; } else { float y = transform.eulerAngles.y; moveVector = Quaternion.Euler(0f, y, 0f) * new Vector3(vector.x, 0f, vector.y); } aimDirection = (cameraRigController.crosshairWorldPosition - bodyInputs.aimOrigin).normalized; } bodyInputs.moveVector = moveVector; bodyInputs.aimDirection = aimDirection; } private void FixedUpdate() { if (hasEffectiveAuthority && (bool)bodyInputs) { PollButtonInput(); CheckPinging(); } } private void PollButtonInput() { bool newState = false; bool newState2 = false; bool newState3 = false; bool newState4 = false; bool newState5 = false; bool newState6 = false; bool newState7 = false; bool newState8 = false; bool newState9 = false; if (CanSendBodyInput(networkUser, out var _, out var inputPlayer, out var _, out var _)) { bool flag = false; flag = body.isSprinting; if (sprintInputPressReceived) { sprintInputPressReceived = false; flag = !flag; } if (flag) { Vector3 aimDirection = bodyInputs.aimDirection; aimDirection.y = 0f; aimDirection.Normalize(); Vector3 moveVector = bodyInputs.moveVector; moveVector.y = 0f; moveVector.Normalize(); if ((body.bodyFlags & CharacterBody.BodyFlags.SprintAnyDirection) == 0 && Vector3.Dot(aimDirection, moveVector) < sprintMinAimMoveDot) { flag = false; } } newState = inputPlayer.GetButton(7); newState2 = inputPlayer.GetButton(8); newState3 = inputPlayer.GetButton(9); newState4 = inputPlayer.GetButton(10); newState5 = inputPlayer.GetButton(5); newState6 = inputPlayer.GetButton(4); newState7 = flag; newState8 = inputPlayer.GetButton(6); newState9 = inputPlayer.GetButton(28); } bodyInputs.skill1.PushState(newState); bodyInputs.skill2.PushState(newState2); bodyInputs.skill3.PushState(newState3); bodyInputs.skill4.PushState(newState4); bodyInputs.interact.PushState(newState5); bodyInputs.jump.PushState(newState6); bodyInputs.sprint.PushState(newState7); bodyInputs.activateEquipment.PushState(newState8); bodyInputs.ping.PushState(newState9); } public void RedirectCamera(Vector3 desiredRotation) { if (CanSendBodyInput(networkUser, out var _, out var _, out var cameraRigController, out var _)) { CameraState cameraStateToMatch = cameraRigController.currentCameraState; cameraStateToMatch.rotation = Quaternion.Euler(desiredRotation.x, desiredRotation.y, desiredRotation.z); CameraModeBase.CameraModeContext context = default(CameraModeBase.CameraModeContext); context.cameraInfo.cameraRigController = cameraRigController; cameraRigController.cameraMode?.MatchState(in context, in cameraStateToMatch); } } private void CheckPinging() { if (hasEffectiveAuthority && (bool)body && (bool)bodyInputs && bodyInputs.ping.justPressed) { pingerController.AttemptPing(new Ray(bodyInputs.aimOrigin, bodyInputs.aimDirection), body.gameObject); } } public string GetDisplayName() { string result = ""; if ((bool)networkUserObject) { NetworkUser component = networkUserObject.GetComponent(); if ((bool)component) { result = component.userName; } } return result; } private void SetBody(GameObject newBody) { if ((bool)newBody) { body = newBody.GetComponent(); } else { body = null; } if ((bool)body) { bodyInputs = body.inputBank; bodyMotor = body.characterMotor; } else { bodyInputs = null; bodyMotor = null; } } [Server] public void OnBodyDeath() { if (!NetworkServer.active) { Debug.LogWarning("[Server] function 'System.Void RoR2.PlayerCharacterMasterController::OnBodyDeath()' called on client"); } } public void OnBodyStart() { if (NetworkServer.active) { finalMessageTokenServer = string.Empty; } } public static int GetPlayersWithBodiesCount() { int num = 0; foreach (PlayerCharacterMasterController instance in _instances) { if (instance.master.hasBody) { num++; } } return num; } [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)] private static void Init() { GlobalEventManager.onCharacterDeathGlobal += delegate(DamageReport damageReport) { CharacterMaster characterMaster = damageReport.attackerMaster; if ((bool)characterMaster) { if ((bool)characterMaster.minionOwnership.ownerMaster) { characterMaster = characterMaster.minionOwnership.ownerMaster; } PlayerCharacterMasterController component = characterMaster.GetComponent(); if ((bool)component && Util.CheckRoll(1f * component.lunarCoinChanceMultiplier)) { PickupDropletController.CreatePickupDroplet(PickupCatalog.FindPickupIndex(RoR2Content.MiscPickups.LunarCoin.miscPickupIndex), damageReport.victim.transform.position, Vector3.up * 10f); component.lunarCoinChanceMultiplier *= 0.5f; } } }; } private void SetBodyPrefabToPreference() { master.bodyPrefab = BodyCatalog.GetBodyPrefab(networkUser.bodyIndexPreference); if (!master.bodyPrefab) { Debug.LogError($"SetBodyPrefabToPreference failed to find a body prefab for index '{networkUser.bodyIndexPreference}'. Reverting to backup: {master.backupBodyIndex}"); master.bodyPrefab = BodyCatalog.GetBodyPrefab(master.backupBodyIndex); if (!master.bodyPrefab) { Debug.LogError($"SetBodyPrefabToPreference backup ({master.backupBodyIndex}) failed."); } } } private void OnNetworkUserBodyPreferenceChanged(NetworkUser networkUser) { if ((bool)this.networkUser && networkUser.netId.Value == this.networkUser.netId.Value) { SetBodyPrefabToPreference(); } } static PlayerCharacterMasterController() { _instances = new List(); _instancesReadOnly = new ReadOnlyCollection(_instances); sprintMinAimMoveDot = Mathf.Cos(MathF.PI / 3f); kRpcRpcOnLinkedToNetworkUser = 585837834; NetworkBehaviour.RegisterRpcDelegate(typeof(PlayerCharacterMasterController), kRpcRpcOnLinkedToNetworkUser, InvokeRpcRpcOnLinkedToNetworkUser); kRpcRpcIncrementRunCount = 1915650359; NetworkBehaviour.RegisterRpcDelegate(typeof(PlayerCharacterMasterController), kRpcRpcIncrementRunCount, InvokeRpcRpcIncrementRunCount); NetworkCRC.RegisterBehaviour("PlayerCharacterMasterController", 0); } private void UNetVersion() { } protected static void InvokeRpcRpcOnLinkedToNetworkUser(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkClient.active) { Debug.LogError("RPC RpcOnLinkedToNetworkUser called on server."); } else { ((PlayerCharacterMasterController)obj).RpcOnLinkedToNetworkUser(GeneratedNetworkCode._ReadNetworkUserId_None(reader)); } } protected static void InvokeRpcRpcIncrementRunCount(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkClient.active) { Debug.LogError("RPC RpcIncrementRunCount called on server."); } else { ((PlayerCharacterMasterController)obj).RpcIncrementRunCount(); } } public void CallRpcOnLinkedToNetworkUser(NetworkUserId id) { if (!NetworkServer.active) { Debug.LogError("RPC Function RpcOnLinkedToNetworkUser called on client."); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)2); networkWriter.WritePackedUInt32((uint)kRpcRpcOnLinkedToNetworkUser); networkWriter.Write(GetComponent().netId); GeneratedNetworkCode._WriteNetworkUserId_None(networkWriter, id); SendRPCInternal(networkWriter, 0, "RpcOnLinkedToNetworkUser"); } public void CallRpcIncrementRunCount() { if (!NetworkServer.active) { Debug.LogError("RPC Function RpcIncrementRunCount called on client."); return; } NetworkWriter networkWriter = new NetworkWriter(); networkWriter.Write((short)0); networkWriter.Write((short)2); networkWriter.WritePackedUInt32((uint)kRpcRpcIncrementRunCount); networkWriter.Write(GetComponent().netId); SendRPCInternal(networkWriter, 0, "RpcIncrementRunCount"); } public override bool OnSerialize(NetworkWriter writer, bool forceAll) { if (forceAll) { writer.Write(networkUserInstanceId); return true; } bool flag = false; if ((base.syncVarDirtyBits & (true ? 1u : 0u)) != 0) { if (!flag) { writer.WritePackedUInt32(base.syncVarDirtyBits); flag = true; } writer.Write(networkUserInstanceId); } if (!flag) { writer.WritePackedUInt32(base.syncVarDirtyBits); } return flag; } public override void OnDeserialize(NetworkReader reader, bool initialState) { if (initialState) { networkUserInstanceId = reader.ReadNetworkId(); return; } int num = (int)reader.ReadPackedUInt32(); if (((uint)num & (true ? 1u : 0u)) != 0) { OnSyncNetworkUserInstanceId(reader.ReadNetworkId()); } } public override void PreStartClient() { } }