diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/VillagerData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/VillagerData.java new file mode 100644 index 000000000..dc4e1fa9a --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/VillagerData.java @@ -0,0 +1,112 @@ +/* + * 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.entities; + +import de.bixilon.minosoft.game.datatypes.MapSet; +import de.bixilon.minosoft.game.datatypes.VersionValueMap; +import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; + +public class VillagerData { + final int type; + final int profession; + final int level; + + public VillagerData(int type, int profession, int level) { + this.type = type; + this.profession = profession; + this.level = level; + } + + public int getType() { + return type; + } + + public int getProfession() { + return profession; + } + + public int getLevel() { + return level; + } + + public enum VillagerProfessions { + NONE(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 0)}), + ARMORER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 1)}), + BUTCHER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 4), new MapSet<>(ProtocolVersion.VERSION_1_14_4, 2)}), + CARTOGRAPHER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 3)}), + CLERIC(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 4)}), + FARMER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 0), new MapSet<>(ProtocolVersion.VERSION_1_14_4, 5)}), + FISHERMAN(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 6)}), + FLETCHER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 7)}), + LEATHER_WORKER(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 8)}), + LIBRARIAN(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 1), new MapSet<>(ProtocolVersion.VERSION_1_14_4, 9)}), + MASON(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 10)}), + NITWIT(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 5), new MapSet<>(ProtocolVersion.VERSION_1_14_4, 11)}), + SHEPHERD(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 12)}), + TOOL_SMITH(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 13)}), + WEAPON_SMITH(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 14)}), + PRIEST(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 2), new MapSet<>(ProtocolVersion.VERSION_1_14_4, -1)}), + BLACKSMITH(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_7_10, 3), new MapSet<>(ProtocolVersion.VERSION_1_14_4, -1)}), + + HUSK(new MapSet[]{}); // used earlier (ZombieVillagerMeta) + + final VersionValueMap valueMap; + + VillagerProfessions(MapSet[] values) { + valueMap = new VersionValueMap<>(values, true); + } + + public static VillagerProfessions byId(int id, ProtocolVersion version) { + for (VillagerProfessions profession : values()) { + if (profession.getId(version) == id) { + return profession; + } + } + return null; + } + + public int getId(ProtocolVersion version) { + return valueMap.get(version); + } + } + + public enum VillagerTypes { + DESSERT(0), + JUNGLE(1), + PLAINS(2), + SAVANNA(3), + SNOW(4), + SWAMP(5), + TAIGA(6); + + final int id; + + VillagerTypes(int id) { + this.id = id; + } + + public static VillagerTypes byId(int id) { + for (VillagerTypes type : values()) { + if (type.getId() == id) { + return type; + } + } + return null; + } + + public int getId() { + return id; + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EntityMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EntityMetaData.java index b16ffcc8c..a6d65e654 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EntityMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/EntityMetaData.java @@ -14,6 +14,7 @@ package de.bixilon.minosoft.game.datatypes.entities.meta; import de.bixilon.minosoft.game.datatypes.*; import de.bixilon.minosoft.game.datatypes.blocks.Blocks; +import de.bixilon.minosoft.game.datatypes.entities.VillagerData; import de.bixilon.minosoft.protocol.protocol.InByteBuffer; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; import de.bixilon.minosoft.util.BitByte; @@ -109,6 +110,12 @@ public class EntityMetaData { int blockId = buffer.readVarInt(); data = Blocks.getBlock(blockId, buffer.getVersion()); break; + case OPT_VAR_INT: + data = buffer.readVarInt() - 1; + break; + case VILLAGER_DATA: + data = new VillagerData(buffer.readVarInt(), buffer.readVarInt(), buffer.readVarInt()); + break; default: throw new IllegalStateException("Unexpected value: " + type); } @@ -299,9 +306,9 @@ public class EntityMetaData { OPT_BLOCK_ID(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_10, 12), new MapSet<>(ProtocolVersion.VERSION_1_13_2, 13)}), NBT(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_12_2, 13), new MapSet<>(ProtocolVersion.VERSION_1_13_2, 14)}), PARTICLE(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_13_2, 15)}), - VILLAGER_DATA(-1), - OPT_VAR_INT(-1), - POSE(-1); + VILLAGER_DATA(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 16)}), + OPT_VAR_INT(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 17)}), + POSE(new MapSet[]{new MapSet<>(ProtocolVersion.VERSION_1_14_4, 18)}); final VersionValueMap valueMap; diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/HuskMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/HuskMetaData.java index 8b09e2d2c..7b3ca63d1 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/HuskMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/HuskMetaData.java @@ -12,6 +12,7 @@ */ package de.bixilon.minosoft.game.datatypes.entities.meta; +import de.bixilon.minosoft.game.datatypes.entities.VillagerData; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; import java.util.HashMap; @@ -24,7 +25,7 @@ public class HuskMetaData extends ZombieMetaData { @Override - public VillagerMetaData.VillagerType getType() { - return null; // ToDo: husk support + public VillagerData.VillagerProfessions getProfession() { + return VillagerData.VillagerProfessions.HUSK; } } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/VillagerMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/VillagerMetaData.java index 672e17349..ebab5197f 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/VillagerMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/VillagerMetaData.java @@ -12,6 +12,7 @@ */ package de.bixilon.minosoft.game.datatypes.entities.meta; +import de.bixilon.minosoft.game.datatypes.entities.VillagerData; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; import java.util.HashMap; @@ -23,49 +24,20 @@ public class VillagerMetaData extends AgeableMetaData { } - public VillagerType getVillagerType() { + public VillagerData.VillagerProfessions getProfession() { switch (version) { case VERSION_1_7_10: case VERSION_1_8: - return VillagerType.byId((int) sets.get(16).getData()); + return VillagerData.VillagerProfessions.byId((int) sets.get(16).getData(), version); case VERSION_1_9_4: - return VillagerType.byId((int) sets.get(12).getData()); + return VillagerData.VillagerProfessions.byId((int) sets.get(12).getData(), version); case VERSION_1_10: case VERSION_1_11_2: case VERSION_1_12_2: case VERSION_1_13_2: - return VillagerType.byId((int) sets.get(13).getData()); - } - return VillagerType.FARMER; - } - - public enum VillagerType { - FARMER(0), - LIBRARIAN(1), - PRIEST(2), - BLACKSMITH(3), - BUTCHER(4), - NITWIT(5); - - - final int id; - - VillagerType(int id) { - this.id = id; - } - - public static VillagerType byId(int id) { - for (VillagerType t : values()) { - if (t.getId() == id) { - return t; - } - } - return null; - } - - public int getId() { - return id; + return VillagerData.VillagerProfessions.byId((int) sets.get(13).getData(), version); } + return VillagerData.VillagerProfessions.FARMER; } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieMetaData.java index 7d9b2b55d..6dff5b192 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieMetaData.java @@ -12,6 +12,7 @@ */ package de.bixilon.minosoft.game.datatypes.entities.meta; +import de.bixilon.minosoft.game.datatypes.entities.VillagerData; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; import java.util.HashMap; @@ -39,17 +40,20 @@ public class ZombieMetaData extends MobMetaData { return false; } - public VillagerMetaData.VillagerType getType() { + public VillagerData.VillagerProfessions getProfession() { switch (version) { case VERSION_1_7_10: case VERSION_1_8: - return VillagerMetaData.VillagerType.byId((byte) sets.get(13).getData() - 1); - case VERSION_1_9_4: - return VillagerMetaData.VillagerType.byId((int) sets.get(12).getData() - 1); case VERSION_1_10: - return VillagerMetaData.VillagerType.byId((int) sets.get(13).getData() - 1); + byte set = (byte) sets.get(13).getData(); + if (version == ProtocolVersion.VERSION_1_10 && set == 6) { + return VillagerData.VillagerProfessions.HUSK; + } + return VillagerData.VillagerProfessions.byId(set - 1, version); + case VERSION_1_9_4: + return VillagerData.VillagerProfessions.byId((int) sets.get(12).getData() - 1, version); } - return null; // ToDo: Husk support + return VillagerData.VillagerProfessions.NONE; } public boolean isConverting() { diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieVillagerMetaData.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieVillagerMetaData.java index f9a0c3a75..f82dcc5a0 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieVillagerMetaData.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/meta/ZombieVillagerMetaData.java @@ -12,6 +12,7 @@ */ package de.bixilon.minosoft.game.datatypes.entities.meta; +import de.bixilon.minosoft.game.datatypes.entities.VillagerData; import de.bixilon.minosoft.protocol.protocol.ProtocolVersion; import java.util.HashMap; @@ -23,15 +24,16 @@ public class ZombieVillagerMetaData extends ZombieMetaData { } @Override - public VillagerMetaData.VillagerType getType() { + public VillagerData.VillagerProfessions getProfession() { switch (version) { case VERSION_1_11_2: case VERSION_1_12_2: - return VillagerMetaData.VillagerType.byId((int) sets.get(16).getData() + 1); + return VillagerData.VillagerProfessions.byId((int) sets.get(16).getData(), version); case VERSION_1_13_2: - return VillagerMetaData.VillagerType.byId((int) sets.get(17).getData() + 1); + return VillagerData.VillagerProfessions.byId((int) sets.get(17).getData(), version); + default: + return super.getProfession(); } - return VillagerMetaData.VillagerType.FARMER; } @Override @@ -42,8 +44,8 @@ public class ZombieVillagerMetaData extends ZombieMetaData { return ((boolean) sets.get(15).getData()); case VERSION_1_13_2: return ((boolean) sets.get(16).getData()); - + default: + return super.isConverting(); } - return false; } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityTeleport.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityTeleport.java index 05620b307..0af0151d6 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityTeleport.java +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityTeleport.java @@ -62,7 +62,7 @@ public class PacketEntityTeleport implements ClientboundPacket { @Override public void log() { - Log.protocol(String.format("Entity %d moved to %s (yaw=%s, pitch=%s", entityId, location.toString(), yaw, pitch)); + Log.protocol(String.format("Entity %d moved to %s (yaw=%s, pitch=%s)", entityId, location.toString(), yaw, pitch)); } public int getEntityId() { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMapData.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMapData.java index 0101fcbc6..0b54a3e9d 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMapData.java +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketMapData.java @@ -109,7 +109,7 @@ public class PacketMapData implements ClientboundPacket { mapId = buffer.readVarInt(); scale = buffer.readByte(); boolean trackPosition = buffer.readBoolean(); - if (buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_12_2.getVersionNumber()) { + if (buffer.getVersion().getVersionNumber() >= ProtocolVersion.VERSION_1_14_4.getVersionNumber()) { locked = buffer.readBoolean(); } int pinCount = buffer.readVarInt(); 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 8dfcff91e..c052728b4 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java @@ -376,7 +376,8 @@ public class InByteBuffer { break; } case VERSION_1_12_2: - case VERSION_1_13_2: { + case VERSION_1_13_2: + case VERSION_1_14_4: { byte index = readByte(); while (index != (byte) 0xFF) { EntityMetaData.Types type = EntityMetaData.Types.byId(readVarInt(), version);