3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-11-03 14:50:30 +01:00

Some minor performance improvements and cleanups (#3134)

Dieser Commit ist enthalten in:
Gero 2022-10-04 13:25:55 +02:00 committet von GitHub
Ursprung c7eb2e4b97
Commit 7698ee7683
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
7 geänderte Dateien mit 140 neuen und 158 gelöschten Zeilen

Datei anzeigen

@ -40,6 +40,18 @@ public interface ChunkSection {
return y << 8 | z << 4 | x; return y << 8 | z << 4 | x;
} }
static int xFromIndex(int idx) {
return idx & 0xF;
}
static int yFromIndex(int idx) {
return idx >> 8 & 0xF;
}
static int zFromIndex(int idx) {
return idx >> 4 & 0xF;
}
@Deprecated/*(forRemoval = true)*/ @Deprecated/*(forRemoval = true)*/
default int getFlatBlock(int idx) { default int getFlatBlock(int idx) {
return palette(PaletteType.BLOCKS).idAt(idx); return palette(PaletteType.BLOCKS).idAt(idx);

Datei anzeigen

@ -24,6 +24,8 @@ package com.viaversion.viaversion.api.type.types.version;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSectionImpl;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
@ -38,16 +40,14 @@ public class ChunkSectionType1_8 extends Type<ChunkSection> {
@Override @Override
public ChunkSection read(ByteBuf buffer) throws Exception { public ChunkSection read(ByteBuf buffer) throws Exception {
ChunkSection chunkSection = new ChunkSectionImpl(true); ChunkSection chunkSection = new ChunkSectionImpl(true);
DataPalette blocks = chunkSection.palette(PaletteType.BLOCKS);
// 0 index needs to be air in 1.9 // 0 index needs to be air in 1.9
chunkSection.addPaletteEntry(0); blocks.addId(0);
ByteBuf littleEndianView = buffer.order(ByteOrder.LITTLE_ENDIAN); ByteBuf littleEndianView = buffer.order(ByteOrder.LITTLE_ENDIAN);
for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
for (int i = 0; i < ChunkSection.SIZE; i++) { blocks.setIdAt(idx, littleEndianView.readShort());
int mask = littleEndianView.readShort();
int type = mask >> 4;
int data = mask & 0xF;
chunkSection.setBlockWithData(i, type, data);
} }
return chunkSection; return chunkSection;
@ -55,15 +55,11 @@ public class ChunkSectionType1_8 extends Type<ChunkSection> {
@Override @Override
public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception { public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception {
for (int y = 0; y < 16; y++) { DataPalette blocks = chunkSection.palette(PaletteType.BLOCKS);
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
int block = chunkSection.getFlatBlock(x, y, z);
buffer.writeByte(block);
buffer.writeByte(block >> 8);
}
}
}
}
ByteBuf littleEndianView = buffer.order(ByteOrder.LITTLE_ENDIAN);
for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
littleEndianView.writeShort(blocks.idAt(idx));
}
}
} }

Datei anzeigen

@ -25,6 +25,8 @@ import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection; import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.minecraft.entities.Entity1_12Types; import com.viaversion.viaversion.api.minecraft.entities.Entity1_12Types;
import com.viaversion.viaversion.api.platform.providers.ViaProviders; import com.viaversion.viaversion.api.platform.providers.ViaProviders;
import com.viaversion.viaversion.api.protocol.AbstractProtocol; import com.viaversion.viaversion.api.protocol.AbstractProtocol;
@ -125,23 +127,22 @@ public class Protocol1_12To1_11_1 extends AbstractProtocol<ClientboundPackets1_9
Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld); Chunk1_9_3_4Type type = new Chunk1_9_3_4Type(clientWorld);
Chunk chunk = wrapper.passthrough(type); Chunk chunk = wrapper.passthrough(type);
for (int i = 0; i < chunk.getSections().length; i++) { for (int s = 0; s < chunk.getSections().length; s++) {
ChunkSection section = chunk.getSections()[i]; ChunkSection section = chunk.getSections()[s];
if (section == null) if (section == null) continue;
continue; DataPalette blocks = section.palette(PaletteType.BLOCKS);
for (int y = 0; y < 16; y++) { for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
for (int z = 0; z < 16; z++) { int id = blocks.idAt(idx) >> 4;
for (int x = 0; x < 16; x++) {
int block = section.getBlockWithoutData(x, y, z);
// Is this a bed? // Is this a bed?
if (block == 26) { if (id != 26) continue;
// NBT -> { color:14, x:132, y:64, z:222, id:"minecraft:bed" } (Debug output) // NBT -> { color:14, x:132, y:64, z:222, id:"minecraft:bed" } (Debug output)
CompoundTag tag = new CompoundTag(); CompoundTag tag = new CompoundTag();
tag.put("color", new IntTag(14)); // Set color to red (Default in previous versions) tag.put("color", new IntTag(14)); // Set color to red (Default in previous versions)
tag.put("x", new IntTag(x + (chunk.getX() << 4))); tag.put("x", new IntTag(ChunkSection.xFromIndex(idx) + (chunk.getX() << 4)));
tag.put("y", new IntTag(y + (i << 4))); tag.put("y", new IntTag(ChunkSection.yFromIndex(idx) + (s << 4)));
tag.put("z", new IntTag(z + (chunk.getZ() << 4))); tag.put("z", new IntTag(ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4)));
tag.put("id", new StringTag("minecraft:bed")); tag.put("id", new StringTag("minecraft:bed"));
// Add a fake block entity // Add a fake block entity
@ -149,10 +150,6 @@ public class Protocol1_12To1_11_1 extends AbstractProtocol<ClientboundPackets1_9
} }
} }
} }
}
}
}
}); });
} }
}); });

Datei anzeigen

@ -28,6 +28,8 @@ import com.viaversion.viaversion.api.minecraft.BlockFace;
import com.viaversion.viaversion.api.minecraft.Position; import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.type.Type; import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13; import com.viaversion.viaversion.protocols.protocol1_13to1_12_2.ClientboundPackets1_13;
@ -75,31 +77,25 @@ public class ConnectionData {
} }
public static void updateChunkSectionNeighbours(UserConnection user, int chunkX, int chunkZ, int chunkSectionY) { public static void updateChunkSectionNeighbours(UserConnection user, int chunkX, int chunkZ, int chunkSectionY) {
int chunkMinY = chunkSectionY << 4;
List<BlockChangeRecord1_8> updates = new ArrayList<>();
for (int chunkDeltaX = -1; chunkDeltaX <= 1; chunkDeltaX++) { for (int chunkDeltaX = -1; chunkDeltaX <= 1; chunkDeltaX++) {
for (int chunkDeltaZ = -1; chunkDeltaZ <= 1; chunkDeltaZ++) { for (int chunkDeltaZ = -1; chunkDeltaZ <= 1; chunkDeltaZ++) {
if (Math.abs(chunkDeltaX) + Math.abs(chunkDeltaZ) == 0) continue; int distance = Math.abs(chunkDeltaX) + Math.abs(chunkDeltaZ);
if (distance == 0) continue;
List<BlockChangeRecord1_8> updates = new ArrayList<>(); int chunkMinX = (chunkX + chunkDeltaX) << 4;
int chunkMinZ = (chunkZ + chunkDeltaZ) << 4;
if (Math.abs(chunkDeltaX) + Math.abs(chunkDeltaZ) == 2) { // Corner if (distance == 2) { // Corner
for (int blockY = chunkSectionY * 16; blockY < chunkSectionY * 16 + 16; blockY++) { for (int blockY = chunkMinY; blockY < chunkMinY + 16; blockY++) {
int blockPosX = chunkDeltaX == 1 ? 0 : 15; int blockPosX = chunkDeltaX == 1 ? 0 : 15;
int blockPosZ = chunkDeltaZ == 1 ? 0 : 15; int blockPosZ = chunkDeltaZ == 1 ? 0 : 15;
updateBlock(user, updateBlock(user, new Position(chunkMinX + blockPosX, blockY, chunkMinZ + blockPosZ), updates);
new Position(
((chunkX + chunkDeltaX) << 4) + blockPosX,
(short) blockY,
((chunkZ + chunkDeltaZ) << 4) + blockPosZ
),
updates
);
} }
} else { } else {
for (int blockY = chunkSectionY * 16; blockY < chunkSectionY * 16 + 16; blockY++) { for (int blockY = chunkMinY; blockY < chunkMinY + 16; blockY++) {
int xStart; int xStart, xEnd;
int xEnd; int zStart, zEnd;
int zStart;
int zEnd;
if (chunkDeltaX == 1) { if (chunkDeltaX == 1) {
xStart = 0; xStart = 0;
xEnd = 2; xEnd = 2;
@ -123,13 +119,7 @@ public class ConnectionData {
} }
for (int blockX = xStart; blockX < xEnd; blockX++) { for (int blockX = xStart; blockX < xEnd; blockX++) {
for (int blockZ = zStart; blockZ < zEnd; blockZ++) { for (int blockZ = zStart; blockZ < zEnd; blockZ++) {
updateBlock(user, updateBlock(user, new Position(chunkMinX + blockX, blockY, chunkMinZ + blockZ), updates);
new Position(
((chunkX + chunkDeltaX) << 4) + blockX,
(short) blockY,
((chunkZ + chunkDeltaZ) << 4) + blockZ),
updates
);
} }
} }
} }
@ -145,6 +135,7 @@ public class ConnectionData {
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
updates.clear();
} }
} }
} }
@ -178,17 +169,17 @@ public class ConnectionData {
} }
public static void connectBlocks(UserConnection user, Chunk chunk) { public static void connectBlocks(UserConnection user, Chunk chunk) {
long xOff = chunk.getX() << 4; int xOff = chunk.getX() << 4;
long zOff = chunk.getZ() << 4; int zOff = chunk.getZ() << 4;
for (int i = 0; i < chunk.getSections().length; i++) { for (int s = 0; s < chunk.getSections().length; s++) {
ChunkSection section = chunk.getSections()[i]; ChunkSection section = chunk.getSections()[s];
if (section == null) continue; if (section == null) continue;
DataPalette blocks = section.palette(PaletteType.BLOCKS);
boolean willConnect = false; boolean willConnect = false;
for (int p = 0; p < blocks.size(); p++) {
for (int p = 0; p < section.getPaletteSize(); p++) { int id = blocks.idByIndex(p);
int id = section.getPaletteEntry(p);
if (ConnectionData.connects(id)) { if (ConnectionData.connects(id)) {
willConnect = true; willConnect = true;
break; break;
@ -196,24 +187,14 @@ public class ConnectionData {
} }
if (!willConnect) continue; if (!willConnect) continue;
long yOff = i << 4; int yOff = s << 4;
for (int y = 0; y < 16; y++) { for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
for (int z = 0; z < 16; z++) { int id = blocks.idAt(idx);
for (int x = 0; x < 16; x++) { ConnectionHandler handler = ConnectionData.getConnectionHandler(id);
int block = section.getFlatBlock(x, y, z); if (handler == null) continue;
id = handler.connect(user, new Position(xOff + ChunkSection.xFromIndex(idx), yOff + ChunkSection.yFromIndex(idx), zOff + ChunkSection.zFromIndex(idx)), id);
ConnectionHandler handler = ConnectionData.getConnectionHandler(block); blocks.setIdAt(idx, id);
if (handler != null) {
block = handler.connect(user, new Position(
(int) (xOff + x),
(short) (yOff + y),
(int) (zOff + z)
), block);
section.setFlatBlock(x, y, z, block);
}
}
}
} }
} }
} }

Datei anzeigen

@ -27,6 +27,8 @@ import com.viaversion.viaversion.api.minecraft.BlockChangeRecord;
import com.viaversion.viaversion.api.minecraft.Position; import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.Protocol; import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper; import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
@ -334,77 +336,62 @@ public class WorldPackets {
Chunk chunk = wrapper.read(type); Chunk chunk = wrapper.read(type);
wrapper.write(type1_13, chunk); wrapper.write(type1_13, chunk);
for (int i = 0; i < chunk.getSections().length; i++) { for (int s = 0; s < chunk.getSections().length; s++) {
ChunkSection section = chunk.getSections()[i]; ChunkSection section = chunk.getSections()[s];
if (section == null) if (section == null) continue;
continue; DataPalette blocks = section.palette(PaletteType.BLOCKS);
for (int p = 0; p < section.getPaletteSize(); p++) { for (int p = 0; p < blocks.size(); p++) {
int old = section.getPaletteEntry(p); int old = blocks.idByIndex(p);
int newId = toNewId(old); int newId = toNewId(old);
section.setPaletteEntry(p, newId); blocks.setIdByIndex(p, newId);
} }
storage: storage:
{ {
if (chunk.isFullChunk()) { if (chunk.isFullChunk()) {
boolean willSave = false; boolean willSave = false;
for (int j = 0; j < section.getPaletteSize(); j++) { for (int p = 0; p < blocks.size(); p++) {
if (storage.isWelcome(section.getPaletteEntry(j))) { if (storage.isWelcome(blocks.idByIndex(p))) {
willSave = true; willSave = true;
break; break;
} }
} }
if (!willSave) break storage; if (!willSave) break storage;
} }
for (int y = 0; y < 16; y++) { for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
for (int z = 0; z < 16; z++) { int id = blocks.idAt(idx);
for (int x = 0; x < 16; x++) { if (storage.isWelcome(id)) {
int block = section.getFlatBlock(x, y, z); storage.store(new Position(ChunkSection.xFromIndex(idx) + (chunk.getX() << 4), ChunkSection.yFromIndex(idx) + (s << 4), ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4)), id);
Position pos = new Position(
(x + (chunk.getX() << 4)),
(y + (i << 4)),
(z + (chunk.getZ() << 4))
);
if (storage.isWelcome(block)) {
storage.store(pos, block);
} else if (!chunk.isFullChunk()) { // Update } else if (!chunk.isFullChunk()) { // Update
storage.remove(pos); storage.remove(new Position(ChunkSection.xFromIndex(idx) + (chunk.getX() << 4), ChunkSection.yFromIndex(idx) + (s << 4), ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4)));
}
}
} }
} }
} }
save_connections: save_connections:
{ {
if (!Via.getConfig().isServersideBlockConnections() if (!Via.getConfig().isServersideBlockConnections() || !ConnectionData.needStoreBlocks()) break save_connections;
|| !ConnectionData.needStoreBlocks()) break save_connections;
if (!chunk.isFullChunk()) { // Update if (!chunk.isFullChunk()) { // Update
ConnectionData.blockConnectionProvider.unloadChunkSection(wrapper.user(), chunk.getX(), i, chunk.getZ()); ConnectionData.blockConnectionProvider.unloadChunkSection(wrapper.user(), chunk.getX(), s, chunk.getZ());
} }
boolean willSave = false; boolean willSave = false;
for (int j = 0; j < section.getPaletteSize(); j++) { for (int p = 0; p < blocks.size(); p++) {
if (ConnectionData.isWelcome(section.getPaletteEntry(j))) { if (ConnectionData.isWelcome(blocks.idByIndex(p))) {
willSave = true; willSave = true;
break; break;
} }
} }
if (!willSave) break save_connections; if (!willSave) break save_connections;
for (int y = 0; y < 16; y++) { for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
for (int z = 0; z < 16; z++) { int id = blocks.idAt(idx);
for (int x = 0; x < 16; x++) { if (ConnectionData.isWelcome(id)) {
int block = section.getFlatBlock(x, y, z); int globalX = ChunkSection.xFromIndex(idx) + (chunk.getX() << 4);
if (ConnectionData.isWelcome(block)) { int globalY = ChunkSection.yFromIndex(idx) + (s << 4);
int globalX = x + (chunk.getX() << 4); int globalZ = ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4);
int globalY = y + (i << 4); ConnectionData.blockConnectionProvider.storeBlock(wrapper.user(), globalX, globalY, globalZ, id);
int globalZ = z + (chunk.getZ() << 4);
ConnectionData.blockConnectionProvider.storeBlock(wrapper.user(), globalX,
globalY, globalZ, block);
}
}
} }
} }
} }

Datei anzeigen

@ -24,7 +24,9 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.BlockFace; import com.viaversion.viaversion.api.minecraft.BlockFace;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.NibbleArray; import com.viaversion.viaversion.api.minecraft.chunks.NibbleArray;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper; import com.viaversion.viaversion.api.protocol.remapper.PacketRemapper;
@ -154,15 +156,16 @@ public class WorldPackets {
for (int s = 0; s < chunk.getSections().length; s++) { for (int s = 0; s < chunk.getSections().length; s++) {
ChunkSection section = chunk.getSections()[s]; ChunkSection section = chunk.getSections()[s];
if (section == null) continue; if (section == null) continue;
DataPalette blocks = section.palette(PaletteType.BLOCKS);
boolean hasBlock = false; boolean hasBlock = false;
for (int i = 0; i < section.getPaletteSize(); i++) { for (int i = 0; i < blocks.size(); i++) {
int old = section.getPaletteEntry(i); int old = blocks.idByIndex(i);
int newId = protocol.getMappingData().getNewBlockStateId(old); int newId = protocol.getMappingData().getNewBlockStateId(old);
if (!hasBlock && newId != air && newId != voidAir && newId != caveAir) { // air, void_air, cave_air if (!hasBlock && newId != air && newId != voidAir && newId != caveAir) { // air, void_air, cave_air
hasBlock = true; hasBlock = true;
} }
section.setPaletteEntry(i, newId); blocks.setIdByIndex(i, newId);
} }
if (!hasBlock) { if (!hasBlock) {
section.setNonAirBlocksCount(0); section.setNonAirBlocksCount(0);
@ -170,25 +173,27 @@ public class WorldPackets {
} }
int nonAirBlockCount = 0; int nonAirBlockCount = 0;
for (int x = 0; x < 16; x++) { int sy = s << 4;
for (int y = 0; y < 16; y++) { for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
for (int z = 0; z < 16; z++) { int id = blocks.idAt(idx);
int id = section.getFlatBlock(x, y, z); if (id == air || id == voidAir || id == caveAir) continue;
if (id != air && id != voidAir && id != caveAir) {
nonAirBlockCount++; nonAirBlockCount++;
worldSurface[x + z * 16] = y + s * 16 + 1; // +1 (top of the block)
} int xz = idx & 0xFF;
int y = ChunkSection.yFromIndex(idx);
worldSurface[xz] = sy + y + 1; // +1 (top of the block)
if (protocol.getMappingData().getMotionBlocking().contains(id)) { if (protocol.getMappingData().getMotionBlocking().contains(id)) {
motionBlocking[x + z * 16] = y + s * 16 + 1; // +1 (top of the block) motionBlocking[xz] = sy + y + 1; // +1 (top of the block)
} }
// Manually update light for non full blocks (block light must not be sent) // Manually update light for non-full blocks (block light must not be sent)
if (Via.getConfig().isNonFullBlockLightFix() && protocol.getMappingData().getNonFullBlocks().contains(id)) { if (Via.getConfig().isNonFullBlockLightFix() && protocol.getMappingData().getNonFullBlocks().contains(id)) {
int x = ChunkSection.xFromIndex(idx);
int z = ChunkSection.zFromIndex(idx);
setNonFullLight(chunk, section, s, x, y, z); setNonFullLight(chunk, section, s, x, y, z);
} }
} }
}
}
section.setNonAirBlocksCount(nonAirBlockCount); section.setNonAirBlocksCount(nonAirBlockCount);
} }

Datei anzeigen

@ -25,6 +25,8 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position; import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk; import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection; import com.viaversion.viaversion.api.minecraft.chunks.ChunkSection;
import com.viaversion.viaversion.api.minecraft.chunks.DataPalette;
import com.viaversion.viaversion.api.minecraft.chunks.PaletteType;
import com.viaversion.viaversion.api.protocol.AbstractProtocol; import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper; import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler; import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
@ -104,18 +106,20 @@ public class Protocol1_9_3To1_9_1_2 extends AbstractProtocol<ClientboundPackets1
wrapper.write(new Chunk1_9_3_4Type(clientWorld), chunk); wrapper.write(new Chunk1_9_3_4Type(clientWorld), chunk);
List<CompoundTag> tags = chunk.getBlockEntities(); List<CompoundTag> tags = chunk.getBlockEntities();
for (int i = 0; i < chunk.getSections().length; i++) { for (int s = 0; s < chunk.getSections().length; s++) {
ChunkSection section = chunk.getSections()[i]; ChunkSection section = chunk.getSections()[s];
if (section == null) continue; if (section == null) continue;
DataPalette blocks = section.palette(PaletteType.BLOCKS);
for (int y = 0; y < 16; y++) { for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
for (int z = 0; z < 16; z++) { int id = blocks.idAt(idx) >> 4;
for (int x = 0; x < 16; x++) { if (FakeTileEntity.isTileEntity(id)) {
int block = section.getBlockWithoutData(x, y, z); tags.add(FakeTileEntity.createTileEntity(
if (FakeTileEntity.isTileEntity(block)) { ChunkSection.xFromIndex(idx) + (chunk.getX() << 4),
tags.add(FakeTileEntity.createTileEntity(x + (chunk.getX() << 4), y + (i << 4), z + (chunk.getZ() << 4), block)); ChunkSection.yFromIndex(idx) + (s << 4),
} ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4),
} id
));
} }
} }
} }