Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-04 23:30:24 +01:00
Fix bungee and velocity boss bar, implement Velocity channel workaround
Dieser Commit ist enthalten in:
Ursprung
5ba7c4ba2c
Commit
44ca95bf85
@ -8,25 +8,27 @@ import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
import net.md_5.bungee.event.EventPriority;
|
||||
import net.md_5.bungee.protocol.packet.PluginMessage;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.boss.BossBar;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolVersion;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
|
||||
import us.myles.ViaVersion.bungee.storage.BungeeStorage;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeServerHandler implements Listener {
|
||||
private static Method getHandshake;
|
||||
@ -87,13 +89,14 @@ public class BungeeServerHandler implements Listener {
|
||||
public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception {
|
||||
if (user == null) return;
|
||||
// Manually hide ViaVersion-created BossBars if the childserver was version 1.8.x (#666)
|
||||
if (user.has(EntityTracker.class)) {
|
||||
// Will be cleared by code below or by ServerConnector#handle(Login)
|
||||
/*if (user.has(EntityTracker.class)) {
|
||||
EntityTracker tracker = user.get(EntityTracker.class);
|
||||
|
||||
if (tracker.getBossBarMap() != null)
|
||||
for (BossBar bar : tracker.getBossBarMap().values())
|
||||
bar.hide();
|
||||
}
|
||||
}*/
|
||||
// Handle server/version change
|
||||
if (user.has(BungeeStorage.class)) {
|
||||
BungeeStorage storage = user.get(BungeeStorage.class);
|
||||
@ -107,6 +110,18 @@ public class BungeeServerHandler implements Listener {
|
||||
|
||||
int protocolId = ProtocolDetectorService.getProtocolId(serverName);
|
||||
|
||||
if (protocolId <= ProtocolVersion.v1_8.getId()) { // 1.8 doesn't have BossBar packet
|
||||
if (storage.getBossbar() != null) {
|
||||
for (UUID uuid : storage.getBossbar()) {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x0C, null, user);
|
||||
wrapper.write(Type.UUID, uuid);
|
||||
wrapper.write(Type.VAR_INT, 1); // remove
|
||||
wrapper.send(Protocol1_9TO1_8.class, true, true);
|
||||
}
|
||||
storage.getBossbar().clear();
|
||||
}
|
||||
}
|
||||
|
||||
ProtocolInfo info = user.get(ProtocolInfo.class);
|
||||
int previousServerProtocol = info.getServerProtocolVersion();
|
||||
|
||||
@ -130,41 +145,32 @@ public class BungeeServerHandler implements Listener {
|
||||
|
||||
// Workaround 1.13 server change
|
||||
Object relayMessages = getRelayMessages.invoke(e.getPlayer().getPendingConnection());
|
||||
if (relayMessages instanceof List) {
|
||||
for (Object message : (List) relayMessages) {
|
||||
if (message instanceof PluginMessage) {
|
||||
PluginMessage plMsg = (PluginMessage) message;
|
||||
String channel = plMsg.getTag();
|
||||
if (previousServerProtocol != -1) {
|
||||
if (previousServerProtocol < ProtocolVersion.v1_13.getId()
|
||||
&& protocolId >= ProtocolVersion.v1_13.getId()) {
|
||||
channel = InventoryPackets.getNewPluginChannelId(channel);
|
||||
if (channel.equals("minecraft:register")) {
|
||||
String[] channels = new String(plMsg.getData(), StandardCharsets.UTF_8).split("\0");
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
channels[i] = InventoryPackets.getNewPluginChannelId(channels[i]);
|
||||
}
|
||||
plMsg.setData(Joiner.on('\0').join(channels).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
} else if (previousServerProtocol >= ProtocolVersion.v1_13.getId()
|
||||
&& protocolId < ProtocolVersion.v1_13.getId()) {
|
||||
channel = InventoryPackets.getOldPluginChannelId(channel);
|
||||
if (channel.equals("REGISTER")) {
|
||||
String[] channels = new String(plMsg.getData(), StandardCharsets.UTF_8).split("\0");
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
channels[i] = InventoryPackets.getOldPluginChannelId(channels[i]);
|
||||
}
|
||||
plMsg.setData(Joiner.on('\0').join(channels).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
for (Object message : (List) relayMessages) {
|
||||
PluginMessage plMsg = (PluginMessage) message;
|
||||
String channel = plMsg.getTag();
|
||||
int id1_13 = ProtocolVersion.v1_13.getId();
|
||||
if (previousServerProtocol != -1) {
|
||||
if (previousServerProtocol < id1_13 && protocolId >= id1_13) {
|
||||
channel = InventoryPackets.getNewPluginChannelId(channel);
|
||||
if (channel.equals("minecraft:register")) {
|
||||
String[] channels = new String(plMsg.getData(), StandardCharsets.UTF_8).split("\0");
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
channels[i] = InventoryPackets.getNewPluginChannelId(channels[i]);
|
||||
}
|
||||
plMsg.setData(Joiner.on('\0').join(channels).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
} else if (previousServerProtocol >= id1_13 && protocolId < id1_13) {
|
||||
channel = InventoryPackets.getOldPluginChannelId(channel);
|
||||
if (channel.equals("REGISTER")) {
|
||||
String[] channels = new String(plMsg.getData(), StandardCharsets.UTF_8).split("\0");
|
||||
for (int i = 0; i < channels.length; i++) {
|
||||
channels[i] = InventoryPackets.getOldPluginChannelId(channels[i]);
|
||||
}
|
||||
plMsg.setData(Joiner.on('\0').join(channels).getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
plMsg.setTag(channel);
|
||||
} else {
|
||||
Via.getPlatform().getLogger().warning("relayMessages contains a element that isn't a Handshake " + message);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Via.getPlatform().getLogger().warning("relayMessages isn't a List! " + relayMessages);
|
||||
plMsg.setTag(channel);
|
||||
}
|
||||
|
||||
user.put(info);
|
||||
|
@ -5,21 +5,27 @@ import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.player.ServerConnectedEvent;
|
||||
import com.velocitypowered.api.event.player.ServerPreConnectEvent;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import us.myles.ViaVersion.api.PacketWrapper;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
import us.myles.ViaVersion.api.boss.BossBar;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.Protocol;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
|
||||
import us.myles.ViaVersion.api.type.Type;
|
||||
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
|
||||
import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.packets.InventoryPackets;
|
||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
import us.myles.ViaVersion.velocity.service.ProtocolDetectorService;
|
||||
import us.myles.ViaVersion.velocity.storage.VelocityStorage;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
public class VelocityServerHandler {
|
||||
@ -27,6 +33,7 @@ public class VelocityServerHandler {
|
||||
private static Method setNextProtocolVersion;
|
||||
private static Method getMinecraftConnection;
|
||||
private static Method getNextProtocolVersion;
|
||||
private static Method getKnownChannels;
|
||||
|
||||
static {
|
||||
try {
|
||||
@ -38,6 +45,8 @@ public class VelocityServerHandler {
|
||||
.getDeclaredMethod("getMinecraftConnection");
|
||||
getNextProtocolVersion = Class.forName("com.velocitypowered.proxy.connection.MinecraftConnection")
|
||||
.getDeclaredMethod("getNextProtocolVersion");
|
||||
getKnownChannels = Class.forName("com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler")
|
||||
.getDeclaredMethod("getKnownChannels");
|
||||
} catch (NoSuchMethodException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -79,13 +88,14 @@ public class VelocityServerHandler {
|
||||
public void checkServerChange(ServerConnectedEvent e, UserConnection user) throws Exception {
|
||||
if (user == null) return;
|
||||
// Manually hide ViaVersion-created BossBars if the childserver was version 1.8.x (#666)
|
||||
if (user.has(EntityTracker.class)) {
|
||||
// Will be cleared by code below or by Velocity's handleBackendJoinGame
|
||||
/*if (user.has(EntityTracker.class)) {
|
||||
EntityTracker tracker = user.get(EntityTracker.class);
|
||||
|
||||
if (tracker.getBossBarMap() != null)
|
||||
for (BossBar bar : tracker.getBossBarMap().values())
|
||||
bar.hide();
|
||||
}
|
||||
}*/
|
||||
// Handle server/version change
|
||||
if (user.has(VelocityStorage.class)) {
|
||||
// Wait all the scheduled packets be sent
|
||||
@ -99,6 +109,8 @@ public class VelocityServerHandler {
|
||||
|
||||
VelocityStorage storage = user.get(VelocityStorage.class);
|
||||
|
||||
if (storage.getBossbar() == null) storage.saveServerBossBars();
|
||||
|
||||
if (e.getServer() != null) {
|
||||
if (!e.getServer().getServerInfo().getName().equals(storage.getCurrentServer())) {
|
||||
String serverName = e.getServer().getServerInfo().getName();
|
||||
@ -107,7 +119,20 @@ public class VelocityServerHandler {
|
||||
|
||||
int protocolId = ProtocolDetectorService.getProtocolId(serverName);
|
||||
|
||||
if (protocolId <= ProtocolVersion.MINECRAFT_1_8.getProtocol()) { // 1.8 doesn't have BossBar packet
|
||||
if (storage.getBossbar() != null) {
|
||||
for (UUID uuid : storage.getBossbar()) {
|
||||
PacketWrapper wrapper = new PacketWrapper(0x0C, null, user);
|
||||
wrapper.write(Type.UUID, uuid);
|
||||
wrapper.write(Type.VAR_INT, 1); // remove
|
||||
wrapper.send(Protocol1_9TO1_8.class, true, true);
|
||||
}
|
||||
storage.getBossbar().clear();
|
||||
}
|
||||
}
|
||||
|
||||
ProtocolInfo info = user.get(ProtocolInfo.class);
|
||||
int previousServerProtocol = info.getServerProtocolVersion();
|
||||
|
||||
// Refresh the pipes
|
||||
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId);
|
||||
@ -127,6 +152,33 @@ public class VelocityServerHandler {
|
||||
// Add version-specific base Protocol
|
||||
pipeline.add(ProtocolRegistry.getBaseProtocol(protocolId));
|
||||
|
||||
// Workaround 1.13 server change
|
||||
Set<String> knownChannels = (Set<String>) getKnownChannels.invoke(
|
||||
ReflectionUtil.invoke(
|
||||
getMinecraftConnection.invoke(e.getPlayer()),
|
||||
"getSessionHandler"
|
||||
)
|
||||
);
|
||||
if (previousServerProtocol != -1) {
|
||||
int id1_13 = ProtocolVersion.MINECRAFT_1_13.getProtocol();
|
||||
if (previousServerProtocol < id1_13 && protocolId >= id1_13) {
|
||||
ArrayList<String> newChannels = new ArrayList<>();
|
||||
for (String oldChannel : knownChannels) {
|
||||
newChannels.add(InventoryPackets.getNewPluginChannelId(oldChannel));
|
||||
}
|
||||
knownChannels.clear();
|
||||
knownChannels.addAll(newChannels);
|
||||
|
||||
} else if (previousServerProtocol >= id1_13 && protocolId < id1_13) {
|
||||
ArrayList<String> newChannels = new ArrayList<>();
|
||||
for (String oldChannel : knownChannels) {
|
||||
newChannels.add(InventoryPackets.getOldPluginChannelId(oldChannel));
|
||||
}
|
||||
knownChannels.clear();
|
||||
knownChannels.addAll(newChannels);
|
||||
}
|
||||
}
|
||||
|
||||
user.put(info);
|
||||
user.put(storage);
|
||||
|
||||
|
@ -5,8 +5,10 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import us.myles.ViaVersion.api.data.StoredObject;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
import java.util.Set;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Data
|
||||
@ -14,24 +16,24 @@ import java.util.UUID;
|
||||
public class VelocityStorage extends StoredObject {
|
||||
private Player player;
|
||||
private String currentServer;
|
||||
private Set<UUID> bossbar;
|
||||
private List<UUID> bossbar;
|
||||
|
||||
public VelocityStorage(UserConnection user, Player player) {
|
||||
super(user);
|
||||
this.player = player;
|
||||
this.currentServer = "";
|
||||
}
|
||||
|
||||
public void saveServerBossBars() {
|
||||
// Get bossbar list if it's supported
|
||||
/* TODO make this work - do we need this?
|
||||
try {
|
||||
Object connection = ReflectionUtil.invoke(player, "getConnection");
|
||||
Object connection = ReflectionUtil.invoke(player, "getMinecraftConnection");
|
||||
Object sessionHandler = ReflectionUtil.invoke(connection, "getSessionHandler");
|
||||
if (sessionHandler.getClass().getSimpleName().contains("Play")) {
|
||||
bossbar = (Set<UUID>) ReflectionUtil.invoke(sessionHandler, "getServerBossBars");
|
||||
bossbar = (List<UUID>) ReflectionUtil.invoke(sessionHandler, "getServerBossBars");
|
||||
}
|
||||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren