entity mappings for 1.8.9, pre flattening bug fixes

This commit is contained in:
Bixilon 2020-11-25 18:23:12 +01:00
parent ba62fe8316
commit cb1bf13140
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
19 changed files with 212 additions and 29 deletions

View File

@ -154,6 +154,7 @@ public final class EntityClassMappings {
ENTITY_CLASS_MAPPINGS.put(Zombie.class, new ModIdentifier("zombie")); ENTITY_CLASS_MAPPINGS.put(Zombie.class, new ModIdentifier("zombie"));
ENTITY_CLASS_MAPPINGS.put(ZombieHorse.class, new ModIdentifier("zombie_horse")); ENTITY_CLASS_MAPPINGS.put(ZombieHorse.class, new ModIdentifier("zombie_horse"));
ENTITY_CLASS_MAPPINGS.put(ZombieVillager.class, new ModIdentifier("zombie_villager")); ENTITY_CLASS_MAPPINGS.put(ZombieVillager.class, new ModIdentifier("zombie_villager"));
ENTITY_CLASS_MAPPINGS.put(ZombiePigman.class, new ModIdentifier("zombie_pigman"));
ENTITY_CLASS_MAPPINGS.put(ZombifiedPiglin.class, new ModIdentifier("zombified_piglin")); ENTITY_CLASS_MAPPINGS.put(ZombifiedPiglin.class, new ModIdentifier("zombified_piglin"));
ENTITY_CLASS_MAPPINGS.put(PlayerEntity.class, new ModIdentifier("player")); ENTITY_CLASS_MAPPINGS.put(PlayerEntity.class, new ModIdentifier("player"));
ENTITY_CLASS_MAPPINGS.put(FishingHook.class, new ModIdentifier("fishing_bobber")); ENTITY_CLASS_MAPPINGS.put(FishingHook.class, new ModIdentifier("fishing_bobber"));

View File

@ -44,7 +44,7 @@ public class EntityMetaData {
return switch (type) { return switch (type) {
case BYTE -> buffer.readByte(); case BYTE -> buffer.readByte();
case VAR_INT -> buffer.readVarInt(); case VAR_INT -> buffer.readVarInt();
case SHORT -> buffer.readShort(); case SHORT -> buffer.readUnsignedShort();
case INT -> buffer.readInt(); case INT -> buffer.readInt();
case FLOAT -> buffer.readFloat(); case FLOAT -> buffer.readFloat();
case STRING -> buffer.readString(); case STRING -> buffer.readString();
@ -226,7 +226,11 @@ public class EntityMetaData {
} }
public ChatComponent getChatComponent(EntityMetaDataFields field) { public ChatComponent getChatComponent(EntityMetaDataFields field) {
return get(field); Object object = get(field);
if (object instanceof String string) {
return ChatComponent.fromString(string);
}
return (ChatComponent) object;
} }
public String getString(EntityMetaDataFields field) { public String getString(EntityMetaDataFields field) {

View File

@ -71,7 +71,7 @@ public enum EntityMetaDataFields {
BOAT_HURT(0), BOAT_HURT(0),
BOAT_HURT_DIRECTION(1), BOAT_HURT_DIRECTION(1),
BOAT_DAMAGE_TAKEN(0f), BOAT_DAMAGE_TAKEN(0f),
BOAT_MATERIAL(Boat.BoatMaterials.OAK), BOAT_MATERIAL(Boat.BoatMaterials.OAK.ordinal()),
BOAT_PADDLE_LEFT(false), BOAT_PADDLE_LEFT(false),
BOAT_PADDLE_RIGHT(false), BOAT_PADDLE_RIGHT(false),
BOAT_BUBBLE_TIME(0), BOAT_BUBBLE_TIME(0),
@ -265,7 +265,24 @@ public enum EntityMetaDataFields {
PILLAGER_IS_CHARGING_CROSSBOW(false), PILLAGER_IS_CHARGING_CROSSBOW(false),
THROWN_EYE_OF_ENDER_ITEM; THROWN_EYE_OF_ENDER_ITEM,
// pretty old stuff here. 1.8 mostly (or even after, I don't know and I don't care)
LEGACY_SKELETON_TYPE((byte) 0),
LEGACY_ENDERMAN_CARRIED_BLOCK(0),
LEGACY_ENDERMAN_CARRIED_BLOCK_DATA(0),
LEGACY_WITCH_IS_AGGRESSIVE(false),
LEGACY_GUARDIAN_FLAGS((byte) 0),
LEGACY_OCELOT_TYPE((byte) 0),
LEGACY_HORSE_OWNER_NAME(""),
LEGACY_HORSE_SPECIAL_TYPE((byte) 0),
LEGACY_HORSE_ARMOR(0),
LEGACY_VILLAGE_PROFESSION(0),
LEGACY_END_CRYSTAL_HEALTH(5),
LEGACY_LIVING_ENTITY_AI_DISABLED((byte) 0),
LEGACY_AGEABLE_ENTITY_AGE((byte) 0),
LEGACY_AGEABLE_OWNER_NAME("");
private final Object defaultValue; private final Object defaultValue;

View File

@ -37,7 +37,7 @@ public enum Objects {
ARROW(60, Arrow.class), // ToDo: Tipped Arrows ARROW(60, Arrow.class), // ToDo: Tipped Arrows
SNOWBALL(61, ThrownSnowball.class), SNOWBALL(61, ThrownSnowball.class),
EGG(62, ThrownEgg.class), EGG(62, ThrownEgg.class),
FIREBALL(63, Fireball.class), FIREBALL(63, LargeFireball.class),
FIRE_CHARGE(64, SmallFireball.class), FIRE_CHARGE(64, SmallFireball.class),
ENDER_PEARL(65, ThrownEnderPearl.class), ENDER_PEARL(65, ThrownEnderPearl.class),
WITHER_SKULL(66, WitherSkull.class), WITHER_SKULL(66, WitherSkull.class),

View File

@ -32,6 +32,7 @@ import java.util.TreeMap;
import java.util.UUID; import java.util.UUID;
public abstract class Entity { public abstract class Entity {
protected final Connection connection;
protected final EntityInformation information; protected final EntityInformation information;
protected final int entityId; protected final int entityId;
protected final UUID uuid; protected final UUID uuid;
@ -44,6 +45,7 @@ public abstract class Entity {
protected EntityMetaData metaData; protected EntityMetaData metaData;
public Entity(Connection connection, int entityId, UUID uuid, Location location, EntityRotation rotation) { public Entity(Connection connection, int entityId, UUID uuid, Location location, EntityRotation rotation) {
this.connection = connection;
this.information = connection.getMapping().getEntityInformation(getClass()); this.information = connection.getMapping().getEntityInformation(getClass());
this.entityId = entityId; this.entityId = entityId;
this.uuid = uuid; this.uuid = uuid;
@ -230,6 +232,9 @@ public abstract class Entity {
@Override @Override
public String toString() { public String toString() {
if (information == null) {
return this.getClass().getCanonicalName();
}
return String.format("%s:%s", information.getMod(), information.getIdentifier()); return String.format("%s:%s", information.getMod(), information.getIdentifier());
} }

View File

@ -42,6 +42,9 @@ public class Wolf extends TamableAnimal {
@EntityMetaDataFunction(identifier = "angerTime") @EntityMetaDataFunction(identifier = "angerTime")
public int getAngerTime() { public int getAngerTime() {
if (versionId <= 47) {//ToDo
return metaData.getSets().getBitMask(EntityMetaDataFields.TAMABLE_ENTITY_FLAGS, 0x02) ? 1 : 0;
}
return metaData.getSets().getInt(EntityMetaDataFields.WOLF_ANGER_TIME); return metaData.getSets().getInt(EntityMetaDataFields.WOLF_ANGER_TIME);
} }

View File

@ -17,11 +17,16 @@ import de.bixilon.minosoft.data.entities.EntityMetaDataFields;
import de.bixilon.minosoft.data.entities.EntityRotation; import de.bixilon.minosoft.data.entities.EntityRotation;
import de.bixilon.minosoft.data.entities.Location; import de.bixilon.minosoft.data.entities.Location;
import de.bixilon.minosoft.data.entities.entities.EntityMetaDataFunction; import de.bixilon.minosoft.data.entities.entities.EntityMetaDataFunction;
import de.bixilon.minosoft.data.mappings.Item;
import de.bixilon.minosoft.protocol.network.Connection; import de.bixilon.minosoft.protocol.network.Connection;
import javax.annotation.Nullable;
import java.util.UUID; import java.util.UUID;
public class Horse extends AbstractHorse { public class Horse extends AbstractHorse {
private static final Item LEGACY_IRON_ARMOR = new Item("iron_horse_armor");
private static final Item LEGACY_GOLD_ARMOR = new Item("golden_horse_armor");
private static final Item LEGACY_DIAMOND_ARMOR = new Item("diamond_horse_armor");
public Horse(Connection connection, int entityId, UUID uuid, Location location, EntityRotation rotation) { public Horse(Connection connection, int entityId, UUID uuid, Location location, EntityRotation rotation) {
super(connection, entityId, uuid, location, rotation); super(connection, entityId, uuid, location, rotation);
@ -45,6 +50,20 @@ public class Horse extends AbstractHorse {
return HorseDots.byId(getVariant() >> 8); return HorseDots.byId(getVariant() >> 8);
} }
@EntityMetaDataFunction(identifier = "armor")
@Nullable
public Item getArmor() {
if (versionId <= 47) { // ToDo
return null;
}
return switch (metaData.getSets().getInt(EntityMetaDataFields.LEGACY_HORSE_ARMOR)) {
default -> null;
case 1 -> LEGACY_IRON_ARMOR;
case 2 -> LEGACY_GOLD_ARMOR;
case 3 -> LEGACY_DIAMOND_ARMOR;
};
}
public enum HorseColors { public enum HorseColors {
WHITE, WHITE,
CREAMY, CREAMY,

View File

@ -29,6 +29,7 @@ public class ItemFrame extends HangingEntity {
super(connection, entityId, uuid, location, rotation); super(connection, entityId, uuid, location, rotation);
} }
@EntityMetaDataFunction(identifier = "item") @EntityMetaDataFunction(identifier = "item")
@Nullable @Nullable
public Slot getItem() { public Slot getItem() {
@ -36,7 +37,7 @@ public class ItemFrame extends HangingEntity {
} }
@EntityMetaDataFunction(identifier = "itemRotationLevel") @EntityMetaDataFunction(identifier = "itemRotationLevel")
public int getItemRotation() { public int get() {
return metaData.getSets().getInt(EntityMetaDataFields.ITEM_FRAME_ROTATION); return metaData.getSets().getInt(EntityMetaDataFields.ITEM_FRAME_ROTATION);
} }

View File

@ -32,6 +32,9 @@ public class Enderman extends AbstractSkeleton {
@EntityMetaDataFunction(identifier = "carriedBlock") @EntityMetaDataFunction(identifier = "carriedBlock")
@Nullable @Nullable
public Block getCarriedBlock() { public Block getCarriedBlock() {
if (versionId <= 47) { // ToDo: No clue here
return connection.getMapping().getBlockById(metaData.getSets().getInt(EntityMetaDataFields.LEGACY_ENDERMAN_CARRIED_BLOCK) << 4 | metaData.getSets().getInt(EntityMetaDataFields.LEGACY_ENDERMAN_CARRIED_BLOCK_DATA));
}
return metaData.getSets().getBlock(EntityMetaDataFields.ENDERMAN_CARRIED_BLOCK); return metaData.getSets().getBlock(EntityMetaDataFields.ENDERMAN_CARRIED_BLOCK);
} }

View File

@ -0,0 +1,32 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.entities.entities.monster;
import de.bixilon.minosoft.data.entities.EntityRotation;
import de.bixilon.minosoft.data.entities.Location;
import de.bixilon.minosoft.protocol.network.Connection;
import java.util.UUID;
/**
* This class is just for the hashmap, it is not used anywhere
*/
@Deprecated
public class ZombiePigman extends ZombifiedPiglin {
public ZombiePigman(Connection connection, int entityId, UUID uuid, Location location, EntityRotation rotation) {
super(connection, entityId, uuid, location, rotation);
}
}

View File

@ -31,4 +31,8 @@ public class Witch extends Raider {
public boolean isDrinkingPotion() { public boolean isDrinkingPotion() {
return metaData.getSets().getBoolean(EntityMetaDataFields.WITCH_IS_DRINKING_POTION); return metaData.getSets().getBoolean(EntityMetaDataFields.WITCH_IS_DRINKING_POTION);
} }
public boolean isAggressive() {
return metaData.getSets().getBoolean(EntityMetaDataFields.LEGACY_WITCH_IS_AGGRESSIVE);
}
} }

View File

@ -0,0 +1,82 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.mappings;
import de.bixilon.minosoft.data.entities.EntityMetaData;
import de.bixilon.minosoft.data.entities.EntityMetaDataFields;
import de.bixilon.minosoft.data.entities.entities.Entity;
import de.bixilon.minosoft.data.entities.entities.animal.horse.*;
import de.bixilon.minosoft.data.entities.entities.monster.*;
import de.bixilon.minosoft.data.entities.entities.vehicle.*;
public class VersionTweaker {
// some data was packed in mata data in early versions (1.8). This function converts it to the real identifier
public static Class<? extends Entity> getRealEntityClass(Class<? extends Entity> fakeClass, EntityMetaData metaData, int versionId) {
if (fakeClass == ZombiePigman.class) {
return ZombifiedPiglin.class;
} else if (fakeClass == Zombie.class) {
if (versionId > 47) { // ToDo: No clue here
return fakeClass;
}
if (metaData.getSets().getInt(EntityMetaDataFields.ZOMBIE_SPECIAL_TYPE) == 1) {
return ZombieVillager.class;
}
} else if (fakeClass == Skeleton.class) {
if (versionId > 47) { // ToDo: No clue here
return fakeClass;
}
if (metaData.getSets().getInt(EntityMetaDataFields.LEGACY_SKELETON_TYPE) == 1) {
return WitherSkeleton.class;
}
} else if (fakeClass == Guardian.class) {
if (versionId > 47) { // ToDo: No clue here
return fakeClass;
}
if (metaData.getSets().getBitMask(EntityMetaDataFields.LEGACY_GUARDIAN_FLAGS, 0x02)) {
return ElderGuardian.class;
}
} else if (fakeClass == Horse.class) {
if (versionId > 47) { // ToDo: No clue here
return fakeClass;
}
return switch (metaData.getSets().getByte(EntityMetaDataFields.LEGACY_HORSE_SPECIAL_TYPE)) {
default -> fakeClass;
case 1 -> Donkey.class;
case 2 -> Mule.class;
case 3 -> ZombieHorse.class;
case 4 -> SkeletonHorse.class;
};
}
return fakeClass;
}
public static Class<? extends Entity> getRealEntityObjectClass(Class<? extends Entity> fakeClass, int data, int versionId) {
if (fakeClass == Minecart.class) {
if (versionId > 47) { // ToDo: No clue here
return fakeClass;
}
return switch (data) {
default -> fakeClass;
case 1 -> MinecartChest.class;
case 2 -> MinecartFurnace.class;
case 3 -> MinecartTNT.class;
case 4 -> MinecartSpawner.class;
case 5 -> MinecartHopper.class;
case 6 -> MinecartCommandBlock.class;
};
}
return fakeClass;
}
}

View File

@ -13,36 +13,37 @@
package de.bixilon.minosoft.modding.event.events; package de.bixilon.minosoft.modding.event.events;
import de.bixilon.minosoft.data.mappings.Item; import de.bixilon.minosoft.data.entities.entities.Entity;
import de.bixilon.minosoft.data.entities.entities.item.ItemEntity;
import de.bixilon.minosoft.modding.event.events.annotations.MinimumProtocolVersion; import de.bixilon.minosoft.modding.event.events.annotations.MinimumProtocolVersion;
import de.bixilon.minosoft.protocol.network.Connection; import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketCollectItem; import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketCollectItem;
public class CollectItemAnimationEvent extends CancelableEvent { public class CollectItemAnimationEvent extends CancelableEvent {
private final Item item; private final ItemEntity item;
private final int collectorEntityId; private final Entity collector;
private final int count; private final int count;
public CollectItemAnimationEvent(Connection connection, Item item, int collectorEntityId, int count) { public CollectItemAnimationEvent(Connection connection, ItemEntity item, Entity collector, int count) {
super(connection); super(connection);
this.item = item; this.item = item;
this.collectorEntityId = collectorEntityId; this.collector = collector;
this.count = count; this.count = count;
} }
public CollectItemAnimationEvent(Connection connection, PacketCollectItem pkg) { public CollectItemAnimationEvent(Connection connection, PacketCollectItem pkg) {
super(connection); super(connection);
this.item = pkg.getItem(); this.item = (ItemEntity) connection.getPlayer().getWorld().getEntity(pkg.getItemEntityId());
this.collectorEntityId = pkg.getCollectorId(); this.collector = connection.getPlayer().getWorld().getEntity(pkg.getCollectorEntityId());
this.count = pkg.getCount(); this.count = pkg.getCount();
} }
public Item getItem() { public ItemEntity getItem() {
return item; return item;
} }
public int getCollectorEntityId() { public Entity getCollector() {
return collectorEntityId; return collector;
} }
@MinimumProtocolVersion(versionId = 301) @MinimumProtocolVersion(versionId = 301)

View File

@ -13,26 +13,24 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play; package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.data.mappings.Item;
import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket; import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer; import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler; import de.bixilon.minosoft.protocol.protocol.PacketHandler;
public class PacketCollectItem implements ClientboundPacket { public class PacketCollectItem implements ClientboundPacket {
Item item; int itemEntityId;
int collectorId; int collectorEntityId;
int count; int count;
@Override @Override
public boolean read(InByteBuffer buffer) { public boolean read(InByteBuffer buffer) {
itemEntityId = buffer.readEntityId();
if (buffer.getVersionId() < 7) { if (buffer.getVersionId() < 7) {
item = buffer.getConnection().getMapping().getItemById(buffer.readInt()); collectorEntityId = buffer.readInt();
collectorId = buffer.readInt();
return true; return true;
} }
item = buffer.getConnection().getMapping().getItemById(buffer.readVarInt()); collectorEntityId = buffer.readVarInt();
collectorId = buffer.readVarInt();
if (buffer.getVersionId() >= 301) { if (buffer.getVersionId() >= 301) {
count = buffer.readVarInt(); count = buffer.readVarInt();
} }
@ -46,15 +44,15 @@ public class PacketCollectItem implements ClientboundPacket {
@Override @Override
public void log() { public void log() {
Log.protocol(String.format("[IN] Item %s was collected by %d (count=%s)", item, collectorId, ((count == 0) ? "?" : count))); Log.protocol(String.format("[IN] Item %d was collected by %d (count=%s)", itemEntityId, collectorEntityId, ((count == 0) ? "?" : count)));
} }
public Item getItem() { public int getItemEntityId() {
return item; return itemEntityId;
} }
public int getCollectorId() { public int getCollectorEntityId() {
return collectorId; return collectorEntityId;
} }
public int getCount() { public int getCount() {

View File

@ -19,6 +19,7 @@ import de.bixilon.minosoft.data.entities.Location;
import de.bixilon.minosoft.data.entities.Velocity; import de.bixilon.minosoft.data.entities.Velocity;
import de.bixilon.minosoft.data.entities.entities.Entity; import de.bixilon.minosoft.data.entities.entities.Entity;
import de.bixilon.minosoft.data.entities.entities.UnknownEntityException; import de.bixilon.minosoft.data.entities.entities.UnknownEntityException;
import de.bixilon.minosoft.data.mappings.VersionTweaker;
import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.network.Connection; import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket; import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
@ -58,6 +59,8 @@ public class PacketSpawnMob implements ClientboundPacket {
EntityMetaData metaData = null; EntityMetaData metaData = null;
if (buffer.getVersionId() < 550) { if (buffer.getVersionId() < 550) {
metaData = buffer.readMetaData(); metaData = buffer.readMetaData();
// we have meta data, check if we need to correct the class
typeClass = VersionTweaker.getRealEntityClass(typeClass, metaData, buffer.getVersionId());
} }
if (typeClass == null) { if (typeClass == null) {
throw new UnknownEntityException(String.format("Unknown entity (typeId=%d)", type)); throw new UnknownEntityException(String.format("Unknown entity (typeId=%d)", type));

View File

@ -19,6 +19,7 @@ import de.bixilon.minosoft.data.entities.Objects;
import de.bixilon.minosoft.data.entities.Velocity; import de.bixilon.minosoft.data.entities.Velocity;
import de.bixilon.minosoft.data.entities.entities.Entity; import de.bixilon.minosoft.data.entities.entities.Entity;
import de.bixilon.minosoft.data.entities.entities.UnknownEntityException; import de.bixilon.minosoft.data.entities.entities.UnknownEntityException;
import de.bixilon.minosoft.data.mappings.VersionTweaker;
import de.bixilon.minosoft.logging.Log; import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.network.Connection; import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket; import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
@ -69,6 +70,11 @@ public class PacketSpawnObject implements ClientboundPacket {
} else { } else {
velocity = new Velocity(buffer.readShort(), buffer.readShort(), buffer.readShort()); velocity = new Velocity(buffer.readShort(), buffer.readShort(), buffer.readShort());
} }
if (buffer.getVersionId() <= 47) { // ToDo
typeClass = VersionTweaker.getRealEntityObjectClass(typeClass, data, buffer.getVersionId());
}
if (typeClass == null) { if (typeClass == null) {
throw new UnknownEntityException(String.format("Unknown entity (typeId=%d)", type)); throw new UnknownEntityException(String.format("Unknown entity (typeId=%d)", type));
} }

View File

@ -73,6 +73,10 @@ public class InByteBuffer {
return buffer.getShort(0); return buffer.getShort(0);
} }
public int readUnsignedShort() {
return readShort() & 0xFFFF;
}
public int readInt() { public int readInt() {
ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES);
buffer.put(readBytes(Integer.BYTES)); buffer.put(readBytes(Integer.BYTES));

File diff suppressed because one or more lines are too long