diff --git a/Plugins/Mineplex.Core/src/mineplex/core/portal/PortalRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/portal/PortalRepository.java new file mode 100644 index 000000000..f2cbf9d3d --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/portal/PortalRepository.java @@ -0,0 +1,148 @@ +package mineplex.core.portal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import mineplex.serverdata.Utility; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; +import redis.clients.jedis.Pipeline; +import redis.clients.jedis.Response; +import redis.clients.jedis.Transaction; + +public class PortalRepository +{ + + // The delimiter character used for redis key paths + public final char KEY_DELIMITER = '.'; + + // The access portal for jedis resources + private JedisPool _jedisPool; + + /** + * Class constructor + * @param host - the host name connection URL for the repository database + */ + public PortalRepository(String host) + { + this._jedisPool = new JedisPool(new JedisPoolConfig(), host); + } + + /** + * @return the {@link Set} of all ongoing {@link ServerTransfer}s available in this repository. + */ + public Collection getServerTransfers() + { + Set serverTransfers = new HashSet(); + Jedis jedis = _jedisPool.getResource(); + + try + { + String setKey = "servertransfers"; + Set playerNames = jedis.smembers(setKey); + + Pipeline pipeline = jedis.pipelined(); + + List> responses = new ArrayList>(); + for (String playerName : playerNames) + { + String dataKey = concatenate(setKey, playerName); + responses.add(pipeline.get(dataKey)); + } + + pipeline.sync(); + + for (Response response : responses) + { + String serializedData = response.get(); + ServerTransfer serverTransfer = Utility.deserialize(serializedData, ServerTransfer.class); + serverTransfers.add(serverTransfer); + } + } + finally + { + _jedisPool.returnResource(jedis); + } + + return serverTransfers; + } + + /** + * Add a new {@link ServerTransfer} to this repository. + * @param serverTransfer - the {@link ServerTransfer} to be added in. + */ + public void addServerTransfer(ServerTransfer serverTransfer) + { + Jedis jedis = _jedisPool.getResource(); + + try + { + String setKey = "servertransfers"; + String dataKey = concatenate(setKey, serverTransfer.getPlayerName()); + String serializedTransfer = Utility.serialize(serverTransfer); + + Transaction transaction = jedis.multi(); + transaction.sadd(setKey, serverTransfer.getPlayerName()); + transaction.set(dataKey, serializedTransfer); + transaction.exec(); + } + finally + { + _jedisPool.returnResource(jedis); + } + } + + /** + * Remove an existing {@link ServerTransfer} from this repository whose + * stored {@code playerName} matches the passed in name. + * @param playerName - the name of the player whose active {@link ServerTransfer} + * is to be removed. + * @return true, if the {@link ServerTransfer} belonging to player with matching + * {@code playerName} was successfully removed, false otherwise. + */ + public boolean removeServerTransfer(String playerName) + { + boolean removedTransfer = false; + Jedis jedis = _jedisPool.getResource(); + + try + { + String setKey = "servertransfers"; + String dataKey = concatenate(setKey, playerName); + + if (jedis.sismember(setKey, playerName)) + { + Transaction transaction = jedis.multi(); + transaction.srem(setKey, playerName); + transaction.del(dataKey); + transaction.exec(); + removedTransfer = true; + } + } + finally + { + _jedisPool.returnResource(jedis); + } + + return removedTransfer; + } + + /** + * @param elements - the elements to concatenate together + * @return the concatenated form of all {@code elements} + * separated by the delimiter {@value KEY_DELIMITER}. + */ + protected String concatenate(String... elements) + { + return Utility.concatenate(KEY_DELIMITER, elements); + } + + /* + * 'servertransfers' contains a set of player names for players with an active server transfer + * 'servertransfers.' contains the JSON serialized 'ServerTransfer' object holding info. + */ +} diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/RedisServerRepository.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/RedisServerRepository.java index a23f72997..7d8cfa140 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/RedisServerRepository.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/RedisServerRepository.java @@ -244,7 +244,26 @@ public class RedisServerRepository implements ServerRepository @Override public int clean() { - // TODO: Clean out expired/dead MinecraftServers. + Jedis jedis = _jedisPool.getResource(); + + try + { + String setKey = concatenate("serverstatus", "minecraft", _region.toString()); + for (String deadName : getDeadNames(setKey)) + { + String dataKey = concatenate(setKey, deadName); + + Transaction transaction = jedis.multi(); + transaction.del(dataKey); + transaction.zrem(setKey, deadName); + transaction.exec(); + } + } + finally + { + _jedisPool.returnResource(jedis); + } + return 0; } @@ -272,6 +291,29 @@ public class RedisServerRepository implements ServerRepository return names; } + /** + * @param key - the key where the sorted set of server sessions is stored + * @return the {@link Set} of dead (expired) server names stored at {@code key}. + */ + protected Set getDeadNames(String key) + { + Set names = new HashSet(); + Jedis jedis = _jedisPool.getResource(); + + try + { + String min = "-inf"; + String max = System.currentTimeMillis() + ""; + names = jedis.zrangeByScore(key, min, max); + } + finally + { + _jedisPool.returnResource(jedis); + } + + return names; + } + /** * @param elements - the elements to concatenate together * @return the concatenated form of all {@code elements}