/// <inheritdoc/>
        public void HandlePacket(Player player, Span <byte> packet)
        {
            if (packet.Length <= 4)
            {
                return;
            }

            if (this.MoveType == MoveType.Walk)
            {
                WalkRequest request = packet;
                this.Walk(player, request, new Point(request.SourceX, request.SourceY));
            }
            else
            {
                // We don't move the player anymore by his request. This was usually requested after a player performed a skill.
                // However, it adds way for cheaters to move through the map.
                // So, we just allow it for developers when the debugger is attached.
                // When handling a skill which moves to the target, we'll handle the move on server-side, instead.
#if DEBUG
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    InstantMoveRequest moveRequest = packet;
                    player.Move(new Point(moveRequest.TargetX, moveRequest.TargetY));
                }
#endif
            }
        }
        private void Walk(Player player, WalkRequest request, Point sourcePoint)
        {
            if (request.Header.Length > 6)
            {
                // in a walk packet, x and y are the current coordinates and the steps are leading us to the target
                var   steps  = this.GetSteps(sourcePoint, this.DecodePayload(request, out _));
                Point target = this.GetTarget(steps, sourcePoint);

                player.WalkTo(target, steps);
            }
            else
            {
                player.Rotation = request.TargetRotation.ParseAsDirection();
            }
        }
Ejemplo n.º 3
0
        private void Walk(Player player, WalkRequest request, Point sourcePoint)
        {
            if (request.Header.Length > 6)
            {
                // in a walk packet, x and y are the current coordinates and the steps are leading us to the target
                var   steps  = this.GetSteps(sourcePoint, this.GetDirections(request.Directions));
                Point target = this.GetTarget(steps, sourcePoint);

                player.WalkTo(target, steps);
            }
            else
            {
                var rotationValue = (byte)((request.Directions[0] >> 4) & 0x0F);
                player.Rotation = rotationValue.ParseAsDirection();
            }
        }
        /// <summary>
        /// Gets the walking directions from the walk packet and the final rotation of the character.
        /// </summary>
        /// <param name="walkRequest">
        /// The walk request, received from the client.
        /// </param>
        /// <param name="rotation">
        /// The rotation of the character once the walking is done.
        /// </param>
        /// <returns>The walking directions and the final rotation of the character.</returns>
        /// <remarks>
        /// We return here the directions left-rotated; I don't know yet if that's an error in our Direction-enum
        /// or just the client uses another enumeration for it.
        /// </remarks>
        private Span <Direction> DecodePayload(WalkRequest walkRequest, out Direction rotation)
        {
            var stepsCount = walkRequest.StepCount;

            rotation = walkRequest.TargetRotation.ParseAsDirection();
            var directions = new Direction[stepsCount];
            var payload    = walkRequest.Directions;

            for (int i = 0; i < stepsCount; i++)
            {
                var val = payload[i / 2];
                val           = (byte)(i % 2 == 0 ? val >> 4 : val & 0x0F);
                directions[i] = val.ParseAsDirection();
            }

            return(directions.AsSpan(0, directions.Length));
        }