diff --git a/pom.xml b/pom.xml
index eadbb533..27076526 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
LibsDisguises
LibsDisguises
- 9.7.0
+ 9.7.0-SNAPSHOT
clean install
@@ -35,6 +35,7 @@
+ unknown
1.8
1.8
UTF-8
diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java
index 1bb8799d..47e93a07 100644
--- a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java
+++ b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java
@@ -22,6 +22,12 @@ public class DisguiseConfig {
CREATE_SCOREBOARD;
}
+ public enum UpdatesBranch {
+ SAME_BUILDS,
+ SNAPSHOTS,
+ RELEASES
+ }
+
private static boolean animationEnabled;
private static boolean bedEnabled;
private static boolean blowDisguisesWhenAttacking;
@@ -69,6 +75,15 @@ public class DisguiseConfig {
private static boolean explicitDisguisePermissions;
private static boolean disableCommands;
private static int uuidGeneratedVersion;
+ private static UpdatesBranch updatesBranch = UpdatesBranch.SAME_BUILDS;
+
+ public static UpdatesBranch getUpdatesBranch() {
+ return updatesBranch;
+ }
+
+ public static void setUpdatesBranch(UpdatesBranch newBranch) {
+ updatesBranch = newBranch;
+ }
public static int getUUIDGeneratedVersion() {
return uuidGeneratedVersion;
@@ -260,6 +275,14 @@ public class DisguiseConfig {
DisguiseUtilities.getLogger().warning("You must purchase the plugin to use saved disguises!");
}
+ try {
+ setUpdatesBranch(UpdatesBranch.valueOf(config.getString("UpdatesBranch").toUpperCase()));
+ }
+ catch (Exception ex) {
+ DisguiseUtilities.getLogger().warning("Cannot parse '" + config.getString("UpdatesBranch") +
+ "' to a valid option for UpdatesBranch");
+ }
+
try {
String option = config.getString("SelfDisguisesScoreboard", DisguisePushing.MODIFY_SCOREBOARD.name())
.toUpperCase();
@@ -270,7 +293,7 @@ public class DisguiseConfig {
disablePushing = DisguisePushing.valueOf(option);
}
catch (Exception ex) {
- DisguiseUtilities.getLogger().info("Cannot parse '" + config.getString("SelfDisguisesScoreboard") +
+ DisguiseUtilities.getLogger().warning("Cannot parse '" + config.getString("SelfDisguisesScoreboard") +
"' to a valid option for SelfDisguisesTeam");
}
diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseListener.java b/src/main/java/me/libraryaddict/disguise/DisguiseListener.java
index be4a8c28..e93090fd 100644
--- a/src/main/java/me/libraryaddict/disguise/DisguiseListener.java
+++ b/src/main/java/me/libraryaddict/disguise/DisguiseListener.java
@@ -23,6 +23,7 @@ import me.libraryaddict.disguise.utilities.parser.DisguisePermissions;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
+import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
@@ -47,60 +48,23 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.concurrent.TimeUnit;
public class DisguiseListener implements Listener {
-
private String currentVersion;
private HashMap disguiseClone = new HashMap<>();
private HashMap disguiseEntity = new HashMap<>();
private HashMap disguiseModify = new HashMap<>();
private HashMap disguiseRunnable = new HashMap<>();
private String latestVersion;
+ private LibsMsg updateMessage;
private LibsDisguises plugin;
private BukkitTask updaterTask;
public DisguiseListener(LibsDisguises libsDisguises) {
plugin = libsDisguises;
- if (plugin.getConfig().getBoolean("NotifyUpdate")) {
- currentVersion = plugin.getDescription().getVersion();
-
- updaterTask = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
- @Override
- public void run() {
- try {
- UpdateChecker updateChecker = new UpdateChecker();
- updateChecker.checkUpdate("v" + currentVersion);
-
- latestVersion = updateChecker.getLatestVersion();
-
- if (latestVersion == null) {
- return;
- }
-
- latestVersion = "v" + latestVersion;
-
- Bukkit.getScheduler().runTask(plugin, new Runnable() {
- @Override
- public void run() {
- for (Player p : Bukkit.getOnlinePlayers()) {
- if (!p.hasPermission(DisguiseConfig.getUpdateNotificationPermission())) {
- continue;
- }
-
- p.sendMessage(LibsMsg.UPDATE_READY.get(currentVersion, latestVersion));
- }
- }
- });
- }
- catch (Exception ex) {
- DisguiseUtilities.getLogger()
- .warning(String.format("Failed to check for update: %s", ex.getMessage()));
- }
- }
- }, 0, (20 * 60 * 60 * 6)); // Check every 6 hours
- // 20 ticks * 60 seconds * 60 minutes * 6 hours
- }
+ runUpdateScheduler();
if (!DisguiseConfig.isSaveEntityDisguises())
return;
@@ -122,6 +86,90 @@ public class DisguiseListener implements Listener {
}
}
+ private boolean isCheckReleases() {
+ if (DisguiseConfig.getUpdatesBranch() == DisguiseConfig.UpdatesBranch.RELEASES) {
+ return true;
+ }
+
+ if (DisguiseConfig.getUpdatesBranch() == DisguiseConfig.UpdatesBranch.SAME_BUILDS && plugin.isReleaseBuild()) {
+ return true;
+ }
+
+ // If build number is null, or not a number. Then we can't check snapshots regardless
+ if (plugin.getBuildNo() == null || !plugin.getBuildNo().matches("[0-9]+")) {
+ return true;
+ }
+
+ // Check snapshots
+ return false;
+ }
+
+ private void runUpdateScheduler() {
+ if (!plugin.getConfig().getBoolean("NotifyUpdate")) {
+ return;
+ }
+
+ updaterTask = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
+ @Override
+ public void run() {
+ try {
+ UpdateChecker updateChecker = new UpdateChecker("32453");
+ boolean checkReleases = isCheckReleases();
+
+ if (checkReleases) {
+ currentVersion = plugin.getDescription().getVersion();
+ updateChecker.checkOfficialUpdate(currentVersion);
+ String version = updateChecker.getLatestVersion();
+
+ if (version == null) {
+ return;
+ }
+
+ latestVersion = version;
+ updateMessage = LibsMsg.UPDATE_READY;
+ } else {
+ updateChecker.checkSnapshotUpdate(Integer.parseInt(plugin.getBuildNo()));
+
+ if (updateChecker.getLatestSnapshot() <= 0) {
+ return;
+ }
+
+ currentVersion = plugin.getBuildNo();
+ latestVersion = "" + updateChecker.getLatestSnapshot();
+ updateMessage = LibsMsg.UPDATE_READY_SNAPSHOT;
+ }
+
+ Bukkit.getScheduler().runTask(plugin, new Runnable() {
+ @Override
+ public void run() {
+ notifyUpdate(Bukkit.getConsoleSender());
+
+ for (Player p : Bukkit.getOnlinePlayers()) {
+ notifyUpdate(p);
+ }
+ }
+ });
+ }
+ catch (Exception ex) {
+ DisguiseUtilities.getLogger()
+ .warning(String.format("Failed to check for update: %s", ex.getMessage()));
+ }
+ }
+ }, 0, (20 * TimeUnit.HOURS.toSeconds(6))); // Check every 6 hours
+ }
+
+ private void notifyUpdate(CommandSender player) {
+ if (!player.hasPermission(DisguiseConfig.getUpdateNotificationPermission())) {
+ return;
+ }
+
+ if (latestVersion == null) {
+ return;
+ }
+
+ player.sendMessage(updateMessage.get(currentVersion, latestVersion));
+ }
+
public void cleanup() {
for (BukkitRunnable r : disguiseRunnable.values()) {
r.cancel();
@@ -284,9 +332,7 @@ public class DisguiseListener implements Listener {
public void onJoin(PlayerJoinEvent event) {
Player p = event.getPlayer();
- if (latestVersion != null && p.hasPermission(DisguiseConfig.getUpdateNotificationPermission())) {
- p.sendMessage(LibsMsg.UPDATE_READY.get(currentVersion, latestVersion));
- }
+ notifyUpdate(p);
if (DisguiseConfig.isBedPacketsEnabled()) {
chunkMove(p, p.getLocation(), null);
diff --git a/src/main/java/me/libraryaddict/disguise/LibsDisguises.java b/src/main/java/me/libraryaddict/disguise/LibsDisguises.java
index 1148bf24..88a12945 100644
--- a/src/main/java/me/libraryaddict/disguise/LibsDisguises.java
+++ b/src/main/java/me/libraryaddict/disguise/LibsDisguises.java
@@ -13,6 +13,7 @@ import org.bukkit.Bukkit;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.TabCompleter;
+import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.*;
import org.bukkit.plugin.java.JavaPlugin;
@@ -27,23 +28,32 @@ import java.util.HashSet;
public class LibsDisguises extends JavaPlugin {
private static LibsDisguises instance;
private DisguiseListener listener;
+ private String buildNumber;
@Override
public void onEnable() {
instance = this;
- getLogger().info("Discovered nms version: " + ReflectionManager.getBukkitVersion());
-
if (!new File(getDataFolder(), "disguises.yml").exists()) {
saveResource("disguises.yml", false);
}
+ YamlConfiguration pluginYml = ReflectionManager.getPluginYaml(getClassLoader());
+ buildNumber = StringUtils.stripToNull(pluginYml.getString("build-number"));
+
+ getLogger().info("Discovered nms version: " + ReflectionManager.getBukkitVersion());
+
+ boolean hashBuild = getBuildNo() != null && getBuildNo().matches("[0-9]+");
+ getLogger().info("Jenkins Build: " + (hashBuild ? "#" : "") + getBuildNo());
+
LibsPremium.check(getDescription().getVersion());
if (ReflectionManager.getMinecraftVersion().startsWith("1.13")) {
if (!LibsPremium.isPremium()) {
getLogger().severe("You must purchase the plugin to use 1.13!");
- getLogger().severe("This will be released in just a few days, or you can buy it now for 50% off with all premium-only features included!");
+ getLogger()
+ .severe("This will be released in just a few days, or you can buy it now for 50% off with all" +
+ " premium-only features included!");
getLogger().severe("If you've already purchased the plugin, place the purchased jar inside the " +
"Lib's Disguises plugin folder");
getPluginLoader().disablePlugin(this);
@@ -92,8 +102,25 @@ public class LibsDisguises extends JavaPlugin {
infectWithMetrics();
}
+ @Override
+ public void onDisable() {
+ DisguiseUtilities.saveDisguises();
+
+ for (Player player : Bukkit.getOnlinePlayers()) {
+ DisguiseUtilities.removeSelfDisguiseScoreboard(player);
+ }
+ }
+
private void infectWithMetrics() {
- Metrics metrics = new Metrics(this);
+ String version = getDescription().getVersion();
+
+ // If a release build, attach build number
+ if (!isReleaseBuild()) {
+ // 9.7.0-SNAPSHOT-b30
+ version += "-b" + getBuildNo();
+ }
+
+ Metrics metrics = new Metrics(this, version);
final String premium = LibsPremium.isPremium() ?
getDescription().getVersion().contains("SNAPSHOT") ? "Paid Builds" : "Paid Plugin" : "Free Builds";
@@ -209,7 +236,6 @@ public class LibsDisguises extends JavaPlugin {
}
});
-
metrics.addCustomChart(new Metrics.SimplePie("commands") {
@Override
public String getValue() {
@@ -239,6 +265,15 @@ public class LibsDisguises extends JavaPlugin {
}
});
+ if (getBuildNo() != null) {
+ metrics.addCustomChart(new Metrics.SimplePie("build_number") {
+ @Override
+ public String getValue() {
+ return getBuildNo();
+ }
+ });
+ }
+
metrics.addCustomChart(new Metrics.SimplePie("targeted_disguises") {
/**
* Store value just to minimize amount of times it's called, and to persist even when not using anymore
@@ -271,13 +306,12 @@ public class LibsDisguises extends JavaPlugin {
});
}
- @Override
- public void onDisable() {
- DisguiseUtilities.saveDisguises();
+ public boolean isReleaseBuild() {
+ return !getDescription().getVersion().contains("-SNAPSHOT");
+ }
- for (Player player : Bukkit.getOnlinePlayers()) {
- DisguiseUtilities.removeSelfDisguiseScoreboard(player);
- }
+ public String getBuildNo() {
+ return buildNumber;
}
private void registerCommand(String commandName, CommandExecutor executioner) {
diff --git a/src/main/java/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java b/src/main/java/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java
index 8bb7e6c6..b551e5a5 100644
--- a/src/main/java/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java
+++ b/src/main/java/me/libraryaddict/disguise/commands/LibsDisguisesCommand.java
@@ -1,9 +1,9 @@
package me.libraryaddict.disguise.commands;
import me.libraryaddict.disguise.DisguiseConfig;
+import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.utilities.LibsMsg;
import me.libraryaddict.disguise.utilities.LibsPremium;
-import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@@ -52,9 +52,16 @@ public class LibsDisguisesCommand implements CommandExecutor, TabCompleter {
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if (args.length == 0) {
- sender.sendMessage(ChatColor.DARK_GREEN + "This server is running " + "Lib's Disguises v" +
- Bukkit.getPluginManager().getPlugin("LibsDisguises").getDescription().getVersion() +
- " by libraryaddict, formerly maintained " + "by Byteflux and NavidK0." +
+ LibsDisguises disguises = LibsDisguises.getInstance();
+
+ String version = disguises.getDescription().getVersion();
+
+ if (!disguises.isReleaseBuild()) {
+ version += "-b" + disguises.getBuildNo();
+ }
+
+ sender.sendMessage(ChatColor.DARK_GREEN + "This server is running " + "Lib's Disguises v" + version +
+ " by libraryaddict, formerly maintained by Byteflux and NavidK0." +
(sender.hasPermission("libsdisguises.reload") ?
"\nUse " + ChatColor.GREEN + "/libsdisguises " + "reload" + ChatColor.DARK_GREEN +
" to reload the config. All disguises will be blown by doing this" + "." : ""));
diff --git a/src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java b/src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java
index 9efcf5d3..49b4edea 100644
--- a/src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java
+++ b/src/main/java/me/libraryaddict/disguise/utilities/LibsMsg.java
@@ -167,7 +167,11 @@ public enum LibsMsg {
UNDISRADIUS(ChatColor.RED + "Successfully undisguised %s entities!"),
UPDATE_READY(ChatColor.RED + "[LibsDisguises] " + ChatColor.DARK_RED +
"There is a update ready to be downloaded! You are using " + ChatColor.RED + "v%s" + ChatColor.DARK_RED +
- ", the new version is " + ChatColor.RED + "%s" + ChatColor.DARK_RED + "!"),
+ ", the new version is " + ChatColor.RED + "v%s" + ChatColor.DARK_RED + "!"),
+ UPDATE_READY_SNAPSHOT(ChatColor.RED + "[LibsDisguises] " + ChatColor.DARK_RED +
+ "There is a new build of Lib's Disguises! You are using " + ChatColor.RED + "#%s" +
+ ChatColor.DARK_RED + ", the latest build is " + ChatColor.RED + "#%s" + ChatColor.DARK_RED + "!" +
+ ChatColor.RED + "\nhttps://ci.md-5.net/job/LibsDisguises/lastSuccessfulBuild/"),
VIEW_SELF_ON(ChatColor.GREEN + "Toggled viewing own disguise on!"),
VIEW_SELF_OFF(ChatColor.GREEN + "Toggled viewing own disguise off!");
diff --git a/src/main/java/me/libraryaddict/disguise/utilities/LibsPremium.java b/src/main/java/me/libraryaddict/disguise/utilities/LibsPremium.java
index 59a1698f..2568ceee 100644
--- a/src/main/java/me/libraryaddict/disguise/utilities/LibsPremium.java
+++ b/src/main/java/me/libraryaddict/disguise/utilities/LibsPremium.java
@@ -1,10 +1,8 @@
package me.libraryaddict.disguise.utilities;
-import org.apache.commons.io.IOUtils;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
-import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
@@ -42,12 +40,9 @@ public class LibsPremium {
thisPluginIsPaidFor = (Boolean) m.invoke(null);
String pluginVersion;
- try (InputStream stream = cl.getResourceAsStream("plugin.yml")) {
- YamlConfiguration config = new YamlConfiguration();
- config.loadFromString(IOUtils.toString(stream, "UTF-8"));
+ YamlConfiguration config = ReflectionManager.getPluginYaml(cl);
- pluginVersion = config.getString("version");
- }
+ pluginVersion = config.getString("version");
if (isPremium()) {
// Found a premium Lib's Disguises jar (v5.2.6), premium enabled!
diff --git a/src/main/java/me/libraryaddict/disguise/utilities/Metrics.java b/src/main/java/me/libraryaddict/disguise/utilities/Metrics.java
index 79ecb62b..0daa4883 100644
--- a/src/main/java/me/libraryaddict/disguise/utilities/Metrics.java
+++ b/src/main/java/me/libraryaddict/disguise/utilities/Metrics.java
@@ -31,8 +31,8 @@ public class Metrics {
final String examplePackage = new String(
new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure nobody just copy & pastes the example and use the wrong package names
- if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName()
- .equals(examplePackage)) {
+ if (Metrics.class.getPackage().getName().equals(defaultPackage) ||
+ Metrics.class.getPackage().getName().equals(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
@@ -51,6 +51,8 @@ public class Metrics {
// The plugin
private final JavaPlugin plugin;
+ // The plugin version
+ private final String version;
// A list with all custom charts
private final List charts = new ArrayList<>();
@@ -60,11 +62,13 @@ public class Metrics {
*
* @param plugin The plugin which stats should be submitted.
*/
- public Metrics(JavaPlugin plugin) {
+ public Metrics(JavaPlugin plugin, String version) {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null!");
}
+
this.plugin = plugin;
+ this.version = version;
// Get the config file
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
@@ -83,8 +87,11 @@ public class Metrics {
// Inform the server owners about bStats
config.options()
- .header("bStats collects some data for plugin authors like how many servers are using their plugins.\n" + "To honor their work, you should not disable it.\n" + "This has nearly no effect on the server performance!\n" + "Check out https://bStats.org/ to learn more :)")
- .copyDefaults(true);
+ .header("bStats collects some data for plugin authors like how many servers are using their " +
+ "plugins.\n" +
+ "To honor their work, you should not disable it.\n" +
+ "This has nearly no effect on the server performance!\n" +
+ "Check out https://bStats.org/ to learn more :)").copyDefaults(true);
try {
config.save(configFile);
}
@@ -140,8 +147,10 @@ public class Metrics {
timer.cancel();
return;
}
- // Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
- // Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
+ // Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit
+ // scheduler
+ // Don't be afraid! The connection to the bStats server is still async, only the stats collection is
+ // sync ;)
Bukkit.getScheduler().runTask(plugin, new Runnable() {
@Override
public void run() {
@@ -165,10 +174,9 @@ public class Metrics {
JSONObject data = new JSONObject();
String pluginName = plugin.getDescription().getName();
- String pluginVersion = plugin.getDescription().getVersion();
data.put("pluginName", pluginName); // Append the name of the plugin
- data.put("pluginVersion", pluginVersion); // Append the version of the plugin
+ data.put("pluginVersion", version); // Append the version of the plugin
JSONArray customCharts = new JSONArray();
for (CustomChart customChart : charts) {
// Add the data of the custom charts
diff --git a/src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java b/src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java
index 7e01a0b2..1cae4fd4 100644
--- a/src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java
+++ b/src/main/java/me/libraryaddict/disguise/utilities/ReflectionManager.java
@@ -8,12 +8,17 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObje
import com.comphenix.protocol.wrappers.nbt.NbtWrapper;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
+import org.apache.commons.io.IOUtils;
import org.bukkit.*;
+import org.bukkit.configuration.InvalidConfigurationException;
+import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.*;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
+import java.io.IOException;
+import java.io.InputStream;
import java.lang.reflect.*;
import java.nio.ByteBuffer;
import java.util.Optional;
@@ -80,6 +85,20 @@ public class ReflectionManager {
entityCountField.setAccessible(true);
}
+ public static YamlConfiguration getPluginYaml(ClassLoader loader) {
+ try (InputStream stream = loader.getResourceAsStream("plugin.yml")) {
+ YamlConfiguration config = new YamlConfiguration();
+ config.loadFromString(IOUtils.toString(stream, "UTF-8"));
+
+ return config;
+ }
+ catch (IOException | InvalidConfigurationException e) {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
public static int getNewEntityId() {
return getNewEntityId(true);
}
diff --git a/src/main/java/me/libraryaddict/disguise/utilities/UpdateChecker.java b/src/main/java/me/libraryaddict/disguise/utilities/UpdateChecker.java
index 212f8650..6f7399a5 100644
--- a/src/main/java/me/libraryaddict/disguise/utilities/UpdateChecker.java
+++ b/src/main/java/me/libraryaddict/disguise/utilities/UpdateChecker.java
@@ -1,29 +1,60 @@
package me.libraryaddict.disguise.utilities;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
+import com.google.gson.Gson;
+import org.apache.commons.io.IOUtils;
+
+import java.io.InputStream;
+import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
-import java.util.regex.Pattern;
+import java.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
public class UpdateChecker {
-
+ private final String resourceID;
private String latestVersion;
+ private int latestSnapshot;
- private boolean checkHigher(String currentVersion, String newVersion) {
- String current = toReadable(currentVersion);
- String newVers = toReadable(newVersion);
- return current.compareTo(newVers) < 0;
+ public UpdateChecker(String resourceID) {
+ this.resourceID = resourceID;
}
- public void checkUpdate(String currentVersion) {
- String version = getSpigotVersion();
+ public void checkSnapshotUpdate(int buildNumber) {
+ Map lastBuild = fetchLastSnapshotBuild();
- if (version == null)
+ if (lastBuild == null || !lastBuild.containsKey("id") || !lastBuild.containsKey("timestamp")) {
return;
+ }
- if (!checkHigher(currentVersion, version))
+ int newBuildNumber = Integer.parseInt((String) lastBuild.get("id"));
+
+ // If new build number is same or older
+ if (newBuildNumber <= buildNumber) {
return;
+ }
+
+ Date newBuildDate = new Date(((Number) lastBuild.get("timestamp")).longValue());
+
+ // If the new snapshot is at least 3 days old
+ /*if (newBuildDate.getTime() >= System.currentTimeMillis() - TimeUnit.DAYS.toMillis(3)) {
+ return;
+ }*/
+
+ latestSnapshot = newBuildNumber;
+ }
+
+ public void checkOfficialUpdate(String currentVersion) {
+ String version = fetchSpigotVersion();
+
+ if (version == null) {
+ return;
+ }
+
+ if (!isNewerVersion(currentVersion, version)) {
+ return;
+ }
latestVersion = version;
}
@@ -32,21 +63,41 @@ public class UpdateChecker {
return latestVersion;
}
+ public int getLatestSnapshot() {
+ return latestSnapshot;
+ }
+
/**
* Asks spigot for the version
*/
- private String getSpigotVersion() {
+ private String fetchSpigotVersion() {
try {
- HttpURLConnection con = (HttpURLConnection) new URL("https://www.spigotmc.org/api/general.php")
- .openConnection();
+ // We're connecting to spigot's API
+ URL url = new URL("https://www.spigotmc.org/api/general.php");
+ // Creating a connection
+ HttpURLConnection con = (HttpURLConnection) url.openConnection();
+ // We're writing a body that contains the API access key (Not required and obsolete, but!)
con.setDoOutput(true);
- con.setRequestMethod("POST");
- con.getOutputStream()
- .write(("key=98BE0FE67F88AB82B4C197FAF1DC3B69206EFDCC4D3B80FC83A00037510B99B4&resource=32453")
- .getBytes("UTF-8"));
- String version = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
- if (version.length() <= 10) {
- return version;
+
+ // Can't think of a clean way to represent this without looking bad
+ String body = "key" + "=" + "98BE0FE67F88AB82B4C197FAF1DC3B69206EFDCC4D3B80FC83A00037510B99B4" + "&" +
+ "resource=" + this.resourceID;
+
+ // Get the output stream, what the site receives
+ try (OutputStream stream = con.getOutputStream()) {
+ // Write our body containing version and access key
+ stream.write(body.getBytes(StandardCharsets.UTF_8));
+ }
+
+ // Get the input stream, what we receive
+ try (InputStream input = con.getInputStream()) {
+ // Read it to string
+ String version = IOUtils.toString(input);
+
+ // If the version is not empty, return it
+ if (!version.isEmpty()) {
+ return version;
+ }
}
}
catch (Exception ex) {
@@ -56,12 +107,62 @@ public class UpdateChecker {
return null;
}
- private String toReadable(String version) {
- String[] split = Pattern.compile(".", Pattern.LITERAL).split(version.replace("v", ""));
- version = "";
- for (String s : split) {
- version += String.format("%4s", s);
+ private boolean isNewerVersion(String currentVersion, String newVersion) {
+ // Remove 'v' from string, split by decimal points
+ String[] cSplit = currentVersion.replace("v", "").split("\\.");
+ String[] nSplit = newVersion.replace("v", "").split("\\.");
+
+ // Iterate over the versions from left to right
+ for (int i = 0; i < Math.max(cSplit.length, nSplit.length); i++) {
+ // If the current version doesn't have the next version, then it's older
+ if (cSplit.length <= i) {
+ return true;
+ } else if (nSplit.length <= i) {
+ // If the new version doesn't have the next version, then it's older
+ return false;
+ }
+
+ // String compare the versions, should perform the same as an int compare
+ int compareResult = cSplit[i].compareTo(nSplit[i]);
+
+ // Same version
+ if (compareResult == 0) {
+ continue;
+ }
+
+ // Return if current version is inferior to new versio
+ return compareResult < 0;
}
- return version;
+
+ // Both versions should be the same, return false as it's not a newer version
+ return false;
+ }
+
+ /**
+ * Fetches from jenkins, using the REST api the last snapshot build information
+ */
+ private Map fetchLastSnapshotBuild() {
+ try {
+ // We're connecting to md_5's jenkins REST api
+ URL url = new URL("https://ci.md-5.net/job/LibsDisguises/lastSuccessfulBuild/api/json");
+ // Creating a connection
+ HttpURLConnection con = (HttpURLConnection) url.openConnection();
+ Map jsonObject;
+
+ // Get the input stream, what we receive
+ try (InputStream input = con.getInputStream()) {
+ // Read it to string
+ String json = IOUtils.toString(input);
+
+ jsonObject = new Gson().fromJson(json, Map.class);
+ }
+
+ return jsonObject;
+ }
+ catch (Exception ex) {
+ DisguiseUtilities.getLogger().warning("Failed to check for a snapshot update on jenkins.");
+ }
+
+ return null;
}
}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index d5f6e6a0..bbafb99b 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -72,6 +72,12 @@ NotifyUpdate: true
# Whats the permission to get the notification?
Permission: 'libsdisguises.update'
+# Where should the plugin check for updates?
+# SAME_BUILDS - Will check snapshots if you're not using a release build
+# RELEASES - Only check for actual releases
+# SNAPSHOTS - Only check for new snapshots
+UpdatesBranch: SAME_BUILDS
+
# Whats the max size allowed for command disguiseradius
DisguiseRadiusMax: 50
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 14e448eb..92a9b8c6 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -2,9 +2,11 @@ name: LibsDisguises
main: me.libraryaddict.disguise.LibsDisguises
description: A disguise plugin with various disguises.
version: ${project.version}
+build-number: ${build.number}
author: libraryaddict
authors: [Byteflux, Navid K.]
depend: [ProtocolLib]
+api-version: 1.13
commands:
libsdisguises:
permission: libsdisguises.seecmd.libsdisguises
@@ -128,6 +130,4 @@ permissions:
libsdisguises.seecmd.disguisemodifyradius:
description: See the /disguisemodifyradius command in tab-completion
libsdisguises.seecmd.disguisemodifyentity:
- description: See the /disguisemodifyentity command in tab-completion
-
-api-version: 1.13
\ No newline at end of file
+ description: See the /disguisemodifyentity command in tab-completion
\ No newline at end of file