Fix cached packets being outdated

This commit is contained in:
themode 2021-03-02 19:14:52 +01:00
parent 85998cabd9
commit a927938677
5 changed files with 77 additions and 21 deletions

View File

@ -16,6 +16,7 @@ import net.minestom.server.utils.Utils;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.cache.CacheablePacket;
import net.minestom.server.utils.cache.TemporaryCache;
import net.minestom.server.utils.cache.TimedBuffer;
import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.world.biomes.Biome;
import org.jetbrains.annotations.NotNull;
@ -27,7 +28,7 @@ import java.util.UUID;
public class ChunkDataPacket implements ServerPacket, CacheablePacket {
private static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
private static final TemporaryCache<ByteBuf> CACHE = new TemporaryCache<>(10000L);
private static final TemporaryCache<TimedBuffer> CACHE = new TemporaryCache<>(10000L);
public boolean fullChunk;
public Biome[] biomes;
@ -46,12 +47,12 @@ public class ChunkDataPacket implements ServerPacket, CacheablePacket {
private static final int MAX_BUFFER_SIZE = (Short.BYTES + Byte.BYTES + 5 * Byte.BYTES + (4096 * MAX_BITS_PER_ENTRY / Long.SIZE * Long.BYTES)) * CHUNK_SECTION_COUNT + 256 * Integer.BYTES;
// Cacheable data
private UUID identifier;
private long lastUpdate;
private final UUID identifier;
private final long timestamp;
public ChunkDataPacket(@Nullable UUID identifier, long lastUpdate) {
public ChunkDataPacket(@Nullable UUID identifier, long timestamp) {
this.identifier = identifier;
this.lastUpdate = lastUpdate;
this.timestamp = timestamp;
}
@Override
@ -139,7 +140,7 @@ public class ChunkDataPacket implements ServerPacket, CacheablePacket {
@NotNull
@Override
public TemporaryCache<ByteBuf> getCache() {
public TemporaryCache<TimedBuffer> getCache() {
return CACHE;
}
@ -147,4 +148,9 @@ public class ChunkDataPacket implements ServerPacket, CacheablePacket {
public UUID getIdentifier() {
return identifier;
}
@Override
public long getTimestamp() {
return timestamp;
}
}

View File

@ -1,11 +1,11 @@
package net.minestom.server.network.packet.server.play;
import io.netty.buffer.ByteBuf;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.cache.CacheablePacket;
import net.minestom.server.utils.cache.TemporaryCache;
import net.minestom.server.utils.cache.TimedBuffer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -14,7 +14,7 @@ import java.util.UUID;
public class UpdateLightPacket implements ServerPacket, CacheablePacket {
private static final TemporaryCache<ByteBuf> CACHE = new TemporaryCache<>(10000L);
private static final TemporaryCache<TimedBuffer> CACHE = new TemporaryCache<>(10000L);
public int chunkX;
public int chunkZ;
@ -31,12 +31,12 @@ public class UpdateLightPacket implements ServerPacket, CacheablePacket {
public List<byte[]> blockLight;
// Cacheable data
private UUID identifier;
private long lastUpdate;
private final UUID identifier;
private final long timestamp;
public UpdateLightPacket(@Nullable UUID identifier, long lastUpdate) {
public UpdateLightPacket(@Nullable UUID identifier, long timestamp) {
this.identifier = identifier;
this.lastUpdate = lastUpdate;
this.timestamp = timestamp;
}
@Override
@ -72,7 +72,7 @@ public class UpdateLightPacket implements ServerPacket, CacheablePacket {
@NotNull
@Override
public TemporaryCache<ByteBuf> getCache() {
public TemporaryCache<TimedBuffer> getCache() {
return CACHE;
}
@ -80,4 +80,9 @@ public class UpdateLightPacket implements ServerPacket, CacheablePacket {
public UUID getIdentifier() {
return identifier;
}
@Override
public long getTimestamp() {
return timestamp;
}
}

View File

@ -18,6 +18,7 @@ import net.minestom.server.network.packet.server.login.SetCompressionPacket;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.cache.CacheablePacket;
import net.minestom.server.utils.cache.TemporaryCache;
import net.minestom.server.utils.cache.TimedBuffer;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -128,15 +129,25 @@ public class NettyPlayerConnection extends PlayerConnection {
// This packet explicitly asks to do not retrieve the cache
write(serverPacket);
} else {
final long time = cacheablePacket.getTimestamp();
// Try to retrieve the cached buffer
TemporaryCache<ByteBuf> temporaryCache = cacheablePacket.getCache();
ByteBuf buffer = temporaryCache.retrieve(identifier);
if (buffer == null) {
TemporaryCache<TimedBuffer> temporaryCache = cacheablePacket.getCache();
TimedBuffer timedBuffer = temporaryCache.retrieve(identifier);
boolean shouldUpdate = false;
if (timedBuffer == null) {
// Buffer not found, create and cache it
buffer = PacketUtils.createFramedPacket(serverPacket, false);
temporaryCache.cache(identifier, buffer);
final ByteBuf buffer = PacketUtils.createFramedPacket(serverPacket, false);
timedBuffer = new TimedBuffer(buffer, time);
shouldUpdate = true;
} else if (time > timedBuffer.getTimestamp()) { // Verify if `serverPacket` is more up-to-date
shouldUpdate = true;
}
FramedPacket framedPacket = new FramedPacket(buffer);
if (shouldUpdate) {
temporaryCache.cache(identifier, timedBuffer);
}
FramedPacket framedPacket = new FramedPacket(timedBuffer.getBuffer());
write(framedPacket);
}

View File

@ -1,6 +1,5 @@
package net.minestom.server.utils.cache;
import io.netty.buffer.ByteBuf;
import net.minestom.server.network.packet.server.ServerPacket;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -23,7 +22,7 @@ public interface CacheablePacket {
* @return the temporary packet cache
*/
@NotNull
TemporaryCache<ByteBuf> getCache();
TemporaryCache<TimedBuffer> getCache();
/**
* Gets the identifier of this packet.
@ -35,4 +34,11 @@ public interface CacheablePacket {
@Nullable
UUID getIdentifier();
/**
* Gets the last time this packet changed.
*
* @return the last packet update time in milliseconds
*/
long getTimestamp();
}

View File

@ -0,0 +1,28 @@
package net.minestom.server.utils.cache;
import io.netty.buffer.ByteBuf;
import org.jetbrains.annotations.NotNull;
/**
* Object containing a {@link ByteBuf buffer} and its timestamp.
* Used for packet-caching to use the most recent.
*/
public class TimedBuffer {
private final ByteBuf buffer;
private final long timestamp;
public TimedBuffer(@NotNull ByteBuf buffer, long timestamp) {
this.buffer = buffer;
this.timestamp = timestamp;
}
@NotNull
public ByteBuf getBuffer() {
return buffer;
}
public long getTimestamp() {
return timestamp;
}
}