Fixed network join address pie having duplicated address numbers

This would happen if player joined two game servers on a network
This commit is contained in:
Risto Lahtela 2021-03-17 16:11:05 +02:00
parent 7f2b23e711
commit 36bb989d7c
4 changed files with 43 additions and 5 deletions

View File

@ -29,6 +29,7 @@ import java.sql.PreparedStatement;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.UUID; import java.util.UUID;
import static com.djrapitops.plan.storage.database.sql.building.Sql.AND;
import static com.djrapitops.plan.storage.database.sql.building.Sql.WHERE; import static com.djrapitops.plan.storage.database.sql.building.Sql.WHERE;
/** /**
@ -297,15 +298,17 @@ public class DataStoreQueries {
}; };
} }
public static Executable updateJoinAddress(UUID playerUUID, String joinAddress) { public static Executable updateJoinAddress(UUID playerUUID, ServerUUID serverUUID, String joinAddress) {
String sql = "UPDATE " + UserInfoTable.TABLE_NAME + " SET " + String sql = "UPDATE " + UserInfoTable.TABLE_NAME + " SET " +
UserInfoTable.JOIN_ADDRESS + "=?" + UserInfoTable.JOIN_ADDRESS + "=?" +
WHERE + UserInfoTable.USER_UUID + "=?"; WHERE + UserInfoTable.USER_UUID + "=?" +
AND + UserInfoTable.SERVER_UUID + "=?";
return new ExecStatement(sql) { return new ExecStatement(sql) {
@Override @Override
public void prepare(PreparedStatement statement) throws SQLException { public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, joinAddress); statement.setString(1, joinAddress);
statement.setString(2, playerUUID.toString()); statement.setString(2, playerUUID.toString());
statement.setString(3, serverUUID.toString());
} }
}; };
} }

View File

@ -198,7 +198,12 @@ public class UserInfoQueries {
String sql = SELECT + String sql = SELECT +
"COUNT(1) as total," + "COUNT(1) as total," +
"COALESCE(" + UserInfoTable.JOIN_ADDRESS + ", ?) as address" + "COALESCE(" + UserInfoTable.JOIN_ADDRESS + ", ?) as address" +
FROM + '(' +
SELECT + DISTINCT +
UserInfoTable.USER_UUID + ',' +
UserInfoTable.JOIN_ADDRESS +
FROM + UserInfoTable.TABLE_NAME + FROM + UserInfoTable.TABLE_NAME +
") q1" +
GROUP_BY + "address" + GROUP_BY + "address" +
ORDER_BY + "address DESC"; ORDER_BY + "address DESC";
@ -210,7 +215,7 @@ public class UserInfoQueries {
@Override @Override
public Map<String, Integer> processResults(ResultSet set) throws SQLException { public Map<String, Integer> processResults(ResultSet set) throws SQLException {
Map<String, Integer> joinAddresses = new HashMap<>(); Map<String, Integer> joinAddresses = new TreeMap<>();
while (set.next()) { while (set.next()) {
joinAddresses.put(set.getString("address"), set.getInt("total")); joinAddresses.put(set.getString("address"), set.getInt("total"));
} }
@ -237,7 +242,7 @@ public class UserInfoQueries {
@Override @Override
public Map<String, Integer> processResults(ResultSet set) throws SQLException { public Map<String, Integer> processResults(ResultSet set) throws SQLException {
Map<String, Integer> joinAddresses = new HashMap<>(); Map<String, Integer> joinAddresses = new TreeMap<>();
while (set.next()) { while (set.next()) {
joinAddresses.put(set.getString("address"), set.getInt("total")); joinAddresses.put(set.getString("address"), set.getInt("total"));
} }

View File

@ -58,6 +58,6 @@ public class PlayerServerRegisterTransaction extends PlayerRegisterTransaction {
execute(DataStoreQueries.updateMainRegisterDate(playerUUID, registerDate)); execute(DataStoreQueries.updateMainRegisterDate(playerUUID, registerDate));
} }
execute(DataStoreQueries.updateJoinAddress(playerUUID, joinAddress)); execute(DataStoreQueries.updateJoinAddress(playerUUID, serverUUID, joinAddress));
} }
} }

View File

@ -18,10 +18,12 @@ package com.djrapitops.plan.storage.database.queries;
import com.djrapitops.plan.gathering.domain.BaseUser; import com.djrapitops.plan.gathering.domain.BaseUser;
import com.djrapitops.plan.gathering.domain.UserInfo; import com.djrapitops.plan.gathering.domain.UserInfo;
import com.djrapitops.plan.identification.Server;
import com.djrapitops.plan.storage.database.DatabaseTestPreparer; import com.djrapitops.plan.storage.database.DatabaseTestPreparer;
import com.djrapitops.plan.storage.database.queries.objects.BaseUserQueries; import com.djrapitops.plan.storage.database.queries.objects.BaseUserQueries;
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries; import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries; import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
import com.djrapitops.plan.storage.database.transactions.StoreServerInformationTransaction;
import com.djrapitops.plan.storage.database.transactions.Transaction; import com.djrapitops.plan.storage.database.transactions.Transaction;
import com.djrapitops.plan.storage.database.transactions.commands.RemoveEverythingTransaction; import com.djrapitops.plan.storage.database.transactions.commands.RemoveEverythingTransaction;
import com.djrapitops.plan.storage.database.transactions.events.*; import com.djrapitops.plan.storage.database.transactions.events.*;
@ -73,6 +75,23 @@ public interface UserInfoQueriesTest extends DatabaseTestPreparer {
assertEquals(expected, userInfo); assertEquals(expected, userInfo);
} }
@Test
default void joinAddressUpdateIsUniquePerServer() {
db().executeTransaction(new PlayerServerRegisterTransaction(playerUUID, () -> TestConstants.REGISTER_TIME, TestConstants.PLAYER_ONE_NAME, serverUUID(), () -> null));
db().executeTransaction(new PlayerServerRegisterTransaction(playerUUID, () -> TestConstants.REGISTER_TIME, TestConstants.PLAYER_ONE_NAME, serverUUID(), TestConstants.GET_PLAYER_HOSTNAME));
db().executeTransaction(new StoreServerInformationTransaction(new Server(TestConstants.SERVER_TWO_UUID, TestConstants.SERVER_TWO_NAME, "")));
db().executeTransaction(new PlayerServerRegisterTransaction(playerUUID, () -> TestConstants.REGISTER_TIME, TestConstants.PLAYER_ONE_NAME, TestConstants.SERVER_TWO_UUID, () -> "example.join.address"));
List<UserInfo> userInfo = db().query(UserInfoQueries.fetchUserInformationOfUser(playerUUID));
List<UserInfo> expected = Arrays.asList(
new UserInfo(playerUUID, serverUUID(), TestConstants.REGISTER_TIME, false, TestConstants.GET_PLAYER_HOSTNAME.get(), false),
new UserInfo(playerUUID, TestConstants.SERVER_TWO_UUID, TestConstants.REGISTER_TIME, false, "example.join.address", false)
);
assertEquals(expected, userInfo);
}
@Test @Test
default void userInfoTableUpdatesBanStatus() { default void userInfoTableUpdatesBanStatus() {
db().executeTransaction(new PlayerServerRegisterTransaction(playerUUID, () -> TestConstants.REGISTER_TIME, db().executeTransaction(new PlayerServerRegisterTransaction(playerUUID, () -> TestConstants.REGISTER_TIME,
@ -279,4 +298,15 @@ public interface UserInfoQueriesTest extends DatabaseTestPreparer {
Map<String, Integer> result = db().query(UserInfoQueries.joinAddresses(serverUUID())); Map<String, Integer> result = db().query(UserInfoQueries.joinAddresses(serverUUID()));
assertEquals(expected, result); assertEquals(expected, result);
} }
@Test
default void joinAddressQueryHasDistinctPlayers() {
db().executeTransaction(new StoreServerInformationTransaction(new Server(TestConstants.SERVER_TWO_UUID, TestConstants.SERVER_TWO_NAME, "")));
db().executeTransaction(new PlayerServerRegisterTransaction(playerUUID, () -> TestConstants.REGISTER_TIME, TestConstants.PLAYER_ONE_NAME, serverUUID(), TestConstants.GET_PLAYER_HOSTNAME));
db().executeTransaction(new PlayerServerRegisterTransaction(playerUUID, () -> TestConstants.REGISTER_TIME, TestConstants.PLAYER_ONE_NAME, TestConstants.SERVER_TWO_UUID, TestConstants.GET_PLAYER_HOSTNAME));
Map<String, Integer> expected = Collections.singletonMap(TestConstants.GET_PLAYER_HOSTNAME.get(), 1);
Map<String, Integer> result = db().query(UserInfoQueries.joinAddresses());
assertEquals(expected, result);
}
} }