diff --git a/src/de/steamwar/bungeecore/comms/PacketIdManager.java b/src/de/steamwar/bungeecore/comms/PacketIdManager.java
index 1d48745d..01d474a5 100644
--- a/src/de/steamwar/bungeecore/comms/PacketIdManager.java
+++ b/src/de/steamwar/bungeecore/comms/PacketIdManager.java
@@ -31,4 +31,8 @@ public class PacketIdManager {
public static final byte INVENTORY_PACKET = 0x10;
public static final byte INVENTORY_CALLBACK_PACKET = 0x11;
public static final byte INVENTORY_CLOSE_PACKET = 0x12;
+
+ //0x2(X) Server Information System
+ public static final byte I_AM_A_LOBBY = 0x20;
+ public static final byte FIGHT_INFO = 0x21;
}
diff --git a/src/de/steamwar/bungeecore/comms/SpigotHandler.java b/src/de/steamwar/bungeecore/comms/SpigotHandler.java
index 5c0f118c..574e9a23 100644
--- a/src/de/steamwar/bungeecore/comms/SpigotHandler.java
+++ b/src/de/steamwar/bungeecore/comms/SpigotHandler.java
@@ -20,8 +20,9 @@
package de.steamwar.bungeecore.comms;
import com.google.common.io.ByteArrayDataInput;
+import net.md_5.bungee.api.config.ServerInfo;
public interface SpigotHandler {
- void handle(ByteArrayDataInput byteArrayDataInput);
+ void handle(ByteArrayDataInput in, ServerInfo info);
}
diff --git a/src/de/steamwar/bungeecore/comms/SpigotReceiver.java b/src/de/steamwar/bungeecore/comms/SpigotReceiver.java
index f87646f1..ab6d246f 100644
--- a/src/de/steamwar/bungeecore/comms/SpigotReceiver.java
+++ b/src/de/steamwar/bungeecore/comms/SpigotReceiver.java
@@ -21,10 +21,9 @@ package de.steamwar.bungeecore.comms;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
-import de.steamwar.bungeecore.comms.handlers.InventoryCallbackHandler;
-import de.steamwar.bungeecore.comms.handlers.PrepareSchemHandler;
-import de.steamwar.bungeecore.comms.handlers.TablistNameHandler;
+import de.steamwar.bungeecore.comms.handlers.*;
import de.steamwar.bungeecore.listeners.BasicListener;
+import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.event.PluginMessageEvent;
import net.md_5.bungee.event.EventHandler;
@@ -39,14 +38,14 @@ public class SpigotReceiver extends BasicListener {
public void onPluginMessage(PluginMessageEvent event) {
if(!event.getTag().equalsIgnoreCase("sw:bridge"))
return;
- if(!event.getSender().getAddress().getHostName().equals("localhost")){
- event.setCancelled(true);
+
+ event.setCancelled(true);
+ if(!(event.getSender() instanceof Server))
return;
- }
+
ByteArrayDataInput in = ByteStreams.newDataInput(event.getData());
Byte handler = in.readByte();
- handlerMap.get(handler).handle(in);
- event.setCancelled(true);
+ handlerMap.get(handler).handle(in, ((Server) event.getSender()).getInfo());
}
public static void registerHandler(Byte id, SpigotHandler handler) {
@@ -55,7 +54,9 @@ public class SpigotReceiver extends BasicListener {
static {
registerHandler(PacketIdManager.INVENTORY_CALLBACK_PACKET, new InventoryCallbackHandler());
- registerHandler(PacketIdManager.TABLIST_NAME, new TablistNameHandler());
+ registerHandler(PacketIdManager.TABLIST_NAME, (in, info) -> {});
registerHandler(PacketIdManager.PREPARE_SCHEM, new PrepareSchemHandler());
+ registerHandler(PacketIdManager.I_AM_A_LOBBY, new ImALobbyHandler());
+ registerHandler(PacketIdManager.FIGHT_INFO, new FightInfoHandler());
}
}
diff --git a/src/de/steamwar/bungeecore/comms/handlers/FightInfoHandler.java b/src/de/steamwar/bungeecore/comms/handlers/FightInfoHandler.java
new file mode 100644
index 00000000..998e53e3
--- /dev/null
+++ b/src/de/steamwar/bungeecore/comms/handlers/FightInfoHandler.java
@@ -0,0 +1,60 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+package de.steamwar.bungeecore.comms.handlers;
+
+import com.google.common.io.ByteArrayDataInput;
+import de.steamwar.bungeecore.comms.SpigotHandler;
+import de.steamwar.bungeecore.comms.packets.FightInfoPacket;
+import de.steamwar.bungeecore.listeners.TablistManager;
+import net.md_5.bungee.api.config.ServerInfo;
+import net.md_5.bungee.api.connection.ProxiedPlayer;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class FightInfoHandler implements SpigotHandler {
+
+ private static final Set lobbys = new HashSet<>();
+
+ public static void addLobby(ServerInfo lobby) {
+ lobbys.add(lobby);
+ }
+
+ @Override
+ public void handle(ByteArrayDataInput in, ServerInfo info) {
+ FightInfoPacket packet = new FightInfoPacket(in);
+ packet.setServerName(info.getName());
+
+ TablistManager.newFightInfo(info, packet);
+
+ Iterator lobbyIt = lobbys.iterator();
+ while(lobbyIt.hasNext()) {
+ ServerInfo lobby = lobbyIt.next();
+ Iterator it = lobby.getPlayers().iterator();
+ if(!it.hasNext()){
+ lobbyIt.remove();
+ continue;
+ }
+
+ packet.send(it.next());
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/comms/handlers/ImALobbyHandler.java b/src/de/steamwar/bungeecore/comms/handlers/ImALobbyHandler.java
new file mode 100644
index 00000000..8d2013d0
--- /dev/null
+++ b/src/de/steamwar/bungeecore/comms/handlers/ImALobbyHandler.java
@@ -0,0 +1,32 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+package de.steamwar.bungeecore.comms.handlers;
+
+import com.google.common.io.ByteArrayDataInput;
+import de.steamwar.bungeecore.comms.SpigotHandler;
+import net.md_5.bungee.api.config.ServerInfo;
+
+public class ImALobbyHandler implements SpigotHandler {
+
+ @Override
+ public void handle(ByteArrayDataInput in, ServerInfo info) {
+ FightInfoHandler.addLobby(info);
+ }
+}
diff --git a/src/de/steamwar/bungeecore/comms/handlers/InventoryCallbackHandler.java b/src/de/steamwar/bungeecore/comms/handlers/InventoryCallbackHandler.java
index 07d37b72..0fd90a69 100644
--- a/src/de/steamwar/bungeecore/comms/handlers/InventoryCallbackHandler.java
+++ b/src/de/steamwar/bungeecore/comms/handlers/InventoryCallbackHandler.java
@@ -27,6 +27,7 @@ import de.steamwar.bungeecore.inventory.InvCallback;
import de.steamwar.bungeecore.inventory.SWInventory;
import de.steamwar.bungeecore.sql.SteamwarUser;
import net.md_5.bungee.api.ProxyServer;
+import net.md_5.bungee.api.config.ServerInfo;
import java.util.HashMap;
import java.util.Map;
@@ -36,9 +37,9 @@ public class InventoryCallbackHandler implements SpigotHandler {
public static final Map inventoryHashMap = new HashMap<>();
@Override
- public void handle(ByteArrayDataInput byteArrayDataInput) {
- SteamwarUser owner = SteamwarUser.get(byteArrayDataInput.readInt());
- CallbackType type = CallbackType.valueOf(byteArrayDataInput.readUTF());
+ public void handle(ByteArrayDataInput in, ServerInfo info) {
+ SteamwarUser owner = SteamwarUser.get(in.readInt());
+ CallbackType type = CallbackType.valueOf(in.readUTF());
if(!inventoryHashMap.containsKey(owner.getId())) {
BungeeCore.send(ProxyServer.getInstance().getPlayer(owner.getUuid()), BungeeCore.CHAT_PREFIX + "§cBitte erneut versuchen. Durch ein Softwareupdate konnte die übliche Aktion nicht durchgeführt werden.");
if(type == CallbackType.CLICK) {
@@ -47,8 +48,8 @@ public class InventoryCallbackHandler implements SpigotHandler {
return;
}
if(type == CallbackType.CLICK) {
- int pos = byteArrayDataInput.readInt();
- InvCallback.ClickType clickType = InvCallback.ClickType.valueOf(byteArrayDataInput.readUTF());
+ int pos = in.readInt();
+ InvCallback.ClickType clickType = InvCallback.ClickType.valueOf(in.readUTF());
inventoryHashMap.get(owner.getId()).handleCallback(clickType, pos);
}else if(type == CallbackType.CLOSE) {
if(inventoryHashMap.get(owner.getId()).isNext()) {
diff --git a/src/de/steamwar/bungeecore/comms/handlers/PrepareSchemHandler.java b/src/de/steamwar/bungeecore/comms/handlers/PrepareSchemHandler.java
index 46d1a032..14171c57 100644
--- a/src/de/steamwar/bungeecore/comms/handlers/PrepareSchemHandler.java
+++ b/src/de/steamwar/bungeecore/comms/handlers/PrepareSchemHandler.java
@@ -27,14 +27,15 @@ import de.steamwar.bungeecore.comms.SpigotHandler;
import de.steamwar.bungeecore.sql.SchematicType;
import de.steamwar.bungeecore.sql.SteamwarUser;
import net.md_5.bungee.api.ProxyServer;
+import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class PrepareSchemHandler implements SpigotHandler {
@Override
- public void handle(ByteArrayDataInput byteArrayDataInput) {
- ProxiedPlayer player = ProxyServer.getInstance().getPlayer(SteamwarUser.get(byteArrayDataInput.readInt()).getUuid());
- int schematicID = byteArrayDataInput.readInt();
- ArenaMode mode = ArenaMode.getBySchemType(SchematicType.fromDB(byteArrayDataInput.readUTF()));
+ public void handle(ByteArrayDataInput in, ServerInfo info) {
+ ProxiedPlayer player = ProxyServer.getInstance().getPlayer(SteamwarUser.get(in.readInt()).getUuid());
+ int schematicID = in.readInt();
+ ArenaMode mode = ArenaMode.getBySchemType(SchematicType.fromDB(in.readUTF()));
BauCommand.stopBauserver(player);
SubserverSystem.startTestServer(player, mode, mode.getRandomMap(), 0, schematicID);
diff --git a/src/de/steamwar/bungeecore/comms/handlers/TablistNameHandler.java b/src/de/steamwar/bungeecore/comms/handlers/TablistNameHandler.java
deleted file mode 100644
index 678d9305..00000000
--- a/src/de/steamwar/bungeecore/comms/handlers/TablistNameHandler.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package de.steamwar.bungeecore.comms.handlers;
-
-import com.google.common.io.ByteArrayDataInput;
-import de.steamwar.bungeecore.Subserver;
-import de.steamwar.bungeecore.comms.SpigotHandler;
-import de.steamwar.bungeecore.sql.SteamwarUser;
-import net.md_5.bungee.api.ProxyServer;
-import net.md_5.bungee.api.connection.ProxiedPlayer;
-
-public class TablistNameHandler implements SpigotHandler {
-
- @Override
- public void handle(ByteArrayDataInput byteArrayDataInput) {
- ProxiedPlayer player = ProxyServer.getInstance().getPlayer(SteamwarUser.get(byteArrayDataInput.readInt()).getUuid());
- Subserver subserver = Subserver.getSubserver(player.getServer().getInfo());
- if(subserver == null)
- return;
- subserver.getTablistNames().put(player, byteArrayDataInput.readUTF());
- }
-}
diff --git a/src/de/steamwar/bungeecore/comms/packets/FightInfoPacket.java b/src/de/steamwar/bungeecore/comms/packets/FightInfoPacket.java
new file mode 100644
index 00000000..34f120a4
--- /dev/null
+++ b/src/de/steamwar/bungeecore/comms/packets/FightInfoPacket.java
@@ -0,0 +1,183 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+package de.steamwar.bungeecore.comms.packets;
+
+import com.google.common.io.ByteArrayDataInput;
+import com.google.common.io.ByteArrayDataOutput;
+import de.steamwar.bungeecore.comms.BungeePacket;
+import de.steamwar.bungeecore.comms.PacketIdManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FightInfoPacket extends BungeePacket {
+
+ private String serverName; // Name of the Server
+ private final String gameMode; // GameMode aka Schematictype (if known, else "")
+ private final String arena; // Name of the arena
+ private final String blueName; // Name of the blue team, expected to begin with "§a" colorcode
+ private final String redName; // Name of the red team, expected to begin with "§a" colorcode
+ private final String fightState; // Fight state (technical term) (if known, else "")
+ private final int countdown; // Countdown state in seconds (if known, else 0)
+ private final int blueLeader; // SWUserID of the blue team leader (if known, else 0)
+ private final int redLeader; // SWUserID of the red team leader (if known, else 0)
+ private final int blueSchem; // Blue SchemID (if known, else 0)
+ private final int redSchem; // Red SchemID (if known, else 0)
+ private final List bluePlayers; // List of Blue SWUserIDs
+ private final List redPlayers; // List of Red SWUserIDs
+ private final List spectators; // List of Spectator SWUserIDs
+
+ public FightInfoPacket(String serverName, String gameMode, String arena, String blueName, String redName, String fightState, int countdown, int blueLeader, int redLeader, int blueSchem, int redSchem, List bluePlayers, List redPlayers, List spectators) {
+ this.serverName = serverName;
+ this.gameMode = gameMode;
+ this.arena = arena;
+ this.blueName = blueName;
+ this.redName = redName;
+ this.fightState = fightState;
+ this.countdown = countdown;
+ this.blueLeader = blueLeader;
+ this.redLeader = redLeader;
+ this.blueSchem = blueSchem;
+ this.redSchem = redSchem;
+ this.bluePlayers = bluePlayers;
+ this.redPlayers = redPlayers;
+ this.spectators = spectators;
+ }
+
+ public FightInfoPacket(ByteArrayDataInput in) {
+ this.serverName = in.readUTF();
+ this.gameMode = in.readUTF();
+ this.arena = in.readUTF();
+ this.blueName = in.readUTF();
+ this.redName = in.readUTF();
+ this.fightState = in.readUTF();
+ this.countdown = in.readInt();
+ this.blueLeader = in.readInt();
+ this.redLeader = in.readInt();
+ this.blueSchem = in.readInt();
+ this.redSchem = in.readInt();
+ this.bluePlayers = readPlayerList(in);
+ this.redPlayers = readPlayerList(in);
+ this.spectators = readPlayerList(in);
+ }
+
+ @Override
+ public int getId() {
+ return PacketIdManager.FIGHT_INFO;
+ }
+
+ @Override
+ public void writeVars(ByteArrayDataOutput out) {
+ out.writeUTF(serverName);
+ out.writeUTF(gameMode);
+ out.writeUTF(arena);
+ out.writeUTF(blueName);
+ out.writeUTF(redName);
+ out.writeUTF(fightState);
+ out.writeInt(countdown);
+ out.writeInt(blueLeader);
+ out.writeInt(redLeader);
+ out.writeInt(blueSchem);
+ out.writeInt(redSchem);
+ writePlayerList(out, bluePlayers);
+ writePlayerList(out, redPlayers);
+ writePlayerList(out, spectators);
+ }
+
+ public String getServerName() {
+ return serverName;
+ }
+
+ public void setServerName(String serverName) {
+ this.serverName = serverName;
+ }
+
+ public String getGameMode() {
+ return gameMode;
+ }
+
+ public String getArena() {
+ return arena;
+ }
+
+ public String getBlueName() {
+ return blueName;
+ }
+
+ public String getRedName() {
+ return redName;
+ }
+
+ public String getFightState() {
+ return fightState;
+ }
+
+ public int getCountdown() {
+ return countdown;
+ }
+
+ public int getBlueLeader() {
+ return blueLeader;
+ }
+
+ public int getRedLeader() {
+ return redLeader;
+ }
+
+ public int getBlueSchem() {
+ return blueSchem;
+ }
+
+ public int getRedSchem() {
+ return redSchem;
+ }
+
+ public List getBluePlayers() {
+ return bluePlayers;
+ }
+
+ public List getRedPlayers() {
+ return redPlayers;
+ }
+
+ public List getSpectators() {
+ return spectators;
+ }
+
+ public int playerSize(){
+ return bluePlayers.size() + redPlayers.size() + spectators.size();
+ }
+
+ private static List readPlayerList(ByteArrayDataInput in) {
+ int length = in.readInt();
+ List players = new ArrayList<>(length);
+ for(int i = 0; i < length; i++) {
+ players.add(in.readInt());
+ }
+ return players;
+ }
+
+ private void writePlayerList(ByteArrayDataOutput out, List players) {
+ out.writeInt(players.size());
+ for(Integer player : players) {
+ out.writeInt(player);
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/listeners/TablistManager.java b/src/de/steamwar/bungeecore/listeners/TablistManager.java
index 7c927366..798f1133 100644
--- a/src/de/steamwar/bungeecore/listeners/TablistManager.java
+++ b/src/de/steamwar/bungeecore/listeners/TablistManager.java
@@ -26,13 +26,12 @@ import de.steamwar.bungeecore.BungeeCore;
import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.Servertype;
import de.steamwar.bungeecore.Subserver;
+import de.steamwar.bungeecore.comms.packets.FightInfoPacket;
import de.steamwar.bungeecore.sql.SteamwarUser;
-import de.steamwar.bungeecore.sql.Team;
import de.steamwar.bungeecore.sql.UserGroup;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
-import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
import net.md_5.bungee.api.event.PostLoginEvent;
import net.md_5.bungee.event.EventHandler;
@@ -42,21 +41,39 @@ import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
public class TablistManager extends BasicListener {
private static final Map tablists = new HashMap<>();
- private int seconds = 0;
- private Icon darkGray;
- private Icon gray;
+ @EventHandler
+ public synchronized void onJoin(PostLoginEvent e){
+ tablists.put(e.getPlayer(), new Tablist(e.getPlayer()));
+ }
+ @EventHandler
+ public synchronized void onLeave(PlayerDisconnectEvent e){
+ tablists.remove(e.getPlayer());
+ }
+
+
+ private static final Map fightInfos = new HashMap<>();
+
+ public static synchronized void newFightInfo(ServerInfo info, FightInfoPacket packet) {
+ fightInfos.put(info, packet);
+ fightInfos.keySet().removeIf(serverInfo -> serverInfo.getPlayers().isEmpty());
+ }
+
+
+ private static Icon darkGray;
+ private static Icon gray;
+
+ private int seconds = 0;
private int size;
- private final TreeMap> playerMap = new TreeMap<>();
+ private TablistGroup tablist;
public TablistManager(){
- ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this::updateCustomTablist, 1, 1, TimeUnit.SECONDS);
+ ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this::updateTablist, 1, 1, TimeUnit.SECONDS);
try{
BungeeTabListPlusAPI.createIcon(ImageIO.read(new File("/configs/BungeeTabListPlus/heads/colors/dark_gray.png")), (icon) -> darkGray = icon);
BungeeTabListPlusAPI.createIcon(ImageIO.read(new File("/configs/BungeeTabListPlus/heads/colors/gray.png")), (icon) -> gray = icon);
@@ -69,61 +86,40 @@ public class TablistManager extends BasicListener {
}
}
- private void calculateSize() {
- size = -1;
- size += playerMap.size() * 2 + ProxyServer.getInstance().getPlayers().size();
- size = (size + 19) / 20;
- if(size > 5) size = 5;
- }
-
- private synchronized void updateCustomTablist(){
+ private synchronized void updateTablist(){
//Calculate server-player-map
- playerMap.clear();
- for (ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) {
- Server pserver = player.getServer();
- if (pserver == null) //Happens temporarily
+ tablist = new TablistGroup(true, "");
+ TablistGroup bau = new TablistGroup(false, "Bau");
+ for (ServerInfo server : ProxyServer.getInstance().getServers().values()){
+ if(server.getPlayers().isEmpty())
continue;
- ServerInfo server = pserver.getInfo();
- String serverName = server.getName();
-
Subserver subserver = Subserver.getSubserver(server);
- if (subserver != null && subserver.getType() == Servertype.BAUSERVER) {
- playerMap.computeIfAbsent("Bau", s -> new ArrayList<>()).add(player);
- } else {
- playerMap.computeIfAbsent(serverName, s -> new ArrayList<>()).add(player);
- }
+ if(subserver != null && subserver.getType() == Servertype.BAUSERVER)
+ bau.addSubTablist(new TablistServer(server));
+ else if(fightInfos.containsKey(server))
+ tablist.addSubTablist(new TablistServer(server, fightInfos.get(server)));
+ else
+ tablist.addSubTablist(new TablistServer(server));
}
- playerMap.forEach((server, players) -> players.sort((proxiedPlayer, t1) -> proxiedPlayer.getName().compareToIgnoreCase(t1.getName())));
-
- //Set size
- calculateSize();
-
- for(Tablist tablist : tablists.values())
- tablist.refresh();
+ if(bau.size() > 0)
+ tablist.addSubTablist(bau);
+ size = (int) Math.ceil(tablist.size() / 20.0);
+ tablists.values().forEach(Tablist::refresh);
seconds++;
}
- @EventHandler
- public synchronized void onJoin(PostLoginEvent e){
- tablists.put(e.getPlayer(), new Tablist(e.getPlayer()));
- }
-
- @EventHandler
- public synchronized void onLeave(PlayerDisconnectEvent e){
- tablists.remove(e.getPlayer());
- }
-
private class Tablist extends DefaultCustomTablist {
private final ProxiedPlayer player;
+ private int pos = 0;
private Tablist(ProxiedPlayer player){
this.player = player;
BungeeTabListPlusAPI.setCustomTabList(player, this);
}
- private String calcHeader(ProxiedPlayer player){
+ private String header(){
int phase = (seconds % 16) / 3;
switch(phase){
case 0:
@@ -136,7 +132,7 @@ public class TablistManager extends BasicListener {
}
}
- private String getPing(){
+ private String ping(){
int ping = player.getPing();
if(ping < 50){
return "§a" + ping;
@@ -151,126 +147,164 @@ public class TablistManager extends BasicListener {
if (player.getServer() == null) {
return;
}
- ServerInfo currentServer = player.getServer().getInfo();
- setHeader(calcHeader(player));
- // TABLIST_FOOTER=§e{0} {1}§8ms §eSpieler§8: §7{2}
- setFooter("§e" + currentServer.getName() + " " + getPing() + "§8ms §eSpieler§8: §7" + ProxyServer.getInstance().getPlayers().size());
- setSize(size, 20);
+ pos = 0;
+ setHeader(header());
+ setFooter("§e" + player.getServer().getInfo().getName() + " " + ping() + "§8ms §eSpieler§8: §7" + ProxyServer.getInstance().getPlayers().size());
+ int currentSize = size > 4 ? tablist.slimSize(player) : size;
+ setSize(currentSize, 20);
- if (size >= 5) {
- refreshSlim(currentServer);
- return;
- }
+ tablist.print(this, size > 4);
- try {
- int i = 0;
- for (String server : playerMap.navigableKeySet()) {
- if (i > 0){
- setSlot(i%20, i/20, darkGray, "", 1000);
- i++;
- }
- if(server.equals("Bau"))
- server = Message.parse("TABLIST_BAU", player);
- setSlot(i%20, i/20, gray, "§7§l" + server, 1000);
- i++;
- i = update(currentServer, playerMap.get(server), i);
- }
-
- finish(i);
- }catch(IndexOutOfBoundsException | NullPointerException e){
- //Ignore IndexOutOfBoundsException
- //Ignore NPE, happens sometimes (only 1s long) when somebody is joining, server switching or disconnecting
+ while (pos < currentSize*20){
+ setSlot(darkGray, "", 1000);
}
}
- private void refreshSlim(ServerInfo currentServer) {
- try {
- int i = 0;
- boolean spacer = true;
- for (String server : playerMap.navigableKeySet()) {
- if (i > 0 && spacer) {
- setSlot(i%20, i/20, darkGray, "", 1000);
- i++;
- }
- spacer = true;
- Team team = getTeam(player);
- List players = playerMap.get(server)
- .stream()
- .filter(p -> (p.getServer() != null && p.getServer().getInfo() == currentServer) || SteamwarUser.get(p).getUserGroup() != UserGroup.Member || (team != null && team == getTeam(p)))
- .collect(Collectors.toList());
+ private void setSlot(Icon icon, String name, int ping){
+ setSlot(pos % 20, pos / 20, icon, name, ping);
+ pos++;
+ }
+ }
- Subserver subserver = Subserver.getSubserver(player);
- if (server.equals("Bau")) {
- if (subserver != null && subserver.getType() == Servertype.BAUSERVER) {
- players = playerMap.get(server);
- }
- server = Message.parse("TABLIST_BAU", player);
- }
- if (subserver != null && subserver.getType() == Servertype.ARENA && playerMap.get(server).size() == 1) {
- players = playerMap.get(server);
- }
+ private interface TablistPart {
+ int size();
+ int slimSize(ProxiedPlayer viewer);
+ String name();
+ void print(Tablist viewer, boolean slim);
+ }
- int increment = playerMap.get(server).size() - players.size();
- if (players.isEmpty()) {
- server += " §7(" + increment + ")";
- spacer = false;
- } else if (increment != 0) {
- server += " §7(+" + increment + ")";
- }
+ private static class TablistGroup implements TablistPart {
- setSlot(i%20, i/20, gray, "§7§l" + server, 1000);
- i++;
- i = update(currentServer, players, i);
- }
+ private final boolean withHeaders;
+ private final String orderName;
+ private final List subTablists = new ArrayList<>();
- finish(i);
- }catch(IndexOutOfBoundsException | NullPointerException e){
- //Ignore IndexOutOfBoundsException
- //Ignore NPE, happens sometimes (only 1s long) when somebody is joining, server switching or disconnecting
- }
+ private TablistGroup(boolean withHeaders, String orderName) {
+ this.withHeaders = withHeaders;
+ this.orderName = orderName;
}
- private int update(ServerInfo currentServer, List players, int i) {
- for (ProxiedPlayer p : players){
- boolean sameServer = currentServer == p.getServer().getInfo();
- setSlot(i % 20, i / 20, BungeeTabListPlusAPI.getIconFromPlayer(p), getTablistName(p), (sameServer ? 1 : 500));
- i++;
- }
- return i;
+ private void addSubTablist(TablistPart tablist){
+ subTablists.add(tablist);
+ subTablists.sort((t1, t2) -> t1.name().compareToIgnoreCase(t2.name()));
}
- private void finish(int i) {
- while (i < size*20){
- setSlot(i%20, i/20, darkGray, "", 1000);
- i++;
- }
+ @Override
+ public int size() {
+ int size = subTablists.stream().map(TablistPart::size).reduce(Integer::sum).orElse(0);
+ if(withHeaders)
+ size += Math.min(subTablists.size() - 1, 0);
+ return size;
}
- private Team getTeam(ProxiedPlayer p) {
- Team team = Team.get(SteamwarUser.get(p).getTeam());
- return team.getTeamId() <= 0 ? null : team;
+ @Override
+ public int slimSize(ProxiedPlayer viewer) {
+ int size = subTablists.stream().map(tablist -> tablist.slimSize(viewer)).reduce(Integer::sum).orElse(0);
+ if(withHeaders)
+ size += Math.min(subTablists.size() - 1, 0);
+ return size;
}
- private String getTablistName(ProxiedPlayer p) {
- Subserver server = Subserver.getSubserver(p);
- if(server != null){
- String tablistName = server.getTablistNames().get(p);
- if(tablistName != null)
- return tablistName;
+ @Override
+ public String name() {
+ return orderName;
+ }
+
+ @Override
+ public void print(Tablist viewer, boolean slim) {
+ subTablists.forEach(tablist -> {
+ if(withHeaders)
+ viewer.setSlot(gray, "§7§l" + tablist.name(), 1000);
+ tablist.print(viewer, slim);
+ if(withHeaders)
+ viewer.setSlot(darkGray, "", 1000);
+ });
+ }
+ }
+
+ private static class TablistServer implements TablistPart {
+ private static class TablistPlayer {
+ private final ProxiedPlayer player;
+ private final String defaultName;
+
+ private TablistPlayer(ProxiedPlayer player, String defaultName) {
+ this.player = player;
+ this.defaultName = defaultName;
}
+ }
+ private final List players = new ArrayList<>();
+ private final ServerInfo info;
+ private final Subserver subserver;
- StringBuilder st = new StringBuilder();
- UserGroup group = SteamwarUser.get(p).getUserGroup();
+ private TablistServer(ServerInfo info, FightInfoPacket packet){
+ this.info = info;
+ subserver = Subserver.getSubserver(info);
+ Collection onlinePlayers = info.getPlayers();
+ addPlayers(packet.getBlueName().substring(0, 2), packet.getBluePlayers(), onlinePlayers);
+ addPlayers(packet.getRedName().substring(0, 2), packet.getRedPlayers(), onlinePlayers);
+ addPlayers("§7", packet.getSpectators(), onlinePlayers);
+ }
- if (group == UserGroup.Member) {
- Team team = getTeam(player);
- if (team != null && team == getTeam(p)) st.append("§f");
- else st.append("§7");
- } else {
- st.append(group.getColorCode());
+ private void addPlayers(String prefix, List teamPlayers, Collection onlinePlayers){
+ teamPlayers.stream().map(SteamwarUser::get).map(
+ user -> onlinePlayers.stream().filter(player -> player.getUniqueId().equals(user.getUuid())).findAny()
+ ).filter(Optional::isPresent).map(Optional::get).sorted(
+ (p1, p2) -> p1.getName().compareToIgnoreCase(p2.getName())
+ ).forEachOrdered(player -> players.add(new TablistPlayer(player, prefix + player.getName())));
+ }
+
+ private TablistServer(ServerInfo info) {
+ this.info = info;
+ subserver = Subserver.getSubserver(info);
+ for(ProxiedPlayer player : info.getPlayers()){
+ players.add(new TablistPlayer(player, SteamwarUser.get(player.getUniqueId()).getUserGroup().getColorCode() + player.getName()));
}
+ players.sort((tp1, tp2) -> tp1.player.getName().compareToIgnoreCase(tp2.player.getName()));
+ }
- return st.append(p.getName()).toString();
+ private boolean displaySlim(ProxiedPlayer viewer, ProxiedPlayer player){
+ if(subserver != null && subserver.getType() == Servertype.ARENA && info.getPlayers().size() == 1)
+ return true;
+
+ SteamwarUser user = SteamwarUser.get(player);
+ if(user.getUserGroup() != UserGroup.Member)
+ return true;
+
+ return user.getTeam() != 0 && SteamwarUser.get(viewer).getTeam() == user.getTeam();
+ }
+
+ @Override
+ public int size() {
+ return 1 + players.size();
+ }
+
+ @Override
+ public int slimSize(ProxiedPlayer viewer) {
+ if(viewer.getServer().getInfo() == info)
+ return size();
+
+ int size = 1;
+ for(TablistPlayer player : players)
+ size += displaySlim(viewer, player.player) ? 1 : 0;
+ return size;
+ }
+
+ @Override
+ public String name() {
+ return info.getName();
+ }
+
+ @Override
+ public void print(Tablist viewer, boolean slim) {
+ boolean sameServer = viewer.player.getServer().getInfo() == info;
+
+ SteamwarUser user = SteamwarUser.get(viewer.player.getUniqueId());
+ for(TablistPlayer player : players){
+ if(sameServer || (user.getTeam() != 0 && user.getTeam() == SteamwarUser.get(player.player.getUniqueId()).getTeam()))
+ viewer.setSlot(BungeeTabListPlusAPI.getIconFromPlayer(player.player), player.defaultName.startsWith("§7") ? "§f" + player.player.getName() : player.defaultName, 1);
+ else if(!slim || displaySlim(viewer.player, player.player))
+ viewer.setSlot(BungeeTabListPlusAPI.getIconFromPlayer(player.player), player.defaultName, 500);
+ }
}
}
}