ru:tutorial:commands
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
ru:tutorial:commands [2022/03/03 11:50] – furnygo | ru:tutorial:commands [2022/03/03 13:27] (current) – furnygo | ||
---|---|---|---|
Line 221: | Line 221: | ||
| [[ru: | | [[ru: | ||
| [[ru: | | [[ru: | ||
- | | [[ru: | + | | [[ru: |
- | | [[ru: | + | | [[ru: |
| [[ru: | | [[ru: | ||
- | |||
- | **Будет сделано позже: | ||
====== Часто задаваемые вопросы ====== | ====== Часто задаваемые вопросы ====== | ||
Line 261: | Line 259: | ||
---- | ---- | ||
- | ====== Со временем | + | ====== Со временем будет перенесено |
- | **__Currently this article is being migrated, so things may be a mess. Below is are the parts of the article that are yet to be migrated to the new format.__** | + | ===== Что может сделать ServerCommandSource? |
- | ===== Requirements ===== | + | '' |
- | + | ||
- | Lets say you have a command you only want operators to be able to execute. This is where the '' | + | |
- | + | ||
- | For example this may look like the following: | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | dispatcher.register(literal(" | + | |
- | .requires(source -> source.hasPermissionLevel(4)) | + | |
- | .executes(ctx -> { | + | |
- | ctx.getSource().sendFeedback(new LiteralText(" | + | |
- | return 1; | + | |
- | }); | + | |
- | </ | + | |
- | + | ||
- | This command will only execute if the Source of the command is a level 4 operator at minimum. If the predicate returns false, then the command will not execute. Also this has the side effect of not showing this command in tab completion to anyone who is not a level 4 operator. | + | |
- | + | ||
- | Nothing prevents someone from specifying calls to permissions implementations within the '' | + | |
- | + | ||
- | ===== Exceptions ===== | + | |
- | + | ||
- | Brigadier supports command exceptions which can be used to end a command such as if an argument didn't parse properly or the command failed to execute, as well as including richer details of the failure. | + | |
- | + | ||
- | All the exceptions from Brigadier are based on the CommandSyntaxException. The two main types of exceptions Brigadier provides are Dynamic and Simple exception types, of which you must '' | + | |
- | Below is a coin flip command to show an example of exceptions in use. | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | dispatcher.register(CommandManager.literal(" | + | |
- | .executes(ctx -> { | + | |
- | Random random = new Random(); | + | |
- | + | ||
- | if(random.nextBoolean()) { // If heads succeed. | + | |
- | ctx.getSource().sendMessage(new TranslateableText(" | + | |
- | return Command.SINGLE_SUCCESS; | + | |
- | } | + | |
- | + | ||
- | throw new SimpleCommandExceptionType(new TranslateableText(" | + | |
- | })); | + | |
- | </ | + | |
- | + | ||
- | Though you are not just limited to a single type of exception as Brigadier also supplies Dynamic exceptions which take additional parameters for context. | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | DynamicCommandExceptionType used_name = new DynamicCommandExceptionType(name -> { | + | |
- | return new LiteralText(" | + | |
- | }); | + | |
- | </ | + | |
- | + | ||
- | There are more Dynamic exception types which each take a different amount of arguments into account ('' | + | |
- | You should remember that the Dynamic exceptions takes an object as an argument so you may have to cast the argument for your use. | + | |
- | + | ||
- | ===== Redirects (Aliases) ===== | + | |
- | + | ||
- | Redirects are Brigadier' | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | public static void register(CommandDispatcher< | + | |
- | LiteralCommandNode node = registerMain(dispatcher); | + | |
- | dispatcher.register(literal(" | + | |
- | .redirect(node)); | + | |
- | dispatcher.register(literal(" | + | |
- | .redirect(node)); | + | |
- | } | + | |
- | + | ||
- | public static LiteralCommandNode registerMain(CommandDispatcher< | + | |
- | return dispatcher.register(literal(" | + | |
- | .then(argument(" | + | |
- | .then(argument(" | + | |
- | .executes(ctx -> { | + | |
- | return execute(ctx.getSource(), | + | |
- | })))); | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | The redirect tells brigadier to continue parsing the command at another command node. | + | |
- | + | ||
- | ===== Redirects (Chainable Commands) ===== | + | |
- | Commands such as ''/ | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | LiteralCommandNode< | + | |
- | LiteralCommandNode< | + | |
- | // You can register under the same literal more than once, it will just register new parts of the branch as shown below if you register a duplicate branch an error will popup in console warning of conflicting commands but one will still work. | + | |
- | .then(literal(" | + | |
- | .then(literal(" | + | |
- | .redirect(root, | + | |
- | .then(literal(" | + | |
- | .redirect(root, | + | |
- | .then(literal(" | + | |
- | .executes(ctx -> { | + | |
- | ctx.getSource().sendFeedback(new LiteralText(" | + | |
- | return Command.SINGLE_SUCCESS; | + | |
- | }))); | + | |
- | </ | + | |
- | The redirect can also modify the CommandSource by use of a '' | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | .redirect(rootNode, | + | |
- | return ((ServerCommandSource) context.getSource()).withLookingAt(Vec3ArgumentType.getVec3(context, | + | |
- | }) | + | |
- | </ | + | |
- | + | ||
- | ===== What can the ServerCommandSource do? ===== | + | |
- | + | ||
- | A server command source provides some additional implementation specific context when a command is run. This includes the ability to get the entity that executed the command, the world the command was ran in or the server the command was run on. | + | |
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
final ServerCommandSource source = ctx.getSource(); | final ServerCommandSource source = ctx.getSource(); | ||
- | // Get the source. This will always work. | + | // Находка источника. Это всегда будет работать. |
final Entity sender = source.getEntity(); | final Entity sender = source.getEntity(); | ||
- | // Unchecked, may be null if the sender was the console. | + | // Непроверенный, может быть нулевым, |
final Entity sender2 = source.getEntityOrThrow(); | final Entity sender2 = source.getEntityOrThrow(); | ||
- | // Will end the command if the source of the command was not an Entity. | + | // Завершит выполнение команды, |
- | // The result of this could contain a player. Also will send feedback telling the sender of the command that they must be an entity. | + | // В результате этого может появиться игрок. Также будет отправлена обратная связь, сообщающая отправителю команды, |
- | // This method will require your methods to throw a CommandSyntaxException. | + | // Этот метод потребует, |
- | // The entity options in ServerCommandSource | + | // Параметры сущности в ServerCommandSource |
final ServerPlayerEntity player = source.getPlayer(); | final ServerPlayerEntity player = source.getPlayer(); | ||
- | // Will end the command if the source of the command was not explicitly a Player. Also will send feedback telling the sender of the command that they must be a player. This method will require your methods to throw a CommandSyntaxException | + | // Завершит выполнение команды, |
+ | // Этот метод потребует, | ||
source.getPosition(); | source.getPosition(); | ||
- | // Get's the sender' | + | // Позиция отправителя в качестве |
source.getWorld(); | source.getWorld(); | ||
- | // Get's the world the sender is within. The console' | + | // Мир, в котором находится отправитель. Мир консоли такой же, как и мир создания по умолчанию. |
source.getRotation(); | source.getRotation(); | ||
- | // Get's the sender' | + | // Вращение отправителя как |
source.getMinecraftServer(); | source.getMinecraftServer(); | ||
- | // Access to the instance of the MinecraftServer | + | // Доступ к экземпляру |
source.getName(); | source.getName(); | ||
- | // The name of the command source. This could be the name of the entity, player, the name of a CommandBlock that has been renamed before being placed down or in the case of the Console, " | + | // Имя источника команды. Это может быть имя сущности, игрока, имя командного блока, который был переименован перед размещением, |
source.hasPermissionLevel(int level); | source.hasPermissionLevel(int level); | ||
- | // Returns | + | // Возвращает значение |
</ | </ | ||
- | ===== Some example commands examples | + | ===== Некоторые примеры команд |
- | === Broadcast a message | + | === Транслировать сообщение |
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
public static void register(CommandDispatcher< | public static void register(CommandDispatcher< | ||
dispatcher.register(literal(" | dispatcher.register(literal(" | ||
- | .requires(source -> source.hasPermissionLevel(2)) // Must be a game master to use the command. Command will not show up in tab completion or execute to non operators or any operator that is permission level 1. | + | .requires(source -> source.hasPermissionLevel(2)) // Должен быть мастером игры, чтобы использовать эту команду. Команда не будет отображаться при перебора через Tab или выполняться не для операторов или любого оператора, |
.then(argument(" | .then(argument(" | ||
.then(argument(" | .then(argument(" | ||
- | .executes(ctx -> broadcast(ctx.getSource(), | + | .executes(ctx -> broadcast(ctx.getSource(), |
} | } | ||
Line 423: | Line 318: | ||
source.getMinecraftServer().getPlayerManager().broadcastChatMessage(text, | source.getMinecraftServer().getPlayerManager().broadcastChatMessage(text, | ||
- | return Command.SINGLE_SUCCESS; | + | return Command.SINGLE_SUCCESS; |
} | } | ||
</ | </ | ||
Line 429: | Line 324: | ||
==== / | ==== / | ||
- | First the basic code where we register "giveMeDiamond" as a literal and then an executes block to tell the dispatcher which method to run. | + | Сначала базовый код, в котором мы регистрируем '' |
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
- | public static LiteralCommandNode register(CommandDispatcher< | + | public static LiteralCommandNode register(CommandDispatcher< |
return dispatcher.register(literal(" | return dispatcher.register(literal(" | ||
.executes(ctx -> giveDiamond(ctx))); | .executes(ctx -> giveDiamond(ctx))); | ||
Line 438: | Line 333: | ||
</ | </ | ||
- | Then since we only want to give to players, we check if the CommandSource | + | Затем, поскольку мы хотим передавать только игрокам, |
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
Line 444: | Line 339: | ||
final ServerCommandSource source = ctx.getSource(); | final ServerCommandSource source = ctx.getSource(); | ||
- | final PlayerEntity self = source.getPlayer(); | + | final PlayerEntity self = source.getPlayer(); |
</ | </ | ||
- | Then we add to the player' | + | Затем мы добавляем в инвентарь игрока, проверяя, |
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
Line 458: | Line 353: | ||
</ | </ | ||
- | ==== Antioch | + | ==== Граната Антиоха |
- | ...lobbest thou thy Holy Hand Grenade of Antioch towards thy foe. | + | ...брось ты свою Святую Ручную Гранату из Антиохии своему врагу. |
- | who being naughty in My sight, shall snuff it. | + | который, будучи непослушным в моих глазах, |
+ | (Иностранный прикол) | ||
- | Aside from the joke this command summons a primed | + | Помимо шутки, эта команда вызывает заряженный |
- | First create an entry into the CommandDispatcher | + | Сначала создайте запись в CommandDispatcher, которая принимает литерал |
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
Line 475: | Line 371: | ||
</ | </ | ||
- | Then the creation and messages behind the joke. | + | Затем создайте сообщения, |
<code java [enable_line_numbers=" | <code java [enable_line_numbers=" | ||
public static int antioch(ServerCommandSource source, BlockPos blockPos) throws CommandSyntaxException { | public static int antioch(ServerCommandSource source, BlockPos blockPos) throws CommandSyntaxException { | ||
if(blockPos == null) { | if(blockPos == null) { | ||
- | // For the case of no inputted argument we calculate the cursor position of the player or throw an error if the nearest position is too far or is outside of the world. | + | // В случае отсутствия введенного аргумента мы вычисляем положение курсора игрока или выдаем ошибку, |
- | // This class is used as an example and actually doesn' | + | // Этот класс используется в качестве примера и на самом деле еще не существует. |
blockPos = LocationUtil.calculateCursorOrThrow(source, | blockPos = LocationUtil.calculateCursorOrThrow(source, | ||
} | } | ||
Line 488: | Line 384: | ||
tnt.setFuse(3); | tnt.setFuse(3); | ||
| | ||
- | source.getMinecraftServer().getPlayerManager().broadcastChatMessage(new LiteralText(" | + | source.getMinecraftServer().getPlayerManager().broadcastChatMessage(new LiteralText(" |
- | source.getMinecraftServer().getPlayerManager().broadcastChatMessage(new LiteralText(" | + | source.getMinecraftServer().getPlayerManager().broadcastChatMessage(new LiteralText(" |
source.getWorld().spawnEntity(tnt); | source.getWorld().spawnEntity(tnt); | ||
return 1; | return 1; | ||
Line 495: | Line 391: | ||
</ | </ | ||
- | ==== More examples coming soon ==== | + | ==== Скоро появятся новые примеры |
- | + | ||
- | ===== Custom Argument Types ===== | + | |
- | + | ||
- | Brigadier has support for custom argument types and this section goes into showing how to create a simple argument type. | + | |
- | + | ||
- | Warning: Custom arguments require client mod installation to be registered correctly! If you are making a server plugin, consider using existing argument type and a custom suggestions provider instead. | + | |
- | + | ||
- | For this example we will create a UuidArgumentType. | + | |
- | + | ||
- | First create a class which extends '' | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | public class UuidArgumentType implements ArgumentType< | + | |
- | </ | + | |
- | + | ||
- | ArgumentType requires you to implement the '' | + | |
- | <code java> | + | |
- | @Override | + | |
- | public UUID parse(StringReader reader) throws CommandSyntaxException { | + | |
- | </ | + | |
- | + | ||
- | This method is where all of your parsing will occur. Either this method will return the object based on the arguments provided in the command line or throw a CommandSyntaxException and parsing will fail. | + | |
- | + | ||
- | Next you will store the current position of the cursor, this is so you can substring out only the specific argument. This will always be at the beginning of where your argument appears on the command line. | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | int argBeginning = reader.getCursor(); | + | |
- | if (!reader.canRead()) { | + | |
- | reader.skip(); | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | Now we grab the entire argument. Depending on your argument type, you may have a different criteria or be similar to some arguments where detecting a '' | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | while (reader.canRead() && reader.peek() != ' ') { // peek provides the character at the current cursor position. | + | |
- | reader.skip(); | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | Then we will ask the StringReader what the current position of the cursor is an substring our argument out of the command line. | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | + | ||
- | Now finally we check if our argument is correct and parse the specific argument to our liking, and throwing an exception if the parsing fails. | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | try { | + | |
- | UUID uuid = UUID.fromString(uuidString); | + | |
- | return uuid; // And we return our type, in this case the parser will consider this argument to have parsed properly and then move on. | + | |
- | } catch (Exception ex) { | + | |
- | // UUIDs can throw an exception when made by a string, so we catch the exception and repackage it into a CommandSyntaxException type. | + | |
- | // Create with context tells Brigadier to supply some context to tell the user where the command failed at. | + | |
- | // Though normal create method could be used. | + | |
- | throw new SimpleCommandExceptionType(new LiteralText(ex.getMessage())).createWithContext(reader); | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | The ArgumentType is done, however your client will refuse the parse the argument and throw an error. This is because the server will tell the client what argument type the command node is. And the client will not parse any argument types it does not know how to parse. To fix this we need to register an ArgumentSerializer. | + | |
- | Within your ModInitializer. For more complex argument types, you may need to create your own ArgumentSerializer. | + | |
- | + | ||
- | <code java [enable_line_numbers=" | + | |
- | ArgumentTypes.register(" | + | |
- | // The argument should be what will create the ArgumentType. | + | |
- | </ | + | |
- | + | ||
- | And here is the whole ArgumentType: | + | |
- | + | ||
- | <file java UuidArgumentType.java [enable_line_numbers=" | + | |
- | + | ||
- | import com.mojang.brigadier.StringReader; | + | |
- | import com.mojang.brigadier.arguments.ArgumentType; | + | |
- | import com.mojang.brigadier.context.CommandContext; | + | |
- | import com.mojang.brigadier.exceptions.CommandSyntaxException; | + | |
- | import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; | + | |
- | import net.minecraft.text.LiteralText; | + | |
- | import net.minecraft.util.SystemUtil; | + | |
- | + | ||
- | import java.util.ArrayList; | + | |
- | import java.util.Collection; | + | |
- | import java.util.UUID; | + | |
- | + | ||
- | /** | + | |
- | * Represents an ArgumentType that will return a UUID. | + | |
- | */ | + | |
- | public class UuidArgumentType implements ArgumentType< | + | |
- | public static UuidArgumentType uuid() { | + | |
- | return new UuidArgumentType(); | + | |
- | } | + | |
- | + | ||
- | public static <S> UUID getUuid(String name, CommandContext< | + | |
- | // Note that you should assume the CommandSource wrapped inside of the CommandContext will always be a generic type. | + | |
- | // If you need to access the ServerCommandSource make sure you verify the source is a server command source before casting. | + | |
- | return context.getArgument(name, | + | |
- | } | + | |
- | + | ||
- | private static final Collection< | + | |
- | list.add(" | + | |
- | list.add(" | + | |
- | list.add(" | + | |
- | }); | + | |
- | + | ||
- | @Override | + | |
- | public UUID parse(StringReader reader) throws CommandSyntaxException { | + | |
- | int argBeginning = reader.getCursor(); | + | |
- | if (!reader.canRead()) { | + | |
- | reader.skip(); | + | |
- | } | + | |
- | + | ||
- | // Now we check the contents of the argument till either we hit the end of the command line (When canRead becomes false) | + | |
- | // Otherwise we go till reach reach a space, which signifies the next argument | + | |
- | while (reader.canRead() && reader.peek() != ' ') { // peek provides the character at the current cursor position. | + | |
- | reader.skip(); | + | |
- | } | + | |
- | + | ||
- | // Now we substring the specific part we want to see using the starting cursor position and the ends where the next argument starts. | + | |
- | String uuidString = reader.getString().substring(argBeginning, | + | |
- | try { | + | |
- | UUID uuid = UUID.fromString(uuidString); | + | |
- | return uuid; // And we return our type, in this case the parser will consider this argument to have parsed properly and then move on. | + | |
- | } catch (Exception ex) { | + | |
- | // UUIDs can throw an exception when made by a string, so we catch the exception and repackage it into a CommandSyntaxException type. | + | |
- | // Create with context tells Brigadier to supply some context to tell the user where the command failed at. | + | |
- | // Though normal create method could be used. | + | |
- | throw new SimpleCommandExceptionType(new LiteralText(ex.getMessage())).createWithContext(reader); | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | @Override | + | |
- | public Collection< | + | |
- | return EXAMPLES; | + | |
- | } | + | |
- | } | + | |
- | </ | + |
ru/tutorial/commands.1646308225.txt.gz · Last modified: 2022/03/03 11:50 by furnygo