Better URL error response handler

This commit is contained in:
Frank van der Heijden 2020-06-30 11:27:14 +02:00
parent 3f24f4acea
commit 93c5adb911
No known key found for this signature in database
GPG key ID: 26DA56488D314D11
2 changed files with 59 additions and 39 deletions

View file

@ -1,6 +1,7 @@
package net.frankheijden.serverutils.tasks; package net.frankheijden.serverutils.tasks;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import java.io.File; import java.io.File;
@ -15,13 +16,13 @@ import java.util.logging.Level;
import net.frankheijden.serverutils.ServerUtils; import net.frankheijden.serverutils.ServerUtils;
import net.frankheijden.serverutils.config.Config; import net.frankheijden.serverutils.config.Config;
import net.frankheijden.serverutils.config.Messenger; import net.frankheijden.serverutils.config.Messenger;
import net.frankheijden.serverutils.managers.CloseableResult;
import net.frankheijden.serverutils.managers.PluginManager;
import net.frankheijden.serverutils.managers.VersionManager; import net.frankheijden.serverutils.managers.VersionManager;
import net.frankheijden.serverutils.utils.FileUtils; import net.frankheijden.serverutils.utils.FileUtils;
import net.frankheijden.serverutils.utils.VersionUtils; import net.frankheijden.serverutils.utils.VersionUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.plugin.InvalidDescriptionException;
import org.bukkit.plugin.InvalidPluginException;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
public class UpdateCheckerTask implements Runnable { public class UpdateCheckerTask implements Runnable {
@ -33,12 +34,10 @@ public class UpdateCheckerTask implements Runnable {
private final boolean startup; private final boolean startup;
private static final String GITHUB_LINK = "https://api.github.com/repos/FrankHeijden/ServerUtils/releases/latest"; private static final String GITHUB_LINK = "https://api.github.com/repos/FrankHeijden/ServerUtils/releases/latest";
private static final String USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:77.0)"
+ "Gecko/20100101"
+ "Firefox/77.0";
private static final String UPDATE_CHECK_START = "Checking for updates..."; private static final String UPDATE_CHECK_START = "Checking for updates...";
private static final String GENERAL_ERROR = "Error fetching new version of ServerUtils"; private static final String GENERAL_ERROR = "Error fetching new version of ServerUtils";
private static final String TRY_LATER = GENERAL_ERROR + ", please try again later!";
private static final String CONNECTION_ERROR = GENERAL_ERROR + ": (%s) %s (maybe check your connection?)"; private static final String CONNECTION_ERROR = GENERAL_ERROR + ": (%s) %s (maybe check your connection?)";
private static final String UNAVAILABLE = GENERAL_ERROR + ": (%s) %s (no update available)"; private static final String UNAVAILABLE = GENERAL_ERROR + ": (%s) %s (no update available)";
private static final String UPDATE_AVAILABLE = "ServerUtils %s is available!"; private static final String UPDATE_AVAILABLE = "ServerUtils %s is available!";
@ -46,6 +45,7 @@ public class UpdateCheckerTask implements Runnable {
private static final String DOWNLOAD_ERROR = "Error downloading a new version of ServerUtils"; private static final String DOWNLOAD_ERROR = "Error downloading a new version of ServerUtils";
private static final String UPGRADE_SUCCESS = "Successfully upgraded ServerUtils to v%s!"; private static final String UPGRADE_SUCCESS = "Successfully upgraded ServerUtils to v%s!";
private static final String DOWNLOADED_RESTART = "Downloaded ServerUtils version v%s. Restarting plugin now..."; private static final String DOWNLOADED_RESTART = "Downloaded ServerUtils version v%s. Restarting plugin now...";
private static final String UP_TO_DATE = "We are up-to-date!";
private UpdateCheckerTask(CommandSender sender, boolean startup) { private UpdateCheckerTask(CommandSender sender, boolean startup) {
this.sender = sender; this.sender = sender;
@ -72,9 +72,9 @@ public class UpdateCheckerTask implements Runnable {
plugin.getLogger().info(UPDATE_CHECK_START); plugin.getLogger().info(UPDATE_CHECK_START);
} }
JsonObject jsonObject; JsonElement jsonElement;
try { try {
jsonObject = FileUtils.readJsonFromUrl(GITHUB_LINK).getAsJsonObject(); jsonElement = FileUtils.readJsonFromUrl(GITHUB_LINK);
} catch (ConnectException | UnknownHostException | SocketTimeoutException ex) { } catch (ConnectException | UnknownHostException | SocketTimeoutException ex) {
plugin.getLogger().severe(String.format(CONNECTION_ERROR, ex.getClass().getSimpleName(), ex.getMessage())); plugin.getLogger().severe(String.format(CONNECTION_ERROR, ex.getClass().getSimpleName(), ex.getMessage()));
return; return;
@ -85,18 +85,21 @@ public class UpdateCheckerTask implements Runnable {
plugin.getLogger().log(Level.SEVERE, ex, () -> GENERAL_ERROR); plugin.getLogger().log(Level.SEVERE, ex, () -> GENERAL_ERROR);
return; return;
} }
String githubVersion = jsonObject.getAsJsonPrimitive("tag_name").getAsString();
githubVersion = githubVersion.replace("v", "");
String body = jsonObject.getAsJsonPrimitive("body").getAsString();
JsonArray assets = jsonObject.getAsJsonArray("assets"); if (jsonElement == null) {
String downloadLink = null; plugin.getLogger().warning(TRY_LATER);
if (assets != null && assets.size() > 0) { return;
downloadLink = assets.get(0)
.getAsJsonObject()
.getAsJsonPrimitive("browser_download_url")
.getAsString();
} }
JsonObject jsonObject = jsonElement.getAsJsonObject();
if (jsonObject.has("message")) {
plugin.getLogger().warning(jsonObject.get("message").getAsString());
return;
}
String githubVersion = getVersion(jsonObject);
String body = jsonObject.getAsJsonPrimitive("body").getAsString();
String downloadUrl = getDownloadUrl(jsonObject);
if (VersionUtils.isNewVersion(currentVersion, githubVersion)) { if (VersionUtils.isNewVersion(currentVersion, githubVersion)) {
if (isStartupCheck()) { if (isStartupCheck()) {
plugin.getLogger().info(String.format(UPDATE_AVAILABLE, githubVersion)); plugin.getLogger().info(String.format(UPDATE_AVAILABLE, githubVersion));
@ -104,14 +107,15 @@ public class UpdateCheckerTask implements Runnable {
} }
if (canDownloadPlugin()) { if (canDownloadPlugin()) {
if (isStartupCheck()) { if (isStartupCheck()) {
plugin.getLogger().info(String.format(DOWNLOAD_START, downloadLink)); plugin.getLogger().info(String.format(DOWNLOAD_START, downloadUrl));
} else { } else {
Messenger.sendMessage(sender, "serverutils.update.downloading", Messenger.sendMessage(sender, "serverutils.update.downloading",
"%old%", currentVersion, "%old%", currentVersion,
"%new%", githubVersion, "%new%", githubVersion,
"%info%", body); "%info%", body);
} }
downloadPlugin(githubVersion, downloadLink); downloadPlugin(githubVersion, downloadUrl);
tryReloadPlugin();
} else if (!isStartupCheck()) { } else if (!isStartupCheck()) {
Messenger.sendMessage(sender, "serverutils.update.available", Messenger.sendMessage(sender, "serverutils.update.available",
"%old%", currentVersion, "%old%", currentVersion,
@ -119,13 +123,25 @@ public class UpdateCheckerTask implements Runnable {
"%info%", body); "%info%", body);
} }
} else if (versionManager.hasDownloaded()) { } else if (versionManager.hasDownloaded()) {
Messenger.sendMessage(sender, "serverutils.update.success", Messenger.sendMessage(sender, "serverutils.update.success",
"%new%", versionManager.getDownloadedVersion()); "%new%", versionManager.getDownloadedVersion());
} else if (isStartupCheck()) { } else if (isStartupCheck()) {
plugin.getLogger().info("We are up-to-date!"); plugin.getLogger().info(UP_TO_DATE);
} }
} }
private String getVersion(JsonObject jsonObject) {
return jsonObject.getAsJsonPrimitive("tag_name").getAsString().replace("v", "");
}
private String getDownloadUrl(JsonObject jsonObject) {
JsonArray assets = jsonObject.getAsJsonArray("assets");
if (assets != null && assets.size() > 0) {
return assets.get(0).getAsJsonObject().getAsJsonPrimitive("browser_download_url").getAsString();
}
return null;
}
private boolean canDownloadPlugin() { private boolean canDownloadPlugin() {
if (isStartupCheck()) return Config.getInstance().getBoolean("settings.download-at-startup-and-update"); if (isStartupCheck()) return Config.getInstance().getBoolean("settings.download-at-startup-and-update");
return Config.getInstance().getBoolean("settings.download-updates"); return Config.getInstance().getBoolean("settings.download-updates");
@ -149,19 +165,19 @@ public class UpdateCheckerTask implements Runnable {
throw new RuntimeException(DOWNLOAD_ERROR, ex); throw new RuntimeException(DOWNLOAD_ERROR, ex);
} }
versionManager.setDownloadedVersion(githubVersion);
}
private void tryReloadPlugin() {
String downloadedVersion = versionManager.getDownloadedVersion();
if (isStartupCheck()) { if (isStartupCheck()) {
plugin.getLogger().info(String.format(DOWNLOADED_RESTART, githubVersion)); plugin.getLogger().info(String.format(DOWNLOADED_RESTART, downloadedVersion));
Bukkit.getPluginManager().disablePlugin(plugin); CloseableResult result = PluginManager.reloadPlugin(plugin);
try { plugin.getLogger().info(String.format(UPGRADE_SUCCESS, downloadedVersion));
Bukkit.getPluginManager().enablePlugin(Bukkit.getPluginManager().loadPlugin(getPluginFile())); result.tryClose();
} catch (InvalidPluginException | InvalidDescriptionException ex) {
ex.printStackTrace();
return;
}
plugin.getLogger().info(String.format(UPGRADE_SUCCESS, githubVersion));
} else { } else {
versionManager.setDownloadedVersion(githubVersion); broadcastDownloadStatus(downloadedVersion, false);
broadcastDownloadStatus(githubVersion, false);
} }
} }

View file

@ -9,8 +9,8 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -28,10 +28,12 @@ public class FileUtils {
* @throws IOException If an I/O exception occurs. * @throws IOException If an I/O exception occurs.
*/ */
public static void download(String urlString, File target) throws IOException { public static void download(String urlString, File target) throws IOException {
try (InputStream is = stream(urlString); try (InputStream is = stream(urlString)) {
ReadableByteChannel rbc = Channels.newChannel(is); if (is == null) return;
FileOutputStream fos = new FileOutputStream(target)) { try (ReadableByteChannel rbc = Channels.newChannel(is);
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); FileOutputStream fos = new FileOutputStream(target)) {
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
}
} }
} }
@ -42,10 +44,11 @@ public class FileUtils {
* @throws IOException If an I/O exception occurs. * @throws IOException If an I/O exception occurs.
*/ */
public static InputStream stream(String url) throws IOException { public static InputStream stream(String url) throws IOException {
URLConnection conn = new URL(url).openConnection(); HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
conn.setRequestProperty("User-Agent", USER_AGENT); conn.setRequestProperty("User-Agent", USER_AGENT);
conn.setConnectTimeout(10000); conn.setConnectTimeout(10000);
return conn.getInputStream(); int res = conn.getResponseCode();
return (res >= 200 && res <= 299) ? conn.getInputStream() : conn.getErrorStream();
} }
/** /**
@ -71,6 +74,7 @@ public class FileUtils {
*/ */
public static JsonElement readJsonFromUrl(String url) throws IOException { public static JsonElement readJsonFromUrl(String url) throws IOException {
try (InputStream is = stream(url)) { try (InputStream is = stream(url)) {
if (is == null) return null;
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String jsonText = readAll(reader); String jsonText = readAll(reader);
return new JsonParser().parse(jsonText); return new JsonParser().parse(jsonText);