diff --git a/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java b/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeBungeeListener.java similarity index 95% rename from RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java rename to RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeBungeeListener.java index 245e8516..67e05608 100644 --- a/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java +++ b/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeBungeeListener.java @@ -26,10 +26,10 @@ import java.net.InetAddress; import java.util.*; -public class RedisBungeeListener extends AbstractRedisBungeeListener implements Listener { +public class RedisBungeeBungeeListener extends AbstractRedisBungeeListener implements Listener { - public RedisBungeeListener(RedisBungeePlugin plugin, List exemptAddresses) { + public RedisBungeeBungeeListener(RedisBungeePlugin plugin, List exemptAddresses) { super(plugin, exemptAddresses); } @@ -194,7 +194,7 @@ public void onPluginMessage(PluginMessageEvent event) { String user = in.readUTF(); out.writeUTF("LastOnline"); out.writeUTF(user); - out.writeLong(plugin.getApi().getLastOnline(plugin.getUuidTranslator().getTranslatedUuid(user, true))); + out.writeLong(plugin.getApi().getLastOnline(Objects.requireNonNull(plugin.getUuidTranslator().getTranslatedUuid(user, true)))); break; case "ServerPlayers": String type1 = in.readUTF(); @@ -235,7 +235,7 @@ public void onPluginMessage(PluginMessageEvent event) { String username = in.readUTF(); out.writeUTF("PlayerProxy"); out.writeUTF(username); - out.writeUTF(plugin.getApi().getProxy(plugin.getUuidTranslator().getTranslatedUuid(username, true))); + out.writeUTF(plugin.getApi().getProxy(Objects.requireNonNull(plugin.getUuidTranslator().getTranslatedUuid(username, true)))); break; default: return; diff --git a/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeBungeePlugin.java b/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeBungeePlugin.java index 31c7c6b0..57c89895 100644 --- a/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeBungeePlugin.java +++ b/RedisBungee-Bungee/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeBungeePlugin.java @@ -7,7 +7,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; import com.google.common.io.ByteStreams; -import com.google.gson.Gson; import com.imaginarycode.minecraft.redisbungee.commands.RedisBungeeCommands; import com.imaginarycode.minecraft.redisbungee.events.PlayerChangedServerNetworkEvent; import com.imaginarycode.minecraft.redisbungee.events.PlayerJoinedNetworkEvent; @@ -397,7 +396,7 @@ public void initialize() { } }, 0, 3, TimeUnit.SECONDS); dataManager = new BungeeDataManager(this); - getProxy().getPluginManager().registerListener(this, new RedisBungeeListener(this, configuration.getExemptAddresses())); + getProxy().getPluginManager().registerListener(this, new RedisBungeeBungeeListener(this, configuration.getExemptAddresses())); getProxy().getPluginManager().registerListener(this, dataManager); psl = new PubSubListener(this); getProxy().getScheduler().runAsync(this, psl); diff --git a/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java b/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityListener.java similarity index 54% rename from RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java rename to RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityListener.java index c85b1362..04184dc4 100644 --- a/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeListener.java +++ b/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityListener.java @@ -1,5 +1,11 @@ package com.imaginarycode.minecraft.redisbungee; +import com.google.common.base.Joiner; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.io.ByteArrayDataInput; +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; import com.imaginarycode.minecraft.redisbungee.internal.AbstractRedisBungeeListener; import com.imaginarycode.minecraft.redisbungee.internal.AbstractDataManager; import com.imaginarycode.minecraft.redisbungee.internal.RedisBungeePlugin; @@ -18,6 +24,7 @@ import com.velocitypowered.api.event.proxy.ProxyPingEvent; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ServerConnection; +import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier; import com.velocitypowered.api.proxy.server.ServerPing; import net.kyori.adventure.text.Component; import redis.clients.jedis.Jedis; @@ -26,10 +33,10 @@ import java.net.InetAddress; import java.util.*; -public class RedisBungeeListener extends AbstractRedisBungeeListener { +public class RedisBungeeVelocityListener extends AbstractRedisBungeeListener { - public RedisBungeeListener(RedisBungeePlugin plugin, List exemptAddresses) { + public RedisBungeeVelocityListener(RedisBungeePlugin plugin, List exemptAddresses) { super(plugin, exemptAddresses); } @@ -136,12 +143,106 @@ public void onPing(ProxyPingEvent event) { } @Override + @SuppressWarnings("UnstableApiUsage") public void onPluginMessage(PluginMessageEvent event) { - /* - * Ham1255 note: for some reason plugin messages were not working in velocity? - * not sure how to fix, but for now i have removed the code until a fix is made. - * - */ + if ((event.getIdentifier().getId().equals("legacy:redisbungee") || event.getIdentifier().getId().equals("RedisBungee")) && event.getSource() instanceof ServerConnection) { + final String currentChannel = event.getIdentifier().getId(); + final byte[] data = Arrays.copyOf(event.getData(), event.getData().length); + plugin.executeAsync(() -> { + ByteArrayDataInput in = ByteStreams.newDataInput(data); + + String subchannel = in.readUTF(); + ByteArrayDataOutput out = ByteStreams.newDataOutput(); + String type; + + switch (subchannel) { + case "PlayerList": + out.writeUTF("PlayerList"); + Set original = Collections.emptySet(); + type = in.readUTF(); + if (type.equals("ALL")) { + out.writeUTF("ALL"); + original = plugin.getPlayers(); + } else { + try { + original = plugin.getApi().getPlayersOnServer(type); + } catch (IllegalArgumentException ignored) { + } + } + Set players = new HashSet<>(); + for (UUID uuid : original) + players.add(plugin.getUuidTranslator().getNameFromUuid(uuid, false)); + out.writeUTF(Joiner.on(',').join(players)); + break; + case "PlayerCount": + out.writeUTF("PlayerCount"); + type = in.readUTF(); + if (type.equals("ALL")) { + out.writeUTF("ALL"); + out.writeInt(plugin.getCount()); + } else { + out.writeUTF(type); + try { + out.writeInt(plugin.getApi().getPlayersOnServer(type).size()); + } catch (IllegalArgumentException e) { + out.writeInt(0); + } + } + break; + case "LastOnline": + String user = in.readUTF(); + out.writeUTF("LastOnline"); + out.writeUTF(user); + out.writeLong(plugin.getApi().getLastOnline(Objects.requireNonNull(plugin.getUuidTranslator().getTranslatedUuid(user, true)))); + break; + case "ServerPlayers": + String type1 = in.readUTF(); + out.writeUTF("ServerPlayers"); + Multimap multimap = plugin.getApi().getServerToPlayers(); + + boolean includesUsers; + + switch (type1) { + case "COUNT": + includesUsers = false; + break; + case "PLAYERS": + includesUsers = true; + break; + default: + // TODO: Should I raise an error? + return; + } + + out.writeUTF(type1); + + if (includesUsers) { + Multimap human = HashMultimap.create(); + for (Map.Entry entry : multimap.entries()) { + human.put(entry.getKey(), plugin.getUuidTranslator().getNameFromUuid(entry.getValue(), false)); + } + serializeMultimap(human, true, out); + } else { + serializeMultiset(multimap.keys(), out); + } + break; + case "Proxy": + out.writeUTF("Proxy"); + out.writeUTF(plugin.getConfiguration().getServerId()); + break; + case "PlayerProxy": + String username = in.readUTF(); + out.writeUTF("PlayerProxy"); + out.writeUTF(username); + out.writeUTF(plugin.getApi().getProxy(Objects.requireNonNull(plugin.getUuidTranslator().getTranslatedUuid(username, true)))); + break; + default: + return; + } + + ((ServerConnection) event.getSource()).sendPluginMessage(new LegacyChannelIdentifier(currentChannel), out.toByteArray()); + }); + } } @@ -153,7 +254,7 @@ public void onPubSubMessage(PubSubMessageEvent event) { if (message.startsWith("/")) message = message.substring(1); plugin.logInfo("Invoking command via PubSub: /" + message); - ((RedisBungeeVelocityPlugin)plugin).getProxy().getCommandManager().executeAsync(RedisBungeeCommandSource.getSingleton(), message);//.dispatchCommand(RedisBungeeCommandSource.getSingleton(), message); + ((RedisBungeeVelocityPlugin) plugin).getProxy().getCommandManager().executeAsync(RedisBungeeCommandSource.getSingleton(), message);//.dispatchCommand(RedisBungeeCommandSource.getSingleton(), message); } } diff --git a/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityPlugin.java b/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityPlugin.java index 956f8b86..7f7308e4 100644 --- a/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityPlugin.java +++ b/RedisBungee-Velocity/src/main/java/com/imaginarycode/minecraft/redisbungee/RedisBungeeVelocityPlugin.java @@ -29,6 +29,8 @@ import com.velocitypowered.api.plugin.annotation.DataDirectory; import com.velocitypowered.api.proxy.Player; import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier; +import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier; import com.velocitypowered.api.scheduler.ScheduledTask; import ninja.leaping.configurate.ConfigurationNode; import ninja.leaping.configurate.objectmapping.ObjectMappingException; @@ -409,7 +411,7 @@ public void initialize() { } }).repeat(3, TimeUnit.SECONDS).schedule(); - getProxy().getEventManager().register(this, new RedisBungeeListener(this, configuration.getExemptAddresses())); + getProxy().getEventManager().register(this, new RedisBungeeVelocityListener(this, configuration.getExemptAddresses())); getProxy().getEventManager().register(this, dataManager); getProxy().getScheduler().buildTask(this, psl).schedule(); integrityCheck = getProxy().getScheduler().buildTask(this, () -> { @@ -473,10 +475,10 @@ public void initialize() { } }).repeat(1, TimeUnit.MINUTES).schedule(); - // plugin messages are disabled for now - //getProxy().registerChannel("legacy:redisbungee"); - //getProxy().registerChannel("RedisBungee"); + getProxy().getChannelRegistrar().register(new LegacyChannelIdentifier("RedisBungee")); + getProxy().getChannelRegistrar().register(new LegacyChannelIdentifier("legacy:redisbungee")); + getProxy().getChannelRegistrar().register(MinecraftChannelIdentifier.create("legacy", "redisbungee")); // register commands // those still bungeecord commands will migrate them later. // if (configuration.doOverrideBungeeCommands()) {