🔥🎵I'M NOT A BIG FAN OF PAPER🎵🔥
This commit is contained in:
@@ -14,14 +14,15 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
package net.gensokyoreimagined.nitori.access;
|
package net.gensokyoreimagined.nitori.access;
|
||||||
|
|
||||||
import com.destroystokyo.paper.util.misc.PooledLinkedHashSets;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface IMixinChunkMap_TrackedEntityAccess {
|
public interface IMixinChunkMap_TrackedEntityAccess {
|
||||||
@SuppressWarnings("EmptyMethod")
|
@SuppressWarnings("EmptyMethod")
|
||||||
Entity getEntity();
|
Entity getEntity();
|
||||||
|
|
||||||
@SuppressWarnings("EmptyMethod")
|
@SuppressWarnings("EmptyMethod")
|
||||||
void callUpdatePlayers(PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates);
|
void callUpdatePlayers(List<ServerPlayer> players);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public class BlockStateFlags {
|
|||||||
OVERSIZED_SHAPE = new TrackedBlockStatePredicate(countingFlags.size()) {
|
OVERSIZED_SHAPE = new TrackedBlockStatePredicate(countingFlags.size()) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(BlockState operand) {
|
public boolean test(BlockState operand) {
|
||||||
return operand.shapeExceedsCube();
|
return operand.hasLargeCollisionShape();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
countingFlags.add(OVERSIZED_SHAPE);
|
countingFlags.add(OVERSIZED_SHAPE);
|
||||||
|
|||||||
@@ -94,6 +94,11 @@ public class RandomGeneratorRandom implements BitRandomSource {
|
|||||||
return new RandomGeneratorRandom((long) seed.hashCode() ^ this.seed);
|
return new RandomGeneratorRandom((long) seed.hashCode() ^ this.seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RandomSource fromSeed(long seed) {
|
||||||
|
return new RandomGeneratorRandom(seed ^ this.seed);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@Override
|
@Override
|
||||||
public Random split(long seed) {
|
public Random split(long seed) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
package net.gensokyoreimagined.nitori.mixin;
|
package net.gensokyoreimagined.nitori.mixin;
|
||||||
|
|
||||||
import com.destroystokyo.paper.util.misc.PooledLinkedHashSets;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
|
||||||
@@ -42,6 +42,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -86,13 +87,13 @@ public class ChunkMapMixin implements IMixinChunkMapAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "processTrackQueue", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "newTrackerTick", at = @At("HEAD"), cancellable = true)
|
||||||
private void atProcessTrackQueueHead(CallbackInfo callbackInfo) {
|
private void atProcessTrackQueueHead(CallbackInfo callbackInfo) {
|
||||||
// Implementation of 0107-Multithreaded-Tracker.patch
|
// Implementation of 0107-Multithreaded-Tracker.patch
|
||||||
//TODO: Restore config condition
|
//TODO: Restore config condition
|
||||||
//if (NitoriConfig.enableAsyncEntityTracker) {
|
//if (NitoriConfig.enableAsyncEntityTracker) {
|
||||||
if (this.gensouHacks$multithreadedTracker == null) {
|
if (this.gensouHacks$multithreadedTracker == null) {
|
||||||
this.gensouHacks$multithreadedTracker = new MultithreadedTracker(this.level.chunkSource.entityTickingChunks, this.gensouHacks$trackerMainThreadTasks);
|
this.gensouHacks$multithreadedTracker = new MultithreadedTracker(((ChunkSystemServerLevel) this.level).moonrise$getEntityTickingChunks(), this.gensouHacks$trackerMainThreadTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.gensouHacks$tracking = true;
|
this.gensouHacks$tracking = true;
|
||||||
@@ -132,9 +133,9 @@ public class ChunkMapMixin implements IMixinChunkMapAccess {
|
|||||||
@Override
|
@Override
|
||||||
@Final
|
@Final
|
||||||
@Invoker
|
@Invoker
|
||||||
public abstract void callUpdatePlayers(PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> newTrackerCandidates); // Mirai -> public
|
public abstract void callUpdatePlayers(List<ServerPlayer> players); // Mirai -> public
|
||||||
|
|
||||||
@Redirect(method = "updatePlayers(Lcom/destroystokyo/paper/util/misc/PooledLinkedHashSets$PooledObjectLinkedOpenHashSet;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ChunkMap$TrackedEntity;updatePlayer(Lnet/minecraft/server/level/ServerPlayer;)V"))
|
@Redirect(method = "updatePlayers", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ChunkMap$TrackedEntity;updatePlayer(Lnet/minecraft/server/level/ServerPlayer;)V"))
|
||||||
private void handleCitizensPluginTracking(ChunkMap.TrackedEntity self, ServerPlayer serverPlayer) {
|
private void handleCitizensPluginTracking(ChunkMap.TrackedEntity self, ServerPlayer serverPlayer) {
|
||||||
// Nitori - Citizens tracker must run on the main thread to avoid cyclic wait
|
// Nitori - Citizens tracker must run on the main thread to avoid cyclic wait
|
||||||
if (PluginCompatibilityRegistry.CITIZENS.shouldRedirectToMainThread(self, serverPlayer)) {
|
if (PluginCompatibilityRegistry.CITIZENS.shouldRedirectToMainThread(self, serverPlayer)) {
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
package net.gensokyoreimagined.nitori.mixin;
|
package net.gensokyoreimagined.nitori.mixin;
|
||||||
|
|
||||||
import com.destroystokyo.paper.util.maplist.EntityList;
|
import ca.spottedleaf.moonrise.common.list.EntityList;
|
||||||
import io.papermc.paper.world.ChunkEntitySlices;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices;
|
||||||
import net.gensokyoreimagined.nitori.access.IMixinChunkEntitySlicesAccess;
|
import net.gensokyoreimagined.nitori.access.IMixinChunkEntitySlicesAccess;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
package net.gensokyoreimagined.nitori.mixin;
|
package net.gensokyoreimagined.nitori.mixin;
|
||||||
|
|
||||||
import io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet;
|
import ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet;
|
||||||
import net.gensokyoreimagined.nitori.access.IMixinIteratorSafeOrderedReferenceSetAccess;
|
import net.gensokyoreimagined.nitori.access.IMixinIteratorSafeOrderedReferenceSetAccess;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package net.gensokyoreimagined.nitori.tracker;
|
|||||||
* Ported from Petal, derived from Airplane
|
* Ported from Petal, derived from Airplane
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import ca.spottedleaf.moonrise.common.list.ReferenceList;
|
||||||
|
import ca.spottedleaf.moonrise.common.misc.NearbyPlayers;
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet; //io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet;
|
import ca.spottedleaf.moonrise.common.list.IteratorSafeOrderedReferenceSet; //io.papermc.paper.util.maplist.IteratorSafeOrderedReferenceSet;
|
||||||
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; //io.papermc.paper.world.ChunkEntitySlices;
|
import ca.spottedleaf.moonrise.patches.chunk_system.level.entity.ChunkEntitySlices; //io.papermc.paper.world.ChunkEntitySlices;
|
||||||
@@ -26,9 +28,13 @@ import net.gensokyoreimagined.nitori.access.IMixinChunkMap_TrackedEntityAccess;
|
|||||||
import net.gensokyoreimagined.nitori.access.IMixinIteratorSafeOrderedReferenceSetAccess;
|
import net.gensokyoreimagined.nitori.access.IMixinIteratorSafeOrderedReferenceSetAccess;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.level.ChunkMap;
|
import net.minecraft.server.level.ChunkMap;
|
||||||
|
import net.minecraft.server.level.ServerChunkCache;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.level.chunk.LevelChunk;
|
import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
@@ -47,64 +53,44 @@ public class MultithreadedTracker {
|
|||||||
.setPriority(Thread.NORM_PRIORITY - 2)
|
.setPriority(Thread.NORM_PRIORITY - 2)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
private final IteratorSafeOrderedReferenceSet<LevelChunk> entityTickingChunks;
|
private final ReferenceList<ServerChunkCache.ChunkAndHolder> entityTickingChunks;
|
||||||
private final AtomicInteger taskIndex = new AtomicInteger();
|
private final AtomicInteger taskIndex = new AtomicInteger();
|
||||||
|
|
||||||
private final ConcurrentLinkedQueue<Runnable> mainThreadTasks;
|
private final ConcurrentLinkedQueue<Runnable> mainThreadTasks;
|
||||||
private final AtomicInteger finishedTasks = new AtomicInteger();
|
private final AtomicInteger finishedTasks = new AtomicInteger();
|
||||||
|
|
||||||
public MultithreadedTracker(IteratorSafeOrderedReferenceSet<LevelChunk> entityTickingChunks, ConcurrentLinkedQueue<Runnable> mainThreadTasks) {
|
public MultithreadedTracker(ReferenceList<ServerChunkCache.ChunkAndHolder> entityTickingChunks, ConcurrentLinkedQueue<Runnable> mainThreadTasks) {
|
||||||
this.entityTickingChunks = entityTickingChunks;
|
this.entityTickingChunks = entityTickingChunks;
|
||||||
this.mainThreadTasks = mainThreadTasks;
|
this.mainThreadTasks = mainThreadTasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tick() {
|
public void tick() {
|
||||||
int iterator = this.entityTickingChunks.createRawIterator();
|
this.taskIndex.set(0);
|
||||||
|
this.finishedTasks.set(0);
|
||||||
|
|
||||||
if (iterator == -1) {
|
for (int i = 0; i < parallelism; i++) {
|
||||||
return;
|
trackerExecutor.execute(this::runUpdatePlayers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// start with updating players
|
// start with updating players
|
||||||
try {
|
while (this.taskIndex.get() < this.entityTickingChunks.size()) {
|
||||||
this.taskIndex.set(iterator);
|
this.runMainThreadTasks();
|
||||||
this.finishedTasks.set(0);
|
this.handleChunkUpdates(5); // assist
|
||||||
|
|
||||||
for (int i = 0; i < parallelism; i++) {
|
|
||||||
trackerExecutor.execute(this::runUpdatePlayers);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (this.taskIndex.get() < ((IMixinIteratorSafeOrderedReferenceSetAccess) (Object) this.entityTickingChunks).getListSize()) {
|
|
||||||
this.runMainThreadTasks();
|
|
||||||
this.handleChunkUpdates(5); // assist
|
|
||||||
}
|
|
||||||
|
|
||||||
while (this.finishedTasks.get() != parallelism) {
|
|
||||||
this.runMainThreadTasks();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.runMainThreadTasks(); // finish any remaining tasks
|
|
||||||
} finally {
|
|
||||||
this.entityTickingChunks.finishRawIterator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// then send changes
|
// then send changes
|
||||||
iterator = this.entityTickingChunks.createRawIterator();
|
while (this.finishedTasks.get() != parallelism) {
|
||||||
|
this.runMainThreadTasks();
|
||||||
if (iterator == -1) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
this.runMainThreadTasks(); // finish any remaining tasks
|
||||||
do {
|
|
||||||
LevelChunk chunk = this.entityTickingChunks.rawGet(iterator);
|
|
||||||
|
|
||||||
if (chunk != null) {
|
for (ServerChunkCache.ChunkAndHolder chunkAndHolder : this.entityTickingChunks) {
|
||||||
this.updateChunkEntities(chunk, TrackerStage.SEND_CHANGES);
|
LevelChunk chunk = chunkAndHolder.chunk();
|
||||||
}
|
|
||||||
} while (++iterator < ((IMixinIteratorSafeOrderedReferenceSetAccess) (Object) this.entityTickingChunks).getListSize());
|
if (chunk != null) {
|
||||||
} finally {
|
this.updateChunkEntities(chunk, TrackerStage.SEND_CHANGES);
|
||||||
this.entityTickingChunks.finishRawIterator();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,9 +115,9 @@ public class MultithreadedTracker {
|
|||||||
|
|
||||||
private boolean handleChunkUpdates(int tasks) {
|
private boolean handleChunkUpdates(int tasks) {
|
||||||
int index;
|
int index;
|
||||||
while ((index = this.taskIndex.getAndAdd(tasks)) < ((IMixinIteratorSafeOrderedReferenceSetAccess) (Object) this.entityTickingChunks).getListSize()) {
|
while ((index = this.taskIndex.getAndAdd(tasks)) < this.entityTickingChunks.size()) {
|
||||||
for (int i = index; i < index + tasks && i < ((IMixinIteratorSafeOrderedReferenceSetAccess) (Object) this.entityTickingChunks).getListSize(); i++) {
|
for (int i = index; i < index + tasks && i < this.entityTickingChunks.size(); i++) {
|
||||||
LevelChunk chunk = this.entityTickingChunks.rawGet(i);
|
LevelChunk chunk = this.entityTickingChunks.getChecked(i).chunk();
|
||||||
if (chunk != null) {
|
if (chunk != null) {
|
||||||
try {
|
try {
|
||||||
this.updateChunkEntities(chunk, TrackerStage.UPDATE_PLAYERS);
|
this.updateChunkEntities(chunk, TrackerStage.UPDATE_PLAYERS);
|
||||||
@@ -149,7 +135,7 @@ public class MultithreadedTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateChunkEntities(LevelChunk chunk, TrackerStage trackerStage) {
|
private void updateChunkEntities(LevelChunk chunk, TrackerStage trackerStage) {
|
||||||
final ChunkEntitySlices entitySlices = chunk.level.getEntityLookup().getChunk(chunk.locX, chunk.locZ);
|
final ChunkEntitySlices entitySlices = chunk.level.moonrise$getEntityLookup().getChunk(chunk.locX, chunk.locZ);
|
||||||
if (entitySlices == null) {
|
if (entitySlices == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -165,7 +151,10 @@ public class MultithreadedTracker {
|
|||||||
if (trackerStage == TrackerStage.SEND_CHANGES) {
|
if (trackerStage == TrackerStage.SEND_CHANGES) {
|
||||||
entityTracker.serverEntity.sendChanges();
|
entityTracker.serverEntity.sendChanges();
|
||||||
} else if (trackerStage == TrackerStage.UPDATE_PLAYERS) {
|
} else if (trackerStage == TrackerStage.UPDATE_PLAYERS) {
|
||||||
((IMixinChunkMap_TrackedEntityAccess) (Object) entityTracker).callUpdatePlayers(((IMixinChunkMap_TrackedEntityAccess) (Object) entityTracker).getEntity().getPlayersInTrackRange());
|
ReferenceList<ServerPlayer> nearbyPlayers = chunkMap.level.moonrise$getNearbyPlayers().getChunk(entity.chunkPosition()).getPlayers(NearbyPlayers.NearbyMapType.VIEW_DISTANCE);
|
||||||
|
List<ServerPlayer> nearbyPlayersList = new ArrayList<ServerPlayer>(nearbyPlayers.size()); // intentionally typed as List for requirement clarity
|
||||||
|
nearbyPlayers.forEach(nearbyPlayersList::add);
|
||||||
|
((IMixinChunkMap_TrackedEntityAccess) (Object) entityTracker).callUpdatePlayers(nearbyPlayersList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user