예제 #1
0
    /// <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;
        }
    }
예제 #2
0
    /// <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;
        }
    }