Skip to content

Commit ab3711e

Browse files
authored
Fix for chunk packets causing client to corrupt biome ID when run with Thermos (#14)
1 parent d6f4a91 commit ab3711e

File tree

3 files changed

+135
-1
lines changed

3 files changed

+135
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.gtnewhorizons.neid;
2+
3+
public class Common {
4+
5+
public static boolean thermosTainted;
6+
7+
static {
8+
try {
9+
Class.forName("org.bukkit.World");
10+
Common.thermosTainted = true;
11+
} catch (ClassNotFoundException e) {
12+
Common.thermosTainted = false;
13+
}
14+
}
15+
}

src/main/java/com/gtnewhorizons/neid/mixins/Mixins.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.util.Set;
88
import java.util.function.Supplier;
99

10+
import com.gtnewhorizons.neid.Common;
1011
import com.gtnewhorizons.neid.NEIDConfig;
1112

1213
import cpw.mods.fml.relauncher.FMLLaunchHandler;
@@ -20,14 +21,19 @@ public enum Mixins {
2021
"minecraft.MixinExtendedBlockStorage",
2122
"minecraft.MixinStatList",
2223
"minecraft.MixinBlockFire",
23-
"minecraft.MixinS21PacketChunkData",
2424
"minecraft.MixinS22PacketMultiBlockChange",
2525
"minecraft.MixinS24PacketBlockAction",
2626
"minecraft.MixinS26PacketMapChunkBulk",
2727
"minecraft.MixinItemInWorldManager",
2828
"minecraft.MixinAnvilChunkLoader",
2929
"minecraft.MixinBlock"
3030
).setApplyIf(() -> true)),
31+
VANILLA_STARTUP_ONLY_WITHOUT_THERMOS(new Builder("Start Vanilla No Thermos").addTargetedMod(TargetedMod.VANILLA).setSide(Side.BOTH).setPhase(Phase.EARLY).addMixinClasses(
32+
"minecraft.MixinS21PacketChunkData"
33+
).setApplyIf(() -> !Common.thermosTainted)),
34+
VANILLA_STARTUP_ONLY_WITH_THERMOS(new Builder("Start Vanilla with Thermos").addTargetedMod(TargetedMod.VANILLA).setSide(Side.BOTH).setPhase(Phase.EARLY).addMixinClasses(
35+
"minecraft.MixinS21PacketChunkDataThermosTainted"
36+
).setApplyIf(() -> Common.thermosTainted)),
3137
VANILLA_STARTUP_CLIENT(new Builder("Start Vanilla Client").addTargetedMod(TargetedMod.VANILLA)
3238
.setSide(Side.CLIENT).setPhase(Phase.EARLY).addMixinClasses(
3339
"minecraft.client.MixinRenderGlobal",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package com.gtnewhorizons.neid.mixins.early.minecraft;
2+
3+
import net.minecraft.network.play.server.S21PacketChunkData;
4+
import net.minecraft.world.chunk.NibbleArray;
5+
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
6+
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.injection.At;
9+
import org.spongepowered.asm.mixin.injection.Constant;
10+
import org.spongepowered.asm.mixin.injection.ModifyConstant;
11+
import org.spongepowered.asm.mixin.injection.Redirect;
12+
13+
import com.gtnewhorizons.neid.Constants;
14+
import com.gtnewhorizons.neid.mixins.interfaces.IExtendedBlockStorageMixin;
15+
import com.llamalad7.mixinextras.injector.WrapWithCondition;
16+
import com.llamalad7.mixinextras.sugar.Local;
17+
import com.llamalad7.mixinextras.sugar.ref.LocalIntRef;
18+
19+
@Mixin(S21PacketChunkData.class)
20+
public class MixinS21PacketChunkDataThermosTainted {
21+
22+
private static final byte[] fakeByteArray = new byte[0];
23+
private static final NibbleArray fakeNibbleArray = new NibbleArray(0, 0);
24+
25+
@ModifyConstant(
26+
method = "<clinit>",
27+
constant = @Constant(intValue = Constants.VANILLA_BYTES_PER_CHUNK),
28+
require = 1)
29+
private static int neid$OverrideBytesPerChunk1(int old) {
30+
return Constants.BYTES_PER_CHUNK;
31+
}
32+
33+
@ModifyConstant(
34+
method = "func_149275_c()I",
35+
constant = @Constant(intValue = Constants.VANILLA_BYTES_PER_CHUNK),
36+
require = 1)
37+
private static int neid$OverrideBytesPerChunk2(int i) {
38+
return Constants.BYTES_PER_CHUNK;
39+
}
40+
41+
@ModifyConstant(
42+
method = "readPacketData",
43+
constant = @Constant(intValue = Constants.VANILLA_BYTES_PER_EBS),
44+
require = 1)
45+
private static int neid$OverrideBytesPerEBS(int i) {
46+
return Constants.BYTES_PER_EBS;
47+
}
48+
49+
@Redirect(
50+
method = "func_149269_a",
51+
at = @At(
52+
value = "INVOKE",
53+
target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;getBlockLSBArray()[B"),
54+
require = 1)
55+
private static byte[] neid$injectNewDataCopy(ExtendedBlockStorage ebs, @Local(ordinal = 0) byte[] thebytes,
56+
@Local(ordinal = 1) LocalIntRef offset) {
57+
IExtendedBlockStorageMixin ebsMixin = (IExtendedBlockStorageMixin) ebs;
58+
byte[] data = ebsMixin.getBlockData();
59+
System.arraycopy(data, 0, thebytes, offset.get(), Constants.BLOCKS_PER_EBS * 2);
60+
offset.set(offset.get() + (Constants.BLOCKS_PER_EBS * 2));
61+
return fakeByteArray;
62+
}
63+
64+
@WrapWithCondition(
65+
method = "func_149269_a",
66+
at = @At(
67+
value = "INVOKE",
68+
target = "Ljava/lang/System;arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V",
69+
ordinal = 0),
70+
require = 1)
71+
private static boolean neid$cancelLSBArrayCopy(Object a, int i, Object b, int j, int k) {
72+
return false;
73+
}
74+
75+
@Redirect(
76+
method = "func_149269_a",
77+
at = @At(
78+
value = "INVOKE",
79+
target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;getMetadataArray()Lnet/minecraft/world/chunk/NibbleArray;"),
80+
require = 1)
81+
private static NibbleArray neid$injectNewMetadataCopy(ExtendedBlockStorage ebs, @Local(ordinal = 0) byte[] thebytes,
82+
@Local(ordinal = 1) LocalIntRef offset) {
83+
IExtendedBlockStorageMixin ebsMixin = (IExtendedBlockStorageMixin) ebs;
84+
byte[] meta = ebsMixin.getBlockMeta();
85+
System.arraycopy(meta, 0, thebytes, offset.get(), Constants.BLOCKS_PER_EBS * 2);
86+
offset.set(offset.get() + (Constants.BLOCKS_PER_EBS * 2));
87+
return fakeNibbleArray;
88+
}
89+
90+
@WrapWithCondition(
91+
method = "func_149269_a",
92+
at = @At(
93+
value = "INVOKE",
94+
target = "Lnet/minecraft/world/chunk/NibbleArray;copyToByteArray([BI)I",
95+
ordinal = 0,
96+
remap = false),
97+
require = 1)
98+
private static boolean neid$cancelMetadataArrayCopy(NibbleArray nibbleArray, byte[] bytes, int i) {
99+
return false;
100+
}
101+
102+
@Redirect(
103+
method = "func_149269_a",
104+
at = @At(
105+
value = "INVOKE",
106+
target = "Lnet/minecraft/world/chunk/storage/ExtendedBlockStorage;getBlockMSBArray()Lnet/minecraft/world/chunk/NibbleArray;",
107+
ordinal = 0),
108+
require = 1)
109+
private static NibbleArray neid$nukeMSBLoop(ExtendedBlockStorage ebs) {
110+
return null;
111+
}
112+
113+
}

0 commit comments

Comments
 (0)