public override void OnRPCCommand(NetworkPlayer player, string command) { base.OnRPCCommand(player, command); NetworkRPC rpc = NetworkRPC.FromString(command); switch (rpc.m_Type) { case NetworkRPCType.RPC_CUSTOM_PLAYER: { NetworkPlayerRPC playerRPC = NetworkRPC.Parse <NetworkPlayerRPC>(command); GameObject obj = NetworkManager.Instance.GetNetworkedObject(playerRPC.m_NetworkId); if (PlayerHasAuthority(obj, player)) { if (playerRPC.m_Health != -1) { ELogger.Log($"{playerRPC.m_NetworkId} is trying to edit their health to {playerRPC.m_Health}!", ELogger.LogType.Server); break; } playerRPC.m_Health = obj.GetComponent <Player>().m_Health; // Set it to the server health obj.GetComponent <Player>().UpdateColor(playerRPC.m_Color); UpdateRPC(obj, playerRPC); SendRPCAll(playerRPC); } } break; } }
/// <summary> /// An optional way to receive any extra RPC commands. /// Can be used to update things like health, active gun, animation (maybe done by library later), etc /// Note, all calls are sent from the server never another client. So things like health can be checked via the server and not here /// </summary> /// <param name="content">The content of the rpc we received. See example below to understand more</param> public override void OnRPCCommand(string content) { base.OnRPCCommand(content); NetworkRPC rpc = NetworkRPC.FromString(content); switch (rpc.m_Type) { case NetworkRPCType.RPC_CUSTOM_PLAYER: { NetworkPlayerRPC playerRPC = NetworkRPC.Parse <NetworkPlayerRPC>(content); UpdateColor(playerRPC.m_Color); m_Health = playerRPC.m_Health; } break; } }
/// <summary> /// Triggers an RPC command on the server /// </summary> /// <param name="command">The raw json command</param> public virtual void OnRPCCommand(NetworkPlayer player, string command) { NetworkRPC rpc = NetworkRPC.FromString(command); switch (rpc.m_Type) { case NetworkRPCType.RPC_LIB_SPAWN: // TODO: Clean this up if at all possible? { NetworkSpawnRPC spawnRPC = NetworkRPC.Parse <NetworkSpawnRPC>(command); GameObject spawnPrefab = NetworkManager.Instance.GetObjectByIndex(spawnRPC.m_PrefabIndex); GameObject prefab = Instantiate(spawnPrefab); NetworkBehaviour networkBehaviour = prefab.GetComponent <NetworkBehaviour>(); NetworkObjectServerInfo serverInfo = prefab.AddComponent <NetworkObjectServerInfo>(); int id = AddObjectToNetwork(prefab); spawnRPC.m_NetworkId = id; networkBehaviour.m_Spawner = (spawnRPC.m_PrefabIndex == -1) ? id : player.m_NetworkId; serverInfo.m_PrefabIndex = spawnRPC.m_PrefabIndex; SendRPC(spawnRPC, player); if (spawnRPC.m_PrefabIndex == -1) { player.m_NetworkId = id; NetworkPlayerConnectRPC connectRPC = new NetworkPlayerConnectRPC(player, -1); SendRPCAll(connectRPC); OnPlayerConnected(player); } if (spawnRPC.m_RequestAuthority) { serverInfo.AddAuthority(player); } NetworkAuthorizationRPC authRPC = new NetworkAuthorizationRPC(true, IsPlayerServer(player), spawnRPC.m_RequestAuthority, id); SendRPC(authRPC, player); OnNetworkObjectCreated(prefab, player); } break; case NetworkRPCType.RPC_LIB_DESTROY: { GameObject obj = NetworkManager.Instance.GetNetworkedObject(rpc.m_NetworkId); if (PlayerHasAuthority(obj, player)) { OnNetworkObjectDestroyed(obj, player); Destroy(obj); SendRPCAll(rpc); } } break; case NetworkRPCType.RPC_LIB_TRANSFORM: { NetworkTransformRPC transformRPC = NetworkRPC.Parse <NetworkTransformRPC>(command); GameObject obj = NetworkManager.Instance.GetNetworkedObject(transformRPC.m_NetworkId); if (PlayerHasAuthority(obj, player)) { // Do any checks on the data here, such as being out of bounds, etc if (!IsPlayerServer(player)) // We dont need to update info we already have { obj.transform.position = transformRPC.m_Position; obj.transform.eulerAngles = transformRPC.m_Rotation; obj.transform.localScale = transformRPC.m_Scale; } UpdateRPC(obj, transformRPC); SendRPCAll(transformRPC, new List <string>() { player.m_Id }); // Probably should add a exclude to this so we dont send it to ourselves? Idk } } break; case NetworkRPCType.RPC_LIB_DISCONNECTED: { NetworkPlayerDisconnctRPC disconnctRPC = NetworkRPC.Parse <NetworkPlayerDisconnctRPC>(command); if (disconnctRPC.m_Player.m_Id == player.m_Id) { // Disconnection checks? RemovePlayer(player, disconnctRPC.m_Reason, disconnctRPC.m_DisconnectType, true); } else { // Authoratative admin checks later : TODO // This is literally terrible, this would just kick the player who is trying to kick. // Make a proper "kick" rpc or add some property into the disconnect rpc RemovePlayer(player, $"Kicked by: {player.m_Name}", NetworkDisconnectType.Kick, true); } } break; } }
/// <summary> /// Send a RPC command to a specified network id /// </summary> /// <param name="rpc">The RPC being sent throughout the network</param> public void OnRPCCommand(string content) { NetworkRPC rpc = NetworkRPC.FromString(content); switch (rpc.m_Type) // If a type is handled here its because it needs to be here, or the networking wont function properly { case NetworkRPCType.RPC_LIB_SPAWN: { if (NetworkManager.Instance.IsMixed()) { break; // We already have it spawned for us } NetworkSpawnRPC spawnRPC = NetworkRPC.Parse <NetworkSpawnRPC>(content); if (NetworkManager.Instance.GetNetworkedObject(spawnRPC.m_NetworkId) != null) { break; } GameObject spawnPrefab = NetworkManager.Instance.GetObjectByIndex(spawnRPC.m_PrefabIndex); if (spawnPrefab == null) { break; } GameObject prefab = Instantiate(spawnPrefab); NetworkBehaviour networkBehaviour = prefab.GetComponent <NetworkBehaviour>(); networkBehaviour.m_IsServer = false; networkBehaviour.m_HasAuthority = false; networkBehaviour.m_IsClient = true; prefab.GetComponent <NetworkIdentity>().m_NetworkId = spawnRPC.m_NetworkId; NetworkManager.Instance.AddObject(spawnRPC.m_NetworkId, prefab); } break; case NetworkRPCType.RPC_LIB_OBJECT_NETAUTH: { NetworkAuthorizationRPC authorizationRPC = NetworkRPC.Parse <NetworkAuthorizationRPC>(content); GameObject gameObject = NetworkManager.Instance.GetNetworkedObject(authorizationRPC.m_NetworkId); if (gameObject != null) { NetworkBehaviour networkBehaviour = gameObject.GetComponent <NetworkBehaviour>(); networkBehaviour.m_IsClient = authorizationRPC.m_LocalSet; networkBehaviour.m_HasAuthority = authorizationRPC.m_LocalAuthSet; networkBehaviour.m_IsServer = authorizationRPC.m_ServerSet; gameObject.GetComponent <NetworkIdentity>().m_NetworkId = authorizationRPC.m_NetworkId; networkBehaviour.OnAuthorityChanged(networkBehaviour.m_HasAuthority); } } break; case NetworkRPCType.RPC_LIB_DESTROY: { GameObject gameObject = NetworkManager.Instance.GetNetworkedObject(rpc.m_NetworkId); if (gameObject != null) { Destroy(gameObject); } } break; case NetworkRPCType.RPC_LIB_TRANSFORM: { if (NetworkManager.Instance.IsMixed()) { break; // We are sort of server, so we have most up to date value } NetworkTransformRPC transformRPC = NetworkRPC.Parse <NetworkTransformRPC>(content); GameObject obj = NetworkManager.Instance.GetNetworkedObject(rpc.m_NetworkId); if (obj != null) { obj.transform.position = transformRPC.m_Position; obj.transform.eulerAngles = transformRPC.m_Rotation; obj.transform.localScale = transformRPC.m_Scale; } } break; case NetworkRPCType.RPC_LIB_CONNECTED: { NetworkPlayerConnectRPC connectRPC = NetworkRPC.Parse <NetworkPlayerConnectRPC>(content); ELogger.Log($"Player Connected: {connectRPC.m_Player.m_Name}", ELogger.LogType.Client); NetworkManager.Instance.AddPlayer(connectRPC.m_Player.m_Id, connectRPC.m_Player); foreach (var networkPair in NetworkManager.Instance.GetNetworkedObjects()) { if (networkPair.Value != null) { NetworkBehaviour networkBehaviour = networkPair.Value.GetComponent <NetworkBehaviour>(); if (networkBehaviour != null) { networkBehaviour.OnPlayerJoined(connectRPC.m_Player); } } } } break; case NetworkRPCType.RPC_LIB_DISCONNECTED: { NetworkPlayerDisconnctRPC disconnectRPC = NetworkRPC.Parse <NetworkPlayerDisconnctRPC>(content); NetworkManager.Instance.RemovePlayer(disconnectRPC.m_Player.m_Id); foreach (var networkPair in NetworkManager.Instance.GetNetworkedObjects()) { if (networkPair.Value != null) { NetworkBehaviour networkBehaviour = networkPair.Value.GetComponent <NetworkBehaviour>(); if (networkBehaviour != null) { networkBehaviour.OnPlayerDisconnected(disconnectRPC.m_Player, disconnectRPC.m_DisconnectType, disconnectRPC.m_Reason); } } } if (disconnectRPC.m_Player.m_Id == GetUniqueIndentifier()) { ELogger.Log($"We were disconnected for reason '{disconnectRPC.m_Reason}' with type {disconnectRPC.m_Type}|{disconnectRPC.m_DisconnectType}", ELogger.LogType.Client); Clean(); UnityEditor.EditorApplication.isPlaying = false; } else { ELogger.Log($"Player Disonnected: {disconnectRPC.m_Player.m_Name}", ELogger.LogType.Client); } } break; default: { GameObject obj = NetworkManager.Instance.GetNetworkedObject(rpc.m_NetworkId); if (obj != null) { NetworkBehaviour behaviour = obj.GetComponent <NetworkBehaviour>(); if (behaviour != null) { behaviour.OnRPCCommand(content); } } } break; } }