geforkt von SteamWar/BungeeCore
Current tablist
Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Ursprung
0da2383adb
Commit
eed24006fb
@ -19,27 +19,37 @@
|
||||
|
||||
package de.steamwar.bungeecore.tablist;
|
||||
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
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.PacketWrapper;
|
||||
import net.md_5.bungee.protocol.packet.PlayerListHeaderFooter;
|
||||
import net.md_5.bungee.protocol.packet.PlayerListItem;
|
||||
import net.md_5.bungee.protocol.packet.Team;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TablistListener extends MessageToMessageDecoder<PacketWrapper> {
|
||||
|
||||
//private boolean teamSent = false;
|
||||
private final ProxiedPlayer player;
|
||||
private final ServerConnection connection;
|
||||
|
||||
public TablistListener(ServerConnection connection) {
|
||||
public TablistListener(ProxiedPlayer player, ServerConnection connection) {
|
||||
this.player = player;
|
||||
this.connection = connection;
|
||||
player.unsafe().sendPacket(TablistManager.teamPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, PacketWrapper packetWrapper, List<Object> out) {
|
||||
//Team
|
||||
if(!connection.isObsolete()) {
|
||||
DefinedPacket packet = packetWrapper.packet;
|
||||
|
||||
@ -48,17 +58,45 @@ public class TablistListener extends MessageToMessageDecoder<PacketWrapper> {
|
||||
return;
|
||||
} else if(packet instanceof PlayerListItem) {
|
||||
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()) {
|
||||
item.setPing(1);
|
||||
//item.setUsername("AAA");
|
||||
//item.setDisplayName(ComponentSerializer.toString(TextComponent.fromLegacyText("")));
|
||||
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.setDisplayName(ComponentSerializer.toString(TextComponent.fromLegacyText(SteamwarUser.get(p.getUniqueId()).getUserGroup().getColorCode() + p.getName())));
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,11 @@ package de.steamwar.bungeecore.tablist;
|
||||
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
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.api.ProxyServer;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
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.protocol.PlayerPublicKey;
|
||||
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.Team;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
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 int seconds = 0;
|
||||
|
||||
public TablistManager() {
|
||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this::updateTablist, 1, 1, TimeUnit.SECONDS);
|
||||
ProxyServer.getInstance().getPlayers().forEach(player -> tablists.put(player, new Tablist(player)));
|
||||
@ -63,7 +77,7 @@ public class TablistManager extends BasicListener {
|
||||
@EventHandler
|
||||
public void onServerConnection(ServerSwitchEvent event) {
|
||||
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
|
||||
@ -83,12 +97,13 @@ public class TablistManager extends BasicListener {
|
||||
private void updateTablist() {
|
||||
synchronized (tablists) {
|
||||
tablists.forEach((player, tablist) -> tablist.update());
|
||||
seconds++;
|
||||
}
|
||||
}
|
||||
|
||||
private static class Tablist {
|
||||
private class Tablist {
|
||||
private final ProxiedPlayer player;
|
||||
private PlayerListItem.Item[] shown = new PlayerListItem.Item[0];
|
||||
private int shown = 0;
|
||||
|
||||
private Tablist(ProxiedPlayer player) {
|
||||
this.player = player;
|
||||
@ -98,34 +113,63 @@ public class TablistManager extends BasicListener {
|
||||
if(player.getServer() == null)
|
||||
return;
|
||||
|
||||
//TODO header & footer
|
||||
PlayerListItem removePacket = removePacket();
|
||||
player.unsafe().sendPacket(new PlayerListHeaderFooter(
|
||||
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();
|
||||
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);
|
||||
for(int i = 0; i < shown.length; i++) {
|
||||
shown[i].setUsername("»SW« " + i);
|
||||
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);
|
||||
if(items.length > 80) {
|
||||
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);
|
||||
//TODO Set direct displaynames for onserver personel (and update correctly)
|
||||
//TODO Add direct onserver not shown
|
||||
}
|
||||
|
||||
private PlayerListItem.Item construct(String displayName, String color) {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
return construct(uuid, null, new Property[]{createSkin(uuid, "»SW«", color)}, null, 1, 1000, displayName);
|
||||
private BaseComponent[] header(ChatSender p){
|
||||
int phase = (seconds % 16) / 3;
|
||||
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) {
|
||||
// \"timestamp\":0,\"profileId\":\"" + uuid.toString().replace("-", "") + "\",\"profileName\":\"" + username + "\",
|
||||
return new Property("textures", Base64.getEncoder().encodeToString(("{\"textures\":{\"SKIN\":{\"url\":\"https://steamwar.de/" + color + ".png\"}}}").getBytes(StandardCharsets.UTF_8)));
|
||||
private String ping() {
|
||||
int ping = player.getPing();
|
||||
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) {
|
||||
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) {
|
||||
@ -140,15 +184,21 @@ public class TablistManager extends BasicListener {
|
||||
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();
|
||||
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;
|
||||
}
|
||||
|
||||
private void remove() {
|
||||
player.unsafe().sendPacket(removePacket());
|
||||
player.unsafe().sendPacket(removePacket(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,10 @@ public interface ChatSender {
|
||||
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) {
|
||||
Locale locale = getLocale();
|
||||
ResourceBundle resourceBundle = SteamwarResourceBundle.getResourceBundle(locale);
|
||||
|
@ -35,7 +35,7 @@ public class SteamwarResourceBundle extends PropertyResourceBundle {
|
||||
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 -> {
|
||||
InputStream inputStream = Message.class.getResourceAsStream(BASE_PATH + ("".equals(locale) ? "" : "_" + locale) + ".properties");
|
||||
if(inputStream == null)
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren