Fix missing group members on 2.5 clients
Build AsminVoicechat / build-and-release (push) Successful in 2m27s

This commit is contained in:
asminme committed 2026-10-24 21:15:00 +02:00
1 parent 578e01eda3
commit 7a91c8a41d
7 files changed
+86 -10

No files matched your search

@@ -112,6 +112,8 @@ public class VoiceChatCommands implements CommandExecutor, TabCompleter {
return true;
}
int clientCompatibilityVersion = Voicechat.SERVER.getClientCompatibilityVersion(player.getUniqueId());
ClientConnection clientConnection = Voicechat.SERVER.getServer().getConnections().get(player.getUniqueId());
if (clientConnection == null) {
@@ -130,6 +132,8 @@ public class VoiceChatCommands implements CommandExecutor, TabCompleter {
} else {
NetManager.sendMessage(commandSender, "message.voicechat.ping_received_attempt", String.valueOf(pingMilliseconds), String.valueOf(attempts));
}
commandSender.sendMessage("Voice chat connection verified (client compatibility version "
+ clientCompatibilityVersion + ").");
}
@Override
@@ -326,4 +330,4 @@ public class VoiceChatCommands implements CommandExecutor, TabCompleter {
return null;
}
}
}
}
@@ -38,6 +38,9 @@ public class NetManager implements Listener {
registerOutgoingPacket(JoinedGroupPacket.class);
registerOutgoingPacket(AddCategoryPacket.class);
registerOutgoingPacket(RemoveCategoryPacket.class);
registerOutgoingChannel(ProtocolChannelCompatibility.LEGACY_PLAYER_STATE);
registerOutgoingChannel(ProtocolChannelCompatibility.LEGACY_PLAYER_STATES);
} catch (Exception e) {
throw new IllegalStateException("Failed to register voice chat packets", e);
}
@@ -100,6 +103,10 @@ public class NetManager implements Listener {
private <T extends Packet<?>> void registerOutgoingPacket(Class<T> packetClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
String id = packetClass.getDeclaredConstructor().newInstance().getID().toString();
registerOutgoingChannel(id);
}
private void registerOutgoingChannel(String id) {
packets.add(id);
Bukkit.getMessenger().registerOutgoingPluginChannel(Voicechat.INSTANCE, id);
}
@@ -114,7 +121,11 @@ public class NetManager implements Listener {
p.toBytes(buf);
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
player.sendPluginMessage(Voicechat.INSTANCE, p.getID().toString(), bytes);
int compatibilityVersion = Voicechat.SERVER.getClientCompatibilityVersion(player.getUniqueId());
String channel = ProtocolChannelCompatibility.outgoingChannel(p.getID().toString(), compatibilityVersion);
if (channel != null) {
player.sendPluginMessage(Voicechat.INSTANCE, channel, bytes);
}
} catch (Exception e) {
Voicechat.LOGGER.error("Failed to send packet to '{}'", player.getName(), e);
}
@@ -129,4 +140,4 @@ public class NetManager implements Listener {
Voicechat.compatibility.sendStatusMessage(player, key, args);
}
}
}
@@ -0,0 +1,27 @@
package de.maxhenkel.voicechat.net;
public final class ProtocolChannelCompatibility {
public static final int LEGACY_COMPATIBILITY_VERSION = 18;
public static final String LEGACY_PLAYER_STATE = "voicechat:player_state";
public static final String LEGACY_PLAYER_STATES = "voicechat:player_states";
private ProtocolChannelCompatibility() {
}
public static String outgoingChannel(String channel, int compatibilityVersion) {
if (compatibilityVersion != LEGACY_COMPATIBILITY_VERSION) {
return channel;
}
switch (channel) {
case "voicechat:state":
return LEGACY_PLAYER_STATE;
case "voicechat:states":
return LEGACY_PLAYER_STATES;
case "voicechat:remove_state":
return null;
default:
return channel;
}
}
}
@@ -56,8 +56,7 @@ public class PlayerStateManager implements Listener {
}
public void onPlayerHide(PlayerHideEvent event) {
RemovePlayerStatePacket packet = new RemovePlayerStatePacket(event.getHiddenPlayer().getUniqueId());
NetManager.sendToClient(event.getObserver(), packet);
sendRemoveState(event.getObserver(), event.getHiddenPlayer());
Voicechat.LOGGER.debug("Removing state of {} for {}", event.getHiddenPlayer().getName(), event.getObserver().getName());
}
@@ -83,14 +82,22 @@ public class PlayerStateManager implements Listener {
}
public void broadcastRemoveState(Player stateOwner) {
RemovePlayerStatePacket packet = new RemovePlayerStatePacket(stateOwner.getUniqueId());
for (Player receiver : Voicechat.INSTANCE.getServer().getOnlinePlayers()) {
NetManager.sendToClient(receiver, packet);
sendRemoveState(receiver, stateOwner);
}
// Send the default disconnected state to the API when disconnecting
PluginManager.instance().onPlayerStateChanged(defaultDisconnectedState(stateOwner));
}
private void sendRemoveState(Player receiver, Player stateOwner) {
if (Voicechat.SERVER.getClientCompatibilityVersion(receiver.getUniqueId())
== de.maxhenkel.voicechat.net.ProtocolChannelCompatibility.LEGACY_COMPATIBILITY_VERSION) {
NetManager.sendToClient(receiver, new PlayerStatePacket(defaultDisconnectedState(stateOwner)));
return;
}
NetManager.sendToClient(receiver, new RemovePlayerStatePacket(stateOwner.getUniqueId()));
}
public void onPlayerCompatibilityCheckSucceeded(Player player) {
List<PlayerState> stateList = new ArrayList<>(states.size());
for (PlayerState state : states.values()) {
@@ -83,6 +83,10 @@ public class ServerVoiceEvents implements Listener {
return isSupportedCompatibilityVersion(clientCompatibilities.getOrDefault(playerUuid, -1));
}
public int getClientCompatibilityVersion(UUID playerUuid) {
return clientCompatibilities.getOrDefault(playerUuid, -1);
}
public static void sendIncompatibleMessage(Player player, int clientCompatibilityVersion) {
if (clientCompatibilityVersion <= 6) {
player.sendMessage(String.format(Voicechat.TRANSLATIONS.voicechatNotCompatibleMessage.get(),