Skip to content

Commit 891f1a2

Browse files
committed
Fix #53 Thread safe LocalMobCapCalculator
1 parent 2f43975 commit 891f1a2

1 file changed

Lines changed: 46 additions & 0 deletions

File tree

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
--- a/net/minecraft/world/level/LocalMobCapCalculator.java
2+
+++ b/net/minecraft/world/level/LocalMobCapCalculator.java
3+
@@ -1,19 +_,22 @@
4+
package net.minecraft.world.level;
5+
6+
import com.google.common.collect.Maps;
7+
+import io.multipaper.shreddedpaper.util.SimpleStampedLock;
8+
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
9+
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
10+
import it.unimi.dsi.fastutil.objects.Object2IntMap;
11+
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
+import java.util.concurrent.ConcurrentHashMap;
15+
import net.minecraft.server.level.ChunkMap;
16+
import net.minecraft.server.level.ServerPlayer;
17+
import net.minecraft.world.entity.MobCategory;
18+
19+
public class LocalMobCapCalculator {
20+
- private final Long2ObjectMap<List<ServerPlayer>> playersNearChunk = new Long2ObjectOpenHashMap<>();
21+
+ private final Map<Long, List<ServerPlayer>> playersNearChunk = new ConcurrentHashMap<>(); // ShreddedPaper - thread safety (playersNearChunk is mostly writes)
22+
private final Map<ServerPlayer, LocalMobCapCalculator.MobCounts> playerMobCounts = Maps.newHashMap();
23+
+ private final SimpleStampedLock playerMobCountsLock = new SimpleStampedLock(); // ShreddedPaper - thread safety (playerMobCounts is mostly reads)
24+
private final ChunkMap chunkMap;
25+
26+
public LocalMobCapCalculator(ChunkMap chunkMap) {
27+
@@ -26,13 +_,17 @@
28+
29+
public void addMob(ChunkPos pos, MobCategory category) {
30+
for (ServerPlayer serverPlayer : this.getPlayersNear(pos)) {
31+
- this.playerMobCounts.computeIfAbsent(serverPlayer, key -> new LocalMobCapCalculator.MobCounts()).add(category);
32+
+ // ShreddedPaper start - thread safety
33+
+ LocalMobCapCalculator.MobCounts playerMobCount = this.playerMobCountsLock.optimisticRead(() -> this.playerMobCounts.get(serverPlayer));
34+
+ if (playerMobCount == null) playerMobCount = this.playerMobCountsLock.write(() -> this.playerMobCounts.computeIfAbsent(serverPlayer, key -> new LocalMobCapCalculator.MobCounts()));
35+
+ playerMobCount.add(category);
36+
+ // ShreddedPaper end - thread safety
37+
}
38+
}
39+
40+
public boolean canSpawn(MobCategory category, ChunkPos pos) {
41+
for (ServerPlayer serverPlayer : this.getPlayersNear(pos)) {
42+
- LocalMobCapCalculator.MobCounts mobCounts = this.playerMobCounts.get(serverPlayer);
43+
+ LocalMobCapCalculator.MobCounts mobCounts = this.playerMobCountsLock.optimisticRead(() -> this.playerMobCounts.get(serverPlayer)); // ShreddedPaper - thread safety
44+
if (mobCounts == null || mobCounts.canSpawn(category)) {
45+
return true;
46+
}

0 commit comments

Comments
 (0)