diff --git a/Plan/pom.xml b/Plan/pom.xml index b271b5cdb..4df5e2979 100644 --- a/Plan/pom.xml +++ b/Plan/pom.xml @@ -42,14 +42,20 @@ 3.6 compile - + + + com.maxmind.geoip2 + geoip2 + 2.9.0 + + com.djrapitops abstract-plugin-framework 2.0.5 compile - + org.apache.commons commons-dbcp2 @@ -68,14 +74,14 @@ 1.2 compile - + com.djrapitops PlanPluginBridge 3.7.0 compile - + org.powermock powermock diff --git a/Plan/src/main/java/com/djrapitops/plan/Plan.java b/Plan/src/main/java/com/djrapitops/plan/Plan.java index 782b8ca7d..32895444f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/Plan.java +++ b/Plan/src/main/java/com/djrapitops/plan/Plan.java @@ -30,7 +30,6 @@ import main.java.com.djrapitops.plan.api.API; import main.java.com.djrapitops.plan.api.IPlan; import main.java.com.djrapitops.plan.api.exceptions.DatabaseInitException; import main.java.com.djrapitops.plan.command.PlanCommand; -import main.java.com.djrapitops.plan.command.commands.RegisterCommandFilter; import main.java.com.djrapitops.plan.data.additional.HookHandler; import main.java.com.djrapitops.plan.database.Database; import main.java.com.djrapitops.plan.database.databases.MySQLDB; @@ -38,6 +37,7 @@ import main.java.com.djrapitops.plan.database.databases.SQLiteDB; import main.java.com.djrapitops.plan.locale.Locale; import main.java.com.djrapitops.plan.locale.Msg; import main.java.com.djrapitops.plan.systems.cache.DataCache; +import main.java.com.djrapitops.plan.systems.cache.GeolocationCache; import main.java.com.djrapitops.plan.systems.info.InformationManager; import main.java.com.djrapitops.plan.systems.info.server.ServerInfoManager; import main.java.com.djrapitops.plan.systems.listeners.*; @@ -47,7 +47,6 @@ import main.java.com.djrapitops.plan.systems.tasks.TPSCountTimer; import main.java.com.djrapitops.plan.systems.webserver.PageCache; import main.java.com.djrapitops.plan.systems.webserver.WebServer; import main.java.com.djrapitops.plan.utilities.Benchmark; -import org.apache.logging.log4j.LogManager; import org.bukkit.ChatColor; import java.util.HashSet; @@ -133,6 +132,8 @@ public class Plan extends BukkitPlugin implements IPlan { Benchmark.start("Enable"); + GeolocationCache.checkDB(); + // Initialize Locale new Locale(this).loadLocale(); @@ -173,8 +174,6 @@ public class Plan extends BukkitPlugin implements IPlan { this.api = new API(this); - setupFilter(); // TODO Move to RegisterCommand Constructor - // Data view settings // TODO Rewrite. (TextUI removed & webServer might be running on bungee boolean usingAlternativeIP = Settings.SHOW_ALTERNATIVE_IP.isTrue(); boolean hasDataViewCapability = usingAlternativeIP; @@ -213,14 +212,15 @@ public class Plan extends BukkitPlugin implements IPlan { Benchmark.start("Task Registration"); tpsCountTimer = new TPSCountTimer(this); - runnableFactory.createNew(tpsCountTimer).runTaskTimer(1000, TimeAmount.SECOND.ticks()); + // Analysis refresh settings int analysisRefreshMinutes = Settings.ANALYSIS_AUTO_REFRESH.getNumber(); boolean analysisRefreshTaskIsEnabled = analysisRefreshMinutes > 0; long analysisPeriod = analysisRefreshMinutes * TimeAmount.MINUTE.ticks(); Log.info(bootAnalysisMsg); + ITask bootAnalysisTask = runnableFactory.createNew("BootAnalysisTask", new AbsRunnable() { @Override public void run() { @@ -229,7 +229,9 @@ public class Plan extends BukkitPlugin implements IPlan { this.cancel(); } }).runTaskLaterAsynchronously(30 * TimeAmount.SECOND.ticks()); + bootAnalysisTaskID = bootAnalysisTask.getTaskId(); + if (analysisRefreshTaskIsEnabled) { runnableFactory.createNew("PeriodicalAnalysisTask", new AbsRunnable() { @Override @@ -238,6 +240,7 @@ public class Plan extends BukkitPlugin implements IPlan { } }).runTaskTimerAsynchronously(analysisPeriod, analysisPeriod); } + Benchmark.stop("Enable", "Task Registration"); } @@ -331,14 +334,6 @@ public class Plan extends BukkitPlugin implements IPlan { db.init(); } - /** - * Setups the command console output filter - */ - private void setupFilter() { - org.apache.logging.log4j.core.Logger logger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger(); - logger.addFilter(new RegisterCommandFilter()); - } - /** * Used to access Cache. * diff --git a/Plan/src/main/java/com/djrapitops/plan/ServerVariableHolder.java b/Plan/src/main/java/com/djrapitops/plan/ServerVariableHolder.java index f88d5ddb6..110ac40ab 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ServerVariableHolder.java +++ b/Plan/src/main/java/com/djrapitops/plan/ServerVariableHolder.java @@ -1,5 +1,8 @@ package main.java.com.djrapitops.plan; +import net.md_5.bungee.api.ProxyServer; +import org.bukkit.Server; + /** * Class responsible for holding server variable values that do not change * without a reload. @@ -22,7 +25,7 @@ public class ServerVariableHolder { * * @param server instance the plugin is running on. */ - public ServerVariableHolder(org.bukkit.Server server) { + public ServerVariableHolder(Server server) { ip = server.getIp(); name = server.getName(); port = server.getPort(); @@ -40,7 +43,7 @@ public class ServerVariableHolder { * * @param server instance the plugin is running on. */ - public ServerVariableHolder(net.md_5.bungee.api.ProxyServer server) { + public ServerVariableHolder(ProxyServer server) { ip = Settings.BUNGEE_IP.toString(); name = "BungeeCord"; port = -1; diff --git a/Plan/src/main/java/com/djrapitops/plan/api/exceptions/DatabaseInitException.java b/Plan/src/main/java/com/djrapitops/plan/api/exceptions/DatabaseInitException.java index fba427886..1df4cda7b 100644 --- a/Plan/src/main/java/com/djrapitops/plan/api/exceptions/DatabaseInitException.java +++ b/Plan/src/main/java/com/djrapitops/plan/api/exceptions/DatabaseInitException.java @@ -10,6 +10,7 @@ package main.java.com.djrapitops.plan.api.exceptions; * @author Rsl1122 */ public class DatabaseInitException extends DatabaseException { + public DatabaseInitException(String message, Throwable cause) { super(message, cause); } diff --git a/Plan/src/main/java/com/djrapitops/plan/api/exceptions/ParseException.java b/Plan/src/main/java/com/djrapitops/plan/api/exceptions/ParseException.java index bb7d1555f..af1763ad6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/api/exceptions/ParseException.java +++ b/Plan/src/main/java/com/djrapitops/plan/api/exceptions/ParseException.java @@ -10,6 +10,7 @@ package main.java.com.djrapitops.plan.api.exceptions; * @author Rsl1122 */ public class ParseException extends Exception { + public ParseException(Throwable cause) { super(cause); } diff --git a/Plan/src/main/java/com/djrapitops/plan/api/exceptions/PlanEnableException.java b/Plan/src/main/java/com/djrapitops/plan/api/exceptions/PlanEnableException.java index 7c8962912..3376a5bb7 100644 --- a/Plan/src/main/java/com/djrapitops/plan/api/exceptions/PlanEnableException.java +++ b/Plan/src/main/java/com/djrapitops/plan/api/exceptions/PlanEnableException.java @@ -10,6 +10,7 @@ package main.java.com.djrapitops.plan.api.exceptions; * @author Rsl1122 */ public class PlanEnableException extends Exception { + public PlanEnableException(String message, Throwable cause) { super(message, cause); } diff --git a/Plan/src/main/java/com/djrapitops/plan/bungee/PlanBungee.java b/Plan/src/main/java/com/djrapitops/plan/bungee/PlanBungee.java index da6b62859..d0b194a95 100644 --- a/Plan/src/main/java/com/djrapitops/plan/bungee/PlanBungee.java +++ b/Plan/src/main/java/com/djrapitops/plan/bungee/PlanBungee.java @@ -42,14 +42,9 @@ public class PlanBungee extends BungeePlugin implements IPlan { private ProcessingQueue processingQueue; - public PlanBungee() { - } - @Override public void onEnable() { try { - - super.setInstance(this); super.setDebugMode(Settings.DEBUG.toString()); super.getPluginLogger().setFolder(getDataFolder()); diff --git a/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java b/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java index d20d12f0d..e29b4e3c6 100644 --- a/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java +++ b/Plan/src/main/java/com/djrapitops/plan/command/commands/RegisterCommand.java @@ -14,6 +14,8 @@ import main.java.com.djrapitops.plan.locale.Locale; import main.java.com.djrapitops.plan.locale.Msg; import main.java.com.djrapitops.plan.utilities.Check; import main.java.com.djrapitops.plan.utilities.PassEncryptUtil; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.Logger; /** * Command for registering web users. @@ -38,7 +40,7 @@ public class RegisterCommand extends SubCommand { Locale.get(Msg.CMD_USG_WEB_REGISTER).toString(), " [name] [access lvl]"); this.plugin = plugin; - + setupFilter(); } @Override @@ -133,4 +135,12 @@ public class RegisterCommand extends SubCommand { } }).runTaskAsynchronously(); } + + /** + * Setups the command console output filter + */ + private void setupFilter() { + Logger logger = (Logger) LogManager.getRootLogger(); + logger.addFilter(new RegisterCommandFilter()); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/additional/PluginData.java b/Plan/src/main/java/com/djrapitops/plan/data/additional/PluginData.java index 7967bf1bd..26b9074f2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/additional/PluginData.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/additional/PluginData.java @@ -1,6 +1,7 @@ package main.java.com.djrapitops.plan.data.additional; import main.java.com.djrapitops.plan.utilities.html.Html; +import org.apache.commons.lang3.builder.ToStringBuilder; import java.io.Serializable; import java.util.*; @@ -289,40 +290,35 @@ public abstract class PluginData { && analysisTypes.contains(AnalysisType.BOOLEAN_TOTAL); } - /** - * If a PluginData object has same placeholder, sourcePlugin and - * analysisTypes, it is considered equal. - * - * @param obj Another Object. - * @return Is current object equal to given object. - */ @Override - public final boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final PluginData other = (PluginData) obj; - return this.analysisOnly == other.analysisOnly - && Objects.equals(this.placeholder, other.placeholder) - && Objects.equals(this.sourcePlugin, other.sourcePlugin) - && Objects.equals(this.analysisTypes, other.analysisTypes); + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PluginData that = (PluginData) o; + return analysisOnly == that.analysisOnly && + Objects.equals(analysisTypes, that.analysisTypes) && + Objects.equals(placeholder, that.placeholder) && + Objects.equals(sourcePlugin, that.sourcePlugin) && + Objects.equals(icon, that.icon) && + Objects.equals(prefix, that.prefix) && + Objects.equals(suffix, that.suffix); } @Override - public final int hashCode() { - int hash = 5; - hash = 47 * hash + Objects.hashCode(this.placeholder); - hash = 47 * hash + Objects.hashCode(this.sourcePlugin); - hash = 47 * hash + (this.analysisOnly ? 1 : 0); - hash = 47 * hash + Objects.hashCode(this.prefix); - hash = 47 * hash + Objects.hashCode(this.suffix); - hash = 47 * hash + Objects.hashCode(this.analysisTypes); - return hash; + public int hashCode() { + return Objects.hash(analysisTypes, placeholder, sourcePlugin, analysisOnly, icon, prefix, suffix); + } + + @Override + public String toString() { + return new ToStringBuilder(this) + .append("analysisTypes", analysisTypes) + .append("placeholder", placeholder) + .append("sourcePlugin", sourcePlugin) + .append("analysisOnly", analysisOnly) + .append("icon", icon) + .append("prefix", prefix) + .append("suffix", suffix) + .toString(); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java b/Plan/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java index 08da3a54f..a5c29b2d2 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/time/TimeKeeper.java @@ -81,10 +81,7 @@ public abstract class TimeKeeper { if (state == null) { state = newState; } - Long currentTime = times.get(state); - if (currentTime == null) { - currentTime = 0L; - } + Long currentTime = times.getOrDefault(state, 0L); long diff = playTime - lastStateChange; times.put(state, currentTime + Math.abs(diff)); state = newState; diff --git a/Plan/src/main/java/com/djrapitops/plan/database/databases/MySQLDB.java b/Plan/src/main/java/com/djrapitops/plan/database/databases/MySQLDB.java index 92e73e7b1..7bd2eca89 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/databases/MySQLDB.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/databases/MySQLDB.java @@ -40,7 +40,7 @@ public class MySQLDB extends SQLDB { String port = config.getInt("Database.MySQL.Port").toString(); String database = config.getString("Database.MySQL.Database"); - dataSource.setUrl("jdbc:mysql://" + host + ":" + port + "/" + database + "?rewriteBatchedStatements=true"); + dataSource.setUrl("jdbc:mysql://" + host + ":" + port + "/" + database + "?rewriteBatchedStatements=true&useSSL=false"); String username = config.getString("Database.MySQL.User"); String password = config.getString("Database.MySQL.Password"); diff --git a/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java b/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java index 2f92e76b6..f53ca887c 100644 --- a/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java +++ b/Plan/src/main/java/com/djrapitops/plan/database/tables/Table.java @@ -59,16 +59,17 @@ public abstract class Table { } } - /** - * @return @throws SQLException + * @return + * @throws SQLException */ protected Connection getConnection() throws SQLException { return db.getConnection(); } /** - * @return @throws SQLException + * @return + * @throws SQLException */ public int getVersion() throws SQLException { return db.getVersion(); diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/cache/GeolocationCache.java b/Plan/src/main/java/com/djrapitops/plan/systems/cache/GeolocationCache.java index 380536c4a..3e4cc48b1 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/cache/GeolocationCache.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/cache/GeolocationCache.java @@ -2,12 +2,20 @@ package main.java.com.djrapitops.plan.systems.cache; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import main.java.com.djrapitops.plan.Log; +import com.maxmind.geoip2.DatabaseReader; +import com.maxmind.geoip2.exception.GeoIp2Exception; +import com.maxmind.geoip2.model.CountryResponse; +import com.maxmind.geoip2.record.Country; +import main.java.com.djrapitops.plan.Plan; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.MalformedURLException; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.InetAddress; import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.util.zip.GZIPInputStream; /** * This class contains the geolocation cache. @@ -21,6 +29,8 @@ import java.net.URL; */ public class GeolocationCache { + private static File geolocationDB = new File(Plan.getInstance().getDataFolder(), "GeoIP.dat"); + private static final Cache geolocationCache = CacheBuilder.newBuilder() .build(); @@ -59,39 +69,48 @@ public class GeolocationCache { /** * Retrieves the country in full length (e.g. United States) from the IP Address. *

- * This method uses the free service of freegeoip.net. The maximum amount of requests is 15.000 per hour. - * + * This product includes GeoLite2 data created by MaxMind, available from + * http://www.maxmind.com. * @param ipAddress The IP Address from which the country is retrieved * @return The name of the country in full length. *

* An exception from that rule is when the country is unknown or the retrieval of the country failed in any way, * if that happens, "Not Known" will be returned. - * @see http://freegeoip.net + * @see http://maxmind.com * @see #getCountry(String) */ private static String getUncachedCountry(String ipAddress) { - URL url; - - String urlString = "http://freegeoip.net/csv/" + ipAddress; - String unknownString = "Not Known"; - try { - url = new URL(urlString); - } catch (MalformedURLException e) { - Log.error("The URL \"" + urlString + "\" couldn't be converted to URL: " + e.getCause()); //Shouldn't ever happen - return unknownString; + checkDB(); + + try (DatabaseReader reader = new DatabaseReader.Builder(geolocationDB).build()) { + InetAddress inetAddress = InetAddress.getByName(ipAddress); + + CountryResponse response = reader.country(inetAddress); + Country country = response.getCountry(); + + return country.getName(); + } + + } catch (IOException | GeoIp2Exception e) { + return "Not Known"; + } + } + + /** + * Checks if the DB exists, if not, it downloads it + * + * @throws IOException when an error at download or saving the DB happens + */ + public static void checkDB() throws IOException { + if (geolocationDB.exists()) { + return; } - try (BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()))) { - String resultLine = in.readLine(); - Log.debug("Result for country request for " + ipAddress + ": " + resultLine); - - String[] results = resultLine.split(","); - String result = results[2]; - - return result.isEmpty() ? unknownString : result; - } catch (Exception exc) { - return unknownString; + URL downloadSite = new URL("http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz"); + try (ReadableByteChannel rbc = Channels.newChannel(new GZIPInputStream(downloadSite.openStream())); + FileOutputStream fos = new FileOutputStream(geolocationDB.getAbsoluteFile())) { + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); } } @@ -115,6 +134,9 @@ public class GeolocationCache { return geolocationCache.asMap().containsKey(ipAddress); } + /** + * Clears the cache + */ public static void clearCache() { geolocationCache.invalidateAll(); } diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/info/parsing/InspectPageParser.java b/Plan/src/main/java/com/djrapitops/plan/systems/info/parsing/InspectPageParser.java index 8abf228b4..cea543a9f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/info/parsing/InspectPageParser.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/info/parsing/InspectPageParser.java @@ -110,16 +110,8 @@ public class InspectPageParser extends PageParser { long playtimeDay = AnalysisUtils.getTotalPlaytime(sessionsDay); long playtimeWeek = AnalysisUtils.getTotalPlaytime(sessionsWeek); - if (!sessionsDay.isEmpty()) { - addValue("sessionLengthLongestDay", FormatUtils.formatTimeAmount(sessionsDay.get(0).getLength())); - } else { - addValue("sessionLengthLongestDay", "-"); - } - if (!sessionsWeek.isEmpty()) { - addValue("sessionLengthLongestWeek", FormatUtils.formatTimeAmount(sessionsWeek.get(0).getLength())); - } else { - addValue("sessionLengthLongestWeek", "-"); - } + addValue("sessionLengthLongestDay", !sessionsDay.isEmpty() ? FormatUtils.formatTimeAmount(sessionsDay.get(0).getLength()) : "-"); + addValue("sessionLengthLongestWeek", !sessionsWeek.isEmpty() ? FormatUtils.formatTimeAmount(sessionsWeek.get(0).getLength()) : "-"); addValue("sessionCountDay", sessionCountDay); addValue("sessionCountWeek", sessionCountWeek); diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/UserImportData.java b/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/UserImportData.java index e8ddfd9d5..2ec16a467 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/UserImportData.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/UserImportData.java @@ -16,7 +16,7 @@ import java.util.*; public class UserImportData { private String name; - private String uuid; + private UUID uuid; private List nicknames; private long registered; @@ -32,7 +32,7 @@ public class UserImportData { private int mobKills; private int deaths; - private UserImportData(String name, String uuid, List nicknames, long registered, boolean op, boolean banned, int timesKicked, List ips, Map worldTimes, List kills, int mobKills, int deaths) { + private UserImportData(String name, UUID uuid, List nicknames, long registered, boolean op, boolean banned, int timesKicked, List ips, Map worldTimes, List kills, int mobKills, int deaths) { this.name = name; this.uuid = uuid; this.nicknames = nicknames; @@ -59,11 +59,11 @@ public class UserImportData { this.name = name; } - public String getUuid() { + public UUID getUuid() { return uuid; } - public void setUuid(String uuid) { + public void setUuid(UUID uuid) { this.uuid = uuid; } @@ -153,7 +153,7 @@ public class UserImportData { private final Map worldTimes = new HashMap<>(); private final List kills = new ArrayList<>(); private String name; - private String uuid; + private UUID uuid; private long registered; private boolean op; private boolean banned; @@ -171,12 +171,12 @@ public class UserImportData { } public UserImportDataBuilder uuid(UUID uuid) { - return uuid(uuid.toString()); + this.uuid = uuid; + return this; } public UserImportDataBuilder uuid(String uuid) { - this.uuid = uuid; - return this; + return uuid(UUID.fromString(uuid)); } public UserImportDataBuilder registered(long registered) { diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/UserImportRefiner.java b/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/UserImportRefiner.java index 8afa969c5..56ef30e38 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/UserImportRefiner.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/UserImportRefiner.java @@ -96,17 +96,15 @@ public class UserImportRefiner { importers.parallelStream().forEach(importer -> { String name = importer.getName(); - String uuid = importer.getUuid(); + UUID uuid = importer.getUuid(); boolean nameNull = name == null; boolean uuidNull = uuid == null; if (nameNull && uuidNull) { invalidData.add(importer); - } - - if (nameNull) { - namesMissing.put(importer, uuid); + } else if (nameNull) { + namesMissing.put(importer, uuid.toString()); } else if (uuidNull) { uuidsMissing.put(importer, name); } @@ -133,7 +131,13 @@ public class UserImportRefiner { addMissingUUIDsOverFetcher(); } - foundUUIDs.entrySet().parallelStream().forEach(entry -> entry.getKey().setUuid(entry.getValue())); + foundUUIDs.entrySet().parallelStream() + .forEach(entry -> { + UserImportData userImportData = entry.getKey(); + UUID uuid = UUID.fromString(entry.getValue()); + + userImportData.setUuid(uuid); + }); importers.removeAll(uuidsMissing.keySet()); diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/importers/Importer.java b/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/importers/Importer.java index 933610a8e..cc3af4acc 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/importers/Importer.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/processing/importing/importers/Importer.java @@ -5,14 +5,25 @@ package main.java.com.djrapitops.plan.systems.processing.importing.importers; import com.djrapitops.plugin.utilities.Verify; +import com.google.common.collect.ImmutableMap; import main.java.com.djrapitops.plan.Log; import main.java.com.djrapitops.plan.Plan; +import main.java.com.djrapitops.plan.data.Session; +import main.java.com.djrapitops.plan.data.UserInfo; +import main.java.com.djrapitops.plan.data.time.WorldTimes; +import main.java.com.djrapitops.plan.database.Database; +import main.java.com.djrapitops.plan.systems.cache.GeolocationCache; import main.java.com.djrapitops.plan.systems.processing.importing.ServerImportData; import main.java.com.djrapitops.plan.systems.processing.importing.UserImportData; import main.java.com.djrapitops.plan.systems.processing.importing.UserImportRefiner; import main.java.com.djrapitops.plan.utilities.Benchmark; -import java.util.List; +import java.sql.SQLException; +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * @author Fuzzlemann @@ -26,7 +37,7 @@ public abstract class Importer { public abstract List getUserImportData(); - public final void processImport() { + public final void processImport() throws SQLException { String benchmarkName = "Import processing"; String serverBenchmarkName = "Server Data processing"; String userDataBenchmarkName = "User Data processing"; @@ -44,7 +55,7 @@ public abstract class Importer { Benchmark.stop(benchmarkName); } - private void processServerData() { + private void processServerData() throws SQLException { String benchmarkName = "Processing Server Data"; String getDataBenchmarkName = "Getting Server Data"; @@ -60,12 +71,17 @@ public abstract class Importer { return; } - //TODO + Plan plan = Plan.getInstance(); + UUID uuid = plan.getServerInfoManager().getServerUUID(); + Database db = plan.getDB(); + + db.getTpsTable().insertAllTPS(ImmutableMap.of(uuid, serverImportData.getTpsData())); + db.getCommandUseTable().insertCommandUsage(ImmutableMap.of(uuid, serverImportData.getCommandUsages())); Benchmark.start(benchmarkName); } - private void processUserData() { + private void processUserData() throws SQLException { String benchmarkName = "Processing User Data"; String getDataBenchmarkName = "Getting User Data"; @@ -81,11 +97,133 @@ public abstract class Importer { return; } - UserImportRefiner userImportRefiner = new UserImportRefiner(Plan.getInstance(), userImportData); + Plan plan = Plan.getInstance(); + + UserImportRefiner userImportRefiner = new UserImportRefiner(plan, userImportData); userImportData = userImportRefiner.refineData(); - //TODO + UUID serverUUID = plan.getServerInfoManager().getServerUUID(); + Database db = plan.getDB(); + + Set existingUUIDs = db.getSavedUUIDs(); + Map users = new Hashtable<>(); + List userInfo = new Vector<>(); + Map> nickNames = new Hashtable<>(); + Map sessions = new Hashtable<>(); + Map> ips = new Hashtable<>(); + Map timesKicked = new Hashtable<>(); + + userImportData.parallelStream().forEach(data -> { + UUID uuid = data.getUuid(); + UserInfo info = toUserInfo(data); + + if (!existingUUIDs.contains(uuid)) { + userInfo.add(info); + } + + users.put(uuid, info); + nickNames.put(uuid, data.getNicknames()); + ips.put(uuid, convertIPs(data)); + timesKicked.put(uuid, data.getTimesKicked()); + sessions.put(uuid, toSession(data)); + }); + + ExecutorService service = Executors.newCachedThreadPool(); + + db.getUsersTable().insertUsers(users); + + new ImportExecutorHelper() { + @Override + void execute() throws SQLException { + // TODO db.getSessionsTable().insertSessions(ImmutableMap.of(serverUUID, sessions)); + } + }.submit(service); + + new ImportExecutorHelper() { + @Override + void execute() throws SQLException { + db.getUsersTable().updateKicked(timesKicked); + } + }.submit(service); + + new ImportExecutorHelper() { + @Override + void execute() throws SQLException { + db.getUserInfoTable().insertUserInfo(ImmutableMap.of(serverUUID, userInfo)); + } + }.submit(service); + + new ImportExecutorHelper() { + @Override + void execute() throws SQLException { + db.getNicknamesTable().insertNicknames(ImmutableMap.of(serverUUID, nickNames)); + } + }.submit(service); + + new ImportExecutorHelper() { + @Override + void execute() throws SQLException { + db.getIpsTable().insertIPsAndGeolocations(ips); + } + }.submit(service); + + service.shutdown(); + + try { + service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + } catch (InterruptedException e) { + Log.toLog(this.getClass().getName(), e); + } Benchmark.stop(benchmarkName); } + + private UserInfo toUserInfo(UserImportData userImportData) { + UUID uuid = userImportData.getUuid(); + String name = userImportData.getName(); + long registered = userImportData.getRegistered(); + boolean op = userImportData.isOp(); + boolean banned = userImportData.isBanned(); + + return new UserInfo(uuid, name, registered, op, banned); + } + + private Session toSession(UserImportData userImportData) { + int mobKills = userImportData.getMobKills(); + int deaths = userImportData.getDeaths(); + + Session session = new Session(0, 0L, 0L, mobKills, deaths); + + session.setPlayerKills(userImportData.getKills()); + session.setWorldTimes(new WorldTimes(userImportData.getWorldTimes())); + + return session; + } + + private Map convertIPs(UserImportData userImportData) { + Map convertedIPs; + List ips = userImportData.getIps(); + + convertedIPs = ips.parallelStream() + .collect(Collectors.toMap(ip -> ip, GeolocationCache::getCountry, (a, b) -> b, HashMap::new)); + + return convertedIPs; + } + + private abstract class ImportExecutorHelper { + abstract void execute() throws SQLException; + + void submit(ExecutorService service) { + service.submit(new Runnable() { + @Override + public void run() { + try { + execute(); + } catch (SQLException e) { + Log.toLog(this.getClass().getName(), e); + } + } + }); + } + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/webapi/universal/PingWebAPI.java b/Plan/src/main/java/com/djrapitops/plan/systems/webapi/universal/PingWebAPI.java new file mode 100644 index 000000000..fcacf043d --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/systems/webapi/universal/PingWebAPI.java @@ -0,0 +1,23 @@ +/* + * 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 main.java.com.djrapitops.plan.systems.webapi.universal; + +import main.java.com.djrapitops.plan.Plan; +import main.java.com.djrapitops.plan.systems.webapi.WebAPI; +import main.java.com.djrapitops.plan.systems.webserver.PageCache; +import main.java.com.djrapitops.plan.systems.webserver.response.Response; +import main.java.com.djrapitops.plan.systems.webserver.response.api.SuccessResponse; + +import java.util.Map; + +/** + * @author Fuzzlemann + */ +public class PingWebAPI implements WebAPI { + @Override + public Response onResponse(Plan plan, Map variables) { + return PageCache.loadPage("success", SuccessResponse::new); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/systems/webserver/WebServer.java b/Plan/src/main/java/com/djrapitops/plan/systems/webserver/WebServer.java index 208c9c50d..72c0b9c2a 100644 --- a/Plan/src/main/java/com/djrapitops/plan/systems/webserver/WebServer.java +++ b/Plan/src/main/java/com/djrapitops/plan/systems/webserver/WebServer.java @@ -14,6 +14,7 @@ import main.java.com.djrapitops.plan.systems.info.InformationManager; import main.java.com.djrapitops.plan.systems.webapi.WebAPI; import main.java.com.djrapitops.plan.systems.webapi.WebAPIManager; import main.java.com.djrapitops.plan.systems.webapi.bukkit.*; +import main.java.com.djrapitops.plan.systems.webapi.universal.PingWebAPI; import main.java.com.djrapitops.plan.systems.webserver.response.*; import main.java.com.djrapitops.plan.systems.webserver.response.api.BadRequestResponse; import main.java.com.djrapitops.plan.systems.webserver.response.api.JsonResponse; @@ -72,6 +73,7 @@ public class WebServer { WebAPIManager.registerNewAPI("configure", new ConfigureWebAPI()); WebAPIManager.registerNewAPI("inspect", new InspectWebAPI()); WebAPIManager.registerNewAPI("onlineplayers", new OnlinePlayersWebAPI()); + WebAPIManager.registerNewAPI("ping", new PingWebAPI()); } /** diff --git a/Plan/test/main/java/com/djrapitops/plan/data/additional/importer/ImportBuilderTest.java b/Plan/test/main/java/com/djrapitops/plan/data/additional/importer/ImportBuilderTest.java index e9d1184e2..b0863a95b 100644 --- a/Plan/test/main/java/com/djrapitops/plan/data/additional/importer/ImportBuilderTest.java +++ b/Plan/test/main/java/com/djrapitops/plan/data/additional/importer/ImportBuilderTest.java @@ -133,7 +133,7 @@ public class ImportBuilderTest { assertEquals(3, data.getNicknames().size()); assertEquals(randomInt, data.getTimesKicked()); - assertEquals(uuid.toString(), data.getUuid()); + assertEquals(uuid, data.getUuid()); assertEquals(randomString, data.getName()); } } diff --git a/Plan/test/main/java/com/djrapitops/plan/utilities/MiscUtilsTest.java b/Plan/test/main/java/com/djrapitops/plan/utilities/MiscUtilsTest.java index 1207f6230..5b77939ad 100644 --- a/Plan/test/main/java/com/djrapitops/plan/utilities/MiscUtilsTest.java +++ b/Plan/test/main/java/com/djrapitops/plan/utilities/MiscUtilsTest.java @@ -36,7 +36,6 @@ import static org.powermock.api.mockito.PowerMockito.when; @PrepareForTest({JavaPlugin.class, Bukkit.class}) public class MiscUtilsTest { - private Plan plan; private SQLDB db; @Test @@ -152,7 +151,7 @@ public class MiscUtilsTest { TestInit.init(); TestInit t = TestInit.init(); - plan = t.getPlanMock(); + Plan plan = t.getPlanMock(); db = new SQLiteDB(plan, "debug" + MiscUtils.getTime()); db.init();