From 1fe283c136ac39f164b58fa28211c776315f7dd7 Mon Sep 17 00:00:00 2001 From: Nathan Adams Date: Mon, 24 Sep 2018 16:21:51 +0200 Subject: [PATCH] Added readme --- README.md | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..73e0573 --- /dev/null +++ b/README.md @@ -0,0 +1,133 @@ +# Brigadier +Brigadier is a command parser & dispatcher, designed and developed for Minecraft: Java Edition and now freely available for use elsewhere under the MIT license. + +# Installation +Brigadier is available to Maven & Gradle via `libraries.minecraft.net`. Its group is `com.mojang`, and artifact name is `brigadier`. + +## Gradle +First include our repository: +```groovy +maven { + url "https://libraries.minecraft.net" +} +``` + +And then use this library (change `(the latest version)` to the latest version!): +```groovy +compile 'com.mojang:brigadier:(the latest version)' +``` + +## Maven +First include our repository: +```xml + + minecraft-libraries + Minecraft Libraries + https://libraries.minecraft.net + +``` + +And then use this library (change `(the latest version)` to the latest version!): +```xml + + com.mojang + brigadier + (the latest version) + +``` + +# Contributing +Contributions are suspended until we have a process in place to handle them. + +Most contributions will require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, +and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com. + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +# Usage +At the heart of Brigadier, you need a `CommandDispatcher`, where `` is any custom object you choose to identify a "command source". + +A command dispatcher holds a "command tree", which are a series of `CommandNode` which represent the various possible syntax that form a valid command. + +## Registering a new command +Before we can start parsing and dispatching commands, we need to build up our command tree. Every registration is an append operation, +so you can freely extend existing commands in a project without needing access to the source code that created them. + +Command registration also encourages use of a builder pattern to keep code cruft to a minimum. + +A "command" is a fairly loose term, but typically it means an exit point of the command tree. +Every node can have an `executes` function attached to it, which signifies that if the input stops here then this function will be called with the context so far. + +Consider the following example: +```java +CommandDispatcher dispatcher = new CommandDispatcher(); + +dispatcher.register( + literal("foo") + .then( + argument("bar", integer()) + .executes(c -> { + System.out.println("Bar is " + getInteger(c, "bar")); + return 1; + }) + ) + .executes(c -> { + System.out.println("Called foo with no arguments"); + return 1; + }) +); +``` + +This snippet registers two "commands": `foo` and `foo `. It is also common to refer to the `` as a "subcommand" of `foo`, as it's a child node. + +At the start of the tree is a "root node", and it **must** have `LiteralCommandNode`s as children. Here, we register one command under the root: `literal("foo")`, which means "the user must type the literal string 'foo'". + +Under that is two extra definitions: a child node for possible further evaluation, or an `executes` block if the user input stops here. + +The child node works exactly the same way, but is no longer limited to literals. The other type of node that is now allowed is an `ArgumentCommandNode`, which takes in a name and an argument type. + +Arguments can be anything, and you are encouraged to build your own for seamless integration into your own product. There are some standard arguments included in brigadier, such as `IntegerArgumentType`. + +Argument types will be asked to parse input as much as they can, and then store the "result" of that argument however they see fit or throw a relevant error if they can't parse. + +For example, an integer argument would parse "123" and store it as `123` (`int`), but throw an error if the input were `onetwothree`. + +When a command is actually ran, it can access these arguments in the context provided to the registered function. + +## Parsing user input +So, we've registered some commands and now we're ready to take in user input. If you're in a rush, you can just call `dispatcher.execute("foo 123", source)` and call it a day. + +The result of `execute` is an integer returned by the command it evaluated. Its meaning varies depending on command, and typically will not be useful to programmers. + +The `source` is an object of ``, your own custom class to track users/players/etc. It will be provided to the command so that it has some context on what's happening. + +If the command failed or could not parse, some form of `CommandSyntaxException` will be thrown. It is also possible for a `RuntimeException` to be bubbled up, if not properly handled in a command. + +If you wish to have more control over the parsing & executing of commands, or wish to cache the parse results so you can execute it multiple times, you can split it up into two steps: + +```java +final ParseResults parse = dispatcher.parse("foo 123", source); +final int result = execute(parse); +``` + +This is highly recommended as the parse step is the most expensive, and may be easily cached depending on your application. + +You can also use this to do further introspection on a command, before (or without) actually running it. + +## Inspecting a command +If you `parse` some input, you can find out what it will perform (if anything) and provide hints to the user safely and immediately. + +The parse will never fail, and the `ParseResults` it returns will contain a *possible* context that a command may be called with +(and from that, you can inspect which nodes the user entered, complete with start/end positions in the input string). +It also contains a map of parse exceptions for each command node it encountered. If it couldn't build a valid context, then +the reason why is inside this exception map. + +## Displaying usage info +There's two forms of "usage strings" provided by this library, both require a target node. + +`getAllUsage(node, source, restricted)` will return a list of all possible commands (executable end-points) under the target node and their human readable path. If `restricted`, it will ignore commands that `source` does not have access to. This will look like [`foo`, `foo `] + +`getSmartUsage(node, source)` will return a map of the child nodes to their "smart usage" human readable path. This tries to squash future-nodes together and show optional & typed information, and can look like `foo ()` +