Exemplo n.º 1
0
    public void OnPlayerPosition(IMinecraftUser user, IMinecraftPacket packet)
    {
        Position destinationPosition = packet.ReadAbsolutePosition();
        bool     isOnGround          = packet.ReadBoolean();

        user.Player.Move(destinationPosition, isOnGround);
    }
Exemplo n.º 2
0
 /// <summary>
 /// Creates a new <see cref="HandshakePacket"/> instance.
 /// </summary>
 /// <param name="packet">Incoming packet from client.</param>
 public HandshakePacket(IMinecraftPacket packet)
 {
     ProtocolVersion = packet.ReadVarInt32();
     ServerAddress   = packet.ReadString();
     ServerPort      = packet.ReadUInt16();
     NextState       = (MinecraftUserStatus)packet.ReadVarInt32();
 }
Exemplo n.º 3
0
 public void Broadcast(IMinecraftPacket packet)
 {
     foreach (IPlayer player in _players.Values)
     {
         player.SendPacket(packet);
     }
 }
Exemplo n.º 4
0
 private static void SendPacketToAllPlayers(IWorldMap map, IMinecraftPacket packet)
 {
     if (map is not null)
     {
         map.Broadcast(packet);
     }
 }
Exemplo n.º 5
0
    private void WriteDimension(Dimension dimension, IMinecraftPacket packet)
    {
        var nbtDimension = NbtSerializer.SerializeCompound(dimension.Element, "");
        var nbtFile      = new NbtFile(nbtDimension);

        packet.WriteBytes(nbtFile.GetBuffer());
    }
Exemplo n.º 6
0
    public void OnPing(IMinecraftUser user, IMinecraftPacket packet)
    {
        var pingPacket = new StatusPingPacket(packet);

        using var pongPacket = new StatusPongPacket(pingPacket.Payload);
        user.Send(pongPacket);
    }
Exemplo n.º 7
0
    public void OnPlayerDigging(IMinecraftUser user, IMinecraftPacket packet)
    {
        var status   = (DiggingType)packet.ReadVarInt32();
        var position = packet.ReadPosition();
        var face     = (BlockFaceType)packet.ReadByte();

        _logger.LogTrace($"Status={status};Position={position};Face={face}");

        if (user.Player.GameMode is ServerGameModeType.Creative)
        {
            IBlock previousBlock = user.Player.Map.GetBlock(position);

            if (previousBlock.IsAir)
            {
                throw new InvalidOperationException($"Cannot dig air blocks ({position})");
            }

            using var playerDiggingAck = new AcknowledgePlayerDiggingPacket(position, previousBlock, DiggingType.Started);
            user.Player.SendPacketToVisibleEntities(playerDiggingAck);

            using var blockChange = new BlockChangePacket(BlockType.Air, position);
            user.Player.SendPacketToVisibleEntities(blockChange);

            IBlock block = user.Player.Map.SetBlock(BlockType.Air, position);

            using var chunkPacket = new ChunkDataPacket(block.Chunk);
            user.Player.SendPacketToVisibleEntities(chunkPacket, includeEntity: true);
        }
        else
        {
            // TODO: other modes
        }
    }
Exemplo n.º 8
0
    public void OnPlayerRotation(IMinecraftUser user, IMinecraftPacket packet)
    {
        float yawAngle   = packet.ReadSingle();
        float pitchAngle = packet.ReadSingle();
        bool  isOnGround = packet.ReadBoolean();

        user.Player.Rotate(yawAngle, pitchAngle);
    }
    public void OnPlayerPositionAndRotation(IMinecraftUser user, IMinecraftPacket packet)
    {
        Position destinationPosition = packet.ReadAbsolutePosition();
        float    yawAngle            = packet.ReadSingle();
        float    pitchAngle          = packet.ReadSingle();
        bool     isOnGround          = packet.ReadBoolean();

        user.Player.MoveAndRotate(destinationPosition, yawAngle, pitchAngle, isOnGround);
    }
Exemplo n.º 10
0
    public void Serialize(IMinecraftPacket packet, bool fullChunk = false)
    {
        packet.WriteInt32(X);
        packet.WriteInt32(Z);
        packet.WriteBoolean(fullChunk);

        int mask = 0;

        // if full chunk
        using var chunkStream = new MinecraftPacket();
        for (int i = 0; i < Sections.Count(); i++)
        {
            IChunkSection section = Sections.ElementAt(i);

            if (fullChunk || section.IsDirty)
            {
                mask |= 1 << i;
                section.Serialize(chunkStream);
            }
        }

        packet.WriteVarInt32(mask);

        // Heightmap serialization
        var heightmapCompound = new NbtCompound("")
        {
            new NbtLongArray("MOTION_BLOCKING", Heightmap.ToArray()),
            new NbtLongArray("WORLD_SURFACE", WorldSurfaceHeightmap.ToArray())
        };
        var nbtFile = new NbtFile(heightmapCompound);

        packet.WriteBytes(nbtFile.GetBuffer());

        // Biomes
        if (fullChunk)
        {
            packet.WriteVarInt32(1024);

            for (int i = 0; i < 1024; i++)
            {
                packet.WriteVarInt32(0);
            }
        }

        chunkStream.Position = 0;

        packet.WriteVarInt32((int)chunkStream.Length);
        packet.WriteBytes(chunkStream.BaseBuffer);

        packet.WriteVarInt32(0); // block count
        // TODO: foreach block in blocks in chunk as NBT
    }
Exemplo n.º 11
0
    public void Send(IMinecraftPacket packet)
    {
        if (packet is MinecraftPacket minecraftPacket)
        {
            using var stream = new MinecraftStream();

            stream.WriteVarInt32(minecraftPacket.PacketLength);
            stream.WriteVarInt32(minecraftPacket.PacketId);
            stream.WriteBytes(minecraftPacket.Buffer);

            base.Send(stream.Buffer);
        }
    }
Exemplo n.º 12
0
    public void OnHeldItemChange(IMinecraftUser user, IMinecraftPacket packet)
    {
        short slot = packet.ReadInt16();

        if (slot < 0 || slot > 8)
        {
            throw new IndexOutOfRangeException($"Slot was out of bounds: {slot}");
        }

        _logger.LogDebug($"Current slot: {slot}");

        user.Player.HotBar.SetSlotIndex(slot);

        _logger.LogDebug($"Selected Item: ItemId = {user.Player.HotBar.SelectedSlot.ItemId}");
    }
Exemplo n.º 13
0
    public void OnPlayerBlockPlacement(IMinecraftUser user, IMinecraftPacket packet)
    {
        var      handType      = (HandType)packet.ReadVarInt32();
        Position blockPosition = packet.ReadPosition();
        var      blockFace     = (BlockFaceType)packet.ReadVarInt32();
        float    cursorX       = packet.ReadSingle();
        float    cursorY       = packet.ReadSingle();
        float    cursorZ       = packet.ReadSingle();
        bool     isInsideBlock = packet.ReadBoolean();

        // TODO: check if the current player is interacting with an interactable object.
        // Like: Chest, anvil, crafting table.

        IItemSlot currentHeldItem = user.Player.HotBar.SelectedSlot;

        if (currentHeldItem.HasItem)
        {
            BlockData block        = _registry.Blocks.FirstOrDefault(x => x.ItemId == currentHeldItem.ItemId);
            BlockType blockToPlace = block.Type;

            if (blockToPlace is not BlockType.Air)
            {
                Position realBlockPosition = blockFace switch
                {
                    BlockFaceType.Bottom => new Position(blockPosition.X, blockPosition.Y - 1, blockPosition.Z),
                    BlockFaceType.Top => new Position(blockPosition.X, blockPosition.Y + 1, blockPosition.Z),
                    BlockFaceType.North => new Position(blockPosition.X, blockPosition.Y, blockPosition.Z - 1),
                    BlockFaceType.South => new Position(blockPosition.X, blockPosition.Y, blockPosition.Z + 1),
                    BlockFaceType.West => new Position(blockPosition.X - 1, blockPosition.Y, blockPosition.Z),
                    BlockFaceType.East => new Position(blockPosition.X + 1, blockPosition.Y, blockPosition.Z),
                    _ => throw new InvalidOperationException("Invalid block face type.")
                };

                _logger.LogDebug($"Placing block '{blockToPlace}' at position {realBlockPosition}");

                user.Player.Map.SetBlock(blockToPlace, (int)realBlockPosition.X, (int)realBlockPosition.Y, (int)realBlockPosition.Z);

                using var blockChangePacket = new BlockChangePacket(blockToPlace, blockPosition);
                user.Player.SendPacketToVisibleEntities(blockChangePacket);

                using var chunkDataPacket = new ChunkDataPacket(user.Player.Chunk);
                user.Player.SendPacketToVisibleEntities(chunkDataPacket);
            }
        }
    }
}
Exemplo n.º 14
0
    public void OnChatMessage(IMinecraftUser user, IMinecraftPacket packet)
    {
        string message = packet.ReadString();

        if (message.Length > 256)
        {
            user.Disconnect("Chat message exceeds 256 characters.");
        }

        if (message.StartsWith(RedstoneContants.CommandPrefix))
        {
            // TODO: interpret commands
        }
        else
        {
            user.Player.Speak(message);
        }
    }
Exemplo n.º 15
0
    public void OnCreativeInventoryAction(IMinecraftUser user, IMinecraftPacket packet)
    {
        short slot = (short)(packet.ReadInt16() - RedstoneContants.PlayerInventoryHotbarOffset);
        // item slot structure
        bool present = packet.ReadBoolean();

        if (present)
        {
            int         itemId     = packet.ReadVarInt32();
            byte        itemCount  = packet.ReadByte();
            NbtCompound itemExtras = packet.ReadNbtCompound();

            _logger.LogInformation($"Item with id: {itemId} (x{itemCount}) set at slot {slot}");
            user.Player.HotBar.SetItem(slot, itemId, itemCount);
        }
        else
        {
            _logger.LogInformation($"Clearing item slot '{slot}'");
            user.Player.HotBar.ClearItem(slot);
        }
    }
Exemplo n.º 16
0
    public void OnAnimation(IMinecraftUser user, IMinecraftPacket packet)
    {
        var hand = (HandType)packet.ReadVarInt32();

        user.Player.SwingHand(hand);
    }
Exemplo n.º 17
0
    public void OnLogin(IMinecraftUser user, IMinecraftPacket packet)
    {
        string username = packet.ReadString();

        _logger.LogInformation($"{user.Username} trying to log-in");

        if (_serverConfiguration.Value.Mode == ServerModeType.Offline)
        {
            if (_serverConfiguration.Value.AllowMultiplayerDebug)
            {
                int count = _server.ConnectedPlayers.Count(x => x.Username.StartsWith(username));

                if (count > 0 && _server.ConnectedPlayers.Any(x => x.Username.Equals(username)))
                {
                    username = $"{username} ({count})";
                }
            }
            else
            {
                if (_server.HasUser(username))
                {
                    user.Disconnect($"A player with the same name '{username}' is already connected.");
                    return;
                }
            }

            Guid playerId = GuidUtilities.GenerateGuidFromString($"OfflinePlayer:{username}");

            // TODO: initialize current player
            // TODO: Read player data from storage (DB or file-system)
            user.LoadPlayer(playerId, username);

            // DEBUG
            user.Player.Position.X = 8;
            user.Player.Position.Y = 2;
            user.Player.Position.Z = 8;

            SendLoginSucess(user);
            user.UpdateStatus(MinecraftUserStatus.Play);
            _server.Events.OnPlayerJoinGame(new PlayerJoinEventArgs(user.Player));

            SendJoinGame(user);
            SendServerBrand(user);
            // TODO: held item changed
            // TODO: declare recipes
            // TODO: Tags
            // TODO: Entity status
            // TODO: declare commands
            // TODO: Unlock recipes
            SendPlayerPositionAndLook(user, user.Player.Position);
            SendPlayerInfo(user, PlayerInfoActionType.Add);
            SendPlayerInfo(user, PlayerInfoActionType.UpdateLatency);
            SendUpdateViewPosition(user);
            // TODO: Update light
            SendChunkData(user);
            SendUpdateViewPosition(user);
            // TODO: World border
            SendSpawnPosition(user, Position.Zero);
            SendPlayerPositionAndLook(user, user.Player.Position);

            user.Player.IsSpawned = true;
        }
        else
        {
            // TODO: login to Mojang API
        }
    }
Exemplo n.º 18
0
    public void OnHandshake(IMinecraftUser user, IMinecraftPacket packet)
    {
        var handshake = new HandshakePacket(packet);

        user.UpdateStatus(handshake.NextState);
    }
Exemplo n.º 19
0
    private void WriteDimensionsAndBiomes(IEnumerable <Dimension> dimensions, IEnumerable <Biome> biomes, IMinecraftPacket packet)
    {
        IEnumerable <NbtTag> dimensionsTags = dimensions.Select(x => NbtSerializer.SerializeCompound(x));
        IEnumerable <NbtTag> biomesTags     = biomes.Select(x => NbtSerializer.SerializeCompound(x));

        var nbtCompound = new NbtCompound("")
        {
            new NbtCompound("minecraft:dimension_type")
            {
                new NbtString("type", "minecraft:dimension_type"),
                new NbtList("value", dimensionsTags, NbtTagType.Compound)
            },
            new NbtCompound("minecraft:worldgen/biome")
            {
                new NbtString("type", "minecraft:worldgen/biome"),
                new NbtList("value", biomesTags, NbtTagType.Compound)
            }
        };
        var nbtFile = new NbtFile(nbtCompound);

        packet.WriteBytes(nbtFile.GetBuffer());
    }
Exemplo n.º 20
0
    public void OnTeleportConfirm(MinecraftUser user, IMinecraftPacket packet)
    {
        int teleportId = packet.ReadVarInt32();

        _logger.LogInformation($"Teleport ID: {teleportId}");
    }
Exemplo n.º 21
0
    public void OnStatusRequest(IMinecraftUser user, IMinecraftPacket _)
    {
        using var responsePacket = new StatusResponsePacket(_server.GetServerStatus());

        user.Send(responsePacket);
    }
Exemplo n.º 22
0
 public void SendToAll(IMinecraftPacket packet)
 {
     SendPacketToAllPlayers(Overworld, packet);
     SendPacketToAllPlayers(Nether, packet);
     SendPacketToAllPlayers(End, packet);
 }
Exemplo n.º 23
0
 public void SendTo(IEnumerable <IMinecraftUser> users, IMinecraftPacket packet)
 => SendTo(users.Cast <MinecraftUser>(), (packet as MinecraftPacket).Buffer);
Exemplo n.º 24
0
 /// <summary>
 /// Creates a new <see cref="StatusPingPacket"/> instance.
 /// </summary>
 /// <param name="packet"></param>
 public StatusPingPacket(IMinecraftPacket packet)
 {
     Payload = packet.ReadInt64();
 }
Exemplo n.º 25
0
    public void OnKeepAlive(MinecraftUser user, IMinecraftPacket packet)
    {
        long keepAliveId = packet.ReadInt64();

        user.Player.CheckKeepAlive(keepAliveId);
    }
Exemplo n.º 26
0
 public override void SendPacket(IMinecraftPacket packet) => _user.Send(packet);