Skip to content

Commit

Permalink
Rewrite uuids in RemovePlayerInfoPacket tablist packet
Browse files Browse the repository at this point in the history
  • Loading branch information
UserNugget committed May 11, 2024
1 parent f0b45a4 commit 5879eb5
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
2 changes: 2 additions & 0 deletions plugin/src/main/java/net/elytrium/limboapi/LimboAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
import net.elytrium.limboapi.injection.packet.MinecraftDiscardCompressDecoder;
import net.elytrium.limboapi.injection.packet.MinecraftLimitedCompressDecoder;
import net.elytrium.limboapi.injection.packet.PreparedPacketImpl;
import net.elytrium.limboapi.injection.packet.RemovePlayerInfoHook;
import net.elytrium.limboapi.injection.packet.UpsertPlayerInfoHook;
import net.elytrium.limboapi.material.Biome;
import net.elytrium.limboapi.protocol.LimboProtocol;
Expand Down Expand Up @@ -189,6 +190,7 @@ public LimboAPI(Logger logger, ProxyServer server, Metrics.Factory metricsFactor
EventManagerHook.init(this);
LegacyPlayerListItemHook.init(this, LimboProtocol.PLAY_CLIENTBOUND_REGISTRY);
UpsertPlayerInfoHook.init(this, LimboProtocol.PLAY_CLIENTBOUND_REGISTRY);
RemovePlayerInfoHook.init(this, LimboProtocol.PLAY_CLIENTBOUND_REGISTRY);

LimboProtocol.init();
} catch (Throwable e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright (C) 2021 - 2024 Elytrium
*
* 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 <http://www.gnu.org/licenses/>.
*/

package net.elytrium.limboapi.injection.packet;

import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.connection.backend.BackendPlaySessionHandler;
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.StateRegistry;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfoPacket;
import io.netty.util.collection.IntObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Supplier;
import net.elytrium.commons.utils.reflection.ReflectionException;
import net.elytrium.limboapi.LimboAPI;
import net.elytrium.limboapi.protocol.LimboProtocol;

@SuppressWarnings("unchecked")
public class RemovePlayerInfoHook extends RemovePlayerInfoPacket {

private static final MethodHandle SERVER_CONN_FIELD;

private final LimboAPI plugin;

private RemovePlayerInfoHook(LimboAPI plugin) {
this.plugin = plugin;
}

@Override
public boolean handle(MinecraftSessionHandler handler) {
if (handler instanceof BackendPlaySessionHandler) {
try {
ConnectedPlayer player = ((VelocityServerConnection) SERVER_CONN_FIELD.invokeExact((BackendPlaySessionHandler) handler)).getPlayer();
UUID initialID = this.plugin.getInitialID(player);
if (this.getProfilesToRemove() instanceof List<UUID> uuids) {
for (int i = 0; i < uuids.size(); i++) {
if (player.getUniqueId().equals(uuids.get(i))) {
uuids.set(i, initialID);
}
}
}
} catch (Throwable e) {
throw new ReflectionException(e);
}
}

return super.handle(handler);
}

static {
try {
SERVER_CONN_FIELD = MethodHandles.privateLookupIn(BackendPlaySessionHandler.class, MethodHandles.lookup())
.findGetter(BackendPlaySessionHandler.class, "serverConn", VelocityServerConnection.class);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new ReflectionException(e);
}
}

public static void init(LimboAPI plugin, StateRegistry.PacketRegistry registry) throws ReflectiveOperationException {
// See LimboProtocol#overlayRegistry about var.
var playProtocolRegistryVersions = (Map<ProtocolVersion, StateRegistry.PacketRegistry.ProtocolRegistry>) LimboProtocol.VERSIONS_FIELD.get(registry);
playProtocolRegistryVersions.forEach((protocolVersion, protocolRegistry) -> {
try {
var packetIDToSupplier = (IntObjectMap<Supplier<? extends MinecraftPacket>>) LimboProtocol.PACKET_ID_TO_SUPPLIER_FIELD.get(protocolRegistry);
var packetClassToID = (Object2IntMap<Class<? extends MinecraftPacket>>) LimboProtocol.PACKET_CLASS_TO_ID_FIELD.get(protocolRegistry);

int id = packetClassToID.getInt(RemovePlayerInfoPacket.class);
packetClassToID.put(RemovePlayerInfoHook.class, id);
packetIDToSupplier.put(id, () -> new RemovePlayerInfoHook(plugin));
} catch (ReflectiveOperationException e) {
throw new ReflectionException(e);
}
});
}
}

0 comments on commit 5879eb5

Please sign in to comment.