added chunk_loaded event and fixed handling these events on 1.17

This commit is contained in:
gnembon committed 2021-06-26 23:20:13 -03:00
1 parent 7a3ad7f0b8
commit b1b7956ea9
5 files changed
+83 -21

No files matched your search

@@ -12,6 +12,8 @@ import java.util.concurrent.Future;
import java.util.function.IntFunction;
import java.util.stream.Collectors;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ServerTask;
import org.apache.commons.lang3.tuple.Pair;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
@@ -50,6 +52,7 @@ import net.minecraft.world.chunk.WorldChunk;
import net.minecraft.world.storage.RegionFile;
import static carpet.script.CarpetEventServer.Event.CHUNK_GENERATED;
import static carpet.script.CarpetEventServer.Event.CHUNK_LOADED;
@Mixin(ThreadedAnvilChunkStorage.class)
public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implements ThreadedAnvilChunkStorageInterface
@@ -98,22 +101,62 @@ public abstract class ThreadedAnvilChunkStorage_scarpetChunkCreationMixin implem
@Shadow
protected abstract Iterable<ChunkHolder> entryIterator();
//in method_20617
//method_19534(Lnet/minecraft/server/world/ChunkHolder;Lnet/minecraft/world/chunk/Chunk;)Ljava/util/concurrent/CompletableFuture;
// incmopatibility with optifine makes this mixin fail.
// lambda for convertToFullChunk
ThreadLocal<Boolean> generated = ThreadLocal.withInitial(() -> null);
// in convertToFullChunk
// fancier version of the one below, ensuring that the event is triggered when the chunk is actually loaded.
@SuppressWarnings("UnresolvedMixinReference")
@Inject(method = "method_19534", require = 0, at = @At(
value = "INVOKE",
target = "Lnet/minecraft/server/world/ThreadedAnvilChunkStorage;convertToFullChunk(Lnet/minecraft/server/world/ChunkHolder;)Ljava/util/concurrent/CompletableFuture;",
shift = At.Shift.AFTER
))
private void onChunkGenerated(final ChunkHolder chunkHolder, final Chunk chunk, final CallbackInfoReturnable<CompletableFuture> cir)
@Inject(method = "method_20460", at = @At("HEAD"))
private void onChunkGeneratedStart(ChunkHolder chunkHolder, Either<Chunk, Unloaded> chunk, CallbackInfoReturnable<CompletableFuture<Either<Chunk, Unloaded>>> cir)
{
if (CHUNK_GENERATED.isNeeded())
this.world.getServer().execute(() -> CHUNK_GENERATED.onChunkGenerated(this.world, chunk));
if (CHUNK_GENERATED.isNeeded() || CHUNK_LOADED.isNeeded())
{
generated.set(chunkHolder.getCurrentChunk().getStatus() != ChunkStatus.FULL);
}
else
{
generated.set(null);
}
}
@SuppressWarnings("UnresolvedMixinReference")
@Inject(method = "method_20460", at = @At("RETURN"))
private void onChunkGeneratedEnd(ChunkHolder chunkHolder, Either<Chunk, Unloaded> chunk, CallbackInfoReturnable<CompletableFuture<Either<Chunk, Unloaded>>> cir)
{
Boolean localGenerated= generated.get();
if (localGenerated != null)
{
MinecraftServer server = this.world.getServer();
int ticks = server.getTicks();
ChunkPos chpos = chunkHolder.getPos();
// need to send these because if an app does something with that event, it may lock the thread
// so better be safe and schedule it for later, aSaP
if (CHUNK_GENERATED.isNeeded() && localGenerated)
server.send(new ServerTask(ticks, () -> CHUNK_GENERATED.onChunkEvent(this.world, chpos, true)));
if (CHUNK_LOADED.isNeeded())
server.send(new ServerTask(ticks, () -> CHUNK_LOADED.onChunkEvent(this.world, chpos, localGenerated)));
}
}
/* simple but a version that doesn't guarantee that the chunk is actually loaded
@Inject(method = "convertToFullChunk", at = @At("HEAD"))
private void onChunkGeneratedEnd(ChunkHolder chunkHolder, CallbackInfoReturnable<CompletableFuture<Either<Chunk, Unloaded>>> cir)
{
if (CHUNK_GENERATED.isNeeded() && chunkHolder.getCurrentChunk().getStatus() != ChunkStatus.FULL)
{
ChunkPos chpos = chunkHolder.getPos();
this.world.getServer().execute(() -> CHUNK_GENERATED.onChunkEvent(this.world, chpos, true));
}
if (CHUNK_LOADED.isNeeded())
{
boolean generated = chunkHolder.getCurrentChunk().getStatus() != ChunkStatus.FULL;
ChunkPos chpos = chunkHolder.getPos();
this.world.getServer().execute(() -> CHUNK_LOADED.onChunkEvent(this.world, chpos, generated));
}
}
*/
@Unique
private void addTicket(final ChunkPos pos, final ChunkStatus status)
{ // UNKNOWN