Some minor performance improvements and cleanups (#3134)

This commit is contained in:
Gero 2022-10-04 13:25:55 +02:00 committed by GitHub
parent c7eb2e4b97
commit 7698ee7683
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 140 additions and 158 deletions

View File

@ -40,6 +40,18 @@ public interface ChunkSection {
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)*/
default int getFlatBlock(int idx) {
return palette(PaletteType.BLOCKS).idAt(idx);

View File

@ -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.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 io.netty.buffer.ByteBuf;
@ -38,16 +40,14 @@ public class ChunkSectionType1_8 extends Type<ChunkSection> {
@Override
public ChunkSection read(ByteBuf buffer) throws Exception {
ChunkSection chunkSection = new ChunkSectionImpl(true);
DataPalette blocks = chunkSection.palette(PaletteType.BLOCKS);
// 0 index needs to be air in 1.9
chunkSection.addPaletteEntry(0);
blocks.addId(0);
ByteBuf littleEndianView = buffer.order(ByteOrder.LITTLE_ENDIAN);
for (int i = 0; i < ChunkSection.SIZE; i++) {
int mask = littleEndianView.readShort();
int type = mask >> 4;
int data = mask & 0xF;
chunkSection.setBlockWithData(i, type, data);
for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
blocks.setIdAt(idx, littleEndianView.readShort());
}
return chunkSection;
@ -55,15 +55,11 @@ public class ChunkSectionType1_8 extends Type<ChunkSection> {
@Override
public void write(ByteBuf buffer, ChunkSection chunkSection) throws Exception {
for (int y = 0; y < 16; y++) {
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);
}
}
DataPalette blocks = chunkSection.palette(PaletteType.BLOCKS);
ByteBuf littleEndianView = buffer.order(ByteOrder.LITTLE_ENDIAN);
for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
littleEndianView.writeShort(blocks.idAt(idx));
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -25,6 +25,8 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.Position;
import com.viaversion.viaversion.api.minecraft.chunks.Chunk;
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.packet.PacketWrapper;
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);
List<CompoundTag> tags = chunk.getBlockEntities();
for (int i = 0; i < chunk.getSections().length; i++) {
ChunkSection section = chunk.getSections()[i];
for (int s = 0; s < chunk.getSections().length; s++) {
ChunkSection section = chunk.getSections()[s];
if (section == null) continue;
DataPalette blocks = section.palette(PaletteType.BLOCKS);
for (int y = 0; y < 16; y++) {
for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) {
int block = section.getBlockWithoutData(x, y, z);
if (FakeTileEntity.isTileEntity(block)) {
tags.add(FakeTileEntity.createTileEntity(x + (chunk.getX() << 4), y + (i << 4), z + (chunk.getZ() << 4), block));
}
}
for (int idx = 0; idx < ChunkSection.SIZE; idx++) {
int id = blocks.idAt(idx) >> 4;
if (FakeTileEntity.isTileEntity(id)) {
tags.add(FakeTileEntity.createTileEntity(
ChunkSection.xFromIndex(idx) + (chunk.getX() << 4),
ChunkSection.yFromIndex(idx) + (s << 4),
ChunkSection.zFromIndex(idx) + (chunk.getZ() << 4),
id
));
}
}
}