From f3c51c9916361f61a9b23f9ec6d4e7f064805a4b Mon Sep 17 00:00:00 2001 From: Woder <17339354+wode490390@users.noreply.github.com> Date: Wed, 14 Feb 2024 15:36:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=80=E6=89=B9=E9=97=AE=E9=A2=98=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=8E=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nukkit/command/defaults/TellCommand.java | 2 +- .../cn/nukkit/inventory/CraftingManager.java | 12 +- src/main/java/cn/nukkit/item/Item.java | 2 +- src/main/java/cn/nukkit/level/Level.java | 37 +- .../level/format/generic/BaseFullChunk.java | 10 +- src/main/java/cn/nukkit/utils/Config.java | 34 +- .../java/cn/nukkit/utils/ConfigSection.java | 349 +++++++++++------- .../cn/nukkit/utils/NumberConversions.java | 131 +++++++ .../java/cn/nukkit/utils/SimpleConfig.java | 3 +- 9 files changed, 414 insertions(+), 166 deletions(-) create mode 100644 src/main/java/cn/nukkit/utils/NumberConversions.java diff --git a/src/main/java/cn/nukkit/command/defaults/TellCommand.java b/src/main/java/cn/nukkit/command/defaults/TellCommand.java index b5d45c3cf30..3aa7a9ab158 100644 --- a/src/main/java/cn/nukkit/command/defaults/TellCommand.java +++ b/src/main/java/cn/nukkit/command/defaults/TellCommand.java @@ -17,7 +17,7 @@ public class TellCommand extends VanillaCommand { public TellCommand(String name) { - super(name, "%commands.tell.description", "%nukkit.command.message.usage", "w"/*, "msg"*/); //FIXME: msg 与插件的 FriendChat 冲突 + super(name, "%commands.tell.description", "%nukkit.command.message.usage", "w", "msg"); this.setPermission("nukkit.command.tell"); this.commandData.flags.add(CommandFlag.NOT_CHEAT); this.commandParameters.clear(); diff --git a/src/main/java/cn/nukkit/inventory/CraftingManager.java b/src/main/java/cn/nukkit/inventory/CraftingManager.java index d870cc070bf..7b1238deae6 100644 --- a/src/main/java/cn/nukkit/inventory/CraftingManager.java +++ b/src/main/java/cn/nukkit/inventory/CraftingManager.java @@ -103,9 +103,9 @@ protected void initialize() { @SuppressWarnings("unchecked") private void loadRecipes(Config config) { - List recipes = config.getMapList("recipes"); + List> recipes = config.getMapList("recipes"); log.info("Loading recipes..."); - for (Map recipe : recipes) { + for (Map recipe : recipes) { try { int type = Utils.toInt(recipe.get("type")); switch (type) { @@ -216,9 +216,9 @@ private void loadRecipes(Config config) { } // Load brewing recipes - List potionMixes = config.getMapList("potionMixes"); + List> potionMixes = config.getMapList("potionMixes"); - for (Map potionMix : potionMixes) { + for (Map potionMix : potionMixes) { int fromPotionId = ((Number) potionMix.get("fromPotionId")).intValue(); // gson returns doubles... int ingredient = ((Number) potionMix.get("ingredient")).intValue(); int toPotionId = ((Number) potionMix.get("toPotionId")).intValue(); @@ -226,9 +226,9 @@ private void loadRecipes(Config config) { registerBrewingRecipe(new BrewingRecipe(Item.get(ItemID.POTION, fromPotionId), Item.get(ingredient), Item.get(ItemID.POTION, toPotionId))); } - List containerMixes = config.getMapList("containerMixes"); + List> containerMixes = config.getMapList("containerMixes"); - for (Map containerMix : containerMixes) { + for (Map containerMix : containerMixes) { int fromItemId = ((Number) containerMix.get("fromItemId")).intValue(); int ingredient = ((Number) containerMix.get("ingredient")).intValue(); int toItemId = ((Number) containerMix.get("toItemId")).intValue(); diff --git a/src/main/java/cn/nukkit/item/Item.java b/src/main/java/cn/nukkit/item/Item.java index fa943e39efc..9361766b341 100644 --- a/src/main/java/cn/nukkit/item/Item.java +++ b/src/main/java/cn/nukkit/item/Item.java @@ -136,7 +136,7 @@ private static void initCreativeItems() { Config config = new Config(Config.JSON); config.load(Server.class.getClassLoader().getResourceAsStream("creativeitems.json")); - List list = config.getMapList("items"); + List> list = config.getMapList("items"); for (Map map : list) { try { diff --git a/src/main/java/cn/nukkit/level/Level.java b/src/main/java/cn/nukkit/level/Level.java index f2cde3b1521..2834488106f 100644 --- a/src/main/java/cn/nukkit/level/Level.java +++ b/src/main/java/cn/nukkit/level/Level.java @@ -84,6 +84,9 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Predicate; @@ -3225,11 +3228,41 @@ public BaseFullChunk getChunk(int chunkX, int chunkZ) { public BaseFullChunk getChunk(int chunkX, int chunkZ, boolean create) { long index = Level.chunkHash(chunkX, chunkZ); boolean isMainThread = server.isPrimaryThread(); + BaseFullChunk chunk = this.getChunkFromCache(isMainThread, index); if (chunk != null) { return chunk; - } else if (this.loadChunkInternal(index, chunkX, chunkZ, create)) { - return this.getChunkFromCache(isMainThread, index); + } + + if (!isMainThread) { + Lock lock = new ReentrantLock(); + Condition condition = lock.newCondition(); + lock.lock(); + + BaseFullChunk[] result = new BaseFullChunk[1]; + getServer().getScheduler().scheduleTask(null, () -> { + lock.lock(); + try { + if (loadChunkInternal(index, chunkX, chunkZ, create)) { + result[0] = getChunkFromCache(true, index); + } + } finally { + condition.signal(); + lock.unlock(); + } + }); + + try { + condition.await(); + } catch (InterruptedException ignored) { + } finally { + lock.unlock(); + } + return result[0]; + } + + if (this.loadChunkInternal(index, chunkX, chunkZ, create)) { + return this.getChunkFromCache(true, index); } return null; diff --git a/src/main/java/cn/nukkit/level/format/generic/BaseFullChunk.java b/src/main/java/cn/nukkit/level/format/generic/BaseFullChunk.java index f3fadd4c15a..d56b502a6fb 100644 --- a/src/main/java/cn/nukkit/level/format/generic/BaseFullChunk.java +++ b/src/main/java/cn/nukkit/level/format/generic/BaseFullChunk.java @@ -143,8 +143,9 @@ public ChunkPacketCache getPacketCache() { public void initChunk() { if (this.getProvider() != null && !this.isInit) { boolean changed = false; - if (this.NBTentities != null) { - for (CompoundTag nbt : NBTentities) { + List entities = this.NBTentities; + if (entities != null) { + for (CompoundTag nbt : entities) { if (!nbt.contains("id")) { this.setChanged(); continue; @@ -162,8 +163,9 @@ public void initChunk() { this.NBTentities = null; } - if (this.NBTtiles != null) { - for (CompoundTag nbt : NBTtiles) { + List blockEntities = this.NBTtiles; + if (blockEntities != null) { + for (CompoundTag nbt : blockEntities) { if (nbt != null) { if (!nbt.contains("id")) { changed = true; diff --git a/src/main/java/cn/nukkit/utils/Config.java b/src/main/java/cn/nukkit/utils/Config.java index 57c787a37f1..116be99dcc2 100644 --- a/src/main/java/cn/nukkit/utils/Config.java +++ b/src/main/java/cn/nukkit/utils/Config.java @@ -5,8 +5,16 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.reflect.TypeToken; +import it.unimi.dsi.fastutil.booleans.BooleanList; +import it.unimi.dsi.fastutil.bytes.ByteList; +import it.unimi.dsi.fastutil.chars.CharList; +import it.unimi.dsi.fastutil.doubles.DoubleList; +import it.unimi.dsi.fastutil.floats.FloatList; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.longs.LongList; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntRBTreeMap; +import it.unimi.dsi.fastutil.shorts.ShortList; import lombok.extern.log4j.Log4j2; import org.snakeyaml.engine.v2.api.Dump; import org.snakeyaml.engine.v2.api.DumpSettings; @@ -274,6 +282,14 @@ public T get(String key, T defaultValue) { return this.correct ? this.config.get(key, defaultValue) : defaultValue; } + public Object getValue(String key) { + return this.getValue(key, null); + } + + public Object getValue(String key, Object defaultValue) { + return this.correct ? this.config.getValue(key, defaultValue) : defaultValue; + } + public ConfigSection getSection(String key) { return this.correct ? this.config.getSection(key) : new ConfigSection(); } @@ -366,39 +382,39 @@ public List getStringList(String key) { return config.getStringList(key); } - public List getIntegerList(String key) { + public IntList getIntegerList(String key) { return config.getIntegerList(key); } - public List getBooleanList(String key) { + public BooleanList getBooleanList(String key) { return config.getBooleanList(key); } - public List getDoubleList(String key) { + public DoubleList getDoubleList(String key) { return config.getDoubleList(key); } - public List getFloatList(String key) { + public FloatList getFloatList(String key) { return config.getFloatList(key); } - public List getLongList(String key) { + public LongList getLongList(String key) { return config.getLongList(key); } - public List getByteList(String key) { + public ByteList getByteList(String key) { return config.getByteList(key); } - public List getCharacterList(String key) { + public CharList getCharacterList(String key) { return config.getCharacterList(key); } - public List getShortList(String key) { + public ShortList getShortList(String key) { return config.getShortList(key); } - public List getMapList(String key) { + public List> getMapList(String key) { return config.getMapList(key); } diff --git a/src/main/java/cn/nukkit/utils/ConfigSection.java b/src/main/java/cn/nukkit/utils/ConfigSection.java index 4c9967c6081..ef70701090d 100644 --- a/src/main/java/cn/nukkit/utils/ConfigSection.java +++ b/src/main/java/cn/nukkit/utils/ConfigSection.java @@ -1,5 +1,22 @@ package cn.nukkit.utils; +import it.unimi.dsi.fastutil.booleans.BooleanArrayList; +import it.unimi.dsi.fastutil.booleans.BooleanList; +import it.unimi.dsi.fastutil.bytes.ByteArrayList; +import it.unimi.dsi.fastutil.bytes.ByteList; +import it.unimi.dsi.fastutil.chars.CharArrayList; +import it.unimi.dsi.fastutil.chars.CharList; +import it.unimi.dsi.fastutil.doubles.DoubleArrayList; +import it.unimi.dsi.fastutil.doubles.DoubleList; +import it.unimi.dsi.fastutil.floats.FloatArrayList; +import it.unimi.dsi.fastutil.floats.FloatList; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.longs.LongArrayList; +import it.unimi.dsi.fastutil.longs.LongList; +import it.unimi.dsi.fastutil.shorts.ShortArrayList; +import it.unimi.dsi.fastutil.shorts.ShortList; + import java.util.*; /** @@ -34,12 +51,13 @@ public ConfigSection(Map map) { this(); if (map == null || map.isEmpty()) return; for (Map.Entry entry : map.entrySet()) { - if (entry.getValue() instanceof Map) { - super.put(entry.getKey(), new ConfigSection((Map) entry.getValue())); - } else if (entry.getValue() instanceof List) { - super.put(entry.getKey(), parseList((List) entry.getValue())); + Object value = entry.getValue(); + if (value instanceof Map) { + super.put(entry.getKey(), new ConfigSection((Map) value)); + } else if (value instanceof List list) { + super.put(entry.getKey(), parseList(list)); } else { - super.put(entry.getKey(), entry.getValue()); + super.put(entry.getKey(), value); } } } @@ -53,7 +71,7 @@ public ConfigSection(LinkedHashMap map) { this((Map) map); } - private List parseList(List list) { + private List parseList(List list) { List newList = new ArrayList<>(); for (Object o : list) { @@ -76,7 +94,6 @@ public Map getAllMap() { return new LinkedHashMap<>(this); } - /** * Get new instance of config section * @@ -101,18 +118,47 @@ public Object get(String key) { * @return */ public T get(String key, T defaultValue) { - if (key == null || key.isEmpty()) return defaultValue; - if (super.containsKey(key)) return (T) super.get(key); + if (key == null || key.isEmpty()) { + return defaultValue; + } + Object value = super.get(key); + if (value != null) { + return (T) value; + } String[] keys = key.split("\\.", 2); - if (!super.containsKey(keys[0])) return defaultValue; - Object value = super.get(keys[0]); - if (value instanceof ConfigSection) { - ConfigSection section = (ConfigSection) value; + value = super.get(keys[0]); + if (value == null) { + return defaultValue; + } + if (value instanceof ConfigSection section) { return section.get(keys[1], defaultValue); } return defaultValue; } + public Object getValue(String key) { + return this.getValue(key, null); + } + + public Object getValue(String key, Object defaultValue) { + if (key == null || key.isEmpty()) { + return defaultValue; + } + Object value = super.get(key); + if (value != null) { + return value; + } + String[] keys = key.split("\\.", 2); + value = super.get(keys[0]); + if (value == null) { + return defaultValue; + } + if (value instanceof ConfigSection section) { + return section.getValue(keys[1], defaultValue); + } + return defaultValue; + } + /** * Store value into config section * @@ -122,12 +168,18 @@ public T get(String key, T defaultValue) { public void set(String key, Object value) { String[] subKeys = key.split("\\.", 2); if (subKeys.length > 1) { - ConfigSection childSection = new ConfigSection(); - if (this.containsKey(subKeys[0]) && super.get(subKeys[0]) instanceof ConfigSection) - childSection = (ConfigSection) super.get(subKeys[0]); + String path = subKeys[0]; + ConfigSection childSection; + if (super.get(path) instanceof ConfigSection section) { + childSection = section; + } else { + childSection = new ConfigSection(); + super.put(path, childSection); + } childSection.set(subKeys[1], value); - super.put(subKeys[0], childSection); - } else super.put(subKeys[0], value); + } else { + super.put(subKeys[0], value); + } } /** @@ -137,7 +189,7 @@ public void set(String key, Object value) { * @return */ public boolean isSection(String key) { - Object value = this.get(key); + Object value = this.getValue(key); return value instanceof ConfigSection; } @@ -148,7 +200,8 @@ public boolean isSection(String key) { * @return */ public ConfigSection getSection(String key) { - return this.get(key, new ConfigSection()); + Object value = this.getValue(key, null); + return value instanceof ConfigSection section ? section : new ConfigSection(); } //@formatter:off @@ -212,7 +265,8 @@ public int getInt(String key) { * @return */ public int getInt(String key, int defaultValue) { - return this.get(key, ((Number) defaultValue)).intValue(); + Object value = this.getValue(key, defaultValue); + return value instanceof Number number ? number.intValue() : defaultValue; } /** @@ -222,7 +276,7 @@ public int getInt(String key, int defaultValue) { * @return */ public boolean isInt(String key) { - Object val = get(key); + Object val = getValue(key); return val instanceof Integer; } @@ -244,7 +298,8 @@ public long getLong(String key) { * @return */ public long getLong(String key, long defaultValue) { - return this.get(key, ((Number) defaultValue)).longValue(); + Object value = this.getValue(key, defaultValue); + return value instanceof Number number ? number.longValue() : defaultValue; } /** @@ -254,7 +309,7 @@ public long getLong(String key, long defaultValue) { * @return */ public boolean isLong(String key) { - Object val = get(key); + Object val = getValue(key); return val instanceof Long; } @@ -276,7 +331,8 @@ public double getDouble(String key) { * @return */ public double getDouble(String key, double defaultValue) { - return this.get(key, ((Number) defaultValue)).doubleValue(); + Object value = this.getValue(key, defaultValue); + return value instanceof Number number ? number.doubleValue() : defaultValue; } /** @@ -286,7 +342,7 @@ public double getDouble(String key, double defaultValue) { * @return */ public boolean isDouble(String key) { - Object val = get(key); + Object val = getValue(key); return val instanceof Double; } @@ -308,8 +364,8 @@ public String getString(String key) { * @return */ public String getString(String key, String defaultValue) { - Object result = this.get(key, defaultValue); - return String.valueOf(result); + Object value = this.getValue(key, defaultValue); + return value != null ? value.toString() : defaultValue; } /** @@ -319,7 +375,7 @@ public String getString(String key, String defaultValue) { * @return */ public boolean isString(String key) { - Object val = get(key); + Object val = getValue(key); return val instanceof String; } @@ -341,7 +397,8 @@ public boolean getBoolean(String key) { * @return */ public boolean getBoolean(String key, boolean defaultValue) { - return this.get(key, defaultValue); + Object value = this.getValue(key, defaultValue); + return value instanceof Boolean bool ? bool : defaultValue; } /** @@ -351,7 +408,7 @@ public boolean getBoolean(String key, boolean defaultValue) { * @return */ public boolean isBoolean(String key) { - Object val = get(key); + Object val = getValue(key); return val instanceof Boolean; } @@ -361,7 +418,7 @@ public boolean isBoolean(String key) { * @param key - key (inside) current section * @return */ - public List getList(String key) { + public List getList(String key) { return this.getList(key, null); } @@ -372,8 +429,9 @@ public List getList(String key) { * @param defaultList - default value that will returned if section element is not exists * @return */ - public List getList(String key, List defaultList) { - return this.get(key, defaultList); + public List getList(String key, List defaultList) { + Object value = this.getValue(key, defaultList); + return value instanceof List list ? list : defaultList; } /** @@ -383,7 +441,7 @@ public List getList(String key, List defaultList) { * @return */ public boolean isList(String key) { - Object val = get(key); + Object val = getValue(key); return val instanceof List; } @@ -394,16 +452,20 @@ public boolean isList(String key) { * @return */ public List getStringList(String key) { - List value = this.getList(key); + List value = this.getList(key); + if (value == null) { return new ArrayList<>(0); } + List result = new ArrayList<>(); + for (Object o : value) { if (o instanceof String || o instanceof Number || o instanceof Boolean || o instanceof Character) { result.add(String.valueOf(o)); } } + return result; } @@ -413,28 +475,28 @@ public List getStringList(String key) { * @param key - key (inside) current section * @return */ - public List getIntegerList(String key) { + public IntList getIntegerList(String key) { List list = getList(key); + if (list == null) { - return new ArrayList<>(0); + return new IntArrayList(0); } - List result = new ArrayList<>(); + + IntList result = new IntArrayList(); for (Object object : list) { - if (object instanceof Integer) { - result.add((Integer) object); - } else if (object instanceof String) { + if (object instanceof Number number) { + result.add(number.intValue()); + } else if (object instanceof String string) { try { - result.add(Integer.valueOf((String) object)); - } catch (Exception ex) { - //ignore + result.add(Integer.parseInt(string)); + } catch (NumberFormatException ignored) { } - } else if (object instanceof Character) { - result.add((int) (Character) object); - } else if (object instanceof Number) { - result.add(((Number) object).intValue()); + } else if (object instanceof Character character) { + result.add((int) character); } } + return result; } @@ -444,23 +506,27 @@ public List getIntegerList(String key) { * @param key - key (inside) current section * @return */ - public List getBooleanList(String key) { + public BooleanList getBooleanList(String key) { List list = getList(key); + if (list == null) { - return new ArrayList<>(0); + return new BooleanArrayList(0); } - List result = new ArrayList<>(); + + BooleanList result = new BooleanArrayList(); + for (Object object : list) { - if (object instanceof Boolean) { - result.add((Boolean) object); + if (object instanceof Boolean bool) { + result.add(bool); } else if (object instanceof String) { - if (Boolean.TRUE.toString().equals(object)) { + if ("true".equals(object)) { result.add(true); - } else if (Boolean.FALSE.toString().equals(object)) { + } else if ("false".equals(object)) { result.add(false); } } } + return result; } @@ -470,27 +536,28 @@ public List getBooleanList(String key) { * @param key - key (inside) current section * @return */ - public List getDoubleList(String key) { + public DoubleList getDoubleList(String key) { List list = getList(key); + if (list == null) { - return new ArrayList<>(0); + return new DoubleArrayList(0); } - List result = new ArrayList<>(); + + DoubleList result = new DoubleArrayList(); + for (Object object : list) { - if (object instanceof Double) { - result.add((Double) object); - } else if (object instanceof String) { + if (object instanceof Number number) { + result.add(number.doubleValue()); + } else if (object instanceof String string) { try { - result.add(Double.valueOf((String) object)); - } catch (Exception ex) { - //ignore + result.add(Double.parseDouble(string)); + } catch (NumberFormatException ignored) { } - } else if (object instanceof Character) { - result.add((double) (Character) object); - } else if (object instanceof Number) { - result.add(((Number) object).doubleValue()); + } else if (object instanceof Character character) { + result.add((double) character); } } + return result; } @@ -500,27 +567,28 @@ public List getDoubleList(String key) { * @param key - key (inside) current section * @return */ - public List getFloatList(String key) { + public FloatList getFloatList(String key) { List list = getList(key); + if (list == null) { - return new ArrayList<>(0); + return new FloatArrayList(0); } - List result = new ArrayList<>(); + + FloatList result = new FloatArrayList(); + for (Object object : list) { - if (object instanceof Float) { - result.add((Float) object); - } else if (object instanceof String) { + if (object instanceof Number number) { + result.add(number.floatValue()); + } else if (object instanceof String string) { try { - result.add(Float.valueOf((String) object)); - } catch (Exception ex) { - //ignore + result.add(Float.parseFloat(string)); + } catch (NumberFormatException ignored) { } - } else if (object instanceof Character) { - result.add((float) (Character) object); - } else if (object instanceof Number) { - result.add(((Number) object).floatValue()); + } else if (object instanceof Character character) { + result.add((float) character); } } + return result; } @@ -530,27 +598,28 @@ public List getFloatList(String key) { * @param key - key (inside) current section * @return */ - public List getLongList(String key) { + public LongList getLongList(String key) { List list = getList(key); + if (list == null) { - return new ArrayList<>(0); + return new LongArrayList(0); } - List result = new ArrayList<>(); + + LongList result = new LongArrayList(); + for (Object object : list) { - if (object instanceof Long) { - result.add((Long) object); - } else if (object instanceof String) { + if (object instanceof Number number) { + result.add(number.longValue()); + } else if (object instanceof String string) { try { - result.add(Long.valueOf((String) object)); - } catch (Exception ex) { - //ignore + result.add(Long.parseLong(string)); + } catch (NumberFormatException ignored) { } - } else if (object instanceof Character) { - result.add((long) (Character) object); - } else if (object instanceof Number) { - result.add(((Number) object).longValue()); + } else if (object instanceof Character character) { + result.add((long) character); } } + return result; } @@ -560,28 +629,25 @@ public List getLongList(String key) { * @param key - key (inside) current section * @return */ - public List getByteList(String key) { + public ByteList getByteList(String key) { List list = getList(key); if (list == null) { - return new ArrayList<>(0); + return new ByteArrayList(0); } - List result = new ArrayList<>(); + ByteList result = new ByteArrayList(); for (Object object : list) { - if (object instanceof Byte) { - result.add((Byte) object); - } else if (object instanceof String) { + if (object instanceof Number number) { + result.add(number.byteValue()); + } else if (object instanceof String string) { try { - result.add(Byte.valueOf((String) object)); - } catch (Exception ex) { - //ignore + result.add(Byte.parseByte(string)); + } catch (NumberFormatException ignored) { } - } else if (object instanceof Character) { - result.add((byte) ((Character) object).charValue()); - } else if (object instanceof Number) { - result.add(((Number) object).byteValue()); + } else if (object instanceof Character character) { + result.add((byte) character.charValue()); } } @@ -594,26 +660,24 @@ public List getByteList(String key) { * @param key - key (inside) current section * @return */ - public List getCharacterList(String key) { + public CharList getCharacterList(String key) { List list = getList(key); if (list == null) { - return new ArrayList<>(0); + return new CharArrayList(0); } - List result = new ArrayList<>(); + CharList result = new CharArrayList(); for (Object object : list) { if (object instanceof Character) { result.add((Character) object); - } else if (object instanceof String) { - String str = (String) object; - + } else if (object instanceof String str) { if (str.length() == 1) { result.add(str.charAt(0)); } - } else if (object instanceof Number) { - result.add((char) ((Number) object).intValue()); + } else if (object instanceof Number number) { + result.add((char) number.intValue()); } } @@ -626,28 +690,25 @@ public List getCharacterList(String key) { * @param key - key (inside) current section * @return */ - public List getShortList(String key) { + public ShortList getShortList(String key) { List list = getList(key); if (list == null) { - return new ArrayList<>(0); + return new ShortArrayList(0); } - List result = new ArrayList<>(); + ShortList result = new ShortArrayList(); for (Object object : list) { - if (object instanceof Short) { - result.add((Short) object); - } else if (object instanceof String) { + if (object instanceof Number number) { + result.add(number.shortValue()); + } else if (object instanceof String string) { try { - result.add(Short.valueOf((String) object)); - } catch (Exception ex) { - //ignore + result.add(Short.parseShort(string)); + } catch (NumberFormatException ignored) { } - } else if (object instanceof Character) { - result.add((short) ((Character) object).charValue()); - } else if (object instanceof Number) { - result.add(((Number) object).shortValue()); + } else if (object instanceof Character character) { + result.add((short) character.charValue()); } } @@ -660,17 +721,17 @@ public List getShortList(String key) { * @param key - key (inside) current section * @return */ - public List getMapList(String key) { - List list = getList(key); - List result = new ArrayList<>(); + public List> getMapList(String key) { + List list = getList(key); + List> result = new ArrayList<>(); if (list == null) { return result; } for (Object object : list) { - if (object instanceof Map) { - result.add((Map) object); + if (object instanceof Map map) { + result.add(map); } } @@ -709,12 +770,17 @@ public boolean exists(String key) { * @param key */ public void remove(String key) { - if (key == null || key.isEmpty()) return; - if (super.containsKey(key)) super.remove(key); - else if (this.containsKey(".")) { + if (key == null || key.isEmpty()) { + return; + } + Object value = super.remove(key); + if (value != null) { + return; + } + if (this.containsKey(".")) { String[] keys = key.split("\\.", 2); - if (super.get(keys[0]) instanceof ConfigSection) { - ConfigSection section = (ConfigSection) super.get(keys[0]); + value = super.get(keys[0]); + if (value instanceof ConfigSection section) { section.remove(keys[1]); } } @@ -730,9 +796,8 @@ public Set getKeys(boolean child) { Set keys = new LinkedHashSet<>(); this.forEach((key, value) -> { keys.add(key); - if (value instanceof ConfigSection) { - if (child) - ((ConfigSection) value).getKeys(true).forEach(childKey -> keys.add(key + "." + childKey)); + if (child && value instanceof ConfigSection section) { + section.getKeys(true).forEach(childKey -> keys.add(key + "." + childKey)); } }); return keys; diff --git a/src/main/java/cn/nukkit/utils/NumberConversions.java b/src/main/java/cn/nukkit/utils/NumberConversions.java new file mode 100644 index 00000000000..52c85f4ae4b --- /dev/null +++ b/src/main/java/cn/nukkit/utils/NumberConversions.java @@ -0,0 +1,131 @@ +package cn.nukkit.utils; + +import javax.annotation.Nullable; + +/** + * Utils for casting number types to other number types. + */ +public final class NumberConversions { + public static byte toByte(@Nullable Object object) { + return toByte(object, (byte) 0); + } + + public static byte toByte(@Nullable Object object, byte defaultValue) { + if (object instanceof Number number) { + return number.byteValue(); + } + + if (object == null) { + return defaultValue; + } + + try { + return Byte.parseByte(object.toString()); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public static short toShort(@Nullable Object object) { + return toShort(object, (short) 0); + } + + public static short toShort(@Nullable Object object, short defaultValue) { + if (object instanceof Number number) { + return number.shortValue(); + } + + if (object == null) { + return defaultValue; + } + + try { + return Short.parseShort(object.toString()); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public static int toInt(@Nullable Object object) { + return toInt(object, 0); + } + + public static int toInt(@Nullable Object object, int defaultValue) { + if (object instanceof Number number) { + return number.intValue(); + } + + if (object == null) { + return defaultValue; + } + + try { + return Integer.parseInt(object.toString()); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public static long toLong(@Nullable Object object) { + return toLong(object, 0); + } + + public static long toLong(@Nullable Object object, long defaultValue) { + if (object instanceof Number number) { + return number.longValue(); + } + + if (object == null) { + return defaultValue; + } + + try { + return Long.parseLong(object.toString()); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public static float toFloat(@Nullable Object object) { + return toFloat(object, 0); + } + + public static float toFloat(@Nullable Object object, float defaultValue) { + if (object instanceof Number number) { + return number.floatValue(); + } + + if (object == null) { + return defaultValue; + } + + try { + return Float.parseFloat(object.toString()); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + public static double toDouble(@Nullable Object object) { + return toDouble(object, 0); + } + + public static double toDouble(@Nullable Object object, double defaultValue) { + if (object instanceof Number number) { + return number.doubleValue(); + } + + if (object == null) { + return defaultValue; + } + + try { + return Double.parseDouble(object.toString()); + } catch (NumberFormatException e) { + return defaultValue; + } + } + + private NumberConversions() { + } +} diff --git a/src/main/java/cn/nukkit/utils/SimpleConfig.java b/src/main/java/cn/nukkit/utils/SimpleConfig.java index 428710bcb06..b52638c563e 100644 --- a/src/main/java/cn/nukkit/utils/SimpleConfig.java +++ b/src/main/java/cn/nukkit/utils/SimpleConfig.java @@ -92,11 +92,12 @@ else if (field.getType() == List.class) { Class fieldArgClass = (Class) aType.getActualTypeArguments()[0]; if (fieldArgClass == Integer.class) field.set(this, cfg.getIntegerList(path)); else if (fieldArgClass == Boolean.class) field.set(this, cfg.getBooleanList(path)); + else if (fieldArgClass == Long.class) field.set(this, cfg.getLongList(path)); else if (fieldArgClass == Double.class) field.set(this, cfg.getDoubleList(path)); else if (fieldArgClass == Character.class) field.set(this, cfg.getCharacterList(path)); else if (fieldArgClass == Byte.class) field.set(this, cfg.getByteList(path)); else if (fieldArgClass == Float.class) field.set(this, cfg.getFloatList(path)); - else if (fieldArgClass == Short.class) field.set(this, cfg.getFloatList(path)); + else if (fieldArgClass == Short.class) field.set(this, cfg.getShortList(path)); else if (fieldArgClass == String.class) field.set(this, cfg.getStringList(path)); } else field.set(this, cfg.getList(path)); // Hell knows what's kind of List was found :) } else