diff --git a/src/main/java/org/parabot/core/Configuration.java b/src/main/java/org/parabot/core/Configuration.java index a8185a6..08a8ca1 100644 --- a/src/main/java/org/parabot/core/Configuration.java +++ b/src/main/java/org/parabot/core/Configuration.java @@ -11,8 +11,10 @@ public class Configuration extends org.parabot.api.Configuration { public static final String LOGIN_SERVER = "http://bdn.parabot.org/api/v2/users/login"; public static final String GET_SCRIPTS = "http://bdn.parabot.org/api/get.php?action=scripts_scripts&server="; public static final String GET_SCRIPT = "http://bdn.parabot.org/api/get.php?action=scripts_script&id="; + public static final String GET_SERVER_PROVIDER_TYPE = "http://v3.bdn.parabot.org/api/bot/server/type?server=%s"; public static final String GET_SERVER_PROVIDERS = "http://bdn.parabot.org/api/get.php?action=server_providers"; public static final String GET_SERVER_PROVIDER = "http://v3.bdn.parabot.org/api/bot/download/provider?nightly=%s&server=%s"; + public static final String SERVER_PROVIDER_INFO = "http://v3.bdn.parabot.org/api/bot/list/%s?latest=true"; public static final String GET_SERVER_PROVIDER_INFO = "http://bdn.parabot.org/api/get.php?action=server_information&name="; public static final String GET_SERVER_SETTINGS = "http://bdn.parabot.org/api/get.php?action=get_settings"; public static final String GET_BOT_VERSION = "http://bdn.parabot.org/api/v2/bot/version"; diff --git a/src/main/java/org/parabot/core/desc/ServerProviderInfo.java b/src/main/java/org/parabot/core/desc/ServerProviderInfo.java index a4e8c98..b5e84ae 100644 --- a/src/main/java/org/parabot/core/desc/ServerProviderInfo.java +++ b/src/main/java/org/parabot/core/desc/ServerProviderInfo.java @@ -166,6 +166,7 @@ public class ServerProviderInfo { /** * Gets the URL to download the Randoms JAR from. + * * @return The provided URL in the server config JSON (denoted by 'randoms:') or, fallback to the default BDN URL. */ public URL getRandoms() { @@ -182,4 +183,19 @@ public class ServerProviderInfo { // Will never return null, unless the BDN URL is changed. It shouldn't be. return null; } + + /** + * Gets the current provider version + * + * @return provider version + */ + public String getProviderVersion() { + String providerType = WebUtil.getJsonValue(String.format(Configuration.GET_SERVER_PROVIDER_TYPE , properties.getProperty("name")), "type"); + if(providerType != null) { + String providerInfo = String.format(Configuration.SERVER_PROVIDER_INFO, providerType); + return WebUtil.getJsonValue(providerInfo, "version"); + } + + return null; + } } diff --git a/src/main/java/org/parabot/environment/api/utils/FileUtil.java b/src/main/java/org/parabot/environment/api/utils/FileUtil.java index ce954d3..a7e2fd5 100644 --- a/src/main/java/org/parabot/environment/api/utils/FileUtil.java +++ b/src/main/java/org/parabot/environment/api/utils/FileUtil.java @@ -1,10 +1,8 @@ package org.parabot.environment.api.utils; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; +import java.io.*; import java.nio.channels.FileChannel; +import java.nio.file.Files; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -88,4 +86,29 @@ public class FileUtil { } destination.close(); } + + /** + * Reads the contents of a text file + * + * @param file file to get contents from + * @return file contents + * @throws IOException when anything goes wrong + */ + public static String getFileContents(File file) throws IOException { + return new String(Files.readAllBytes(file.toPath())); + } + + /** + * Writes a string to a file overwriting the existing contents if present + * + * @param file file to write to + * @param contents contents to write to given file + * @throws IOException when anything goes wrong + */ + public static void writeFileContents(File file, String contents) throws IOException { + BufferedWriter writer = new BufferedWriter(new FileWriter(file.getAbsolutePath())); + writer.write(contents); + + writer.close(); + } } diff --git a/src/main/java/org/parabot/environment/api/utils/PBLocalPreferences.java b/src/main/java/org/parabot/environment/api/utils/PBLocalPreferences.java new file mode 100644 index 0000000..74eb1d7 --- /dev/null +++ b/src/main/java/org/parabot/environment/api/utils/PBLocalPreferences.java @@ -0,0 +1,118 @@ +package org.parabot.environment.api.utils; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.parabot.core.Directories; + +import java.io.File; +import java.util.HashMap; + +/** + * Manages preferences in a local file in JSON format in the Parabot settings folder + * + * @author AlexanderBielen + */ +public class PBLocalPreferences { + private static JSONParser parser = new JSONParser(); + private File settingsFile; + + public PBLocalPreferences(String fileName) { + settingsFile = new File(Directories.getSettingsPath() + "/" + secureFileName(fileName)); + } + + /** + * Gets all settings inside the file + * + * @return JSONObject or null if anything went wrong + */ + public JSONObject getSettings() { + try { + String stringContents = FileUtil.getFileContents(settingsFile); + return (JSONObject) parser.parse(stringContents); + } catch(Exception ex) { + return null; + } + } + + /** + * Convert a HashMap to json and writes it to the file + * + * @param settings HashMap + * @param append If true, append to existing settings in file + */ + public void writeSettings(HashMap settings, boolean append) { + JSONObject existingSettings; + if(append && (existingSettings = getSettings()) != null) { + existingSettings.putAll(settings); + settings = existingSettings; + } + + try { + if (!settingsFile.exists()) { + settingsFile.createNewFile(); + } + FileUtil.writeFileContents(settingsFile, new JSONObject(settings).toJSONString()); + + } catch (Exception ignore) { + ignore.printStackTrace(); + } + + } + + /** + * Adds a setting, or overwrites it if it exists + * + * @param key key of the setting + * @param value value of the setting + */ + public void addSetting(String key, String value) { + HashMap pair = new HashMap<>(); + pair.put(key, value); + writeSettings(pair, true); + } + + /** + * Fetches a setting + * + * @param key key to get the value for + * @return value that belongs to given key or null if non-existent + */ + public String getSetting(String key) { + if(getSettings() == null) { + return null; + } + + return getSettings().get(key).toString(); + } + + /** + * Adjusts an existing setting + * + * @param key key to adjust the value for + * @param value value for the key + */ + public void adjustSetting(String key, String value) { + addSetting(key, value); + } + + /** + * Removes a setting + * + * @param key key to remove + */ + public void removeSetting(String key) { + JSONObject json = getSettings(); + json.remove(key); + writeSettings(json, false); + } + + /** + * Replaces all double dots to make sure the link does not leave the settings folder + * + * @param filePath path to secure + * @return secured string + */ + private static String secureFileName(String filePath) { + return filePath.replace("..", ""); + } +} diff --git a/src/main/java/org/parabot/environment/api/utils/WebUtil.java b/src/main/java/org/parabot/environment/api/utils/WebUtil.java index 14c175b..8f1532d 100644 --- a/src/main/java/org/parabot/environment/api/utils/WebUtil.java +++ b/src/main/java/org/parabot/environment/api/utils/WebUtil.java @@ -1,5 +1,7 @@ package org.parabot.environment.api.utils; +import org.json.simple.JSONObject; + /** * A WebUtil class fetches data from an URL * @@ -7,4 +9,27 @@ package org.parabot.environment.api.utils; */ public class WebUtil extends org.parabot.api.io.WebUtil { + /** + * Fetches a single value from a JSON string at the given url + * + * @param url url to get the JSON string from + * @param key key to search for in the JSON string + * @return value that belongs to given key + */ + public static String getJsonValue(String url, String key) { + try { + String response = WebUtil.getContents(url); + + if(response.length() > 0) { + JSONObject jsonObject = (JSONObject) WebUtil.getJsonParser().parse(response); + if (jsonObject.get(key) != null) { + return jsonObject.get(key).toString(); + } + } + } catch (Exception ex) { + ex.printStackTrace(); + } + + return null; + } } diff --git a/src/main/java/org/parabot/environment/servers/executers/PublicServerExecuter.java b/src/main/java/org/parabot/environment/servers/executers/PublicServerExecuter.java index b98bd3c..a316586 100644 --- a/src/main/java/org/parabot/environment/servers/executers/PublicServerExecuter.java +++ b/src/main/java/org/parabot/environment/servers/executers/PublicServerExecuter.java @@ -11,6 +11,7 @@ import org.parabot.core.forum.AccountManager; import org.parabot.core.forum.AccountManagerAccess; import org.parabot.core.ui.components.VerboseLoader; import org.parabot.core.ui.utils.UILog; +import org.parabot.environment.api.utils.PBLocalPreferences; import org.parabot.environment.api.utils.WebUtil; import org.parabot.environment.servers.ServerProvider; import org.parabot.environment.servers.loader.ServerLoader; @@ -37,6 +38,9 @@ public class PublicServerExecuter extends ServerExecuter { }; private String serverName; + private PBLocalPreferences settings; + private final String cacheVersionKey = "cachedProviderVersion"; + public PublicServerExecuter(final String serverName) { this.serverName = serverName; } @@ -53,6 +57,24 @@ public class PublicServerExecuter extends ServerExecuter { Core.verbose("Downloading: " + jarUrl + " ..."); + String providerVersion = serverProviderInfo.getProviderVersion(); + if(providerVersion == null) { + providerVersion = "error"; + } + + settings = new PBLocalPreferences(serverProviderInfo.getClientCRC32()+".json"); + if(settings.getSetting(cacheVersionKey) != null) { + Core.verbose(String.format("Latest provider version: %s, local provider version: %s", settings.getSetting(cacheVersionKey), providerVersion)); + if(!settings.getSetting(cacheVersionKey).equals(providerVersion)) { + Core.verbose("Local provider outdated, clearing cache."); + Directories.clearCache(); + } + } else { + Core.verbose("No local provider version in settings, adding to settings file"); + } + + settings.addSetting(cacheVersionKey, providerVersion); + if (destination.exists()) { Core.verbose("Found cached server provider [CRC32: " + serverProviderInfo.getCRC32() + "]"); } else {