From ce9ace2a7ac7709d8af5324e5b3dffed19c13ba3 Mon Sep 17 00:00:00 2001 From: Jonas Gunz Date: Wed, 21 Oct 2020 05:05:41 +0200 Subject: Fix client crash when accessing stats on non-parquet clients --- src/main/java/re/jag/parquet/ParquetSettings.java | 2 + .../parquet/mixin/StatisticsS2CPacketMixin.java | 61 ++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/main/java/re/jag/parquet/mixin/StatisticsS2CPacketMixin.java (limited to 'src/main/java') diff --git a/src/main/java/re/jag/parquet/ParquetSettings.java b/src/main/java/re/jag/parquet/ParquetSettings.java index 030306d..203c648 100644 --- a/src/main/java/re/jag/parquet/ParquetSettings.java +++ b/src/main/java/re/jag/parquet/ParquetSettings.java @@ -14,6 +14,7 @@ public class ParquetSettings { public final boolean dispenser_custom_behavior; public final boolean stats_villager_trades; + public final boolean stats_send_to_client; public final boolean command_cameramode; public final boolean command_stats; @@ -30,6 +31,7 @@ public class ParquetSettings { this.dispenser_custom_behavior = get_boolean("dispenser-custom-behavior", true); this.stats_villager_trades = get_boolean("stats-villager-trades", true); + this.stats_send_to_client = get_boolean("stats-send-to-client", false); this.command_cameramode = get_boolean("command-cameramode", true); this.command_stats = get_boolean("command-stats", true); diff --git a/src/main/java/re/jag/parquet/mixin/StatisticsS2CPacketMixin.java b/src/main/java/re/jag/parquet/mixin/StatisticsS2CPacketMixin.java new file mode 100644 index 0000000..173edcb --- /dev/null +++ b/src/main/java/re/jag/parquet/mixin/StatisticsS2CPacketMixin.java @@ -0,0 +1,61 @@ +package re.jag.parquet.mixin; + +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectIterator; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.network.packet.s2c.play.StatisticsS2CPacket; +import net.minecraft.stat.Stat; +import net.minecraft.util.registry.Registry; +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 re.jag.parquet.CustomStats; +import re.jag.parquet.Parquet; + +@Mixin(StatisticsS2CPacket.class) +public class StatisticsS2CPacketMixin { + @Shadow + private Object2IntMap> stats; + + @Shadow + private int getStatId(Stat stat) { return 0; } + + /* + * Opening the statistics menu on client causes crash with custom stats enabled. + * This new write() removes all custom stats from the list sent to the client. + */ + @Inject(method="write", at=@At("HEAD"), cancellable = true) + protected void onWrite(PacketByteBuf buf, CallbackInfo ci){ + if (Parquet.get_settings().stats_send_to_client) + return; + + Object2IntMap> copy = ((Object2IntOpenHashMap)stats).clone(); + + ObjectIterator iter = copy.object2IntEntrySet().iterator(); + + while (iter.hasNext()) { + Object2IntMap.Entry> entry = (Object2IntMap.Entry)iter.next(); + Stat stat = (Stat)entry.getKey(); + + if( Parquet.get_settings().stats_villager_trades && stat.getType() == CustomStats.TRADED ) + copy.removeInt(stat); + } + + iter = copy.object2IntEntrySet().iterator(); + buf.writeVarInt(copy.size()); + + while(iter.hasNext()) { + Object2IntMap.Entry> entry = (Object2IntMap.Entry)iter.next(); + Stat stat = (Stat)entry.getKey(); + + buf.writeVarInt(Registry.STAT_TYPE.getRawId(stat.getType())); + buf.writeVarInt(this.getStatId(stat)); + buf.writeVarInt(entry.getIntValue()); + } + + ci.cancel(); + } +} -- cgit v1.2.3