mirror of
https://github.com/libraryaddict/LibsDisguises.git
synced 2024-12-14 15:26:54 +01:00
Better handling for updates checking, can now autoupdate on dev and release builds
This commit is contained in:
parent
41dffe1b46
commit
b247a49a23
@ -13,6 +13,7 @@ import me.libraryaddict.disguise.utilities.parser.DisguiseParseException;
|
||||
import me.libraryaddict.disguise.utilities.parser.DisguiseParser;
|
||||
import me.libraryaddict.disguise.utilities.parser.DisguisePerm;
|
||||
import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
|
||||
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
||||
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
|
||||
import me.libraryaddict.disguise.utilities.translations.TranslateType;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -26,16 +27,16 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class DisguiseConfig {
|
||||
@Getter
|
||||
@ -46,9 +47,6 @@ public class DisguiseConfig {
|
||||
private static HashMap<DisguisePerm, String> customDisguises = new HashMap<>();
|
||||
@Getter
|
||||
@Setter
|
||||
private static String updateNotificationPermission;
|
||||
@Getter
|
||||
@Setter
|
||||
private static UpdatesBranch updatesBranch = UpdatesBranch.SAME_BUILDS;
|
||||
@Getter
|
||||
@Setter
|
||||
@ -231,6 +229,127 @@ public class DisguiseConfig {
|
||||
@Getter
|
||||
@Setter
|
||||
private static int tablistRemoveDelay;
|
||||
@Getter
|
||||
private static boolean usingReleaseBuild = true;
|
||||
@Getter
|
||||
private static boolean bisectHosted = true;
|
||||
@Getter
|
||||
private static String savedServerIp = "";
|
||||
@Getter
|
||||
private static boolean autoUpdate;
|
||||
@Getter
|
||||
private static boolean notifyUpdate;
|
||||
private static BukkitTask updaterTask;
|
||||
|
||||
public static void setAutoUpdate(boolean update) {
|
||||
if (isAutoUpdate() == update) {
|
||||
return;
|
||||
}
|
||||
|
||||
autoUpdate = update;
|
||||
doUpdaterTask();
|
||||
}
|
||||
|
||||
public static void setNotifyUpdate(boolean update) {
|
||||
if (isNotifyUpdate() == update) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifyUpdate = update;
|
||||
doUpdaterTask();
|
||||
}
|
||||
|
||||
private static void doUpdaterTask() {
|
||||
boolean startTask = isAutoUpdate() || isNotifyUpdate();
|
||||
|
||||
// Don't ever run the auto updater on a custom build..
|
||||
if (!LibsDisguises.getInstance().isNumberedBuild()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (updaterTask == null != startTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!startTask) {
|
||||
updaterTask.cancel();
|
||||
updaterTask = null;
|
||||
return;
|
||||
}
|
||||
|
||||
updaterTask = Bukkit.getScheduler().runTaskTimerAsynchronously(LibsDisguises.getInstance(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
LibsDisguises.getInstance().getUpdateChecker().doAutoUpdateCheck();
|
||||
}
|
||||
}, 0, (20 * TimeUnit.HOURS.toSeconds(6))); // Check every 6 hours
|
||||
}
|
||||
|
||||
public static void setUsingReleaseBuilds(boolean useReleaseBuilds) {
|
||||
if (useReleaseBuilds == isUsingReleaseBuild()) {
|
||||
return;
|
||||
}
|
||||
|
||||
usingReleaseBuild = useReleaseBuilds;
|
||||
saveInternalConfig();
|
||||
}
|
||||
|
||||
public static void setBisectHosted(boolean isBisectHosted, String serverIP) {
|
||||
if (isBisectHosted() == isBisectHosted && getSavedServerIp().equals(serverIP)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bisectHosted = isBisectHosted;
|
||||
savedServerIp = serverIP;
|
||||
saveInternalConfig();
|
||||
}
|
||||
|
||||
public static void loadInternalConfig() {
|
||||
File internalFile = new File(LibsDisguises.getInstance().getDataFolder(), "internal.yml");
|
||||
|
||||
if (!internalFile.exists()) {
|
||||
saveInternalConfig();
|
||||
}
|
||||
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(internalFile);
|
||||
|
||||
bisectHosted = configuration.getBoolean("Bisect-Hosted", isBisectHosted());
|
||||
savedServerIp = configuration.getString("Server-IP", getSavedServerIp());
|
||||
usingReleaseBuild = configuration.getBoolean("ReleaseBuild", isUsingReleaseBuild());
|
||||
|
||||
if (!configuration.contains("Bisect-Hosted") || !configuration.contains("Server-IP") ||
|
||||
!configuration.contains("ReleaseBuild")) {
|
||||
saveInternalConfig();
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveInternalConfig() {
|
||||
File internalFile = new File(LibsDisguises.getInstance().getDataFolder(), "internal.yml");
|
||||
|
||||
String internalConfig = ReflectionManager
|
||||
.getResourceAsString(LibsDisguises.getInstance().getFile(), "internal.yml");
|
||||
|
||||
// Bisect hosted, server ip, release builds
|
||||
for (Object s : new Object[]{isBisectHosted(), getSavedServerIp(), isUsingReleaseBuild()}) {
|
||||
internalConfig = internalConfig.replaceFirst("%data%", "" + s);
|
||||
}
|
||||
|
||||
internalFile.delete();
|
||||
|
||||
try {
|
||||
internalFile.createNewFile();
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try (PrintWriter writer = new PrintWriter(internalFile, "UTF-8")) {
|
||||
writer.write(internalConfig);
|
||||
}
|
||||
catch (FileNotFoundException | UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static PermissionDefault getCommandVisibility() {
|
||||
return commandVisibility;
|
||||
@ -438,7 +557,6 @@ public class DisguiseConfig {
|
||||
setUUIDGeneratedVersion(config.getInt("UUIDVersion"));
|
||||
setUndisguiseOnWorldChange(config.getBoolean("UndisguiseOnWorldChange"));
|
||||
setUpdateGameProfiles(config.getBoolean("UpdateGameProfiles"));
|
||||
setUpdateNotificationPermission(config.getString("Permission"));
|
||||
setUseTranslations(config.getBoolean("Translations"));
|
||||
setVelocitySent(config.getBoolean("SendVelocity"));
|
||||
setViewDisguises(config.getBoolean("ViewSelfDisguises"));
|
||||
@ -447,6 +565,7 @@ public class DisguiseConfig {
|
||||
setWolfDyeable(config.getBoolean("DyeableWolf"));
|
||||
setScoreboardDisguiseNames(config.getBoolean("ScoreboardNames"));
|
||||
setTablistRemoveDelay(config.getInt("TablistRemoveDelay"));
|
||||
setAutoUpdate(config.getBoolean("AutoUpdate"));
|
||||
|
||||
if (!LibsPremium.isPremium() && (isSavePlayerDisguises() || isSaveEntityDisguises())) {
|
||||
DisguiseUtilities.getLogger().warning("You must purchase the plugin to use saved disguises!");
|
||||
@ -561,7 +680,8 @@ public class DisguiseConfig {
|
||||
if (missingConfigs > 0) {
|
||||
DisguiseUtilities.getLogger().warning("Your config is missing " + missingConfigs +
|
||||
" options! Please consider regenerating your config!");
|
||||
DisguiseUtilities.getLogger().info("You can also add the missing entries yourself! Try '/libsdisguises config'");
|
||||
DisguiseUtilities.getLogger()
|
||||
.info("You can also add the missing entries yourself! Try '/libsdisguises config'");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ import me.libraryaddict.disguise.commands.undisguise.UndisguiseRadiusCommand;
|
||||
import me.libraryaddict.disguise.commands.utils.*;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsPremium;
|
||||
import me.libraryaddict.disguise.utilities.UpdateChecker;
|
||||
import me.libraryaddict.disguise.utilities.updates.UpdateChecker;
|
||||
import me.libraryaddict.disguise.utilities.listeners.DisguiseListener;
|
||||
import me.libraryaddict.disguise.utilities.metrics.MetricsInitalizer;
|
||||
import me.libraryaddict.disguise.utilities.packets.PacketsManager;
|
||||
@ -31,10 +31,13 @@ import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.craftbukkit.libs.org.apache.commons.io.FileUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.FileUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -81,6 +84,8 @@ public class LibsDisguises extends JavaPlugin {
|
||||
|
||||
getLogger().info("Build Date: " + pluginYml.getString("build-date"));
|
||||
|
||||
DisguiseConfig.loadInternalConfig();
|
||||
|
||||
LibsPremium.check(getDescription().getVersion(), getFile());
|
||||
|
||||
if (!LibsPremium.isPremium()) {
|
||||
@ -98,6 +103,17 @@ public class LibsDisguises extends JavaPlugin {
|
||||
return;
|
||||
}
|
||||
|
||||
// If this is a release build, even if jenkins build..
|
||||
if (isReleaseBuild()) {
|
||||
// If downloaded from spigot, forcibly set release build to true
|
||||
if (LibsPremium.getUserID().matches("[0-9]+")) {
|
||||
DisguiseConfig.setUsingReleaseBuilds(true);
|
||||
}
|
||||
// Otherwise leave it untouched as they might've just happened to hit a dev build, which is a release build
|
||||
} else {
|
||||
DisguiseConfig.setUsingReleaseBuilds(false);
|
||||
}
|
||||
|
||||
ReflectionManager.init();
|
||||
|
||||
PacketsManager.init();
|
||||
|
@ -1,7 +1,8 @@
|
||||
package me.libraryaddict.disguise.commands.libsdisguises;
|
||||
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.utilities.UpdateChecker;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.updates.UpdateChecker;
|
||||
import me.libraryaddict.disguise.utilities.plugin.PluginInformation;
|
||||
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -18,7 +19,10 @@ import java.util.List;
|
||||
public class LDUpdate implements LDCommand {
|
||||
@Override
|
||||
public List<String> getTabComplete() {
|
||||
return Arrays.asList("update", "update!");
|
||||
// Update by download
|
||||
// Update check
|
||||
// Update to latest dev build
|
||||
return Arrays.asList("update", "update?", "update!");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -35,16 +39,21 @@ public class LDUpdate implements LDCommand {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean check = args[0].endsWith("?");
|
||||
boolean force = args[0].endsWith("!");
|
||||
|
||||
if (!force) {
|
||||
if (checker.getLatestSnapshot() <= 0) {
|
||||
sender.sendMessage(LibsMsg.UPDATE_NOT_READY.get());
|
||||
if (!check && !force && checker.getUpdate() != null) {
|
||||
if (checker.getUpdate().getVersion().equals(checker.getUpdate().isReleaseBuild() ?
|
||||
LibsDisguises.getInstance().getDescription().getDescription() :
|
||||
LibsDisguises.getInstance().getBuildNumber())) {
|
||||
sender.sendMessage(LibsMsg.UPDATE_ON_LATEST.get());
|
||||
return;
|
||||
}
|
||||
|
||||
if (checker.getLatestSnapshot() == LibsDisguises.getInstance().getBuildNumber()) {
|
||||
sender.sendMessage(LibsMsg.UPDATE_ON_LATEST.get());
|
||||
if (checker.getLastDownload() != null && checker.getUpdate().getVersion()
|
||||
.equals(checker.isUsingReleaseBuilds() ? checker.getLastDownload().getVersion() :
|
||||
checker.getLastDownload().getBuildNumber())) {
|
||||
sender.sendMessage(LibsMsg.UPDATE_ALREADY_DOWNLOADED.get());
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -52,29 +61,49 @@ public class LDUpdate implements LDCommand {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PluginInformation result;
|
||||
LibsMsg updateResult = null;
|
||||
|
||||
if (force) {
|
||||
result = checker.grabLatestSnapshot();
|
||||
} else {
|
||||
result = checker.grabSnapshotBuild();
|
||||
if (check || checker.getUpdate() == null || force) {
|
||||
updateResult = checker.doUpdateCheck();
|
||||
}
|
||||
|
||||
if (checker.getUpdate() == null) {
|
||||
sender.sendMessage(LibsMsg.UPDATE_FAILED.get());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!checker.isUpdateReady()) {
|
||||
sender.sendMessage(LibsMsg.UPDATE_ON_LATEST.get());
|
||||
return;
|
||||
}
|
||||
|
||||
if (check) {
|
||||
if (updateResult != null) {
|
||||
sender.sendMessage(updateResult.get());
|
||||
} else {
|
||||
for (String msg : checker.getUpdateMessage()) {
|
||||
sender.sendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PluginInformation result = checker.doUpdate();
|
||||
|
||||
if (result == null) {
|
||||
sender.sendMessage(LibsMsg.UPDATE_FAILED.get());
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(LibsMsg.UPDATE_SUCCESS.get()); // Update success, please restart to update
|
||||
sender.sendMessage(LibsMsg.UPDATE_INFO
|
||||
.get(result.getVersion(), result.getBuildNumber(), result.getParsedBuildDate().toString(),
|
||||
result.getSize() / 1024));
|
||||
for (String msg : checker.getUpdateMessage()) {
|
||||
sender.sendMessage(msg);
|
||||
}
|
||||
|
||||
if (sender instanceof Player) {
|
||||
Bukkit.getConsoleSender().sendMessage(LibsMsg.UPDATE_SUCCESS.get());
|
||||
Bukkit.getConsoleSender().sendMessage(LibsMsg.UPDATE_INFO
|
||||
.get(result.getVersion(), result.getBuildNumber(), result.getParsedBuildDate().toString(),
|
||||
result.getSize() / 1024));
|
||||
for (String msg : checker.getUpdateMessage()) {
|
||||
DisguiseUtilities.getLogger().info(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}.runTaskAsynchronously(LibsDisguises.getInstance());
|
||||
|
@ -1,286 +0,0 @@
|
||||
package me.libraryaddict.disguise.utilities;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.Getter;
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.utilities.plugin.PluginInformation;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.libs.org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UpdateChecker {
|
||||
private final String resourceID;
|
||||
@Getter
|
||||
private String latestVersion;
|
||||
@Getter
|
||||
private int latestSnapshot;
|
||||
private final long started = System.currentTimeMillis();
|
||||
private int lastDownload;
|
||||
|
||||
public UpdateChecker(String resourceID) {
|
||||
this.resourceID = resourceID;
|
||||
}
|
||||
|
||||
public PluginInformation grabSnapshotBuild() {
|
||||
if (getLatestSnapshot() == 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
if (lastDownload == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (getLatestSnapshot() == lastDownload) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return grabSnapshotBuild(getLatestSnapshot());
|
||||
}
|
||||
|
||||
public PluginInformation grabSnapshotBuild(int buildNo) {
|
||||
PluginInformation result = grabSnapshotBuild(
|
||||
"https://ci.md-5.net/job/LibsDisguises/" + buildNo + "/artifact/target/LibsDisguises.jar");
|
||||
|
||||
if (result != null) {
|
||||
lastDownload = buildNo;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public PluginInformation grabLatestSnapshot() {
|
||||
PluginInformation result = grabSnapshotBuild(
|
||||
"https://ci.md-5.net/job/LibsDisguises/lastSuccessfulBuild/artifact/target/LibsDisguises.jar");
|
||||
|
||||
if (result != null) {
|
||||
lastDownload = LibsDisguises.getInstance().getBuildNumber();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isDownloading() {
|
||||
return lastDownload == -1;
|
||||
}
|
||||
|
||||
public int getLastDownload() {
|
||||
return lastDownload;
|
||||
}
|
||||
|
||||
public PluginInformation grabSnapshotBuild(String urlString) {
|
||||
DisguiseUtilities.getLogger().info("Now downloading latest build of Lib's Disguises from " + urlString);
|
||||
lastDownload = -1;
|
||||
|
||||
File dest = new File(Bukkit.getUpdateFolderFile(), "LibsDisguises.jar");
|
||||
|
||||
if (dest.exists()) {
|
||||
dest.delete();
|
||||
}
|
||||
|
||||
dest.getParentFile().mkdirs();
|
||||
|
||||
try {
|
||||
// We're connecting to spigot's API
|
||||
URL url = new URL(urlString);
|
||||
// Creating a connection
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||
con.setDefaultUseCaches(false);
|
||||
|
||||
// Get the input stream, what we receive
|
||||
try (InputStream input = con.getInputStream()) {
|
||||
FileUtils.copyInputStreamToFile(input, dest);
|
||||
}
|
||||
|
||||
DisguiseUtilities.getLogger().info("Download success!");
|
||||
|
||||
return LibsPremium.getInformation(dest);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Failed, set the last download back to previous build
|
||||
dest.delete();
|
||||
DisguiseUtilities.getLogger().warning("Failed to download snapshot build.");
|
||||
lastDownload = 0;
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void checkSnapshotUpdate(int buildNumber) {
|
||||
Map<String, Object> lastBuild = fetchLastSnapshotBuild();
|
||||
|
||||
if (lastBuild == null || !lastBuild.containsKey("id") || !lastBuild.containsKey("timestamp")) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks spigot for the version
|
||||
*/
|
||||
private String fetchSpigotVersion() {
|
||||
try {
|
||||
// We're connecting to spigot's API
|
||||
URL url = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + resourceID);
|
||||
// Creating a connection
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||
con.setDefaultUseCaches(false);
|
||||
|
||||
// Get the input stream, what we receive
|
||||
try (InputStream input = con.getInputStream()) {
|
||||
// Read it to string
|
||||
String version = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)).lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
// If the version is not empty, return it
|
||||
if (!version.isEmpty()) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
DisguiseUtilities.getLogger().warning("Failed to check for a update on spigot.");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isNewerVersion(String currentVersion, String newVersion) {
|
||||
currentVersion = currentVersion.replaceAll("(v)|(-SNAPSHOT)", "");
|
||||
newVersion = newVersion.replaceAll("(v)|(-SNAPSHOT)", "");
|
||||
|
||||
// If the server has been online for less than 6 hours and both versions are 1.1.1 kind of versions
|
||||
if (started + TimeUnit.HOURS.toMillis(6) > System.currentTimeMillis() &&
|
||||
currentVersion.matches("[0-9]+(\\.[0-9]+)*") && newVersion.matches("[0-9]+(\\.[0-9]+)*")) {
|
||||
|
||||
int cVersion = Integer.parseInt(currentVersion.replace(".", ""));
|
||||
int nVersion = Integer.parseInt(newVersion.replace(".", ""));
|
||||
|
||||
// If the current version is a higher version, and is only a higher version by 3 minor numbers
|
||||
// Then we have a cache problem
|
||||
if (cVersion > nVersion && nVersion + 3 > cVersion) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Lets just ignore all this fancy logic, and say that if you're not on the current release, you're outdated!
|
||||
return !currentVersion.equals(newVersion);
|
||||
|
||||
/*
|
||||
// Remove 'v' and '-SNAPSHOT' from string, split by decimal points
|
||||
String[] cSplit = currentVersion.replaceAll("(v)|(-SNAPSHOT)", "").split("\\.");
|
||||
String[] nSplit = newVersion.replaceAll("(v)|(-SNAPSHOT)", "").split("\\.");
|
||||
|
||||
// Lets just ignore all this fancy logic, and say that if you're not on the current release, you're outdated!
|
||||
return !Arrays.equals(cSplit, nSplit);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// If both strings are numerical
|
||||
if (cSplit[i].matches("[0-9]+") && nSplit[i].matches("[0-9]+")) {
|
||||
int cInt = Integer.parseInt(cSplit[i]);
|
||||
int nInt = Integer.parseInt(nSplit[i]);
|
||||
|
||||
// Same version
|
||||
if (cInt == nInt) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Return if current version is inferior to new version
|
||||
return cInt < nInt;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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();
|
||||
con.setDefaultUseCaches(false);
|
||||
Map<String, Object> jsonObject;
|
||||
|
||||
// Get the input stream, what we receive
|
||||
try (InputStream input = con.getInputStream()) {
|
||||
// Read it to string
|
||||
String json = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)).lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ import me.libraryaddict.disguise.disguisetypes.TargetedDisguise;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsEntityInteract;
|
||||
import me.libraryaddict.disguise.utilities.LibsPremium;
|
||||
import me.libraryaddict.disguise.utilities.UpdateChecker;
|
||||
import me.libraryaddict.disguise.utilities.updates.UpdateChecker;
|
||||
import me.libraryaddict.disguise.utilities.modded.ModdedEntity;
|
||||
import me.libraryaddict.disguise.utilities.modded.ModdedManager;
|
||||
import me.libraryaddict.disguise.utilities.plugin.PluginInformation;
|
||||
@ -53,13 +53,9 @@ import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class DisguiseListener implements Listener {
|
||||
private String currentVersion;
|
||||
private HashMap<String, LibsEntityInteract> interactions = new HashMap<>();
|
||||
private HashMap<String, BukkitRunnable> disguiseRunnable = new HashMap<>();
|
||||
private String latestVersion;
|
||||
private LibsMsg updateMessage;
|
||||
private LibsDisguises plugin;
|
||||
private BukkitTask updaterTask;
|
||||
|
||||
public DisguiseListener(LibsDisguises libsDisguises) {
|
||||
plugin = libsDisguises;
|
||||
@ -117,87 +113,6 @@ public class DisguiseListener implements Listener {
|
||||
DisguiseUtilities.getLogger()
|
||||
.info("Plugin will attempt to auto update when new builds are ready! Check config to disable.");
|
||||
}
|
||||
|
||||
updaterTask = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
UpdateChecker updateChecker = LibsDisguises.getInstance().getUpdateChecker();
|
||||
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(plugin.getBuildNumber());
|
||||
|
||||
if (updateChecker.getLatestSnapshot() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
latestVersion = "" + updateChecker.getLatestSnapshot();
|
||||
|
||||
if (autoUpdate && plugin.isNumberedBuild()) {
|
||||
PluginInformation result = updateChecker.grabSnapshotBuild();
|
||||
updateMessage = result != null ? LibsMsg.UPDATE_SUCCESS : LibsMsg.UPDATE_FAILED;
|
||||
Bukkit.getConsoleSender().sendMessage(LibsMsg.UPDATE_INFO
|
||||
.get(result.getVersion(), result.getBuildNumber(),
|
||||
result.getParsedBuildDate().toString(), result.getSize() / 1024));
|
||||
} else {
|
||||
currentVersion = plugin.getBuildNo();
|
||||
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;
|
||||
}
|
||||
|
||||
if (updateMessage == LibsMsg.UPDATE_SUCCESS || updateMessage == LibsMsg.UPDATE_FAILED) {
|
||||
if (player instanceof Player) {
|
||||
player.sendMessage(updateMessage.get());
|
||||
} else {
|
||||
DisguiseUtilities.getLogger().info(updateMessage.get());
|
||||
}
|
||||
} else {
|
||||
if (player instanceof Player) {
|
||||
player.sendMessage(updateMessage.get(currentVersion, latestVersion));
|
||||
} else {
|
||||
DisguiseUtilities.getLogger().info(updateMessage.get(currentVersion, latestVersion));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
@ -206,7 +121,6 @@ public class DisguiseListener implements Listener {
|
||||
}
|
||||
|
||||
interactions.clear();
|
||||
updaterTask.cancel();
|
||||
}
|
||||
|
||||
private void checkPlayerCanBlowDisguise(Player player) {
|
||||
@ -423,7 +337,7 @@ public class DisguiseListener implements Listener {
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
|
||||
notifyUpdate(p);
|
||||
plugin.getUpdateChecker().notifyUpdate(p);
|
||||
|
||||
if (DisguiseConfig.isSaveGameProfiles() && DisguiseConfig.isUpdateGameProfiles() &&
|
||||
DisguiseUtilities.hasGameProfile(p.getName())) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package me.libraryaddict.disguise.utilities.plugin;
|
||||
|
||||
import me.libraryaddict.disguise.DisguiseConfig;
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@ -13,24 +14,15 @@ import java.net.URL;
|
||||
*/
|
||||
public class BisectHosting {
|
||||
public boolean isBisectHosted(String pluginName) {
|
||||
File configFile = new File("plugins/" + pluginName + "/internal.yml");
|
||||
boolean claimedHosted = false;
|
||||
String serverIp = Bukkit.getIp().replaceAll("[^:0-9.]", "");
|
||||
boolean claimedHosted = DisguiseConfig.isBisectHosted();
|
||||
String ip = Bukkit.getIp();
|
||||
String parsedIP = ip.replaceAll("[^:0-9.]", "");
|
||||
|
||||
if (configFile.exists()) {
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
if (configuration.contains("Bisect-Hosted") && configuration.contains("Server-IP")) {
|
||||
claimedHosted = configuration.getBoolean("Bisect-Hosted");
|
||||
|
||||
// If not hosted by bisect
|
||||
if (!claimedHosted && configuration.getString("Server-IP").equals(serverIp)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// If not hosted by bisect
|
||||
if (!claimedHosted && DisguiseConfig.getSavedServerIp().equals(parsedIP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String ip = Bukkit.getIp();
|
||||
boolean hostedBy = false;
|
||||
|
||||
if (ip.matches("((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\\.(?!$)|$)){4}")) {
|
||||
@ -45,27 +37,11 @@ public class BisectHosting {
|
||||
}
|
||||
}
|
||||
|
||||
// If config doesn't exist, or it's not a bisect server
|
||||
if (!configFile.exists()) {
|
||||
if (!configFile.getParentFile().exists()) {
|
||||
configFile.getParentFile().mkdirs();
|
||||
}
|
||||
if (claimedHosted != hostedBy || !DisguiseConfig.getSavedServerIp().equals(parsedIP)) {
|
||||
DisguiseConfig.setBisectHosted(hostedBy, Bukkit.getIp());
|
||||
}
|
||||
|
||||
try (PrintWriter writer = new PrintWriter(configFile, "UTF-8")) {
|
||||
// This setting is if the server should check if you are using Bisect Hosting",
|
||||
writer.write("# If you're using BisectHosting, this will tell the server to enable premium for free!");
|
||||
writer.write("\n# However if you're not using BisectHosting, this is false so the server won't waste " +
|
||||
"time");
|
||||
writer.write(
|
||||
"\n# Coupon 'libraryaddict' for 25% off your first invoice on any of their gaming servers");
|
||||
writer.write("\n# Be sure to visit through this link! https://bisecthosting.com/libraryaddict");
|
||||
writer.write("\nBisect-Hosted: " + hostedBy);
|
||||
writer.write("\nServer-IP: " + serverIp);
|
||||
}
|
||||
catch (FileNotFoundException | UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (claimedHosted) {
|
||||
if (!hostedBy && !DisguiseConfig.getSavedServerIp().equals("")) {
|
||||
// Just a small message for those who tried to enable it
|
||||
LibsDisguises.getInstance().getLogger().severe("Check for BisectHosting failed! Connection error?");
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import me.libraryaddict.disguise.utilities.LibsPremium;
|
||||
import org.apache.commons.lang.ArrayUtils;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
@ -158,21 +159,13 @@ public class ReflectionManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from Bukkit
|
||||
*/
|
||||
public static YamlConfiguration getPluginYAML(File file) {
|
||||
public static String getResourceAsString(File file, String fileName) {
|
||||
try (JarFile jar = new JarFile(file)) {
|
||||
JarEntry entry = jar.getJarEntry("plugin.yml");
|
||||
JarEntry entry = jar.getJarEntry(fileName);
|
||||
|
||||
try (InputStream stream = jar.getInputStream(entry)) {
|
||||
YamlConfiguration config = new YamlConfiguration();
|
||||
|
||||
String configString = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)).lines()
|
||||
return new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)).lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
config.loadFromString(configString);
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
@ -182,6 +175,30 @@ public class ReflectionManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from Bukkit
|
||||
*/
|
||||
public static YamlConfiguration getPluginYAML(File file) {
|
||||
try {
|
||||
String s = getResourceAsString(file, "plugin.yml");
|
||||
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
YamlConfiguration config = new YamlConfiguration();
|
||||
|
||||
config.loadFromString(getResourceAsString(file, "plugin.yml"));
|
||||
|
||||
return config;
|
||||
}
|
||||
catch (InvalidConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int getNewEntityId() {
|
||||
return getNewEntityId(true);
|
||||
}
|
||||
|
@ -143,9 +143,8 @@ public enum LibsMsg {
|
||||
NO_MODS(ChatColor.RED + "%s is not using any mods!"),
|
||||
MODS_LIST(ChatColor.DARK_GREEN + "%s has the mods:" + ChatColor.AQUA + " %s"),
|
||||
NO_PERM(ChatColor.RED + "You are forbidden to use this command."),
|
||||
UPDATE_NOT_READY(ChatColor.RED +
|
||||
"Lib's Disguises doesn't know what's the latest update! Use 'update!' to force an update to latest!"),
|
||||
UPDATE_ON_LATEST(ChatColor.RED + "You are already on the latest version of LibsDisguises!"),
|
||||
UPDATE_ALREADY_DOWNLOADED(ChatColor.RED + "That update has already been downloaded!"),
|
||||
UPDATE_FAILED(ChatColor.RED + "LibsDisguises update failed! Check console for errors."),
|
||||
UPDATE_SUCCESS(ChatColor.DARK_GREEN + "LibsDisguises update success! Restart server to update!"),
|
||||
UPDATE_INFO(ChatColor.DARK_GREEN + "Lib's Disguises v%s, build %s, built %s and size %skb"),
|
||||
|
@ -0,0 +1,24 @@
|
||||
package me.libraryaddict.disguise.utilities.updates;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 26/04/2020.
|
||||
*/
|
||||
public interface DisguiseUpdate {
|
||||
/**
|
||||
* Null if invalid
|
||||
*/
|
||||
String getVersion();
|
||||
|
||||
boolean isReleaseBuild();
|
||||
|
||||
String getDownload();
|
||||
|
||||
String[] getChangelog();
|
||||
|
||||
/**
|
||||
* When was this update fetched?
|
||||
*/
|
||||
Date getFetched();
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
package me.libraryaddict.disguise.utilities.updates;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 26/04/2020.
|
||||
*/
|
||||
public class LDGithub {
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
private class GithubUpdate implements DisguiseUpdate {
|
||||
private String version;
|
||||
private String[] changelog;
|
||||
private String download;
|
||||
private final Date fetched = new Date();
|
||||
|
||||
@Override
|
||||
public boolean isReleaseBuild() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
private class GithubData {
|
||||
@Getter
|
||||
class Asset {
|
||||
String browser_download_url;
|
||||
String name;
|
||||
String content_type;
|
||||
}
|
||||
|
||||
String name;
|
||||
String tag_name;
|
||||
String body;
|
||||
Date published_at;
|
||||
Asset[] assets;
|
||||
}
|
||||
|
||||
public DisguiseUpdate getLatestRelease() {
|
||||
try {
|
||||
// We're connecting to md_5's jenkins REST api
|
||||
URL url = new URL("https://api.github.com/repos/libraryaddict/LibsDisguises/releases/latest");
|
||||
// Creating a connection
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||
con.setRequestProperty("User-Agent", "libraryaddict/LibsDisguises");
|
||||
con.setRequestProperty("Accept", "application/vnd.github.v3+json");
|
||||
|
||||
GithubData gitData;
|
||||
|
||||
// Get the input stream, what we receive
|
||||
try (InputStream input = con.getInputStream()) {
|
||||
// Read it to string
|
||||
String json = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)).lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
gitData = new Gson().fromJson(json, GithubData.class);
|
||||
}
|
||||
|
||||
String download = null;
|
||||
|
||||
for (GithubData.Asset asset : gitData.getAssets()) {
|
||||
if (!asset.getName().endsWith(".jar")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
download = asset.getBrowser_download_url();
|
||||
break;
|
||||
}
|
||||
|
||||
if (download == null) {
|
||||
throw new IllegalStateException("Download url is missing");
|
||||
}
|
||||
|
||||
return new GithubUpdate(gitData.getTag_name().replace("v", ""), gitData.getBody().split("(\\r|\\n)+"), download);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
DisguiseUtilities.getLogger().warning("Failed to check for a release on Github");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package me.libraryaddict.disguise.utilities.updates;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.plugin.PluginInformation;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 26/04/2020.
|
||||
*/
|
||||
public class LDJenkins {
|
||||
private UpdateChecker updateChecker;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
private class JenkinsUpdate implements DisguiseUpdate {
|
||||
private final Date fetched = new Date();
|
||||
private final String version;
|
||||
private final String[] changelog;
|
||||
|
||||
@Override
|
||||
public String getDownload() {
|
||||
return "https://ci.md-5.net/job/LibsDisguises/" + getVersion() + "/artifact/target/LibsDisguises.jar";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReleaseBuild() {
|
||||
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();
|
||||
con.setDefaultUseCaches(false);
|
||||
Map<String, Object> jsonObject;
|
||||
|
||||
// Get the input stream, what we receive
|
||||
try (InputStream input = con.getInputStream()) {
|
||||
// Read it to string
|
||||
String json = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)).lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
jsonObject = new Gson().fromJson(json, Map.class);
|
||||
}
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
DisguiseUtilities.getLogger().warning("Failed to check for a snapshot update on jenkins.");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public DisguiseUpdate getLatestSnapshot() {
|
||||
Map<String, Object> lastBuild = fetchLastSnapshotBuild();
|
||||
|
||||
if (lastBuild == null || !lastBuild.containsKey("id") || !lastBuild.containsKey("timestamp")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ArrayList<String> changelog = new ArrayList<>();
|
||||
|
||||
if (lastBuild.get("changeSet") instanceof Map) {
|
||||
Object items = ((Map) lastBuild.get("changeSet")).get("items");
|
||||
|
||||
if (items instanceof Map[]) {
|
||||
for (Map item : (Map[]) items) {
|
||||
String msg = (String) item.get("msg");
|
||||
|
||||
if (msg == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
changelog.add(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new JenkinsUpdate((String) lastBuild.get("id"), changelog.toArray(new String[0]));
|
||||
}
|
||||
}
|
@ -0,0 +1,290 @@
|
||||
package me.libraryaddict.disguise.utilities.updates;
|
||||
|
||||
import lombok.Getter;
|
||||
import me.libraryaddict.disguise.DisguiseConfig;
|
||||
import me.libraryaddict.disguise.LibsDisguises;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.LibsPremium;
|
||||
import me.libraryaddict.disguise.utilities.plugin.PluginInformation;
|
||||
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.libs.org.apache.commons.io.FileUtils;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class UpdateChecker {
|
||||
private final String resourceID;
|
||||
private final long started = System.currentTimeMillis();
|
||||
@Getter
|
||||
private PluginInformation lastDownload;
|
||||
private final AtomicBoolean downloading = new AtomicBoolean(false);
|
||||
@Getter
|
||||
private DisguiseUpdate update;
|
||||
private LDGithub githubUpdater = new LDGithub();
|
||||
private LDJenkins jenkinsUpdater = new LDJenkins();
|
||||
@Getter
|
||||
private String[] updateMessage = new String[0];
|
||||
|
||||
public UpdateChecker(String resourceID) {
|
||||
this.resourceID = resourceID;
|
||||
}
|
||||
|
||||
public boolean isDownloading() {
|
||||
return downloading.get();
|
||||
}
|
||||
|
||||
public boolean isUsingReleaseBuilds() {
|
||||
DisguiseConfig.UpdatesBranch builds = DisguiseConfig.getUpdatesBranch();
|
||||
|
||||
return builds == DisguiseConfig.UpdatesBranch.RELEASES ||
|
||||
(builds == DisguiseConfig.UpdatesBranch.SAME_BUILDS && DisguiseConfig.isUsingReleaseBuild());
|
||||
}
|
||||
|
||||
public void notifyUpdate(CommandSender player) {
|
||||
if (!DisguiseConfig.isNotifyUpdate() || !player.hasPermission("libsdisguises.update")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (updateMessage == null || updateMessage.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player instanceof Player) {
|
||||
player.sendMessage(updateMessage);
|
||||
} else {
|
||||
for (String s : updateMessage) {
|
||||
DisguiseUtilities.getLogger().info(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUpdateReady() {
|
||||
if (getUpdate() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String version;
|
||||
|
||||
if (getUpdate().isReleaseBuild()) {
|
||||
if (lastDownload != null) {
|
||||
version = lastDownload.getVersion();
|
||||
} else {
|
||||
version = LibsDisguises.getInstance().getDescription().getVersion();
|
||||
}
|
||||
} else {
|
||||
if (lastDownload != null) {
|
||||
version = lastDownload.getBuildNumber();
|
||||
} else {
|
||||
version = LibsDisguises.getInstance().getBuildNo();
|
||||
}
|
||||
}
|
||||
|
||||
return getUpdate() != null && !getUpdate().getVersion().equals(version);
|
||||
}
|
||||
|
||||
public void doAutoUpdateCheck() {
|
||||
try {
|
||||
DisguiseUpdate oldUpdate = getUpdate();
|
||||
|
||||
updateMessage = new String[0];
|
||||
|
||||
doUpdateCheck();
|
||||
|
||||
if (!isUpdateReady() || (oldUpdate != null && oldUpdate.getVersion().equals(getUpdate().getVersion()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifyUpdate(Bukkit.getConsoleSender());
|
||||
|
||||
if (DisguiseConfig.isAutoUpdate()) {
|
||||
// Update message changed by download
|
||||
grabJarDownload(getUpdate().getDownload());
|
||||
|
||||
notifyUpdate(Bukkit.getConsoleSender());
|
||||
}
|
||||
|
||||
Bukkit.getScheduler().runTask(LibsDisguises.getInstance(), () -> {
|
||||
for (Player p : Bukkit.getOnlinePlayers()) {
|
||||
notifyUpdate(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex) {
|
||||
DisguiseUtilities.getLogger().warning(String.format("Failed to check for update: %s", ex.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
public PluginInformation doUpdate() {
|
||||
// If no update on file, or more than 6 hours hold. Check for update
|
||||
if (getUpdate() == null ||
|
||||
getUpdate().getFetched().before(new Date(System.currentTimeMillis() - TimeUnit.HOURS.toMillis(6)))) {
|
||||
doUpdateCheck();
|
||||
}
|
||||
|
||||
if (getUpdate() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return grabJarDownload(getUpdate().getDownload());
|
||||
}
|
||||
|
||||
public LibsMsg doUpdateCheck() {
|
||||
downloading.set(false);
|
||||
|
||||
try {
|
||||
update = null;
|
||||
|
||||
if (isUsingReleaseBuilds()) {
|
||||
update = githubUpdater.getLatestRelease();
|
||||
} else {
|
||||
update = jenkinsUpdater.getLatestSnapshot();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
downloading.set(false);
|
||||
}
|
||||
|
||||
if (getUpdate() == null) {
|
||||
return LibsMsg.UPDATE_FAILED;
|
||||
}
|
||||
|
||||
if (getUpdate().isReleaseBuild()) {
|
||||
String currentVersion = LibsDisguises.getInstance().getDescription().getVersion();
|
||||
|
||||
if (!isNewerVersion(currentVersion, getUpdate().getVersion())) {
|
||||
return LibsMsg.UPDATE_ON_LATEST;
|
||||
}
|
||||
|
||||
updateMessage = new String[]{LibsMsg.UPDATE_READY.get(currentVersion, getUpdate().getVersion())};
|
||||
} else {
|
||||
if (!getUpdate().getVersion().matches("[0-9]+")) {
|
||||
return LibsMsg.UPDATE_FAILED;
|
||||
}
|
||||
|
||||
int newBuild = Integer.parseInt(getUpdate().getVersion());
|
||||
|
||||
if (newBuild <= LibsDisguises.getInstance().getBuildNumber()) {
|
||||
return LibsMsg.UPDATE_ON_LATEST;
|
||||
}
|
||||
|
||||
updateMessage = new String[]{
|
||||
LibsMsg.UPDATE_READY_SNAPSHOT.get(LibsDisguises.getInstance().getBuildNo(), newBuild)};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private PluginInformation grabJarDownload(String urlString) {
|
||||
downloading.set(true);
|
||||
|
||||
DisguiseUtilities.getLogger().info("Now downloading build of Lib's Disguises from " + urlString);
|
||||
|
||||
File dest = new File(Bukkit.getUpdateFolderFile(), LibsDisguises.getInstance().getFile().getName());
|
||||
|
||||
if (dest.exists()) {
|
||||
dest.delete();
|
||||
}
|
||||
|
||||
dest.getParentFile().mkdirs();
|
||||
|
||||
try {
|
||||
// We're connecting to spigot's API
|
||||
URL url = new URL(urlString);
|
||||
// Creating a connection
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||
con.setDefaultUseCaches(false);
|
||||
|
||||
// Get the input stream, what we receive
|
||||
try (InputStream input = con.getInputStream()) {
|
||||
FileUtils.copyInputStreamToFile(input, dest);
|
||||
}
|
||||
|
||||
DisguiseUtilities.getLogger().info("Download success!");
|
||||
|
||||
PluginInformation result = LibsPremium.getInformation(dest);
|
||||
lastDownload = result;
|
||||
|
||||
updateMessage = new String[]{LibsMsg.UPDATE_SUCCESS.get(),
|
||||
LibsMsg.UPDATE_INFO.get(result.getVersion(), result.getBuildNumber(),
|
||||
result.getParsedBuildDate().toString(), result.getSize() / 1024)};
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Failed, set the last download back to previous build
|
||||
dest.delete();
|
||||
DisguiseUtilities.getLogger().warning("Failed to download snapshot build.");
|
||||
ex.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
downloading.set(false);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asks spigot for the version
|
||||
*/
|
||||
private String fetchSpigotVersion() {
|
||||
try {
|
||||
// We're connecting to spigot's API
|
||||
URL url = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + resourceID);
|
||||
// Creating a connection
|
||||
HttpURLConnection con = (HttpURLConnection) url.openConnection();
|
||||
con.setDefaultUseCaches(false);
|
||||
|
||||
// Get the input stream, what we receive
|
||||
try (InputStream input = con.getInputStream()) {
|
||||
// Read it to string
|
||||
String version = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)).lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
// If the version is not empty, return it
|
||||
if (!version.isEmpty()) {
|
||||
return version;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
DisguiseUtilities.getLogger().warning("Failed to check for a update on spigot.");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isNewerVersion(String currentVersion, String newVersion) {
|
||||
currentVersion = currentVersion.replaceAll("(v)|(-SNAPSHOT)", "");
|
||||
newVersion = newVersion.replaceAll("(v)|(-SNAPSHOT)", "");
|
||||
|
||||
// If the server has been online for less than 6 hours and both versions are 1.1.1 kind of versions
|
||||
if (started + TimeUnit.HOURS.toMillis(6) > System.currentTimeMillis() &&
|
||||
currentVersion.matches("[0-9]+(\\.[0-9]+)*") && newVersion.matches("[0-9]+(\\.[0-9]+)*")) {
|
||||
|
||||
int cVersion = Integer.parseInt(currentVersion.replace(".", ""));
|
||||
int nVersion = Integer.parseInt(newVersion.replace(".", ""));
|
||||
|
||||
// If the current version is a higher version, and is only a higher version by 3 minor numbers
|
||||
// Then we have a cache problem
|
||||
if (cVersion > nVersion && nVersion + 3 > cVersion) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Lets just ignore all this fancy logic, and say that if you're not on the current release, you're outdated!
|
||||
return !currentVersion.equals(newVersion);
|
||||
}
|
||||
}
|
@ -99,19 +99,16 @@ Scoreboard:
|
||||
WarnConflict: true
|
||||
|
||||
# Shall I notify those with the correct permission when there's a LibsDisguises update?
|
||||
# Disabling this will also disable auto updating
|
||||
# Disabling this will also disable notifications when the plugin updated
|
||||
NotifyUpdate: true
|
||||
|
||||
# Whats the permission to get the notification?
|
||||
Permission: 'libsdisguises.update'
|
||||
# Should the plugin automatically update?
|
||||
AutoUpdate: true
|
||||
|
||||
# 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
|
||||
# Should the plugin automatically update if the server is using dev builds?
|
||||
AutoUpdateDev: true
|
||||
|
||||
# Whats the max size allowed for command disguiseradius
|
||||
DisguiseRadiusMax: 50
|
||||
|
8
src/main/resources/internal.yml
Normal file
8
src/main/resources/internal.yml
Normal file
@ -0,0 +1,8 @@
|
||||
# If you're using BisectHosting, this will tell the server to enable premium for free!
|
||||
# However if you're not using BisectHosting, this is false so the server won't waste time
|
||||
# Coupon 'libraryaddict' for 25% off your first invoice on any of their gaming server
|
||||
# Be sure to visit through this link! https://bisecthosting.com/libraryaddict
|
||||
Bisect-Hosted: %data%
|
||||
Server-IP: %data%
|
||||
# Should the plugin be doing release or dev builds updating?
|
||||
ReleaseBuild: %data%
|
Loading…
Reference in New Issue
Block a user