Skip to content

Commit

Permalink
Implement tab list entry uuid rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
Fallen-Breath committed Oct 29, 2023
1 parent 54634a7 commit 1d5031b
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ A list of small tweaks I made:
- Supported proxy types: `socks4`, `socks5`, `http`
- Due to [an issue](https://github.com/AsyncHttpClient/async-http-client/issues/1913) in the http library velocity uses, you can only use `http` proxy for now
- If enabled, velocity will firstly try authenticating with the given proxy, if failed it will try again without the proxy
- Implement UUID rewrite for TabList packets, like what bungeecord does

# Velocity

Expand Down
24 changes: 24 additions & 0 deletions proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.velocitypowered.api.util.Favicon;
import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.api.util.ProxyVersion;
import com.velocitypowered.api.util.UuidUtils;
import com.velocitypowered.proxy.command.VelocityCommandManager;
import com.velocitypowered.proxy.command.builtin.GlistCommand;
import com.velocitypowered.proxy.command.builtin.ServerCommand;
Expand Down Expand Up @@ -148,6 +149,9 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
private final VelocityChannelRegistrar channelRegistrar = new VelocityChannelRegistrar();
private ServerListPingHandler serverListPingHandler;

// [fallen's fork] tab list entry uuid rewrite: maintain offline uuid mapping
private final Map<UUID, ConnectedPlayer> connectionsByOfflineUuid = new ConcurrentHashMap<>();

VelocityServer(final ProxyOptions options) {
pluginManager = new VelocityPluginManager(this);
eventManager = new VelocityEventManager(pluginManager);
Expand Down Expand Up @@ -625,6 +629,11 @@ public boolean registerConnection(ConnectedPlayer connection) {
connectionsByName.remove(lowerName, connection);
return false;
}

// [fallen's fork] tab list entry uuid rewrite
connectionsByOfflineUuid.put(
UuidUtils.generateOfflinePlayerUuid(connection.getUsername()), connection);

} else {
ConnectedPlayer existing = connectionsByUuid.get(connection.getUniqueId());
if (existing != null) {
Expand All @@ -634,6 +643,10 @@ public boolean registerConnection(ConnectedPlayer connection) {
// We can now replace the entries as needed.
connectionsByName.put(lowerName, connection);
connectionsByUuid.put(connection.getUniqueId(), connection);

// [fallen's fork] tab list entry uuid rewrite: maintain offline uuid mapping
connectionsByOfflineUuid.put(
UuidUtils.generateOfflinePlayerUuid(connection.getUsername()), connection);
}
return true;
}
Expand All @@ -646,6 +659,11 @@ public boolean registerConnection(ConnectedPlayer connection) {
public void unregisterConnection(ConnectedPlayer connection) {
connectionsByName.remove(connection.getUsername().toLowerCase(Locale.US), connection);
connectionsByUuid.remove(connection.getUniqueId(), connection);

// [fallen's fork] tab list entry uuid rewrite: maintain offline uuid mapping
connectionsByOfflineUuid.remove(
UuidUtils.generateOfflinePlayerUuid(connection.getUsername()), connection);

bossBarManager.onDisconnect(connection);
}

Expand All @@ -661,6 +679,12 @@ public Optional<Player> getPlayer(UUID uuid) {
return Optional.ofNullable(connectionsByUuid.get(uuid));
}

// [fallen's fork] tab list entry uuid rewrite: maintain offline uuid mapping
public Optional<Player> getPlayerByOfflineUuid(UUID uuid) {
Preconditions.checkNotNull(uuid, "uuid");
return Optional.ofNullable(connectionsByOfflineUuid.get(uuid));
}

@Override
public Collection<Player> matchPlayer(String partialName) {
Objects.requireNonNull(partialName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo;
import com.velocitypowered.proxy.protocol.packet.config.StartUpdate;
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
import com.velocitypowered.proxy.tablist.TabListUuidRewriter;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
Expand Down Expand Up @@ -263,18 +264,27 @@ public boolean handle(TabCompleteResponse packet) {

@Override
public boolean handle(LegacyPlayerListItem packet) {
// [fallen's fork] tab list entry uuid rewrite: impl
TabListUuidRewriter.rewrite(server, packet);

serverConn.getPlayer().getTabList().processLegacy(packet);
return false;
}

@Override
public boolean handle(UpsertPlayerInfo packet) {
// [fallen's fork] tab list entry uuid rewrite: impl
TabListUuidRewriter.rewrite(server, packet);

serverConn.getPlayer().getTabList().processUpdate(packet);
return false;
}

@Override
public boolean handle(RemovePlayerInfo packet) {
// [fallen's fork] tab list entry uuid rewrite: impl
TabListUuidRewriter.rewrite(server, packet);

serverConn.getPlayer().getTabList().processRemove(packet);
return false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (C) 2018-2023 Velocity Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.velocitypowered.proxy.tablist;

import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItem;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo;
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo;
import java.util.Optional;
import java.util.stream.Collectors;

/**
* [fallen's fork] tab list entry uuid rewrite: rewrite logic.
*/
public class TabListUuidRewriter {
/**
* Rewrite uuid for a LegacyPlayerListItem packet.
*/
public static void rewrite(VelocityServer server, LegacyPlayerListItem packet) {
packet.getItems().replaceAll(item -> {
Optional<Player> opt = server.getPlayerByOfflineUuid(item.getUuid());
if (opt.isPresent()) {
Player player = opt.get();

var newItem = new LegacyPlayerListItem.Item(player.getUniqueId());
newItem.setName(item.getName());
newItem.setProperties(item.getProperties());
newItem.setGameMode(item.getGameMode());
newItem.setLatency(item.getLatency());
newItem.setDisplayName(item.getDisplayName());
newItem.setPlayerKey(item.getPlayerKey());

item = newItem;
}

return item;
});
}

/**
* Rewrite uuid for a UpsertPlayerInfo packet.
*/
public static void rewrite(VelocityServer server, UpsertPlayerInfo packet) {
packet.getEntries().replaceAll(entry -> {
Optional<Player> opt = server.getPlayerByOfflineUuid(entry.getProfileId());
if (opt.isPresent()) {
Player player = opt.get();

var newEntry = new UpsertPlayerInfo.Entry(player.getUniqueId());
newEntry.setProfile(player.getGameProfile());
newEntry.setListed(entry.isListed());
newEntry.setLatency(entry.getLatency());
newEntry.setGameMode(entry.getGameMode());
newEntry.setDisplayName(entry.getDisplayName());
newEntry.setChatSession(entry.getChatSession());

entry = newEntry;
}

return entry;
});
}

/**
* Rewrite uuid for a RemovePlayerInfo packet.
*/
public static void rewrite(VelocityServer server, RemovePlayerInfo packet) {
var newProfiles = packet.getProfilesToRemove().stream()
.map(
uuid -> server.getPlayerByOfflineUuid(uuid)
.map(Player::getUniqueId)
.orElse(uuid)
)
.collect(Collectors.toList());
packet.setProfilesToRemove(newProfiles);
}
}

0 comments on commit 1d5031b

Please sign in to comment.