utility commands

This commit is contained in:
zelophed 2021-02-22 03:20:09 +01:00
parent 46daa3f699
commit 5da1a64622
7 changed files with 367 additions and 84 deletions

View file

@ -1,44 +1,87 @@
package com.simibubi.create.foundation.command; package com.simibubi.create.foundation.command;
import java.util.Collections;
import java.util.function.Predicate;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode; import com.mojang.brigadier.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode; import com.mojang.brigadier.tree.LiteralCommandNode;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands; import net.minecraft.command.Commands;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import java.util.Collections;
import java.util.function.Predicate;
public class AllCommands { public class AllCommands {
public static Predicate<CommandSource> sourceIsPlayer = (cs) -> cs.getEntity() instanceof PlayerEntity; public static Predicate<CommandSource> sourceIsPlayer = (cs) -> cs.getEntity() instanceof PlayerEntity;
public static void register(CommandDispatcher<CommandSource> dispatcher) { public static void register(CommandDispatcher<CommandSource> dispatcher) {
LiteralCommandNode<CommandSource> createRoot = dispatcher.register(Commands.literal("create") LiteralCommandNode<CommandSource> util = buildUtilityCommands();
//general purpose
.then(ToggleDebugCommand.register())
.then(OverlayConfigCommand.register())
.then(FixLightingCommand.register())
.then(ReplaceInCommandBlocksCommand.register())
.then(HighlightCommand.register())
.then(ToggleExperimentalRenderingCommand.register())
//dev-util LiteralCommandNode<CommandSource> createRoot = dispatcher.register(Commands.literal("create")
//Comment out for release .requires(cs -> cs.hasPermissionLevel(0))
.then(ClearBufferCacheCommand.register()) //general purpose
.then(ChunkUtilCommand.register()) .then(new ToggleExperimentalRenderingCommand().register())
//.then(KillTPSCommand.register()) .then(new ToggleDebugCommand().register())
.then(OverlayConfigCommand.register())
.then(FixLightingCommand.register())
.then(HighlightCommand.register())
.then(CouplingCommand.register())
//utility
.then(util)
); );
createRoot.addChild(buildRedirect("u", util));
CommandNode<CommandSource> c = dispatcher.findNode(Collections.singleton("c")); CommandNode<CommandSource> c = dispatcher.findNode(Collections.singleton("c"));
if (c != null) if (c != null)
return; return;
dispatcher.register(Commands.literal("c") dispatcher.getRoot().addChild(buildRedirect("c", createRoot));
.redirect(createRoot)
); }
private static LiteralCommandNode<CommandSource> buildUtilityCommands() {
return Commands.literal("util")
.then(FlySpeedCommand.register())
.then(ReplaceInCommandBlocksCommand.register())
.then(ClearBufferCacheCommand.register())
.then(ChunkUtilCommand.register())
//.then(KillTPSCommand.register())
.build();
}
/**
* *****
* https://github.com/VelocityPowered/Velocity/blob/8abc9c80a69158ebae0121fda78b55c865c0abad/proxy/src/main/java/com/velocitypowered/proxy/util/BrigadierUtils.java#L38
* *****
* <p>
* Returns a literal node that redirects its execution to
* the given destination node.
*
* @param alias the command alias
* @param destination the destination node
*
* @return the built node
*/
public static LiteralCommandNode<CommandSource> buildRedirect(final String alias, final LiteralCommandNode<CommandSource> destination) {
// Redirects only work for nodes with children, but break the top argument-less command.
// Manually adding the root command after setting the redirect doesn't fix it.
// See https://github.com/Mojang/brigadier/issues/46). Manually clone the node instead.
LiteralArgumentBuilder<CommandSource> builder = LiteralArgumentBuilder
.<CommandSource>literal(alias)
.requires(destination.getRequirement())
.forward(
destination.getRedirect(), destination.getRedirectModifier(), destination.isFork())
.executes(destination.getCommand());
for (CommandNode<CommandSource> child : destination.getChildren()) {
builder.then(child);
}
return builder.build();
} }
} }

View file

@ -0,0 +1,45 @@
package com.simibubi.create.foundation.command;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.builder.ArgumentBuilder;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.entity.player.ServerPlayerEntity;
public abstract class ConfigureConfigCommand {
protected final String commandLiteral;
ConfigureConfigCommand(String commandLiteral) {
this.commandLiteral = commandLiteral;
}
ArgumentBuilder<CommandSource, ?> register() {
return Commands.literal(this.commandLiteral)
.requires(cs -> cs.hasPermissionLevel(0))
.then(Commands.literal("on")
.executes(ctx -> {
ServerPlayerEntity player = ctx.getSource().asPlayer();
sendPacket(player, String.valueOf(true));
return Command.SINGLE_SUCCESS;
})
)
.then(Commands.literal("off")
.executes(ctx -> {
ServerPlayerEntity player = ctx.getSource().asPlayer();
sendPacket(player, String.valueOf(false));
return Command.SINGLE_SUCCESS;
})
)
.executes(ctx -> {
ServerPlayerEntity player = ctx.getSource().asPlayer();
sendPacket(player, "info");
return Command.SINGLE_SUCCESS;
});
}
protected abstract void sendPacket(ServerPlayerEntity player, String option);
}

View file

@ -1,23 +1,25 @@
package com.simibubi.create.foundation.command; package com.simibubi.create.foundation.command;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.apache.logging.log4j.LogManager;
import com.simibubi.create.content.contraptions.goggles.GoggleConfigScreen; import com.simibubi.create.content.contraptions.goggles.GoggleConfigScreen;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.networking.SimplePacketBase; import com.simibubi.create.foundation.networking.SimplePacketBase;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.ForgeConfig; import net.minecraftforge.common.ForgeConfig;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.network.NetworkEvent; import net.minecraftforge.fml.network.NetworkEvent;
import org.apache.logging.log4j.LogManager;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class ConfigureConfigPacket extends SimplePacketBase { public class ConfigureConfigPacket extends SimplePacketBase {
@ -79,23 +81,44 @@ public class ConfigureConfigPacket extends SimplePacketBase {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
private static void rainbowDebug(String value) { private static void rainbowDebug(String value) {
ClientPlayerEntity player = Minecraft.getInstance().player;
if (player == null || "".equals(value)) return;
if (value.equals("info")) {
ITextComponent text = new StringTextComponent("Rainbow Debug Utility is currently: ").appendSibling(boolToText(AllConfigs.CLIENT.rainbowDebug.get()));
player.sendStatusMessage(text, false);
return;
}
AllConfigs.CLIENT.rainbowDebug.set(Boolean.parseBoolean(value)); AllConfigs.CLIENT.rainbowDebug.set(Boolean.parseBoolean(value));
ITextComponent text = boolToText(AllConfigs.CLIENT.rainbowDebug.get()).appendSibling(new StringTextComponent(" Rainbow Debug Utility").applyTextStyle(TextFormatting.WHITE));
player.sendStatusMessage(text, false);
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
private static void experimentalRendering(String value) { private static void experimentalRendering(String value) {
if (!"".equals(value)) { ClientPlayerEntity player = Minecraft.getInstance().player;
AllConfigs.CLIENT.experimentalRendering.set(Boolean.parseBoolean(value)); if (player == null || "".equals(value)) return;
if (value.equals("info")) {
ITextComponent text = new StringTextComponent("Experimental Rendering is currently: ").appendSibling(boolToText(AllConfigs.CLIENT.experimentalRendering.get()));
player.sendStatusMessage(text, false);
return;
} }
AllConfigs.CLIENT.experimentalRendering.set(Boolean.parseBoolean(value));
ITextComponent text = boolToText(AllConfigs.CLIENT.experimentalRendering.get()).appendSibling(new StringTextComponent(" Experimental Rendering").applyTextStyle(TextFormatting.WHITE));
player.sendStatusMessage(text, false);
FastRenderDispatcher.refresh(); FastRenderDispatcher.refresh();
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
private static void overlayReset(String value) { private static void overlayReset(String value) {
AllConfigs.CLIENT.overlayOffsetX.set(0); AllConfigs.CLIENT.overlayOffsetX.set(0);
AllConfigs.CLIENT.overlayOffsetY.set(0); AllConfigs.CLIENT.overlayOffsetY.set(0);
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
private static void overlayScreen(String value) { private static void overlayScreen(String value) {
ScreenOpener.open(new GoggleConfigScreen()); ScreenOpener.open(new GoggleConfigScreen());
@ -106,5 +129,11 @@ public class ConfigureConfigPacket extends SimplePacketBase {
ForgeConfig.CLIENT.experimentalForgeLightPipelineEnabled.set(true); ForgeConfig.CLIENT.experimentalForgeLightPipelineEnabled.set(true);
Minecraft.getInstance().worldRenderer.loadRenderers(); Minecraft.getInstance().worldRenderer.loadRenderers();
} }
private static ITextComponent boolToText(boolean b) {
return b
? new StringTextComponent("enabled").applyTextStyle(TextFormatting.DARK_GREEN)
: new StringTextComponent("disabled").applyTextStyle(TextFormatting.RED);
}
} }
} }

View file

@ -0,0 +1,136 @@
package com.simibubi.create.foundation.command;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.simibubi.create.content.contraptions.components.structureMovement.train.CouplingHandler;
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.CapabilityMinecartController;
import com.simibubi.create.content.contraptions.components.structureMovement.train.capability.MinecartController;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.command.arguments.EntityArgument;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.common.util.LazyOptional;
import java.util.UUID;
public class CouplingCommand {
public static final SimpleCommandExceptionType ONLY_MINECARTS_ALLOWED = new SimpleCommandExceptionType(new StringTextComponent("Only Minecarts can be coupled"));
public static final SimpleCommandExceptionType SAME_DIMENSION = new SimpleCommandExceptionType(new StringTextComponent("Minecarts have to be in the same Dimension"));
public static ArgumentBuilder<CommandSource, ?> register() {
return Commands.literal("coupling")
.requires(cs -> cs.hasPermissionLevel(2))
.then(Commands.literal("add")
.then(Commands.argument("cart1", EntityArgument.entity())
.then(Commands.argument("cart2", EntityArgument.entity())
.executes(ctx -> {
Entity cart1 = EntityArgument.getEntity(ctx, "cart1");
if (!(cart1 instanceof AbstractMinecartEntity))
throw ONLY_MINECARTS_ALLOWED.create();
Entity cart2 = EntityArgument.getEntity(ctx, "cart2");
if (!(cart2 instanceof AbstractMinecartEntity))
throw ONLY_MINECARTS_ALLOWED.create();
if (!cart1.getEntityWorld().equals(cart2.getEntityWorld()))
throw SAME_DIMENSION.create();
Entity source = ctx.getSource().getEntity();
CouplingHandler.tryToCoupleCarts(source instanceof PlayerEntity ? (PlayerEntity) source : null, cart1.getEntityWorld(), cart1.getEntityId(), cart2.getEntityId());
return Command.SINGLE_SUCCESS;
})
)
)
)
.then(Commands.literal("remove")
.then(Commands.argument("cart1", EntityArgument.entity())
.then(Commands.argument("cart2", EntityArgument.entity())
.executes(ctx -> {
Entity cart1 = EntityArgument.getEntity(ctx, "cart1");
if (!(cart1 instanceof AbstractMinecartEntity))
throw ONLY_MINECARTS_ALLOWED.create();
Entity cart2 = EntityArgument.getEntity(ctx, "cart2");
if (!(cart2 instanceof AbstractMinecartEntity))
throw ONLY_MINECARTS_ALLOWED.create();
LazyOptional<MinecartController> cart1Capability = cart1.getCapability(CapabilityMinecartController.MINECART_CONTROLLER_CAPABILITY);
if (!cart1Capability.isPresent()) {
ctx.getSource().sendFeedback(new StringTextComponent("Minecart has no Couplings Attached"), true);
return 0;
}
MinecartController cart1Controller = cart1Capability.orElse(null);
int cart1Couplings = (cart1Controller.isConnectedToCoupling() ? 1 : 0) + (cart1Controller.isLeadingCoupling() ? 1 : 0);
if (cart1Couplings == 0) {
ctx.getSource().sendFeedback(new StringTextComponent("Minecart has no Couplings Attached"), true);
return 0;
}
for (boolean bool : Iterate.trueAndFalse) {
UUID coupledCart = cart1Controller.getCoupledCart(bool);
if (coupledCart == null)
continue;
if (coupledCart != cart2.getUniqueID())
continue;
MinecartController cart2Controller = CapabilityMinecartController.getIfPresent(cart1.getEntityWorld(), coupledCart);
if (cart2Controller == null)
return 0;
cart1Controller.removeConnection(bool);
cart2Controller.removeConnection(!bool);
return Command.SINGLE_SUCCESS;
}
ctx.getSource().sendFeedback(new StringTextComponent("The specified Carts are not coupled"), true);
return 0;
})
)
)
)
.then(Commands.literal("removeAll")
.then(Commands.argument("cart", EntityArgument.entity())
.executes(ctx -> {
Entity cart = EntityArgument.getEntity(ctx, "cart");
if (!(cart instanceof AbstractMinecartEntity))
throw ONLY_MINECARTS_ALLOWED.create();
LazyOptional<MinecartController> capability = cart.getCapability(CapabilityMinecartController.MINECART_CONTROLLER_CAPABILITY);
if (!capability.isPresent()) {
ctx.getSource().sendFeedback(new StringTextComponent("Minecart has no Couplings Attached"), true);
return 0;
}
MinecartController controller = capability.orElse(null);
int couplings = (controller.isConnectedToCoupling() ? 1 : 0) + (controller.isLeadingCoupling() ? 1 : 0);
if (couplings == 0) {
ctx.getSource().sendFeedback(new StringTextComponent("Minecart has no Couplings Attached"), true);
return 0;
}
controller.decouple();
ctx.getSource().sendFeedback(new StringTextComponent("Removed " + couplings + " couplings from the Minecart"), true);
return couplings;
})
)
);
}
}

View file

@ -0,0 +1,64 @@
package com.simibubi.create.foundation.command;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.arguments.FloatArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.context.CommandContext;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.command.arguments.EntityArgument;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.network.play.server.SPlayerAbilitiesPacket;
import net.minecraft.util.text.StringTextComponent;
public class FlySpeedCommand {
public static ArgumentBuilder<CommandSource, ?> register() {
return Commands.literal("flySpeed")
.requires(cs -> cs.hasPermissionLevel(2))
.then(Commands.argument("speed", FloatArgumentType.floatArg(0))
.then(Commands.argument("target", EntityArgument.player())
.executes(ctx -> sendFlySpeedUpdate(
ctx,
EntityArgument.getPlayer(ctx, "target"),
FloatArgumentType.getFloat(ctx, "speed")
)
)
)
.executes(ctx -> sendFlySpeedUpdate(
ctx,
ctx.getSource().asPlayer(),
FloatArgumentType.getFloat(ctx, "speed")
)
)
)
.then(Commands.literal("reset")
.then(Commands.argument("target", EntityArgument.player())
.executes(ctx -> sendFlySpeedUpdate(
ctx,
EntityArgument.getPlayer(ctx, "target"),
0.05f
)
)
)
.executes(ctx -> sendFlySpeedUpdate(
ctx,
ctx.getSource().asPlayer(),
0.05f
)
)
);
}
private static int sendFlySpeedUpdate(CommandContext<CommandSource> ctx, ServerPlayerEntity player, float speed) {
SPlayerAbilitiesPacket packet = new SPlayerAbilitiesPacket(player.abilities);
packet.setFlySpeed(speed);
player.connection.sendPacket(packet);
ctx.getSource().sendFeedback(new StringTextComponent("Temporarily set " + player.getName().getFormattedText() + "'s Flying Speed to: " + speed), true);
return Command.SINGLE_SUCCESS;
}
}

View file

@ -1,38 +1,20 @@
package com.simibubi.create.foundation.command; package com.simibubi.create.foundation.command;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.fml.network.PacketDistributor;
public class ToggleDebugCommand { public class ToggleDebugCommand extends ConfigureConfigCommand {
static ArgumentBuilder<CommandSource, ?> register() { public ToggleDebugCommand() {
return Commands.literal("toggleDebug") super("rainbowDebug");
.requires(cs -> cs.hasPermissionLevel(0)) }
.then(Commands.argument("value", BoolArgumentType.bool())
.executes(ctx -> {
boolean value = BoolArgumentType.getBool(ctx, "value");
//DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> AllConfigs.CLIENT.rainbowDebug.set(value));
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ConfigureConfigPacket.Actions.rainbowDebug.performAction(String.valueOf(value)));
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () -> @Override
AllPackets.channel.send( protected void sendPacket(ServerPlayerEntity player, String option) {
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()), AllPackets.channel.send(
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.rainbowDebug.name(), String.valueOf(value)))); PacketDistributor.PLAYER.with(() -> player),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.rainbowDebug.name(), option)
ctx.getSource().sendFeedback(new StringTextComponent((value ? "enabled" : "disabled") + " rainbow debug"), true); );
return Command.SINGLE_SUCCESS;
})
);
} }
} }

View file

@ -1,36 +1,20 @@
package com.simibubi.create.foundation.command; package com.simibubi.create.foundation.command;
import com.mojang.brigadier.arguments.BoolArgumentType;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.fml.network.PacketDistributor;
public class ToggleExperimentalRenderingCommand { public class ToggleExperimentalRenderingCommand extends ConfigureConfigCommand {
static ArgumentBuilder<CommandSource, ?> register() { public ToggleExperimentalRenderingCommand() {
return Commands.literal("experimentalRendering") super("experimentalRendering");
.requires(cs -> cs.hasPermissionLevel(0)) }
.then(Commands.argument("value", BoolArgumentType.bool())
.executes(ctx -> {
boolean value = BoolArgumentType.getBool(ctx, "value");
//DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> AllConfigs.CLIENT.rainbowDebug.set(value));
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ConfigureConfigPacket.Actions.experimentalRendering.performAction(String.valueOf(value)));
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () -> @Override
AllPackets.channel.send( protected void sendPacket(ServerPlayerEntity player, String option) {
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()), AllPackets.channel.send(
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.experimentalRendering.name(), String.valueOf(value)))); PacketDistributor.PLAYER.with(() -> player),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.experimentalRendering.name(), option)
ctx.getSource().sendFeedback(new StringTextComponent((value ? "enabled" : "disabled") + " experimental rendering"), true); );
return 1;
}));
} }
} }