Skip to content

Commit fd19d2e

Browse files
committed
feat: guard against use of storages linked to invalidated block entities
1 parent 5362b8c commit fd19d2e

20 files changed

+87
-39
lines changed

.github/workflows/codeql.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
uses: actions/checkout@v4
1616

1717
- name: Validate Gradle wrapper
18-
uses: gradle/actions/wrapper-validation@v3
18+
uses: gradle/actions/wrapper-validation@v4
1919

2020
- name: Setup JDK 21
2121
uses: actions/setup-java@v4

.github/workflows/commit.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
uses: actions/checkout@v4
1313

1414
- name: Validate Gradle wrapper
15-
uses: gradle/actions/wrapper-validation@v3
15+
uses: gradle/actions/wrapper-validation@v4
1616

1717
- name: Setup JDK 21
1818
uses: actions/setup-java@v4

.github/workflows/pr_check.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
uses: actions/checkout@v4
1414

1515
- name: Validate Gradle wrapper
16-
uses: gradle/actions/wrapper-validation@v3
16+
uses: gradle/actions/wrapper-validation@v4
1717

1818
- name: Setup JDK 21
1919
uses: actions/setup-java@v4

build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ plugins {
4747
id("fabric-loom") version("1.7-SNAPSHOT")
4848
id("org.cadixdev.licenser") version("0.6.1")
4949
id("org.ajoberstar.grgit") version("5.2.2")
50-
id("dev.galacticraft.mojarn") version("0.4.0+9")
50+
id("dev.galacticraft.mojarn") version("0.4.0+10")
5151
}
5252

5353
group = "dev.galacticraft"

gradle.properties

+7-7
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ mod.name=MachineLib
66
mod.version=0.7.0
77

88
# Minecraft and Fabric Loader
9-
minecraft.version=1.21
9+
minecraft.version=1.21.1
1010
loader.version=0.15.11
11-
yarn.build=8
11+
yarn.build=3
1212

1313
# Mod Dependencies
1414
badpackets.version=0.8.1
1515
energy.version=4.1.0
16-
fabric.version=0.100.6+1.21
16+
fabric.version=0.102.1+1.21.1
1717

1818
# Optional Mod Dependencies
19-
cloth.config.version=15.0.127
19+
cloth.config.version=15.0.130
2020
modmenu.version=11.0.1
21-
rei.version=16.0.729
22-
architectury.version=13.0.3
23-
wthit.version=12.2.2
21+
rei.version=16.0.754
22+
architectury.version=13.0.6
23+
wthit.version=12.3.0

gradle/wrapper/gradle-wrapper.jar

130 Bytes
Binary file not shown.

gradle/wrapper/gradle-wrapper.properties

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612
4-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
3+
distributionSha256Sum=5b9c5eb3f9fc2c94abaea57d90bd78747ca117ddbbf96c859d3741181a12bf2a
4+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
55
networkTimeout=10000
66
validateDistributionUrl=true
77
zipStoreBase=GRADLE_USER_HOME

gradlew

+4-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
1717
#
18+
# SPDX-License-Identifier: Apache-2.0
19+
#
1820

1921
##############################################################################
2022
#
@@ -84,7 +86,8 @@ done
8486
# shellcheck disable=SC2034
8587
APP_BASE_NAME=${0##*/}
8688
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
87-
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
89+
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
90+
' "$PWD" ) || exit
8891

8992
# Use the maximum available, or set MAX_FD != -1 to use that value.
9093
MAX_FD=maximum

gradlew.bat

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
@rem See the License for the specific language governing permissions and
1414
@rem limitations under the License.
1515
@rem
16+
@rem SPDX-License-Identifier: Apache-2.0
17+
@rem
1618

1719
@if "%DEBUG%"=="" @echo off
1820
@rem ##########################################################################

src/main/java/dev/galacticraft/machinelib/api/compat/transfer/ExposedEnergyStorage.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
package dev.galacticraft.machinelib.api.compat.transfer;
2424

25+
import dev.galacticraft.machinelib.api.storage.MachineEnergyStorage;
2526
import dev.galacticraft.machinelib.impl.storage.exposed.ExposedEnergyStorageImpl;
2627
import org.jetbrains.annotations.Contract;
2728
import org.jetbrains.annotations.NotNull;
@@ -40,7 +41,7 @@ public interface ExposedEnergyStorage extends EnergyStorage {
4041
* @return A new exposed energy storage.
4142
*/
4243
@Contract("_, _, _ -> new")
43-
static @NotNull ExposedEnergyStorage create(@NotNull EnergyStorage parent, long maxInsertion, long maxExtraction) {
44+
static @NotNull ExposedEnergyStorage create(@NotNull MachineEnergyStorage parent, long maxInsertion, long maxExtraction) {
4445
return new ExposedEnergyStorageImpl(parent, maxInsertion, maxExtraction);
4546
}
4647
}

src/main/java/dev/galacticraft/machinelib/api/storage/MachineEnergyStorage.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import net.fabricmc.fabric.api.transfer.v1.storage.StoragePreconditions;
3535
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
3636
import net.minecraft.nbt.LongTag;
37+
import net.minecraft.world.level.block.entity.BlockEntity;
3738
import org.jetbrains.annotations.ApiStatus;
3839
import org.jetbrains.annotations.Contract;
3940
import org.jetbrains.annotations.NotNull;
@@ -204,10 +205,15 @@ public interface MachineEnergyStorage extends EnergyStorage, Serializable<LongTa
204205
long externalExtractionRate();
205206

206207
/**
207-
* Sets the listener (called when the energy storage changes). Internal use only.
208+
* Sets the parent of this energy storage (notified when the energy storage changes). Internal use only.
208209
*/
209210
@ApiStatus.Internal
210-
void setListener(Runnable listener);
211+
void setParent(BlockEntity parent);
212+
213+
/**
214+
* {@return whether the energy storage should still be interacted with}
215+
*/
216+
boolean isValid();
211217

212218
record Spec(long capacity, long insertion, long extraction) {
213219
public Spec {

src/main/java/dev/galacticraft/machinelib/api/storage/ResourceStorage.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import net.fabricmc.fabric.api.transfer.v1.storage.TransferVariant;
3333
import net.minecraft.nbt.ListTag;
3434
import net.minecraft.network.RegistryFriendlyByteBuf;
35+
import net.minecraft.world.level.block.entity.BlockEntity;
3536
import org.jetbrains.annotations.NotNull;
3637
import org.jetbrains.annotations.Nullable;
3738

@@ -44,11 +45,13 @@
4445
*/
4546
public interface ResourceStorage<Resource, Slot extends ResourceSlot<Resource>> extends Iterable<Slot>, MutableModifiable, SlottedStorageAccess<Resource, Slot>, Serializable<ListTag>, DeltaPacketSerializable<RegistryFriendlyByteBuf, long[]>, PacketSerializable<RegistryFriendlyByteBuf> {
4647
/**
47-
* Set the listener for this storage. This listener will be called whenever the storage is modified.
48+
* Set the parent for this storage. This parent will be notified whenever the storage is modified.
4849
*
49-
* @param listener the listener to set.
50+
* @param parent the parent of this storage.
5051
*/
51-
void setListener(Runnable listener);
52+
void setParent(BlockEntity parent);
53+
54+
boolean isValid();
5255

5356
/**
5457
* Create an exposed storage for this storage.

src/main/java/dev/galacticraft/machinelib/api/storage/slot/ResourceSlot.java

+5
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@
4747
* @see StorageAccess
4848
*/
4949
public interface ResourceSlot<Resource> extends StorageAccess<Resource>, MutableModifiable, Serializable<CompoundTag>, PacketSerializable<RegistryFriendlyByteBuf> {
50+
/**
51+
* {@return whether this slot should still be interacted with}
52+
*/
53+
boolean isValid();
54+
5055
/**
5156
* {@return the way this slot is allowed to be interacted with}
5257
* Governs in-world (block-to-block) and player (menu) interactions.

src/main/java/dev/galacticraft/machinelib/impl/compat/transfer/ExposedSlotImpl.java

+4-4
Original file line numberDiff line numberDiff line change
@@ -50,24 +50,24 @@ public ExposedSlotImpl(@NotNull ResourceSlot<Resource> slot, @NotNull ResourceFl
5050

5151
@Override
5252
public long insert(Variant variant, long maxAmount, TransactionContext transaction) {
53-
return this.insertion && this.slot.getFilter().test(variant.getObject(), variant.getComponents()) ?
53+
return this.supportsInsertion() && this.slot.getFilter().test(variant.getObject(), variant.getComponents()) ?
5454
this.slot.insert(variant.getObject(), variant.getComponents(), maxAmount, transaction)
5555
: 0;
5656
}
5757

5858
@Override
5959
public long extract(Variant variant, long maxAmount, TransactionContext transaction) {
60-
return this.extraction ? this.slot.extract(variant.getObject(), variant.getComponents(), maxAmount, transaction) : 0;
60+
return this.supportsExtraction() ? this.slot.extract(variant.getObject(), variant.getComponents(), maxAmount, transaction) : 0;
6161
}
6262

6363
@Override
6464
public boolean supportsInsertion() {
65-
return this.insertion;
65+
return this.insertion && this.slot.isValid() ;
6666
}
6767

6868
@Override
6969
public boolean supportsExtraction() {
70-
return this.extraction;
70+
return this.extraction && this.slot.isValid() ;
7171
}
7272

7373
@Override

src/main/java/dev/galacticraft/machinelib/impl/compat/transfer/ExposedStorageImpl.java

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public ExposedStorageImpl(ResourceStorage<Resource, ?> storage, ExposedSlot<Reso
4444

4545
@Override
4646
public boolean supportsInsertion() {
47+
if (!this.storage.isValid()) return false;
4748
for (ExposedSlot<Resource, Variant> slot : this.slots) {
4849
if (slot.supportsInsertion()) {
4950
return true;
@@ -54,6 +55,7 @@ public boolean supportsInsertion() {
5455

5556
@Override
5657
public boolean supportsExtraction() {
58+
if (!this.storage.isValid()) return false;
5759
for (ExposedSlot<Resource, Variant> slot : this.slots) {
5860
if (slot.supportsExtraction()) {
5961
return true;
@@ -64,6 +66,7 @@ public boolean supportsExtraction() {
6466

6567
@Override
6668
public long insert(Variant variant, long maxAmount, TransactionContext transaction) {
69+
if (!this.storage.isValid()) return 0;
6770
long requested = maxAmount;
6871
for (ExposedSlot<Resource, Variant> slot : this.slots) {
6972
if (maxAmount == 0) return requested;
@@ -74,6 +77,7 @@ public long insert(Variant variant, long maxAmount, TransactionContext transacti
7477

7578
@Override
7679
public long extract(Variant variant, long maxAmount, TransactionContext transaction) {
80+
if (!this.storage.isValid()) return 0;
7781
long requested = maxAmount;
7882
for (ExposedSlot<Resource, Variant> slot : this.slots) {
7983
if (maxAmount == 0) return requested;

src/main/java/dev/galacticraft/machinelib/impl/storage/EmptyMachineEnergyStorage.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import io.netty.buffer.ByteBuf;
2828
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
2929
import net.minecraft.nbt.LongTag;
30+
import net.minecraft.world.level.block.entity.BlockEntity;
3031
import org.jetbrains.annotations.NotNull;
3132
import org.jetbrains.annotations.Nullable;
3233
import team.reborn.energy.api.EnergyStorage;
@@ -138,7 +139,12 @@ public long externalExtractionRate() {
138139
}
139140

140141
@Override
141-
public void setListener(Runnable listener) {
142+
public void setParent(BlockEntity parent) {
143+
}
144+
145+
@Override
146+
public boolean isValid() {
147+
return true;
142148
}
143149

144150
@Override

src/main/java/dev/galacticraft/machinelib/impl/storage/MachineEnergyStorageImpl.java

+10-4
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
3030
import net.fabricmc.fabric.api.transfer.v1.transaction.base.SnapshotParticipant;
3131
import net.minecraft.nbt.LongTag;
32+
import net.minecraft.world.level.block.entity.BlockEntity;
3233
import org.jetbrains.annotations.ApiStatus;
3334
import org.jetbrains.annotations.NotNull;
3435
import org.jetbrains.annotations.Nullable;
@@ -41,7 +42,7 @@ public final class MachineEnergyStorageImpl extends SnapshotParticipant<Long> im
4142
private final long maxOutput;
4243
private final @Nullable EnergyStorage[] exposedStorages = new EnergyStorage[3];
4344
public long amount = 0;
44-
private Runnable listener;
45+
private BlockEntity parent;
4546

4647
public MachineEnergyStorageImpl(long capacity, long maxInput, long maxOutput) {
4748
this.capacity = capacity;
@@ -199,8 +200,13 @@ public long externalExtractionRate() {
199200
}
200201

201202
@Override
202-
public void setListener(Runnable listener) {
203-
this.listener = listener;
203+
public void setParent(BlockEntity parent) {
204+
this.parent = parent;
205+
}
206+
207+
@Override
208+
public boolean isValid() {
209+
return this.parent == null || !this.parent.isRemoved();
204210
}
205211

206212
@Override
@@ -235,7 +241,7 @@ public long getModifications() {
235241
}
236242

237243
private void markModified() {
238-
if (this.listener != null) this.listener.run();
244+
if (this.parent != null) this.parent.setChanged();
239245
}
240246

241247
@Override

src/main/java/dev/galacticraft/machinelib/impl/storage/ResourceStorageImpl.java

+11-5
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@
2929
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
3030
import net.minecraft.nbt.ListTag;
3131
import net.minecraft.network.RegistryFriendlyByteBuf;
32+
import net.minecraft.world.level.block.entity.BlockEntity;
3233
import org.jetbrains.annotations.NotNull;
3334
import org.jetbrains.annotations.Nullable;
3435

3536
public abstract class ResourceStorageImpl<Resource, Slot extends ResourceSlot<Resource>> extends BaseSlottedStorage<Resource, Slot> implements ResourceStorage<Resource, Slot>, TransactionContext.CloseCallback {
3637
private final LongList transactions = new LongArrayList();
3738
private long modifications = 1;
38-
private Runnable listener;
39+
private @Nullable BlockEntity parent;
3940

4041
public ResourceStorageImpl(@NotNull Slot @NotNull [] slots) {
4142
super(slots);
@@ -45,8 +46,13 @@ public ResourceStorageImpl(@NotNull Slot @NotNull [] slots) {
4546
}
4647

4748
@Override
48-
public void setListener(Runnable listener) {
49-
this.listener = listener;
49+
public void setParent(@Nullable BlockEntity parent) {
50+
this.parent = parent;
51+
}
52+
53+
@Override
54+
public boolean isValid() {
55+
return this.parent == null || !this.parent.isRemoved();
5056
}
5157

5258
@Override
@@ -57,7 +63,7 @@ public long getModifications() {
5763
@Override
5864
public void markModified() {
5965
this.modifications++;
60-
if (this.listener != null) this.listener.run();
66+
if (this.parent != null) this.parent.setChanged();
6167
}
6268

6369
@Override
@@ -92,7 +98,7 @@ public void onClose(TransactionContext transaction, TransactionContext.Result re
9298
this.transactions.clear();
9399
transaction.addOuterCloseCallback((res) -> {
94100
assert res.wasCommitted();
95-
if (this.listener != null) this.listener.run();
101+
if (this.parent != null) this.parent.setChanged();
96102
});
97103
}
98104
}

src/main/java/dev/galacticraft/machinelib/impl/storage/exposed/ExposedEnergyStorageImpl.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
package dev.galacticraft.machinelib.impl.storage.exposed;
2424

2525
import dev.galacticraft.machinelib.api.compat.transfer.ExposedEnergyStorage;
26+
import dev.galacticraft.machinelib.api.storage.MachineEnergyStorage;
2627
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
2728
import org.jetbrains.annotations.NotNull;
2829
import team.reborn.energy.api.EnergyStorage;
@@ -35,29 +36,29 @@
3536
* @param maxExtraction The maximum amount of energy that can be extracted in one transaction.
3637
* @see EnergyStorage
3738
*/
38-
public record ExposedEnergyStorageImpl(@NotNull EnergyStorage parent, long maxInsertion,
39+
public record ExposedEnergyStorageImpl(@NotNull MachineEnergyStorage parent, long maxInsertion,
3940
long maxExtraction) implements ExposedEnergyStorage {
4041
@Override
4142
public boolean supportsInsertion() {
42-
return this.maxInsertion > 0;
43+
return this.parent.isValid() && this.maxInsertion > 0;
4344
}
4445

4546
@Override
4647
public long insert(long maxAmount, TransactionContext transaction) {
47-
if (this.maxInsertion > 0) {
48+
if (this.supportsInsertion()) {
4849
return this.parent.insert(Math.min(this.maxInsertion, maxAmount), transaction);
4950
}
5051
return 0;
5152
}
5253

5354
@Override
5455
public boolean supportsExtraction() {
55-
return this.maxExtraction > 0;
56+
return this.parent.isValid() && this.maxExtraction > 0;
5657
}
5758

5859
@Override
5960
public long extract(long maxAmount, TransactionContext transaction) {
60-
if (this.maxExtraction > 0) {
61+
if (this.supportsExtraction()) {
6162
return this.parent.extract(Math.min(this.maxExtraction, maxAmount), transaction);
6263
}
6364
return 0;

0 commit comments

Comments
 (0)