From c848126aa7016044a96e867e2c5947b227d27e08 Mon Sep 17 00:00:00 2001 From: mohammed jasem alaajel Date: Tue, 19 Jul 2022 15:30:45 +0400 Subject: [PATCH] Implement network kick --- .../minecraft/redisbungee/RedisBungeeAPI.java | 24 ++++ .../redisbungee/api/AbstractDataManager.java | 104 ++++++++++-------- .../api/AbstractRedisBungeeListener.java | 2 + .../redisbungee/api/RedisBungeePlugin.java | 4 + .../redisbungee/api/util/RedisUtil.java | 39 ------- .../api/util/payload/PayloadUtils.java | 65 +++++++++++ .../redisbungee/BungeeDataManager.java | 13 +++ .../RedisBungeeBungeeListener.java | 6 +- .../redisbungee/RedisBungeeBungeePlugin.java | 37 ++++++- .../RedisBungeeVelocityListener.java | 6 +- .../RedisBungeeVelocityPlugin.java | 42 +++++-- .../redisbungee/VelocityDataManager.java | 16 +++ .../commands/RedisBungeeCommands.java | 2 + 13 files changed, 255 insertions(+), 105 deletions(-) create mode 100644 RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/util/payload/PayloadUtils.java diff --git a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeAPI.java b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeAPI.java index f027dd3..856bb4f 100644 --- a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeAPI.java +++ b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeAPI.java @@ -333,6 +333,30 @@ public class RedisBungeeAPI { return plugin.getUuidTranslator().getTranslatedUuid(name, expensiveLookups); } + + /** + * Kicks a player from the network + * + * @param playerName player name + * @param message kick message that player will see on kick + * @since 0.8.0 + */ + + public void kickPlayer(String playerName, String message) { + plugin.kickPlayer(playerName, message); + } + + /** + * Kicks a player from the network + * + * @param playerUUID player name + * @param message kick message that player will see on kick + * @since 0.8.0 + */ + public void kickPlayer(UUID playerUUID, String message) { + plugin.kickPlayer(playerUUID, message); + } + /** * This gives you instance of Jedis * diff --git a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/AbstractDataManager.java b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/AbstractDataManager.java index 391a9dd..61fe40e 100644 --- a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/AbstractDataManager.java +++ b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/AbstractDataManager.java @@ -25,7 +25,7 @@ import java.util.concurrent.TimeUnit; * @since 0.3.3 */ public abstract class AbstractDataManager { - private final RedisBungeePlugin

plugin; + protected final RedisBungeePlugin

plugin; private final Cache serverCache = createCache(); private final Cache proxyCache = createCache(); private final Cache ipCache = createCache(); @@ -44,8 +44,6 @@ public abstract class AbstractDataManager { .build(); } - private final JsonParser parser = new JsonParser(); - public String getServer(final UUID uuid) { P player = plugin.getPlayer(uuid); @@ -174,14 +172,16 @@ public abstract class AbstractDataManager { public abstract void onPubSubMessage(PS event); + public abstract boolean handleKick(UUID target, String message); + protected void handlePubSubMessage(String channel, String message) { if (!channel.equals("redisbungee-data")) return; // Partially deserialize the message so we can look at the action - JsonObject jsonObject = parser.parse(message).getAsJsonObject(); + JsonObject jsonObject = JsonParser.parseString(message).getAsJsonObject(); - String source = jsonObject.get("source").getAsString(); + final String source = jsonObject.get("source").getAsString(); if (source.equals(plugin.getConfiguration().getProxyId())) return; @@ -190,24 +190,20 @@ public abstract class AbstractDataManager { switch (action) { case JOIN: - final DataManagerMessage message1 = gson.fromJson(jsonObject, new TypeToken>() { - }.getType()); + final DataManagerMessage message1 = gson.fromJson(jsonObject, new TypeToken>() {}.getType()); proxyCache.put(message1.getTarget(), message1.getSource()); lastOnlineCache.put(message1.getTarget(), (long) 0); ipCache.put(message1.getTarget(), message1.getPayload().getAddress()); - plugin.executeAsync(new Runnable() { - @Override - public void run() { - Object event; - try { - event = plugin.getNetworkJoinEventClass().getDeclaredConstructor(UUID.class).newInstance(message1.getTarget()); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | - NoSuchMethodException e) { - throw new RuntimeException("unable to dispatch an network join event", e); - } - plugin.callEvent(event); - + plugin.executeAsync(() -> { + Object event; + try { + event = plugin.getNetworkJoinEventClass().getDeclaredConstructor(UUID.class).newInstance(message1.getTarget()); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException e) { + throw new RuntimeException("unable to dispatch an network join event", e); } + plugin.callEvent(event); + }); break; case LEAVE: @@ -215,42 +211,40 @@ public abstract class AbstractDataManager { }.getType()); invalidate(message2.getTarget()); lastOnlineCache.put(message2.getTarget(), message2.getPayload().getTimestamp()); - plugin.executeAsync(new Runnable() { - @Override - public void run() { - Object event; - try { - event = plugin.getNetworkQuitEventClass().getDeclaredConstructor(UUID.class).newInstance(message2.getTarget()); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | - NoSuchMethodException e) { - throw new RuntimeException("unable to dispatch an network quit event", e); - } - plugin.callEvent(event); + plugin.executeAsync(() -> { + Object event; + try { + event = plugin.getNetworkQuitEventClass().getDeclaredConstructor(UUID.class).newInstance(message2.getTarget()); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException e) { + throw new RuntimeException("unable to dispatch an network quit event", e); } + plugin.callEvent(event); }); break; case SERVER_CHANGE: - final DataManagerMessage message3 = gson.fromJson(jsonObject, new TypeToken>() { - }.getType()); + final DataManagerMessage message3 = gson.fromJson(jsonObject, new TypeToken>() {}.getType()); serverCache.put(message3.getTarget(), message3.getPayload().getServer()); - plugin.executeAsync(new Runnable() { - @Override - public void run() { - Object event; - try { - event = plugin.getServerChangeEventClass().getDeclaredConstructor(UUID.class, String.class, String.class).newInstance(message3.getTarget(), ((ServerChangePayload) message3.getPayload()).getOldServer(), ((ServerChangePayload) message3.getPayload()).getServer()); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | - NoSuchMethodException e) { - throw new RuntimeException("unable to dispatch an server change event", e); - } - plugin.callEvent(event); + plugin.executeAsync(() -> { + Object event; + try { + event = plugin.getServerChangeEventClass().getDeclaredConstructor(UUID.class, String.class, String.class).newInstance(message3.getTarget(), ((ServerChangePayload) message3.getPayload()).getOldServer(), ((ServerChangePayload) message3.getPayload()).getServer()); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException e) { + throw new RuntimeException("unable to dispatch an server change event", e); } + plugin.callEvent(event); }); break; + case KICK: + final DataManagerMessage kickPayload = gson.fromJson(jsonObject, new TypeToken>() {}.getType()); + plugin.executeAsync(() -> handleKick(kickPayload.target, kickPayload.payload.message)); + break; + } } - public static class DataManagerMessage { + public static class DataManagerMessage { private final UUID target; private final String source; private final Action action; // for future use! @@ -282,11 +276,27 @@ public abstract class AbstractDataManager { public enum Action { JOIN, LEAVE, + KICK, SERVER_CHANGE } } - public static class LoginPayload { + public static abstract class Payload {} + + public static class KickPayload extends Payload { + + private final String message; + + public KickPayload(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + } + + public static class LoginPayload extends Payload{ private final InetAddress address; public LoginPayload(InetAddress address) { @@ -298,7 +308,7 @@ public abstract class AbstractDataManager { } } - public static class ServerChangePayload { + public static class ServerChangePayload extends Payload{ private final String server; private final String oldServer; @@ -317,7 +327,7 @@ public abstract class AbstractDataManager { } - public static class LogoutPayload { + public static class LogoutPayload extends Payload{ private final long timestamp; public LogoutPayload(long timestamp) { diff --git a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/AbstractRedisBungeeListener.java b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/AbstractRedisBungeeListener.java index 753207a..f88fc40 100644 --- a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/AbstractRedisBungeeListener.java +++ b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/AbstractRedisBungeeListener.java @@ -67,4 +67,6 @@ public abstract class AbstractRedisBungeeListener { } public abstract void onPubSubMessage(PS event); + + } diff --git a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/RedisBungeePlugin.java b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/RedisBungeePlugin.java index 09827c0..3b49d24 100644 --- a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/RedisBungeePlugin.java +++ b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/RedisBungeePlugin.java @@ -94,6 +94,10 @@ public interface RedisBungeePlugin

extends EventsPlatform { void loadConfig() throws Exception; + void kickPlayer(UUID playerUniqueId, String message); + + void kickPlayer(String playerName, String message); + RedisBungeeMode getRedisBungeeMode(); Long getRedisClusterTime(); diff --git a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/util/RedisUtil.java b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/util/RedisUtil.java index 6abee82..c2c3c21 100644 --- a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/util/RedisUtil.java +++ b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/util/RedisUtil.java @@ -1,48 +1,9 @@ package com.imaginarycode.minecraft.redisbungee.api.util; import com.google.common.annotations.VisibleForTesting; -import com.google.gson.Gson; -import com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI; -import com.imaginarycode.minecraft.redisbungee.api.AbstractDataManager; -import redis.clients.jedis.Jedis; -import redis.clients.jedis.JedisCluster; -import redis.clients.jedis.Pipeline; - -import java.util.UUID; @VisibleForTesting public class RedisUtil { - private static final Gson gson = new Gson(); - - public static void cleanUpPlayer(String player, Jedis rsc) { - rsc.srem("proxy:" + RedisBungeeAPI.getRedisBungeeApi().getProxyId() + ":usersOnline", player); - rsc.hdel("player:" + player, "server", "ip", "proxy"); - long timestamp = System.currentTimeMillis(); - rsc.hset("player:" + player, "online", String.valueOf(timestamp)); - rsc.publish("redisbungee-data", gson.toJson(new AbstractDataManager.DataManagerMessage<>( - UUID.fromString(player), RedisBungeeAPI.getRedisBungeeApi().getProxyId(), AbstractDataManager.DataManagerMessage.Action.LEAVE, - new AbstractDataManager.LogoutPayload(timestamp)))); - } - - public static void cleanUpPlayer(String player, Pipeline rsc) { - rsc.srem("proxy:" + RedisBungeeAPI.getRedisBungeeApi().getProxyId() + ":usersOnline", player); - rsc.hdel("player:" + player, "server", "ip", "proxy"); - long timestamp = System.currentTimeMillis(); - rsc.hset("player:" + player, "online", String.valueOf(timestamp)); - rsc.publish("redisbungee-data", gson.toJson(new AbstractDataManager.DataManagerMessage<>( - UUID.fromString(player), RedisBungeeAPI.getRedisBungeeApi().getProxyId(), AbstractDataManager.DataManagerMessage.Action.LEAVE, - new AbstractDataManager.LogoutPayload(timestamp)))); - } - public static void cleanUpPlayer(String player, JedisCluster rsc) { - rsc.srem("proxy:" + RedisBungeeAPI.getRedisBungeeApi().getProxyId() + ":usersOnline", player); - rsc.hdel("player:" + player, "server", "ip", "proxy"); - long timestamp = System.currentTimeMillis(); - rsc.hset("player:" + player, "online", String.valueOf(timestamp)); - rsc.publish("redisbungee-data", gson.toJson(new AbstractDataManager.DataManagerMessage<>( - UUID.fromString(player), RedisBungeeAPI.getRedisBungeeApi().getProxyId(), AbstractDataManager.DataManagerMessage.Action.LEAVE, - new AbstractDataManager.LogoutPayload(timestamp)))); - } - public static boolean isRedisVersionRight(String redisVersion) { String[] args = redisVersion.split("\\."); if (args.length < 2) { diff --git a/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/util/payload/PayloadUtils.java b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/util/payload/PayloadUtils.java new file mode 100644 index 0000000..b077082 --- /dev/null +++ b/RedisBungee-API/src/main/java/com/imaginarycode/minecraft/redisbungee/api/util/payload/PayloadUtils.java @@ -0,0 +1,65 @@ +package com.imaginarycode.minecraft.redisbungee.api.util.payload; + +import com.google.gson.Gson; +import com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI; +import com.imaginarycode.minecraft.redisbungee.api.AbstractDataManager; +import redis.clients.jedis.Jedis; +import redis.clients.jedis.JedisCluster; +import redis.clients.jedis.Pipeline; + +import java.util.UUID; + +public class PayloadUtils { + private static final Gson gson = new Gson(); + + public static void cleanUpPlayer(String uuid, Jedis rsc) { + rsc.srem("proxy:" + RedisBungeeAPI.getRedisBungeeApi().getProxyId() + ":usersOnline", uuid); + rsc.hdel("player:" + uuid, "server", "ip", "proxy"); + long timestamp = System.currentTimeMillis(); + rsc.hset("player:" + uuid, "online", String.valueOf(timestamp)); + rsc.publish("redisbungee-data", gson.toJson(new AbstractDataManager.DataManagerMessage<>( + UUID.fromString(uuid), RedisBungeeAPI.getRedisBungeeApi().getProxyId(), AbstractDataManager.DataManagerMessage.Action.LEAVE, + new AbstractDataManager.LogoutPayload(timestamp)))); + } + + public static void cleanUpPlayer(String uuid, Pipeline rsc) { + rsc.srem("proxy:" + RedisBungeeAPI.getRedisBungeeApi().getProxyId() + ":usersOnline", uuid); + rsc.hdel("player:" + uuid, "server", "ip", "proxy"); + long timestamp = System.currentTimeMillis(); + rsc.hset("player:" + uuid, "online", String.valueOf(timestamp)); + rsc.publish("redisbungee-data", gson.toJson(new AbstractDataManager.DataManagerMessage<>( + UUID.fromString(uuid), RedisBungeeAPI.getRedisBungeeApi().getProxyId(), AbstractDataManager.DataManagerMessage.Action.LEAVE, + new AbstractDataManager.LogoutPayload(timestamp)))); + } + + public static void cleanUpPlayer(String uuid, JedisCluster rsc) { + rsc.srem("proxy:" + RedisBungeeAPI.getRedisBungeeApi().getProxyId() + ":usersOnline", uuid); + rsc.hdel("player:" + uuid, "server", "ip", "proxy"); + long timestamp = System.currentTimeMillis(); + rsc.hset("player:" + uuid, "online", String.valueOf(timestamp)); + rsc.publish("redisbungee-data", gson.toJson(new AbstractDataManager.DataManagerMessage<>( + UUID.fromString(uuid), RedisBungeeAPI.getRedisBungeeApi().getProxyId(), AbstractDataManager.DataManagerMessage.Action.LEAVE, + new AbstractDataManager.LogoutPayload(timestamp)))); + } + + public static void kickPlayer(UUID uuid, String message, Pipeline pipeline) { + System.out.println(uuid); + pipeline.publish("redisbungee-data", gson.toJson(new AbstractDataManager.DataManagerMessage<>( + uuid, RedisBungeeAPI.getRedisBungeeApi().getProxyId(), AbstractDataManager.DataManagerMessage.Action.KICK, + new AbstractDataManager.KickPayload(message)))); + } + + public static void kickPlayer(UUID uuid, String message, Jedis jedis) { + System.out.println(uuid); + jedis.publish("redisbungee-data", gson.toJson(new AbstractDataManager.DataManagerMessage<>( + uuid, RedisBungeeAPI.getRedisBungeeApi().getProxyId(), AbstractDataManager.DataManagerMessage.Action.KICK, + new AbstractDataManager.KickPayload(message)))); + } + + public static void kickPlayer(UUID uuid, String message, JedisCluster jedisCluster) { + System.out.println(uuid); + jedisCluster.publish("redisbungee-data", gson.toJson(new AbstractDataManager.DataManagerMessage<>( + uuid, RedisBungeeAPI.getRedisBungeeApi().getProxyId(), AbstractDataManager.DataManagerMessage.Action.KICK, + new AbstractDataManager.KickPayload(message)))); + } +} diff --git a/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/BungeeDataManager.java b/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/BungeeDataManager.java index bd9e0f6..806fd8c 100644 --- a/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/BungeeDataManager.java +++ b/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/BungeeDataManager.java @@ -3,12 +3,16 @@ package com.imaginarycode.minecraft.redisbungee; import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent; import com.imaginarycode.minecraft.redisbungee.api.AbstractDataManager; import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.PlayerDisconnectEvent; import net.md_5.bungee.api.event.PostLoginEvent; import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.event.EventHandler; +import java.util.UUID; + public class BungeeDataManager extends AbstractDataManager implements Listener { public BungeeDataManager(RedisBungeePlugin plugin) { @@ -32,4 +36,13 @@ public class BungeeDataManager extends AbstractDataManager 0) { Set players = jedis.smembers("proxy:" + configuration.getProxyId() + ":usersOnline"); for (String member : players) - RedisUtil.cleanUpPlayer(member, jedis); + PayloadUtils.cleanUpPlayer(member, jedis); } return null; } @@ -828,7 +829,7 @@ public class RedisBungeeBungeePlugin extends Plugin implements RedisBungeePlugin if (jedisCluster.scard("proxy:" + configuration.getProxyId() + ":usersOnline") > 0) { Set players = jedisCluster.smembers("proxy:" + configuration.getProxyId() + ":usersOnline"); for (String member : players) - RedisUtil.cleanUpPlayer(member, jedisCluster); + PayloadUtils.cleanUpPlayer(member, jedisCluster); } return null; } @@ -915,6 +916,30 @@ public class RedisBungeeBungeePlugin extends Plugin implements RedisBungeePlugin } } + @Override + public void kickPlayer(UUID playerUniqueId, String message) { + new RedisTask(api) { + @Override + public Void jedisTask(Jedis jedis) { + PayloadUtils.kickPlayer(playerUniqueId, message, jedis); + return null; + } + + @Override + public Void clusterJedisTask(JedisCluster jedisCluster) { + PayloadUtils.kickPlayer(playerUniqueId, message, jedisCluster); + return null; + } + }.execute(); + } + + @Override + public void kickPlayer(String playerName, String message) { + // fetch the uuid + UUID playerUUID = this.uuidTranslator.getTranslatedUuid(playerName,true); + kickPlayer(playerUUID, message); + } + @Override public RedisBungeeMode getRedisBungeeMode() { return this.redisBungeeMode; diff --git a/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityListener.java b/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityListener.java index 74065ff..0fd7c5f 100644 --- a/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityListener.java +++ b/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityListener.java @@ -10,8 +10,8 @@ import com.imaginarycode.minecraft.redisbungee.api.AbstractRedisBungeeListener; import com.imaginarycode.minecraft.redisbungee.api.AbstractDataManager; import com.imaginarycode.minecraft.redisbungee.api.RedisBungeePlugin; import com.imaginarycode.minecraft.redisbungee.api.tasks.RedisTask; +import com.imaginarycode.minecraft.redisbungee.api.util.payload.PayloadUtils; import com.imaginarycode.minecraft.redisbungee.events.PubSubMessageEvent; -import com.imaginarycode.minecraft.redisbungee.api.util.RedisUtil; import com.velocitypowered.api.event.Continuation; import com.velocitypowered.api.event.PostOrder; import com.velocitypowered.api.event.ResultedEvent; @@ -148,14 +148,14 @@ public class RedisBungeeVelocityListener extends AbstractRedisBungeeListener { if (!laggedPlayers.isEmpty()) { getLogger().info("Cleaning up lagged proxy {} ({} players)...", s, laggedPlayers.size()); for (String laggedPlayer : laggedPlayers) { - RedisUtil.cleanUpPlayer(laggedPlayer, jedis); + PayloadUtils.cleanUpPlayer(laggedPlayer, jedis); } } } @@ -714,7 +715,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin { } } if (!found) { - RedisUtil.cleanUpPlayer(member, jedis); + PayloadUtils.cleanUpPlayer(member, jedis); getLogger().warn("Player found in set that was not found locally and globally: {}", member); } else { jedis.srem("proxy:" + configuration.getProxyId() + ":usersOnline", member); @@ -756,7 +757,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin { if (!laggedPlayers.isEmpty()) { getLogger().info("Cleaning up lagged proxy {} ({} players)...", s, laggedPlayers.size()); for (String laggedPlayer : laggedPlayers) { - RedisUtil.cleanUpPlayer(laggedPlayer, jedisCluster); + PayloadUtils.cleanUpPlayer(laggedPlayer, jedisCluster); } } } @@ -777,7 +778,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin { } } if (!found) { - RedisUtil.cleanUpPlayer(member, jedisCluster); + PayloadUtils.cleanUpPlayer(member, jedisCluster); getLogger().warn("Player found in set that was not found locally and globally: {}", member); } else { jedisCluster.srem("proxy:" + configuration.getProxyId() + ":usersOnline", member); @@ -811,7 +812,6 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin { if (configuration.doOverrideBungeeCommands()) { getProxy().getCommandManager().register("glist", new RedisBungeeCommands.GlistCommand(this), "redisbungee", "rglist"); } - getProxy().getCommandManager().register("sendtoall", new RedisBungeeCommands.SendToAll(this), "rsendtoall"); getProxy().getCommandManager().register("serverid", new RedisBungeeCommands.ServerId(this), "rserverid"); getProxy().getCommandManager().register("serverids", new RedisBungeeCommands.ServerIds(this)); @@ -820,6 +820,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin { getProxy().getCommandManager().register("lastseen", new RedisBungeeCommands.LastSeenCommand(this), "rlastseen"); getProxy().getCommandManager().register("ip", new RedisBungeeCommands.IpCommand(this), "playerip", "rip", "rplayerip"); getProxy().getCommandManager().register("find", new RedisBungeeCommands.FindCommand(this), "rfind"); + getProxy().getCommandManager().register("networkkick", new RedisBungeeCommands.KickCommand(this)); } @Override @@ -841,7 +842,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin { if (jedis.scard("proxy:" + configuration.getProxyId() + ":usersOnline") > 0) { Set players = jedis.smembers("proxy:" + configuration.getProxyId() + ":usersOnline"); for (String member : players) - RedisUtil.cleanUpPlayer(member, jedis); + PayloadUtils.cleanUpPlayer(member, jedis); } return null; } @@ -852,7 +853,7 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin { if (jedisCluster.scard("proxy:" + configuration.getProxyId() + ":usersOnline") > 0) { Set players = jedisCluster.smembers("proxy:" + configuration.getProxyId() + ":usersOnline"); for (String member : players) - RedisUtil.cleanUpPlayer(member, jedisCluster); + PayloadUtils.cleanUpPlayer(member, jedisCluster); } return null; } @@ -954,6 +955,33 @@ public class RedisBungeeVelocityPlugin implements RedisBungeePlugin { } } + @Override + public void kickPlayer(UUID playerUniqueId, String message) { + // first handle on origin proxy if player not found publish the payload + if (!dataManager.handleKick(playerUniqueId, message)) { + new RedisTask(api) { + @Override + public Void jedisTask(Jedis jedis) { + PayloadUtils.kickPlayer(playerUniqueId, message, jedis); + return null; + } + + @Override + public Void clusterJedisTask(JedisCluster jedisCluster) { + PayloadUtils.kickPlayer(playerUniqueId, message, jedisCluster); + return null; + } + }.execute(); + } + } + + @Override + public void kickPlayer(String playerName, String message) { + // fetch the uuid + UUID playerUUID = this.uuidTranslator.getTranslatedUuid(playerName,true); + kickPlayer(playerUUID, message); + } + @Override public RedisBungeeMode getRedisBungeeMode() { return this.redisBungeeMode; diff --git a/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/VelocityDataManager.java b/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/VelocityDataManager.java index cf3c82f..f0fdfcf 100644 --- a/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/VelocityDataManager.java +++ b/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/VelocityDataManager.java @@ -7,6 +7,11 @@ import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.connection.DisconnectEvent; import com.velocitypowered.api.event.connection.PostLoginEvent; import com.velocitypowered.api.proxy.Player; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; + +import java.util.UUID; public class VelocityDataManager extends AbstractDataManager { @@ -32,4 +37,15 @@ public class VelocityDataManager extends AbstractDataManager