1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-01-25 08:26:54 +00:00

Merge branch 'mc-1.20.x' into mc-1.21.x

This commit is contained in:
Jonathan Coates 2024-06-22 22:33:18 +01:00
commit 28f75a0687
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
24 changed files with 169 additions and 245 deletions

View File

@ -24,7 +24,6 @@ import dan200.computercraft.shared.command.CommandComputerCraft;
import dan200.computercraft.shared.computer.core.ComputerState;
import dan200.computercraft.shared.computer.core.ServerContext;
import dan200.computercraft.shared.computer.inventory.AbstractComputerMenu;
import dan200.computercraft.shared.computer.inventory.ViewComputerMenu;
import dan200.computercraft.shared.media.items.DiskItem;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
@ -101,15 +100,12 @@ public final class ClientRegistry {
public static void registerMenuScreens(RegisterMenuScreen register) {
register.<AbstractComputerMenu, ComputerScreen<AbstractComputerMenu>>register(ModRegistry.Menus.COMPUTER.get(), ComputerScreen::new);
register.<AbstractComputerMenu, ComputerScreen<AbstractComputerMenu>>register(ModRegistry.Menus.POCKET_COMPUTER.get(), ComputerScreen::new);
register.<AbstractComputerMenu, NoTermComputerScreen<AbstractComputerMenu>>register(ModRegistry.Menus.POCKET_COMPUTER_NO_TERM.get(), NoTermComputerScreen::new);
register.register(ModRegistry.Menus.TURTLE.get(), TurtleScreen::new);
register.register(ModRegistry.Menus.PRINTER.get(), PrinterScreen::new);
register.register(ModRegistry.Menus.DISK_DRIVE.get(), DiskDriveScreen::new);
register.register(ModRegistry.Menus.PRINTOUT.get(), PrintoutScreen::new);
register.<ViewComputerMenu, ComputerScreen<ViewComputerMenu>>register(ModRegistry.Menus.VIEW_COMPUTER.get(), ComputerScreen::new);
}
public interface RegisterMenuScreen {

View File

@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: MPL-2.0
package dan200.computercraft.shared.integration.jei;
package dan200.computercraft.client.integration.jei;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.turtle.TurtleSide;

View File

@ -2,7 +2,7 @@
//
// SPDX-License-Identifier: MPL-2.0
package dan200.computercraft.shared.integration.jei;
package dan200.computercraft.client.integration.jei;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.shared.integration.RecipeModHelpers;

View File

@ -27,12 +27,10 @@ import dan200.computercraft.shared.common.ColourableRecipe;
import dan200.computercraft.shared.common.DefaultBundledRedstoneProvider;
import dan200.computercraft.shared.common.HeldItemMenu;
import dan200.computercraft.shared.computer.blocks.CommandComputerBlock;
import dan200.computercraft.shared.computer.blocks.CommandComputerBlockEntity;
import dan200.computercraft.shared.computer.blocks.ComputerBlock;
import dan200.computercraft.shared.computer.blocks.ComputerBlockEntity;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.inventory.ComputerMenuWithoutInventory;
import dan200.computercraft.shared.computer.inventory.ViewComputerMenu;
import dan200.computercraft.shared.computer.items.AbstractComputerItem;
import dan200.computercraft.shared.computer.items.CommandComputerItem;
import dan200.computercraft.shared.computer.items.ComputerItem;
@ -155,8 +153,7 @@ public final class ModRegistry {
() -> new ComputerBlock<>(computerProperties().mapColor(MapColor.STONE), BlockEntities.COMPUTER_NORMAL));
public static final RegistryEntry<ComputerBlock<ComputerBlockEntity>> COMPUTER_ADVANCED = REGISTRY.register("computer_advanced",
() -> new ComputerBlock<>(computerProperties().mapColor(MapColor.GOLD), BlockEntities.COMPUTER_ADVANCED));
public static final RegistryEntry<ComputerBlock<CommandComputerBlockEntity>> COMPUTER_COMMAND = REGISTRY.register("computer_command",
public static final RegistryEntry<ComputerBlock<ComputerBlockEntity>> COMPUTER_COMMAND = REGISTRY.register("computer_command",
() -> new CommandComputerBlock<>(computerProperties().strength(-1, 6000000.0F), BlockEntities.COMPUTER_COMMAND));
public static final RegistryEntry<TurtleBlock> TURTLE_NORMAL = REGISTRY.register("turtle_normal",
@ -199,8 +196,8 @@ public final class ModRegistry {
ofBlock(Blocks.COMPUTER_NORMAL, (p, s) -> new ComputerBlockEntity(BlockEntities.COMPUTER_NORMAL.get(), p, s, ComputerFamily.NORMAL));
public static final RegistryEntry<BlockEntityType<ComputerBlockEntity>> COMPUTER_ADVANCED =
ofBlock(Blocks.COMPUTER_ADVANCED, (p, s) -> new ComputerBlockEntity(BlockEntities.COMPUTER_ADVANCED.get(), p, s, ComputerFamily.ADVANCED));
public static final RegistryEntry<BlockEntityType<CommandComputerBlockEntity>> COMPUTER_COMMAND =
ofBlock(Blocks.COMPUTER_COMMAND, (p, s) -> new CommandComputerBlockEntity(BlockEntities.COMPUTER_COMMAND.get(), p, s));
public static final RegistryEntry<BlockEntityType<ComputerBlockEntity>> COMPUTER_COMMAND =
ofBlock(Blocks.COMPUTER_COMMAND, (p, s) -> new ComputerBlockEntity(BlockEntities.COMPUTER_COMMAND.get(), p, s, ComputerFamily.COMMAND));
public static final RegistryEntry<BlockEntityType<TurtleBlockEntity>> TURTLE_NORMAL =
ofBlock(Blocks.TURTLE_NORMAL, (p, s) -> new TurtleBlockEntity(BlockEntities.TURTLE_NORMAL.get(), p, s, () -> Config.turtleFuelLimit, ComputerFamily.NORMAL));
@ -413,9 +410,6 @@ public final class ModRegistry {
public static final RegistryEntry<MenuType<ComputerMenuWithoutInventory>> COMPUTER = REGISTRY.register("computer",
() -> ContainerData.toType(ComputerContainerData.STREAM_CODEC, (id, inv, data) -> new ComputerMenuWithoutInventory(Menus.COMPUTER.get(), id, inv, data)));
public static final RegistryEntry<MenuType<ComputerMenuWithoutInventory>> POCKET_COMPUTER = REGISTRY.register("pocket_computer",
() -> ContainerData.toType(ComputerContainerData.STREAM_CODEC, (id, inv, data) -> new ComputerMenuWithoutInventory(Menus.POCKET_COMPUTER.get(), id, inv, data)));
public static final RegistryEntry<MenuType<ComputerMenuWithoutInventory>> POCKET_COMPUTER_NO_TERM = REGISTRY.register("pocket_computer_no_term",
() -> ContainerData.toType(ComputerContainerData.STREAM_CODEC, (id, inv, data) -> new ComputerMenuWithoutInventory(Menus.POCKET_COMPUTER_NO_TERM.get(), id, inv, data)));
@ -433,9 +427,6 @@ public final class ModRegistry {
HeldItemContainerData.STREAM_CODEC,
(id, inventory, data) -> new HeldItemMenu(Menus.PRINTOUT.get(), id, inventory.player, data.hand())
));
public static final RegistryEntry<MenuType<ViewComputerMenu>> VIEW_COMPUTER = REGISTRY.register("view_computer",
() -> ContainerData.toType(ComputerContainerData.STREAM_CODEC, ViewComputerMenu::new));
}
static class ArgumentTypes {

View File

@ -18,7 +18,7 @@ import dan200.computercraft.shared.command.text.TableBuilder;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.computer.core.ServerContext;
import dan200.computercraft.shared.computer.inventory.ViewComputerMenu;
import dan200.computercraft.shared.computer.inventory.ComputerMenuWithoutInventory;
import dan200.computercraft.shared.computer.metrics.basic.Aggregate;
import dan200.computercraft.shared.computer.metrics.basic.AggregatedMetric;
import dan200.computercraft.shared.computer.metrics.basic.BasicComputerMetricsObserver;
@ -268,7 +268,7 @@ public final class CommandComputerCraft {
@Override
public AbstractContainerMenu createMenu(int id, Inventory player, Player entity) {
return new ViewComputerMenu(id, player, computer);
return new ComputerMenuWithoutInventory(ModRegistry.Menus.COMPUTER.get(), id, player, p -> true, computer);
}
});
return 1;

View File

@ -10,15 +10,19 @@ import dan200.computercraft.api.detail.BlockReference;
import dan200.computercraft.api.detail.VanillaDetailRegistries;
import dan200.computercraft.api.lua.*;
import dan200.computercraft.core.Logging;
import dan200.computercraft.shared.computer.blocks.CommandComputerBlockEntity;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.util.NBTUtil;
import net.minecraft.commands.CommandSource;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -31,9 +35,10 @@ import java.util.*;
public class CommandAPI implements ILuaAPI {
private static final Logger LOG = LoggerFactory.getLogger(CommandAPI.class);
private final CommandComputerBlockEntity computer;
private final ServerComputer computer;
private final OutputReceiver receiver = new OutputReceiver();
public CommandAPI(CommandComputerBlockEntity computer) {
public CommandAPI(ServerComputer computer) {
this.computer = computer;
}
@ -48,16 +53,15 @@ public class CommandAPI implements ILuaAPI {
private Object[] doCommand(String command) {
var server = computer.getLevel().getServer();
if (server == null || !server.isCommandBlockEnabled()) {
if (!server.isCommandBlockEnabled()) {
return new Object[]{ false, createOutput("Command blocks disabled by server") };
}
var commandManager = server.getCommands();
var receiver = computer.getReceiver();
try {
receiver.clearOutput();
var state = new CommandState();
var source = computer.getSource().withCallback((success, x) -> {
var source = getSource().withCallback((success, x) -> {
if (success) state.successes++;
});
commandManager.performPrefixedCommand(source, command);
@ -142,7 +146,6 @@ public class CommandAPI implements ILuaAPI {
public final List<String> list(IArguments args) throws LuaException {
var server = computer.getLevel().getServer();
if (server == null) return List.of();
CommandNode<CommandSourceStack> node = server.getCommands().getDispatcher().getRoot();
for (var j = 0; j < args.count(); j++) {
var name = args.getString(j);
@ -169,7 +172,7 @@ public class CommandAPI implements ILuaAPI {
@LuaFunction
public final Object[] getBlockPosition() {
// This is probably safe to do on the Lua thread. Probably.
var pos = computer.getBlockPos();
var pos = computer.getPosition();
return new Object[]{ pos.getX(), pos.getY(), pos.getZ() };
}
@ -194,7 +197,6 @@ public class CommandAPI implements ILuaAPI {
* @throws LuaException If trying to get information about more than 4096 blocks.
* @cc.since 1.76
* @cc.changed 1.99 Added {@code dimension} argument.
*
* @cc.usage Print out all blocks in a cube around the computer.
*
* <pre>{@code
@ -228,7 +230,7 @@ public class CommandAPI implements ILuaAPI {
Math.max(minY, maxY),
Math.max(minZ, maxZ)
);
if (world == null || !world.isInWorldBounds(min) || !world.isInWorldBounds(max)) {
if (!world.isInWorldBounds(min) || !world.isInWorldBounds(max)) {
throw new LuaException("Co-ordinates out of range");
}
@ -273,10 +275,9 @@ public class CommandAPI implements ILuaAPI {
}
private Level getLevel(Optional<String> id) throws LuaException {
var currentLevel = (ServerLevel) computer.getLevel();
if (currentLevel == null) throw new LuaException("No world exists");
var currentLevel = computer.getLevel();
if (!id.isPresent()) return currentLevel;
if (id.isEmpty()) return currentLevel;
var dimensionId = ResourceLocation.tryParse(id.get());
if (dimensionId == null) throw new LuaException("Invalid dimension name");
@ -286,4 +287,52 @@ public class CommandAPI implements ILuaAPI {
return level;
}
private CommandSourceStack getSource() {
var name = "@";
var label = computer.getLabel();
if (label != null) name = label;
return new CommandSourceStack(receiver,
Vec3.atCenterOf(computer.getPosition()), Vec2.ZERO,
computer.getLevel(), 2,
name, Component.literal(name),
computer.getLevel().getServer(), null
);
}
/**
* A {@link CommandSource} that consumes output messages and stores them to a list.
*/
private final class OutputReceiver implements CommandSource {
private final List<String> output = new ArrayList<>();
void clearOutput() {
output.clear();
}
List<String> copyOutput() {
return List.copyOf(output);
}
@Override
public void sendSystemMessage(Component textComponent) {
output.add(textComponent.getString());
}
@Override
public boolean acceptsSuccess() {
return true;
}
@Override
public boolean acceptsFailure() {
return true;
}
@Override
public boolean shouldInformAdmins() {
return computer.getLevel().getGameRules().getBoolean(GameRules.RULE_COMMANDBLOCKOUTPUT);
}
}
}

View File

@ -82,7 +82,8 @@ public abstract class AbstractComputerBlockEntity extends BlockEntity implements
}
public boolean isUsable(Player player) {
return BaseContainerBlockEntity.canUnlock(player, lockCode, getDisplayName())
return getFamily().checkUsable(player)
&& BaseContainerBlockEntity.canUnlock(player, lockCode, getDisplayName())
&& Container.stillValidBlockEntity(this, player, getInteractRange());
}

View File

@ -18,7 +18,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
* @param <T> The type of the computer block entity.
* @see dan200.computercraft.shared.computer.items.CommandComputerItem
*/
public class CommandComputerBlock<T extends CommandComputerBlockEntity> extends ComputerBlock<T> implements GameMasterBlock {
public class CommandComputerBlock<T extends ComputerBlockEntity> extends ComputerBlock<T> implements GameMasterBlock {
private static final MapCodec<CommandComputerBlock<?>> CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
BlockCodecs.propertiesCodec(),
BlockCodecs.blockEntityCodec(x -> x.type)

View File

@ -1,114 +0,0 @@
// Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
//
// SPDX-License-Identifier: LicenseRef-CCPL
package dan200.computercraft.shared.computer.blocks;
import dan200.computercraft.shared.computer.apis.CommandAPI;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.config.Config;
import net.minecraft.commands.CommandSource;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import java.util.ArrayList;
import java.util.List;
public class CommandComputerBlockEntity extends ComputerBlockEntity {
public class CommandReceiver implements CommandSource {
private final List<String> output = new ArrayList<>();
public void clearOutput() {
output.clear();
}
public List<String> copyOutput() {
return new ArrayList<>(output);
}
@Override
public void sendSystemMessage(Component textComponent) {
output.add(textComponent.getString());
}
@Override
public boolean acceptsSuccess() {
return true;
}
@Override
public boolean acceptsFailure() {
return true;
}
@Override
public boolean shouldInformAdmins() {
return getLevel().getGameRules().getBoolean(GameRules.RULE_COMMANDBLOCKOUTPUT);
}
}
private final CommandReceiver receiver;
public CommandComputerBlockEntity(BlockEntityType<? extends ComputerBlockEntity> type, BlockPos pos, BlockState state) {
super(type, pos, state, ComputerFamily.COMMAND);
receiver = new CommandReceiver();
}
public CommandReceiver getReceiver() {
return receiver;
}
public CommandSourceStack getSource() {
var computer = getServerComputer();
var name = "@";
if (computer != null) {
var label = computer.getLabel();
if (label != null) name = label;
}
return new CommandSourceStack(receiver,
Vec3.atCenterOf(worldPosition), Vec2.ZERO,
(ServerLevel) getLevel(), 2,
name, Component.literal(name),
getLevel().getServer(), null
);
}
@Override
protected ServerComputer createComputer(int id) {
var computer = super.createComputer(id);
computer.addAPI(new CommandAPI(this));
return computer;
}
@Override
public boolean isUsable(Player player) {
return isCommandUsable(player) && super.isUsable(player);
}
public static boolean isCommandUsable(Player player) {
var server = player.getServer();
if (server == null || !server.isCommandBlockEnabled()) {
player.displayClientMessage(Component.translatable("advMode.notEnabled"), true);
return false;
} else if (!canUseCommandBlock(player)) {
player.displayClientMessage(Component.translatable("advMode.notAllowed"), true);
return false;
}
return true;
}
private static boolean canUseCommandBlock(Player player) {
return Config.commandRequireCreative ? player.canUseGameMasterBlocks() : player.hasPermissions(2);
}
}

View File

@ -67,7 +67,7 @@ public class ComputerBlockEntity extends AbstractComputerBlockEntity {
@Nullable
@Override
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player) {
return new ComputerMenuWithoutInventory(ModRegistry.Menus.COMPUTER.get(), id, inventory, this::isUsableByPlayer, createServerComputer(), getFamily());
return new ComputerMenuWithoutInventory(ModRegistry.Menus.COMPUTER.get(), id, inventory, this::isUsableByPlayer, createServerComputer());
}
public IPeripheral peripheral() {

View File

@ -4,8 +4,45 @@
package dan200.computercraft.shared.computer.core;
import dan200.computercraft.shared.config.Config;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player;
public enum ComputerFamily {
NORMAL,
ADVANCED,
COMMAND,
COMMAND;
/**
* Check whether computers with this family can be used by the provided player.
* <p>
* This method is not pure. On failure, the method may send a message to the player telling them why they cannot
* interact with the computer.
*
* @param player The player trying to use a computer.
* @return Whether this computer family can be used.
*/
public boolean checkUsable(Player player) {
return switch (this) {
case NORMAL, ADVANCED -> true;
case COMMAND -> checkCommandUsable(player);
};
}
private static boolean checkCommandUsable(Player player) {
var server = player.getServer();
if (server == null || !server.isCommandBlockEnabled()) {
player.displayClientMessage(Component.translatable("advMode.notEnabled"), true);
return false;
} else if (!canUseCommandBlock(player)) {
player.displayClientMessage(Component.translatable("advMode.notAllowed"), true);
return false;
}
return true;
}
private static boolean canUseCommandBlock(Player player) {
return Config.commandRequireCreative ? player.canUseGameMasterBlocks() : player.hasPermissions(2);
}
}

View File

@ -8,11 +8,12 @@ import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.filesystem.WritableMount;
import dan200.computercraft.api.lua.ILuaAPI;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.core.apis.IAPIEnvironment;
import dan200.computercraft.api.peripheral.WorkMonitor;
import dan200.computercraft.core.computer.Computer;
import dan200.computercraft.core.computer.ComputerEnvironment;
import dan200.computercraft.core.computer.ComputerSide;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.shared.computer.apis.CommandAPI;
import dan200.computercraft.shared.computer.menu.ComputerMenu;
import dan200.computercraft.shared.computer.terminal.NetworkedTerminal;
import dan200.computercraft.shared.computer.terminal.TerminalState;
@ -23,6 +24,7 @@ import dan200.computercraft.shared.network.client.ComputerTerminalClientMessage;
import dan200.computercraft.shared.network.server.ServerNetworking;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import javax.annotation.Nullable;
@ -58,6 +60,8 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
computer = new Computer(context.computerContext(), this, terminal, computerID);
computer.setLabel(label);
if (family == ComputerFamily.COMMAND) addAPI(new CommandAPI(this));
}
public ComputerFamily getFamily() {
@ -68,32 +72,20 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
return level;
}
public void setLevel(ServerLevel level) {
this.level = level;
}
public BlockPos getPosition() {
return position;
}
public void setPosition(BlockPos pos) {
position = new BlockPos(pos);
}
public IAPIEnvironment getAPIEnvironment() {
return computer.getAPIEnvironment();
}
public Computer getComputer() {
return computer;
public void setPosition(ServerLevel level, BlockPos pos) {
this.level = level;
position = pos.immutable();
}
protected void markTerminalChanged() {
terminalChanged.set(true);
}
public void tickServer() {
protected void tickServer() {
ticksSincePing++;
computer.tick();
if (terminalChanged.getAndSet(false)) onTerminalChanged();
@ -111,10 +103,15 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
ticksSincePing = 0;
}
public boolean hasTimedOut() {
boolean hasTimedOut() {
return ticksSincePing > 100;
}
/**
* Get a bitmask returning which sides on the computer have changed, resetting the internal state.
*
* @return What sides on the computer have changed.
*/
public int pollAndResetChanges() {
return computer.pollAndResetChanges();
}
@ -133,6 +130,17 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
ServerContext.get(level.getServer()).registry().remove(this);
}
/**
* Check whether this computer is usable by a player.
*
* @param player The player trying to use this computer.
* @return Whether this computer can be used.
*/
public final boolean checkUsable(Player player) {
return ServerContext.get(level.getServer()).registry().get(instanceUUID) == this
&& getFamily().checkUsable(player);
}
private void sendToAllInteracting(Function<AbstractContainerMenu, NetworkMessage<ClientNetworkContext>> createPacket) {
var server = level.getServer();
@ -169,25 +177,21 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
@Override
public void turnOn() {
// Turn on
computer.turnOn();
}
@Override
public void shutdown() {
// Shutdown
computer.shutdown();
}
@Override
public void reboot() {
// Reboot
computer.reboot();
}
@Override
public void queueEvent(String event, @Nullable Object[] arguments) {
// Queue event
computer.queueEvent(event, arguments);
}
@ -239,6 +243,10 @@ public class ServerComputer implements InputHandler, ComputerEnvironment {
return metrics;
}
public WorkMonitor getMainThreadMonitor() {
return computer.getMainThreadMonitor();
}
@Override
public @Nullable WritableMount createRootMount() {
return ComputerCraftAPI.createSaveDirMount(level.getServer(), "computer/" + computer.getID(), Config.computerSpaceLimit);

View File

@ -59,7 +59,7 @@ public abstract class AbstractComputerMenu extends AbstractContainerMenu impleme
@Override
public boolean stillValid(Player player) {
return canUse.test(player);
return (computer == null || computer.checkUsable(player)) && canUse.test(player);
}
public ComputerFamily getFamily() {

View File

@ -4,7 +4,6 @@
package dan200.computercraft.shared.computer.inventory;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.container.InvisibleSlot;
import dan200.computercraft.shared.network.container.ComputerContainerData;
@ -23,9 +22,9 @@ import java.util.function.Predicate;
public class ComputerMenuWithoutInventory extends AbstractComputerMenu {
public ComputerMenuWithoutInventory(
MenuType<? extends AbstractComputerMenu> type, int id, Inventory player, Predicate<Player> canUse,
ServerComputer computer, ComputerFamily family
ServerComputer computer
) {
super(type, id, canUse, family, computer, null);
super(type, id, canUse, computer.getFamily(), computer, null);
addSlots(player);
}

View File

@ -1,39 +0,0 @@
// SPDX-FileCopyrightText: 2017 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package dan200.computercraft.shared.computer.inventory;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.computer.blocks.CommandComputerBlockEntity;
import dan200.computercraft.shared.computer.core.ComputerFamily;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.computer.core.ServerContext;
import dan200.computercraft.shared.network.container.ComputerContainerData;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
public class ViewComputerMenu extends ComputerMenuWithoutInventory {
public ViewComputerMenu(int id, Inventory player, ServerComputer computer) {
super(ModRegistry.Menus.VIEW_COMPUTER.get(), id, player, p -> canInteractWith(computer, p), computer, computer.getFamily());
}
public ViewComputerMenu(int id, Inventory player, ComputerContainerData data) {
super(ModRegistry.Menus.VIEW_COMPUTER.get(), id, player, data);
}
private static boolean canInteractWith(ServerComputer computer, Player player) {
// If this computer no longer exists then discard it.
if (ServerContext.get(computer.getLevel().getServer()).registry().get(computer.getInstanceUUID()) != computer) {
return false;
}
// If we're a command computer then ensure we're in creative
if (computer.getFamily() == ComputerFamily.COMMAND && !CommandComputerBlockEntity.isCommandUsable(player)) {
return false;
}
return true;
}
}

View File

@ -138,10 +138,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
}
public synchronized void updateValues(@Nullable Entity entity, ItemStack stack, @Nullable IPocketUpgrade upgrade) {
if (entity != null) {
setLevel((ServerLevel) entity.getCommandSenderWorld());
setPosition(entity.blockPosition());
}
if (entity != null) setPosition((ServerLevel) entity.level(), entity.blockPosition());
// If a new entity has picked it up then rebroadcast the terminal to them
if (entity != this.entity && entity instanceof ServerPlayer) markTerminalChanged();
@ -156,7 +153,7 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
}
@Override
public void tickServer() {
protected void tickServer() {
super.tickServer();
// Find any players which have gone missing and remove them from the tracking list.

View File

@ -45,12 +45,12 @@ public class PocketComputerMenuProvider implements MenuProvider {
@Override
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player entity) {
return new ComputerMenuWithoutInventory(
isTypingOnly ? ModRegistry.Menus.POCKET_COMPUTER_NO_TERM.get() : ModRegistry.Menus.POCKET_COMPUTER.get(), id, inventory,
isTypingOnly ? ModRegistry.Menus.POCKET_COMPUTER_NO_TERM.get() : ModRegistry.Menus.COMPUTER.get(), id, inventory,
p -> {
var stack = p.getItemInHand(hand);
return stack.getItem() == item && PocketComputerItem.getServerComputer(assertNonNull(entity.level().getServer()), stack) == computer;
},
computer, item.getFamily()
computer
);
}
}

View File

@ -53,10 +53,9 @@ public class PocketComputerItem extends Item implements IMedia {
this.family = family;
}
private boolean tick(ItemStack stack, Level world, Entity entity, PocketServerComputer computer) {
private boolean tick(ItemStack stack, Entity entity, PocketServerComputer computer) {
var upgrade = getUpgrade(stack);
computer.setLevel((ServerLevel) world);
computer.updateValues(entity, stack, upgrade);
var changed = false;
@ -87,7 +86,7 @@ public class PocketComputerItem extends Item implements IMedia {
var computer = createServerComputer((ServerLevel) world, entity, inventory, stack);
computer.keepAlive();
var changed = tick(stack, world, entity, computer);
var changed = tick(stack, entity, computer);
if (changed && inventory != null) inventory.setChanged();
}
@ -97,7 +96,7 @@ public class PocketComputerItem extends Item implements IMedia {
if (level.isClientSide || level.getServer() == null) return false;
var computer = getServerComputer(level.getServer(), stack);
if (computer != null && tick(stack, entity.level(), entity, computer)) entity.setItem(stack.copy());
if (computer != null && tick(stack, entity, computer)) entity.setItem(stack.copy());
return false;
}
@ -175,7 +174,7 @@ public class PocketComputerItem extends Item implements IMedia {
if (inventory != null) inventory.setChanged();
}
computer.setLevel(level);
return computer;
}

View File

@ -25,7 +25,7 @@ public class PocketModemPeripheral extends WirelessModemPeripheral {
void setLocation(IPocketAccess access) {
var entity = access.getEntity();
if (entity != null) {
level = entity.getCommandSenderWorld();
level = entity.level();
position = entity.getEyePosition(1);
}
}

View File

@ -9,8 +9,9 @@ import dan200.computercraft.api.lua.*;
import dan200.computercraft.api.turtle.TurtleCommand;
import dan200.computercraft.api.turtle.TurtleCommandResult;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.core.apis.IAPIEnvironment;
import dan200.computercraft.core.metrics.Metrics;
import dan200.computercraft.core.metrics.MetricsObserver;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.peripheral.generic.methods.AbstractInventoryMethods;
import dan200.computercraft.shared.turtle.core.*;
@ -64,11 +65,11 @@ import java.util.Optional;
* @cc.since 1.3
*/
public class TurtleAPI implements ILuaAPI {
private final IAPIEnvironment environment;
private final MetricsObserver metrics;
private final TurtleAccessInternal turtle;
public TurtleAPI(IAPIEnvironment environment, TurtleAccessInternal turtle) {
this.environment = environment;
public TurtleAPI(ServerComputer computer, TurtleAccessInternal turtle) {
this.metrics = computer.getMetrics();
this.turtle = turtle;
}
@ -78,7 +79,7 @@ public class TurtleAPI implements ILuaAPI {
}
private MethodResult trackCommand(TurtleCommand command) {
environment.observe(Metrics.TURTLE_OPS);
metrics.observe(Metrics.TURTLE_OPS);
return turtle.executeCommand(command);
}
@ -169,7 +170,7 @@ public class TurtleAPI implements ILuaAPI {
*/
@LuaFunction
public final MethodResult dig(Optional<TurtleSide> side) {
environment.observe(Metrics.TURTLE_OPS);
metrics.observe(Metrics.TURTLE_OPS);
return trackCommand(TurtleToolCommand.dig(InteractDirection.FORWARD, side.orElse(null)));
}
@ -184,7 +185,7 @@ public class TurtleAPI implements ILuaAPI {
*/
@LuaFunction
public final MethodResult digUp(Optional<TurtleSide> side) {
environment.observe(Metrics.TURTLE_OPS);
metrics.observe(Metrics.TURTLE_OPS);
return trackCommand(TurtleToolCommand.dig(InteractDirection.UP, side.orElse(null)));
}
@ -199,7 +200,7 @@ public class TurtleAPI implements ILuaAPI {
*/
@LuaFunction
public final MethodResult digDown(Optional<TurtleSide> side) {
environment.observe(Metrics.TURTLE_OPS);
metrics.observe(Metrics.TURTLE_OPS);
return trackCommand(TurtleToolCommand.dig(InteractDirection.DOWN, side.orElse(null)));
}

View File

@ -84,7 +84,7 @@ public class TurtleBlockEntity extends AbstractComputerBlockEntity implements Ba
getFamily(), Config.turtleTermWidth,
Config.turtleTermHeight
);
computer.addAPI(new TurtleAPI(computer.getAPIEnvironment(), brain));
computer.addAPI(new TurtleAPI(computer, brain));
brain.setupComputer(computer);
return computer;
}

View File

@ -266,8 +266,7 @@ public class TurtleBrain implements TurtleAccessInternal {
newTurtle.transferStateFrom(oldOwner);
var computer = newTurtle.createServerComputer();
computer.setLevel((ServerLevel) world);
computer.setPosition(pos);
computer.setPosition((ServerLevel) world, pos);
// Remove the old turtle
oldWorld.removeBlock(oldPos, false);
@ -586,7 +585,7 @@ public class TurtleBrain implements TurtleAccessInternal {
// If we've got a computer, ensure that we're allowed to perform work.
var computer = owner.getServerComputer();
if (computer != null && !computer.getComputer().getMainThreadMonitor().canWork()) return;
if (computer != null && !computer.getMainThreadMonitor().canWork()) return;
// Pull a new command
var nextCommand = commandQueue.poll();
@ -599,7 +598,7 @@ public class TurtleBrain implements TurtleAccessInternal {
// Dispatch the callback
if (computer == null) return;
computer.getComputer().getMainThreadMonitor().trackWork(end - start, TimeUnit.NANOSECONDS);
computer.getMainThreadMonitor().trackWork(end - start, TimeUnit.NANOSECONDS);
var callbackID = nextCommand.callbackID();
if (callbackID < 0) return;

View File

@ -60,7 +60,7 @@ public final class TurtlePlayer {
var player = brain.cachedPlayer;
if (player == null || player.player.getGameProfile() != getProfile(access.getOwningPlayer())
|| player.player.getCommandSenderWorld() != access.getLevel()) {
|| player.player.level() != access.getLevel()) {
player = brain.cachedPlayer = create(brain);
} else {
player.setState(access);

View File

@ -27,7 +27,7 @@
"dan200.computercraft.data.FabricDataGenerators"
],
"jei_mod_plugin": [
"dan200.computercraft.shared.integration.jei.JEIComputerCraft"
"dan200.computercraft.client.integration.jei.JEIComputerCraft"
],
"rei_client": [
"dan200.computercraft.client.integration.rei.REIComputerCraft"