Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-26 08:10:09 +01:00
Start working on packet-level chunk bulks
Dieser Commit ist enthalten in:
Ursprung
36301a595b
Commit
aeec7e5f95
@ -3,9 +3,9 @@ package us.myles.ViaVersion.bukkit.providers;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||||
import us.myles.ViaVersion.api.Via;
|
import us.myles.ViaVersion.api.Via;
|
||||||
|
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
||||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
|
||||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@ -79,4 +79,9 @@ public class BukkitViaBulkChunkTranslator extends BulkChunkTranslatorProvider {
|
|||||||
public boolean isFiltered(Class<?> packetClass) {
|
public boolean isFiltered(Class<?> packetClass) {
|
||||||
return packetClass.getName().endsWith("PacketPlayOutMapChunkBulk");
|
return packetClass.getName().endsWith("PacketPlayOutMapChunkBulk");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPacketLevel() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,7 +358,7 @@ public class PacketWrapper {
|
|||||||
* Be careful not to send packets twice.
|
* Be careful not to send packets twice.
|
||||||
* (Sends it after current)
|
* (Sends it after current)
|
||||||
* <br />
|
* <br />
|
||||||
* <b>This method is no longer used, it's favoured to use send(Protocol) as it will handle the pipeline properly.</b>
|
* <b>This method is no longer used, it's favoured to use {@link #send(Class)} as it will handle the pipeline properly.</b>
|
||||||
*
|
*
|
||||||
* @throws Exception if it fails to write
|
* @throws Exception if it fails to write
|
||||||
*/
|
*/
|
||||||
|
@ -27,13 +27,13 @@ public class ProtocolRegistry {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
// Base Protocol
|
// Base Protocol
|
||||||
registerProtocol(BASE_PROTOCOL, Arrays.<Integer>asList(), -1);
|
registerProtocol(BASE_PROTOCOL, Collections.<Integer>emptyList(), -1);
|
||||||
// Register built in protocols
|
// Register built in protocols
|
||||||
registerProtocol(new Protocol1_9TO1_8(), Collections.singletonList(ProtocolVersion.v1_9.getId()), ProtocolVersion.v1_8.getId());
|
registerProtocol(new Protocol1_9TO1_8(), Collections.singletonList(ProtocolVersion.v1_9.getId()), ProtocolVersion.v1_8.getId());
|
||||||
registerProtocol(new Protocol1_9_1TO1_9(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9.getId());
|
registerProtocol(new Protocol1_9_1TO1_9(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9.getId());
|
||||||
registerProtocol(new Protocol1_9_3TO1_9_1_2(), Arrays.asList(ProtocolVersion.v1_9_3.getId()), ProtocolVersion.v1_9_2.getId());
|
registerProtocol(new Protocol1_9_3TO1_9_1_2(), Collections.singletonList(ProtocolVersion.v1_9_3.getId()), ProtocolVersion.v1_9_2.getId());
|
||||||
// Only supported for 1.9.4 server to 1.9 (nothing else)
|
// Only supported for 1.9.4 server to 1.9 (nothing else)
|
||||||
registerProtocol(new Protocol1_9TO1_9_1(), Arrays.asList(ProtocolVersion.v1_9.getId()), ProtocolVersion.v1_9_2.getId());
|
registerProtocol(new Protocol1_9TO1_9_1(), Collections.singletonList(ProtocolVersion.v1_9.getId()), ProtocolVersion.v1_9_2.getId());
|
||||||
registerProtocol(new Protocol1_9_1_2TO1_9_3_4(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9_3.getId());
|
registerProtocol(new Protocol1_9_1_2TO1_9_3_4(), Arrays.asList(ProtocolVersion.v1_9_1.getId(), ProtocolVersion.v1_9_2.getId()), ProtocolVersion.v1_9_3.getId());
|
||||||
registerProtocol(new Protocol1_10To1_9_3_4(), Collections.singletonList(ProtocolVersion.v1_10.getId()), ProtocolVersion.v1_9_3.getId());
|
registerProtocol(new Protocol1_10To1_9_3_4(), Collections.singletonList(ProtocolVersion.v1_10.getId()), ProtocolVersion.v1_9_3.getId());
|
||||||
|
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package us.myles.ViaVersion.api.type.types;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import us.myles.ViaVersion.api.type.PartialType;
|
||||||
|
|
||||||
|
public class CustomByteType extends PartialType<byte[], Integer> {
|
||||||
|
|
||||||
|
public CustomByteType(Integer param) {
|
||||||
|
super(param, byte[].class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] read(ByteBuf byteBuf, Integer integer) throws Exception {
|
||||||
|
if (byteBuf.readableBytes() < integer) throw new RuntimeException("Readable bytes does not match expected!");
|
||||||
|
|
||||||
|
byte[] byteArray = new byte[integer];
|
||||||
|
byteBuf.readBytes(byteArray);
|
||||||
|
|
||||||
|
return byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(ByteBuf byteBuf, Integer integer, byte[] bytes) throws Exception {
|
||||||
|
byteBuf.writeBytes(bytes);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets;
|
package us.myles.ViaVersion.protocols.protocol1_9to1_8.packets;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||||
import org.spacehq.opennbt.tag.builtin.StringTag;
|
import org.spacehq.opennbt.tag.builtin.StringTag;
|
||||||
import us.myles.ViaVersion.api.PacketWrapper;
|
import us.myles.ViaVersion.api.PacketWrapper;
|
||||||
@ -15,6 +17,7 @@ import us.myles.ViaVersion.packets.State;
|
|||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.ItemRewriter;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.Protocol1_9TO1_8;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.Chunk1_9to1_8;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.chunks.Chunk1_9to1_8;
|
||||||
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.Effect;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.Effect;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.SoundEffect;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.sounds.SoundEffect;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
||||||
@ -22,6 +25,9 @@ import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.EntityTracker;
|
|||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.PlaceBlockTracker;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.PlaceBlockTracker;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.ChunkType;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.types.ChunkType;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class WorldPackets {
|
public class WorldPackets {
|
||||||
public static void register(Protocol protocol) {
|
public static void register(Protocol protocol) {
|
||||||
// Sign Update Packet
|
// Sign Update Packet
|
||||||
@ -132,18 +138,26 @@ public class WorldPackets {
|
|||||||
handler(new PacketHandler() {
|
handler(new PacketHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(PacketWrapper wrapper) throws Exception {
|
public void handle(PacketWrapper wrapper) throws Exception {
|
||||||
// ClientChunks clientChunks = wrapper.user().get(ClientChunks.class);
|
wrapper.cancel(); // Cancel the packet from being sent
|
||||||
// Chunk1_9to1_8 chunk = (Chunk1_9to1_8) wrapper.passthrough(new ChunkType(clientChunks));
|
BulkChunkTranslatorProvider provider = Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class);
|
||||||
// if (chunk.isUnloadPacket())
|
|
||||||
// wrapper.setId(0x1D);
|
|
||||||
//
|
|
||||||
// // eat any other data (Usually happens with unload packets)
|
|
||||||
// wrapper.read(Type.REMAINING_BYTES);
|
|
||||||
// TODO: Implement Bulk Chunks
|
|
||||||
// Boolean
|
|
||||||
// Column Count
|
|
||||||
|
|
||||||
wrapper.cancel();
|
// Don't read the packet
|
||||||
|
if (!provider.isPacketLevel())
|
||||||
|
return;
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
PacketWrapper output = (PacketWrapper) obj;
|
||||||
|
|
||||||
|
ByteBuf buffer = Unpooled.buffer();
|
||||||
|
output.writeToBuffer(buffer);
|
||||||
|
|
||||||
|
PacketWrapper chunkPacket = new PacketWrapper(0x21, buffer, wrapper.user());
|
||||||
|
chunkPacket.send(Protocol1_9TO1_8.class, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package us.myles.ViaVersion.protocols.protocol1_9to1_8.providers;
|
package us.myles.ViaVersion.protocols.protocol1_9to1_8.providers;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import us.myles.ViaVersion.api.PacketWrapper;
|
||||||
import us.myles.ViaVersion.api.platform.providers.Provider;
|
import us.myles.ViaVersion.api.platform.providers.Provider;
|
||||||
|
import us.myles.ViaVersion.api.type.Type;
|
||||||
|
import us.myles.ViaVersion.api.type.types.CustomByteType;
|
||||||
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
import us.myles.ViaVersion.protocols.protocol1_9to1_8.storage.ClientChunks;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BulkChunkTranslatorProvider implements Provider {
|
public class BulkChunkTranslatorProvider implements Provider {
|
||||||
@ -14,10 +18,42 @@ public class BulkChunkTranslatorProvider implements Provider {
|
|||||||
* @param clientChunks The ClientChunks object for the current player
|
* @param clientChunks The ClientChunks object for the current player
|
||||||
* @return A List of all the output packets
|
* @return A List of all the output packets
|
||||||
*/
|
*/
|
||||||
public List<Object> transformMapChunkBulk(Object packet, ClientChunks clientChunks) {
|
public List<Object> transformMapChunkBulk(Object packet, ClientChunks clientChunks) throws Exception {
|
||||||
return Arrays.asList(packet);
|
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 = new PacketWrapper(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() & 0x0F);
|
||||||
|
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
|
* Check if a packet of a class should be filtered
|
||||||
*
|
*
|
||||||
@ -27,4 +63,34 @@ public class BulkChunkTranslatorProvider implements Provider {
|
|||||||
public boolean isFiltered(Class<?> packet) {
|
public boolean isFiltered(Class<?> packet) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the packet should be provided as PacketWrapper
|
||||||
|
*
|
||||||
|
* @return True if enabled
|
||||||
|
*/
|
||||||
|
public boolean isPacketLevel() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public class ClientChunks extends StoredObject {
|
public class ClientChunks extends StoredObject {
|
||||||
|
|
||||||
|
|
||||||
private final Set<Long> loadedChunks = Sets.newConcurrentHashSet();
|
private final Set<Long> loadedChunks = Sets.newConcurrentHashSet();
|
||||||
private final Set<Long> bulkChunks = Sets.newConcurrentHashSet();
|
private final Set<Long> bulkChunks = Sets.newConcurrentHashSet();
|
||||||
|
|
||||||
@ -25,7 +23,7 @@ public class ClientChunks extends StoredObject {
|
|||||||
return ((long) msw << 32) + lsw - -2147483648L;
|
return ((long) msw << 32) + lsw - -2147483648L;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Object> transformMapChunkBulk(Object packet) {
|
public List<Object> transformMapChunkBulk(Object packet) throws Exception {
|
||||||
return Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class).transformMapChunkBulk(packet, this);
|
return Via.getManager().getProviders().get(BulkChunkTranslatorProvider.class).transformMapChunkBulk(packet, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,9 @@ package us.myles.ViaVersion.util;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
@Getter
|
|
||||||
public class GsonUtil {
|
public class GsonUtil {
|
||||||
private final Gson gson = getGsonBuilder().create();
|
private final Gson gson = getGsonBuilder().create();
|
||||||
|
|
||||||
|
@ -55,4 +55,9 @@ public class SpongeViaBulkChunkTranslator extends BulkChunkTranslatorProvider {
|
|||||||
public boolean isFiltered(Class<?> packetClass) {
|
public boolean isFiltered(Class<?> packetClass) {
|
||||||
return packetClass.getName().endsWith("S26PacketMapChunkBulk");
|
return packetClass.getName().endsWith("S26PacketMapChunkBulk");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPacketLevel() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren