Beispiel #1
0
    /// <summary>
    /// Connects a client to a character or redirects a logged out ConnectedPlayer.
    /// </summary>
    /// <param name="conn">The client's NetworkConnection. If logged out the playerlist will return an invalid connectedplayer</param>
    /// <param name="playerControllerId">ID of the client player to be transfered. If logged out it's empty.</param>
    /// <param name="newBody">The character gameobject to be transfered into.</param>
    /// <param name="oldBody">The old body of the character.</param>
    /// <param name="eventType">Event type for the player sync.</param>
    public static void TransferPlayer(NetworkConnection conn, short playerControllerId, GameObject newBody, GameObject oldBody, EVENT eventType, CharacterSettings characterSettings)
    {
        var oldPlayerNetworkActions = oldBody.GetComponent <PlayerNetworkActions>();

        if (oldPlayerNetworkActions)
        {
            oldPlayerNetworkActions.RpcBeforeBodyTransfer();
        }

        var connectedPlayer = PlayerList.Instance.Get(conn);

        if (connectedPlayer == ConnectedPlayer.Invalid)         //this isn't an online player
        {
            PlayerList.Instance.UpdateLoggedOffPlayer(newBody, oldBody);
            NetworkServer.Spawn(newBody);
        }
        else
        {
            PlayerList.Instance.UpdatePlayer(conn, newBody);
            NetworkServer.ReplacePlayerForConnection(conn, newBody, playerControllerId);
            NetworkServer.ReplacePlayerForConnection(new NetworkConnection(), oldBody, 0);
            TriggerEventMessage.Send(newBody, eventType);
        }
        var playerScript = newBody.GetComponent <PlayerScript>();

        if (playerScript.PlayerSync != null)
        {
            playerScript.PlayerSync.NotifyPlayers(true);
        }

        // If the player is inside a container, send a ClosetHandlerMessage.
        // The ClosetHandlerMessage will attach the container to the transfered player.
        var playerObjectBehavior = newBody.GetComponent <ObjectBehaviour>();

        if (playerObjectBehavior && playerObjectBehavior.parentContainer)
        {
            ClosetHandlerMessage.Send(newBody, playerObjectBehavior.parentContainer.gameObject);
        }
        bool newMob = false;

        if (characterSettings != null)
        {
            playerScript.characterSettings = characterSettings;
            playerScript.playerName        = characterSettings.Name;
            newBody.name = characterSettings.Name;
            var playerSprites = newBody.GetComponent <PlayerSprites>();
            if (playerSprites)
            {
                playerSprites.OnCharacterSettingsChange(characterSettings);
            }
            newMob = true;
        }
        var healthStateMonitor = newBody.GetComponent <HealthStateMonitor>();

        if (healthStateMonitor)
        {
            healthStateMonitor.ProcessClientUpdateRequest(newBody);
        }
    }
Beispiel #2
0
    /// <summary>
    /// Sends the event message to the player.
    /// </summary>
    /// <param name="recipient"></param>
    /// <param name="eventType"></param>
    /// <returns></returns>
    public static TriggerEventMessage Send(GameObject recipient, EVENT eventType)
    {
        TriggerEventMessage msg = new TriggerEventMessage();

        msg.EventType = eventType;
        msg.SendTo(recipient);
        return(msg);
    }
    /// <summary>
    /// Sends the event message to the player.
    /// </summary>
    /// <param name="recipient"></param>
    /// <param name="eventType"></param>
    /// /// <param name="unsetLocal">if specified, client will call UnsetLocal on this object so they think they are no longer in control of it.</param>
    /// <param name="setLocal">if specified, client will call SetLocal on this object so they think they are in control of it.</param>
    /// <returns></returns>
    public static TriggerEventMessage Send(GameObject recipient, EVENT eventType, GameObject unsetLocal = null, GameObject setLocal = null)
    {
        TriggerEventMessage msg = new TriggerEventMessage();

        msg.EventType  = eventType;
        msg.SetLocal   = setLocal == null ?  NetId.Invalid : setLocal.NetId();
        msg.UnsetLocal = unsetLocal == null ?  NetId.Invalid : unsetLocal.NetId();
        msg.SendTo(recipient);
        return(msg);
    }
Beispiel #4
0
    public static void RespawnPlayer(NetworkConnection conn, short playerControllerId, JobType jobType)
    {
        GameObject player          = CreatePlayer(jobType);
        var        connectedPlayer = PlayerList.Instance.UpdatePlayer(conn, player);

        NetworkServer.ReplacePlayerForConnection(conn, player, playerControllerId);
        TriggerEventMessage.Send(player, EVENT.PlayerSpawned);
        if (connectedPlayer.Script.PlayerSync != null)
        {
            connectedPlayer.Script.PlayerSync.NotifyPlayers(true);
        }
    }
Beispiel #5
0
    IEnumerator ServerRoundRestart()
    {
        Logger.Log("Server restarting round now.", Category.Round);
        Chat.AddGameWideSystemMsgToChat("<b>The round is now restarting...</b>");

        //Notify all clients that the round has ended
        TriggerEventMessage.SendToAll(EVENT.RoundEnded);

        yield return(WaitFor.Seconds(0.2f));

        CustomNetworkManager.Instance.ServerChangeScene("OnlineScene");

        StopAllCoroutines();
    }
Beispiel #6
0
    /// <summary>
    /// Trigger the given event. If networked, will trigger the event on all clients.
    /// </summary>
    public static void Broadcast(EVENT evnt, bool network = false)
    {
        LogEventBroadcast(evnt);
        if (eventTable.ContainsKey(evnt) == false || eventTable[evnt] == null)
        {
            return;
        }

        eventTable[evnt]();
        if (CustomNetworkManager.IsServer && network)
        {
            TriggerEventMessage.SendToAll(evnt);
        }
    }
Beispiel #7
0
    /// <summary>
    /// Spawn the ghost as a new object and set that as the focus / what the user controls. Leave the player body where it is.
    /// </summary>
    /// <param name="conn">connection whose ghost is being spawned</param>
    /// <param name="playerControllerId">ID of player whose ghost should be spawned</param>
    /// <returns>the gameobject of the ghost</returns>
    public static void SpawnPlayerGhost(NetworkConnection conn, short playerControllerId)
    {
        var        connectedPlayer = PlayerList.Instance.Get(conn);
        GameObject body            = connectedPlayer.GameObject;
        JobType    savedJobType    = body.GetComponent <PlayerScript>().JobType;
        GameObject ghost           = CreateGhost(connectedPlayer, savedJobType);

        PlayerList.Instance.UpdatePlayer(conn, ghost);
        NetworkServer.ReplacePlayerForConnection(conn, ghost, playerControllerId);
        TriggerEventMessage.Send(ghost, EVENT.GhostSpawned);
        if (connectedPlayer.Script.PlayerSync != null)
        {
            connectedPlayer.Script.PlayerSync.NotifyPlayers(true);
        }
    }
    /// <summary>
    /// Connects a client to a character or redirects a logged out ConnectedPlayer.
    /// </summary>
    /// <param name="conn">The client's NetworkConnection. If logged out the playerlist will return an invalid connectedplayer</param>
    /// <param name="playerControllerId">ID of the client player to be transfered. If logged out it's empty.</param>
    /// <param name="newBody">The character gameobject to be transfered into.</param>
    /// <param name="oldBody">The old body of the character.</param>
    /// <param name="eventType">Event type for the player sync.</param>
    public static void TransferPlayer(NetworkConnection conn, short playerControllerId, GameObject newBody, GameObject oldBody, EVENT eventType, CharacterSettings characterSettings)
    {
        var connectedPlayer = PlayerList.Instance.Get(conn);

        if (connectedPlayer == ConnectedPlayer.Invalid)         //this isn't an online player
        {
            PlayerList.Instance.UpdateLoggedOffPlayer(newBody, oldBody);
            NetworkServer.Spawn(newBody);
        }
        else
        {
            PlayerList.Instance.UpdatePlayer(conn, newBody);
            NetworkServer.ReplacePlayerForConnection(conn, newBody, playerControllerId);
            TriggerEventMessage.Send(newBody, eventType);
        }
        var playerScript = newBody.GetComponent <PlayerScript>();

        if (playerScript.PlayerSync != null)
        {
            playerScript.PlayerSync.NotifyPlayers(true);
        }

        // If the player is inside a container, send a ClosetHandlerMessage.
        // The ClosetHandlerMessage will attach the container to the transfered player.
        var playerObjectBehavior = newBody.GetComponent <ObjectBehaviour>();

        if (playerObjectBehavior && playerObjectBehavior.parentContainer)
        {
            ClosetHandlerMessage.Send(newBody, playerObjectBehavior.parentContainer.gameObject);
        }

        CustomNetworkManager.Instance.SyncPlayerData(newBody);
        if (characterSettings != null)
        {
            playerScript.characterSettings = characterSettings;
        }
    }
Beispiel #9
0
    /// <summary>
    /// Server-side only. Transfers control of a player object to the indicated connection.
    /// </summary>
    /// <param name="conn">The client's NetworkConnection. If logged out the playerlist will return an invalid connectedplayer</param>
    /// <param name="newBody">The character gameobject to be transfered into.</param>
    /// <param name="oldBody">The old body of the character.</param>
    /// <param name="eventType">Event type for the player sync.</param>
    /// <param name="characterSettings">settings, ignored if transferring to an existing player body</param>
    /// <param name="willDestroyOldBody">if true, indicates the old body is going to be destroyed rather than pooled,
    /// thus we shouldn't send any network message which reference's the old body's ID since it won't exist.</param>
    private static void ServerTransferPlayer(NetworkConnection conn, GameObject newBody, GameObject oldBody,
                                             EVENT eventType, CharacterSettings characterSettings, bool willDestroyOldBody = false)
    {
        if (oldBody)
        {
            var oldPlayerNetworkActions = oldBody.GetComponent <PlayerNetworkActions>();
            if (oldPlayerNetworkActions)
            {
                oldPlayerNetworkActions.RpcBeforeBodyTransfer();
            }

            //no longer can observe their inventory
            oldBody.GetComponent <ItemStorage>()?.ServerRemoveObserverPlayer(oldBody);
        }

        var connectedPlayer = PlayerList.Instance.Get(conn);

        if (connectedPlayer == ConnectedPlayer.Invalid)         //this isn't an online player
        {
            PlayerList.Instance.UpdateLoggedOffPlayer(newBody, oldBody);
            NetworkServer.Spawn(newBody);
        }
        else
        {
            PlayerList.Instance.UpdatePlayer(conn, newBody);
            NetworkServer.ReplacePlayerForConnection(conn, newBody);
            if (oldBody)
            {
                NetworkServer.ReplacePlayerForConnection(new NetworkConnection("0.0.0.0"), oldBody);
            }
            //mirrorworkaround: only added setLocal/unsetlocal for workaround for https://github.com/vis2k/Mirror/issues/962
            TriggerEventMessage.Send(newBody, eventType, willDestroyOldBody ? null : oldBody, newBody);

            //can observe their new inventory
            newBody.GetComponent <ItemStorage>()?.ServerAddObserverPlayer(newBody);
        }

        var playerScript = newBody.GetComponent <PlayerScript>();

        if (playerScript.PlayerSync != null)
        {
            playerScript.PlayerSync.NotifyPlayers(true);
        }

        // If the player is inside a container, send a ClosetHandlerMessage.
        // The ClosetHandlerMessage will attach the container to the transfered player.
        var playerObjectBehavior = newBody.GetComponent <ObjectBehaviour>();

        if (playerObjectBehavior && playerObjectBehavior.parentContainer)
        {
            FollowCameraMessage.Send(newBody, playerObjectBehavior.parentContainer.gameObject);
        }
        bool newMob = false;

        if (characterSettings != null)
        {
            playerScript.characterSettings = characterSettings;
            playerScript.playerName        = characterSettings.Name;
            newBody.name = characterSettings.Name;
            var playerSprites = newBody.GetComponent <PlayerSprites>();
            if (playerSprites)
            {
                playerSprites.OnCharacterSettingsChange(characterSettings);
            }
            newMob = true;
        }
        var healthStateMonitor = newBody.GetComponent <HealthStateMonitor>();

        if (healthStateMonitor)
        {
            healthStateMonitor.ProcessClientUpdateRequest(newBody);
        }
    }
Beispiel #10
0
    /// <summary>
    /// Server-side only. Transfers control of a player object to the indicated connection.
    /// </summary>
    /// <param name="conn">The client's NetworkConnection. If logged out the playerlist will return an invalid connectedplayer</param>
    /// <param name="newBody">The character gameobject to be transfered into.</param>
    /// <param name="oldBody">The old body of the character.</param>
    /// <param name="eventType">Event type for the player sync.</param>
    /// <param name="characterSettings">settings, ignored if transferring to an existing player body</param>
    /// <param name="willDestroyOldBody">if true, indicates the old body is going to be destroyed rather than pooled,
    /// thus we shouldn't send any network message which reference's the old body's ID since it won't exist.</param>
    private static void ServerTransferPlayer(NetworkConnection conn, GameObject newBody, GameObject oldBody,
                                             EVENT eventType, CharacterSettings characterSettings, bool willDestroyOldBody = false)
    {
        if (oldBody)
        {
            var oldPlayerNetworkActions = oldBody.GetComponent <PlayerNetworkActions>();
            if (oldPlayerNetworkActions)
            {
                oldPlayerNetworkActions.RpcBeforeBodyTransfer();
            }

            //no longer can observe their inventory
            oldBody.GetComponent <ItemStorage>()?.ServerRemoveObserverPlayer(oldBody);
        }

        var connectedPlayer = PlayerList.Instance.Get(conn);

        if (connectedPlayer == ConnectedPlayer.Invalid)         //this isn't an online player
        {
            PlayerList.Instance.UpdateLoggedOffPlayer(newBody, oldBody);
            NetworkServer.Spawn(newBody);
        }
        else
        {
            PlayerList.Instance.UpdatePlayer(conn, newBody);
            NetworkServer.ReplacePlayerForConnection(conn, newBody);
            //NOTE: With mirror upgrade 04 Feb 2020, it appears we no longer need to do what has been
            //commented out below. Below appears to have been an attempt to give authority back to server
            //But it's implicitly given such authority by the ReplacePlayerForConnection call - that call
            //now removes authority for the player's old object
            // if (oldBody)
            // {
            //  NetworkServer.ReplacePlayerForConnection(new NetworkConnectionToClient(0), oldBody);
            // }
            TriggerEventMessage.Send(newBody, eventType);

            //can observe their new inventory
            newBody.GetComponent <ItemStorage>()?.ServerAddObserverPlayer(newBody);
        }

        var playerScript = newBody.GetComponent <PlayerScript>();

        if (playerScript.PlayerSync != null)
        {
            playerScript.PlayerSync.NotifyPlayers(true);
        }

        // If the player is inside a container, send a ClosetHandlerMessage.
        // The ClosetHandlerMessage will attach the container to the transfered player.
        var playerObjectBehavior = newBody.GetComponent <ObjectBehaviour>();

        if (playerObjectBehavior && playerObjectBehavior.parentContainer)
        {
            FollowCameraMessage.Send(newBody, playerObjectBehavior.parentContainer.gameObject);
        }

        if (characterSettings != null)
        {
            playerScript.characterSettings = characterSettings;
            playerScript.playerName        = characterSettings.Name;
            newBody.name = characterSettings.Name;
            var playerSprites = newBody.GetComponent <PlayerSprites>();
            if (playerSprites)
            {
                playerSprites.OnCharacterSettingsChange(characterSettings);
            }
        }
        var healthStateMonitor = newBody.GetComponent <HealthStateMonitor>();

        if (healthStateMonitor)
        {
            healthStateMonitor.ProcessClientUpdateRequest(newBody);
        }
    }
Beispiel #11
0
        /// <summary>
        /// Actions the server performs when the player dies
        /// </summary>
        protected override void OnDeathActions()
        {
            if (CustomNetworkManager.Instance._isServer)
            {
                ConnectedPlayer player = PlayerList.Instance.Get(gameObject, true);

                string killerName = null;
                if (LastDamagedBy != null)
                {
                    var lastDamager = PlayerList.Instance.Get(LastDamagedBy, true);
                    if (lastDamager != null)
                    {
                        killerName = lastDamager.Name;
                        AutoMod.ProcessPlayerKill(lastDamager, player);
                    }
                }

                if (killerName == null)
                {
                    killerName = "stressful work";
                }

                string playerName = player?.Name ?? "dummy";
                if (killerName == playerName)
                {
                    Chat.AddActionMsgToChat(gameObject, "You committed suicide, what a waste.", $"{playerName} committed suicide.");
                }
                else if (killerName.EndsWith(playerName))
                {
                    string themself = null;
                    if (player != null)
                    {
                        themself = player.CharacterSettings?.ThemselfPronoun(player.Script);
                    }
                    if (themself == null)
                    {
                        themself = "themself";
                    }
                    //chain reactions
                    Chat.AddActionMsgToChat(gameObject, $"You screwed yourself up with some help from {killerName}",
                                            $"{playerName} screwed {themself} up with some help from {killerName}");
                }
                else
                {
                    PlayerList.Instance.TrackKill(LastDamagedBy, gameObject);
                }

                //drop items in hand
                if (dynamicItemStorage != null)
                {
                    foreach (var itemSlot in dynamicItemStorage.GetHandSlots())
                    {
                        Inventory.ServerDrop(itemSlot);
                    }
                }

                if (isServer)
                {
                    //TODO: Re - impliment this using the new reagent- first code introduced in PR #6810
                    //EffectsFactory.BloodSplat(RegisterTile.WorldPositionServer);
                    string their = null;
                    if (player != null)
                    {
                        their = player.CharacterSettings?.TheirPronoun(player.Script);
                    }

                    if (their == null)
                    {
                        their = "their";
                    }

                    Chat.AddLocalMsgToChat($"<b>{player.Name}</b> seizes up and falls limp, {their} eyes dead and lifeless...", gameObject);
                }

                TriggerEventMessage.SendTo(gameObject, Event.PlayerDied);
            }
        }
    /// <summary>
    /// Server-side only. Transfers control of a player object to the indicated connection.
    /// </summary>
    /// <param name="conn">The client's NetworkConnection. If logged out the playerlist will return an invalid connectedplayer</param>
    /// <param name="newBody">The character gameobject to be transfered into.</param>
    /// <param name="oldBody">The old body of the character.</param>
    /// <param name="eventType">Event type for the player sync.</param>
    /// <param name="characterSettings">settings, ignored if transferring to an existing player body</param>
    /// <param name="occupation">occupation, ignored if transferring to an existing player body</param>
    private static void ServerTransferPlayer(NetworkConnection conn, GameObject newBody, GameObject oldBody,
                                             EVENT eventType, CharacterSettings characterSettings, Occupation occupation)
    {
        if (oldBody)
        {
            var oldPlayerNetworkActions = oldBody.GetComponent <PlayerNetworkActions>();
            if (oldPlayerNetworkActions)
            {
                oldPlayerNetworkActions.RpcBeforeBodyTransfer();
            }
            //no longer can observe their inventory
            oldBody.GetComponent <ItemStorage>()?.ServerRemoveObserverPlayer(oldBody);
        }

        var connectedPlayer = PlayerList.Instance.Get(conn);

        if (connectedPlayer == ConnectedPlayer.Invalid)         //this isn't an online player
        {
            Logger.LogErrorFormat("Cannot transfer player from {0} to {1}, networkconnection of player to transfer is not online.",
                                  Category.ItemSpawn, oldBody, newBody);
            return;
        }

        PlayerList.Instance.UpdatePlayer(conn, newBody);
        NetworkServer.ReplacePlayerForConnection(conn, newBody);
        if (oldBody)
        {
            NetworkServer.ReplacePlayerForConnection(new NetworkConnection("0.0.0.0"), oldBody);
        }
        TriggerEventMessage.Send(newBody, eventType);
        //can observe their new inventory
        newBody.GetComponent <ItemStorage>()?.ServerAddObserverPlayer(newBody);

        var playerScript = newBody.GetComponent <PlayerScript>();

        if (playerScript.PlayerSync != null)
        {
            playerScript.PlayerSync.NotifyPlayers(true);
        }

        // If the player is inside a container, send a ClosetHandlerMessage.
        // The ClosetHandlerMessage will attach the container to the transfered player.
        var playerObjectBehavior = newBody.GetComponent <ObjectBehaviour>();

        if (playerObjectBehavior && playerObjectBehavior.parentContainer)
        {
            FollowCameraMessage.Send(newBody, playerObjectBehavior.parentContainer.gameObject);
        }
        bool newMob = false;

        if (characterSettings != null)
        {
            playerScript.characterSettings = characterSettings;
            playerScript.playerName        = characterSettings.Name;
            newBody.name = characterSettings.Name;
            var playerSprites = newBody.GetComponent <PlayerSprites>();
            if (playerSprites)
            {
                playerSprites.OnCharacterSettingsChange(characterSettings);
            }
            newMob = true;
        }
        var healthStateMonitor = newBody.GetComponent <HealthStateMonitor>();

        if (healthStateMonitor)
        {
            healthStateMonitor.ProcessClientUpdateRequest(newBody);
        }
    }