2022-07-16 12:50:09 +00:00
|
|
|
package com.imaginarycode.minecraft.redisbungee.api;
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
import com.google.common.collect.ImmutableList;
|
|
|
|
import com.google.common.collect.ImmutableMultimap;
|
|
|
|
import com.google.common.collect.ImmutableSet;
|
2022-04-13 13:14:08 +00:00
|
|
|
import com.google.common.collect.Multimap;
|
|
|
|
import com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI;
|
2022-07-22 08:29:39 +00:00
|
|
|
import com.imaginarycode.minecraft.redisbungee.api.config.ConfigLoader;
|
|
|
|
import com.imaginarycode.minecraft.redisbungee.api.config.RedisBungeeConfiguration;
|
2022-07-16 12:50:09 +00:00
|
|
|
import com.imaginarycode.minecraft.redisbungee.api.summoners.Summoner;
|
2022-07-26 06:58:00 +00:00
|
|
|
import com.imaginarycode.minecraft.redisbungee.api.tasks.RedisTask;
|
|
|
|
import com.imaginarycode.minecraft.redisbungee.api.util.RedisUtil;
|
|
|
|
import com.imaginarycode.minecraft.redisbungee.api.util.payload.PayloadUtils;
|
2022-07-16 12:50:09 +00:00
|
|
|
import com.imaginarycode.minecraft.redisbungee.api.util.uuid.UUIDTranslator;
|
2022-07-26 08:40:14 +00:00
|
|
|
import redis.clients.jedis.Protocol;
|
|
|
|
import redis.clients.jedis.UnifiedJedis;
|
2022-07-26 06:58:00 +00:00
|
|
|
import redis.clients.jedis.exceptions.JedisConnectionException;
|
2022-04-13 13:14:08 +00:00
|
|
|
|
|
|
|
import java.net.InetAddress;
|
2022-07-26 06:58:00 +00:00
|
|
|
import java.util.*;
|
2022-04-13 13:14:08 +00:00
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
import static com.google.common.base.Preconditions.checkArgument;
|
|
|
|
|
2022-04-14 10:12:47 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* This Class has all internal methods needed by every redis bungee plugin, and it can be used to implement another platforms than bungeecord
|
|
|
|
*
|
|
|
|
* @author Ham1255
|
|
|
|
* @since 0.7.0
|
|
|
|
*/
|
2022-07-22 08:29:39 +00:00
|
|
|
public interface RedisBungeePlugin<P> extends EventsPlatform, ConfigLoader {
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-07-07 23:23:44 +00:00
|
|
|
default void initialize() {
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-04-13 18:17:38 +00:00
|
|
|
}
|
|
|
|
|
2022-07-06 19:04:09 +00:00
|
|
|
default void stop() {
|
2022-04-13 18:17:38 +00:00
|
|
|
|
|
|
|
}
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-07-16 05:18:33 +00:00
|
|
|
Summoner<?> getSummoner();
|
2022-07-15 22:58:48 +00:00
|
|
|
|
2022-04-13 13:14:08 +00:00
|
|
|
RedisBungeeConfiguration getConfiguration();
|
|
|
|
|
|
|
|
int getCount();
|
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
default int getCurrentCount() {
|
|
|
|
return new RedisTask<Long>(this) {
|
|
|
|
@Override
|
2022-07-26 13:47:18 +00:00
|
|
|
public Long unifiedJedisTask(UnifiedJedis unifiedJedis) {
|
2022-07-26 06:58:00 +00:00
|
|
|
long total = 0;
|
2022-07-26 13:47:18 +00:00
|
|
|
long redisTime = getRedisTime(unifiedJedis);
|
|
|
|
Map<String, String> heartBeats = unifiedJedis.hgetAll("heartbeats");
|
2022-07-26 06:58:00 +00:00
|
|
|
for (Map.Entry<String, String> stringStringEntry : heartBeats.entrySet()) {
|
|
|
|
String k = stringStringEntry.getKey();
|
|
|
|
String v = stringStringEntry.getValue();
|
|
|
|
|
|
|
|
long heartbeatTime = Long.parseLong(v);
|
|
|
|
if (heartbeatTime + 30 >= redisTime) {
|
2022-07-26 13:47:18 +00:00
|
|
|
total = total + unifiedJedis.scard("proxy:" + k + ":usersOnline");
|
2022-07-26 06:58:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
}.execute().intValue();
|
|
|
|
}
|
2022-04-13 18:17:38 +00:00
|
|
|
|
|
|
|
Set<String> getLocalPlayersAsUuidStrings();
|
|
|
|
|
2022-07-07 22:39:05 +00:00
|
|
|
AbstractDataManager<P, ?, ?, ?> getDataManager();
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
default Set<UUID> getPlayers() {
|
|
|
|
return new RedisTask<Set<UUID>>(this) {
|
|
|
|
@Override
|
2022-07-26 13:47:18 +00:00
|
|
|
public Set<UUID> unifiedJedisTask(UnifiedJedis unifiedJedis) {
|
2022-07-26 06:58:00 +00:00
|
|
|
ImmutableSet.Builder<UUID> setBuilder = ImmutableSet.builder();
|
|
|
|
try {
|
|
|
|
List<String> keys = new ArrayList<>();
|
|
|
|
for (String i : getProxiesIds()) {
|
|
|
|
keys.add("proxy:" + i + ":usersOnline");
|
|
|
|
}
|
|
|
|
if (!keys.isEmpty()) {
|
2022-07-26 13:47:18 +00:00
|
|
|
Set<String> users = unifiedJedis.sunion(keys.toArray(new String[0]));
|
2022-07-26 06:58:00 +00:00
|
|
|
if (users != null && !users.isEmpty()) {
|
|
|
|
for (String user : users) {
|
|
|
|
try {
|
|
|
|
setBuilder = setBuilder.add(UUID.fromString(user));
|
|
|
|
} catch (IllegalArgumentException ignored) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (JedisConnectionException e) {
|
|
|
|
// Redis server has disappeared!
|
|
|
|
logFatal("Unable to get connection from pool - did your Redis server go away?");
|
|
|
|
throw new RuntimeException("Unable to get all players online", e);
|
|
|
|
}
|
|
|
|
return setBuilder.build();
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
}
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-07-26 14:42:29 +00:00
|
|
|
RedisBungeeAPI getRedisBungeeApi();
|
2022-04-13 13:14:08 +00:00
|
|
|
|
|
|
|
UUIDTranslator getUuidTranslator();
|
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
Multimap<String, UUID> serverToPlayersCache();
|
|
|
|
|
|
|
|
default Multimap<String, UUID> serversToPlayers() {
|
|
|
|
return new RedisTask<Multimap<String, UUID>>(this) {
|
|
|
|
@Override
|
2022-07-26 13:47:18 +00:00
|
|
|
public Multimap<String, UUID> unifiedJedisTask(UnifiedJedis unifiedJedis) {
|
2022-07-26 06:58:00 +00:00
|
|
|
ImmutableMultimap.Builder<String, UUID> builder = ImmutableMultimap.builder();
|
|
|
|
for (String serverId : getProxiesIds()) {
|
2022-07-26 13:47:18 +00:00
|
|
|
Set<String> players = unifiedJedis.smembers("proxy:" + serverId + ":usersOnline");
|
2022-07-26 06:58:00 +00:00
|
|
|
for (String player : players) {
|
2022-07-26 13:47:18 +00:00
|
|
|
String playerServer = unifiedJedis.hget("player:" + player, "server");
|
2022-07-26 06:58:00 +00:00
|
|
|
if (playerServer == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
builder.put(playerServer, UUID.fromString(player));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return builder.build();
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
}
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
default Set<UUID> getPlayersOnProxy(String proxyId) {
|
|
|
|
checkArgument(getProxiesIds().contains(proxyId), proxyId + " is not a valid proxy ID");
|
|
|
|
return new RedisTask<Set<UUID>>(this) {
|
|
|
|
@Override
|
2022-07-26 13:47:18 +00:00
|
|
|
public Set<UUID> unifiedJedisTask(UnifiedJedis unifiedJedis) {
|
|
|
|
Set<String> users = unifiedJedis.smembers("proxy:" + proxyId + ":usersOnline");
|
2022-07-26 06:58:00 +00:00
|
|
|
ImmutableSet.Builder<UUID> builder = ImmutableSet.builder();
|
|
|
|
for (String user : users) {
|
|
|
|
builder.add(UUID.fromString(user));
|
|
|
|
}
|
|
|
|
return builder.build();
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
}
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
default void sendProxyCommand(String proxyId, String command) {
|
|
|
|
checkArgument(getProxiesIds().contains(proxyId) || proxyId.equals("allservers"), "proxyId is invalid");
|
|
|
|
sendChannelMessage("redisbungee-" + proxyId, command);
|
|
|
|
}
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-07-17 11:38:00 +00:00
|
|
|
List<String> getProxiesIds();
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
default List<String> getCurrentProxiesIds(boolean lagged) {
|
|
|
|
return new RedisTask<List<String>>(this) {
|
|
|
|
@Override
|
2022-07-26 13:47:18 +00:00
|
|
|
public List<String> unifiedJedisTask(UnifiedJedis unifiedJedis) {
|
2022-07-26 06:58:00 +00:00
|
|
|
try {
|
2022-07-26 13:47:18 +00:00
|
|
|
long time = getRedisTime(unifiedJedis);
|
2022-07-26 06:58:00 +00:00
|
|
|
ImmutableList.Builder<String> servers = ImmutableList.builder();
|
2022-07-26 13:47:18 +00:00
|
|
|
Map<String, String> heartbeats = unifiedJedis.hgetAll("heartbeats");
|
2022-07-26 06:58:00 +00:00
|
|
|
for (Map.Entry<String, String> entry : heartbeats.entrySet()) {
|
|
|
|
try {
|
|
|
|
long stamp = Long.parseLong(entry.getValue());
|
|
|
|
if (lagged ? time >= stamp + RedisUtil.PROXY_TIMEOUT : time <= stamp + RedisUtil.PROXY_TIMEOUT) {
|
|
|
|
servers.add(entry.getKey());
|
|
|
|
} else if (time > stamp + RedisUtil.PROXY_TIMEOUT) {
|
|
|
|
logWarn(entry.getKey() + " is " + (time - stamp) + " seconds behind! (Time not synchronized or server down?) and was removed from heartbeat.");
|
2022-07-26 13:47:18 +00:00
|
|
|
unifiedJedis.hdel("heartbeats", entry.getKey());
|
2022-07-26 06:58:00 +00:00
|
|
|
}
|
|
|
|
} catch (NumberFormatException ignored) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return servers.build();
|
|
|
|
} catch (JedisConnectionException e) {
|
|
|
|
logFatal("Unable to fetch server IDs");
|
|
|
|
e.printStackTrace();
|
|
|
|
return Collections.singletonList(getConfiguration().getProxyId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
}
|
2022-04-13 18:17:38 +00:00
|
|
|
|
2022-04-13 13:14:08 +00:00
|
|
|
PubSubListener getPubSubListener();
|
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
default void sendChannelMessage(String channel, String message) {
|
|
|
|
new RedisTask<Void>(this) {
|
|
|
|
@Override
|
2022-07-26 13:47:18 +00:00
|
|
|
public Void unifiedJedisTask(UnifiedJedis unifiedJedis) {
|
2022-07-26 06:58:00 +00:00
|
|
|
try {
|
2022-07-26 13:47:18 +00:00
|
|
|
unifiedJedis.publish(channel, message);
|
2022-07-26 06:58:00 +00:00
|
|
|
} catch (JedisConnectionException e) {
|
|
|
|
// Redis server has disappeared!
|
|
|
|
logFatal("Unable to get connection from pool - did your Redis server go away?");
|
|
|
|
throw new RuntimeException("Unable to publish channel message", e);
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
}
|
2022-04-13 13:14:08 +00:00
|
|
|
|
|
|
|
void executeAsync(Runnable runnable);
|
|
|
|
|
2022-04-13 18:17:38 +00:00
|
|
|
void executeAsyncAfter(Runnable runnable, TimeUnit timeUnit, int time);
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-04-13 18:17:38 +00:00
|
|
|
void callEvent(Object event);
|
2022-04-13 13:14:08 +00:00
|
|
|
|
|
|
|
boolean isOnlineMode();
|
|
|
|
|
|
|
|
void logInfo(String msg);
|
|
|
|
|
|
|
|
void logWarn(String msg);
|
|
|
|
|
|
|
|
void logFatal(String msg);
|
|
|
|
|
|
|
|
P getPlayer(UUID uuid);
|
|
|
|
|
|
|
|
P getPlayer(String name);
|
|
|
|
|
|
|
|
UUID getPlayerUUID(String player);
|
|
|
|
|
|
|
|
String getPlayerName(UUID player);
|
|
|
|
|
|
|
|
String getPlayerServerName(P player);
|
|
|
|
|
|
|
|
boolean isPlayerOnAServer(P player);
|
|
|
|
|
|
|
|
InetAddress getPlayerIp(P player);
|
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
default void sendProxyCommand(String cmd) {
|
|
|
|
sendProxyCommand(getConfiguration().getProxyId(), cmd);
|
|
|
|
}
|
2022-04-13 13:14:08 +00:00
|
|
|
|
2022-07-26 08:40:14 +00:00
|
|
|
default Long getRedisTime(UnifiedJedis unifiedJedis) {
|
|
|
|
List<Object> data = (List<Object>) unifiedJedis.sendCommand(Protocol.Command.TIME);
|
|
|
|
List<String> times = new ArrayList<>();
|
|
|
|
data.forEach((o) -> times.add(new String((byte[])o)));
|
|
|
|
return getRedisTime(times);
|
|
|
|
}
|
2022-07-26 06:58:00 +00:00
|
|
|
default long getRedisTime(List<String> timeRes) {
|
|
|
|
return Long.parseLong(timeRes.get(0));
|
|
|
|
}
|
2022-04-13 18:17:38 +00:00
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
default void kickPlayer(UUID playerUniqueId, String message) {
|
|
|
|
// first handle on origin proxy if player not found publish the payload
|
|
|
|
if (!getDataManager().handleKick(playerUniqueId, message)) {
|
|
|
|
new RedisTask<Void>(this) {
|
|
|
|
@Override
|
2022-07-26 13:47:18 +00:00
|
|
|
public Void unifiedJedisTask(UnifiedJedis unifiedJedis) {
|
|
|
|
PayloadUtils.kickPlayerPayload(playerUniqueId, message, unifiedJedis);
|
2022-07-26 06:58:00 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}.execute();
|
|
|
|
}
|
|
|
|
}
|
2022-07-19 11:30:45 +00:00
|
|
|
|
2022-07-26 06:58:00 +00:00
|
|
|
default void kickPlayer(String playerName, String message) {
|
|
|
|
// fetch the uuid from name
|
|
|
|
UUID playerUUID = getUuidTranslator().getTranslatedUuid(playerName, true);
|
|
|
|
kickPlayer(playerUUID, message);
|
|
|
|
}
|
2022-07-19 11:30:45 +00:00
|
|
|
|
2022-07-16 05:18:33 +00:00
|
|
|
RedisBungeeMode getRedisBungeeMode();
|
|
|
|
|
2022-07-26 08:42:42 +00:00
|
|
|
void updateProxiesIds();
|
2022-07-20 09:21:24 +00:00
|
|
|
|
2022-04-13 13:14:08 +00:00
|
|
|
}
|