Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.shared.Capabilities;
import de.srendi.advancedperipherals.AdvancedPeripherals;
import de.srendi.advancedperipherals.lib.peripherals.DisabledPeripheral;
import de.srendi.advancedperipherals.lib.peripherals.BasePeripheral;
import de.srendi.advancedperipherals.lib.peripherals.IPeripheralTileEntity;
import net.minecraft.core.BlockPos;
Expand Down Expand Up @@ -32,85 +32,96 @@
import org.jetbrains.annotations.Nullable;

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

public abstract class PeripheralBlockEntity<T extends BasePeripheral<?>> extends BaseContainerBlockEntity implements WorldlyContainer, MenuProvider, IPeripheralTileEntity {
// TODO: move inventory logic to another tile entity!

private static final String PERIPHERAL_SETTINGS_KEY = "peripheralSettings";
protected CompoundTag peripheralSettings;
protected CompoundTag peripheralSettings = new CompoundTag();
protected NonNullList<ItemStack> items;
@Nullable
protected T peripheral = null;
private LazyOptional<? extends IItemHandler> handler;
private LazyOptional<? extends IFluidHandler> fluidHandler;
private LazyOptional<IPeripheral> peripheralCap;
private LazyOptional<? extends IItemHandler> handler = LazyOptional.empty();
private LazyOptional<? extends IFluidHandler> fluidHandler = LazyOptional.empty();
private LazyOptional<IPeripheral> peripheralCap = LazyOptional.empty();

public PeripheralBlockEntity(BlockEntityType<?> tileEntityTypeIn, BlockPos pos, BlockState state) {
protected PeripheralBlockEntity(BlockEntityType<?> tileEntityTypeIn, BlockPos pos, BlockState state) {
super(tileEntityTypeIn, pos, state);
if (this instanceof IInventoryBlock<?> inventoryBlock) {
if (this instanceof IInventoryBlock inventoryBlock) {
items = NonNullList.withSize(inventoryBlock.getInvSize(), ItemStack.EMPTY);
} else {
items = NonNullList.withSize(0, ItemStack.EMPTY);
}
peripheralSettings = new CompoundTag();
}

@NotNull
@Override
public <T1> LazyOptional<T1> getCapability(@NotNull Capability<T1> cap, @Nullable Direction direction) {
public <U> LazyOptional<U> getCapability(@NotNull Capability<U> cap, @Nullable Direction direction) {
if (cap == Capabilities.CAPABILITY_PERIPHERAL) {
if (peripheral == null)
// Perform later peripheral creation, because creating peripheral
// on init of tile entity cause some infinity loop, if peripheral
// are depend on tile entity data
this.peripheral = createPeripheral();
if (peripheral.isEnabled()) {
if (peripheralCap == null) {
peripheralCap = LazyOptional.of(() -> peripheral);
} else if (!peripheralCap.isPresent()) {
// Recreate peripheral to allow CC: Tweaked correctly handle
// peripheral update logic, so new peripheral and old one will be
// different
peripheral = createPeripheral();
peripheralCap = LazyOptional.of(() -> peripheral);
return this.getLazyPeripheral().cast();
} else if (cap == ForgeCapabilities.ITEM_HANDLER) {
if (!remove && direction != null && this instanceof IInventoryBlock) {
if (!handler.isPresent()) {
handler = LazyOptional.of(() -> new SidedInvWrapper(this, Direction.NORTH));
}
return peripheralCap.cast();
} else {
AdvancedPeripherals.debug(peripheral.getType() + " is disabled, you can enable it in the Configuration.");
return handler.cast();
}
} else if (cap == ForgeCapabilities.FLUID_HANDLER) {
if (!remove && direction != null) {
if (!fluidHandler.isPresent()) {
fluidHandler = LazyOptional.of(() -> new FluidTank(0));
}
return fluidHandler.cast();
}
}

if (cap == ForgeCapabilities.ITEM_HANDLER && !remove && direction != null && this instanceof IInventoryBlock) {
if (handler == null || !handler.isPresent())
handler = LazyOptional.of(() -> new SidedInvWrapper(this, Direction.NORTH));
return handler.cast();
}

if (cap == ForgeCapabilities.FLUID_HANDLER && !remove && direction != null) {
if (fluidHandler == null || !fluidHandler.isPresent())
fluidHandler = LazyOptional.of(() -> new FluidTank(0));
return fluidHandler.cast();
}
return super.getCapability(cap, direction);
}

@Override
public void invalidateCaps() {
super.invalidateCaps();
if (peripheralCap != null)
peripheralCap.invalidate();
if (handler != null)
handler.invalidate();
if (fluidHandler != null)
fluidHandler.invalidate();
peripheralCap.invalidate();
handler.invalidate();
fluidHandler.invalidate();
}

@NotNull
protected abstract T createPeripheral();

protected IPeripheral createPeripheralDisable() {
T peripheral = this.createPeripheral();
if (peripheral.isEnabled()) {
return peripheral;
}
return new DisabledPeripheral(peripheral);
}

public Iterable<IComputerAccess> getConnectedComputers() {
if (peripheral == null) // just avoid some NPE in strange cases
return Collections.emptyList();
return peripheral.getConnectedComputers();
return this.getPeripheralOptional().map(BasePeripheral::getConnectedComputers).orElse(Collections.emptyList());
}

public LazyOptional<IPeripheral> getLazyPeripheral() {
// Perform later peripheral creation, because creating peripheral
// on init of tile entity cause some infinity loop, if peripheral
// are depend on tile entity data
if (!this.peripheralCap.isPresent()) {
// Recreate peripheral to allow CC: Tweaked correctly handle
// peripheral update logic, so new peripheral and old one will be
// different
this.peripheralCap = LazyOptional.of(this::createPeripheralDisable);
}
return this.peripheralCap;
}

@Nullable
public T getPeripheral() {
IPeripheral peripheral = this.getLazyPeripheral().orElse(null);
if (peripheral == null || peripheral instanceof DisabledPeripheral) {
return null;
}
return (T) peripheral;
}

public Optional<T> getPeripheralOptional() {
return Optional.ofNullable(this.getPeripheral());
}

/*@Override
Expand All @@ -122,7 +133,9 @@ public ITextComponent getDisplayName() {
public void saveAdditional(@NotNull CompoundTag compound) {
super.saveAdditional(compound);
ContainerHelper.saveAllItems(compound, items);
if (!peripheralSettings.isEmpty()) compound.put(PERIPHERAL_SETTINGS_KEY, peripheralSettings);
if (!peripheralSettings.isEmpty()) {
compound.put(PERIPHERAL_SETTINGS_KEY, peripheralSettings);
}
}

@Override
Expand All @@ -132,6 +145,7 @@ public void load(@NotNull CompoundTag compound) {
super.load(compound);
}

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

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

@Override
public int[] getSlotsForFace(@NotNull Direction side) {
public int @NotNull [] getSlotsForFace(@NotNull Direction side) {
return new int[]{0};
}

Expand Down Expand Up @@ -222,7 +237,6 @@ public CompoundTag getPeripheralSettings() {

@Override
public void markSettingsChanged() {
setChanged();
this.setChanged();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ protected ChatBoxPeripheral createPeripheral() {

@Override
public <T extends BlockEntity> void handleTick(Level level, BlockState state, BlockEntityType<T> type) {
if (peripheral != null) {
peripheral.update();
}
this.getPeripheralOptional().ifPresent(ChatBoxPeripheral::update);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ public <T extends BlockEntity> void handleTick(Level level, BlockState state, Bl
mainNode.setInWorldNode(true);
mainNode.create(level, getBlockPos());

//peripheral can be null if `getCapability` was not called before
if (peripheral == null)
peripheral = createPeripheral();
peripheral.setNode(mainNode);
this.getPeripheralOptional().ifPresent(peripheral -> peripheral.setNode(mainNode));
initialized = true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,73 @@
package de.srendi.advancedperipherals.lib.peripherals;

import dan200.computercraft.api.pocket.IPocketAccess;
import de.srendi.advancedperipherals.common.addons.computercraft.owner.PocketPeripheralOwner;
import dan200.computercraft.api.lua.IArguments;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.lua.LuaFunction;
import dan200.computercraft.api.lua.MethodResult;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IDynamicPeripheral;
import dan200.computercraft.api.peripheral.IPeripheral;

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

private DisabledPeripheral(String type, IPocketAccess access) {
super(type, new PocketPeripheralOwner(access));
public class DisabledPeripheral implements IDynamicPeripheral {
private static final MethodResult TRUE_RESULT = MethodResult.of(true);

private final IPeripheral basePeripheral;
private final String[] methods;

public DisabledPeripheral(IPeripheral basePeripheral) {
this.basePeripheral = basePeripheral;
Stream.Builder<String> builder = Stream.builder();
builder.add("peripheralDisabled");
for (Method method : basePeripheral.getClass().getMethods()) {
LuaFunction annotation = method.getAnnotation(LuaFunction.class);
if (annotation == null) {
continue;
}
String[] names = annotation.value();
if (names.length == 0) {
builder.add(method.getName());
} else {
for (String name : names) {
builder.add(name);
}
}
}
Stream<String> methodStream = builder.build();
if (basePeripheral instanceof IDynamicPeripheral dynPeripheral) {
methodStream = Stream.concat(methodStream, Stream.of(dynPeripheral.getMethodNames()));
}
this.methods = methodStream.toArray(String[]::new);
}

@Override
public String getType() {
return this.basePeripheral.getType();
}

@Override
public Object getTarget() {
return this.basePeripheral.getTarget();
}

@Override
public boolean equals(IPeripheral other) {
return other instanceof DisabledPeripheral disabled && this.basePeripheral.equals(disabled.basePeripheral);
}

@Override
public String[] getMethodNames() {
return this.methods;
}

@Override
public boolean isEnabled() {
return true;
public MethodResult callMethod(IComputerAccess computer, ILuaContext context, int method, IArguments arguments) throws LuaException {
if (method == 0) {
return TRUE_RESULT;
}
throw new LuaException("This peripheral is disabled, please contact server administrator if you want to use it");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ protected BasePocketUpgrade(ResourceLocation id, ItemStack stack) {
@Override
public IPeripheral createPeripheral(@NotNull IPocketAccess access) {
peripheral = getPeripheral(access);
if (!peripheral.isEnabled()) return DisabledPeripheral.INSTANCE;
if (!peripheral.isEnabled()) {
return new DisabledPeripheral(peripheral);
}
return peripheral;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ protected PeripheralTurtleUpgrade(ResourceLocation id, ItemStack item) {
public IPeripheral createPeripheral(@NotNull ITurtleAccess turtle, @NotNull TurtleSide side) {
T peripheral = buildPeripheral(turtle, side);
if (!peripheral.isEnabled()) {
return DisabledPeripheral.INSTANCE;
return new DisabledPeripheral(peripheral);
}
return peripheral;
}
Expand Down