Skip to content

Commit 5dee231

Browse files
authored
Merge pull request #755 from zyxkad/dev/1.19.2-disable-patch
Throw exceptions when using disabled peripherals
2 parents cfb9b4a + 944555c commit 5dee231

File tree

6 files changed

+138
-71
lines changed

6 files changed

+138
-71
lines changed

src/main/java/de/srendi/advancedperipherals/common/blocks/base/PeripheralBlockEntity.java

Lines changed: 68 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import dan200.computercraft.api.peripheral.IComputerAccess;
44
import dan200.computercraft.api.peripheral.IPeripheral;
55
import dan200.computercraft.shared.Capabilities;
6-
import de.srendi.advancedperipherals.AdvancedPeripherals;
6+
import de.srendi.advancedperipherals.lib.peripherals.DisabledPeripheral;
77
import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral;
88
import de.srendi.advancedperipherals.lib.peripherals.IPeripheralTileEntity;
99
import net.minecraft.core.BlockPos;
@@ -32,85 +32,96 @@
3232
import org.jetbrains.annotations.Nullable;
3333

3434
import java.util.Collections;
35+
import java.util.Optional;
3536

3637
public abstract class PeripheralBlockEntity<T extends BasePeripheral<?>> extends BaseContainerBlockEntity implements WorldlyContainer, MenuProvider, IPeripheralTileEntity {
37-
// TODO: move inventory logic to another tile entity!
38+
3839
private static final String PERIPHERAL_SETTINGS_KEY = "peripheralSettings";
39-
protected CompoundTag peripheralSettings;
40+
protected CompoundTag peripheralSettings = new CompoundTag();
4041
protected NonNullList<ItemStack> items;
41-
@Nullable
42-
protected T peripheral = null;
43-
private LazyOptional<? extends IItemHandler> handler;
44-
private LazyOptional<? extends IFluidHandler> fluidHandler;
45-
private LazyOptional<IPeripheral> peripheralCap;
42+
private LazyOptional<? extends IItemHandler> handler = LazyOptional.empty();
43+
private LazyOptional<? extends IFluidHandler> fluidHandler = LazyOptional.empty();
44+
private LazyOptional<IPeripheral> peripheralCap = LazyOptional.empty();
4645

47-
public PeripheralBlockEntity(BlockEntityType<?> tileEntityTypeIn, BlockPos pos, BlockState state) {
46+
protected PeripheralBlockEntity(BlockEntityType<?> tileEntityTypeIn, BlockPos pos, BlockState state) {
4847
super(tileEntityTypeIn, pos, state);
49-
if (this instanceof IInventoryBlock<?> inventoryBlock) {
48+
if (this instanceof IInventoryBlock inventoryBlock) {
5049
items = NonNullList.withSize(inventoryBlock.getInvSize(), ItemStack.EMPTY);
5150
} else {
5251
items = NonNullList.withSize(0, ItemStack.EMPTY);
5352
}
54-
peripheralSettings = new CompoundTag();
5553
}
5654

5755
@NotNull
5856
@Override
59-
public <T1> LazyOptional<T1> getCapability(@NotNull Capability<T1> cap, @Nullable Direction direction) {
57+
public <U> LazyOptional<U> getCapability(@NotNull Capability<U> cap, @Nullable Direction direction) {
6058
if (cap == Capabilities.CAPABILITY_PERIPHERAL) {
61-
if (peripheral == null)
62-
// Perform later peripheral creation, because creating peripheral
63-
// on init of tile entity cause some infinity loop, if peripheral
64-
// are depend on tile entity data
65-
this.peripheral = createPeripheral();
66-
if (peripheral.isEnabled()) {
67-
if (peripheralCap == null) {
68-
peripheralCap = LazyOptional.of(() -> peripheral);
69-
} else if (!peripheralCap.isPresent()) {
70-
// Recreate peripheral to allow CC: Tweaked correctly handle
71-
// peripheral update logic, so new peripheral and old one will be
72-
// different
73-
peripheral = createPeripheral();
74-
peripheralCap = LazyOptional.of(() -> peripheral);
59+
return this.getLazyPeripheral().cast();
60+
} else if (cap == ForgeCapabilities.ITEM_HANDLER) {
61+
if (!remove && direction != null && this instanceof IInventoryBlock) {
62+
if (!handler.isPresent()) {
63+
handler = LazyOptional.of(() -> new SidedInvWrapper(this, Direction.NORTH));
7564
}
76-
return peripheralCap.cast();
77-
} else {
78-
AdvancedPeripherals.debug(peripheral.getType() + " is disabled, you can enable it in the Configuration.");
65+
return handler.cast();
66+
}
67+
} else if (cap == ForgeCapabilities.FLUID_HANDLER) {
68+
if (!remove && direction != null) {
69+
if (!fluidHandler.isPresent()) {
70+
fluidHandler = LazyOptional.of(() -> new FluidTank(0));
71+
}
72+
return fluidHandler.cast();
7973
}
80-
}
81-
82-
if (cap == ForgeCapabilities.ITEM_HANDLER && !remove && direction != null && this instanceof IInventoryBlock) {
83-
if (handler == null || !handler.isPresent())
84-
handler = LazyOptional.of(() -> new SidedInvWrapper(this, Direction.NORTH));
85-
return handler.cast();
86-
}
87-
88-
if (cap == ForgeCapabilities.FLUID_HANDLER && !remove && direction != null) {
89-
if (fluidHandler == null || !fluidHandler.isPresent())
90-
fluidHandler = LazyOptional.of(() -> new FluidTank(0));
91-
return fluidHandler.cast();
9274
}
9375
return super.getCapability(cap, direction);
9476
}
9577

9678
@Override
9779
public void invalidateCaps() {
9880
super.invalidateCaps();
99-
if (peripheralCap != null)
100-
peripheralCap.invalidate();
101-
if (handler != null)
102-
handler.invalidate();
103-
if (fluidHandler != null)
104-
fluidHandler.invalidate();
81+
peripheralCap.invalidate();
82+
handler.invalidate();
83+
fluidHandler.invalidate();
10584
}
10685

10786
@NotNull
10887
protected abstract T createPeripheral();
10988

89+
protected IPeripheral createPeripheralDisable() {
90+
T peripheral = this.createPeripheral();
91+
if (peripheral.isEnabled()) {
92+
return peripheral;
93+
}
94+
return new DisabledPeripheral(peripheral);
95+
}
96+
11097
public Iterable<IComputerAccess> getConnectedComputers() {
111-
if (peripheral == null) // just avoid some NPE in strange cases
112-
return Collections.emptyList();
113-
return peripheral.getConnectedComputers();
98+
return this.getPeripheralOptional().map(BasePeripheral::getConnectedComputers).orElse(Collections.emptyList());
99+
}
100+
101+
public LazyOptional<IPeripheral> getLazyPeripheral() {
102+
// Perform later peripheral creation, because creating peripheral
103+
// on init of tile entity cause some infinity loop, if peripheral
104+
// are depend on tile entity data
105+
if (!this.peripheralCap.isPresent()) {
106+
// Recreate peripheral to allow CC: Tweaked correctly handle
107+
// peripheral update logic, so new peripheral and old one will be
108+
// different
109+
this.peripheralCap = LazyOptional.of(this::createPeripheralDisable);
110+
}
111+
return this.peripheralCap;
112+
}
113+
114+
@Nullable
115+
public T getPeripheral() {
116+
IPeripheral peripheral = this.getLazyPeripheral().orElse(null);
117+
if (peripheral == null || peripheral instanceof DisabledPeripheral) {
118+
return null;
119+
}
120+
return (T) peripheral;
121+
}
122+
123+
public Optional<T> getPeripheralOptional() {
124+
return Optional.ofNullable(this.getPeripheral());
114125
}
115126

116127
/*@Override
@@ -122,7 +133,9 @@ public ITextComponent getDisplayName() {
122133
public void saveAdditional(@NotNull CompoundTag compound) {
123134
super.saveAdditional(compound);
124135
ContainerHelper.saveAllItems(compound, items);
125-
if (!peripheralSettings.isEmpty()) compound.put(PERIPHERAL_SETTINGS_KEY, peripheralSettings);
136+
if (!peripheralSettings.isEmpty()) {
137+
compound.put(PERIPHERAL_SETTINGS_KEY, peripheralSettings);
138+
}
126139
}
127140

128141
@Override
@@ -132,6 +145,7 @@ public void load(@NotNull CompoundTag compound) {
132145
super.load(compound);
133146
}
134147

148+
@NotNull
135149
@Override
136150
protected Component getDefaultName() {
137151
return this instanceof IInventoryBlock<?> inventoryBlock ? inventoryBlock.getDisplayName() : null;
@@ -143,13 +157,14 @@ public AbstractContainerMenu createMenu(int id, @NotNull Inventory inventory, @N
143157
return createMenu(id, inventory);
144158
}
145159

160+
@NotNull
146161
@Override
147162
protected AbstractContainerMenu createMenu(int id, @NotNull Inventory player) {
148163
return this instanceof IInventoryBlock<?> inventoryBlock ? inventoryBlock.createContainer(id, player, worldPosition, level) : null;
149164
}
150165

151166
@Override
152-
public int[] getSlotsForFace(@NotNull Direction side) {
167+
public int @NotNull [] getSlotsForFace(@NotNull Direction side) {
153168
return new int[]{0};
154169
}
155170

@@ -222,7 +237,6 @@ public CompoundTag getPeripheralSettings() {
222237

223238
@Override
224239
public void markSettingsChanged() {
225-
setChanged();
240+
this.setChanged();
226241
}
227242
}
228-

src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/ChatBoxEntity.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ protected ChatBoxPeripheral createPeripheral() {
2323

2424
@Override
2525
public <T extends BlockEntity> void handleTick(Level level, BlockState state, BlockEntityType<T> type) {
26-
if (peripheral != null) {
27-
peripheral.update();
28-
}
26+
this.getPeripheralOptional().ifPresent(ChatBoxPeripheral::update);
2927
}
3028
}

src/main/java/de/srendi/advancedperipherals/common/blocks/blockentities/MeBridgeEntity.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,7 @@ public <T extends BlockEntity> void handleTick(Level level, BlockState state, Bl
5454
mainNode.setInWorldNode(true);
5555
mainNode.create(level, getBlockPos());
5656

57-
//peripheral can be null if `getCapability` was not called before
58-
if (peripheral == null)
59-
peripheral = createPeripheral();
60-
peripheral.setNode(mainNode);
57+
this.getPeripheralOptional().ifPresent(peripheral -> peripheral.setNode(mainNode));
6158
initialized = true;
6259
}
6360

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,73 @@
11
package de.srendi.advancedperipherals.lib.peripherals;
22

3-
import dan200.computercraft.api.pocket.IPocketAccess;
4-
import de.srendi.advancedperipherals.common.addons.computercraft.owner.PocketPeripheralOwner;
3+
import dan200.computercraft.api.lua.IArguments;
4+
import dan200.computercraft.api.lua.ILuaContext;
5+
import dan200.computercraft.api.lua.LuaException;
6+
import dan200.computercraft.api.lua.LuaFunction;
7+
import dan200.computercraft.api.lua.MethodResult;
8+
import dan200.computercraft.api.peripheral.IComputerAccess;
9+
import dan200.computercraft.api.peripheral.IDynamicPeripheral;
10+
import dan200.computercraft.api.peripheral.IPeripheral;
511

6-
public class DisabledPeripheral extends BasePeripheral<PocketPeripheralOwner> {
7-
public static final DisabledPeripheral INSTANCE = new DisabledPeripheral("disabledPeripheral", null);
12+
import java.lang.reflect.Method;
13+
import java.util.stream.Stream;
814

9-
private DisabledPeripheral(String type, IPocketAccess access) {
10-
super(type, new PocketPeripheralOwner(access));
15+
public class DisabledPeripheral implements IDynamicPeripheral {
16+
private static final MethodResult TRUE_RESULT = MethodResult.of(true);
17+
18+
private final IPeripheral basePeripheral;
19+
private final String[] methods;
20+
21+
public DisabledPeripheral(IPeripheral basePeripheral) {
22+
this.basePeripheral = basePeripheral;
23+
Stream.Builder<String> builder = Stream.builder();
24+
builder.add("peripheralDisabled");
25+
for (Method method : basePeripheral.getClass().getMethods()) {
26+
LuaFunction annotation = method.getAnnotation(LuaFunction.class);
27+
if (annotation == null) {
28+
continue;
29+
}
30+
String[] names = annotation.value();
31+
if (names.length == 0) {
32+
builder.add(method.getName());
33+
} else {
34+
for (String name : names) {
35+
builder.add(name);
36+
}
37+
}
38+
}
39+
Stream<String> methodStream = builder.build();
40+
if (basePeripheral instanceof IDynamicPeripheral dynPeripheral) {
41+
methodStream = Stream.concat(methodStream, Stream.of(dynPeripheral.getMethodNames()));
42+
}
43+
this.methods = methodStream.toArray(String[]::new);
44+
}
45+
46+
@Override
47+
public String getType() {
48+
return this.basePeripheral.getType();
49+
}
50+
51+
@Override
52+
public Object getTarget() {
53+
return this.basePeripheral.getTarget();
54+
}
55+
56+
@Override
57+
public boolean equals(IPeripheral other) {
58+
return other instanceof DisabledPeripheral disabled && this.basePeripheral.equals(disabled.basePeripheral);
59+
}
60+
61+
@Override
62+
public String[] getMethodNames() {
63+
return this.methods;
1164
}
1265

1366
@Override
14-
public boolean isEnabled() {
15-
return true;
67+
public MethodResult callMethod(IComputerAccess computer, ILuaContext context, int method, IArguments arguments) throws LuaException {
68+
if (method == 0) {
69+
return TRUE_RESULT;
70+
}
71+
throw new LuaException("This peripheral is disabled, please contact server administrator if you want to use it");
1672
}
1773
}

src/main/java/de/srendi/advancedperipherals/lib/pocket/BasePocketUpgrade.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ protected BasePocketUpgrade(ResourceLocation id, ItemStack stack) {
2525
@Override
2626
public IPeripheral createPeripheral(@NotNull IPocketAccess access) {
2727
peripheral = getPeripheral(access);
28-
if (!peripheral.isEnabled()) return DisabledPeripheral.INSTANCE;
28+
if (!peripheral.isEnabled()) {
29+
return new DisabledPeripheral(peripheral);
30+
}
2931
return peripheral;
3032
}
3133
}

src/main/java/de/srendi/advancedperipherals/lib/turtle/PeripheralTurtleUpgrade.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ protected PeripheralTurtleUpgrade(ResourceLocation id, ItemStack item) {
3434
public IPeripheral createPeripheral(@NotNull ITurtleAccess turtle, @NotNull TurtleSide side) {
3535
T peripheral = buildPeripheral(turtle, side);
3636
if (!peripheral.isEnabled()) {
37-
return DisabledPeripheral.INSTANCE;
37+
return new DisabledPeripheral(peripheral);
3838
}
3939
return peripheral;
4040
}

0 commit comments

Comments
 (0)