Ability to check jenkin builds, rewritten version checking, show build number, config option for update check type, show console update notifications, minor change in string for update check

This commit is contained in:
libraryaddict
2018-12-16 14:47:42 +13:00
parent add91b6705
commit 5a8d39a3a0
12 changed files with 352 additions and 108 deletions

View File

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

View File

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

View File

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

View File

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

View File

@@ -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<String, Object> 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<String, Object> 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<String, Object> 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;
}
}