Convert friend system over to redis-based PlayerStatus data tracking from old SQL storage.
This commit is contained in:
parent
c1c284002d
commit
7811279b26
@ -1,33 +0,0 @@
|
||||
package mineplex.bungee.playerTracker;
|
||||
|
||||
import mineplex.serverdata.data.Data;
|
||||
|
||||
public class PlayerStatus implements Data
|
||||
{
|
||||
// The name of this server.
|
||||
private String _name;
|
||||
public String getName() { return _name; }
|
||||
|
||||
// The current message of the day (MOTD) of the server.
|
||||
private String _server;
|
||||
public String getServer() { return _server; }
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
* @param name
|
||||
* @param server
|
||||
*/
|
||||
public PlayerStatus(String name, String server)
|
||||
{
|
||||
_name = name;
|
||||
_server = server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unique identifying String ID associated with this {@link PlayerStatus}.
|
||||
*/
|
||||
public String getDataId()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import java.io.File;
|
||||
|
||||
import mineplex.serverdata.Region;
|
||||
import mineplex.serverdata.data.DataRepository;
|
||||
import mineplex.serverdata.data.PlayerStatus;
|
||||
import mineplex.serverdata.redis.RedisDataRepository;
|
||||
import mineplex.serverdata.servers.ServerManager;
|
||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
||||
|
@ -409,7 +409,7 @@ public class FriendManager extends MiniDbClientPlugin<FriendData>
|
||||
@Override
|
||||
public String getQuery(String uuid, String name)
|
||||
{
|
||||
return "SELECT tA.Name, status, serverName, tA.lastLogin, now() FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget LEFT JOIN playerMap ON tA.name = playerName WHERE uuidSource = '"
|
||||
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 = '"
|
||||
+ uuid + "';";
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,12 @@ package mineplex.core.friend.data;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@ -12,18 +18,29 @@ import mineplex.core.database.RepositoryBase;
|
||||
import mineplex.core.database.ResultSetCallable;
|
||||
import mineplex.core.database.column.ColumnVarChar;
|
||||
import mineplex.core.friend.FriendStatusType;
|
||||
import mineplex.serverdata.Region;
|
||||
import mineplex.serverdata.data.DataRepository;
|
||||
import mineplex.serverdata.data.PlayerStatus;
|
||||
import mineplex.serverdata.redis.RedisDataRepository;
|
||||
import mineplex.serverdata.servers.ServerManager;
|
||||
|
||||
public class FriendRepository extends RepositoryBase
|
||||
{
|
||||
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, serverName, tA.lastLogin, now() FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget LEFT JOIN playerMap ON tA.name = playerName WHERE uuidSource IN ";
|
||||
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 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 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 = ?;";
|
||||
|
||||
// Repository holding active PlayerStatus data.
|
||||
private DataRepository<PlayerStatus> _repository;
|
||||
|
||||
public FriendRepository(JavaPlugin plugin)
|
||||
{
|
||||
super(plugin, DBPool.ACCOUNT);
|
||||
|
||||
_repository = new RedisDataRepository<PlayerStatus>(ServerManager.getMasterConnection(), ServerManager.getSlaveConnection(),
|
||||
Region.currentRegion(), PlayerStatus.class, "playerStatus");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -81,29 +98,35 @@ public class FriendRepository extends RepositoryBase
|
||||
{
|
||||
public void processResultSet(ResultSet resultSet) throws SQLException
|
||||
{
|
||||
Set<FriendData> friendDatas = new HashSet<FriendData>();
|
||||
while (resultSet.next())
|
||||
{
|
||||
FriendStatus friend = new FriendStatus();
|
||||
|
||||
String uuidSource = resultSet.getString(1);
|
||||
friend.Name = resultSet.getString(2);
|
||||
friend.Status = Enum.valueOf(FriendStatusType.class, resultSet.getString(3));
|
||||
friend.ServerName = resultSet.getString(4);
|
||||
friend.Online = !(friend.ServerName == null || friend.ServerName.isEmpty());
|
||||
|
||||
friend.LastSeenOnline = resultSet.getTimestamp(6).getTime() - resultSet.getTimestamp(5).getTime();
|
||||
friend.Status = Enum.valueOf(FriendStatusType.class, resultSet.getString(3));
|
||||
friend.LastSeenOnline = resultSet.getTimestamp(5).getTime() - resultSet.getTimestamp(4).getTime();
|
||||
|
||||
if (!friends.containsKey(uuidSource))
|
||||
friends.put(uuidSource, new FriendData());
|
||||
|
||||
friends.get(uuidSource).getFriends().add(friend);
|
||||
|
||||
friendDatas.add(friends.get(uuidSource));
|
||||
}
|
||||
|
||||
// Load the server status of friends for all sources.
|
||||
for(FriendData friendData : friendDatas)
|
||||
{
|
||||
loadFriendStatuses(friendData);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return friends;
|
||||
}
|
||||
|
||||
|
||||
public FriendData loadClientInformation(ResultSet resultSet) throws SQLException
|
||||
{
|
||||
FriendData friendData = new FriendData();
|
||||
@ -114,12 +137,59 @@ public class FriendRepository extends RepositoryBase
|
||||
|
||||
friend.Name = resultSet.getString(1);
|
||||
friend.Status = Enum.valueOf(FriendStatusType.class, resultSet.getString(2));
|
||||
friend.ServerName = resultSet.getString(3);
|
||||
friend.LastSeenOnline = resultSet.getTimestamp(5).getTime() - resultSet.getTimestamp(4).getTime();
|
||||
|
||||
friend.LastSeenOnline = resultSet.getTimestamp(4).getTime() - resultSet.getTimestamp(3).getTime();
|
||||
friend.ServerName = null;
|
||||
friend.Online = (friend.ServerName != null);
|
||||
friendData.getFriends().add(friend);
|
||||
}
|
||||
|
||||
loadFriendStatuses(friendData);
|
||||
|
||||
return friendData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the server status information for a list of {@link FriendStatus}.
|
||||
* @param friendData - the {@link FriendStatus} object friends server status' are to be updated
|
||||
* @param statuses - the fetched {@link PlayerStatus} associated with all online {@code friends}.
|
||||
*/
|
||||
public void loadFriendStatuses(FriendData friendData)
|
||||
{
|
||||
// Generate a set of all friend names
|
||||
Set<String> friendNames = new HashSet<String>();
|
||||
for(FriendStatus status : friendData.getFriends())
|
||||
{
|
||||
friendNames.add(status.Name);
|
||||
}
|
||||
|
||||
// Load PlayerStatus' for friends
|
||||
Collection<PlayerStatus> statuses = _repository.getElements(friendNames);
|
||||
|
||||
// Load player statuses into a mapping
|
||||
Map<String, PlayerStatus> playerStatuses = new HashMap<String, PlayerStatus>();
|
||||
for(PlayerStatus status : statuses)
|
||||
{
|
||||
playerStatuses.put(status.getName(), status);
|
||||
}
|
||||
|
||||
// Load status information into friend data.
|
||||
for (FriendStatus friend : friendData.getFriends())
|
||||
{
|
||||
PlayerStatus status = playerStatuses.get(friend.Name);
|
||||
friend.Online = (status != null);
|
||||
friend.ServerName = (friend.Online) ? status.getServer() : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param playerName - the name of the player whose current server status is being fetched
|
||||
* @return the {@link MinecraftServer} name that the player matching {@code playerName}
|
||||
* is currently online on, if they are online, null otherwise.
|
||||
*/
|
||||
public String fetchPlayerServer(String playerName)
|
||||
{
|
||||
PlayerStatus status = _repository.getElement(playerName);
|
||||
|
||||
return (status == null) ? null : status.getServer();
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package mineplex.serverdata;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Region enumerates the various geographical regions where Mineplex servers are
|
||||
* hosted.
|
||||
@ -11,4 +13,12 @@ public enum Region
|
||||
US,
|
||||
EU,
|
||||
ALL;
|
||||
|
||||
/**
|
||||
* @return the geographical {@link Region} of the current running process.
|
||||
*/
|
||||
public static Region currentRegion()
|
||||
{
|
||||
return !new File("eu.dat").exists() ? Region.US : Region.EU;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ public interface DataRepository<T extends Data>
|
||||
public Collection<T> getElements();
|
||||
|
||||
public T getElement(String dataId);
|
||||
|
||||
public Collection<T> getElements(Collection<String> dataIds);
|
||||
|
||||
public void addElement(T element, int timeout);
|
||||
|
||||
|
@ -85,6 +85,12 @@ public class RedisDataRepository<T extends Data> implements DataRepository<T>
|
||||
|
||||
@Override
|
||||
public Collection<T> getElements()
|
||||
{
|
||||
return getElements(getActiveElements());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<T> getElements(Collection<String> dataIds)
|
||||
{
|
||||
Collection<T> elements = new HashSet<T>();
|
||||
Jedis jedis = _readPool.getResource();
|
||||
@ -94,11 +100,12 @@ public class RedisDataRepository<T extends Data> implements DataRepository<T>
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
|
||||
List<Response<String>> responses = new ArrayList<Response<String>>();
|
||||
for (String dataId : getActiveElements())
|
||||
for (String dataId : dataIds)
|
||||
{
|
||||
responses.add(pipeline.get(generateKey(dataId)));
|
||||
}
|
||||
|
||||
// Block until all requests have received pipelined responses
|
||||
pipeline.sync();
|
||||
|
||||
for (Response<String> response : responses)
|
||||
@ -128,7 +135,7 @@ public class RedisDataRepository<T extends Data> implements DataRepository<T>
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public T getElement(String dataId)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user