2828import static io .github .opencubicchunks .cubicchunks .api .util .Coords .blockToLocal ;
2929import io .github .opencubicchunks .cubicchunks .core .util .WatchersSortingList2D ;
3030import io .github .opencubicchunks .cubicchunks .core .util .WatchersSortingList3D ;
31+ import it .unimi .dsi .fastutil .objects .Object2ObjectOpenHashMap ;
3132import static net .minecraft .util .math .MathHelper .clamp ;
3233
3334import com .google .common .base .Predicate ;
9596public class PlayerCubeMap extends PlayerChunkMap {
9697
9798 private static final Predicate <EntityPlayerMP > NOT_SPECTATOR = player -> player != null && !player .isSpectator ();
98- private static final Predicate <EntityPlayerMP > CAN_GENERATE_CHUNKS = player -> player != null &&
99- (!player .isSpectator () || player .getServerWorld ().getGameRules ().getBoolean ("spectatorsGenerateChunks" ));
10099
101100 /**
102101 * Cube selector is used to find which cube positions need to be loaded/unloaded
@@ -189,7 +188,7 @@ public class PlayerCubeMap extends PlayerChunkMap {
189188
190189 private final CubeProviderServer cubeCache ;
191190
192- private final Multimap <EntityPlayerMP , Cube > cubesToSend = Multimaps . newSetMultimap ( new HashMap <>(), HashSet :: new );
191+ private final Object2ObjectOpenHashMap <EntityPlayerMP , ObjectOpenHashSet < Cube >> cubesToSend = new Object2ObjectOpenHashMap <>(2 );
193192
194193 // these player adds will be processed on the next tick
195194 // this exists as temporary workaround to player respawn code calling addPlayer() before spawning
@@ -287,6 +286,9 @@ private void addTickableColumns(TickableChunkContainer tickableChunksCubes) {
287286 @ Override
288287 public void tick () {
289288 getWorldServer ().profiler .startSection ("playerCubeMapTick" );
289+ boolean spectatorsGenerateChunks = getWorldServer ().getGameRules ().getBoolean ("spectatorsGenerateChunks" );
290+ Predicate <EntityPlayerMP > canGenerateChunkPredicate = player -> player != null && (spectatorsGenerateChunks ||!player .isSpectator ());
291+
290292 long currentTime = this .getWorldServer ().getTotalWorldTime ();
291293
292294 getWorldServer ().profiler .startSection ("addPendingPlayers" );
@@ -320,7 +322,6 @@ public void tick() {
320322 this .columnWatchersToUpdate .forEach (ColumnWatcher ::update );
321323 this .columnWatchersToUpdate .clear ();
322324 }
323-
324325 getWorldServer ().profiler .endStartSection ("sortTickableTracker" );
325326 tickableCubeTracker .tick ();
326327
@@ -329,7 +330,6 @@ public void tick() {
329330 this .columnsToGenerate .tick ();
330331
331332 getWorldServer ().profiler .endStartSection ("sortToSend" );
332- //sort cubesToSendToClients every other 4 ticks
333333 this .cubesToSendToClients .tick ();
334334 this .columnsToSendToClients .tick ();
335335 this .watchersToAddPlayersTo .tick ();
@@ -343,7 +343,7 @@ public void tick() {
343343
344344 boolean success = entry .getChunk () != null ;
345345 if (!success ) {
346- boolean canGenerate = entry .hasPlayerMatching (CAN_GENERATE_CHUNKS );
346+ boolean canGenerate = entry .hasPlayerMatching (canGenerateChunkPredicate );
347347 getWorldServer ().profiler .startSection ("generate" );
348348 success = entry .providePlayerChunk (canGenerate );
349349 getWorldServer ().profiler .endSection (); // generate
@@ -375,7 +375,7 @@ public void tick() {
375375 boolean success = !watcher .isWaitingForCube ();
376376 boolean alreadyLoaded = success ;
377377 if (!success ) {
378- boolean canGenerate = watcher .hasPlayerMatching (CAN_GENERATE_CHUNKS );
378+ boolean canGenerate = watcher .hasPlayerMatching (canGenerateChunkPredicate );
379379 getWorldServer ().profiler .startSection ("generate" );
380380 success = watcher .providePlayerCube (canGenerate );
381381 getWorldServer ().profiler .endSection ();
@@ -894,7 +894,8 @@ public void removeEntry(ColumnWatcher entry) {
894894 }
895895
896896 public void scheduleSendCubeToPlayer (Cube cube , EntityPlayerMP player ) {
897- cubesToSend .put (player , cube );
897+ ObjectOpenHashSet <Cube > cubes = cubesToSend .computeIfAbsent (player , k -> new ObjectOpenHashSet <>(1024 ));
898+ cubes .add (cube );
898899 }
899900
900901 public void removeSchedulesSendCubeToPlayer (Cube cube , EntityPlayerMP player ) {
0 commit comments