Skip to content

Commit

Permalink
fix tablist removal packet on multiple velocity setups
Browse files Browse the repository at this point in the history
with the old codes, an only player leaving the velocity server will keep the `uuidMappingCache` unclear, creating issue if that player joins another velocity server + same mc server
  • Loading branch information
Fallen-Breath committed Aug 2, 2024
1 parent 289b82b commit 667bdbd
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import com.velocitypowered.proxy.network.ConnectionManager;
import com.velocitypowered.proxy.plugin.VelocityPluginManager;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.packet.uuidrewrite.TabListUuidRewriter;
import com.velocitypowered.proxy.protocol.util.FaviconSerializer;
import com.velocitypowered.proxy.protocol.util.GameProfileSerializer;
import com.velocitypowered.proxy.scheduler.VelocityScheduler;
Expand Down Expand Up @@ -654,6 +655,9 @@ public void unregisterConnection(ConnectedPlayer connection) {
connectionsByName.remove(connection.getUsername().toLowerCase(Locale.US), connection);
connectionsByUuid.remove(connection.getUniqueId(), connection);
connection.disconnected();

// [fallen's fork] player uuid rewrite -
TabListUuidRewriter.onPlayerDisconnect(this, connection);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@

package com.velocitypowered.proxy.protocol.packet.uuidrewrite;

import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.config.PlayerInfoForwarding;
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItemPacket;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfoPacket;
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfoPacket;
import java.util.LinkedHashMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
Expand All @@ -34,26 +39,53 @@
*/
public class TabListUuidRewriter {

// offline / server uuid -> online / client uuid
// this cache is necessary, cuz during processing the RemovePlayerInfoPacket, the player might have already disconnected
private static final Map<UUID, UUID> uuidMappingCache = new LinkedHashMap<>(16, 0.75f, true);

@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private static boolean shouldRewrite(VelocityServer server) {
var config = server.getConfiguration();
return config.isOnlineMode() && config.getPlayerInfoForwardingMode() == PlayerInfoForwarding.NONE;
}

// offline / server uuid -> online / client uuid
private static Map<UUID, UUID> makeUuidMappingView(VelocityServer server) {
synchronized (uuidMappingCache) {
for (Player player : server.getAllPlayers()) {
uuidMappingCache.put(player.getOfflineUuid(), player.getUniqueId());
}
Map<UUID, UUID> view = new HashMap<>();
for (Player player : server.getAllPlayers()) {
view.put(player.getOfflineUuid(), player.getUniqueId());
}
return view;
}

// allow at most 1024 players to disconnect at the same time
while (uuidMappingCache.size() > server.getAllPlayers().size() + 1024) {
uuidMappingCache.remove(uuidMappingCache.keySet().iterator().next());
// [fallen's fork] player uuid rewrite
// send the missing player tab-list removal packets to other players in the mc server
// see bungeecord net.md_5.bungee.connection.UpstreamBridge#disconnected
public static void onPlayerDisconnect(VelocityServer server, ConnectedPlayer player) {
if (!shouldRewrite(server)) {
return;
}

VelocityServerConnection connectedServer = player.getConnectedServer();
if (connectedServer == null) {
return;
}

var oldPacket = new LegacyPlayerListItemPacket(
LegacyPlayerListItemPacket.REMOVE_PLAYER,
Collections.singletonList(new LegacyPlayerListItemPacket.Item(player.getUniqueId()))
);
var newPacket = new RemovePlayerInfoPacket(
Collections.singleton(player.getUniqueId())
);

for (Player otherPlayer : connectedServer.getServer().getPlayersConnected()) {
if (otherPlayer != player && otherPlayer instanceof ConnectedPlayer) {
var connection = ((ConnectedPlayer)otherPlayer).getConnection();
MinecraftPacket packet;
if (connection.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_19_3)) {
packet = newPacket;
} else {
packet = oldPacket;
}
connection.write(packet);
}
return Map.copyOf(uuidMappingCache);
}
}

Expand Down Expand Up @@ -126,10 +158,6 @@ public static void rewrite(VelocityServer server, RemovePlayerInfoPacket packet)
.map(serverUuid -> Optional.ofNullable(uuidMapping.get(serverUuid)).orElse(serverUuid))
.collect(Collectors.toList());

synchronized (uuidMappingCache) {
packet.getProfilesToRemove().forEach(uuidMappingCache::remove);
}

packet.setProfilesToRemove(newProfiles);
}
}

0 comments on commit 667bdbd

Please sign in to comment.