mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-10 01:10:30 +00:00
Decouple CommandAPI from the command computer BE
All we really need for its implementation is a level and position, which we can get directly from the server block entity!
This commit is contained in:
parent
e81af93043
commit
571ea794a8
@ -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,15 +53,14 @@ 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 result = commandManager.performPrefixedCommand(computer.getSource(), command);
|
||||
var result = commandManager.performPrefixedCommand(getSource(), command);
|
||||
return new Object[]{ result > 0, receiver.copyOutput(), result };
|
||||
} catch (Throwable t) {
|
||||
LOG.error(Logging.JAVA_ERROR, "Error running command.", t);
|
||||
@ -134,7 +138,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);
|
||||
@ -161,7 +164,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() };
|
||||
}
|
||||
|
||||
@ -186,7 +189,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
|
||||
@ -220,7 +222,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");
|
||||
}
|
||||
|
||||
@ -265,10 +267,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");
|
||||
@ -278,4 +279,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,85 +8,21 @@ 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));
|
||||
computer.addAPI(new CommandAPI(computer));
|
||||
return computer;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user