Skip to content

Commit

Permalink
Fix NPE on furnace interrupt
Browse files Browse the repository at this point in the history
  • Loading branch information
aromaa committed Jan 20, 2024
1 parent 6306a4d commit ea72580
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* This file is part of Sponge, licensed under the MIT License (MIT).
*
* Copyright (c) SpongePowered <https://www.spongepowered.org>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.spongepowered.common.bridge.block.entity;

import net.minecraft.world.item.crafting.AbstractCookingRecipe;
import net.minecraft.world.item.crafting.RecipeHolder;

import java.util.Optional;

public interface AbstractFurnaceBlockEntityBridge {

Optional<? extends RecipeHolder<? extends AbstractCookingRecipe>> bridge$getCurrentRecipe();

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,15 @@
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.common.SpongeCommon;
import org.spongepowered.common.bridge.block.entity.AbstractFurnaceBlockEntityBridge;
import org.spongepowered.common.event.tracking.PhaseTracker;
import org.spongepowered.common.item.util.ItemStackUtil;

import java.util.Collections;
import java.util.Optional;

@Mixin(AbstractFurnaceBlockEntity.class)
public abstract class AbstractFurnaceBlockEntityMixin extends BaseContainerBlockEntityMixin {
public abstract class AbstractFurnaceBlockEntityMixin extends BaseContainerBlockEntityMixin implements AbstractFurnaceBlockEntityBridge {

// @Formatter:off
@Shadow protected NonNullList<ItemStack> items;
Expand All @@ -80,9 +81,9 @@ public abstract class AbstractFurnaceBlockEntityMixin extends BaseContainerBlock
final ItemStackSnapshot shrinkedFuel = ItemStackUtil.snapshotOf(ItemStackUtil.cloneDefensive(itemStack, itemStack.getCount() - 1));

final Transaction<ItemStackSnapshot> transaction = new Transaction<>(fuel, shrinkedFuel);
final var recipe = ((AbstractFurnaceBlockEntityMixin) (Object) entity).impl$getCurrentRecipe();
final var recipe = ((AbstractFurnaceBlockEntityMixin) (Object) entity).bridge$getCurrentRecipe();
final CookingEvent.ConsumeFuel event = SpongeEventFactory.createCookingEventConsumeFuel(cause, (FurnaceBlockEntity) entity, Optional.of(fuel),
Optional.of((CookingRecipe) recipe.value()), Optional.of((ResourceKey) (Object) recipe.id()), Collections.singletonList(transaction));
recipe.map(r -> (CookingRecipe) r.value()), recipe.map(r -> (ResourceKey) (Object) r.id()), Collections.singletonList(transaction));
SpongeCommon.post(event);
if (event.isCancelled()) {
((AbstractFurnaceBlockEntityMixin) (Object) entity).cookingTotalTime = 0;
Expand All @@ -100,8 +101,9 @@ public abstract class AbstractFurnaceBlockEntityMixin extends BaseContainerBlock
}
}

private RecipeHolder<? extends AbstractCookingRecipe> impl$getCurrentRecipe() {
return this.quickCheck.getRecipeFor((AbstractFurnaceBlockEntity) (Object) this, this.level).orElse(null);
@Override
public Optional<? extends RecipeHolder<? extends AbstractCookingRecipe>> bridge$getCurrentRecipe() {
return this.quickCheck.getRecipeFor((AbstractFurnaceBlockEntity) (Object) this, this.level);
}

// Interrupt-Active - e.g. a player removing the currently smelting item
Expand Down Expand Up @@ -144,9 +146,9 @@ public abstract class AbstractFurnaceBlockEntityMixin extends BaseContainerBlock
if (this.cookingProgress > 0) {
final ItemStackSnapshot fuel = ItemStackUtil.snapshotOf(this.items.get(1));
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final var recipe = this.impl$getCurrentRecipe();
final var recipe = this.bridge$getCurrentRecipe();
final CookingEvent.Interrupt event = SpongeEventFactory.createCookingEventInterrupt(cause, (FurnaceBlockEntity) this, Optional.of(fuel),
Optional.ofNullable((CookingRecipe) recipe.value()), Optional.of((ResourceKey) (Object) recipe.id()));
recipe.map(r -> (CookingRecipe) r.value()), recipe.map(r -> (ResourceKey) (Object) r.id()));
SpongeCommon.post(event);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import org.spongepowered.common.SpongeCommon;
import org.spongepowered.common.accessor.world.level.block.entity.AbstractFurnaceBlockEntityAccessor;
import org.spongepowered.common.bridge.block.entity.AbstractFurnaceBlockEntityBridge;
import org.spongepowered.common.event.tracking.PhaseTracker;
import org.spongepowered.common.item.util.ItemStackUtil;
import org.spongepowered.common.mixin.core.world.level.block.entity.BaseContainerBlockEntityMixin;
Expand All @@ -61,18 +62,14 @@
import java.util.Optional;

@Mixin(AbstractFurnaceBlockEntity.class)
public abstract class AbstractFurnaceBlockEntityMixin_Vanilla extends BaseContainerBlockEntityMixin {
public abstract class AbstractFurnaceBlockEntityMixin_Vanilla extends BaseContainerBlockEntityMixin implements AbstractFurnaceBlockEntityBridge {

// @formatter:off
@Shadow protected NonNullList<ItemStack> items;
@Shadow int cookingProgress;
@Shadow @Final private RecipeManager.CachedCheck<Container, ? extends AbstractCookingRecipe> quickCheck;
// @formatter:on

private RecipeHolder<? extends AbstractCookingRecipe> impl$getCurrentRecipe() {
return this.quickCheck.getRecipeFor((AbstractFurnaceBlockEntity) (Object) this, this.level).orElse(null);
}

// Tick up and Start
@Redirect(method = "serverTick",
at = @At(value = "INVOKE",
Expand Down Expand Up @@ -107,10 +104,10 @@ public abstract class AbstractFurnaceBlockEntityMixin_Vanilla extends BaseContai
final int clampedCookTime = Mth.clamp(newCookTime, zero, totalCookTime);
final ItemStackSnapshot fuel = ItemStackUtil.snapshotOf(((AbstractFurnaceBlockEntityMixin_Vanilla) (Object) entity).items.get(1));
final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
final var recipe = ((AbstractFurnaceBlockEntityMixin_Vanilla) (Object) entity).impl$getCurrentRecipe();
final var recipe = ((AbstractFurnaceBlockEntityMixin_Vanilla) (Object) entity).bridge$getCurrentRecipe();
final ItemStackSnapshot cooking = ItemStackUtil.snapshotOf(((AbstractFurnaceBlockEntityMixin_Vanilla) (Object) entity).items.get(0));
final CookingEvent.Tick event = SpongeEventFactory.createCookingEventTick(cause, (FurnaceBlockEntity) entity, cooking, Optional.of(fuel),
Optional.of((CookingRecipe) recipe.value()), Optional.of((ResourceKey) (Object) recipe.id()));
recipe.map(r -> (CookingRecipe) r.value()), recipe.map(r -> (ResourceKey) (Object) r.id()));
SpongeCommon.post(event);
if (event.isCancelled()) {
return ((AbstractFurnaceBlockEntityMixin_Vanilla) (Object) entity).cookingProgress; // dont tick down
Expand Down

0 comments on commit ea72580

Please sign in to comment.