From 8bf891a6d84310648ed01b67f107e76ec32ca090 Mon Sep 17 00:00:00 2001 From: bixilon Date: Sun, 7 Jun 2020 23:48:16 +0200 Subject: [PATCH] entities wip (8): equipment (not working because of missing nbt support); Inventory wip(1) --- .idea/dictionaries/moritz.xml | 2 + .../game/datatypes/ChatComponent.java | 5 + .../bixilon/minosoft/game/datatypes/Slot.java | 15 ++- .../minosoft/game/datatypes/Slots.java | 117 ++++++++++++++++++ .../game/datatypes/entities/Entity.java | 6 + .../game/datatypes/entities/OtherPlayer.java | 15 +++ .../game/datatypes/entities/Zombie.java | 16 +++ .../play/PacketEntityEquipment.java | 67 ++++++++++ .../protocol/protocol/InByteBuffer.java | 5 +- .../protocol/protocol/PacketHandler.java | 4 + .../minosoft/protocol/protocol/Protocol.java | 1 + 11 files changed, 247 insertions(+), 6 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/game/datatypes/Slots.java create mode 100644 src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityEquipment.java diff --git a/.idea/dictionaries/moritz.xml b/.idea/dictionaries/moritz.xml index 5aa5b75b4..69e0864e7 100644 --- a/.idea/dictionaries/moritz.xml +++ b/.idea/dictionaries/moritz.xml @@ -1,9 +1,11 @@ + chestplate clientbound cooldown gamemode + hotbar jitpack minosoft mojang diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/ChatComponent.java b/src/main/java/de/bixilon/minosoft/game/datatypes/ChatComponent.java index 59b931583..4d91abef1 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/ChatComponent.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/ChatComponent.java @@ -54,4 +54,9 @@ public class ChatComponent { public JSONObject getRaw() { return this.json; } + + public String getColoredMessage() { + //ToDo + return getRawMessage(); + } } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/Slot.java b/src/main/java/de/bixilon/minosoft/game/datatypes/Slot.java index 9a2f299b3..c89711831 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/Slot.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/Slot.java @@ -13,14 +13,14 @@ package de.bixilon.minosoft.game.datatypes; -import net.querz.nbt.io.NamedTag; +import net.querz.nbt.tag.CompoundTag; public class Slot { int itemId; int itemCount; - NamedTag nbt; + CompoundTag nbt; - public Slot(int itemId, int itemCount, NamedTag nbt) { + public Slot(int itemId, int itemCount, CompoundTag nbt) { this.itemId = itemId; this.itemCount = itemCount; this.nbt = nbt; @@ -34,7 +34,14 @@ public class Slot { return itemCount; } - public NamedTag getNbt() { + public CompoundTag getNbt() { return nbt; } + + public String getDisplayName() { + if (nbt.containsKey("display") && nbt.getCompoundTag("display").containsKey("Name")) { + return new ChatComponent(nbt.getCompoundTag("display").getString("Name")).getColoredMessage(); + } + return ""; //ToDo display name per Item + } } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/Slots.java b/src/main/java/de/bixilon/minosoft/game/datatypes/Slots.java new file mode 100644 index 000000000..00ff5ea2f --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/Slots.java @@ -0,0 +1,117 @@ +/* + * Codename Minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.game.datatypes; + +public class Slots { + public enum Inventory { + CRAFTING_OUTPUT(0), + CRAFTING_UPPER_LEFT(1), + CRAFTING_UPPER_RIGHT(2), + CRAFTING_LOWER_LEFT(3), + CRAFTING_LOWER_RIGHT(4), + ARMOR_HELMET(5), + ARMOR_CHESTPLATE(6), + ARMOR_LEGGINGS(7), + ARMOR_BOOTS(8), + // inventory up to down, left to right + INVENTORY_1_1(9), + INVENTORY_1_2(10), + INVENTORY_1_3(11), + INVENTORY_1_4(12), + INVENTORY_1_5(13), + INVENTORY_1_6(14), + INVENTORY_1_7(15), + INVENTORY_1_8(16), + INVENTORY_1_9(17), + INVENTORY_2_1(18), + INVENTORY_2_2(19), + INVENTORY_2_3(20), + INVENTORY_2_4(21), + INVENTORY_2_5(22), + INVENTORY_2_6(23), + INVENTORY_2_7(24), + INVENTORY_2_8(25), + INVENTORY_2_9(26), + INVENTORY_3_1(27), + INVENTORY_3_2(28), + INVENTORY_3_3(29), + INVENTORY_3_4(30), + INVENTORY_3_5(31), + INVENTORY_3_6(32), + INVENTORY_3_7(33), + INVENTORY_3_8(34), + INVENTORY_3_9(35), + + // left to right + HOTBAR_1(36), + HOTBAR_2(27), + HOTBAR_3(38), + HOTBAR_4(39), + HOTBAR_5(40), + HOTBAR_6(41), + HOTBAR_7(42), + HOTBAR_8(43), + HOTBAR_9(44), + OFF_HAND(45); + + + final int id; + + Inventory(int id) { + this.id = id; + } + + public static Inventory byId(int id) { + for (Inventory i : values()) { + if (i.getId() == id) { + return i; + } + } + return null; + } + + public int getId() { + return id; + } + } + + public enum Entity { + HELD(0), + BOOTS(1), + LEGGINGS(2), + CHESTPLATE(3), + HELMET(4); + + + final int id; + + Entity(int id) { + this.id = id; + } + + public static Entity byId(int id) { + for (Entity e : values()) { + if (e.getId() == id) { + return e; + } + } + return null; + } + + public int getId() { + return id; + } + } + +} \ No newline at end of file diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/Entity.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/Entity.java index 81efc46a0..0d965bced 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/Entity.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/Entity.java @@ -13,6 +13,8 @@ package de.bixilon.minosoft.game.datatypes.entities; +import de.bixilon.minosoft.game.datatypes.Slot; +import de.bixilon.minosoft.game.datatypes.Slots; import de.bixilon.minosoft.game.datatypes.entities.meta.EntityMetaData; public interface Entity { @@ -46,5 +48,9 @@ public interface Entity { void setMetaData(EntityMetaData data); + void setEquipment(Slots.Entity slot, Slot data); + + Slot getEquipment(Slots.Entity slot); + } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/OtherPlayer.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/OtherPlayer.java index dcdd4fb09..18aabc2bf 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/OtherPlayer.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/OtherPlayer.java @@ -15,9 +15,12 @@ package de.bixilon.minosoft.game.datatypes.entities; import de.bixilon.minosoft.game.datatypes.PlayerPropertyData; +import de.bixilon.minosoft.game.datatypes.Slot; +import de.bixilon.minosoft.game.datatypes.Slots; import de.bixilon.minosoft.game.datatypes.entities.meta.EntityMetaData; import de.bixilon.minosoft.game.datatypes.entities.meta.HumanMetaData; +import java.util.HashMap; import java.util.UUID; public class OtherPlayer implements Mob { @@ -34,6 +37,7 @@ public class OtherPlayer implements Mob { HumanMetaData metaData; float health; Pose status = Pose.STANDING; + final HashMap equipment; public OtherPlayer(int id, String name, UUID uuid, PlayerPropertyData[] properties, Location location, int yaw, int pitch, short currentItem, HumanMetaData metaData) { this.id = id; @@ -45,6 +49,7 @@ public class OtherPlayer implements Mob { this.pitch = pitch; this.currentItem = currentItem; this.metaData = metaData; + equipment = new HashMap<>(); } @Override @@ -188,4 +193,14 @@ public class OtherPlayer implements Mob { public Pose getStatus() { return status; } + + @Override + public void setEquipment(Slots.Entity slot, Slot data) { + equipment.replace(slot, data); + } + + @Override + public Slot getEquipment(Slots.Entity slot) { + return equipment.get(slot); + } } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/Zombie.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/Zombie.java index cf4799a4a..6ef768c2c 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/Zombie.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/Zombie.java @@ -13,11 +13,15 @@ package de.bixilon.minosoft.game.datatypes.entities; +import de.bixilon.minosoft.game.datatypes.Slot; +import de.bixilon.minosoft.game.datatypes.Slots; import de.bixilon.minosoft.game.datatypes.entities.meta.EntityMetaData; import de.bixilon.minosoft.game.datatypes.entities.meta.ZombieMetaData; import de.bixilon.minosoft.protocol.protocol.InByteBuffer; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; +import java.util.HashMap; + public class Zombie implements Mob { final int id; Location location; @@ -27,6 +31,7 @@ public class Zombie implements Mob { int headYaw; ZombieMetaData metaData; float health; + final HashMap equipment; public Zombie(int id, Location location, int yaw, int pitch, Velocity velocity, InByteBuffer buffer, ProtocolVersion v) { this.id = id; @@ -35,6 +40,7 @@ public class Zombie implements Mob { this.pitch = pitch; this.velocity = velocity; this.metaData = new ZombieMetaData(buffer, v); + this.equipment = new HashMap<>(); } @Override @@ -115,6 +121,16 @@ public class Zombie implements Mob { this.metaData = (ZombieMetaData) data; } + @Override + public void setEquipment(Slots.Entity slot, Slot data) { + equipment.replace(slot, data); + } + + @Override + public Slot getEquipment(Slots.Entity slot) { + return equipment.get(slot); + } + @Override public float getHealth() { return health; diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityEquipment.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityEquipment.java new file mode 100644 index 000000000..91b127822 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityEquipment.java @@ -0,0 +1,67 @@ +/* + * Codename Minosoft + * Copyright (C) 2020 Moritz Zwerger + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.protocol.packets.clientbound.play; + +import de.bixilon.minosoft.game.datatypes.Slot; +import de.bixilon.minosoft.game.datatypes.Slots; +import de.bixilon.minosoft.logging.Log; +import de.bixilon.minosoft.protocol.packets.ClientboundPacket; +import de.bixilon.minosoft.protocol.protocol.InPacketBuffer; +import de.bixilon.minosoft.protocol.protocol.PacketHandler; +import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; + +public class PacketEntityEquipment implements ClientboundPacket { + int entityId; + Slots.Entity slot; + Slot data; + + + @Override + public void read(InPacketBuffer buffer, ProtocolVersion v) { + switch (v) { + case VERSION_1_7_10: + entityId = buffer.readInteger(); + this.slot = Slots.Entity.byId(buffer.readShort()); + this.data = buffer.readSlot(); + break; + } + } + + @Override + public void log() { + if (data != null) { + Log.protocol(String.format("Entity equipment changed (entityId=%d, slot=%s): %s", entityId, slot.name(), data.getDisplayName())); + } else { + // null means nothing, means air + Log.protocol(String.format("Entity equipment changed (entityId=%d, slot=%s): AIR", entityId, slot.name())); + } + } + + @Override + public void handle(PacketHandler h) { + h.handle(this); + } + + public int getEntityId() { + return entityId; + } + + public Slots.Entity getSlot() { + return slot; + } + + public Slot getData() { + return data; + } +} diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java index 06954f4fd..0717e8f1d 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java @@ -22,7 +22,7 @@ import de.bixilon.minosoft.game.datatypes.particle.BlockParticle; import de.bixilon.minosoft.game.datatypes.particle.OtherParticles; import de.bixilon.minosoft.game.datatypes.particle.Particle; import de.bixilon.minosoft.game.datatypes.particle.Particles; -import net.querz.nbt.io.NamedTag; +import net.querz.nbt.tag.CompoundTag; import org.json.JSONObject; import java.lang.reflect.InvocationTargetException; @@ -212,8 +212,9 @@ public class InByteBuffer { return null; } - public NamedTag readNBT() { + public CompoundTag readNBT() { //ToDo + new CompoundTag(); return null; } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java index 9701001e4..007bdaaf6 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java @@ -201,4 +201,8 @@ public class PacketHandler { } } + + public void handle(PacketEntityEquipment pkg) { + connection.getPlayer().getWorld().getEntity(pkg.getEntityId()).setEquipment(pkg.getSlot(), pkg.getData()); + } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/Protocol.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/Protocol.java index 49b9973b9..98129414d 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/Protocol.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/Protocol.java @@ -73,5 +73,6 @@ public interface Protocol { packetClassMapping.put(Packets.Clientbound.PLAY_ENTITY_HEAD_LOOK, PacketEntityHeadRotation.class); packetClassMapping.put(Packets.Clientbound.PLAY_WINDOW_ITEMS, PacketWindowItems.class); packetClassMapping.put(Packets.Clientbound.PLAY_ENTITY_METADATA, PacketEntityMetadata.class); + packetClassMapping.put(Packets.Clientbound.PLAY_ENTITY_EQUIPMENT, PacketEntityEquipment.class); } } \ No newline at end of file