diff --git a/build.gradle.kts b/build.gradle.kts index 0d20468..b8110fa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -51,9 +51,13 @@ minecraft_fp { } repositories { + cursemavenEX() exclusive(maven("mavenpattern", "https://mvn.falsepattern.com/releases/"), "com.falsepattern") } dependencies { apiSplit("com.falsepattern:falsepatternlib-mc1.7.10:1.5.9") + + //LookingGlass 0.2.0.01 + compileOnly(deobfCurse("lookingglass-230541:2321557")) } \ No newline at end of file diff --git a/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/lookingglass/PacketChunkInfoMixin.java b/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/lookingglass/PacketChunkInfoMixin.java new file mode 100644 index 0000000..21a83a6 --- /dev/null +++ b/src/main/java/com/falsepattern/chunk/internal/mixin/mixins/common/lookingglass/PacketChunkInfoMixin.java @@ -0,0 +1,113 @@ +/* + * ChunkAPI + * + * Copyright (C) 2023-2025 FalsePattern, The MEGA Team, LegacyModdingMC contributors + * All Rights Reserved + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, only version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.falsepattern.chunk.internal.mixin.mixins.common.lookingglass; + +import com.xcompwiz.lookingglass.log.LoggerUtils; +import com.xcompwiz.lookingglass.network.LookingGlassPacketManager; +import com.xcompwiz.lookingglass.network.packet.PacketChunkInfo; +import com.xcompwiz.lookingglass.network.packet.PacketHandlerBase; +import com.xcompwiz.lookingglass.network.packet.PacketRequestChunk; +import io.netty.buffer.ByteBuf; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.network.play.server.S21PacketChunkData; +import net.minecraft.world.chunk.Chunk; +import cpw.mods.fml.common.network.internal.FMLProxyPacket; + +import java.util.concurrent.Semaphore; + +@Mixin(PacketChunkInfo.class) +public abstract class PacketChunkInfoMixin extends PacketHandlerBase { + @Shadow(remap = false) private static Semaphore deflateGate; + + @Shadow(remap = false) + private static int deflate(byte[] chunkData, byte[] compressedChunkData) { + return 0; + } + + @Shadow(remap = false) public abstract void handle(EntityPlayer player, byte[] chunkData, int dim, int xPos, int zPos, boolean reqinit, short yPos, short yMSBPos); + + @Shadow(remap = false) protected abstract byte[] inflateChunkData(ByteBuf in, int compressedsize, int uncompressedsize); + + /** + * @author FalsePattern + * @reason This class was just copied vanilla code. + */ + @Overwrite(remap = false) + public static S21PacketChunkData.Extracted getMapChunkData(Chunk chunk, boolean forceUpdate, int subChunkMask) { + return S21PacketChunkData.func_149269_a(chunk, forceUpdate, subChunkMask); + } + + /** + * @author FalsePattern + * @reason Wired up to ChunkAPI + */ + @Overwrite(remap = false) + public static FMLProxyPacket createPacket(Chunk chunk, boolean forceUpdate, int subChunkMask, int dim) { + int xPos = chunk.xPosition; + int zPos = chunk.zPosition; + S21PacketChunkData.Extracted extracted = getMapChunkData(chunk, forceUpdate, subChunkMask); + int realSubChunkMask = extracted.field_150280_b; + byte[] chunkData = extracted.field_150282_a; + deflateGate.acquireUninterruptibly(); + byte[] compressedChunkData = new byte[chunkData.length]; + int len = deflate(chunkData, compressedChunkData); + deflateGate.release(); + ByteBuf data = PacketHandlerBase.createDataBuffer(PacketChunkInfo.class); + data.writeInt(dim); + data.writeInt(xPos); + data.writeInt(zPos); + data.writeBoolean(forceUpdate); + data.writeShort((short)(realSubChunkMask & 0xFFFF)); + data.writeInt(len); + data.writeInt(chunkData.length); + data.ensureWritable(len); + data.writeBytes(compressedChunkData, 0, len); + return buildPacket(data); + } + + /** + * @author FalsePattern + * @reason Wired up to ChunkAPI + */ + @Overwrite(remap = false) + public void handle(ByteBuf in, EntityPlayer player) { + int dim = in.readInt(); + int xPos = in.readInt(); + int zPos = in.readInt(); + boolean forceUpdate = in.readBoolean(); + int subChunkMask = in.readShort() & 0xFFFF; + int compressedSize = in.readInt(); + int uncompressedSize = in.readInt(); + byte[] chunkData = this.inflateChunkData(in, compressedSize, uncompressedSize); + if (chunkData == null) { + LookingGlassPacketManager.bus.sendToServer(PacketRequestChunk.createPacket(xPos, subChunkMask, zPos, dim)); + LoggerUtils.error("Chunk decompression failed: \t%d\t\t%d : %d\n", subChunkMask, compressedSize, uncompressedSize); + } else { + this.handle(player, chunkData, dim, xPos, zPos, forceUpdate, (short) subChunkMask, (short)0); + } + } +} diff --git a/src/main/java/com/falsepattern/chunk/internal/mixin/plugin/Mixin.java b/src/main/java/com/falsepattern/chunk/internal/mixin/plugin/Mixin.java index 2675837..213b23a 100644 --- a/src/main/java/com/falsepattern/chunk/internal/mixin/plugin/Mixin.java +++ b/src/main/java/com/falsepattern/chunk/internal/mixin/plugin/Mixin.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.function.Predicate; import static com.falsepattern.lib.mixin.IMixin.PredicateHelpers.always; +import static com.falsepattern.lib.mixin.IMixin.PredicateHelpers.require; @RequiredArgsConstructor public enum Mixin implements IMixin { @@ -44,6 +45,10 @@ public enum Mixin implements IMixin { ChunkMixin(Side.CLIENT, always(), "vanilla.ChunkMixin"), NetHandlerPlayClientMixin(Side.CLIENT, always(), "vanilla.NetHandlerPlayClientMixin"), + + //region Looking Glass + PacketChunkInfoMixin(Side.COMMON, require(TargetedMod.LOOKINGGLASS), "lookingglass.PacketChunkInfoMixin"), + //endregion ; // @formatter:on diff --git a/src/main/java/com/falsepattern/chunk/internal/mixin/plugin/TargetedMod.java b/src/main/java/com/falsepattern/chunk/internal/mixin/plugin/TargetedMod.java index db012df..49b0f1b 100644 --- a/src/main/java/com/falsepattern/chunk/internal/mixin/plugin/TargetedMod.java +++ b/src/main/java/com/falsepattern/chunk/internal/mixin/plugin/TargetedMod.java @@ -28,8 +28,11 @@ import lombok.RequiredArgsConstructor; import java.util.function.Predicate; +import static com.falsepattern.lib.mixin.ITargetedMod.PredicateHelpers.contains; + @RequiredArgsConstructor public enum TargetedMod implements ITargetedMod { + LOOKINGGLASS("Looking Glass", false, contains("lookingglass-")) ; @Getter