Skip to content

Commit 8e5669e

Browse files
committed
cache blocklimiter result to prevent lag
1 parent 2175d87 commit 8e5669e

File tree

2 files changed

+71
-24
lines changed
  • AnarchyExploitFixesFolia/src/main/java/me/xginko/aef/modules/chunklimits
  • AnarchyExploitFixesLegacy/src/main/java/me/xginko/aef/modules/chunklimits

2 files changed

+71
-24
lines changed

AnarchyExploitFixesFolia/src/main/java/me/xginko/aef/modules/chunklimits/BlockLimit.java

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package me.xginko.aef.modules.chunklimits;
22

33
import com.cryptomorin.xseries.XMaterial;
4+
import com.github.benmanes.caffeine.cache.Cache;
5+
import com.github.benmanes.caffeine.cache.Caffeine;
46
import io.github.thatsmusic99.configurationmaster.api.ConfigSection;
57
import me.xginko.aef.modules.AEFModule;
68
import org.bukkit.Chunk;
@@ -12,16 +14,21 @@
1214
import org.bukkit.event.block.BlockPlaceEvent;
1315
import org.bukkit.event.player.PlayerInteractEvent;
1416

17+
import java.time.Duration;
1518
import java.util.EnumMap;
1619
import java.util.Map;
1720
import java.util.TreeMap;
1821

1922
public class BlockLimit extends AEFModule implements Listener {
2023

2124
private final Map<Material, Integer> blockLimits = new EnumMap<>(Material.class);
25+
private final long materialCountCacheMillis;
26+
27+
private Cache<Chunk, Cache<Material, Integer>> chunkMaterialCache;
2228

2329
public BlockLimit() {
2430
super("chunk-limits.block-limit", false);
31+
this.materialCountCacheMillis = config.getLong(configPath + ".material-count-cache-millis", 5000);
2532

2633
Map<XMaterial, Integer> universal = new EnumMap<>(XMaterial.class);
2734
universal.put(XMaterial.ENCHANTING_TABLE, 16);
@@ -144,12 +151,22 @@ public BlockLimit() {
144151

145152
@Override
146153
public void enable() {
154+
chunkMaterialCache = Caffeine.newBuilder().expireAfterWrite(Duration.ofMinutes(1)).build();
147155
plugin.getServer().getPluginManager().registerEvents(this, plugin);
148156
}
149157

150158
@Override
151159
public void disable() {
152160
HandlerList.unregisterAll(this);
161+
if (chunkMaterialCache != null) {
162+
for (Map.Entry<Chunk, Cache<Material, Integer>> entry : chunkMaterialCache.asMap().entrySet()) {
163+
entry.getValue().invalidateAll();
164+
entry.getValue().cleanUp();
165+
}
166+
chunkMaterialCache.invalidateAll();
167+
chunkMaterialCache.cleanUp();
168+
chunkMaterialCache = null;
169+
}
153170
}
154171

155172
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
@@ -170,24 +187,30 @@ && exceedsPerChunkLimit(event.getMaterial(), event.getPlayer().getChunk())) {
170187
}
171188
}
172189

173-
private boolean exceedsPerChunkLimit(Material material, Chunk chunk) {
174-
final int materialLimit = blockLimits.get(material);
190+
private boolean exceedsPerChunkLimit(Material blockType, Chunk chunk) {
175191
final int minY = chunk.getWorld().getMinHeight();
176192
final int maxY = chunk.getWorld().getMaxHeight();
177193

178-
int count = 0;
179-
for (int x = 0; x < 16; x++) {
180-
for (int z = 0; z < 16; z++) {
181-
for (int y = minY; y < maxY; y++) {
182-
if (chunk.getBlock(x, y, z).getType() == material) {
183-
count++;
184-
if (count > materialLimit) {
185-
return true;
194+
Cache<Material, Integer> materialCountCache = chunkMaterialCache.getIfPresent(chunk);
195+
if (materialCountCache == null) {
196+
materialCountCache = Caffeine.newBuilder().expireAfterWrite(Duration.ofMillis(materialCountCacheMillis)).build();
197+
}
198+
199+
Integer materialCount = materialCountCache.get(blockType, material -> {
200+
int count = 0;
201+
for (int x = 0; x < 16; x++) {
202+
for (int z = 0; z < 16; z++) {
203+
for (int y = minY; y < maxY; y++) {
204+
if (chunk.getBlock(x, y, z).getType() == material) {
205+
count++;
186206
}
187207
}
188208
}
189209
}
190-
}
191-
return false;
210+
return count;
211+
});
212+
213+
chunkMaterialCache.put(chunk, materialCountCache);
214+
return materialCount > blockLimits.get(blockType);
192215
}
193216
}

AnarchyExploitFixesLegacy/src/main/java/me/xginko/aef/modules/chunklimits/BlockLimit.java

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package me.xginko.aef.modules.chunklimits;
22

33
import com.cryptomorin.xseries.XMaterial;
4+
import com.github.benmanes.caffeine.cache.Cache;
5+
import com.github.benmanes.caffeine.cache.Caffeine;
46
import io.github.thatsmusic99.configurationmaster.api.ConfigSection;
57
import me.xginko.aef.modules.AEFModule;
68
import me.xginko.aef.utils.WorldUtil;
@@ -14,16 +16,21 @@
1416
import org.bukkit.event.block.BlockPlaceEvent;
1517
import org.bukkit.event.player.PlayerInteractEvent;
1618

19+
import java.time.Duration;
1720
import java.util.EnumMap;
1821
import java.util.Map;
1922
import java.util.TreeMap;
2023

2124
public class BlockLimit extends AEFModule implements Listener {
2225

2326
private final Map<Material, Integer> blockLimits = new EnumMap<>(Material.class);
27+
private final long materialCountCacheMillis;
28+
29+
private Cache<Chunk, Cache<Material, Integer>> chunkMaterialCache;
2430

2531
public BlockLimit() {
2632
super("chunk-limits.block-limit", false);
33+
this.materialCountCacheMillis = config.getLong(configPath + ".material-count-cache-millis", 5000);
2734

2835
Map<XMaterial, Integer> universal = new EnumMap<>(XMaterial.class);
2936
universal.put(XMaterial.ENCHANTING_TABLE, 16);
@@ -146,12 +153,22 @@ public BlockLimit() {
146153

147154
@Override
148155
public void enable() {
156+
chunkMaterialCache = Caffeine.newBuilder().expireAfterWrite(Duration.ofMinutes(1)).build();
149157
plugin.getServer().getPluginManager().registerEvents(this, plugin);
150158
}
151159

152160
@Override
153161
public void disable() {
154162
HandlerList.unregisterAll(this);
163+
if (chunkMaterialCache != null) {
164+
for (Map.Entry<Chunk, Cache<Material, Integer>> entry : chunkMaterialCache.asMap().entrySet()) {
165+
entry.getValue().invalidateAll();
166+
entry.getValue().cleanUp();
167+
}
168+
chunkMaterialCache.invalidateAll();
169+
chunkMaterialCache.cleanUp();
170+
chunkMaterialCache = null;
171+
}
155172
}
156173

157174
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
@@ -172,23 +189,30 @@ && exceedsPerChunkLimit(event.getMaterial(), event.getPlayer().getChunk())) {
172189
}
173190
}
174191

175-
private boolean exceedsPerChunkLimit(Material material, Chunk chunk) {
176-
final int materialLimit = blockLimits.get(material);
192+
private boolean exceedsPerChunkLimit(Material blockType, Chunk chunk) {
177193
final int minY = WorldUtil.getMinWorldHeight(chunk.getWorld());
178194
final int maxY = chunk.getWorld().getMaxHeight();
179-
int count = 0;
180-
for (int x = 0; x < 16; x++) {
181-
for (int z = 0; z < 16; z++) {
182-
for (int y = minY; y < maxY; y++) {
183-
if (chunk.getBlock(x, y, z).getType() == material) {
184-
count++;
185-
if (count > materialLimit) {
186-
return true;
195+
196+
Cache<Material, Integer> materialCountCache = chunkMaterialCache.getIfPresent(chunk);
197+
if (materialCountCache == null) {
198+
materialCountCache = Caffeine.newBuilder().expireAfterWrite(Duration.ofMillis(materialCountCacheMillis)).build();
199+
}
200+
201+
Integer materialCount = materialCountCache.get(blockType, material -> {
202+
int count = 0;
203+
for (int x = 0; x < 16; x++) {
204+
for (int z = 0; z < 16; z++) {
205+
for (int y = minY; y < maxY; y++) {
206+
if (chunk.getBlock(x, y, z).getType() == material) {
207+
count++;
187208
}
188209
}
189210
}
190211
}
191-
}
192-
return false;
212+
return count;
213+
});
214+
215+
chunkMaterialCache.put(chunk, materialCountCache);
216+
return materialCount > blockLimits.get(blockType);
193217
}
194218
}

0 commit comments

Comments
 (0)