mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-07 17:08:30 +01:00
Overall performance improvement
This commit is contained in:
parent
c2f302ad0e
commit
01d233f7d8
@ -4,8 +4,10 @@ import com.google.common.collect.Queues;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.InstanceManager;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.network.player.NettyPlayerConnection;
|
||||
import net.minestom.server.thread.PerInstanceThreadProvider;
|
||||
import net.minestom.server.thread.ThreadProvider;
|
||||
import net.minestom.server.utils.async.AsyncUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@ -80,6 +82,12 @@ public final class UpdateManager {
|
||||
// Tick end callbacks
|
||||
doTickCallback(tickEndCallbacks, tickTime / 1000000L);
|
||||
|
||||
// Flush all waiting packets
|
||||
AsyncUtils.runAsync(() -> connectionManager.getOnlinePlayers().stream()
|
||||
.filter(player -> player.getPlayerConnection() instanceof NettyPlayerConnection)
|
||||
.map(player -> (NettyPlayerConnection) player.getPlayerConnection())
|
||||
.forEach(NettyPlayerConnection::flush));
|
||||
|
||||
} catch (Exception e) {
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
package net.minestom.server.instance;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.data.Data;
|
||||
import net.minestom.server.data.SerializableData;
|
||||
@ -34,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
@ -56,7 +54,7 @@ public class InstanceContainer extends Instance {
|
||||
// the chunk generator used, can be null
|
||||
private ChunkGenerator chunkGenerator;
|
||||
// (chunk index -> chunk) map, contains all the chunks in the instance
|
||||
private final Long2ObjectMap<Chunk> chunks = Long2ObjectMaps.synchronize(new Long2ObjectOpenHashMap<>());
|
||||
private final Map<Long, Chunk> chunks = new ConcurrentHashMap<>();
|
||||
// contains all the chunks to remove during the next instance tick, should be synchronized
|
||||
protected final Set<Chunk> scheduledChunksToRemove = new HashSet<>();
|
||||
|
||||
|
@ -19,6 +19,7 @@ import net.minestom.server.utils.binary.BinaryReader;
|
||||
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.TemporaryPacketCache;
|
||||
import net.minestom.server.utils.cache.TimedBuffer;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.world.biomes.Biome;
|
||||
@ -34,8 +35,7 @@ import java.util.concurrent.TimeUnit;
|
||||
public class ChunkDataPacket implements ServerPacket, CacheablePacket {
|
||||
|
||||
private static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
|
||||
private static final TemporaryCache<TimedBuffer> CACHE = new TemporaryCache<>(5, TimeUnit.MINUTES,
|
||||
notification -> notification.getValue().getBuffer().release());
|
||||
private static final TemporaryCache<TimedBuffer> CACHE = new TemporaryPacketCache(5, TimeUnit.MINUTES);
|
||||
|
||||
public boolean fullChunk;
|
||||
public Biome[] biomes;
|
||||
|
@ -6,6 +6,7 @@ import net.minestom.server.utils.binary.BinaryReader;
|
||||
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.TemporaryPacketCache;
|
||||
import net.minestom.server.utils.cache.TimedBuffer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -17,8 +18,7 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class UpdateLightPacket implements ServerPacket, CacheablePacket {
|
||||
|
||||
private static final TemporaryCache<TimedBuffer> CACHE = new TemporaryCache<>(5, TimeUnit.MINUTES,
|
||||
notification -> notification.getValue().getBuffer().release());
|
||||
private static final TemporaryCache<TimedBuffer> CACHE = new TemporaryPacketCache(5, TimeUnit.MINUTES);
|
||||
|
||||
public int chunkX;
|
||||
public int chunkZ;
|
||||
@ -102,7 +102,7 @@ public class UpdateLightPacket implements ServerPacket, CacheablePacket {
|
||||
skyLight.clear();
|
||||
for (int i = 0; i < 14; i++) {
|
||||
int length = reader.readVarInt();
|
||||
if(length != 2048) {
|
||||
if (length != 2048) {
|
||||
throw new IllegalStateException("Length must be 2048.");
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ public class UpdateLightPacket implements ServerPacket, CacheablePacket {
|
||||
blockLight.clear();
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int length = reader.readVarInt();
|
||||
if(length != 2048) {
|
||||
if (length != 2048) {
|
||||
throw new IllegalStateException("Length must be 2048.");
|
||||
}
|
||||
|
||||
|
@ -71,22 +71,6 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
this.tickBuffer.ensureWritable(INITIAL_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
// Flush
|
||||
final int bufferSize = tickBuffer.writerIndex();
|
||||
if (bufferSize > 0) {
|
||||
this.channel.eventLoop().submit(() -> {
|
||||
if (channel.isActive()) {
|
||||
writeWaitingPackets();
|
||||
channel.flush();
|
||||
}
|
||||
});
|
||||
}
|
||||
// Network stats
|
||||
super.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the encryption key and add the codecs to the pipeline.
|
||||
*
|
||||
@ -196,7 +180,7 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
}
|
||||
}
|
||||
|
||||
private void writeWaitingPackets() {
|
||||
public void writeWaitingPackets() {
|
||||
if (tickBuffer.writerIndex() == 0) {
|
||||
// Nothing to write
|
||||
return;
|
||||
@ -221,6 +205,16 @@ public class NettyPlayerConnection extends PlayerConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
final int bufferSize = tickBuffer.writerIndex();
|
||||
if (bufferSize > 0) {
|
||||
if (channel.isActive()) {
|
||||
writeWaitingPackets();
|
||||
channel.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SocketAddress getRemoteAddress() {
|
||||
|
@ -46,6 +46,9 @@ public interface CacheablePacket {
|
||||
|
||||
@Nullable
|
||||
static FramedPacket getCache(@NotNull ServerPacket serverPacket) {
|
||||
if (!(serverPacket instanceof CacheablePacket))
|
||||
return null;
|
||||
|
||||
final CacheablePacket cacheablePacket = (CacheablePacket) serverPacket;
|
||||
final UUID identifier = cacheablePacket.getIdentifier();
|
||||
if (identifier == null) {
|
||||
@ -72,4 +75,20 @@ public interface CacheablePacket {
|
||||
}
|
||||
}
|
||||
|
||||
static void writeCache(@NotNull ByteBuf buffer, @NotNull ServerPacket serverPacket) {
|
||||
FramedPacket framedPacket = CacheablePacket.getCache(serverPacket);
|
||||
if (framedPacket == null) {
|
||||
PacketUtils.writeFramedPacket(buffer, serverPacket);
|
||||
return;
|
||||
}
|
||||
final ByteBuf body = framedPacket.getBody();
|
||||
synchronized (body) {
|
||||
if (framedPacket.getBody().refCnt() != 0) {
|
||||
buffer.writeBytes(body, body.readerIndex(), body.readableBytes());
|
||||
} else {
|
||||
PacketUtils.writeFramedPacket(buffer, serverPacket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
16
src/main/java/net/minestom/server/utils/cache/TemporaryPacketCache.java
vendored
Normal file
16
src/main/java/net/minestom/server/utils/cache/TemporaryPacketCache.java
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
package net.minestom.server.utils.cache;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class TemporaryPacketCache extends TemporaryCache<TimedBuffer> {
|
||||
public TemporaryPacketCache(long duration, TimeUnit timeUnit) {
|
||||
super(duration, timeUnit, notification -> {
|
||||
final ByteBuf buffer = notification.getValue().getBuffer();
|
||||
synchronized (buffer) {
|
||||
buffer.release();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -37,6 +37,13 @@ public final class Check {
|
||||
}
|
||||
}
|
||||
|
||||
@Contract("true, _, _ -> fail")
|
||||
public static void argCondition(boolean condition, @NotNull String reason, Object... arguments) {
|
||||
if (condition) {
|
||||
throw new IllegalArgumentException(MessageFormat.format(reason, arguments));
|
||||
}
|
||||
}
|
||||
|
||||
@Contract("_ -> fail")
|
||||
public static void fail(@NotNull String reason) {
|
||||
throw new IllegalArgumentException(reason);
|
||||
|
Loading…
Reference in New Issue
Block a user