mirror of
https://github.com/songoda/SongodaCore.git
synced 2025-02-02 20:51:27 +01:00
Apply new code style [DEV-2]
This commit is contained in:
parent
92f42e6261
commit
39bdd862fb
@ -1,7 +1,6 @@
|
||||
package com.songoda.core.compatibility;
|
||||
|
||||
public enum ClassMapping {
|
||||
|
||||
BIOME_BASE("world.level.biome", "BiomeBase"),
|
||||
BIOME_STORAGE("world.level.chunk", "BiomeStorage"),
|
||||
BLOCK("world.level.block", "Block"),
|
||||
@ -65,15 +64,18 @@ public enum ClassMapping {
|
||||
public Class<?> getClazz(String sub) {
|
||||
try {
|
||||
String name = sub == null ? className : className + "$" + sub;
|
||||
if (className.startsWith("Craft"))
|
||||
if (className.startsWith("Craft")) {
|
||||
return Class.forName("org.bukkit.craftbukkit." + ServerVersion.getServerVersionString()
|
||||
+ (packageName == null ? "" : "." + packageName) + "." + name);
|
||||
}
|
||||
|
||||
return Class.forName("net.minecraft." + (
|
||||
ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17) && packageName != null
|
||||
? packageName : "server." + ServerVersion.getServerVersionString()) + "." + name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import java.util.Set;
|
||||
* @since 2020-03-27
|
||||
*/
|
||||
public enum CompatibleBiome {
|
||||
|
||||
/* 1.17 */
|
||||
DRIPSTONE_CAVES(ServerVersion.V1_17),
|
||||
LUSH_CAVES(ServerVersion.V1_17),
|
||||
@ -121,13 +120,17 @@ public enum CompatibleBiome {
|
||||
private static Field fieldStorageRegistry;
|
||||
|
||||
static {
|
||||
for (CompatibleBiome biome : values())
|
||||
for (Version version : biome.getVersions())
|
||||
for (CompatibleBiome biome : values()) {
|
||||
for (Version version : biome.getVersions()) {
|
||||
lookupMap.put(version.biome, biome);
|
||||
}
|
||||
}
|
||||
|
||||
for (CompatibleBiome biome : CompatibleBiome.values())
|
||||
if (biome.isCompatible())
|
||||
for (CompatibleBiome biome : CompatibleBiome.values()) {
|
||||
if (biome.isCompatible()) {
|
||||
compatibleBiomes.add(biome);
|
||||
}
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
|
||||
try {
|
||||
@ -148,13 +151,14 @@ public enum CompatibleBiome {
|
||||
try {
|
||||
// If 1.16.5
|
||||
fieldStorageRegistry = classBiomeStorage.getDeclaredField("registry");
|
||||
} catch (NoSuchFieldException e) {
|
||||
} catch (NoSuchFieldException ex) {
|
||||
// If less than 1.16.5
|
||||
fieldStorageRegistry = classBiomeStorage.getDeclaredField("g");
|
||||
}
|
||||
|
||||
fieldStorageRegistry.setAccessible(true);
|
||||
} catch (NoSuchMethodException | NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException | NoSuchFieldException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -171,6 +175,7 @@ public enum CompatibleBiome {
|
||||
public boolean isCompatible() {
|
||||
Version version = versions.getLast();
|
||||
ServerVersion.isServerVersionAtLeast(version.version);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -179,9 +184,12 @@ public enum CompatibleBiome {
|
||||
}
|
||||
|
||||
public Biome getBiome() {
|
||||
for (Version version : versions)
|
||||
if (ServerVersion.isServerVersionAtLeast(version.version))
|
||||
for (Version version : versions) {
|
||||
if (ServerVersion.isServerVersionAtLeast(version.version)) {
|
||||
return Biome.valueOf(version.biome);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -201,36 +209,48 @@ public enum CompatibleBiome {
|
||||
Object nmsChunk = null;
|
||||
Object biomeStorage = null;
|
||||
Object biomeBase = null;
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
|
||||
nmsChunk = methodGetHandle.invoke(chunk);
|
||||
biomeStorage = methodGetBiomeIndex.invoke(nmsChunk);
|
||||
|
||||
if (isAbove1_16_R1) {
|
||||
Object registry = fieldStorageRegistry.get(biomeStorage);
|
||||
biomeBase = methodBiomeToBiomeBase.invoke(null, registry, getBiome());
|
||||
} else
|
||||
} else {
|
||||
biomeBase = methodBiomeToBiomeBase.invoke(null, getBiome());
|
||||
}
|
||||
}
|
||||
|
||||
World world = chunk.getWorld();
|
||||
int chunkX = chunk.getX();
|
||||
int chunkZ = chunk.getZ();
|
||||
for (int x = chunkX << 4; x < (chunkX << 4) + 16; x++) {
|
||||
for (int z = chunkZ << 4; z < (chunkZ << 4) + 16; z++) {
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15))
|
||||
for (int y = 0; y < world.getMaxHeight(); ++y)
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
|
||||
for (int y = 0; y < world.getMaxHeight(); ++y) {
|
||||
methodSetBiome.invoke(biomeStorage, x >> 2, y >> 2, z >> 2, biomeBase);
|
||||
else
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
chunk.getWorld().setBiome(x, z, getBiome());
|
||||
}
|
||||
}
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15))
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
|
||||
methodMarkDirty.invoke(nmsChunk);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBiome(World world, int x, int y, int z) {
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15))
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)) {
|
||||
world.setBiome(x, y, z, getBiome());
|
||||
else
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
world.setBiome(x, z, getBiome());
|
||||
}
|
||||
|
||||
@ -243,7 +263,6 @@ public enum CompatibleBiome {
|
||||
}
|
||||
|
||||
private static class Version {
|
||||
|
||||
final ServerVersion version;
|
||||
final String biome;
|
||||
|
||||
|
@ -16,7 +16,6 @@ import java.util.Map;
|
||||
* @since 2020-03-24
|
||||
*/
|
||||
public enum CompatibleHand {
|
||||
|
||||
MAIN_HAND, OFF_HAND;
|
||||
|
||||
private static Map<String, Method> methodCache = new HashMap<>();
|
||||
@ -25,6 +24,7 @@ public enum CompatibleHand {
|
||||
try {
|
||||
Class<?> clazz = event.getClass();
|
||||
String className = clazz.getName();
|
||||
|
||||
Method method;
|
||||
if (methodCache.containsKey(className)) {
|
||||
method = methodCache.get(className);
|
||||
@ -32,10 +32,15 @@ public enum CompatibleHand {
|
||||
method = clazz.getDeclaredMethod("getHand");
|
||||
methodCache.put(className, method);
|
||||
}
|
||||
|
||||
EquipmentSlot slot = (EquipmentSlot) method.invoke(event);
|
||||
if (slot == EquipmentSlot.OFF_HAND) return OFF_HAND;
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) {
|
||||
|
||||
if (slot == EquipmentSlot.OFF_HAND) {
|
||||
return OFF_HAND;
|
||||
}
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignore) {
|
||||
}
|
||||
|
||||
return MAIN_HAND;
|
||||
}
|
||||
|
||||
@ -65,9 +70,11 @@ public enum CompatibleHand {
|
||||
int result = item.getAmount() - amount;
|
||||
item.setAmount(result);
|
||||
|
||||
if (this == CompatibleHand.MAIN_HAND)
|
||||
if (this == CompatibleHand.MAIN_HAND) {
|
||||
player.setItemInHand(result > 0 ? item : null);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
player.getInventory().setItemInOffHand(result > 0 ? item : null);
|
||||
}
|
||||
|
||||
@ -79,9 +86,10 @@ public enum CompatibleHand {
|
||||
* @return the item
|
||||
*/
|
||||
public ItemStack getItem(Player player) {
|
||||
if (this == MAIN_HAND)
|
||||
if (this == MAIN_HAND) {
|
||||
return player.getItemInHand();
|
||||
else
|
||||
}
|
||||
|
||||
return player.getInventory().getItemInOffHand();
|
||||
}
|
||||
|
||||
@ -92,9 +100,11 @@ public enum CompatibleHand {
|
||||
* @param item the item to set
|
||||
*/
|
||||
public void setItem(Player player, ItemStack item) {
|
||||
if (this == MAIN_HAND)
|
||||
if (this == MAIN_HAND) {
|
||||
player.setItemInHand(item);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
player.getInventory().setItemInOffHand(item);
|
||||
}
|
||||
}
|
||||
|
@ -1304,22 +1304,27 @@ public enum CompatibleMaterial {
|
||||
lookupMap.put(m.legacy, m);
|
||||
continue;
|
||||
}
|
||||
|
||||
lookupMap.put(m.name(), m);
|
||||
if (!m.usesCompatibility()) {
|
||||
lookupMap.put(m.material + ":" + (m.data == null ? "" : m.data), m);
|
||||
}
|
||||
}
|
||||
|
||||
for (CompatibleMaterial m : values()) {
|
||||
if (!m.usesCompatibility()) {
|
||||
if (m.legacy != null && !lookupMap.containsKey(m.legacy)) {
|
||||
lookupMap.put(m.legacy, m);
|
||||
}
|
||||
|
||||
if (m.modern2 != null && !lookupMap.containsKey(m.modern2)) {
|
||||
lookupMap.put(m.modern2, m);
|
||||
}
|
||||
|
||||
if (m.legacyBlockMaterial != null && !lookupMap.containsKey(m.legacyBlockMaterial.blockMaterialName)) {
|
||||
lookupMap.put(m.legacyBlockMaterial.blockMaterialName, m);
|
||||
}
|
||||
|
||||
if (m.legacyBlockMaterial != null && !lookupMap.containsKey(m.legacyBlockMaterial.alternateBlockMaterialName)) {
|
||||
lookupMap.put(m.legacyBlockMaterial.alternateBlockMaterialName, m);
|
||||
}
|
||||
@ -1422,8 +1427,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Does this material need to use a legacy fallback?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean usesLegacy() {
|
||||
return legacy != null && ServerVersion.isServerVersionBelow(minVersion);
|
||||
@ -1431,8 +1434,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Does this material need to use a fallback item on this server?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean usesCompatibility() {
|
||||
return compatibleMaterial != null && material == compatibleMaterial.material;
|
||||
@ -1441,18 +1442,13 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Is this item reused in later versions of Minecraft?
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isRecycled() {
|
||||
return usesLegacy() && this == CompatibleMaterial.GRASS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the legacy data value for this material if there is one, or -1 if
|
||||
* none
|
||||
*
|
||||
* @return
|
||||
* Get the legacy data value for this material if there is one, or -1 if none
|
||||
*/
|
||||
public byte getData() {
|
||||
return data != null ? data : -1;
|
||||
@ -1523,6 +1519,7 @@ public enum CompatibleMaterial {
|
||||
if (item == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String key = item.getType() + ":";
|
||||
CompatibleMaterial m = lookupMap.get(key);
|
||||
return m != null ? m : lookupMap.get(key + item.getDurability());
|
||||
@ -1561,8 +1558,8 @@ public enum CompatibleMaterial {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12)) {
|
||||
try {
|
||||
methodGetBlockData = FallingBlock.class.getDeclaredMethod("getBlockData");
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1575,16 +1572,20 @@ public enum CompatibleMaterial {
|
||||
* @return LegacyMaterial or null if none found
|
||||
*/
|
||||
public static CompatibleMaterial getMaterial(FallingBlock block) {
|
||||
if (block == null) return null;
|
||||
if (block == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
|
||||
return getMaterial(block.getBlockData().getMaterial());
|
||||
} else {
|
||||
}
|
||||
|
||||
try {
|
||||
return getMaterial(block.getMaterial(), (byte) methodGetBlockData.invoke(block));
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1599,21 +1600,21 @@ public enum CompatibleMaterial {
|
||||
public static CompatibleMaterial getMaterial(Material mat, byte data) {
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) { // Flattening
|
||||
return CompatibleMaterial.getMaterial(mat);
|
||||
} else { // Pre-Flattening
|
||||
}
|
||||
|
||||
// Pre-Flattening
|
||||
if (mat != null) {
|
||||
if (data != 0) {
|
||||
for (CompatibleMaterial cm : CompatibleMaterial.values()) {
|
||||
if (cm.getMaterial() != null
|
||||
&& cm.getMaterial().equals(mat)) {
|
||||
if (cm.getData() == data) {
|
||||
if (cm.getMaterial() != null && cm.getMaterial().equals(mat) && cm.getData() == data) {
|
||||
return cm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CompatibleMaterial.getMaterial(mat);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1621,15 +1622,19 @@ public enum CompatibleMaterial {
|
||||
if (block == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Material mat = block.getType();
|
||||
|
||||
if (useLegacy) {
|
||||
LegacyMaterialBlockType legacyBlock = LegacyMaterialBlockType.getFromLegacy(mat.name(), block.getData());
|
||||
if (legacyBlock != null) {
|
||||
return lookupMap.get(legacyBlock.name());
|
||||
}
|
||||
|
||||
CompatibleMaterial withData = lookupMap.get(mat.name() + ":" + block.getData());
|
||||
return withData == null ? lookupMap.get(mat.name()) : withData;
|
||||
}
|
||||
|
||||
return lookupMap.get(mat.name());
|
||||
}
|
||||
|
||||
@ -1645,12 +1650,16 @@ public enum CompatibleMaterial {
|
||||
public static CompatibleMaterial getBlockMaterial(String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
} else if (useLegacy) {
|
||||
}
|
||||
|
||||
if (useLegacy) {
|
||||
LegacyMaterialBlockType legacyBlock = LegacyMaterialBlockType.getFromLegacy(name.toUpperCase());
|
||||
|
||||
if (legacyBlock != null) {
|
||||
return lookupMap.get(legacyBlock.name());
|
||||
}
|
||||
}
|
||||
|
||||
return lookupMap.get(name.toUpperCase());
|
||||
}
|
||||
|
||||
@ -1667,12 +1676,16 @@ public enum CompatibleMaterial {
|
||||
public static CompatibleMaterial getBlockMaterial(String name, CompatibleMaterial def) {
|
||||
if (name == null) {
|
||||
return def;
|
||||
} else if (useLegacy) {
|
||||
}
|
||||
|
||||
if (useLegacy) {
|
||||
LegacyMaterialBlockType legacyBlock = LegacyMaterialBlockType.getFromLegacy(name.toUpperCase());
|
||||
|
||||
if (legacyBlock != null) {
|
||||
return lookupMap.get(legacyBlock.name());
|
||||
}
|
||||
}
|
||||
|
||||
return lookupMap.getOrDefault(name.toUpperCase(), def);
|
||||
}
|
||||
|
||||
@ -1686,12 +1699,16 @@ public enum CompatibleMaterial {
|
||||
public static CompatibleMaterial getBlockMaterial(Material mat) {
|
||||
if (mat == null) {
|
||||
return null;
|
||||
} else if (useLegacy) {
|
||||
}
|
||||
|
||||
if (useLegacy) {
|
||||
LegacyMaterialBlockType legacyBlock = LegacyMaterialBlockType.getFromLegacy(mat.name());
|
||||
|
||||
if (legacyBlock != null) {
|
||||
return lookupMap.get(legacyBlock.name());
|
||||
}
|
||||
}
|
||||
|
||||
return lookupMap.get(mat.name());
|
||||
}
|
||||
|
||||
@ -1699,13 +1716,15 @@ public enum CompatibleMaterial {
|
||||
|
||||
public static Set<CompatibleMaterial> getAllValidItemMaterials() {
|
||||
if (all == null) {
|
||||
all = new LinkedHashSet();
|
||||
all = new LinkedHashSet<>();
|
||||
|
||||
for (CompatibleMaterial mat : values()) {
|
||||
if (mat.isValidItem() && !mat.usesCompatibility()) {
|
||||
all.add(mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableSet(all);
|
||||
}
|
||||
|
||||
@ -1723,10 +1742,12 @@ public enum CompatibleMaterial {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
CompatibleMaterial m = lookupMap.get(name.toUpperCase());
|
||||
if (m != null) {
|
||||
return m.getItem();
|
||||
}
|
||||
|
||||
Material mat = Material.getMaterial(name);
|
||||
return mat != null ? new ItemStack(mat) : null;
|
||||
}
|
||||
@ -1737,8 +1758,8 @@ public enum CompatibleMaterial {
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12)) {
|
||||
try {
|
||||
methodSetData = Block.class.getDeclaredMethod("setData", byte.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1750,12 +1771,14 @@ public enum CompatibleMaterial {
|
||||
*/
|
||||
public void applyToBlock(Block block) {
|
||||
if (block == null) return;
|
||||
|
||||
block.setType(material);
|
||||
|
||||
if (data != null && data != -1 && ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12)) {
|
||||
try {
|
||||
methodSetData.invoke(block, data);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1768,14 +1791,15 @@ public enum CompatibleMaterial {
|
||||
* @return true if material of the ItemStack matches this item, corrected for legacy data
|
||||
*/
|
||||
public boolean matches(ItemStack item) {
|
||||
return item != null && !usesCompatibility() && item.getType() == material && (data == null || item.getDurability() == data); // eons ago, ItemStack.getData() would return a byte. 1.7 doesn't, though.
|
||||
return item != null &&
|
||||
!usesCompatibility() && item.getType() == material &&
|
||||
// eons ago, ItemStack.getData() would return a byte. 1.7 doesn't, though.
|
||||
(data == null || item.getDurability() == data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some blocks change to other materials when placed down. This checks to
|
||||
* see if this one is one of those.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean hasDifferentBlockItem() {
|
||||
switch (this) {
|
||||
@ -1832,14 +1856,13 @@ public enum CompatibleMaterial {
|
||||
case CAKE:
|
||||
case COMPARATOR:
|
||||
return usesLegacy();
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if this is a material that can exist as a block
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isBlock() {
|
||||
return material != null && material.isBlock();
|
||||
@ -1847,8 +1870,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check to see if this is an item that can be consumed to restore hunger
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isEdible() {
|
||||
return material != null && material.isEdible();
|
||||
@ -1856,8 +1877,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is a block and can be built on
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isSolid() {
|
||||
return material != null && material.isSolid();
|
||||
@ -1865,8 +1884,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is a block and does not block any light
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isTransparent() {
|
||||
return material != null && material.isTransparent();
|
||||
@ -1874,8 +1891,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is a block and can catch fire
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isFlammable() {
|
||||
return material != null && material.isFlammable();
|
||||
@ -1883,8 +1898,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is a block and can be destroyed by burning
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isBurnable() {
|
||||
return material != null && material.isBurnable();
|
||||
@ -1892,8 +1905,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Checks if this Material can be used as fuel in a Furnace
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isFuel() {
|
||||
// this function is not implemented in some older versions, so we need this here..
|
||||
@ -2253,8 +2264,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is air
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isAir() {
|
||||
switch (this) {
|
||||
@ -2269,8 +2278,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Check if the material is water
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isWater() {
|
||||
return this == CompatibleMaterial.WATER;
|
||||
@ -2278,26 +2285,26 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Get the EntityType of the monster spawn egg.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public EntityType getEggType() {
|
||||
String entityName = this.name().replace("_SPAWN_EGG", "");
|
||||
if (entityName.equals("MOOSHROOM"))
|
||||
|
||||
if (entityName.equals("MOOSHROOM")) {
|
||||
entityName = "MUSHROOM_COW";
|
||||
else if (entityName.equals("ZOMBIE_PIGMAN"))
|
||||
} else if (entityName.equals("ZOMBIE_PIGMAN")) {
|
||||
entityName = "PIG_ZOMBIE";
|
||||
}
|
||||
|
||||
try {
|
||||
return EntityType.valueOf(entityName);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the material is a block and completely blocks vision
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isOccluding() {
|
||||
return material != null && material.isOccluding();
|
||||
@ -2312,8 +2319,6 @@ public enum CompatibleMaterial {
|
||||
|
||||
/**
|
||||
* Checks if this Material is an obtainable item.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isItem() {
|
||||
// this function is not implemented in some older versions, so we need this here..
|
||||
@ -2410,16 +2415,15 @@ public enum CompatibleMaterial {
|
||||
case YELLOW_WALL_BANNER:
|
||||
case ZOMBIE_WALL_HEAD:
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this Material can be interacted with. <br />
|
||||
* This method will return true if there is at least one state in which
|
||||
* additional interact handling is performed for the material.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isInteractable() {
|
||||
// this function is not implemented in some older versions, so we need this here..
|
||||
@ -2634,12 +2638,12 @@ public enum CompatibleMaterial {
|
||||
case WHITE_BED:
|
||||
case WHITE_SHULKER_BOX:
|
||||
case YELLOW_BED:
|
||||
case YELLOW_SHULKER_BOX: {
|
||||
case YELLOW_SHULKER_BOX:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this material is valid as an item
|
||||
@ -2738,7 +2742,10 @@ public enum CompatibleMaterial {
|
||||
case WHITE_WALL_BANNER:
|
||||
case WITHER_SKELETON_WALL_SKULL:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12)) {
|
||||
switch (this) {
|
||||
case ACACIA_WOOD:
|
||||
@ -2754,8 +2761,11 @@ public enum CompatibleMaterial {
|
||||
case STRIPPED_OAK_WOOD:
|
||||
case STRIPPED_SPRUCE_WOOD:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2801,9 +2811,10 @@ public enum CompatibleMaterial {
|
||||
case COOKED_SALMON:
|
||||
case DRIED_KELP:
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this material is a food that can be cooked and is in its raw state
|
||||
@ -2820,9 +2831,10 @@ public enum CompatibleMaterial {
|
||||
case RABBIT:
|
||||
case SALMON:
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this material is two blocks tall
|
||||
@ -2836,9 +2848,10 @@ public enum CompatibleMaterial {
|
||||
case PEONY:
|
||||
case TALL_GRASS:
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: If using this on a legacy server without #getBlockMaterial
|
||||
@ -2935,8 +2948,7 @@ public enum CompatibleMaterial {
|
||||
return MOOSHROOM_SPAWN_EGG;
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionBelow(ServerVersion.V1_16)
|
||||
&& type == EntityType.valueOf("PIG_ZOMBIE")) {
|
||||
if (ServerVersion.isServerVersionBelow(ServerVersion.V1_16) && type == EntityType.valueOf("PIG_ZOMBIE")) {
|
||||
return ZOMBIE_PIGMAN_SPAWN_EGG;
|
||||
}
|
||||
|
||||
@ -2977,8 +2989,9 @@ public enum CompatibleMaterial {
|
||||
return RED_STAINED_GLASS_PANE;
|
||||
case 15:
|
||||
return BLACK_STAINED_GLASS_PANE;
|
||||
default:
|
||||
return WHITE_STAINED_GLASS;
|
||||
}
|
||||
return WHITE_STAINED_GLASS_PANE;
|
||||
}
|
||||
|
||||
public static CompatibleMaterial getGlassColor(int color) {
|
||||
@ -3015,9 +3028,10 @@ public enum CompatibleMaterial {
|
||||
return RED_STAINED_GLASS;
|
||||
case 15:
|
||||
return BLACK_STAINED_GLASS;
|
||||
}
|
||||
default:
|
||||
return WHITE_STAINED_GLASS;
|
||||
}
|
||||
}
|
||||
|
||||
public static CompatibleMaterial getWoolColor(int color) {
|
||||
switch (color) {
|
||||
@ -3053,9 +3067,10 @@ public enum CompatibleMaterial {
|
||||
return RED_WOOL;
|
||||
case 15:
|
||||
return BLACK_WOOL;
|
||||
}
|
||||
default:
|
||||
return WHITE_WOOL;
|
||||
}
|
||||
}
|
||||
|
||||
public static CompatibleMaterial getDyeColor(int color) {
|
||||
switch (color) {
|
||||
@ -3091,7 +3106,8 @@ public enum CompatibleMaterial {
|
||||
return ORANGE_DYE;
|
||||
case 15:
|
||||
return WHITE_DYE;
|
||||
}
|
||||
default:
|
||||
return WHITE_DYE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class CompatibleParticleHandler {
|
||||
|
||||
public static enum ParticleType {
|
||||
EXPLOSION_NORMAL,
|
||||
EXPLOSION_LARGE,
|
||||
|
@ -18,7 +18,6 @@ import org.bukkit.entity.Player;
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
public enum CompatibleSound {
|
||||
|
||||
// some of these values are missing an API value..
|
||||
// would using the raw strings be better?
|
||||
// 1.8 list:
|
||||
@ -1247,14 +1246,15 @@ public enum CompatibleSound {
|
||||
private CompatibleSound(String compatibility_18) {
|
||||
try {
|
||||
compatibilityMode = false;
|
||||
|
||||
if (ServerVersion.isServerVersionBelow(ServerVersion.V1_9)) {
|
||||
sound = Sound.valueOf(compatibility_18);
|
||||
} else {
|
||||
sound = Sound.valueOf(name());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ex) {
|
||||
System.err.println("ERROR loading " + name());
|
||||
e.printStackTrace();
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1267,12 +1267,13 @@ public enum CompatibleSound {
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ex) {
|
||||
System.err.println("ERROR loading " + name());
|
||||
for (Version v : versions) {
|
||||
System.err.println(v.version + " - " + v.sound);
|
||||
}
|
||||
e.printStackTrace();
|
||||
|
||||
ex.printStackTrace();
|
||||
}
|
||||
Sound find = null;
|
||||
for (Sound s : Sound.values()) {
|
||||
@ -1302,12 +1303,13 @@ public enum CompatibleSound {
|
||||
sound = null;
|
||||
compatibilityMode = false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (Exception ex) {
|
||||
System.err.println("ERROR loading " + name() + " (" + minVersion);
|
||||
for (Version v : versions) {
|
||||
System.err.println(v.version + " - " + v.sound);
|
||||
}
|
||||
e.printStackTrace();
|
||||
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class EntityNamespace {
|
||||
|
||||
static final HashMap<String, EntityType> validTypes = new HashMap();
|
||||
static final HashMap<String, String> legacyToModernTypes = new HashMap() {
|
||||
{
|
||||
@ -66,11 +65,14 @@ public class EntityNamespace {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// first try to translate natively
|
||||
EntityType type = EntityType.fromName(entity);
|
||||
|
||||
if (type == null) {
|
||||
// try legacy values
|
||||
type = EntityType.fromName(legacyToModernTypes.get(entity));
|
||||
|
||||
// try converting modern to legacy
|
||||
if (type == null && legacyToModernTypes.containsValue(entity)) {
|
||||
for (Map.Entry<String, String> e : legacyToModernTypes.entrySet()) {
|
||||
@ -80,6 +82,7 @@ public class EntityNamespace {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import java.util.Map;
|
||||
* @since 2019-08-23
|
||||
*/
|
||||
public enum LegacyMaterialAnalouge {
|
||||
|
||||
/* 1.17 */
|
||||
// ToDo: Improve legal materials.
|
||||
AMETHYST_BLOCK(ServerVersion.V1_17, "STONE"),
|
||||
@ -739,7 +738,6 @@ public enum LegacyMaterialAnalouge {
|
||||
YELLOW_WALL_BANNER(ServerVersion.V1_8, "WALL_SIGN"),
|
||||
ZOMBIE_HORSE_SPAWN_EGG(ServerVersion.V1_11, "MONSTER_EGG", (byte) 0),
|
||||
ZOMBIE_VILLAGER_SPAWN_EGG(ServerVersion.V1_11, "MONSTER_EGG", (byte) 0),
|
||||
|
||||
;
|
||||
|
||||
final ServerVersion versionLessThan;
|
||||
@ -822,11 +820,8 @@ public enum LegacyMaterialAnalouge {
|
||||
// use legacy material if on legacy
|
||||
material = Material.getMaterial(legacyMaterial);
|
||||
data = legacyData;
|
||||
} else if (modernMaterial != null) {
|
||||
material = Material.getMaterial(modernMaterial);
|
||||
data = null;
|
||||
} else {
|
||||
material = null;
|
||||
material = Material.getMaterial(modernMaterial);
|
||||
data = null;
|
||||
}
|
||||
} else {
|
||||
@ -851,6 +846,7 @@ public enum LegacyMaterialAnalouge {
|
||||
if (material == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return data != null ? new ItemStack(material, 1, data) : new ItemStack(material);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,6 @@ import java.util.Map;
|
||||
* @since 2019-09-12
|
||||
*/
|
||||
public enum LegacyMaterialBlockType {
|
||||
|
||||
OAK_LEAVES("LEAVES", (byte) 8, true),
|
||||
SPRUCE_LEAVES("LEAVES", (byte) 9, true),
|
||||
BIRCH_LEAVES("LEAVES", (byte) 10, true),
|
||||
|
@ -20,9 +20,7 @@ import java.util.logging.Logger;
|
||||
* @since 2019-08-23
|
||||
*/
|
||||
public class LegacyParticleEffects {
|
||||
|
||||
public static enum Type {
|
||||
|
||||
EXPLOSION_NORMAL("explode"),
|
||||
EXPLOSION_LARGE("largeexplode"),
|
||||
EXPLOSION_HUGE("hugeexplosion"),
|
||||
@ -205,6 +203,7 @@ public class LegacyParticleEffects {
|
||||
// Set those fields we need to be accessible!
|
||||
field.setAccessible(true);
|
||||
final String fieldName = field.getName();
|
||||
|
||||
// Set them to what we want!
|
||||
if (fieldName.equals("a")) {
|
||||
// we're just going to assume it's either 1.7 or 1.8
|
||||
@ -237,6 +236,7 @@ public class LegacyParticleEffects {
|
||||
k = int[] for packet data (like block type for ITEM_CRACK)
|
||||
*/
|
||||
}
|
||||
|
||||
// send it on its way!
|
||||
for (Player p : sendTo) {
|
||||
sendPacket(sPacket, p);
|
||||
@ -250,6 +250,7 @@ public class LegacyParticleEffects {
|
||||
private static void sendPacket(Object packet, Player to) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||
Object cbPlayer = cb_craftPlayer_getHandle.invoke(to);
|
||||
Object mcConnection = mc_entityPlayer_playerConnection.get(cbPlayer);
|
||||
|
||||
mc_playerConnection_sendPacket.invoke(mcConnection, packet);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
|
||||
public class LegacyPotionEffects {
|
||||
|
||||
private LegacyPotionEffects() {
|
||||
}
|
||||
|
||||
|
@ -4,38 +4,43 @@ import org.apache.commons.lang.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public enum ServerProject {
|
||||
|
||||
UNKNOWN, CRAFTBUKKIT, SPIGOT, PAPER, TACO, GLOWSTONE;
|
||||
private final static ServerProject serverProject = checkProject();
|
||||
|
||||
private static ServerProject checkProject() {
|
||||
String serverPath = Bukkit.getServer().getClass().getName();
|
||||
|
||||
if (serverPath.contains("glowstone")) {
|
||||
return GLOWSTONE;
|
||||
}
|
||||
|
||||
// taco is pretty easy to check. it uses paper stuff, though, so should be checked first
|
||||
try {
|
||||
Class.forName("net.techcable.tacospigot.TacoSpigotConfig");
|
||||
return TACO;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
// paper used to be called "paperclip"
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paperclip.Paperclip");
|
||||
return PAPER;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
try {
|
||||
Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||
return PAPER;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
// spigot is the fork that pretty much all builds are based on anymore
|
||||
try {
|
||||
Class.forName("org.spigotmc.SpigotConfig");
|
||||
return SPIGOT;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
|
||||
return serverPath.contains("craftbukkit") ? CRAFTBUKKIT : UNKNOWN;
|
||||
}
|
||||
|
||||
|
@ -87,13 +87,14 @@ public class SongodaCore {
|
||||
for (Class<?> clazz : Bukkit.getServicesManager().getKnownServices()) {
|
||||
if (clazz.getSimpleName().equals("SongodaCore")) {
|
||||
try {
|
||||
// test to see if we're up to date
|
||||
// test to see if we're up-to-date
|
||||
int otherVersion;
|
||||
try {
|
||||
otherVersion = (int) clazz.getMethod("getCoreVersion").invoke(null);
|
||||
} catch (Exception ignore) {
|
||||
otherVersion = -1;
|
||||
}
|
||||
|
||||
if (otherVersion >= getCoreVersion()) {
|
||||
// use the active service
|
||||
// assuming that the other is greater than R6 if we get here ;)
|
||||
@ -104,21 +105,26 @@ public class SongodaCore {
|
||||
INSTANCE.shadingListener = new ShadedEventListener();
|
||||
Bukkit.getPluginManager().registerEvents(INSTANCE.shadingListener, plugin);
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
|
||||
// we are newer than the registered service: steal all of its registrations
|
||||
// grab the old core's registrations
|
||||
List otherPlugins = (List) clazz.getMethod("getPlugins").invoke(null);
|
||||
|
||||
// destroy the old core
|
||||
Object oldCore = clazz.getMethod("getInstance").invoke(null);
|
||||
Method destruct = clazz.getDeclaredMethod("destroy");
|
||||
destruct.setAccessible(true);
|
||||
destruct.invoke(oldCore);
|
||||
|
||||
// register ourselves as the SongodaCore service!
|
||||
INSTANCE = new SongodaCore(plugin);
|
||||
INSTANCE.init();
|
||||
INSTANCE.register(plugin, pluginID, icon, coreVersion);
|
||||
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal);
|
||||
|
||||
// we need (JavaPlugin plugin, int pluginID, String icon) for our object
|
||||
if (!otherPlugins.isEmpty()) {
|
||||
Object testSubject = otherPlugins.get(0);
|
||||
@ -127,6 +133,7 @@ public class SongodaCore {
|
||||
Method otherPluginInfo_getSongodaId = otherPluginInfo.getMethod("getSongodaId");
|
||||
Method otherPluginInfo_getCoreIcon = otherPluginInfo.getMethod("getCoreIcon");
|
||||
Method otherPluginInfo_getCoreLibraryVersion = otherVersion >= 6 ? otherPluginInfo.getMethod("getCoreLibraryVersion") : null;
|
||||
|
||||
for (Object other : otherPlugins) {
|
||||
INSTANCE.register(
|
||||
(JavaPlugin) otherPluginInfo_getJavaPlugin.invoke(other),
|
||||
@ -135,18 +142,20 @@ public class SongodaCore {
|
||||
otherPluginInfo_getCoreLibraryVersion != null ? (String) otherPluginInfo_getCoreLibraryVersion.invoke(other) : "?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ignored) {
|
||||
plugin.getLogger().log(Level.WARNING, "Error registering core service", ignored);
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException ex) {
|
||||
plugin.getLogger().log(Level.WARNING, "Error registering core service", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// register ourselves as the SongodaCore service!
|
||||
INSTANCE = new SongodaCore(plugin);
|
||||
INSTANCE.init();
|
||||
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, plugin, ServicePriority.Normal);
|
||||
}
|
||||
|
||||
INSTANCE.register(plugin, pluginID, icon, coreVersion);
|
||||
}
|
||||
|
||||
@ -166,6 +175,7 @@ public class SongodaCore {
|
||||
.addSubCommand(new SongodaCoreDiagCommand());
|
||||
Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin);
|
||||
Bukkit.getPluginManager().registerEvents(shadingListener, piggybackedPlugin);
|
||||
|
||||
// we aggressively want to own this command
|
||||
tasks.add(Bukkit.getScheduler().runTaskLaterAsynchronously(piggybackedPlugin, () -> {
|
||||
CommandManager.registerCommandDynamically(piggybackedPlugin, "songoda", commandManager, commandManager);
|
||||
@ -183,12 +193,15 @@ public class SongodaCore {
|
||||
*/
|
||||
private void destroy() {
|
||||
Bukkit.getServicesManager().unregister(SongodaCore.class, INSTANCE);
|
||||
|
||||
tasks.stream().filter(Objects::nonNull)
|
||||
.forEach(task -> Bukkit.getScheduler().cancelTask(task.getTaskId()));
|
||||
|
||||
HandlerList.unregisterAll(loginListener);
|
||||
if (!hasShading()) {
|
||||
HandlerList.unregisterAll(shadingListener);
|
||||
}
|
||||
|
||||
registeredPlugins.clear();
|
||||
commandManager = null;
|
||||
loginListener = null;
|
||||
@ -199,6 +212,7 @@ public class SongodaCore {
|
||||
private void register(JavaPlugin plugin, int pluginID, String icon, String libraryVersion) {
|
||||
logger.info(getPrefix() + "Hooked " + plugin.getName() + ".");
|
||||
PluginInfo info = new PluginInfo(plugin, pluginID, icon, libraryVersion);
|
||||
|
||||
// don't forget to check for language pack updates ;)
|
||||
info.addModule(new LocaleModule());
|
||||
registeredPlugins.add(info);
|
||||
@ -238,10 +252,10 @@ public class SongodaCore {
|
||||
for (PluginInfoModule module : plugin.getModules()) {
|
||||
module.run(plugin);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
final String er = e.getMessage();
|
||||
} catch (IOException ex) {
|
||||
final String er = ex.getMessage();
|
||||
logger.log(Level.FINE, "Connection with Songoda servers failed: " + (er.contains("URL") ? er.substring(0, er.indexOf("URL") + 3) : er));
|
||||
} catch (ParseException e) {
|
||||
} catch (ParseException ex) {
|
||||
logger.log(Level.FINE, "Failed to parse json for " + plugin.getJavaPlugin().getName() + " update check");
|
||||
}
|
||||
}
|
||||
@ -287,9 +301,15 @@ public class SongodaCore {
|
||||
boolean proto = false;
|
||||
|
||||
ShadedEventListener() {
|
||||
if ((via = Bukkit.getPluginManager().isPluginEnabled("ViaVersion"))) {
|
||||
via = Bukkit.getPluginManager().isPluginEnabled("ViaVersion");
|
||||
|
||||
if (via) {
|
||||
Bukkit.getOnlinePlayers().forEach(p -> ClientVersion.onLoginVia(p, getHijackedPlugin()));
|
||||
} else if ((proto = Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
proto = Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport");
|
||||
if (proto) {
|
||||
Bukkit.getOnlinePlayers().forEach(p -> ClientVersion.onLoginProtocol(p, getHijackedPlugin()));
|
||||
}
|
||||
}
|
||||
@ -298,7 +318,10 @@ public class SongodaCore {
|
||||
void onLogin(PlayerLoginEvent event) {
|
||||
if (via) {
|
||||
ClientVersion.onLoginVia(event.getPlayer(), getHijackedPlugin());
|
||||
} else if (proto) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (proto) {
|
||||
ClientVersion.onLoginProtocol(event.getPlayer(), getHijackedPlugin());
|
||||
}
|
||||
}
|
||||
@ -327,13 +350,20 @@ public class SongodaCore {
|
||||
@EventHandler
|
||||
void onLogin(PlayerLoginEvent event) {
|
||||
final Player player = event.getPlayer();
|
||||
|
||||
// don't spam players with update checks
|
||||
long now = System.currentTimeMillis();
|
||||
Long last = lastCheck.get(player.getUniqueId());
|
||||
if (last != null && now - 10000 < last) return;
|
||||
|
||||
if (last != null && now - 10000 < last) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastCheck.put(player.getUniqueId(), now);
|
||||
|
||||
// is this player good to revieve update notices?
|
||||
if (!event.getPlayer().isOp() && !player.hasPermission("songoda.updatecheck")) return;
|
||||
|
||||
// check for updates! ;)
|
||||
for (PluginInfo plugin : getPlugins()) {
|
||||
if (plugin.getNotification() != null && plugin.getJavaPlugin().isEnabled())
|
||||
@ -346,16 +376,20 @@ public class SongodaCore {
|
||||
void onDisable(PluginDisableEvent event) {
|
||||
// don't track disabled plugins
|
||||
PluginInfo pi = registeredPlugins.stream().filter(p -> event.getPlugin() == p.getJavaPlugin()).findFirst().orElse(null);
|
||||
|
||||
if (pi != null) {
|
||||
registeredPlugins.remove(pi);
|
||||
}
|
||||
|
||||
if (event.getPlugin() == piggybackedPlugin) {
|
||||
// uh-oh! Abandon ship!!
|
||||
Bukkit.getServicesManager().unregisterAll(piggybackedPlugin);
|
||||
|
||||
// can we move somewhere else?
|
||||
if ((pi = registeredPlugins.stream().findFirst().orElse(null)) != null) {
|
||||
// move ourselves to this plugin
|
||||
piggybackedPlugin = pi.getJavaPlugin();
|
||||
|
||||
Bukkit.getServicesManager().register(SongodaCore.class, INSTANCE, piggybackedPlugin, ServicePriority.Normal);
|
||||
Bukkit.getPluginManager().registerEvents(loginListener, piggybackedPlugin);
|
||||
Bukkit.getPluginManager().registerEvents(shadingListener, piggybackedPlugin);
|
||||
|
@ -78,6 +78,7 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
+ " v" + getDescription().getVersion()
|
||||
+ " c" + SongodaCore.getCoreLibraryVersion()
|
||||
+ ": Disabling plugin!", t);
|
||||
|
||||
emergencyStop = true;
|
||||
}
|
||||
}
|
||||
@ -86,6 +87,7 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
public final void onEnable() {
|
||||
if (emergencyStop) {
|
||||
setEnabled(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -98,26 +100,33 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
|
||||
try {
|
||||
locale = Locale.loadDefaultLocale(this, "en_US");
|
||||
|
||||
// plugin setup
|
||||
onPluginEnable();
|
||||
|
||||
// Load Data.
|
||||
Bukkit.getScheduler().runTaskLater(this, this::onDataLoad, dataLoadDelay);
|
||||
|
||||
if (emergencyStop) {
|
||||
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
console.sendMessage(" ");
|
||||
return;
|
||||
}
|
||||
|
||||
// Start Metrics
|
||||
Metrics.start(this);
|
||||
} catch (Throwable t) {
|
||||
} catch (Throwable th) {
|
||||
Bukkit.getLogger().log(Level.SEVERE,
|
||||
"Unexpected error while loading " + getDescription().getName()
|
||||
+ " v" + getDescription().getVersion()
|
||||
+ " c" + SongodaCore.getCoreLibraryVersion()
|
||||
+ ": Disabling plugin!", t);
|
||||
+ ": Disabling plugin!", th);
|
||||
|
||||
emergencyStop();
|
||||
|
||||
console.sendMessage(ChatColor.RED + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
|
||||
console.sendMessage(" ");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -127,6 +136,7 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
|
||||
protected void emergencyStop() {
|
||||
emergencyStop = true;
|
||||
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
|
||||
@ -135,13 +145,16 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
if (emergencyStop) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.sendMessage(" "); // blank line to speparate chatter
|
||||
console.sendMessage(ChatColor.GREEN + "=============================");
|
||||
console.sendMessage(String.format("%s%s %s by %sSongoda <3!", ChatColor.GRAY.toString(),
|
||||
getDescription().getName(), getDescription().getVersion(), ChatColor.DARK_PURPLE.toString()));
|
||||
console.sendMessage(String.format("%sAction: %s%s%s...", ChatColor.GRAY.toString(),
|
||||
ChatColor.RED.toString(), "Disabling", ChatColor.GRAY.toString()));
|
||||
|
||||
onPluginDisable();
|
||||
|
||||
console.sendMessage(ChatColor.GREEN + "=============================");
|
||||
console.sendMessage(" "); // blank line to speparate chatter
|
||||
}
|
||||
@ -166,16 +179,16 @@ public abstract class SongodaPlugin extends JavaPlugin {
|
||||
public boolean setLocale(String localeName, boolean reload) {
|
||||
if (locale != null && locale.getName().equals(localeName)) {
|
||||
return !reload || locale.reloadMessages();
|
||||
} else {
|
||||
}
|
||||
|
||||
Locale l = Locale.loadLocale(this, localeName);
|
||||
if (l != null) {
|
||||
locale = l;
|
||||
return true;
|
||||
} else {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void shutdownDataManager(DataManagerAbstract dataManager) {
|
||||
// 3 minutes is overkill, but we just want to make sure
|
||||
|
@ -23,7 +23,6 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ChatMessage {
|
||||
|
||||
private static final Gson gson = new GsonBuilder().create();
|
||||
private final List<JsonObject> textList = new ArrayList<>();
|
||||
|
||||
@ -36,7 +35,8 @@ public class ChatMessage {
|
||||
}
|
||||
|
||||
public ChatMessage fromText(String text, boolean noHex) {
|
||||
Pattern pattern = Pattern.compile("(.*?)(?!&([omnlk]))(?=(&([123456789abcdefr#])|$)|#([a-f]|[A-F]|[0-9]){6})",
|
||||
Pattern pattern = Pattern.compile(
|
||||
"(.*?)(?!&([omnlk]))(?=(&([123456789abcdefr#])|$)|#([a-f]|[A-F]|[0-9]){6})",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
Matcher matcher = pattern.matcher(text);
|
||||
|
||||
@ -44,12 +44,15 @@ public class ChatMessage {
|
||||
ColorContainer color = null;
|
||||
String match1 = matcher.group(1);
|
||||
|
||||
if (matcher.groupCount() == 0 || match1.length() == 0) continue;
|
||||
if (matcher.groupCount() == 0 || match1.length() == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char colorChar = '-';
|
||||
|
||||
if (matcher.start() != 0)
|
||||
if (matcher.start() != 0) {
|
||||
colorChar = text.substring(matcher.start() - 1, matcher.start()).charAt(0);
|
||||
}
|
||||
|
||||
if (colorChar != '-') {
|
||||
if (colorChar == '#') {
|
||||
@ -70,17 +73,19 @@ public class ChatMessage {
|
||||
|
||||
ColorCode code = ColorCode.getByChar(Character.toLowerCase(match2.charAt(0)));
|
||||
|
||||
if (code != null && code != ColorCode.RESET)
|
||||
if (code != null && code != ColorCode.RESET) {
|
||||
stackedCodes.add(code);
|
||||
}
|
||||
|
||||
if (color != null)
|
||||
if (color != null) {
|
||||
match2 = match2.substring(1);
|
||||
}
|
||||
|
||||
if (match2.length() == 0) continue;
|
||||
|
||||
if (match2.length() != 0) {
|
||||
addMessage(match2, color, stackedCodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -91,31 +96,40 @@ public class ChatMessage {
|
||||
|
||||
public String toText(boolean noHex) {
|
||||
StringBuilder text = new StringBuilder();
|
||||
|
||||
for (JsonObject object : textList) {
|
||||
if (object.has("color")) {
|
||||
String color = object.get("color").getAsString();
|
||||
text.append("&");
|
||||
|
||||
if (color.length() == 7) {
|
||||
text.append(new ColorContainer(color, noHex).getColor().getCode());
|
||||
} else {
|
||||
text.append(ColorCode.valueOf(color.toUpperCase()).getCode());
|
||||
}
|
||||
}
|
||||
|
||||
for (ColorCode code : ColorCode.values()) {
|
||||
if (code.isColor()) continue;
|
||||
|
||||
String c = code.name().toLowerCase();
|
||||
if (object.has(c) && object.get(c).getAsBoolean())
|
||||
if (object.has(c) && object.get(c).getAsBoolean()) {
|
||||
text.append("&").append(code.getCode());
|
||||
}
|
||||
}
|
||||
|
||||
text.append(object.get("text").getAsString());
|
||||
}
|
||||
|
||||
return text.toString();
|
||||
}
|
||||
|
||||
public ChatMessage addMessage(String s) {
|
||||
JsonObject txt = new JsonObject();
|
||||
txt.addProperty("text", s);
|
||||
|
||||
textList.add(txt);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -127,12 +141,15 @@ public class ChatMessage {
|
||||
JsonObject txt = new JsonObject();
|
||||
txt.addProperty("text", text);
|
||||
|
||||
if (color != null)
|
||||
if (color != null) {
|
||||
txt.addProperty("color", color.getHexCode() != null ? "#" + color.getHexCode() : color.getColorCode().name().toLowerCase());
|
||||
}
|
||||
|
||||
for (ColorCode code : ColorCode.values()) {
|
||||
if (!code.isColor())
|
||||
if (!code.isColor()) {
|
||||
txt.addProperty(code.name().toLowerCase(), colorCodes.contains(code));
|
||||
}
|
||||
}
|
||||
|
||||
textList.add(txt);
|
||||
return this;
|
||||
@ -141,14 +158,17 @@ public class ChatMessage {
|
||||
public ChatMessage addRunCommand(String text, String hoverText, String cmd) {
|
||||
JsonObject txt = new JsonObject();
|
||||
txt.addProperty("text", text);
|
||||
|
||||
JsonObject hover = new JsonObject();
|
||||
hover.addProperty("action", "show_text");
|
||||
hover.addProperty("value", hoverText);
|
||||
txt.add("hoverEvent", hover);
|
||||
|
||||
JsonObject click = new JsonObject();
|
||||
click.addProperty("action", "run_command");
|
||||
click.addProperty("value", cmd);
|
||||
txt.add("clickEvent", click);
|
||||
|
||||
textList.add(txt);
|
||||
return this;
|
||||
}
|
||||
@ -156,14 +176,17 @@ public class ChatMessage {
|
||||
public ChatMessage addPromptCommand(String text, String hoverText, String cmd) {
|
||||
JsonObject txt = new JsonObject();
|
||||
txt.addProperty("text", text);
|
||||
|
||||
JsonObject hover = new JsonObject();
|
||||
hover.addProperty("action", "show_text");
|
||||
hover.addProperty("value", hoverText);
|
||||
txt.add("hoverEvent", hover);
|
||||
|
||||
JsonObject click = new JsonObject();
|
||||
click.addProperty("action", "suggest_command");
|
||||
click.addProperty("value", cmd);
|
||||
txt.add("clickEvent", click);
|
||||
|
||||
textList.add(txt);
|
||||
return this;
|
||||
}
|
||||
@ -171,14 +194,17 @@ public class ChatMessage {
|
||||
public ChatMessage addURL(String text, String hoverText, String url) {
|
||||
JsonObject txt = new JsonObject();
|
||||
txt.addProperty("text", text);
|
||||
|
||||
JsonObject hover = new JsonObject();
|
||||
hover.addProperty("action", "show_text");
|
||||
hover.addProperty("value", hoverText);
|
||||
txt.add("hoverEvent", hover);
|
||||
|
||||
JsonObject click = new JsonObject();
|
||||
click.addProperty("action", "open_url");
|
||||
click.addProperty("value", url);
|
||||
txt.add("clickEvent", hover);
|
||||
|
||||
textList.add(txt);
|
||||
return this;
|
||||
}
|
||||
@ -200,10 +226,14 @@ public class ChatMessage {
|
||||
|
||||
Object packet;
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16)) {
|
||||
packet = mc_PacketPlayOutChat_new.newInstance(mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)), mc_chatMessageType_Chat.get(null), ((Player) sender).getUniqueId());
|
||||
packet = mc_PacketPlayOutChat_new.newInstance(
|
||||
mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)),
|
||||
mc_chatMessageType_Chat.get(null),
|
||||
((Player) sender).getUniqueId());
|
||||
} else {
|
||||
packet = mc_PacketPlayOutChat_new.newInstance(mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)));
|
||||
}
|
||||
|
||||
Object cbPlayer = cb_craftPlayer_getHandle.invoke(sender);
|
||||
Object mcConnection = mc_entityPlayer_playerConnection.get(cbPlayer);
|
||||
mc_playerConnection_sendPacket.invoke(mcConnection, packet);
|
||||
@ -211,9 +241,11 @@ public class ChatMessage {
|
||||
Bukkit.getLogger().log(Level.WARNING, "Problem preparing raw chat packets (disabling further packets)", ex);
|
||||
enabled = false;
|
||||
}
|
||||
} else {
|
||||
sender.sendMessage(TextUtils.formatText((prefix == null ? "" : prefix.toText(true) + " ") + toText(true)));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(TextUtils.formatText((prefix == null ? "" : prefix.toText(true) + " ") + toText(true)));
|
||||
}
|
||||
|
||||
private static boolean enabled = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_8);
|
||||
@ -230,7 +262,6 @@ public class ChatMessage {
|
||||
static void init() {
|
||||
if (enabled) {
|
||||
try {
|
||||
|
||||
final String version = ServerVersion.getServerVersionString();
|
||||
Class<?> cb_craftPlayerClazz, mc_entityPlayerClazz, mc_playerConnectionClazz, mc_PacketInterface,
|
||||
mc_IChatBaseComponent, mc_IChatBaseComponent_ChatSerializer, mc_PacketPlayOutChat;
|
||||
@ -263,11 +294,12 @@ public class ChatMessage {
|
||||
|
||||
public ChatMessage replaceAll(String toReplace, String replaceWith) {
|
||||
for (JsonObject object : textList) {
|
||||
String text = object.get("text").getAsString()
|
||||
.replaceAll(toReplace, replaceWith);
|
||||
String text = object.get("text").getAsString().replaceAll(toReplace, replaceWith);
|
||||
|
||||
object.remove("text");
|
||||
object.addProperty("text", text);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public enum ColorCode {
|
||||
|
||||
BLACK('0', ChatColor.BLACK, true),
|
||||
DARK_BLUE('1', ChatColor.DARK_BLUE, true),
|
||||
DARK_GREEN('2', ChatColor.DARK_GREEN, true),
|
||||
|
@ -3,10 +3,9 @@ package com.songoda.core.chat;
|
||||
import com.songoda.core.compatibility.ServerVersion;
|
||||
import com.songoda.core.utils.ColorUtils;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.*;
|
||||
|
||||
public class ColorContainer {
|
||||
|
||||
private ColorCode colorCode;
|
||||
private String hexCode;
|
||||
|
||||
@ -17,6 +16,7 @@ public class ColorContainer {
|
||||
|
||||
public ColorContainer(String hexCode, boolean noHex) {
|
||||
this.hexCode = hexCode;
|
||||
|
||||
if (noHex || ServerVersion.isServerVersionBelow(ServerVersion.V1_16)) {
|
||||
this.colorCode = getColor();
|
||||
this.hexCode = null;
|
||||
@ -32,12 +32,19 @@ public class ColorContainer {
|
||||
}
|
||||
|
||||
public ColorCode getColor() {
|
||||
if (colorCode != null) return colorCode;
|
||||
if (hexCode == null) return null;
|
||||
if (colorCode != null) {
|
||||
return colorCode;
|
||||
}
|
||||
|
||||
if (hexCode == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
java.awt.Color jColor = new Color(
|
||||
Integer.valueOf(hexCode.substring(0, 2), 16),
|
||||
Integer.valueOf(hexCode.substring(2, 4), 16),
|
||||
Integer.valueOf(hexCode.substring(4, 6), 16));
|
||||
|
||||
return ColorUtils.fromRGB(jColor.getRed(), jColor.getGreen(), jColor.getBlue());
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractCommand {
|
||||
|
||||
private final CommandType _cmdType;
|
||||
private final boolean _hasArgs;
|
||||
private final List<String> _handledCommands = new ArrayList<>();
|
||||
|
@ -28,7 +28,6 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
|
||||
private final JavaPlugin plugin;
|
||||
|
||||
private final HashMap<String, SimpleNestedCommand> commands = new HashMap<>();
|
||||
@ -68,19 +67,27 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
|
||||
public List<String> getSubCommands(String command) {
|
||||
SimpleNestedCommand nested = command == null ? null : commands.get(command.toLowerCase());
|
||||
return nested == null ? Collections.emptyList() : new ArrayList<>(nested.children.keySet());
|
||||
|
||||
if (nested == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return new ArrayList<>(nested.children.keySet());
|
||||
}
|
||||
|
||||
public Set<AbstractCommand> getAllCommands() {
|
||||
HashSet<AbstractCommand> all = new HashSet<>();
|
||||
|
||||
commands.values().stream()
|
||||
.filter(c -> c.parent != null && !all.contains(c.parent))
|
||||
.forEach(c -> {
|
||||
all.add(c.parent);
|
||||
|
||||
c.children.values().stream()
|
||||
.filter(s -> !all.contains(s))
|
||||
.forEach(s -> all.add(s));
|
||||
});
|
||||
|
||||
return all;
|
||||
}
|
||||
|
||||
@ -91,10 +98,12 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
|
||||
public SimpleNestedCommand registerCommandDynamically(AbstractCommand abstractCommand) {
|
||||
SimpleNestedCommand nested = new SimpleNestedCommand(abstractCommand);
|
||||
|
||||
abstractCommand.getCommands().forEach(cmd -> {
|
||||
CommandManager.registerCommandDynamically(plugin, cmd, this, this);
|
||||
commands.put(cmd.toLowerCase(), nested);
|
||||
PluginCommand pcmd = plugin.getCommand(cmd);
|
||||
|
||||
if (pcmd != null) {
|
||||
pcmd.setExecutor(this);
|
||||
pcmd.setTabCompleter(this);
|
||||
@ -102,21 +111,26 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
plugin.getLogger().warning("Failed to register command: /" + cmd);
|
||||
}
|
||||
});
|
||||
|
||||
return nested;
|
||||
}
|
||||
|
||||
public SimpleNestedCommand addCommand(AbstractCommand abstractCommand) {
|
||||
SimpleNestedCommand nested = new SimpleNestedCommand(abstractCommand);
|
||||
|
||||
abstractCommand.getCommands().forEach(cmd -> {
|
||||
commands.put(cmd.toLowerCase(), nested);
|
||||
PluginCommand pcmd = plugin.getCommand(cmd);
|
||||
if (pcmd != null) {
|
||||
|
||||
if (pcmd == null) {
|
||||
plugin.getLogger().warning("Failed to register command: /" + cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
pcmd.setExecutor(this);
|
||||
pcmd.setTabCompleter(this);
|
||||
} else {
|
||||
plugin.getLogger().warning("Failed to register command: /" + cmd);
|
||||
}
|
||||
});
|
||||
|
||||
return nested;
|
||||
}
|
||||
|
||||
@ -137,9 +151,11 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
|
||||
public MainCommand getMainCommand(String command) {
|
||||
SimpleNestedCommand nested = command == null ? null : commands.get(command.toLowerCase());
|
||||
|
||||
if (nested != null && nested.parent instanceof MainCommand) {
|
||||
return (MainCommand) nested.parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -147,16 +163,19 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
for (AbstractCommand abstractCommand : abstractCommands) {
|
||||
addCommand(abstractCommand);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandManager setExecutor(String command) {
|
||||
PluginCommand pcmd = command == null ? null : plugin.getCommand(command);
|
||||
|
||||
if (pcmd != null) {
|
||||
pcmd.setExecutor(this);
|
||||
} else {
|
||||
plugin.getLogger().warning("Failed to register command: /" + command);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -169,28 +188,34 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
public boolean onCommand(CommandSender commandSender, Command command, String label, String[] args) {
|
||||
// grab the specific command that's being called
|
||||
SimpleNestedCommand nested = commands.get(command.getName().toLowerCase());
|
||||
|
||||
if (nested != null) {
|
||||
// check to see if we're trying to call a sub-command
|
||||
if (args.length != 0 && !nested.children.isEmpty()) {
|
||||
String subCmd = getSubCommand(nested, args);
|
||||
|
||||
if (subCmd != null) {
|
||||
// we have a subcommand to use!
|
||||
AbstractCommand sub = nested.children.get(subCmd);
|
||||
|
||||
// adjust the arguments to match - BREAKING!!
|
||||
int i = subCmd.indexOf(' ') == -1 ? 1 : 2;
|
||||
String[] newArgs = new String[args.length - i];
|
||||
System.arraycopy(args, i, newArgs, 0, newArgs.length);
|
||||
|
||||
// now process the command
|
||||
processRequirements(sub, commandSender, newArgs);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// if we've gotten this far, then just use the command we have
|
||||
if (nested.parent != null) {
|
||||
processRequirements(nested.parent, commandSender, args);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
commandSender.sendMessage(msg_noCommand);
|
||||
return true;
|
||||
}
|
||||
@ -227,6 +252,7 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
@ -235,17 +261,24 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
sender.sendMessage(msg_noConsole);
|
||||
return;
|
||||
}
|
||||
|
||||
if (command.getPermissionNode() == null || sender.hasPermission(command.getPermissionNode())) {
|
||||
AbstractCommand.ReturnType returnType = command.runCommand(sender, args);
|
||||
|
||||
if (returnType == AbstractCommand.ReturnType.NEEDS_PLAYER) {
|
||||
sender.sendMessage(msg_noConsole);
|
||||
} else if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (returnType == AbstractCommand.ReturnType.SYNTAX_ERROR) {
|
||||
for (String s : msg_syntaxError) {
|
||||
sender.sendMessage(s.replace("%syntax%", command.getSyntax()));
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(msg_noPerms);
|
||||
}
|
||||
|
||||
@ -253,10 +286,12 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
|
||||
// grab the specific command that's being called
|
||||
SimpleNestedCommand nested = commands.get(command.getName().toLowerCase());
|
||||
|
||||
if (nested != null) {
|
||||
if (args.length == 0 || nested.children.isEmpty()) {
|
||||
return nested.parent != null ? nested.parent.onTab(sender, args) : null;
|
||||
}
|
||||
|
||||
// check for each sub-command that they have access to
|
||||
final boolean op = sender.isOp();
|
||||
final boolean console = !(sender instanceof Player);
|
||||
@ -269,42 +304,47 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
.filter(e -> op || e.getValue().getPermissionNode() == null || sender.hasPermission(e.getValue().getPermissionNode()))
|
||||
.map(e -> e.getKey())
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
}
|
||||
|
||||
// more than one arg, let's check to see if we have a command here
|
||||
String subCmd = getSubCommand(nested, args);
|
||||
AbstractCommand sub;
|
||||
if (subCmd != null && (sub = nested.children.get(subCmd)) != null
|
||||
&& (!console || !sub.isNoConsole())
|
||||
&& (op || sub.getPermissionNode() == null || sender.hasPermission(sub.getPermissionNode()))) {
|
||||
if (subCmd != null &&
|
||||
(sub = nested.children.get(subCmd)) != null &&
|
||||
(!console || !sub.isNoConsole()) &&
|
||||
(op || sub.getPermissionNode() == null || sender.hasPermission(sub.getPermissionNode()))) {
|
||||
// adjust the arguments to match - BREAKING!!
|
||||
int i = subCmd.indexOf(' ') == -1 ? 1 : 2;
|
||||
String[] newArgs = new String[args.length - i];
|
||||
System.arraycopy(args, i, newArgs, 0, newArgs.length);
|
||||
|
||||
// we're good to go!
|
||||
return fetchList(sub, newArgs, sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private List<String> fetchList(AbstractCommand abstractCommand, String[] args, CommandSender sender) {
|
||||
List<String> list = abstractCommand.onTab(sender, args);
|
||||
|
||||
if (args.length != 0) {
|
||||
String str = args[args.length - 1];
|
||||
|
||||
if (list != null && str != null && str.length() >= 1) {
|
||||
try {
|
||||
list.removeIf(s -> !s.toLowerCase().startsWith(str.toLowerCase()));
|
||||
} catch (UnsupportedOperationException ignored) {
|
||||
} catch (UnsupportedOperationException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void registerCommandDynamically(Plugin plugin, String command, CommandExecutor executor, TabCompleter tabManager) {
|
||||
try {
|
||||
|
||||
// Retrieve the SimpleCommandMap from the server
|
||||
Class<?> clazzCraftServer = Bukkit.getServer().getClass();
|
||||
Object craftServer = clazzCraftServer.cast(Bukkit.getServer());
|
||||
@ -337,8 +377,8 @@ public class CommandManager implements CommandExecutor, TabCompleter {
|
||||
fieldKnownCommands.setAccessible(true);
|
||||
Map<String, Command> knownCommands = (Map<String, Command>) fieldKnownCommands.get(commandMap);
|
||||
knownCommands.put(command, commandObject);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MainCommand extends AbstractCommand {
|
||||
|
||||
String header = null;
|
||||
String description;
|
||||
boolean sortHelp = false;
|
||||
@ -22,6 +21,7 @@ public class MainCommand extends AbstractCommand {
|
||||
|
||||
public MainCommand(Plugin plugin, String command) {
|
||||
super(CommandType.CONSOLE_OK, command);
|
||||
|
||||
this.command = command;
|
||||
this.plugin = plugin;
|
||||
this.description = "Shows the command help page for /" + command;
|
||||
@ -56,6 +56,7 @@ public class MainCommand extends AbstractCommand {
|
||||
@Override
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
sender.sendMessage("");
|
||||
|
||||
if (header != null) {
|
||||
sender.sendMessage(header);
|
||||
} else {
|
||||
@ -63,17 +64,21 @@ public class MainCommand extends AbstractCommand {
|
||||
plugin.getDescription().getName(), plugin.getDescription().getVersion()), sender instanceof ConsoleCommandSender)
|
||||
.sendTo(sender);
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.YELLOW + "/songoda" + ChatColor.GRAY + " - Opens the Songoda plugin GUI");
|
||||
sender.sendMessage("");
|
||||
|
||||
if (nestedCommands != null) {
|
||||
List<String> commands = nestedCommands.children.values().stream().distinct().map(c -> c.getCommands().get(0)).collect(Collectors.toList());
|
||||
|
||||
if (sortHelp) {
|
||||
Collections.sort(commands);
|
||||
}
|
||||
|
||||
boolean isPlayer = sender instanceof Player;
|
||||
// todo? pagation if commands.size is too large? (player-only)
|
||||
sender.sendMessage(ChatColor.DARK_GRAY + "- " + ChatColor.YELLOW + getSyntax() + ChatColor.GRAY + " - " + getDescription());
|
||||
|
||||
for (String cmdStr : commands) {
|
||||
final AbstractCommand cmd = nestedCommands.children.get(cmdStr);
|
||||
if (cmd == null) continue;
|
||||
|
@ -20,7 +20,6 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SelectorArguments {
|
||||
|
||||
static Pattern selectorPattern = Pattern.compile("^(@[apers])(\\[(.*?)\\])?$");
|
||||
static Pattern selectorRangePattern = Pattern.compile("^([0-9]{1,9}(\\.[0-9]{1,9})?)?(\\.\\.)?([0-9]{1,9}(\\.[0-9]{1,9})?)?$");
|
||||
|
||||
@ -38,14 +37,17 @@ public class SelectorArguments {
|
||||
if (!(sender instanceof BlockCommandSender || sender instanceof Player)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Matcher m = selectorPattern.matcher(argument);
|
||||
if (!m.find()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SelectorType type = SelectorType.getType(m.group(1));
|
||||
if (type == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SelectorArguments selector = new SelectorArguments(sender, type);
|
||||
|
||||
if (m.group(3) != null) {
|
||||
@ -67,9 +69,11 @@ public class SelectorArguments {
|
||||
|
||||
private void parseArguments(String selectorArgs) {
|
||||
String[] args = selectorArgs.split(",");
|
||||
|
||||
for (String s : args) {
|
||||
if (s.contains("=")) {
|
||||
String[] v = s.split("=");
|
||||
|
||||
if (v[0].equals("distance")) {
|
||||
// 10 = d == 10
|
||||
// 10..12 = d > 10 && d <= 12
|
||||
@ -80,6 +84,7 @@ public class SelectorArguments {
|
||||
if (distGroup.group(1) != null) {
|
||||
rangeMin = Double.parseDouble(distGroup.group(1));
|
||||
}
|
||||
|
||||
if (distGroup.group(3) == null) {
|
||||
rangeMax = rangeMin;
|
||||
} else if (distGroup.group(4) != null) {
|
||||
@ -89,9 +94,11 @@ public class SelectorArguments {
|
||||
} else if (v[0].equals("type")) {
|
||||
entityType = EntityNamespace.minecraftToBukkit(v[1]);
|
||||
}
|
||||
|
||||
// more arguments can be parsed here (TODO)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
advancements Advancement earned by entity.
|
||||
distance Distance to entity.
|
||||
@ -121,13 +128,17 @@ public class SelectorArguments {
|
||||
public Collection<Entity> getSelection() {
|
||||
final Location location = sender instanceof Player ? ((Player) sender).getLocation() : ((BlockCommandSender) sender).getBlock().getLocation();
|
||||
Collection<Entity> list = preSelect(location);
|
||||
|
||||
if (list.isEmpty()) {
|
||||
return list;
|
||||
}
|
||||
|
||||
List<Entity> list2 = filter(location, list);
|
||||
|
||||
if (list2.isEmpty()) {
|
||||
return list2;
|
||||
}
|
||||
|
||||
switch (selector) {
|
||||
case PLAYER:
|
||||
Collections.sort(list2, (o1, o2) -> (int) (o1.getLocation().distanceSquared(location) - o2.getLocation().distanceSquared(location)));
|
||||
@ -140,6 +151,7 @@ public class SelectorArguments {
|
||||
case SELF:
|
||||
return list2;
|
||||
}
|
||||
|
||||
return list2;
|
||||
}
|
||||
|
||||
@ -152,13 +164,16 @@ public class SelectorArguments {
|
||||
? location.getWorld().getEntitiesByClasses(Player.class)
|
||||
: location.getWorld().getNearbyEntities(location, rangeMax * 2, rangeMax * 2, rangeMax * 2).stream()
|
||||
.filter(e -> e instanceof Player).collect(Collectors.toSet());
|
||||
|
||||
case ALL_ENTITIES:
|
||||
return rangeMax == Double.POSITIVE_INFINITY
|
||||
? location.getWorld().getEntities()
|
||||
: location.getWorld().getNearbyEntities(location, rangeMax * 2, rangeMax * 2, rangeMax * 2);
|
||||
|
||||
case SELF:
|
||||
return sender instanceof Entity ? Arrays.asList((Entity) sender) : Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@ -166,11 +181,11 @@ public class SelectorArguments {
|
||||
Stream<Entity> stream = list.stream()
|
||||
.filter(p -> rangeMin == 0 || p.getLocation().distance(location) > rangeMin)
|
||||
.filter(e -> entityType == null || e.getType() == entityType);
|
||||
|
||||
return stream.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public static enum SelectorType {
|
||||
|
||||
PLAYER, RANDOM_PLAYER, ALL_PLAYER, ALL_ENTITIES, SELF;
|
||||
|
||||
public static SelectorType getType(String str) {
|
||||
@ -188,6 +203,7 @@ public class SelectorArguments {
|
||||
return SELF;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import java.util.LinkedHashMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SimpleNestedCommand {
|
||||
|
||||
final AbstractCommand parent;
|
||||
final LinkedHashMap<String, AbstractCommand> children = new LinkedHashMap<>();
|
||||
|
||||
|
@ -16,7 +16,6 @@ import java.util.stream.Collectors;
|
||||
* @since 2019-08-28
|
||||
*/
|
||||
public class Comment {
|
||||
|
||||
final List<String> lines = new ArrayList();
|
||||
CommentStyle commentStyle = null;
|
||||
|
||||
@ -37,6 +36,7 @@ public class Comment {
|
||||
|
||||
public Comment(CommentStyle commentStyle, List<String> lines) {
|
||||
this.commentStyle = commentStyle;
|
||||
|
||||
if (lines != null) {
|
||||
lines.forEach(s -> this.lines.addAll(Arrays.asList(s.split("\n"))));
|
||||
}
|
||||
@ -61,22 +61,27 @@ public class Comment {
|
||||
|
||||
public static Comment loadComment(List<String> lines) {
|
||||
CommentStyle style = ConfigFormattingRules.parseStyle(lines);
|
||||
|
||||
int linePad = (style.drawBorder ? 1 : 0) + (style.drawSpace ? 1 : 0);
|
||||
int prefix = style.commentPrefix.length();
|
||||
int suffix = style.commentSuffix.length();
|
||||
|
||||
return new Comment(style, lines.subList(linePad, lines.size() - linePad).stream().map(s -> s.substring(prefix, s.length() - suffix).trim()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public void writeComment(Writer output, int offset, CommentStyle defaultStyle) throws IOException {
|
||||
CommentStyle style = commentStyle != null ? commentStyle : defaultStyle;
|
||||
int minSpacing = 0, borderSpacing = 0;
|
||||
|
||||
// first draw the top of the comment
|
||||
if (style.drawBorder) {
|
||||
// grab the longest line in the list of lines
|
||||
minSpacing = lines.stream().max((s1, s2) -> s1.length() - s2.length()).get().length();
|
||||
borderSpacing = minSpacing + style.commentPrefix.length() + style.commentSuffix.length();
|
||||
|
||||
// draw the first line
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + (new String(new char[borderSpacing + 2])).replace('\0', '#') + "\n");
|
||||
|
||||
if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ')
|
||||
+ "#" + style.spacePrefixTop
|
||||
@ -86,12 +91,14 @@ public class Comment {
|
||||
} else if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + "#\n");
|
||||
}
|
||||
|
||||
// then the actual comment lines
|
||||
for (String line : lines) {
|
||||
// todo? should we auto-wrap comment lines that are longer than 80 characters?
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + "#" + style.commentPrefix
|
||||
+ (minSpacing == 0 ? line : line + (new String(new char[minSpacing - line.length()])).replace('\0', ' ')) + style.commentSuffix + (style.drawBorder ? "#\n" : "\n"));
|
||||
}
|
||||
|
||||
// now draw the bottom of the comment border
|
||||
if (style.drawBorder) {
|
||||
if (style.drawSpace) {
|
||||
@ -100,6 +107,7 @@ public class Comment {
|
||||
+ (new String(new char[borderSpacing - style.spacePrefixBottom.length() - style.spaceSuffixBottom.length()])).replace('\0', style.spaceCharBottom)
|
||||
+ style.spaceSuffixBottom + "#\n");
|
||||
}
|
||||
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + (new String(new char[borderSpacing + 2])).replace('\0', '#') + "\n");
|
||||
} else if (style.drawSpace) {
|
||||
output.write((new String(new char[offset])).replace('\0', ' ') + "#\n");
|
||||
|
@ -50,7 +50,6 @@ import java.util.stream.Collectors;
|
||||
* @since 2019-08-28
|
||||
*/
|
||||
public class Config extends ConfigSection {
|
||||
|
||||
/*
|
||||
Serialization notes:
|
||||
// implements ConfigurationSerializable:
|
||||
@ -75,35 +74,43 @@ public class Config extends ConfigSection {
|
||||
Charset defaultCharset = StandardCharsets.UTF_8;
|
||||
SaveTask saveTask;
|
||||
Timer autosaveTimer;
|
||||
|
||||
////////////// Config settings ////////////////
|
||||
/**
|
||||
* save file whenever a change is made
|
||||
*/
|
||||
boolean autosave = false;
|
||||
|
||||
/**
|
||||
* time in seconds to start a save after a change is made
|
||||
*/
|
||||
int autosaveInterval = 60;
|
||||
|
||||
/**
|
||||
* remove nodes not defined in defaults
|
||||
*/
|
||||
boolean autoremove = false;
|
||||
|
||||
/**
|
||||
* load comments when loading the file
|
||||
*/
|
||||
boolean loadComments = true;
|
||||
|
||||
/**
|
||||
* Default comment applied to config nodes
|
||||
*/
|
||||
ConfigFormattingRules.CommentStyle defaultNodeCommentFormat = ConfigFormattingRules.CommentStyle.SIMPLE;
|
||||
|
||||
/**
|
||||
* Default comment applied to section nodes
|
||||
*/
|
||||
ConfigFormattingRules.CommentStyle defaultSectionCommentFormat = ConfigFormattingRules.CommentStyle.SPACED;
|
||||
|
||||
/**
|
||||
* Extra lines to put between root nodes
|
||||
*/
|
||||
int rootNodeSpacing = 1;
|
||||
|
||||
/**
|
||||
* Extra lines to put in front of comments. <br>
|
||||
* This is separate from rootNodeSpacing, if applicable.
|
||||
@ -113,6 +120,7 @@ public class Config extends ConfigSection {
|
||||
public Config() {
|
||||
this.plugin = null;
|
||||
this.file = null;
|
||||
|
||||
dirName = null;
|
||||
fileName = null;
|
||||
}
|
||||
@ -120,24 +128,28 @@ public class Config extends ConfigSection {
|
||||
public Config(@NotNull File file) {
|
||||
this.plugin = null;
|
||||
this.file = file.getAbsoluteFile();
|
||||
|
||||
dirName = null;
|
||||
fileName = null;
|
||||
}
|
||||
|
||||
public Config(@NotNull Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
dirName = null;
|
||||
fileName = null;
|
||||
}
|
||||
|
||||
public Config(@NotNull Plugin plugin, @NotNull String file) {
|
||||
this.plugin = plugin;
|
||||
|
||||
dirName = null;
|
||||
fileName = file;
|
||||
}
|
||||
|
||||
public Config(@NotNull Plugin plugin, @Nullable String directory, @NotNull String file) {
|
||||
this.plugin = plugin;
|
||||
|
||||
dirName = directory;
|
||||
fileName = file;
|
||||
}
|
||||
@ -156,6 +168,7 @@ public class Config extends ConfigSection {
|
||||
this.file = new File(plugin.getDataFolder(), fileName != null ? fileName : "config.yml");
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
@ -337,6 +350,7 @@ public class Config extends ConfigSection {
|
||||
} else {
|
||||
headerComment = new Comment(description);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -347,6 +361,7 @@ public class Config extends ConfigSection {
|
||||
} else {
|
||||
headerComment = new Comment(commentStyle, description);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -357,6 +372,7 @@ public class Config extends ConfigSection {
|
||||
} else {
|
||||
headerComment = new Comment(description);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -367,6 +383,7 @@ public class Config extends ConfigSection {
|
||||
} else {
|
||||
headerComment = new Comment(commentStyle, description);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -374,24 +391,27 @@ public class Config extends ConfigSection {
|
||||
public List<String> getHeader() {
|
||||
if (headerComment != null) {
|
||||
return headerComment.getLines();
|
||||
} else {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
public Config clearConfig(boolean clearDefaults) {
|
||||
root.values.clear();
|
||||
root.configComments.clear();
|
||||
|
||||
if (clearDefaults) {
|
||||
root.defaultComments.clear();
|
||||
root.defaults.clear();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Config clearDefaults() {
|
||||
root.defaultComments.clear();
|
||||
root.defaults.clear();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -404,17 +424,22 @@ public class Config extends ConfigSection {
|
||||
if (file.exists()) {
|
||||
try (BufferedInputStream stream = new BufferedInputStream(new FileInputStream(file))) {
|
||||
Charset charset = TextUtils.detectCharset(stream, StandardCharsets.UTF_8);
|
||||
|
||||
// upgrade charset if file was saved in a more complex format
|
||||
if (charset == StandardCharsets.UTF_16BE || charset == StandardCharsets.UTF_16LE) {
|
||||
defaultCharset = StandardCharsets.UTF_16;
|
||||
}
|
||||
|
||||
this.load(new InputStreamReader(stream, charset));
|
||||
|
||||
return true;
|
||||
} catch (IOException | InvalidConfigurationException ex) {
|
||||
(plugin != null ? plugin.getLogger() : Bukkit.getLogger()).log(Level.SEVERE, "Failed to load config file: " + file.getName(), ex);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -432,11 +457,13 @@ public class Config extends ConfigSection {
|
||||
builder.append(line).append('\n');
|
||||
}
|
||||
}
|
||||
|
||||
this.loadFromString(builder.toString());
|
||||
}
|
||||
|
||||
public void loadFromString(@NotNull String contents) throws InvalidConfigurationException {
|
||||
Map input;
|
||||
|
||||
try {
|
||||
input = (Map) this.yaml.load(contents);
|
||||
} catch (YAMLException e2) {
|
||||
@ -444,10 +471,12 @@ public class Config extends ConfigSection {
|
||||
} catch (ClassCastException e3) {
|
||||
throw new InvalidConfigurationException("Top level is not a Map.");
|
||||
}
|
||||
|
||||
if (input != null) {
|
||||
if (loadComments) {
|
||||
this.parseComments(contents, input);
|
||||
}
|
||||
|
||||
this.convertMapsToSections(input, this);
|
||||
}
|
||||
}
|
||||
@ -457,10 +486,12 @@ public class Config extends ConfigSection {
|
||||
for (Map.Entry<?, ?> entry : input.entrySet()) {
|
||||
String key = entry.getKey().toString();
|
||||
Object value = entry.getValue();
|
||||
|
||||
if (value instanceof Map) {
|
||||
this.convertMapsToSections((Map) value, section.createSection(key));
|
||||
continue;
|
||||
}
|
||||
|
||||
section.set(key, value);
|
||||
}
|
||||
}
|
||||
@ -477,6 +508,7 @@ public class Config extends ConfigSection {
|
||||
int index = 0;
|
||||
LinkedList<String> currentPath = new LinkedList();
|
||||
ArrayList<String> commentBlock = new ArrayList();
|
||||
|
||||
try {
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.isEmpty()) {
|
||||
@ -523,6 +555,7 @@ public class Config extends ConfigSection {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!commentBlock.isEmpty()) {
|
||||
footerComment = Comment.loadComment(commentBlock);
|
||||
commentBlock.clear();
|
||||
@ -534,6 +567,7 @@ public class Config extends ConfigSection {
|
||||
public void deleteNonDefaultSettings() {
|
||||
// Delete old config values (thread-safe)
|
||||
List<String> defaultKeys = Arrays.asList(defaults.keySet().toArray(new String[0]));
|
||||
|
||||
for (String key : values.keySet().toArray(new String[0])) {
|
||||
if (!defaultKeys.contains(key)) {
|
||||
values.remove(key);
|
||||
@ -558,9 +592,11 @@ public class Config extends ConfigSection {
|
||||
|
||||
public boolean saveChanges() {
|
||||
boolean saved = true;
|
||||
|
||||
if (changed || hasNewDefaults()) {
|
||||
saved = save();
|
||||
}
|
||||
|
||||
if (saveTask != null) {
|
||||
//Close Threads
|
||||
saveTask.cancel();
|
||||
@ -568,14 +604,19 @@ public class Config extends ConfigSection {
|
||||
saveTask = null;
|
||||
autosaveTimer = null;
|
||||
}
|
||||
|
||||
return saved;
|
||||
}
|
||||
|
||||
boolean hasNewDefaults() {
|
||||
if (file != null && !file.exists()) return true;
|
||||
|
||||
for (String def : defaults.keySet()) {
|
||||
if (!values.containsKey(def)) return true;
|
||||
if (!values.containsKey(def)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -587,6 +628,7 @@ public class Config extends ConfigSection {
|
||||
saveTask = null;
|
||||
autosaveTimer = null;
|
||||
}
|
||||
|
||||
return save(getFile());
|
||||
}
|
||||
|
||||
@ -597,15 +639,18 @@ public class Config extends ConfigSection {
|
||||
|
||||
public boolean save(@NotNull File file) {
|
||||
Validate.notNull(file, "File cannot be null");
|
||||
|
||||
if (file.getParentFile() != null && !file.getParentFile().exists()) {
|
||||
file.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
String data = this.saveToString();
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter((OutputStream) new FileOutputStream(file), defaultCharset);) {
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter((OutputStream) new FileOutputStream(file), defaultCharset)) {
|
||||
writer.write(data);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -615,28 +660,35 @@ public class Config extends ConfigSection {
|
||||
if (autoremove) {
|
||||
deleteNonDefaultSettings();
|
||||
}
|
||||
|
||||
yamlOptions.setIndent(indentation);
|
||||
yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
yamlOptions.setSplitLines(false);
|
||||
yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
|
||||
StringWriter str = new StringWriter();
|
||||
|
||||
if (headerComment != null) {
|
||||
headerComment.writeComment(str, 0, ConfigFormattingRules.CommentStyle.BLOCKED);
|
||||
str.write("\n"); // add one space after the header
|
||||
}
|
||||
|
||||
String dump = yaml.dump(this.getValues(false));
|
||||
if (!dump.equals(BLANK_CONFIG)) {
|
||||
writeComments(dump, str);
|
||||
}
|
||||
|
||||
if (footerComment != null) {
|
||||
str.write("\n");
|
||||
footerComment.writeComment(str, 0, ConfigFormattingRules.CommentStyle.BLOCKED);
|
||||
}
|
||||
|
||||
return str.toString();
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(Config.class.getName()).log(Level.SEVERE, "Error saving config", ex);
|
||||
delaySave();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -645,10 +697,12 @@ public class Config extends ConfigSection {
|
||||
protected void writeComments(String data, Writer out) throws IOException {
|
||||
// line-by-line apply line spacing formatting and comments per-node
|
||||
BufferedReader in = new BufferedReader(new StringReader(data));
|
||||
|
||||
String line;
|
||||
boolean insideScalar = false;
|
||||
boolean firstNode = true;
|
||||
int index = 0;
|
||||
|
||||
LinkedList<String> currentPath = new LinkedList();
|
||||
while ((line = in.readLine()) != null) {
|
||||
// ignore comments and empty lines (there shouldn't be any, but just in case)
|
||||
@ -667,6 +721,7 @@ public class Config extends ConfigSection {
|
||||
while (depth < currentPath.size()) {
|
||||
currentPath.removeLast();
|
||||
}
|
||||
|
||||
currentPath.add(m.group(2));
|
||||
String path = currentPath.stream().collect(Collectors.joining(String.valueOf(pathChar)));
|
||||
|
||||
@ -708,6 +763,7 @@ public class Config extends ConfigSection {
|
||||
// write it down!
|
||||
comment.writeComment(out, lineOffset, style);
|
||||
}
|
||||
|
||||
// ignore scalars
|
||||
index = lineOffset;
|
||||
if (m.group(3).trim().equals("|") || m.group(3).trim().equals(">")) {
|
||||
@ -727,11 +783,11 @@ public class Config extends ConfigSection {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
class SaveTask extends TimerTask {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
saveChanges();
|
||||
|
@ -14,11 +14,11 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ConfigFileConfigurationAdapter extends FileConfiguration {
|
||||
|
||||
final Config config;
|
||||
|
||||
public ConfigFileConfigurationAdapter(Config config) {
|
||||
super(config);
|
||||
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
|
@ -3,14 +3,12 @@ package com.songoda.core.configuration;
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigFormattingRules {
|
||||
|
||||
int spacesBetweenMainCategories;
|
||||
int spacesBetweenValues;
|
||||
CommentStyle rootCommentStyle = CommentStyle.BLOCKSPACED;
|
||||
CommentStyle mainCategoryCommentStyle = CommentStyle.SPACED;
|
||||
|
||||
public static enum CommentStyle {
|
||||
|
||||
/**
|
||||
* # Comment
|
||||
*/
|
||||
@ -71,14 +69,18 @@ public class ConfigFormattingRules {
|
||||
public static CommentStyle parseStyle(List<String> lines) {
|
||||
if (lines == null || lines.size() <= 2) {
|
||||
return CommentStyle.SIMPLE;
|
||||
} else if (lines.size() > 2 && lines.get(0).trim().equals("#") && lines.get(lines.size() - 1).trim().equals("#")) {
|
||||
}
|
||||
|
||||
if (lines.size() > 2 && lines.get(0).trim().equals("#") && lines.get(lines.size() - 1).trim().equals("#")) {
|
||||
return CommentStyle.SPACED;
|
||||
}
|
||||
|
||||
boolean hasBorders = lines.size() > 2 && lines.get(0).trim().matches("^##+$") && lines.get(lines.size() - 1).trim().matches("^##+$");
|
||||
if (!hasBorders) {
|
||||
// default return
|
||||
return CommentStyle.SIMPLE;
|
||||
}
|
||||
|
||||
// now need to figure out if this is blocked or not
|
||||
if (lines.size() > 4 && lines.get(1).trim().matches(("^#"
|
||||
+ CommentStyle.BLOCKSPACED.spacePrefixTop + CommentStyle.BLOCKSPACED.spaceCharTop + "+"
|
||||
@ -88,6 +90,7 @@ public class ConfigFormattingRules {
|
||||
+ CommentStyle.BLOCKSPACED.spaceSuffixTop + "#$").replace("|", "\\|"))) {
|
||||
return CommentStyle.BLOCKSPACED;
|
||||
}
|
||||
|
||||
return CommentStyle.BLOCKED;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigOptionsAdapter extends FileConfigurationOptions {
|
||||
|
||||
final ConfigSection config;
|
||||
|
||||
public ConfigOptionsAdapter(ConfigSection config) {
|
||||
@ -47,6 +46,7 @@ public class ConfigOptionsAdapter extends FileConfigurationOptions {
|
||||
} else {
|
||||
((Config) config.root).setHeader(value.split("\n"));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -56,6 +56,7 @@ public class ConfigOptionsAdapter extends FileConfigurationOptions {
|
||||
if (!value) {
|
||||
((Config) config.root).setHeader((List) null);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,6 @@ import java.util.stream.Collectors;
|
||||
* @since 2019-08-28
|
||||
*/
|
||||
public class ConfigSection extends MemoryConfiguration {
|
||||
|
||||
final String fullPath, nodeKey;
|
||||
final ConfigSection root;
|
||||
final ConfigSection parent;
|
||||
@ -47,6 +46,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
this.parent = null;
|
||||
isDefault = false;
|
||||
nodeKey = fullPath = "";
|
||||
|
||||
configComments = new HashMap();
|
||||
defaultComments = new HashMap();
|
||||
defaults = new LinkedHashMap();
|
||||
@ -85,8 +85,10 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
* @param pathChar character to use
|
||||
*/
|
||||
public void setPathSeparator(char pathChar) {
|
||||
if (!root.values.isEmpty() || !root.defaults.isEmpty())
|
||||
if (!root.values.isEmpty() || !root.defaults.isEmpty()) {
|
||||
throw new RuntimeException("Path change after config initialization");
|
||||
}
|
||||
|
||||
root.pathChar = pathChar;
|
||||
}
|
||||
|
||||
@ -122,9 +124,11 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
StringBuilder nodePath = new StringBuilder(fullPath);
|
||||
LinkedHashMap<String, Object> writeTo = useDefault ? root.defaults : root.values;
|
||||
ConfigSection travelNode = this;
|
||||
|
||||
synchronized (root.lock) {
|
||||
for (int i = 0; i < pathParts.length - 1; ++i) {
|
||||
final String node = (i != 0 ? nodePath.append(root.pathChar) : nodePath).append(pathParts[i]).toString();
|
||||
|
||||
if (!(writeTo.get(node) instanceof ConfigSection)) {
|
||||
writeTo.put(node, travelNode = new ConfigSection(root, travelNode, pathParts[i], useDefault));
|
||||
} else {
|
||||
@ -139,9 +143,11 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
public ConfigSection createDefaultSection(@NotNull String path) {
|
||||
createNodePath(path, true);
|
||||
ConfigSection section = new ConfigSection(root, this, path, true);
|
||||
|
||||
synchronized (root.lock) {
|
||||
root.defaults.put(fullPath + path, section);
|
||||
}
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
@ -149,10 +155,12 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
public ConfigSection createDefaultSection(@NotNull String path, String... comment) {
|
||||
createNodePath(path, true);
|
||||
ConfigSection section = new ConfigSection(root, this, path, true);
|
||||
|
||||
synchronized (root.lock) {
|
||||
root.defaults.put(fullPath + path, section);
|
||||
root.defaultComments.put(fullPath + path, new Comment(comment));
|
||||
}
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
@ -160,10 +168,12 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
public ConfigSection createDefaultSection(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
createNodePath(path, true);
|
||||
ConfigSection section = new ConfigSection(root, this, path, true);
|
||||
|
||||
synchronized (root.lock) {
|
||||
root.defaults.put(fullPath + path, section);
|
||||
root.defaultComments.put(fullPath + path, new Comment(commentStyle, comment));
|
||||
}
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
@ -186,6 +196,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
root.configComments.put(fullPath + path, comment);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -199,6 +210,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
synchronized (root.lock) {
|
||||
root.defaultComments.put(fullPath + path, new Comment(lines));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -212,6 +224,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
synchronized (root.lock) {
|
||||
root.defaultComments.put(fullPath + path, new Comment(commentStyle, lines));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -220,30 +233,36 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
synchronized (root.lock) {
|
||||
root.defaultComments.put(fullPath + path, comment);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Comment getComment(@NotNull String path) {
|
||||
Comment result = root.configComments.get(fullPath + path);
|
||||
|
||||
if (result == null) {
|
||||
result = root.defaultComments.get(fullPath + path);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getCommentString(@NotNull String path) {
|
||||
Comment result = root.configComments.get(fullPath + path);
|
||||
|
||||
if (result == null) {
|
||||
result = root.defaultComments.get(fullPath + path);
|
||||
}
|
||||
|
||||
return result != null ? result.toString() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addDefault(@NotNull String path, @Nullable Object value) {
|
||||
createNodePath(path, true);
|
||||
|
||||
synchronized (root.lock) {
|
||||
root.defaults.put(fullPath + path, value);
|
||||
}
|
||||
@ -264,6 +283,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
.filter(k -> k.startsWith(fullPath))
|
||||
.forEach(k -> root.defaults.remove(k));
|
||||
}
|
||||
|
||||
addDefaults(c);
|
||||
}
|
||||
|
||||
@ -287,6 +307,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
public Set<String> getKeys(boolean deep) {
|
||||
LinkedHashSet<String> result = new LinkedHashSet();
|
||||
int pathIndex = fullPath.lastIndexOf(root.pathChar);
|
||||
|
||||
if (deep) {
|
||||
result.addAll(root.defaults.keySet().stream()
|
||||
.filter(k -> k.startsWith(fullPath))
|
||||
@ -306,6 +327,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
.map(k -> !k.endsWith(String.valueOf(root.pathChar)) ? k.substring(pathIndex + 1) : k.substring(pathIndex + 1, k.length() - 1))
|
||||
.collect(Collectors.toCollection(LinkedHashSet::new)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -314,6 +336,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
public Map<String, Object> getValues(boolean deep) {
|
||||
LinkedHashMap<String, Object> result = new LinkedHashMap();
|
||||
int pathIndex = fullPath.lastIndexOf(root.pathChar);
|
||||
|
||||
if (deep) {
|
||||
result.putAll((Map<String, Object>) root.defaults.entrySet().stream()
|
||||
.filter(k -> k.getKey().startsWith(fullPath))
|
||||
@ -324,6 +347,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
throw new IllegalStateException();
|
||||
}, // never going to be merging keys
|
||||
LinkedHashMap::new)));
|
||||
|
||||
result.putAll((Map<String, Object>) root.values.entrySet().stream()
|
||||
.filter(k -> k.getKey().startsWith(fullPath))
|
||||
.collect(Collectors.toMap(
|
||||
@ -343,6 +367,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
throw new IllegalStateException();
|
||||
}, // never going to be merging keys
|
||||
LinkedHashMap::new)));
|
||||
|
||||
result.putAll((Map<String, Object>) root.values.entrySet().stream()
|
||||
.filter(k -> k.getKey().startsWith(fullPath) && k.getKey().lastIndexOf(root.pathChar) == pathIndex)
|
||||
.collect(Collectors.toMap(
|
||||
@ -353,20 +378,24 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
}, // never going to be merging keys
|
||||
LinkedHashMap::new)));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ConfigSection> getSections(String path) {
|
||||
ConfigSection rootSection = getConfigurationSection(path);
|
||||
|
||||
if (rootSection == null) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
ArrayList<ConfigSection> result = new ArrayList();
|
||||
rootSection.getKeys(false).stream()
|
||||
.map(key -> rootSection.get(key))
|
||||
.filter(object -> object != null && object instanceof ConfigSection)
|
||||
.forEachOrdered(object -> result.add((ConfigSection) object));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -392,8 +421,10 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
if (fullPath.isEmpty())
|
||||
if (fullPath.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String[] parts = fullPath.split(Pattern.quote(String.valueOf(root.pathChar)));
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
@ -412,9 +443,11 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
@Override
|
||||
public Object get(@NotNull String path) {
|
||||
Object result = root.values.get(fullPath + path);
|
||||
|
||||
if (result == null) {
|
||||
result = root.defaults.get(fullPath + path);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -422,6 +455,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
@Override
|
||||
public Object get(@NotNull String path, @Nullable Object def) {
|
||||
Object result = root.values.get(fullPath + path);
|
||||
|
||||
return result != null ? result : def;
|
||||
}
|
||||
|
||||
@ -429,7 +463,9 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
public void set(@NotNull String path, @Nullable Object value) {
|
||||
if (isDefault) {
|
||||
addDefault(path, value);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
createNodePath(path, false);
|
||||
Object last = null;
|
||||
synchronized (root.lock) {
|
||||
@ -439,6 +475,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
root.changed |= (last = root.values.remove(fullPath + path)) != null;
|
||||
}
|
||||
}
|
||||
|
||||
if (last != value && last != null && last instanceof ConfigSection) {
|
||||
// clean up orphaned nodes
|
||||
final String trim = fullPath + path + root.pathChar;
|
||||
@ -447,9 +484,9 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
.forEach(k -> root.values.remove(k));
|
||||
}
|
||||
}
|
||||
|
||||
onChange();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection set(@NotNull String path, @Nullable Object value, String... comment) {
|
||||
@ -510,11 +547,14 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
public ConfigSection createSection(@NotNull String path) {
|
||||
createNodePath(path, false);
|
||||
ConfigSection section = new ConfigSection(root, this, path, false);
|
||||
|
||||
synchronized (root.lock) {
|
||||
root.values.put(fullPath + path, section);
|
||||
}
|
||||
|
||||
root.changed = true;
|
||||
onChange();
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
@ -537,12 +577,15 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
public ConfigSection createSection(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> comment) {
|
||||
createNodePath(path, false);
|
||||
ConfigSection section = new ConfigSection(root, this, path, false);
|
||||
|
||||
synchronized (root.lock) {
|
||||
root.values.put(fullPath + path, section);
|
||||
}
|
||||
|
||||
setComment(path, commentStyle, comment);
|
||||
root.changed = true;
|
||||
onChange();
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
@ -551,18 +594,23 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
public ConfigSection createSection(@NotNull String path, Map<?, ?> map) {
|
||||
createNodePath(path, false);
|
||||
ConfigSection section = new ConfigSection(root, this, path, false);
|
||||
|
||||
synchronized (root.lock) {
|
||||
root.values.put(fullPath + path, section);
|
||||
}
|
||||
|
||||
for (Map.Entry<?, ?> entry : map.entrySet()) {
|
||||
if (entry.getValue() instanceof Map) {
|
||||
section.createSection(entry.getKey().toString(), (Map) entry.getValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
section.set(entry.getKey().toString(), entry.getValue());
|
||||
}
|
||||
|
||||
root.changed = true;
|
||||
onChange();
|
||||
|
||||
return section;
|
||||
}
|
||||
|
||||
@ -570,6 +618,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
@Override
|
||||
public String getString(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
|
||||
return result != null ? result.toString() : null;
|
||||
}
|
||||
|
||||
@ -577,64 +626,75 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
@Override
|
||||
public String getString(@NotNull String path, @Nullable String def) {
|
||||
Object result = get(path);
|
||||
|
||||
return result != null ? result.toString() : def;
|
||||
}
|
||||
|
||||
public char getChar(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
|
||||
return result != null && !result.toString().isEmpty() ? result.toString().charAt(0) : '\0';
|
||||
}
|
||||
|
||||
public char getChar(@NotNull String path, char def) {
|
||||
Object result = get(path);
|
||||
|
||||
return result != null && !result.toString().isEmpty() ? result.toString().charAt(0) : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof Number ? ((Number) result).intValue() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(@NotNull String path, int def) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof Number ? ((Number) result).intValue() : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof Boolean ? (Boolean) result : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(@NotNull String path, boolean def) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof Boolean ? (Boolean) result : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof Number ? ((Number) result).doubleValue() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(@NotNull String path, double def) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof Number ? ((Number) result).doubleValue() : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof Number ? ((Number) result).longValue() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(@NotNull String path, long def) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof Number ? ((Number) result).longValue() : def;
|
||||
}
|
||||
|
||||
@ -642,6 +702,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
@Override
|
||||
public List<?> getList(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof List ? (List) result : null;
|
||||
}
|
||||
|
||||
@ -649,20 +710,25 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
@Override
|
||||
public List<?> getList(@NotNull String path, @Nullable List<?> def) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof List ? (List) result : def;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompatibleMaterial getMaterial(@NotNull String path) {
|
||||
String val = getString(path);
|
||||
|
||||
CompatibleMaterial mat = val != null ? CompatibleMaterial.getMaterial(val) : null;
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompatibleMaterial getMaterial(@NotNull String path, @Nullable CompatibleMaterial def) {
|
||||
String val = getString(path);
|
||||
|
||||
CompatibleMaterial mat = val != null ? CompatibleMaterial.getMaterial(val) : null;
|
||||
|
||||
return mat != null ? mat : def;
|
||||
}
|
||||
|
||||
@ -670,6 +736,7 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
@Override
|
||||
public <T> T getObject(@NotNull String path, @NotNull Class<T> clazz) {
|
||||
Object result = get(path);
|
||||
|
||||
return result != null && clazz.isInstance(result) ? clazz.cast(result) : null;
|
||||
}
|
||||
|
||||
@ -677,18 +744,21 @@ public class ConfigSection extends MemoryConfiguration {
|
||||
@Override
|
||||
public <T> T getObject(@NotNull String path, @NotNull Class<T> clazz, @Nullable T def) {
|
||||
Object result = get(path);
|
||||
|
||||
return result != null && clazz.isInstance(result) ? clazz.cast(result) : def;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigSection getConfigurationSection(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof ConfigSection ? (ConfigSection) result : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConfigSection getOrCreateConfigurationSection(@NotNull String path) {
|
||||
Object result = get(path);
|
||||
|
||||
return result instanceof ConfigSection ? (ConfigSection) result : createSection(path);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ConfigSetting {
|
||||
|
||||
final Config config;
|
||||
final String key;
|
||||
|
||||
@ -21,12 +20,14 @@ public class ConfigSetting {
|
||||
public ConfigSetting(@NotNull Config config, @NotNull String key, @NotNull Object defaultValue, String... comment) {
|
||||
this.config = config;
|
||||
this.key = key;
|
||||
|
||||
config.setDefault(key, defaultValue, comment);
|
||||
}
|
||||
|
||||
public ConfigSetting(@NotNull Config config, @NotNull String key, @NotNull Object defaultValue, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
|
||||
this.config = config;
|
||||
this.key = key;
|
||||
|
||||
config.setDefault(key, defaultValue, commentStyle, comment);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ package com.songoda.core.configuration;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
public interface DataStoreObject<T> {
|
||||
|
||||
/**
|
||||
* @return a unique hashable instance of T to store this value under
|
||||
*/
|
||||
@ -16,8 +15,6 @@ public interface DataStoreObject<T> {
|
||||
|
||||
/**
|
||||
* Save this data to a ConfigurationSection
|
||||
*
|
||||
* @param sec
|
||||
*/
|
||||
public abstract void saveToSection(ConfigurationSection sec);
|
||||
|
||||
@ -28,8 +25,6 @@ public interface DataStoreObject<T> {
|
||||
|
||||
/**
|
||||
* Mark this data as needing a save or not
|
||||
*
|
||||
* @param isChanged
|
||||
*/
|
||||
public void setChanged(boolean isChanged);
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ import java.util.logging.Level;
|
||||
* @since 2019-09-06
|
||||
*/
|
||||
public class SimpleDataStore<T extends DataStoreObject> {
|
||||
|
||||
protected final Plugin plugin;
|
||||
protected final String filename, dirName;
|
||||
private final Function<ConfigurationSection, T> getFromSection;
|
||||
@ -63,6 +62,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
this.file = new File(plugin.getDataFolder(), filename != null ? filename : "data.yml");
|
||||
}
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
@ -99,10 +99,13 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
@Nullable
|
||||
public T remove(@NotNull Object key) {
|
||||
T temp;
|
||||
|
||||
synchronized (lock) {
|
||||
temp = data.remove(key);
|
||||
}
|
||||
|
||||
save();
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@ -119,11 +122,15 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T temp;
|
||||
|
||||
synchronized (lock) {
|
||||
temp = data.remove(value.getKey());
|
||||
}
|
||||
|
||||
save();
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@ -141,11 +148,15 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
T temp;
|
||||
|
||||
synchronized (lock) {
|
||||
temp = data.put(value.getKey(), value);
|
||||
}
|
||||
|
||||
save();
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@ -160,6 +171,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
for (int i = 0; i < value.length; ++i) {
|
||||
if (value[i] != null) {
|
||||
@ -167,6 +179,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
@ -181,6 +194,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
for (T v : value) {
|
||||
if (v != null) {
|
||||
@ -188,6 +202,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
@ -198,6 +213,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
if (!getFile().exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
YamlConfiguration f = new YamlConfiguration();
|
||||
f.options().pathSeparator('\0');
|
||||
@ -205,6 +221,7 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
|
||||
synchronized (lock) {
|
||||
data.clear();
|
||||
|
||||
f.getValues(false).entrySet().stream()
|
||||
.filter(d -> d.getValue() instanceof ConfigurationSection)
|
||||
.map(Map.Entry::getValue)
|
||||
@ -248,10 +265,13 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
saveTask = null;
|
||||
autosaveTimer = null;
|
||||
}
|
||||
|
||||
YamlConfiguration f = new YamlConfiguration();
|
||||
|
||||
synchronized (lock) {
|
||||
data.values().stream().forEach(e -> e.saveToSection(f.createSection(e.getConfigKey())));
|
||||
}
|
||||
|
||||
try {
|
||||
f.save(getFile());
|
||||
data.values().stream().forEach(e -> e.setChanged(false));
|
||||
@ -261,7 +281,6 @@ public class SimpleDataStore<T extends DataStoreObject> {
|
||||
}
|
||||
|
||||
class SaveTask extends TimerTask {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
flushSave();
|
||||
|
@ -32,7 +32,6 @@ import java.util.logging.Level;
|
||||
* @since 2019-08-31
|
||||
*/
|
||||
public class ConfigEditorGui extends SimplePagedGui {
|
||||
|
||||
final JavaPlugin plugin;
|
||||
final String file;
|
||||
final MemoryConfiguration config;
|
||||
@ -49,6 +48,7 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
|
||||
protected ConfigEditorGui(Player player, JavaPlugin plugin, Gui parent, String file, MemoryConfiguration config, ConfigurationSection node) {
|
||||
super(parent);
|
||||
|
||||
this.player = player;
|
||||
this.plugin = plugin;
|
||||
this.file = file;
|
||||
@ -65,7 +65,7 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
// if we have a ConfigSection, we can also grab comments
|
||||
try {
|
||||
configSection_getCommentString = node.getClass().getDeclaredMethod("getCommentString", String.class);
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
|
||||
// decorate header
|
||||
@ -80,9 +80,10 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
for (String key : node.getKeys(false)) {
|
||||
if (node.isConfigurationSection(key)) {
|
||||
sections.add(key);
|
||||
} else {
|
||||
settings.add(key);
|
||||
continue;
|
||||
}
|
||||
|
||||
settings.add(key);
|
||||
}
|
||||
|
||||
// next we need to display the config settings
|
||||
@ -95,11 +96,15 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
// now display individual settings
|
||||
for (final String settingKey : settings) {
|
||||
final Object val = node.get(settingKey);
|
||||
if (val == null) continue;
|
||||
else if (val instanceof Boolean) {
|
||||
if (val == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (val instanceof Boolean) {
|
||||
// toggle switch
|
||||
setButton(index, configItem(CompatibleMaterial.LEVER, ChatColor.YELLOW + settingKey, node, settingKey, String.valueOf((Boolean) val), "Click to toggle this setting"),
|
||||
(event) -> this.toggle(event.slot, settingKey));
|
||||
|
||||
if ((Boolean) val) {
|
||||
highlightItem(index);
|
||||
}
|
||||
@ -159,9 +164,9 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
}
|
||||
}));
|
||||
});
|
||||
} else {
|
||||
} /* else {
|
||||
// idk. should we display uneditable values?
|
||||
}
|
||||
} */
|
||||
|
||||
++index;
|
||||
}
|
||||
@ -173,9 +178,14 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
|
||||
protected void updateValue(int clickCell, String path) {
|
||||
ItemStack item = inventory.getItem(clickCell);
|
||||
if (item == null || item == AIR) return;
|
||||
|
||||
if (item == null || item == AIR) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
Object val = node.get(path);
|
||||
|
||||
if (meta != null && val != null) {
|
||||
String valStr;
|
||||
if (val instanceof List) {
|
||||
@ -183,6 +193,7 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
} else {
|
||||
valStr = val.toString();
|
||||
}
|
||||
|
||||
List<String> lore = meta.getLore();
|
||||
if (lore == null || lore.isEmpty()) {
|
||||
meta.setLore(Arrays.asList(valStr));
|
||||
@ -190,20 +201,24 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
lore.set(0, valStr);
|
||||
meta.setLore(lore);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
setItem(clickCell, item);
|
||||
}
|
||||
|
||||
edits = true;
|
||||
}
|
||||
|
||||
void toggle(int clickCell, String path) {
|
||||
boolean val = !node.getBoolean(path);
|
||||
node.set(path, val);
|
||||
|
||||
if (val) {
|
||||
setItem(clickCell, ItemUtils.addGlow(inventory.getItem(clickCell)));
|
||||
} else {
|
||||
setItem(clickCell, ItemUtils.removeGlow(inventory.getItem(clickCell)));
|
||||
}
|
||||
|
||||
updateValue(clickCell, path);
|
||||
}
|
||||
|
||||
@ -216,20 +231,24 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
} else if (node.isLong(path)) {
|
||||
node.set(path, Long.parseLong(input));
|
||||
}
|
||||
|
||||
updateValue(clickCell, path);
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (NumberFormatException ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setMaterial(int clickCell, String path, ItemStack item) {
|
||||
CompatibleMaterial mat = CompatibleMaterial.getMaterial(item);
|
||||
|
||||
if (mat == null) {
|
||||
node.set(path, CompatibleMaterial.STONE.name());
|
||||
} else {
|
||||
node.set(path, mat.name());
|
||||
}
|
||||
|
||||
updateValue(clickCell, path);
|
||||
}
|
||||
|
||||
@ -242,6 +261,7 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
if (!edits) {
|
||||
return;
|
||||
}
|
||||
|
||||
// could also check and call saveChanges()
|
||||
if (config instanceof FileConfiguration) {
|
||||
try {
|
||||
@ -257,13 +277,13 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
plugin.getLogger().log(Level.WARNING, "Unknown configuration type '" + config.getClass().getName() + "' - Please report this error!");
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.reloadConfig();
|
||||
player.sendMessage(ChatColor.GREEN + "Config " + file + " saved!");
|
||||
}
|
||||
|
||||
private boolean isNumber(Object value) {
|
||||
return value != null && (
|
||||
value instanceof Long
|
||||
return value != null && (value instanceof Long
|
||||
|| value instanceof Integer
|
||||
|| value instanceof Float
|
||||
|| value instanceof Double);
|
||||
@ -271,36 +291,45 @@ public class ConfigEditorGui extends SimplePagedGui {
|
||||
|
||||
private boolean isMaterial(Object value) {
|
||||
CompatibleMaterial m;
|
||||
|
||||
return value instanceof String && value.toString().equals(value.toString().toUpperCase())
|
||||
&& (m = CompatibleMaterial.getMaterial(value.toString())) != null && m.isValidItem();
|
||||
}
|
||||
|
||||
protected ItemStack configItem(CompatibleMaterial type, String name, ConfigurationSection node, String path, String def) {
|
||||
String[] info = null;
|
||||
|
||||
if (configSection_getCommentString != null) {
|
||||
try {
|
||||
Object comment = configSection_getCommentString.invoke(node, path);
|
||||
|
||||
if (comment != null) {
|
||||
info = comment.toString().split("\n");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
return GuiUtils.createButtonItem(type, name, info != null ? info : (def != null ? def.split("\n") : null));
|
||||
}
|
||||
|
||||
protected ItemStack configItem(CompatibleMaterial type, String name, ConfigurationSection node, String path, String value, String def) {
|
||||
if (value == null) value = "";
|
||||
if (value == null) {
|
||||
value = "";
|
||||
}
|
||||
|
||||
String[] info = null;
|
||||
|
||||
if (configSection_getCommentString != null) {
|
||||
try {
|
||||
Object comment = configSection_getCommentString.invoke(node, path);
|
||||
if (comment != null) {
|
||||
info = (value + "\n" + comment.toString()).split("\n");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
return GuiUtils.createButtonItem(type, name, info != null ? info : (def != null ? (value + "\n" + def).split("\n") : null));
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ import java.util.List;
|
||||
* @since 2019-08-31
|
||||
*/
|
||||
public class ConfigEditorListEditorGui extends SimplePagedGui {
|
||||
|
||||
final ConfigEditorGui current;
|
||||
|
||||
public boolean saveChanges = false;
|
||||
@ -25,6 +24,7 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
|
||||
|
||||
public ConfigEditorListEditorGui(ConfigEditorGui current, String key, List<String> val) {
|
||||
super(current);
|
||||
|
||||
this.current = current;
|
||||
this.blankItem = current.getDefaultItem();
|
||||
headerBackItem = footerBackItem = current.getHeaderBackItem();
|
||||
@ -59,6 +59,7 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
|
||||
|
||||
void redraw() {
|
||||
page = 1;
|
||||
|
||||
// clear old display
|
||||
if (inventory != null) {
|
||||
for (Integer i : cellItems.keySet().toArray(new Integer[0])) {
|
||||
@ -78,6 +79,7 @@ public class ConfigEditorListEditorGui extends SimplePagedGui {
|
||||
redraw();
|
||||
});
|
||||
}
|
||||
|
||||
// update display
|
||||
update();
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import java.util.Map;
|
||||
* @since 2019-08-31
|
||||
*/
|
||||
public class PluginConfigGui extends SimplePagedGui {
|
||||
|
||||
final JavaPlugin plugin;
|
||||
LinkedHashMap<String, MemoryConfiguration> configs = new LinkedHashMap();
|
||||
|
||||
@ -34,6 +33,7 @@ public class PluginConfigGui extends SimplePagedGui {
|
||||
|
||||
public PluginConfigGui(SongodaPlugin plugin, Gui parent) {
|
||||
super(parent);
|
||||
|
||||
this.plugin = plugin;
|
||||
|
||||
// collect list of plugins
|
||||
@ -44,6 +44,7 @@ public class PluginConfigGui extends SimplePagedGui {
|
||||
configs.put(cfg.getFile().getName(), cfg);
|
||||
}
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@ -76,6 +77,7 @@ public class PluginConfigGui extends SimplePagedGui {
|
||||
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
|
||||
// I guess not!
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
@ -12,13 +12,16 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class LocaleModule implements PluginInfoModule {
|
||||
|
||||
@Override
|
||||
public void run(PluginInfo plugin) {
|
||||
if (plugin.getJavaPlugin() == null || plugin.getSongodaId() <= 0) return;
|
||||
JSONObject json = plugin.getJson();
|
||||
if (plugin.getJavaPlugin() == null || plugin.getSongodaId() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject json = plugin.getJson();
|
||||
JSONArray files = (JSONArray) json.get("neededFiles");
|
||||
|
||||
for (Object o : files) {
|
||||
JSONObject file = (JSONObject) o;
|
||||
|
||||
@ -33,6 +36,7 @@ public class LocaleModule implements PluginInfoModule {
|
||||
|
||||
void downloadLocale(PluginInfo plugin, String link, String fileName) throws MalformedURLException, IOException {
|
||||
URL url = new URL(link);
|
||||
|
||||
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
|
||||
urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11");
|
||||
urlConnection.setRequestProperty("Accept", "*/*");
|
||||
|
@ -9,7 +9,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class PluginInfo {
|
||||
|
||||
protected final JavaPlugin javaPlugin;
|
||||
protected final int songodaId;
|
||||
protected final String coreIcon;
|
||||
@ -37,6 +36,7 @@ public final class PluginInfo {
|
||||
|
||||
public void setLatestVersion(String latestVersion) {
|
||||
this.latestVersion = latestVersion;
|
||||
|
||||
hasUpdate = latestVersion != null && !latestVersion.isEmpty() && !javaPlugin.getDescription().getVersion().equalsIgnoreCase(latestVersion);
|
||||
}
|
||||
|
||||
@ -82,6 +82,7 @@ public final class PluginInfo {
|
||||
|
||||
public PluginInfoModule addModule(PluginInfoModule module) {
|
||||
modules.add(module);
|
||||
|
||||
return module;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.songoda.core.core;
|
||||
|
||||
public interface PluginInfoModule {
|
||||
|
||||
void run(PluginInfo plugin);
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import org.bukkit.entity.Player;
|
||||
import java.util.List;
|
||||
|
||||
public class SongodaCoreCommand extends AbstractCommand {
|
||||
|
||||
protected GuiManager guiManager;
|
||||
|
||||
public SongodaCoreCommand() {
|
||||
@ -22,10 +21,12 @@ public class SongodaCoreCommand extends AbstractCommand {
|
||||
if (guiManager == null || guiManager.isClosed()) {
|
||||
guiManager = new GuiManager(SongodaCore.getHijackedPlugin());
|
||||
}
|
||||
|
||||
guiManager.showGUI((Player) sender, new SongodaCoreOverviewGUI());
|
||||
} else {
|
||||
sender.sendMessage("/songoda diag");
|
||||
}
|
||||
|
||||
return ReturnType.SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,6 @@ import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
|
||||
public class SongodaCoreDiagCommand extends AbstractCommand {
|
||||
|
||||
private final DecimalFormat format = new DecimalFormat("##.##");
|
||||
|
||||
private Object serverInstance;
|
||||
@ -27,36 +26,38 @@ public class SongodaCoreDiagCommand extends AbstractCommand {
|
||||
serverInstance = ClassMapping.MINECRAFT_SERVER.getClazz().getMethod("getServer").invoke(null);
|
||||
tpsField = serverInstance.getClass().getField("recentTps");
|
||||
} catch (NoSuchFieldException | SecurityException | IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
| InvocationTargetException | NoSuchMethodException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReturnType runCommand(CommandSender sender, String... args) {
|
||||
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage("Songoda Diagnostics Information");
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage("Plugins:");
|
||||
|
||||
for (PluginInfo plugin : SongodaCore.getPlugins()) {
|
||||
sender.sendMessage(plugin.getJavaPlugin().getName()
|
||||
+ " (" + plugin.getJavaPlugin().getDescription().getVersion() + " Core " + plugin.getCoreLibraryVersion() + ")");
|
||||
}
|
||||
|
||||
sender.sendMessage("");
|
||||
sender.sendMessage("Server Version: " + Bukkit.getVersion());
|
||||
sender.sendMessage("NMS: " + ServerProject.getServerVersion() + " " + ServerVersion.getServerVersionString());
|
||||
sender.sendMessage("Operating System: " + System.getProperty("os.name"));
|
||||
sender.sendMessage("Allocated Memory: " + format.format(Runtime.getRuntime().maxMemory() / (1024 * 1024)) + "Mb");
|
||||
sender.sendMessage("Online Players: " + Bukkit.getOnlinePlayers().size());
|
||||
|
||||
if (tpsField != null) {
|
||||
try {
|
||||
double[] tps = ((double[]) tpsField.get(serverInstance));
|
||||
|
||||
sender.sendMessage("TPS from last 1m, 5m, 15m: " + format.format(tps[0]) + ", "
|
||||
+ format.format(tps[1]) + ", " + format.format(tps[2]));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@ import org.bukkit.event.inventory.ClickType;
|
||||
import java.util.List;
|
||||
|
||||
final class SongodaCoreOverviewGUI extends Gui {
|
||||
|
||||
protected SongodaCoreOverviewGUI() {
|
||||
List<PluginInfo> plugins = SongodaCore.getPlugins();
|
||||
// could do pages, too, but don't think we'll have that many at a time for a while
|
||||
@ -23,6 +22,7 @@ final class SongodaCoreOverviewGUI extends Gui {
|
||||
|
||||
for (int i = 0; i < plugins.size(); i++) {
|
||||
final PluginInfo plugin = plugins.get(i);
|
||||
|
||||
if (plugin.hasUpdate()) {
|
||||
setButton(i, GuiUtils.createButtonItem(plugin.icon != null ? plugin.icon : CompatibleMaterial.STONE,
|
||||
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
|
||||
@ -38,7 +38,10 @@ final class SongodaCoreOverviewGUI extends Gui {
|
||||
ClickType.LEFT, (event) -> event.player.sendMessage(plugin.getMarketplaceLink()));
|
||||
setAction(i, ClickType.RIGHT, (event) -> event.manager.showGUI(event.player, new PluginConfigGui(plugin.getJavaPlugin(), event.gui)));
|
||||
highlightItem(i);
|
||||
} else {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
setButton(i, GuiUtils.createButtonItem(plugin.icon != null ? plugin.icon : CompatibleMaterial.STONE,
|
||||
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
|
||||
ChatColor.GRAY + "Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
|
||||
@ -50,5 +53,4 @@ final class SongodaCoreOverviewGUI extends Gui {
|
||||
setAction(i, ClickType.RIGHT, (event) -> event.manager.showGUI(event.player, new PluginConfigGui(plugin.getJavaPlugin(), event.gui)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,9 +64,10 @@ public class DataManagerAbstract {
|
||||
ResultSet result = statement.executeQuery(query);
|
||||
result.next();
|
||||
id = result.getInt(1);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SQLException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -150,17 +151,24 @@ public class DataManagerAbstract {
|
||||
*/
|
||||
@Deprecated
|
||||
public void queueAsync(Runnable runnable, String queueKey) {
|
||||
if (queueKey == null) return;
|
||||
if (queueKey == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<Runnable> queue = queues.computeIfAbsent(queueKey, t -> new LinkedList<>());
|
||||
queue.add(runnable);
|
||||
if (queue.size() == 1) runQueue(queueKey);
|
||||
|
||||
if (queue.size() == 1) {
|
||||
runQueue(queueKey);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void runQueue(String queueKey) {
|
||||
doQueue(queueKey, (s) -> {
|
||||
if (!queues.get(queueKey).isEmpty())
|
||||
if (!queues.get(queueKey).isEmpty()) {
|
||||
runQueue(queueKey);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public abstract class DataMigration {
|
||||
|
||||
private final int revision;
|
||||
|
||||
public DataMigration(int revision) {
|
||||
|
@ -8,7 +8,6 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DataMigrationManager {
|
||||
|
||||
private final List<DataMigration> migrations;
|
||||
private final DatabaseConnector databaseConnector;
|
||||
private final DataManagerAbstract dataManagerAbstract;
|
||||
@ -65,23 +64,23 @@ public class DataMigrationManager {
|
||||
|
||||
// Grab required migrations
|
||||
int finalCurrentMigration = currentMigration;
|
||||
List<DataMigration> requiredMigrations = this.migrations
|
||||
.stream()
|
||||
List<DataMigration> requiredMigrations = this.migrations.stream()
|
||||
.filter(x -> x.getRevision() > finalCurrentMigration)
|
||||
.sorted(Comparator.comparingInt(DataMigration::getRevision))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Nothing to migrate, abort
|
||||
if (requiredMigrations.isEmpty())
|
||||
if (requiredMigrations.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Migrate the data
|
||||
for (DataMigration dataMigration : requiredMigrations)
|
||||
for (DataMigration dataMigration : requiredMigrations) {
|
||||
dataMigration.migrate(connection, this.dataManagerAbstract.getTablePrefix());
|
||||
}
|
||||
|
||||
// Set the new current migration to be the highest migrated to
|
||||
currentMigration = requiredMigrations
|
||||
.stream()
|
||||
currentMigration = requiredMigrations.stream()
|
||||
.map(DataMigration::getRevision)
|
||||
.max(Integer::compareTo)
|
||||
.orElse(-1);
|
||||
|
@ -4,7 +4,6 @@ import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public interface DatabaseConnector {
|
||||
|
||||
/**
|
||||
* Checks if the connection to the database has been created
|
||||
*
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.songoda.core.database;
|
||||
|
||||
import com.songoda.core.SongodaCore;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@ -9,7 +8,6 @@ import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class MySQLConnector implements DatabaseConnector {
|
||||
|
||||
private final Plugin plugin;
|
||||
private HikariDataSource hikari;
|
||||
private boolean initializedSuccessfully;
|
||||
|
@ -8,7 +8,6 @@ import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class SQLiteConnector implements DatabaseConnector {
|
||||
|
||||
private final Plugin plugin;
|
||||
private final String connectionString;
|
||||
private Connection connection;
|
||||
@ -19,8 +18,8 @@ public class SQLiteConnector implements DatabaseConnector {
|
||||
|
||||
try {
|
||||
Class.forName("org.sqlite.JDBC"); // This is required to put here for Spigot 1.10 and below to force class load
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ import java.util.List;
|
||||
* @since 2019-09-15
|
||||
*/
|
||||
public class AnvilGui extends Gui {
|
||||
|
||||
final Player player;
|
||||
CustomAnvil anvil;
|
||||
List<String> endPrompt = null;
|
||||
@ -33,6 +32,7 @@ public class AnvilGui extends Gui {
|
||||
|
||||
public AnvilGui(Player player, Gui parent) {
|
||||
super(parent);
|
||||
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
@ -117,11 +117,14 @@ public class AnvilGui extends Gui {
|
||||
@Override
|
||||
protected void createInventory() {
|
||||
AnvilCore nms = NmsManager.getAnvil();
|
||||
|
||||
if (nms != null) {
|
||||
anvil = nms.createAnvil(player, new GuiHolder(guiManager, this));
|
||||
anvil.setCustomTitle(title);
|
||||
anvil.setLevelCost(0);
|
||||
|
||||
inventory = anvil.getInventory();
|
||||
|
||||
anvil.setOnChange(this::updateOutputPrompt);
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CustomizableGui extends Gui {
|
||||
|
||||
private static boolean showGuiKeys = false;
|
||||
private int activationCount = 0;
|
||||
|
||||
@ -41,7 +40,10 @@ public class CustomizableGui extends Gui {
|
||||
|
||||
if (!loadedGuis.containsKey(guiKey) || showGuiKeys) {
|
||||
File localeFolder = new File(plugin.getDataFolder(), "gui/");
|
||||
if (!localeFolder.exists()) localeFolder.mkdir();
|
||||
|
||||
if (!localeFolder.exists()) {
|
||||
localeFolder.mkdir();
|
||||
}
|
||||
|
||||
Config config = new Config(plugin, "gui/" + guiKey + ".yml");
|
||||
config.load();
|
||||
@ -59,6 +61,7 @@ public class CustomizableGui extends Gui {
|
||||
.setDefaultComment("overrides",
|
||||
"For information on how to apply overrides please visit",
|
||||
"https://wiki.songoda.com/Gui");
|
||||
|
||||
config.saveChanges();
|
||||
}
|
||||
|
||||
@ -66,6 +69,7 @@ public class CustomizableGui extends Gui {
|
||||
config.setDefault("disabled", Arrays.asList("example3", "example4", "example5"),
|
||||
"All keys on this list will be disabled. You can add any items key here",
|
||||
"if you no longer want that item in the GUI.");
|
||||
|
||||
config.saveChanges();
|
||||
}
|
||||
|
||||
@ -74,24 +78,28 @@ public class CustomizableGui extends Gui {
|
||||
this.customContent = customContent;
|
||||
|
||||
int rows = config.getInt("overrides.__ROWS__", -1);
|
||||
if (rows != -1)
|
||||
if (rows != -1) {
|
||||
customContent.setRows(rows);
|
||||
}
|
||||
|
||||
for (ConfigSection section : config.getSections("overrides")) {
|
||||
if (section.contains("row") || section.contains("col")
|
||||
|| section.contains("mirrorrow") || section.contains("mirrorcol")) {
|
||||
if (section.contains("mirrorrow") || section.contains("mirrorcol"))
|
||||
if (section.contains("row") ||
|
||||
section.contains("col") ||
|
||||
section.contains("mirrorrow") ||
|
||||
section.contains("mirrorcol")) {
|
||||
if (section.contains("mirrorrow") || section.contains("mirrorcol")) {
|
||||
customContent.addButton(section.getNodeKey(), section.getInt("row", -1),
|
||||
section.getInt("col", -1),
|
||||
section.getBoolean("mirrorrow", false),
|
||||
section.getBoolean("mirrorcol", false),
|
||||
section.isSet("item") ? CompatibleMaterial.getMaterial(section.getString("item")) : null);
|
||||
else
|
||||
} else {
|
||||
customContent.addButton(section.getNodeKey(), section.getInt("row", -1),
|
||||
section.getInt("col", -1),
|
||||
section.getString("title", null),
|
||||
section.isSet("lore") ? section.getStringList("lore") : null,
|
||||
section.isSet("item") ? CompatibleMaterial.getMaterial(section.getString("item")) : null);
|
||||
}
|
||||
} else {
|
||||
customContent.addButton(section.getNodeKey(), section.getString("position", "-1"),
|
||||
section.getString("title", null),
|
||||
@ -100,34 +108,42 @@ public class CustomizableGui extends Gui {
|
||||
}
|
||||
}
|
||||
|
||||
for (String disabled : config.getStringList("disabled"))
|
||||
for (String disabled : config.getStringList("disabled")) {
|
||||
customContent.disableButton(disabled);
|
||||
}
|
||||
} else {
|
||||
customContent = loadedGuis.get(guiKey);
|
||||
}
|
||||
|
||||
setPrivateDefaultAction(event -> {
|
||||
if (event.clickType == ClickType.SHIFT_RIGHT)
|
||||
if (event.clickType == ClickType.SHIFT_RIGHT) {
|
||||
activationCount++;
|
||||
}
|
||||
|
||||
if (activationCount >= 8 && event.player.hasPermission("songoda.admin")) {
|
||||
showGuiKeys = !showGuiKeys;
|
||||
activationCount = 0;
|
||||
|
||||
event.player.sendMessage("Gui keys " + (showGuiKeys ? "enabled" : "disabled") + ".");
|
||||
}
|
||||
});
|
||||
|
||||
if (customContent.isButtonCustomized("__DEFAULT__"))
|
||||
if (customContent.isButtonCustomized("__DEFAULT__")) {
|
||||
blankItem = GuiUtils.getBorderItem(customContent.getCustomizedButton("__DEFAULT__").item);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setRows(int rows) {
|
||||
int customRows = customContent.getRows();
|
||||
|
||||
return super.setRows(customRows != -1 ? customRows : rows);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Inventory generateInventory(@NotNull GuiManager manager) {
|
||||
applyCustomItems();
|
||||
|
||||
return super.generateInventory(manager);
|
||||
}
|
||||
|
||||
@ -137,322 +153,493 @@ public class CustomizableGui extends Gui {
|
||||
}
|
||||
|
||||
private void applyCustomItems() {
|
||||
for (CustomButton customButton : customContent.getCustomButtons().values())
|
||||
if (customButton instanceof MirrorFill)
|
||||
for (CustomButton customButton : customContent.getCustomButtons().values()) {
|
||||
if (customButton instanceof MirrorFill) {
|
||||
applyCustomItem(customButton);
|
||||
for (CustomButton customButton : customContent.getCustomButtons().values())
|
||||
if (!(customButton instanceof MirrorFill))
|
||||
}
|
||||
}
|
||||
|
||||
for (CustomButton customButton : customContent.getCustomButtons().values()) {
|
||||
if (!(customButton instanceof MirrorFill)) {
|
||||
applyCustomItem(customButton);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void applyCustomItem(CustomButton customButton) {
|
||||
if (customButton.row != -1 && customButton.col != -1)
|
||||
if (customButton instanceof MirrorFill)
|
||||
if (customButton.row != -1 && customButton.col != -1) {
|
||||
if (customButton instanceof MirrorFill) {
|
||||
mirrorFill(customButton.key, customButton.row, customButton.col,
|
||||
((MirrorFill) customButton).mirrorRow, ((MirrorFill) customButton).mirrorCol,
|
||||
customButton.createItem());
|
||||
else
|
||||
} else {
|
||||
setItem(customButton.key, customButton.row, customButton.col, customButton.createItem());
|
||||
else
|
||||
for (Integer position : customButton.positions)
|
||||
}
|
||||
} else {
|
||||
for (Integer position : customButton.positions) {
|
||||
setItem(customButton.key, position, customButton.createItem());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setDefaultItem(@Nullable ItemStack item) {
|
||||
if (item == null) return this;
|
||||
applyShowGuiKeys("__DEFAULT__", item);
|
||||
if (customContent.isButtonCustomized("__DEFAULT__"))
|
||||
if (item == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
applyShowGuiKeys("__DEFAULT__", item);
|
||||
|
||||
if (customContent.isButtonCustomized("__DEFAULT__")) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return super.setDefaultItem(item);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setItem(@NotNull String key, int cell, @Nullable ItemStack item) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
applyShowGuiKeys(key, item);
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
CustomButton btn = customContent.getCustomizedButton(key);
|
||||
cells = btn.applyPosition(cell);
|
||||
btn.applyItem(item);
|
||||
}
|
||||
for (int c : cells)
|
||||
|
||||
for (int c : cells) {
|
||||
setItem(c, item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setItem(@NotNull String key, int row, int col, @Nullable ItemStack item) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
return setItem(key, cell, item);
|
||||
}
|
||||
|
||||
public Gui mirrorFill(@NotNull String key, int row, int col, boolean mirrorRow, boolean mirrorCol, @NotNull ItemStack item) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
ItemStack newItem = item.clone();
|
||||
boolean isShow = applyShowGuiKeys(key, newItem);
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
CustomButton btn = customContent.getCustomizedButton(key);
|
||||
row = btn.applyPositionRow(row);
|
||||
col = btn.applyPositionCol(col);
|
||||
if (btn.applyItem(newItem))
|
||||
|
||||
if (btn.applyItem(newItem)) {
|
||||
isShow = true;
|
||||
}
|
||||
|
||||
if (btn instanceof MirrorFill) {
|
||||
MirrorFill mf = (MirrorFill) btn;
|
||||
mirrorRow = mf.mirrorRow;
|
||||
mirrorCol = mf.mirrorCol;
|
||||
}
|
||||
}
|
||||
|
||||
return mirrorFill(row, col, mirrorRow, mirrorCol, isShow ? newItem : item);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui highlightItem(@NotNull String key, int cell) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
highlightItem(c);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui highlightItem(@NotNull String key, int row, int col) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
return highlightItem(key, cell);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui removeHighlight(@NotNull String key, int cell) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
removeHighlight(c);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui removeHighlight(@NotNull String key, int row, int col) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
return removeHighlight(key, cell);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItemLore(@NotNull String key, int row, int col, @NotNull String... lore) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return updateItemLore(key, col + row * inventoryType.columns, lore);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItemLore(@NotNull String key, int cell, @NotNull String... lore) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
updateItemLore(c, lore);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItemLore(@NotNull String key, int row, int col, @Nullable List<String> lore) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return updateItemLore(key, col + row * inventoryType.columns, lore);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItemLore(@NotNull String key, int cell, @Nullable List<String> lore) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
updateItemLore(c, lore);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItemName(@NotNull String key, int row, int col, @Nullable String name) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return updateItemName(key, col + row * inventoryType.columns, name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItemName(@NotNull String key, int cell, @Nullable String name) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
updateItemName(c, name);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int row, int col, @Nullable String name, @NotNull String... lore) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return updateItem(key, col + row * inventoryType.columns, name, lore);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int cell, @Nullable String name, @NotNull String... lore) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return updateItem(key, cell, name, Arrays.asList(lore));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int row, int col, @Nullable String name, @Nullable List<String> lore) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return updateItem(key, col + row * inventoryType.columns, name, lore);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int cell, @NotNull String name, @Nullable List<String> lore) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
lore = applyShowGuiKeys(key, lore);
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
lore = applyShowGuiKeys(key, lore);
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
updateItem(c, name, lore);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int row, int col, @NotNull ItemStack itemTo, @Nullable String title, @NotNull String... lore) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return updateItem(key, col + row * inventoryType.columns, itemTo, title, lore);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int cell, @NotNull ItemStack itemTo, @Nullable String title, @NotNull String... lore) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
updateItem(c, itemTo, title, lore);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int row, int col, @NotNull CompatibleMaterial itemTo, @Nullable String title, @NotNull String... lore) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return updateItem(key, col + row * inventoryType.columns, itemTo, title, lore);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int cell, @NotNull CompatibleMaterial itemTo, @Nullable String title, @Nullable String... lore) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
updateItem(key, c, itemTo, title, lore);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int row, int col, @NotNull ItemStack itemTo, @Nullable String title, @Nullable List<String> lore) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return updateItem(key, col + row * inventoryType.columns, itemTo, title, lore);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int cell, @NotNull ItemStack itemTo, @Nullable String title, @Nullable List<String> lore) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
updateItem(key, c, itemTo, title, lore);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int row, int col, @NotNull CompatibleMaterial itemTo, @Nullable String title, @Nullable List<String> lore) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return updateItem(key, col + row * inventoryType.columns, itemTo, title, lore);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui updateItem(@NotNull String key, int cell, @NotNull CompatibleMaterial itemTo, @Nullable String title, @Nullable List<String> lore) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
updateItem(key, c, itemTo, title, lore);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setAction(@NotNull String key, int cell, @Nullable Clickable action) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
setConditional(key, cell, null, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setAction(@NotNull String key, int row, int col, @Nullable Clickable action) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
setConditional(key, col + row * inventoryType.columns, null, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setAction(@NotNull String key, int cell, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
setConditional(key, cell, type, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setAction(@NotNull String key, int row, int col, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
setConditional(key, col + row * inventoryType.columns, type, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui clearActions(@NotNull String key, int cell) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
clearActions(c);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui clearActions(@NotNull String key, int row, int col) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return clearActions(key, col + row * inventoryType.columns);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setButton(@NotNull String key, int cell, ItemStack item, @Nullable Clickable action) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
applyShowGuiKeys(key, item);
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
CustomButton btn = customContent.getCustomizedButton(key);
|
||||
cells = btn.applyPosition(cell);
|
||||
@ -463,59 +650,83 @@ public class CustomizableGui extends Gui {
|
||||
setItem(c, item);
|
||||
setConditional(c, null, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setButton(@NotNull String key, int row, int col, @Nullable ItemStack item, @Nullable Clickable action) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return setButton(key, col + row * inventoryType.columns, item, action);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setButton(@NotNull String key, int cell, @Nullable ItemStack item, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
applyShowGuiKeys(key, item);
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
CustomButton btn = customContent.getCustomizedButton(key);
|
||||
cells = btn.applyPosition(cell);
|
||||
btn.applyItem(item);
|
||||
}
|
||||
|
||||
for (int c : cells)
|
||||
for (int c : cells) {
|
||||
setButton(c, item, type, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setButton(@NotNull String key, int row, int col, @Nullable ItemStack item, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
if (customContent.isButtonDisabled(key)) return this;
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return setButton(key, col + row + inventoryType.columns, item, type, action);
|
||||
}
|
||||
|
||||
protected void setConditional(@NotNull String key, int cell, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
if (customContent.isButtonDisabled(key)) return;
|
||||
if (customContent.isButtonCustomized(key))
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
|
||||
for (int c : cells)
|
||||
if (customContent.isButtonDisabled(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (customContent.isButtonCustomized(key)) {
|
||||
cells = customContent.getCustomizedButton(key).applyPosition(cell);
|
||||
}
|
||||
|
||||
for (int c : cells) {
|
||||
setConditional(c, type, action);
|
||||
}
|
||||
}
|
||||
|
||||
public Gui setNextPage(ItemStack item) {
|
||||
applyShowGuiKeys("__NEXT__", item);
|
||||
if (customContent.isButtonCustomized("__NEXT__"))
|
||||
|
||||
if (customContent.isButtonCustomized("__NEXT__")) {
|
||||
customContent.getCustomizedButton("__NEXT__").applyItem(item);
|
||||
}
|
||||
|
||||
return super.setNextPage(item);
|
||||
}
|
||||
|
||||
public Gui setPrevPage(ItemStack item) {
|
||||
applyShowGuiKeys("__PREV__", item);
|
||||
if (customContent.isButtonCustomized("__PREV__"))
|
||||
|
||||
if (customContent.isButtonCustomized("__PREV__")) {
|
||||
customContent.getCustomizedButton("__PREV__").applyItem(item);
|
||||
}
|
||||
|
||||
return super.setPrevPage(item);
|
||||
}
|
||||
@ -523,66 +734,89 @@ public class CustomizableGui extends Gui {
|
||||
@NotNull
|
||||
public Gui setNextPage(int cell, @NotNull ItemStack item) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
|
||||
applyShowGuiKeys("__NEXT__", item);
|
||||
|
||||
if (customContent.isButtonCustomized("__NEXT__")) {
|
||||
CustomButton btn = customContent.getCustomizedButton("__NEXT__");
|
||||
cells = btn.applyPosition(cell);
|
||||
btn.applyItem(item);
|
||||
}
|
||||
|
||||
for (int c : cells)
|
||||
for (int c : cells) {
|
||||
return super.setNextPage(c, item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setNextPage(int row, int col, @NotNull ItemStack item) {
|
||||
applyShowGuiKeys("__NEXT__", item);
|
||||
|
||||
return setNextPage(col + row * inventoryType.columns, item);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setPrevPage(int cell, @NotNull ItemStack item) {
|
||||
List<Integer> cells = Collections.singletonList(cell);
|
||||
|
||||
applyShowGuiKeys("__PREV__", item);
|
||||
|
||||
if (customContent.isButtonCustomized("__PREV__")) {
|
||||
CustomButton btn = customContent.getCustomizedButton("__PREV__");
|
||||
cells = btn.applyPosition(cell);
|
||||
btn.applyItem(item);
|
||||
}
|
||||
|
||||
for (int c : cells)
|
||||
for (int c : cells) {
|
||||
super.setPrevPage(c, item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setPrevPage(int row, int col, @NotNull ItemStack item) {
|
||||
applyShowGuiKeys("__PREV__", item);
|
||||
|
||||
return setPrevPage(col + row * inventoryType.columns, item);
|
||||
}
|
||||
|
||||
private boolean applyShowGuiKeys(String key, ItemStack item) {
|
||||
if (!showGuiKeys) return false;
|
||||
if (!showGuiKeys) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null) meta = Bukkit.getItemFactory().getItemMeta(item.getType());
|
||||
if (meta == null) {
|
||||
meta = Bukkit.getItemFactory().getItemMeta(item.getType());
|
||||
}
|
||||
|
||||
List<String> lore = new ArrayList<>(Collections.singletonList("Key: " + key));
|
||||
if (meta.hasLore())
|
||||
|
||||
if (meta.hasLore()) {
|
||||
lore.addAll(meta.getLore());
|
||||
}
|
||||
|
||||
meta.setLore(lore);
|
||||
item.setItemMeta(meta);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<String> applyShowGuiKeys(String key, List<String> lore) {
|
||||
if (!showGuiKeys) return lore;
|
||||
if (!showGuiKeys) {
|
||||
return lore;
|
||||
}
|
||||
|
||||
List<String> newLore = new ArrayList<>(Collections.singletonList("Key: " + key));
|
||||
newLore.addAll(lore);
|
||||
|
||||
return newLore;
|
||||
}
|
||||
|
||||
private class CustomButton {
|
||||
|
||||
private final String key;
|
||||
|
||||
private final List<Integer> positions;
|
||||
@ -619,32 +853,47 @@ public class CustomizableGui extends Gui {
|
||||
}
|
||||
|
||||
public boolean applyItem(ItemStack item) {
|
||||
if (item == null) return false;
|
||||
if (item == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
item.setType(this.item.getMaterial());
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_13))
|
||||
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_13)) {
|
||||
item.setDurability(this.item.getData());
|
||||
}
|
||||
|
||||
applyMeta(item);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ItemStack createItem() {
|
||||
ItemStack item = this.item.getItem();
|
||||
applyMeta(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private void applyMeta(ItemStack item) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (title != null)
|
||||
|
||||
if (title != null) {
|
||||
meta.setDisplayName(TextUtils.formatText(title));
|
||||
if (lore != null)
|
||||
}
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(TextUtils.formatText(lore));
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
public List<Integer> applyPosition(int cell) {
|
||||
if (row != -1 && col != -1)
|
||||
if (row != -1 && col != -1) {
|
||||
return Collections.singletonList(col + row * inventoryType.columns);
|
||||
}
|
||||
|
||||
return positions == null ? Collections.singletonList(cell) : positions;
|
||||
}
|
||||
|
||||
@ -658,12 +907,12 @@ public class CustomizableGui extends Gui {
|
||||
}
|
||||
|
||||
private class MirrorFill extends CustomButton {
|
||||
|
||||
private final boolean mirrorRow;
|
||||
private final boolean mirrorCol;
|
||||
|
||||
public MirrorFill(String key, int row, int col, boolean mirrorRow, boolean mirrorCol, CompatibleMaterial item) {
|
||||
super(key, row, col, null, null, item);
|
||||
|
||||
this.mirrorRow = mirrorRow;
|
||||
this.mirrorCol = mirrorCol;
|
||||
}
|
||||
@ -678,7 +927,6 @@ public class CustomizableGui extends Gui {
|
||||
}
|
||||
|
||||
private class CustomContent {
|
||||
|
||||
private final String guiKey;
|
||||
private final Map<String, CustomButton> customizedButtons = new HashMap<>();
|
||||
private final Map<String, CustomButton> customButtons = new HashMap<>();
|
||||
@ -708,28 +956,38 @@ public class CustomizableGui extends Gui {
|
||||
|
||||
public void addButton(String key, String position, String title, List<String> lore, CompatibleMaterial item) {
|
||||
List<Integer> positions = Arrays.stream(position.split(","))
|
||||
.map(Integer::parseInt).collect(Collectors.toList());
|
||||
.map(Integer::parseInt)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
CustomButton customButton = new CustomButton(key, positions, title, lore, item);
|
||||
if (key.startsWith("custom_"))
|
||||
|
||||
if (key.startsWith("custom_")) {
|
||||
customButtons.put(key, customButton);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
customizedButtons.put(key, customButton);
|
||||
}
|
||||
|
||||
public void addButton(String key, int row, int col, String title, List<String> lore, CompatibleMaterial item) {
|
||||
CustomButton customButton = new CustomButton(key, row, col, title, lore, item);
|
||||
if (key.startsWith("custom_"))
|
||||
|
||||
if (key.startsWith("custom_")) {
|
||||
customButtons.put(key, customButton);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
customizedButtons.put(key, customButton);
|
||||
}
|
||||
|
||||
public void addButton(String key, int row, int col, boolean mirrorRow, boolean mirrorCol, CompatibleMaterial item) {
|
||||
MirrorFill mirrorFill = new MirrorFill(key, row, col, mirrorRow, mirrorCol, item);
|
||||
if (key.startsWith("custom_"))
|
||||
|
||||
if (key.startsWith("custom_")) {
|
||||
customButtons.put(key, mirrorFill);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
customizedButtons.put(key, mirrorFill);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@ import java.util.Map;
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
public class DoubleGui extends Gui {
|
||||
|
||||
protected boolean startStashed = true;
|
||||
protected int playerRows = 4;
|
||||
protected Map<Player, ItemStack[]> stash = new HashMap();
|
||||
@ -111,67 +110,83 @@ public class DoubleGui extends Gui {
|
||||
|
||||
public DoubleGui setPlayerUnlockedRange(int cellFirst, int cellLast, boolean open) {
|
||||
final int last = invOffset(cellLast);
|
||||
|
||||
for (int cell = invOffset(cellFirst); cell <= last; ++cell) {
|
||||
unlockedCells.put(cell, open);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui setPlayerUnlockedRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast) {
|
||||
final int last = invOffset(cellColLast + cellRowLast * 9);
|
||||
|
||||
for (int cell = invOffset(cellColFirst + cellRowFirst * 9); cell <= last; ++cell) {
|
||||
unlockedCells.put(cell, true);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui setPlayerUnlockedRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, boolean open) {
|
||||
final int last = invOffset(cellColLast + cellRowLast * 9);
|
||||
|
||||
for (int cell = invOffset(cellColFirst + cellRowFirst * 9); cell <= last; ++cell) {
|
||||
unlockedCells.put(cell, open);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui setPlayerItem(int cell, ItemStack item) {
|
||||
cellItems.put(invOffset(cell), item);
|
||||
|
||||
if (open && cell >= 0 && cell < 36) {
|
||||
cell = cell >= 27 ? cell - 27 : cell + 9;
|
||||
|
||||
for (HumanEntity e : inventory.getViewers()) {
|
||||
e.getInventory().setItem(cell, item);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui setPlayerItem(int row, int col, ItemStack item) {
|
||||
int cell = col + row * 9;
|
||||
cellItems.put(invOffset(cell), item);
|
||||
|
||||
if (open && cell >= 0 && cell < 36) {
|
||||
cell = cell >= 27 ? cell - 27 : cell + 9;
|
||||
|
||||
for (HumanEntity e : inventory.getViewers()) {
|
||||
e.getInventory().setItem(cell, item);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui highlightPlayerItem(int cell) {
|
||||
final int invCell = invOffset(cell);
|
||||
ItemStack item = cellItems.get(invCell);
|
||||
|
||||
if (item != null) {
|
||||
setPlayerItem(cell, ItemUtils.addGlow(item));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui highlightPlayerItem(int row, int col) {
|
||||
final int cell = col + row * 9;
|
||||
final int invCell = invOffset(cell);
|
||||
|
||||
ItemStack item = cellItems.get(invCell);
|
||||
if (item != null) {
|
||||
setPlayerItem(cell, ItemUtils.addGlow(item));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -199,14 +214,17 @@ public class DoubleGui extends Gui {
|
||||
for (int cell = cellFirst; cell <= cellLast; ++cell) {
|
||||
setConditional(invOffset(cell), null, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui setPlayerActionForRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, Clickable action) {
|
||||
final int last = cellColLast + cellRowLast * 9;
|
||||
|
||||
for (int cell = cellColFirst + cellRowFirst * 9; cell <= last; ++cell) {
|
||||
setConditional(invOffset(cell), null, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -214,14 +232,17 @@ public class DoubleGui extends Gui {
|
||||
for (int cell = cellFirst; cell <= cellLast; ++cell) {
|
||||
setConditional(invOffset(cell), type, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui setPlayerActionForRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, ClickType type, Clickable action) {
|
||||
final int last = cellColLast + cellRowLast * 9;
|
||||
|
||||
for (int cell = cellColFirst + cellRowFirst * 9; cell <= last; ++cell) {
|
||||
setConditional(invOffset(cell), type, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -233,32 +254,39 @@ public class DoubleGui extends Gui {
|
||||
public DoubleGui clearPlayerActions(int row, int col) {
|
||||
final int cell = invOffset(col + row * 9);
|
||||
conditionalButtons.remove(cell);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui setPlayerButton(int cell, ItemStack item, Clickable action) {
|
||||
setPlayerItem(cell, item);
|
||||
setConditional(invOffset(cell), null, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui setPlayerButton(int row, int col, ItemStack item, Clickable action) {
|
||||
final int cell = col + row * 9;
|
||||
|
||||
setPlayerItem(cell, item);
|
||||
setConditional(invOffset(cell), null, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui setPlayerButton(int cell, ItemStack item, ClickType type, Clickable action) {
|
||||
setItem(cell, item);
|
||||
setConditional(invOffset(cell), type, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public DoubleGui setPlayerButton(int row, int col, ItemStack item, ClickType type, Clickable action) {
|
||||
final int cell = col + row * 9;
|
||||
|
||||
setPlayerItem(cell, item);
|
||||
setConditional(invOffset(cell), type, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -267,6 +295,7 @@ public class DoubleGui extends Gui {
|
||||
final int cell = event.getSlot(), offsetCell = clickOffset(cell);
|
||||
Map<ClickType, Clickable> conditionals = conditionalButtons.get(offsetCell);
|
||||
Clickable button;
|
||||
|
||||
if (conditionals != null
|
||||
&& ((button = conditionals.get(event.getClick())) != null || (button = conditionals.get(null)) != null)) {
|
||||
button.onClick(new GuiClickEvent(manager, this, player, event, cell, true));
|
||||
@ -274,7 +303,9 @@ public class DoubleGui extends Gui {
|
||||
// no event for this button
|
||||
return false;
|
||||
}
|
||||
|
||||
event.setCancelled(!unlockedCells.entrySet().stream().anyMatch(e -> offsetCell == e.getKey() && e.getValue()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -283,6 +314,7 @@ public class DoubleGui extends Gui {
|
||||
if (dropper != null) {
|
||||
return dropper.onDrop(new GuiDropItemEvent(manager, this, player, event));
|
||||
}
|
||||
|
||||
// do not allow by default
|
||||
return false;
|
||||
}
|
||||
@ -290,8 +322,9 @@ public class DoubleGui extends Gui {
|
||||
@Override
|
||||
public void onOpen(GuiManager manager, Player player) {
|
||||
// replace the player's inventory
|
||||
if (startStashed)
|
||||
if (startStashed) {
|
||||
stashItems(player);
|
||||
}
|
||||
|
||||
// other opening functions
|
||||
super.onOpen(manager, player);
|
||||
|
@ -38,7 +38,6 @@ import java.util.stream.Collectors;
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
public class Gui {
|
||||
|
||||
protected Inventory inventory;
|
||||
protected String title;
|
||||
protected GuiType inventoryType = GuiType.STANDARD;
|
||||
@ -72,6 +71,7 @@ public class Gui {
|
||||
|
||||
public Gui(@NotNull GuiType type) {
|
||||
this.inventoryType = type;
|
||||
|
||||
switch (type) {
|
||||
case HOPPER:
|
||||
case DISPENSER:
|
||||
@ -79,6 +79,7 @@ public class Gui {
|
||||
break;
|
||||
default:
|
||||
this.rows = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,8 +98,11 @@ public class Gui {
|
||||
|
||||
@NotNull
|
||||
public List<Player> getPlayers() {
|
||||
return inventory == null ? Collections.EMPTY_LIST
|
||||
: inventory.getViewers().stream()
|
||||
if (inventory == null) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
return inventory.getViewers().stream()
|
||||
.filter(e -> e instanceof Player)
|
||||
.map(e -> (Player) e)
|
||||
.collect(Collectors.toList());
|
||||
@ -109,6 +113,7 @@ public class Gui {
|
||||
if (inventory != null && inventory.getViewers().isEmpty()) {
|
||||
open = false;
|
||||
}
|
||||
|
||||
return open;
|
||||
}
|
||||
|
||||
@ -154,6 +159,7 @@ public class Gui {
|
||||
public void exit() {
|
||||
allowClose = true;
|
||||
open = false;
|
||||
|
||||
inventory.getViewers().stream()
|
||||
.filter(e -> e instanceof Player)
|
||||
.map(e -> (Player) e)
|
||||
@ -166,6 +172,7 @@ public class Gui {
|
||||
*/
|
||||
public void close() {
|
||||
allowClose = true;
|
||||
|
||||
inventory.getViewers().stream()
|
||||
.filter(e -> e instanceof Player)
|
||||
.map(e -> (Player) e)
|
||||
@ -188,6 +195,7 @@ public class Gui {
|
||||
public Gui setUnlocked(int row, int col) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
unlockedCells.put(cell, true);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -196,6 +204,7 @@ public class Gui {
|
||||
for (int cell = cellFirst; cell <= cellLast; ++cell) {
|
||||
unlockedCells.put(cell, true);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -204,24 +213,29 @@ public class Gui {
|
||||
for (int cell = cellFirst; cell <= cellLast; ++cell) {
|
||||
unlockedCells.put(cell, open);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setUnlockedRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast) {
|
||||
final int last = cellColLast + cellRowLast * inventoryType.columns;
|
||||
|
||||
for (int cell = cellColFirst + cellRowFirst * inventoryType.columns; cell <= last; ++cell) {
|
||||
unlockedCells.put(cell, true);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setUnlockedRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, boolean open) {
|
||||
final int last = cellColLast + cellRowLast * inventoryType.columns;
|
||||
|
||||
for (int cell = cellColFirst + cellRowFirst * inventoryType.columns; cell <= last; ++cell) {
|
||||
unlockedCells.put(cell, open);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -235,26 +249,35 @@ public class Gui {
|
||||
public Gui setUnlocked(int row, int col, boolean open) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
unlockedCells.put(cell, open);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setTitle(String title) {
|
||||
if (title == null) title = "";
|
||||
if (title == null) {
|
||||
title = "";
|
||||
}
|
||||
|
||||
if (!title.equals(this.title)) {
|
||||
this.title = title;
|
||||
|
||||
if (inventory != null) {
|
||||
// update active inventory
|
||||
List<Player> toUpdate = getPlayers();
|
||||
boolean isAllowClose = allowClose;
|
||||
exit();
|
||||
|
||||
Inventory oldInv = inventory;
|
||||
createInventory();
|
||||
inventory.setContents(oldInv.getContents());
|
||||
|
||||
toUpdate.forEach(player -> player.openInventory(inventory));
|
||||
|
||||
allowClose = isAllowClose;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -270,7 +293,9 @@ public class Gui {
|
||||
break;
|
||||
default:
|
||||
this.rows = Math.max(1, Math.min(6, rows));
|
||||
break;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -302,24 +327,29 @@ public class Gui {
|
||||
if (inventory != null && unlockedCells.getOrDefault(cell, false)) {
|
||||
return inventory.getItem(cell);
|
||||
}
|
||||
|
||||
return cellItems.get(cell);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemStack getItem(int row, int col) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
if (inventory != null && unlockedCells.getOrDefault(cell, false)) {
|
||||
return inventory.getItem(cell);
|
||||
}
|
||||
|
||||
return cellItems.get(cell);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setItem(int cell, @Nullable ItemStack item) {
|
||||
cellItems.put(cell, item);
|
||||
|
||||
if (inventory != null && cell >= 0 && cell < inventory.getSize()) {
|
||||
inventory.setItem(cell, item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -332,36 +362,48 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui mirrorFill(int row, int col, boolean mirrorRow, boolean mirrorCol, ItemStack item) {
|
||||
setItem(row, col, item);
|
||||
if (mirrorRow)
|
||||
|
||||
if (mirrorRow) {
|
||||
setItem(rows - row - 1, col, item);
|
||||
if (mirrorCol)
|
||||
}
|
||||
|
||||
if (mirrorCol) {
|
||||
setItem(row, 8 - col, item);
|
||||
if (mirrorRow && mirrorCol)
|
||||
}
|
||||
|
||||
if (mirrorRow && mirrorCol) {
|
||||
setItem(rows - row - 1, 8 - col, item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui highlightItem(int cell) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, ItemUtils.addGlow(item));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui highlightItem(int row, int col) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
return highlightItem(cell);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui removeHighlight(int cell) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, ItemUtils.removeGlow(item));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -379,9 +421,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItemLore(int cell, @NotNull String... lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItemLore(item, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -393,9 +437,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItemLore(int cell, @Nullable List<String> lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItemLore(item, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -407,9 +453,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItemName(int cell, @Nullable String name) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItemName(item, name));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -431,9 +479,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItem(int cell, @NotNull String name, @Nullable List<String> lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItem(item, name, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -445,9 +495,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItem(int cell, @NotNull ItemStack itemTo, @Nullable String title, @NotNull String... lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItem(item, itemTo, title, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -459,9 +511,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItem(int cell, @NotNull CompatibleMaterial itemTo, @Nullable String title, @Nullable String... lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItem(item, itemTo, title, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -473,9 +527,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItem(int cell, @NotNull ItemStack itemTo, @Nullable String title, @Nullable List<String> lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItem(item, itemTo, title, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -487,9 +543,11 @@ public class Gui {
|
||||
@NotNull
|
||||
public Gui updateItem(int cell, @NotNull CompatibleMaterial itemTo, @Nullable String title, @Nullable List<String> lore) {
|
||||
ItemStack item = cellItems.get(cell);
|
||||
|
||||
if (item != null && item.getType() != Material.AIR) {
|
||||
setItem(cell, GuiUtils.updateItem(item, itemTo, title, lore));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -522,15 +580,18 @@ public class Gui {
|
||||
for (int cell = cellFirst; cell <= cellLast; ++cell) {
|
||||
setConditional(cell, null, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setActionForRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, @Nullable Clickable action) {
|
||||
final int last = cellColLast + cellRowLast * inventoryType.columns;
|
||||
|
||||
for (int cell = cellColFirst + cellRowFirst * inventoryType.columns; cell <= last; ++cell) {
|
||||
setConditional(cell, null, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -539,15 +600,18 @@ public class Gui {
|
||||
for (int cell = cellFirst; cell <= cellLast; ++cell) {
|
||||
setConditional(cell, type, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setActionForRange(int cellRowFirst, int cellColFirst, int cellRowLast, int cellColLast, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
final int last = cellColLast + cellRowLast * inventoryType.columns;
|
||||
|
||||
for (int cell = cellColFirst + cellRowFirst * inventoryType.columns; cell <= last; ++cell) {
|
||||
setConditional(cell, type, action);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -566,14 +630,17 @@ public class Gui {
|
||||
public Gui setButton(int cell, ItemStack item, @Nullable Clickable action) {
|
||||
setItem(cell, item);
|
||||
setConditional(cell, null, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setButton(int row, int col, @Nullable ItemStack item, @Nullable Clickable action) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
setItem(cell, item);
|
||||
setConditional(cell, null, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -581,14 +648,17 @@ public class Gui {
|
||||
public Gui setButton(int cell, @Nullable ItemStack item, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
setItem(cell, item);
|
||||
setConditional(cell, type, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Gui setButton(int row, int col, @Nullable ItemStack item, @Nullable ClickType type, @Nullable Clickable action) {
|
||||
final int cell = col + row * inventoryType.columns;
|
||||
|
||||
setItem(cell, item);
|
||||
setConditional(cell, type, action);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -632,8 +702,9 @@ public class Gui {
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
if (inventory != null)
|
||||
if (inventory != null) {
|
||||
inventory.clear();
|
||||
}
|
||||
|
||||
setActionForRange(0, 53, null);
|
||||
cellItems.clear();
|
||||
@ -645,9 +716,11 @@ public class Gui {
|
||||
nextPageItem = cellItems.get(cell);
|
||||
nextPageIndex = cell;
|
||||
nextPage = item;
|
||||
|
||||
if (page < pages) {
|
||||
setButton(nextPageIndex, nextPage, ClickType.LEFT, (event) -> this.nextPage());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -661,9 +734,11 @@ public class Gui {
|
||||
prevPageItem = cellItems.get(cell);
|
||||
prevPageIndex = cell;
|
||||
prevPage = item;
|
||||
|
||||
if (page > 1) {
|
||||
setButton(prevPageIndex, prevPage, ClickType.LEFT, (event) -> this.prevPage());
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -674,6 +749,7 @@ public class Gui {
|
||||
|
||||
public void setPages(int pages) {
|
||||
this.pages = Math.max(1, pages);
|
||||
|
||||
if (page > pages) {
|
||||
setPage(pages);
|
||||
}
|
||||
@ -682,8 +758,10 @@ public class Gui {
|
||||
public void setPage(int page) {
|
||||
int lastPage = this.page;
|
||||
this.page = Math.max(1, Math.min(pages, page));
|
||||
|
||||
if (pager != null && this.page != lastPage) {
|
||||
pager.onPageChange(new GuiPageEvent(this, guiManager, lastPage, page));
|
||||
|
||||
// page markers
|
||||
updatePageNavigation();
|
||||
}
|
||||
@ -692,8 +770,10 @@ public class Gui {
|
||||
public void changePage(int direction) {
|
||||
int lastPage = page;
|
||||
this.page = Math.max(1, Math.min(pages, page + direction));
|
||||
|
||||
if (pager != null && this.page != lastPage) {
|
||||
pager.onPageChange(new GuiPageEvent(this, guiManager, lastPage, page));
|
||||
|
||||
// page markers
|
||||
updatePageNavigation();
|
||||
}
|
||||
@ -703,6 +783,7 @@ public class Gui {
|
||||
if (page < pages) {
|
||||
int lastPage = page;
|
||||
++page;
|
||||
|
||||
// page switch events
|
||||
if (pager != null) {
|
||||
pager.onPageChange(new GuiPageEvent(this, guiManager, lastPage, page));
|
||||
@ -721,6 +802,7 @@ public class Gui {
|
||||
if (page > 1) {
|
||||
int lastPage = page;
|
||||
--page;
|
||||
|
||||
if (pager != null) {
|
||||
pager.onPageChange(new GuiPageEvent(this, guiManager, lastPage, page));
|
||||
|
||||
@ -743,6 +825,7 @@ public class Gui {
|
||||
this.clearActions(prevPageIndex);
|
||||
}
|
||||
}
|
||||
|
||||
if (nextPage != null) {
|
||||
if (pages > 1 && page != pages) {
|
||||
this.setButton(nextPageIndex, nextPage, ClickType.LEFT, (event) -> this.nextPage());
|
||||
@ -764,6 +847,7 @@ public class Gui {
|
||||
final int cells = rows * inventoryType.columns;
|
||||
|
||||
createInventory();
|
||||
|
||||
for (int i = 0; i < cells; ++i) {
|
||||
final ItemStack item = cellItems.get(i);
|
||||
inventory.setItem(i, item != null ? item : (unlockedCells.getOrDefault(i, false) ? AIR : blankItem));
|
||||
@ -784,6 +868,7 @@ public class Gui {
|
||||
default:
|
||||
inventory = new GuiHolder(guiManager, this).newInventory(rows * 9,
|
||||
title == null ? "" : trimTitle(title));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -793,8 +878,9 @@ public class Gui {
|
||||
}
|
||||
|
||||
public void update() {
|
||||
if (inventory == null)
|
||||
if (inventory == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int cells = rows * inventoryType.columns;
|
||||
for (int i = 0; i < cells; ++i) {
|
||||
@ -806,9 +892,12 @@ public class Gui {
|
||||
protected static String trimTitle(String title) {
|
||||
if (title == null) {
|
||||
return "";
|
||||
} else if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8) && title.length() > 32) {
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8) && title.length() > 32) {
|
||||
return title.charAt(30) == '\u00A7' ? title.substring(0, 30) : title.substring(0, 31);
|
||||
}
|
||||
|
||||
return title;
|
||||
}
|
||||
|
||||
@ -819,6 +908,7 @@ public class Gui {
|
||||
protected boolean onClick(@NotNull GuiManager manager, @NotNull Player player, @NotNull Inventory inventory, @NotNull InventoryClickEvent event) {
|
||||
final int cell = event.getSlot();
|
||||
Map<ClickType, Clickable> conditionals = conditionalButtons.get(cell);
|
||||
|
||||
Clickable button;
|
||||
if (conditionals != null
|
||||
&& ((button = conditionals.get(event.getClick())) != null || (button = conditionals.get(null)) != null)) {
|
||||
@ -829,12 +919,15 @@ public class Gui {
|
||||
// this is a default action, not a triggered action
|
||||
defaultClicker.onClick(new GuiClickEvent(manager, this, player, event, cell, true));
|
||||
}
|
||||
|
||||
if (privateDefaultClicker != null) {
|
||||
// this is a private default action, not a triggered action
|
||||
privateDefaultClicker.onClick(new GuiClickEvent(manager, this, player, event, cell, true));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -846,6 +939,7 @@ public class Gui {
|
||||
public void onOpen(@NotNull GuiManager manager, @NotNull Player player) {
|
||||
open = true;
|
||||
guiManager = manager;
|
||||
|
||||
if (opener != null) {
|
||||
opener.onOpen(new GuiOpenEvent(manager, this, player));
|
||||
}
|
||||
@ -856,10 +950,13 @@ public class Gui {
|
||||
manager.showGUI(player, this);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean showParent = open && parent != null;
|
||||
|
||||
if (closer != null) {
|
||||
closer.onClose(new GuiCloseEvent(manager, this, player));
|
||||
}
|
||||
|
||||
if (showParent) {
|
||||
manager.showGUI(player, parent);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ import org.bukkit.inventory.InventoryHolder;
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
class GuiHolder implements InventoryHolder {
|
||||
|
||||
final Gui gui;
|
||||
final GuiManager manager;
|
||||
|
||||
|
@ -33,7 +33,6 @@ import java.util.stream.Collectors;
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
public class GuiManager {
|
||||
|
||||
final Plugin plugin;
|
||||
final UUID uuid = UUID.randomUUID(); // manager tracking to fix weird bugs from lazy programming
|
||||
final GuiListener listener = new GuiListener(this);
|
||||
@ -55,6 +54,7 @@ public class GuiManager {
|
||||
*/
|
||||
public void init() {
|
||||
Bukkit.getPluginManager().registerEvents(listener, plugin);
|
||||
|
||||
initialized = true;
|
||||
shutdown = false;
|
||||
}
|
||||
@ -76,44 +76,54 @@ public class GuiManager {
|
||||
*/
|
||||
public void showGUI(Player player, Gui gui) {
|
||||
if (shutdown) {
|
||||
if (plugin.isEnabled()) {
|
||||
// recover if reloaded without calling init manually
|
||||
init();
|
||||
} else {
|
||||
if (!plugin.isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// recover if reloaded without calling init manually
|
||||
init();
|
||||
} else if (!initialized) {
|
||||
init();
|
||||
}
|
||||
|
||||
if (gui instanceof AnvilGui) {
|
||||
// bukkit throws a fit now if you try to set anvil stuff asynchronously
|
||||
Gui openInv = openInventories.get(player);
|
||||
|
||||
if (openInv != null) {
|
||||
openInv.open = false;
|
||||
}
|
||||
|
||||
gui.getOrCreateInventory(this);
|
||||
((AnvilGui) gui).open();
|
||||
gui.onOpen(this, player);
|
||||
|
||||
synchronized (lock) {
|
||||
openInventories.put(player, gui);
|
||||
}
|
||||
} else {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
Gui openInv = openInventories.get(player);
|
||||
|
||||
if (openInv != null) {
|
||||
openInv.open = false;
|
||||
}
|
||||
|
||||
Inventory inv = gui.getOrCreateInventory(this);
|
||||
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
player.openInventory(inv);
|
||||
gui.onOpen(this, player);
|
||||
|
||||
synchronized (lock) {
|
||||
openInventories.put(player, gui);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void showPopup(Player player, String message) {
|
||||
showPopup(player, message, CompatibleMaterial.NETHER_STAR, BackgroundType.ADVENTURE);
|
||||
@ -128,15 +138,21 @@ public class GuiManager {
|
||||
PopupMessage popup = new PopupMessage(plugin, icon, message, background);
|
||||
popup.add();
|
||||
popup.grant(player);
|
||||
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> {
|
||||
popup.revoke(player);
|
||||
popup.remove();
|
||||
}, 70);
|
||||
} else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
|
||||
player.sendTitle("", message, 10, 70, 10);
|
||||
} else {
|
||||
player.sendTitle("", message);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
|
||||
player.sendTitle("", message, 10, 70, 10);
|
||||
return;
|
||||
}
|
||||
|
||||
player.sendTitle("", message);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,12 +164,12 @@ public class GuiManager {
|
||||
.filter(e -> e.getKey().getOpenInventory().getTopInventory().getHolder() instanceof GuiHolder)
|
||||
.collect(Collectors.toList()) // to prevent concurrency exceptions
|
||||
.forEach(e -> e.getKey().closeInventory());
|
||||
|
||||
openInventories.clear();
|
||||
}
|
||||
}
|
||||
|
||||
protected static class GuiListener implements Listener {
|
||||
|
||||
final GuiManager manager;
|
||||
|
||||
public GuiListener(GuiManager manager) {
|
||||
@ -172,7 +188,9 @@ public class GuiManager {
|
||||
&& ((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
gui = ((GuiHolder) openInv.getHolder()).getGUI();
|
||||
|
||||
if (event.getRawSlots().stream().filter(slot -> gui.inventory.getSize() > slot).anyMatch(slot -> !gui.unlockedCells.getOrDefault(slot, false))) {
|
||||
if (event.getRawSlots().stream()
|
||||
.filter(slot -> gui.inventory.getSize() > slot)
|
||||
.anyMatch(slot -> !gui.unlockedCells.getOrDefault(slot, false))) {
|
||||
event.setCancelled(true);
|
||||
event.setResult(Result.DENY);
|
||||
}
|
||||
@ -189,8 +207,8 @@ public class GuiManager {
|
||||
final Player player = (Player) event.getWhoClicked();
|
||||
|
||||
Gui gui;
|
||||
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder
|
||||
&& ((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder &&
|
||||
((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
gui = ((GuiHolder) openInv.getHolder()).getGUI();
|
||||
|
||||
if (event.getClick() == ClickType.DOUBLE_CLICK) {
|
||||
@ -201,9 +219,11 @@ public class GuiManager {
|
||||
for (ItemStack it : gui.inventory.getContents()) {
|
||||
if (!gui.unlockedCells.getOrDefault(cell++, false) && clicked.isSimilar(it)) {
|
||||
event.setCancelled(true);
|
||||
|
||||
if (gui instanceof AnvilGui) {
|
||||
((AnvilGui) gui).anvil.update();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -215,9 +235,10 @@ public class GuiManager {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
} // did we click the gui or in the user's inventory?
|
||||
else if (event.getRawSlot() < gui.inventory.getSize()) {// or could use event.getClickedInventory() == gui.inventory
|
||||
else if (event.getRawSlot() < gui.inventory.getSize()) { // or could use event.getClickedInventory() == gui.inventory
|
||||
// allow event if this is not a GUI element
|
||||
event.setCancelled(gui.unlockedCells.entrySet().stream().noneMatch(e -> event.getSlot() == e.getKey() && e.getValue()));
|
||||
|
||||
// process button press
|
||||
if (gui.onClick(manager, player, openInv, event)) {
|
||||
player.playSound(player.getLocation(), gui.getDefaultSound().getSound(), 1F, 1F);
|
||||
@ -228,6 +249,7 @@ public class GuiManager {
|
||||
player.playSound(player.getLocation(), gui.getDefaultSound().getSound(), 1F, 1F);
|
||||
} else if (!gui.acceptsItems || event.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) {
|
||||
event.setCancelled(true);
|
||||
|
||||
if (gui instanceof AnvilGui) {
|
||||
((AnvilGui) gui).anvil.update();
|
||||
}
|
||||
@ -239,25 +261,31 @@ public class GuiManager {
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
void onCloseGUI(InventoryCloseEvent event) {
|
||||
Inventory openInv = event.getInventory();
|
||||
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder
|
||||
&& ((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
|
||||
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder &&
|
||||
((GuiHolder) openInv.getHolder()).manager.uuid.equals(manager.uuid)) {
|
||||
Gui gui = ((GuiHolder) openInv.getHolder()).getGUI();
|
||||
|
||||
if (gui instanceof AnvilGui) {
|
||||
gui.inventory.clear();
|
||||
gui.inventory = null;
|
||||
}
|
||||
|
||||
if (!gui.open) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Player player = (Player) event.getPlayer();
|
||||
if (!gui.allowDropItems) {
|
||||
player.setItemOnCursor(null);
|
||||
}
|
||||
|
||||
if (manager.shutdown) {
|
||||
gui.onClose(manager, player);
|
||||
} else {
|
||||
Bukkit.getScheduler().runTaskLater(manager.plugin, () -> gui.onClose(manager, player), 1);
|
||||
}
|
||||
|
||||
manager.openInventories.remove(player);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package com.songoda.core.gui;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
|
||||
public enum GuiType {
|
||||
|
||||
STANDARD(InventoryType.CHEST, 6, 9),
|
||||
DISPENSER(InventoryType.DISPENSER, 9, 3),
|
||||
HOPPER(InventoryType.HOPPER, 5, 1);
|
||||
|
@ -15,27 +15,32 @@ import java.util.List;
|
||||
* @since 2019-08-25
|
||||
*/
|
||||
public class GuiUtils {
|
||||
|
||||
public static ItemStack getBorderGlassItem() {
|
||||
ItemStack glass = CompatibleMaterial.LIGHT_BLUE_STAINED_GLASS_PANE.getItem();
|
||||
ItemMeta glassmeta = glass.getItemMeta();
|
||||
|
||||
glassmeta.setDisplayName(ChatColor.BLACK.toString());
|
||||
glass.setItemMeta(glassmeta);
|
||||
|
||||
return glass;
|
||||
}
|
||||
|
||||
public static ItemStack getBorderItem(ItemStack item) {
|
||||
ItemMeta glassmeta = item.getItemMeta();
|
||||
|
||||
glassmeta.setDisplayName(ChatColor.BLACK.toString());
|
||||
item.setItemMeta(glassmeta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack getBorderItem(CompatibleMaterial mat) {
|
||||
ItemStack item = mat.getItem();
|
||||
ItemMeta glassmeta = item.getItemMeta();
|
||||
|
||||
glassmeta.setDisplayName(ChatColor.BLACK.toString());
|
||||
item.setItemMeta(glassmeta);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -53,17 +58,21 @@ public class GuiUtils {
|
||||
public static List<String> getSafeLore(List<String> lines) {
|
||||
// fix newlines
|
||||
ArrayList<String> newLore = new ArrayList();
|
||||
|
||||
for (String l : lines) {
|
||||
for (String l2 : l.split("\n")) {
|
||||
if (l2.length() < 54) {
|
||||
newLore.add(l2);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
// try to shorten the string
|
||||
String shorterString = l2;
|
||||
ChatColor lastColor = null; // todo? probably should also track formatting codes..
|
||||
int line = 0;
|
||||
while (shorterString.length() > 50) {
|
||||
int breakingSpace = -1;
|
||||
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
if (shorterString.charAt(i) == ChatColor.COLOR_CHAR) {
|
||||
lastColor = ChatColor.getByChar(shorterString.charAt(++i));
|
||||
@ -71,6 +80,7 @@ public class GuiUtils {
|
||||
breakingSpace = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (breakingSpace == -1) {
|
||||
breakingSpace = Math.max(50, shorterString.length());
|
||||
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace) + "-");
|
||||
@ -79,171 +89,216 @@ public class GuiUtils {
|
||||
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace));
|
||||
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
|
||||
}
|
||||
|
||||
++line;
|
||||
}
|
||||
|
||||
if (!shorterString.isEmpty()) {
|
||||
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + " " + shorterString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newLore;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, String title, String... lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String title, String... lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
item.setAmount(amount);
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(ItemStack from, String title, String... lore) {
|
||||
ItemStack item = from.clone();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, String title, List<String> lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String title, List<String> lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
item.setAmount(amount);
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(ItemStack from, String title, List<String> lore) {
|
||||
ItemStack item = from.clone();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, String[] lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && lore.length != 0) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, int amount, String[] lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
item.setAmount(amount);
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && lore.length != 0) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(ItemStack from, String[] lore) {
|
||||
ItemStack item = from.clone();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && lore.length != 0) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(CompatibleMaterial mat, List<String> lore) {
|
||||
ItemStack item = mat.getItem();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && !lore.isEmpty()) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -251,81 +306,101 @@ public class GuiUtils {
|
||||
ItemStack item = mat.getItem();
|
||||
item.setAmount(amount);
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && !lore.isEmpty()) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack createButtonItem(ItemStack from, List<String> lore) {
|
||||
ItemStack item = from.clone();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && !lore.isEmpty()) {
|
||||
List<String> safe = getSafeLore(lore);
|
||||
|
||||
meta.setDisplayName(safe.get(0));
|
||||
meta.setLore(safe.subList(1, safe.size()));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack updateItem(ItemStack item, String title, String... lore) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack updateItemName(ItemStack item, String title) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack updateItemLore(ItemStack item, String... lore) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null && lore.length != 0) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack updateItemLore(ItemStack item, List<String> lore) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -333,16 +408,21 @@ public class GuiUtils {
|
||||
if (!matTo.matches(item)) {
|
||||
item = matTo.getItem();
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -350,30 +430,39 @@ public class GuiUtils {
|
||||
if (!CompatibleMaterial.getMaterial(item).matches(to)) {
|
||||
item = to.clone();
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public static ItemStack updateItem(ItemStack item, String title, List<String> lore) {
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -381,16 +470,21 @@ public class GuiUtils {
|
||||
if (!matTo.matches(item)) {
|
||||
item = matTo.getItem();
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -398,16 +492,21 @@ public class GuiUtils {
|
||||
if (!CompatibleMaterial.getMaterial(item).matches(to)) {
|
||||
item = to.clone();
|
||||
}
|
||||
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
|
||||
if (meta != null) {
|
||||
meta.setDisplayName(title);
|
||||
|
||||
if (lore != null) {
|
||||
meta.setLore(getSafeLore(lore));
|
||||
} else {
|
||||
meta.setLore(Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
item.setItemMeta(meta);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import java.util.UUID;
|
||||
* Calling this class on anything below 1.12 will cause ClassLoader Exceptions!
|
||||
*/
|
||||
class PopupMessage {
|
||||
|
||||
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
private static final HashSet<UUID> registeredMessages = new HashSet();
|
||||
|
||||
@ -52,14 +51,18 @@ class PopupMessage {
|
||||
private String getJSON() {
|
||||
JsonObject json = new JsonObject();
|
||||
JsonObject advDisplay = new JsonObject();
|
||||
|
||||
if (this.icon != null) {
|
||||
JsonObject displayIcon = new JsonObject();
|
||||
displayIcon.addProperty("item", "minecraft:" + this.icon.getMaterial().name().toLowerCase());
|
||||
|
||||
if (this.icon.usesData()) {
|
||||
displayIcon.addProperty("data", this.icon.getData());
|
||||
}
|
||||
|
||||
advDisplay.add("icon", displayIcon);
|
||||
}
|
||||
|
||||
advDisplay.add("title", gson.fromJson(ComponentSerializer.toString(this.title), JsonElement.class));
|
||||
advDisplay.addProperty("background", background.key);
|
||||
advDisplay.addProperty("description", "");
|
||||
@ -88,24 +91,27 @@ class PopupMessage {
|
||||
final Advancement adv = getAdvancement();
|
||||
final AdvancementProgress progress = pl.getAdvancementProgress(adv);
|
||||
|
||||
if (!progress.isDone())
|
||||
if (!progress.isDone()) {
|
||||
progress.getRemainingCriteria().forEach((crit) -> progress.awardCriteria(crit));
|
||||
}
|
||||
}
|
||||
|
||||
protected void revoke(final Player pl) {
|
||||
final Advancement adv = getAdvancement();
|
||||
final AdvancementProgress prog = pl.getAdvancementProgress(adv);
|
||||
|
||||
if (prog.isDone())
|
||||
if (prog.isDone()) {
|
||||
prog.getAwardedCriteria().forEach((crit) -> prog.revokeCriteria(crit));
|
||||
}
|
||||
}
|
||||
|
||||
protected void add() {
|
||||
if (!registeredMessages.contains(id)) {
|
||||
registeredMessages.add(id);
|
||||
|
||||
try {
|
||||
Bukkit.getUnsafe().loadAdvancement(key, getJSON());
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (IllegalArgumentException ex) {
|
||||
Bukkit.getLogger().warning("Failed to create popup advancement!");
|
||||
}
|
||||
}
|
||||
@ -126,6 +132,7 @@ class PopupMessage {
|
||||
TASK,
|
||||
CHALLENGE,
|
||||
GOAL;
|
||||
|
||||
final String id;
|
||||
|
||||
private FrameType() {
|
||||
@ -163,6 +170,7 @@ class PopupMessage {
|
||||
USED_ENDER_EYE,
|
||||
USED_TOTEM,
|
||||
VILLAGER_TRADE;
|
||||
|
||||
final ServerVersion minVersion;
|
||||
final String compatible;
|
||||
final String key;
|
||||
|
@ -20,7 +20,6 @@ import java.util.Map;
|
||||
* @since 2019-08-31
|
||||
*/
|
||||
public class SimplePagedGui extends Gui {
|
||||
|
||||
protected boolean useHeader;
|
||||
private int rowsPerPage, maxCellSlot;
|
||||
protected ItemStack headerBackItem;
|
||||
@ -75,6 +74,7 @@ public class SimplePagedGui extends Gui {
|
||||
if (open && cell >= 0 && cell < inventory.getSize()) {
|
||||
inventory.setItem(cell, item);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -102,6 +102,7 @@ public class SimplePagedGui extends Gui {
|
||||
final ItemStack item = cellItems.get(cellIndex++);
|
||||
inventory.setItem(i, item != null ? item : blankItem);
|
||||
}
|
||||
|
||||
// page markers
|
||||
updatePageNavigation();
|
||||
}
|
||||
@ -110,17 +111,22 @@ public class SimplePagedGui extends Gui {
|
||||
protected void updatePageNavigation() {
|
||||
if (page > 1) {
|
||||
inventory.setItem(inventory.getSize() - prevPageIndex, prevPage);
|
||||
|
||||
this.setButton(-prevPageIndex, prevPage, ClickType.LEFT, (event) -> this.prevPage());
|
||||
} else {
|
||||
inventory.setItem(inventory.getSize() - prevPageIndex, footerBackItem != null ? footerBackItem : blankItem);
|
||||
|
||||
this.setItem(-prevPageIndex, null);
|
||||
this.clearActions(-prevPageIndex);
|
||||
}
|
||||
|
||||
if (pages > 1 && page != pages) {
|
||||
inventory.setItem(inventory.getSize() - nextPageIndex, nextPage);
|
||||
|
||||
this.setButton(-nextPageIndex, nextPage, ClickType.LEFT, (event) -> this.nextPage());
|
||||
} else {
|
||||
inventory.setItem(inventory.getSize() - nextPageIndex, footerBackItem != null ? footerBackItem : blankItem);
|
||||
|
||||
this.setItem(-nextPageIndex, null);
|
||||
this.clearActions(-nextPageIndex);
|
||||
}
|
||||
@ -129,6 +135,7 @@ public class SimplePagedGui extends Gui {
|
||||
@Override
|
||||
protected Inventory generateInventory(GuiManager manager) {
|
||||
this.guiManager = manager;
|
||||
|
||||
// calculate pages here
|
||||
rowsPerPage = useHeader ? 4 : 5;
|
||||
maxCellSlot = (this.cellItems.isEmpty() ? 0 : this.cellItems.keySet().stream().max(Integer::compare).get()) + 1;
|
||||
@ -142,12 +149,14 @@ public class SimplePagedGui extends Gui {
|
||||
// populate and return the display inventory
|
||||
setPage(Math.min(page, pages));
|
||||
update();
|
||||
|
||||
return inventory;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createInventory() {
|
||||
final int cells = rows * 9;
|
||||
|
||||
inventory = Bukkit.getServer().createInventory(new GuiHolder(guiManager, this), cells,
|
||||
title == null ? "" : trimTitle(title));
|
||||
}
|
||||
@ -168,7 +177,9 @@ public class SimplePagedGui extends Gui {
|
||||
List<Player> toUpdate = null;
|
||||
if (Math.min(54, (maxRows + (useHeader ? 1 : 0)) * 9) != inventory.getSize()) {
|
||||
toUpdate = getPlayers();
|
||||
|
||||
this.setRows(maxRows + (useHeader ? 1 : 0));
|
||||
|
||||
createInventory();
|
||||
}
|
||||
|
||||
@ -176,6 +187,7 @@ public class SimplePagedGui extends Gui {
|
||||
if (useHeader) {
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
final ItemStack item = cellItems.get(i);
|
||||
|
||||
inventory.setItem(i, item != null ? item : (headerBackItem != null ? headerBackItem : blankItem));
|
||||
}
|
||||
}
|
||||
@ -220,6 +232,7 @@ public class SimplePagedGui extends Gui {
|
||||
// no event for this button
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -17,10 +17,13 @@ public class GuiClickEvent extends GuiEvent {
|
||||
|
||||
public GuiClickEvent(GuiManager manager, Gui gui, Player player, InventoryClickEvent event, int slot, boolean guiClicked) {
|
||||
super(manager, gui, player);
|
||||
|
||||
this.slot = slot;
|
||||
this.guiClicked = guiClicked;
|
||||
this.cursor = event.getCursor();
|
||||
|
||||
Inventory clicked = event.getClickedInventory();
|
||||
|
||||
this.clickedItem = clicked == null ? null : clicked.getItem(event.getSlot());
|
||||
this.clickType = event.getClick();
|
||||
this.event = event;
|
||||
|
@ -5,7 +5,6 @@ import com.songoda.core.gui.GuiManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class GuiCloseEvent extends GuiEvent {
|
||||
|
||||
public GuiCloseEvent(GuiManager manager, Gui gui, Player player) {
|
||||
super(manager, gui, player);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ public class GuiDropItemEvent extends GuiEvent {
|
||||
|
||||
public GuiDropItemEvent(GuiManager manager, Gui gui, Player player, InventoryClickEvent event) {
|
||||
super(manager, gui, player);
|
||||
|
||||
this.cursor = event.getCursor();
|
||||
this.clickType = event.getClick();
|
||||
this.event = event;
|
||||
|
@ -5,7 +5,6 @@ import com.songoda.core.gui.GuiManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class GuiEvent {
|
||||
|
||||
public final GuiManager manager;
|
||||
public final Gui gui;
|
||||
public final Player player;
|
||||
|
@ -5,7 +5,6 @@ import com.songoda.core.gui.GuiManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class GuiOpenEvent extends GuiEvent {
|
||||
|
||||
public GuiOpenEvent(GuiManager manager, Gui gui, Player player) {
|
||||
super(manager, gui, player);
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import com.songoda.core.gui.Gui;
|
||||
import com.songoda.core.gui.GuiManager;
|
||||
|
||||
public class GuiPageEvent {
|
||||
|
||||
final Gui gui;
|
||||
final GuiManager manager;
|
||||
final int lastPage;
|
||||
|
@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
|
||||
import com.songoda.core.gui.events.GuiClickEvent;
|
||||
|
||||
public interface Clickable {
|
||||
|
||||
void onClick(GuiClickEvent event);
|
||||
}
|
||||
|
@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
|
||||
import com.songoda.core.gui.events.GuiCloseEvent;
|
||||
|
||||
public interface Closable {
|
||||
|
||||
void onClose(GuiCloseEvent event);
|
||||
}
|
||||
|
@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
|
||||
import com.songoda.core.gui.events.GuiDropItemEvent;
|
||||
|
||||
public interface Droppable {
|
||||
|
||||
boolean onDrop(GuiDropItemEvent event);
|
||||
}
|
||||
|
@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
|
||||
import com.songoda.core.gui.events.GuiOpenEvent;
|
||||
|
||||
public interface Openable {
|
||||
|
||||
void onOpen(GuiOpenEvent event);
|
||||
}
|
||||
|
@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
|
||||
import com.songoda.core.gui.events.GuiPageEvent;
|
||||
|
||||
public interface Pagable {
|
||||
|
||||
void onPageChange(GuiPageEvent event);
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.OfflinePlayer;
|
||||
* A convenience class for static access to an Economy HookManager
|
||||
*/
|
||||
public class EconomyManager {
|
||||
|
||||
private static char currencySymbol = '$';
|
||||
|
||||
private static final HookManager<Economy> manager = new HookManager(Economy.class);
|
||||
@ -48,8 +47,6 @@ public class EconomyManager {
|
||||
/**
|
||||
* Get the name of the economy plugin being used. <br />
|
||||
* NOTE: using a default economy assumes that this library is shaded
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getName() {
|
||||
return manager.getName();
|
||||
@ -119,7 +116,7 @@ public class EconomyManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the curency symbl used in the #formatEconomy method.
|
||||
* Change the curency symbol used in the #formatEconomy method.
|
||||
*
|
||||
* @param currencySymbol the new symbol
|
||||
*/
|
||||
@ -128,7 +125,7 @@ public class EconomyManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the curency symbl used in the #formatEconomy method.
|
||||
* Change the curency symbol used in the #formatEconomy method.
|
||||
*
|
||||
* @param currencySymbol the new symbol
|
||||
*/
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.entity.LivingEntity;
|
||||
* A convenience class for static access to a Stacker HookManager
|
||||
*/
|
||||
public class EntityStackerManager {
|
||||
|
||||
private static final HookManager<Stacker> manager = new HookManager(Stacker.class);
|
||||
|
||||
/**
|
||||
@ -56,18 +55,20 @@ public class EntityStackerManager {
|
||||
}
|
||||
|
||||
public static void remove(LivingEntity entity, int amount) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().remove(entity, amount);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addOne(LivingEntity entity) {
|
||||
add(entity, 1);
|
||||
}
|
||||
|
||||
public static void add(LivingEntity entity, int amount) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().add(entity, amount);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getMinStackSize(EntityType type) {
|
||||
return manager.isEnabled() ? manager.getCurrentHook().getMinStackSize(type) : 1;
|
||||
|
@ -11,7 +11,6 @@ import java.util.Map;
|
||||
* A convenience class for static access to a Holograms HookManager
|
||||
*/
|
||||
public class HologramManager {
|
||||
|
||||
private static final HookManager<Holograms> manager = new HookManager(Holograms.class);
|
||||
|
||||
/**
|
||||
@ -49,37 +48,44 @@ public class HologramManager {
|
||||
}
|
||||
|
||||
public static void createHologram(Location location, String line) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().createHologram(location, line);
|
||||
}
|
||||
}
|
||||
|
||||
public static void createHologram(Location location, List<String> lines) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().createHologram(location, lines);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeHologram(Location location) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().removeHologram(location);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeAllHolograms() {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().removeAllHolograms();
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateHologram(Location location, String line) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().updateHologram(location, line);
|
||||
}
|
||||
}
|
||||
|
||||
public static void updateHologram(Location location, List<String> lines) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().updateHologram(location, lines);
|
||||
}
|
||||
}
|
||||
|
||||
public static void bulkUpdateHolograms(Map<Location, List<String>> holograms) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().bulkUpdateHolograms(holograms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,8 @@
|
||||
package com.songoda.core.hooks;
|
||||
|
||||
public interface Hook {
|
||||
|
||||
/**
|
||||
* Get the name of the plugin being used
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
abstract String getName();
|
||||
|
||||
|
@ -10,7 +10,6 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HookManager<T extends Hook> {
|
||||
|
||||
private final Class typeClass;
|
||||
private T defaultHook = null;
|
||||
private boolean loaded = false;
|
||||
@ -36,9 +35,11 @@ public class HookManager<T extends Hook> {
|
||||
if (!loaded) {
|
||||
registeredHooks.putAll(PluginHook.loadHooks(typeClass, hookingPlugin).entrySet().stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, e -> (T) e.getValue())));
|
||||
|
||||
if (!registeredHooks.isEmpty()) {
|
||||
defaultHook = (T) registeredHooks.values().iterator().next();
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
}
|
||||
}
|
||||
@ -66,8 +67,10 @@ public class HookManager<T extends Hook> {
|
||||
T hook = getHook(name);
|
||||
if (hook != null) {
|
||||
defaultHook = hook;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -84,8 +87,10 @@ public class HookManager<T extends Hook> {
|
||||
T hook = getHook(plugin);
|
||||
if (hook != null) {
|
||||
defaultHook = hook;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -97,8 +102,10 @@ public class HookManager<T extends Hook> {
|
||||
* @return returns null if plugin is not enabled
|
||||
*/
|
||||
public T getHook(String name) {
|
||||
if (name == null)
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String plugin = name.trim();
|
||||
return (T) registeredHooks.get(registeredHooks.keySet().stream()
|
||||
.filter(type -> type.plugin.equalsIgnoreCase(plugin))
|
||||
|
@ -12,7 +12,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class JobsHook {
|
||||
|
||||
static boolean canHook;
|
||||
|
||||
static {
|
||||
@ -20,7 +19,7 @@ public class JobsHook {
|
||||
// if this class exists, we're good to use Jobs classes
|
||||
Class.forName("com.gamingmesh.jobs.Jobs");
|
||||
canHook = true;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +27,7 @@ public class JobsHook {
|
||||
if (canHook) {
|
||||
return JobsPlayerHandler.loadPlayer(player);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -39,35 +39,43 @@ public class JobsHook {
|
||||
if (canHook) {
|
||||
return JobsHandler.getJobs();
|
||||
}
|
||||
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
public static double getBoostExp(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getBoostExp(job);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static double getBoostMoney(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getBoostMoney(job);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static double getBoostPoints(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getBoostPoints(job);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static void promoteJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.promoteJob(job);
|
||||
}
|
||||
@ -75,6 +83,7 @@ public class JobsHook {
|
||||
|
||||
public static void promoteJob(Player player, String job, int levels) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.promoteJob(job, levels);
|
||||
}
|
||||
@ -82,6 +91,7 @@ public class JobsHook {
|
||||
|
||||
public static void demoteJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.demoteJob(job);
|
||||
}
|
||||
@ -89,6 +99,7 @@ public class JobsHook {
|
||||
|
||||
public static void demoteJob(Player player, String job, int levels) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.demoteJob(job, levels);
|
||||
}
|
||||
@ -96,6 +107,7 @@ public class JobsHook {
|
||||
|
||||
public static void joinJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.joinJob(job);
|
||||
}
|
||||
@ -103,6 +115,7 @@ public class JobsHook {
|
||||
|
||||
public static void leaveAllJobs(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.leaveAllJobs();
|
||||
}
|
||||
@ -110,6 +123,7 @@ public class JobsHook {
|
||||
|
||||
public static void leaveJob(Player player, String job) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.leaveJob(job);
|
||||
}
|
||||
@ -117,38 +131,47 @@ public class JobsHook {
|
||||
|
||||
public static int getTotalLevels(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getTotalLevels();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int getMaxBrewingStandsAllowed(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getMaxBrewingStandsAllowed();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int getMaxFurnacesAllowed(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getMaxFurnacesAllowed();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static List<String> getJobs(Player player) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
return jPlayer.getJobs();
|
||||
}
|
||||
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
public static void eatItem(Player player, ItemStack item) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.eatItem(item);
|
||||
}
|
||||
@ -156,6 +179,7 @@ public class JobsHook {
|
||||
|
||||
public static void breakBlock(Player player, Block block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.breakBlock(block);
|
||||
}
|
||||
@ -163,6 +187,7 @@ public class JobsHook {
|
||||
|
||||
public static void tntBreakBlock(Player player, Block block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.tntBreakBlock(block);
|
||||
}
|
||||
@ -170,6 +195,7 @@ public class JobsHook {
|
||||
|
||||
public static void placeBlock(Player player, Block block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.placeBlock(block);
|
||||
}
|
||||
@ -177,6 +203,7 @@ public class JobsHook {
|
||||
|
||||
public static void placeEntity(Player player, Entity block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.placeEntity(block);
|
||||
}
|
||||
@ -184,6 +211,7 @@ public class JobsHook {
|
||||
|
||||
public static void breakEntity(Player player, Entity block) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.breakEntity(block);
|
||||
}
|
||||
@ -191,6 +219,7 @@ public class JobsHook {
|
||||
|
||||
public static void breedEntity(Player player, LivingEntity entity) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.breedEntity(entity);
|
||||
}
|
||||
@ -198,6 +227,7 @@ public class JobsHook {
|
||||
|
||||
public static void killEntity(Player player, LivingEntity entity) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.killEntity(entity);
|
||||
}
|
||||
@ -205,6 +235,7 @@ public class JobsHook {
|
||||
|
||||
public static void tameEntity(Player player, LivingEntity entity) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.tameEntity(entity);
|
||||
}
|
||||
@ -212,6 +243,7 @@ public class JobsHook {
|
||||
|
||||
public static void catchFish(Player player, ItemStack items) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.catchFish(items);
|
||||
}
|
||||
@ -219,6 +251,7 @@ public class JobsHook {
|
||||
|
||||
public static void killEntity(Player player, LivingEntity entity, Entity damageSource) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.killEntity(entity, damageSource);
|
||||
}
|
||||
@ -226,6 +259,7 @@ public class JobsHook {
|
||||
|
||||
public static void itemEnchanted(Player player, ItemStack resultStack) {
|
||||
JobsPlayerHandler jPlayer = getPlayer(player);
|
||||
|
||||
if (jPlayer != null) {
|
||||
jPlayer.itemEnchanted(resultStack);
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import org.bukkit.block.Block;
|
||||
* A convenience class for static access to a Log HookManager
|
||||
*/
|
||||
public class LogManager {
|
||||
|
||||
private static final HookManager<Log> manager = new HookManager(Log.class);
|
||||
|
||||
/**
|
||||
@ -47,8 +46,6 @@ public class LogManager {
|
||||
/**
|
||||
* Get the name of the log plugin being used. <br />
|
||||
* NOTE: using a default log assumes that this library is shaded
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getName() {
|
||||
return manager.getName();
|
||||
@ -62,9 +59,10 @@ public class LogManager {
|
||||
* @param block the block that is placed
|
||||
*/
|
||||
public static void logPlacement(OfflinePlayer player, Block block) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().logPlacement(player, block);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the removal of a block. <br />
|
||||
@ -73,9 +71,10 @@ public class LogManager {
|
||||
* @param player player to commit actionremvedplaced
|
||||
*/
|
||||
public static void logRemoval(OfflinePlayer player, Block block) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().logRemoval(player, block);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a player interaction. <br />
|
||||
@ -85,7 +84,8 @@ public class LogManager {
|
||||
* @param location the location that is interacted with
|
||||
*/
|
||||
public static void logInteraction(OfflinePlayer player, Location location) {
|
||||
if (manager.isEnabled())
|
||||
if (manager.isEnabled()) {
|
||||
manager.getCurrentHook().logInteraction(player, location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.entity.Player;
|
||||
import java.util.Collection;
|
||||
|
||||
public class McMMOHook {
|
||||
|
||||
static boolean canHook = false;
|
||||
|
||||
static {
|
||||
@ -16,7 +15,7 @@ public class McMMOHook {
|
||||
// if this class exists, we're good to use McMMO
|
||||
Class.forName("com.gmail.nossr50.api.AbilityAPI");
|
||||
canHook = true;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,6 @@ import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class PluginHook<T extends Class> {
|
||||
|
||||
public static final PluginHook ECO_VAULT = new PluginHook(Economy.class, "Vault", VaultEconomy.class);
|
||||
public static final PluginHook ECO_PLAYER_POINTS = new PluginHook(Economy.class, "PlayerPoints", PlayerPointsEconomy.class);
|
||||
public static final PluginHook ECO_RESERVE = new PluginHook(Economy.class, "Reserve", ReserveEconomy.class);
|
||||
@ -65,13 +64,17 @@ public final class PluginHook<T extends Class> {
|
||||
if (!Hook.class.isAssignableFrom(handler)) {
|
||||
throw new RuntimeException("Tried to register a non-Hook plugin hook! " + pluginName + " -> " + handler.getName());
|
||||
}
|
||||
|
||||
this.hookGeneric = type;
|
||||
this.plugin = pluginName;
|
||||
this.managerClass = handler;
|
||||
|
||||
if (hooks == null) {
|
||||
hooks = new LinkedHashMap();
|
||||
}
|
||||
|
||||
hooks.put(handler, this);
|
||||
|
||||
// Does this class have a plugin constructor?
|
||||
try {
|
||||
pluginConstructor = handler.getDeclaredConstructor(Plugin.class);
|
||||
@ -89,7 +92,6 @@ public final class PluginHook<T extends Class> {
|
||||
* Permissible constructors are empty () or (org.bukkit.plugin.Plugin) <br>
|
||||
* Each plugin defined must use a different handler class.
|
||||
*
|
||||
* @param <T>
|
||||
* @param type Generic hook type for this plugin
|
||||
* @param pluginName Plugin name
|
||||
* @param handler Specific class that will handle this plugin, if enabled.
|
||||
@ -107,6 +109,7 @@ public final class PluginHook<T extends Class> {
|
||||
for (PluginHook hook : getHooks(type)) {
|
||||
if (pluginManager.isPluginEnabled(hook.plugin)) {
|
||||
Hook handler = (Hook) (plugin != null ? hook.load(plugin) : hook.load());
|
||||
|
||||
if (handler != null && handler.isEnabled()) {
|
||||
loaded.put(hook, handler);
|
||||
}
|
||||
@ -136,6 +139,7 @@ public final class PluginHook<T extends Class> {
|
||||
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Unexpected Error while creating a new Hook Manager for " + plugin, ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -148,6 +152,7 @@ public final class PluginHook<T extends Class> {
|
||||
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
|
||||
Bukkit.getLogger().log(Level.SEVERE, "Unexpected Error while creating a new Hook Manager for " + plugin, ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -156,6 +161,7 @@ public final class PluginHook<T extends Class> {
|
||||
int hash = 3;
|
||||
hash = 37 * hash + Objects.hashCode(this.plugin);
|
||||
hash = 37 * hash + Objects.hashCode(this.managerClass);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -164,8 +170,8 @@ public final class PluginHook<T extends Class> {
|
||||
if (obj == null || getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final PluginHook<?> other = (PluginHook<?>) obj;
|
||||
return Objects.equals(this.plugin, other.plugin)
|
||||
&& Objects.equals(this.managerClass, other.managerClass);
|
||||
return Objects.equals(this.plugin, other.plugin) && Objects.equals(this.managerClass, other.managerClass);
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class ProtectionManager {
|
||||
|
||||
private static final HookManager<Protection> manager = new HookManager(Protection.class);
|
||||
|
||||
/**
|
||||
|
@ -13,7 +13,6 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class WorldGuardHook {
|
||||
|
||||
static boolean canHook = false;
|
||||
|
||||
static {
|
||||
@ -21,7 +20,7 @@ public class WorldGuardHook {
|
||||
// if this class exists, we're good to use WG classes
|
||||
Class.forName("com.sk89q.worldguard.protection.flags.Flag");
|
||||
canHook = true;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
} catch (ClassNotFoundException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import com.songoda.core.hooks.Hook;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public abstract class Economy implements Hook {
|
||||
|
||||
/**
|
||||
* Get the players available balance
|
||||
*
|
||||
|
@ -5,7 +5,6 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class PlayerPointsEconomy extends Economy {
|
||||
|
||||
private final PlayerPoints playerPoints;
|
||||
|
||||
public PlayerPointsEconomy() {
|
||||
@ -34,18 +33,21 @@ public class PlayerPointsEconomy extends Economy {
|
||||
@Override
|
||||
public boolean hasBalance(OfflinePlayer player, double cost) {
|
||||
int amount = convertAmount(cost);
|
||||
|
||||
return playerPoints.getAPI().look(player.getUniqueId()) >= amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean withdrawBalance(OfflinePlayer player, double cost) {
|
||||
int amount = convertAmount(cost);
|
||||
|
||||
return playerPoints.getAPI().take(player.getUniqueId(), amount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deposit(OfflinePlayer player, double amount) {
|
||||
int amt = convertAmount(amount);
|
||||
|
||||
return playerPoints.getAPI().give(player.getUniqueId(), amt);
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,13 @@ import org.bukkit.OfflinePlayer;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
public class ReserveEconomy extends Economy {
|
||||
|
||||
EconomyAPI economyAPI;
|
||||
|
||||
public ReserveEconomy() {
|
||||
if (Reserve.instance().economyProvided())
|
||||
if (Reserve.instance().economyProvided()) {
|
||||
economyAPI = Reserve.instance().economy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
|
@ -5,12 +5,12 @@ import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
|
||||
public class VaultEconomy extends Economy {
|
||||
|
||||
private final net.milkbowl.vault.economy.Economy vault;
|
||||
|
||||
public VaultEconomy() {
|
||||
// this returns null if we have Vault with no compatible eco plugin
|
||||
RegisteredServiceProvider<net.milkbowl.vault.economy.Economy> v = Bukkit.getServicesManager().getRegistration(net.milkbowl.vault.economy.Economy.class);
|
||||
|
||||
if (v != null) {
|
||||
this.vault = v.getProvider();
|
||||
} else {
|
||||
@ -31,8 +31,10 @@ public class VaultEconomy extends Economy {
|
||||
|
||||
@Override
|
||||
public double getBalance(OfflinePlayer player) {
|
||||
if (vault == null)
|
||||
if (vault == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return vault.getBalance(player);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class CMIHolograms extends Holograms {
|
||||
|
||||
private static CMI cmi;
|
||||
private static HologramManager cmiHologramManager;
|
||||
private static HashSet<String> ourHolograms = new HashSet<>();
|
||||
@ -28,14 +27,16 @@ public class CMIHolograms extends Holograms {
|
||||
try {
|
||||
useOldMethod = CMIHologram.class.getDeclaredField("lines").getDeclaringClass() == String[].class;
|
||||
cmi_CMIHologram_getLines = CMIHologram.class.getMethod("getLines");
|
||||
} catch (NoSuchFieldException | NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchFieldException | NoSuchMethodException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public CMIHolograms(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
cmi = (CMI) Bukkit.getPluginManager().getPlugin("CMI");
|
||||
|
||||
if (cmi != null) {
|
||||
cmiHologramManager = cmi.getHologramManager();
|
||||
}
|
||||
@ -64,11 +65,14 @@ public class CMIHolograms extends Holograms {
|
||||
@Override
|
||||
public void removeHologram(Location location) {
|
||||
location = fixLocation(location);
|
||||
|
||||
final String id = locStr(location);
|
||||
CMIHologram holo = cmiHologramManager.getByName(id);
|
||||
|
||||
if (holo != null) {
|
||||
cmiHologramManager.removeHolo(holo);
|
||||
}
|
||||
|
||||
ourHolograms.remove(id);
|
||||
}
|
||||
|
||||
@ -76,10 +80,12 @@ public class CMIHolograms extends Holograms {
|
||||
public void removeAllHolograms() {
|
||||
for (String id : ourHolograms) {
|
||||
CMIHologram holo = cmiHologramManager.getByName(id);
|
||||
|
||||
if (holo != null) {
|
||||
cmiHologramManager.removeHolo(holo);
|
||||
}
|
||||
}
|
||||
|
||||
ourHolograms.clear();
|
||||
}
|
||||
|
||||
@ -87,6 +93,7 @@ public class CMIHolograms extends Holograms {
|
||||
public void updateHologram(Location location, List<String> lines) {
|
||||
location = fixLocation(location);
|
||||
CMIHologram holo = cmiHologramManager.getByName(locStr(location));
|
||||
|
||||
if (holo != null) {
|
||||
// only update if there is a change to the text
|
||||
List<String> holoLines;
|
||||
@ -100,6 +107,7 @@ public class CMIHolograms extends Holograms {
|
||||
Logger.getLogger(CMIHolograms.class.getName()).log(Level.SEVERE, "CMI Hologram error!", ex);
|
||||
holoLines = Collections.emptyList();
|
||||
}
|
||||
|
||||
boolean isChanged = lines.size() != holoLines.size();
|
||||
if (!isChanged) {
|
||||
// double-check the lines
|
||||
@ -107,12 +115,15 @@ public class CMIHolograms extends Holograms {
|
||||
isChanged = !holo.getLine(i).equals(lines.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (isChanged) {
|
||||
holo.setLines(lines);
|
||||
holo.update();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
createAt(location, lines);
|
||||
}
|
||||
|
||||
@ -129,6 +140,7 @@ public class CMIHolograms extends Holograms {
|
||||
|
||||
private void createAt(Location location, List<String> lines) {
|
||||
final String id = locStr(location);
|
||||
|
||||
CMIHologram holo = new CMIHologram(id, location);
|
||||
holo.setLines(lines);
|
||||
|
||||
|
@ -9,7 +9,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class Holograms implements Hook {
|
||||
|
||||
protected double xOffset = 0.5;
|
||||
protected double yOffset = 0.5;
|
||||
protected double zOffset = 0.5;
|
||||
@ -24,6 +23,7 @@ public abstract class Holograms implements Hook {
|
||||
this.xOffset = x;
|
||||
this.yOffset = y;
|
||||
this.zOffset = z;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ public abstract class Holograms implements Hook {
|
||||
double x = location.getX();
|
||||
double y = location.getY();
|
||||
double z = location.getZ();
|
||||
|
||||
return location.clone().add((x - (int) x) + xOffset, (y - (int) y) + yOffset + defaultHeightOffset(), (z - (int) z) + zOffset);
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HologramsHolograms extends Holograms {
|
||||
|
||||
HologramPlugin hologramPlugin;
|
||||
HashSet<String> ourHolograms = new HashSet<>();
|
||||
|
||||
public HologramsHolograms(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
hologramPlugin = (HologramPlugin) Bukkit.getPluginManager().getPlugin("Holograms");
|
||||
}
|
||||
|
||||
@ -45,12 +45,15 @@ public class HologramsHolograms extends Holograms {
|
||||
@Override
|
||||
public void removeHologram(Location location) {
|
||||
location = fixLocation(location);
|
||||
|
||||
final String id = locStr(location);
|
||||
Hologram hologram = hologramPlugin.getHologramManager().getHologram(id);
|
||||
|
||||
if (hologram != null) {
|
||||
hologram.despawn();
|
||||
hologramPlugin.getHologramManager().removeActiveHologram(hologram);
|
||||
}
|
||||
|
||||
ourHolograms.remove(id);
|
||||
}
|
||||
|
||||
@ -58,11 +61,13 @@ public class HologramsHolograms extends Holograms {
|
||||
public void removeAllHolograms() {
|
||||
for (String id : ourHolograms) {
|
||||
Hologram hologram = hologramPlugin.getHologramManager().getHologram(id);
|
||||
|
||||
if (hologram != null) {
|
||||
hologram.despawn();
|
||||
hologramPlugin.getHologramManager().removeActiveHologram(hologram);
|
||||
}
|
||||
}
|
||||
|
||||
ourHolograms.clear();
|
||||
}
|
||||
|
||||
@ -112,14 +117,17 @@ public class HologramsHolograms extends Holograms {
|
||||
|
||||
private void createAt(Location location, List<String> lines) {
|
||||
final String id = locStr(location);
|
||||
|
||||
Hologram hologram = new Hologram(id, location);
|
||||
|
||||
for (String line : lines) {
|
||||
hologram.addLine(new TextLine(hologram, line));
|
||||
}
|
||||
|
||||
hologramPlugin.getHologramManager().addActiveHologram(hologram);
|
||||
|
||||
if (!ourHolograms.contains(id))
|
||||
if (!ourHolograms.contains(id)) {
|
||||
ourHolograms.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class HolographicDisplaysHolograms extends Holograms {
|
||||
|
||||
public HolographicDisplaysHolograms(Plugin plugin) {
|
||||
super(plugin);
|
||||
}
|
||||
@ -39,10 +38,14 @@ public class HolographicDisplaysHolograms extends Holograms {
|
||||
@Override
|
||||
public void removeHologram(Location location) {
|
||||
location = fixLocation(location);
|
||||
|
||||
for (Hologram hologram : HologramsAPI.getHolograms(plugin)) {
|
||||
if (hologram.getX() != location.getX()
|
||||
|| hologram.getY() != location.getY()
|
||||
|| hologram.getZ() != location.getZ()) continue;
|
||||
|| hologram.getZ() != location.getZ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hologram.delete();
|
||||
}
|
||||
}
|
||||
@ -63,7 +66,9 @@ public class HolographicDisplaysHolograms extends Holograms {
|
||||
for (Hologram hologram : holograms) {
|
||||
if (hologram.getX() != location.getX()
|
||||
|| hologram.getY() != location.getY()
|
||||
|| hologram.getZ() != location.getZ()) continue;
|
||||
|| hologram.getZ() != location.getZ()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// only update if there is a change to the text
|
||||
boolean isChanged = lines.size() != hologram.size();
|
||||
@ -92,6 +97,7 @@ public class HolographicDisplaysHolograms extends Holograms {
|
||||
|
||||
private void createAt(Location location, List<String> lines) {
|
||||
Hologram hologram = HologramsAPI.createHologram(plugin, location);
|
||||
|
||||
for (String line : lines) {
|
||||
hologram.appendTextLine(line);
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JobsHandler {
|
||||
|
||||
public static List<String> getJobs() {
|
||||
return Jobs.getJobs().stream().map(j -> j.getName()).collect(Collectors.toList());
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JobsPlayerHandler {
|
||||
|
||||
protected final JobsPlayer jPlayer;
|
||||
|
||||
protected JobsPlayerHandler(JobsPlayer jPlayer) {
|
||||
@ -33,6 +32,7 @@ public class JobsPlayerHandler {
|
||||
|
||||
public static JobsPlayerHandler loadPlayer(Player player) {
|
||||
JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player);
|
||||
|
||||
return jPlayer != null ? new JobsPlayerHandler(jPlayer) : null;
|
||||
}
|
||||
|
||||
@ -50,6 +50,7 @@ public class JobsPlayerHandler {
|
||||
|
||||
public void promoteJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.promoteJob(job, 1);
|
||||
}
|
||||
@ -57,6 +58,7 @@ public class JobsPlayerHandler {
|
||||
|
||||
public void promoteJob(String jobName, int levels) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.promoteJob(job, levels);
|
||||
}
|
||||
@ -64,6 +66,7 @@ public class JobsPlayerHandler {
|
||||
|
||||
public void demoteJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.demoteJob(job, 1);
|
||||
}
|
||||
@ -71,6 +74,7 @@ public class JobsPlayerHandler {
|
||||
|
||||
public void demoteJob(String jobName, int levels) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.demoteJob(job, levels);
|
||||
}
|
||||
@ -78,6 +82,7 @@ public class JobsPlayerHandler {
|
||||
|
||||
public void joinJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.joinJob(job);
|
||||
}
|
||||
@ -89,6 +94,7 @@ public class JobsPlayerHandler {
|
||||
|
||||
public void leaveJob(String jobName) {
|
||||
Job job = Jobs.getJob(jobName);
|
||||
|
||||
if (job != null) {
|
||||
jPlayer.leaveJob(job);
|
||||
}
|
||||
@ -154,13 +160,16 @@ public class JobsPlayerHandler {
|
||||
Jobs.action(jPlayer, new EntityActionInfo(entity, ActionType.KILL), damageSource, entity);
|
||||
if (entity instanceof Player && !entity.hasMetadata("NPC")) {
|
||||
JobsPlayer jVictim = Jobs.getPlayerManager().getJobsPlayer((Player) entity);
|
||||
|
||||
if (jVictim == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<JobProgression> jobs = jVictim.getJobProgression();
|
||||
if (jobs == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (JobProgression job : jobs) {
|
||||
Jobs.action(jPlayer, new CustomKillInfo(job.getJob().getName(), ActionType.CUSTOMKILL), damageSource, entity);
|
||||
}
|
||||
@ -169,14 +178,17 @@ public class JobsPlayerHandler {
|
||||
|
||||
public void itemEnchanted(ItemStack resultStack) {
|
||||
Map<Enchantment, Integer> enchants = resultStack.getEnchantments();
|
||||
|
||||
for (Map.Entry<Enchantment, Integer> oneEnchant : enchants.entrySet()) {
|
||||
CMIEnchantment e;
|
||||
String enchantName;
|
||||
Integer level2;
|
||||
Enchantment enchant = oneEnchant.getKey();
|
||||
|
||||
if (enchant == null || (enchantName = (e = CMIEnchantment.get(enchant)) == null ? null : e.toString()) == null || (level2 = oneEnchant.getValue()) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Jobs.action(jPlayer, new EnchantActionInfo(enchantName, level2, ActionType.ENCHANT));
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public class CoreProtectLog extends Log {
|
||||
|
||||
private CoreProtectAPI api;
|
||||
private boolean useDeprecatedMethod = ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12);
|
||||
|
||||
@ -30,18 +29,20 @@ public class CoreProtectLog extends Log {
|
||||
public void logPlacement(OfflinePlayer player, Block block) {
|
||||
if (this.useDeprecatedMethod) {
|
||||
this.api.logPlacement(player.getName(), block.getLocation(), block.getType(), block.getData());
|
||||
} else {
|
||||
this.api.logPlacement(player.getName(), block.getLocation(), block.getType(), block.getBlockData());
|
||||
return;
|
||||
}
|
||||
|
||||
this.api.logPlacement(player.getName(), block.getLocation(), block.getType(), block.getBlockData());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logRemoval(OfflinePlayer player, Block block) {
|
||||
if (this.useDeprecatedMethod) {
|
||||
this.api.logRemoval(player.getName(), block.getLocation(), block.getType(), block.getData());
|
||||
} else {
|
||||
this.api.logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData());
|
||||
return;
|
||||
}
|
||||
|
||||
this.api.logRemoval(player.getName(), block.getLocation(), block.getType(), block.getBlockData());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -6,7 +6,6 @@ import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
public abstract class Log implements Hook {
|
||||
|
||||
public abstract void logPlacement(OfflinePlayer player, Block block);
|
||||
|
||||
public abstract void logRemoval(OfflinePlayer player, Block block);
|
||||
|
@ -26,7 +26,6 @@ import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class McMMOHandler {
|
||||
|
||||
static boolean mcmmo_v2 = false;
|
||||
static boolean legacy_v13 = false;
|
||||
static boolean legacy_v12 = false;
|
||||
@ -62,6 +61,7 @@ public class McMMOHandler {
|
||||
mcmmo_SecondaryAbility_valueOf = mcmmo_SecondaryAbility.getDeclaredMethod("valueOf", String.class);
|
||||
mcmmo_Permissions_secondaryAbilityEnabled = com.gmail.nossr50.util.Permissions.class.getDeclaredMethod("secondaryAbilityEnabled", Player.class, mcmmo_SecondaryAbility);
|
||||
mcmmo_SkillUtils_activationSuccessful = com.gmail.nossr50.util.skills.SkillUtils.class.getDeclaredMethod("activationSuccessful", mcmmo_SecondaryAbility, Player.class, int.class, int.class);
|
||||
|
||||
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
|
||||
mcmmo_ExperienceConfig_getXp = mcmmo_ExperienceConfig_instance.getClass().getDeclaredMethod("getXp", mcmmo_SkillType, org.bukkit.block.data.BlockData.class);
|
||||
legacy_v13 = true;
|
||||
@ -72,8 +72,8 @@ public class McMMOHandler {
|
||||
mcmmo_ExperienceConfig_getXp = mcmmo_ExperienceConfig_instance.getClass().getDeclaredMethod("getXp", mcmmo_SkillType, org.bukkit.Material.class);
|
||||
legacy_v8 = true;
|
||||
}
|
||||
} catch (Exception ex1) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to register McMMO Legacy Hook", ex1);
|
||||
} catch (Exception ex2) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to register McMMO Legacy Hook", ex2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,10 +81,13 @@ public class McMMOHandler {
|
||||
public static void addMining(Player player, Collection<Block> blocks) {
|
||||
if (player == null || blocks == null || blocks.isEmpty()) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
addBlockSkillLegacy(player, blocks, "mining");
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new));
|
||||
ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.MINING);
|
||||
}
|
||||
@ -92,10 +95,13 @@ public class McMMOHandler {
|
||||
public static void addExcavation(Player player, Collection<Block> blocks) {
|
||||
if (player == null || blocks == null || blocks.isEmpty()) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
addBlockSkillLegacy(player, blocks, "excavation");
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new));
|
||||
ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.EXCAVATION);
|
||||
}
|
||||
@ -103,10 +109,13 @@ public class McMMOHandler {
|
||||
public static void addHerbalism(Player player, Collection<Block> blocks) {
|
||||
if (player == null || blocks == null || blocks.isEmpty()) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
addBlockSkillLegacy(player, blocks, "herbalism");
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new));
|
||||
ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.HERBALISM);
|
||||
}
|
||||
@ -114,10 +123,13 @@ public class McMMOHandler {
|
||||
public static void addWoodcutting(Player player, Collection<Block> blocks) {
|
||||
if (player == null || blocks == null || blocks.isEmpty()) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
addBlockSkillLegacy(player, blocks, "woodcutting");
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<BlockState> blockStates = blocks.stream().map(b -> b.getState()).collect(Collectors.toCollection(ArrayList::new));
|
||||
ExperienceAPI.addXpFromBlocksBySkill(blockStates, UserManager.getPlayer(player), PrimarySkillType.WOODCUTTING);
|
||||
}
|
||||
@ -125,252 +137,336 @@ public class McMMOHandler {
|
||||
public static int getAcrobaticsSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "acrobatics");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.ACROBATICS);
|
||||
}
|
||||
|
||||
public static int getAlchemySkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "alchemy");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.ALCHEMY);
|
||||
}
|
||||
|
||||
public static int getArcherySkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "archery");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.ARCHERY);
|
||||
}
|
||||
|
||||
public static int getAxesSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "axes");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.AXES);
|
||||
}
|
||||
|
||||
public static int getExcavationSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "excavation");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.EXCAVATION);
|
||||
}
|
||||
|
||||
public static int getFishingSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "fishing");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.FISHING);
|
||||
}
|
||||
|
||||
public static int getHerbalismSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "herbalism");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.HERBALISM);
|
||||
}
|
||||
|
||||
public static int getMiningSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "mining");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.MINING);
|
||||
}
|
||||
|
||||
public static int getRepairSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "repair");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.REPAIR);
|
||||
}
|
||||
|
||||
public static int getSmeltingSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "smelting");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.SMELTING);
|
||||
}
|
||||
|
||||
public static int getSwordsSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "swords");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.SWORDS);
|
||||
}
|
||||
|
||||
public static int getTamingSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "taming");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.TAMING);
|
||||
}
|
||||
|
||||
public static int getUnarmedSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "unarmed");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.UNARMED);
|
||||
}
|
||||
|
||||
public static int getWoodcuttingSkill(Player player) {
|
||||
if (player == null) {
|
||||
return -1;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
return getSkillLegacy(player, "woodcutting");
|
||||
}
|
||||
|
||||
return UserManager.getPlayer(player).getSkillLevel(PrimarySkillType.WOODCUTTING);
|
||||
}
|
||||
|
||||
public static void addAcrobatics(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "acrobatics", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.ACROBATICS, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addAlchemy(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "alchemy", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.ALCHEMY, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addArchery(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "archery", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.ARCHERY, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addAxes(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "axes", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.AXES, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addExcavation(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "excavation", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.EXCAVATION, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addFishing(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "fishing", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.FISHING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addHerbalism(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "herbalism", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.HERBALISM, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addMining(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "mining", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.MINING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addRepair(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "repair", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.REPAIR, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addSmelting(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "smelting", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.SMELTING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addSwords(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "swords", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.SWORDS, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addTaming(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "taming", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.TAMING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addUnarmed(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "unarmed", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.UNARMED, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
public static void addWoodcutting(Player player, int xp) {
|
||||
if (player == null) {
|
||||
return;
|
||||
} else if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
}
|
||||
|
||||
if (legacy_v13 || legacy_v12 || legacy_v8) {
|
||||
ExperienceAPI.addXP(player, "woodcutting", xp);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(PrimarySkillType.WOODCUTTING, xp, XPGainReason.UNKNOWN, XPGainSource.CUSTOM);
|
||||
}
|
||||
|
||||
@ -455,22 +551,25 @@ public class McMMOHandler {
|
||||
if (player.hasMetadata("mcMMO: Player Data")) {
|
||||
try {
|
||||
Object skillType = mcmmo_SkillType_valueOf.invoke(null, skill.toUpperCase());
|
||||
|
||||
if ((boolean) mcmmo_SkillType_getDoubleDropsDisabled.invoke(skillType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int skillLevel = (int) mcmmo_McMMOPlayer_getSkillLevel.invoke(UserManager.getPlayer(player), skillType);
|
||||
int activationChance = (int) mcmmo_PerksUtils_handleLuckyPerks.invoke(null, player, skillType);
|
||||
|
||||
Object secondaryDouble = mcmmo_SecondaryAbility_valueOf.invoke(null, skill.toUpperCase() + "_DOUBLE_DROPS");
|
||||
|
||||
if (!((boolean) mcmmo_Permissions_secondaryAbilityEnabled.invoke(null, player, secondaryDouble))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (boolean) mcmmo_SkillUtils_activationSuccessful.invoke(null, secondaryDouble, player, skillLevel, activationChance);
|
||||
} catch (Exception ex1) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex1);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -484,30 +583,34 @@ public class McMMOHandler {
|
||||
}
|
||||
|
||||
ExperienceAPI.addXP(player, skill, xp);
|
||||
} catch (Exception ex1) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex1);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex);
|
||||
}
|
||||
}
|
||||
|
||||
protected static Object legacy_getBlock(Block block) {
|
||||
if (legacy_v13) {
|
||||
return block.getBlockData();
|
||||
} else if (legacy_v12) {
|
||||
return block.getState().getData();
|
||||
} else {
|
||||
return block.getType();
|
||||
}
|
||||
|
||||
if (legacy_v12) {
|
||||
return block.getState().getData();
|
||||
}
|
||||
|
||||
return block.getType();
|
||||
}
|
||||
|
||||
protected static int getSkillLegacy(Player player, String skill) {
|
||||
if (player.hasMetadata("mcMMO: Player Data")) {
|
||||
try {
|
||||
Object skillType = mcmmo_SkillType_valueOf.invoke(null, skill.toUpperCase());
|
||||
|
||||
return (int) mcmmo_McMMOPlayer_getSkillLevel.invoke(UserManager.getPlayer(player), skillType);
|
||||
} catch (Exception ex1) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex1);
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(McMMOHandler.class.getName()).log(Level.SEVERE, "Failed to invoke McMMO Legacy Hook", ex);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -13,11 +13,11 @@ import world.bentobox.bentobox.managers.IslandsManager;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BentoBoxProtection extends Protection {
|
||||
|
||||
private final IslandsManager islandsManager;
|
||||
|
||||
public BentoBoxProtection(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
this.islandsManager = BentoBox.getInstance().getIslands();
|
||||
}
|
||||
|
||||
|
@ -8,38 +8,44 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class GriefPreventionProtection extends Protection {
|
||||
|
||||
private final DataStore dataStore;
|
||||
|
||||
public GriefPreventionProtection(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
this.dataStore = GriefPrevention.instance.dataStore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlace(Player player, Location location) {
|
||||
Claim claim = getClaim(location);
|
||||
|
||||
if (claim == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return claim.allowBuild(player, location.getBlock().getType()) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBreak(Player player, Location location) {
|
||||
Claim claim = getClaim(location);
|
||||
|
||||
if (claim == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return claim.allowBreak(player, location.getBlock().getType()) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteract(Player player, Location location) {
|
||||
Claim claim = getClaim(location);
|
||||
|
||||
if (claim == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return claim.allowContainers(player) == null;
|
||||
}
|
||||
|
||||
|
@ -8,11 +8,11 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class LandsProtection extends Protection {
|
||||
|
||||
private final LandsIntegration landsIntegration;
|
||||
|
||||
public LandsProtection(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
this.landsIntegration = new LandsIntegration(plugin);
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ public class LandsProtection extends Protection {
|
||||
|
||||
private boolean hasPerms(Player player, Location location, RoleSetting roleSetting) {
|
||||
Area area = landsIntegration.getAreaByLoc(location);
|
||||
|
||||
if (area == null) {
|
||||
return true;
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public abstract class Protection implements Hook {
|
||||
|
||||
protected final Plugin plugin;
|
||||
|
||||
public Protection(Plugin plugin) {
|
||||
|
@ -8,17 +8,18 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class RedProtectProtection extends Protection {
|
||||
|
||||
private final RedProtectAPI api;
|
||||
|
||||
public RedProtectProtection(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
this.api = RedProtect.get().getAPI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlace(Player player, Location location) {
|
||||
Region region = api.getRegion(location);
|
||||
|
||||
if (region == null) {
|
||||
return true;
|
||||
}
|
||||
@ -29,6 +30,7 @@ public class RedProtectProtection extends Protection {
|
||||
@Override
|
||||
public boolean canBreak(Player player, Location location) {
|
||||
Region region = api.getRegion(location);
|
||||
|
||||
if (region == null) {
|
||||
return true;
|
||||
}
|
||||
@ -39,6 +41,7 @@ public class RedProtectProtection extends Protection {
|
||||
@Override
|
||||
public boolean canInteract(Player player, Location location) {
|
||||
Region region = api.getRegion(location);
|
||||
|
||||
if (region == null) {
|
||||
return true;
|
||||
}
|
||||
|
@ -9,22 +9,25 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class ResidenceProtection extends Protection {
|
||||
|
||||
private final Residence instance;
|
||||
|
||||
public ResidenceProtection(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
this.instance = Residence.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlace(Player player, Location location) {
|
||||
ResidencePlayer rPlayer = Residence.getInstance().getPlayerManager().getResidencePlayer(player);
|
||||
|
||||
return rPlayer.canPlaceBlock(location.getBlock(), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBreak(Player player, Location location) {
|
||||
ResidencePlayer rPlayer = Residence.getInstance().getPlayerManager().getResidencePlayer(player);
|
||||
|
||||
return rPlayer.canBreakBlock(location.getBlock(), false);
|
||||
}
|
||||
|
||||
@ -34,11 +37,13 @@ public class ResidenceProtection extends Protection {
|
||||
}
|
||||
|
||||
private boolean hasPerms(Player player, Location location, Flags flag) {
|
||||
if (instance.isDisabledWorldListener(location.getWorld()))
|
||||
if (instance.isDisabledWorldListener(location.getWorld())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (instance.isResAdminOn(player))
|
||||
if (instance.isResAdminOn(player)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
FlagPermissions perms = instance.getPermsByLocForPlayer(location, player);
|
||||
return perms.playerHas(player, flag, true);
|
||||
|
@ -8,11 +8,11 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
public class UltimateClaimsProtection extends Protection {
|
||||
|
||||
private final UltimateClaims instance;
|
||||
|
||||
public UltimateClaimsProtection(Plugin plugin) {
|
||||
super(plugin);
|
||||
|
||||
instance = UltimateClaims.getInstance();
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ import uk.antiperson.stackmob.api.EntityManager;
|
||||
import uk.antiperson.stackmob.api.StackedEntity;
|
||||
|
||||
public class StackMob extends Stacker {
|
||||
|
||||
private final EntityManager plugin;
|
||||
|
||||
public StackMob() {
|
||||
|
@ -6,7 +6,6 @@ import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
public abstract class Stacker implements Hook {
|
||||
|
||||
public abstract boolean supportsItemStacking();
|
||||
|
||||
public abstract boolean supportsEntityStacking();
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user