diff --git a/src/main/java/com/viaversion/viafabricplus/features/FeaturesLoading.java b/src/main/java/com/viaversion/viafabricplus/features/FeaturesLoading.java index d4c06cf2f..2e49f5126 100644 --- a/src/main/java/com/viaversion/viafabricplus/features/FeaturesLoading.java +++ b/src/main/java/com/viaversion/viafabricplus/features/FeaturesLoading.java @@ -35,6 +35,7 @@ import com.viaversion.viafabricplus.features.global.ResourcePackHeaderDiff; import com.viaversion.viafabricplus.features.v1_11_1.Recipes1_11_2; import com.viaversion.viafabricplus.features.v1_12_2.FootStepParticle1_12_2; +import com.viaversion.viafabricplus.features.v26_2.PotionBrewing26_2; import com.viaversion.viafabricplus.util.network.SyncTasks; import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import net.minecraft.client.Minecraft; @@ -81,6 +82,7 @@ public static void onPostGameLoading() { Recipes1_11_2.init(); ArmorHudEmulation1_8.init(); CPEAdditions.postInit(); + PotionBrewing26_2.init(); } } diff --git a/src/main/java/com/viaversion/viafabricplus/features/v1_11/FurnaceFuels.java b/src/main/java/com/viaversion/viafabricplus/features/v1_11/FurnaceFuels.java new file mode 100644 index 000000000..32d2ad2be --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/features/v1_11/FurnaceFuels.java @@ -0,0 +1,205 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.features.v1_11; + +import net.minecraft.core.Holder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.tags.ItemTags; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Blocks; +import java.util.ArrayList; + +public final class FurnaceFuels { + + private static FurnaceFuels FUELS_1_11 = null; + private static FurnaceFuels FUELS_1_3_1 = null; + private static FurnaceFuels FUELS_1_2_5 = null; + + private final ArrayList values; + + private FurnaceFuels(final ArrayList values) { + this.values = values; + } + + public boolean isFuel(final ItemStack itemStack) { + return this.values.contains(itemStack.getItem()); + } + + public static FurnaceFuels getFuels_1_11() { + if (FUELS_1_11 == null) + FUELS_1_11 = new FurnaceFuels.Builder() + .add(Items.LAVA_BUCKET) + .add(Blocks.COAL_BLOCK) + .add(Items.BLAZE_ROD) + .add(Items.COAL) + .add(Items.CHARCOAL) + .add(ItemTags.PLANKS) + .add(ItemTags.WOODEN_STAIRS) + .add(ItemTags.WOODEN_TRAPDOORS) + .add(ItemTags.WOODEN_PRESSURE_PLATES) + .add(ItemTags.WOODEN_FENCES) + .add(ItemTags.FENCE_GATES) + .add(Blocks.NOTE_BLOCK) + .add(Blocks.BOOKSHELF) + .add(Blocks.JUKEBOX) + .add(Blocks.CHEST) + .add(Blocks.TRAPPED_CHEST) + .add(Blocks.CRAFTING_TABLE) + .add(Blocks.DAYLIGHT_DETECTOR) + .add(ItemTags.BANNERS) + .add(Items.BOW) + .add(Items.FISHING_ROD) + .add(Blocks.LADDER) + .add(ItemTags.SIGNS) + .add(Items.WOODEN_SHOVEL) + .add(Items.WOODEN_SWORD) + .add(Items.WOODEN_SPEAR) + .add(Items.WOODEN_HOE) + .add(Items.WOODEN_AXE) + .add(Items.WOODEN_PICKAXE) + .add(ItemTags.WOODEN_DOORS) + .add(ItemTags.BOATS) + .add(ItemTags.WOOL) + .add(ItemTags.WOODEN_BUTTONS) + .add(Items.STICK) + .add(ItemTags.SAPLINGS) + .add(Items.BOWL) + .add(ItemTags.WOOL_CARPETS) + .remove(ItemTags.NON_FLAMMABLE_WOOD) + .build(); + + return FUELS_1_11; + } + + public static FurnaceFuels getFuels_1_3_1() { + if (FUELS_1_3_1 == null) + FUELS_1_3_1 = new FurnaceFuels.Builder() + .add(Items.LAVA_BUCKET) + .add(Blocks.COAL_BLOCK) + .add(Items.BLAZE_ROD) + .add(Items.COAL) + .add(Items.CHARCOAL) + .add(ItemTags.PLANKS) + .add(ItemTags.WOODEN_STAIRS) + .add(ItemTags.WOODEN_TRAPDOORS) + .add(ItemTags.WOODEN_PRESSURE_PLATES) + .add(ItemTags.WOODEN_FENCES) + .add(ItemTags.FENCE_GATES) + .add(Blocks.NOTE_BLOCK) + .add(Blocks.BOOKSHELF) + .add(Blocks.JUKEBOX) + .add(Blocks.CHEST) + .add(Blocks.TRAPPED_CHEST) + .add(Blocks.CRAFTING_TABLE) + .add(Blocks.DAYLIGHT_DETECTOR) + .add(ItemTags.BANNERS) + .add(Items.BOW) + .add(Items.FISHING_ROD) + .add(Blocks.LADDER) + .add(Items.WOODEN_SHOVEL) + .add(Items.WOODEN_SWORD) + .add(Items.WOODEN_SPEAR) + .add(Items.WOODEN_HOE) + .add(Items.WOODEN_AXE) + .add(Items.WOODEN_PICKAXE) + .add(Items.STICK) + .add(ItemTags.SAPLINGS) + .add(Items.BOWL) + .remove(ItemTags.NON_FLAMMABLE_WOOD) + .build(); + + return FUELS_1_3_1; + } + + public static FurnaceFuels getFuels_1_2_5() { + if (FUELS_1_2_5 == null) + FUELS_1_2_5 = new FurnaceFuels.Builder() + .add(Items.LAVA_BUCKET) + .add(Blocks.COAL_BLOCK) + .add(Items.BLAZE_ROD) + .add(Items.COAL) + .add(Items.CHARCOAL) + .add(ItemTags.PLANKS) + .add(ItemTags.WOODEN_STAIRS) + .add(ItemTags.WOODEN_TRAPDOORS) + .add(ItemTags.WOODEN_PRESSURE_PLATES) + .add(ItemTags.WOODEN_FENCES) + .add(ItemTags.FENCE_GATES) + .add(Blocks.NOTE_BLOCK) + .add(Blocks.BOOKSHELF) + .add(Blocks.JUKEBOX) + .add(Blocks.CHEST) + .add(Blocks.TRAPPED_CHEST) + .add(Blocks.CRAFTING_TABLE) + .add(Blocks.DAYLIGHT_DETECTOR) + .add(ItemTags.BANNERS) + .add(Items.BOW) + .add(Items.FISHING_ROD) + .add(Blocks.LADDER) + .add(Items.STICK) + .add(ItemTags.SAPLINGS) + .add(Items.BOWL) + .remove(ItemTags.NON_FLAMMABLE_WOOD) + .build(); + + return FUELS_1_2_5; + } + + public static class Builder { + + private final ArrayList values = new ArrayList<>(); + + public FurnaceFuels build() { + return new FurnaceFuels(this.values); + } + + public FurnaceFuels.Builder remove(final TagKey tag) { + BuiltInRegistries.ITEM.get(tag).ifPresent(items -> { + for (Holder item : items) { + this.values.remove(item.value()); + } + }); + return this; + } + + public FurnaceFuels.Builder add(final TagKey tag) { + BuiltInRegistries.ITEM.get(tag).ifPresent(items -> { + for (Holder item : items) { + this.values.add(item.value()); + } + }); + return this; + } + + public FurnaceFuels.Builder add(final ItemLike itemLike) { + Item item = itemLike.asItem(); + this.values.add(item); + return this; + } + + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/features/v26_2/PotionBrewing26_2.java b/src/main/java/com/viaversion/viafabricplus/features/v26_2/PotionBrewing26_2.java new file mode 100644 index 000000000..9a314c308 --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/features/v26_2/PotionBrewing26_2.java @@ -0,0 +1,160 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.features.v26_2; + +import net.minecraft.core.Holder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.Potion; +import net.minecraft.world.item.alchemy.Potions; +import net.minecraft.world.item.crafting.Ingredient; +import java.util.ArrayList; +import java.util.List; + +public class PotionBrewing26_2 { + public static PotionBrewing26_2 INSTANCE = null; + private final List> potionMixes; + private final List> containerMixes; + + private PotionBrewing26_2( + final List> potionMixes, final List> containerMixes + ) { + this.potionMixes = potionMixes; + this.containerMixes = containerMixes; + } + + public boolean isIngredient(final ItemStack ingredient) { + return this.isContainerIngredient(ingredient) || this.isPotionIngredient(ingredient); + } + + public boolean isContainerIngredient(final ItemStack ingredient) { + for (PotionBrewing26_2.Mix containerMix : this.containerMixes) { + if (containerMix.ingredient.test(ingredient)) { + return true; + } + } + + return false; + } + + public boolean isPotionIngredient(final ItemStack ingredient) { + for (PotionBrewing26_2.Mix potionMix : this.potionMixes) { + if (potionMix.ingredient.test(ingredient)) { + return true; + } + } + + return false; + } + + public static void init() { + if (INSTANCE != null) { + throw new IllegalStateException("PotionBrewing26_2 is already initialized"); + } + + PotionBrewing26_2.Builder builder = new PotionBrewing26_2.Builder(); + + builder.addContainerRecipe(Items.POTION, Items.GUNPOWDER, Items.SPLASH_POTION); + builder.addContainerRecipe(Items.SPLASH_POTION, Items.DRAGON_BREATH, Items.LINGERING_POTION); + builder.addMix(Potions.WATER, Items.GLOWSTONE_DUST, Potions.THICK); + builder.addMix(Potions.WATER, Items.REDSTONE, Potions.MUNDANE); + builder.addMix(Potions.WATER, Items.NETHER_WART, Potions.AWKWARD); + builder.addStartMix(Items.BREEZE_ROD, Potions.WIND_CHARGED); + builder.addStartMix(Items.SLIME_BLOCK, Potions.OOZING); + builder.addStartMix(Items.STONE, Potions.INFESTED); + builder.addStartMix(Items.COBWEB, Potions.WEAVING); + builder.addMix(Potions.AWKWARD, Items.GOLDEN_CARROT, Potions.NIGHT_VISION); + builder.addMix(Potions.NIGHT_VISION, Items.REDSTONE, Potions.LONG_NIGHT_VISION); + builder.addMix(Potions.NIGHT_VISION, Items.FERMENTED_SPIDER_EYE, Potions.INVISIBILITY); + builder.addMix(Potions.LONG_NIGHT_VISION, Items.FERMENTED_SPIDER_EYE, Potions.LONG_INVISIBILITY); + builder.addMix(Potions.INVISIBILITY, Items.REDSTONE, Potions.LONG_INVISIBILITY); + builder.addStartMix(Items.MAGMA_CREAM, Potions.FIRE_RESISTANCE); + builder.addMix(Potions.FIRE_RESISTANCE, Items.REDSTONE, Potions.LONG_FIRE_RESISTANCE); + builder.addStartMix(Items.RABBIT_FOOT, Potions.LEAPING); + builder.addMix(Potions.LEAPING, Items.REDSTONE, Potions.LONG_LEAPING); + builder.addMix(Potions.LEAPING, Items.GLOWSTONE_DUST, Potions.STRONG_LEAPING); + builder.addMix(Potions.LEAPING, Items.FERMENTED_SPIDER_EYE, Potions.SLOWNESS); + builder.addMix(Potions.LONG_LEAPING, Items.FERMENTED_SPIDER_EYE, Potions.LONG_SLOWNESS); + builder.addMix(Potions.SLOWNESS, Items.REDSTONE, Potions.LONG_SLOWNESS); + builder.addMix(Potions.SLOWNESS, Items.GLOWSTONE_DUST, Potions.STRONG_SLOWNESS); + builder.addMix(Potions.AWKWARD, Items.TURTLE_HELMET, Potions.TURTLE_MASTER); + builder.addMix(Potions.TURTLE_MASTER, Items.REDSTONE, Potions.LONG_TURTLE_MASTER); + builder.addMix(Potions.TURTLE_MASTER, Items.GLOWSTONE_DUST, Potions.STRONG_TURTLE_MASTER); + builder.addMix(Potions.SWIFTNESS, Items.FERMENTED_SPIDER_EYE, Potions.SLOWNESS); + builder.addMix(Potions.LONG_SWIFTNESS, Items.FERMENTED_SPIDER_EYE, Potions.LONG_SLOWNESS); + builder.addStartMix(Items.SUGAR, Potions.SWIFTNESS); + builder.addMix(Potions.SWIFTNESS, Items.REDSTONE, Potions.LONG_SWIFTNESS); + builder.addMix(Potions.SWIFTNESS, Items.GLOWSTONE_DUST, Potions.STRONG_SWIFTNESS); + builder.addMix(Potions.AWKWARD, Items.PUFFERFISH, Potions.WATER_BREATHING); + builder.addMix(Potions.WATER_BREATHING, Items.REDSTONE, Potions.LONG_WATER_BREATHING); + builder.addStartMix(Items.GLISTERING_MELON_SLICE, Potions.HEALING); + builder.addMix(Potions.HEALING, Items.GLOWSTONE_DUST, Potions.STRONG_HEALING); + builder.addMix(Potions.HEALING, Items.FERMENTED_SPIDER_EYE, Potions.HARMING); + builder.addMix(Potions.STRONG_HEALING, Items.FERMENTED_SPIDER_EYE, Potions.STRONG_HARMING); + builder.addMix(Potions.HARMING, Items.GLOWSTONE_DUST, Potions.STRONG_HARMING); + builder.addMix(Potions.POISON, Items.FERMENTED_SPIDER_EYE, Potions.HARMING); + builder.addMix(Potions.LONG_POISON, Items.FERMENTED_SPIDER_EYE, Potions.HARMING); + builder.addMix(Potions.STRONG_POISON, Items.FERMENTED_SPIDER_EYE, Potions.STRONG_HARMING); + builder.addStartMix(Items.SPIDER_EYE, Potions.POISON); + builder.addMix(Potions.POISON, Items.REDSTONE, Potions.LONG_POISON); + builder.addMix(Potions.POISON, Items.GLOWSTONE_DUST, Potions.STRONG_POISON); + builder.addStartMix(Items.GHAST_TEAR, Potions.REGENERATION); + builder.addMix(Potions.REGENERATION, Items.REDSTONE, Potions.LONG_REGENERATION); + builder.addMix(Potions.REGENERATION, Items.GLOWSTONE_DUST, Potions.STRONG_REGENERATION); + builder.addStartMix(Items.BLAZE_POWDER, Potions.STRENGTH); + builder.addMix(Potions.STRENGTH, Items.REDSTONE, Potions.LONG_STRENGTH); + builder.addMix(Potions.STRENGTH, Items.GLOWSTONE_DUST, Potions.STRONG_STRENGTH); + builder.addMix(Potions.WATER, Items.FERMENTED_SPIDER_EYE, Potions.WEAKNESS); + builder.addMix(Potions.WEAKNESS, Items.REDSTONE, Potions.LONG_WEAKNESS); + builder.addMix(Potions.AWKWARD, Items.PHANTOM_MEMBRANE, Potions.SLOW_FALLING); + builder.addMix(Potions.SLOW_FALLING, Items.REDSTONE, Potions.LONG_SLOW_FALLING); + + INSTANCE = builder.build(); + } + + public static class Builder { + private final List> potionMixes = new ArrayList<>(); + private final List> containerMixes = new ArrayList<>(); + + public void addContainerRecipe(final Item from, final Item ingredient, final Item to) { + this.containerMixes.add(new PotionBrewing26_2.Mix<>(BuiltInRegistries.ITEM.wrapAsHolder(from), Ingredient.of(ingredient), BuiltInRegistries.ITEM.wrapAsHolder(to))); + } + + public void addMix(final Holder from, final Item ingredient, final Holder to) { + this.potionMixes.add(new PotionBrewing26_2.Mix<>(from, Ingredient.of(ingredient), to)); + } + + public void addStartMix(final Item ingredient, final Holder potion) { + this.addMix(Potions.WATER, ingredient, Potions.MUNDANE); + this.addMix(Potions.AWKWARD, ingredient, potion); + } + + public PotionBrewing26_2 build() { + return new PotionBrewing26_2(List.copyOf(this.potionMixes), List.copyOf(this.containerMixes)); + } + } + + private record Mix(Holder from, Ingredient ingredient, Holder to) { + } +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_4/MixinChestMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_4/MixinChestMenu.java new file mode 100644 index 000000000..3456409a0 --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_4/MixinChestMenu.java @@ -0,0 +1,40 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.b1_4; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import net.minecraft.world.inventory.ChestMenu; +import net.minecraft.world.inventory.Slot; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ChestMenu.class) +public abstract class MixinChestMenu { + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/Slot;hasItem()Z")) + private boolean disableShiftClickInChests(Slot instance) { + return instance.hasItem() && ViaFabricPlus.api().targetVersion().newerThan(LegacyProtocolVersion.b1_4tob1_4_1); + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinAbstractFurnaceMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinAbstractFurnaceMenu.java new file mode 100644 index 000000000..32c4ef40a --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinAbstractFurnaceMenu.java @@ -0,0 +1,40 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.b1_5; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import net.minecraft.world.inventory.AbstractFurnaceMenu; +import net.minecraft.world.inventory.Slot; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(AbstractFurnaceMenu.class) +public abstract class MixinAbstractFurnaceMenu { + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/Slot;hasItem()Z")) + private boolean disableShiftClickInFurnace(Slot instance) { + return instance.hasItem() && ViaFabricPlus.api().targetVersion().newerThan(LegacyProtocolVersion.b1_5tob1_5_2); + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinChestMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinChestMenu.java new file mode 100644 index 000000000..9aaace2e4 --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinChestMenu.java @@ -0,0 +1,51 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.b1_5; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ChestMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.ItemStack; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ChestMenu.class) +public abstract class MixinChestMenu extends AbstractContainerMenu { + + public MixinChestMenu(final MenuType menuType, final int containerId) { + super(menuType, containerId); + } + + /** + * b1.5 is the first version to have chest shift clicking + * and the only version to have reversed item placement ordering + * when shift clicking an item to player inventory + */ + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/ChestMenu;moveItemStackTo(Lnet/minecraft/world/item/ItemStack;IIZ)Z", ordinal = 0)) + private boolean reverseShiftClickItemPlacementOrdering(ChestMenu instance, ItemStack itemStack, int startSlot, int endSlot, boolean backwards) { + return this.moveItemStackTo(itemStack, startSlot, endSlot, ViaFabricPlus.api().targetVersion().newerThan(LegacyProtocolVersion.b1_5tob1_5_2) && backwards); + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinCraftingMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinCraftingMenu.java new file mode 100644 index 000000000..43bcceccf --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinCraftingMenu.java @@ -0,0 +1,40 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.b1_5; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import net.minecraft.world.inventory.CraftingMenu; +import net.minecraft.world.inventory.Slot; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(CraftingMenu.class) +public abstract class MixinCraftingMenu { + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/Slot;hasItem()Z")) + private boolean disableShiftClickInCraftingMenu(Slot instance) { + return instance.hasItem() && ViaFabricPlus.api().targetVersion().newerThan(LegacyProtocolVersion.b1_5tob1_5_2); + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinInventoryMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinInventoryMenu.java new file mode 100644 index 000000000..ea1ff7a2a --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_5/MixinInventoryMenu.java @@ -0,0 +1,40 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.b1_5; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.inventory.Slot; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(InventoryMenu.class) +public abstract class MixinInventoryMenu { + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/Slot;hasItem()Z", ordinal = 0)) + private boolean disableShiftClickInInventory(Slot instance) { + return instance.hasItem() && ViaFabricPlus.api().targetVersion().newerThan(LegacyProtocolVersion.b1_5tob1_5_2); + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_7/MixinAbstractContainerMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_7/MixinAbstractContainerMenu.java new file mode 100644 index 000000000..e9f02296e --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_7/MixinAbstractContainerMenu.java @@ -0,0 +1,48 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.b1_7; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.AbstractCraftingMenu; +import net.minecraft.world.item.ItemStack; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(AbstractContainerMenu.class) +public abstract class MixinAbstractContainerMenu { + + @Redirect(method = "doClick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/AbstractContainerMenu;quickMoveStack(Lnet/minecraft/world/entity/player/Player;I)Lnet/minecraft/world/item/ItemStack;", ordinal = 0)) + private ItemStack disableQuickCraftMaxAmount(AbstractContainerMenu instance, Player player, int slotIndex) { + ItemStack clicked = instance.quickMoveStack(player, slotIndex); + + if ((Object) this instanceof AbstractCraftingMenu && slotIndex == 0 && ViaFabricPlus.api().targetVersion().equalTo(LegacyProtocolVersion.b1_7tob1_7_3)) { + return ItemStack.EMPTY; + } + + return clicked; + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_7/MixinDispenserMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_7/MixinDispenserMenu.java new file mode 100644 index 000000000..2da2c77a2 --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/b1_7/MixinDispenserMenu.java @@ -0,0 +1,40 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.b1_7; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import net.minecraft.world.inventory.DispenserMenu; +import net.minecraft.world.inventory.Slot; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(DispenserMenu.class) +public abstract class MixinDispenserMenu { + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/Slot;hasItem()Z")) + private boolean disableShiftClickInDispensers(Slot instance) { + return instance.hasItem() && ViaFabricPlus.api().targetVersion().newerThan(LegacyProtocolVersion.b1_7tob1_7_3); + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_10/MixinBrewingStandMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_10/MixinBrewingStandMenu.java new file mode 100644 index 000000000..eb2551991 --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_10/MixinBrewingStandMenu.java @@ -0,0 +1,51 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.v1_10; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import net.minecraft.world.inventory.BrewingStandMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import org.spongepowered.asm.mixin.Final; +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.Redirect; + +@Mixin(BrewingStandMenu.class) +public abstract class MixinBrewingStandMenu { + + @Shadow + @Final + private Slot ingredientSlot; + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/BrewingStandMenu$FuelSlot;mayPlaceItem(Lnet/minecraft/world/item/ItemStack;)Z")) + private boolean disableShiftClickBlazePowderFuelSlotWhenIngredientSlotEmpty(ItemStack itemStack) { + if (ViaFabricPlus.api().targetVersion().betweenInclusive(ProtocolVersion.v1_9, ProtocolVersion.v1_10)) { + return BrewingStandMenu.FuelSlot.mayPlaceItem(itemStack) && !this.ingredientSlot.getItem().isEmpty(); + } + + return BrewingStandMenu.FuelSlot.mayPlaceItem(itemStack); + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_10/MixinBrewingStandMenu_FuelSlot.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_10/MixinBrewingStandMenu_FuelSlot.java new file mode 100644 index 000000000..f036f7331 --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_10/MixinBrewingStandMenu_FuelSlot.java @@ -0,0 +1,44 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.v1_10; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import net.minecraft.world.inventory.BrewingStandMenu; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +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.CallbackInfoReturnable; + +@Mixin(BrewingStandMenu.FuelSlot.class) +public abstract class MixinBrewingStandMenu_FuelSlot { + + @Inject(method = "mayPlaceItem", at = @At("HEAD"), cancellable = true) + private static void enableShiftClickBlazePowderFuelSlot(ItemStack itemStack, CallbackInfoReturnable cir) { + if (itemStack.is(Items.BLAZE_POWDER) && ViaFabricPlus.api().targetVersion().betweenInclusive(ProtocolVersion.v1_9, ProtocolVersion.v1_10)) { + cir.setReturnValue(true); + } + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_10/MixinBrewingStandMenu_IngredientSlot.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_10/MixinBrewingStandMenu_IngredientSlot.java new file mode 100644 index 000000000..a4d063344 --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_10/MixinBrewingStandMenu_IngredientSlot.java @@ -0,0 +1,52 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.v1_10; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import com.viaversion.viafabricplus.features.v26_2.PotionBrewing26_2; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import net.minecraft.world.Container; +import net.minecraft.world.inventory.BrewingStandMenu; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +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.CallbackInfoReturnable; + +@Mixin(BrewingStandMenu.IngredientsSlot.class) +public abstract class MixinBrewingStandMenu_IngredientSlot extends Slot { + + public MixinBrewingStandMenu_IngredientSlot(final Container container, final int slot, final int x, final int y) { + super(container, slot, x, y); + } + + @Inject(method = "mayPlace", at = @At("HEAD"), cancellable = true) + private void disableShiftClickIngredientWhenIngredientSlotNotEmpty(ItemStack itemStack, CallbackInfoReturnable cir) { + if (ViaFabricPlus.api().targetVersion().olderThanOrEqualTo(ProtocolVersion.v1_10)) { + cir.setReturnValue(PotionBrewing26_2.INSTANCE.isIngredient(itemStack) && this.getItem().isEmpty()); + } else if (ViaFabricPlus.api().targetVersion().olderThanOrEqualTo(ProtocolVersion.v26_2)) { + cir.setReturnValue(PotionBrewing26_2.INSTANCE.isIngredient(itemStack)); + } + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_15_2/MixinMultiPlayerGameMode.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_15_2/MixinMultiPlayerGameMode.java index 815e3f3fb..864c6f8d5 100644 --- a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_15_2/MixinMultiPlayerGameMode.java +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_15_2/MixinMultiPlayerGameMode.java @@ -29,6 +29,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractCraftingMenu; import net.minecraft.world.inventory.ContainerInput; import net.minecraft.world.level.block.Blocks; import net.raphimc.vialegacy.api.LegacyProtocolVersion; @@ -59,7 +60,9 @@ private boolean checkFireBlock(MultiPlayerGameMode instance, BlockPos pos, @Loca @Inject(method = "handleContainerInput", at = @At("HEAD"), cancellable = true) private void removeClickActions(int containerId, int slotNum, int buttonNum, ContainerInput containerInput, Player player, CallbackInfo ci) { - if (ViaFabricPlus.api().targetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_5tob1_5_2) && !containerInput.equals(ContainerInput.PICKUP)) { + if (ViaFabricPlus.api().targetVersion().olderThan(LegacyProtocolVersion.b1_5tob1_5_2) && !containerInput.equals(ContainerInput.PICKUP)) { + ci.cancel(); + } else if (ViaFabricPlus.api().targetVersion().olderThanOrEqualTo(LegacyProtocolVersion.b1_6tob1_6_6) && slotNum == 0 && player.containerMenu instanceof AbstractCraftingMenu && !containerInput.equals(ContainerInput.PICKUP)) { ci.cancel(); } else if (ViaFabricPlus.api().targetVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_4_6tor1_4_7) && !containerInput.equals(ContainerInput.PICKUP) && !containerInput.equals(ContainerInput.QUICK_MOVE) && !containerInput.equals(ContainerInput.SWAP) && !containerInput.equals(ContainerInput.CLONE)) { ci.cancel(); diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_2_1/MixinAbstractFurnaceMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_2_1/MixinAbstractFurnaceMenu.java index cb5c56431..add829c0e 100644 --- a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_2_1/MixinAbstractFurnaceMenu.java +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_2_1/MixinAbstractFurnaceMenu.java @@ -22,13 +22,22 @@ package com.viaversion.viafabricplus.injection.mixin.features.v1_2_1; import com.viaversion.viafabricplus.ViaFabricPlus; +import com.viaversion.viafabricplus.features.v1_11.FurnaceFuels; +import com.viaversion.viafabricplus.features.v1_11_1.Recipes1_11_2; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; import net.minecraft.world.inventory.AbstractFurnaceMenu; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.item.crafting.SingleRecipeInput; +import net.minecraft.world.level.Level; import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import org.spongepowered.asm.mixin.Final; 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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(AbstractFurnaceMenu.class) public abstract class MixinAbstractFurnaceMenu { @@ -39,6 +48,28 @@ public abstract class MixinAbstractFurnaceMenu { @Shadow protected abstract boolean isFuel(ItemStack itemStack); + @Final + @Shadow + protected Level level; + + @Inject(method = "canSmelt", at = @At("HEAD"), cancellable = true) + private void smeltingSlotShiftClickWhitelist(ItemStack itemStack, CallbackInfoReturnable cir) { + if (ViaFabricPlus.api().targetVersion().olderThanOrEqualTo(ProtocolVersion.v1_11_1)) { + cir.setReturnValue(Recipes1_11_2.getRecipeManager(this.level.registryAccess().freeze()).getFirstMatch(RecipeType.SMELTING, new SingleRecipeInput(itemStack), this.level).isPresent()); + } + } + + @Inject(method = "isFuel", at = @At("HEAD"), cancellable = true) + private void fuelSlotShiftClickWhitelist(ItemStack itemStack, CallbackInfoReturnable cir) { + if (ViaFabricPlus.api().targetVersion().equalTo(LegacyProtocolVersion.r1_2_4tor1_2_5)) { + cir.setReturnValue(FurnaceFuels.getFuels_1_2_5().isFuel(itemStack)); + } else if (ViaFabricPlus.api().targetVersion().betweenInclusive(LegacyProtocolVersion.r1_3_1tor1_3_2, ProtocolVersion.v1_10)) { + cir.setReturnValue(FurnaceFuels.getFuels_1_3_1().isFuel(itemStack)); + } else if (ViaFabricPlus.api().targetVersion().betweenInclusive(ProtocolVersion.v1_11, ProtocolVersion.v1_13_2)) { + cir.setReturnValue(FurnaceFuels.getFuels_1_11().isFuel(itemStack)); + } + } + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/AbstractFurnaceMenu;canSmelt(Lnet/minecraft/world/item/ItemStack;)Z")) private boolean disableShiftClickSmeltingSlot(AbstractFurnaceMenu instance, ItemStack itemStack) { return this.canSmelt(itemStack) && ViaFabricPlus.api().targetVersion().newerThan(LegacyProtocolVersion.r1_2_1tor1_2_3); diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_3_1/MixinBrewingStandMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_3_1/MixinBrewingStandMenu.java new file mode 100644 index 000000000..b629e2bff --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_3_1/MixinBrewingStandMenu.java @@ -0,0 +1,61 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.v1_3_1; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.BrewingStandMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.PotionIngredient; +import net.minecraft.world.item.crafting.RecipeAccess; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import org.jspecify.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(BrewingStandMenu.class) +public abstract class MixinBrewingStandMenu extends AbstractContainerMenu { + + protected MixinBrewingStandMenu(@Nullable final MenuType menuType, final int containerId) { + super(menuType, containerId); + } + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/Slot;mayPlace(Lnet/minecraft/world/item/ItemStack;)Z")) + private boolean disableShiftClickIngredientSlot(Slot instance, ItemStack itemStack) { + return instance.mayPlace(itemStack) && ViaFabricPlus.api().targetVersion().newerThanOrEqualTo(LegacyProtocolVersion.r1_3_1tor1_3_2); + } + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/crafting/PotionIngredient;isPotionInput(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/crafting/RecipeAccess;)Z")) + private boolean disableShiftClickPotionSlot(ItemStack itemStack, RecipeAccess recipeAccess) { + if (ViaFabricPlus.api().targetVersion().olderThanOrEqualTo(ProtocolVersion.v26_2)) { + return (itemStack.is(Items.POTION) || itemStack.is(Items.SPLASH_POTION) || itemStack.is(Items.LINGERING_POTION) || itemStack.is(Items.GLASS_BOTTLE)) && ViaFabricPlus.api().targetVersion().newerThanOrEqualTo(LegacyProtocolVersion.r1_3_1tor1_3_2); + } + + return PotionIngredient.isPotionInput(itemStack, recipeAccess); + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_6_1/MixinAbstractContainerScreen.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_3_1/MixinEnchantmentMenu.java similarity index 68% rename from src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_6_1/MixinAbstractContainerScreen.java rename to src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_3_1/MixinEnchantmentMenu.java index 7af719768..398cb9d1d 100644 --- a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_6_1/MixinAbstractContainerScreen.java +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_3_1/MixinEnchantmentMenu.java @@ -19,22 +19,22 @@ * along with this program. If not, see . */ -package com.viaversion.viafabricplus.injection.mixin.features.v1_6_1; +package com.viaversion.viafabricplus.injection.mixin.features.v1_3_1; import com.viaversion.viafabricplus.ViaFabricPlus; -import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.minecraft.client.input.MouseButtonEvent; +import net.minecraft.world.inventory.EnchantmentMenu; +import net.minecraft.world.inventory.Slot; import net.raphimc.vialegacy.api.LegacyProtocolVersion; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; -@Mixin(AbstractContainerScreen.class) -public abstract class MixinAbstractContainerScreen { +@Mixin(EnchantmentMenu.class) +public abstract class MixinEnchantmentMenu { - @Redirect(method = {"mouseClicked", "mouseReleased"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/input/MouseButtonEvent;hasShiftDown()Z")) - private boolean disableShiftClickItems(final MouseButtonEvent instance) { - return instance.hasShiftDown() && ViaFabricPlus.api().targetVersion().newerThanOrEqualTo(LegacyProtocolVersion.r1_6_1); + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/Slot;hasItem()Z", ordinal = 1)) + private boolean disableShiftClickEnchantmentSlot(Slot instance) { + return instance.hasItem() || ViaFabricPlus.api().targetVersion().olderThan(LegacyProtocolVersion.r1_3_1tor1_3_2); } } diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_3_1/MixinInventoryMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_3_1/MixinInventoryMenu.java new file mode 100644 index 000000000..1fdb451c1 --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_3_1/MixinInventoryMenu.java @@ -0,0 +1,40 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.v1_3_1; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.inventory.Slot; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(InventoryMenu.class) +public abstract class MixinInventoryMenu { + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/Slot;hasItem()Z", ordinal = 1)) + private boolean disableShiftClickArmor(Slot instance) { + return instance.hasItem() || ViaFabricPlus.api().targetVersion().olderThan(LegacyProtocolVersion.r1_3_1tor1_3_2); + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_4_4/MixinMultiPlayerGameMode.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_4_4/MixinMultiPlayerGameMode.java new file mode 100644 index 000000000..c27b3b8c1 --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_4_4/MixinMultiPlayerGameMode.java @@ -0,0 +1,44 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.v1_4_4; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.ContainerInput; +import net.raphimc.vialegacy.api.LegacyProtocolVersion; +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(MultiPlayerGameMode.class) +public abstract class MixinMultiPlayerGameMode { + + @Inject(method = "handleContainerInput", at = @At("HEAD"), cancellable = true) + private void cancelQuickMoveWithNegativeSlotNumber(int containerId, int slotNum, int buttonNum, ContainerInput containerInput, Player player, CallbackInfo ci) { + if (slotNum < 0 && containerInput.equals(ContainerInput.QUICK_MOVE) && ViaFabricPlus.api().targetVersion().olderThanOrEqualTo(LegacyProtocolVersion.r1_4_4tor1_4_5)) { + ci.cancel(); + } + } + +} diff --git a/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_8/screen/MixinEnchantmentMenu.java b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_8/screen/MixinEnchantmentMenu.java new file mode 100644 index 000000000..75e09e00a --- /dev/null +++ b/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/v1_8/screen/MixinEnchantmentMenu.java @@ -0,0 +1,54 @@ +/* + * This file is part of ViaFabricPlus - https://github.com/ViaVersion/ViaFabricPlus + * Copyright (C) 2021-2026 the original authors + * - Florian Reuth + * - RK_01/RaphiMC + * Copyright (C) 2023-2026 ViaVersion and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.viaversion.viafabricplus.injection.mixin.features.v1_8.screen; + +import com.viaversion.viafabricplus.ViaFabricPlus; +import com.viaversion.viaversion.api.protocol.version.ProtocolVersion; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.EnchantmentMenu; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import org.jspecify.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + + +@Mixin(EnchantmentMenu.class) +public abstract class MixinEnchantmentMenu extends AbstractContainerMenu { + + protected MixinEnchantmentMenu(@Nullable final MenuType menuType, final int containerId) { + super(menuType, containerId); + } + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/EnchantmentMenu;moveItemStackTo(Lnet/minecraft/world/item/ItemStack;IIZ)Z", ordinal = 1)) + private boolean disableShiftClickLapisLazuliSlot(EnchantmentMenu instance, ItemStack itemStack, int startSlot, int endSlot, boolean backwards) { + return ViaFabricPlus.api().targetVersion().newerThanOrEqualTo(ProtocolVersion.v1_8) && this.moveItemStackTo(itemStack, startSlot, endSlot, backwards); + } + + @Redirect(method = "quickMoveStack", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;is(Ljava/lang/Object;)Z")) + private boolean disableShiftClickLapisLazuliIntoLapisLazuliSlot(ItemStack instance, Object lapisLazuli) { + return instance.is((Item) lapisLazuli) && ViaFabricPlus.api().targetVersion().newerThanOrEqualTo(ProtocolVersion.v1_8); + } + +} diff --git a/src/main/resources/viafabricplus.accesswidener b/src/main/resources/viafabricplus.accesswidener index 29d1a8f3d..466c77c68 100644 --- a/src/main/resources/viafabricplus.accesswidener +++ b/src/main/resources/viafabricplus.accesswidener @@ -53,3 +53,6 @@ accessible class net/minecraft/client/multiplayer/ClientPacketListener$CommandCh accessible class net/minecraft/world/entity/EntityFluidInteraction$CurrentAccumulator accessible class net/minecraft/client/gui/screens/debug/GameModeSwitcherScreen$GameModeIcon accessible class net/minecraft/client/gui/Font$PreparedTextBuilder +accessible class net/minecraft/world/inventory/BrewingStandMenu$PotionSlot +accessible class net/minecraft/world/inventory/BrewingStandMenu$FuelSlot +accessible class net/minecraft/world/inventory/BrewingStandMenu$IngredientsSlot diff --git a/src/main/resources/viafabricplus.mixins.json b/src/main/resources/viafabricplus.mixins.json index c452fa290..c99f15f82 100644 --- a/src/main/resources/viafabricplus.mixins.json +++ b/src/main/resources/viafabricplus.mixins.json @@ -38,8 +38,15 @@ "core.integration.event.MixinMinecraft", "core.integration.sync_tasks.MixinClientCommonPacketListenerImpl", "core.performance.MixinServerStatusPinger", + "features.b1_4.MixinChestMenu", "features.b1_5.MixinLivingEntity", + "features.b1_5.MixinAbstractFurnaceMenu", + "features.b1_5.MixinChestMenu", + "features.b1_5.MixinInventoryMenu", + "features.b1_5.MixinCraftingMenu", + "features.b1_7.MixinDispenserMenu", "features.b1_7.MixinBowItem", + "features.b1_7.MixinAbstractContainerMenu", "features.b1_7.MixinHud", "features.b1_7.MixinMultiPlayerGameMode", "features.b1_7.MixinServerSelectionList_OnlineServerEntry", @@ -336,13 +343,16 @@ "features.v1_21_9.movement.MixinLocalPlayer", "features.v1_2_1.MixinAbstractFurnaceMenu", "features.v1_3_1.MixinServerRedirectHandler", + "features.v1_3_1.MixinBrewingStandMenu", + "features.v1_3_1.MixinEnchantmentMenu", + "features.v1_3_1.MixinInventoryMenu", "features.v1_4_2.MixinAbstractContainerScreen", "features.v1_4_2.MixinChestBlock", "features.v1_4_2.MixinEnderChestBlock", + "features.v1_4_4.MixinMultiPlayerGameMode", "features.v1_4_6.MixinBlockBehaviour", "features.v1_5.MixinAbstractContainerScreen", "features.v1_5_2.MixinLocalPlayer", - "features.v1_6_1.MixinAbstractContainerScreen", "features.v1_6_4.MixinEntityPacketRewriter1_20_5", "features.v1_7_6.MixinCarpetBlock", "features.v1_7_6.MixinMinecraft", @@ -381,6 +391,10 @@ "features.v1_8.screen.MixinBrewingStandMenu_FuelSlot", "features.v1_8.screen.MixinCommandBlockEditScreen", "features.v1_8.screen.MixinInventoryMenu", + "features.v1_8.screen.MixinEnchantmentMenu", + "features.v1_10.MixinBrewingStandMenu_IngredientSlot", + "features.v1_10.MixinBrewingStandMenu", + "features.v1_10.MixinBrewingStandMenu_FuelSlot", "features.v1_9_3.MixinFarmlandBlock", "features.v1_9_3.MixinLivingEntity", "features.v1_9_3.network.MixinChatScreen",