Default MessagePack enum values to prevent NPE

This commit is contained in:
kuroppoi 2021-05-09 18:04:33 +02:00
parent f7c99997e9
commit 5670778f9a
4 changed files with 27 additions and 2 deletions

View file

@ -1,11 +1,13 @@
package brainwine.gameserver.entity;
import brainwine.gameserver.msgpack.DefaultEnumValue;
import brainwine.gameserver.msgpack.EnumValue;
import brainwine.gameserver.msgpack.RegisterEnum;
@RegisterEnum
public enum FacingDirection {
@DefaultEnumValue
WEST(-1),
EAST(1);

View file

@ -2,6 +2,7 @@ package brainwine.gameserver.item;
import com.fasterxml.jackson.annotation.JsonEnumDefaultValue;
import brainwine.gameserver.msgpack.DefaultEnumValue;
import brainwine.gameserver.msgpack.RegisterEnum;
@RegisterEnum
@ -12,6 +13,7 @@ public enum Layer {
FRONT,
LIQUID,
@DefaultEnumValue
@JsonEnumDefaultValue
NONE;
}

View file

@ -0,0 +1,10 @@
package brainwine.gameserver.msgpack;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DefaultEnumValue {}

View file

@ -13,17 +13,28 @@ import org.msgpack.template.AbstractTemplate;
import org.msgpack.type.ValueType;
import org.msgpack.unpacker.Unpacker;
import brainwine.gameserver.msgpack.DefaultEnumValue;
import brainwine.gameserver.msgpack.EnumValue;
@SuppressWarnings("unchecked")
public class EnumTemplate<T> extends AbstractTemplate<T> {
private final Map<T, Object> ids = new HashMap<>();
private final Map<Object, T> values = new HashMap<>();
private T defaultValue;
public EnumTemplate(Class<T> type) {
T[] entries = type.getEnumConstants();
for(Field field : type.getFields()) {
if(field.getType() == type && field.isAnnotationPresent(DefaultEnumValue.class)) {
try {
defaultValue = (T)field.get(type);
} catch (IllegalArgumentException | IllegalAccessException e) {
throw new MessageTypeException(e);
}
}
if(field.isAnnotationPresent(EnumValue.class)) {
try {
for(T entry : entries) {
@ -85,9 +96,9 @@ public class EnumTemplate<T> extends AbstractTemplate<T> {
ValueType next = unpacker.getNextType();
if(next == ValueType.INTEGER) {
return values.get(unpacker.readInt());
return values.getOrDefault(unpacker.readInt(), defaultValue);
} else if(next == ValueType.RAW) {
return values.get(unpacker.readString());
return values.getOrDefault(unpacker.readString(), defaultValue);
}
throw new MessageTypeException("Unsupported enum id type");