Merge branch 'development' into extension-api

This commit is contained in:
Rsl1122 2019-03-06 15:58:19 +02:00
commit b5bf859b78
16 changed files with 221 additions and 28 deletions

View File

@ -12,7 +12,7 @@ allprojects {
wrapper.gradleVersion = "5.0"
group "com.djrapitops"
version "4.7.0"
version "4.7.1"
test {
// useJUnitPlatform()
@ -107,8 +107,8 @@ subprojects {
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.24.5" // Mockito Core
testCompile "org.mockito:mockito-junit-jupiter:2.24.5" // Mockito JUnit 5 Extension
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.seleniumhq.selenium:selenium-java:3.141.59" // Selenium (Browser tests)
testCompile "com.jayway.awaitility:awaitility:1.7.0" // Awaitility (Concurrent wait conditions)

View File

@ -60,11 +60,12 @@ public class PerServerContainer extends HashMap<UUID, DataContainer> {
container.putSupplier(PerServerKeys.WORLD_TIMES, () -> SessionsMutator.forContainer(container).toTotalWorldTimes());
container.putSupplier(PerServerKeys.PLAYER_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList());
container.putSupplier(PerServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
container.putSupplier(PerServerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PerServerKeys.PLAYER_KILLS).size());
container.putSupplier(PerServerKeys.PLAYER_KILL_COUNT, () -> container.getValue(PerServerKeys.PLAYER_KILLS).map(Collection::size).orElse(0));
container.putSupplier(PerServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
container.putSupplier(PerServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
container.putSupplier(PerServerKeys.PLAYER_DEATH_COUNT, () -> SessionsMutator.forContainer(container).toPlayerDeathCount());
container.putSupplier(PerServerKeys.MOB_DEATH_COUNT, () ->
container.getUnsafe(PerServerKeys.DEATH_COUNT) - container.getUnsafe(PerServerKeys.PLAYER_DEATH_COUNT)
container.getValue(PerServerKeys.DEATH_COUNT).orElse(0) - container.getValue(PerServerKeys.PLAYER_DEATH_COUNT).orElse(0)
);
}
}

View File

@ -96,11 +96,12 @@ public class AllPlayerContainersQuery implements Query<List<PlayerContainer>> {
container.putSupplier(PerServerKeys.WORLD_TIMES, () -> SessionsMutator.forContainer(container).toTotalWorldTimes());
container.putSupplier(PerServerKeys.PLAYER_DEATHS, () -> SessionsMutator.forContainer(container).toPlayerDeathList());
container.putSupplier(PerServerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
container.putSupplier(PerServerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PerServerKeys.PLAYER_KILLS).size());
container.putSupplier(PerServerKeys.PLAYER_KILL_COUNT, () -> container.getValue(PerServerKeys.PLAYER_KILLS).map(Collection::size).orElse(0));
container.putSupplier(PerServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
container.putSupplier(PerServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
container.putSupplier(PerServerKeys.PLAYER_DEATH_COUNT, () -> SessionsMutator.forContainer(container).toPlayerDeathCount());
container.putSupplier(PerServerKeys.MOB_DEATH_COUNT, () ->
container.getUnsafe(PerServerKeys.DEATH_COUNT) - container.getUnsafe(PerServerKeys.PLAYER_DEATH_COUNT)
container.getValue(PerServerKeys.DEATH_COUNT).orElse(0) - container.getValue(PerServerKeys.PLAYER_DEATH_COUNT).orElse(0)
);
perServerContainer.put(serverUUID, container);
perServerContainers.put(playerUUID, perServerContainer);

View File

@ -40,15 +40,14 @@ import static com.djrapitops.plan.db.sql.parsing.Sql.*;
public class WorldTimesQueries {
private static String worldColumn = "world";
private static final String SELECT_WORLD_TIMES_JOIN_WORLD_NAME = WorldTable.TABLE_NAME + "." + WorldTable.NAME + " as " + worldColumn +
FROM + WorldTimesTable.TABLE_NAME +
INNER_JOIN + WorldTable.TABLE_NAME + " on " + WorldTable.TABLE_NAME + "." + WorldTable.ID + "=" + WorldTimesTable.WORLD_ID;
private static final String SELECT_WORLD_TIMES_STATEMENT_START = SELECT +
"SUM(" + WorldTimesTable.SURVIVAL + ") as survival, " +
"SUM(" + WorldTimesTable.CREATIVE + ") as creative, " +
"SUM(" + WorldTimesTable.ADVENTURE + ") as adventure, " +
"SUM(" + WorldTimesTable.SPECTATOR + ") as spectator, " +
WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.SERVER_UUID + ", " +
WorldTable.TABLE_NAME + "." + WorldTable.NAME + " as " + worldColumn +
FROM + WorldTimesTable.TABLE_NAME +
" INNER JOIN " + WorldTable.TABLE_NAME + " on " + WorldTable.TABLE_NAME + "." + WorldTable.ID + "=" + WorldTimesTable.WORLD_ID;
"SUM(" + WorldTimesTable.SPECTATOR + ") as spectator, ";
private WorldTimesQueries() {
/* Static method class */
@ -62,6 +61,7 @@ public class WorldTimesQueries {
*/
public static Query<WorldTimes> fetchServerTotalWorldTimes(UUID serverUUID) {
String sql = SELECT_WORLD_TIMES_STATEMENT_START +
SELECT_WORLD_TIMES_JOIN_WORLD_NAME +
WHERE + WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.SERVER_UUID + "=?" +
GROUP_BY + worldColumn;
@ -96,6 +96,7 @@ public class WorldTimesQueries {
*/
public static Query<WorldTimes> fetchPlayerTotalWorldTimes(UUID playerUUID) {
String sql = SELECT_WORLD_TIMES_STATEMENT_START +
SELECT_WORLD_TIMES_JOIN_WORLD_NAME +
WHERE + WorldTimesTable.USER_UUID + "=?" +
GROUP_BY + worldColumn;
@ -130,6 +131,8 @@ public class WorldTimesQueries {
*/
public static Query<Map<UUID, WorldTimes>> fetchPlayerWorldTimesOnServers(UUID playerUUID) {
String sql = SELECT_WORLD_TIMES_STATEMENT_START +
WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.SERVER_UUID + ", " +
SELECT_WORLD_TIMES_JOIN_WORLD_NAME +
WHERE + WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.USER_UUID + "=?" +
GROUP_BY + worldColumn + ", " + WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.SERVER_UUID;

View File

@ -23,7 +23,6 @@ import org.apache.commons.text.TextStringBuilder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* World Map that uses iso-a3 specification of Country codes.
@ -59,8 +58,19 @@ public class WorldMap implements HighChart {
private Map<String, Integer> toGeoCodeCounts(Map<String, Integer> geolocationCounts) {
Map<String, String> geoCodes = getGeoCodes();
return geolocationCounts.entrySet().stream()
.collect(Collectors.toMap(entry -> geoCodes.get(entry.getKey().toLowerCase()), Map.Entry::getValue));
Map<String, Integer> geoCodeCounts = new HashMap<>();
for (Map.Entry<String, Integer> entry : geolocationCounts.entrySet()) {
String geolocation = entry.getKey().toLowerCase();
String geoCode = geoCodes.get(geolocation);
if (geoCode == null) {
continue;
}
geoCodeCounts.put(geoCode, entry.getValue());
}
return geoCodeCounts;
}
private Map<String, Integer> toGeoCodeCounts(List<String> geoLocations) {

View File

@ -1,7 +1,7 @@
name: Plan
author: Rsl1122
main: com.djrapitops.plan.PlanBungee
version: 4.7.0
version: 4.7.1
softdepend:
- AdvancedBan
- LiteBans

View File

@ -1,7 +1,7 @@
name: Plan
author: Rsl1122
main: com.djrapitops.plan.Plan
version: 4.7.0
version: 4.7.1
softdepend:
- EssentialsX
- Towny

View File

@ -711,7 +711,7 @@ public abstract class CommonDBTest {
}
@Test
public void testSaveSessionsWorldTimes() {
public void worldTimesAreSavedWithSession() {
saveTwoWorlds();
saveUserOne();
@ -733,21 +733,21 @@ public abstract class CommonDBTest {
}
@Test
public void testGetUserWorldTimes() {
testSaveSessionsWorldTimes();
public void playersWorldTimesMatchTotal() {
worldTimesAreSavedWithSession();
WorldTimes worldTimesOfUser = db.query(WorldTimesQueries.fetchPlayerTotalWorldTimes(playerUUID));
assertEquals(createWorldTimes(), worldTimesOfUser);
}
@Test
public void testGetServerWorldTimes() {
testSaveSessionsWorldTimes();
public void serverWorldTimesMatchTotal() {
worldTimesAreSavedWithSession();
WorldTimes worldTimesOfServer = db.query(WorldTimesQueries.fetchServerTotalWorldTimes(serverUUID));
assertEquals(createWorldTimes(), worldTimesOfServer);
}
@Test
public void testGetServerWorldTimesNoSessions() {
public void emptyServerWorldTimesIsEmpty() {
WorldTimes worldTimesOfServer = db.query(WorldTimesQueries.fetchServerTotalWorldTimes(serverUUID));
assertEquals(new WorldTimes(new HashMap<>()), worldTimesOfServer);
}

View File

@ -75,6 +75,9 @@ public class MySQLTest extends CommonDBTest {
UUID firstUuid = UUID.randomUUID();
UUID secondUuid = UUID.randomUUID();
UUID thirdUuid = UUID.randomUUID();
UUID fourthUuid = UUID.randomUUID();
UUID fifthUuid = UUID.randomUUID();
UUID sixthUuid = UUID.randomUUID();
db.executeTransaction(new PlayerRegisterTransaction(firstUuid, () -> 0L, ""));
db.executeTransaction(new PlayerRegisterTransaction(secondUuid, () -> 0L, ""));
@ -84,6 +87,9 @@ public class MySQLTest extends CommonDBTest {
saveGeoInfo(firstUuid, new GeoInfo("-", "Finland", 5, "3"));
saveGeoInfo(secondUuid, new GeoInfo("-", "Sweden", 0, "3"));
saveGeoInfo(thirdUuid, new GeoInfo("-", "Denmark", 0, "3"));
saveGeoInfo(fourthUuid, new GeoInfo("-", "Denmark", 0, "3"));
saveGeoInfo(fifthUuid, new GeoInfo("-", "Not Known", 0, "3"));
saveGeoInfo(sixthUuid, new GeoInfo("-", "Local Machine", 0, "3"));
Map<String, Integer> got = db.query(ServerAggregateQueries.networkGeolocationCounts());
@ -91,7 +97,9 @@ public class MySQLTest extends CommonDBTest {
// first user has a more recent connection from Finland so their country should be counted as Finland.
expected.put("Finland", 1);
expected.put("Sweden", 1);
expected.put("Denmark", 1);
expected.put("Not Known", 1);
expected.put("Local Machine", 1);
expected.put("Denmark", 2);
assertEquals(expected, got);
}

View File

@ -92,6 +92,9 @@ public class SQLiteTest extends CommonDBTest {
UUID firstUuid = UUID.randomUUID();
UUID secondUuid = UUID.randomUUID();
UUID thirdUuid = UUID.randomUUID();
UUID fourthUuid = UUID.randomUUID();
UUID fifthUuid = UUID.randomUUID();
UUID sixthUuid = UUID.randomUUID();
db.executeTransaction(new PlayerRegisterTransaction(firstUuid, () -> 0L, ""));
db.executeTransaction(new PlayerRegisterTransaction(secondUuid, () -> 0L, ""));
@ -101,6 +104,9 @@ public class SQLiteTest extends CommonDBTest {
saveGeoInfo(firstUuid, new GeoInfo("-", "Finland", 5, "3"));
saveGeoInfo(secondUuid, new GeoInfo("-", "Sweden", 0, "3"));
saveGeoInfo(thirdUuid, new GeoInfo("-", "Denmark", 0, "3"));
saveGeoInfo(fourthUuid, new GeoInfo("-", "Denmark", 0, "3"));
saveGeoInfo(fifthUuid, new GeoInfo("-", "Not Known", 0, "3"));
saveGeoInfo(sixthUuid, new GeoInfo("-", "Local Machine", 0, "3"));
Map<String, Integer> got = db.query(ServerAggregateQueries.networkGeolocationCounts());
@ -108,7 +114,9 @@ public class SQLiteTest extends CommonDBTest {
// first user has a more recent connection from Finland so their country should be counted as Finland.
expected.put("Finland", 1);
expected.put("Sweden", 1);
expected.put("Denmark", 1);
expected.put("Not Known", 1);
expected.put("Local Machine", 1);
expected.put("Denmark", 2);
assertEquals(expected, got);
}

View File

@ -0,0 +1,110 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.system.info.request;
import com.djrapitops.plan.api.exceptions.connection.WebException;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.db.Database;
import com.djrapitops.plan.db.access.transactions.events.PlayerRegisterTransaction;
import com.djrapitops.plan.db.access.transactions.events.SessionEndTransaction;
import com.djrapitops.plan.db.access.transactions.events.WorldNameStoreTransaction;
import com.djrapitops.plan.system.PlanSystem;
import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.ExportSettings;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import utilities.TestConstants;
import utilities.dagger.DaggerPlanPluginComponent;
import utilities.dagger.PlanPluginComponent;
import utilities.mocks.PlanPluginMocker;
import java.io.File;
import java.nio.file.Path;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test against Server JSON Export errors.
*
* @author Rsl1122
*/
class AnalysisExportTest {
private PlanSystem system;
@BeforeEach
void setupPlanSystem(@TempDir Path dir) throws Exception {
PlanPluginComponent component = DaggerPlanPluginComponent.builder().plan(PlanPluginMocker.setUp()
.withDataFolder(dir.toFile()).withLogging()
.withResourceFetchingFromJar()
.getPlanMock()
).build();
system = component.system();
PlanConfig config = system.getConfigSystem().getConfig();
config.set(ExportSettings.JSON_EXPORT_PATH, "Test");
config.set(ExportSettings.SERVER_JSON, true);
system.enable();
Database database = system.getDatabaseSystem().getDatabase();
storeSomeData(database);
}
private void storeSomeData(Database database) {
UUID uuid = TestConstants.PLAYER_ONE_UUID;
database.executeTransaction(new PlayerRegisterTransaction(uuid, () -> 1000L, "name"));
Session session = new Session(uuid, TestConstants.SERVER_UUID, 1000L, "world", "SURVIVAL");
session.endSession(11000L);
database.executeTransaction(new WorldNameStoreTransaction(TestConstants.SERVER_UUID, "world"));
database.executeTransaction(new SessionEndTransaction(session));
}
@AfterEach
void tearDownSystem() {
system.disable();
}
@Test
void serverJSONIsExported() throws WebException {
system.getInfoSystem().generateAnalysisPage(TestConstants.SERVER_UUID);
File exportFolder = system.getPlanFiles().getFileFromPluginFolder("Test");
File[] folders = exportFolder.listFiles();
assertNotNull(folders);
boolean found = false;
for (File folder : folders) {
if (folder.isFile()) {
continue;
}
if (folder.getName().equals("server")) {
for (File file : folder.listFiles()) {
if (file.getName().contains("Test.json")) {
found = true;
}
}
}
}
assertTrue(found);
}
}

View File

@ -0,0 +1,50 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.utilities.html.graphs.special;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* Test against exceptions due to unnamed geolocations.
*
* @author Rsl1122
*/
@RunWith(JUnitPlatform.class)
class WorldMapTest {
@Test
void toGeolocationCountsCausesNoException() {
Map<String, Integer> geolocations = new HashMap<>();
geolocations.put("Finland", 1);
geolocations.put("Sweden", 1);
geolocations.put("Not Known", 1);
geolocations.put("Local Machine", 1);
geolocations.put("Denmark", 2);
String expected = "[{'code':'SWE','value':1},{'code':'DNK','value':2},{'code':'FIN','value':1}]";
String result = new WorldMap(geolocations).toHighChartsSeries();
assertEquals(expected, result);
}
}

View File

@ -42,7 +42,7 @@ import java.io.InputStream;
@Plugin(
id = "plan",
name = "Plan",
version = "4.7.0",
version = "4.7.1",
description = "Player Analytics Plugin by Rsl1122",
authors = {"Rsl1122"},
dependencies = {

View File

@ -46,7 +46,7 @@ import java.nio.file.Path;
@Plugin(
id = "plan",
name = "Plan",
version = "4.7.0",
version = "4.7.1",
description = "Player Analytics Plugin by Rsl1122",
authors = {"Rsl1122"}
)

View File

@ -180,7 +180,7 @@
<dependency>
<groupId>io.github.nucleuspowered</groupId>
<artifactId>nucleus-api</artifactId>
<version>1.8.3-S7.1</version>
<version>1.9.0-S7.1</version>
<scope>provided</scope>
</dependency>
<dependency> <!-- Maven Central -->

View File

@ -1,3 +1,5 @@
REL|4.7.1|https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/download/4.7.1/Plan-4.7.1.jar|https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/tag/4.7.1
DEV|4.7.0-b1|https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/download/4.7.1-DEV1/Plan-4.7.1-SNAPSHOT-b1.jar|https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/tag/4.7.1-DEV1
REL|4.7.0|https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/download/4.7.0/Plan-4.7.0.jar|https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/tag/4.7.0
DEV|4.6.2-b3|https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/download/4.7.0-DEV3/Plan-4.7.0-SNAPSHOT-b3.jar|https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/tag/4.7.0-DEV3
DEV|4.6.2-b2|https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/download/4.7.0-DEV2/Plan-4.7.0-SNAPSHOT-b2.jar|https://github.com/Rsl1122/Plan-PlayerAnalytics/releases/tag/4.7.0-DEV2