mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-28 19:11:45 +01:00
Add server flag for ChunkUpdateLimitChecker history size (#2596)
* Add server flag for ChunkUpdateLimitChecker history size * Fixup server flag for ChunkUpdateLimitChecker history size
This commit is contained in:
parent
807a887fbd
commit
6f107c7f88
@ -27,6 +27,7 @@ public final class ServerFlag {
|
||||
public static final int PLAYER_PACKET_QUEUE_SIZE = intProperty("minestom.packet-queue-size", 1000);
|
||||
public static final long KEEP_ALIVE_DELAY = longProperty("minestom.keep-alive-delay", 10_000);
|
||||
public static final long KEEP_ALIVE_KICK = longProperty("minestom.keep-alive-kick", 15_000);
|
||||
public static final int PLAYER_CHUNK_UPDATE_LIMITER_HISTORY_SIZE = intProperty("minestom.player.chunk-update-limiter-history-size", 5, 0, Integer.MAX_VALUE);
|
||||
|
||||
// Network buffers
|
||||
public static final int MAX_PACKET_SIZE = intProperty("minestom.max-packet-size", 2_097_151); // 3 bytes var-int
|
||||
@ -98,8 +99,19 @@ public final class ServerFlag {
|
||||
return System.getProperty(name);
|
||||
}
|
||||
|
||||
private static int intProperty(String name, int defaultValue, int minValue, int maxValue) {
|
||||
int value = Integer.getInteger(name, defaultValue);
|
||||
if (value < minValue || value > maxValue) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"Property '%s' value must be in range [%d..%d] but was %d",
|
||||
name, minValue, maxValue, value
|
||||
));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static int intProperty(String name, int defaultValue) {
|
||||
return Integer.getInteger(name, defaultValue);
|
||||
return intProperty(name, defaultValue, Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
private static long longProperty(String name, long defaultValue) {
|
||||
|
@ -191,7 +191,7 @@ public class Player extends LivingEntity implements CommandSender, HoverEventSou
|
||||
|
||||
// Game state (https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol#Game_Event)
|
||||
private boolean enableRespawnScreen;
|
||||
private final ChunkUpdateLimitChecker chunkUpdateLimitChecker = new ChunkUpdateLimitChecker(6);
|
||||
private final ChunkUpdateLimitChecker chunkUpdateLimitChecker = new ChunkUpdateLimitChecker(ServerFlag.PLAYER_CHUNK_UPDATE_LIMITER_HISTORY_SIZE);
|
||||
|
||||
// Experience orb pickup
|
||||
protected Cooldown experiencePickupCooldown = new Cooldown(Duration.of(10, TimeUnit.SERVER_TICK));
|
||||
|
@ -6,17 +6,28 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Allows to limit operations with recently operated chunks
|
||||
* <p>
|
||||
* {@link ChunkUpdateLimitChecker#historySize} defines how many last chunks will be remembered
|
||||
* to skip operations with them via {@link ChunkUpdateLimitChecker#addToHistory(Chunk)} returning {@code false}
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public final class ChunkUpdateLimitChecker {
|
||||
|
||||
private final int historySize;
|
||||
private final long[] chunkHistory;
|
||||
|
||||
public ChunkUpdateLimitChecker(int historySize) {
|
||||
this.historySize = historySize;
|
||||
this.chunkHistory = new long[historySize];
|
||||
this.historySize = Math.max(0, historySize);
|
||||
this.chunkHistory = new long[this.historySize];
|
||||
this.clearHistory();
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return historySize > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the chunk to the history
|
||||
*
|
||||
@ -24,14 +35,19 @@ public final class ChunkUpdateLimitChecker {
|
||||
* @return {@code true} if it's a new chunk in the history
|
||||
*/
|
||||
public boolean addToHistory(Chunk chunk) {
|
||||
if (!isEnabled()) {
|
||||
return true;
|
||||
}
|
||||
final long index = CoordConversion.chunkIndex(chunk.getChunkX(), chunk.getChunkZ());
|
||||
boolean result = true;
|
||||
final int lastIndex = historySize - 1;
|
||||
for (int i = 0; i < lastIndex; i++) {
|
||||
for (int i = 0; i <= lastIndex; i++) {
|
||||
if (chunkHistory[i] == index) {
|
||||
result = false;
|
||||
}
|
||||
chunkHistory[i] = chunkHistory[i + 1];
|
||||
if (i != lastIndex) {
|
||||
chunkHistory[i] = chunkHistory[i + 1];
|
||||
}
|
||||
}
|
||||
chunkHistory[lastIndex] = index;
|
||||
return result;
|
||||
|
@ -0,0 +1,54 @@
|
||||
package net.minestom.server.utils.chunk;
|
||||
|
||||
import net.minestom.server.instance.DynamicChunk;
|
||||
import net.minestom.testing.Env;
|
||||
import net.minestom.testing.EnvTest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@EnvTest
|
||||
public class ChunkUpdateLimitCheckerTest {
|
||||
|
||||
@Test
|
||||
public void testHistory(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var limiter = new ChunkUpdateLimitChecker(3);
|
||||
|
||||
assertTrue(limiter.addToHistory(new DynamicChunk(instance, 0, 0)));
|
||||
assertTrue(limiter.addToHistory(new DynamicChunk(instance, 0, 1)));
|
||||
assertTrue(limiter.addToHistory(new DynamicChunk(instance, 0, 2)));
|
||||
// history : 0, 1, 2
|
||||
|
||||
assertFalse(limiter.addToHistory(new DynamicChunk(instance, 0, 0)));
|
||||
// history : 1, 2, 0
|
||||
assertFalse(limiter.addToHistory(new DynamicChunk(instance, 0, 1)));
|
||||
// history : 2, 0, 1
|
||||
assertFalse(limiter.addToHistory(new DynamicChunk(instance, 0, 2)));
|
||||
// history : 0, 1, 2
|
||||
|
||||
assertFalse(limiter.addToHistory(new DynamicChunk(instance, 0, 2)));
|
||||
// history : 1, 2, 2
|
||||
assertTrue(limiter.addToHistory(new DynamicChunk(instance, 0, 0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOneSlotHistory(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var limiter = new ChunkUpdateLimitChecker(1);
|
||||
assertTrue(limiter.addToHistory(new DynamicChunk(instance, 0, 0)));
|
||||
assertFalse(limiter.addToHistory(new DynamicChunk(instance, 0, 0)));
|
||||
assertTrue(limiter.addToHistory(new DynamicChunk(instance, 0, 1)));
|
||||
assertTrue(limiter.addToHistory(new DynamicChunk(instance, 0, 0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisabling(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
var limiter = new ChunkUpdateLimitChecker(0);
|
||||
assertTrue(limiter.addToHistory(new DynamicChunk(instance, 0, 0)));
|
||||
assertTrue(limiter.addToHistory(new DynamicChunk(instance, 0, 0)));
|
||||
assertTrue(limiter.addToHistory(new DynamicChunk(instance, 0, 1)));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user