Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Command api v2 #5036

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
59d489e
rebuild dispatcher to support dynamic registries
RacoonDog Dec 7, 2024
4e8626c
use redirect nodes for aliases
RacoonDog Dec 7, 2024
a32bc82
utils for encoding/decoding components
RacoonDog Dec 7, 2024
7ce2c4b
simplify creative inventory packet usage
RacoonDog Dec 7, 2024
a6f8bb4
add item slot argument type
RacoonDog Dec 7, 2024
a646490
import some useful argument types from clientarguments
RacoonDog Dec 7, 2024
f3d9a17
fix terrible SettingArgumentType hack
RacoonDog Dec 7, 2024
b65ceab
split and rewrite .nbt command
RacoonDog Dec 7, 2024
50914f9
add .config
RacoonDog Dec 7, 2024
c473c58
add .multitool
RacoonDog Dec 7, 2024
969dbea
add .transmogrify
RacoonDog Dec 7, 2024
b91caf8
make `NotebotSongArgumentType` check if file exists
RacoonDog Dec 7, 2024
6c267a9
sort command registration alphabetically
RacoonDog Dec 7, 2024
92b25bb
various minor optimizations
RacoonDog Dec 7, 2024
cb44128
fix waypoint crash
RacoonDog Dec 7, 2024
702900f
use proper type for argument types rather than `String`
RacoonDog Dec 7, 2024
4bd6559
.enderchest check if memory
RacoonDog Dec 7, 2024
b896c84
.fov prevent crash
RacoonDog Dec 7, 2024
51e172b
rewrite .give to use new utils
RacoonDog Dec 7, 2024
b633be2
create & modify macros in .macro
RacoonDog Dec 7, 2024
04b7d0f
throw syntax error instead of chat error
RacoonDog Dec 7, 2024
bb334de
code deduplication
RacoonDog Dec 7, 2024
f3e4ca3
consistency
RacoonDog Dec 7, 2024
f15146b
Merge branch 'master' into command-api-v2
RacoonDog Dec 7, 2024
b63dadd
creative packets check feature flags + send listener updates
RacoonDog Dec 8, 2024
eb0368b
update .multitool and .transmogrify
RacoonDog Feb 1, 2025
14d662c
Merge branch 'master' into command-api-v2
RacoonDog Feb 1, 2025
c676b7c
fix cobwebs in multitool
RacoonDog Feb 1, 2025
bc7ffe4
fix stuff to work in 1.21.4
RacoonDog Feb 1, 2025
e4712f8
better feedback for .components
RacoonDog Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions src/main/java/meteordevelopment/meteorclient/commands/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import meteordevelopment.meteorclient.MeteorClient;
import meteordevelopment.meteorclient.systems.config.Config;
import meteordevelopment.meteorclient.utils.Utils;
Expand All @@ -23,7 +24,7 @@
import java.util.List;

public abstract class Command {
protected static final CommandRegistryAccess REGISTRY_ACCESS = CommandManager.createRegistryAccess(BuiltinRegistries.createWrapperLookup());
protected static CommandRegistryAccess REGISTRY_ACCESS = CommandManager.createRegistryAccess(BuiltinRegistries.createWrapperLookup());
protected static final int SINGLE_SUCCESS = com.mojang.brigadier.Command.SINGLE_SUCCESS;
protected static final MinecraftClient mc = MeteorClient.mc;

Expand All @@ -49,14 +50,21 @@ protected static LiteralArgumentBuilder<CommandSource> literal(final String name
}

public final void registerTo(CommandDispatcher<CommandSource> dispatcher) {
register(dispatcher, name);
for (String alias : aliases) register(dispatcher, alias);
LiteralArgumentBuilder<CommandSource> builder = literal(name);
build(builder);
LiteralCommandNode<CommandSource> node = dispatcher.register(builder);

for (String alias : aliases) registerAlias(dispatcher, node, alias);
}

public void register(CommandDispatcher<CommandSource> dispatcher, String name) {
LiteralArgumentBuilder<CommandSource> builder = LiteralArgumentBuilder.literal(name);
build(builder);
dispatcher.register(builder);
private void registerAlias(CommandDispatcher<CommandSource> dispatcher, LiteralCommandNode<CommandSource> node, String alias) {
LiteralArgumentBuilder<CommandSource> aliasBuilder = literal(alias);
if (node.getChildren().isEmpty()) { // apparently redirect nodes break when the target node has no children :/
build(aliasBuilder);
} else {
aliasBuilder.redirect(node);
}
dispatcher.register(aliasBuilder);
}

public abstract void build(LiteralArgumentBuilder<CommandSource> builder);
Expand Down
90 changes: 67 additions & 23 deletions src/main/java/meteordevelopment/meteorclient/commands/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@

import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import meteordevelopment.meteorclient.MeteorClient;
import meteordevelopment.meteorclient.commands.commands.*;
import meteordevelopment.meteorclient.events.game.GameJoinedEvent;
import meteordevelopment.meteorclient.pathing.PathManagers;
import meteordevelopment.meteorclient.utils.PostInit;
import meteordevelopment.orbit.EventHandler;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.command.CommandSource;

import java.util.ArrayList;
Expand All @@ -19,56 +24,61 @@
import static meteordevelopment.meteorclient.MeteorClient.mc;

public class Commands {
public static final CommandDispatcher<CommandSource> DISPATCHER = new CommandDispatcher<>();
public static final List<Command> COMMANDS = new ArrayList<>();
public static CommandDispatcher<CommandSource> DISPATCHER = new CommandDispatcher<>();

@PostInit(dependencies = PathManagers.class)
public static void init() {
add(new VClipCommand());
add(new HClipCommand());
add(new DismountCommand());
add(new DisconnectCommand());
add(new BindCommand());
add(new BindsCommand());
add(new CommandsCommand());
add(new ComponentsCommand());
add(new ConfigCommand());
add(new DamageCommand());
add(new DisconnectCommand());
add(new DismountCommand());
add(new DropCommand());
add(new EnchantCommand());
add(new EnderChestCommand());
add(new FakePlayerCommand());
add(new FovCommand());
add(new FriendsCommand());
add(new CommandsCommand());
add(new GamemodeCommand());
add(new GiveCommand());
add(new HClipCommand());
add(new InputCommand());
add(new InventoryCommand());
add(new LocateCommand());
add(new MacroCommand());
add(new ModulesCommand());
add(new MultitoolCommand());
add(new NameHistoryCommand());
add(new NbtCommand());
add(new NotebotCommand());
add(new PeekCommand());
add(new EnderChestCommand());
add(new ProfilesCommand());
add(new ReloadCommand());
add(new ResetCommand());
add(new RotationCommand());
add(new SaveMapCommand());
add(new SayCommand());
add(new ServerCommand());
add(new SwarmCommand());
add(new ToggleCommand());
add(new SettingCommand());
add(new SpectateCommand());
add(new GamemodeCommand());
add(new SaveMapCommand());
add(new MacroCommand());
add(new ModulesCommand());
add(new BindsCommand());
add(new GiveCommand());
add(new NameHistoryCommand());
add(new BindCommand());
add(new FovCommand());
add(new RotationCommand());
add(new WaypointCommand());
add(new InputCommand());
add(new SwarmCommand());
add(new ToggleCommand());
add(new TransmogrifyCommand());
add(new VClipCommand());
add(new WaspCommand());
add(new LocateCommand());
add(new WaypointCommand());

COMMANDS.sort(Comparator.comparing(Command::getName));

MeteorClient.EVENT_BUS.subscribe(Commands.class);
}

public static void add(Command command) {
COMMANDS.removeIf(existing -> existing.getName().equals(command.getName()));
command.registerTo(DISPATCHER);
COMMANDS.add(command);
}

Expand All @@ -85,4 +95,38 @@ public static Command get(String name) {

return null;
}

/**
* Argument types that rely on Minecraft registries access those registries through a {@link CommandRegistryAccess}
* object.
* Since dynamic registries are specific to each server, we need to make a new {@link CommandRegistryAccess} object
* every time we join a server.
* <p>
* Annoyingly, we also have to create a new {@link CommandDispatcher} because the command tree needs to be rebuilt
* from scratch. This is mainly due to two reasons:
* <ol>
* <li>Argument types that access registries do so through a registry wrapper object that is created and cached
* when the argument type objects are created, that is to say when the command tree is built.
* This would cause the registry wrapper objects to become stale after joining another server.
* <li>We can't re-register command nodes to the same {@link CommandDispatcher}, because the node merging that
* happens only registers missing children, it doesn't replace existing ones so the stale argument type
* objects wouldn't get replaced.
* </ol>
* <p>
* Ensuring dynamic registry entries match up perfectly is important, because even if a stale registry has identical
* contents to an up-to-date one, registry entries and keys are compared using referential equality, so their
* contents would not match.
*
* @author Crosby
*/
@EventHandler
private static void onJoin(GameJoinedEvent event) {
ClientPlayNetworkHandler networkHandler = mc.getNetworkHandler();
Command.REGISTRY_ACCESS = CommandRegistryAccess.of(networkHandler.getRegistryManager(), networkHandler.getEnabledFeatures());

DISPATCHER = new CommandDispatcher<>();
for (Command command : COMMANDS) {
command.registerTo(DISPATCHER);
}
}
}
Loading
Loading