use of net.glowstone.entity.meta.MetadataIndex in project Glowstone by GlowstoneMC.
the class MetadataIndexTest method testNoOverlap.
/**
* Tests that no two MetadataIndex entries can overlap on a single
* entity. Will not catch failure for entities without any metadata
* keys defined.
*/
@Test
public void testNoOverlap() {
HashMap<Class<?>, HashMap<Integer, MetadataIndex>> map = new HashMap<>();
for (MetadataIndex index : MetadataIndex.values()) {
Class<?> clazz = index.getAppliesTo();
if (clazz == null) {
continue;
}
if (index == MetadataIndex.ARMORSTAND_LEFT_LEG_POSITION) {
// this index is permitted to override others
continue;
}
// check for duplication
// check that class is a parent
// look for matching index
map.entrySet().stream().filter(entry -> entry.getKey().isAssignableFrom(clazz)).filter(entry -> entry.getValue().containsKey(index.getIndex())).forEach(entry -> fail("Index " + index + "(" + clazz.getSimpleName() + ") conflicts with " + entry.getValue().get(index.getIndex()) + "(" + entry.getKey().getSimpleName() + ")"));
// insert this index
HashMap<Integer, MetadataIndex> classMap = map.computeIfAbsent(index.getAppliesTo(), k -> new HashMap<>());
classMap.put(index.getIndex(), index);
}
}
use of net.glowstone.entity.meta.MetadataIndex in project Glowstone by GlowstoneMC.
the class GlowBufUtils method writeMetadata.
/**
* Write a list of mob metadata entries to the buffer.
*
* @param buf The buffer.
* @param entries The metadata.
* @throws IOException if the buffer could not be written to
*/
public static void writeMetadata(ByteBuf buf, List<Entry> entries) throws IOException {
for (Entry entry : entries) {
MetadataIndex index = entry.index;
Object value = entry.value;
int type = index.getType().getId();
int id = index.getIndex();
buf.writeByte(id);
buf.writeByte(type);
if (!index.getType().isOptional() && value == null) {
continue;
}
if (index.getType().isOptional()) {
buf.writeBoolean(value != null);
if (value == null) {
continue;
}
}
switch(index.getType()) {
case BYTE:
buf.writeByte((Byte) value);
break;
case INT:
ByteBufUtils.writeVarInt(buf, (Integer) value);
break;
case FLOAT:
buf.writeFloat((Float) value);
break;
case STRING:
ByteBufUtils.writeUTF8(buf, (String) value);
break;
case CHAT:
writeChat(buf, (TextMessage) value);
break;
case ITEM:
writeSlot(buf, (ItemStack) value);
break;
case BOOLEAN:
buf.writeBoolean((Boolean) value);
break;
case VECTOR:
EulerAngle angle = (EulerAngle) value;
buf.writeFloat((float) Math.toDegrees(angle.getX()));
buf.writeFloat((float) Math.toDegrees(angle.getY()));
buf.writeFloat((float) Math.toDegrees(angle.getZ()));
break;
case POSITION:
case OPTPOSITION:
BlockVector vector = (BlockVector) value;
buf.writeLong(Position.getPosition(vector));
break;
case DIRECTION:
ByteBufUtils.writeVarInt(buf, (Integer) value);
break;
case OPTUUID:
writeUuid(buf, (UUID) value);
break;
case BLOCKID:
ByteBufUtils.writeVarInt(buf, (Integer) value);
break;
}
}
buf.writeByte(0xff);
}
use of net.glowstone.entity.meta.MetadataIndex in project Dragonet-Legacy by DragonetMC.
the class MetadataIndexTest method testNoOverlap.
/**
* Tests that no two MetadataIndex entries can overlap on a single
* entity. Will not catch failure for entities without any metadata
* keys defined.
*/
@Test
public void testNoOverlap() {
HashMap<Class<?>, HashMap<Integer, MetadataIndex>> map = new HashMap<>();
for (MetadataIndex index : MetadataIndex.values()) {
Class<?> clazz = index.getAppliesTo();
if (index == MetadataIndex.PLAYER_SKIN_FLAGS) {
// this index is permitted to override others
continue;
}
// check for duplication
for (Map.Entry<Class<?>, HashMap<Integer, MetadataIndex>> entry : map.entrySet()) {
// check that class is a parent
if (entry.getKey().isAssignableFrom(clazz)) {
// look for matching index
if (entry.getValue().containsKey(index.getIndex())) {
fail("Index " + index + "(" + clazz.getSimpleName() + ") conflicts with " + entry.getValue().get(index.getIndex()) + "(" + entry.getKey().getSimpleName() + ")");
}
}
}
// insert this index
HashMap<Integer, MetadataIndex> classMap = map.get(index.getAppliesTo());
if (classMap == null) {
classMap = new HashMap<>();
map.put(index.getAppliesTo(), classMap);
}
classMap.put(index.getIndex(), index);
}
}
use of net.glowstone.entity.meta.MetadataIndex in project Glowstone by GlowstoneMC.
the class MetadataIndexTest method testOrdering.
/**
* Tests that more specific metadata always appears later.
*/
@Test
public void testOrdering() {
HashMap<Class<?>, MetadataIndex> seen = new HashMap<>();
for (MetadataIndex index : MetadataIndex.values()) {
Class<?> clazz = index.getAppliesTo();
if (clazz == null) {
continue;
}
seen.entrySet().stream().filter(entry -> clazz != entry.getKey() && clazz.isAssignableFrom(entry.getKey())).forEach(entry -> fail("Index " + index + "(" + clazz.getSimpleName() + ") follows index " + entry.getValue() + "(" + entry.getKey().getSimpleName() + ") which it parents"));
if (!seen.containsKey(clazz)) {
seen.put(clazz, index);
}
}
}
use of net.glowstone.entity.meta.MetadataIndex in project Glowstone by GlowstoneMC.
the class GlowBufUtils method readMetadata.
/**
* Read a list of mob metadata entries from the buffer.
*
* @param buf The buffer.
* @return The metadata.
* @throws IOException if the buffer could not be read
*/
public static List<Entry> readMetadata(ByteBuf buf) throws IOException {
List<Entry> entries = new ArrayList<>();
byte item;
while ((item = buf.readByte()) != -1) {
MetadataType type = MetadataType.byId(buf.readByte());
MetadataIndex index = MetadataIndex.getIndex((int) item, type);
switch(type) {
case BYTE:
entries.add(new Entry(index, buf.readByte()));
break;
case INT:
entries.add(new Entry(index, ByteBufUtils.readVarInt(buf)));
break;
case FLOAT:
entries.add(new Entry(index, buf.readFloat()));
break;
case STRING:
entries.add(new Entry(index, ByteBufUtils.readUTF8(buf)));
break;
case ITEM:
entries.add(new Entry(index, readSlot(buf)));
break;
case BOOLEAN:
entries.add(new Entry(index, buf.readBoolean()));
break;
case VECTOR:
float x = buf.readFloat();
float y = buf.readFloat();
float z = buf.readFloat();
entries.add(new MetadataMap.Entry(index, new EulerAngle(x, y, z)));
break;
case POSITION:
case OPTPOSITION:
entries.add(new Entry(index, Position.getPosition(buf.readLong())));
break;
case DIRECTION:
entries.add(new Entry(index, ByteBufUtils.readVarInt(buf)));
break;
case OPTUUID:
if (buf.readBoolean()) {
entries.add(new Entry(index, readUuid(buf)));
}
break;
case BLOCKID:
entries.add(new Entry(index, ByteBufUtils.readVarInt(buf)));
}
}
return entries;
}
Aggregations