Ejemplo n.º 1
0
        public override async Task PopulateAsync()
        {
            if (UUID != Guid.Empty || !string.IsNullOrEmpty(this.Username))
            {
                return;
            }

            using (var stream = new MinecraftStream(this.PacketData))
            {
                this.Username = await stream.ReadStringAsync();

                this.UUID = Guid.Parse(await stream.ReadStringAsync());
            }
        }
Ejemplo n.º 2
0
        public async ValueTask <PluginMessageStore> HandleAsync()
        {
            using var stream = new MinecraftStream(this.PluginData);

            var result = this.Channel switch
            {
                "minecraft:brand" => new PluginMessageStore
                {
                    Type  = PluginMessageType.Brand,
                    Value = await stream.ReadStringAsync()
                },
                "minecraft:register" => new PluginMessageStore//Payload should be a list of strings
                {
                    Type  = PluginMessageType.Register,
                    Value = Encoding.UTF8.GetString(this.PluginData)
                },
                "minecraft:unregister" => new PluginMessageStore
                {
                    Type  = PluginMessageType.UnRegister,
                    Value = Encoding.UTF8.GetString(this.PluginData)
                },
                _ => null
            };

            return(result);
        }
Ejemplo n.º 3
0
        public async Task HandleAsync(Obsidian.Server server, Player player)
        {
            var result = await this.HandleAsync();

            switch (result.Type)
            {
            case PluginMessageType.Brand:
                player.client.Brand = result.Value.ToString();
                break;

            case PluginMessageType.Register:
            {
                using var stream = new MinecraftStream(this.PluginData);
                var len = await stream.ReadVarIntAsync();

                //Idk how this would work so I'm assuming a length will be sent first
                for (int i = 0; i < len; i++)
                {
                    server.RegisteredChannels.Add(await stream.ReadStringAsync());
                }

                break;
            }

            case PluginMessageType.UnRegister:
                server.RegisteredChannels.RemoveWhere(x => x == this.Channel.ToLower());
                break;

            case PluginMessageType.Custom:    //This can be ignored for now
            default:
                break;
            }
        }
Ejemplo n.º 4
0
        public async ValueTask <PluginMessageStore> HandleAsync()
        {
            using var stream = new MinecraftStream(this.PluginData);
            var result = this.Channel switch
            {
                "minecraft:brand" => new PluginMessageStore
                {
                    Type  = PluginMessageType.Brand,
                    Value = await stream.ReadStringAsync()
                },
                "minecraft:register" => new PluginMessageStore//Payload should be a list of strings
                {
                    Type  = PluginMessageType.Register,
                    Value = this.PluginData
                },
                "minecraft:unregister" => new PluginMessageStore
                {
                    Type = PluginMessageType.UnRegister
                },
                _ => throw new System.NotImplementedException()
            };

            return(result);
        }
    }
Ejemplo n.º 5
0
 public override async Task PopulateAsync()
 {
     using (var stream = new MinecraftStream(this.PacketData))
     {
         this.Message = await stream.ReadStringAsync(256);
     }
 }
Ejemplo n.º 6
0
        } = 0;                                          // 0 = chatbox, 1 = system message, 2 = game info (actionbar)

        public override async Task PopulateAsync()
        {
            using (var stream = new MinecraftStream(this.PacketData))
            {
                this.Message  = JsonConvert.DeserializeObject <ChatMessage>(await stream.ReadStringAsync());
                this.Position = await stream.ReadUnsignedByteAsync();
            }
        }
Ejemplo n.º 7
0
        public async Task ReadAsync(MinecraftStream stream)
        {
            this.Channel = await stream.ReadStringAsync();

            var length = stream.Length - stream.Position;

            this.PluginData = await stream.ReadUInt8ArrayAsync((int)length);
        }
Ejemplo n.º 8
0
        public async Task ReadAsync(MinecraftStream stream)
        {
            this.WindowId = await stream.ReadByteAsync();

            this.RecipeId = await stream.ReadStringAsync();

            this.MakeAll = await stream.ReadBooleanAsync();
        }
Ejemplo n.º 9
0
    public async void SameAsync(string expectedValue)
    {
        using var stream = new MinecraftStream();

        await stream.WriteStringAsync(expectedValue);

        stream.Position = 0; //Reset to beginning for read

        string actualValue = await stream.ReadStringAsync();

        Assert.Equal(expectedValue, actualValue);
    }
Ejemplo n.º 10
0
        public override async Task PopulateAsync()
        {
            using (var stream = new MinecraftStream(this.PacketData))
            {
                this.Version = (ProtocolVersion)await stream.ReadVarIntAsync();

                this.ServerAddress = await stream.ReadStringAsync();

                this.ServerPort = await stream.ReadUnsignedShortAsync();

                this.NextState = (ClientState)await stream.ReadVarIntAsync();
            }
        }
Ejemplo n.º 11
0
        public async Task ReadAsync(MinecraftStream stream)
        {
            this.Locale = await stream.ReadStringAsync();

            this.ViewDistance = await stream.ReadByteAsync();

            this.ChatMode = await stream.ReadVarIntAsync();

            this.ChatColors = await stream.ReadBooleanAsync();

            this.SkinParts = await stream.ReadUnsignedByteAsync();

            this.MainHand = await stream.ReadVarIntAsync();
        }
Ejemplo n.º 12
0
        public override async Task PopulateAsync()
        {
            using (var stream = new MinecraftStream(this.PacketData))
            {
                this.ServerId = await stream.ReadStringAsync() ?? string.Empty;

                var keyLength = await stream.ReadVarIntAsync();

                this.PublicKey = await stream.ReadUInt8ArrayAsync(keyLength);

                var tokenLength = await stream.ReadVarIntAsync();

                this.VerifyToken = await stream.ReadUInt8ArrayAsync(tokenLength);
            }
        }
Ejemplo n.º 13
0
        public override async Task PopulateAsync()
        {
            using (var stream = new MinecraftStream(this.PacketData))
            {
                Locale = await stream.ReadStringAsync();

                ViewDistance = await stream.ReadByteAsync();

                ChatMode = await stream.ReadIntAsync();

                ChatColors = await stream.ReadBooleanAsync();

                SkinParts = await stream.ReadUnsignedByteAsync();

                MainHand = await stream.ReadVarIntAsync();
            }
        }
Ejemplo n.º 14
0
        public override async Task PopulateAsync()
        {
            using (var stream = new MinecraftStream(this.PacketData))
            {
                this.EntityId = await stream.ReadVarIntAsync();

                this.GameMode = (Gamemode)await stream.ReadUnsignedByteAsync();

                this.Dimension = (Dimension)await stream.ReadIntAsync();

                this.Difficulty = (Difficulty)await stream.ReadUnsignedByteAsync();

                this.MaxPlayers = await stream.ReadUnsignedByteAsync();

                this.LevelType = await stream.ReadStringAsync();

                this.ReducedDebugInfo = await stream.ReadBooleanAsync();
            }
        }
Ejemplo n.º 15
0
 public override async Task HandleAsync(MinecraftStream stream) => await stream.ReadStringAsync();
Ejemplo n.º 16
0
        public async Task ReadAsync(MinecraftStream stream)
        {
            this.Message = await stream.ReadStringAsync();

            this.Format = "<{0}> {1}";
        }
Ejemplo n.º 17
0
 public async Task ReadAsync(MinecraftStream stream)
 {
     this.Message = await stream.ReadStringAsync();
 }
Ejemplo n.º 18
0
        public async Task ReadAsync(MinecraftStream stream)
        {
            this.Channel = await stream.ReadStringAsync();

            this.PluginData = await stream.ReadUInt8ArrayAsync();
        }
Ejemplo n.º 19
0
        public static async Task HandlePlayPackets(Packet packet, Client client)
        {
            Server server = client.Server;
            Player player = client.Player;

            switch (packet.id)
            {
            case 0x00:     // Teleport Confirm
                var confirm = PacketSerializer.FastDeserialize <TeleportConfirm>(packet.data);

                if (confirm.TeleportId == player.TeleportId)
                {
                    break;
                }

                await player.KickAsync("Invalid teleport... cheater?");

                //await player.TeleportAsync(player.LastLocation);//Teleport them back we didn't send this packet
                break;

            case 0x01:
                // Query Block NBT
                Logger.LogDebug("Received query block nbt");
                break;

            case 0x02:    //Set difficulty

                break;

            case 0x03:
                // Incoming chat message
                var message = await PacketSerializer.FastDeserializeAsync <IncomingChatMessage>(packet.data);

                await server.ParseMessageAsync(message.Message, client);

                break;

            case 0x04:
                // Client status
                break;

            case 0x05:
                // Client Settings
                client.ClientSettings = PacketSerializer.FastDeserialize <ClientSettings>(packet.data);
                Logger.LogDebug("Received client settings");
                break;

            case 0x06:
                // Tab-Complete
                Logger.LogDebug("Received tab-complete");
                break;

            case 0x07:
                //TODO look more into this
                // Window Confirmation (serverbound)
                var conf = PacketSerializer.FastDeserialize <WindowConfirmation>(packet.data);

                Logger.LogDebug("Window Confirmation (serverbound)");
                break;

            case 0x08:
                // Click Window Button
                var clicked = PacketSerializer.FastDeserialize <ClickWindowButton>(packet.data);

                break;

            case 0x09:    // Click Window
            {
                var window = PacketSerializer.FastDeserialize <ClickWindow>(packet.data);

                Logger.LogDebug("Click window");

                if (window.WindowId == 0)
                {
                    //This is the player inventory
                    switch (window.Mode)
                    {
                    case InventoryOperationMode.MouseClick:            //TODO InventoryClickEvent
                    {
                        if (window.Button == 0)
                        {
                            player.Inventory.RemoveItem(window.ClickedSlot, 64);
                        }
                        else
                        {
                            player.Inventory.RemoveItem(window.ClickedSlot, window.Item.Count / 2);
                        }
                        break;
                    }

                    case InventoryOperationMode.ShiftMouseClick:
                        break;

                    case InventoryOperationMode.NumberKeys:
                        break;

                    case InventoryOperationMode.MiddleMouseClick:
                        break;

                    case InventoryOperationMode.Drop:
                    {
                        //If clicked slot is -999 that means they clicked outside the inventory
                        if (window.ClickedSlot != -999)
                        {
                            Logger.LogDebug("Dropped Item");
                            if (window.Button == 0)
                            {
                                player.Inventory.RemoveItem(window.ClickedSlot);
                            }
                            else
                            {
                                player.Inventory.RemoveItem(window.ClickedSlot, 64);
                            }
                        }
                        break;
                    }

                    case InventoryOperationMode.MouseDrag:
                    {
                        if (window.ClickedSlot == -999)
                        {
                            if (window.Button == 0 || window.Button == 4 || window.Button == 8)
                            {
                                client.isDragging = true;
                            }
                            else if (window.Button == 2 || window.Button == 6 || window.Button == 10)
                            {
                                client.isDragging = false;
                            }
                        }
                        else if (client.isDragging)
                        {
                            if (player.Gamemode == Gamemode.Creative)
                            {
                                if (window.Button != 9)
                                {
                                    break;
                                }

                                //creative copy
                                player.Inventory.SetItem(window.ClickedSlot, new ItemStack(window.Item.Id, window.Item.Count)
                                        {
                                            Nbt = window.Item.Nbt
                                        });
                            }
                            else
                            {
                                if (window.Button != 1 || window.Button != 5)
                                {
                                    break;
                                }

                                //survival painting
                                player.Inventory.SetItem(window.ClickedSlot, new ItemStack(window.Item.Id, window.Item.Count)
                                        {
                                            Nbt = window.Item.Nbt
                                        });
                            }
                        }
                        else
                        {
                            //It shouldn't get here
                        }

                        break;
                    }

                    case InventoryOperationMode.DoubleClick:
                        break;

                    default:
                        break;
                    }
                }
                else
                {
                }
                break;
            }

            case 0x0A:
                // Close Window (serverbound)
                var closedWindow = PacketSerializer.FastDeserialize <CloseWindow>(packet.data);

                Logger.LogDebug("Received close window");
                break;

            case 0x0B:     // Plugin Message (serverbound)
            {
                var msg = await PacketSerializer.DeserializeAsync <PluginMessage>(packet.data);

                var result = await msg.HandleAsync();

                switch (result.Type)
                {
                case PluginMessageType.Brand:
                    client.Brand = result.Value.ToString();
                    break;

                case PluginMessageType.Register:
                {
                    using var stream = new MinecraftStream(msg.PluginData);
                    var len = await stream.ReadVarIntAsync();

                    //Idk how this would work so I'm assuming a length will be sent first
                    for (int i = 0; i < len; i++)
                    {
                        server.RegisteredChannels.Add(await stream.ReadStringAsync());
                    }

                    break;
                }

                case PluginMessageType.UnRegister:
                    server.RegisteredChannels.RemoveWhere(x => x == msg.Channel.ToLower());
                    break;

                case PluginMessageType.Custom:            //This can be ignored for now
                default:
                    break;
                }

                Logger.LogDebug($"Received plugin message: {msg.Channel}");
            }
            break;

            case 0x0C:
                // Edit Book
                Logger.LogDebug("Received edit book");
                break;

            case 0x0E:
                //Interact Entity
                Logger.LogDebug("Interact entity");
                break;

            case 0x0F:
                //Generate structure
                break;

            case 0x10:
                // Keep Alive (serverbound)
                var keepalive = PacketSerializer.FastDeserialize <KeepAlive>(packet.data);
                Logger.LogDebug($"Successfully kept alive player {player.Username} with ka id " +
                                $"{keepalive.KeepAliveId} previously missed {client.missedKeepalives - 1} ka's"); // missed is 1 more bc we just handled one

                // Server is alive, reset missed keepalives.
                client.missedKeepalives = 0;
                break;

            case 0x11:    //Lock Difficulty
                break;

            case 0x12:
                // Player Position
                var pos = PacketSerializer.FastDeserialize <PlayerPosition>(packet.data);

                await player.UpdateAsync(server, pos.Position, pos.OnGround);

                break;

            case 0x13:
                //Player Position And rotation (serverbound)
                var ppos = PacketSerializer.FastDeserialize <ServerPlayerPositionLook>(packet.data);

                await player.UpdateAsync(server, ppos.Position, ppos.Yaw, ppos.Pitch, ppos.OnGround);

                break;

            case 0x14:    // Player rotation
                var look = PacketSerializer.FastDeserialize <PlayerRotation>(packet.data);

                await player.UpdateAsync(server, look.Yaw, look.Pitch, look.OnGround);

                break;

            case 0x15:    //Player movement
                break;

            case 0x16:    // Vehicle Move (serverbound)
                break;

            case 0x17:    //Steer boat
                break;

            case 0x18:
                // Pick Item
                var item = PacketSerializer.FastDeserialize <PickItem>(packet.data);

                Logger.LogDebug("Received pick item");

                break;

            case 0x19:
                // Craft Recipe Request
                Logger.LogDebug("Received craft recipe request");

                break;

            case 0x1A:
                // Player Abilities (serverbound)
                Logger.LogDebug("Received player abilities");
                break;

            case 0x1B:
                // Player Digging

                var digging = PacketSerializer.FastDeserialize <PlayerDigging>(packet.data);

                await server.BroadcastPlayerDigAsync(new PlayerDiggingStore
                {
                    Player = player.Uuid,
                    Packet = digging
                });

                break;

            case 0x1C:
                //TODO Entity Action
                var action = PacketSerializer.FastDeserialize <EntityAction>(packet.data);


                switch (action.Action)
                {
                case EAction.StartSneaking:
                    player.Sneaking = true;
                    break;

                case EAction.StopSneaking:
                    player.Sneaking = false;
                    break;

                case EAction.LeaveBed:
                    player.Sleeping = false;
                    break;

                case EAction.StartSprinting:
                    player.Sprinting = true;
                    break;

                case EAction.StopSprinting:
                    player.Sprinting = false;
                    break;

                case EAction.StartJumpWithHorse:
                    break;

                case EAction.StopJumpWithHorse:
                    break;

                case EAction.OpenHorseInventory:
                    player.InHorseInventory = true;
                    break;

                case EAction.StartFlyingWithElytra:
                    player.FlyingWithElytra = true;
                    break;

                default:
                    break;
                }
                Logger.LogDebug("Received entity action");
                break;

            case 0x1D:
                // Steer Vehicle
                break;

            case 0x1E:    // Set Displayed Recipe
                break;

            case 0x1F:    //Set recipe book state
                break;

            case 0x20:    // Name Item
                var nameItem = PacketSerializer.FastDeserialize <NameItem>(packet.data);
                break;

            case 0x21:    //Resource pack status
                break;

            case 0x22:    //Advancement tab
                break;

            case 0x23:    //Select trade
                break;

            case 0x24:    //Set beacon effect
                break;

            case 0x25:    // Held Item Change (serverbound)
                var heldItemChange = PacketSerializer.FastDeserialize <ServerHeldItemChange>(packet.data);
                player.CurrentSlot = (short)(heldItemChange.Slot + 36);

                var heldItem = player.GetHeldItem();

                await server.BroadcastPacketAsync(new EntityEquipment
                {
                    EntityId = client.id,
                    Slot     = ESlot.MainHand,
                    Item     = new ItemStack
                    {
                        Present = heldItem.Present,
                        Count   = (sbyte)heldItem.Count,
                        Id      = heldItem.Id,
                        Nbt     = heldItem.Nbt
                    }
                }, player);

                Logger.LogDebug("Held item change");
                break;

            case 0x26:    //Update command block
                break;

            case 0x27:    //Update command block minecart
                break;

            case 0x28:    // Creative Inventory Action in creative they send this to replace whatever item existed in the slot
            {
                var ca = PacketSerializer.FastDeserialize <CreativeInventoryAction>(packet.data);

                player.Inventory.SetItem(ca.ClickedSlot, new ItemStack(ca.ClickedItem.Id, ca.ClickedItem.Count)
                    {
                        Nbt     = ca.ClickedItem.Nbt,
                        Present = ca.ClickedItem.Present
                    });

                if (ca.ClickedSlot >= 36 && ca.ClickedSlot <= 44)
                {
                    heldItem = player.GetHeldItem();
                    await server.BroadcastPacketAsync(new EntityEquipment
                        {
                            EntityId = client.id,
                            Slot     = ESlot.MainHand,
                            Item     = new ItemStack
                            {
                                Present = heldItem.Present,
                                Count   = (sbyte)heldItem.Count,
                                Id      = heldItem.Id,
                                Nbt     = heldItem.Nbt
                            }
                        }, player);
                }
            }
            break;

            case 0x29:    //Update jigsaw block
                break;

            case 0x2A:    //Update structure block
                break;

            case 0x2B:    //Update sign
                break;

            case 0x2C:    // Animation (serverbound)
                var serverAnim = PacketSerializer.FastDeserialize <Animation>(packet.data);

                //TODO broadcast entity animation to nearby players
                switch (serverAnim.Hand)
                {
                case Hand.MainHand:
                    await server.BroadcastPacketAsync(new EntityAnimation
                    {
                        EntityId  = client.id,
                        Animation = EAnimation.SwingMainArm
                    }, player);

                    break;

                case Hand.OffHand:
                    await server.BroadcastPacketAsync(new EntityAnimation
                    {
                        EntityId  = client.id,
                        Animation = EAnimation.SwingOffhand
                    }, player);

                    break;

                default:
                    break;
                }
                break;

            case 0x2D:    //Spectate
                break;

            case 0x2E:    // Player Block Placement
            {
                var pbp = PacketSerializer.FastDeserialize <PlayerBlockPlacement>(packet.data);

                var currentItem = player.GetHeldItem();

                var block = Registry.GetBlock(currentItem.Type);

                var location = pbp.Location;

                var interactedBlock = server.World.GetBlock(location);

                if (interactedBlock.CanInteract() && !player.Sneaking)
                {
                    var arg = await server.Events.InvokeBlockInteractAsync(new BlockInteractEventArgs(player, block, pbp.Location));

                    if (arg.Cancel)
                    {
                        return;
                    }

                    //TODO open chests/Crafting inventory ^ ^

                    Logger.LogDebug($"Block Interact: {interactedBlock} - {location}");

                    return;
                }

                if (player.Gamemode != Gamemode.Creative)
                {
                    player.Inventory.RemoveItem(player.CurrentSlot);
                }

                switch (pbp.Face)         // TODO fix this for logs
                {
                case BlockFace.Bottom:
                    location.Y -= 1;
                    break;

                case BlockFace.Top:
                    location.Y += 1;
                    break;

                case BlockFace.North:
                    location.Z -= 1;
                    break;

                case BlockFace.South:
                    location.Z += 1;
                    break;

                case BlockFace.West:
                    location.X -= 1;
                    break;

                case BlockFace.East:
                    location.X += 1;
                    break;

                default:
                    break;
                }

                block.Location = location;
                server.World.SetBlock(location, block);

                await server.BroadcastBlockPlacementAsync(player, block, location);

                break;
            }

            case 0x2F:    //Use item
                Logger.LogDebug("Use item");
                break;
            }
        }
Ejemplo n.º 20
0
 public async Task ReadAsync(MinecraftStream stream)
 {
     this.ItemName = await stream.ReadStringAsync();
 }
Ejemplo n.º 21
0
 public async Task ReadAsync(MinecraftStream stream)
 {
     this.RecipeId = await stream.ReadStringAsync();
 }