A powerful, extendable, flexible yet simple to use commands annotation framework.

Overview

Lamp

License: MIT

Background

Building commands has always been a core concept in many applications, and, lots of times, a really boring and cumbersome one to pull off: Having to think of all the possible input from the user, all the mistakes they will make, validating input and then finally executing the actual command logic.

We aren't supposed to mess our hands up with so much of this. We really shouldn't get ourselves dirty with the highly error-prone string manipulation, nor are we supposed to repeat 3 lines of code a thousand times. We also should not be forced to think of all the edge cases and possible output of the user side. Developers should focus on what's important, not what isn't.

Then after all that, we really should make sure our code is clean, maintainable, extendable and flexible.

Building upon this belief, Lamp was born.

Lamp has taken responsibility upon itself to take all the crap of the command creation process: parsing input, validating arguments, auto completions, tokenizing and redirection, and leaves you only to the important part of your job here: the actual command logic.

Through annotations, parameter resolvers, command conditions, permissions, argument validators, cooldowns, dependency injection, auto-completers, Lamp not only makes the command creation process much easier, it also becomes more fun, intuitive and less error prone.

There are many commands frameworks out there, why should I use Lamp?

Glad you asked!

  • Lamp is small in size: The overall size of Lamp will not exceed 150 KB. Built to be lightweight, Lamp is convenient to package and ship.

  • Lamp is extendable: Lamp has been built thoroughly with this in mind. You can create custom annotations for commands, parameters, permissions and resolvers, with their very own functionality. This gives so much space for your own extendability, and also helps make sure the code you write is minimal.

  • Lamp is portable: Created with a high-level command API and an extendable codebase, Lamp has been produced to provide first-class support to as many platforms as possible. As of now, Lamp supports the following platforms:

    With the help of the built-in APIs for dispatching commands and auto-completions, it is possible to support almost any platform out-of-the-box.

  • Lamp is easy: Despite all the powerful features and extendability, getting started with Lamp couldn't be easier. Simply create a command handler for your appropriate platform, then proceed with creating your command with the main @Command and @Subcommand annotations, and finally registering it with CommandHandler#register().

  • Lamp is powerful: Lamp allows you to leverage some of the command features which would be otherwise too burdensome to build:

Documentation

Comments
  • Allow invalid usernames (GeyserMC/Floodgate)

    Allow invalid usernames (GeyserMC/Floodgate)

    An user of my plugin using Lamp on a GeyserMC+Floodgate server is having this issue while trying to execute a command with a player selector: He sent me his Floodgate config:

    # Floodgate prepends a prefix to bedrock usernames to avoid conflicts
    # However, certain conflicts can cause issues with some plugins so this prefix is configurable using the property below
    # It is recommended to use a prefix that does not contain alphanumerical to avoid the possibility of duplicate usernames.
    username-prefix: '*'
    

    It seems like Lamp recognizes the star as an incorrect username character and completely blocks player selector from there. Is it possible to fix this, or at least have an option somewhere to allow "unsafe" usernames? Some plugins do have such options: LuckPerms have a allow-invalid-usernames boolean config option, and ChestChop have a VALID_PLAYERNAME_REGEXP regex option.

    opened by SkytAsul 10
  • Parent Command & Standalone Command simultaneously

    Parent Command & Standalone Command simultaneously

    Hey! Is it possible to have a command under a parent, and also be standalone simultaneously? If that doesn't make sense to you, here; let me show you a demonstration of the idea:

    @Command("parent")
    public final class ExampleCommand {
        
        @Default // /parent
        public String defaultCommand() {
            return "default command";
        }
        
        @Subcommand("sub") // /parent sub
        public String subCommand() {
            return "sub command";
        }
        
        @Command("test") // /test
        @Subcommand("test") // /parent test
        public String subCommand2() {
            return "test command";
        }
    }
    

    If so, could you please show me how I could achieve such a thing? Thank you!

    question 
    opened by Tofpu 6
  • NoSuchElementException when dispatching command with ArgumentStack with empty String

    NoSuchElementException when dispatching command with ArgumentStack with empty String

    Error occurs with jda module. When user sends picture, or emote MessageReceivedEvent occurs, and MessageReceivedEvent#getMessage#getContentRaw returns empty string.

    java.util.NoSuchElementException
    at java.util.LinkedList.getFirst(LinkedList.java:244)
    at revxrsal.commands.core.BaseCommandDispatcher.eval([BaseCommandDispatcher.java:33](https://github.com/Revxrsal/Lamp/blob/5d00ebe8ec30e2f5f24db5d57717fc0a682c8eb2/common/src/main/java/revxrsal/commands/core/BaseCommandDispatcher.java#L33))
    at revxrsal.commands.core.BaseCommandHandler.dispatch([BaseCommandHandler.java:519](https://github.com/Revxrsal/Lamp/blob/5d00ebe8ec30e2f5f24db5d57717fc0a682c8eb2/common/src/main/java/revxrsal/commands/core/BaseCommandHandler.java#L519))
    

    I think it occurs because BaseCommandHandler#parseArguments returns ArgumentStack.empty() when string empty.

    So if we add something like this to the BaseCommandDispatcher#eval:

    if(arguments.isEmpty()) throw new InvalidCommandException("", "");
    

    Everything will be fine

    opened by U61vashka 4
  • add NamespacedKey resolver

    add NamespacedKey resolver

    this PR adds value resolver for org.bukkit.NamespacedKey with resource_location brigadier type to support nice client-side formatting

    bumped Lamp version to 3.0.4-SNAPSHOT

    opened by Grabsky 4
  • default argument type resolvers do not make sense to me.

    default argument type resolvers do not make sense to me.

    each default arg type bound like this: image but the type does not do anything at all in the bind method: image and the parameter's class type hasn't check in the argument resolver too: image and looks like it does support nullable too: image so i've made the string resolver like this:

    public interface CommandFactory {
      @Inject
      @NotNull
      @Provides
      @Singleton
      static BukkitCommandHandler commandManager(@NotNull final Plugin plugin) {
        final var handler = BukkitCommandHandler.create(plugin);
        handler.registerBrigadier();
        handler.enableAdventure();
        handler
          .getBrigadier()
          .orElseThrow()
          .registerArgumentTypeResolver(
            0,
            parameter -> {
              if (parameter.getType() != String.class) {
                return null;
              }
              if (parameter.getType().isAnnotationPresent(Quoted.class)) {
                return StringArgumentType.string();
              }
              if (parameter.consumesAllString()) {
                return StringArgumentType.greedyString();
              }
              return StringArgumentType.word();
            }
          );
        return handler;
      }
    }
    

    am i wrong with the returning null if the parameter is not a string? because looks like if it does not find any resolver, returns string already so it should check the parameter type first.

    opened by portlek 3
  • feat: minecraft brigadier argument types

    feat: minecraft brigadier argument types

    Lamp currently supports arguments provided by Brigadier library directly. There are, however more Minecraft-specific arguments included in game internals. All of them are handled by the client to support completions etc. (see wiki)

    They can be accessed with a bit of reflection or NMS on supported platforms. Do note there is a Paper PR (https://github.com/PaperMC/Paper/pull/6695) open to expose them directly to the API which may, or may not be merged in the future.

    Notes

    • Some existing arguments would need to be handled differently to mimic their brigadier parser behavior.
      • Lamp uses StringArgumentType for String which expects validation (see this)
      • EntitySelector<T> should refer to internal minecraft:entity type to support rich client-side completions.
    • Supporting some arguments (eg. minecraft:vec2 and vec3) could be a bit hacky and would most likely require internal changes.

    Thoughts

    Since that have more side effects than it sounds, I think that addition of BrigadierCommandHandler (or similar) is necessary. This would keep current users unaffected by these changes and also make brigadier easier to maintain.

    Sponge

    I know nothing about Sponge and can't really suggest anything in that regards. I can only say that since all (minecraft) platforms can use Brigadier, maybe a new module structure is needed. (example)

    MinecraftCommandHandler<T> extends CommandHandler<T> { ... }
    BrigadierCommandHandler<T> extends MinecraftCommandHandler<T> { ... }
    
    MinecraftCommandHandler<Bukkit> handler = ... // for simple commands
    BrigadierCommandHandler<Bukkit> handler = ... // for brigadier commands
    
    MinecraftCommandHandler<Sponge> handler = ... // for simple commands
    BrigadierCommandHandler<Sponge> handler = ... // for brigadier commands
    
    opened by Grabsky 3
  • Fixed the jitpack build not being found

    Fixed the jitpack build not being found

    At the moment, the 3.0.1 release is currently not available on JitPack due to the error below, this PR solves the following issue:

    ⚠️ ERROR: No build artifacts found Expected artifacts in: $HOME/.m2/repository/io/github/revxrsal/bukkit/3.0.1

    You can view the live result of this PR at https://jitpack.io/#Tofpu/Lamp/3.0.2

    opened by Tofpu 3
  • Parent commands do not allow non-subcommand overload

    Parent commands do not allow non-subcommand overload

    i.e. if I have the following commands:

    mycom
    mycom list
    mycom add
    

    The only command that shows up is mycom. (Each is its own method, and the path is specified in full via @Command) I am currently working on a plugin that would benefit from this functionality, so it would be best if Lamp supported it.

    opened by ghost 3
  • get missing permission from NoPermissionException handler

    get missing permission from NoPermissionException handler

    Hi, i have a question. Is it possible to get missing permission from NoPermissionException handler? if so how to do it?

    my code: commandHandler.registerExceptionHandler(NoPermissionException.class, (actor, ex) -> { TextBuilder.builder() .text("&7You dont have permission to execute this command! &7(&c{PERM}&7)") .placeholder("{PERM}", I WANT TO GET MISSING PERMISSION HERE ) .send(((BukkitCommandActor) actor).getSender()); });

    opened by megagigakox 2
  • Paper 1.19.2 brigadier no argument command issue

    Paper 1.19.2 brigadier no argument command issue

    Hey,

    I've encountered an issue with paper brigadier using latest Lamp version (from latest commit) on Paper 1.19.2.

    Commands with multiple arguments (including optional ones) work as intended. But when I create a command with no arguments, brigadier expects an argument (which shouldn't be happening).

    Code example:

    @Command("testcmd")
    public void execute(Player player) { ... }
    

    Result in-game: In-game screenshot

    I should note that the same issue is with subcommands - if subcommand doesn't have arguments, same issue occurs.

    opened by airoons 2
  • Args in command (not at the ending)

    Args in command (not at the ending)

    Hey, I've been playing with Lamp for a while and I am trying something, but I can't figure out how.

    Is ist possible to set args at a specific position in the (sub)command? Like "user <name> changePassword <password>" and not having all args at the end?

    opened by wasn325 2
  • feat: Flag and Switch aliases

    feat: Flag and Switch aliases

    Hello,

    A neat suggestion I think would be nice for Lamp is the option for @Flag and @Switch annotations to support aliases. I'm unsure if this is natively supported by brigadier since I've never worked with commands before, but it would be cool to use.

    Perhaps the inputted array could override all of the names for the switch/flag, or add on upon the inputted parameter name (that could be an option in the CommandHandler). The original message is available on the Lamp Discord.

    Something like this:

    public void send(Player sender, @Flag({"sendtype", "sendingtype", "st"}) SendType type, @Switch({"broadcast", "sendall"}) boolean sendAll) {
       // ...
    }
    

    @SkytAsul (their original message) also recommended the option to mix flags and/or switches together, as in some Unix commands, such as:

    rm -r -f
    # Becomes...
    rm -rf
    

    Thanks!

    enhancement 
    opened by GamerCoder215 1
  • Not working

    Not working "switch" arguments only for players

    With those two commands:

    	@Subcommand("test")
    	public void test(int dumbArg, @Optional Player optionalArg, @Switch boolean switchArg) {}
    
    	@Subcommand("test2")
    	public void test2(int dumbArg, @Switch boolean switchArg) {}
    

    It's working normally when I do:

    /mycommand test2 4 /mycommand test 5 /mycommand test 5 -switchArgs

    But I am getting this: image when executing:

    /mycommand test2 4 -switchArg /mycommand test 5 SkytAsul -switchArg

    But if I execute all of these commands in console, I get no issue. It's only for players. I also get normal syntax coloring in chat when typing the 2 failing commands, it only fails after I hit enter.

    I can't find a reason why those two commands are failing.

    opened by SkytAsul 1
Releases(3.1.1)
  • 3.1.1(Dec 14, 2022)

    • Fixed flag parameters getting incorrect type in Brigadier
    • Fixed player suggestions being half-broken when Brigadier is supported
    • Added BukkitBrigadier#disableNativePlayerCompletion() to disable native player completions on Brigadier
    • Italian translation by @HornMCPE
    • Minor optimizations to Brigadier node parser

    Full Changelog: https://github.com/Revxrsal/Lamp/compare/3.1.0...3.1.1

    Source code(tar.gz)
    Source code(zip)
  • 3.1.0(Oct 17, 2022)

    This version implements native Brigadier support on Minecraft 1.19+.

    • Players can't see commands they don't have access to
    • Certain parameter errors (such as ranges) that are handled by Brigadier will receive Brigadier errors, just like normal Minecraft commands image
    • Commands are handled entirely by brigadier now. So unknown subcommands will receive Brigadier errors.
    • ArgumentTypeResolvers are no longer bound to types
    • New Either type 🎉
    • Code cleanups
    • Brigadier cleanup
    Source code(tar.gz)
    Source code(zip)
  • 3.0.8(Aug 14, 2022)

  • 3.0.71(Jul 14, 2022)

  • 3.0.7(Jun 16, 2022)

    • Remove ArgumentTypes utility for 1.19 support
    • Added MinecraftArgumentType enum for accessing and creating Minecraft's argument types
    • Replaced brigadier.bind(Class, String) with brigadier.bind(Class, MinecraftArgumentType)
    Source code(tar.gz)
    Source code(zip)
  • 3.0.6(Jun 11, 2022)

    • Remove ktx module and migrate it to common
    • Add adventure APIs to Bukkit
      • BukkitCommandHandler#enableAdventure() and BukkitCommandHandler#enableAdventure(BukkitAudiences)
      • BukkitCommandActor#audience()
      • BukkitCommandActor#reply(ComponentLike)
      • Use Audience as a sender in commands
      • Returning Components from methods will be sent to the command actor
    • Add Kotlin extensions to Bukkit
      • bukkitCommandHandler {} DSL
      • brigadier {} DSL
      • CommandActor.sender: CommandSender
      • CommandActor.player: Player
      • CommandActor.playerOrNull: Player?
      • brigadier.bind<Type>(argumentType)
      • brigadier.bind<Type>(argumentTypeResolver)
      • brigadier.bind<Type>(String)
    Source code(tar.gz)
    Source code(zip)
  • 3.0.6-SNAPSHOT(Jun 9, 2022)

  • 3.0.5(Jun 8, 2022)

    • minor "no-subcommand-specified" translation fix by @alisson0022 in https://github.com/Revxrsal/Lamp/pull/22
    • Lamp is now truly 100% dependency-less
    • bukkit's module no longer depends on commodore and instead embeds a stripped-down version of it (to change certain behaviour in it as well)
    • bukkit's module also no longer depends on the brigadier module for Brigadier support
    • Introduced new Brigadier API for Bukkit, allowing to register custom argument types for parameters
    • Fixed Brigadier's usage not displaying
    • Player arguments on 1.13.2+ will now be auto-completed by vanilla, allowing selectors to be used on them directly
    • ArgumentStack can be used as a parameter type to access the command input
    • Added SelfHandlingException interface for exceptions that wish to immediately handle themselves
    • General code cleanups
    Source code(tar.gz)
    Source code(zip)
  • 3.0.4(Apr 27, 2022)

    • Help entries will now include all sibling commands and children of siblings
    • ExecutableCommand and CommandCategory now implement Comparable, to allow them to be sorted according to the alphabetical order
    • Help entries will automatically be sorted in alphabetical order
    Source code(tar.gz)
    Source code(zip)
  • 3.0.3(Apr 18, 2022)

    Warning: This release introduces breaking changes to ArgumentStack.

    • French translation by @SkytAsul
    • Fix MissingArgumentException was not thrown with a missing flag value (#20)
    • Fixed annotation priorities when an annotation is present on both the class and method
    • Added CommandHandler.unregisterAllCommands()
    • @AutoComplete annotations can now accept * for a parameter to reference the default auto-completer
    • Use a supplier for Bukkit's config to avoid loading it (which would throw an error if the config had any problems)
    • Fixed flags not working correctly with Brigadier
    • Fixed flag completion being semi-broken
    • Introduced the ArgumentParser API
    • Added CommandHandler.getArgumentParser(), CommandHandler.setArgumentParser(ArgumentParser), CommandHandler.parseArguments(String...) and CommandHandler.parseArgumentsForCompletion(String...)
    • Fixed Brigadier commands being registered on the minecraft: namespace
    • Improved Brigadier support

    ArgumentStack changes:

    • Removed ArgumentStack#of(String...)
    • Removed ArgumentStack#of(Collection<String>)
    • Removed ArgumentStack#forAutoCompletion(String...)
    • Removed ArgumentStack#fromString(String)
    • Renamed ArgumentStack#exactly(Collection<String> to #copy(Collection<String>)
    • Added ArgumentStack#copy(String...)
    Source code(tar.gz)
    Source code(zip)
  • 3.0.2(Mar 25, 2022)

  • 3.0.1(Mar 25, 2022)

    What's Changed

    • Added Portuguese language support by @alisson0022 in https://github.com/Revxrsal/Lamp/pull/9
    • Fix odd issue in English messages by @TehNeon in https://github.com/Revxrsal/Lamp/pull/10
    • Update from Gradle 6.8 to 7.4.1 by @TehNeon in https://github.com/Revxrsal/Lamp/pull/12
    • Add auto-completer extensions for Kotlin https://github.com/Revxrsal/Lamp/issues/11 and annotation replacer extensions https://github.com/Revxrsal/Lamp/pull/15/
    • Support Kotlin's suspend functions
    • Fix locale issues on Bukkit 1.8.X https://github.com/Revxrsal/Lamp/issues/17

    Full Changelog: https://github.com/Revxrsal/Lamp/compare/3.0.0...3.0.1

    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Mar 16, 2022)

  • 2.9.6(Mar 8, 2022)

  • 2.9.5(Feb 27, 2022)

  • 2.9.4(Feb 19, 2022)

  • 2.9.3(Feb 17, 2022)

  • 2.9.2(Feb 16, 2022)

  • 2.9.1(Feb 14, 2022)

  • 2.9(Feb 13, 2022)

  • 2.8(Feb 13, 2022)

  • 2.6(Feb 11, 2022)

  • 2.5(Feb 6, 2022)

    • Added the new OrphanCommand API, which allows resolving paths for commands at runtime
    • Added CommandHandler.setMessagePrefix() for setting prefixes for messages
    • Fixed newly registered resolvers and suggestion factories not taking precedence over default ones
    • Added SuggestionProvider.of(Supplier<Collection>)
    • Added a default suggestion factory for enums
    • Prevent unauthorized commands from appearing in suggestions

    Bukkit:

    • Allow CommandActor.getUniqueId() for console and command blocks
    • Removed PlayerSelector in favor of the more versatile EntitySelector
    • Updated commodore to support Minecraft 1.18
    Source code(tar.gz)
    Source code(zip)
  • 1.8(Oct 18, 2021)

  • 1.7.2(Oct 14, 2021)

Owner
Revxrsal
Software developer - Well-experienced in Java, Kotlin, C++, SQL and web development. A fan of asynchronous things and obsessed with performance and optimization
Revxrsal
Chih-Jen Lin 4.3k Jan 2, 2023
Use this to open hidden activities on MIUI.

miui_hidden_libs Use this to open hidden activities on MIUI. Translate for your language: https://drive.google.com/file/d/1---II4WVVvPIn3cPodTC52VPVG3

ios7jbpro 51 Nov 10, 2022
Easy to use, very low overhead, Java APM

Glowroot Requirements Java 8+ Quick start Download and unzip glowroot-0.14.0-beta.2-dist.zip Add -javaagent:path/to/glowroot.jar to your application's

null 1.1k Dec 14, 2022
Library for helping mods that use graph networks, like Wired Redstone

GraphLib Library for helping mods that use graph networks, like Wired Redstone. GraphLib and HCTM-Base This library is based on HCTM-Base by 2xsaiko a

Data 6 Nov 5, 2022
Model import deployment framework for retraining models (pytorch, tensorflow,keras) deploying in JVM Micro service environments, mobile devices, iot, and Apache Spark

The Eclipse Deeplearning4J (DL4J) ecosystem is a set of projects intended to support all the needs of a JVM based deep learning application. This mean

Eclipse Foundation 12.7k Dec 30, 2022
An Engine-Agnostic Deep Learning Framework in Java

Deep Java Library (DJL) Overview Deep Java Library (DJL) is an open-source, high-level, engine-agnostic Java framework for deep learning. DJL is desig

Amazon Web Services - Labs 2.9k Jan 7, 2023
Datumbox is an open-source Machine Learning framework written in Java which allows the rapid development of Machine Learning and Statistical applications.

Datumbox Machine Learning Framework The Datumbox Machine Learning Framework is an open-source framework written in Java which allows the rapid develop

Vasilis Vryniotis 1.1k Dec 9, 2022
Java Exp FrameWork

Exp Poc框架并不少,TangScan、Pocsuite 等等,用python写一个其实是很简单的事情。为什么要重复造这个轮子呢? 看过不少漏洞了,差不多都是本地很杂乱的存放poc,很多语言都有,而且大多数poc也只能弹个计算器而已.....所以很早就想拥有一个属于自己的统一存放Exp的地方,也

Skay 100 Oct 9, 2022
JUNG: Java Universal Network/Graph Framework

JUNG: The Java Universal Network/Graph Framework JUNG is a software library that provides a common and extensible language for the modeling, analysis,

Joshua O'Madadhain 346 Dec 28, 2022
An Engine-Agnostic Deep Learning Framework in Java

Deep Java Library (DJL) Overview Deep Java Library (DJL) is an open-source, high-level, engine-agnostic Java framework for deep learning. DJL is desig

DeepJavaLibrary 2.9k Jan 7, 2023
Abstract machine for formal semantics of SIMP (Simple Imperative Language)

SIMP-abstract-machine In 2020/21 I was a Teaching Assistant for the second year module 5CCS2PLD Programming Language Paradigms at King's College Londo

Sten Arthur Laane 25 Oct 10, 2022
A Simple movies app using JAVA,MVVM and with a offline caching capability

IMDB-CLONE A simple imdb clone using JAVA,MVVM with searching and bookmarking ability with offline caching ability screenshots Home Screen 1 Home Scre

saiteja janjirala 13 Aug 16, 2022
Simple ATM Machine made with Java

Output / Preview Enter your account number: Enter your pin number: ATM main menu: 1. - View Account Balance 2. - Withdraw funds 3. - Add funds 4. - T

SonLyte 10 Oct 21, 2021
Just a simple implementation of K-Nearest Neighbour algorithm.

A simple K-Nearest Neighbor (KNN) Java library What is this repository for? Its a very simple implementation of K-Nearest Neighbor algorithm for Super

Felipe Appio 3 Apr 23, 2021
A simple utility that allows you to query which items can be placed in a specific slot by holding down Left-Alt

What's That Slot This mod is a simple utility that allows you to query which items can be placed in a specific slot by holding down Left-Alt. You can

null 11 Dec 25, 2022
An extremely flexible yet vanilla-esque multiblock mod, that embraces aspects of MultiblockTweaker and Modular Machinery.

Multiblocked Multiblocked (mbd) is an extremely flexible yet vanilla-esque multiblock mod, that embraces aspects of MultiblockTweaker and Modular Mach

Cleanroom 36 Jan 4, 2023
A simple yet powerful parameterized test runner for Java.

TestParameterInjector Introduction TestParameterInjector is a JUnit4 test runner that runs its test methods for different combinations of field/parame

Google 324 Dec 30, 2022
Yet another Java annotation-based command parsing library, with Dependency Injection inspired by Guice

Commander A universal java command parsing library Building This project uses Gradle. Clone this repository: git clone https://github.com/OctoPvP/Comm

OctoDev 4 Oct 2, 2022
JDA Commands is an extension for JDA to make commands easier and clearer to develop.

JDA Commands JDA Commands is an extension for JDA to make commands easier and clearer to develop. With the API you can easily create commands for the

Dominik 12 Oct 14, 2022