Skip to content

Commit

Permalink
Update to Minecraft 1.21
Browse files Browse the repository at this point in the history
  • Loading branch information
Ampflower committed Sep 30, 2024
1 parent 050894d commit 732f64f
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 73 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
org.gradle.jvmargs=-Xmx1G

# Mod Properties
projectVersion=4.3.2
projectVersion=4.4.0
maven_group=gay.ampflower.mod

curseforgeId=914551
Expand Down
6 changes: 3 additions & 3 deletions libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[versions]

# Minecraft
minecraft_version = "1.20.4"
minecraft_required = "~1.20.3-"
minecraft_compatible = "1.20.3,1.20.4,1.20.5,1.20.6"
minecraft_version = "1.21"
minecraft_required = "~1.21"
minecraft_compatible = "1.21,1.21.1"

fabric_loader = "0.15.+"

Expand Down
43 changes: 29 additions & 14 deletions src/main/java/tfar/fastbench/MixinHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,19 @@

package tfar.fastbench;

import net.minecraft.core.NonNullList;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.CraftingContainer;
import net.minecraft.world.inventory.ResultContainer;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingInput;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeInput;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.Level;
import tfar.fastbench.interfaces.CraftingInventoryDuck;
Expand All @@ -49,23 +51,25 @@

public final class MixinHooks {
private static final MethodHandle recipe$assemble = Reflector.virtual(Recipe.class, "method_8116",
MethodType.methodType(ItemStack.class, Container.class, RegistryAccess.class));
MethodType.methodType(ItemStack.class, CraftingInput.class, RegistryAccess.class));

public static boolean hascachedrecipe = false;

public static Recipe<CraftingContainer> lastRecipe;
public static Recipe<CraftingInput> lastRecipe;

public static void slotChangedCraftingGrid(Level level, CraftingContainer inv, ResultContainer result) {
public static void slotChangedCraftingGrid(Level level, CraftingContainer container, ResultContainer result) {
if (!level.isClientSide) {

CraftingInput input = container.asCraftInput();
ItemStack itemstack = ItemStack.EMPTY;

RecipeHolder<CraftingRecipe> recipe = coerce(result.getRecipeUsed());
if (recipe == null || !recipe.value().matches(inv, level)) recipe = findRecipe(inv, level);
if (recipe == null || !recipe.value().matches(input, level)) {
recipe = findRecipe(input, level);
}

if (recipe != null) {
try {
itemstack = (ItemStack) recipe$assemble.invoke(recipe.value(), inv, level.registryAccess());
itemstack = (ItemStack) recipe$assemble.invoke(recipe.value(), input, level.registryAccess());
} catch (Throwable t) {
throw new AssertionError(t);
}
Expand All @@ -77,21 +81,24 @@ public static void slotChangedCraftingGrid(Level level, CraftingContainer inv, R
}
}

public static ItemStack handleShiftCraft(Player player, AbstractContainerMenu container, Slot resultSlot, CraftingContainer input, ResultContainer craftResult, int outStart, int outEnd) {
public static ItemStack handleShiftCraft(
Player player, AbstractContainerMenu menu, Slot resultSlot, CraftingContainer container,
ResultContainer craftResult, int outStart, int outEnd) {
ItemStack outputCopy = ItemStack.EMPTY;
CraftingInventoryDuck duck = (CraftingInventoryDuck) input;
CraftingInput input = container.asCraftInput();
CraftingInventoryDuck duck = (CraftingInventoryDuck) container;
duck.setCheckMatrixChanges(false);
RecipeHolder<CraftingRecipe> recipeHolder = coerce(craftResult.getRecipeUsed());

if (recipeHolder != null && resultSlot != null && resultSlot.hasItem()) {
final Recipe<CraftingContainer> recipe = recipeHolder.value();
final Recipe<CraftingInput> recipe = recipeHolder.value();
while (recipe.matches(input, player.level())) {
ItemStack recipeOutput = resultSlot.getItem().copy();
outputCopy = recipeOutput.copy();

recipeOutput.getItem().onCraftedBy(recipeOutput, player.level(), player);

if (!player.level().isClientSide && !((ContainerAccessor) container).insert(recipeOutput, outStart, outEnd, true)) {
if (!player.level().isClientSide && !((ContainerAccessor) menu).insert(recipeOutput, outStart, outEnd, true)) {
duck.setCheckMatrixChanges(true);
return ItemStack.EMPTY;
}
Expand All @@ -109,7 +116,7 @@ public static ItemStack handleShiftCraft(Player player, AbstractContainerMenu co
//player.drop(resultSlot.getItem(), false);
}
duck.setCheckMatrixChanges(true);
slotChangedCraftingGrid(player.level(), input, craftResult);
slotChangedCraftingGrid(player.level(), container, craftResult);

// Award the player the recipe for using it. Mimics vanilla behaviour.
if (!recipe.isSpecial()) {
Expand All @@ -120,12 +127,20 @@ public static ItemStack handleShiftCraft(Player player, AbstractContainerMenu co
return recipeHolder == null ? ItemStack.EMPTY : outputCopy;
}

public static RecipeHolder<CraftingRecipe> findRecipe(CraftingContainer inv, Level level) {
public static RecipeHolder<CraftingRecipe> findRecipe(CraftingInput inv, Level level) {
return level.getRecipeManager().getRecipeFor(RecipeType.CRAFTING, inv, level).orElse(null);
}

@SuppressWarnings("unchecked")
public static <C extends Container, T extends Recipe<C>> RecipeHolder<T> coerce(RecipeHolder<?> in) {
public static <I extends RecipeInput, T extends Recipe<I>> RecipeHolder<T> coerce(RecipeHolder<?> in) {
return (RecipeHolder<T>) in;
}

public static NonNullList<ItemStack> copy(RecipeInput recipeInput) {
final var list = NonNullList.withSize(recipeInput.size(), ItemStack.EMPTY);
for (int i = 0; i < recipeInput.size(); i++) {
list.set(i, recipeInput.getItem(i));
}
return list;
}
}
27 changes: 0 additions & 27 deletions src/main/java/tfar/fastbench/mixin/CraftingInventoryAccessor.java

This file was deleted.

15 changes: 10 additions & 5 deletions src/main/java/tfar/fastbench/mixin/CraftingMenuMixin.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023 Ampflower
* Copyright (c) 2022-2024 Ampflower
* Copyright (c) 2020-2021 Tfarcenim
* Copyright (c) 2018-2021 Brennan Ward
*
Expand All @@ -26,7 +26,6 @@

package tfar.fastbench.mixin;

import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.CraftingContainer;
Expand All @@ -35,6 +34,9 @@
import net.minecraft.world.inventory.RecipeBookMenu;
import net.minecraft.world.inventory.ResultContainer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingInput;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
Expand All @@ -49,7 +51,7 @@
import tfar.fastbench.interfaces.CraftingInventoryDuck;

@Mixin(CraftingMenu.class)
abstract class CraftingMenuMixin<C extends Container> extends RecipeBookMenu<C> implements CraftingInventoryDuck {
abstract class CraftingMenuMixin extends RecipeBookMenu<CraftingInput, CraftingRecipe> implements CraftingInventoryDuck {

@Shadow
@Final
Expand All @@ -62,8 +64,11 @@ protected CraftingMenuMixin(@Nullable MenuType<?> type, int syncId) {
super(type, syncId);
}

@Redirect(method = "method_17401", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/CraftingMenu;slotChangedCraftingGrid(Lnet/minecraft/world/inventory/AbstractContainerMenu;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/inventory/CraftingContainer;Lnet/minecraft/world/inventory/ResultContainer;)V"))
private void hookChangedCraftingGrid(AbstractContainerMenu self, Level level, Player player, CraftingContainer craftSlots, ResultContainer resultSlots) {
@Redirect(method = "method_17401", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/inventory/CraftingMenu;slotChangedCraftingGrid(Lnet/minecraft/world/inventory/AbstractContainerMenu;Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/inventory/CraftingContainer;Lnet/minecraft/world/inventory/ResultContainer;Lnet/minecraft/world/item/crafting/RecipeHolder;)V"))
private void hookChangedCraftingGrid(
final AbstractContainerMenu self, final Level level, final Player player,
final CraftingContainer craftSlots, final ResultContainer resultSlots,
final RecipeHolder<CraftingRecipe> recipeHolder) {
MixinHooks.slotChangedCraftingGrid(level, craftSlots, resultSlots);
}

Expand Down
10 changes: 6 additions & 4 deletions src/main/java/tfar/fastbench/mixin/CraftingResultSlotMixin.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023 Ampflower
* Copyright (c) 2022-2024 Ampflower
* Copyright (c) 2020-2021 Tfarcenim
* Copyright (c) 2018-2021 Brennan Ward
*
Expand Down Expand Up @@ -27,6 +27,7 @@
package tfar.fastbench.mixin;


import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.CraftingContainer;
Expand All @@ -35,6 +36,7 @@
import net.minecraft.world.inventory.ResultSlot;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingInput;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.RecipeHolder;
import org.spongepowered.asm.mixin.Final;
Expand Down Expand Up @@ -97,10 +99,10 @@ public void no(final RecipeCraftingHolder instance, final Player player, final L

//this.container is actually the crafting result inventory so it's a safe cast
//using an inject instead of a redirect as a workaround for tech reborn's BS
@Inject(method = "onTake", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/crafting/RecipeManager;getRemainingItemsFor(Lnet/minecraft/world/item/crafting/RecipeType;Lnet/minecraft/world/Container;Lnet/minecraft/world/level/Level;)Lnet/minecraft/core/NonNullList;"))
private void cache(Player player, ItemStack stack, CallbackInfo ci) {
@Inject(method = "onTake", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/crafting/RecipeManager;getRemainingItemsFor(Lnet/minecraft/world/item/crafting/RecipeType;Lnet/minecraft/world/item/crafting/RecipeInput;Lnet/minecraft/world/level/Level;)Lnet/minecraft/core/NonNullList;"))
private void cache(Player player, ItemStack stack, CallbackInfo ci, @Local CraftingInput input) {
RecipeHolder<CraftingRecipe> lastRecipe = MixinHooks.coerce(((ResultContainer) this.container).getRecipeUsed());
MixinHooks.lastRecipe = lastRecipe != null && lastRecipe.value().matches(craftSlots, player.level()) ? lastRecipe.value() : null;
MixinHooks.lastRecipe = lastRecipe != null && lastRecipe.value().matches(input, player.level()) ? lastRecipe.value() : null;
MixinHooks.hascachedrecipe = true;
}
}
29 changes: 15 additions & 14 deletions src/main/java/tfar/fastbench/mixin/RecipeManagerMixin.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
* Copyright (c) 2024 Ampflower
* Copyright (c) 2020-2021 Tfarcenim
*
* This software is subject to the terms of the MIT License.
Expand All @@ -15,10 +16,10 @@
package tfar.fastbench.mixin;

import net.minecraft.core.NonNullList;
import net.minecraft.world.Container;
import net.minecraft.world.inventory.CraftingContainer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingInput;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeInput;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.Level;
Expand All @@ -31,17 +32,17 @@
@Mixin(RecipeManager.class)
public class RecipeManagerMixin {

//note: C is actually CraftingInventory, treat it accordingly
@Inject(method = "getRemainingItemsFor",at = @At("HEAD"),cancellable = true)
private <C extends Container, T extends Recipe<C>> void techRebornWorkAround(RecipeType<T> recipeType, C craftInput, Level world, CallbackInfoReturnable<NonNullList<ItemStack>> cir) {
// Explicit check on CraftingInventoryAccessor resolves crash relating to Traveler's Backpack
if (MixinHooks.hascachedrecipe && craftInput instanceof CraftingInventoryAccessor accessor) {
if (MixinHooks.lastRecipe != null) {
cir.setReturnValue(MixinHooks.lastRecipe.getRemainingItems((CraftingContainer) craftInput));
} else {
cir.setReturnValue(accessor.getItems());
}
MixinHooks.hascachedrecipe = false;
}
}
private <C extends RecipeInput, T extends Recipe<C>> void techRebornWorkAround(
RecipeType<T> recipeType, C craftInput, Level world, CallbackInfoReturnable<NonNullList<ItemStack>> cir) {
if (!MixinHooks.hascachedrecipe || !(craftInput instanceof CraftingInput craftingInput)) {
return;
}
if (MixinHooks.lastRecipe != null) {
cir.setReturnValue(MixinHooks.lastRecipe.getRemainingItems(craftingInput));
} else {
cir.setReturnValue(MixinHooks.copy(craftingInput));
}
MixinHooks.hascachedrecipe = false;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022-2023 Ampflower
* Copyright (c) 2022-2024 Ampflower
*
* This software is subject to the terms of either the MIT or CC0-1.0 Licenses.
* If a copy was not distributed with this file, you can obtain one at
Expand All @@ -18,8 +18,9 @@
package tfar.fastbench.mixin;// Created 2022-05-12T13:17:33

import net.minecraft.recipebook.ServerPlaceRecipe;
import net.minecraft.world.Container;
import net.minecraft.world.inventory.RecipeBookMenu;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeInput;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
Expand All @@ -32,9 +33,9 @@
* @since ${version}
**/
@Mixin(ServerPlaceRecipe.class)
public class ServerPlaceRecipeMixin<C extends Container> {
public class ServerPlaceRecipeMixin<I extends RecipeInput, R extends Recipe<I>> {
@Shadow
protected RecipeBookMenu<C> menu;
protected RecipeBookMenu<I, R> menu;

/**
* Inhibits the matrix check to avoid doing expensive checks for recipes while the inventory is being cleared.
Expand Down
1 change: 0 additions & 1 deletion src/main/resources/quickbench.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"mixins": [
"ContainerAccessor",
"CraftingContainerMixin",
"CraftingInventoryAccessor",
"CraftingMenuMixin",
"CraftingResultSlotMixin",
"PlayerContainerMixin",
Expand Down

0 comments on commit 732f64f

Please sign in to comment.