From db65cbaa4fb46d61e7bade1ee0c0b11c92a0863c Mon Sep 17 00:00:00 2001 From: Aaron <51387595+AzureAaron@users.noreply.github.com> Date: Mon, 2 Oct 2023 03:00:02 -0400 Subject: Item Protection --- .../skyblocker/mixin/ClientPlayerEntityMixin.java | 6 +- .../skyblocker/mixin/HandledScreenMixin.java | 67 +++++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) (limited to 'src/main/java/me/xmrvizzy/skyblocker/mixin') diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayerEntityMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayerEntityMixin.java index ee1fc5b8..531fa3c5 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayerEntityMixin.java @@ -4,6 +4,7 @@ import com.mojang.authlib.GameProfile; import dev.cbyrne.betterinject.annotations.Inject; import me.xmrvizzy.skyblocker.skyblock.HotbarSlotLock; +import me.xmrvizzy.skyblocker.skyblock.ItemProtection; import me.xmrvizzy.skyblocker.skyblock.rift.HealingMelonIndicator; import me.xmrvizzy.skyblocker.utils.Utils; import net.minecraft.client.network.AbstractClientPlayerEntity; @@ -21,7 +22,10 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity @Inject(method = "dropSelectedItem", at = @At("HEAD"), cancellable = true) public void skyblocker$dropSelectedItem(CallbackInfoReturnable cir) { - if (Utils.isOnSkyblock()) HotbarSlotLock.handleDropSelectedItem(this.getInventory().selectedSlot, cir); + if (Utils.isOnSkyblock()) { + if (ItemProtection.isItemProtected(this.getInventory().getMainHandStack())) cir.setReturnValue(false); + HotbarSlotLock.handleDropSelectedItem(this.getInventory().selectedSlot, cir); + } } @Inject(method = "updateHealth", at = @At("RETURN")) diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java index 17497ded..fcdcb10e 100644 --- a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java +++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java @@ -2,6 +2,7 @@ package me.xmrvizzy.skyblocker.mixin; import me.xmrvizzy.skyblocker.SkyblockerMod; import me.xmrvizzy.skyblocker.config.SkyblockerConfigManager; +import me.xmrvizzy.skyblocker.skyblock.ItemProtection; import me.xmrvizzy.skyblocker.skyblock.experiment.ChronomatronSolver; import me.xmrvizzy.skyblocker.skyblock.experiment.ExperimentSolver; import me.xmrvizzy.skyblocker.skyblock.experiment.SuperpairsSolver; @@ -12,16 +13,21 @@ import me.xmrvizzy.skyblocker.skyblock.item.WikiLookup; import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry; import me.xmrvizzy.skyblocker.utils.Utils; import me.xmrvizzy.skyblocker.utils.render.gui.ContainerSolver; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.item.TooltipContext; import net.minecraft.inventory.SimpleInventory; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.screen.GenericContainerScreenHandler; +import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.slot.Slot; import net.minecraft.screen.slot.SlotActionType; import net.minecraft.text.Text; import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -36,10 +42,20 @@ import java.util.Map; import java.util.regex.Matcher; @Mixin(HandledScreen.class) -public abstract class HandledScreenMixin extends Screen { +public abstract class HandledScreenMixin extends Screen { + /** + * This is the slot id returned for when a click is outside of the screen's bounds + */ + @Unique + private static final int OUT_OF_BOUNDS_SLOT = -999; + @Shadow @Nullable protected Slot focusedSlot; + + @Shadow + @Final + protected T handler; protected HandledScreenMixin(Text title) { super(title); @@ -120,4 +136,53 @@ public abstract class HandledScreenMixin extends Screen { } } } + + /** + * The naming of this method in yarn is half true, its mostly to handle slot/item interactions (which are mouse or keyboard clicks) + * + * For example, using the drop key bind while hovering over an item will invoke this method to drop the players item + */ + @Inject(method = "onMouseClick(Lnet/minecraft/screen/slot/Slot;IILnet/minecraft/screen/slot/SlotActionType;)V", at = @At("HEAD"), cancellable = true) + private void skyblocker$onSlotInteract(Slot slot, int slotId, int button, SlotActionType actionType, CallbackInfo ci) { + if (Utils.isOnSkyblock()) { + // When you try and drop the item by picking it up then clicking outside of the screen + if (slotId == OUT_OF_BOUNDS_SLOT) { + ItemStack cursorStack = this.handler.getCursorStack(); + + if (ItemProtection.isItemProtected(cursorStack)) ci.cancel(); + } + + if (slot != null) { + // When you click your drop key while hovering over an item + if (actionType == SlotActionType.THROW) { + ItemStack stack = slot.getStack(); + + if (ItemProtection.isItemProtected(stack)) ci.cancel(); + } + + //Prevent salvaging + if (this.getTitle().getString().equals("Salvage Items")) { + ItemStack stack = slot.getStack(); + + if (ItemProtection.isItemProtected(stack)) ci.cancel(); + } + + //Prevent selling to NPC shops + if (this.handler instanceof GenericContainerScreenHandler handler && handler.getRows() == 6) { + ItemStack sellItem = this.handler.slots.get(49).getStack(); + + if (sellItem.getName().getString().equals("Sell Item") || skyblocker$doesLoreContain(sellItem, this.client, "buyback")) { + ItemStack stack = slot.getStack(); + + if (ItemProtection.isItemProtected(stack)) ci.cancel(); + } + } + } + } + } + + //TODO make this a util method somewhere else, eventually + private static boolean skyblocker$doesLoreContain(ItemStack stack, MinecraftClient client, String searchString) { + return stack.getTooltip(client.player, TooltipContext.BASIC).stream().map(Text::getString).anyMatch(line -> line.contains(searchString)); + } } -- cgit