diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index bef12ed..f1a3769 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -96,7 +96,7 @@ public class BungeeCore extends Plugin { new Broadcaster(); new SessionManager(); - new Tablist(); + new TablistManager(); getProxy().getScheduler().schedule(this, () -> { SteamwarUser.clearCache(); diff --git a/src/de/steamwar/bungeecore/listeners/Tablist.java b/src/de/steamwar/bungeecore/listeners/Tablist.java deleted file mode 100644 index d39f48b..0000000 --- a/src/de/steamwar/bungeecore/listeners/Tablist.java +++ /dev/null @@ -1,120 +0,0 @@ -package de.steamwar.bungeecore.listeners; - -import codecrafter47.bungeetablistplus.BungeeTabListPlus; -import codecrafter47.bungeetablistplus.api.bungee.BungeeTabListPlusAPI; -import codecrafter47.bungeetablistplus.api.bungee.CustomTablist; -import codecrafter47.bungeetablistplus.api.bungee.Icon; -import de.steamwar.bungeecore.BungeeCore; -import de.steamwar.bungeecore.Servertype; -import de.steamwar.bungeecore.Subserver; -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.event.PostLoginEvent; -import net.md_5.bungee.event.EventHandler; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -public class Tablist extends BasicListener { - - private final CustomTablist tablist; - private int seconds = 0; - private final Icon darkGray; - private final Icon gray; - - - public Tablist(){ - tablist = BungeeTabListPlusAPI.createCustomTablist(); - ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this::updateCustomTablist, 1, 1, TimeUnit.SECONDS); - tablist.setFooter("§8Ping: ${viewer_colored_ping}ms §8Server: §e${viewer server}"); //TODO: Set to tablist per player - //Preload due to bug - BungeeTabListPlus.getInstance().getSkinManager().getIcon("colors/dark_gray.png"); - BungeeTabListPlus.getInstance().getSkinManager().getIcon("colors/gray.png"); - darkGray = BungeeTabListPlus.getInstance().getSkinManager().getIcon("colors/dark_gray.png"); - gray = BungeeTabListPlus.getInstance().getSkinManager().getIcon("colors/gray.png"); - //TODO: Fix icons - } - - private void setHeader(){ - if(seconds % 4 == 0){ - int phase = (seconds % 16) / 4; - switch(phase){ - case 0: - tablist.setHeader("§8Spieler online: §e" + ProxyServer.getInstance().getPlayers().size()); - break; - case 1: - tablist.setHeader("§8Teamspeak: §eSteam§8War.de"); - break; - case 2: - tablist.setHeader("§8Discord: §8https://discord.gg/J4NtQmM"); - break; - case 3: - tablist.setHeader("§8Website: https://§eSteam§8War.de"); - break; - } - } - } - - private void updateCustomTablist(){ - setHeader(); - - //Calculate server-player-map - Map> playerMap = new HashMap<>(); - for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()){ - ServerInfo server = player.getServer().getInfo(); - String serverName = server.getName(); - if(serverName.equals("Developer")) - continue; - - Subserver subserver = Subserver.getSubserver(server); - List players; - if(subserver != null && subserver.getType() == Servertype.BAUSERVER){ - players = playerMap.getOrDefault("Bau", new ArrayList<>()); - }else{ - players = playerMap.getOrDefault(serverName, new ArrayList<>()); - } - - players.add(player); - playerMap.putIfAbsent(serverName, players); - } - - //Set size - int size = -1; - for(Map.Entry> server : playerMap.entrySet()) - size += 2 + server.getValue().size(); - if(size < 0) - return; - - size = size/20+20; - - if(size > 80){ - size = 80; - //TODO: Handle Oversize - } - tablist.setSize(size); - - int i = 0; - //TODO: Set sorting - for(Map.Entry> server : playerMap.entrySet()){ - if(i > 0) - tablist.setSlot(i++, 0, darkGray, "", 1000); - tablist.setSlot(i++, 0, gray,"§7§l" + server.getKey(), 1000); - for(ProxiedPlayer player : server.getValue()) - tablist.setSlot(i++, 0, BungeeTabListPlusAPI.getIconFromPlayer(player), player.getDisplayName(), 1); - } - - while(i < size) - tablist.setSlot(i++, 0, darkGray, "", 1000); - - seconds++; - } - - @EventHandler - public void onJoin(PostLoginEvent e){ - BungeeTabListPlusAPI.setCustomTabList(e.getPlayer(), tablist); - } -} diff --git a/src/de/steamwar/bungeecore/listeners/TablistManager.java b/src/de/steamwar/bungeecore/listeners/TablistManager.java new file mode 100644 index 0000000..5a44330 --- /dev/null +++ b/src/de/steamwar/bungeecore/listeners/TablistManager.java @@ -0,0 +1,165 @@ +package de.steamwar.bungeecore.listeners; + +import codecrafter47.bungeetablistplus.api.bungee.BungeeTabListPlusAPI; +import codecrafter47.bungeetablistplus.api.bungee.CustomTablist; +import codecrafter47.bungeetablistplus.api.bungee.Icon; +import de.steamwar.bungeecore.BungeeCore; +import de.steamwar.bungeecore.Servertype; +import de.steamwar.bungeecore.Subserver; +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.event.PlayerDisconnectEvent; +import net.md_5.bungee.api.event.PostLoginEvent; +import net.md_5.bungee.event.EventHandler; + +import javax.imageio.ImageIO; +import java.io.File; +import java.io.IOException; +import java.util.*; +import java.util.concurrent.TimeUnit; + +public class TablistManager extends BasicListener { + + private static final Map tablists = new HashMap<>(); + + private int seconds = 0; + private Icon darkGray; + private Icon gray; + + private String header; + private int size; + private TreeMap> playerMap = new TreeMap<>(); + + public TablistManager(){ + ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this::updateCustomTablist, 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); + }catch(IOException e){ + throw new SecurityException("Could not load icons", e); + } + } + + private void setHeader(){ + if(seconds % 4 == 0){ + int phase = (seconds % 16) / 4; + switch(phase){ + case 0: + header = "§8Spieler online: §e" + ProxyServer.getInstance().getPlayers().size(); + break; + case 1: + header = "§8Teamspeak: §eSteam§8War.de"; + break; + case 2: + header = "§8Discord: §8https://discord.gg/J4NtQmM"; + break; + case 3: + default: + header = "§8Website: https://§eSteam§8War.de"; + break; + } + } + } + + private void calculateSize(){ + size = -1; + for(Map.Entry> server : playerMap.entrySet()) + size += 2 + server.getValue().size(); + if(size < 0){ + size = 0; + return; + } + + size = size/20+20; + } + + private synchronized void updateCustomTablist(){ + setHeader(); + + //Calculate server-player-map + playerMap.clear(); + for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()){ + ServerInfo server = player.getServer().getInfo(); + String serverName = server.getName(); + if(serverName.equals("Developer")) + continue; + + Subserver subserver = Subserver.getSubserver(server); + List players; + if(subserver != null && subserver.getType() == Servertype.BAUSERVER){ + players = playerMap.getOrDefault("Bau", new ArrayList<>()); + }else{ + players = playerMap.getOrDefault(serverName, new ArrayList<>()); + } + + players.add(player); + playerMap.putIfAbsent(serverName, players); + } + playerMap.forEach((server, players) -> players.sort((proxiedPlayer, t1) -> proxiedPlayer.getName().compareToIgnoreCase(t1.getName()))); + + //Set size + calculateSize(); + if(size > 80) + size = 80; + + for(Tablist tablist : tablists.values()) + 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{ + private final CustomTablist customTablist; + private final ProxiedPlayer player; + + private Tablist(ProxiedPlayer player){ + this.player = player; + this.customTablist = BungeeTabListPlusAPI.createCustomTablist(); + BungeeTabListPlusAPI.setCustomTabList(player, customTablist); + } + + private String getPing(){ + int ping = player.getPing(); + if(ping < 50){ + return "§a" + ping; + }else if(ping < 150){ + return "§e" + ping; + }else{ + return "§c" + ping; + } + } + + private void refresh(){ + customTablist.setHeader(header); + customTablist.setFooter("§e" + player.getServer().getInfo().getName() + " " + getPing() + "§8ms"); + customTablist.setSize(size); + + try { + int i = 0; + for (String server : playerMap.navigableKeySet()) { + if (i > 0) + customTablist.setSlot(i++, 0, darkGray, "", 1000); + customTablist.setSlot(i++, 0, gray, "§7§l" + server, 1000); + for (ProxiedPlayer p : playerMap.get(server)) + customTablist.setSlot(i++, 0, BungeeTabListPlusAPI.getIconFromPlayer(p), p.getDisplayName(), 1); + } + + while (i < size) + customTablist.setSlot(i++, 0, darkGray, "", 1000); + }catch(IndexOutOfBoundsException e){ + //Ignore + } + } + } +}