diff --git a/src/main/java/de/bixilon/minosoft/EntityPropertyModifier.java b/src/main/java/de/bixilon/minosoft/EntityPropertyModifier.java
new file mode 100644
index 000000000..603511fa8
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/EntityPropertyModifier.java
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+public class EntityPropertyModifier {
+ double amount;
+
+ public EntityPropertyModifier(double amount) {
+ this.amount = amount;
+ }
+
+ public double getAmount() {
+ return amount;
+ }
+
+ public void setAmount(double amount) {
+ this.amount = amount;
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/EntityProperty.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/EntityProperty.java
new file mode 100644
index 000000000..c11eddf39
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/EntityProperty.java
@@ -0,0 +1,36 @@
+/*
+ * 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.EntityPropertyModifier;
+
+import java.util.HashMap;
+import java.util.UUID;
+
+public class EntityProperty {
+ final double value;
+ HashMap modifiers = new HashMap<>();
+
+ public EntityProperty(double value) {
+ this.value = value;
+ }
+
+ public double getValue() {
+ return value;
+ }
+
+ public HashMap getModifiers() {
+ return modifiers;
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/entities/EntityPropertyKey.java b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/EntityPropertyKey.java
new file mode 100644
index 000000000..5cea18c38
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/game/datatypes/entities/EntityPropertyKey.java
@@ -0,0 +1,45 @@
+/*
+ * 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.Identifier;
+
+public enum EntityPropertyKey {
+ MAX_HEALTH(new Identifier("generic.maxHealth")),
+ FOLLOW_RANGE(new Identifier("generic.followRange")),
+ KNOCKBACK_RESISTANCE(new Identifier("generic.knockbackResistance")),
+ MOVEMENT_SPEED(new Identifier("generic.movementSpeed")),
+ ATTACK_DAMAGE(new Identifier("generic.attackDamage")),
+ HORSE_JUMP_STRENGTH(new Identifier("horse.jumpStrength")),
+ ZOMBIE_SPAWN_REINFORCEMENT(new Identifier("zombie.spawnReinforcements"));
+
+ final Identifier identifier;
+
+ EntityPropertyKey(Identifier identifier) {
+ this.identifier = identifier;
+ }
+
+ public static EntityPropertyKey byIdentifier(Identifier identifier) {
+ for (EntityPropertyKey b : values()) {
+ if (b.getIdentifier().equals(identifier)) {
+ return b;
+ }
+ }
+ return null;
+ }
+
+ public Identifier getIdentifier() {
+ return identifier;
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityProperties.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityProperties.java
new file mode 100644
index 000000000..6c5213e8f
--- /dev/null
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketEntityProperties.java
@@ -0,0 +1,111 @@
+/*
+ * 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.Identifier;
+import de.bixilon.minosoft.game.datatypes.entities.EntityProperty;
+import de.bixilon.minosoft.game.datatypes.entities.EntityPropertyKey;
+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;
+
+import java.util.HashMap;
+import java.util.UUID;
+
+public class PacketEntityProperties implements ClientboundPacket {
+ int entityId;
+ HashMap properties = new HashMap<>();
+
+
+ @Override
+ public void read(InPacketBuffer buffer, ProtocolVersion v) {
+ switch (v) {
+ case VERSION_1_7_10: {
+ entityId = buffer.readInteger();
+ int count = buffer.readInteger();
+ for (int i = 0; i < count; i++) {
+ EntityPropertyKey key = EntityPropertyKey.byIdentifier(new Identifier(buffer.readString()));
+ double value = buffer.readDouble();
+ short listLength = buffer.readShort();
+ for (int ii = 0; ii < listLength; ii++) {
+ UUID uuid = buffer.readUUID();
+ double amount = buffer.readDouble();
+ ModifierAction operation = ModifierAction.byId(buffer.readByte());
+ //ToDo: modifiers
+ }
+ properties.put(key, new EntityProperty(value));
+ }
+ break;
+ }
+ case VERSION_1_8: {
+ entityId = buffer.readVarInt();
+ int count = buffer.readInteger();
+ for (int i = 0; i < count; i++) {
+ EntityPropertyKey key = EntityPropertyKey.byIdentifier(new Identifier(buffer.readString()));
+ double value = buffer.readDouble();
+ int listLength = buffer.readVarInt();
+ for (int ii = 0; ii < listLength; ii++) {
+ UUID uuid = buffer.readUUID();
+ double amount = buffer.readDouble();
+ ModifierAction operation = ModifierAction.byId(buffer.readByte());
+ //ToDo: modifiers
+ }
+ properties.put(key, new EntityProperty(value));
+ }
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void log() {
+ Log.protocol(String.format("Received entity properties (entityId=%d)", entityId));
+ }
+
+ @Override
+ public void handle(PacketHandler h) {
+ h.handle(this);
+ }
+
+ public int getEntityId() {
+ return entityId;
+ }
+
+ public enum ModifierAction {
+ ADD(0),
+ ADD_PERCENT(1),
+ MULTIPLY(2);
+
+ final int id;
+
+ ModifierAction(int id) {
+ this.id = id;
+ }
+
+ public static ModifierAction byId(int id) {
+ for (ModifierAction a : values()) {
+ if (a.getId() == id) {
+ return a;
+ }
+ }
+ return null;
+ }
+
+ public int getId() {
+ return id;
+ }
+ }
+}
diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketPlayerInfo.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketPlayerInfo.java
index 92d28b2c1..f8e340bec 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketPlayerInfo.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketPlayerInfo.java
@@ -86,7 +86,7 @@ public class PacketPlayerInfo implements ClientboundPacket {
public void log() {
for (PlayerInfoBulk property : infos) {
if (property.isLegacy()) {
- Log.game(String.format("[TAB] Player info bulk (uuid=%s)", property.getUUID()));
+ Log.game(String.format("[TAB] Player info bulk (uuid=%s, name=%s, ping=%d)", property.getUUID(), property.getName(), property.getPing()));
} else {
Log.game(String.format("[TAB] Player info bulk (uuid=%s, action=%s, name=%s, gameMode=%s, ping=%d)", property.getUUID(), property.getAction(), property.getName(), ((property.getGameMode() == null) ? "null" : property.getGameMode().name()), property.getPing()));
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 77e33e6c1..7f4dce327 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java
@@ -125,6 +125,11 @@ public class PacketHandler {
break;
case REMOVE_PLAYER:
if (bulk.isLegacy()) {
+ PlayerInfo info = connection.getPlayer().getPlayerInfo(bulk.getName());
+ if (info == null) {
+ // not initialized yet
+ return;
+ }
connection.getPlayer().getPlayerInfos().remove(connection.getPlayer().getPlayerInfo(bulk.getName()).getUUID());
return;
}
@@ -485,7 +490,11 @@ public class PacketHandler {
}
public void handle(PackerResourcePackSend pkg) {
- //ToDo ask user, download pack. for now send an okay
+ //ToDo ask user, download pack. for now just send an okay
connection.sendPacket(new PacketResourcePackStatus(pkg.getHash(), PacketResourcePackStatus.ResourcePackStatus.SUCCESSFULLY));
}
+
+ public void handle(PacketEntityProperties pkg) {
+ //ToDo
+ }
}
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 56c3aff43..2df8b9881 100644
--- a/src/main/java/de/bixilon/minosoft/protocol/protocol/Protocol.java
+++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/Protocol.java
@@ -116,6 +116,7 @@ public abstract class Protocol implements ProtocolInterface {
packetClassMapping.put(Packets.Clientbound.PLAY_SERVER_DIFFICULTY, PacketServerDifficulty.class);
packetClassMapping.put(Packets.Clientbound.PLAY_LIST_HEADER_AND_FOOTER, PacketTabHeaderAndFooter.class);
packetClassMapping.put(Packets.Clientbound.PLAY_RESOURCE_PACK_SEND, PackerResourcePackSend.class);
+ packetClassMapping.put(Packets.Clientbound.PLAY_ENTITY_PROPERTIES, PacketEntityProperties.class);
}
public static ProtocolVersion getLowestVersionSupported() {