Current tablist
Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Ursprung
9703e9ea33
Commit
598dfcd8a0
@ -19,27 +19,37 @@
|
|||||||
|
|
||||||
package de.steamwar.bungeecore.tablist;
|
package de.steamwar.bungeecore.tablist;
|
||||||
|
|
||||||
|
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||||
import net.md_5.bungee.ServerConnection;
|
import net.md_5.bungee.ServerConnection;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.chat.ComponentSerializer;
|
||||||
import net.md_5.bungee.protocol.DefinedPacket;
|
import net.md_5.bungee.protocol.DefinedPacket;
|
||||||
import net.md_5.bungee.protocol.PacketWrapper;
|
import net.md_5.bungee.protocol.PacketWrapper;
|
||||||
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
|
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
|
||||||
import net.md_5.bungee.protocol.packet.PlayerListItem;
|
import net.md_5.bungee.protocol.packet.PlayerListItem;
|
||||||
|
import net.md_5.bungee.protocol.packet.Team;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TablistListener extends MessageToMessageDecoder<PacketWrapper> {
|
public class TablistListener extends MessageToMessageDecoder<PacketWrapper> {
|
||||||
|
|
||||||
|
//private boolean teamSent = false;
|
||||||
|
private final ProxiedPlayer player;
|
||||||
private final ServerConnection connection;
|
private final ServerConnection connection;
|
||||||
|
|
||||||
public TablistListener(ServerConnection connection) {
|
public TablistListener(ProxiedPlayer player, ServerConnection connection) {
|
||||||
|
this.player = player;
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
|
player.unsafe().sendPacket(TablistManager.teamPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, PacketWrapper packetWrapper, List<Object> out) {
|
protected void decode(ChannelHandlerContext ctx, PacketWrapper packetWrapper, List<Object> out) {
|
||||||
//Team
|
|
||||||
if(!connection.isObsolete()) {
|
if(!connection.isObsolete()) {
|
||||||
DefinedPacket packet = packetWrapper.packet;
|
DefinedPacket packet = packetWrapper.packet;
|
||||||
|
|
||||||
@ -48,17 +58,45 @@ public class TablistListener extends MessageToMessageDecoder<PacketWrapper> {
|
|||||||
return;
|
return;
|
||||||
} else if(packet instanceof PlayerListItem) {
|
} else if(packet instanceof PlayerListItem) {
|
||||||
PlayerListItem list = (PlayerListItem) packet;
|
PlayerListItem list = (PlayerListItem) packet;
|
||||||
if(list.getAction() == PlayerListItem.Action.UPDATE_LATENCY || list.getAction() == PlayerListItem.Action.ADD_PLAYER) {
|
PlayerListItem.Action action = list.getAction();
|
||||||
|
if(action == PlayerListItem.Action.UPDATE_DISPLAY_NAME || action == PlayerListItem.Action.UPDATE_LATENCY) {
|
||||||
|
packetWrapper.trySingleRelease();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(action == PlayerListItem.Action.UPDATE_GAMEMODE) {
|
||||||
for (PlayerListItem.Item item : list.getItems()) {
|
for (PlayerListItem.Item item : list.getItems()) {
|
||||||
|
ProxiedPlayer p = ProxyServer.getInstance().getPlayer(item.getUuid());
|
||||||
|
if(p != null && p != player && item.getGamemode() == 3) {
|
||||||
|
item.setGamemode(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(action != PlayerListItem.Action.REMOVE_PLAYER) {
|
||||||
|
List<String> npcs = new ArrayList<>();
|
||||||
|
for (PlayerListItem.Item item : list.getItems()) {
|
||||||
|
ProxiedPlayer p = ProxyServer.getInstance().getPlayer(item.getUuid());
|
||||||
|
if(p == null) {
|
||||||
|
item.setPing(1000);
|
||||||
|
item.setDisplayName(ComponentSerializer.toString(TextComponent.fromLegacyText("")));
|
||||||
|
npcs.add(item.getUsername());
|
||||||
|
} else {
|
||||||
item.setPing(1);
|
item.setPing(1);
|
||||||
//item.setUsername("AAA");
|
item.setDisplayName(ComponentSerializer.toString(TextComponent.fromLegacyText(SteamwarUser.get(p.getUniqueId()).getUserGroup().getColorCode() + p.getName())));
|
||||||
//item.setDisplayName(ComponentSerializer.toString(TextComponent.fromLegacyText("")));
|
if(p != player && item.getGamemode() == 3) {
|
||||||
|
item.setGamemode(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!npcs.isEmpty()) {
|
||||||
|
Team teamPacket = new Team(TablistManager.TAB_TEAM);
|
||||||
|
teamPacket.setMode((byte) 3);
|
||||||
|
teamPacket.setPlayers(npcs.toArray(new String[0]));
|
||||||
|
player.unsafe().sendPacket(teamPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.add(packetWrapper);
|
out.add(packetWrapper);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,11 @@ package de.steamwar.bungeecore.tablist;
|
|||||||
|
|
||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.BungeeCore;
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||||
|
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||||
|
import de.steamwar.messages.ChatSender;
|
||||||
import net.md_5.bungee.ServerConnection;
|
import net.md_5.bungee.ServerConnection;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
import net.md_5.bungee.api.event.PlayerDisconnectEvent;
|
||||||
@ -34,20 +37,31 @@ import net.md_5.bungee.event.EventHandler;
|
|||||||
import net.md_5.bungee.netty.PipelineUtils;
|
import net.md_5.bungee.netty.PipelineUtils;
|
||||||
import net.md_5.bungee.protocol.PlayerPublicKey;
|
import net.md_5.bungee.protocol.PlayerPublicKey;
|
||||||
import net.md_5.bungee.protocol.Property;
|
import net.md_5.bungee.protocol.Property;
|
||||||
|
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
|
||||||
import net.md_5.bungee.protocol.packet.PlayerListItem;
|
import net.md_5.bungee.protocol.packet.PlayerListItem;
|
||||||
|
import net.md_5.bungee.protocol.packet.Team;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Base64;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class TablistManager extends BasicListener {
|
public class TablistManager extends BasicListener {
|
||||||
|
|
||||||
|
public static final String TAB_TEAM = "»SW-Tab";
|
||||||
|
|
||||||
|
private static final Property[] GRAY = new Property[]{new Property("textures", Base64.getEncoder().encodeToString(("{\"textures\":{\"SKIN\":{\"url\":\"https://steamwar.de/gray.png\"}}}").getBytes(StandardCharsets.UTF_8)))};
|
||||||
|
private static final Property[] LIGHT_GRAY = new Property[]{new Property("textures", Base64.getEncoder().encodeToString(("{\"textures\":{\"SKIN\":{\"url\":\"https://steamwar.de/lightgray.png\"}}}").getBytes(StandardCharsets.UTF_8)))};
|
||||||
|
|
||||||
|
private static final UUID[] uuids = IntStream.range(0, 80).mapToObj(i -> UUID.randomUUID()).toArray(UUID[]::new);
|
||||||
|
private static final String[] names = IntStream.range(0, 80).mapToObj(i -> " »SW« " + i).toArray(String[]::new);
|
||||||
|
public static final Team teamPacket = new Team(TAB_TEAM, (byte) 0, ComponentSerializer.toString(TextComponent.fromLegacyText("")), ComponentSerializer.toString(TextComponent.fromLegacyText("")), ComponentSerializer.toString(TextComponent.fromLegacyText("")), "never", "never", 21, (byte)0x00, names); // new String[]{}
|
||||||
|
|
||||||
private final Map<ProxiedPlayer, Tablist> tablists = new HashMap<>();
|
private final Map<ProxiedPlayer, Tablist> tablists = new HashMap<>();
|
||||||
|
|
||||||
|
private int seconds = 0;
|
||||||
|
|
||||||
public TablistManager() {
|
public TablistManager() {
|
||||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this::updateTablist, 1, 1, TimeUnit.SECONDS);
|
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this::updateTablist, 1, 1, TimeUnit.SECONDS);
|
||||||
ProxyServer.getInstance().getPlayers().forEach(player -> tablists.put(player, new Tablist(player)));
|
ProxyServer.getInstance().getPlayers().forEach(player -> tablists.put(player, new Tablist(player)));
|
||||||
@ -63,7 +77,7 @@ public class TablistManager extends BasicListener {
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void onServerConnection(ServerSwitchEvent event) {
|
public void onServerConnection(ServerSwitchEvent event) {
|
||||||
ServerConnection server = (ServerConnection) event.getPlayer().getServer();
|
ServerConnection server = (ServerConnection) event.getPlayer().getServer();
|
||||||
server.getCh().getHandle().pipeline().addBefore(PipelineUtils.BOSS_HANDLER, "steamwar-tablist", new TablistListener(server));
|
server.getCh().getHandle().pipeline().addBefore(PipelineUtils.BOSS_HANDLER, "steamwar-tablist", new TablistListener(event.getPlayer(), server));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@ -83,12 +97,13 @@ public class TablistManager extends BasicListener {
|
|||||||
private void updateTablist() {
|
private void updateTablist() {
|
||||||
synchronized (tablists) {
|
synchronized (tablists) {
|
||||||
tablists.forEach((player, tablist) -> tablist.update());
|
tablists.forEach((player, tablist) -> tablist.update());
|
||||||
|
seconds++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Tablist {
|
private class Tablist {
|
||||||
private final ProxiedPlayer player;
|
private final ProxiedPlayer player;
|
||||||
private PlayerListItem.Item[] shown = new PlayerListItem.Item[0];
|
private int shown = 0;
|
||||||
|
|
||||||
private Tablist(ProxiedPlayer player) {
|
private Tablist(ProxiedPlayer player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
@ -98,34 +113,63 @@ public class TablistManager extends BasicListener {
|
|||||||
if(player.getServer() == null)
|
if(player.getServer() == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//TODO header & footer
|
player.unsafe().sendPacket(new PlayerListHeaderFooter(
|
||||||
PlayerListItem removePacket = removePacket();
|
ComponentSerializer.toString(header(ChatSender.of(player))),
|
||||||
|
ComponentSerializer.toString(ChatSender.of(player).parse(false, "TABLIST_FOOTER", player.getServer().getInfo().getName(), ping(), ProxyServer.getInstance().getPlayers().size()))
|
||||||
|
));
|
||||||
|
|
||||||
PlayerListItem addPacket = new PlayerListItem();
|
PlayerListItem addPacket = new PlayerListItem();
|
||||||
addPacket.setAction(PlayerListItem.Action.ADD_PLAYER);
|
addPacket.setAction(PlayerListItem.Action.ADD_PLAYER);
|
||||||
|
|
||||||
shown = ProxyServer.getInstance().getServers().entrySet().stream().filter(entry -> entry.getValue() != player.getServer().getInfo()).sorted((e1, e2) -> e1.getKey().compareToIgnoreCase(e2.getKey())).flatMap(entry -> Stream.concat(Stream.of(construct("", "gray"), construct("§7§l" + entry.getKey(), "lightgray")), entry.getValue().getPlayers().stream().map(this::construct))).toArray(PlayerListItem.Item[]::new);
|
PlayerListItem.Item[] items = ProxyServer.getInstance().getServers().entrySet().stream().filter(entry -> entry.getValue() != player.getServer().getInfo()).sorted((e1, e2) -> e1.getKey().compareToIgnoreCase(e2.getKey())).flatMap(entry -> Stream.concat(Stream.of(construct("", false), construct("§7§l" + entry.getKey(), true)), entry.getValue().getPlayers().stream().map(this::construct))).toArray(PlayerListItem.Item[]::new);
|
||||||
for(int i = 0; i < shown.length; i++) {
|
if(items.length > 80) {
|
||||||
shown[i].setUsername("»SW« " + i);
|
items = Arrays.copyOf(items, 80);
|
||||||
}
|
}
|
||||||
addPacket.setItems(shown);
|
for(int i = 0; i < items.length; i++) {
|
||||||
|
items[i].setUuid(uuids[i]);
|
||||||
|
items[i].setUsername(names[i]);
|
||||||
|
}
|
||||||
|
addPacket.setItems(items);
|
||||||
|
|
||||||
player.unsafe().sendPacket(removePacket);
|
if(shown > items.length)
|
||||||
|
player.unsafe().sendPacket(removePacket(items.length));
|
||||||
|
|
||||||
|
shown = items.length;
|
||||||
player.unsafe().sendPacket(addPacket);
|
player.unsafe().sendPacket(addPacket);
|
||||||
|
//TODO Set direct displaynames for onserver personel (and update correctly)
|
||||||
|
//TODO Add direct onserver not shown
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlayerListItem.Item construct(String displayName, String color) {
|
private BaseComponent[] header(ChatSender p){
|
||||||
UUID uuid = UUID.randomUUID();
|
int phase = (seconds % 16) / 3;
|
||||||
return construct(uuid, null, new Property[]{createSkin(uuid, "»SW«", color)}, null, 1, 1000, displayName);
|
switch(phase){
|
||||||
|
case 0:
|
||||||
|
return p.parse(false, "TABLIST_PHASE_1");
|
||||||
|
case 1:
|
||||||
|
return p.parse(false, "TABLIST_PHASE_2");
|
||||||
|
default:
|
||||||
|
return p.parse(false, "TABLIST_PHASE_DEFAULT");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Property createSkin(UUID uuid, String username, String color) {
|
private String ping() {
|
||||||
// \"timestamp\":0,\"profileId\":\"" + uuid.toString().replace("-", "") + "\",\"profileName\":\"" + username + "\",
|
int ping = player.getPing();
|
||||||
return new Property("textures", Base64.getEncoder().encodeToString(("{\"textures\":{\"SKIN\":{\"url\":\"https://steamwar.de/" + color + ".png\"}}}").getBytes(StandardCharsets.UTF_8)));
|
if(ping < 50){
|
||||||
|
return "§a" + ping;
|
||||||
|
}else if(ping < 150){
|
||||||
|
return "§e" + ping;
|
||||||
|
}else{
|
||||||
|
return "§c" + ping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlayerListItem.Item construct(String displayName, boolean lightgray) {
|
||||||
|
// TODO lightgray ? LIGHT_GRAY : GRAY
|
||||||
|
return construct(null, null, new Property[]{}, null, 1, 1000, displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlayerListItem.Item construct(ProxiedPlayer player) {
|
private PlayerListItem.Item construct(ProxiedPlayer player) {
|
||||||
return construct(player.getUniqueId(), null, ((InitialHandler)player.getPendingConnection()).getLoginProfile().getProperties(), ((InitialHandler)player.getPendingConnection()).getLoginRequest().getPublicKey(), 1, 1000, player.getDisplayName());
|
return construct(player.getUniqueId(), null, ((InitialHandler)player.getPendingConnection()).getLoginProfile().getProperties(), ((InitialHandler)player.getPendingConnection()).getLoginRequest().getPublicKey(), 1, 1000, SteamwarUser.get(player.getUniqueId()).getUserGroup().getColorCode() + player.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlayerListItem.Item construct(UUID uuid, String username, Property[] properties, PlayerPublicKey publicKey, int gamemode, int ping, String displayName) {
|
private PlayerListItem.Item construct(UUID uuid, String username, Property[] properties, PlayerPublicKey publicKey, int gamemode, int ping, String displayName) {
|
||||||
@ -140,15 +184,21 @@ public class TablistManager extends BasicListener {
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlayerListItem removePacket() {
|
private PlayerListItem.Item construct(UUID uuid) {
|
||||||
|
PlayerListItem.Item item = new PlayerListItem.Item();
|
||||||
|
item.setUuid(uuid);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlayerListItem removePacket(int newLength) {
|
||||||
PlayerListItem packet = new PlayerListItem();
|
PlayerListItem packet = new PlayerListItem();
|
||||||
packet.setAction(PlayerListItem.Action.REMOVE_PLAYER);
|
packet.setAction(PlayerListItem.Action.REMOVE_PLAYER);
|
||||||
packet.setItems(shown);
|
packet.setItems(IntStream.range(newLength, shown).mapToObj(i -> construct(uuids[i])).toArray(PlayerListItem.Item[]::new));
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void remove() {
|
private void remove() {
|
||||||
player.unsafe().sendPacket(removePacket());
|
player.unsafe().sendPacket(removePacket(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,10 @@ public interface ChatSender {
|
|||||||
return parseToComponent(false, message).toLegacyText();
|
return parseToComponent(false, message).toLegacyText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default BaseComponent[] parse(boolean prefixed, String format, Object... params) {
|
||||||
|
return parse(prefixed, new Message(format, params));
|
||||||
|
}
|
||||||
|
|
||||||
default BaseComponent[] parse(boolean prefixed, Message message) {
|
default BaseComponent[] parse(boolean prefixed, Message message) {
|
||||||
Locale locale = getLocale();
|
Locale locale = getLocale();
|
||||||
ResourceBundle resourceBundle = SteamwarResourceBundle.getResourceBundle(locale);
|
ResourceBundle resourceBundle = SteamwarResourceBundle.getResourceBundle(locale);
|
||||||
|
@ -35,7 +35,7 @@ public class SteamwarResourceBundle extends PropertyResourceBundle {
|
|||||||
return getResourceBundle(locale.toString(), getResourceBundle(locale.getLanguage(), getResourceBundle( "", null)));
|
return getResourceBundle(locale.toString(), getResourceBundle(locale.getLanguage(), getResourceBundle( "", null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ResourceBundle getResourceBundle(String locale, ResourceBundle parent) {
|
private static synchronized ResourceBundle getResourceBundle(String locale, ResourceBundle parent) {
|
||||||
return bundles.computeIfAbsent(locale, locale1 -> {
|
return bundles.computeIfAbsent(locale, locale1 -> {
|
||||||
InputStream inputStream = Message.class.getResourceAsStream(BASE_PATH + ("".equals(locale) ? "" : "_" + locale) + ".properties");
|
InputStream inputStream = Message.class.getResourceAsStream(BASE_PATH + ("".equals(locale) ? "" : "_" + locale) + ".properties");
|
||||||
if(inputStream == null)
|
if(inputStream == null)
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren