mirror of
https://github.com/TotalFreedomMC/TF-EssentialsX.git
synced 2025-02-14 05:01:28 +00:00
Implement ItemDbProviders, pt 1
This commit is contained in:
parent
3e1857b966
commit
c5376d3088
6 changed files with 619 additions and 0 deletions
|
@ -34,9 +34,12 @@ import com.google.common.collect.Iterables;
|
|||
import net.ess3.api.*;
|
||||
import net.ess3.api.IEssentials;
|
||||
import net.ess3.api.ISettings;
|
||||
import net.ess3.nms.ItemDbProvider;
|
||||
import net.ess3.nms.PotionMetaProvider;
|
||||
import net.ess3.nms.SpawnEggProvider;
|
||||
import net.ess3.nms.SpawnerProvider;
|
||||
import net.ess3.nms.flattened.FlatItemDbProvider;
|
||||
import net.ess3.nms.legacy.LegacyItemDbProvider;
|
||||
import net.ess3.nms.legacy.LegacyPotionMetaProvider;
|
||||
import net.ess3.nms.refl.ReflSpawnEggProvider;
|
||||
import net.ess3.nms.updatedmeta.BasePotionDataProvider;
|
||||
|
@ -103,6 +106,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
|||
private transient EssentialsTimer timer;
|
||||
private final transient Set<String> vanishedPlayers = new LinkedHashSet<>();
|
||||
private transient Method oldGetOnlinePlayers;
|
||||
private transient ItemDbProvider itemDbProvider;
|
||||
private transient SpawnerProvider spawnerProvider;
|
||||
private transient SpawnEggProvider spawnEggProvider;
|
||||
private transient PotionMetaProvider potionMetaProvider;
|
||||
|
@ -211,6 +215,12 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
|||
execTimer.mark("Init(Worth/ItemDB)");
|
||||
jails = new Jails(this);
|
||||
confList.add(jails);
|
||||
|
||||
itemDbProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
FlatItemDbProvider.class,
|
||||
LegacyItemDbProvider.class
|
||||
), "item database").getProvider();
|
||||
spawnerProvider = new ProviderFactory<>(getLogger(),
|
||||
Arrays.asList(
|
||||
BlockMetaSpawnerProvider.class,
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package net.ess3.nms.flattened;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonParser;
|
||||
import net.ess3.nms.ItemDbProvider;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FlatItemDbProvider extends ItemDbProvider {
|
||||
private static Gson gson = new Gson();
|
||||
|
||||
|
||||
@Override
|
||||
public Material resolve(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLegacyIds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLegacyId(Material material) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getFromLegacyId(int id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryName(ItemStack item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNames(ItemStack item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rebuild(List<String> lines) {
|
||||
String json = lines.stream().collect(Collectors.joining("\n"));
|
||||
JsonArray jsonArray = (new JsonParser()).parse(json).getAsJsonArray();
|
||||
jsonArray.forEach(element -> {
|
||||
if (element.isJsonObject()) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
// Build the database initially so that we can actually test the provider
|
||||
this.rebuild(this.loadResource("/items.json"));
|
||||
return super.tryProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHumanName() {
|
||||
return "Post-1.13 item database provider";
|
||||
}
|
||||
|
||||
private class MaterialData {
|
||||
private Material material;
|
||||
private PotionType potionEnum;
|
||||
private String potionModifier;
|
||||
}
|
||||
}
|
32
nms/IdProvider/pom.xml
Normal file
32
nms/IdProvider/pom.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>EssentialsXParent</artifactId>
|
||||
<groupId>net.ess3</groupId>
|
||||
<version>2.15.0</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>IdProvider</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>NMSProvider</artifactId>
|
||||
<version>2.15.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.ess3</groupId>
|
||||
<artifactId>ReflectionProvider</artifactId>
|
||||
<version>2.15.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bukkit</groupId>
|
||||
<artifactId>bukkit</artifactId>
|
||||
<version>1.12.2-R0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
261
nms/IdProvider/src/net/ess3/nms/ids/LegacyItemDbProvider.java
Normal file
261
nms/IdProvider/src/net/ess3/nms/ids/LegacyItemDbProvider.java
Normal file
|
@ -0,0 +1,261 @@
|
|||
package net.ess3.nms.ids;
|
||||
|
||||
import net.ess3.nms.ItemDbProvider;
|
||||
import net.ess3.nms.PotionMetaProvider;
|
||||
import net.ess3.nms.SpawnEggProvider;
|
||||
import net.ess3.nms.refl.ReflUtil;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class LegacyItemDbProvider extends ItemDbProvider {
|
||||
private final transient Map<String, Integer> items = new HashMap<>();
|
||||
private final transient Map<ItemData, List<String>> names = new HashMap<>();
|
||||
private final transient Map<ItemData, String> primaryNames = new HashMap<>();
|
||||
private final transient Map<Integer, ItemData> legacyIds = new HashMap<>();
|
||||
private final transient Map<String, Short> durabilities = new HashMap<>();
|
||||
private final transient Map<String, String> nbtData = new HashMap<>();
|
||||
|
||||
private final transient Pattern splitPattern = Pattern.compile("((.*)[:+',;.](\\d+))");
|
||||
private final transient Pattern csvSplitPattern = Pattern.compile("(\"([^\"]*)\"|[^,]*)(,|$)");
|
||||
|
||||
@Override
|
||||
public Material resolve(String name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStack(String name) throws Exception {
|
||||
int itemid = 0;
|
||||
String itemname;
|
||||
short metaData = 0;
|
||||
|
||||
Matcher parts = splitPattern.matcher(name);
|
||||
if (parts.matches()) {
|
||||
itemname = parts.group(2);
|
||||
metaData = Short.parseShort(parts.group(3));
|
||||
} else {
|
||||
itemname = name;
|
||||
}
|
||||
|
||||
if (isInt(itemname)) {
|
||||
itemid = Integer.parseInt(itemname);
|
||||
} else if (isInt(name)) {
|
||||
itemid = Integer.parseInt(name);
|
||||
} else {
|
||||
itemname = itemname.toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
if (itemid < 1) {
|
||||
if (items.containsKey(itemname)) {
|
||||
itemid = items.get(itemname);
|
||||
if (durabilities.containsKey(itemname) && metaData == 0) {
|
||||
metaData = durabilities.get(itemname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itemid < 1) {
|
||||
throw new Exception("Unknown item name " + itemname);
|
||||
}
|
||||
|
||||
ItemData data = legacyIds.get(itemid);
|
||||
if (data == null) {
|
||||
throw new Exception("Unknown item ID " + itemid);
|
||||
}
|
||||
|
||||
Material mat = data.getMaterial();
|
||||
ItemStack retval = new ItemStack(mat);
|
||||
if (nbtData.containsKey(itemname)) {
|
||||
String nbt = nbtData.get(itemname);
|
||||
if (nbt.startsWith("*")) {
|
||||
nbt = nbtData.get(nbt.substring(1));
|
||||
}
|
||||
retval = Bukkit.getServer().getUnsafe().modifyItemStack(retval, nbt);
|
||||
}
|
||||
|
||||
|
||||
Material MOB_SPAWNER;
|
||||
try {
|
||||
MOB_SPAWNER = Material.valueOf("SPAWNER");
|
||||
} catch (Exception e) {
|
||||
MOB_SPAWNER = Material.valueOf("MOB_SPAWNER");
|
||||
}
|
||||
if (mat == MOB_SPAWNER) {
|
||||
if (metaData == 0) metaData = EntityType.PIG.getTypeId();
|
||||
try {
|
||||
retval = getSpawnerProvider().setEntityType(retval, EntityType.fromId(metaData));
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new Exception("Can't spawn entity ID " + metaData + " from mob spawners.");
|
||||
}
|
||||
} else if (mat == Material.MONSTER_EGG) {
|
||||
EntityType type;
|
||||
try {
|
||||
type = EntityType.fromId(metaData);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new Exception("Can't spawn entity ID " + metaData + " from spawn eggs.");
|
||||
}
|
||||
retval = getSpawnEggProvider().createEggItem(type);
|
||||
} else if (mat.name().endsWith("POTION")
|
||||
&& ReflUtil.getNmsVersionObject().isLowerThan(ReflUtil.V1_11_R1)) { // Only apply this to pre-1.11 as items.csv might only work in 1.11
|
||||
retval = getPotionMetaProvider().createPotionItem(mat, metaData);
|
||||
} else {
|
||||
retval.setDurability(metaData);
|
||||
}
|
||||
retval.setAmount(mat.getMaxStackSize());
|
||||
return retval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLegacyIds() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLegacyId(Material material) throws Exception {
|
||||
for (Map.Entry<String, Integer> entry : items.entrySet()) {
|
||||
if (material.name().toLowerCase(Locale.ENGLISH).equalsIgnoreCase(entry.getKey())) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("Item ID missing for material " + material.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material getFromLegacyId(int id) {
|
||||
ItemData data = this.legacyIds.get(id);
|
||||
if (data == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return data.getMaterial();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrimaryName(ItemStack item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNames(ItemStack item) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rebuild(List<String> lines) {
|
||||
durabilities.clear();
|
||||
items.clear();
|
||||
names.clear();
|
||||
primaryNames.clear();
|
||||
|
||||
lines.stream()
|
||||
.filter(line -> line.length() > 0 && !(line.charAt(0) == '#'))
|
||||
.map(this::parseLine)
|
||||
.filter(itemData -> itemData != null)
|
||||
.forEach(this::addItem);
|
||||
|
||||
for (List<String> nameList : names.values()) {
|
||||
nameList.sort(LengthCompare.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
private ItemData parseLine(String line) {
|
||||
String itemName = null;
|
||||
int numeric = -1;
|
||||
short data = 0;
|
||||
String nbt = null;
|
||||
|
||||
int col = 0;
|
||||
Matcher matcher = csvSplitPattern.matcher(line);
|
||||
while (matcher.find()) {
|
||||
String match = matcher.group(1);
|
||||
if (StringUtils.stripToNull(match) == null) {
|
||||
continue;
|
||||
}
|
||||
match = StringUtils.strip(match.trim(), "\"");
|
||||
switch (col) {
|
||||
case 0:
|
||||
itemName = match.toLowerCase(Locale.ENGLISH);
|
||||
break;
|
||||
case 1:
|
||||
numeric = Integer.parseInt(match);
|
||||
break;
|
||||
case 2:
|
||||
data = Short.parseShort(match);
|
||||
break;
|
||||
case 3:
|
||||
nbt = StringUtils.stripToNull(match);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
col++;
|
||||
}
|
||||
// Invalid row
|
||||
if (itemName == null || numeric < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Material material = Material.matchMaterial(itemName);
|
||||
if (material == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new ItemData(itemName, material, numeric, data, nbt);
|
||||
}
|
||||
|
||||
private void addItem(ItemData itemData) {
|
||||
final String name = itemData.getItemName();
|
||||
final int numeric = itemData.getItemNo();
|
||||
final short data = itemData.getItemData();
|
||||
final String nbt = itemData.getNbt();
|
||||
|
||||
durabilities.put(name, data);
|
||||
items.put(name, numeric);
|
||||
|
||||
if (nbt != null) {
|
||||
nbtData.put(itemData.getItemName(), nbt);
|
||||
}
|
||||
|
||||
if (names.containsKey(itemData)) {
|
||||
List<String> nameList = names.get(itemData);
|
||||
nameList.add(name);
|
||||
} else {
|
||||
List<String> nameList = new ArrayList<>();
|
||||
nameList.add(name);
|
||||
names.put(itemData, nameList);
|
||||
primaryNames.put(itemData, name);
|
||||
}
|
||||
|
||||
legacyIds.put(numeric, itemData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
// Build the database initially so that we can actually test the provider
|
||||
this.rebuild(this.loadResource("/items.csv"));
|
||||
return super.tryProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHumanName() {
|
||||
return "Pre-1.13 item database provider";
|
||||
}
|
||||
|
||||
private boolean isInt(String integer) {
|
||||
try {
|
||||
Integer.parseInt(integer);
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
240
nms/NMSProvider/src/net/ess3/nms/ItemDbProvider.java
Normal file
240
nms/NMSProvider/src/net/ess3/nms/ItemDbProvider.java
Normal file
|
@ -0,0 +1,240 @@
|
|||
package net.ess3.nms;
|
||||
|
||||
import net.ess3.providers.Provider;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionType;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class ItemDbProvider implements Provider {
|
||||
|
||||
private SpawnerProvider spawnerProvider;
|
||||
private SpawnEggProvider spawnEggProvider;
|
||||
private PotionMetaProvider potionMetaProvider;
|
||||
|
||||
/**
|
||||
* Resolves a material name to its corresponding Material
|
||||
*
|
||||
* @param name The material name to look up
|
||||
* @return The corresponding Material for the given name
|
||||
*/
|
||||
public abstract Material resolve(String name);
|
||||
|
||||
/**
|
||||
* Whether the provider supports legacy ID values or not.
|
||||
*
|
||||
* @return True if the provider supports legacy IDs, otherwise false
|
||||
*/
|
||||
public abstract boolean supportsLegacyIds();
|
||||
|
||||
/**
|
||||
* Get the legacy ID for the material.
|
||||
*
|
||||
* @param material The material to look up
|
||||
* @return The ID corresponding to the material, or null if not supported
|
||||
*/
|
||||
public abstract int getLegacyId(Material material) throws Exception;
|
||||
|
||||
/**
|
||||
* Get the material for the legacy ID.
|
||||
*
|
||||
* @param id The ID to look up
|
||||
* @return The material corresponding to the ID, or -1 if not supported
|
||||
*/
|
||||
public abstract Material getFromLegacyId(int id);
|
||||
|
||||
/**
|
||||
* Get the primary name for the item in the given stack.
|
||||
*
|
||||
* @param item The ItemStack to check
|
||||
* @return The primary name for the item
|
||||
*/
|
||||
public abstract String getPrimaryName(ItemStack item);
|
||||
|
||||
/**
|
||||
* Get all names for the item in the given stack.
|
||||
*
|
||||
* @param item The ItemStack to check
|
||||
* @return The names for the item
|
||||
*/
|
||||
public abstract List<String> getNames(ItemStack item);
|
||||
|
||||
/**
|
||||
* Rebuild the item database, using the given lines of a file.
|
||||
*
|
||||
* @param lines The lines of the file from which the database should be built.
|
||||
*/
|
||||
public abstract void rebuild(List<String> lines);
|
||||
|
||||
/**
|
||||
* Creates a stack of a given item by its name.
|
||||
*
|
||||
* @param name The material name to look up
|
||||
* @return An ItemStack of size 1 of the given item
|
||||
*/
|
||||
public ItemStack getStack(String name) throws Exception {
|
||||
return new ItemStack(resolve(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a stack with the given amount of a given item by its name.
|
||||
*
|
||||
* @param name The material name to look up
|
||||
* @param amount The amount of items in the returned ItemStack
|
||||
* @return An ItemStack with the given amount of the given item
|
||||
*/
|
||||
public ItemStack getStack(String name, int amount) throws Exception {
|
||||
ItemStack is = getStack(name);
|
||||
is.setAmount(amount);
|
||||
return is;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a resource from the jar.
|
||||
* Used to build the database before data from a ManagedFile is available.
|
||||
*
|
||||
* @param name The name of the resource to load.
|
||||
* @return The lines of the resource.
|
||||
*/
|
||||
protected List<String> loadResource(final String name) {
|
||||
try (InputStreamReader isr = new InputStreamReader(ItemDbProvider.class.getResourceAsStream(name))) {
|
||||
BufferedReader br = new BufferedReader(isr);
|
||||
return br.lines().collect(Collectors.toList());
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryProvider() {
|
||||
try {
|
||||
getStack("cstone");
|
||||
getStack("diorite");
|
||||
getStack("steelbar", 5);
|
||||
getStack("aoepot");
|
||||
getStack("skeletonegg", 12);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected SpawnerProvider getSpawnerProvider() {
|
||||
return spawnerProvider;
|
||||
}
|
||||
|
||||
public void setSpawnerProvider(SpawnerProvider spawnerProvider) {
|
||||
this.spawnerProvider = spawnerProvider;
|
||||
}
|
||||
|
||||
protected SpawnEggProvider getSpawnEggProvider() {
|
||||
return spawnEggProvider;
|
||||
}
|
||||
|
||||
public void setSpawnEggProvider(SpawnEggProvider spawnEggProvider) {
|
||||
this.spawnEggProvider = spawnEggProvider;
|
||||
}
|
||||
|
||||
protected PotionMetaProvider getPotionMetaProvider() {
|
||||
return potionMetaProvider;
|
||||
}
|
||||
|
||||
public void setPotionMetaProvider(PotionMetaProvider potionMetaProvider) {
|
||||
this.potionMetaProvider = potionMetaProvider;
|
||||
}
|
||||
|
||||
public static class ItemData {
|
||||
final private String itemName;
|
||||
final private Material material;
|
||||
private int legacyId;
|
||||
private short itemData;
|
||||
final private String nbt;
|
||||
private PotionData potionData;
|
||||
|
||||
public ItemData(String itemName, Material material, String nbt) {
|
||||
this.itemName = itemName;
|
||||
this.material = material;
|
||||
this.nbt = nbt;
|
||||
}
|
||||
|
||||
public ItemData(String itemName, Material material, String nbt, PotionData potionData) {
|
||||
this.itemName = itemName;
|
||||
this.material = material;
|
||||
this.nbt = nbt;
|
||||
this.potionData = potionData;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public ItemData(String itemName, Material material, final int legacyId, final short itemData, String nbt) {
|
||||
this.itemName = itemName;
|
||||
this.material = material;
|
||||
this.legacyId = legacyId;
|
||||
this.itemData = itemData;
|
||||
this.nbt = nbt;
|
||||
}
|
||||
|
||||
public String getItemName() {
|
||||
return itemName;
|
||||
}
|
||||
|
||||
public Material getMaterial() {
|
||||
return material;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getItemNo() {
|
||||
return legacyId;
|
||||
}
|
||||
|
||||
public short getItemData() {
|
||||
return itemData;
|
||||
}
|
||||
|
||||
public String getNbt() {
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (31 * material.hashCode()) ^ itemData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(o instanceof ItemData)) {
|
||||
return false;
|
||||
}
|
||||
ItemData pairo = (ItemData) o;
|
||||
return this.material == pairo.getMaterial() && this.itemData == pairo.getItemData() && this.nbt.equals(pairo.getNbt());
|
||||
}
|
||||
}
|
||||
|
||||
public static class PotionData {
|
||||
private PotionType bukkitType;
|
||||
private String vanillaType;
|
||||
private boolean isStrong;
|
||||
private boolean isLong;
|
||||
}
|
||||
|
||||
protected static class LengthCompare implements java.util.Comparator<String> {
|
||||
|
||||
public static final LengthCompare INSTANCE = new LengthCompare();
|
||||
|
||||
public LengthCompare() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(String s1, String s2) {
|
||||
return s1.length() - s2.length();
|
||||
}
|
||||
}
|
||||
}
|
1
pom.xml
1
pom.xml
|
@ -47,6 +47,7 @@
|
|||
<module>nms/1_8_R2Provider</module>
|
||||
<module>nms/LegacyProvider</module>
|
||||
<module>nms/ReflectionProvider</module>
|
||||
<module>nms/IdProvider</module>
|
||||
<module>nms/FlattenedProvider</module>
|
||||
</modules>
|
||||
|
||||
|
|
Loading…
Reference in a new issue