diff --git a/Plan/build.gradle b/Plan/build.gradle index bc90f4282..b7a1b8d87 100644 --- a/Plan/build.gradle +++ b/Plan/build.gradle @@ -12,7 +12,7 @@ allprojects { wrapper.gradleVersion = "5.0" group "com.djrapitops" - version "4.7.1" + version "4.7.2" test { // useJUnitPlatform() @@ -103,17 +103,17 @@ subprojects { testAnnotationProcessor "com.google.dagger:dagger-compiler:$daggerCompilerVersion" // Test Tooling Dependencies - testCompile "org.junit.jupiter:junit-jupiter-engine:5.4.0" // JUnit 5 - testCompile "org.junit.platform:junit-platform-runner:1.4.0" // JUnit 4 runner for JUnit 5 tests - testCompile "org.junit.vintage:junit-vintage-engine:5.4.0" // JUnit 4 compatibility for JUnit 5 - testCompile "org.junit.jupiter:junit-jupiter-params:5.4.0" // JUnit 5, parameterized tests - testCompile "org.mockito:mockito-core:2.25.0" // Mockito Core - testCompile "org.mockito:mockito-junit-jupiter:2.25.0" // Mockito JUnit 5 Extension + testCompile "org.junit.jupiter:junit-jupiter-engine:5.4.1" // JUnit 5 + testCompile "org.junit.platform:junit-platform-runner:1.4.1" // JUnit 4 runner for JUnit 5 tests + testCompile "org.junit.vintage:junit-vintage-engine:5.4.1" // JUnit 4 compatibility for JUnit 5 + testCompile "org.junit.jupiter:junit-jupiter-params:5.4.1" // JUnit 5, parameterized tests + testCompile "org.mockito:mockito-core:2.25.1" // Mockito Core + testCompile "org.mockito:mockito-junit-jupiter:2.25.1" // Mockito JUnit 5 Extension testCompile "org.seleniumhq.selenium:selenium-java:3.141.59" // Selenium (Browser tests) testCompile "com.jayway.awaitility:awaitility:1.7.0" // Awaitility (Concurrent wait conditions) // Testing dependencies required by Plan - testCompile "org.xerial:sqlite-jdbc:3.25.2" // SQLite + testCompile "org.xerial:sqlite-jdbc:3.27.2.1" // SQLite testCompile "mysql:mysql-connector-java:8.0.15" // MySQL } diff --git a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java index 8413b8939..dfa5627b4 100644 --- a/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java +++ b/Plan/bungeecord/src/main/java/com/djrapitops/plan/system/info/server/BungeeServerInfo.java @@ -59,7 +59,7 @@ public class BungeeServerInfo extends ServerInfo { } @Override - public Server loadServerInfo() throws EnableException { + public void loadServerInfo() throws EnableException { checkIfDefaultIP(); try { @@ -76,7 +76,6 @@ public class BungeeServerInfo extends ServerInfo { } catch (InterruptedException e) { Thread.currentThread().interrupt(); } - return server; } private void updateServerInfo(Database db) { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java index 2fd1de56b..ad95725d6 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/ManageCommand.java @@ -51,6 +51,7 @@ public class ManageCommand extends TreeCmdNode { ManageSetupCommand setupCommand, ManageConDebugCommand conDebugCommand, ManageImportCommand importCommand, + ManageExportCommand exportCommand, ManageDisableCommand disableCommand, ManageUninstalledCommand uninstalledCommand ) { @@ -72,6 +73,7 @@ public class ManageCommand extends TreeCmdNode { setupCommand, conDebugCommand, importCommand, + exportCommand, disableCommand, uninstalledCommand }; diff --git a/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageExportCommand.java b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageExportCommand.java new file mode 100644 index 000000000..d2a6fd570 --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/command/commands/manage/ManageExportCommand.java @@ -0,0 +1,157 @@ +/* + * This file is part of Player Analytics (Plan). + * + * Plan is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License v3 as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Plan is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Plan. If not, see . + */ +package com.djrapitops.plan.command.commands.manage; + +import com.djrapitops.plan.db.Database; +import com.djrapitops.plan.db.access.queries.objects.UserIdentifierQueries; +import com.djrapitops.plan.system.database.DBSystem; +import com.djrapitops.plan.system.export.HtmlExport; +import com.djrapitops.plan.system.export.JSONExport; +import com.djrapitops.plan.system.info.server.ServerInfo; +import com.djrapitops.plan.system.locale.Locale; +import com.djrapitops.plan.system.locale.lang.CmdHelpLang; +import com.djrapitops.plan.system.locale.lang.CommandLang; +import com.djrapitops.plan.system.locale.lang.DeepHelpLang; +import com.djrapitops.plan.system.locale.lang.ManageLang; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.settings.Permissions; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.settings.paths.ExportSettings; +import com.djrapitops.plugin.command.ColorScheme; +import com.djrapitops.plugin.command.CommandNode; +import com.djrapitops.plugin.command.CommandType; +import com.djrapitops.plugin.command.Sender; +import com.djrapitops.plugin.utilities.Verify; + +import javax.inject.Inject; +import javax.inject.Singleton; +import java.util.Arrays; +import java.util.Map; +import java.util.UUID; +import java.util.function.Consumer; + +/** + * This manage SubCommand is used to import data from 3rd party plugins. + * + * @author Rsl1122 + */ +@Singleton +public class ManageExportCommand extends CommandNode { + + private final Locale locale; + private final ColorScheme colorScheme; + private final PlanConfig config; + private final DBSystem dbSystem; + private final ServerInfo serverInfo; + private final HtmlExport htmlExport; + private final JSONExport jsonExport; + private final Processing processing; + + @Inject + public ManageExportCommand( + Locale locale, + ColorScheme colorScheme, + PlanConfig config, + DBSystem dbSystem, + ServerInfo serverInfo, + Processing processing, + HtmlExport htmlExport, + JSONExport jsonExport + ) { + super("export", Permissions.MANAGE.getPermission(), CommandType.CONSOLE); + + this.locale = locale; + this.colorScheme = colorScheme; + this.config = config; + this.dbSystem = dbSystem; + this.serverInfo = serverInfo; + this.htmlExport = htmlExport; + this.jsonExport = jsonExport; + this.processing = processing; + + setArguments("/list"); + setShortHelp(locale.getString(CmdHelpLang.MANAGE_EXPORT)); + setInDepthHelp(locale.getArray(DeepHelpLang.MANAGE_EXPORT)); + } + + @Override + public void onCommand(Sender sender, String commandLabel, String[] args) { + Verify.isTrue(args.length >= 1, + () -> new IllegalArgumentException(locale.getString(CommandLang.FAIL_REQ_ARGS, "1+", Arrays.toString(this.getArguments())))); + + String exportArg = args[0]; + + if ("list".equals(exportArg)) { + sender.sendMessage("> " + colorScheme.getMainColor() + "players, server_json"); + return; + } + + Database.State dbState = dbSystem.getDatabase().getState(); + if (dbState != Database.State.OPEN) { + sender.sendMessage(locale.getString(CommandLang.FAIL_DATABASE_NOT_OPEN, dbState.name())); + return; + } + + getExportFunction(exportArg).accept(sender); + } + + private Consumer getExportFunction(String exportArg) { + switch (exportArg) { + case "players": + return this::exportPlayers; + case "server_json": + return this::exportServerJSON; + default: + return sender -> sender.sendMessage(locale.getString(ManageLang.FAIL_EXPORTER_NOT_FOUND, exportArg)); + } + } + + private void exportServerJSON(Sender sender) { + sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); + processing.submitNonCritical(() -> { + jsonExport.exportServerJSON(serverInfo.getServerUUID()); + sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); + }); + } + + private void exportPlayers(Sender sender) { + sender.sendMessage(locale.getString(ManageLang.PROGRESS_START)); + if (config.get(ExportSettings.PLAYERS_PAGE)) { + processing.submitNonCritical(htmlExport::exportPlayersPage); + } + Boolean exportPlayerJSON = config.get(ExportSettings.PLAYER_JSON); + Boolean exportPlayerHTML = config.get(ExportSettings.PLAYER_PAGES); + processing.submitNonCritical(() -> { + Map players = dbSystem.getDatabase().query(UserIdentifierQueries.fetchAllPlayerNames()); + int size = players.size(); + int i = 1; + for (Map.Entry entry : players.entrySet()) { + if (exportPlayerJSON) { + jsonExport.exportPlayerJSON(entry.getKey()); + } + if (exportPlayerHTML) { + htmlExport.exportPlayerPage(entry.getKey(), entry.getValue()); + } + i++; + if (i % 1000 == 0) { + sender.sendMessage(i + " / " + size + " processed.."); + } + } + sender.sendMessage(locale.getString(ManageLang.PROGRESS_SUCCESS)); + }); + } +} diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/BaseUser.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/BaseUser.java index 0d6532cfc..b83985cc3 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/BaseUser.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/container/BaseUser.java @@ -66,14 +66,21 @@ public class BaseUser { if (this == o) return true; if (!(o instanceof BaseUser)) return false; BaseUser baseUser = (BaseUser) o; - return registered == baseUser.registered && - timesKicked == baseUser.timesKicked && - uuid.equals(baseUser.uuid) && - name.equals(baseUser.name); + return uuid.equals(baseUser.uuid) && name.equals(baseUser.name); } @Override public int hashCode() { - return Objects.hash(uuid, name, registered, timesKicked); + return Objects.hash(uuid, name); + } + + @Override + public String toString() { + return "BaseUser{" + + uuid + + ", '" + name + '\'' + + ", +" + registered + + ", kick:" + timesKicked + + '}'; } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java index f85729cab..db1ac4fed 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java @@ -21,7 +21,10 @@ import com.djrapitops.plan.data.store.keys.SessionKeys; import com.djrapitops.plan.data.store.objects.DateHolder; import com.djrapitops.plan.data.time.WorldTimes; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.UUID; /** * DataContainer for information about a player's play session. @@ -91,7 +94,7 @@ public class Session extends DynamicDataContainer implements DateHolder { */ public Session(int id, UUID uuid, UUID serverUUID, long sessionStart, long sessionEnd, int mobKills, int deaths, long afkTime) { this.sessionStart = sessionStart; - worldTimes = new WorldTimes(new HashMap<>()); + worldTimes = new WorldTimes(); playerKills = new ArrayList<>(); this.mobKills = mobKills; diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java index 8106966b7..29e81b854 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java @@ -364,7 +364,7 @@ public class AnalysisContainer extends DynamicDataContainer { private void addGraphSuppliers() { Key worldPie = new Key<>(WorldPie.class, "WORLD_PIE"); putCachingSupplier(worldPie, () -> graphs.pie().worldPie( - serverContainer.getValue(ServerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())) + serverContainer.getValue(ServerKeys.WORLD_TIMES).orElse(new WorldTimes()) )); putSupplier(AnalysisKeys.WORLD_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsSeries()); putSupplier(AnalysisKeys.GM_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsDrilldown()); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PerServerMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PerServerMutator.java index df5bde1b1..2062ac002 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PerServerMutator.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/PerServerMutator.java @@ -46,13 +46,13 @@ public class PerServerMutator { public List flatMapSessions() { return data.values().stream() .filter(container -> container.supports(PerServerKeys.SESSIONS)) - .map(container -> container.getUnsafe(PerServerKeys.SESSIONS)) + .map(container -> container.getValue(PerServerKeys.SESSIONS).orElse(Collections.emptyList())) .flatMap(Collection::stream) .collect(Collectors.toList()); } public WorldTimes flatMapWorldTimes() { - WorldTimes total = new WorldTimes(new HashMap<>()); + WorldTimes total = new WorldTimes(); for (DataContainer container : data.values()) { if (container.supports(PerServerKeys.WORLD_TIMES)) { @@ -68,7 +68,7 @@ public class PerServerMutator { Map timesMap = new HashMap<>(); for (Map.Entry entry : data.entrySet()) { DataContainer container = entry.getValue(); - timesMap.put(entry.getKey(), container.getValue(PerServerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>()))); + timesMap.put(entry.getKey(), container.getValue(PerServerKeys.WORLD_TIMES).orElse(new WorldTimes())); } return timesMap; } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java index d4a04c050..cf6328dbc 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java @@ -75,7 +75,7 @@ public class SessionsMutator { } public WorldTimes toTotalWorldTimes() { - WorldTimes total = new WorldTimes(new HashMap<>()); + WorldTimes total = new WorldTimes(); for (Session session : sessions) { session.getValue(SessionKeys.WORLD_TIMES).ifPresent(total::add); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java b/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java index 55902a718..e5bbc3741 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java @@ -54,6 +54,10 @@ public class WorldTimes { this.times = times; } + public WorldTimes() { + this(new HashMap<>()); + } + private void addWorld(String worldName, String gameMode, long changeTime) { if (worldName == null || gameMode == null) return; times.put(worldName, new GMTimes(gameMode, changeTime)); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/DataStoreQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/DataStoreQueries.java index 62705088c..a35f6aa9a 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/DataStoreQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/DataStoreQueries.java @@ -103,9 +103,9 @@ public class DataStoreQueries { statement.setString(1, session.getUnsafe(SessionKeys.UUID).toString()); statement.setLong(2, session.getUnsafe(SessionKeys.START)); statement.setLong(3, session.getUnsafe(SessionKeys.END)); - statement.setInt(4, session.getUnsafe(SessionKeys.DEATH_COUNT)); - statement.setInt(5, session.getUnsafe(SessionKeys.MOB_KILL_COUNT)); - statement.setLong(6, session.getUnsafe(SessionKeys.AFK_TIME)); + statement.setInt(4, session.getValue(SessionKeys.DEATH_COUNT).orElse(0)); + statement.setInt(5, session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0)); + statement.setLong(6, session.getValue(SessionKeys.AFK_TIME).orElse(0L)); statement.setString(7, session.getUnsafe(SessionKeys.SERVER_UUID).toString()); } }; diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeStoreQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeStoreQueries.java index 5d3bd6cee..2846e1b9c 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeStoreQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/LargeStoreQueries.java @@ -341,9 +341,9 @@ public class LargeStoreQueries { statement.setString(1, session.getUnsafe(SessionKeys.UUID).toString()); statement.setLong(2, session.getUnsafe(SessionKeys.START)); statement.setLong(3, session.getUnsafe(SessionKeys.END)); - statement.setInt(4, session.getUnsafe(SessionKeys.DEATH_COUNT)); - statement.setInt(5, session.getUnsafe(SessionKeys.MOB_KILL_COUNT)); - statement.setLong(6, session.getUnsafe(SessionKeys.AFK_TIME)); + statement.setInt(4, session.getValue(SessionKeys.DEATH_COUNT).orElse(0)); + statement.setInt(5, session.getValue(SessionKeys.MOB_KILL_COUNT).orElse(0)); + statement.setLong(6, session.getValue(SessionKeys.AFK_TIME).orElse(0L)); statement.setString(7, session.getUnsafe(SessionKeys.SERVER_UUID).toString()); statement.addBatch(); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java index 3ac493e16..2322319e6 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java @@ -63,7 +63,7 @@ public class PerServerContainerQuery implements Query { // After-values that can be calculated without database. for (DataContainer serverContainer : perServerContainer.values()) { serverContainer.putSupplier(PerServerKeys.MOB_DEATH_COUNT, () -> - serverContainer.getUnsafe(PerServerKeys.DEATH_COUNT) - serverContainer.getUnsafe(PerServerKeys.PLAYER_DEATH_COUNT) + serverContainer.getValue(PerServerKeys.DEATH_COUNT).orElse(0) - serverContainer.getValue(PerServerKeys.PLAYER_DEATH_COUNT).orElse(0) ); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PlayerContainerQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PlayerContainerQuery.java index 1850b5c14..415272f45 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PlayerContainerQuery.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PlayerContainerQuery.java @@ -19,6 +19,7 @@ package com.djrapitops.plan.db.access.queries.containers; import com.djrapitops.plan.data.container.BaseUser; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.store.Key; +import com.djrapitops.plan.data.store.containers.PerServerContainer; import com.djrapitops.plan.data.store.containers.PlayerContainer; import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.keys.SessionKeys; @@ -29,7 +30,7 @@ import com.djrapitops.plan.db.SQLDB; import com.djrapitops.plan.db.access.Query; import com.djrapitops.plan.db.access.queries.objects.*; -import java.util.HashMap; +import java.util.Collection; import java.util.List; import java.util.UUID; @@ -64,11 +65,11 @@ public class PlayerContainerQuery implements Query { container.putCachingSupplier(PlayerKeys.NICKNAMES, () -> db.query(NicknameQueries.fetchNicknameDataOfPlayer(uuid))); container.putCachingSupplier(PlayerKeys.PER_SERVER, () -> db.query(new PerServerContainerQuery(uuid))); - container.putSupplier(PlayerKeys.BANNED, () -> new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).isBanned()); - container.putSupplier(PlayerKeys.OPERATOR, () -> new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).isOperator()); + container.putSupplier(PlayerKeys.BANNED, () -> new PerServerMutator(container.getValue(PlayerKeys.PER_SERVER).orElse(new PerServerContainer())).isBanned()); + container.putSupplier(PlayerKeys.OPERATOR, () -> new PerServerMutator(container.getValue(PlayerKeys.PER_SERVER).orElse(new PerServerContainer())).isOperator()); container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { - List sessions = new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapSessions(); + List sessions = new PerServerMutator(container.getValue(PlayerKeys.PER_SERVER).orElse(new PerServerContainer())).flatMapSessions(); container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(sessions::add); return sessions; } @@ -77,7 +78,7 @@ public class PlayerContainerQuery implements Query { { WorldTimes worldTimes = db.query(WorldTimesQueries.fetchPlayerTotalWorldTimes(uuid)); container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(session -> worldTimes.add( - session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>()))) + session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes())) ); return worldTimes; }); @@ -86,7 +87,7 @@ public class PlayerContainerQuery implements Query { container.putSupplier(PlayerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList()); container.putSupplier(PlayerKeys.PLAYER_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList()); - container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PlayerKeys.PLAYER_KILLS).size()); + container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getValue(PlayerKeys.PLAYER_KILLS).map(Collection::size).orElse(0)); container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount()); container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount()); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerContainerQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerContainerQuery.java index af0620bb8..6c7411769 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerContainerQuery.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerContainerQuery.java @@ -31,6 +31,7 @@ import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionSer import com.djrapitops.plan.system.cache.SessionCache; import com.djrapitops.plan.system.info.server.Server; +import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.UUID; @@ -66,7 +67,7 @@ public class ServerContainerQuery implements Query { container.putRawData(ServerKeys.SERVER_UUID, serverUUID); container.putRawData(ServerKeys.NAME, serverInfo.get().getName()); container.putCachingSupplier(ServerKeys.PLAYERS, () -> db.query(new ServerPlayerContainersQuery(serverUUID))); - container.putSupplier(ServerKeys.PLAYER_COUNT, () -> container.getUnsafe(ServerKeys.PLAYERS).size()); + container.putSupplier(ServerKeys.PLAYER_COUNT, () -> container.getValue(ServerKeys.PLAYERS).map(Collection::size).orElse(0)); container.putCachingSupplier(ServerKeys.TPS, () -> db.query(TPSQueries.fetchTPSDataOfServer(serverUUID))); container.putCachingSupplier(ServerKeys.PING, () -> PlayersMutator.forContainer(container).pings()); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java index 1a27d83bc..d5b757e77 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java @@ -103,7 +103,7 @@ public class ServerPlayerContainersQuery implements Query> WorldTimes worldTimes = new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapWorldTimes(); container.getValue(PlayerKeys.ACTIVE_SESSION) .ifPresent(session -> worldTimes.add( - session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>()))) + session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes())) ); return worldTimes; }); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/BaseUserQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/BaseUserQueries.java index 69fc945cf..94bf82227 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/BaseUserQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/BaseUserQueries.java @@ -27,7 +27,10 @@ import com.djrapitops.plan.db.sql.tables.UsersTable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.*; +import java.util.Collection; +import java.util.HashSet; +import java.util.Optional; +import java.util.UUID; /** * Queries for {@link BaseUser} objects. @@ -126,8 +129,8 @@ public class BaseUserQueries { } @Override - public List processResults(ResultSet set) throws SQLException { - List users = new ArrayList<>(); + public Collection processResults(ResultSet set) throws SQLException { + Collection users = new HashSet<>(); while (set.next()) { UUID playerUUID = UUID.fromString(set.getString(UsersTable.USER_UUID)); String name = set.getString(UsersTable.USER_NAME); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java index 9632e4510..8f9e21046 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java @@ -214,7 +214,7 @@ public class SessionQueries { set.getLong(SessionsTable.AFK_TIME) )); - WorldTimes worldTimes = session.getUnsafe(SessionKeys.WORLD_TIMES); + WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes()); String worldName = set.getString(WorldTable.NAME); if (!worldTimes.contains(worldName)) { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WorldTimesQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WorldTimesQueries.java index 1243ba289..e1fa6ee85 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WorldTimesQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/WorldTimesQueries.java @@ -75,7 +75,7 @@ public class WorldTimesQueries { public WorldTimes processResults(ResultSet set) throws SQLException { String[] gms = GMTimes.getGMKeyArray(); - WorldTimes worldTimes = new WorldTimes(new HashMap<>()); + WorldTimes worldTimes = new WorldTimes(); while (set.next()) { String worldName = set.getString(worldColumn); @@ -110,7 +110,7 @@ public class WorldTimesQueries { public WorldTimes processResults(ResultSet set) throws SQLException { String[] gms = GMTimes.getGMKeyArray(); - WorldTimes worldTimes = new WorldTimes(new HashMap<>()); + WorldTimes worldTimes = new WorldTimes(); while (set.next()) { String worldName = set.getString(worldColumn); @@ -149,7 +149,7 @@ public class WorldTimesQueries { Map worldTimesMap = new HashMap<>(); while (set.next()) { UUID serverUUID = UUID.fromString(set.getString(WorldTimesTable.SERVER_UUID)); - WorldTimes worldTimes = worldTimesMap.getOrDefault(serverUUID, new WorldTimes(new HashMap<>())); + WorldTimes worldTimes = worldTimesMap.getOrDefault(serverUUID, new WorldTimes()); String worldName = set.getString(worldColumn); GMTimes gmTimes = extractGMTimes(set, gms); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/export/HtmlExport.java b/Plan/common/src/main/java/com/djrapitops/plan/system/export/HtmlExport.java index a41497e00..78abc8897 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/export/HtmlExport.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/export/HtmlExport.java @@ -33,6 +33,7 @@ import com.djrapitops.plan.system.settings.paths.ExportSettings; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; import com.djrapitops.plan.utilities.file.FileUtil; +import com.djrapitops.plan.utilities.html.pages.InspectPage; import com.djrapitops.plan.utilities.html.pages.PageFactory; import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.logging.L; @@ -107,7 +108,21 @@ public class HtmlExport extends SpecificExport { }); } - public void exportPlayer(UUID playerUUID) { + public void exportPlayerPage(UUID playerUUID) { + Optional name = dbSystem.getDatabase().query(UserIdentifierQueries.fetchPlayerNameOf(playerUUID)); + exportPlayerPage(playerUUID, name.orElse("Unknown")); + } + + public void exportPlayerPage(UUID playerUUID, String playerName) { + InspectPage playerPage = pageFactory.inspectPage(playerUUID); + try { + exportPlayerPage(playerName, playerPage.toHtml()); + } catch (ParseException | IOException e) { + errorHandler.log(L.ERROR, this.getClass(), e); + } + } + + public void exportCachedPlayerPage(UUID playerUUID) { if (Check.isBukkitAvailable() && connectionSystem.isServerAvailable()) { return; } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/export/JSONExport.java b/Plan/common/src/main/java/com/djrapitops/plan/system/export/JSONExport.java index 4f92cec13..805512eac 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/export/JSONExport.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/export/JSONExport.java @@ -32,6 +32,7 @@ import javax.inject.Inject; import javax.inject.Singleton; import java.io.File; import java.io.IOException; +import java.net.URLEncoder; import java.util.Collections; import java.util.UUID; @@ -77,7 +78,7 @@ public class JSONExport extends SpecificExport { try { File htmlLocation = getPlayerFolder(); htmlLocation.mkdirs(); - File exportFile = new File(htmlLocation, playerName.replace(" ", "%20").replace(".", "%2E") + ".json"); + File exportFile = new File(htmlLocation, URLEncoder.encode(playerName, "UTF-8") + ".json"); export(exportFile, Collections.singletonList(json)); } catch (IOException e) { @@ -94,7 +95,7 @@ public class JSONExport extends SpecificExport { try { File htmlLocation = getServerFolder(); htmlLocation.mkdirs(); - File exportFile = new File(htmlLocation, serverName.replace(" ", "%20").replace(".", "%2E") + ".json"); + File exportFile = new File(htmlLocation, URLEncoder.encode(serverName, "UTF-8") + ".json"); export(exportFile, Collections.singletonList(json)); } catch (IOException e) { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/export/SpecificExport.java b/Plan/common/src/main/java/com/djrapitops/plan/system/export/SpecificExport.java index 4ab72258f..a84da8e30 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/export/SpecificExport.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/export/SpecificExport.java @@ -25,6 +25,7 @@ import com.djrapitops.plugin.api.Check; import java.io.File; import java.io.IOException; +import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; @@ -89,20 +90,24 @@ public abstract class SpecificExport { return player; } - protected void exportAvailablePlayerPage(UUID uuid, String name) throws IOException { - Response response = ResponseCache.loadResponse(PageId.PLAYER.of(uuid)); + protected void exportPlayerPage(String playerName, String html) throws IOException { + List lines = Arrays.asList(html.split("\n")); + + File htmlLocation = new File(getPlayerFolder(), URLEncoder.encode(playerName, "UTF-8").replace(".", "%2E")); + htmlLocation.mkdirs(); + File exportFile = new File(htmlLocation, "index.html"); + + export(exportFile, lines); + } + + protected void exportAvailablePlayerPage(UUID playerUUID, String name) throws IOException { + Response response = ResponseCache.loadResponse(PageId.PLAYER.of(playerUUID)); if (response == null) { return; } String html = response.getContent().replace("../", "../../"); - List lines = Arrays.asList(html.split("\n")); - - File htmlLocation = new File(getPlayerFolder(), name.replace(" ", "%20").replace(".", "%2E")); - htmlLocation.mkdirs(); - File exportFile = new File(htmlLocation, "index.html"); - - export(exportFile, lines); + exportPlayerPage(name, html); } protected void exportAvailableServerPage(UUID serverUUID, String serverName) throws IOException { @@ -123,7 +128,7 @@ public abstract class SpecificExport { if (serverUUID.equals(serverInfo.getServerUUID())) { htmlLocation = new File(getFolder(), "network"); } else { - htmlLocation = new File(getServerFolder(), serverName.replace(" ", "%20").replace(".", "%2E")); + htmlLocation = new File(getServerFolder(), URLEncoder.encode(serverName, "UTF-8").replace(".", "%2E")); html = html.replace("../", "../../"); } } else { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java index ca68f796f..1d1485b78 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/info/request/CacheInspectPageRequest.java @@ -105,13 +105,13 @@ public class CacheInspectPageRequest extends InfoRequestWithVariables implements return DefaultResponses.SUCCESS.get(); } - private void cache(UUID uuid, String html) { - ResponseCache.cacheResponse(PageId.PLAYER.of(uuid), () -> new InspectPageResponse(uuid, html)); + private void cache(UUID playerUUID, String html) { + ResponseCache.cacheResponse(PageId.PLAYER.of(playerUUID), () -> new InspectPageResponse(playerUUID, html)); if (config.get(ExportSettings.PLAYER_PAGES)) { - processing.submitNonCritical(() -> htmlExport.exportPlayer(uuid)); + processing.submitNonCritical(() -> htmlExport.exportCachedPlayerPage(playerUUID)); } if (config.get(ExportSettings.PLAYER_JSON)) { - processing.submitNonCritical(() -> jsonExport.exportPlayerJSON(uuid)); + processing.submitNonCritical(() -> jsonExport.exportPlayerJSON(playerUUID)); } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java index 5e8c1113e..4bbb56980 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerInfo.java @@ -53,11 +53,11 @@ public abstract class ServerInfo implements SubSystem { @Override public void enable() throws EnableException { - server = loadServerInfo(); + loadServerInfo(); Verify.nullCheck(server, () -> new EnableException("Server information did not load!")); } - protected abstract Server loadServerInfo() throws EnableException; + protected abstract void loadServerInfo() throws EnableException; @Override public void disable() { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerServerInfo.java b/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerServerInfo.java index 4cd45feb7..0e1e004a3 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerServerInfo.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/info/server/ServerServerInfo.java @@ -23,9 +23,12 @@ import com.djrapitops.plan.db.access.queries.objects.ServerQueries; import com.djrapitops.plan.db.access.transactions.StoreServerInformationTransaction; import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.info.server.properties.ServerProperties; +import com.djrapitops.plan.system.processing.Processing; import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.settings.paths.PluginSettings; import com.djrapitops.plan.system.webserver.WebServer; +import com.djrapitops.plugin.logging.L; +import com.djrapitops.plugin.logging.error.ErrorHandler; import dagger.Lazy; import javax.inject.Inject; @@ -45,24 +48,31 @@ import java.util.concurrent.ExecutionException; @Singleton public class ServerServerInfo extends ServerInfo { - private final Lazy webServer; + private final ServerInfoFile serverInfoFile; + private final PlanConfig config; - private ServerInfoFile serverInfoFile; - private DBSystem dbSystem; + private final Processing processing; + private final DBSystem dbSystem; + private final Lazy webServer; + private final ErrorHandler errorHandler; @Inject public ServerServerInfo( ServerProperties serverProperties, ServerInfoFile serverInfoFile, + Processing processing, + PlanConfig config, DBSystem dbSystem, Lazy webServer, - PlanConfig config + ErrorHandler errorHandler ) { super(serverProperties); this.serverInfoFile = serverInfoFile; + this.processing = processing; this.dbSystem = dbSystem; this.webServer = webServer; this.config = config; + this.errorHandler = errorHandler; } @Override @@ -76,10 +86,15 @@ public class ServerServerInfo extends ServerInfo { } @Override - protected Server loadServerInfo() throws EnableException { + protected void loadServerInfo() throws EnableException { Optional serverUUID = serverInfoFile.getUUID(); try { - return serverUUID.isPresent() ? updateDbInfo(serverUUID.get()) : registerServer(); + if (serverUUID.isPresent()) { + server = createServerObject(serverUUID.get()); + processing.submitNonCritical(() -> updateDbInfo(serverUUID.get())); + } else { + server = registerServer(); + } } catch (DBOpException e) { String causeMsg = e.getMessage(); throw new EnableException("Failed to read Server information from Database: " + causeMsg, e); @@ -87,7 +102,6 @@ public class ServerServerInfo extends ServerInfo { throw new EnableException("Failed to read ServerInfoFile.yml", e); } catch (InterruptedException e) { Thread.currentThread().interrupt(); - return null; // This line is not reached due to the thread interrupt. } catch (Exception e) { throw new EnableException("Failed to perform a database transaction to store the server information", e); } @@ -98,9 +112,11 @@ public class ServerServerInfo extends ServerInfo { Optional foundServer = db.query(ServerQueries.fetchServerMatchingIdentifier(serverUUID)); if (!foundServer.isPresent()) { - return registerServer(serverUUID); + server = registerServer(serverUUID); + return; } - Server server = foundServer.get(); + + server = foundServer.get(); // Update information String name = config.get(PluginSettings.SERVER_NAME).replaceAll("[^a-zA-Z0-9_\\s]", "_"); @@ -114,7 +130,6 @@ public class ServerServerInfo extends ServerInfo { // Save db.executeTransaction(new StoreServerInformationTransaction(server)); - return server; } private Server registerServer() throws Exception { @@ -124,11 +139,7 @@ public class ServerServerInfo extends ServerInfo { private Server registerServer(UUID serverUUID) throws ExecutionException, InterruptedException, IOException { Database db = dbSystem.getDatabase(); - // Create the server object - String webAddress = webServer.get().getAccessAddress(); - String name = config.get(PluginSettings.SERVER_NAME).replaceAll("[^a-zA-Z0-9_\\s]", "_"); - int maxPlayers = serverProperties.getMaxPlayers(); - Server server = new Server(-1, serverUUID, name, webAddress, maxPlayers); + Server server = createServerObject(serverUUID); // Save db.executeTransaction(new StoreServerInformationTransaction(server)) @@ -142,4 +153,11 @@ public class ServerServerInfo extends ServerInfo { serverInfoFile.saveServerUUID(serverUUID); return server; } + + private Server createServerObject(UUID serverUUID) { + String webAddress = webServer.get().getAccessAddress(); + String name = config.get(PluginSettings.SERVER_NAME).replaceAll("[^a-zA-Z0-9_\\s]", "_"); + int maxPlayers = serverProperties.getMaxPlayers(); + return new Server(-1, serverUUID, name, webAddress, maxPlayers); + } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java index e7b55bd1c..10ff9c657 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/CmdHelpLang.java @@ -48,6 +48,7 @@ public enum CmdHelpLang implements Lang { MANAGE_CLEAR("Command Help - /plan manage clear", "Clear a Database"), MANAGE_CON("Command Help - /plan manage con", "Debug Server-Bungee connections"), MANAGE_IMPORT("Command Help - /plan manage import", "Import data from elsewhere"), + MANAGE_EXPORT("Command Help - /plan manage export", "Trigger export manually"), MANAGE_DISABLE("Command Help - /plan manage disable", "Disable a feature temporarily"), MANAGE_SETUP("Command Help - /plan manage setup", "Set-up Server-Bungee connection"), diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java index bc18e9c30..1fb60f935 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/DeepHelpLang.java @@ -41,6 +41,7 @@ public enum DeepHelpLang implements Lang { MANAGE_CON("In Depth Help - /plan manage con ?", "> §2Connection Debug Subcommand\\ Used to debug connections in the network.\\ Sends a request to each server in the database."), MANAGE_DISABLE("In Depth Help - /plan manage disable ?", "> §2Disable Subcommand\\ Can disable parts of the plugin until next reload.\\ Accepted arguments:\\ §2kickcount §fDisables kick counts in case /kickall is used on shutdown macro."), MANAGE_IMPORT("In Depth Help - /plan manage import ?", "> §2Import Subcommand\\ Import data from other sources.\\ Accepted Arguments:\\ §2offline §fBukkit player data, only register date and name."), + MANAGE_EXPORT("In Depth Help - /plan manage export ?", "> §2Export Subcommand\\ Trigger export to result folders.\\ Accepted Arguments:\\ §2list §fList possible arguments.\\ §2players §fExport /players, /player pages + /player/raw json depending on config values.\\ §2server_json §fExport /server/raw JSON if enabled in config."), MANAGE_MOVE("In Depth Help - /plan manage move ?", "> §2Move Subcommand\\ Move data from SQLite to MySQL or other way around.\\ Target database is cleared before transfer."), MANAGE_REMOVE("In Depth Help - /plan manage remove ?", "> §2Remove Subcommand\\ Remove player's data from the active database."), MANAGE_RESTORE("In Depth Help - /plan manage restore ?", "> §2Restore Subcommand\\ Restore a previous backup SQLite database (.db file)\\ You can also restore database.db from another server to MySQL.\\ Target database is cleared before transfer."), diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ManageLang.java b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ManageLang.java index 4e4bc4463..7d706ef11 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ManageLang.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/locale/lang/ManageLang.java @@ -45,6 +45,7 @@ public enum ManageLang implements Lang { FAIL_INCORRECT_DB("Manage - Fail Incorrect Database", "> §c'${0}' is not a supported database."), FAIL_FILE_NOT_FOUND("Manage - Fail File not found", "> §cNo File found at ${0}"), FAIL_IMPORTER_NOT_FOUND("Manage - Fail No Importer", "§eImporter '${0}' doesn't exist"), + FAIL_EXPORTER_NOT_FOUND("Manage - Fail No Exporter", "§eExporter '${0}' doesn't exist"), NO_SERVER("Manage - Fail No Server", "No server found with given parameters."), UNINSTALLING_SAME_SERVER("Manage - Fail Same server", "Can not mark this server as uninstalled (You are on it)"); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java index 00e9bf2cd..4331bb963 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/InfoProcessors.java @@ -16,8 +16,11 @@ */ package com.djrapitops.plan.system.processing.processors.info; +import com.djrapitops.plan.system.export.HtmlExport; +import com.djrapitops.plan.system.export.JSONExport; import com.djrapitops.plan.system.info.InfoSystem; import com.djrapitops.plan.system.info.connection.WebExceptionLogger; +import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plugin.command.Sender; import dagger.Lazy; @@ -34,14 +37,23 @@ import java.util.function.BiConsumer; @Singleton public class InfoProcessors { + private final Lazy config; + private final Lazy htmlExport; + private final Lazy jsonExport; private final Lazy infoSystem; private final Lazy webExceptionLogger; @Inject public InfoProcessors( + Lazy config, + Lazy htmlExport, + Lazy jsonExport, Lazy infoSystem, Lazy webExceptionLogger ) { + this.config = config; + this.htmlExport = htmlExport; + this.jsonExport = jsonExport; this.infoSystem = infoSystem; this.webExceptionLogger = webExceptionLogger; } @@ -58,6 +70,6 @@ public class InfoProcessors { } public PlayerPageUpdateProcessor playerPageUpdateProcessor(UUID uuid) { - return new PlayerPageUpdateProcessor(uuid); + return new PlayerPageUpdateProcessor(uuid, config.get(), htmlExport.get(), jsonExport.get()); } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java index 3e27c188f..0f80614d9 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/processing/processors/info/PlayerPageUpdateProcessor.java @@ -16,6 +16,10 @@ */ package com.djrapitops.plan.system.processing.processors.info; +import com.djrapitops.plan.system.export.HtmlExport; +import com.djrapitops.plan.system.export.JSONExport; +import com.djrapitops.plan.system.settings.config.PlanConfig; +import com.djrapitops.plan.system.settings.paths.ExportSettings; import com.djrapitops.plan.system.webserver.cache.PageId; import com.djrapitops.plan.system.webserver.cache.ResponseCache; @@ -23,16 +27,35 @@ import java.util.UUID; public class PlayerPageUpdateProcessor implements Runnable { - private final UUID uuid; + private final UUID playerUUID; + + private final PlanConfig config; + private final HtmlExport htmlExport; + private final JSONExport jsonExport; PlayerPageUpdateProcessor( - UUID uuid + UUID playerUUID, + PlanConfig config, + HtmlExport htmlExport, + JSONExport jsonExport ) { - this.uuid = uuid; + this.playerUUID = playerUUID; + this.config = config; + this.htmlExport = htmlExport; + this.jsonExport = jsonExport; } @Override public void run() { - ResponseCache.clearResponse(PageId.PLAYER.of(uuid)); + ResponseCache.clearResponse(PageId.PLAYER.of(playerUUID)); + + if (config.get(ExportSettings.EXPORT_ON_ONLINE_STATUS_CHANGE)) { + if (config.get(ExportSettings.PLAYER_JSON)) { + jsonExport.exportPlayerJSON(playerUUID); + } + if (config.get(ExportSettings.PLAYER_PAGES)) { + htmlExport.exportPlayerPage(playerUUID); + } + } } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/WorldAliasSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/WorldAliasSettings.java index 866af95c2..fab64b193 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/WorldAliasSettings.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/config/WorldAliasSettings.java @@ -165,7 +165,7 @@ public class WorldAliasSettings { if (!session.supports(SessionKeys.WORLD_TIMES)) { return "No World Time Data"; } - WorldTimes worldTimes = session.getUnsafe(SessionKeys.WORLD_TIMES); + WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes()); if (!session.supports(SessionKeys.END)) { return "Current: " + aliases.getOrDefault(worldTimes.getCurrentWorld(), "Unknown"); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ExportSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ExportSettings.java index 17cf7e851..7a10c4306 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ExportSettings.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/settings/paths/ExportSettings.java @@ -35,6 +35,7 @@ public class ExportSettings { public static final Setting PLAYERS_PAGE = new BooleanSetting("Export.Parts.Players_page"); public static final Setting SERVER_PAGE = new BooleanSetting("Export.Parts.Server_page"); public static final Setting SERVER_JSON = new BooleanSetting("Export.Parts.Server_JSON"); + public static final Setting EXPORT_ON_ONLINE_STATUS_CHANGE = new BooleanSetting("Export.Export_player_on_login_and_logout"); private ExportSettings() { /* static variable class */ diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java index 89a7f44c6..3a69977b6 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/RequestHandler.java @@ -104,7 +104,7 @@ public class RequestHandler implements HttpHandler { // Authentication failed, but was not blocked if (response instanceof PromptAuthorizationResponse) { - responseHeaders.set("WWW-Authenticate", response.getHeader("WWW-Authenticate").orElse("Basic realm=\"Plan WebUser (/plan register)\";")); + responseHeaders.set("WWW-Authenticate", response.getHeader("WWW-Authenticate").orElse("Basic realm=\"Plan WebUser (/plan register)\"")); } response.setResponseHeaders(responseHeaders); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java index 57a4ce949..69ea8a8c6 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/response/PromptAuthorizationResponse.java @@ -45,7 +45,7 @@ public class PromptAuthorizationResponse extends ErrorResponse { public static PromptAuthorizationResponse getBasicAuthResponse(VersionCheckSystem versionCheckSystem, PlanFiles files) throws IOException { PromptAuthorizationResponse response = new PromptAuthorizationResponse(versionCheckSystem, files); response.setHeader("HTTP/1.1 401 Access Denied\r\n" - + "WWW-Authenticate: Basic realm=\"Plan WebUser (/plan register)\";"); + + "WWW-Authenticate: Basic realm=\"Plan WebUser (/plan register)\""); response.setParagraph("Authentication Failed." + TIPS); response.replacePlaceholders(); @@ -69,7 +69,7 @@ public class PromptAuthorizationResponse extends ErrorResponse { } response.setHeader("HTTP/1.1 401 Access Denied\r\n" - + "WWW-Authenticate: Basic realm=\"" + failReason.getReason() + "\";"); + + "WWW-Authenticate: Basic realm=\"" + failReason.getReason() + "\""); response.setParagraph("Authentication Failed.

Reason: " + reason + "

" + TIPS); response.replacePlaceholders(); return response; diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/PlayerCalendar.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/PlayerCalendar.java index 198b6aca8..5fdd255fc 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/PlayerCalendar.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/calendar/PlayerCalendar.java @@ -118,7 +118,7 @@ public class PlayerCalendar { .orElse(System.currentTimeMillis())) .append("}"); - for (PlayerKill kill : session.getUnsafe(SessionKeys.PLAYER_KILLS)) { + for (PlayerKill kill : session.getPlayerKills()) { long time = kill.getDate(); series.append(",{title: 'Killed: ").append(kill.getVictim()) diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/PunchCard.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/PunchCard.java index 32339fa29..3cf9fca55 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/PunchCard.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/special/PunchCard.java @@ -110,7 +110,7 @@ public class PunchCard implements HighChart { private List getSessionStarts(Collection data) { return data.stream() .filter(Objects::nonNull) - .map(s -> s.getUnsafe(SessionKeys.START)) + .map(session -> session.getUnsafe(SessionKeys.START)) .sorted() .collect(Collectors.toList()); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java index c4989bdb6..a8e9eb6bd 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/pages/InspectPage.java @@ -229,7 +229,7 @@ public class InspectPage implements Page { sessionsAndPlaytime(replacer, sessionsMutator, daySessionsMutator, weekSessionsMutator, monthSessionsMutator); String punchCardData = graphs.special().punchCard(allSessions).toHighChartsSeries(); - WorldTimes worldTimes = player.getValue(PlayerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())); + WorldTimes worldTimes = player.getValue(PlayerKeys.WORLD_TIMES).orElse(new WorldTimes()); WorldPie worldPie = graphs.pie().worldPie(worldTimes); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java index 9fa72a3ca..b0ca88385 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/RecentLoginList.java @@ -25,6 +25,7 @@ import com.djrapitops.plan.utilities.comparators.SessionStartComparator; import com.djrapitops.plan.utilities.formatting.Formatter; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -85,7 +86,7 @@ public class RecentLoginList { String name = player.getUnsafe(PlayerKeys.NAME); long registerDate = player.getValue(PlayerKeys.REGISTERED).orElse(0L); - List sessions = player.getUnsafe(PlayerKeys.SESSIONS); + List sessions = player.getValue(PlayerKeys.SESSIONS).orElse(Collections.emptyList()); if (sessions.isEmpty()) { continue; } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java index 83e0da852..2f052c905 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/ServerAccordion.java @@ -33,7 +33,6 @@ import com.djrapitops.plan.utilities.html.icon.Icon; import com.djrapitops.plan.utilities.html.icon.Icons; import com.djrapitops.plugin.utilities.Format; -import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.UUID; @@ -92,7 +91,7 @@ public class ServerAccordion extends Accordion { UUID serverUUID = entry.getKey(); DataContainer container = entry.getValue(); String serverName = serverNames.getOrDefault(serverUUID, "Unknown"); - WorldTimes worldTimes = container.getValue(PerServerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())); + WorldTimes worldTimes = container.getValue(PerServerKeys.WORLD_TIMES).orElse(new WorldTimes()); SessionsMutator sessionsMutator = SessionsMutator.forContainer(container); boolean banned = container.getValue(PerServerKeys.BANNED).orElse(false); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java index ed1b1fa58..d4c57c874 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/structure/SessionAccordion.java @@ -33,7 +33,10 @@ import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; import com.djrapitops.plan.utilities.html.icon.Icons; import com.djrapitops.plan.utilities.html.tables.HtmlTables; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; import java.util.function.Supplier; /** @@ -119,7 +122,7 @@ public class SessionAccordion extends Accordion { String playerName = playerNames.getOrDefault(session.getValue(SessionKeys.UUID).orElse(null), "Unknown"); String sessionStart = yearFormatter.apply(session); - WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())); + WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes()); WorldPie worldPie = graphs.pie().worldPie(worldTimes); String longestWorldPlayed = worldAliasSettings.getLongestWorldPlayed(session); @@ -191,7 +194,7 @@ public class SessionAccordion extends Accordion { String serverName = serverNames.getOrDefault(session.getValue(SessionKeys.SERVER_UUID).orElse(null), "Unknown"); String sessionStart = yearFormatter.apply(session); - WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())); + WorldTimes worldTimes = session.getValue(SessionKeys.WORLD_TIMES).orElse(new WorldTimes()); WorldPie worldPie = graphs.pie().worldPie(worldTimes); String longestWorldPlayed = worldAliasSettings.getLongestWorldPlayed(session); diff --git a/Plan/common/src/main/resources/bungee.yml b/Plan/common/src/main/resources/bungee.yml index 99fdbfeb5..ff9e0aa2b 100644 --- a/Plan/common/src/main/resources/bungee.yml +++ b/Plan/common/src/main/resources/bungee.yml @@ -1,7 +1,7 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.PlanBungee -version: 4.7.1 +version: 4.7.2 softdepend: - AdvancedBan - LiteBans diff --git a/Plan/common/src/main/resources/bungeeconfig.yml b/Plan/common/src/main/resources/bungeeconfig.yml index 7a1620e03..7567f6e8e 100644 --- a/Plan/common/src/main/resources/bungeeconfig.yml +++ b/Plan/common/src/main/resources/bungeeconfig.yml @@ -163,6 +163,7 @@ Export: Players_page: false Server_page: false Server_JSON: false + Export_player_on_login_and_logout: false # ----------------------------------------------------- # These settings affect Plugin data integration. # If a plugin is causing issues the integration can be disabled by setting Plugin_name.Enabled: false diff --git a/Plan/common/src/main/resources/config.yml b/Plan/common/src/main/resources/config.yml index 09d96755a..30514c56a 100644 --- a/Plan/common/src/main/resources/config.yml +++ b/Plan/common/src/main/resources/config.yml @@ -176,6 +176,8 @@ Export: Players_page: false Server_page: false Server_JSON: false + # All player pages/JSON can be exported by using /plan m export players + Export_player_on_login_and_logout: false # ----------------------------------------------------- # These settings affect Plugin data integration. # If a plugin is causing issues the integration can be disabled by setting Plugin_name.Enabled: false diff --git a/Plan/common/src/main/resources/plugin.yml b/Plan/common/src/main/resources/plugin.yml index e37486753..4e96517f3 100644 --- a/Plan/common/src/main/resources/plugin.yml +++ b/Plan/common/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ name: Plan author: Rsl1122 main: com.djrapitops.plan.Plan -version: 4.7.1 +version: 4.7.2 softdepend: - EssentialsX - Towny diff --git a/Plan/common/src/test/java/com/djrapitops/plan/db/CommonDBTest.java b/Plan/common/src/test/java/com/djrapitops/plan/db/CommonDBTest.java index 1abad4963..02cf890f1 100644 --- a/Plan/common/src/test/java/com/djrapitops/plan/db/CommonDBTest.java +++ b/Plan/common/src/test/java/com/djrapitops/plan/db/CommonDBTest.java @@ -32,7 +32,9 @@ import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.db.access.Executable; import com.djrapitops.plan.db.access.Query; import com.djrapitops.plan.db.access.queries.*; +import com.djrapitops.plan.db.access.queries.containers.AllPlayerContainersQuery; import com.djrapitops.plan.db.access.queries.containers.ContainerFetchQueries; +import com.djrapitops.plan.db.access.queries.containers.ServerPlayerContainersQuery; import com.djrapitops.plan.db.access.queries.objects.*; import com.djrapitops.plan.db.access.transactions.BackupCopyTransaction; import com.djrapitops.plan.db.access.transactions.StoreConfigTransaction; @@ -73,10 +75,7 @@ import org.junit.rules.TemporaryFolder; import org.junit.rules.Timeout; import rules.ComponentMocker; import rules.PluginComponentMocker; -import utilities.FieldFetcher; -import utilities.OptionalAssert; -import utilities.RandomData; -import utilities.TestConstants; +import utilities.*; import java.io.File; import java.lang.management.ManagementFactory; @@ -769,7 +768,7 @@ public abstract class CommonDBTest { @Test public void emptyServerWorldTimesIsEmpty() { WorldTimes worldTimesOfServer = db.query(WorldTimesQueries.fetchServerTotalWorldTimes(serverUUID)); - assertEquals(new WorldTimes(new HashMap<>()), worldTimesOfServer); + assertEquals(new WorldTimes(), worldTimesOfServer); } @Test @@ -1036,6 +1035,85 @@ public abstract class CommonDBTest { assertEquals(expected, result); } + private void executeTransactions(Transaction... transactions) { + for (Transaction transaction : transactions) { + db.executeTransaction(transaction); + } + } + + @Test + public void baseUsersQueryDoesNotReturnDuplicatePlayers() { + db.executeTransaction(TestData.storeServers()); + executeTransactions(TestData.storePlayerOneData()); + executeTransactions(TestData.storePlayerTwoData()); + + Collection expected = new HashSet<>(Arrays.asList(TestData.getPlayerBaseUser(), TestData.getPlayer2BaseUser())); + Collection result = db.query(BaseUserQueries.fetchServerBaseUsers(TestConstants.SERVER_UUID)); + + assertEquals(expected, result); + + result = db.query(BaseUserQueries.fetchServerBaseUsers(TestConstants.SERVER_TWO_UUID)); + + assertEquals(expected, result); + } + + @Test + public void serverPlayerContainersQueryDoesNotReturnDuplicatePlayers() { + db.executeTransaction(TestData.storeServers()); + executeTransactions(TestData.storePlayerOneData()); + executeTransactions(TestData.storePlayerTwoData()); + + List expected = Arrays.asList(playerUUID, player2UUID); + Collections.sort(expected); + + Collection result = db.query(new ServerPlayerContainersQuery(TestConstants.SERVER_UUID)) + .stream().map(player -> player.getUnsafe(PlayerKeys.UUID)) + .sorted() + .collect(Collectors.toList()); + + assertEquals(expected, result); + } + + @Test + public void allPlayerContainersQueryDoesNotReturnDuplicatePlayers() { + db.executeTransaction(TestData.storeServers()); + executeTransactions(TestData.storePlayerOneData()); + executeTransactions(TestData.storePlayerTwoData()); + + List expected = Arrays.asList(playerUUID, player2UUID); + Collections.sort(expected); + + Collection result = db.query(new AllPlayerContainersQuery()) + .stream().map(player -> player.getUnsafe(PlayerKeys.UUID)) + .sorted() + .collect(Collectors.toList()); + + assertEquals(expected, result); + } + + // This test is against issue https://github.com/Rsl1122/Plan-PlayerAnalytics/issues/956 + @Test + public void analysisContainerPlayerNamesAreCollectedFromBaseUsersCorrectly() { + db.executeTransaction(TestData.storeServers()); + executeTransactions(TestData.storePlayerOneData()); + executeTransactions(TestData.storePlayerTwoData()); + + BaseUser playerBaseUser = TestData.getPlayerBaseUser(); + BaseUser player2BaseUser = TestData.getPlayer2BaseUser(); + + AnalysisContainer.Factory factory = constructAnalysisContainerFactory(); + AnalysisContainer analysisContainer = factory.forServerContainer( + db.query(ContainerFetchQueries.fetchServerContainer(TestConstants.SERVER_UUID)) + ); + + Map expected = new HashMap<>(); + expected.put(playerBaseUser.getUuid(), playerBaseUser.getName()); + expected.put(player2BaseUser.getUuid(), player2BaseUser.getName()); + Map result = analysisContainer.getValue(AnalysisKeys.PLAYER_NAMES).orElseThrow(AssertionError::new); + + assertEquals(expected, result); + } + @Test public void extensionPlayerValuesAreStored() { ExtensionServiceImplementation extensionService = (ExtensionServiceImplementation) system.getExtensionService(); @@ -1241,5 +1319,4 @@ public abstract class CommonDBTest { public String stringVal(UUID playerUUID) { return "Something"; } - } } diff --git a/Plan/common/src/test/java/utilities/TestConstants.java b/Plan/common/src/test/java/utilities/TestConstants.java index bb94d5aac..7acb2654f 100644 --- a/Plan/common/src/test/java/utilities/TestConstants.java +++ b/Plan/common/src/test/java/utilities/TestConstants.java @@ -26,10 +26,12 @@ import java.util.UUID; public class TestConstants { public static final UUID SERVER_UUID = UUID.fromString("e4ec2edd-e0ed-3c58-a87d-8a9021899479"); + public static final UUID SERVER_TWO_UUID = UUID.fromString("c4ec2edd-e0ed-3c58-a87d-8a9024791899"); public static final UUID PLAYER_ONE_UUID = UUID.fromString("45b0dfdb-f71d-4cf3-8c21-27c9d4c651db"); public static final UUID PLAYER_TWO_UUID = UUID.fromString("ec94a954-1fa1-445b-b09b-9b698519af80"); public static final String PLAYER_ONE_NAME = "Test_Player_one"; + public static final String PLAYER_TWO_NAME = "Test_Player_two"; public static final String WORLD_ONE_NAME = "World One"; diff --git a/Plan/common/src/test/java/utilities/TestData.java b/Plan/common/src/test/java/utilities/TestData.java new file mode 100644 index 000000000..d1e106cae --- /dev/null +++ b/Plan/common/src/test/java/utilities/TestData.java @@ -0,0 +1,190 @@ +/* + * This file is part of Player Analytics (Plan). + * + * Plan is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License v3 as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Plan is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Plan. If not, see . + */ +package utilities; + +import com.djrapitops.plan.data.container.BaseUser; +import com.djrapitops.plan.data.container.GeoInfo; +import com.djrapitops.plan.data.container.PlayerKill; +import com.djrapitops.plan.data.container.Session; +import com.djrapitops.plan.data.time.GMTimes; +import com.djrapitops.plan.db.access.transactions.StoreServerInformationTransaction; +import com.djrapitops.plan.db.access.transactions.Transaction; +import com.djrapitops.plan.db.access.transactions.events.*; +import com.djrapitops.plan.system.info.server.Server; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Class for saving test data to a database. + * + * @author Rsl1122 + */ +public class TestData { + + private static UUID playerUUID = TestConstants.PLAYER_ONE_UUID; + private static UUID player2UUID = TestConstants.PLAYER_TWO_UUID; + private static UUID serverUUID = TestConstants.SERVER_UUID; + private static UUID server2UUID = TestConstants.SERVER_TWO_UUID; + private static String playerName = TestConstants.PLAYER_ONE_NAME; + private static String player2Name = TestConstants.PLAYER_TWO_NAME; + + private static String[] serverWorldNames = new String[]{ + TestConstants.WORLD_ONE_NAME, "World Two", "world" + }; + private static String[] server2WorldNames = new String[]{ + "Foo", "Bar", "Z" + }; + + private static long playerFirstJoin = 1234500L; + private static long playerSecondJoin = 234000L; + + private static List playerSessions = createSessionsForPlayer(playerUUID); + private static List player2Sessions = createSessionsForPlayer(player2UUID); + + private static List playerGeoInfo = createGeoInfoForPlayer(); + + private static List createGeoInfoForPlayer() { + List geoInfos = new ArrayList<>(); + + try { + geoInfos.add(new GeoInfo(InetAddress.getByName("1.2.3.4"), "Not Known", playerFirstJoin)); + geoInfos.add(new GeoInfo(InetAddress.getByName("43b9:416b:3cb2:649d:ebaf:872:d89a:343d"), "Not Known", playerFirstJoin)); + geoInfos.add(new GeoInfo(InetAddress.getByName("127.0.0.1"), "Local Machine", playerFirstJoin)); + geoInfos.add(new GeoInfo(InetAddress.getByName("181.103.227.78"), "Argentina", playerFirstJoin)); + } catch (UnknownHostException | NoSuchAlgorithmException e) { + Logger.getGlobal().log(Level.WARNING, e, () -> "Failed to create GeoInfo"); + } + + return geoInfos; + } + + private static List createSessionsForPlayer(UUID uuid) { + List sessions = new ArrayList<>(); + + String[] gms = GMTimes.getGMKeyArray(); + + Session sessionOne = new Session(uuid, serverUUID, playerFirstJoin, serverWorldNames[0], gms[0]); + + UUID otherUUID = uuid.equals(playerUUID) ? player2UUID : playerUUID; + sessionOne.playerKilled(new PlayerKill(otherUUID, "Iron Sword", 1234750L)); + sessionOne.playerKilled(new PlayerKill(otherUUID, "Gold Sword", 1234800L)); + + sessionOne.endSession(1235000L); // Length 500ms + sessions.add(sessionOne); + + Session sessionTwo = new Session(uuid, server2UUID, playerSecondJoin, server2WorldNames[0], gms[1]); + sessionTwo.changeState(server2WorldNames[1], gms[0], 334000L); // Length 100s + sessionTwo.endSession(434000L); // Length 200s + sessions.add(sessionTwo); + + return sessions; + } + + public static Transaction storeServers() { + return new Transaction() { + @Override + protected void performOperations() { + executeOther(new StoreServerInformationTransaction(new Server(-1, serverUUID, "Server 1", "", 20))); + executeOther(new StoreServerInformationTransaction(new Server(-1, server2UUID, "Server 2", "", 50))); + + for (String worldName : serverWorldNames) { + executeOther(new WorldNameStoreTransaction(serverUUID, worldName)); + } + for (String worldName : server2WorldNames) { + executeOther(new WorldNameStoreTransaction(server2UUID, worldName)); + } + } + }; + } + + public static Transaction[] storePlayerOneData() { + return new Transaction[]{ + new PlayerRegisterTransaction(playerUUID, () -> playerFirstJoin, playerName), + new Transaction() { + @Override + protected void performOperations() { + executeOther(new PlayerServerRegisterTransaction(playerUUID, () -> playerFirstJoin, playerName, serverUUID)); + executeOther(new PlayerServerRegisterTransaction(playerUUID, () -> playerSecondJoin, playerName, server2UUID)); + + for (GeoInfo geoInfo : playerGeoInfo) { + executeOther(new GeoInfoStoreTransaction(playerUUID, geoInfo)); + } + + for (Session session : playerSessions) { + executeOther(new SessionEndTransaction(session)); + } + } + } + }; + } + + public static Transaction[] storePlayerTwoData() { + return new Transaction[]{ + new PlayerRegisterTransaction(player2UUID, () -> playerFirstJoin, player2Name), + new Transaction() { + @Override + protected void performOperations() { + executeOther(new PlayerServerRegisterTransaction(player2UUID, () -> playerFirstJoin, player2Name, serverUUID)); + executeOther(new PlayerServerRegisterTransaction(player2UUID, () -> playerSecondJoin, player2Name, server2UUID)); + + for (GeoInfo geoInfo : playerGeoInfo) { + executeOther(new GeoInfoStoreTransaction(player2UUID, geoInfo)); + } + + for (Session session : player2Sessions) { + executeOther(new SessionEndTransaction(session)); + } + } + } + }; + } + + public static String[] getServerWorldNames() { + return serverWorldNames; + } + + public static String[] getServer2WorldNames() { + return server2WorldNames; + } + + public static List getPlayerSessions() { + return playerSessions; + } + + public static List getPlayer2Sessions() { + return player2Sessions; + } + + public static List getPlayerGeoInfo() { + return playerGeoInfo; + } + + public static BaseUser getPlayerBaseUser() { + return new BaseUser(playerUUID, playerName, playerFirstJoin, 0); + } + + public static BaseUser getPlayer2BaseUser() { + return new BaseUser(player2UUID, player2Name, playerFirstJoin, 0); + } +} \ No newline at end of file diff --git a/Plan/sponge/src/main/java/com/djrapitops/plan/PlanSponge.java b/Plan/sponge/src/main/java/com/djrapitops/plan/PlanSponge.java index 127a09ab4..f86998654 100644 --- a/Plan/sponge/src/main/java/com/djrapitops/plan/PlanSponge.java +++ b/Plan/sponge/src/main/java/com/djrapitops/plan/PlanSponge.java @@ -42,7 +42,7 @@ import java.io.InputStream; @Plugin( id = "plan", name = "Plan", - version = "4.7.1", + version = "4.7.2", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"}, dependencies = { diff --git a/Plan/velocity/src/main/java/com/djrapitops/plan/PlanVelocity.java b/Plan/velocity/src/main/java/com/djrapitops/plan/PlanVelocity.java index 052da5e00..9a2ad8894 100644 --- a/Plan/velocity/src/main/java/com/djrapitops/plan/PlanVelocity.java +++ b/Plan/velocity/src/main/java/com/djrapitops/plan/PlanVelocity.java @@ -46,7 +46,7 @@ import java.nio.file.Path; @Plugin( id = "plan", name = "Plan", - version = "4.7.1", + version = "4.7.2", description = "Player Analytics Plugin by Rsl1122", authors = {"Rsl1122"} ) diff --git a/Plan/velocity/src/main/java/com/djrapitops/plan/system/info/server/VelocityServerInfo.java b/Plan/velocity/src/main/java/com/djrapitops/plan/system/info/server/VelocityServerInfo.java index 8ac96a8f4..04f82ca65 100644 --- a/Plan/velocity/src/main/java/com/djrapitops/plan/system/info/server/VelocityServerInfo.java +++ b/Plan/velocity/src/main/java/com/djrapitops/plan/system/info/server/VelocityServerInfo.java @@ -59,7 +59,7 @@ public class VelocityServerInfo extends ServerInfo { } @Override - public Server loadServerInfo() throws EnableException { + public void loadServerInfo() throws EnableException { checkIfDefaultIP(); try { @@ -76,7 +76,6 @@ public class VelocityServerInfo extends ServerInfo { } catch (InterruptedException e) { Thread.currentThread().interrupt(); } - return server; } private void updateServerInfo(Database db) { diff --git a/PlanPluginBridge/pom.xml b/PlanPluginBridge/pom.xml index 5342ffe3f..cf17561ed 100644 --- a/PlanPluginBridge/pom.xml +++ b/PlanPluginBridge/pom.xml @@ -180,7 +180,7 @@ io.github.nucleuspowered nucleus-api - 1.9.0-S7.1 + 1.9.2-S7.1 provided