public void SetClientOwner()
 {
     // SetClientOwner
     (_, NetworkConnection original) = PipedConnections();
     identity.SetClientOwner(original);
     Assert.That(identity.ConnectionToClient, Is.EqualTo(original));
 }
        /// <summary>
        /// <para>When an <see cref="AddCharacterMessage"/> message handler has received a request from a player, the server calls this to associate the player object with the connection.</para>
        /// <para>When a player is added for a connection, the client for that connection is made ready automatically. The player object is automatically spawned, so you do not need to call NetworkServer.Spawn for that object. This function is used for "adding" a player, not for "replacing" the player on a connection. If there is already a player on this playerControllerId for this connection, this will fail.</para>
        /// </summary>
        /// <param name="player">Connection which is adding the player.</param>
        /// <param name="identity">Player object spawned for the player.</param>
        /// <exception cref="ArgumentException">NetworkIdentity must not be null.</exception>
        public void AddCharacter(INetworkPlayer player, NetworkIdentity identity)
        {
            // cannot have an existing player object while trying to Add another.
            if (player.HasCharacter)
            {
                throw new ArgumentException("AddCharacter can only be called if the player does not already have a character");
            }

            // make sure we have a controller before we call SetClientReady
            // because the observers will be rebuilt only if we have a controller
            player.Identity = identity;

            identity.SetServerValues(Server, this);

            // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients)
            identity.SetClientOwner(player);

            // special case, we are in host mode, set hasAuthority to true so that all overrides see it
            if (player == Server.LocalPlayer)
            {
                identity.HasAuthority = true;
                Server.LocalClient.Player.Identity = identity;
            }

            // spawn any new visible scene objects
            SpawnVisibleObjects(player);

            if (logger.LogEnabled())
            {
                logger.Log($"Adding new playerGameObject object netId: {identity.NetId} asset ID {identity.PrefabHash:X}");
            }

            Respawn(identity);
        }
        /// <summary>
        /// <para>When an <see cref="AddCharacterMessage"/> message handler has received a request from a player, the server calls this to associate the player object with the connection.</para>
        /// <para>When a player is added for a connection, the client for that connection is made ready automatically. The player object is automatically spawned, so you do not need to call NetworkServer.Spawn for that object. This function is used for "adding" a player, not for "replacing" the player on a connection. If there is already a player on this playerControllerId for this connection, this will fail.</para>
        /// </summary>
        /// <param name="player">Connection which is adding the player.</param>
        /// <param name="identity">Player object spawned for the player.</param>
        /// <exception cref="ArgumentException">NetworkIdentity must not be null.</exception>
        public void AddCharacter(INetworkPlayer player, NetworkIdentity identity)
        {
            // cannot have an existing player object while trying to Add another.
            if (player.Identity != null)
            {
                throw new ArgumentException("AddPlayer: player object already exists");
            }

            // make sure we have a controller before we call SetClientReady
            // because the observers will be rebuilt only if we have a controller
            player.Identity = identity;

            identity.SetServerValues(Server, this);

            // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients)
            identity.SetClientOwner(player);

            // special case,  we are in host mode,  set hasAuthority to true so that all overrides see it
            if (player == Server.LocalPlayer)
            {
                identity.HasAuthority = true;
                Server.LocalClient.Player.Identity = identity;
            }

            // set ready if not set yet
            SetClientReady(player);

            if (logger.LogEnabled())
            {
                logger.Log("Adding new playerGameObject object netId: " + identity.NetId + " asset ID " + identity.AssetId);
            }

            Respawn(identity);
        }
Exemple #4
0
        internal bool InternalReplacePlayerForConnection(INetworkConnection conn, NetworkClient client, GameObject player, bool keepAuthority)
        {
            NetworkIdentity identity = player.GetComponent <NetworkIdentity>();

            if (identity is null)
            {
                logger.LogError("ReplacePlayer: playerGameObject has no NetworkIdentity. Please add a NetworkIdentity to " + player);
                return(false);
            }

            if (identity.ConnectionToClient != null && identity.ConnectionToClient != conn)
            {
                logger.LogError("Cannot replace player for connection. New player is already owned by a different connection" + player);
                return(false);
            }

            //NOTE: there can be an existing player
            logger.Log("NetworkServer ReplacePlayer");

            NetworkIdentity previousPlayer = conn.Identity;

            conn.Identity   = identity;
            identity.Client = client;

            // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients)
            identity.SetClientOwner(conn);

            // special case,  we are in host mode,  set hasAuthority to true so that all overrides see it
            if (conn == Server.LocalConnection)
            {
                identity.HasAuthority = true;
                Server.LocalClient.Connection.Identity = identity;
            }

            // add connection to observers AFTER the playerController was set.
            // by definition, there is nothing to observe if there is no player
            // controller.
            //
            // IMPORTANT: do this in AddPlayerForConnection & ReplacePlayerForConnection!
            SpawnObserversForConnection(conn);

            if (logger.LogEnabled())
            {
                logger.Log("Replacing playerGameObject object netId: " + player.GetComponent <NetworkIdentity>().NetId + " asset ID " + player.GetComponent <NetworkIdentity>().AssetId);
            }

            Respawn(identity);

            if (!keepAuthority)
            {
                previousPlayer.RemoveClientAuthority();
            }

            return(true);
        }
Exemple #5
0
        /// <summary>
        /// This replaces the player object for a connection with a different player object. The old player object is not destroyed.
        /// <para>If a connection already has a player object, this can be used to replace that object with a different player object. This does NOT change the ready state of the connection, so it can safely be used while changing scenes.</para>
        /// </summary>
        /// <param name="player">Connection which is adding the player.</param>
        /// <param name="client">Client associated to the player.</param>
        /// <param name="character">Player object spawned for the player.</param>
        /// <param name="keepAuthority">Does the previous player remain attached to this connection?</param>
        /// <returns></returns>
        public void ReplaceCharacter(INetworkPlayer player, GameObject character, bool keepAuthority = false)
        {
            NetworkIdentity identity = character.GetComponent <NetworkIdentity>();

            if (identity is null)
            {
                throw new ArgumentException("ReplacePlayer: playerGameObject has no NetworkIdentity. Please add a NetworkIdentity to " + character);
            }

            if (identity.ConnectionToClient != null && identity.ConnectionToClient != player)
            {
                throw new ArgumentException("Cannot replace player for connection. New player is already owned by a different connection" + character);
            }

            //NOTE: there can be an existing player
            logger.Log("NetworkServer ReplacePlayer");

            NetworkIdentity previousPlayer = player.Identity;

            player.Identity = identity;

            // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients)
            identity.SetClientOwner(player);

            // special case,  we are in host mode,  set hasAuthority to true so that all overrides see it
            if (player == Server.LocalPlayer)
            {
                identity.HasAuthority = true;
                Server.LocalClient.Player.Identity = identity;
            }

            // add connection to observers AFTER the playerController was set.
            // by definition, there is nothing to observe if there is no player
            // controller.
            //
            // IMPORTANT: do this in AddCharacter & ReplaceCharacter!
            SpawnObserversForConnection(player);

            if (logger.LogEnabled())
            {
                logger.Log("Replacing playerGameObject object netId: " + character.GetComponent <NetworkIdentity>().NetId + " asset ID " + character.GetComponent <NetworkIdentity>().AssetId);
            }

            Respawn(identity);

            if (!keepAuthority)
            {
                previousPlayer.RemoveClientAuthority();
            }
        }
Exemple #6
0
        /// <summary>
        /// <para>When an AddPlayer message handler has received a request from a player, the server calls this to associate the player object with the connection.</para>
        /// <para>When a player is added for a connection, the client for that connection is made ready automatically. The player object is automatically spawned, so you do not need to call NetworkServer.Spawn for that object. This function is used for "adding" a player, not for "replacing" the player on a connection. If there is already a player on this playerControllerId for this connection, this will fail.</para>
        /// </summary>
        /// <param name="conn">Connection which is adding the player.</param>
        /// <param name="client">Client associated to the player.</param>
        /// <param name="player">Player object spawned for the player.</param>
        /// <returns></returns>
        public bool AddPlayerForConnection(INetworkConnection conn, GameObject player)
        {
            NetworkIdentity identity = player.GetComponent <NetworkIdentity>();

            if (identity is null)
            {
                logger.Log("AddPlayer: playerGameObject has no NetworkIdentity. Please add a NetworkIdentity to " + player);
                return(false);
            }

            // cannot have a player object in "Add" version
            if (conn.Identity != null)
            {
                logger.Log("AddPlayer: player object already exists");
                return(false);
            }

            // make sure we have a controller before we call SetClientReady
            // because the observers will be rebuilt only if we have a controller
            conn.Identity = identity;

            // set server to the NetworkIdentity
            identity.Server = Server;
            identity.ServerObjectManager = this;
            identity.Client = Server.LocalClient;

            // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients)
            identity.SetClientOwner(conn);

            // special case,  we are in host mode,  set hasAuthority to true so that all overrides see it
            if (conn == Server.LocalConnection)
            {
                identity.HasAuthority = true;
                Server.LocalClient.Connection.Identity = identity;
            }

            // set ready if not set yet
            SetClientReady(conn);

            if (logger.LogEnabled())
            {
                logger.Log("Adding new playerGameObject object netId: " + identity.NetId + " asset ID " + identity.AssetId);
            }

            Respawn(identity);
            return(true);
        }
        /// <summary>
        /// This replaces the player object for a connection with a different player object. The old player object is not destroyed.
        /// <para>If a connection already has a player object, this can be used to replace that object with a different player object. This does NOT change the ready state of the connection, so it can safely be used while changing scenes.</para>
        /// </summary>
        /// <param name="player">Connection which is adding the player.</param>
        /// <param name="identity">Player object spawned for the player.</param>
        /// <param name="keepAuthority">Does the previous player remain attached to this connection?</param>
        /// <returns></returns>
        public void ReplaceCharacter(INetworkPlayer player, NetworkIdentity identity, bool keepAuthority = false)
        {
            if (identity.Owner != null && identity.Owner != player)
            {
                throw new ArgumentException($"Cannot replace player for connection. New player is already owned by a different connection {identity}");
            }
            if (!player.HasCharacter)
            {
                throw new InvalidOperationException($"ReplaceCharacter can only be called if Player already has a charater");
            }

            //NOTE: there can be an existing player
            logger.Log("NetworkServer ReplacePlayer");

            var previousCharacter = player.Identity;

            player.Identity = identity;

            // Set the connection on the NetworkIdentity on the server, NetworkIdentity.SetLocalPlayer is not called on the server (it is on clients)
            identity.SetClientOwner(player);

            // special case,  we are in host mode,  set hasAuthority to true so that all overrides see it
            if (player == Server.LocalPlayer)
            {
                identity.HasAuthority = true;
                Server.LocalClient.Player.Identity = identity;
            }

            // add connection to observers AFTER the playerController was set.
            // by definition, there is nothing to observe if there is no player
            // controller.
            //
            // IMPORTANT: do this in AddCharacter & ReplaceCharacter!
            SpawnVisibleObjectForPlayer(player);

            if (logger.LogEnabled())
            {
                logger.Log($"Replacing playerGameObject object netId: {identity.NetId} asset ID {identity.PrefabHash:X}");
            }

            Respawn(identity);

            if (!keepAuthority)
            {
                previousCharacter.RemoveClientAuthority();
            }
        }