Vanish plugin support, fix gui page off by 1, fix 1.9 chat hook

This commit is contained in:
Esophose 2019-04-28 03:58:01 -06:00
parent bf5f50c1d0
commit 40bde0a33e
11 changed files with 68 additions and 30 deletions

View file

@ -2,11 +2,14 @@
* Create a backup of your config.yml if you wish to import all your old settings! * Create a backup of your config.yml if you wish to import all your old settings!
=== v6.4 (In progress) === === v6.4 (In progress) ===
+ Added support for Minecraft 1.14 + Added support for Minecraft 1.14
+ Added effects: '', '', '', '', '', '' + Added effects: 'campfire_cosy_smoke', 'campfire_signal_smoke', 'composter', 'falling_lava', 'falling_water', 'landing_lava'
+ Added setting 'gui-close-after-group-selected' to the config.yml + Added setting 'gui-close-after-group-selected' to the config.yml
+ Added setting 'gui-presets-only' to the config.yml + Added setting 'gui-presets-only' to the config.yml
+ Added Vietnamese translation file (vi_VN.lang) + Added Vietnamese translation file (vi_VN.lang)
+ Added support for vanish plugins as long as they use the Spigot hidden player API properly
* Fixed a whole bunch of errors in the fr_FR.lang file
* Fixed '/pp add' item data parameter being ignored * Fixed '/pp add' item data parameter being ignored
* Fixed an error with the GUI chat hook for creating a new group in 1.9
=== v6.3 === === v6.3 ===
+ Added the ability to remove particles by id/effect/style using '/pp remove <id>|<effect>|<style>' + Added the ability to remove particles by id/effect/style using '/pp remove <id>|<effect>|<style>'
+ Added new styles 'popper', 'pulse', 'twins', 'whirl', and 'whirlwind' + Added new styles 'popper', 'pulse', 'twins', 'whirl', and 'whirlwind'

View file

@ -106,7 +106,7 @@ public class FixedCommandModule implements CommandModule {
double xPos, yPos, zPos; double xPos, yPos, zPos;
if (args[0].equalsIgnoreCase("looking")) { if (args[0].equalsIgnoreCase("looking")) {
Block targetBlock = p.getTargetBlock(null, 8); Block targetBlock = p.getTargetBlock((Set<Material>) null, 8);
int maxDistanceSqrd = 6 * 6; int maxDistanceSqrd = 6 * 6;
if (targetBlock.getLocation().distanceSquared(p.getLocation()) > maxDistanceSqrd) { if (targetBlock.getLocation().distanceSquared(p.getLocation()) > maxDistanceSqrd) {
LangManager.sendMessage(pplayer, Lang.FIXED_CREATE_LOOKING_TOO_FAR); LangManager.sendMessage(pplayer, Lang.FIXED_CREATE_LOOKING_TOO_FAR);
@ -307,7 +307,7 @@ public class FixedCommandModule implements CommandModule {
double xPos, yPos, zPos; double xPos, yPos, zPos;
if (args[2].equalsIgnoreCase("looking")) { if (args[2].equalsIgnoreCase("looking")) {
Block targetBlock = p.getTargetBlock(null, 8); Block targetBlock = p.getTargetBlock((Set<Material>) null, 8);
int maxDistanceSqrd = 6 * 6; int maxDistanceSqrd = 6 * 6;
if (targetBlock.getLocation().distanceSquared(p.getLocation()) > maxDistanceSqrd) { if (targetBlock.getLocation().distanceSquared(p.getLocation()) > maxDistanceSqrd) {
LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_LOOKING_TOO_FAR); LangManager.sendMessage(pplayer, Lang.FIXED_EDIT_LOOKING_TOO_FAR);

View file

@ -3,6 +3,7 @@ package com.esophose.playerparticles.gui;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.esophose.playerparticles.util.NMSUtil;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
@ -166,7 +167,7 @@ public class GuiActionButton {
} }
// Split the lore along \n onto a new line if any exist // Split the lore along \n onto a new line if any exist
String[] splitLines = line.split("\\\\n"); String[] splitLines = NMSUtil.getVersionNumber() > 13 ? line.split("\n") : line.split("\\\\n");
for (String parsedLine : splitLines) { for (String parsedLine : splitLines) {
if (ChatColor.stripColor(parsedLine).isEmpty()) continue; if (ChatColor.stripColor(parsedLine).isEmpty()) continue;
parsedLore.add(lineColor + parsedLine); parsedLore.add(lineColor + parsedLine);

View file

@ -242,7 +242,7 @@ public class GuiInventoryEditData extends GuiInventory {
*/ */
private void populateNoteData(ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) { private void populateNoteData(ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
int numberOfItems = noteColorMapping.length; int numberOfItems = noteColorMapping.length;
int maxPages = (int) Math.floor(numberOfItems / 28.0); int maxPages = (int) Math.ceil(numberOfItems / 28.0);
int itemsPerPage = 14; int itemsPerPage = 14;
int slot = 10; int slot = 10;
int nextWrap = 17; int nextWrap = 17;
@ -335,7 +335,7 @@ public class GuiInventoryEditData extends GuiInventory {
*/ */
private void populateItemData(ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) { private void populateItemData(ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
int numberOfItems = ITEM_MATERIALS.size(); int numberOfItems = ITEM_MATERIALS.size();
int maxPages = (int) Math.floor(numberOfItems / 28.0); int maxPages = (int) Math.ceil(numberOfItems / 28.0);
int itemsPerPage = 28; int itemsPerPage = 28;
int slot = 10; int slot = 10;
int nextWrap = 17; int nextWrap = 17;
@ -396,7 +396,7 @@ public class GuiInventoryEditData extends GuiInventory {
*/ */
private void populateBlockData(ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) { private void populateBlockData(ParticlePair editingParticle, int pageNumber, List<GuiInventoryEditFinishedCallback> callbackList, int callbackListPosition) {
int numberOfItems = BLOCK_MATERIALS.size(); int numberOfItems = BLOCK_MATERIALS.size();
int maxPages = (int) Math.floor(numberOfItems / 28.0); int maxPages = (int) Math.ceil(numberOfItems / 28.0);
int itemsPerPage = 28; int itemsPerPage = 28;
int slot = 10; int slot = 10;
int nextWrap = 17; int nextWrap = 17;

View file

@ -22,7 +22,7 @@ public class GuiInventoryEditEffect extends GuiInventory {
// Select Effect Buttons // Select Effect Buttons
List<ParticleEffect> effectsUserHasPermissionFor = PermissionManager.getEffectsUserHasPermissionFor(pplayer.getPlayer()); List<ParticleEffect> effectsUserHasPermissionFor = PermissionManager.getEffectsUserHasPermissionFor(pplayer.getPlayer());
int numberOfItems = effectsUserHasPermissionFor.size(); int numberOfItems = effectsUserHasPermissionFor.size();
int maxPages = (int) Math.floor(numberOfItems / 28.0); int maxPages = (int) Math.ceil(numberOfItems / 28.0);
int itemsPerPage = 28; int itemsPerPage = 28;
int slot = 10; int slot = 10;
int nextWrap = 17; int nextWrap = 17;

View file

@ -22,7 +22,7 @@ public class GuiInventoryEditStyle extends GuiInventory {
// Select Style Buttons // Select Style Buttons
List<ParticleStyle> stylesUserHasPermissionFor = PermissionManager.getStylesUserHasPermissionFor(pplayer.getPlayer()); List<ParticleStyle> stylesUserHasPermissionFor = PermissionManager.getStylesUserHasPermissionFor(pplayer.getPlayer());
int numberOfItems = stylesUserHasPermissionFor.size(); int numberOfItems = stylesUserHasPermissionFor.size();
int maxPages = (int) Math.floor(numberOfItems / 28.0); int maxPages = (int) Math.ceil(numberOfItems / 28.0);
int itemsPerPage = 28; int itemsPerPage = 28;
int slot = 10; int slot = 10;
int nextWrap = 17; int nextWrap = 17;

View file

@ -3,6 +3,7 @@ package com.esophose.playerparticles.gui.hook;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import com.esophose.playerparticles.util.NMSUtil;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -68,7 +69,12 @@ public class PlayerChatHook extends BukkitRunnable implements Listener {
if (player == null) { if (player == null) {
hooksToRemove.remove(hook); hooksToRemove.remove(hook);
} else { } else {
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(LangManager.getText(Lang.GUI_SAVE_GROUP_HOTBAR_MESSAGE, hook.getTimeRemaining()))); if (NMSUtil.getVersionNumber() == 9) {
if (hook.getMaxHookLength() == hook.getTimeRemaining())
player.sendMessage(LangManager.getText(Lang.GUI_SAVE_GROUP_HOTBAR_MESSAGE, hook.getTimeRemaining()));
} else {
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(LangManager.getText(Lang.GUI_SAVE_GROUP_HOTBAR_MESSAGE, hook.getTimeRemaining())));
}
} }
} }

View file

@ -5,11 +5,13 @@ import java.util.UUID;
public class PlayerChatHookData { public class PlayerChatHookData {
private UUID playerUUID; private UUID playerUUID;
private int maxHookLength;
private int hookLength; private int hookLength;
private PlayerChatHookCallback hookCallback; private PlayerChatHookCallback hookCallback;
public PlayerChatHookData(UUID playerUUID, int hookLength, PlayerChatHookCallback hookCallback) { public PlayerChatHookData(UUID playerUUID, int hookLength, PlayerChatHookCallback hookCallback) {
this.playerUUID = playerUUID; this.playerUUID = playerUUID;
this.maxHookLength = hookLength;
this.hookLength = hookLength; this.hookLength = hookLength;
this.hookCallback = hookCallback; this.hookCallback = hookCallback;
} }
@ -39,6 +41,15 @@ public class PlayerChatHookData {
return this.hookLength <= 0; return this.hookLength <= 0;
} }
/**
* Gets the max length of the hook
*
* @return The max length of the hook
*/
public int getMaxHookLength() {
return this.maxHookLength;
}
/** /**
* Gets how much time is remaining on the hook * Gets how much time is remaining on the hook
* *

View file

@ -129,10 +129,10 @@ public class ParticleManager extends BukkitRunnable implements Listener {
if (!ParticleStyleManager.isCustomHandled(particle.getStyle())) { if (!ParticleStyleManager.isCustomHandled(particle.getStyle())) {
if (PSetting.TOGGLE_ON_MOVE.getBoolean() && particle.getStyle().canToggleWithMovement() && pplayer.isMoving()) { if (PSetting.TOGGLE_ON_MOVE.getBoolean() && particle.getStyle().canToggleWithMovement() && pplayer.isMoving()) {
for (PParticle pparticle : DefaultStyles.FEET.getParticles(particle, location)) for (PParticle pparticle : DefaultStyles.FEET.getParticles(particle, location))
ParticleEffect.display(particle, pparticle, false); ParticleEffect.display(particle, pparticle, false, pplayer.getPlayer());
} else { } else {
for (PParticle pparticle : particle.getStyle().getParticles(particle, location)) for (PParticle pparticle : particle.getStyle().getParticles(particle, location))
ParticleEffect.display(particle, pparticle, false); ParticleEffect.display(particle, pparticle, false, pplayer.getPlayer());
} }
} }
} }
@ -145,7 +145,7 @@ public class ParticleManager extends BukkitRunnable implements Listener {
*/ */
public static void displayParticles(ParticlePair particle, List<PParticle> particles) { public static void displayParticles(ParticlePair particle, List<PParticle> particles) {
for (PParticle pparticle : particles) for (PParticle pparticle : particles)
ParticleEffect.display(particle, pparticle, false); ParticleEffect.display(particle, pparticle, false, Bukkit.getPlayer(particle.getOwnerUniqueId()));
} }
/** /**
@ -156,7 +156,7 @@ public class ParticleManager extends BukkitRunnable implements Listener {
private void displayFixedParticleEffect(FixedParticleEffect fixedEffect) { private void displayFixedParticleEffect(FixedParticleEffect fixedEffect) {
ParticlePair particle = fixedEffect.getParticlePair(); ParticlePair particle = fixedEffect.getParticlePair();
for (PParticle pparticle : particle.getStyle().getParticles(particle, fixedEffect.getLocation().clone().add(0, particle.getStyle().getFixedEffectOffset(), 0))) for (PParticle pparticle : particle.getStyle().getParticles(particle, fixedEffect.getLocation().clone().add(0, particle.getStyle().getFixedEffectOffset(), 0)))
ParticleEffect.display(particle, pparticle, true); ParticleEffect.display(particle, pparticle, true, null);
} }
/** /**

View file

@ -209,17 +209,18 @@ public enum ParticleEffect {
* @param particle The ParticlePair, given the effect/style/data * @param particle The ParticlePair, given the effect/style/data
* @param pparticle The particle spawn information * @param pparticle The particle spawn information
* @param isFixedEffect If the particle is spawned from a fixed effect * @param isFixedEffect If the particle is spawned from a fixed effect
* @param owner The player that owns the particles
*/ */
public static void display(ParticlePair particle, PParticle pparticle, boolean isFixedEffect) { public static void display(ParticlePair particle, PParticle pparticle, boolean isFixedEffect, Player owner) {
ParticleEffect effect = particle.getEffect(); ParticleEffect effect = particle.getEffect();
int count = pparticle.isDirectional() ? 0 : 1; int count = pparticle.isDirectional() ? 0 : 1;
if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { if (effect.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
effect.display(particle.getSpawnMaterial(), pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect); effect.display(particle.getSpawnMaterial(), pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), 1, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect, owner);
} else if (effect.hasProperty(ParticleProperty.COLORABLE)) { } else if (effect.hasProperty(ParticleProperty.COLORABLE)) {
effect.display(particle.getSpawnColor(), pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect); effect.display(particle.getSpawnColor(), pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect, owner);
} else { } else {
effect.display(pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), count, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect); effect.display(pparticle.getXOff(), pparticle.getYOff(), pparticle.getZOff(), pparticle.getSpeed(), count, pparticle.getLocation(effect.hasProperty(ParticleProperty.COLORABLE)), isFixedEffect, owner);
} }
} }
@ -233,14 +234,15 @@ public enum ParticleEffect {
* @param amount Amount of particles * @param amount Amount of particles
* @param center Center location of the effect * @param center Center location of the effect
* @param isFixedEffect If the particle is spawned from a fixed effect * @param isFixedEffect If the particle is spawned from a fixed effect
* @param owner The player that owns the particles
* @throws ParticleDataException If the particle effect requires additional data * @throws ParticleDataException If the particle effect requires additional data
*/ */
public void display(double offsetX, double offsetY, double offsetZ, double speed, int amount, Location center, boolean isFixedEffect) throws ParticleDataException { public void display(double offsetX, double offsetY, double offsetZ, double speed, int amount, Location center, boolean isFixedEffect, Player owner) throws ParticleDataException {
if (this.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { if (this.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
throw new ParticleDataException("This particle effect requires additional data"); throw new ParticleDataException("This particle effect requires additional data");
} }
for (Player player : this.getPlayersInRange(center, isFixedEffect)) { for (Player player : this.getPlayersInRange(center, isFixedEffect, owner)) {
player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), amount, offsetX, offsetY, offsetZ, speed); player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), amount, offsetX, offsetY, offsetZ, speed);
} }
} }
@ -251,9 +253,10 @@ public enum ParticleEffect {
* @param color Color of the particle * @param color Color of the particle
* @param center Center location of the effect * @param center Center location of the effect
* @param isFixedEffect If the particle is spawned from a fixed effect * @param isFixedEffect If the particle is spawned from a fixed effect
* @param owner The player that owns the particles
* @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect * @throws ParticleColorException If the particle effect is not colorable or the color type is incorrect
*/ */
public void display(ParticleColor color, Location center, boolean isFixedEffect) throws ParticleColorException { public void display(ParticleColor color, Location center, boolean isFixedEffect, Player owner) throws ParticleColorException {
if (!this.hasProperty(ParticleProperty.COLORABLE)) { if (!this.hasProperty(ParticleProperty.COLORABLE)) {
throw new ParticleColorException("This particle effect is not colorable"); throw new ParticleColorException("This particle effect is not colorable");
} }
@ -265,11 +268,11 @@ public enum ParticleEffect {
dustData = DustOptions_CONSTRUCTOR.newInstance(Color.fromRGB(dustColor.getRed(), dustColor.getGreen(), dustColor.getBlue()), 1); // Wait, you can change the size of these now??? AWESOME! I might implement this in the future! dustData = DustOptions_CONSTRUCTOR.newInstance(Color.fromRGB(dustColor.getRed(), dustColor.getGreen(), dustColor.getBlue()), 1); // Wait, you can change the size of these now??? AWESOME! I might implement this in the future!
} catch (Exception ignored) { } } catch (Exception ignored) { }
for (Player player : this.getPlayersInRange(center, isFixedEffect)) { for (Player player : this.getPlayersInRange(center, isFixedEffect, owner)) {
player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), 1, 0, 0, 0, 0, dustData); player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), 1, 0, 0, 0, 0, dustData);
} }
} else { } else {
for (Player player : this.getPlayersInRange(center, isFixedEffect)) { for (Player player : this.getPlayersInRange(center, isFixedEffect, owner)) {
// Minecraft clients require that you pass a non-zero value if the Red value should be zero // Minecraft clients require that you pass a non-zero value if the Red value should be zero
player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), 0, this == ParticleEffect.DUST && color.getValueX() == 0 ? Float.MIN_VALUE : color.getValueX(), color.getValueY(), color.getValueZ(), 1); player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), 0, this == ParticleEffect.DUST && color.getValueX() == 0 ? Float.MIN_VALUE : color.getValueX(), color.getValueY(), color.getValueZ(), 1);
} }
@ -289,9 +292,10 @@ public enum ParticleEffect {
* @param amount Amount of particles * @param amount Amount of particles
* @param center Center location of the effect * @param center Center location of the effect
* @param isFixedEffect If the particle is spawned from a fixed effect * @param isFixedEffect If the particle is spawned from a fixed effect
* @param owner The player that owns the particles
* @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect * @throws ParticleDataException If the particle effect does not require additional data or if the data type is incorrect
*/ */
public void display(Material spawnMaterial, double offsetX, double offsetY, double offsetZ, double speed, int amount, Location center, boolean isFixedEffect) throws ParticleDataException { public void display(Material spawnMaterial, double offsetX, double offsetY, double offsetZ, double speed, int amount, Location center, boolean isFixedEffect, Player owner) throws ParticleDataException {
if (!this.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) { if (!this.hasProperty(ParticleProperty.REQUIRES_MATERIAL_DATA)) {
throw new ParticleDataException("This particle effect does not require additional data"); throw new ParticleDataException("This particle effect does not require additional data");
} }
@ -307,7 +311,7 @@ public enum ParticleEffect {
extraData = new MaterialData(spawnMaterial); // Deprecated, only used in versions < 1.13 extraData = new MaterialData(spawnMaterial); // Deprecated, only used in versions < 1.13
} }
for (Player player : this.getPlayersInRange(center, isFixedEffect)) for (Player player : this.getPlayersInRange(center, isFixedEffect, owner))
player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), amount, offsetX, offsetY, offsetZ, speed, extraData); player.spawnParticle(this.internalEnum, center.getX(), center.getY(), center.getZ(), amount, offsetX, offsetY, offsetZ, speed, extraData);
} }
@ -316,14 +320,18 @@ public enum ParticleEffect {
* *
* @param center The center of the radius to check around * @param center The center of the radius to check around
* @param isFixedEffect If the particle is spawned from a fixed effect * @param isFixedEffect If the particle is spawned from a fixed effect
* @param owner The player that owns the particles
* @return A List of Players within the particle display range * @return A List of Players within the particle display range
*/ */
private List<Player> getPlayersInRange(Location center, boolean isFixedEffect) { private List<Player> getPlayersInRange(Location center, boolean isFixedEffect, Player owner) {
List<Player> players = new ArrayList<>(); List<Player> players = new ArrayList<>();
int range = !isFixedEffect ? PSetting.PARTICLE_RENDER_RANGE_PLAYER.getInt() : PSetting.PARTICLE_RENDER_RANGE_FIXED_EFFECT.getInt(); int range = !isFixedEffect ? PSetting.PARTICLE_RENDER_RANGE_PLAYER.getInt() : PSetting.PARTICLE_RENDER_RANGE_FIXED_EFFECT.getInt();
for (PPlayer pplayer : ParticleManager.getPPlayers()) { for (PPlayer pplayer : ParticleManager.getPPlayers()) {
Player p = pplayer.getPlayer(); Player p = pplayer.getPlayer();
if (!isFixedEffect && !p.canSee(owner))
continue;
if (p != null && pplayer.canSeeParticles() && p.getWorld().equals(center.getWorld()) && center.distanceSquared(p.getLocation()) <= range * range) { if (p != null && pplayer.canSeeParticles() && p.getWorld().equals(center.getWorld()) && center.distanceSquared(p.getLocation()) <= range * range) {
players.add(p); players.add(p);
} }

View file

@ -4,14 +4,20 @@ import org.bukkit.Bukkit;
public class NMSUtil { public class NMSUtil {
private static String cachedVersion = null;
private static int cachedVersionNumber = -1;
/** /**
* Gets the server version * Gets the server version
* *
* @return The server version * @return The server version
*/ */
public static String getVersion() { public static String getVersion() {
String name = Bukkit.getServer().getClass().getPackage().getName(); if (cachedVersion == null) {
return name.substring(name.lastIndexOf('.') + 1) + "."; String name = Bukkit.getServer().getClass().getPackage().getName();
cachedVersion = name.substring(name.lastIndexOf('.') + 1) + ".";
}
return cachedVersion;
} }
/** /**
@ -20,8 +26,11 @@ public class NMSUtil {
* @return The server version major release number * @return The server version major release number
*/ */
public static int getVersionNumber() { public static int getVersionNumber() {
String name = getVersion().substring(3); if (cachedVersionNumber == -1) {
return Integer.valueOf(name.substring(0, name.length() - 4)); String name = getVersion().substring(3);
cachedVersionNumber = Integer.valueOf(name.substring(0, name.length() - 4));
}
return cachedVersionNumber;
} }
} }