Tablist #411
@ -26,6 +26,7 @@ import de.steamwar.bungeecore.comms.SpigotReceiver;
|
||||
import de.steamwar.bungeecore.listeners.*;
|
||||
import de.steamwar.bungeecore.listeners.mods.*;
|
||||
import de.steamwar.bungeecore.sql.*;
|
||||
import de.steamwar.bungeecore.tablist.TablistManager;
|
||||
import net.md_5.bungee.api.ChatMessageType;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
@ -63,6 +64,7 @@ public class BungeeCore extends Plugin {
|
||||
public static final Map<String, String> commands = new HashMap<>();
|
||||
|
||||
private ErrorLogger errorLogger;
|
||||
private TablistManager tablistManager;
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
@ -157,7 +159,7 @@ public class BungeeCore extends Plugin {
|
||||
new EventStarter();
|
||||
new SessionManager();
|
||||
new SpigotReceiver();
|
||||
new TablistManager();
|
||||
tablistManager = new TablistManager();
|
||||
new SettingsChangedListener();
|
||||
|
||||
getProxy().getScheduler().schedule(this, () -> {
|
||||
@ -185,6 +187,7 @@ public class BungeeCore extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
tablistManager.disable();
|
||||
errorLogger.unregister();
|
||||
Statement.closeAll();
|
||||
}
|
||||
|
64
src/de/steamwar/bungeecore/tablist/TablistListener.java
Normale Datei
64
src/de/steamwar/bungeecore/tablist/TablistListener.java
Normale Datei
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.tablist;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import net.md_5.bungee.ServerConnection;
|
||||
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 java.util.List;
|
||||
|
||||
public class TablistListener extends MessageToMessageDecoder<PacketWrapper> {
|
||||
|
||||
private final ServerConnection connection;
|
||||
|
||||
public TablistListener(ServerConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, PacketWrapper packetWrapper, List<Object> out) {
|
||||
//Team
|
||||
if(!connection.isObsolete()) {
|
||||
DefinedPacket packet = packetWrapper.packet;
|
||||
|
||||
if(packet instanceof PlayerListHeaderFooter) {
|
||||
packetWrapper.trySingleRelease();
|
||||
return;
|
||||
} else if(packet instanceof PlayerListItem) {
|
||||
PlayerListItem list = (PlayerListItem) packet;
|
||||
if(list.getAction() == PlayerListItem.Action.UPDATE_LATENCY || list.getAction() == PlayerListItem.Action.ADD_PLAYER) {
|
||||
for (PlayerListItem.Item item : list.getItems()) {
|
||||
item.setPing(1);
|
||||
//item.setUsername("AAA");
|
||||
//item.setDisplayName(ComponentSerializer.toString(TextComponent.fromLegacyText("")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
out.add(packetWrapper);
|
||||
|
||||
|
||||
}
|
||||
}
|
154
src/de/steamwar/bungeecore/tablist/TablistManager.java
Normale Datei
154
src/de/steamwar/bungeecore/tablist/TablistManager.java
Normale Datei
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2022 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.tablist;
|
||||
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||
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.api.event.PlayerDisconnectEvent;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.event.ServerSwitchEvent;
|
||||
import net.md_5.bungee.chat.ComponentSerializer;
|
||||
import net.md_5.bungee.connection.InitialHandler;
|
||||
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.PlayerListItem;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class TablistManager extends BasicListener {
|
||||
|
||||
private final Map<ProxiedPlayer, Tablist> tablists = new HashMap<>();
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PostLoginEvent event) {
|
||||
synchronized (tablists) {
|
||||
tablists.put(event.getPlayer(), new Tablist(event.getPlayer()));
|
||||
}
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onLeave(PlayerDisconnectEvent event) {
|
||||
synchronized (tablists) {
|
||||
tablists.remove(event.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
synchronized (tablists) {
|
||||
tablists.forEach((player, tablist) -> tablist.remove());
|
||||
tablists.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTablist() {
|
||||
synchronized (tablists) {
|
||||
tablists.forEach((player, tablist) -> tablist.update());
|
||||
}
|
||||
}
|
||||
|
||||
private static class Tablist {
|
||||
private final ProxiedPlayer player;
|
||||
private PlayerListItem.Item[] shown = new PlayerListItem.Item[0];
|
||||
|
||||
private Tablist(ProxiedPlayer player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if(player.getServer() == null)
|
||||
return;
|
||||
|
||||
//TODO header & footer
|
||||
PlayerListItem removePacket = removePacket();
|
||||
|
||||
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);
|
||||
}
|
||||
addPacket.setItems(shown);
|
||||
|
||||
player.unsafe().sendPacket(removePacket);
|
||||
player.unsafe().sendPacket(addPacket);
|
||||
}
|
||||
|
||||
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 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 PlayerListItem.Item construct(ProxiedPlayer player) {
|
||||
return construct(player.getUniqueId(), null, ((InitialHandler)player.getPendingConnection()).getLoginProfile().getProperties(), ((InitialHandler)player.getPendingConnection()).getLoginRequest().getPublicKey(), 1, 1000, player.getDisplayName());
|
||||
}
|
||||
|
||||
private PlayerListItem.Item construct(UUID uuid, String username, Property[] properties, PlayerPublicKey publicKey, int gamemode, int ping, String displayName) {
|
||||
PlayerListItem.Item item = new PlayerListItem.Item();
|
||||
item.setUuid(uuid);
|
||||
item.setUsername(username);
|
||||
item.setProperties(properties);
|
||||
item.setPublicKey(publicKey);
|
||||
item.setGamemode(gamemode);
|
||||
item.setPing(ping);
|
||||
item.setDisplayName(ComponentSerializer.toString(TextComponent.fromLegacyText(displayName)));
|
||||
return item;
|
||||
}
|
||||
|
||||
private PlayerListItem removePacket() {
|
||||
PlayerListItem packet = new PlayerListItem();
|
||||
packet.setAction(PlayerListItem.Action.REMOVE_PLAYER);
|
||||
packet.setItems(shown);
|
||||
return packet;
|
||||
}
|
||||
|
||||
private void remove() {
|
||||
player.unsafe().sendPacket(removePacket());
|
||||
}
|
||||
}
|
||||
}
|
@ -2,4 +2,5 @@ name: BungeeCore
|
||||
main: de.steamwar.bungeecore.BungeeCore
|
||||
version: 1.0
|
||||
author: Lixfel
|
||||
depends: [PersistentBungeeCore, BungeeTabListPlus]
|
||||
depends:
|
||||
- PersistentBungeeCore
|
In neuem Issue referenzieren
Einen Benutzer sperren