From dc45b32dfff4e243743bc8923a7a4d612af85694 Mon Sep 17 00:00:00 2001 From: rootEnginear Date: Thu, 7 Dec 2023 04:00:48 +0700 Subject: [PATCH] feat: first proto --- .../playground/mixin/ChunkProviderMixin.java | 47 +++++++++++++++++++ .../mixin/NetServerHandlerMixin.java | 28 +++++++++++ .../accessor/ChunkProviderServerInvoker.java | 12 +++++ src/main/resources/playground.mixins.json | 19 ++++---- 4 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 src/main/java/rootenginear/playground/mixin/ChunkProviderMixin.java create mode 100644 src/main/java/rootenginear/playground/mixin/NetServerHandlerMixin.java create mode 100644 src/main/java/rootenginear/playground/mixin/accessor/ChunkProviderServerInvoker.java diff --git a/src/main/java/rootenginear/playground/mixin/ChunkProviderMixin.java b/src/main/java/rootenginear/playground/mixin/ChunkProviderMixin.java new file mode 100644 index 0000000..f55eb74 --- /dev/null +++ b/src/main/java/rootenginear/playground/mixin/ChunkProviderMixin.java @@ -0,0 +1,47 @@ +package rootenginear.playground.mixin; + +import net.minecraft.core.world.chunk.Chunk; +import net.minecraft.server.world.WorldServer; +import net.minecraft.server.world.chunk.provider.ChunkProviderServer; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import rootenginear.playground.mixin.accessor.ChunkProviderServerInvoker; + +import java.io.FileOutputStream; +import java.io.IOException; + +@Mixin(value = ChunkProviderServer.class, remap = false) +public abstract class ChunkProviderMixin { + @Shadow + @Final + private WorldServer world; + + @Redirect(method = "prepareChunk", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/chunk/provider/ChunkProviderServer;loadChunkFromFile(II)Lnet/minecraft/core/world/chunk/Chunk;")) + private Chunk readTopOpaqueBlockData(ChunkProviderServer cps, int chunkX, int chunkZ) throws IOException { + Chunk chunk = ((ChunkProviderServerInvoker) cps).invokeLoadChunkFromFile(chunkX, chunkZ); + if (chunk == null) return null; + if (this.world.dimension.id == 0) { + try (FileOutputStream chunkData = new FileOutputStream(String.format("livemap/chunks/%d.%d.txt", chunkX, chunkZ))) { + for (int shiftZ = 0; shiftZ < 16; shiftZ++) { + for (int shiftX = 0; shiftX < 16; shiftX++) { + short blockData = 0; + for (int y = chunk.getHeightValue(shiftX, shiftZ); y > -1; y--) { + int blockId = chunk.getBlockID(shiftX, y, shiftZ); + if (blockId != 0) { + int metadata = chunk.getBlockMetadata(shiftX, y, shiftZ); + blockData = (short) ((blockId & 0x3FF) | ((metadata & 0xF) << 10)); + break; + } + } + chunkData.write(blockData & 0xFF); + chunkData.write((blockData >> 8) & 0xFF); + } + } + } + } + return chunk; + } +} diff --git a/src/main/java/rootenginear/playground/mixin/NetServerHandlerMixin.java b/src/main/java/rootenginear/playground/mixin/NetServerHandlerMixin.java new file mode 100644 index 0000000..be370e6 --- /dev/null +++ b/src/main/java/rootenginear/playground/mixin/NetServerHandlerMixin.java @@ -0,0 +1,28 @@ +package rootenginear.playground.mixin; + +import net.minecraft.core.net.packet.Packet10Flying; +import net.minecraft.server.entity.player.EntityPlayerMP; +import net.minecraft.server.net.handler.NetServerHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.io.FileWriter; +import java.io.IOException; + +@Mixin(value = NetServerHandler.class, remap = false) +public class NetServerHandlerMixin { + @Shadow + private EntityPlayerMP playerEntity; + + @Inject(method = "handleFlying", at = @At("HEAD")) + private void trackLocation(Packet10Flying packet, CallbackInfo ci) throws IOException { + if (packet.moving) { + try (FileWriter chunkData = new FileWriter(String.format("livemap/players/%s.txt", this.playerEntity.username))) { + chunkData.write(String.format("%f %f", this.playerEntity.x, this.playerEntity.z)); + } + } + } +} diff --git a/src/main/java/rootenginear/playground/mixin/accessor/ChunkProviderServerInvoker.java b/src/main/java/rootenginear/playground/mixin/accessor/ChunkProviderServerInvoker.java new file mode 100644 index 0000000..c932ee4 --- /dev/null +++ b/src/main/java/rootenginear/playground/mixin/accessor/ChunkProviderServerInvoker.java @@ -0,0 +1,12 @@ +package rootenginear.playground.mixin.accessor; + +import net.minecraft.core.world.chunk.Chunk; +import net.minecraft.server.world.chunk.provider.ChunkProviderServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(value = ChunkProviderServer.class, remap = false) +public interface ChunkProviderServerInvoker { + @Invoker("loadChunkFromFile") + Chunk invokeLoadChunkFromFile(int chunkX, int chunkZ); +} diff --git a/src/main/resources/playground.mixins.json b/src/main/resources/playground.mixins.json index 97606d0..d91bdbf 100644 --- a/src/main/resources/playground.mixins.json +++ b/src/main/resources/playground.mixins.json @@ -1,11 +1,14 @@ { - "required": true, - "minVersion": "0.8", - "package": "rootenginear.playground.mixin", - "compatibilityLevel": "JAVA_8", - "mixins": [ - ], - "injectors": { - "defaultRequire": 1 + "required": true, + "minVersion": "0.8", + "package": "rootenginear.playground.mixin", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "ChunkProviderMixin", + "NetServerHandlerMixin", + "accessor.ChunkProviderServerInvoker" + ], + "injectors": { + "defaultRequire": 1 } }