Refactor Redis PlayerStatus to use UUID as a key instead of Name, and make communities not force every server to subscribe to join publishes from proxies

This commit is contained in:
AlexTheCoder 2016-12-23 18:01:52 -05:00
parent 4ae21e66c9
commit 74a6071d4e
9 changed files with 43 additions and 74 deletions

View File

@ -60,7 +60,7 @@ public class PlayerTracker implements Listener
{ {
public void run() public void run()
{ {
PlayerStatus snapshot = new PlayerStatus(event.getPlayer().getName(), event.getServer().getInfo().getName()); PlayerStatus snapshot = new PlayerStatus(event.getPlayer().getUniqueId().toString(), event.getPlayer().getName(), event.getServer().getInfo().getName());
_repository.addElement(snapshot, DEFAULT_STATUS_TIMEOUT); _repository.addElement(snapshot, DEFAULT_STATUS_TIMEOUT);
} }
}); });
@ -73,7 +73,7 @@ public class PlayerTracker implements Listener
{ {
public void run() public void run()
{ {
_repository.removeElement(event.getPlayer().getName().toLowerCase()); _repository.removeElement(event.getPlayer().getUniqueId().toString());
} }
}); });
} }

View File

@ -8,7 +8,6 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Random;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -57,13 +56,11 @@ import mineplex.core.communities.redis.CommunityUpdateName;
import mineplex.core.communities.redis.CommunityUpdateNameHandler; import mineplex.core.communities.redis.CommunityUpdateNameHandler;
import mineplex.core.communities.redis.CommunityUpdateSetting; import mineplex.core.communities.redis.CommunityUpdateSetting;
import mineplex.core.communities.redis.CommunityUpdateSettingHandler; import mineplex.core.communities.redis.CommunityUpdateSettingHandler;
import mineplex.core.communities.redis.PlayerJoinHandler;
import mineplex.core.communities.storage.CommunityRepository; import mineplex.core.communities.storage.CommunityRepository;
import mineplex.core.preferences.Preference; import mineplex.core.preferences.Preference;
import mineplex.core.preferences.PreferencesManager; import mineplex.core.preferences.PreferencesManager;
import mineplex.core.recharge.Recharge; import mineplex.core.recharge.Recharge;
import mineplex.serverdata.Region; import mineplex.serverdata.Region;
import mineplex.serverdata.commands.PlayerJoinCommand;
import mineplex.serverdata.commands.ServerCommandManager; import mineplex.serverdata.commands.ServerCommandManager;
import mineplex.serverdata.data.DataRepository; import mineplex.serverdata.data.DataRepository;
import mineplex.serverdata.data.PlayerStatus; import mineplex.serverdata.data.PlayerStatus;
@ -143,7 +140,7 @@ public class CommunityManager extends MiniDbClientPlugin<CommunityMemberData>
LinkedList<Community> communities = new LinkedList<>(); LinkedList<Community> communities = new LinkedList<>();
_loadedCommunities.values().forEach(community -> communities.add(community)); _loadedCommunities.values().forEach(community -> communities.add(community));
_repo.updateMembers(communities); _repo.updateMembers(communities);
}, 0L, 20 * 5); }, 0L, 20 * 7);
Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () -> Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, () ->
{ {
@ -166,7 +163,6 @@ public class CommunityManager extends MiniDbClientPlugin<CommunityMemberData>
ServerCommandManager.getInstance().registerCommandType(CommunityUpdateMembership.class, new CommunityUpdateMembershipHandler(this)); ServerCommandManager.getInstance().registerCommandType(CommunityUpdateMembership.class, new CommunityUpdateMembershipHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityUpdateName.class, new CommunityUpdateNameHandler(this)); ServerCommandManager.getInstance().registerCommandType(CommunityUpdateName.class, new CommunityUpdateNameHandler(this));
ServerCommandManager.getInstance().registerCommandType(CommunityUpdateSetting.class, new CommunityUpdateSettingHandler(this)); ServerCommandManager.getInstance().registerCommandType(CommunityUpdateSetting.class, new CommunityUpdateSettingHandler(this));
ServerCommandManager.getInstance().registerCommandType(PlayerJoinCommand.class, new PlayerJoinHandler(this));
} }
public boolean ownsCommunity(UUID uuid) public boolean ownsCommunity(UUID uuid)
@ -176,41 +172,6 @@ public class CommunityManager extends MiniDbClientPlugin<CommunityMemberData>
.anyMatch(entry -> entry.getKey().equals(uuid) && entry.getValue().Role == CommunityRole.LEADER); .anyMatch(entry -> entry.getKey().equals(uuid) && entry.getValue().Role == CommunityRole.LEADER);
} }
public void updateAllMemberData(UUID uuid, String name)
{
if (uuid == null)
{
return;
}
if (name == null)
{
return;
}
_loadedCommunities.values().stream().filter(community -> community.getMembers().containsKey(uuid) && !community.getMembers().get(uuid).Name.equalsIgnoreCase(name)).forEach(community ->
{
community.getMembers().get(uuid).updateName(name);
community.getMembers().get(uuid).update(System.currentTimeMillis(), false, "");
UtilServer.CallEvent(new CommunityMembershipUpdateEvent(community));
});
}
public void updateAllJoinRequests(UUID uuid, String name)
{
if (uuid == null)
{
return;
}
if (name == null)
{
return;
}
_loadedCommunities.values().stream().filter(community -> community.getJoinRequests().containsKey(uuid) && !community.getJoinRequests().get(uuid).Name.equalsIgnoreCase(name)).forEach(community ->
{
community.getJoinRequests().get(uuid).update(name);
UtilServer.CallEvent(new CommunityJoinRequestsUpdateEvent(community));
});
}
private void cycleBrowser() private void cycleBrowser()
{ {
if (_cycling) if (_cycling)

View File

@ -1,7 +1,5 @@
package mineplex.core.communities.redis; package mineplex.core.communities.redis;
import java.util.UUID;
import mineplex.core.communities.CommunityManager; import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback; import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.PlayerJoinCommand; import mineplex.serverdata.commands.PlayerJoinCommand;
@ -22,7 +20,7 @@ public class PlayerJoinHandler implements CommandCallback
if (command instanceof PlayerJoinCommand) if (command instanceof PlayerJoinCommand)
{ {
PlayerJoinCommand joinCommand = (PlayerJoinCommand)command; PlayerJoinCommand joinCommand = (PlayerJoinCommand)command;
_communityManager.updateAllMemberData(UUID.fromString(joinCommand.getUuid()), joinCommand.getName()); //_communityManager.updateAllMemberData(UUID.fromString(joinCommand.getUuid()), joinCommand.getName());
} }
} }
} }

View File

@ -212,7 +212,7 @@ public class CommunityRepository extends MinecraftRepository
{ {
for (CommunityMemberInfo info : c.getMembers().values()) for (CommunityMemberInfo info : c.getMembers().values())
{ {
PlayerStatus status = _repo.getElement(info.Name.toLowerCase()); PlayerStatus status = _repo.getElement(info.UUID.toString());
boolean online = false; boolean online = false;
String server = ""; String server = "";
if (status != null) if (status != null)
@ -220,6 +220,10 @@ public class CommunityRepository extends MinecraftRepository
online = true; online = true;
server = status.getServer(); server = status.getServer();
info.update(System.currentTimeMillis(), online, server); info.update(System.currentTimeMillis(), online, server);
if (!info.Name.equalsIgnoreCase(status.getName()))
{
info.updateName(status.getName());
}
} }
else else
{ {

View File

@ -392,8 +392,8 @@ public class PlayerDisguiseManager extends MiniPlugin implements IPacketHandler
CoreClient client = getClientManager().Get(caller); CoreClient client = getClientManager().Get(caller);
client.undisguise(); client.undisguise();
require(FriendManager.class).updatePlayerStatus(disguisedProfile.getName(), null); require(FriendManager.class).updatePlayerStatus(disguisedProfile.getId().toString(), null);
require(FriendManager.class).updatePlayerStatus(originalProfile.getName(), new PlayerStatus(originalProfile.getName(), _serverName)); require(FriendManager.class).updatePlayerStatus(originalProfile.getId().toString(), new PlayerStatus(originalProfile.getId().toString(), originalProfile.getName(), _serverName));
getPreferencesManager().handlePlayerJoin(caller, true); getPreferencesManager().handlePlayerJoin(caller, true);
require(ScoreboardManager.class).handlePlayerJoin(disguise.getOriginalProfile().getName()); require(ScoreboardManager.class).handlePlayerJoin(disguise.getOriginalProfile().getName());
@ -539,8 +539,8 @@ public class PlayerDisguiseManager extends MiniPlugin implements IPacketHandler
callerProfile.getProperties().removeAll(ORIGINAL_UUID_KEY); callerProfile.getProperties().removeAll(ORIGINAL_UUID_KEY);
callerProfile.getProperties().put(ORIGINAL_UUID_KEY, new Property(ORIGINAL_UUID_KEY, caller.getUniqueId().toString())); callerProfile.getProperties().put(ORIGINAL_UUID_KEY, new Property(ORIGINAL_UUID_KEY, caller.getUniqueId().toString()));
require(FriendManager.class).updatePlayerStatus(disguisePlayer.getOriginalProfile().getName(), null); require(FriendManager.class).updatePlayerStatus(disguisePlayer.getOriginalProfile().getId().toString(), null);
require(FriendManager.class).updatePlayerStatus(requestedUsername, new PlayerStatus(requestedUsername, _serverName)); require(FriendManager.class).updatePlayerStatus(disguisePlayer.getProfile().getId().toString(), new PlayerStatus(disguisePlayer.getProfile().getId().toString(), requestedUsername, _serverName));
getPreferencesManager().handlePlayerJoin(caller, true); getPreferencesManager().handlePlayerJoin(caller, true);

View File

@ -402,14 +402,14 @@ public class FriendManager extends MiniDbClientPlugin<FriendData>
} }
public void updatePlayerStatus(String playerName, PlayerStatus status) public void updatePlayerStatus(String playerUUID, PlayerStatus status)
{ {
_repository.updatePlayerStatus(playerName, status); _repository.updatePlayerStatus(playerUUID, status);
} }
public PlayerStatus getStatus(String playerName) public PlayerStatus getStatus(String playerUUID)
{ {
return _repository.getStatus(playerName); return _repository.getStatus(playerUUID);
} }
@Override @Override
@ -421,7 +421,7 @@ public class FriendManager extends MiniDbClientPlugin<FriendData>
@Override @Override
public String getQuery(int accountId, String uuid, String name) public String getQuery(int accountId, String uuid, String name)
{ {
return "SELECT tA.Name, status, tA.lastLogin, now() FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget WHERE uuidSource = '" return "SELECT tA.Name, status, tA.lastLogin, now(), uuidTarget FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget WHERE uuidSource = '"
+ uuid + "';"; + uuid + "';";
} }
} }

View File

@ -26,7 +26,7 @@ import mineplex.serverdata.servers.ServerManager;
public class FriendRepository extends MinecraftRepository public class FriendRepository extends MinecraftRepository
{ {
private static String CREATE_FRIEND_TABLE = "CREATE TABLE IF NOT EXISTS accountFriend (id INT NOT NULL AUTO_INCREMENT, uuidSource VARCHAR(100), uuidTarget VARCHAR(100), status VARCHAR(100), PRIMARY KEY (id), UNIQUE INDEX uuidIndex (uuidSource, uuidTarget));"; private static String CREATE_FRIEND_TABLE = "CREATE TABLE IF NOT EXISTS accountFriend (id INT NOT NULL AUTO_INCREMENT, uuidSource VARCHAR(100), uuidTarget VARCHAR(100), status VARCHAR(100), PRIMARY KEY (id), UNIQUE INDEX uuidIndex (uuidSource, uuidTarget));";
private static String RETRIEVE_MULTIPLE_FRIEND_RECORDS = "SELECT uuidSource, tA.Name, status, tA.lastLogin, now() FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget WHERE uuidSource IN "; private static String RETRIEVE_MULTIPLE_FRIEND_RECORDS = "SELECT uuidSource, tA.Name, status, tA.lastLogin, now(), uuidTarget FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget WHERE uuidSource IN ";
private static String ADD_FRIEND_RECORD = "INSERT INTO accountFriend (uuidSource, uuidTarget, status, created) SELECT fA.uuid AS uuidSource, tA.uuid AS uuidTarget, ?, now() FROM accounts as fA LEFT JOIN accounts AS tA ON tA.name = ? WHERE fA.name = ?;"; private static String ADD_FRIEND_RECORD = "INSERT INTO accountFriend (uuidSource, uuidTarget, status, created) SELECT fA.uuid AS uuidSource, tA.uuid AS uuidTarget, ?, now() FROM accounts as fA LEFT JOIN accounts AS tA ON tA.name = ? WHERE fA.name = ?;";
private static String UPDATE_MUTUAL_RECORD = "UPDATE accountFriend AS aF INNER JOIN accounts as fA ON aF.uuidSource = fA.uuid INNER JOIN accounts AS tA ON aF.uuidTarget = tA.uuid SET aF.status = ? WHERE tA.name = ? AND fA.name = ?;"; private static String UPDATE_MUTUAL_RECORD = "UPDATE accountFriend AS aF INNER JOIN accounts as fA ON aF.uuidSource = fA.uuid INNER JOIN accounts AS tA ON aF.uuidTarget = tA.uuid SET aF.status = ? WHERE tA.name = ? AND fA.name = ?;";
private static String DELETE_FRIEND_RECORD = "DELETE aF FROM accountFriend AS aF INNER JOIN accounts as fA ON aF.uuidSource = fA.uuid INNER JOIN accounts AS tA ON aF.uuidTarget = tA.uuid WHERE fA.name = ? AND tA.name = ?;"; private static String DELETE_FRIEND_RECORD = "DELETE aF FROM accountFriend AS aF INNER JOIN accounts as fA ON aF.uuidSource = fA.uuid INNER JOIN accounts AS tA ON aF.uuidTarget = tA.uuid WHERE fA.name = ? AND tA.name = ?;";
@ -95,6 +95,7 @@ public class FriendRepository extends MinecraftRepository
friend.Name = resultSet.getString(2); friend.Name = resultSet.getString(2);
friend.Status = Enum.valueOf(FriendStatusType.class, resultSet.getString(3)); friend.Status = Enum.valueOf(FriendStatusType.class, resultSet.getString(3));
friend.LastSeenOnline = resultSet.getTimestamp(5).getTime() - resultSet.getTimestamp(4).getTime(); friend.LastSeenOnline = resultSet.getTimestamp(5).getTime() - resultSet.getTimestamp(4).getTime();
friend.UUID = resultSet.getString(6);
if (!friends.containsKey(uuidSource)) if (!friends.containsKey(uuidSource))
friends.put(uuidSource, new FriendData()); friends.put(uuidSource, new FriendData());
@ -126,6 +127,7 @@ public class FriendRepository extends MinecraftRepository
friend.Name = resultSet.getString(1); friend.Name = resultSet.getString(1);
friend.Status = Enum.valueOf(FriendStatusType.class, resultSet.getString(2)); friend.Status = Enum.valueOf(FriendStatusType.class, resultSet.getString(2));
friend.LastSeenOnline = resultSet.getTimestamp(4).getTime() - resultSet.getTimestamp(3).getTime(); friend.LastSeenOnline = resultSet.getTimestamp(4).getTime() - resultSet.getTimestamp(3).getTime();
friend.UUID = resultSet.getString(5);
friend.ServerName = null; friend.ServerName = null;
friend.Online = (friend.ServerName != null); friend.Online = (friend.ServerName != null);
friendData.getFriends().add(friend); friendData.getFriends().add(friend);
@ -144,26 +146,26 @@ public class FriendRepository extends MinecraftRepository
public void loadFriendStatuses(FriendData friendData) public void loadFriendStatuses(FriendData friendData)
{ {
// Generate a set of all friend names // Generate a set of all friend names
Set<String> friendNames = new HashSet<String>(); Set<String> friendUUIDS = new HashSet<String>();
for(FriendStatus status : friendData.getFriends()) for(FriendStatus status : friendData.getFriends())
{ {
friendNames.add(status.Name.toLowerCase()); friendUUIDS.add(status.UUID);
} }
// Load PlayerStatus' for friends // Load PlayerStatus' for friends
Collection<PlayerStatus> statuses = _repository.getElements(friendNames); Collection<PlayerStatus> statuses = _repository.getElements(friendUUIDS);
// Load player statuses into a mapping // Load player statuses into a mapping
Map<String, PlayerStatus> playerStatuses = new HashMap<String, PlayerStatus>(); Map<String, PlayerStatus> playerStatuses = new HashMap<String, PlayerStatus>();
for(PlayerStatus status : statuses) for(PlayerStatus status : statuses)
{ {
playerStatuses.put(status.getName(), status); playerStatuses.put(status.getUUID(), status);
} }
// Load status information into friend data. // Load status information into friend data.
for (FriendStatus friend : friendData.getFriends()) for (FriendStatus friend : friendData.getFriends())
{ {
PlayerStatus status = playerStatuses.get(friend.Name); PlayerStatus status = playerStatuses.get(friend.UUID);
friend.Online = (status != null); friend.Online = (status != null);
friend.ServerName = (friend.Online) ? status.getServer() : null; friend.ServerName = (friend.Online) ? status.getServer() : null;
} }
@ -174,14 +176,14 @@ public class FriendRepository extends MinecraftRepository
* @return the name that the player matching {@code playerName} * @return the name that the player matching {@code playerName}
* is currently online on, if they are online, null otherwise. * is currently online on, if they are online, null otherwise.
*/ */
public String fetchPlayerServer(String playerName) public String fetchPlayerServer(String playerUUID)
{ {
PlayerStatus status = _repository.getElement(playerName.toLowerCase()); PlayerStatus status = _repository.getElement(playerUUID);
return (status == null) ? null : status.getServer(); return (status == null) ? null : status.getServer();
} }
public void updatePlayerStatus(String playerName, PlayerStatus status) public void updatePlayerStatus(String playerUUID, PlayerStatus status)
{ {
if (status != null) if (status != null)
{ {
@ -189,12 +191,12 @@ public class FriendRepository extends MinecraftRepository
} }
else else
{ {
_repository.removeElement(playerName.toLowerCase()); _repository.removeElement(playerUUID);
} }
} }
public PlayerStatus getStatus(String playerName) public PlayerStatus getStatus(String playerUUID)
{ {
return _repository.getElement(playerName.toLowerCase()); return _repository.getElement(playerUUID);
} }
} }

View File

@ -5,6 +5,7 @@ import mineplex.core.friend.FriendStatusType;
public class FriendStatus public class FriendStatus
{ {
public String Name; public String Name;
public String UUID;
public String ServerName; public String ServerName;
public boolean Online; public boolean Online;
/** /**

View File

@ -4,11 +4,15 @@ import mineplex.serverdata.data.Data;
public class PlayerStatus implements Data public class PlayerStatus implements Data
{ {
// The name of this server. // The uuid of this player.
private String _uuid;
public String getUUID() { return _uuid; }
// The name of this player.
private String _name; private String _name;
public String getName() { return _name; } public String getName() { return _name; }
// The current message of the day (MOTD) of the server. // The current server occupied by this player.
private String _server; private String _server;
public String getServer() { return _server; } public String getServer() { return _server; }
@ -17,19 +21,18 @@ public class PlayerStatus implements Data
* @param name * @param name
* @param server * @param server
*/ */
public PlayerStatus(String name, String server) public PlayerStatus(String uuid, String name, String server)
{ {
_uuid = uuid;
_name = name; _name = name;
_server = server; _server = server;
} }
/** /**
* Unique identifying String ID associated with this {@link PlayerStatus}. * Unique identifying String ID associated with this {@link PlayerStatus}.
*
* Use the lowercase name so we can have case-insensitive lookup
*/ */
public String getDataId() public String getDataId()
{ {
return _name.toLowerCase(); return _uuid;
} }
} }