2023-03-15 21:52:13 +00:00
|
|
|
// SPDX-FileCopyrightText: 2017 The CC: Tweaked Developers
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2017-12-06 15:51:02 +00:00
|
|
|
package dan200.computercraft.shared.command;
|
|
|
|
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
import com.mojang.brigadier.CommandDispatcher;
|
|
|
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
2023-07-05 10:38:21 +00:00
|
|
|
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
2023-07-05 10:38:21 +00:00
|
|
|
import com.mojang.brigadier.suggestion.Suggestions;
|
2019-04-09 09:02:54 +00:00
|
|
|
import dan200.computercraft.core.computer.ComputerSide;
|
2022-10-22 00:35:04 +00:00
|
|
|
import dan200.computercraft.core.metrics.Metrics;
|
2023-08-27 11:15:55 +00:00
|
|
|
import dan200.computercraft.shared.ModRegistry;
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
import dan200.computercraft.shared.command.arguments.ComputerArgumentType;
|
|
|
|
import dan200.computercraft.shared.command.arguments.ComputerSelector;
|
2018-12-29 12:18:05 +00:00
|
|
|
import dan200.computercraft.shared.command.text.TableBuilder;
|
2018-11-29 11:57:52 +00:00
|
|
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
2017-12-06 15:51:02 +00:00
|
|
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
2022-10-21 20:01:01 +00:00
|
|
|
import dan200.computercraft.shared.computer.core.ServerContext;
|
2022-11-09 23:58:56 +00:00
|
|
|
import dan200.computercraft.shared.computer.inventory.ViewComputerMenu;
|
2022-10-22 00:35:04 +00:00
|
|
|
import dan200.computercraft.shared.computer.metrics.basic.Aggregate;
|
|
|
|
import dan200.computercraft.shared.computer.metrics.basic.AggregatedMetric;
|
|
|
|
import dan200.computercraft.shared.computer.metrics.basic.BasicComputerMetricsObserver;
|
|
|
|
import dan200.computercraft.shared.computer.metrics.basic.ComputerMetrics;
|
Remove ClientComputer
Historically CC has maintained two computer registries; one on the
server (which runs the actual computer) and one on the client (which
stores the terminal and some small bits of additional data).
This means when a user opens the computer UI, we send the terminal
contents and store it in the client computer registry. We then send the
instance id alongside the "open container" packet, which is used to look
up the client computer (and thus terminal) in our client-side registry.
This patch makes the computer menu syncing behaviour more consistent
with vanilla. The initial terminal contents is sent alongside the "open
container" packet, and subsequent terminal changes apply /just/ to the
open container. Computer on/off state is synced via a vanilla
ContainerData/IIntArray.
Likewise, sending user input to the server now targets the open
container, rather than an arbitrary instance id.
The one remaining usage of ClientComputer is for pocket computers. For
these, we still need to sync the current on/off/blinking state and the
pocket computer light.
We don't need the full ClientComputer interface for this case (after
all, you can't send input to a pocket computer someone else is
holding!). This means we can tear out ClientComputer and
ClientComputerRegistry, replacing it with a much simpler
ClientPocketComputers store.
This in turn allows the following changes:
- Remove IComputer, as we no longer need to abstract over client and
server computers.
- Likewise, we can merge ComputerRegistry into the server
registry. This commit also cleans up the handling of instance IDs a
little bit: ServerComputers are now responsible for generating their
ID and adding/removing themselves from the registry.
- As the client-side terminal will never be null, we can remove a whole
bunch of null checks throughout the codebase.
- As the terminal is available immediately, we don't need to explicitly
pass in terminal sizes to the computer GUIs. This means we're no
longer reliant on those config values on the client side!
- Remove the "request computer state" packet. Pocket computers now
store which players need to know the computer state, automatically
sending data when a new player starts tracking the computer.
2022-10-21 17:17:42 +00:00
|
|
|
import dan200.computercraft.shared.network.container.ComputerContainerData;
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
import net.minecraft.ChatFormatting;
|
2021-08-03 20:46:53 +00:00
|
|
|
import net.minecraft.commands.CommandSourceStack;
|
|
|
|
import net.minecraft.core.BlockPos;
|
|
|
|
import net.minecraft.network.chat.Component;
|
|
|
|
import net.minecraft.world.MenuProvider;
|
2023-03-15 21:04:11 +00:00
|
|
|
import net.minecraft.world.entity.RelativeMovement;
|
2021-08-03 20:46:53 +00:00
|
|
|
import net.minecraft.world.entity.player.Inventory;
|
|
|
|
import net.minecraft.world.entity.player.Player;
|
|
|
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
2022-10-30 08:49:52 +00:00
|
|
|
import net.minecraft.world.item.ItemStack;
|
2021-08-03 20:46:53 +00:00
|
|
|
import net.minecraft.world.level.Level;
|
2023-09-05 17:37:10 +00:00
|
|
|
import net.minecraft.world.phys.Vec3;
|
2017-12-06 15:51:02 +00:00
|
|
|
|
2022-11-09 18:58:31 +00:00
|
|
|
import javax.annotation.Nullable;
|
2021-05-28 21:19:04 +00:00
|
|
|
import java.io.File;
|
2018-02-02 13:34:27 +00:00
|
|
|
import java.util.*;
|
2017-12-06 15:51:02 +00:00
|
|
|
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
import static dan200.computercraft.shared.command.CommandUtils.isPlayer;
|
2023-09-05 17:37:10 +00:00
|
|
|
import static dan200.computercraft.shared.command.Exceptions.NOT_TRACKING_EXCEPTION;
|
|
|
|
import static dan200.computercraft.shared.command.Exceptions.NO_TIMINGS_EXCEPTION;
|
2022-10-22 00:35:04 +00:00
|
|
|
import static dan200.computercraft.shared.command.arguments.TrackingFieldArgumentType.metric;
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
import static dan200.computercraft.shared.command.builder.CommandBuilder.args;
|
|
|
|
import static dan200.computercraft.shared.command.builder.CommandBuilder.command;
|
|
|
|
import static dan200.computercraft.shared.command.builder.HelpingArgumentBuilder.choice;
|
2018-12-29 12:18:05 +00:00
|
|
|
import static dan200.computercraft.shared.command.text.ChatHelpers.*;
|
2021-08-03 20:46:53 +00:00
|
|
|
import static net.minecraft.commands.Commands.literal;
|
2017-12-06 15:51:02 +00:00
|
|
|
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
public final class CommandComputerCraft {
|
2018-04-16 20:06:16 +00:00
|
|
|
public static final UUID SYSTEM_UUID = new UUID(0, 0);
|
2024-01-30 22:00:36 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The client-side command to open the folder. Ideally this would live under the main {@code computercraft}
|
|
|
|
* namespace, but unfortunately that overrides commands, rather than merging them.
|
|
|
|
*/
|
|
|
|
public static final String CLIENT_OPEN_FOLDER = "computercraft-computer-folder";
|
2018-04-16 20:06:16 +00:00
|
|
|
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
private CommandComputerCraft() {
|
2017-12-06 15:51:02 +00:00
|
|
|
}
|
|
|
|
|
2021-08-03 20:46:53 +00:00
|
|
|
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
dispatcher.register(choice("computercraft")
|
|
|
|
.then(literal("dump")
|
2023-08-27 11:15:55 +00:00
|
|
|
.requires(ModRegistry.Permissions.PERMISSION_DUMP)
|
2023-09-05 17:37:10 +00:00
|
|
|
.executes(c -> dump(c.getSource()))
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
.then(args()
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
.arg("computer", ComputerArgumentType.get())
|
|
|
|
.executes(c -> dumpComputer(c.getSource(), ComputerArgumentType.getOne(c, "computer")))))
|
2022-11-03 23:43:14 +00:00
|
|
|
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
.then(command("shutdown")
|
2023-08-27 11:15:55 +00:00
|
|
|
.requires(ModRegistry.Permissions.PERMISSION_SHUTDOWN)
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
.argManyValue("computers", ComputerArgumentType.get(), ComputerSelector.all())
|
2023-09-05 17:37:10 +00:00
|
|
|
.executes((c, a) -> shutdown(c.getSource(), unwrap(c.getSource(), a))))
|
2022-11-03 23:43:14 +00:00
|
|
|
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
.then(command("turn-on")
|
2023-08-27 11:15:55 +00:00
|
|
|
.requires(ModRegistry.Permissions.PERMISSION_TURN_ON)
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
.argManyValue("computers", ComputerArgumentType.get(), ComputerSelector.all())
|
2023-09-05 17:37:10 +00:00
|
|
|
.executes((c, a) -> turnOn(c.getSource(), unwrap(c.getSource(), a))))
|
2017-12-06 15:51:02 +00:00
|
|
|
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
.then(command("tp")
|
2023-08-27 11:15:55 +00:00
|
|
|
.requires(ModRegistry.Permissions.PERMISSION_TP)
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
.arg("computer", ComputerArgumentType.get())
|
|
|
|
.executes(c -> teleport(c.getSource(), ComputerArgumentType.getOne(c, "computer"))))
|
2022-11-03 23:43:14 +00:00
|
|
|
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
.then(command("queue")
|
2023-08-27 11:15:55 +00:00
|
|
|
.requires(ModRegistry.Permissions.PERMISSION_QUEUE)
|
2023-07-05 10:38:21 +00:00
|
|
|
.arg(
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
RequiredArgumentBuilder.<CommandSourceStack, ComputerSelector>argument("computer", ComputerArgumentType.get())
|
2023-07-05 10:38:21 +00:00
|
|
|
.suggests((context, builder) -> Suggestions.empty())
|
|
|
|
)
|
2023-10-21 09:37:43 +00:00
|
|
|
.argManyValue("args", StringArgumentType.string(), List.of())
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
.executes((c, a) -> queue(ComputerArgumentType.getMany(c, "computer"), a)))
|
2022-11-03 23:43:14 +00:00
|
|
|
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
.then(command("view")
|
2023-08-27 11:15:55 +00:00
|
|
|
.requires(ModRegistry.Permissions.PERMISSION_VIEW)
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
.arg("computer", ComputerArgumentType.get())
|
|
|
|
.executes(c -> view(c.getSource(), ComputerArgumentType.getOne(c, "computer"))))
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
|
|
|
|
.then(choice("track")
|
2023-08-27 11:15:55 +00:00
|
|
|
.requires(ModRegistry.Permissions.PERMISSION_TRACK)
|
2023-09-05 17:37:10 +00:00
|
|
|
.then(command("start").executes(c -> trackStart(c.getSource())))
|
|
|
|
.then(command("stop").executes(c -> trackStop(c.getSource())))
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
.then(command("dump")
|
2022-10-22 00:35:04 +00:00
|
|
|
.argManyValue("fields", metric(), DEFAULT_FIELDS)
|
2023-09-05 17:37:10 +00:00
|
|
|
.executes((c, f) -> trackDump(c.getSource(), f))))
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
);
|
2017-12-06 15:51:02 +00:00
|
|
|
}
|
|
|
|
|
2023-09-05 17:37:10 +00:00
|
|
|
/**
|
|
|
|
* Display loaded computers to a table.
|
|
|
|
*
|
|
|
|
* @param source The thing that executed this command.
|
|
|
|
* @return The number of loaded computers.
|
|
|
|
*/
|
|
|
|
private static int dump(CommandSourceStack source) {
|
|
|
|
var table = new TableBuilder("DumpAll", "Computer", "On", "Position");
|
|
|
|
|
|
|
|
List<ServerComputer> computers = new ArrayList<>(ServerContext.get(source.getServer()).registry().getComputers());
|
|
|
|
|
|
|
|
Level world = source.getLevel();
|
|
|
|
var pos = BlockPos.containing(source.getPosition());
|
|
|
|
|
|
|
|
// Sort by nearby computers.
|
|
|
|
computers.sort((a, b) -> {
|
|
|
|
if (a.getLevel() == b.getLevel() && a.getLevel() == world) {
|
|
|
|
return Double.compare(a.getPosition().distSqr(pos), b.getPosition().distSqr(pos));
|
|
|
|
} else if (a.getLevel() == world) {
|
|
|
|
return -1;
|
|
|
|
} else if (b.getLevel() == world) {
|
|
|
|
return 1;
|
|
|
|
} else {
|
Replace integer instance IDs with UUIDs
Here's a fun bug you can try at home:
- Create a new world
- Spawn in a pocket computer, turn it on, and place it in a chest.
- Reload the world - the pocket computer in the chest should now be
off.
- Spawn in a new pocket computer, and turn it on. The computer in chest
will also appear to be on!
This bug has been present since pocket computers were added (27th March,
2024).
When a pocket computer is added to a player's inventory, it is assigned
a unique *per-session* "instance id" , which is used to find the
associated computer. Note the "per-session" there - these ids will be
reused if you reload the world (or restart the server).
In the above bug, we see the following:
- The first pocket computer is assigned an instance id of 0.
- After reloading, the second pocket computer is assigned an instance
id of 0.
- If the first pocket computer was in our inventory, it'd be ticked and
assigned a new instance id. However, because it's in an inventory, it
keeps its old one.
- Both computers look up their client-side computer state and get the
same value, meaning the first pocket computer mirrors the second!
To fix this, we now ensure instance ids are entirely unique (not just
per-session). Rather than sequentially assigning an int, we now use a
random UUID (we probably could get away with a random long, but this
feels more idiomatic).
This has a couple of user-visible changes:
- /computercraft no longer lists instance ids outside of dumping an
individual computer.
- The @c[instance=...] selector uses UUIDs. We still use int instance
ids for the legacy selector, but that'll be removed in a later MC
version.
- Pocket computers now store a UUID rather than an int.
Related to this change (I made this change first, but then they got
kinda mixed up together), we now only create PocketComputerData when
receiving server data. This makes the code a little uglier in some
places (the data may now be null), but means we don't populate the
client-side pocket computer map with computers the server doesn't know
about.
2024-03-17 12:21:21 +00:00
|
|
|
return a.getInstanceUUID().compareTo(b.getInstanceUUID());
|
2023-09-05 17:37:10 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
for (var computer : computers) {
|
|
|
|
table.row(
|
|
|
|
linkComputer(source, computer, computer.getID()),
|
|
|
|
bool(computer.isOn()),
|
|
|
|
linkPosition(source, computer)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
table.display(source);
|
|
|
|
return computers.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Display additional information about a single computer.
|
|
|
|
*
|
|
|
|
* @param source The thing that executed this command.
|
|
|
|
* @param computer The computer we're dumping.
|
|
|
|
* @return The constant {@code 1}.
|
|
|
|
*/
|
|
|
|
private static int dumpComputer(CommandSourceStack source, ServerComputer computer) {
|
|
|
|
var table = new TableBuilder("Dump");
|
Replace integer instance IDs with UUIDs
Here's a fun bug you can try at home:
- Create a new world
- Spawn in a pocket computer, turn it on, and place it in a chest.
- Reload the world - the pocket computer in the chest should now be
off.
- Spawn in a new pocket computer, and turn it on. The computer in chest
will also appear to be on!
This bug has been present since pocket computers were added (27th March,
2024).
When a pocket computer is added to a player's inventory, it is assigned
a unique *per-session* "instance id" , which is used to find the
associated computer. Note the "per-session" there - these ids will be
reused if you reload the world (or restart the server).
In the above bug, we see the following:
- The first pocket computer is assigned an instance id of 0.
- After reloading, the second pocket computer is assigned an instance
id of 0.
- If the first pocket computer was in our inventory, it'd be ticked and
assigned a new instance id. However, because it's in an inventory, it
keeps its old one.
- Both computers look up their client-side computer state and get the
same value, meaning the first pocket computer mirrors the second!
To fix this, we now ensure instance ids are entirely unique (not just
per-session). Rather than sequentially assigning an int, we now use a
random UUID (we probably could get away with a random long, but this
feels more idiomatic).
This has a couple of user-visible changes:
- /computercraft no longer lists instance ids outside of dumping an
individual computer.
- The @c[instance=...] selector uses UUIDs. We still use int instance
ids for the legacy selector, but that'll be removed in a later MC
version.
- Pocket computers now store a UUID rather than an int.
Related to this change (I made this change first, but then they got
kinda mixed up together), we now only create PocketComputerData when
receiving server data. This makes the code a little uglier in some
places (the data may now be null), but means we don't populate the
client-side pocket computer map with computers the server doesn't know
about.
2024-03-17 12:21:21 +00:00
|
|
|
table.row(header("Instance UUID"), text(computer.getInstanceUUID().toString()));
|
2023-09-05 17:37:10 +00:00
|
|
|
table.row(header("Id"), text(Integer.toString(computer.getID())));
|
|
|
|
table.row(header("Label"), text(computer.getLabel()));
|
|
|
|
table.row(header("On"), bool(computer.isOn()));
|
|
|
|
table.row(header("Position"), linkPosition(source, computer));
|
|
|
|
table.row(header("Family"), text(computer.getFamily().toString()));
|
|
|
|
|
|
|
|
for (var side : ComputerSide.values()) {
|
|
|
|
var peripheral = computer.getPeripheral(side);
|
|
|
|
if (peripheral != null) {
|
|
|
|
table.row(header("Peripheral " + side.getName()), text(peripheral.getType()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
table.display(source);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shutdown a list of computers.
|
|
|
|
*
|
|
|
|
* @param source The thing that executed this command.
|
|
|
|
* @param computers The computers to shutdown.
|
|
|
|
* @return The constant {@code 1}.
|
|
|
|
*/
|
|
|
|
private static int shutdown(CommandSourceStack source, Collection<ServerComputer> computers) {
|
|
|
|
var shutdown = 0;
|
|
|
|
for (var computer : computers) {
|
|
|
|
if (computer.isOn()) shutdown++;
|
|
|
|
computer.shutdown();
|
|
|
|
}
|
|
|
|
|
|
|
|
var didShutdown = shutdown;
|
|
|
|
source.sendSuccess(() -> Component.translatable("commands.computercraft.shutdown.done", didShutdown, computers.size()), false);
|
|
|
|
return shutdown;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Turn on a list of computers.
|
|
|
|
*
|
|
|
|
* @param source The thing that executed this command.
|
|
|
|
* @param computers The computers to turn on.
|
|
|
|
* @return The constant {@code 1}.
|
|
|
|
*/
|
|
|
|
private static int turnOn(CommandSourceStack source, Collection<ServerComputer> computers) {
|
|
|
|
var on = 0;
|
|
|
|
for (var computer : computers) {
|
|
|
|
if (!computer.isOn()) on++;
|
|
|
|
computer.turnOn();
|
|
|
|
}
|
|
|
|
|
|
|
|
var didOn = on;
|
|
|
|
source.sendSuccess(() -> Component.translatable("commands.computercraft.turn_on.done", didOn, computers.size()), false);
|
|
|
|
return on;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Teleport to a computer.
|
|
|
|
*
|
|
|
|
* @param source The thing that executed this command. This must be an entity, other types will throw an exception.
|
|
|
|
* @param computer The computer to teleport to.
|
|
|
|
* @return The constant {@code 1}.
|
|
|
|
*/
|
|
|
|
private static int teleport(CommandSourceStack source, ServerComputer computer) throws CommandSyntaxException {
|
|
|
|
var world = computer.getLevel();
|
|
|
|
var pos = Vec3.atBottomCenterOf(computer.getPosition());
|
|
|
|
source.getEntityOrException().teleportTo(world, pos.x(), pos.y(), pos.z(), EnumSet.noneOf(RelativeMovement.class), 0, 0);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Queue a {@code computer_command} event on a command computer.
|
|
|
|
*
|
|
|
|
* @param computers The list of computers to queue on.
|
|
|
|
* @param args The arguments for this event.
|
|
|
|
* @return The number of computers this event was queued on.
|
|
|
|
*/
|
|
|
|
private static int queue(Collection<ServerComputer> computers, List<String> args) {
|
|
|
|
var rest = args.toArray();
|
|
|
|
|
|
|
|
var queued = 0;
|
|
|
|
for (var computer : computers) {
|
|
|
|
if (computer.getFamily() == ComputerFamily.COMMAND && computer.isOn()) {
|
|
|
|
computer.queueEvent("computer_command", rest);
|
|
|
|
queued++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return queued;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Open a terminal for a computer.
|
|
|
|
*
|
|
|
|
* @param source The thing that executed this command.
|
|
|
|
* @param computer The computer to view.
|
|
|
|
* @return The constant {@code 1}.
|
|
|
|
*/
|
|
|
|
private static int view(CommandSourceStack source, ServerComputer computer) throws CommandSyntaxException {
|
|
|
|
var player = source.getPlayerOrException();
|
2024-04-25 20:32:48 +00:00
|
|
|
new ComputerContainerData(computer, new ItemStack(ModRegistry.Items.COMPUTER_NORMAL.get())).open(player, new MenuProvider() {
|
2023-09-05 17:37:10 +00:00
|
|
|
@Override
|
|
|
|
public Component getDisplayName() {
|
|
|
|
return Component.translatable("gui.computercraft.view_computer");
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public AbstractContainerMenu createMenu(int id, Inventory player, Player entity) {
|
|
|
|
return new ViewComputerMenu(id, player, computer);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start tracking metrics for the current player.
|
|
|
|
*
|
|
|
|
* @param source The thing that executed this command.
|
|
|
|
* @return The constant {@code 1}.
|
|
|
|
*/
|
|
|
|
private static int trackStart(CommandSourceStack source) {
|
|
|
|
getMetricsInstance(source).start();
|
|
|
|
|
|
|
|
var stopCommand = "/computercraft track stop";
|
|
|
|
source.sendSuccess(() -> Component.translatable(
|
|
|
|
"commands.computercraft.track.start.stop",
|
|
|
|
link(text(stopCommand), stopCommand, Component.translatable("commands.computercraft.track.stop.action"))
|
|
|
|
), false);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop tracking metrics for the current player, displaying a table with the results.
|
|
|
|
*
|
|
|
|
* @param source The thing that executed this command.
|
|
|
|
* @return The constant {@code 1}.
|
|
|
|
*/
|
|
|
|
private static int trackStop(CommandSourceStack source) throws CommandSyntaxException {
|
|
|
|
var metrics = getMetricsInstance(source);
|
|
|
|
if (!metrics.stop()) throw NOT_TRACKING_EXCEPTION.create();
|
|
|
|
displayTimings(source, metrics.getSnapshot(), new AggregatedMetric(Metrics.COMPUTER_TASKS, Aggregate.AVG), DEFAULT_FIELDS);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2023-10-21 09:37:43 +00:00
|
|
|
private static final List<AggregatedMetric> DEFAULT_FIELDS = List.of(
|
2023-09-05 17:37:10 +00:00
|
|
|
new AggregatedMetric(Metrics.COMPUTER_TASKS, Aggregate.COUNT),
|
|
|
|
new AggregatedMetric(Metrics.COMPUTER_TASKS, Aggregate.NONE),
|
|
|
|
new AggregatedMetric(Metrics.COMPUTER_TASKS, Aggregate.AVG)
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Display the latest metrics for the current player.
|
|
|
|
*
|
|
|
|
* @param source The thing that executed this command.
|
|
|
|
* @param fields The fields to display in this table, defaulting to {@link #DEFAULT_FIELDS}.
|
|
|
|
* @return The constant {@code 1}.
|
|
|
|
*/
|
|
|
|
private static int trackDump(CommandSourceStack source, List<AggregatedMetric> fields) throws CommandSyntaxException {
|
|
|
|
AggregatedMetric sort;
|
|
|
|
if (fields.size() == 1 && DEFAULT_FIELDS.contains(fields.get(0))) {
|
|
|
|
sort = fields.get(0);
|
|
|
|
fields = DEFAULT_FIELDS;
|
|
|
|
} else {
|
|
|
|
sort = fields.get(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return displayTimings(source, getMetricsInstance(source).getTimings(), sort, fields);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Additional helper functions.
|
|
|
|
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
private static Component linkComputer(CommandSourceStack source, @Nullable ServerComputer computer, int computerId) {
|
2022-06-07 23:08:24 +00:00
|
|
|
var out = Component.literal("");
|
2018-06-22 07:28:36 +00:00
|
|
|
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
// And instance
|
|
|
|
if (computer == null) {
|
|
|
|
out.append("#" + computerId + " ").append(coloured("(unloaded)", ChatFormatting.GRAY));
|
2018-06-22 07:28:36 +00:00
|
|
|
} else {
|
Replace integer instance IDs with UUIDs
Here's a fun bug you can try at home:
- Create a new world
- Spawn in a pocket computer, turn it on, and place it in a chest.
- Reload the world - the pocket computer in the chest should now be
off.
- Spawn in a new pocket computer, and turn it on. The computer in chest
will also appear to be on!
This bug has been present since pocket computers were added (27th March,
2024).
When a pocket computer is added to a player's inventory, it is assigned
a unique *per-session* "instance id" , which is used to find the
associated computer. Note the "per-session" there - these ids will be
reused if you reload the world (or restart the server).
In the above bug, we see the following:
- The first pocket computer is assigned an instance id of 0.
- After reloading, the second pocket computer is assigned an instance
id of 0.
- If the first pocket computer was in our inventory, it'd be ticked and
assigned a new instance id. However, because it's in an inventory, it
keeps its old one.
- Both computers look up their client-side computer state and get the
same value, meaning the first pocket computer mirrors the second!
To fix this, we now ensure instance ids are entirely unique (not just
per-session). Rather than sequentially assigning an int, we now use a
random UUID (we probably could get away with a random long, but this
feels more idiomatic).
This has a couple of user-visible changes:
- /computercraft no longer lists instance ids outside of dumping an
individual computer.
- The @c[instance=...] selector uses UUIDs. We still use int instance
ids for the legacy selector, but that'll be removed in a later MC
version.
- Pocket computers now store a UUID rather than an int.
Related to this change (I made this change first, but then they got
kinda mixed up together), we now only create PocketComputerData when
receiving server data. This makes the code a little uglier in some
places (the data may now be null), but means we don't populate the
client-side pocket computer map with computers the server doesn't know
about.
2024-03-17 12:21:21 +00:00
|
|
|
out.append(makeComputerDumpCommand(computer));
|
2018-06-22 07:28:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// And, if we're a player, some useful links
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
if (computer != null && isPlayer(source)) {
|
2023-08-27 11:15:55 +00:00
|
|
|
if (ModRegistry.Permissions.PERMISSION_TP.test(source)) {
|
|
|
|
out.append(" ").append(link(
|
2018-06-22 07:28:36 +00:00
|
|
|
text("\u261b"),
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
makeComputerCommand("tp", computer),
|
2023-06-02 20:47:52 +00:00
|
|
|
Component.translatable("commands.computercraft.tp.action")
|
2023-08-27 11:15:55 +00:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ModRegistry.Permissions.PERMISSION_VIEW.test(source)) {
|
|
|
|
out.append(" ").append(link(
|
2018-06-22 07:28:36 +00:00
|
|
|
text("\u20e2"),
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
makeComputerCommand("view", computer),
|
2023-06-02 20:47:52 +00:00
|
|
|
Component.translatable("commands.computercraft.view.action")
|
2018-06-22 07:28:36 +00:00
|
|
|
));
|
2023-08-27 11:15:55 +00:00
|
|
|
}
|
2018-06-22 07:28:36 +00:00
|
|
|
}
|
|
|
|
|
2023-08-27 11:15:55 +00:00
|
|
|
if (isPlayer(source) && UserLevel.isOwner(source)) {
|
2022-10-25 21:36:21 +00:00
|
|
|
var linkPath = linkStorage(source, computerId);
|
2021-05-28 21:19:04 +00:00
|
|
|
if (linkPath != null) out.append(" ").append(linkPath);
|
|
|
|
}
|
|
|
|
|
2018-06-22 07:28:36 +00:00
|
|
|
return out;
|
2017-12-06 15:51:02 +00:00
|
|
|
}
|
|
|
|
|
2021-08-03 20:46:53 +00:00
|
|
|
private static Component linkPosition(CommandSourceStack context, ServerComputer computer) {
|
2023-08-27 11:15:55 +00:00
|
|
|
if (ModRegistry.Permissions.PERMISSION_TP.test(context)) {
|
2017-12-06 15:51:02 +00:00
|
|
|
return link(
|
|
|
|
position(computer.getPosition()),
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
makeComputerCommand("tp", computer),
|
2023-06-02 20:47:52 +00:00
|
|
|
Component.translatable("commands.computercraft.tp.action")
|
2017-12-06 15:51:02 +00:00
|
|
|
);
|
|
|
|
} else {
|
|
|
|
return position(computer.getPosition());
|
|
|
|
}
|
|
|
|
}
|
2018-02-02 13:34:27 +00:00
|
|
|
|
2022-11-09 18:58:31 +00:00
|
|
|
private static @Nullable Component linkStorage(CommandSourceStack source, int id) {
|
2022-10-21 20:01:01 +00:00
|
|
|
var file = new File(ServerContext.get(source.getServer()).storageDir().toFile(), "computer/" + id);
|
2021-05-28 21:19:04 +00:00
|
|
|
if (!file.isDirectory()) return null;
|
|
|
|
|
2024-03-21 21:45:17 +00:00
|
|
|
return clientLink(
|
2021-05-28 21:19:04 +00:00
|
|
|
text("\u270E"),
|
2024-01-30 22:00:36 +00:00
|
|
|
"/" + CLIENT_OPEN_FOLDER + " " + id,
|
2023-06-02 20:47:52 +00:00
|
|
|
Component.translatable("commands.computercraft.dump.open_path")
|
2021-05-28 21:19:04 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-10-25 21:36:21 +00:00
|
|
|
private static BasicComputerMetricsObserver getMetricsInstance(CommandSourceStack source) {
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
var entity = source.getEntity();
|
2022-10-25 21:36:21 +00:00
|
|
|
return ServerContext.get(source.getServer()).metrics().getMetricsInstance(entity instanceof Player ? entity.getUUID() : SYSTEM_UUID);
|
2018-04-16 20:06:16 +00:00
|
|
|
}
|
2018-02-02 13:34:27 +00:00
|
|
|
|
2022-10-25 21:36:21 +00:00
|
|
|
private static int displayTimings(CommandSourceStack source, List<ComputerMetrics> timings, AggregatedMetric sortField, List<AggregatedMetric> fields) throws CommandSyntaxException {
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
if (timings.isEmpty()) throw NO_TIMINGS_EXCEPTION.create();
|
2018-02-02 13:34:27 +00:00
|
|
|
|
2022-10-22 00:35:04 +00:00
|
|
|
timings.sort(Comparator.<ComputerMetrics, Long>comparing(x -> x.get(sortField.metric(), sortField.aggregate())).reversed());
|
2018-04-16 20:06:16 +00:00
|
|
|
|
2021-08-03 20:46:53 +00:00
|
|
|
var headers = new Component[1 + fields.size()];
|
2023-06-02 20:47:52 +00:00
|
|
|
headers[0] = Component.translatable("commands.computercraft.track.dump.computer");
|
2022-10-22 00:35:04 +00:00
|
|
|
for (var i = 0; i < fields.size(); i++) headers[i + 1] = fields.get(i).displayName();
|
2022-07-28 07:51:10 +00:00
|
|
|
var table = new TableBuilder("Metrics", headers);
|
2018-04-16 20:06:16 +00:00
|
|
|
|
2022-10-22 00:35:04 +00:00
|
|
|
for (var entry : timings) {
|
|
|
|
var serverComputer = entry.computer();
|
2018-02-02 13:34:27 +00:00
|
|
|
|
2022-10-25 21:36:21 +00:00
|
|
|
var computerComponent = linkComputer(source, serverComputer, entry.computerId());
|
2018-08-04 09:39:44 +00:00
|
|
|
|
2021-08-03 20:46:53 +00:00
|
|
|
var row = new Component[1 + fields.size()];
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
row[0] = computerComponent;
|
2022-10-22 00:35:04 +00:00
|
|
|
for (var i = 0; i < fields.size(); i++) {
|
|
|
|
var metric = fields.get(i);
|
|
|
|
row[i + 1] = text(entry.getFormatted(metric.metric(), metric.aggregate()));
|
|
|
|
}
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
table.row(row);
|
2018-08-04 09:39:44 +00:00
|
|
|
}
|
|
|
|
|
Update CC: Tweaked to 1.13
Look, I originally had this split into several commits, but lots of
other cleanups got mixed in. I then backported some of the cleanups to
1.12, did other tidy ups there, and eventually the web of merges was
unreadable.
Yes, this is a horrible mess, but it's still nicer than it was. Anyway,
changes:
- Flatten everything. For instance, there are now three instances of
BlockComputer, two BlockTurtle, ItemPocketComputer. There's also no
more BlockPeripheral (thank heavens) - there's separate block classes
for each peripheral type.
- Remove pretty much all legacy code. As we're breaking world
compatibility anyway, we can remove all the code to load worlds from
1.4 days.
- The command system is largely rewriten to take advantage of 1.13's
new system. It's very fancy!
- WidgetTerminal now uses Minecraft's "GUI listener" system.
- BREAKING CHANGE: All the codes in keys.lua are different, due to the
move to LWJGL 3. Hopefully this won't have too much of an impact.
I don't want to map to the old key codes on the Java side, as there
always ends up being small but slight inconsistencies. IMO it's
better to make a clean break - people should be using keys rather
than hard coding the constants anyway.
- commands.list now allows fetching sub-commands. The ROM has already
been updated to allow fancy usage such as commands.time.set("noon").
- Turtles, modems and cables can be waterlogged.
2019-04-02 12:27:27 +00:00
|
|
|
table.display(source);
|
|
|
|
return timings.size();
|
2018-08-04 09:39:44 +00:00
|
|
|
}
|
Rewrite computer selectors
This adds support for computer selectors, in the style of entity
selectors. The long-term goal here is to replace our existing ad-hoc
selectors. However, to aid migration, we currently support both - the
previous one will most likely be removed in MC 1.21.
Computer selectors take the form @c[<key>=<value>,...]. Currently we
support filtering by id, instance id, label, family (as before) and
distance from the player (new!). The code also supports computers within
a bounding box, but there's no parsing support for that yet.
This commit also (finally) documents the /computercraft command. Well,
sort of - it's definitely not my best word, but I couldn't find better
words.
2024-03-12 20:12:13 +00:00
|
|
|
|
|
|
|
public static Set<ServerComputer> unwrap(CommandSourceStack source, Collection<ComputerSelector> suppliers) {
|
|
|
|
Set<ServerComputer> computers = new HashSet<>();
|
|
|
|
for (var supplier : suppliers) supplier.find(source).forEach(computers::add);
|
|
|
|
return computers;
|
|
|
|
}
|
2017-12-06 15:51:02 +00:00
|
|
|
}
|