Remove platform bulk chunk transformers

This commit is contained in:
KennyTV 2021-05-02 10:12:37 +02:00
parent 44e928d53c
commit d183d76c47
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
16 changed files with 94 additions and 540 deletions

View File

@ -25,11 +25,9 @@ package com.viaversion.viaversion.api.protocol.packet;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.configuration.ViaVersionConfig;
import com.viaversion.viaversion.api.connection.UserConnection;
import org.checkerframework.checker.nullness.qual.Nullable;
public class PacketTracker {
private final UserConnection connection;
private Object lastPacket;
private long sentPackets;
private long receivedPackets;
// Used for tracking pps
@ -111,14 +109,6 @@ public class PacketTracker {
return false;
}
public @Nullable Object getLastPacket() {
return lastPacket;
}
public void setLastPacket(Object lastPacket) {
this.lastPacket = lastPacket;
}
public long getSentPackets() {
return sentPackets;
}

View File

@ -323,4 +323,8 @@ public interface PacketWrapper {
int getId();
void setId(int id);
default void setId(PacketType packetType) {
setId(packetType.ordinal());
}
}

View File

@ -65,9 +65,7 @@ public class BukkitChannelInitializer extends ChannelInitializer<SocketChannel>
MessageToByteEncoder encoder = constructor.newEncodeHandler(connection, (MessageToByteEncoder) channel.pipeline().get("encoder"));
ByteToMessageDecoder decoder = constructor.newDecodeHandler(connection, (ByteToMessageDecoder) channel.pipeline().get("decoder"));
BukkitPacketHandler chunkHandler = new BukkitPacketHandler(connection);
channel.pipeline().replace("encoder", "encoder", encoder);
channel.pipeline().replace("decoder", "decoder", decoder);
channel.pipeline().addAfter("packet_handler", "viaversion_packet_handler", chunkHandler);
}
}

View File

@ -1,63 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion and 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 <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.bukkit.handlers;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
public class BukkitPacketHandler extends MessageToMessageEncoder {
private final UserConnection info;
public BukkitPacketHandler(UserConnection info) {
this.info = info;
}
@Override
protected void encode(ChannelHandlerContext ctx, Object o, List list) throws Exception {
// Split chunks bulk packet up in to single chunks packets before it reached the encoder.
// This will prevent issues with several plugins and other protocol handlers due to the chunks being sent twice.
// It also sends the chunks in the right order possible resolving some issues with added chunks/block/entity data.
if (!(o instanceof ByteBuf)) {
info.getPacketTracker().setLastPacket(o);
/* This transformer is more for fixing issues which we find hard at packet level :) */
if (info.isActive() && filter(o, list)) {
return;
}
}
list.add(o);
}
@Deprecated
public boolean filter(Object o, List list) throws Exception {
if (info.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
Protocol1_9To1_8 protocol = Via.getManager().getProtocolManager().getProtocol(Protocol1_9To1_8.class);
if (protocol.isFiltered(o.getClass())) {
protocol.filterPacket(info, o, list);
return true;
}
}
return false;
}
}

View File

@ -139,8 +139,13 @@ public class BukkitViaInjector implements ViaInjector {
}
@Override
public void uninject() {
public void uninject() throws Exception {
// TODO: Uninject from players currently online to prevent protocol lib issues.
if (PaperViaInjector.PAPER_INJECTION_METHOD) {
PaperViaInjector.removePaperChannelInitializeListener();
return;
}
for (ChannelFuture future : injectedFutures) {
List<String> names = future.channel().pipeline().names();
ChannelHandler bootstrapAcceptor = null;

View File

@ -34,12 +34,10 @@ import com.viaversion.viaversion.bukkit.listeners.protocol1_9to1_8.HandItemCache
import com.viaversion.viaversion.bukkit.listeners.protocol1_9to1_8.PaperPatch;
import com.viaversion.viaversion.bukkit.providers.BukkitBlockConnectionProvider;
import com.viaversion.viaversion.bukkit.providers.BukkitInventoryQuickMoveProvider;
import com.viaversion.viaversion.bukkit.providers.BukkitViaBulkChunkTranslator;
import com.viaversion.viaversion.bukkit.providers.BukkitViaMovementTransmitter;
import com.viaversion.viaversion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.ConnectionData;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.blockconnections.providers.BlockConnectionProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import org.bukkit.Bukkit;
@ -129,7 +127,6 @@ public class BukkitViaLoader implements ViaPlatformLoader {
/* Providers */
if (serverProtocolVersion < ProtocolVersion.v1_9.getVersion()) {
Via.getManager().getProviders().use(BulkChunkTranslatorProvider.class, new BukkitViaBulkChunkTranslator());
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BukkitViaMovementTransmitter());
Via.getManager().getProviders().use(HandItemProvider.class, new HandItemProvider() {

View File

@ -48,6 +48,12 @@ public final class PaperViaInjector {
addListenerMethod.invoke(null, Key.key("viaversion", "injector"), channelInitializeListener);
}
public static void removePaperChannelInitializeListener() throws ReflectiveOperationException {
Class<?> holderClass = Class.forName("io.papermc.paper.network.ChannelInitializeListenerHolder");
Method addListenerMethod = holderClass.getDeclaredMethod("removeListener", Key.class);
addListenerMethod.invoke(null, Key.key("viaversion", "injector"));
}
private static boolean hasServerProtocolMethod() {
try {
Class.forName("org.bukkit.UnsafeValues").getDeclaredMethod("getProtocolVersion");

View File

@ -1,104 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion and 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 <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.bukkit.providers;
import com.google.common.collect.Lists;
import com.viaversion.viaversion.ViaVersionPlugin;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.bukkit.util.NMSUtil;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.ClientChunks;
import com.viaversion.viaversion.util.ReflectionUtil;
import java.lang.reflect.Method;
import java.util.List;
import java.util.logging.Level;
public class BukkitViaBulkChunkTranslator extends BulkChunkTranslatorProvider {
// Reflection
private static ReflectionUtil.ClassReflection mapChunkBulkRef;
private static ReflectionUtil.ClassReflection mapChunkRef;
private static Method obfuscateRef;
static {
try {
mapChunkBulkRef = new ReflectionUtil.ClassReflection(NMSUtil.nms("PacketPlayOutMapChunkBulk"));
mapChunkRef = new ReflectionUtil.ClassReflection(NMSUtil.nms("PacketPlayOutMapChunk"));
if (((ViaVersionPlugin) Via.getPlatform()).isSpigot()) {
obfuscateRef = Class.forName("org.spigotmc.AntiXray").getMethod("obfuscate", int.class, int.class, int.class, byte[].class, NMSUtil.nms("World"));
}
} catch (ClassNotFoundException e) {
// Ignore as server is probably 1.9+
} catch (Exception e) {
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to initialise chunks reflection", e);
}
}
@Override
public List<Object> transformMapChunkBulk(Object packet, ClientChunks clientChunks) {
List<Object> list = Lists.newArrayList();
try {
int[] xcoords = mapChunkBulkRef.getFieldValue("a", packet, int[].class);
int[] zcoords = mapChunkBulkRef.getFieldValue("b", packet, int[].class);
Object[] chunkMaps = mapChunkBulkRef.getFieldValue("c", packet, Object[].class);
if (Via.getConfig().isAntiXRay() && ((ViaVersionPlugin) Via.getPlatform()).isSpigot()) { //Spigot anti-xray patch
try {
Object world = mapChunkBulkRef.getFieldValue("world", packet, Object.class);
Object spigotConfig = ReflectionUtil.getPublic(world, "spigotConfig", Object.class);
Object antiXrayInstance = ReflectionUtil.getPublic(spigotConfig, "antiXrayInstance", Object.class);
for (int i = 0; i < xcoords.length; ++i) {
// TODO: Possibly optimise this
Object b = ReflectionUtil.get(chunkMaps[i], "b", Object.class);
Object a = ReflectionUtil.get(chunkMaps[i], "a", Object.class);
obfuscateRef.invoke(antiXrayInstance, xcoords[i], zcoords[i], b, a, world);
}
} catch (Exception e) {
// not spigot, or it failed.
}
}
for (int i = 0; i < chunkMaps.length; i++) {
int x = xcoords[i];
int z = zcoords[i];
Object chunkMap = chunkMaps[i];
Object chunkPacket = mapChunkRef.newInstance();
mapChunkRef.setFieldValue("a", chunkPacket, x);
mapChunkRef.setFieldValue("b", chunkPacket, z);
mapChunkRef.setFieldValue("c", chunkPacket, chunkMap);
mapChunkRef.setFieldValue("d", chunkPacket, true); // Chunk bulk chunks are always ground-up
clientChunks.getBulkChunks().add(ClientChunks.toLong(x, z)); // Store for later
list.add(chunkPacket);
}
} catch (Exception e) {
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to transform chunks bulk", e);
}
return list;
}
@Override
public boolean isFiltered(Class<?> packetClass) {
return packetClass.getName().endsWith("PacketPlayOutMapChunkBulk");
}
@Override
public boolean isPacketLevel() {
return false;
}
}

View File

@ -38,7 +38,6 @@ import com.viaversion.viaversion.protocols.protocol1_9to1_8.packets.PlayerPacket
import com.viaversion.viaversion.protocols.protocol1_9to1_8.packets.SpawnPackets;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.packets.WorldPackets;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BossBarProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.CommandBlockProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.EntityIdProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemProvider;
@ -52,8 +51,6 @@ import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.MovementTrac
import com.viaversion.viaversion.rewriter.MetadataRewriter;
import com.viaversion.viaversion.util.GsonUtil;
import java.util.List;
public class Protocol1_9To1_8 extends AbstractProtocol<ClientboundPackets1_8, ClientboundPackets1_9, ServerboundPackets1_8, ServerboundPackets1_9> {
public static final ValueTransformer<String, JsonElement> FIX_JSON = new ValueTransformer<String, JsonElement>(Type.COMPONENT) {
@Override
@ -139,7 +136,6 @@ public class Protocol1_9To1_8 extends AbstractProtocol<ClientboundPackets1_8, Cl
@Override
public void register(ViaProviders providers) {
providers.register(HandItemProvider.class, new HandItemProvider());
providers.register(BulkChunkTranslatorProvider.class, new BulkChunkTranslatorProvider());
providers.register(CommandBlockProvider.class, new CommandBlockProvider());
providers.register(EntityIdProvider.class, new EntityIdProvider());
providers.register(BossBarProvider.class, new BossBarProvider());
@ -147,28 +143,6 @@ public class Protocol1_9To1_8 extends AbstractProtocol<ClientboundPackets1_8, Cl
providers.require(MovementTransmitterProvider.class);
}
/**
* Should this protocol filter an object packet from this class.
*
* @param packetClass The class of the current input
* @return True if it should handle the filtering
*/
public boolean isFiltered(Class packetClass) {
return Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class).isFiltered(packetClass);
}
/**
* Filter a packet into the output
*
* @param info The current user connection
* @param packet The input packet as an object (NMS)
* @param output The list to put the object into.
* @throws Exception Throws exception if cancelled / error.
*/
public void filterPacket(UserConnection info, Object packet, List output) throws Exception {
output.addAll(info.get(ClientChunks.class).transformMapChunkBulk(packet));
}
@Override
public void init(UserConnection userConnection) {
// Entity tracker

View File

@ -29,11 +29,12 @@ import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
import com.viaversion.viaversion.api.protocol.remapper.ValueCreator;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.CustomByteType;
import com.viaversion.viaversion.protocols.protocol1_8.ClientboundPackets1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ClientboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ItemRewriter;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.ServerboundPackets1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.CommandBlockProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.sounds.Effect;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.sounds.SoundEffect;
@ -41,9 +42,8 @@ import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.ClientChunks
import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.EntityTracker1_9;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.types.Chunk1_9to1_8Type;
import io.netty.buffer.ByteBuf;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
public class WorldPackets {
@ -136,7 +136,7 @@ public class WorldPackets {
Chunk1_9to1_8Type type = new Chunk1_9to1_8Type(clientChunks);
Chunk1_8 chunk = (Chunk1_8) wrapper.read(type);
if (chunk.isUnloadPacket()) {
wrapper.setId(0x1D);
wrapper.setId(ClientboundPackets1_9.UNLOAD_CHUNK);
wrapper.write(Type.INT, chunk.getX());
wrapper.write(Type.INT, chunk.getZ());
@ -156,29 +156,42 @@ public class WorldPackets {
protocol.registerClientbound(ClientboundPackets1_8.MAP_BULK_CHUNK, null, new PacketRemapper() {
@Override
public void registerMap() {
handler(new PacketHandler() {
@Override
public void handle(PacketWrapper wrapper) throws Exception {
wrapper.cancel(); // Cancel the packet from being sent
BulkChunkTranslatorProvider provider = Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class);
handler(wrapper -> {
wrapper.cancel(); // Cancel the packet from being sent
// Don't read the packet
if (!provider.isPacketLevel())
return;
boolean skyLight = wrapper.read(Type.BOOLEAN);
int count = wrapper.read(Type.VAR_INT);
List<Object> list = provider.transformMapChunkBulk(wrapper, wrapper.user().get(ClientChunks.class));
for (Object obj : list) {
if (!(obj instanceof PacketWrapper))
throw new IOException("transformMapChunkBulk returned the wrong object type");
ChunkBulkSection[] chunks = new ChunkBulkSection[count];
for (int i = 0; i < count; i++) {
chunks[i] = new ChunkBulkSection(wrapper, skyLight);
}
PacketWrapper output = (PacketWrapper) obj;
ByteBuf buffer = wrapper.user().getChannel().alloc().buffer();
try {
output.setId(-1); // -1 for no writing of id
output.writeToBuffer(buffer);
PacketWrapper chunkPacket = PacketWrapper.create(0x21, buffer, wrapper.user());
chunkPacket.send(Protocol1_9To1_8.class, false, true);
} finally {
ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
for (ChunkBulkSection chunk : chunks) {
// Data is at the end
CustomByteType customByteType = new CustomByteType(chunk.getLength());
chunk.setData(wrapper.read(customByteType));
clientChunks.getBulkChunks().add(ClientChunks.toLong(chunk.getX(), chunk.getZ())); // Store for later
// Construct chunk packet
ByteBuf buffer = null;
try {
buffer = wrapper.user().getChannel().alloc().buffer();
Type.INT.write(buffer, chunk.getX());
Type.INT.write(buffer, chunk.getZ());
Type.BOOLEAN.write(buffer, true); // Always ground-up
Type.UNSIGNED_SHORT.write(buffer, chunk.getBitMask());
Type.VAR_INT.writePrimitive(buffer, chunk.getLength());
customByteType.write(buffer, chunk.getData());
// Send through this protocol again
PacketWrapper chunkPacket = PacketWrapper.create(ClientboundPackets1_8.CHUNK_DATA, buffer, wrapper.user());
chunkPacket.send(Protocol1_9To1_8.class, false, true);
} finally {
if (buffer != null) {
buffer.release();
}
}
@ -428,4 +441,45 @@ public class WorldPackets {
}
});
}
public static final class ChunkBulkSection {
private final int x;
private final int z;
private final int bitMask;
private final int length;
private byte[] data;
public ChunkBulkSection(PacketWrapper wrapper, boolean skylight) throws Exception {
x = wrapper.read(Type.INT);
z = wrapper.read(Type.INT);
bitMask = wrapper.read(Type.UNSIGNED_SHORT);
int bitCount = Integer.bitCount(bitMask);
length = (bitCount * ((4096 * 2) + 2048)) + (skylight ? bitCount * 2048 : 0) + 256; // Thanks MCProtocolLib
}
public int getX() {
return x;
}
public int getZ() {
return z;
}
public int getBitMask() {
return bitMask;
}
public int getLength() {
return length;
}
public byte @Nullable [] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}
}

View File

@ -1,152 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion and 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 <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.protocols.protocol1_9to1_8.providers;
import com.viaversion.viaversion.api.platform.providers.Provider;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.CustomByteType;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.ClientChunks;
import java.util.ArrayList;
import java.util.List;
public class BulkChunkTranslatorProvider implements Provider {
/**
* Transforms a Bulk Chunk packet into Chunk Packets
*
* @param packet The NMS Packet
* @param clientChunks The ClientChunks object for the current player
* @return A List of all the output packets
* @throws Exception If there is an issue translating
*/
public List<Object> transformMapChunkBulk(Object packet, ClientChunks clientChunks) throws Exception {
if (!(packet instanceof PacketWrapper))
throw new IllegalArgumentException("The default packet has to be a PacketWrapper for transformMapChunkBulk, unexpected " + packet.getClass());
List<Object> packets = new ArrayList<>();
PacketWrapper wrapper = (PacketWrapper) packet;
boolean skyLight = wrapper.read(Type.BOOLEAN);
int count = wrapper.read(Type.VAR_INT);
ChunkBulkSection[] metas = new ChunkBulkSection[count];
for (int i = 0; i < count; i++) {
metas[i] = ChunkBulkSection.read(wrapper, skyLight);
}
for (ChunkBulkSection meta : metas) {
CustomByteType customByteType = new CustomByteType(meta.getLength());
meta.setData(wrapper.read(customByteType));
// Construct chunk packet
PacketWrapper chunkPacket = PacketWrapper.create(0x21, null, wrapper.user());
chunkPacket.write(Type.INT, meta.getX());
chunkPacket.write(Type.INT, meta.getZ());
chunkPacket.write(Type.BOOLEAN, true); // Always ground-up
chunkPacket.write(Type.UNSIGNED_SHORT, meta.getBitMask());
chunkPacket.write(Type.VAR_INT, meta.getLength());
chunkPacket.write(customByteType, meta.getData());
clientChunks.getBulkChunks().add(ClientChunks.toLong(meta.getX(), meta.getZ())); // Store for later
packets.add(chunkPacket);
}
return packets;
}
/**
* Check if a packet of a class should be filtered
*
* @param packet NMS Packet
* @return True if it should be filtered into transformmapChunkBulk
*/
public boolean isFiltered(Class<?> packet) {
return false;
}
/**
* Check if the packet should be provided as PacketWrapper
*
* @return True if enabled
*/
public boolean isPacketLevel() {
return true;
}
private static class ChunkBulkSection {
private int x;
private int z;
private int bitMask;
private int length;
private byte[] data;
public static ChunkBulkSection read(PacketWrapper wrapper, boolean skylight) throws Exception {
ChunkBulkSection bulkSection = new ChunkBulkSection();
bulkSection.setX(wrapper.read(Type.INT));
bulkSection.setZ(wrapper.read(Type.INT));
bulkSection.setBitMask(wrapper.read(Type.UNSIGNED_SHORT));
int bitCount = Integer.bitCount(bulkSection.getBitMask());
bulkSection.setLength((bitCount * ((4096 * 2) + 2048)) + (skylight ? bitCount * 2048 : 0) + 256); // Thanks MCProtocolLib
return bulkSection;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getZ() {
return z;
}
public void setZ(int z) {
this.z = z;
}
public int getBitMask() {
return bitMask;
}
public void setBitMask(int bitMask) {
this.bitMask = bitMask;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}
}

View File

@ -18,12 +18,9 @@
package com.viaversion.viaversion.protocols.protocol1_9to1_8.storage;
import com.google.common.collect.Sets;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.StoredObject;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import java.util.List;
import java.util.Set;
public class ClientChunks extends StoredObject {
@ -38,10 +35,6 @@ public class ClientChunks extends StoredObject {
return ((long) msw << 32) + lsw - -2147483648L;
}
public List<Object> transformMapChunkBulk(Object packet) throws Exception {
return Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class).transformMapChunkBulk(packet, this);
}
public Set<Long> getLoadedChunks() {
return loadedChunks;
}

View File

@ -58,11 +58,9 @@ public class SpongeChannelInitializer extends ChannelInitializer<Channel> {
// Add our transformers
MessageToByteEncoder encoder = new SpongeEncodeHandler(info, (MessageToByteEncoder) channel.pipeline().get("encoder"));
ByteToMessageDecoder decoder = new SpongeDecodeHandler(info, (ByteToMessageDecoder) channel.pipeline().get("decoder"));
SpongePacketHandler chunkHandler = new SpongePacketHandler(info);
channel.pipeline().replace("encoder", "encoder", encoder);
channel.pipeline().replace("decoder", "decoder", decoder);
channel.pipeline().addAfter("packet_handler", "viaversion_packet_handler", chunkHandler);
} else {
this.method.invoke(this.original, channel);
}

View File

@ -1,63 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion and 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 <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.sponge.handlers;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.Protocol1_9To1_8;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageEncoder;
import java.util.List;
public class SpongePacketHandler extends MessageToMessageEncoder {
private final UserConnection info;
public SpongePacketHandler(UserConnection info) {
this.info = info;
}
@Override
protected void encode(ChannelHandlerContext ctx, Object o, List list) throws Exception {
// Split chunks bulk packet up in to single chunks packets before it reached the encoder.
// This will prevent issues with several plugins and other protocol handlers due to the chunks being sent twice.
// It also sends the chunks in the right order possible resolving some issues with added chunks/block/entity data.
if (!(o instanceof ByteBuf)) {
info.getPacketTracker().setLastPacket(o);
/* This transformer is more for fixing issues which we find hard at packet level :) */
if (info.isActive() && filter(o, list)) {
return;
}
}
list.add(o);
}
@Deprecated
public boolean filter(Object o, List list) throws Exception {
if (info.getProtocolInfo().getPipeline().contains(Protocol1_9To1_8.class)) {
Protocol1_9To1_8 protocol = Via.getManager().getProtocolManager().getProtocol(Protocol1_9To1_8.class);
if (protocol.isFiltered(o.getClass())) {
protocol.filterPacket(info, o, list);
return true;
}
}
return false;
}
}

View File

@ -24,7 +24,6 @@ import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.platform.PlatformTask;
import com.viaversion.viaversion.api.platform.ViaPlatformLoader;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.HandItemProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import com.viaversion.viaversion.sponge.listeners.UpdateListener;
@ -33,7 +32,6 @@ import com.viaversion.viaversion.sponge.listeners.protocol1_9to1_8.DeathListener
import com.viaversion.viaversion.sponge.listeners.protocol1_9to1_8.HandItemCache;
import com.viaversion.viaversion.sponge.listeners.protocol1_9to1_8.sponge4.Sponge4ArmorListener;
import com.viaversion.viaversion.sponge.listeners.protocol1_9to1_8.sponge5.Sponge5ArmorListener;
import com.viaversion.viaversion.sponge.providers.SpongeViaBulkChunkTranslator;
import com.viaversion.viaversion.sponge.providers.SpongeViaMovementTransmitter;
import org.spongepowered.api.Sponge;
@ -84,7 +82,6 @@ public class SpongeViaLoader implements ViaPlatformLoader {
/* Providers */
if (Via.getAPI().getServerVersion().lowestSupportedVersion() < ProtocolVersion.v1_9.getVersion()) {
Via.getManager().getProviders().use(BulkChunkTranslatorProvider.class, new SpongeViaBulkChunkTranslator());
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new SpongeViaMovementTransmitter());
Via.getManager().getProviders().use(HandItemProvider.class, new HandItemProvider() {

View File

@ -1,80 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2021 ViaVersion and 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 <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.sponge.providers;
import com.google.common.collect.Lists;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
import com.viaversion.viaversion.protocols.protocol1_9to1_8.storage.ClientChunks;
import com.viaversion.viaversion.util.ReflectionUtil;
import java.util.List;
import java.util.logging.Level;
public class SpongeViaBulkChunkTranslator extends BulkChunkTranslatorProvider {
// Reflection
private static ReflectionUtil.ClassReflection mapChunkBulkRef;
private static ReflectionUtil.ClassReflection mapChunkRef;
static {
try {
mapChunkBulkRef = new ReflectionUtil.ClassReflection(Class.forName("net.minecraft.network.play.server.S26PacketMapChunkBulk"));
mapChunkRef = new ReflectionUtil.ClassReflection(Class.forName("net.minecraft.network.play.server.S21PacketChunkData"));
} catch (ClassNotFoundException e) {
// Ignore as server is probably 1.9+
} catch (Exception e) {
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to initialise chunks reflection", e);
}
}
@Override
public List<Object> transformMapChunkBulk(Object packet, ClientChunks clientChunks) {
List<Object> list = Lists.newArrayList();
try {
int[] xcoords = mapChunkBulkRef.getFieldValue("field_149266_a", packet, int[].class);
int[] zcoords = mapChunkBulkRef.getFieldValue("field_149264_b", packet, int[].class);
Object[] chunkMaps = mapChunkBulkRef.getFieldValue("field_179755_c", packet, Object[].class);
for (int i = 0; i < chunkMaps.length; i++) {
int x = xcoords[i];
int z = zcoords[i];
Object chunkMap = chunkMaps[i];
Object chunkPacket = mapChunkRef.newInstance();
mapChunkRef.setFieldValue("field_149284_a", chunkPacket, x);
mapChunkRef.setFieldValue("field_149282_b", chunkPacket, z);
mapChunkRef.setFieldValue("field_179758_c", chunkPacket, chunkMap);
mapChunkRef.setFieldValue("field_149279_g", chunkPacket, true); // Chunk bulk chunks are always ground-up
clientChunks.getBulkChunks().add(ClientChunks.toLong(x, z)); // Store for later
list.add(chunkPacket);
}
} catch (Exception e) {
Via.getPlatform().getLogger().log(Level.WARNING, "Failed to transform chunks bulk", e);
}
return list;
}
@Override
public boolean isFiltered(Class<?> packetClass) {
return packetClass.getName().endsWith("S26PacketMapChunkBulk");
}
@Override
public boolean isPacketLevel() {
return false;
}
}