2
0
mirror of https://github.com/proxiodev/RedisBungee.git synced 2024-11-23 04:28:01 +00:00

more progress

This commit is contained in:
mohammed jasem alaajel 2022-04-13 20:22:07 +04:00
parent 17fdeda147
commit 9f09ed21f1
4 changed files with 164 additions and 10 deletions

View File

@ -38,7 +38,7 @@ public abstract class AbstractRedisBungeeListener<LE, PLE, PD, SC, PP, PM, PS> {
public abstract void onPluginMessage(PM event); public abstract void onPluginMessage(PM event);
private void serializeMultiset(Multiset<String> collection, ByteArrayDataOutput output) { protected void serializeMultiset(Multiset<String> collection, ByteArrayDataOutput output) {
output.writeInt(collection.elementSet().size()); output.writeInt(collection.elementSet().size());
for (Multiset.Entry<String> entry : collection.entrySet()) { for (Multiset.Entry<String> entry : collection.entrySet()) {
output.writeUTF(entry.getElement()); output.writeUTF(entry.getElement());
@ -47,7 +47,7 @@ public abstract class AbstractRedisBungeeListener<LE, PLE, PD, SC, PP, PM, PS> {
} }
@SuppressWarnings("SameParameterValue") @SuppressWarnings("SameParameterValue")
private void serializeMultimap(Multimap<String, String> collection, boolean includeNames, ByteArrayDataOutput output) { protected void serializeMultimap(Multimap<String, String> collection, boolean includeNames, ByteArrayDataOutput output) {
output.writeInt(collection.keySet().size()); output.writeInt(collection.keySet().size());
for (Map.Entry<String, Collection<String>> entry : collection.asMap().entrySet()) { for (Map.Entry<String, Collection<String>> entry : collection.asMap().entrySet()) {
output.writeUTF(entry.getKey()); output.writeUTF(entry.getKey());

View File

@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
* *
* @since 0.3.3 * @since 0.3.3
*/ */
public abstract class DataManager<P, PS, PL, PD> { public abstract class DataManager<P, PL, PD, PS> {
private final RedisBungeePlugin<P> plugin; private final RedisBungeePlugin<P> plugin;
private final Cache<UUID, String> serverCache = createCache(); private final Cache<UUID, String> serverCache = createCache();
private final Cache<UUID, String> proxyCache = createCache(); private final Cache<UUID, String> proxyCache = createCache();
@ -141,16 +141,15 @@ public abstract class DataManager<P, PS, PL, PD> {
} }
} }
private void invalidate(UUID uuid) { protected void invalidate(UUID uuid) {
ipCache.invalidate(uuid); ipCache.invalidate(uuid);
lastOnlineCache.invalidate(uuid); lastOnlineCache.invalidate(uuid);
serverCache.invalidate(uuid); serverCache.invalidate(uuid);
proxyCache.invalidate(uuid); proxyCache.invalidate(uuid);
} }
// Invalidate all entries related to this player, since they now lie. (call invalidate(uuid))
public abstract void onPostLogin(PL event); public abstract void onPostLogin(PL event);
// Invalidate all entries related to this player, since they now lie. (call invalidate(uuid))
public abstract void onPlayerDisconnect(PD event); public abstract void onPlayerDisconnect(PD event);
public abstract void onPubSubMessage(PS event); public abstract void onPubSubMessage(PS event);
@ -285,7 +284,7 @@ public abstract class DataManager<P, PS, PL, PD> {
private final String server; private final String server;
private final String oldServer; private final String oldServer;
ServerChangePayload(String server, String oldServer) { public ServerChangePayload(String server, String oldServer) {
this.server = server; this.server = server;
this.oldServer = oldServer; this.oldServer = oldServer;
} }

View File

@ -0,0 +1,30 @@
package com.imaginarycode.minecraft.redisbungee;
import com.imaginarycode.minecraft.redisbungee.events.bungee.PubSubMessageEvent;
import com.imaginarycode.minecraft.redisbungee.internal.DataManager;
import com.imaginarycode.minecraft.redisbungee.internal.RedisBungeePlugin;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
import net.md_5.bungee.api.event.PostLoginEvent;
public class BungeeDataManager extends DataManager<ProxiedPlayer, PostLoginEvent, PlayerDisconnectEvent, PubSubMessageEvent> {
public BungeeDataManager(RedisBungeePlugin<ProxiedPlayer> plugin) {
super(plugin);
}
@Override
public void onPostLogin(PostLoginEvent event) {
invalidate(event.getPlayer().getUniqueId());
}
@Override
public void onPlayerDisconnect(PlayerDisconnectEvent event) {
invalidate(event.getPlayer().getUniqueId());
}
@Override
public void onPubSubMessage(PubSubMessageEvent event) {
handlePubSubMessage(event.getChannel(), event.getMessage());
}
}

View File

@ -1,12 +1,21 @@
package com.imaginarycode.minecraft.redisbungee; 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.AbstractRedisBungeeListener;
import com.imaginarycode.minecraft.redisbungee.internal.DataManager; import com.imaginarycode.minecraft.redisbungee.internal.DataManager;
import com.imaginarycode.minecraft.redisbungee.internal.RedisBungeePlugin; import com.imaginarycode.minecraft.redisbungee.internal.RedisBungeePlugin;
import com.imaginarycode.minecraft.redisbungee.events.bungee.PubSubMessageEvent; import com.imaginarycode.minecraft.redisbungee.events.bungee.PubSubMessageEvent;
import com.imaginarycode.minecraft.redisbungee.internal.RedisUtil; import com.imaginarycode.minecraft.redisbungee.internal.RedisUtil;
import com.imaginarycode.minecraft.redisbungee.internal.util.RedisCallable; import com.imaginarycode.minecraft.redisbungee.internal.util.RedisCallable;
import net.md_5.bungee.api.AbstractReconnectHandler;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.event.*; import net.md_5.bungee.api.event.*;
import net.md_5.bungee.api.plugin.Listener; import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin; import net.md_5.bungee.api.plugin.Plugin;
@ -15,7 +24,7 @@ import redis.clients.jedis.Jedis;
import redis.clients.jedis.Pipeline; import redis.clients.jedis.Pipeline;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.List; import java.util.*;
public class RedisBungeeListener extends AbstractRedisBungeeListener<LoginEvent, PostLoginEvent, PlayerDisconnectEvent, ServerConnectedEvent, ProxyPingEvent, PluginMessageEvent, PubSubMessageEvent> implements Listener { public class RedisBungeeListener extends AbstractRedisBungeeListener<LoginEvent, PostLoginEvent, PlayerDisconnectEvent, ServerConnectedEvent, ProxyPingEvent, PluginMessageEvent, PubSubMessageEvent> implements Listener {
@ -106,19 +115,135 @@ public class RedisBungeeListener extends AbstractRedisBungeeListener<LoginEvent,
@Override @Override
@EventHandler @EventHandler
public void onServerChange(ServerConnectedEvent event) { public void onServerChange(ServerConnectedEvent event) {
final String currentServer = event.getPlayer().getServer() == null ? null : event.getPlayer().getServer().getInfo().getName();
plugin.executeAsync(new RedisCallable<Void>(plugin) {
@Override
protected Void call(Jedis jedis) {
jedis.hset("player:" + event.getPlayer().getUniqueId().toString(), "server", event.getServer().getInfo().getName());
jedis.publish("redisbungee-data", gson.toJson(new DataManager.DataManagerMessage(
event.getPlayer().getUniqueId(), plugin.getApi().getServerId(), DataManager.DataManagerMessage.Action.SERVER_CHANGE,
new DataManager.ServerChangePayload(event.getServer().getInfo().getName(), currentServer))));
return null;
}
});
} }
@Override @Override
@EventHandler @EventHandler
public void onPing(ProxyPingEvent event) { public void onPing(ProxyPingEvent event) {
if (exemptAddresses.contains(event.getConnection().getAddress().getAddress())) {
return;
}
ServerInfo forced = AbstractReconnectHandler.getForcedHost(event.getConnection());
if (forced != null && event.getConnection().getListener().isPingPassthrough()) {
return;
}
event.getResponse().getPlayers().setOnline(plugin.getCount());
} }
@Override @Override
@SuppressWarnings("UnstableApiUsage")
@EventHandler @EventHandler
public void onPluginMessage(PluginMessageEvent event) { public void onPluginMessage(PluginMessageEvent event) {
if ((event.getTag().equals("legacy:redisbungee") || event.getTag().equals("RedisBungee")) && event.getSender() instanceof Server) {
final String currentChannel = event.getTag();
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<UUID> 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<String> 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(plugin.getUuidTranslator().getTranslatedUuid(user, true)));
break;
case "ServerPlayers":
String type1 = in.readUTF();
out.writeUTF("ServerPlayers");
Multimap<String, UUID> 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<String, String> human = HashMultimap.create();
for (Map.Entry<String, UUID> 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(plugin.getUuidTranslator().getTranslatedUuid(username, true)));
break;
default:
return;
}
((Server) event.getSender()).sendData(currentChannel, out.toByteArray());
});
}
} }
@Override @Override