146 lines
6.2 KiB
Java
146 lines
6.2 KiB
Java
package com.imaginarycode.minecraft.redisbungee.api.tasks;
|
|
|
|
import com.imaginarycode.minecraft.redisbungee.api.GenericPlayerUtils;
|
|
import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin;
|
|
import redis.clients.jedis.Jedis;
|
|
import redis.clients.jedis.JedisCluster;
|
|
import redis.clients.jedis.Pipeline;
|
|
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.logging.Level;
|
|
|
|
public abstract class IntegrityCheckTask extends RedisTask<Void> {
|
|
|
|
public static int INTERVAL = 30;
|
|
public static TimeUnit TIMEUNIT = TimeUnit.SECONDS;
|
|
|
|
|
|
public IntegrityCheckTask(RedisBungeePlugin<?> plugin) {
|
|
super(plugin);
|
|
}
|
|
|
|
@Override
|
|
public Void jedisTask(Jedis jedis) {
|
|
try {
|
|
Set<String> players = plugin.getLocalPlayersAsUuidStrings();
|
|
Set<String> playersInRedis = jedis.smembers("proxy:" + plugin.getConfiguration().getProxyId() + ":usersOnline");
|
|
List<String> lagged = plugin.getCurrentProxiesIds(true);
|
|
|
|
// Clean up lagged players.
|
|
for (String s : lagged) {
|
|
Set<String> laggedPlayers = jedis.smembers("proxy:" + s + ":usersOnline");
|
|
jedis.del("proxy:" + s + ":usersOnline");
|
|
if (!laggedPlayers.isEmpty()) {
|
|
plugin.logInfo("Cleaning up lagged proxy " + s + " (" + laggedPlayers.size() + " players)...");
|
|
for (String laggedPlayer : laggedPlayers) {
|
|
GenericPlayerUtils.cleanUpPlayer(laggedPlayer, jedis, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
Set<String> absentLocally = new HashSet<>(playersInRedis);
|
|
absentLocally.removeAll(players);
|
|
Set<String> absentInRedis = new HashSet<>(players);
|
|
absentInRedis.removeAll(playersInRedis);
|
|
|
|
for (String member : absentLocally) {
|
|
boolean found = false;
|
|
for (String proxyId : plugin.getProxiesIds()) {
|
|
if (proxyId.equals(plugin.getConfiguration().getProxyId())) continue;
|
|
if (jedis.sismember("proxy:" + proxyId + ":usersOnline", member)) {
|
|
// Just clean up the set.
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
GenericPlayerUtils.cleanUpPlayer(member, jedis, false);
|
|
plugin.logWarn("Player found in set that was not found locally and globally: " + member);
|
|
} else {
|
|
jedis.srem("proxy:" + plugin.getConfiguration().getProxyId() + ":usersOnline", member);
|
|
plugin.logWarn("Player found in set that was not found locally, but is on another proxy: " + member);
|
|
}
|
|
}
|
|
|
|
Pipeline pipeline = jedis.pipelined();
|
|
|
|
for (String player : absentInRedis) {
|
|
// Player not online according to Redis but not BungeeCord.
|
|
plugin.logWarn("Player " + player + " is on the proxy but not in Redis.");
|
|
handlePlatformPlayer(player, pipeline);
|
|
}
|
|
|
|
pipeline.sync();
|
|
} catch (Throwable e) {
|
|
plugin.logFatal("Unable to fix up stored player data");
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
public Void clusterJedisTask(JedisCluster jedisCluster) {
|
|
try {
|
|
Set<String> players = plugin.getLocalPlayersAsUuidStrings();
|
|
Set<String> playersInRedis = jedisCluster.smembers("proxy:" + plugin.getConfiguration().getProxyId() + ":usersOnline");
|
|
List<String> lagged = plugin.getCurrentProxiesIds(true);
|
|
|
|
// Clean up lagged players.
|
|
for (String s : lagged) {
|
|
Set<String> laggedPlayers = jedisCluster.smembers("proxy:" + s + ":usersOnline");
|
|
jedisCluster.del("proxy:" + s + ":usersOnline");
|
|
if (!laggedPlayers.isEmpty()) {
|
|
plugin.logInfo("Cleaning up lagged proxy " + s + " (" + laggedPlayers.size() + " players)...");
|
|
for (String laggedPlayer : laggedPlayers) {
|
|
GenericPlayerUtils.cleanUpPlayer(laggedPlayer, jedisCluster, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
Set<String> absentLocally = new HashSet<>(playersInRedis);
|
|
absentLocally.removeAll(players);
|
|
Set<String> absentInRedis = new HashSet<>(players);
|
|
absentInRedis.removeAll(playersInRedis);
|
|
|
|
for (String member : absentLocally) {
|
|
boolean found = false;
|
|
for (String proxyId : plugin.getProxiesIds()) {
|
|
if (proxyId.equals(plugin.getConfiguration().getProxyId())) continue;
|
|
if (jedisCluster.sismember("proxy:" + proxyId + ":usersOnline", member)) {
|
|
// Just clean up the set.
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
GenericPlayerUtils.cleanUpPlayer(member, jedisCluster, false);
|
|
plugin.logWarn("Player found in set that was not found locally and globally: " + member);
|
|
} else {
|
|
jedisCluster.srem("proxy:" + plugin.getConfiguration().getProxyId() + ":usersOnline", member);
|
|
plugin.logWarn("Player found in set that was not found locally, but is on another proxy: " + member);
|
|
}
|
|
}
|
|
// due JedisCluster does not support pipelined.
|
|
//Pipeline pipeline = jedis.pipelined();
|
|
|
|
for (String player : absentInRedis) {
|
|
// Player not online according to Redis but not BungeeCord.
|
|
handlePlatformPlayer(player, jedisCluster);
|
|
}
|
|
} catch (Throwable e) {
|
|
plugin.logFatal("Unable to fix up stored player data");
|
|
e.printStackTrace();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
public abstract void handlePlatformPlayer(String player, JedisCluster jedisCluster);
|
|
|
|
public abstract void handlePlatformPlayer(String player, Pipeline pipeline);
|
|
}
|