mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-01-13 11:41:34 +01:00
Update command #539
This commit is contained in:
parent
23a3fc441b
commit
4e0f1b38f1
@ -4,6 +4,7 @@ import com.djrapitops.plan.PlanBungee;
|
||||
import com.djrapitops.plan.command.commands.*;
|
||||
import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.system.settings.locale.Locale;
|
||||
import com.djrapitops.plan.system.settings.locale.Msg;
|
||||
import com.djrapitops.plugin.command.CommandNode;
|
||||
@ -49,6 +50,7 @@ public class PlanBungeeCommand extends TreeCmdNode {
|
||||
new BungeeSetupToggleCommand(),
|
||||
new ReloadCommand(plugin),
|
||||
new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()),
|
||||
(Settings.ALLOW_UPDATE.isTrue() ? new UpdateCommand() : null)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -46,7 +46,8 @@ public class PlanCommand extends TreeCmdNode {
|
||||
new ReloadCommand(plugin),
|
||||
new ManageCommand(plugin, this),
|
||||
new StatusCommand<>(plugin, Permissions.MANAGE.getPermission(), plugin.getColorScheme()),
|
||||
(Settings.DEV_MODE.isTrue() ? new DevCommand() : null)
|
||||
(Settings.DEV_MODE.isTrue() ? new DevCommand() : null),
|
||||
(Settings.ALLOW_UPDATE.isTrue() ? new UpdateCommand() : null)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,210 @@
|
||||
package com.djrapitops.plan.command.commands;
|
||||
|
||||
import com.djrapitops.plan.api.exceptions.connection.*;
|
||||
import com.djrapitops.plan.api.exceptions.database.DBException;
|
||||
import com.djrapitops.plan.command.commands.manage.ManageConDebugCommand;
|
||||
import com.djrapitops.plan.system.database.databases.Database;
|
||||
import com.djrapitops.plan.system.database.databases.operation.FetchOperations;
|
||||
import com.djrapitops.plan.system.info.InfoSystem;
|
||||
import com.djrapitops.plan.system.info.request.CheckConnectionRequest;
|
||||
import com.djrapitops.plan.system.info.request.UpdateCancelRequest;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
import com.djrapitops.plan.system.settings.Permissions;
|
||||
import com.djrapitops.plan.system.update.VersionCheckSystem;
|
||||
import com.djrapitops.plan.system.update.VersionInfo;
|
||||
import com.djrapitops.plan.system.webserver.WebServerSystem;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
import com.djrapitops.plugin.command.CommandNode;
|
||||
import com.djrapitops.plugin.command.CommandType;
|
||||
import com.djrapitops.plugin.command.ISender;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Command that updates all servers in the network
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class UpdateCommand extends CommandNode {
|
||||
|
||||
public UpdateCommand() {
|
||||
super("update", Permissions.MANAGE.getPermission(), CommandType.ALL);
|
||||
setArguments("[-update]/[cancel]");
|
||||
setShortHelp("Get change log link or update plugin.");
|
||||
setInDepthHelp(
|
||||
"/plan update",
|
||||
" Used to update the plugin on the next shutdown\n",
|
||||
" /plan update - get change log link",
|
||||
" /plan update -update - Schedule update to happen on all network servers that are online next time they reboot.",
|
||||
" /plan update cancel - Cancel scheduled update on servers that haven't rebooted yet."
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(ISender sender, String commandLabel, String[] args) {
|
||||
if (!VersionCheckSystem.isNewVersionAvailable()) {
|
||||
sender.sendMessage("§aYou're running the latest version of Plan.");
|
||||
return;
|
||||
}
|
||||
|
||||
VersionInfo available = VersionCheckSystem.getInstance().getNewVersionAvailable();
|
||||
String downloadUrl = available.getDownloadUrl();
|
||||
|
||||
if (!available.isTrusted()) {
|
||||
sender.sendMessage("§cVersion download url did not start with " +
|
||||
"https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/ " +
|
||||
"and might not be trusted. You can download this version manually here (Direct download):");
|
||||
sender.sendLink(downloadUrl, downloadUrl);
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
sender.sendLink("Change Log v" + available.getVersion().toString() + ": ", "Click me", available.getChangeLogUrl());
|
||||
return;
|
||||
}
|
||||
|
||||
String firstArgument = args[0];
|
||||
if ("-update".equals(firstArgument)) {
|
||||
handleUpdate(sender, args);
|
||||
} else if ("cancel".equals(firstArgument)) {
|
||||
cancel(sender);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown argument, use '-update' or 'cancel'");
|
||||
}
|
||||
}
|
||||
|
||||
private void cancel(ISender sender) {
|
||||
try {
|
||||
cancel(sender, Database.getActive().fetch().getServers());
|
||||
sender.sendMessage("§aUpdate has been cancelled.");
|
||||
} catch (DBException e) {
|
||||
sender.sendMessage("§cDatabase error occurred, cancel could not be performed.");
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleUpdate(ISender sender, String[] args) {
|
||||
sender.sendMessage("§aYou can cancel the update on servers that haven't rebooted yet with /plan update cancel.");
|
||||
sender.sendMessage("Checking that all servers are online..");
|
||||
if (!checkNetworkStatus(sender)) {
|
||||
sender.sendMessage("§cNot all servers were online or accessible, you can still update available servers using -force as a 2nd argument.");
|
||||
if (args.length <= 1 || !"-force".equals(args[1])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
List<Server> servers = Database.getActive().fetch().getServers();
|
||||
update(sender, servers);
|
||||
} catch (DBException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void update(ISender sender, List<Server> servers) {
|
||||
for (Server server : servers) {
|
||||
if (update(sender, server)) {
|
||||
sender.sendMessage("§a" + server.getName() + " scheduled for update.");
|
||||
} else {
|
||||
sender.sendMessage("§cUpdate failed on a server, cancelling update on all servers..");
|
||||
cancel(sender, servers);
|
||||
sender.sendMessage("§cUpdate cancelled.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cancel(ISender sender, List<Server> servers) {
|
||||
for (Server server : servers) {
|
||||
cancel(sender, server);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void cancel(ISender sender, Server server) {
|
||||
try {
|
||||
InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new UpdateCancelRequest(), server);
|
||||
} catch (ForbiddenException | GatewayException | InternalErrorException e) {
|
||||
sender.sendMessage("§cCancel failed on " + server.getName() + ": Odd Exception: " + e.getClass().getSimpleName());
|
||||
} catch (UnauthorizedServerException e) {
|
||||
sender.sendMessage("§cCancel failed on " + server.getName() + ": Unauthorized. " + server.getName() + " might be using different database.");
|
||||
} catch (ConnectionFailException e) {
|
||||
sender.sendMessage("§cCancel failed on " + server.getName() + ": " + e.getCause().getClass().getSimpleName() + " " + e.getCause().getMessage());
|
||||
String address = server.getWebAddress();
|
||||
boolean local = address.contains("localhost")
|
||||
|| address.startsWith("https://:") // IP empty = Localhost
|
||||
|| address.startsWith("http://:") // IP empty = Localhost
|
||||
|| address.contains("127.0.0.1");
|
||||
if (!local) {
|
||||
sender.sendMessage("§cNon-local address, check that port is open");
|
||||
}
|
||||
} catch (NotFoundException e) {
|
||||
/* Ignored, older version */
|
||||
} catch (WebException e) {
|
||||
sender.sendMessage("§cCancel failed on " + server.getName() + ": Odd Exception:" + e.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean update(ISender sender, Server server) {
|
||||
try {
|
||||
InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new CheckConnectionRequest(), server);
|
||||
return true;
|
||||
} catch (BadRequestException e) {
|
||||
sender.sendMessage("§c" + server.getName() + " has Allow-Update set to false, aborting update.");
|
||||
return false;
|
||||
} catch (ForbiddenException | GatewayException | InternalErrorException e) {
|
||||
sender.sendMessage("§c" + server.getName() + ": Odd Exception: " + e.getClass().getSimpleName());
|
||||
return false;
|
||||
} catch (UnauthorizedServerException e) {
|
||||
sender.sendMessage("§cFail reason: Unauthorized. " + server.getName() + " might be using different database.");
|
||||
return false;
|
||||
} catch (ConnectionFailException e) {
|
||||
sender.sendMessage("§cFail reason: " + e.getCause().getClass().getSimpleName() + " " + e.getCause().getMessage());
|
||||
String address = server.getWebAddress();
|
||||
boolean local = address.contains("localhost")
|
||||
|| address.startsWith("https://:") // IP empty = Localhost
|
||||
|| address.startsWith("http://:") // IP empty = Localhost
|
||||
|| address.contains("127.0.0.1");
|
||||
if (!local) {
|
||||
sender.sendMessage("§cNon-local address, check that port is open");
|
||||
}
|
||||
return false;
|
||||
} catch (NotFoundException e) {
|
||||
sender.sendMessage("§e" + server.getName() + " is using older version and can not be scheduled for update. " +
|
||||
"You can update it manually, update will proceed.");
|
||||
return true;
|
||||
} catch (WebException e) {
|
||||
sender.sendMessage("§eOdd Exception: " + e.getClass().getSimpleName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkNetworkStatus(ISender sender) {
|
||||
try {
|
||||
FetchOperations fetch = Database.getActive().fetch();
|
||||
Optional<Server> bungeeInformation = fetch.getBungeeInformation();
|
||||
if (!bungeeInformation.isPresent()) {
|
||||
return true;
|
||||
}
|
||||
Map<UUID, Server> bukkitServers = fetch.getBukkitServers();
|
||||
String accessAddress = WebServerSystem.getInstance().getWebServer().getAccessAddress();
|
||||
boolean success = true;
|
||||
for (Server server : bukkitServers.values()) {
|
||||
if (!ManageConDebugCommand.testServer(sender, accessAddress, server)) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
Server bungee = bungeeInformation.get();
|
||||
if (!ManageConDebugCommand.testServer(sender, accessAddress, bungee)) {
|
||||
success = false;
|
||||
}
|
||||
return success;
|
||||
} catch (DBException e) {
|
||||
sender.sendMessage("§cDatabase error occurred, update has been cancelled.");
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -28,12 +28,9 @@ import java.util.UUID;
|
||||
*/
|
||||
public class ManageConDebugCommand extends CommandNode {
|
||||
|
||||
private final ColorScheme cs;
|
||||
|
||||
public ManageConDebugCommand() {
|
||||
super("con", Permissions.MANAGE.getPermission(), CommandType.ALL);
|
||||
setShortHelp("Debug Bukkit-Bungee Connections");
|
||||
cs = PlanPlugin.getInstance().getColorScheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -68,18 +65,19 @@ public class ManageConDebugCommand extends CommandNode {
|
||||
}
|
||||
}
|
||||
|
||||
private void testServer(ISender sender, String accessAddress, Server server) {
|
||||
public static boolean testServer(ISender sender, String accessAddress, Server server) {
|
||||
String address = server.getWebAddress().toLowerCase();
|
||||
boolean usingHttps = address.startsWith("https");
|
||||
boolean local = address.contains("localhost")
|
||||
|| address.startsWith("https://:")
|
||||
|| address.startsWith("http://:")
|
||||
|| address.startsWith("https://:") // IP empty = Localhost
|
||||
|| address.startsWith("http://:") // IP empty = Localhost
|
||||
|| address.contains("127.0.0.1");
|
||||
|
||||
try {
|
||||
|
||||
InfoSystem.getInstance().getConnectionSystem().sendInfoRequest(new CheckConnectionRequest(accessAddress), server);
|
||||
sender.sendMessage(getMsgFor(address, usingHttps, local, true, true));
|
||||
return true;
|
||||
|
||||
} catch (ForbiddenException | BadRequestException | InternalErrorException e) {
|
||||
sender.sendMessage(getMsgFor(address, usingHttps, local, false, false));
|
||||
@ -102,9 +100,11 @@ public class ManageConDebugCommand extends CommandNode {
|
||||
sender.sendMessage(getMsgFor(address, usingHttps, local, false, false));
|
||||
sender.sendMessage("§eOdd Exception: " + e.getClass().getSimpleName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getMsgFor(String address, boolean usingHttps, boolean local, boolean successTo, boolean successFrom) {
|
||||
private static String getMsgFor(String address, boolean usingHttps, boolean local, boolean successTo, boolean successFrom) {
|
||||
ColorScheme cs = PlanPlugin.getInstance().getColorScheme();
|
||||
String tCol = cs.getTertiaryColor();
|
||||
String sCol = cs.getSecondaryColor();
|
||||
return tCol + address + sCol + ": "
|
||||
|
@ -125,6 +125,9 @@ public abstract class ConnectionSystem implements SubSystem {
|
||||
putRequest(requests, SaveDBSettingsRequest.createHandler());
|
||||
putRequest(requests, SendDBSettingsRequest.createHandler());
|
||||
putRequest(requests, CheckConnectionRequest.createHandler());
|
||||
|
||||
putRequest(requests, UpdateRequest.createHandler());
|
||||
putRequest(requests, UpdateCancelRequest.createHandler());
|
||||
return requests;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Licence is provided in the jar as license.yml also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
|
||||
*/
|
||||
package com.djrapitops.plan.system.info.request;
|
||||
|
||||
import com.djrapitops.plan.system.update.ShutdownUpdateHook;
|
||||
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
|
||||
import com.djrapitops.plan.system.webserver.response.Response;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* InfoRequest used for Updating the plugin on a network.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class UpdateCancelRequest implements InfoRequest {
|
||||
|
||||
public UpdateCancelRequest() {
|
||||
}
|
||||
|
||||
public static UpdateCancelRequest createHandler() {
|
||||
return new UpdateCancelRequest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runLocally() {
|
||||
ShutdownUpdateHook.deActivate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response handleRequest(Map<String, String> variables) {
|
||||
ShutdownUpdateHook.deActivate();
|
||||
return DefaultResponses.SUCCESS.get();
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Licence is provided in the jar as license.yml also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
|
||||
*/
|
||||
package com.djrapitops.plan.system.info.request;
|
||||
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.system.update.ShutdownUpdateHook;
|
||||
import com.djrapitops.plan.system.webserver.response.DefaultResponses;
|
||||
import com.djrapitops.plan.system.webserver.response.Response;
|
||||
import com.djrapitops.plan.system.webserver.response.api.BadRequestResponse;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* InfoRequest used for Updating the plugin on a network.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class UpdateRequest implements InfoRequest {
|
||||
|
||||
public UpdateRequest() {
|
||||
}
|
||||
|
||||
public static UpdateRequest createHandler() {
|
||||
return new UpdateRequest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runLocally() {
|
||||
new ShutdownUpdateHook().register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response handleRequest(Map<String, String> variables) {
|
||||
if (Settings.ALLOW_UPDATE.isTrue()) {
|
||||
new ShutdownUpdateHook().register();
|
||||
return DefaultResponses.SUCCESS.get();
|
||||
} else {
|
||||
return new BadRequestResponse("Update not allowed on this server");
|
||||
}
|
||||
}
|
||||
}
|
@ -37,6 +37,8 @@ public enum Settings {
|
||||
DISPLAY_PLAYER_IPS("Customization.Display.PlayerIPs"),
|
||||
DISPLAY_GAPS_IN_GRAPH_DATA("Customization.Display.GapsInGraphData"),
|
||||
DATA_GEOLOCATIONS("Data.Geolocations"),
|
||||
ALLOW_UPDATE("Plugin.Allow-Update-Command"),
|
||||
NOTIFY_ABOUT_DEV_RELEASES("Plugin.Notify-About-DEV-Releases"),
|
||||
|
||||
// Integer
|
||||
WEBSERVER_PORT("WebServer.Port"),
|
||||
|
@ -0,0 +1,104 @@
|
||||
package com.djrapitops.plan.system.update;
|
||||
|
||||
import com.djrapitops.plan.PlanPlugin;
|
||||
import com.djrapitops.plugin.api.Check;
|
||||
import com.djrapitops.plugin.api.utility.Version;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.Channels;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
|
||||
/**
|
||||
* Shutdown hook that updates the plugin on server shutdown.
|
||||
* <p>
|
||||
* Does not perform update on force close.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class ShutdownUpdateHook extends Thread {
|
||||
|
||||
private static boolean activated = false;
|
||||
|
||||
private static boolean isActivated() {
|
||||
return activated;
|
||||
}
|
||||
|
||||
private static void activate(ShutdownUpdateHook hook) {
|
||||
activated = true;
|
||||
Runtime.getRuntime().addShutdownHook(hook);
|
||||
}
|
||||
|
||||
public static void deActivate() {
|
||||
activated = false;
|
||||
Log.infoColor("§aUpdate has been cancelled.");
|
||||
}
|
||||
|
||||
public void register() {
|
||||
if (isActivated()) {
|
||||
return;
|
||||
}
|
||||
Log.infoColor("§aUpdate has been scheduled, The new jar will be downloaded on server shutdown.");
|
||||
activate(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!activated) {
|
||||
return;
|
||||
}
|
||||
activated = false;
|
||||
VersionInfo available = VersionCheckSystem.getInstance().getNewVersionAvailable();
|
||||
|
||||
if (!Version.isNewVersionAvailable(new Version(VersionCheckSystem.getCurrentVersion()), available.getVersion())) {
|
||||
return;
|
||||
}
|
||||
|
||||
File dataFolder = PlanPlugin.getInstance().getDataFolder();
|
||||
File pluginsFolder = Check.isSpongeAvailable()
|
||||
? dataFolder.getParentFile()
|
||||
: new File(dataFolder.getParentFile().getParentFile(), "mods");
|
||||
if (pluginsFolder == null || !pluginsFolder.isDirectory()) {
|
||||
System.out.println("Could not get plugin folder for Plan.");
|
||||
return;
|
||||
}
|
||||
File newFileLocation = new File(pluginsFolder, "Plan-" + available.getVersion() + ".jar");
|
||||
|
||||
try {
|
||||
downloadNewJar(available, newFileLocation);
|
||||
deleteOldJar(pluginsFolder, newFileLocation);
|
||||
} catch (IOException e) {
|
||||
Log.toLog(this.getClass().getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteOldJar(File pluginsFolder, File newFileLocation) {
|
||||
File[] files = pluginsFolder.listFiles();
|
||||
if (files == null) {
|
||||
System.out.println("Could not delete old jar.");
|
||||
return;
|
||||
}
|
||||
for (File file : files) {
|
||||
String fileName = file.getName();
|
||||
boolean isPlanJar = (fileName.startsWith("Plan-")
|
||||
&& fileName.endsWith(".jar"))
|
||||
|| fileName.equals("Plan.jar");
|
||||
boolean isNewJar = fileName.equals(newFileLocation.getName());
|
||||
if (isPlanJar && !isNewJar) {
|
||||
file.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void downloadNewJar(VersionInfo available, File newFileLocation) throws IOException {
|
||||
URL downloadFrom = new URL(available.getDownloadUrl());
|
||||
|
||||
ReadableByteChannel rbc = Channels.newChannel(downloadFrom.openStream());
|
||||
FileOutputStream fos = new FileOutputStream(newFileLocation);
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
}
|
||||
|
||||
}
|
@ -6,6 +6,7 @@ package com.djrapitops.plan.system.update;
|
||||
|
||||
import com.djrapitops.plan.system.PlanSystem;
|
||||
import com.djrapitops.plan.system.SubSystem;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plugin.api.Priority;
|
||||
import com.djrapitops.plugin.api.systems.NotificationCenter;
|
||||
import com.djrapitops.plugin.api.utility.Version;
|
||||
@ -13,6 +14,8 @@ import com.djrapitops.plugin.api.utility.log.Log;
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* System for checking if new Version is available when the System initializes.
|
||||
@ -22,7 +25,7 @@ import java.io.IOException;
|
||||
public class VersionCheckSystem implements SubSystem {
|
||||
|
||||
private final String currentVersion;
|
||||
private boolean newVersionAvailable = false;
|
||||
private VersionInfo newVersionAvailable;
|
||||
|
||||
public VersionCheckSystem(String currentVersion) {
|
||||
this.currentVersion = currentVersion;
|
||||
@ -35,7 +38,7 @@ public class VersionCheckSystem implements SubSystem {
|
||||
}
|
||||
|
||||
public static boolean isNewVersionAvailable() {
|
||||
return getInstance().newVersionAvailable;
|
||||
return getInstance().newVersionAvailable != null;
|
||||
}
|
||||
|
||||
public static String getCurrentVersion() {
|
||||
@ -44,14 +47,35 @@ public class VersionCheckSystem implements SubSystem {
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
checkForNewVersion();
|
||||
if (Settings.ALLOW_UPDATE.isTrue()) {
|
||||
try {
|
||||
List<VersionInfo> versions = VersionInfoLoader.load();
|
||||
if (Settings.NOTIFY_ABOUT_DEV_RELEASES.isFalse()) {
|
||||
versions = versions.stream().filter(VersionInfo::isRelease).collect(Collectors.toList());
|
||||
}
|
||||
VersionInfo newestVersion = versions.get(0);
|
||||
if (Version.isNewVersionAvailable(new Version(currentVersion), newestVersion.getVersion())) {
|
||||
String notification =
|
||||
"New Release (" + newestVersion.getVersion().toString() + ") is available and can be updated " +
|
||||
"to using update subcommand." + (newestVersion.isRelease() ? "" : " This is a DEV release.");
|
||||
Log.info(notification);
|
||||
NotificationCenter.addNotification(newestVersion.isRelease() ? Priority.HIGH : Priority.MEDIUM, notification);
|
||||
} else {
|
||||
Log.info("You're using the latest version.");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.error("Version information could not be loaded from Github/versions.txt");
|
||||
}
|
||||
} else {
|
||||
checkForNewVersion();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkForNewVersion() {
|
||||
String githubVersionUrl = "https://raw.githubusercontent.com/Rsl1122/Plan-PlayerAnalytics/master/Plan/src/main/resources/plugin.yml";
|
||||
String spigotUrl = "https://www.spigotmc.org/resources/plan-player-analytics.32536/";
|
||||
try {
|
||||
newVersionAvailable = Version.checkVersion(currentVersion, githubVersionUrl);
|
||||
boolean newVersionAvailable = Version.checkVersion(currentVersion, githubVersionUrl);
|
||||
if (!newVersionAvailable) {
|
||||
try {
|
||||
newVersionAvailable = Version.checkVersion(currentVersion, spigotUrl);
|
||||
@ -77,4 +101,8 @@ public class VersionCheckSystem implements SubSystem {
|
||||
public void disable() {
|
||||
/* Does not need to be closed */
|
||||
}
|
||||
|
||||
public VersionInfo getNewVersionAvailable() {
|
||||
return newVersionAvailable;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.djrapitops.plan.system.update;
|
||||
|
||||
import com.djrapitops.plugin.api.utility.Version;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* Data class for reading version.txt in https://github.com/Rsl1122/Plan-PlayerAnalytics.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class VersionInfo implements Comparable<VersionInfo> {
|
||||
|
||||
private final boolean release;
|
||||
private final Version version;
|
||||
private final String downloadUrl;
|
||||
private final String changeLogUrl;
|
||||
|
||||
public VersionInfo(boolean release, Version version, String downloadUrl, String changeLogUrl) {
|
||||
this.release = release;
|
||||
this.version = version;
|
||||
this.downloadUrl = downloadUrl;
|
||||
this.changeLogUrl = changeLogUrl;
|
||||
}
|
||||
|
||||
public boolean isRelease() {
|
||||
return release;
|
||||
}
|
||||
|
||||
public Version getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getDownloadUrl() {
|
||||
return downloadUrl;
|
||||
}
|
||||
|
||||
public String getChangeLogUrl() {
|
||||
return changeLogUrl;
|
||||
}
|
||||
|
||||
public boolean isTrusted() {
|
||||
return downloadUrl.startsWith("https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/download/");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
VersionInfo that = (VersionInfo) o;
|
||||
return release == that.release &&
|
||||
Objects.equal(version, that.version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(release, version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(VersionInfo o) {
|
||||
return -this.version.compareTo(o.version);
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.djrapitops.plan.system.update;
|
||||
|
||||
import com.djrapitops.plugin.api.utility.Version;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* Utility for loading version information from github.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class VersionInfoLoader {
|
||||
|
||||
private static final String VERSION_TXT_URL =
|
||||
"https://raw.githubusercontent.com/Rsl1122/Plan-PlayerAnalytics/master/versions.txt";
|
||||
|
||||
/**
|
||||
* Loads version information from github.
|
||||
*
|
||||
* @return List of VersionInfo, newest version first.
|
||||
* @throws IOException If site can not be accessed.
|
||||
* @throws java.net.MalformedURLException If VERSION_TXT_URL is not valid.
|
||||
*/
|
||||
public static List<VersionInfo> load() throws IOException {
|
||||
URL url = new URL(VERSION_TXT_URL);
|
||||
|
||||
List<VersionInfo> versionInfo = new ArrayList<>();
|
||||
|
||||
try (Scanner websiteScanner = new Scanner(url.openStream())) {
|
||||
while (websiteScanner.hasNextLine()) {
|
||||
String line = websiteScanner.nextLine();
|
||||
if (!line.startsWith("REL") && !line.startsWith("DEV")) {
|
||||
continue;
|
||||
}
|
||||
String[] parts = line.split("\\|");
|
||||
if (parts.length < 4) {
|
||||
continue;
|
||||
}
|
||||
boolean release = parts[0].equals("REL");
|
||||
Version version = new Version(parts[1]);
|
||||
String downloadUrl = parts[2];
|
||||
String changeLogUrl = parts[3];
|
||||
|
||||
versionInfo.add(new VersionInfo(release, version, downloadUrl, changeLogUrl));
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(versionInfo);
|
||||
return versionInfo;
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
name: Plan
|
||||
author: Rsl1122
|
||||
main: com.djrapitops.plan.PlanBungee
|
||||
version: 4.2.0
|
||||
version: 4.2.0-b1
|
@ -12,6 +12,8 @@ Network:
|
||||
Plugin:
|
||||
Debug: 'false'
|
||||
Locale: default
|
||||
Allow-Update-Command: true
|
||||
Notify-About-DEV-Releases: false
|
||||
|
||||
# -----------------------------------------------------
|
||||
# More information about SSL Certificate Settings:
|
||||
|
@ -17,6 +17,8 @@ Plugin:
|
||||
Bungee-Override:
|
||||
StandaloneMode: false
|
||||
CopyBungeeConfig: true
|
||||
Allow-Update-Command: true
|
||||
Notify-About-DEV-Releases: false
|
||||
|
||||
# -----------------------------------------------------
|
||||
# More information about SSL Certificate Settings:
|
||||
|
@ -1,7 +1,7 @@
|
||||
name: Plan
|
||||
author: Rsl1122
|
||||
main: com.djrapitops.plan.Plan
|
||||
version: 4.2.0
|
||||
version: 4.2.0-b1
|
||||
softdepend:
|
||||
- EssentialsX
|
||||
- Towny
|
||||
|
@ -0,0 +1,24 @@
|
||||
package com.djrapitops.plan.system.update;
|
||||
|
||||
import com.djrapitops.plugin.api.utility.Version;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class VersionInfoLoaderTest {
|
||||
|
||||
@Test
|
||||
public void versionLoaderTest() throws IOException {
|
||||
List<VersionInfo> versions = VersionInfoLoader.load();
|
||||
|
||||
VersionInfo oldest = versions.get(versions.size() - 1);
|
||||
assertEquals(new Version("4.1.7"), oldest.getVersion());
|
||||
assertTrue(oldest.isRelease());
|
||||
assertTrue(oldest.isTrusted());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user