Skip to content

Commit

Permalink
Fix item insertion into Condenser giving free singularities under som…
Browse files Browse the repository at this point in the history
…e circumstances (#7506)

For some reason we never made the item inventory transactional, EVER.
This bug has existed since the dawn of Fabric Transfer API
  • Loading branch information
shartte authored Dec 25, 2023
1 parent 5c6c1f4 commit 31a29fe
Showing 1 changed file with 21 additions and 19 deletions.
40 changes: 21 additions & 19 deletions src/main/java/appeng/blockentity/misc/CondenserBlockEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@

package appeng.blockentity.misc;

import java.util.Collections;
import java.util.Iterator;

import net.fabricmc.fabric.api.transfer.v1.fluid.FluidVariant;
import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant;
import net.fabricmc.fabric.api.transfer.v1.storage.Storage;
import net.fabricmc.fabric.api.transfer.v1.storage.StorageView;
import net.fabricmc.fabric.api.transfer.v1.storage.base.InsertionOnlyStorage;
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
import net.fabricmc.fabric.api.transfer.v1.transaction.base.SnapshotParticipant;
Expand Down Expand Up @@ -63,7 +60,9 @@ public class CondenserBlockEntity extends AEBaseInvBlockEntity implements IConfi
private final AppEngInternalInventory outputSlot = new AppEngInternalInventory(this, 1);
private final AppEngInternalInventory storageSlot = new AppEngInternalInventory(this, 1);
private final InternalInventory inputSlot = new CondenseItemHandler();
private final Storage<FluidVariant> fluidHandler = new FluidHandler();
private final Storage<FluidVariant> fluidHandler = new CondenseStorage<>(
1.0 / AEKeyType.fluids().getAmountPerOperation(),
AEFluidKey.AMOUNT_BUCKET);

/**
* This is used to expose a fake ME subnetwork that is only composed of this condenser. The purpose of this is to
Expand Down Expand Up @@ -225,27 +224,30 @@ public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
public ItemStack extractItem(int slot, int amount, boolean simulate) {
return ItemStack.EMPTY;
}

@Override
protected Storage<ItemVariant> createStorage() {
return new CondenseStorage<>(1.0, Long.MAX_VALUE);
}
}

/**
* A fluid handler that exposes a 1 bucket tank that can only be filled, and - when filled - will add power to this
* condenser.
*/
private class FluidHandler extends SnapshotParticipant<Double> implements InsertionOnlyStorage<FluidVariant> {
private class CondenseStorage<T> extends SnapshotParticipant<Double> implements InsertionOnlyStorage<T> {
private double pendingEnergy = 0;
private final double energyFactor;
private final long maxAmountPerOperation;

@Override
public long insert(FluidVariant resource, long maxAmount, TransactionContext transaction) {
// We allow up to a bucket per insert
var amount = Math.min(AEFluidKey.AMOUNT_BUCKET, maxAmount);
updateSnapshots(transaction);
pendingEnergy += amount / AEKeyType.fluids().getAmountPerOperation();
return amount;
public CondenseStorage(double energyFactor, long maxAmountPerOperation) {
this.energyFactor = energyFactor;
this.maxAmountPerOperation = maxAmountPerOperation;
}

@Override
public Iterator<StorageView<FluidVariant>> iterator() {
return Collections.emptyIterator();
public long insert(T resource, long maxAmount, TransactionContext transaction) {
// Clamp the amount per operation
var amount = Math.min(maxAmountPerOperation, maxAmount);
updateSnapshots(transaction);
pendingEnergy += amount * energyFactor;
return amount;
}

@Override
Expand Down

0 comments on commit 31a29fe

Please sign in to comment.