diff --git a/build.gradle.kts b/build.gradle.kts index 59b52c7..48b204e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,6 +17,7 @@ minecraft_fp { core { coreModClass = "asm.EndlessIDsCore" + accessTransformerFile = "endlessids_at.cfg" } tokens { diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/biome/galaxyspace/ChunkProviderSpaceLakesGTNHMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/biome/galaxyspace/ChunkProviderSpaceLakesGTNHMixin.java new file mode 100644 index 0000000..6986df2 --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/biome/galaxyspace/ChunkProviderSpaceLakesGTNHMixin.java @@ -0,0 +1,63 @@ +/* + * EndlessIDs + * + * Copyright (C) 2022-2025 FalsePattern, The MEGA Team + * Copyright (C) 2025 Cardinalstar16 + * All Rights Reserved + * + * The above copyright notice, this permission notice and the word "MEGA" + * 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.endlessids.mixin.mixins.common.biome.galaxyspace; + +import com.falsepattern.endlessids.mixin.helpers.BiomePatchHelper; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +import net.minecraft.world.World; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.gen.ChunkProviderGenerate; + +@Pseudo +@Mixin(targets = "galaxyspace.core.dimension.ChunkProviderSpaceLakes", + remap = false) + +public abstract class ChunkProviderSpaceLakesGTNHMixin extends ChunkProviderGenerate +{ + + public ChunkProviderSpaceLakesGTNHMixin(World p_i2006_1_, long p_i2006_2_, boolean p_i2006_4_) { + super(p_i2006_1_, p_i2006_2_, p_i2006_4_); + } + + /** + * @author Cardinalstar16 + * @reason The Galaxy-space mod maintained by GTNH has a different class layout than + * non-GTNH versions of galaxy space. More importantly, biomesForGeneration is AT'd to be protected, + * but cannot be shadowed due to the fact that private members aren't in the byte code of the + * children classes (from what I understand). + */ + @SuppressWarnings("UnresolvedMixinReference") + @Redirect(method = "func_73154_d", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/chunk/Chunk;func_76605_m()[B"), + require = 0, + expect = 0) + private byte[] setBiomesTweaked(Chunk chunk) { + return BiomePatchHelper.getBiomeArrayTweaked(chunk, biomesForGeneration); + } +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/BlockFireMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/BlockFireMixin.java similarity index 99% rename from src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/BlockFireMixin.java rename to src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/BlockFireMixin.java index 75d5215..868428e 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/BlockFireMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/BlockFireMixin.java @@ -20,7 +20,7 @@ * along with this program. If not, see . */ -package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla; +package com.falsepattern.endlessids.mixin.mixins.common.blockitem.common; import com.falsepattern.endlessids.constants.ExtendedConstants; import com.falsepattern.endlessids.constants.VanillaConstants; diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/BlockMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/BlockMixin.java similarity index 99% rename from src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/BlockMixin.java rename to src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/BlockMixin.java index e199ea8..f9e4c0e 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/BlockMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/BlockMixin.java @@ -20,7 +20,7 @@ * along with this program. If not, see . */ -package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla; +package com.falsepattern.endlessids.mixin.mixins.common.blockitem.common; import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/ExtendedBlockStorageMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/ExtendedBlockStorageMixin.java new file mode 100644 index 0000000..2d23efe --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/ExtendedBlockStorageMixin.java @@ -0,0 +1,368 @@ +/* + * EndlessIDs + * + * Copyright (C) 2022-2025 FalsePattern, The MEGA Team + * All Rights Reserved + * + * The above copyright notice, this permission notice and the words "MEGA" + * 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.endlessids.mixin.mixins.common.blockitem.common; + +import com.falsepattern.endlessids.EndlessIDs; +import com.falsepattern.endlessids.Hooks; +import com.falsepattern.endlessids.Tags; +import com.falsepattern.endlessids.config.GeneralConfig; +import com.falsepattern.endlessids.mixin.helpers.SubChunkBlockHook; +import lombok.val; +import lombok.var; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.world.chunk.NibbleArray; +import net.minecraft.world.chunk.storage.ExtendedBlockStorage; + +import static com.falsepattern.endlessids.constants.ExtendedConstants.blocksPerSubChunk; + +@Mixin(ExtendedBlockStorage.class) +public abstract class ExtendedBlockStorageMixin implements SubChunkBlockHook { + @Shadow + private int blockRefCount; + @Shadow + private int tickRefCount; + + @Shadow + private byte[] blockLSBArray; + @Shadow + private NibbleArray blockMSBArray; + private NibbleArray b2High; + private byte[] b3; + + @Shadow + private NibbleArray blockMetadataArray; + private NibbleArray m1High; + private byte[] m2; + + public int eid$getID(int x, int y, int z) { + int index = y << 8 | z << 4 | x; + int id = blockLSBArray[index] & 0xFF; + if (blockMSBArray != null) { + id |= blockMSBArray.get(x, y, z) << 8; + if (b2High != null) { + id |= b2High.get(x, y, z) << 12; + if (b3 != null) { + id |= (b3[index] & 0xFF) << 16; + } + } + } + return id; + } + + public void eid$setID(int x, int y, int z, int id) { + int index = y << 8 | z << 4 | x; + blockLSBArray[index] = (byte) (id & 0xFF); + if (id > 0xFF) { + if (blockMSBArray == null) { + eid$createB2Low(); + } + if (id > 0xFFF) { + if (b2High == null) { + eid$createB2High(); + } + if (id > 0xFFFF && b3 == null) { + eid$createB3(); + } + } + } + if (blockMSBArray != null) { + blockMSBArray.set(x, y, z, (id >>> 8) & 0xF); + if (b2High != null) { + b2High.set(x, y, z, (id >>> 12) & 0xF); + if (b3 != null) { + b3[index] = (byte) ((id >>> 16) & 0xFF); + } + } + } + } + + /** + * @author FalsePattern + * @reason Direct port from dumped code + */ + @Overwrite + public Block getBlockByExtId(int x, int y, int z) { + return Block.getBlockById(eid$getID(x, y, z)); + } + + /** + * @author FalsePattern + * @reason Direct port from dumped code + */ + @Overwrite + public void func_150818_a(int x, int y, int z, Block newBlock) { + Block oldBlock = this.getBlockByExtId(x, y, z); + if (oldBlock != Blocks.air) { + --this.blockRefCount; + if (oldBlock.getTickRandomly()) { + --this.tickRefCount; + } + } + + if (newBlock != Blocks.air) { + ++this.blockRefCount; + if (newBlock.getTickRandomly()) { + ++this.tickRefCount; + } + } + + int blockID = Hooks.getIdFromBlockWithCheck(newBlock, oldBlock); + eid$setID(x, y, z, blockID); + } + + /** + * @author FalsePattern + * @reason meta ID extension + */ + @Overwrite + public int getExtBlockMetadata(int x, int y, int z) { + int meta = blockMetadataArray.get(x, y, z); + if (m1High != null) { + meta |= m1High.get(x, y, z) << 4; + if (m2 != null) { + meta |= (m2[(y << 8) | (z << 4) | x] & 0xFF) << 8; + } + } + return meta; + } + + /** + * @author FalsePattern + * @reason meta ID extension + */ + @Overwrite + public void setExtBlockMetadata(int x, int y, int z, int meta) { + blockMetadataArray.set(x, y, z, meta & 0xF); + if (meta > 0xF) { + if (m1High == null) { + eid$createM1High(); + } + if (meta > 0xFF && m2 == null) { + eid$createM2(); + } + } + if (m1High != null) { + m1High.set(x, y, z, (meta >>> 4) & 0xF); + if (m2 != null) { + m2[(y << 8) | (z << 4) | x] = (byte) ((meta >>> 8) & 0xFF); + } + } + } + + @Override + public int eid$getMetadata(int x, int y, int z) { + return getExtBlockMetadata(x, y, z); + } + + @Override + public void eid$setMetadata(int x, int y, int z, int id) { + setExtBlockMetadata(x, y, z, id); + } + + private UnsupportedOperationException emergencyCrash() { + val crashMSG = "A mod that is incompatible with " + Tags.MODNAME + " has tried to access the block array of a" + + " chunk like in vanilla! Crashing in fear of potential world corruption!\n" + + "Please report this issue on https://github.com/GTMEGA/EndlessIDs ASAP!"; + EndlessIDs.LOG.fatal(crashMSG); + return new UnsupportedOperationException(crashMSG); + } + + @Override + public byte[] eid$getB1() { + return blockLSBArray; + } + + @Override + public void eid$setB1(byte[] data) { + blockLSBArray = data; + } + + @Override + public NibbleArray eid$getB2Low() { + return blockMSBArray; + } + + @Override + public void eid$setB2Low(NibbleArray data) { + blockMSBArray = data; + } + + @Override + public NibbleArray eid$createB2Low() { + return (blockMSBArray = new NibbleArray(blocksPerSubChunk, 4)); + } + + @Override + public NibbleArray eid$getB2High() { + return b2High; + } + + @Override + public void eid$setB2High(NibbleArray data) { + b2High = data; + } + + @Override + public NibbleArray eid$createB2High() { + return (b2High = new NibbleArray(blocksPerSubChunk, 4)); + } + + @Override + public byte[] eid$getB3() { + return b3; + } + + @Override + public void eid$setB3(byte[] data) { + b3 = data; + } + + @Override + public byte[] eid$createB3() { + return b3 = new byte[blocksPerSubChunk]; + } + + @Override + public NibbleArray eid$getM1Low() { + return blockMetadataArray; + } + + @Override + public void eid$setM1Low(NibbleArray m1Low) { + blockMetadataArray = m1Low; + } + + @Override + public NibbleArray eid$getM1High() { + return m1High; + } + + @Override + public void eid$setM1High(NibbleArray m1High) { + this.m1High = m1High; + } + + @Override + public NibbleArray eid$createM1High() { + return (m1High = new NibbleArray(blocksPerSubChunk, 4)); + } + + @Override + public byte[] eid$getM2() { + return m2; + } + + @Override + public void eid$setM2(byte[] m2) { + this.m2 = m2; + } + + @Override + public byte[] eid$createM2() { + return (m2 = new byte[blocksPerSubChunk]); + } + + @Override + public int eid$getBlockMask() { + if (blockMSBArray == null) { + return 0b00; + } + if (b2High == null) { + return 0b01; + } + if (b3 == null) { + return 0b10; + } + return 0b11; + } + + @Override + public int eid$getMetadataMask() { + if (m1High == null) { + return 0b01; + } + if (m2 == null) { + return 0b10; + } + return 0b11; + } + + @Inject(method = {"getBlockMSBArray", "createBlockMSBArray"}, + at = @At("HEAD"), + expect = 0) + private void crashMSBArray(CallbackInfoReturnable cir) { + throw emergencyCrash(); + } + + @Inject(method = "clearMSBArray", + at = @At("HEAD"), + expect = 0) + private void crashMSBArray(CallbackInfo ci) { + throw emergencyCrash(); + } + + @Inject(method = "setBlockMSBArray", + at = @At("HEAD"), + expect = 0) + private void crashMSBArray(NibbleArray p_76673_1_, CallbackInfo ci) { + throw emergencyCrash(); + } + + @Inject(method = "setBlockLSBArray", + at = @At("HEAD"), + expect = 0) + private void crashLSBArray(byte[] p_76664_1_, CallbackInfo ci) { + throw emergencyCrash(); + } + + @Inject(method = "getBlockLSBArray", + at = @At("HEAD"), + expect = 0) + private void crashLSBArray(CallbackInfoReturnable cir) { + throw emergencyCrash(); + } + + @Inject(method = "setBlockMetadataArray", + at = @At("HEAD"), + expect = 0) + private void crashMetadataArray(NibbleArray p_76668_1_, CallbackInfo ci) { + throw emergencyCrash(); + } + + @Inject(method = "getMetadataArray", + at = @At("HEAD"), + expect = 0) + private void crashMetadataArray(CallbackInfoReturnable cir) { + throw emergencyCrash(); + } +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/ItemInWorldManagerMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/ItemInWorldManagerMixin.java similarity index 99% rename from src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/ItemInWorldManagerMixin.java rename to src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/ItemInWorldManagerMixin.java index daf8092..4b2425f 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/ItemInWorldManagerMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/ItemInWorldManagerMixin.java @@ -20,7 +20,7 @@ * along with this program. If not, see . */ -package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla; +package com.falsepattern.endlessids.mixin.mixins.common.blockitem.common; import com.falsepattern.endlessids.constants.ExtendedConstants; import com.falsepattern.endlessids.constants.VanillaConstants; diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/ItemStackMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/ItemStackMixin.java similarity index 97% rename from src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/ItemStackMixin.java rename to src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/ItemStackMixin.java index e806f8e..d50d7b5 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/ItemStackMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/ItemStackMixin.java @@ -20,9 +20,8 @@ * along with this program. If not, see . */ -package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla; +package com.falsepattern.endlessids.mixin.mixins.common.blockitem.common; -import com.falsepattern.endlessids.constants.VanillaConstants; import com.falsepattern.endlessids.util.DataUtil; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/PacketBufferMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/PacketBufferMixin.java similarity index 99% rename from src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/PacketBufferMixin.java rename to src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/PacketBufferMixin.java index 50ca213..dbc0758 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/PacketBufferMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/PacketBufferMixin.java @@ -20,7 +20,7 @@ * along with this program. If not, see . */ -package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla; +package com.falsepattern.endlessids.mixin.mixins.common.blockitem.common; import io.netty.buffer.ByteBuf; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/S22PacketMultiBlockChangeMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/S22PacketMultiBlockChangeMixin.java similarity index 99% rename from src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/S22PacketMultiBlockChangeMixin.java rename to src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/S22PacketMultiBlockChangeMixin.java index 023ed94..184e91b 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/S22PacketMultiBlockChangeMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/S22PacketMultiBlockChangeMixin.java @@ -20,7 +20,7 @@ * along with this program. If not, see . */ -package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla; +package com.falsepattern.endlessids.mixin.mixins.common.blockitem.common; import com.falsepattern.endlessids.constants.ExtendedConstants; import com.falsepattern.endlessids.constants.VanillaConstants; diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/S24PacketBlockActionMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/S24PacketBlockActionMixin.java similarity index 99% rename from src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/S24PacketBlockActionMixin.java rename to src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/S24PacketBlockActionMixin.java index 6a63749..757a011 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/S24PacketBlockActionMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/S24PacketBlockActionMixin.java @@ -20,7 +20,7 @@ * along with this program. If not, see . */ -package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla; +package com.falsepattern.endlessids.mixin.mixins.common.blockitem.common; import com.falsepattern.endlessids.constants.ExtendedConstants; import com.falsepattern.endlessids.constants.VanillaConstants; diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/StatListMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/StatListMixin.java similarity index 99% rename from src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/StatListMixin.java rename to src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/StatListMixin.java index b84c93d..10d8802 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/StatListMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/StatListMixin.java @@ -20,7 +20,7 @@ * along with this program. If not, see . */ -package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla; +package com.falsepattern.endlessids.mixin.mixins.common.blockitem.common; import com.falsepattern.endlessids.constants.ExtendedConstants; import com.falsepattern.endlessids.constants.VanillaConstants; diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/WorldMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/WorldMixin.java similarity index 99% rename from src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/WorldMixin.java rename to src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/WorldMixin.java index 18444b9..edc2be7 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/WorldMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/common/WorldMixin.java @@ -20,7 +20,7 @@ * along with this program. If not, see . */ -package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla; +package com.falsepattern.endlessids.mixin.mixins.common.blockitem.common; import com.falsepattern.endlessids.constants.ExtendedConstants; import com.falsepattern.endlessids.constants.VanillaConstants; diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/thermos/NibbleArrayMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/thermos/NibbleArrayMixin.java new file mode 100644 index 0000000..984c717 --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/thermos/NibbleArrayMixin.java @@ -0,0 +1,86 @@ +/* + * EndlessIDs + * + * Copyright (C) 2022-2025 FalsePattern, The MEGA Team + * Copyright (C) 2025 Cardinalstar16 + * All Rights Reserved + * + * The above copyright notice, this permission notice and the word "MEGA" + * 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.endlessids.mixin.mixins.common.blockitem.thermos; + +import org.spongepowered.asm.lib.Opcodes; +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 net.minecraft.world.chunk.NibbleArray; + +@Mixin(NibbleArray.class) +public class NibbleArrayMixin { + + @Shadow + public byte[] data; // Thermos renamed 'data' + @Shadow private int depthBits; // depthBits + @Shadow private int depthBitsPlusFour; // depthBitsPlusFour + + @SuppressWarnings("MixinAnnotationTarget") + @Shadow private int length; + @SuppressWarnings("MixinAnnotationTarget") + @Shadow private byte trivialByte; + @SuppressWarnings("MixinAnnotationTarget") + @Shadow private byte trivialValue; + + /** + * @author Cardinalstar16 + * @reason Thermos compat. + * Thermos thinks it's a good idea to nullify some nibble array members if they are a + * "Trivial array". Just disable this functionality if we detect thermos. + */ + @SuppressWarnings("MixinAnnotationTarget") + @Inject( + method = "detectAndProcessTrivialArray", + at = @At( + value = "FIELD", + opcode = Opcodes.PUTFIELD, + target = "Lnet/minecraft/world/chunk/NibbleArray;data:[B", + shift = At.Shift.BEFORE + ), + cancellable = true) + private void logBeforeNull(CallbackInfo ci) { + ci.cancel(); + } + + /** + * @author Cardinalstar16 + * @reason Thermos compat. + * Thermos thinks it's a good idea to nullify some nibble array members if they are a + * "Trivial array". Just disable this functionality if we detect thermos. + */ + @Inject(method = "(II)V", at = @At("RETURN")) + private void fixConstructor(int par1, int par2, CallbackInfo ci) { + this.data = new byte[par1 >> 1]; + this.depthBits = par2; + this.depthBitsPlusFour = par2 + 4; + this.length = par1 >> 1; + this.trivialValue = 0; + this.trivialByte = 0; + } + +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/ExtendedBlockStorageMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/ExtendedBlockStorageMixin.java index e7906de..8ccddad 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/ExtendedBlockStorageMixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/blockitem/vanilla/ExtendedBlockStorageMixin.java @@ -22,173 +22,25 @@ package com.falsepattern.endlessids.mixin.mixins.common.blockitem.vanilla; -import com.falsepattern.endlessids.EndlessIDs; -import com.falsepattern.endlessids.Hooks; -import com.falsepattern.endlessids.Tags; import com.falsepattern.endlessids.config.GeneralConfig; -import com.falsepattern.endlessids.mixin.helpers.SubChunkBlockHook; -import lombok.val; import lombok.var; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import net.minecraft.block.Block; import net.minecraft.init.Blocks; -import net.minecraft.world.chunk.NibbleArray; import net.minecraft.world.chunk.storage.ExtendedBlockStorage; -import static com.falsepattern.endlessids.constants.ExtendedConstants.blocksPerSubChunk; - @Mixin(ExtendedBlockStorage.class) -public abstract class ExtendedBlockStorageMixin implements SubChunkBlockHook { - @Shadow - private int blockRefCount; - @Shadow - private int tickRefCount; - - @Shadow - private byte[] blockLSBArray; - @Shadow - private NibbleArray blockMSBArray; - private NibbleArray b2High; - private byte[] b3; - - @Shadow - private NibbleArray blockMetadataArray; - private NibbleArray m1High; - private byte[] m2; - - public int eid$getID(int x, int y, int z) { - int index = y << 8 | z << 4 | x; - int id = blockLSBArray[index] & 0xFF; - if (blockMSBArray != null) { - id |= blockMSBArray.get(x, y, z) << 8; - if (b2High != null) { - id |= b2High.get(x, y, z) << 12; - if (b3 != null) { - id |= (b3[index] & 0xFF) << 16; - } - } - } - return id; - } - - public void eid$setID(int x, int y, int z, int id) { - int index = y << 8 | z << 4 | x; - blockLSBArray[index] = (byte) (id & 0xFF); - if (id > 0xFF) { - if (blockMSBArray == null) { - eid$createB2Low(); - } - if (id > 0xFFF) { - if (b2High == null) { - eid$createB2High(); - } - if (id > 0xFFFF && b3 == null) { - eid$createB3(); - } - } - } - if (blockMSBArray != null) { - blockMSBArray.set(x, y, z, (id >>> 8) & 0xF); - if (b2High != null) { - b2High.set(x, y, z, (id >>> 12) & 0xF); - if (b3 != null) { - b3[index] = (byte) ((id >>> 16) & 0xFF); - } - } - } - } - - /** - * @author FalsePattern - * @reason Direct port from dumped code - */ - @Overwrite - public Block getBlockByExtId(int x, int y, int z) { - return Block.getBlockById(eid$getID(x, y, z)); - } - - /** - * @author FalsePattern - * @reason Direct port from dumped code - */ - @Overwrite - public void func_150818_a(int x, int y, int z, Block newBlock) { - Block oldBlock = this.getBlockByExtId(x, y, z); - if (oldBlock != Blocks.air) { - --this.blockRefCount; - if (oldBlock.getTickRandomly()) { - --this.tickRefCount; - } - } - - if (newBlock != Blocks.air) { - ++this.blockRefCount; - if (newBlock.getTickRandomly()) { - ++this.tickRefCount; - } - } - - int blockID = Hooks.getIdFromBlockWithCheck(newBlock, oldBlock); - eid$setID(x, y, z, blockID); - } - - /** - * @author FalsePattern - * @reason meta ID extension - */ - @Overwrite - public int getExtBlockMetadata(int x, int y, int z) { - int meta = blockMetadataArray.get(x, y, z); - if (m1High != null) { - meta |= m1High.get(x, y, z) << 4; - if (m2 != null) { - meta |= (m2[(y << 8) | (z << 4) | x] & 0xFF) << 8; - } - } - return meta; - } - +public class ExtendedBlockStorageMixin +{ /** - * @author FalsePattern - * @reason meta ID extension + * @author Cardinalstar16 + * @reason Id Extension + * Thermos does this already, so I just moved this into a mixin that is only loaded if thermos + * is not enabled. */ - @Overwrite - public void setExtBlockMetadata(int x, int y, int z, int meta) { - blockMetadataArray.set(x, y, z, meta & 0xF); - if (meta > 0xF) { - if (m1High == null) { - eid$createM1High(); - } - if (meta > 0xFF && m2 == null) { - eid$createM2(); - } - } - if (m1High != null) { - m1High.set(x, y, z, (meta >>> 4) & 0xF); - if (m2 != null) { - m2[(y << 8) | (z << 4) | x] = (byte) ((meta >>> 8) & 0xFF); - } - } - } - - @Override - public int eid$getMetadata(int x, int y, int z) { - return getExtBlockMetadata(x, y, z); - } - - @Override - public void eid$setMetadata(int x, int y, int z, int id) { - setExtBlockMetadata(x, y, z, id); - } - @Redirect(method = "removeInvalidBlocks", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;getBlockByExtId(III)Lnet/minecraft/block/Block;"), @@ -201,181 +53,4 @@ private Block removeInvalidBlocks(ExtendedBlockStorage instance, int x, int y, i } return block; } - - private UnsupportedOperationException emergencyCrash() { - val crashMSG = "A mod that is incompatible with " + Tags.MODNAME + " has tried to access the block array of a" + - " chunk like in vanilla! Crashing in fear of potential world corruption!\n" + - "Please report this issue on https://github.com/GTMEGA/EndlessIDs ASAP!"; - EndlessIDs.LOG.fatal(crashMSG); - return new UnsupportedOperationException(crashMSG); - } - - @Override - public byte[] eid$getB1() { - return blockLSBArray; - } - - @Override - public void eid$setB1(byte[] data) { - blockLSBArray = data; - } - - @Override - public NibbleArray eid$getB2Low() { - return blockMSBArray; - } - - @Override - public void eid$setB2Low(NibbleArray data) { - blockMSBArray = data; - } - - @Override - public NibbleArray eid$createB2Low() { - return (blockMSBArray = new NibbleArray(blocksPerSubChunk, 4)); - } - - @Override - public NibbleArray eid$getB2High() { - return b2High; - } - - @Override - public void eid$setB2High(NibbleArray data) { - b2High = data; - } - - @Override - public NibbleArray eid$createB2High() { - return (b2High = new NibbleArray(blocksPerSubChunk, 4)); - } - - @Override - public byte[] eid$getB3() { - return b3; - } - - @Override - public void eid$setB3(byte[] data) { - b3 = data; - } - - @Override - public byte[] eid$createB3() { - return b3 = new byte[blocksPerSubChunk]; - } - - @Override - public NibbleArray eid$getM1Low() { - return blockMetadataArray; - } - - @Override - public void eid$setM1Low(NibbleArray m1Low) { - blockMetadataArray = m1Low; - } - - @Override - public NibbleArray eid$getM1High() { - return m1High; - } - - @Override - public void eid$setM1High(NibbleArray m1High) { - this.m1High = m1High; - } - - @Override - public NibbleArray eid$createM1High() { - return (m1High = new NibbleArray(blocksPerSubChunk, 4)); - } - - @Override - public byte[] eid$getM2() { - return m2; - } - - @Override - public void eid$setM2(byte[] m2) { - this.m2 = m2; - } - - @Override - public byte[] eid$createM2() { - return (m2 = new byte[blocksPerSubChunk]); - } - - @Override - public int eid$getBlockMask() { - if (blockMSBArray == null) { - return 0b00; - } - if (b2High == null) { - return 0b01; - } - if (b3 == null) { - return 0b10; - } - return 0b11; - } - - @Override - public int eid$getMetadataMask() { - if (m1High == null) { - return 0b01; - } - if (m2 == null) { - return 0b10; - } - return 0b11; - } - - @Inject(method = {"getBlockMSBArray", "createBlockMSBArray"}, - at = @At("HEAD"), - expect = 0) - private void crashMSBArray(CallbackInfoReturnable cir) { - throw emergencyCrash(); - } - - @Inject(method = "clearMSBArray", - at = @At("HEAD"), - expect = 0) - private void crashMSBArray(CallbackInfo ci) { - throw emergencyCrash(); - } - - @Inject(method = "setBlockMSBArray", - at = @At("HEAD"), - expect = 0) - private void crashMSBArray(NibbleArray p_76673_1_, CallbackInfo ci) { - throw emergencyCrash(); - } - - @Inject(method = "setBlockLSBArray", - at = @At("HEAD"), - expect = 0) - private void crashLSBArray(byte[] p_76664_1_, CallbackInfo ci) { - throw emergencyCrash(); - } - - @Inject(method = "getBlockLSBArray", - at = @At("HEAD"), - expect = 0) - private void crashLSBArray(CallbackInfoReturnable cir) { - throw emergencyCrash(); - } - - @Inject(method = "setBlockMetadataArray", - at = @At("HEAD"), - expect = 0) - private void crashMetadataArray(NibbleArray p_76668_1_, CallbackInfo ci) { - throw emergencyCrash(); - } - - @Inject(method = "getMetadataArray", - at = @At("HEAD"), - expect = 0) - private void crashMetadataArray(CallbackInfoReturnable cir) { - throw emergencyCrash(); - } } diff --git a/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java b/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java index af06951..179d6a4 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java @@ -277,12 +277,13 @@ public enum Mixin implements IMixins { common("biome.galacticraft.ChunkProviderOrbitMixin", "biome.galacticraft.ConfigManagerCoreMixin")), - Biome_GalaxySpace(Phase.EARLY, + Biome_GalaxySpace(Phase.LATE, Ext.Biome, require(GalaxySpace), common("biome.galaxyspace.ChunkProviderKuiperMixin", "biome.galaxyspace.ChunkProviderMarsSSMixin", "biome.galaxyspace.ChunkProviderSpaceLakesMixin", + "biome.galaxyspace.ChunkProviderSpaceLakesGTNHMixin", "biome.galaxyspace.ChunkProviderVenusSSMixin")), Biome_Highlands(Phase.LATE, @@ -418,19 +419,26 @@ public enum Mixin implements IMixins { // endregion Biome // region BlockItem - + BlockItem_Vanilla(Phase.EARLY, + () -> { return Ext.BlockItem.getAsBoolean() && !hasThermos(); }, + common("blockitem.vanilla.ExtendedBlockStorageMixin")), + BlockItem_Thermos(Phase.EARLY, + () -> { return Ext.BlockItem.getAsBoolean() && hasThermos(); }, + common("blockitem.thermos.NibbleArrayMixin")), + + BlockItem_Common(Phase.EARLY, Ext.BlockItem, - common("blockitem.vanilla.BlockFireMixin", - "blockitem.vanilla.BlockMixin", - "blockitem.vanilla.ExtendedBlockStorageMixin", - "blockitem.vanilla.ItemInWorldManagerMixin", - "blockitem.vanilla.ItemStackMixin", - "blockitem.vanilla.PacketBufferMixin", - "blockitem.vanilla.S22PacketMultiBlockChangeMixin", - "blockitem.vanilla.S24PacketBlockActionMixin", - "blockitem.vanilla.StatListMixin", - "blockitem.vanilla.WorldMixin"), + common("blockitem.common.BlockFireMixin", + "blockitem.common.BlockMixin", + "blockitem.common.ExtendedBlockStorageMixin", + "blockitem.common.ItemInWorldManagerMixin", + "blockitem.common.ItemStackMixin", + "blockitem.common.PacketBufferMixin", + "blockitem.common.S22PacketMultiBlockChangeMixin", + "blockitem.common.S24PacketBlockActionMixin", + "blockitem.common.StatListMixin", + "blockitem.common.WorldMixin"), client("blockitem.vanilla.PlayerControllerMPMixin", "blockitem.vanilla.RenderGlobalMixin")), @@ -607,4 +615,16 @@ private static class Ext { public static final BooleanSupplier Potion = () -> GeneralConfig.extendPotion; public static final BooleanSupplier Entity = () -> GeneralConfig.extendEntity; } + + static boolean hasThermos() + { + try + { + Class.forName("thermos.Thermos"); + return true; + } + catch(ClassNotFoundException ignored) { + return false; + } + } } diff --git a/src/main/resources/META-INF/endlessids_at.cfg b/src/main/resources/META-INF/endlessids_at.cfg new file mode 100644 index 0000000..06e2d10 --- /dev/null +++ b/src/main/resources/META-INF/endlessids_at.cfg @@ -0,0 +1,2 @@ +#Fields +protected net.minecraft.world.gen.ChunkProviderGenerate field_73231_z # biomesForGeneration \ No newline at end of file