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:
commit
28f75a0687
@ -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 {
|
||||
|
@ -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;
|
@ -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;
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
Loading…
Reference in New Issue
Block a user