Exemplo n.º 1
0
        private void OnPlayerUpdate(On.HeroController.orig_Update orig, HeroController self)
        {
            // Make sure the original method executes
            orig(self);

            // Ignore player position updates on non-gameplay scenes
            var currentSceneName = SceneUtil.GetCurrentSceneName();

            if (SceneUtil.IsNonGameplayScene(currentSceneName))
            {
                return;
            }

            // If we are not connected, there is nothing to send to
            if (!_netClient.IsConnected)
            {
                return;
            }

            var heroTransform = HeroController.instance.transform;

            var newPosition = heroTransform.position;

            // If the position changed since last check
            if (newPosition != _lastPosition)
            {
                // Update the last position, since it changed
                _lastPosition = newPosition;

                if (_sceneChanged)
                {
                    _sceneChanged = false;


                    // Set some default values for the packet variables in case we don't have a HeroController instance
                    // This might happen when we are in a non-gameplay scene without the knight
                    var    position        = Vector3.zero;
                    var    scale           = Vector3.zero;
                    ushort animationClipId = 0;

                    // If we do have a HeroController instance, use its values
                    if (HeroController.instance != null)
                    {
                        var transform = HeroController.instance.transform;

                        position        = transform.position;
                        scale           = transform.localScale;
                        animationClipId = (ushort)_animationManager.GetCurrentAnimationClip();
                    }

                    // Create the EnterScene packet
                    var packet = new ServerPlayerEnterScenePacket {
                        NewSceneName    = SceneUtil.GetCurrentSceneName(),
                        Position        = position,
                        Scale           = scale,
                        AnimationClipId = animationClipId
                    };
                    packet.CreatePacket();

                    Logger.Info(this, "Sending EnterScene packet");

                    // Send it to the server
                    _netClient.SendTcp(packet);
                }
                else
                {
                    // If this was not the first position update after a scene change,
                    // we can simply send a position update packet
                    _netClient.SendPositionUpdate(newPosition);
                }
            }

            var newScale = heroTransform.localScale;

            // If the scale changed since last check
            if (newScale != _lastScale)
            {
                _netClient.SendScaleUpdate(newScale);

                // Update the last scale, since it changed
                _lastScale = newScale;
            }
        }
Exemplo n.º 2
0
        private void OnClientEnterScene(ushort id, ServerPlayerEnterScenePacket packet)
        {
            if (!_playerData.TryGetValue(id, out var playerData))
            {
                Logger.Warn(this, $"Received EnterScene packet from {id}, but player is not in mapping");
                return;
            }

            // Read the values in from the packet
            var newSceneName    = packet.NewSceneName;
            var position        = packet.Position;
            var scale           = packet.Scale;
            var animationClipId = packet.AnimationClipId;

            Logger.Info(this, $"Received EnterScene packet from ID {id}, new scene: {newSceneName}");

            // Store it in their PlayerData object
            playerData.CurrentScene      = newSceneName;
            playerData.LastPosition      = position;
            playerData.LastScale         = scale;
            playerData.LastAnimationClip = animationClipId;

            // Create a PlayerEnterScene packet containing the ID
            // of the player entering the scene and the respective values
            var enterScenePacket = new ClientPlayerEnterScenePacket {
                ScenePlayerData = new ScenePlayerData {
                    Id              = id,
                    Username        = playerData.Username,
                    Position        = position,
                    Scale           = scale,
                    Team            = playerData.Team,
                    AnimationClipId = animationClipId,
                }
            };

            enterScenePacket.CreatePacket();

            // Create the AlreadyInScene packet
            var alreadyInScenePacket = new ClientAlreadyInScenePacket();

            foreach (var idPlayerDataPair in _playerData.GetCopy())
            {
                // Skip source player
                if (idPlayerDataPair.Key == id)
                {
                    continue;
                }

                var otherPlayerData = idPlayerDataPair.Value;

                // Send the packet to all clients on the new scene
                // to indicate that this client has entered their scene
                if (otherPlayerData.CurrentScene.Equals(newSceneName))
                {
                    Logger.Info(this, $"Sending enter scene packet to {idPlayerDataPair.Key}");
                    _netServer.SendTcp(idPlayerDataPair.Key, enterScenePacket);

                    Logger.Info(this, $"Sending that {idPlayerDataPair.Key} is already in scene to {id}");

                    // Also send a packet to the client that switched scenes,
                    // notifying that these players are already in this new scene.
                    // We do this by adding a new player data instance to the AlreadyInScene packet
                    alreadyInScenePacket.ScenePlayerData.Add(new ScenePlayerData {
                        Id              = idPlayerDataPair.Key,
                        Username        = otherPlayerData.Username,
                        Position        = otherPlayerData.LastPosition,
                        Scale           = otherPlayerData.LastScale,
                        Team            = otherPlayerData.Team,
                        AnimationClipId = otherPlayerData.LastAnimationClip,
                    });
                }
            }

            // Now we send the AlreadyInScene packet after it is completely populated,
            // or not in case of no players in the scene already
            _netServer.SendTcp(id, alreadyInScenePacket.CreatePacket());
        }