Fix issue #7 by adding Tab List Support. Thanks @ranzdo
This commit is contained in:
parent
e4522c7ab4
commit
2c1d7b34e6
@ -22,7 +22,12 @@ import net.md_5.bungee.command.CommandMotd;
|
||||
import net.md_5.bungee.command.CommandSender;
|
||||
import net.md_5.bungee.command.CommandServer;
|
||||
import net.md_5.bungee.command.ConsoleCommandSender;
|
||||
import net.md_5.bungee.packet.DefinedPacket;
|
||||
import net.md_5.bungee.plugin.JavaPluginManager;
|
||||
import net.md_5.bungee.tablist.GlobalPingTabList;
|
||||
import net.md_5.bungee.tablist.GlobalTabList;
|
||||
import net.md_5.bungee.tablist.ServerUnqiueTabList;
|
||||
import net.md_5.bungee.tablist.TabListHandler;
|
||||
|
||||
/**
|
||||
* Main BungeeCord proxy class.
|
||||
@ -66,6 +71,10 @@ public class BungeeCord
|
||||
* Registered commands.
|
||||
*/
|
||||
public Map<String, Command> commandMap = new HashMap<>();
|
||||
/**
|
||||
* Tab list handler
|
||||
*/
|
||||
public TabListHandler tabListHandler;
|
||||
/**
|
||||
* Plugin manager.
|
||||
*/
|
||||
@ -154,6 +163,19 @@ public class BungeeCord
|
||||
|
||||
pluginManager.loadPlugins();
|
||||
|
||||
switch (config.tabList)
|
||||
{
|
||||
case 1:
|
||||
tabListHandler = new GlobalPingTabList();
|
||||
break;
|
||||
case 2:
|
||||
tabListHandler = new GlobalTabList();
|
||||
break;
|
||||
case 3:
|
||||
tabListHandler = new ServerUnqiueTabList();
|
||||
break;
|
||||
}
|
||||
|
||||
InetSocketAddress addr = Util.getAddr(config.bindHost);
|
||||
listener = new ListenThread(addr);
|
||||
listener.start();
|
||||
@ -219,4 +241,17 @@ public class BungeeCord
|
||||
socket.setTrafficClass(0x18);
|
||||
socket.setTcpNoDelay(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts a packet to all clients that is connected to this instance.
|
||||
*
|
||||
* @param packet the packet to send
|
||||
*/
|
||||
public void broadcast(DefinedPacket packet)
|
||||
{
|
||||
for (UserConnection con : connections.values())
|
||||
{
|
||||
con.packetQueue.add(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +70,13 @@ public class Configuration
|
||||
* Max players as displayed in list ping. Soft limit.
|
||||
*/
|
||||
public int maxPlayers = 1;
|
||||
/**
|
||||
* Tab list 1: For a tab list that is global over all server (using their
|
||||
* minecraft name) and updating their ping frequently 2: Same as 1 but does
|
||||
* not update their ping frequently, just once. 3: Makes the individual
|
||||
* servers handle the tab list (server unique)
|
||||
*/
|
||||
public int tabList = 1;
|
||||
/**
|
||||
* Socket timeout.
|
||||
*/
|
||||
|
@ -9,10 +9,12 @@ import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import net.md_5.bungee.command.CommandSender;
|
||||
import net.md_5.bungee.packet.DefinedPacket;
|
||||
import net.md_5.bungee.packet.Packet0KeepAlive;
|
||||
import net.md_5.bungee.packet.Packet1Login;
|
||||
import net.md_5.bungee.packet.Packet2Handshake;
|
||||
import net.md_5.bungee.packet.Packet3Chat;
|
||||
import net.md_5.bungee.packet.Packet9Respawn;
|
||||
import net.md_5.bungee.packet.PacketC9PlayerListItem;
|
||||
import net.md_5.bungee.packet.PacketFAPluginMessage;
|
||||
import net.md_5.bungee.packet.PacketInputStream;
|
||||
import net.md_5.bungee.plugin.ServerConnectEvent;
|
||||
@ -29,6 +31,10 @@ public class UserConnection extends GenericConnection implements CommandSender
|
||||
private int clientEntityId;
|
||||
private int serverEntityId;
|
||||
private volatile boolean reconnecting;
|
||||
// ping stuff
|
||||
private int trackingPingId;
|
||||
private long pingTime;
|
||||
private int ping;
|
||||
|
||||
public UserConnection(Socket socket, PacketInputStream in, OutputStream out, Packet2Handshake handshake)
|
||||
{
|
||||
@ -36,6 +42,7 @@ public class UserConnection extends GenericConnection implements CommandSender
|
||||
this.handshake = handshake;
|
||||
username = handshake.username;
|
||||
BungeeCord.instance.connections.put(username, this);
|
||||
BungeeCord.instance.tabListHandler.onJoin(this);
|
||||
}
|
||||
|
||||
public void connect(String server)
|
||||
@ -63,6 +70,7 @@ public class UserConnection extends GenericConnection implements CommandSender
|
||||
|
||||
private void connect(String name, InetSocketAddress serverAddr)
|
||||
{
|
||||
BungeeCord.instance.tabListHandler.onServerChange(this);
|
||||
try
|
||||
{
|
||||
reconnecting = true;
|
||||
@ -115,6 +123,17 @@ public class UserConnection extends GenericConnection implements CommandSender
|
||||
return socket.getRemoteSocketAddress();
|
||||
}
|
||||
|
||||
public int getPing()
|
||||
{
|
||||
return ping;
|
||||
}
|
||||
|
||||
private void setPing(int ping)
|
||||
{
|
||||
BungeeCord.instance.tabListHandler.onPingChange(this, ping);
|
||||
this.ping = ping;
|
||||
}
|
||||
|
||||
private void destroySelf(String reason)
|
||||
{
|
||||
if (BungeeCord.instance.isRunning)
|
||||
@ -129,6 +148,13 @@ public class UserConnection extends GenericConnection implements CommandSender
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect(String reason)
|
||||
{
|
||||
BungeeCord.instance.tabListHandler.onDisconnect(this);
|
||||
super.disconnect(reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message)
|
||||
{
|
||||
@ -168,6 +194,12 @@ public class UserConnection extends GenericConnection implements CommandSender
|
||||
{
|
||||
sendPacket = !BungeeCord.instance.dispatchCommand(message.substring(1), UserConnection.this);
|
||||
}
|
||||
} else if (id == 0x00)
|
||||
{
|
||||
if (trackingPingId == new Packet0KeepAlive(packet).id)
|
||||
{
|
||||
setPing((int) (System.currentTimeMillis() - pingTime));
|
||||
}
|
||||
}
|
||||
|
||||
EntityMap.rewrite(packet, clientEntityId, serverEntityId);
|
||||
@ -213,6 +245,16 @@ public class UserConnection extends GenericConnection implements CommandSender
|
||||
connect(server);
|
||||
break;
|
||||
}
|
||||
} else if (id == 0x00)
|
||||
{
|
||||
trackingPingId = new Packet0KeepAlive(packet).id;
|
||||
pingTime = System.currentTimeMillis();
|
||||
} else if (id == 0xC9)
|
||||
{
|
||||
if (!BungeeCord.instance.tabListHandler.onPacketC9(UserConnection.this, new PacketC9PlayerListItem(packet)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
while (!packetQueue.isEmpty())
|
||||
|
18
src/main/java/net/md_5/bungee/packet/Packet0KeepAlive.java
Normal file
18
src/main/java/net/md_5/bungee/packet/Packet0KeepAlive.java
Normal file
@ -0,0 +1,18 @@
|
||||
package net.md_5.bungee.packet;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class Packet0KeepAlive extends DefinedPacket
|
||||
{
|
||||
|
||||
public int id;
|
||||
|
||||
public Packet0KeepAlive(byte[] buffer)
|
||||
{
|
||||
super(0x00, buffer);
|
||||
id = readInt();
|
||||
}
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package net.md_5.bungee.packet;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
|
||||
@ToString
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PacketC9PlayerListItem extends DefinedPacket
|
||||
{
|
||||
|
||||
public String username;
|
||||
public boolean online;
|
||||
public int ping;
|
||||
|
||||
public PacketC9PlayerListItem(byte[] packet)
|
||||
{
|
||||
super(0xC9, packet);
|
||||
username = readUTF();
|
||||
online = readBoolean();
|
||||
ping = readShort();
|
||||
}
|
||||
|
||||
public PacketC9PlayerListItem(String username, boolean online, int ping)
|
||||
{
|
||||
super(0xC9);
|
||||
writeUTF(username);
|
||||
writeBoolean(online);
|
||||
writeShort(ping);
|
||||
}
|
||||
}
|
@ -15,8 +15,7 @@ public class ServerConnectEvent
|
||||
*/
|
||||
private final boolean firstTime;
|
||||
/**
|
||||
* Message to send just before the change.
|
||||
* null for no message
|
||||
* Message to send just before the change. null for no message
|
||||
*/
|
||||
private String message;
|
||||
/**
|
||||
|
28
src/main/java/net/md_5/bungee/tablist/GlobalPingTabList.java
Normal file
28
src/main/java/net/md_5/bungee/tablist/GlobalPingTabList.java
Normal file
@ -0,0 +1,28 @@
|
||||
package net.md_5.bungee.tablist;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.UserConnection;
|
||||
import net.md_5.bungee.packet.PacketC9PlayerListItem;
|
||||
|
||||
public class GlobalPingTabList extends GlobalTabList
|
||||
{
|
||||
|
||||
public static final int PING_THRESHOLD = 20;
|
||||
private Map<UserConnection, Integer> lastPings =
|
||||
Collections.synchronizedMap(new WeakHashMap<UserConnection, Integer>());
|
||||
|
||||
@Override
|
||||
public void onPingChange(final UserConnection con, final int ping)
|
||||
{
|
||||
Integer lastPing = lastPings.get(con);
|
||||
if (lastPing == null || (ping - PING_THRESHOLD > lastPing && ping + PING_THRESHOLD < lastPing))
|
||||
{
|
||||
BungeeCord.instance.broadcast(new PacketC9PlayerListItem(con.username, true, ping));
|
||||
lastPings.put(con, ping);
|
||||
}
|
||||
}
|
||||
}
|
52
src/main/java/net/md_5/bungee/tablist/GlobalTabList.java
Normal file
52
src/main/java/net/md_5/bungee/tablist/GlobalTabList.java
Normal file
@ -0,0 +1,52 @@
|
||||
package net.md_5.bungee.tablist;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.UserConnection;
|
||||
import net.md_5.bungee.packet.PacketC9PlayerListItem;
|
||||
|
||||
public class GlobalTabList implements TabListHandler
|
||||
{
|
||||
|
||||
private Set<UserConnection> sentPings = Collections.synchronizedSet(new HashSet<UserConnection>());
|
||||
|
||||
@Override
|
||||
public void onJoin(UserConnection con)
|
||||
{
|
||||
for (UserConnection con2 : BungeeCord.instance.connections.values())
|
||||
{
|
||||
con.packetQueue.add(new PacketC9PlayerListItem(con2.username, true, con2.getPing()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerChange(UserConnection con)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingChange(final UserConnection con, final int ping)
|
||||
{
|
||||
if (!sentPings.contains(con))
|
||||
{
|
||||
BungeeCord.instance.broadcast(new PacketC9PlayerListItem(con.username, true, con.getPing()));
|
||||
sentPings.add(con);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(final UserConnection con)
|
||||
{
|
||||
BungeeCord.instance.broadcast(new PacketC9PlayerListItem(con.username, false, 9999));
|
||||
sentPings.remove(con);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPacketC9(UserConnection con, PacketC9PlayerListItem packet)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package net.md_5.bungee.tablist;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import net.md_5.bungee.UserConnection;
|
||||
import net.md_5.bungee.packet.PacketC9PlayerListItem;
|
||||
|
||||
public class ServerUnqiueTabList implements TabListHandler
|
||||
{
|
||||
|
||||
private Map<UserConnection, Set<String>> sentUsernames =
|
||||
Collections.synchronizedMap(new WeakHashMap<UserConnection, Set<String>>());
|
||||
|
||||
@Override
|
||||
public void onJoin(UserConnection con)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServerChange(UserConnection con)
|
||||
{
|
||||
Set<String> usernames = sentUsernames.get(con);
|
||||
synchronized (usernames)
|
||||
{
|
||||
if (usernames != null)
|
||||
{
|
||||
for (String username : usernames)
|
||||
{
|
||||
con.packetQueue.add(new PacketC9PlayerListItem(username, false, 9999));
|
||||
}
|
||||
}
|
||||
usernames.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPingChange(UserConnection con, int ping)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(UserConnection con)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPacketC9(final UserConnection con, final PacketC9PlayerListItem packet)
|
||||
{
|
||||
Set<String> usernames = sentUsernames.get(con);
|
||||
if (usernames == null)
|
||||
{
|
||||
usernames = new LinkedHashSet<>();
|
||||
sentUsernames.put(con, usernames);
|
||||
}
|
||||
|
||||
if (packet.online)
|
||||
{
|
||||
usernames.add(packet.username);
|
||||
} else
|
||||
{
|
||||
usernames.remove(packet.username);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
18
src/main/java/net/md_5/bungee/tablist/TabListHandler.java
Normal file
18
src/main/java/net/md_5/bungee/tablist/TabListHandler.java
Normal file
@ -0,0 +1,18 @@
|
||||
package net.md_5.bungee.tablist;
|
||||
|
||||
import net.md_5.bungee.UserConnection;
|
||||
import net.md_5.bungee.packet.PacketC9PlayerListItem;
|
||||
|
||||
public interface TabListHandler
|
||||
{
|
||||
|
||||
public void onJoin(UserConnection con);
|
||||
|
||||
public void onServerChange(UserConnection con);
|
||||
|
||||
public void onPingChange(UserConnection con, int ping);
|
||||
|
||||
public void onDisconnect(UserConnection con);
|
||||
|
||||
public boolean onPacketC9(UserConnection con, PacketC9PlayerListItem packet);
|
||||
}
|
Loading…
Reference in New Issue
Block a user