Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-26 16:12:42 +01:00
Remove platform bulk chunk transformers
Dieser Commit ist enthalten in:
Ursprung
44e928d53c
Commit
d183d76c47
@ -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;
|
||||
}
|
||||
|
@ -323,4 +323,8 @@ public interface PacketWrapper {
|
||||
int getId();
|
||||
|
||||
void setId(int id);
|
||||
|
||||
default void setId(PacketType packetType) {
|
||||
setId(packetType.ordinal());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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() {
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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() {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren