aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/moe/nea/firmament/mixins
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/moe/nea/firmament/mixins')
-rw-r--r--src/main/java/moe/nea/firmament/mixins/EntityUpdateEventListener.java47
-rw-r--r--src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java58
2 files changed, 105 insertions, 0 deletions
diff --git a/src/main/java/moe/nea/firmament/mixins/EntityUpdateEventListener.java b/src/main/java/moe/nea/firmament/mixins/EntityUpdateEventListener.java
new file mode 100644
index 0000000..b7476af
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/EntityUpdateEventListener.java
@@ -0,0 +1,47 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package moe.nea.firmament.mixins;
+
+import com.llamalad7.mixinextras.sugar.Local;
+import moe.nea.firmament.events.EntityUpdateEvent;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.network.ClientCommonNetworkHandler;
+import net.minecraft.client.network.ClientConnectionState;
+import net.minecraft.client.network.ClientPlayNetworkHandler;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.network.ClientConnection;
+import net.minecraft.network.packet.s2c.play.EntityAttributesS2CPacket;
+import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket;
+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;
+
+@Mixin(ClientPlayNetworkHandler.class)
+public abstract class EntityUpdateEventListener extends ClientCommonNetworkHandler {
+
+ @Shadow
+ private ClientWorld world;
+
+ protected EntityUpdateEventListener(MinecraftClient client, ClientConnection connection, ClientConnectionState connectionState) {
+ super(client, connection, connectionState);
+ }
+
+ @Inject(method = "onEntityAttributes", at = @At("TAIL"))
+ private void onAttributeUpdate(EntityAttributesS2CPacket packet, CallbackInfo ci) {
+ EntityUpdateEvent.Companion.publish(new EntityUpdateEvent.AttributeUpdate(
+ (LivingEntity) world.getEntityById(packet.getEntityId()), packet.getEntries()));
+ }
+
+ @Inject(method = "onEntityTrackerUpdate", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/data/DataTracker;writeUpdatedEntries(Ljava/util/List;)V", shift = At.Shift.AFTER))
+ private void onEntityTracker(EntityTrackerUpdateS2CPacket packet, CallbackInfo ci, @Local Entity entity) {
+ EntityUpdateEvent.Companion.publish(new EntityUpdateEvent.TrackedDataUpdate(entity, packet.trackedValues()));
+ }
+}
diff --git a/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java b/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java
new file mode 100644
index 0000000..ad2a919
--- /dev/null
+++ b/src/main/java/moe/nea/firmament/mixins/SlotUpdateListener.java
@@ -0,0 +1,58 @@
+/*
+ * SPDX-FileCopyrightText: 2024 Linnea Gräf <nea@nea.moe>
+ *
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ */
+
+package moe.nea.firmament.mixins;
+
+import com.llamalad7.mixinextras.sugar.Local;
+import moe.nea.firmament.events.PlayerInventoryUpdate;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.network.ClientCommonNetworkHandler;
+import net.minecraft.client.network.ClientConnectionState;
+import net.minecraft.client.network.ClientPlayNetworkHandler;
+import net.minecraft.client.network.ClientPlayerEntity;
+import net.minecraft.network.ClientConnection;
+import net.minecraft.network.packet.s2c.play.InventoryS2CPacket;
+import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(ClientPlayNetworkHandler.class)
+public abstract class SlotUpdateListener extends ClientCommonNetworkHandler {
+ protected SlotUpdateListener(MinecraftClient client, ClientConnection connection, ClientConnectionState connectionState) {
+ super(client, connection, connectionState);
+ }
+
+ @Inject(
+ method = "onScreenHandlerSlotUpdate",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/tutorial/TutorialManager;onSlotUpdate(Lnet/minecraft/item/ItemStack;)V"))
+ private void onSingleSlotUpdate(
+ ScreenHandlerSlotUpdateS2CPacket packet,
+ CallbackInfo ci) {
+ var player = this.client.player;
+ assert player != null;
+ if (packet.getSyncId() == ScreenHandlerSlotUpdateS2CPacket.UPDATE_PLAYER_INVENTORY_SYNC_ID
+ || packet.getSyncId() == 0) {
+ PlayerInventoryUpdate.Companion.publish(new PlayerInventoryUpdate.Single(packet.getSlot(), packet.getStack()));
+ } else if (packet.getSyncId() == player.currentScreenHandler.syncId) {
+ // TODO: dispatch single chest slot
+ }
+ }
+
+ @Inject(method = "onInventory",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/network/NetworkThreadUtils;forceMainThread(Lnet/minecraft/network/packet/Packet;Lnet/minecraft/network/listener/PacketListener;Lnet/minecraft/util/thread/ThreadExecutor;)V",
+ shift = At.Shift.AFTER))
+ private void onMultiSlotUpdate(InventoryS2CPacket packet, CallbackInfo ci) {
+ var player = this.client.player;
+ assert player != null;
+ if (packet.getSyncId() == 0) {
+ PlayerInventoryUpdate.Companion.publish(new PlayerInventoryUpdate.Multi(packet.getContents()));
+ } else if (packet.getSyncId() == player.currentScreenHandler.syncId) {
+ // TODO: dispatch multi chest
+ }
+ }
+}