Apply new code style [DEV-2]

This commit is contained in:
Christian Koop 2021-09-26 15:27:06 +02:00
parent 92f42e6261
commit 39bdd862fb
No known key found for this signature in database
GPG Key ID: 89A8181384E010A3
365 changed files with 9780 additions and 7804 deletions

View File

@ -50,13 +50,13 @@ jobs:
if: ${{ success() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/development') }}
continue-on-error: true
run: |
curl -X POST --data "{\"content\":null,\"embeds\":[{\"title\":\"Build succeeded!\",\"description\":\"The build with the ID #$GITHUB_RUN_NUMBER has succeeded!\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\",\"color\":5490477,\"fields\":[{\"name\":\"Branch\",\"value\":\"$GITHUB_REF\",\"inline\":true}],\"author\":{\"name\":\"$GITHUB_REPOSITORY\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY\",\"icon_url\":\"$GITHUB_SERVER_URL/songoda.png\"},\"footer\":{\"text\":\"Initiated by $GITHUB_ACTOR\",\"icon_url\":\"$GITHUB_SERVER_URL/$GITHUB_ACTOR.png\"}}],\"username\":\"OctoAgent\",\"avatar_url\":\"https://github.githubassets.com/images/modules/logos_page/Octocat.png\"}" --header 'Content-Type: application/json' $DISCORD_WEBHOOK
curl -X POST --data "{\"content\":null,\"embeds\":[{\"title\":\"Build succeeded!\",\"description\":\"The build with the ID #$GITHUB_RUN_NUMBER has succeeded!\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\",\"color\":5490477,\"fields\":[{\"name\":\"Branch\",\"value\":\"$GITHUB_REF\",\"inline\":true}],\"author\":{\"name\":\"$GITHUB_REPOSITORY\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY\",\"icon_url\":\"$GITHUB_SERVER_URL/songoda.png\"},\"footer\":{\"text\":\"Initiated by $GITHUB_ACTOR\",\"icon_url\":\"$GITHUB_SERVER_URL/$GITHUB_ACTOR.png\"}}],\"username\":\"OctoAgent\",\"avatar_url\":\"https://github.githubassets.com/images/modules/logos_page/Octocat.png\"}" --header 'Content-Type: application/json' $DISCORD_WEBHOOK
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_BUILD_STATUS_WEBHOOK }}
- name: 'Discord Webhook (Failure)'
if: ${{ failure() && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/development') }}
continue-on-error: true
run: |
curl -X POST --data "{\"content\":null,\"embeds\":[{\"title\":\"Build failed!\",\"description\":\"The build with the ID #$GITHUB_RUN_NUMBER has failed!\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\",\"color\":15611419,\"fields\":[{\"name\":\"Branch\",\"value\":\"$GITHUB_REF\",\"inline\":true}],\"author\":{\"name\":\"$GITHUB_REPOSITORY\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY\",\"icon_url\":\"$GITHUB_SERVER_URL/songoda.png\"},\"footer\":{\"text\":\"Initiated by $GITHUB_ACTOR\",\"icon_url\":\"$GITHUB_SERVER_URL/$GITHUB_ACTOR.png\"}}],\"username\":\"OctoAgent\",\"avatar_url\":\"https://github.githubassets.com/images/modules/logos_page/Octocat.png\"}" --header "Content-Type:application/json" $DISCORD_WEBHOOK
curl -X POST --data "{\"content\":null,\"embeds\":[{\"title\":\"Build failed!\",\"description\":\"The build with the ID #$GITHUB_RUN_NUMBER has failed!\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID\",\"color\":15611419,\"fields\":[{\"name\":\"Branch\",\"value\":\"$GITHUB_REF\",\"inline\":true}],\"author\":{\"name\":\"$GITHUB_REPOSITORY\",\"url\":\"$GITHUB_SERVER_URL/$GITHUB_REPOSITORY\",\"icon_url\":\"$GITHUB_SERVER_URL/songoda.png\"},\"footer\":{\"text\":\"Initiated by $GITHUB_ACTOR\",\"icon_url\":\"$GITHUB_SERVER_URL/$GITHUB_ACTOR.png\"}}],\"username\":\"OctoAgent\",\"avatar_url\":\"https://github.githubassets.com/images/modules/logos_page/Octocat.png\"}" --header "Content-Type:application/json" $DISCORD_WEBHOOK
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_BUILD_STATUS_WEBHOOK }}

View File

@ -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;
}
}

View File

@ -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,14 +209,17 @@ 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();
@ -216,22 +227,31 @@ public enum CompatibleBiome {
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
chunk.getWorld().setBiome(x, z, getBiome());
}
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
world.setBiome(x, z, getBiome());
return;
}
world.setBiome(x, z, getBiome());
}
private static Version v(ServerVersion version, String biome) {
@ -243,7 +263,6 @@ public enum CompatibleBiome {
}
private static class Version {
final ServerVersion version;
final String biome;

View File

@ -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,10 +70,12 @@ 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
player.getInventory().setItemInOffHand(result > 0 ? item : null);
return;
}
player.getInventory().setItemInOffHand(result > 0 ? item : null);
}
/**
@ -79,10 +86,11 @@ 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();
}
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
player.getInventory().setItemInOffHand(item);
return;
}
player.getInventory().setItemInOffHand(item);
}
}

View File

@ -21,7 +21,7 @@ import java.util.Set;
* @since 2019-08-23
*/
public enum CompatibleMaterial {
/*
/*
TODO: add another handler for getBlockItem() for materials and fallback materials
Legacy has some values not used in modern, eg:
@ -33,7 +33,7 @@ public enum CompatibleMaterial {
JUNGLE_DOOR_ITEM(429),
ACACIA_DOOR_ITEM(430),
DARK_OAK_DOOR_ITEM(431),
*/
*/
/* 1.17 */
AMETHYST_BLOCK(),
@ -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();
}
}
try {
return getMaterial(block.getMaterial(), (byte) methodGetBlockData.invoke(block));
} 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
if (mat != null) {
if (data != 0) {
for (CompatibleMaterial cm : CompatibleMaterial.values()) {
if (cm.getMaterial() != null
&& cm.getMaterial().equals(mat)) {
if (cm.getData() == data) {
return cm;
}
}
}
// Pre-Flattening
if (mat != null) {
if (data != 0) {
for (CompatibleMaterial cm : CompatibleMaterial.values()) {
if (cm.getMaterial() != null && cm.getMaterial().equals(mat) && cm.getData() == data) {
return cm;
}
}
return CompatibleMaterial.getMaterial(mat);
}
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;
}
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;
}
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,11 +2638,11 @@ 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 false;
}
/**
@ -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,8 +2811,9 @@ public enum CompatibleMaterial {
case COOKED_SALMON:
case DRIED_KELP:
return true;
default:
return false;
}
return false;
}
/**
@ -2820,8 +2831,9 @@ public enum CompatibleMaterial {
case RABBIT:
case SALMON:
return true;
default:
return false;
}
return false;
}
/**
@ -2836,8 +2848,9 @@ public enum CompatibleMaterial {
case PEONY:
case TALL_GRASS:
return true;
default:
return false;
}
return false;
}
/**
@ -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,8 +3028,9 @@ public enum CompatibleMaterial {
return RED_STAINED_GLASS;
case 15:
return BLACK_STAINED_GLASS;
default:
return WHITE_STAINED_GLASS;
}
return WHITE_STAINED_GLASS;
}
public static CompatibleMaterial getWoolColor(int color) {
@ -3053,8 +3067,9 @@ public enum CompatibleMaterial {
return RED_WOOL;
case 15:
return BLACK_WOOL;
default:
return WHITE_WOOL;
}
return WHITE_WOOL;
}
public static CompatibleMaterial getDyeColor(int color) {
@ -3091,7 +3106,8 @@ public enum CompatibleMaterial {
return ORANGE_DYE;
case 15:
return WHITE_DYE;
default:
return WHITE_DYE;
}
return WHITE_DYE;
}
}

View File

@ -1,326 +1,325 @@
package com.songoda.core.compatibility;
import org.bukkit.Color;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class CompatibleParticleHandler {
public static enum ParticleType {
EXPLOSION_NORMAL,
EXPLOSION_LARGE,
EXPLOSION_HUGE,
FIREWORKS_SPARK,
WATER_BUBBLE,
WATER_SPLASH,
WATER_WAKE,
SUSPENDED,
SUSPENDED_DEPTH,
CRIT,
CRIT_MAGIC,
SMOKE_NORMAL,
SMOKE_LARGE,
SPELL,
SPELL_INSTANT,
SPELL_MOB,
SPELL_MOB_AMBIENT,
SPELL_WITCH,
DRIP_WATER,
DRIP_LAVA,
VILLAGER_ANGRY,
VILLAGER_HAPPY,
TOWN_AURA,
NOTE,
PORTAL,
ENCHANTMENT_TABLE,
FLAME,
LAVA,
CLOUD,
REDSTONE(), //DustOptions
SNOWBALL,
SNOW_SHOVEL,
SLIME,
HEART,
BARRIER,
ITEM_CRACK(), // ItemStack
BLOCK_CRACK(), // BlockData
BLOCK_DUST(), // BlockData
WATER_DROP,
// 1.8-1.12 included ITEM_TAKE
MOB_APPEARANCE,
/// End 1.8 particles ///
DRAGON_BREATH(ServerVersion.V1_9, "SPELL_MOB_AMBIENT"),
END_ROD(ServerVersion.V1_9, "ENCHANTMENT_TABLE"),
DAMAGE_INDICATOR(ServerVersion.V1_9, "VILLAGER_ANGRY"),
SWEEP_ATTACK(ServerVersion.V1_9, "CRIT"),
/// End 1.9 particles ///
FALLING_DUST(ServerVersion.V1_10, "BLOCK_DUST"), // BlockData
/// End 1.10 ///
TOTEM(ServerVersion.V1_11, "VILLAGER_HAPPY"),
SPIT(ServerVersion.V1_11, "REDSTONE"),
/// End 1.11-1.12 ///
SQUID_INK(ServerVersion.V1_13, "CRIT"),
BUBBLE_POP(ServerVersion.V1_13, "CRIT"),
CURRENT_DOWN(ServerVersion.V1_13, "CRIT"),
BUBBLE_COLUMN_UP(ServerVersion.V1_13, "CRIT"),
NAUTILUS(ServerVersion.V1_13, "ENCHANTMENT_TABLE"),
DOLPHIN(ServerVersion.V1_13, "TOWN_AURA"),
/// End 1.13 ///
SNEEZE(ServerVersion.V1_14, "REDSTONE"),
CAMPFIRE_COSY_SMOKE(ServerVersion.V1_14, "SMOKE_NORMAL"),
CAMPFIRE_SIGNAL_SMOKE(ServerVersion.V1_14, "SMOKE_LARGE"),
COMPOSTER(ServerVersion.V1_14, "CRIT"),
FLASH(ServerVersion.V1_14, "EXPLOSION_NORMAL"), // idk
FALLING_LAVA(ServerVersion.V1_14, "DRIP_LAVA"),
LANDING_LAVA(ServerVersion.V1_14, "LAVA"),
FALLING_WATER(ServerVersion.V1_14, "DRIP_WATER"),
/// End 1.14 ///
DRIPPING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
FALLING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
FALLING_NECTAR(ServerVersion.V1_15, "DRIP_WATER"),
LANDING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
/// End 1.15 ///
// ToDo: Someone needs to make better compatible fall backs.
SOUL_FIRE_FLAME(ServerVersion.V1_16, "DRIP_WATER"),
ASH(ServerVersion.V1_16, "DRIP_WATER"),
CRIMSON_SPORE(ServerVersion.V1_16, "DRIP_WATER"),
WARPED_SPORE(ServerVersion.V1_16, "DRIP_WATER"),
SOUL(ServerVersion.V1_16, "DRIP_WATER"),
DRIPPING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
FALLING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
LANDING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
REVERSE_PORTAL(ServerVersion.V1_16, "DRIP_WATER"),
WHITE_ASH(ServerVersion.V1_16, "DRIP_WATER"),
/// End 1.16 ///
// ToDo: Someone needs to make better compatible fall backs.
LIGHT(ServerVersion.V1_17, "DRIP_WATER"),
DUST_COLOR_TRANSITION(ServerVersion.V1_17, "DRIP_WATER"),
VIBRATION(ServerVersion.V1_17, "DRIP_WATER"),
FALLING_SPORE_BLOSSOM(ServerVersion.V1_17, "DRIP_WATER"),
SPORE_BLOSSOM_AIR(ServerVersion.V1_17, "DRIP_WATER"),
SMALL_FLAME(ServerVersion.V1_17, "DRIP_WATER"),
SNOWFLAKE(ServerVersion.V1_17, "DRIP_WATER"),
DRIPPING_DRIPSTONE_LAVA(ServerVersion.V1_17, "DRIP_WATER"),
FALLING_DRIPSTONE_LAVA(ServerVersion.V1_17, "DRIP_WATER"),
DRIPPING_DRIPSTONE_WATER(ServerVersion.V1_17, "DRIP_WATER"),
FALLING_DRIPSTONE_WATER(ServerVersion.V1_17, "DRIP_WATER"),
GLOW_SQUID_INK(ServerVersion.V1_17, "DRIP_WATER"),
GLOW(ServerVersion.V1_17, "DRIP_WATER"),
WAX_ON(ServerVersion.V1_17, "DRIP_WATER"),
WAX_OFF(ServerVersion.V1_17, "DRIP_WATER"),
ELECTRIC_SPARK(ServerVersion.V1_17, "DRIP_WATER"),
SCRAPE(ServerVersion.V1_17, "DRIP_WATER"),
/// End 1.17 ///
;
final boolean compatibilityMode;
final LegacyParticleEffects.Type compatibleEffect;
final Object particle;
final static Map<String, ParticleType> map = new HashMap<>();
static {
for (ParticleType t : values()) {
map.put(t.name(), t);
}
}
private ParticleType() {
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
this.compatibilityMode = true;
this.particle = null;
this.compatibleEffect = LegacyParticleEffects.Type.valueOf(name());
} else {
this.compatibleEffect = null;
// does this particle exist in our version?
Particle check = Stream.of(Particle.values()).filter(p -> p.name().equals(name())).findFirst().orElse(null);
if (check != null) {
this.particle = check;
this.compatibilityMode = false;
} else {
// this shouldn't happen, really
this.particle = Particle.END_ROD;
this.compatibilityMode = true;
}
}
}
private ParticleType(ServerVersion minVersion, String compatible) {
// Particle class doesn't exist in 1.8
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
this.compatibilityMode = true;
this.compatibleEffect = LegacyParticleEffects.Type.valueOf(compatible);
this.particle = null;
} else if (ServerVersion.isServerVersionBelow(minVersion)) {
this.compatibilityMode = true;
this.compatibleEffect = null;
this.particle = Particle.valueOf(compatible);
} else {
this.compatibleEffect = null;
// does this particle exist in our version?
Particle check = Stream.of(Particle.values()).filter(p -> p.name().equals(name())).findFirst().orElse(null);
if (check != null) {
this.particle = check;
this.compatibilityMode = false;
} else {
// this shouldn't happen, really
this.particle = Particle.END_ROD;
this.compatibilityMode = true;
}
}
}
public static ParticleType getParticle(String name) {
return map.get(name);
}
}
public static void spawnParticles(String type, Location location) {
spawnParticles(type, location, 0);
}
public static void spawnParticles(String type, Location location, int count) {
ParticleType pt;
if (type != null && (pt = ParticleType.getParticle(type.toUpperCase())) != null) {
spawnParticles(pt, location, count);
}
}
public static void spawnParticles(String type, Location location, int count, double offsetX, double offsetY, double offsetZ) {
ParticleType pt;
if (type != null && (pt = ParticleType.getParticle(type.toUpperCase())) != null) {
spawnParticles(pt, location, count, offsetX, offsetY, offsetZ);
}
}
public static void spawnParticles(ParticleType type, Location location) {
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
LegacyParticleEffects.createParticle(location, type.compatibleEffect);
} else {
location.getWorld().spawnParticle((Particle) type.particle, location, 0);
}
}
public static void spawnParticles(ParticleType type, Location location, int count) {
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
for (int i = 0; i < count; i++) {
float xx = (float) (1 * (Math.random() - Math.random()));
float yy = (float) (1 * (Math.random() - Math.random()));
float zz = (float) (1 * (Math.random() - Math.random()));
Location at = location.clone().add(xx, yy, zz);
LegacyParticleEffects.createParticle(at, type.compatibleEffect);
}
} else {
location.getWorld().spawnParticle((Particle) type.particle, location, count);
}
}
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ) {
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
for (int i = 0; i < count; i++) {
float xx = (float) (offsetX * (Math.random() - Math.random()));
float yy = (float) (offsetY * (Math.random() - Math.random()));
float zz = (float) (offsetZ * (Math.random() - Math.random()));
Location at = location.clone().add(xx, yy, zz);
LegacyParticleEffects.createParticle(at, type.compatibleEffect);
}
} else {
location.getWorld().spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ);
}
}
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra) {
spawnParticles(type, location, count, offsetX, offsetY, offsetZ, extra, null);
}
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, Player receiver) {
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
for (int i = 0; i < count; i++) {
float xx = (float) (offsetX * (Math.random() - Math.random()));
float yy = (float) (offsetY * (Math.random() - Math.random()));
float zz = (float) (offsetZ * (Math.random() - Math.random()));
Location at = location.clone().add(xx, yy, zz);
LegacyParticleEffects.createParticle(at, type.compatibleEffect, 0F, 0F, 0F, (float) extra, 0, receiver != null ? Collections.singletonList(receiver) : null);
}
} else {
if (receiver == null) {
location.getWorld().spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ, extra);
} else {
receiver.spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ, extra);
}
}
}
public static void redstoneParticles(Location location, int red, int green, int blue) {
redstoneParticles(location, red, green, blue, 1F, 1, 0, null);
}
public static void redstoneParticles(Location location, int red, int green, int blue, float size, int count, float radius) {
redstoneParticles(location, red, green, blue, size, count, radius, null);
}
/**
* Spawn colored redstone particles
*
* @param location area to spawn the particle in
* @param red red value 0-255
* @param green green value 0-255
* @param blue blue value 0-255
* @param size (1.13+) size of the particles
* @param count how many particles to spawn
* @param radius how far to spread out the particles from location
*/
public static void redstoneParticles(Location location, int red, int green, int blue, float size, int count, float radius, Player player) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
float xx = (float) (radius * (Math.random() - Math.random()));
float yy = (float) (radius * (Math.random() - Math.random()));
float zz = (float) (radius * (Math.random() - Math.random()));
if (player == null)
location.getWorld().spawnParticle(Particle.REDSTONE, location, count, xx, yy, zz, 1, new Particle.DustOptions(Color.fromBGR(blue, green, red), size));
else
player.spawnParticle(Particle.REDSTONE, location, count, xx, yy, zz, 1, new Particle.DustOptions(Color.fromBGR(blue, green, red), size));
} else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) {
for (int i = 0; i < count; i++) {
float xx = (float) (radius * (Math.random() - Math.random()));
float yy = (float) (radius * (Math.random() - Math.random()));
float zz = (float) (radius * (Math.random() - Math.random()));
Location at = location.clone().add(xx, yy, zz);
if (player == null)
location.getWorld().spawnParticle(Particle.REDSTONE, at, 0, red / 255F, green / 255F, blue / 255F, size); // particle, location, count, red, green, blue, extra data
else
player.spawnParticle(Particle.REDSTONE, at, 0, red / 255F, green / 255F, blue / 255F, size); // particle, location, count, red, green, blue, extra data
}
} else {
// WE NEED MAGIC!
for (int i = 0; i < count; i++) {
float xx = (float) (radius * (Math.random() - Math.random()));
float yy = (float) (radius * (Math.random() - Math.random()));
float zz = (float) (radius * (Math.random() - Math.random()));
Location at = location.clone().add(xx, yy, zz);
LegacyParticleEffects.createParticle(at, LegacyParticleEffects.Type.REDSTONE,
red / 255F, green / 255F, blue / 255F, 1F,
0, player == null ? null : Collections.singletonList(player));
}
}
}
public static void bonemealSmoke(Location l) {
final org.bukkit.World w = l.getWorld();
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH_EAST);
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH);
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH_WEST);
w.playEffect(l, Effect.SMOKE, BlockFace.EAST);
w.playEffect(l, Effect.SMOKE, BlockFace.SELF);
w.playEffect(l, Effect.SMOKE, BlockFace.WEST);
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH_EAST);
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH);
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH_WEST);
}
}
package com.songoda.core.compatibility;
import org.bukkit.Color;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class CompatibleParticleHandler {
public static enum ParticleType {
EXPLOSION_NORMAL,
EXPLOSION_LARGE,
EXPLOSION_HUGE,
FIREWORKS_SPARK,
WATER_BUBBLE,
WATER_SPLASH,
WATER_WAKE,
SUSPENDED,
SUSPENDED_DEPTH,
CRIT,
CRIT_MAGIC,
SMOKE_NORMAL,
SMOKE_LARGE,
SPELL,
SPELL_INSTANT,
SPELL_MOB,
SPELL_MOB_AMBIENT,
SPELL_WITCH,
DRIP_WATER,
DRIP_LAVA,
VILLAGER_ANGRY,
VILLAGER_HAPPY,
TOWN_AURA,
NOTE,
PORTAL,
ENCHANTMENT_TABLE,
FLAME,
LAVA,
CLOUD,
REDSTONE(), //DustOptions
SNOWBALL,
SNOW_SHOVEL,
SLIME,
HEART,
BARRIER,
ITEM_CRACK(), // ItemStack
BLOCK_CRACK(), // BlockData
BLOCK_DUST(), // BlockData
WATER_DROP,
// 1.8-1.12 included ITEM_TAKE
MOB_APPEARANCE,
/// End 1.8 particles ///
DRAGON_BREATH(ServerVersion.V1_9, "SPELL_MOB_AMBIENT"),
END_ROD(ServerVersion.V1_9, "ENCHANTMENT_TABLE"),
DAMAGE_INDICATOR(ServerVersion.V1_9, "VILLAGER_ANGRY"),
SWEEP_ATTACK(ServerVersion.V1_9, "CRIT"),
/// End 1.9 particles ///
FALLING_DUST(ServerVersion.V1_10, "BLOCK_DUST"), // BlockData
/// End 1.10 ///
TOTEM(ServerVersion.V1_11, "VILLAGER_HAPPY"),
SPIT(ServerVersion.V1_11, "REDSTONE"),
/// End 1.11-1.12 ///
SQUID_INK(ServerVersion.V1_13, "CRIT"),
BUBBLE_POP(ServerVersion.V1_13, "CRIT"),
CURRENT_DOWN(ServerVersion.V1_13, "CRIT"),
BUBBLE_COLUMN_UP(ServerVersion.V1_13, "CRIT"),
NAUTILUS(ServerVersion.V1_13, "ENCHANTMENT_TABLE"),
DOLPHIN(ServerVersion.V1_13, "TOWN_AURA"),
/// End 1.13 ///
SNEEZE(ServerVersion.V1_14, "REDSTONE"),
CAMPFIRE_COSY_SMOKE(ServerVersion.V1_14, "SMOKE_NORMAL"),
CAMPFIRE_SIGNAL_SMOKE(ServerVersion.V1_14, "SMOKE_LARGE"),
COMPOSTER(ServerVersion.V1_14, "CRIT"),
FLASH(ServerVersion.V1_14, "EXPLOSION_NORMAL"), // idk
FALLING_LAVA(ServerVersion.V1_14, "DRIP_LAVA"),
LANDING_LAVA(ServerVersion.V1_14, "LAVA"),
FALLING_WATER(ServerVersion.V1_14, "DRIP_WATER"),
/// End 1.14 ///
DRIPPING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
FALLING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
FALLING_NECTAR(ServerVersion.V1_15, "DRIP_WATER"),
LANDING_HONEY(ServerVersion.V1_15, "DRIP_WATER"),
/// End 1.15 ///
// ToDo: Someone needs to make better compatible fall backs.
SOUL_FIRE_FLAME(ServerVersion.V1_16, "DRIP_WATER"),
ASH(ServerVersion.V1_16, "DRIP_WATER"),
CRIMSON_SPORE(ServerVersion.V1_16, "DRIP_WATER"),
WARPED_SPORE(ServerVersion.V1_16, "DRIP_WATER"),
SOUL(ServerVersion.V1_16, "DRIP_WATER"),
DRIPPING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
FALLING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
LANDING_OBSIDIAN_TEAR(ServerVersion.V1_16, "DRIP_WATER"),
REVERSE_PORTAL(ServerVersion.V1_16, "DRIP_WATER"),
WHITE_ASH(ServerVersion.V1_16, "DRIP_WATER"),
/// End 1.16 ///
// ToDo: Someone needs to make better compatible fall backs.
LIGHT(ServerVersion.V1_17, "DRIP_WATER"),
DUST_COLOR_TRANSITION(ServerVersion.V1_17, "DRIP_WATER"),
VIBRATION(ServerVersion.V1_17, "DRIP_WATER"),
FALLING_SPORE_BLOSSOM(ServerVersion.V1_17, "DRIP_WATER"),
SPORE_BLOSSOM_AIR(ServerVersion.V1_17, "DRIP_WATER"),
SMALL_FLAME(ServerVersion.V1_17, "DRIP_WATER"),
SNOWFLAKE(ServerVersion.V1_17, "DRIP_WATER"),
DRIPPING_DRIPSTONE_LAVA(ServerVersion.V1_17, "DRIP_WATER"),
FALLING_DRIPSTONE_LAVA(ServerVersion.V1_17, "DRIP_WATER"),
DRIPPING_DRIPSTONE_WATER(ServerVersion.V1_17, "DRIP_WATER"),
FALLING_DRIPSTONE_WATER(ServerVersion.V1_17, "DRIP_WATER"),
GLOW_SQUID_INK(ServerVersion.V1_17, "DRIP_WATER"),
GLOW(ServerVersion.V1_17, "DRIP_WATER"),
WAX_ON(ServerVersion.V1_17, "DRIP_WATER"),
WAX_OFF(ServerVersion.V1_17, "DRIP_WATER"),
ELECTRIC_SPARK(ServerVersion.V1_17, "DRIP_WATER"),
SCRAPE(ServerVersion.V1_17, "DRIP_WATER"),
/// End 1.17 ///
;
final boolean compatibilityMode;
final LegacyParticleEffects.Type compatibleEffect;
final Object particle;
final static Map<String, ParticleType> map = new HashMap<>();
static {
for (ParticleType t : values()) {
map.put(t.name(), t);
}
}
private ParticleType() {
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
this.compatibilityMode = true;
this.particle = null;
this.compatibleEffect = LegacyParticleEffects.Type.valueOf(name());
} else {
this.compatibleEffect = null;
// does this particle exist in our version?
Particle check = Stream.of(Particle.values()).filter(p -> p.name().equals(name())).findFirst().orElse(null);
if (check != null) {
this.particle = check;
this.compatibilityMode = false;
} else {
// this shouldn't happen, really
this.particle = Particle.END_ROD;
this.compatibilityMode = true;
}
}
}
private ParticleType(ServerVersion minVersion, String compatible) {
// Particle class doesn't exist in 1.8
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
this.compatibilityMode = true;
this.compatibleEffect = LegacyParticleEffects.Type.valueOf(compatible);
this.particle = null;
} else if (ServerVersion.isServerVersionBelow(minVersion)) {
this.compatibilityMode = true;
this.compatibleEffect = null;
this.particle = Particle.valueOf(compatible);
} else {
this.compatibleEffect = null;
// does this particle exist in our version?
Particle check = Stream.of(Particle.values()).filter(p -> p.name().equals(name())).findFirst().orElse(null);
if (check != null) {
this.particle = check;
this.compatibilityMode = false;
} else {
// this shouldn't happen, really
this.particle = Particle.END_ROD;
this.compatibilityMode = true;
}
}
}
public static ParticleType getParticle(String name) {
return map.get(name);
}
}
public static void spawnParticles(String type, Location location) {
spawnParticles(type, location, 0);
}
public static void spawnParticles(String type, Location location, int count) {
ParticleType pt;
if (type != null && (pt = ParticleType.getParticle(type.toUpperCase())) != null) {
spawnParticles(pt, location, count);
}
}
public static void spawnParticles(String type, Location location, int count, double offsetX, double offsetY, double offsetZ) {
ParticleType pt;
if (type != null && (pt = ParticleType.getParticle(type.toUpperCase())) != null) {
spawnParticles(pt, location, count, offsetX, offsetY, offsetZ);
}
}
public static void spawnParticles(ParticleType type, Location location) {
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
LegacyParticleEffects.createParticle(location, type.compatibleEffect);
} else {
location.getWorld().spawnParticle((Particle) type.particle, location, 0);
}
}
public static void spawnParticles(ParticleType type, Location location, int count) {
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
for (int i = 0; i < count; i++) {
float xx = (float) (1 * (Math.random() - Math.random()));
float yy = (float) (1 * (Math.random() - Math.random()));
float zz = (float) (1 * (Math.random() - Math.random()));
Location at = location.clone().add(xx, yy, zz);
LegacyParticleEffects.createParticle(at, type.compatibleEffect);
}
} else {
location.getWorld().spawnParticle((Particle) type.particle, location, count);
}
}
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ) {
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
for (int i = 0; i < count; i++) {
float xx = (float) (offsetX * (Math.random() - Math.random()));
float yy = (float) (offsetY * (Math.random() - Math.random()));
float zz = (float) (offsetZ * (Math.random() - Math.random()));
Location at = location.clone().add(xx, yy, zz);
LegacyParticleEffects.createParticle(at, type.compatibleEffect);
}
} else {
location.getWorld().spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ);
}
}
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra) {
spawnParticles(type, location, count, offsetX, offsetY, offsetZ, extra, null);
}
public static void spawnParticles(ParticleType type, Location location, int count, double offsetX, double offsetY, double offsetZ, double extra, Player receiver) {
if (ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_8)) {
for (int i = 0; i < count; i++) {
float xx = (float) (offsetX * (Math.random() - Math.random()));
float yy = (float) (offsetY * (Math.random() - Math.random()));
float zz = (float) (offsetZ * (Math.random() - Math.random()));
Location at = location.clone().add(xx, yy, zz);
LegacyParticleEffects.createParticle(at, type.compatibleEffect, 0F, 0F, 0F, (float) extra, 0, receiver != null ? Collections.singletonList(receiver) : null);
}
} else {
if (receiver == null) {
location.getWorld().spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ, extra);
} else {
receiver.spawnParticle((Particle) type.particle, location, count, offsetX, offsetY, offsetZ, extra);
}
}
}
public static void redstoneParticles(Location location, int red, int green, int blue) {
redstoneParticles(location, red, green, blue, 1F, 1, 0, null);
}
public static void redstoneParticles(Location location, int red, int green, int blue, float size, int count, float radius) {
redstoneParticles(location, red, green, blue, size, count, radius, null);
}
/**
* Spawn colored redstone particles
*
* @param location area to spawn the particle in
* @param red red value 0-255
* @param green green value 0-255
* @param blue blue value 0-255
* @param size (1.13+) size of the particles
* @param count how many particles to spawn
* @param radius how far to spread out the particles from location
*/
public static void redstoneParticles(Location location, int red, int green, int blue, float size, int count, float radius, Player player) {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)) {
float xx = (float) (radius * (Math.random() - Math.random()));
float yy = (float) (radius * (Math.random() - Math.random()));
float zz = (float) (radius * (Math.random() - Math.random()));
if (player == null)
location.getWorld().spawnParticle(Particle.REDSTONE, location, count, xx, yy, zz, 1, new Particle.DustOptions(Color.fromBGR(blue, green, red), size));
else
player.spawnParticle(Particle.REDSTONE, location, count, xx, yy, zz, 1, new Particle.DustOptions(Color.fromBGR(blue, green, red), size));
} else if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) {
for (int i = 0; i < count; i++) {
float xx = (float) (radius * (Math.random() - Math.random()));
float yy = (float) (radius * (Math.random() - Math.random()));
float zz = (float) (radius * (Math.random() - Math.random()));
Location at = location.clone().add(xx, yy, zz);
if (player == null)
location.getWorld().spawnParticle(Particle.REDSTONE, at, 0, red / 255F, green / 255F, blue / 255F, size); // particle, location, count, red, green, blue, extra data
else
player.spawnParticle(Particle.REDSTONE, at, 0, red / 255F, green / 255F, blue / 255F, size); // particle, location, count, red, green, blue, extra data
}
} else {
// WE NEED MAGIC!
for (int i = 0; i < count; i++) {
float xx = (float) (radius * (Math.random() - Math.random()));
float yy = (float) (radius * (Math.random() - Math.random()));
float zz = (float) (radius * (Math.random() - Math.random()));
Location at = location.clone().add(xx, yy, zz);
LegacyParticleEffects.createParticle(at, LegacyParticleEffects.Type.REDSTONE,
red / 255F, green / 255F, blue / 255F, 1F,
0, player == null ? null : Collections.singletonList(player));
}
}
}
public static void bonemealSmoke(Location l) {
final org.bukkit.World w = l.getWorld();
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH_EAST);
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH);
w.playEffect(l, Effect.SMOKE, BlockFace.SOUTH_WEST);
w.playEffect(l, Effect.SMOKE, BlockFace.EAST);
w.playEffect(l, Effect.SMOKE, BlockFace.SELF);
w.playEffect(l, Effect.SMOKE, BlockFace.WEST);
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH_EAST);
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH);
w.playEffect(l, Effect.SMOKE, BlockFace.NORTH_WEST);
}
}

View File

@ -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();
}
}

View File

@ -1,85 +1,88 @@
package com.songoda.core.compatibility;
import org.bukkit.entity.EntityType;
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() {
{
put("xporb", "experience_orb");
put("xp_orb", "experience_orb");
put("leashknot", "leash_knot");
put("smallfireball", "small_fireball");
put("thrownenderpearl", "ender_pearl");
put("eyeofendersignal", "eye_of_ender");
put("eye_of_ender_signal", "eye_of_ender");
put("thrownexpbottle", "experience_bottle");
put("xp_bottle", "experience_bottle");
put("itemframe", "item_frame");
put("witherskull", "wither_skull");
put("primedtnt", "tnt");
put("fallingsand", "falling_block");
put("fireworksrocketentity", "firework_rocket");
put("fireworks_rocket", "firework_rocket");
put("spectralarrow", "spectral_arrow");
put("tippedarrow", "arrow");
put("shulkerbullet", "shulker_bullet");
put("dragonfireball", "dragon_fireball");
put("armorstand", "armor_stand");
put("minecartcommandblock", "command_block_minecart");
put("commandblock_minecart", "command_block_minecart");
put("minecartrideable", "minecart");
put("minecartchest", "chest_minecart");
put("minecartfurnace", "furnace_minecart");
put("minecarttnt", "tnt_minecart");
put("minecarthopper", "hopper_minecart");
put("minecartmobspawner", "spawner_minecart");
put("pigzombie", "zombie_pigman");
put("cavespider", "cave_spider");
put("lavaslime", "magma_cube");
put("enderdragon", "ender_dragon");
put("witherboss", "wither");
put("mushroomcow", "mooshroom");
put("snowman", "snow_golem");
put("ozelot", "ocelot");
put("villagergolem", "iron_golem");
put("villager_golem", "iron_golem");
put("entityhorse", "horse");
put("endercrystal", "end_crystal");
put("ender_crystal", "end_crystal");
}
};
static {
for (EntityType t : EntityType.values()) {
if (t.getName() != null) {
validTypes.put(t.getName().toLowerCase(), t);
}
}
}
public static EntityType minecraftToBukkit(String entity) {
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()) {
if (e.getValue().equals(entity) && (type = EntityType.fromName(legacyToModernTypes.get(e.getKey()))) != null) {
return type;
}
}
}
}
return type;
}
}
package com.songoda.core.compatibility;
import org.bukkit.entity.EntityType;
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() {
{
put("xporb", "experience_orb");
put("xp_orb", "experience_orb");
put("leashknot", "leash_knot");
put("smallfireball", "small_fireball");
put("thrownenderpearl", "ender_pearl");
put("eyeofendersignal", "eye_of_ender");
put("eye_of_ender_signal", "eye_of_ender");
put("thrownexpbottle", "experience_bottle");
put("xp_bottle", "experience_bottle");
put("itemframe", "item_frame");
put("witherskull", "wither_skull");
put("primedtnt", "tnt");
put("fallingsand", "falling_block");
put("fireworksrocketentity", "firework_rocket");
put("fireworks_rocket", "firework_rocket");
put("spectralarrow", "spectral_arrow");
put("tippedarrow", "arrow");
put("shulkerbullet", "shulker_bullet");
put("dragonfireball", "dragon_fireball");
put("armorstand", "armor_stand");
put("minecartcommandblock", "command_block_minecart");
put("commandblock_minecart", "command_block_minecart");
put("minecartrideable", "minecart");
put("minecartchest", "chest_minecart");
put("minecartfurnace", "furnace_minecart");
put("minecarttnt", "tnt_minecart");
put("minecarthopper", "hopper_minecart");
put("minecartmobspawner", "spawner_minecart");
put("pigzombie", "zombie_pigman");
put("cavespider", "cave_spider");
put("lavaslime", "magma_cube");
put("enderdragon", "ender_dragon");
put("witherboss", "wither");
put("mushroomcow", "mooshroom");
put("snowman", "snow_golem");
put("ozelot", "ocelot");
put("villagergolem", "iron_golem");
put("villager_golem", "iron_golem");
put("entityhorse", "horse");
put("endercrystal", "end_crystal");
put("ender_crystal", "end_crystal");
}
};
static {
for (EntityType t : EntityType.values()) {
if (t.getName() != null) {
validTypes.put(t.getName().toLowerCase(), t);
}
}
}
public static EntityType minecraftToBukkit(String entity) {
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()) {
if (e.getValue().equals(entity) && (type = EntityType.fromName(legacyToModernTypes.get(e.getKey()))) != null) {
return type;
}
}
}
}
return type;
}
}

View File

@ -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),

View File

@ -1,255 +1,256 @@
package com.songoda.core.compatibility;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Particle effects for servers 1.8 and below
*
* @author jascotty2
* @since 2019-08-23
*/
public class LegacyParticleEffects {
public static enum Type {
EXPLOSION_NORMAL("explode"),
EXPLOSION_LARGE("largeexplode"),
EXPLOSION_HUGE("hugeexplosion"),
FIREWORKS_SPARK("fireworksSpark"),
WATER_BUBBLE("bubble"),
WATER_SPLASH("splash"),
WATER_WAKE("wake", ServerVersion.V1_8),
SUSPENDED("suspended"),
SUSPENDED_DEPTH("depthsuspend"),
CRIT("crit"),
CRIT_MAGIC("magicCrit"),
SMOKE_NORMAL("smoke"),
SMOKE_LARGE("largesmoke"),
SPELL("spell"),
SPELL_INSTANT("instantSpell"),
SPELL_MOB("mobSpell"),
SPELL_MOB_AMBIENT("mobSpellAmbient"),
SPELL_WITCH("witchMagic"),
DRIP_WATER("dripWater"),
DRIP_LAVA("dripLava"),
VILLAGER_ANGRY("angryVillager"),
VILLAGER_HAPPY("happyVillager"),
TOWN_AURA("townaura"),
NOTE("note"),
PORTAL("portal"),
ENCHANTMENT_TABLE("enchantmenttable"),
FLAME("flame"),
LAVA("lava"),
FOOTSTEP("footstep"),
CLOUD("cloud"),
REDSTONE("reddust"),
SNOWBALL("snowballpoof"),
SNOW_SHOVEL("snowshovel"),
SLIME("slime"),
HEART("heart"),
BARRIER("barrier", ServerVersion.V1_8),
/**
* Used when a block is broken
*/
ITEM_CRACK("iconcrack_"),
BLOCK_CRACK("blockcrack_", ServerVersion.V1_8),
BLOCK_DUST("blockdust_", ServerVersion.V1_8),
WATER_DROP("droplet", ServerVersion.V1_8),
ITEM_TAKE("take", ServerVersion.V1_8),
MOB_APPEARANCE("mobappearance", ServerVersion.V1_8),
TOOL_BREAK("tilecrack_", ServerVersion.UNKNOWN, ServerVersion.V1_7);
public final String name;
public final ServerVersion minVersion;
public final ServerVersion maxVersion;
private Type(String name) {
this.name = name;
this.minVersion = ServerVersion.UNKNOWN;
this.maxVersion = null;
}
private Type(String name, ServerVersion minVersion) {
this.name = name;
this.minVersion = minVersion;
this.maxVersion = null;
}
private Type(String name, ServerVersion minVersion, ServerVersion maxVersion) {
this.name = name;
this.minVersion = minVersion;
this.maxVersion = maxVersion;
}
public static Type getById(String id) {
for (Type t : Type.values()) {
if (t.name.equalsIgnoreCase(id) || t.name().equalsIgnoreCase(id)) {
return t;
}
}
return null;
}
}
private static final String version = getNMSVersion();
private static boolean enabled = true;
private static Class mc_packetPlayOutWorldParticlesClazz;
private static Class cb_craftPlayerClazz;
private static Method cb_craftPlayer_getHandle;
private static Class mc_entityPlayerClazz;
private static Class mc_playerConnectionClazz;
private static Field mc_entityPlayer_playerConnection;
private static Class mc_PacketInterface;
private static Method mc_playerConnection_sendPacket;
private static Class mc_EnumParticle;
private static Method mc_EnumParticle_valueOf;
static {
try {
// lower versions use "Packet63WorldParticles"
if (!version.startsWith("v1_7") && !version.startsWith("v1_8")) {
mc_packetPlayOutWorldParticlesClazz = Class.forName("net.minecraft.server." + version + ".Packet63WorldParticles");
} else {
mc_packetPlayOutWorldParticlesClazz = Class.forName("net.minecraft.server." + version + ".PacketPlayOutWorldParticles");
}
cb_craftPlayerClazz = Class.forName("org.bukkit.craftbukkit." + version + ".entity.CraftPlayer");
cb_craftPlayer_getHandle = cb_craftPlayerClazz.getDeclaredMethod("getHandle");
mc_entityPlayerClazz = Class.forName("net.minecraft.server." + version + ".EntityPlayer");
mc_entityPlayer_playerConnection = mc_entityPlayerClazz.getDeclaredField("playerConnection");
mc_playerConnectionClazz = Class.forName("net.minecraft.server." + version + ".PlayerConnection");
mc_PacketInterface = Class.forName("net.minecraft.server." + version + ".Packet");
mc_playerConnection_sendPacket = mc_playerConnectionClazz.getDeclaredMethod("sendPacket", mc_PacketInterface);
if (version.startsWith("v1_8")) {
// Aren't worrying about anything after 1.8 in this class here
mc_EnumParticle = Class.forName("net.minecraft.server." + version + ".EnumParticle");
mc_EnumParticle_valueOf = mc_EnumParticle.getDeclaredMethod("valueOf", String.class);
}
} catch (Throwable ex) {
Logger.getAnonymousLogger().log(Level.WARNING, "Problem preparing particle packets (disabling further packets)", ex);
enabled = false;
}
}
private static String getNMSVersion() {
String ver = Bukkit.getServer().getClass().getPackage().getName();
return ver.substring(ver.lastIndexOf('.') + 1);
}
public static void createParticle(Location l, Type e) {
createParticle(l, e, 0F, 0F, 0F, 1, 0, null);
}
public static void createParticle(Location l, Type e, List<Player> localOnly) {
createParticle(l, e, 0F, 0F, 0F, 1, 0, localOnly);
}
public static void createParticle(Location l, Type e, float effectSpeed, int amountOfParticles) {
createParticle(l, e, 0F, 0F, 0F, effectSpeed, amountOfParticles, null);
}
/**
* @param l exact location to spawn the particle
* @param e particle effect type
* @param xx for notes, this is a value 0-1 for the color ([0-24]/24), for
* redstone this is the red value 0-1 ([0-255]/255).
* Otherwise this is the distance for particles to fly on the x-axis.
* @param yy for redstone this is the green value 0-1 ([0-255]/255)
* Otherwise this is the distance for particles to fly on the y-axis.
* @param zz for redstone this is the blue value 0-1 ([0-255]/255)
* Otherwise this is the distance for particles to fly on the z-axis.
* @param effectSpeed particle effect speed
* @param amountOfParticles extra particles to spawn (client-side)
* @param localOnly list of players to send the packets to, or null for all players
*/
public static void createParticle(Location l, Type e, float xx, float yy, float zz, float effectSpeed, int amountOfParticles, List<Player> localOnly) {
if (!enabled || e == null || effectSpeed < 0 || amountOfParticles < 0
|| !ServerVersion.isServerVersionAtLeast(e.minVersion)
|| (e.maxVersion != null && !ServerVersion.isServerVersionBelow(e.maxVersion))) {
return;
}
final int rangeSquared = 256; // apparently there is no way to override this (unless to make smaller, of course)
// collect a list of players to send this packet to
List<Player> sendTo = new ArrayList();
if (localOnly == null) {
for (Player p : l.getWorld().getPlayers()) {
if (p.getLocation().distanceSquared(l) <= rangeSquared) {
sendTo.add(p);
}
}
} else {
final World w = l.getWorld();
for (Player p : localOnly) {
if (p.getWorld() == w && p.getLocation().distanceSquared(l) <= rangeSquared) {
sendTo.add(p);
}
}
}
if (sendTo.isEmpty()) {
return;
}
try {
// Make an instance of the packet!
Object sPacket = mc_packetPlayOutWorldParticlesClazz.newInstance();
for (Field field : sPacket.getClass().getDeclaredFields()) {
// 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
if (version.startsWith("v1_8")) {
// 1.8 uses an Enum
field.set(sPacket, mc_EnumParticle_valueOf.invoke(null, e.name()));
} else {
field.set(sPacket, e.name);
}
} else if (fieldName.equals("b")) {
field.setFloat(sPacket, (float) l.getX()); // x
} else if (fieldName.equals("c")) {
field.setFloat(sPacket, (float) l.getY()); // y
} else if (fieldName.equals("d")) {
field.setFloat(sPacket, (float) l.getZ()); // z
} else if (fieldName.equals("e")) {
field.setFloat(sPacket, xx); // xOffset
} else if (fieldName.equals("f")) {
field.setFloat(sPacket, yy); // yOffset
} else if (fieldName.equals("g")) {
field.setFloat(sPacket, zz); // zOffset
} else if (fieldName.equals("h")) {
field.setFloat(sPacket, effectSpeed);
} else if (fieldName.equals("i")) {
field.setInt(sPacket, amountOfParticles);
}
/*
1.8 also includes other data:
j = boolean, set if view distance is increased from 256 to 65536
k = int[] for packet data (like block type for ITEM_CRACK)
*/
}
// send it on its way!
for (Player p : sendTo) {
sendPacket(sPacket, p);
}
} catch (Throwable ex) {
Logger.getAnonymousLogger().log(Level.WARNING, "Problem preparing a particle packet (disabling further packets)", ex);
enabled = false;
}
}
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);
}
}
package com.songoda.core.compatibility;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Particle effects for servers 1.8 and below
*
* @author jascotty2
* @since 2019-08-23
*/
public class LegacyParticleEffects {
public static enum Type {
EXPLOSION_NORMAL("explode"),
EXPLOSION_LARGE("largeexplode"),
EXPLOSION_HUGE("hugeexplosion"),
FIREWORKS_SPARK("fireworksSpark"),
WATER_BUBBLE("bubble"),
WATER_SPLASH("splash"),
WATER_WAKE("wake", ServerVersion.V1_8),
SUSPENDED("suspended"),
SUSPENDED_DEPTH("depthsuspend"),
CRIT("crit"),
CRIT_MAGIC("magicCrit"),
SMOKE_NORMAL("smoke"),
SMOKE_LARGE("largesmoke"),
SPELL("spell"),
SPELL_INSTANT("instantSpell"),
SPELL_MOB("mobSpell"),
SPELL_MOB_AMBIENT("mobSpellAmbient"),
SPELL_WITCH("witchMagic"),
DRIP_WATER("dripWater"),
DRIP_LAVA("dripLava"),
VILLAGER_ANGRY("angryVillager"),
VILLAGER_HAPPY("happyVillager"),
TOWN_AURA("townaura"),
NOTE("note"),
PORTAL("portal"),
ENCHANTMENT_TABLE("enchantmenttable"),
FLAME("flame"),
LAVA("lava"),
FOOTSTEP("footstep"),
CLOUD("cloud"),
REDSTONE("reddust"),
SNOWBALL("snowballpoof"),
SNOW_SHOVEL("snowshovel"),
SLIME("slime"),
HEART("heart"),
BARRIER("barrier", ServerVersion.V1_8),
/**
* Used when a block is broken
*/
ITEM_CRACK("iconcrack_"),
BLOCK_CRACK("blockcrack_", ServerVersion.V1_8),
BLOCK_DUST("blockdust_", ServerVersion.V1_8),
WATER_DROP("droplet", ServerVersion.V1_8),
ITEM_TAKE("take", ServerVersion.V1_8),
MOB_APPEARANCE("mobappearance", ServerVersion.V1_8),
TOOL_BREAK("tilecrack_", ServerVersion.UNKNOWN, ServerVersion.V1_7);
public final String name;
public final ServerVersion minVersion;
public final ServerVersion maxVersion;
private Type(String name) {
this.name = name;
this.minVersion = ServerVersion.UNKNOWN;
this.maxVersion = null;
}
private Type(String name, ServerVersion minVersion) {
this.name = name;
this.minVersion = minVersion;
this.maxVersion = null;
}
private Type(String name, ServerVersion minVersion, ServerVersion maxVersion) {
this.name = name;
this.minVersion = minVersion;
this.maxVersion = maxVersion;
}
public static Type getById(String id) {
for (Type t : Type.values()) {
if (t.name.equalsIgnoreCase(id) || t.name().equalsIgnoreCase(id)) {
return t;
}
}
return null;
}
}
private static final String version = getNMSVersion();
private static boolean enabled = true;
private static Class mc_packetPlayOutWorldParticlesClazz;
private static Class cb_craftPlayerClazz;
private static Method cb_craftPlayer_getHandle;
private static Class mc_entityPlayerClazz;
private static Class mc_playerConnectionClazz;
private static Field mc_entityPlayer_playerConnection;
private static Class mc_PacketInterface;
private static Method mc_playerConnection_sendPacket;
private static Class mc_EnumParticle;
private static Method mc_EnumParticle_valueOf;
static {
try {
// lower versions use "Packet63WorldParticles"
if (!version.startsWith("v1_7") && !version.startsWith("v1_8")) {
mc_packetPlayOutWorldParticlesClazz = Class.forName("net.minecraft.server." + version + ".Packet63WorldParticles");
} else {
mc_packetPlayOutWorldParticlesClazz = Class.forName("net.minecraft.server." + version + ".PacketPlayOutWorldParticles");
}
cb_craftPlayerClazz = Class.forName("org.bukkit.craftbukkit." + version + ".entity.CraftPlayer");
cb_craftPlayer_getHandle = cb_craftPlayerClazz.getDeclaredMethod("getHandle");
mc_entityPlayerClazz = Class.forName("net.minecraft.server." + version + ".EntityPlayer");
mc_entityPlayer_playerConnection = mc_entityPlayerClazz.getDeclaredField("playerConnection");
mc_playerConnectionClazz = Class.forName("net.minecraft.server." + version + ".PlayerConnection");
mc_PacketInterface = Class.forName("net.minecraft.server." + version + ".Packet");
mc_playerConnection_sendPacket = mc_playerConnectionClazz.getDeclaredMethod("sendPacket", mc_PacketInterface);
if (version.startsWith("v1_8")) {
// Aren't worrying about anything after 1.8 in this class here
mc_EnumParticle = Class.forName("net.minecraft.server." + version + ".EnumParticle");
mc_EnumParticle_valueOf = mc_EnumParticle.getDeclaredMethod("valueOf", String.class);
}
} catch (Throwable ex) {
Logger.getAnonymousLogger().log(Level.WARNING, "Problem preparing particle packets (disabling further packets)", ex);
enabled = false;
}
}
private static String getNMSVersion() {
String ver = Bukkit.getServer().getClass().getPackage().getName();
return ver.substring(ver.lastIndexOf('.') + 1);
}
public static void createParticle(Location l, Type e) {
createParticle(l, e, 0F, 0F, 0F, 1, 0, null);
}
public static void createParticle(Location l, Type e, List<Player> localOnly) {
createParticle(l, e, 0F, 0F, 0F, 1, 0, localOnly);
}
public static void createParticle(Location l, Type e, float effectSpeed, int amountOfParticles) {
createParticle(l, e, 0F, 0F, 0F, effectSpeed, amountOfParticles, null);
}
/**
* @param l exact location to spawn the particle
* @param e particle effect type
* @param xx for notes, this is a value 0-1 for the color ([0-24]/24), for
* redstone this is the red value 0-1 ([0-255]/255).
* Otherwise this is the distance for particles to fly on the x-axis.
* @param yy for redstone this is the green value 0-1 ([0-255]/255)
* Otherwise this is the distance for particles to fly on the y-axis.
* @param zz for redstone this is the blue value 0-1 ([0-255]/255)
* Otherwise this is the distance for particles to fly on the z-axis.
* @param effectSpeed particle effect speed
* @param amountOfParticles extra particles to spawn (client-side)
* @param localOnly list of players to send the packets to, or null for all players
*/
public static void createParticle(Location l, Type e, float xx, float yy, float zz, float effectSpeed, int amountOfParticles, List<Player> localOnly) {
if (!enabled || e == null || effectSpeed < 0 || amountOfParticles < 0
|| !ServerVersion.isServerVersionAtLeast(e.minVersion)
|| (e.maxVersion != null && !ServerVersion.isServerVersionBelow(e.maxVersion))) {
return;
}
final int rangeSquared = 256; // apparently there is no way to override this (unless to make smaller, of course)
// collect a list of players to send this packet to
List<Player> sendTo = new ArrayList();
if (localOnly == null) {
for (Player p : l.getWorld().getPlayers()) {
if (p.getLocation().distanceSquared(l) <= rangeSquared) {
sendTo.add(p);
}
}
} else {
final World w = l.getWorld();
for (Player p : localOnly) {
if (p.getWorld() == w && p.getLocation().distanceSquared(l) <= rangeSquared) {
sendTo.add(p);
}
}
}
if (sendTo.isEmpty()) {
return;
}
try {
// Make an instance of the packet!
Object sPacket = mc_packetPlayOutWorldParticlesClazz.newInstance();
for (Field field : sPacket.getClass().getDeclaredFields()) {
// 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
if (version.startsWith("v1_8")) {
// 1.8 uses an Enum
field.set(sPacket, mc_EnumParticle_valueOf.invoke(null, e.name()));
} else {
field.set(sPacket, e.name);
}
} else if (fieldName.equals("b")) {
field.setFloat(sPacket, (float) l.getX()); // x
} else if (fieldName.equals("c")) {
field.setFloat(sPacket, (float) l.getY()); // y
} else if (fieldName.equals("d")) {
field.setFloat(sPacket, (float) l.getZ()); // z
} else if (fieldName.equals("e")) {
field.setFloat(sPacket, xx); // xOffset
} else if (fieldName.equals("f")) {
field.setFloat(sPacket, yy); // yOffset
} else if (fieldName.equals("g")) {
field.setFloat(sPacket, zz); // zOffset
} else if (fieldName.equals("h")) {
field.setFloat(sPacket, effectSpeed);
} else if (fieldName.equals("i")) {
field.setInt(sPacket, amountOfParticles);
}
/*
1.8 also includes other data:
j = boolean, set if view distance is increased from 256 to 65536
k = int[] for packet data (like block type for ITEM_CRACK)
*/
}
// send it on its way!
for (Player p : sendTo) {
sendPacket(sPacket, p);
}
} catch (Throwable ex) {
Logger.getAnonymousLogger().log(Level.WARNING, "Problem preparing a particle packet (disabling further packets)", ex);
enabled = false;
}
}
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);
}
}

View File

@ -1,50 +1,49 @@
package com.songoda.core.compatibility;
import org.bukkit.potion.PotionEffectType;
import java.util.HashMap;
import java.util.Random;
public class LegacyPotionEffects {
private LegacyPotionEffects() {
}
protected final static Random rand = new Random();
private final static HashMap<Integer, String> potionEffectNames = new HashMap() {
{
put(PotionEffectType.SPEED.getId(), "Speed");
put(PotionEffectType.SLOW.getId(), "Slowness");
put(PotionEffectType.FAST_DIGGING.getId(), "Haste");
put(PotionEffectType.SLOW_DIGGING.getId(), "Mining Fatigue");
put(PotionEffectType.INCREASE_DAMAGE.getId(), "Strength");
put(PotionEffectType.WEAKNESS.getId(), "Weakness");
put(PotionEffectType.HEAL.getId(), "Instant Health");
put(PotionEffectType.HARM.getId(), "Instant Damage");
put(PotionEffectType.JUMP.getId(), "Jump Boost");
put(PotionEffectType.CONFUSION.getId(), "Nausea");
put(PotionEffectType.REGENERATION.getId(), "Regeneration");
put(PotionEffectType.DAMAGE_RESISTANCE.getId(), "Resistance");
put(PotionEffectType.FIRE_RESISTANCE.getId(), "Fire Resistance");
put(PotionEffectType.WATER_BREATHING.getId(), "Water Breathing");
put(PotionEffectType.INVISIBILITY.getId(), "Invisibility");
put(PotionEffectType.BLINDNESS.getId(), "Blindness");
put(PotionEffectType.NIGHT_VISION.getId(), "Night Vision");
put(PotionEffectType.HUNGER.getId(), "Hunger");
put(PotionEffectType.POISON.getId(), "Poison");
put(PotionEffectType.WITHER.getId(), "Wither");
put(PotionEffectType.HEALTH_BOOST.getId(), "Health Boost");
put(PotionEffectType.ABSORPTION.getId(), "Absorption");
put(PotionEffectType.SATURATION.getId(), "Saturation");
}
};
public static String getEffectName(PotionEffectType e) {
if (e == null) {
return "null";
}
final String n = potionEffectNames.get(e.getId());
return n == null ? e.getName() : n;
}
}
package com.songoda.core.compatibility;
import org.bukkit.potion.PotionEffectType;
import java.util.HashMap;
import java.util.Random;
public class LegacyPotionEffects {
private LegacyPotionEffects() {
}
protected final static Random rand = new Random();
private final static HashMap<Integer, String> potionEffectNames = new HashMap() {
{
put(PotionEffectType.SPEED.getId(), "Speed");
put(PotionEffectType.SLOW.getId(), "Slowness");
put(PotionEffectType.FAST_DIGGING.getId(), "Haste");
put(PotionEffectType.SLOW_DIGGING.getId(), "Mining Fatigue");
put(PotionEffectType.INCREASE_DAMAGE.getId(), "Strength");
put(PotionEffectType.WEAKNESS.getId(), "Weakness");
put(PotionEffectType.HEAL.getId(), "Instant Health");
put(PotionEffectType.HARM.getId(), "Instant Damage");
put(PotionEffectType.JUMP.getId(), "Jump Boost");
put(PotionEffectType.CONFUSION.getId(), "Nausea");
put(PotionEffectType.REGENERATION.getId(), "Regeneration");
put(PotionEffectType.DAMAGE_RESISTANCE.getId(), "Resistance");
put(PotionEffectType.FIRE_RESISTANCE.getId(), "Fire Resistance");
put(PotionEffectType.WATER_BREATHING.getId(), "Water Breathing");
put(PotionEffectType.INVISIBILITY.getId(), "Invisibility");
put(PotionEffectType.BLINDNESS.getId(), "Blindness");
put(PotionEffectType.NIGHT_VISION.getId(), "Night Vision");
put(PotionEffectType.HUNGER.getId(), "Hunger");
put(PotionEffectType.POISON.getId(), "Poison");
put(PotionEffectType.WITHER.getId(), "Wither");
put(PotionEffectType.HEALTH_BOOST.getId(), "Health Boost");
put(PotionEffectType.ABSORPTION.getId(), "Absorption");
put(PotionEffectType.SATURATION.getId(), "Saturation");
}
};
public static String getEffectName(PotionEffectType e) {
if (e == null) {
return "null";
}
final String n = potionEffectNames.get(e.getId());
return n == null ? e.getName() : n;
}
}

View File

@ -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;
}

View File

@ -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,49 +105,57 @@ 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);
Class otherPluginInfo = testSubject.getClass();
Method otherPluginInfo_getJavaPlugin = otherPluginInfo.getMethod("getJavaPlugin");
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),
(int) otherPluginInfo_getSongodaId.invoke(other),
(String) otherPluginInfo_getCoreIcon.invoke(other),
otherPluginInfo_getCoreLibraryVersion != null ? (String) otherPluginInfo_getCoreLibraryVersion.invoke(other) : "?");
}
}
// 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);
Class otherPluginInfo = testSubject.getClass();
Method otherPluginInfo_getJavaPlugin = otherPluginInfo.getMethod("getJavaPlugin");
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),
(int) otherPluginInfo_getSongodaId.invoke(other),
(String) otherPluginInfo_getCoreIcon.invoke(other),
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);

View File

@ -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,15 +179,15 @@ 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;
}
}
Locale l = Locale.loadLocale(this, localeName);
if (l != null) {
locale = l;
return true;
}
return false;
}
protected void shutdownDataManager(DataManagerAbstract dataManager) {

View File

@ -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,15 +73,17 @@ 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;
addMessage(match2, color, stackedCodes);
if (match2.length() != 0) {
addMessage(match2, color, stackedCodes);
}
}
}
@ -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,11 +141,14 @@ 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);
@ -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;
}
}

View File

@ -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),

View File

@ -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());
}
}

View File

@ -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<>();

View File

@ -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) {
pcmd.setExecutor(this);
pcmd.setTabCompleter(this);
} else {
if (pcmd == null) {
plugin.getLogger().warning("Failed to register command: /" + cmd);
return;
}
pcmd.setExecutor(this);
pcmd.setTabCompleter(this);
});
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()))) {
// 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);
}
}
// 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()))) {
// 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();
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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<>();

View File

@ -1,108 +1,116 @@
package com.songoda.core.configuration;
import com.songoda.core.configuration.ConfigFormattingRules.CommentStyle;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* A comment for a configuration key
*
* @author jascotty2
* @since 2019-08-28
*/
public class Comment {
final List<String> lines = new ArrayList();
CommentStyle commentStyle = null;
public Comment() {
}
public Comment(String... lines) {
this(null, Arrays.asList(lines));
}
public Comment(List<String> lines) {
this(null, lines);
}
public Comment(CommentStyle commentStyle, String... lines) {
this(commentStyle, Arrays.asList(lines));
}
public Comment(CommentStyle commentStyle, List<String> lines) {
this.commentStyle = commentStyle;
if (lines != null) {
lines.forEach(s -> this.lines.addAll(Arrays.asList(s.split("\n"))));
}
}
public CommentStyle getCommentStyle() {
return commentStyle;
}
public void setCommentStyle(CommentStyle commentStyle) {
this.commentStyle = commentStyle;
}
public List<String> getLines() {
return lines;
}
@Override
public String toString() {
return lines.isEmpty() ? "" : lines.stream().collect(Collectors.joining("\n"));
}
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
+ (new String(new char[borderSpacing - style.spacePrefixTop.length() - style.spaceSuffixTop.length()])).replace('\0', style.spaceCharTop)
+ style.spaceSuffixTop + "#\n");
}
} 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) {
output.write((new String(new char[offset])).replace('\0', ' ')
+ "#" + style.spacePrefixBottom
+ (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");
}
}
}
package com.songoda.core.configuration;
import com.songoda.core.configuration.ConfigFormattingRules.CommentStyle;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* A comment for a configuration key
*
* @author jascotty2
* @since 2019-08-28
*/
public class Comment {
final List<String> lines = new ArrayList();
CommentStyle commentStyle = null;
public Comment() {
}
public Comment(String... lines) {
this(null, Arrays.asList(lines));
}
public Comment(List<String> lines) {
this(null, lines);
}
public Comment(CommentStyle commentStyle, String... lines) {
this(commentStyle, Arrays.asList(lines));
}
public Comment(CommentStyle commentStyle, List<String> lines) {
this.commentStyle = commentStyle;
if (lines != null) {
lines.forEach(s -> this.lines.addAll(Arrays.asList(s.split("\n"))));
}
}
public CommentStyle getCommentStyle() {
return commentStyle;
}
public void setCommentStyle(CommentStyle commentStyle) {
this.commentStyle = commentStyle;
}
public List<String> getLines() {
return lines;
}
@Override
public String toString() {
return lines.isEmpty() ? "" : lines.stream().collect(Collectors.joining("\n"));
}
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
+ (new String(new char[borderSpacing - style.spacePrefixTop.length() - style.spaceSuffixTop.length()])).replace('\0', style.spaceCharTop)
+ style.spaceSuffixTop + "#\n");
}
} 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) {
output.write((new String(new char[offset])).replace('\0', ' ')
+ "#" + style.spacePrefixBottom
+ (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");
}
}
}

View File

@ -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();

View File

@ -1,273 +1,273 @@
package com.songoda.core.configuration;
import com.songoda.core.compatibility.CompatibleMaterial;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
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;
}
public Config getCoreConfig() {
return config;
}
@Override
public String saveToString() {
return config.saveToString();
}
@Override
public void loadFromString(String string) throws InvalidConfigurationException {
config.loadFromString(string);
}
@Override
protected String buildHeader() {
return "#" + config.getHeader().stream().collect(Collectors.joining("\n#"));
}
@Override
public ConfigOptionsAdapter options() {
return new ConfigOptionsAdapter(config);
}
@Override
public Set<String> getKeys(boolean deep) {
return config.getKeys(deep);
}
@Override
public Map<String, Object> getValues(boolean deep) {
return config.getValues(deep);
}
@Override
public boolean contains(String path) {
return config.contains(path);
}
@Override
public boolean isSet(String path) {
return config.isSet(path);
}
@Override
public String getCurrentPath() {
return config.getCurrentPath();
}
@Override
public String getName() {
return config.getName();
}
@Override
public Configuration getRoot() {
return config;
}
@Override
public ConfigurationSection getParent() {
return null;
}
@Override
public void addDefault(String path, Object value) {
config.addDefault(path, value);
}
@Override
public ConfigurationSection getDefaultSection() {
return config.getDefaultSection();
}
@Override
public void set(String path, Object value) {
config.set(path, value);
}
@Override
public Object get(String path) {
return config.get(path);
}
@Override
public Object get(String path, Object def) {
return config.get(path, def);
}
@Override
public ConfigurationSection createSection(String path) {
return config.createSection(path);
}
@Override
public ConfigurationSection createSection(String path, Map<?, ?> map) {
return config.createSection(path, map);
}
// Other non-FileConfiguration methods
@NotNull
public ConfigSection createDefaultSection(@NotNull String path) {
return config.createDefaultSection(path);
}
@NotNull
public ConfigSection createDefaultSection(@NotNull String path, String... comment) {
return config.createDefaultSection(path, comment);
}
@NotNull
public ConfigSection createDefaultSection(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
return config.createDefaultSection(path, commentStyle, comment);
}
@NotNull
public ConfigSection setComment(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... lines) {
return config.setComment(path, commentStyle, lines);
}
@NotNull
public ConfigSection setComment(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> lines) {
return config.setComment(path, commentStyle, lines);
}
@NotNull
public ConfigSection setDefaultComment(@NotNull String path, String... lines) {
return config.setDefaultComment(path, lines);
}
@NotNull
public ConfigSection setDefaultComment(@NotNull String path, @Nullable List<String> lines) {
return config.setDefaultComment(path, lines);
}
@NotNull
public ConfigSection setDefaultComment(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... lines) {
return config.setDefaultComment(path, commentStyle, lines);
}
@NotNull
public ConfigSection setDefaultComment(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> lines) {
return config.setDefaultComment(path, commentStyle, lines);
}
@Nullable
public Comment getComment(@NotNull String path) {
return config.getComment(path);
}
@Nullable
public String getCommentString(@NotNull String path) {
return config.getCommentString(path);
}
@NotNull
public List<ConfigSection> getSections(String path) {
return config.getSections(path);
}
@NotNull
public ConfigSection set(@NotNull String path, @Nullable Object value, String... comment) {
return config.set(path, value, comment);
}
@NotNull
public ConfigSection set(@NotNull String path, @Nullable Object value, List<String> comment) {
return config.set(path, value, comment);
}
@NotNull
public ConfigSection set(@NotNull String path, @Nullable Object value, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
return config.set(path, value, commentStyle, comment);
}
@NotNull
public ConfigSection set(@NotNull String path, @Nullable Object value, @Nullable ConfigFormattingRules.CommentStyle commentStyle, List<String> comment) {
return config.set(path, value, commentStyle, comment);
}
@NotNull
public ConfigSection setDefault(@NotNull String path, @Nullable Object value) {
return config.setDefault(path, value);
}
@NotNull
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, String... comment) {
return config.setDefault(path, value, comment);
}
@NotNull
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, List<String> comment) {
return config.setDefault(path, value, comment);
}
@NotNull
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
return config.setDefault(path, value, commentStyle, comment);
}
@NotNull
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, ConfigFormattingRules.CommentStyle commentStyle, List<String> comment) {
return config.setDefault(path, value, commentStyle, comment);
}
@NotNull
public ConfigSection createSection(@NotNull String path, String... comment) {
return config.createSection(path, comment);
}
@NotNull
public ConfigSection createSection(@NotNull String path, @Nullable List<String> comment) {
return config.createSection(path, comment);
}
@NotNull
public ConfigSection createSection(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
return config.createSection(path, commentStyle, comment);
}
@NotNull
public ConfigSection createSection(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> comment) {
return config.createSection(path, commentStyle, comment);
}
public char getChar(@NotNull String path) {
return config.getChar(path);
}
public char getChar(@NotNull String path, char def) {
return config.getChar(path, def);
}
@Nullable
public CompatibleMaterial getMaterial(@NotNull String path) {
return config.getMaterial(path);
}
@Nullable
public CompatibleMaterial getMaterial(@NotNull String path, @Nullable CompatibleMaterial def) {
return config.getMaterial(path, def);
}
@NotNull
public ConfigSection getOrCreateConfigurationSection(@NotNull String path) {
return config.getOrCreateConfigurationSection(path);
}
}
package com.songoda.core.configuration;
import com.songoda.core.compatibility.CompatibleMaterial;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Map;
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;
}
public Config getCoreConfig() {
return config;
}
@Override
public String saveToString() {
return config.saveToString();
}
@Override
public void loadFromString(String string) throws InvalidConfigurationException {
config.loadFromString(string);
}
@Override
protected String buildHeader() {
return "#" + config.getHeader().stream().collect(Collectors.joining("\n#"));
}
@Override
public ConfigOptionsAdapter options() {
return new ConfigOptionsAdapter(config);
}
@Override
public Set<String> getKeys(boolean deep) {
return config.getKeys(deep);
}
@Override
public Map<String, Object> getValues(boolean deep) {
return config.getValues(deep);
}
@Override
public boolean contains(String path) {
return config.contains(path);
}
@Override
public boolean isSet(String path) {
return config.isSet(path);
}
@Override
public String getCurrentPath() {
return config.getCurrentPath();
}
@Override
public String getName() {
return config.getName();
}
@Override
public Configuration getRoot() {
return config;
}
@Override
public ConfigurationSection getParent() {
return null;
}
@Override
public void addDefault(String path, Object value) {
config.addDefault(path, value);
}
@Override
public ConfigurationSection getDefaultSection() {
return config.getDefaultSection();
}
@Override
public void set(String path, Object value) {
config.set(path, value);
}
@Override
public Object get(String path) {
return config.get(path);
}
@Override
public Object get(String path, Object def) {
return config.get(path, def);
}
@Override
public ConfigurationSection createSection(String path) {
return config.createSection(path);
}
@Override
public ConfigurationSection createSection(String path, Map<?, ?> map) {
return config.createSection(path, map);
}
// Other non-FileConfiguration methods
@NotNull
public ConfigSection createDefaultSection(@NotNull String path) {
return config.createDefaultSection(path);
}
@NotNull
public ConfigSection createDefaultSection(@NotNull String path, String... comment) {
return config.createDefaultSection(path, comment);
}
@NotNull
public ConfigSection createDefaultSection(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
return config.createDefaultSection(path, commentStyle, comment);
}
@NotNull
public ConfigSection setComment(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... lines) {
return config.setComment(path, commentStyle, lines);
}
@NotNull
public ConfigSection setComment(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> lines) {
return config.setComment(path, commentStyle, lines);
}
@NotNull
public ConfigSection setDefaultComment(@NotNull String path, String... lines) {
return config.setDefaultComment(path, lines);
}
@NotNull
public ConfigSection setDefaultComment(@NotNull String path, @Nullable List<String> lines) {
return config.setDefaultComment(path, lines);
}
@NotNull
public ConfigSection setDefaultComment(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, String... lines) {
return config.setDefaultComment(path, commentStyle, lines);
}
@NotNull
public ConfigSection setDefaultComment(@NotNull String path, ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> lines) {
return config.setDefaultComment(path, commentStyle, lines);
}
@Nullable
public Comment getComment(@NotNull String path) {
return config.getComment(path);
}
@Nullable
public String getCommentString(@NotNull String path) {
return config.getCommentString(path);
}
@NotNull
public List<ConfigSection> getSections(String path) {
return config.getSections(path);
}
@NotNull
public ConfigSection set(@NotNull String path, @Nullable Object value, String... comment) {
return config.set(path, value, comment);
}
@NotNull
public ConfigSection set(@NotNull String path, @Nullable Object value, List<String> comment) {
return config.set(path, value, comment);
}
@NotNull
public ConfigSection set(@NotNull String path, @Nullable Object value, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
return config.set(path, value, commentStyle, comment);
}
@NotNull
public ConfigSection set(@NotNull String path, @Nullable Object value, @Nullable ConfigFormattingRules.CommentStyle commentStyle, List<String> comment) {
return config.set(path, value, commentStyle, comment);
}
@NotNull
public ConfigSection setDefault(@NotNull String path, @Nullable Object value) {
return config.setDefault(path, value);
}
@NotNull
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, String... comment) {
return config.setDefault(path, value, comment);
}
@NotNull
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, List<String> comment) {
return config.setDefault(path, value, comment);
}
@NotNull
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
return config.setDefault(path, value, commentStyle, comment);
}
@NotNull
public ConfigSection setDefault(@NotNull String path, @Nullable Object value, ConfigFormattingRules.CommentStyle commentStyle, List<String> comment) {
return config.setDefault(path, value, commentStyle, comment);
}
@NotNull
public ConfigSection createSection(@NotNull String path, String... comment) {
return config.createSection(path, comment);
}
@NotNull
public ConfigSection createSection(@NotNull String path, @Nullable List<String> comment) {
return config.createSection(path, comment);
}
@NotNull
public ConfigSection createSection(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, String... comment) {
return config.createSection(path, commentStyle, comment);
}
@NotNull
public ConfigSection createSection(@NotNull String path, @Nullable ConfigFormattingRules.CommentStyle commentStyle, @Nullable List<String> comment) {
return config.createSection(path, commentStyle, comment);
}
public char getChar(@NotNull String path) {
return config.getChar(path);
}
public char getChar(@NotNull String path, char def) {
return config.getChar(path, def);
}
@Nullable
public CompatibleMaterial getMaterial(@NotNull String path) {
return config.getMaterial(path);
}
@Nullable
public CompatibleMaterial getMaterial(@NotNull String path, @Nullable CompatibleMaterial def) {
return config.getMaterial(path, def);
}
@NotNull
public ConfigSection getOrCreateConfigurationSection(@NotNull String path) {
return config.getOrCreateConfigurationSection(path);
}
}

View File

@ -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;
}
}

View File

@ -1,71 +1,72 @@
package com.songoda.core.configuration;
import org.bukkit.configuration.file.FileConfigurationOptions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class ConfigOptionsAdapter extends FileConfigurationOptions {
final ConfigSection config;
public ConfigOptionsAdapter(ConfigSection config) {
super(config);
this.config = config;
}
public Config getConfig() {
return (Config) config.root;
}
@NotNull
@Override
public ConfigFileConfigurationAdapter configuration() {
return new ConfigFileConfigurationAdapter((Config) config.root);
}
@NotNull
@Override
public ConfigOptionsAdapter copyDefaults(boolean value) {
// we always copy new values
return this;
}
@NotNull
@Override
public ConfigOptionsAdapter pathSeparator(char value) {
((Config) config.root).setPathSeparator(value);
return this;
}
@NotNull
@Override
public ConfigOptionsAdapter header(@Nullable String value) {
if (value == null) {
((Config) config.root).setHeader((List) null);
} else {
((Config) config.root).setHeader(value.split("\n"));
}
return this;
}
@NotNull
@Override
public ConfigOptionsAdapter copyHeader(boolean value) {
if (!value) {
((Config) config.root).setHeader((List) null);
}
return this;
}
public int indent() {
return ((Config) config.root).getIndent();
}
@NotNull
public ConfigOptionsAdapter indent(int value) {
((Config) config.root).setIndent(value);
return this;
}
}
package com.songoda.core.configuration;
import org.bukkit.configuration.file.FileConfigurationOptions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class ConfigOptionsAdapter extends FileConfigurationOptions {
final ConfigSection config;
public ConfigOptionsAdapter(ConfigSection config) {
super(config);
this.config = config;
}
public Config getConfig() {
return (Config) config.root;
}
@NotNull
@Override
public ConfigFileConfigurationAdapter configuration() {
return new ConfigFileConfigurationAdapter((Config) config.root);
}
@NotNull
@Override
public ConfigOptionsAdapter copyDefaults(boolean value) {
// we always copy new values
return this;
}
@NotNull
@Override
public ConfigOptionsAdapter pathSeparator(char value) {
((Config) config.root).setPathSeparator(value);
return this;
}
@NotNull
@Override
public ConfigOptionsAdapter header(@Nullable String value) {
if (value == null) {
((Config) config.root).setHeader((List) null);
} else {
((Config) config.root).setHeader(value.split("\n"));
}
return this;
}
@NotNull
@Override
public ConfigOptionsAdapter copyHeader(boolean value) {
if (!value) {
((Config) config.root).setHeader((List) null);
}
return this;
}
public int indent() {
return ((Config) config.root).getIndent();
}
@NotNull
public ConfigOptionsAdapter indent(int value) {
((Config) config.root).setIndent(value);
return this;
}
}

View File

@ -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);
}

View File

@ -1,35 +1,30 @@
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
*/
public abstract T getKey();
/**
* @return a unique identifier for saving this value with
*/
public abstract String getConfigKey();
/**
* Save this data to a ConfigurationSection
*
* @param sec
*/
public abstract void saveToSection(ConfigurationSection sec);
/**
* @return true if this data has changed from the state saved to file
*/
public boolean hasChanged();
/**
* Mark this data as needing a save or not
*
* @param isChanged
*/
public void setChanged(boolean isChanged);
}
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
*/
public abstract T getKey();
/**
* @return a unique identifier for saving this value with
*/
public abstract String getConfigKey();
/**
* Save this data to a ConfigurationSection
*/
public abstract void saveToSection(ConfigurationSection sec);
/**
* @return true if this data has changed from the state saved to file
*/
public boolean hasChanged();
/**
* Mark this data as needing a save or not
*/
public void setChanged(boolean isChanged);
}

View File

@ -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();

View File

@ -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,50 +277,59 @@ 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
|| value instanceof Integer
|| value instanceof Float
|| value instanceof Double);
return value != null && (value instanceof Long
|| value instanceof Integer
|| value instanceof Float
|| value instanceof Double);
}
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));
}
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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", "*/*");

View File

@ -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;
}

View File

@ -1,6 +1,5 @@
package com.songoda.core.core;
public interface PluginInfoModule {
void run(PluginInfo plugin);
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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,17 +38,19 @@ 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 {
setButton(i, GuiUtils.createButtonItem(plugin.icon != null ? plugin.icon : CompatibleMaterial.STONE,
ChatColor.GOLD + plugin.getJavaPlugin().getName(),
ChatColor.GRAY + "Installed Version: " + plugin.getJavaPlugin().getDescription().getVersion(),
"",
ChatColor.GOLD + "Click for the marketplace page link.",
ChatColor.GOLD + "Right Click to edit plugin settings."
),
ClickType.LEFT, (event) -> event.player.sendMessage(plugin.getMarketplaceLink()));
setAction(i, ClickType.RIGHT, (event) -> event.manager.showGUI(event.player, new PluginConfigGui(plugin.getJavaPlugin(), event.gui)));
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(),
"",
ChatColor.GOLD + "Click for the marketplace page link.",
ChatColor.GOLD + "Right Click to edit plugin settings."
),
ClickType.LEFT, (event) -> event.player.sendMessage(plugin.getMarketplaceLink()));
setAction(i, ClickType.RIGHT, (event) -> event.manager.showGUI(event.player, new PluginConfigGui(plugin.getJavaPlugin(), event.gui)));
}
}
}

View File

@ -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);
}
});
}

View File

@ -4,7 +4,6 @@ import java.sql.Connection;
import java.sql.SQLException;
public abstract class DataMigration {
private final int revision;
public DataMigration(int revision) {

View File

@ -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);

View File

@ -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
*

View File

@ -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;

View File

@ -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();
}
}

View File

@ -1,128 +1,131 @@
package com.songoda.core.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.methods.Clickable;
import com.songoda.core.nms.NmsManager;
import com.songoda.core.nms.anvil.AnvilCore;
import com.songoda.core.nms.anvil.CustomAnvil;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
/**
* Anvil GUI for text prompts
*
* @author jascotty2
* @since 2019-09-15
*/
public class AnvilGui extends Gui {
final Player player;
CustomAnvil anvil;
List<String> endPrompt = null;
public AnvilGui(Player player) {
this.player = player;
}
public AnvilGui(Player player, Gui parent) {
super(parent);
this.player = player;
}
@NotNull
public AnvilGui setAction(@Nullable Clickable action) {
return (AnvilGui) setAction(2, action);
}
@NotNull
public AnvilGui setAction(@Nullable ClickType type, @Nullable Clickable action) {
return (AnvilGui) setAction(2, type, action);
}
protected void open() {
anvil.open();
}
public AnvilGui setInput(ItemStack item) {
return (AnvilGui) this.setItem(0, item);
}
public ItemStack getInput() {
return this.getItem(0);
}
public AnvilGui setOutput(ItemStack item) {
return (AnvilGui) this.setItem(2, item);
}
public AnvilGui setOutputPrompt(String str) {
endPrompt = Arrays.asList(str);
return this;
}
public AnvilGui setOutputPrompt(String... str) {
endPrompt = Arrays.asList(str);
return this;
}
public AnvilGui setOutputPrompt(List<String> str) {
endPrompt = str;
return this;
}
void updateOutputPrompt() {
final ItemStack in;
if (endPrompt != null && (in = cellItems.get(0)) != null) {
setItem(2, GuiUtils.createButtonItem(in, endPrompt));
}
}
public ItemStack getOutput() {
return this.getItem(2);
}
public String getInputText() {
return anvil != null ? anvil.getRenameText() : null;
}
@NotNull
@Override
protected Inventory generateInventory(@NotNull GuiManager manager) {
this.guiManager = manager;
createInventory();
ItemStack item;
if ((item = cellItems.get(0)) != null) {
inventory.setItem(0, item);
} else if ((item = cellItems.get(1)) != null) {
inventory.setItem(1, item);
} else if (!acceptsItems) {
cellItems.put(0, item = GuiUtils.createButtonItem(CompatibleMaterial.PAPER, " ", " "));
inventory.setItem(0, item);
}
if ((item = cellItems.get(2)) != null) {
inventory.setItem(2, item);
}
return inventory;
}
@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);
}
}
}
package com.songoda.core.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.methods.Clickable;
import com.songoda.core.nms.NmsManager;
import com.songoda.core.nms.anvil.AnvilCore;
import com.songoda.core.nms.anvil.CustomAnvil;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
/**
* Anvil GUI for text prompts
*
* @author jascotty2
* @since 2019-09-15
*/
public class AnvilGui extends Gui {
final Player player;
CustomAnvil anvil;
List<String> endPrompt = null;
public AnvilGui(Player player) {
this.player = player;
}
public AnvilGui(Player player, Gui parent) {
super(parent);
this.player = player;
}
@NotNull
public AnvilGui setAction(@Nullable Clickable action) {
return (AnvilGui) setAction(2, action);
}
@NotNull
public AnvilGui setAction(@Nullable ClickType type, @Nullable Clickable action) {
return (AnvilGui) setAction(2, type, action);
}
protected void open() {
anvil.open();
}
public AnvilGui setInput(ItemStack item) {
return (AnvilGui) this.setItem(0, item);
}
public ItemStack getInput() {
return this.getItem(0);
}
public AnvilGui setOutput(ItemStack item) {
return (AnvilGui) this.setItem(2, item);
}
public AnvilGui setOutputPrompt(String str) {
endPrompt = Arrays.asList(str);
return this;
}
public AnvilGui setOutputPrompt(String... str) {
endPrompt = Arrays.asList(str);
return this;
}
public AnvilGui setOutputPrompt(List<String> str) {
endPrompt = str;
return this;
}
void updateOutputPrompt() {
final ItemStack in;
if (endPrompt != null && (in = cellItems.get(0)) != null) {
setItem(2, GuiUtils.createButtonItem(in, endPrompt));
}
}
public ItemStack getOutput() {
return this.getItem(2);
}
public String getInputText() {
return anvil != null ? anvil.getRenameText() : null;
}
@NotNull
@Override
protected Inventory generateInventory(@NotNull GuiManager manager) {
this.guiManager = manager;
createInventory();
ItemStack item;
if ((item = cellItems.get(0)) != null) {
inventory.setItem(0, item);
} else if ((item = cellItems.get(1)) != null) {
inventory.setItem(1, item);
} else if (!acceptsItems) {
cellItems.put(0, item = GuiUtils.createButtonItem(CompatibleMaterial.PAPER, " ", " "));
inventory.setItem(0, item);
}
if ((item = cellItems.get(2)) != null) {
inventory.setItem(2, item);
}
return inventory;
}
@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);
}
}
}

View File

@ -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,29 +956,39 @@ 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
customizedButtons.put(key, customButton);
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
customizedButtons.put(key, customButton);
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
customizedButtons.put(key, mirrorFill);
return;
}
customizedButtons.put(key, mirrorFill);
}
public boolean isButtonCustomized(String key) {

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -1,40 +1,39 @@
package com.songoda.core.gui;
import org.bukkit.Bukkit;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
/**
* Internal class for marking an inventory as a GUI inventory
*
* @author jascotty2
* @since 2019-08-25
*/
class GuiHolder implements InventoryHolder {
final Gui gui;
final GuiManager manager;
public GuiHolder(GuiManager manager, Gui gui) {
this.gui = gui;
this.manager = manager;
}
@Override
public Inventory getInventory() {
return gui.inventory;
}
public Gui getGUI() {
return gui;
}
public Inventory newInventory(int size, String title) {
return Bukkit.createInventory(this, size, title);
}
public Inventory newInventory(InventoryType type, String title) {
return Bukkit.createInventory(this, type, title);
}
}
package com.songoda.core.gui;
import org.bukkit.Bukkit;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
/**
* Internal class for marking an inventory as a GUI inventory
*
* @author jascotty2
* @since 2019-08-25
*/
class GuiHolder implements InventoryHolder {
final Gui gui;
final GuiManager manager;
public GuiHolder(GuiManager manager, Gui gui) {
this.gui = gui;
this.manager = manager;
}
@Override
public Inventory getInventory() {
return gui.inventory;
}
public Gui getGUI() {
return gui;
}
public Inventory newInventory(int size, String title) {
return Bukkit.createInventory(this, size, title);
}
public Inventory newInventory(InventoryType type, String title) {
return Bukkit.createInventory(this, type, title);
}
}

View File

@ -1,275 +1,303 @@
package com.songoda.core.gui;
import com.songoda.core.compatibility.ClientVersion;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ServerVersion;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* Manages events for GUI screens
*
* @author jascotty2
* @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);
final Map<Player, Gui> openInventories = new HashMap();
private final Object lock = new Object();
private boolean initialized = false;
private boolean shutdown = false;
public GuiManager(Plugin plugin) {
this.plugin = plugin;
}
public Plugin getPlugin() {
return plugin;
}
/**
* Initialize the GUI handlers
*/
public void init() {
Bukkit.getPluginManager().registerEvents(listener, plugin);
initialized = true;
shutdown = false;
}
/**
* Check to see if this manager cannot open any more GUI screens
*
* @return true if the owning plugin has shutdown
*/
public boolean isClosed() {
return shutdown;
}
/**
* Create and display a GUI interface for a player
*
* @param player player to open the interface for
* @param gui GUI to use
*/
public void showGUI(Player player, Gui gui) {
if (shutdown) {
if (plugin.isEnabled()) {
// recover if reloaded without calling init manually
init();
} else {
return;
}
} 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 {
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);
}
public void showPopup(Player player, String message, CompatibleMaterial icon) {
showPopup(player, message, icon, BackgroundType.ADVENTURE);
}
public void showPopup(Player player, String message, CompatibleMaterial icon, BackgroundType background) {
if (ClientVersion.getClientVersion(player).isAtLeast(ServerVersion.V1_12)) {
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);
}
}
/**
* Close all active GUIs
*/
public void closeAll() {
synchronized (lock) {
openInventories.entrySet().stream()
.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) {
this.manager = manager;
}
@EventHandler(priority = EventPriority.LOW)
void onDragGUI(InventoryDragEvent event) {
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
Inventory openInv = event.getInventory();
Gui gui;
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder
&& ((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))) {
event.setCancelled(true);
event.setResult(Result.DENY);
}
}
}
@EventHandler(priority = EventPriority.LOW)
void onClickGUI(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
Inventory openInv = event.getInventory();
final Player player = (Player) event.getWhoClicked();
Gui gui;
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) {
// always cancel this event if there are matching gui elements, since it tends to do bad things
ItemStack clicked = event.getCursor();
if (clicked != null && clicked.getType() != Material.AIR) {
int cell = 0;
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;
}
}
}
}
if (event.getSlotType() == SlotType.OUTSIDE) {
if (!gui.onClickOutside(manager, player, event)) {
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
// 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);
}
} else {
// Player clicked in the bottom inventory while GUI is open
if (gui.onClickPlayerInventory(manager, player, openInv, event)) {
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();
}
}
}
}
}
@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)) {
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);
}
}
@EventHandler
void onDisable(PluginDisableEvent event) {
if (event.getPlugin() == manager.plugin) {
// uh-oh! Abandon ship!!
manager.shutdown = true;
manager.closeAll();
manager.initialized = false;
}
}
}
}
package com.songoda.core.gui;
import com.songoda.core.compatibility.ClientVersion;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.compatibility.ServerVersion;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* Manages events for GUI screens
*
* @author jascotty2
* @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);
final Map<Player, Gui> openInventories = new HashMap();
private final Object lock = new Object();
private boolean initialized = false;
private boolean shutdown = false;
public GuiManager(Plugin plugin) {
this.plugin = plugin;
}
public Plugin getPlugin() {
return plugin;
}
/**
* Initialize the GUI handlers
*/
public void init() {
Bukkit.getPluginManager().registerEvents(listener, plugin);
initialized = true;
shutdown = false;
}
/**
* Check to see if this manager cannot open any more GUI screens
*
* @return true if the owning plugin has shutdown
*/
public boolean isClosed() {
return shutdown;
}
/**
* Create and display a GUI interface for a player
*
* @param player player to open the interface for
* @param gui GUI to use
*/
public void showGUI(Player player, Gui gui) {
if (shutdown) {
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);
}
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);
}
public void showPopup(Player player, String message, CompatibleMaterial icon) {
showPopup(player, message, icon, BackgroundType.ADVENTURE);
}
public void showPopup(Player player, String message, CompatibleMaterial icon, BackgroundType background) {
if (ClientVersion.getClientVersion(player).isAtLeast(ServerVersion.V1_12)) {
PopupMessage popup = new PopupMessage(plugin, icon, message, background);
popup.add();
popup.grant(player);
Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, () -> {
popup.revoke(player);
popup.remove();
}, 70);
return;
}
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) {
player.sendTitle("", message, 10, 70, 10);
return;
}
player.sendTitle("", message);
}
/**
* Close all active GUIs
*/
public void closeAll() {
synchronized (lock) {
openInventories.entrySet().stream()
.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) {
this.manager = manager;
}
@EventHandler(priority = EventPriority.LOW)
void onDragGUI(InventoryDragEvent event) {
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
Inventory openInv = event.getInventory();
Gui gui;
if (openInv.getHolder() != null && openInv.getHolder() instanceof GuiHolder
&& ((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))) {
event.setCancelled(true);
event.setResult(Result.DENY);
}
}
}
@EventHandler(priority = EventPriority.LOW)
void onClickGUI(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
Inventory openInv = event.getInventory();
final Player player = (Player) event.getWhoClicked();
Gui gui;
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) {
// always cancel this event if there are matching gui elements, since it tends to do bad things
ItemStack clicked = event.getCursor();
if (clicked != null && clicked.getType() != Material.AIR) {
int cell = 0;
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;
}
}
}
}
if (event.getSlotType() == SlotType.OUTSIDE) {
if (!gui.onClickOutside(manager, player, event)) {
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
// 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);
}
} else {
// Player clicked in the bottom inventory while GUI is open
if (gui.onClickPlayerInventory(manager, player, openInv, event)) {
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();
}
}
}
}
}
@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)) {
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);
}
}
@EventHandler
void onDisable(PluginDisableEvent event) {
if (event.getPlugin() == manager.plugin) {
// uh-oh! Abandon ship!!
manager.shutdown = true;
manager.closeAll();
manager.initialized = false;
}
}
}
}

View File

@ -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);

View File

@ -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,197 +58,247 @@ 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 {
// 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));
} else if (shorterString.charAt(i) == ' ' || shorterString.charAt(i) == '-') {
breakingSpace = i;
}
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));
} else if (shorterString.charAt(i) == ' ' || shorterString.charAt(i) == '-') {
breakingSpace = i;
}
if (breakingSpace == -1) {
breakingSpace = Math.max(50, shorterString.length());
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace) + "-");
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
} else {
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);
if (breakingSpace == -1) {
breakingSpace = Math.max(50, shorterString.length());
newLore.add((line != 0 && lastColor != null ? lastColor.toString() : "") + shorterString.substring(0, breakingSpace) + "-");
shorterString = breakingSpace == shorterString.length() ? "" : shorterString.substring(breakingSpace + 1);
} else {
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;
}
}

View File

@ -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;

View File

@ -1,225 +1,238 @@
package com.songoda.core.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.events.GuiClickEvent;
import com.songoda.core.gui.methods.Clickable;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.Map;
/**
* Paged GUI for when you aren't going to be making too many pages
*
* @author jascotty2
* @since 2019-08-31
*/
public class SimplePagedGui extends Gui {
protected boolean useHeader;
private int rowsPerPage, maxCellSlot;
protected ItemStack headerBackItem;
protected ItemStack footerBackItem;
final int nextPageIndex = 4, prevPageIndex = 6;
public SimplePagedGui() {
this(null);
}
public SimplePagedGui(Gui parent) {
super(parent);
nextPage = GuiUtils.createButtonItem(CompatibleMaterial.ARROW, "Next Page");
prevPage = GuiUtils.createButtonItem(CompatibleMaterial.ARROW, "Previous Page");
}
public SimplePagedGui setUseHeader(boolean useHeader) {
this.useHeader = useHeader;
return this;
}
public ItemStack getHeaderBackItem() {
return headerBackItem;
}
public SimplePagedGui setHeaderBackItem(ItemStack headerBackItem) {
this.headerBackItem = headerBackItem;
return this;
}
public ItemStack getFooterBackItem() {
return footerBackItem;
}
public SimplePagedGui setFooterBackItem(ItemStack footerBackItem) {
this.footerBackItem = footerBackItem;
return this;
}
@Override
public SimplePagedGui setItem(int row, int col, ItemStack item) {
return setItem(col + row * 9, item);
}
@Override
public SimplePagedGui setItem(int cell, ItemStack item) {
// set the cell relative to the current page
int cellIndex = cell < 0 ? cell : (page == 1 || (useHeader && cell < 9) ? cell : (cell + (page - 1) * (rowsPerPage * 9)));
cellItems.put(cellIndex, item);
if (open && cell >= 0 && cell < inventory.getSize()) {
inventory.setItem(cell, item);
}
return this;
}
@Override
public void nextPage() {
if (page < pages) {
++page;
showPage();
}
}
@Override
public void prevPage() {
if (page > 1) {
--page;
showPage();
}
}
public void showPage() {
int startCell = useHeader ? 9 : 0;
int cellIndex = startCell + (page - 1) * (rowsPerPage * 9);
for (int i = startCell; i < (rows - 1) * 9; ++i) {
final ItemStack item = cellItems.get(cellIndex++);
inventory.setItem(i, item != null ? item : blankItem);
}
// page markers
updatePageNavigation();
}
@Override
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);
}
}
@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;
int maxRows = (int) Math.ceil(maxCellSlot / 9.);
pages = (int) Math.max(1, Math.ceil(maxRows / (double) rowsPerPage));
this.setRows(maxRows + (useHeader ? 1 : 0));
// create inventory view
createInventory();
// 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));
}
@Override
public void update() {
if (inventory == null) {
return;
}
// calculate pages here
rowsPerPage = useHeader ? 4 : 5;
maxCellSlot = (this.cellItems.isEmpty() ? 0 : this.cellItems.keySet().stream().max(Integer::compare).get()) + 1;
int maxRows = Math.max((useHeader ? 1 : 0), (int) Math.ceil(maxCellSlot / 9.));
pages = (int) Math.ceil(maxRows / rowsPerPage);
// create a new inventory if needed
List<Player> toUpdate = null;
if (Math.min(54, (maxRows + (useHeader ? 1 : 0)) * 9) != inventory.getSize()) {
toUpdate = getPlayers();
this.setRows(maxRows + (useHeader ? 1 : 0));
createInventory();
}
// populate header
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));
}
}
// last row is dedicated to pagation
final int cells = rows * 9;
for (int i = cells - 9; i < cells; ++i) {
inventory.setItem(i, footerBackItem != null ? footerBackItem : blankItem);
}
// fill out the rest of the page
showPage();
// did we need to change the display window size?
if (toUpdate != null) {
// whoopsie!
exit();
toUpdate.forEach(player -> guiManager.showGUI(player, this));
}
}
@Override
protected boolean onClick(GuiManager manager, Player player, Inventory inventory, InventoryClickEvent event) {
int cell = event.getSlot();
Map<ClickType, Clickable> conditionals;
if (useHeader && cell < 9) {
conditionals = conditionalButtons.get(cell);
} else if (cell >= (rows - 1) * 9) {
// footer row
conditionals = conditionalButtons.get(cell - (rows * 9));
} else {
int cellIndex = page == 1 || (useHeader && cell < 9) ? cell : (cell + (page - 1) * (rowsPerPage * 9));
conditionals = conditionalButtons.get(cellIndex);
}
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));
} else {
// no event for this button
return false;
}
return true;
}
}
package com.songoda.core.gui;
import com.songoda.core.compatibility.CompatibleMaterial;
import com.songoda.core.gui.events.GuiClickEvent;
import com.songoda.core.gui.methods.Clickable;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.Map;
/**
* Paged GUI for when you aren't going to be making too many pages
*
* @author jascotty2
* @since 2019-08-31
*/
public class SimplePagedGui extends Gui {
protected boolean useHeader;
private int rowsPerPage, maxCellSlot;
protected ItemStack headerBackItem;
protected ItemStack footerBackItem;
final int nextPageIndex = 4, prevPageIndex = 6;
public SimplePagedGui() {
this(null);
}
public SimplePagedGui(Gui parent) {
super(parent);
nextPage = GuiUtils.createButtonItem(CompatibleMaterial.ARROW, "Next Page");
prevPage = GuiUtils.createButtonItem(CompatibleMaterial.ARROW, "Previous Page");
}
public SimplePagedGui setUseHeader(boolean useHeader) {
this.useHeader = useHeader;
return this;
}
public ItemStack getHeaderBackItem() {
return headerBackItem;
}
public SimplePagedGui setHeaderBackItem(ItemStack headerBackItem) {
this.headerBackItem = headerBackItem;
return this;
}
public ItemStack getFooterBackItem() {
return footerBackItem;
}
public SimplePagedGui setFooterBackItem(ItemStack footerBackItem) {
this.footerBackItem = footerBackItem;
return this;
}
@Override
public SimplePagedGui setItem(int row, int col, ItemStack item) {
return setItem(col + row * 9, item);
}
@Override
public SimplePagedGui setItem(int cell, ItemStack item) {
// set the cell relative to the current page
int cellIndex = cell < 0 ? cell : (page == 1 || (useHeader && cell < 9) ? cell : (cell + (page - 1) * (rowsPerPage * 9)));
cellItems.put(cellIndex, item);
if (open && cell >= 0 && cell < inventory.getSize()) {
inventory.setItem(cell, item);
}
return this;
}
@Override
public void nextPage() {
if (page < pages) {
++page;
showPage();
}
}
@Override
public void prevPage() {
if (page > 1) {
--page;
showPage();
}
}
public void showPage() {
int startCell = useHeader ? 9 : 0;
int cellIndex = startCell + (page - 1) * (rowsPerPage * 9);
for (int i = startCell; i < (rows - 1) * 9; ++i) {
final ItemStack item = cellItems.get(cellIndex++);
inventory.setItem(i, item != null ? item : blankItem);
}
// page markers
updatePageNavigation();
}
@Override
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);
}
}
@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;
int maxRows = (int) Math.ceil(maxCellSlot / 9.);
pages = (int) Math.max(1, Math.ceil(maxRows / (double) rowsPerPage));
this.setRows(maxRows + (useHeader ? 1 : 0));
// create inventory view
createInventory();
// 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));
}
@Override
public void update() {
if (inventory == null) {
return;
}
// calculate pages here
rowsPerPage = useHeader ? 4 : 5;
maxCellSlot = (this.cellItems.isEmpty() ? 0 : this.cellItems.keySet().stream().max(Integer::compare).get()) + 1;
int maxRows = Math.max((useHeader ? 1 : 0), (int) Math.ceil(maxCellSlot / 9.));
pages = (int) Math.ceil(maxRows / rowsPerPage);
// create a new inventory if needed
List<Player> toUpdate = null;
if (Math.min(54, (maxRows + (useHeader ? 1 : 0)) * 9) != inventory.getSize()) {
toUpdate = getPlayers();
this.setRows(maxRows + (useHeader ? 1 : 0));
createInventory();
}
// populate header
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));
}
}
// last row is dedicated to pagation
final int cells = rows * 9;
for (int i = cells - 9; i < cells; ++i) {
inventory.setItem(i, footerBackItem != null ? footerBackItem : blankItem);
}
// fill out the rest of the page
showPage();
// did we need to change the display window size?
if (toUpdate != null) {
// whoopsie!
exit();
toUpdate.forEach(player -> guiManager.showGUI(player, this));
}
}
@Override
protected boolean onClick(GuiManager manager, Player player, Inventory inventory, InventoryClickEvent event) {
int cell = event.getSlot();
Map<ClickType, Clickable> conditionals;
if (useHeader && cell < 9) {
conditionals = conditionalButtons.get(cell);
} else if (cell >= (rows - 1) * 9) {
// footer row
conditionals = conditionalButtons.get(cell - (rows * 9));
} else {
int cellIndex = page == 1 || (useHeader && cell < 9) ? cell : (cell + (page - 1) * (rowsPerPage * 9));
conditionals = conditionalButtons.get(cellIndex);
}
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));
} else {
// no event for this button
return false;
}
return true;
}
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
import com.songoda.core.gui.events.GuiClickEvent;
public interface Clickable {
void onClick(GuiClickEvent event);
}

View File

@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
import com.songoda.core.gui.events.GuiCloseEvent;
public interface Closable {
void onClose(GuiCloseEvent event);
}

View File

@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
import com.songoda.core.gui.events.GuiDropItemEvent;
public interface Droppable {
boolean onDrop(GuiDropItemEvent event);
}

View File

@ -1,8 +1,7 @@
package com.songoda.core.gui.methods;
import com.songoda.core.gui.events.GuiOpenEvent;
public interface Openable {
void onOpen(GuiOpenEvent event);
}
package com.songoda.core.gui.methods;
import com.songoda.core.gui.events.GuiOpenEvent;
public interface Openable {
void onOpen(GuiOpenEvent event);
}

View File

@ -3,6 +3,5 @@ package com.songoda.core.gui.methods;
import com.songoda.core.gui.events.GuiPageEvent;
public interface Pagable {
void onPageChange(GuiPageEvent event);
}

View File

@ -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
*/

View File

@ -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,8 +55,9 @@ 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) {
@ -65,8 +65,9 @@ public class EntityStackerManager {
}
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) {

View File

@ -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);
}
}
}

View File

@ -1,18 +1,15 @@
package com.songoda.core.hooks;
public interface Hook {
/**
* Get the name of the plugin being used
*
* @return
*/
abstract String getName();
/**
* Check to see if the economy plugin being used is active
*
* @return true if the plugin is loaded and active
*/
abstract boolean isEnabled();
}
package com.songoda.core.hooks;
public interface Hook {
/**
* Get the name of the plugin being used
*/
abstract String getName();
/**
* Check to see if the economy plugin being used is active
*
* @return true if the plugin is loaded and active
*/
abstract boolean isEnabled();
}

View File

@ -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))

View File

@ -1,233 +1,267 @@
package com.songoda.core.hooks;
import com.songoda.core.hooks.jobs.JobsHandler;
import com.songoda.core.hooks.jobs.JobsPlayerHandler;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Collections;
import java.util.List;
public class JobsHook {
static boolean canHook;
static {
try {
// if this class exists, we're good to use Jobs classes
Class.forName("com.gamingmesh.jobs.Jobs");
canHook = true;
} catch (ClassNotFoundException ex) {
}
}
public static JobsPlayerHandler getPlayer(Player player) {
if (canHook) {
return JobsPlayerHandler.loadPlayer(player);
}
return null;
}
public static boolean isEnabled() {
return canHook;
}
public static List<String> getAllJobs() {
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);
}
}
public static void promoteJob(Player player, String job, int levels) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.promoteJob(job, levels);
}
}
public static void demoteJob(Player player, String job) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.demoteJob(job);
}
}
public static void demoteJob(Player player, String job, int levels) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.demoteJob(job, levels);
}
}
public static void joinJob(Player player, String job) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.joinJob(job);
}
}
public static void leaveAllJobs(Player player) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.leaveAllJobs();
}
}
public static void leaveJob(Player player, String job) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.leaveJob(job);
}
}
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);
}
}
public static void breakBlock(Player player, Block block) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.breakBlock(block);
}
}
public static void tntBreakBlock(Player player, Block block) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.tntBreakBlock(block);
}
}
public static void placeBlock(Player player, Block block) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.placeBlock(block);
}
}
public static void placeEntity(Player player, Entity block) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.placeEntity(block);
}
}
public static void breakEntity(Player player, Entity block) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.breakEntity(block);
}
}
public static void breedEntity(Player player, LivingEntity entity) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.breedEntity(entity);
}
}
public static void killEntity(Player player, LivingEntity entity) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.killEntity(entity);
}
}
public static void tameEntity(Player player, LivingEntity entity) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.tameEntity(entity);
}
}
public static void catchFish(Player player, ItemStack items) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.catchFish(items);
}
}
public static void killEntity(Player player, LivingEntity entity, Entity damageSource) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.killEntity(entity, damageSource);
}
}
public static void itemEnchanted(Player player, ItemStack resultStack) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.itemEnchanted(resultStack);
}
}
}
package com.songoda.core.hooks;
import com.songoda.core.hooks.jobs.JobsHandler;
import com.songoda.core.hooks.jobs.JobsPlayerHandler;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Collections;
import java.util.List;
public class JobsHook {
static boolean canHook;
static {
try {
// if this class exists, we're good to use Jobs classes
Class.forName("com.gamingmesh.jobs.Jobs");
canHook = true;
} catch (ClassNotFoundException ignore) {
}
}
public static JobsPlayerHandler getPlayer(Player player) {
if (canHook) {
return JobsPlayerHandler.loadPlayer(player);
}
return null;
}
public static boolean isEnabled() {
return canHook;
}
public static List<String> getAllJobs() {
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);
}
}
public static void promoteJob(Player player, String job, int levels) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.promoteJob(job, levels);
}
}
public static void demoteJob(Player player, String job) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.demoteJob(job);
}
}
public static void demoteJob(Player player, String job, int levels) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.demoteJob(job, levels);
}
}
public static void joinJob(Player player, String job) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.joinJob(job);
}
}
public static void leaveAllJobs(Player player) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.leaveAllJobs();
}
}
public static void leaveJob(Player player, String job) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.leaveJob(job);
}
}
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);
}
}
public static void breakBlock(Player player, Block block) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.breakBlock(block);
}
}
public static void tntBreakBlock(Player player, Block block) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.tntBreakBlock(block);
}
}
public static void placeBlock(Player player, Block block) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.placeBlock(block);
}
}
public static void placeEntity(Player player, Entity block) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.placeEntity(block);
}
}
public static void breakEntity(Player player, Entity block) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.breakEntity(block);
}
}
public static void breedEntity(Player player, LivingEntity entity) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.breedEntity(entity);
}
}
public static void killEntity(Player player, LivingEntity entity) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.killEntity(entity);
}
}
public static void tameEntity(Player player, LivingEntity entity) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.tameEntity(entity);
}
}
public static void catchFish(Player player, ItemStack items) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.catchFish(items);
}
}
public static void killEntity(Player player, LivingEntity entity, Entity damageSource) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.killEntity(entity, damageSource);
}
}
public static void itemEnchanted(Player player, ItemStack resultStack) {
JobsPlayerHandler jPlayer = getPlayer(player);
if (jPlayer != null) {
jPlayer.itemEnchanted(resultStack);
}
}
}

View File

@ -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,8 +59,9 @@ 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);
}
}
/**
@ -73,8 +71,9 @@ 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);
}
}
/**
@ -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);
}
}
}

View File

@ -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) {
}
}

View File

@ -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);
}
}

View File

@ -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);
/**

View File

@ -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) {
}
}

View File

@ -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
*

View File

@ -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);
}
}

View File

@ -7,12 +7,12 @@ 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

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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);
}

View File

@ -1,13 +1,12 @@
package com.songoda.core.hooks.jobs;
import com.gamingmesh.jobs.Jobs;
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());
}
}
package com.songoda.core.hooks.jobs;
import com.gamingmesh.jobs.Jobs;
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());
}
}

View File

@ -1,183 +1,195 @@
package com.songoda.core.hooks.jobs;
import com.gamingmesh.jobs.CMILib.CMIEnchantment;
import com.gamingmesh.jobs.Jobs;
import com.gamingmesh.jobs.actions.BlockActionInfo;
import com.gamingmesh.jobs.actions.CustomKillInfo;
import com.gamingmesh.jobs.actions.EnchantActionInfo;
import com.gamingmesh.jobs.actions.EntityActionInfo;
import com.gamingmesh.jobs.actions.ItemActionInfo;
import com.gamingmesh.jobs.container.ActionType;
import com.gamingmesh.jobs.container.CurrencyType;
import com.gamingmesh.jobs.container.Job;
import com.gamingmesh.jobs.container.JobProgression;
import com.gamingmesh.jobs.container.JobsPlayer;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class JobsPlayerHandler {
protected final JobsPlayer jPlayer;
protected JobsPlayerHandler(JobsPlayer jPlayer) {
this.jPlayer = jPlayer;
}
public static JobsPlayerHandler loadPlayer(Player player) {
JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player);
return jPlayer != null ? new JobsPlayerHandler(jPlayer) : null;
}
public double getBoostExp(String job) {
return jPlayer.getBoost(job, CurrencyType.EXP);
}
public double getBoostMoney(String job) {
return jPlayer.getBoost(job, CurrencyType.MONEY);
}
public double getBoostPoints(String job) {
return jPlayer.getBoost(job, CurrencyType.POINTS);
}
public void promoteJob(String jobName) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.promoteJob(job, 1);
}
}
public void promoteJob(String jobName, int levels) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.promoteJob(job, levels);
}
}
public void demoteJob(String jobName) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.demoteJob(job, 1);
}
}
public void demoteJob(String jobName, int levels) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.demoteJob(job, levels);
}
}
public void joinJob(String jobName) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.joinJob(job);
}
}
public void leaveAllJobs() {
jPlayer.leaveAllJobs();
}
public void leaveJob(String jobName) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.leaveJob(job);
}
}
public int getTotalLevels() {
return jPlayer.getTotalLevels();
}
public int getMaxBrewingStandsAllowed() {
return jPlayer.getMaxBrewingStandsAllowed();
}
public int getMaxFurnacesAllowed() {
return jPlayer.getMaxFurnacesAllowed();
}
public List<String> getJobs() {
return jPlayer.getJobProgression().stream().map(p -> p.getJob().getName()).collect(Collectors.toList());
}
public void eatItem(ItemStack item) {
Jobs.action(jPlayer, new ItemActionInfo(item, ActionType.EAT));
}
public void breakBlock(Block block) {
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.BREAK), block);
}
public void tntBreakBlock(Block block) {
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.TNTBREAK), block);
}
public void placeBlock(Block block) {
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.PLACE), block);
}
public void placeEntity(Entity block) {
Jobs.action(jPlayer, new EntityActionInfo(block, ActionType.PLACE));
}
public void breakEntity(Entity block) {
Jobs.action(jPlayer, new EntityActionInfo(block, ActionType.BREAK));
}
public void breedEntity(LivingEntity entity) {
Jobs.action(jPlayer, new EntityActionInfo(entity, ActionType.BREED));
}
public void killEntity(LivingEntity entity) {
killEntity(entity, jPlayer.getPlayer());
}
public void tameEntity(LivingEntity entity) {
Jobs.action(jPlayer, new EntityActionInfo((Entity) entity, ActionType.TAME));
}
public void catchFish(ItemStack items) {
Jobs.action(jPlayer, new ItemActionInfo(items, ActionType.FISH));
}
public void killEntity(LivingEntity entity, Entity damageSource) {
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);
}
}
}
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));
}
}
}
package com.songoda.core.hooks.jobs;
import com.gamingmesh.jobs.CMILib.CMIEnchantment;
import com.gamingmesh.jobs.Jobs;
import com.gamingmesh.jobs.actions.BlockActionInfo;
import com.gamingmesh.jobs.actions.CustomKillInfo;
import com.gamingmesh.jobs.actions.EnchantActionInfo;
import com.gamingmesh.jobs.actions.EntityActionInfo;
import com.gamingmesh.jobs.actions.ItemActionInfo;
import com.gamingmesh.jobs.container.ActionType;
import com.gamingmesh.jobs.container.CurrencyType;
import com.gamingmesh.jobs.container.Job;
import com.gamingmesh.jobs.container.JobProgression;
import com.gamingmesh.jobs.container.JobsPlayer;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class JobsPlayerHandler {
protected final JobsPlayer jPlayer;
protected JobsPlayerHandler(JobsPlayer jPlayer) {
this.jPlayer = jPlayer;
}
public static JobsPlayerHandler loadPlayer(Player player) {
JobsPlayer jPlayer = Jobs.getPlayerManager().getJobsPlayer(player);
return jPlayer != null ? new JobsPlayerHandler(jPlayer) : null;
}
public double getBoostExp(String job) {
return jPlayer.getBoost(job, CurrencyType.EXP);
}
public double getBoostMoney(String job) {
return jPlayer.getBoost(job, CurrencyType.MONEY);
}
public double getBoostPoints(String job) {
return jPlayer.getBoost(job, CurrencyType.POINTS);
}
public void promoteJob(String jobName) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.promoteJob(job, 1);
}
}
public void promoteJob(String jobName, int levels) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.promoteJob(job, levels);
}
}
public void demoteJob(String jobName) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.demoteJob(job, 1);
}
}
public void demoteJob(String jobName, int levels) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.demoteJob(job, levels);
}
}
public void joinJob(String jobName) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.joinJob(job);
}
}
public void leaveAllJobs() {
jPlayer.leaveAllJobs();
}
public void leaveJob(String jobName) {
Job job = Jobs.getJob(jobName);
if (job != null) {
jPlayer.leaveJob(job);
}
}
public int getTotalLevels() {
return jPlayer.getTotalLevels();
}
public int getMaxBrewingStandsAllowed() {
return jPlayer.getMaxBrewingStandsAllowed();
}
public int getMaxFurnacesAllowed() {
return jPlayer.getMaxFurnacesAllowed();
}
public List<String> getJobs() {
return jPlayer.getJobProgression().stream().map(p -> p.getJob().getName()).collect(Collectors.toList());
}
public void eatItem(ItemStack item) {
Jobs.action(jPlayer, new ItemActionInfo(item, ActionType.EAT));
}
public void breakBlock(Block block) {
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.BREAK), block);
}
public void tntBreakBlock(Block block) {
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.TNTBREAK), block);
}
public void placeBlock(Block block) {
Jobs.action(jPlayer, new BlockActionInfo(block, ActionType.PLACE), block);
}
public void placeEntity(Entity block) {
Jobs.action(jPlayer, new EntityActionInfo(block, ActionType.PLACE));
}
public void breakEntity(Entity block) {
Jobs.action(jPlayer, new EntityActionInfo(block, ActionType.BREAK));
}
public void breedEntity(LivingEntity entity) {
Jobs.action(jPlayer, new EntityActionInfo(entity, ActionType.BREED));
}
public void killEntity(LivingEntity entity) {
killEntity(entity, jPlayer.getPlayer());
}
public void tameEntity(LivingEntity entity) {
Jobs.action(jPlayer, new EntityActionInfo((Entity) entity, ActionType.TAME));
}
public void catchFish(ItemStack items) {
Jobs.action(jPlayer, new ItemActionInfo(items, ActionType.FISH));
}
public void killEntity(LivingEntity entity, Entity damageSource) {
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);
}
}
}
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));
}
}
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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);

View File

@ -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();
}

View File

@ -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() {

Some files were not shown because too many files have changed in this diff Show More