Skip to content

Commit b37cf70

Browse files
committed
v9.0.0
Removed the use of apache commons due to future planned removal of the library. Removed "unused" package and all its classes. XMaterial Fixed a few issues regarding some wood and disc materials. XItemStack Custom model data option name is now consistent. XEnchantment Removed "ItemStack addEnchantFromString(@nonnull ItemStack item, @nullable String enchantment)" because I believe it's useless and I encourage all devs to make a simple yaml map based with key as enchant name and value as the level config system instead.
1 parent 17565da commit b37cf70

File tree

16 files changed

+290
-1048
lines changed

16 files changed

+290
-1048
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ if it's unrelated to adding support for that version since your changes are like
1818
* Make sure the utility works on different Minecraft server versions.
1919
* Use method and variable names that make sense and are related to the context.
2020
* Don't use Optional everywhere that can return null.
21-
* Using Guava and Apache Commons is a plus, but make sure what you're using is supported in
22-
older versions of Bukkit's libraries.
21+
* Using Google's Guava is a plus, but not always. Make sure what you're using is supported in
22+
older versions of Bukkit's libraries and don't. Don't use other libraries included in Bukkit, specially Apache Commons since it was removed.
2323
* Add JavaDocs with proper formatting. It's also preferred to explain how the complex parts of a method work
2424
inside the method. Use simple English when possible.
2525
* All the functions used in the utilities should be compatible with Bukkit, Spigot and Paper.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[![Build Status](https://travis-ci.com/CryptoMorin/XSeries.svg?branch=master)](https://travis-ci.com/CryptoMorin/XSeries)
55
![maven-central](https://img.shields.io/maven-central/v/com.github.cryptomorin/XSeries)
66

7-
Library mainly designed to provide cross-version support for Minecraft Bukkit servers,
7+
Library mainly designed to provide cross-version support for Minecraft Bukkit plugins,
88
but it also includes numerous extra methods to help developers design their plugins easier and efficiently.
99
Some utilities are completely unrelated to cross-version support such as NoteBlockMusic.
1010

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.cryptomorin</groupId>
88
<artifactId>XSeries</artifactId>
9-
<version>8.8.0</version>
9+
<version>9.0.0</version>
1010

1111
<name>XSeries</name>
1212
<description>A set of utilities for Minecraft plugins</description>

src/main/java/com/cryptomorin/xseries/SkullCacheListener.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import com.google.gson.JsonObject;
2626
import com.google.gson.JsonParser;
2727
import com.mojang.authlib.GameProfile;
28-
import org.apache.commons.lang.Validate;
2928
import org.bukkit.entity.Player;
3029
import org.bukkit.event.EventHandler;
3130
import org.bukkit.event.player.PlayerJoinEvent;
@@ -100,7 +99,7 @@ public static String getSkinValue(@Nonnull String id) {
10099

101100
@Nullable
102101
public static String getIdFromUsername(@Nonnull String username) {
103-
Validate.notEmpty(username, "Cannot get UUID of a null or empty username");
102+
if (username == null || username.isEmpty()) throw new IllegalArgumentException("Cannot get UUID of a null or empty username");
104103
int len = username.length();
105104
if (len < 3 || len > 16) throw new IllegalArgumentException("Username cannot be less than 3 and longer than 16 characters: " + username);
106105

src/main/java/com/cryptomorin/xseries/SkullUtils.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import com.google.common.collect.Lists;
2525
import com.mojang.authlib.GameProfile;
2626
import com.mojang.authlib.properties.Property;
27-
import org.apache.commons.lang.Validate;
2827
import org.bukkit.Bukkit;
2928
import org.bukkit.OfflinePlayer;
3029
import org.bukkit.inventory.ItemStack;
@@ -131,7 +130,7 @@ public static SkullMeta applySkin(@Nonnull ItemMeta head, @Nonnull String identi
131130

132131
@Nonnull
133132
protected static SkullMeta getSkullByValue(@Nonnull SkullMeta head, @Nonnull String value) {
134-
Validate.notEmpty(value, "Skull value cannot be null or empty");
133+
if (value == null || value.isEmpty()) throw new IllegalArgumentException("Skull value cannot be null or empty");
135134
GameProfile profile = new GameProfile(UUID.randomUUID(), null);
136135
profile.getProperties().put("textures", new Property("textures", value));
137136

src/main/java/com/cryptomorin/xseries/XBiome.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
package com.cryptomorin.xseries;
2323

2424
import com.google.common.base.Enums;
25-
import org.apache.commons.lang.Validate;
2625
import org.bukkit.Chunk;
2726
import org.bukkit.Location;
2827
import org.bukkit.World;
@@ -240,7 +239,7 @@ private static String format(@Nonnull String name) {
240239
*/
241240
@Nonnull
242241
public static Optional<XBiome> matchXBiome(@Nonnull String biome) {
243-
Validate.notEmpty(biome, "Cannot match XBiome of a null or empty biome name");
242+
if (biome == null || biome.isEmpty()) throw new IllegalArgumentException("Cannot match XBiome of a null or empty biome name");
244243
return Optional.ofNullable(Data.NAMES.get(format(biome)));
245244
}
246245

@@ -296,7 +295,7 @@ public CompletableFuture<Void> setBiome(@Nonnull Chunk chunk) {
296295
Objects.requireNonNull(biome, () -> "Unsupported biome: " + this.name());
297296
Objects.requireNonNull(chunk, "Cannot set biome of null chunk");
298297
if (!chunk.isLoaded()) {
299-
Validate.isTrue(chunk.load(true), "Could not load chunk at " + chunk.getX() + ", " + chunk.getZ());
298+
if (!chunk.load(true)) throw new IllegalStateException("Could not load chunk at " + chunk.getX() + ", " + chunk.getZ());
300299
}
301300
int heightMax = HORIZONTAL_SUPPORT ? chunk.getWorld().getMaxHeight() : 1;
302301
int heightMin = EXTENDED_MINIMUM ? chunk.getWorld().getMinHeight() : 0;
@@ -337,7 +336,7 @@ public CompletableFuture<Void> setBiome(@Nonnull Location start, @Nonnull Locati
337336
Objects.requireNonNull(biome, () -> "Unsupported biome: " + this.name());
338337

339338
World world = start.getWorld(); // Avoid getting from weak reference in a loop.
340-
Validate.isTrue(world.getUID().equals(end.getWorld().getUID()), "Location worlds mismatch");
339+
if (!world.getUID().equals(end.getWorld().getUID())) throw new IllegalArgumentException("Location worlds mismatch");
341340
int heightMax = HORIZONTAL_SUPPORT ? world.getMaxHeight() : 1;
342341
int heightMin = EXTENDED_MINIMUM ? world.getMinHeight() : 0;
343342

src/main/java/com/cryptomorin/xseries/XBlock.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
*/
2222
package com.cryptomorin.xseries;
2323

24-
import org.apache.commons.lang.Validate;
2524
import org.bukkit.DyeColor;
2625
import org.bukkit.Material;
2726
import org.bukkit.TreeSpecies;
@@ -486,7 +485,7 @@ public static boolean isOneOf(Block block, Collection<String> blocks) {
486485
}
487486

488487
public static void setCakeSlices(Block block, int amount) {
489-
Validate.isTrue(isCake(block.getType()), "Block is not a cake: " + block.getType());
488+
if (!isCake(block.getType())) throw new IllegalArgumentException("Block is not a cake: " + block.getType());
490489
if (ISFLAT) {
491490
BlockData data = block.getBlockData();
492491
org.bukkit.block.data.type.Cake cake = (org.bukkit.block.data.type.Cake) data;
@@ -512,7 +511,7 @@ public static void setCakeSlices(Block block, int amount) {
512511
}
513512

514513
public static int addCakeSlices(Block block, int slices) {
515-
Validate.isTrue(isCake(block.getType()), "Block is not a cake: " + block.getType());
514+
if (!isCake(block.getType())) throw new IllegalArgumentException("Block is not a cake: " + block.getType());
516515
if (ISFLAT) {
517516
BlockData data = block.getBlockData();
518517
org.bukkit.block.data.type.Cake cake = (org.bukkit.block.data.type.Cake) data;

src/main/java/com/cryptomorin/xseries/XEnchantment.java

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,17 @@
2222
package com.cryptomorin.xseries;
2323

2424
import com.google.common.base.Enums;
25-
import com.google.common.base.Strings;
26-
import org.apache.commons.lang.StringUtils;
27-
import org.apache.commons.lang.Validate;
28-
import org.apache.commons.lang.WordUtils;
29-
import org.apache.commons.lang.math.NumberUtils;
3025
import org.bukkit.Material;
3126
import org.bukkit.NamespacedKey;
3227
import org.bukkit.enchantments.Enchantment;
3328
import org.bukkit.entity.EntityType;
3429
import org.bukkit.inventory.ItemStack;
3530
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
36-
import org.bukkit.inventory.meta.ItemMeta;
3731

3832
import javax.annotation.Nonnull;
3933
import javax.annotation.Nullable;
4034
import java.util.*;
35+
import java.util.stream.Collectors;
4136

4237
/**
4338
* Enchantment support with multiple aliases.
@@ -237,7 +232,7 @@ private static String format(@Nonnull String name) {
237232
*/
238233
@Nonnull
239234
public static Optional<XEnchantment> matchXEnchantment(@Nonnull String enchantment) {
240-
Validate.notEmpty(enchantment, "Enchantment name cannot be null or empty");
235+
if (enchantment == null || enchantment.isEmpty()) throw new IllegalArgumentException("Enchantment name cannot be null or empty");
241236
return Optional.ofNullable(Data.NAMES.get(format(enchantment)));
242237
}
243238

@@ -258,47 +253,6 @@ public static XEnchantment matchXEnchantment(@Nonnull Enchantment enchantment) {
258253
return Objects.requireNonNull(Data.NAMES.get(enchantment.getName()), () -> "Unsupported enchantment: " + enchantment.getName());
259254
}
260255

261-
/**
262-
* Adds an unsafe enchantment to the given item from a string.
263-
* <p>
264-
* <blockquote><pre>
265-
* ItemStack item = ...;
266-
* addEnchantFromString(item, "unbreaking, 10");
267-
* addEnchantFromString(item, "mending");
268-
* </pre></blockquote>
269-
* <p>
270-
* Note that if you set your item's meta {@link ItemStack#setItemMeta(ItemMeta)} the enchantment
271-
* will be removed.
272-
* You need to use {@link ItemMeta#addEnchant(Enchantment, int, boolean)} instead.
273-
* You can use the {@link #matchXEnchantment(String)} method in this case.
274-
*
275-
* @param item the item to add the enchantment to.
276-
* @param enchantment the enchantment string containing the enchantment name and level (optional)
277-
*
278-
* @return an enchanted {@link ItemStack} or the item itself without enchantment added if enchantment type is null.
279-
* @see #matchXEnchantment(String)
280-
* @since 1.0.0
281-
*/
282-
@Nonnull
283-
public static ItemStack addEnchantFromString(@Nonnull ItemStack item, @Nullable String enchantment) {
284-
Objects.requireNonNull(item, "Cannot add enchantment to null ItemStack");
285-
if (Strings.isNullOrEmpty(enchantment) || enchantment.equalsIgnoreCase("none")) return item;
286-
287-
String[] split = StringUtils.split(StringUtils.deleteWhitespace(enchantment), ',');
288-
if (split.length == 0) split = StringUtils.split(enchantment, ' ');
289-
290-
Optional<XEnchantment> enchantOpt = matchXEnchantment(split[0]);
291-
if (!enchantOpt.isPresent()) return item;
292-
Enchantment enchant = enchantOpt.get().enchantment;
293-
if (enchant == null) return item;
294-
295-
int lvl = 1;
296-
if (split.length > 1) lvl = NumberUtils.toInt(split[1]);
297-
298-
item.addUnsafeEnchantment(enchant, lvl);
299-
return item;
300-
}
301-
302256
/**
303257
* Gets the enchanted book of this enchantment.
304258
*
@@ -352,7 +306,9 @@ public boolean isSupported() {
352306
@Override
353307
@Nonnull
354308
public String toString() {
355-
return WordUtils.capitalize(this.name().replace('_', ' ').toLowerCase(Locale.ENGLISH));
309+
return Arrays.stream(name().split("_"))
310+
.map(t -> t.charAt(0) + t.substring(1).toLowerCase())
311+
.collect(Collectors.joining(" "));
356312
}
357313

358314
/**

src/main/java/com/cryptomorin/xseries/XItemStack.java

Lines changed: 79 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
import com.google.common.base.Enums;
2525
import com.google.common.base.Strings;
2626
import com.google.common.collect.Multimap;
27-
import org.apache.commons.lang.StringUtils;
28-
import org.apache.commons.lang.math.NumberUtils;
2927
import org.bukkit.*;
3028
import org.bukkit.attribute.Attribute;
3129
import org.bukkit.attribute.AttributeModifier;
@@ -125,7 +123,7 @@ public static void serialize(@Nonnull ItemStack item, @Nonnull ConfigurationSect
125123
if (meta.hasLore()) config.set("lore", meta.getLore()); // TODO Add a method to "untranslate" color codes.
126124

127125
if (supports(14)) {
128-
if (meta.hasCustomModelData()) config.set("custom-model", meta.getCustomModelData());
126+
if (meta.hasCustomModelData()) config.set("custom-model-data", meta.getCustomModelData());
129127
}
130128
if (supports(11)) {
131129
if (meta.isUnbreakable()) config.set("unbreakable", true);
@@ -436,6 +434,42 @@ public static ItemStack deserialize(@Nonnull Map<String, Object> serializedItem,
436434
return deserialize(mapToConfigSection(serializedItem), translator);
437435
}
438436

437+
private static int toInt(String str, @SuppressWarnings("SameParameterValue") int defaultValue) {
438+
try {
439+
return Integer.parseInt(str);
440+
} catch (NumberFormatException nfe) {
441+
return defaultValue;
442+
}
443+
}
444+
445+
private static List<String> split(@Nonnull String str, @SuppressWarnings("SameParameterValue") char separatorChar) {
446+
List<String> list = new ArrayList<>(5);
447+
boolean match = false, lastMatch = false;
448+
int len = str.length();
449+
int start = 0;
450+
451+
for (int i = 0; i < len; i++) {
452+
if (str.charAt(i) == separatorChar) {
453+
if (match) {
454+
list.add(str.substring(start, i));
455+
match = false;
456+
lastMatch = true;
457+
}
458+
459+
// This is important, it should not be i++
460+
start = i + 1;
461+
continue;
462+
}
463+
464+
lastMatch = false;
465+
match = true;
466+
}
467+
468+
if (match || lastMatch) {
469+
list.add(str.substring(start, len));
470+
}
471+
return list;
472+
}
439473

440474
/**
441475
* Deserialize an ItemStack from the config.
@@ -539,10 +573,10 @@ public static ItemStack edit(@Nonnull ItemStack item,
539573

540574
String baseEffect = config.getString("base-effect");
541575
if (!Strings.isNullOrEmpty(baseEffect)) {
542-
String[] split = StringUtils.split(baseEffect, ',');
543-
PotionType type = Enums.getIfPresent(PotionType.class, split[0].trim().toUpperCase(Locale.ENGLISH)).or(PotionType.UNCRAFTABLE);
544-
boolean extended = split.length != 1 && Boolean.parseBoolean(split[1].trim());
545-
boolean upgraded = split.length > 2 && Boolean.parseBoolean(split[2].trim());
576+
List<String> split = split(baseEffect, ',');
577+
PotionType type = Enums.getIfPresent(PotionType.class, split.get(0).trim().toUpperCase(Locale.ENGLISH)).or(PotionType.UNCRAFTABLE);
578+
boolean extended = split.size() != 1 && Boolean.parseBoolean(split.get(1).trim());
579+
boolean upgraded = split.size() > 2 && Boolean.parseBoolean(split.get(2).trim());
546580
PotionData potionData = new PotionData(type, extended, upgraded);
547581
potion.setBasePotionData(potionData);
548582
}
@@ -556,10 +590,10 @@ public static ItemStack edit(@Nonnull ItemStack item,
556590
int level = config.getInt("level");
557591
String baseEffect = config.getString("base-effect");
558592
if (!Strings.isNullOrEmpty(baseEffect)) {
559-
String[] split = StringUtils.split(baseEffect, ',');
560-
PotionType type = Enums.getIfPresent(PotionType.class, split[0].trim().toUpperCase(Locale.ENGLISH)).or(PotionType.SLOWNESS);
561-
boolean extended = split.length != 1 && Boolean.parseBoolean(split[1].trim());
562-
boolean splash = split.length > 2 && Boolean.parseBoolean(split[2].trim());
593+
List<String> split = split(baseEffect, ',');
594+
PotionType type = Enums.getIfPresent(PotionType.class, split.get(0).trim().toUpperCase(Locale.ENGLISH)).or(PotionType.SLOWNESS);
595+
boolean extended = split.size() != 1 && Boolean.parseBoolean(split.get(1).trim());
596+
boolean splash = split.size() > 2 && Boolean.parseBoolean(split.get(2).trim());
563597

564598
item = (new Potion(type, level, splash, extended)).toItemStack(1);
565599
}
@@ -580,7 +614,7 @@ public static ItemStack edit(@Nonnull ItemStack item,
580614
ShulkerBox box = (ShulkerBox) state;
581615
for (String key : shulkerSection.getKeys(false)) {
582616
ItemStack boxItem = deserialize(shulkerSection.getConfigurationSection(key));
583-
int slot = NumberUtils.toInt(key, 0);
617+
int slot = toInt(key, 0);
584618
box.getInventory().setItem(slot, boxItem);
585619
}
586620
box.update(true);
@@ -774,35 +808,47 @@ public static ItemStack edit(@Nonnull ItemStack item,
774808

775809
// Custom Model Data
776810
if (supports(14)) {
777-
int modelData = config.getInt("model-data");
811+
int modelData = config.getInt("custom-model-data");
778812
if (modelData != 0) meta.setCustomModelData(modelData);
779813
}
780814

781815
// Lore
782-
List<String> translatedLore;
783-
List<String> lores = config.getStringList("lore");
784-
if (!lores.isEmpty()) {
785-
translatedLore = new ArrayList<>(lores.size());
786-
787-
for (String lore : lores) {
788-
if (lore.isEmpty()) {
789-
translatedLore.add(" ");
790-
continue;
791-
}
792-
793-
for (String singleLore : splitNewLine(lore)) {
794-
if (singleLore.isEmpty()) {
816+
if (config.isSet("lore")) {
817+
List<String> translatedLore;
818+
List<String> lores = config.getStringList("lore");
819+
if (!lores.isEmpty()) {
820+
translatedLore = new ArrayList<>(lores.size());
821+
822+
for (String lore : lores) {
823+
if (lore.isEmpty()) {
795824
translatedLore.add(" ");
796825
continue;
797826
}
798-
translatedLore.add(translator.apply(singleLore));
827+
828+
for (String singleLore : splitNewLine(lore)) {
829+
if (singleLore.isEmpty()) {
830+
translatedLore.add(" ");
831+
continue;
832+
}
833+
translatedLore.add(translator.apply(singleLore));
834+
}
835+
}
836+
} else {
837+
String lore = config.getString("lore");
838+
translatedLore = new ArrayList<>(10);
839+
840+
if (!Strings.isNullOrEmpty(lore)) {
841+
for (String singleLore : splitNewLine(lore)) {
842+
if (singleLore.isEmpty()) {
843+
translatedLore.add(" ");
844+
continue;
845+
}
846+
translatedLore.add(translator.apply(singleLore));
847+
}
799848
}
800849
}
801850

802851
meta.setLore(translatedLore);
803-
} else {
804-
String lore = config.getString("lore");
805-
if (!Strings.isNullOrEmpty(lore)) meta.setLore(Collections.singletonList(translator.apply(lore)));
806852
}
807853

808854
// Enchantments
@@ -949,9 +995,9 @@ private static Map<String, Object> configSectionToMap(@Nonnull ConfigurationSect
949995
@Nonnull
950996
public static Color parseColor(@Nullable String str) {
951997
if (Strings.isNullOrEmpty(str)) return Color.BLACK;
952-
String[] rgb = StringUtils.split(StringUtils.deleteWhitespace(str), ',');
953-
if (rgb.length < 3) return Color.WHITE;
954-
return Color.fromRGB(NumberUtils.toInt(rgb[0], 0), NumberUtils.toInt(rgb[1], 0), NumberUtils.toInt(rgb[2], 0));
998+
List<String> rgb = split(str.replace(" ", ""), ',');
999+
if (rgb.size() < 3) return Color.WHITE;
1000+
return Color.fromRGB(toInt(rgb.get(0), 0), toInt(rgb.get(1), 0), toInt(rgb.get(2), 0));
9551001
}
9561002

9571003
/**

0 commit comments

Comments
 (0)