Skip to content

Instantly share code, notes, and snippets.

@Redoishi
Last active July 21, 2022 19:22
Show Gist options
  • Select an option

  • Save Redoishi/46a9eb30991bf6007508f72aba7da89f to your computer and use it in GitHub Desktop.

Select an option

Save Redoishi/46a9eb30991bf6007508f72aba7da89f to your computer and use it in GitHub Desktop.
Create a minecraft command without plugin.yml
package your.package;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.*;
import org.bukkit.plugin.java.JavaPlugin;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* Create a minecraft command without plugin.yml
* https://gist.github.com/redsarow/46a9eb30991bf6007508f72aba7da89f
*
* @author redsarow
*/
public abstract class AMyCommand<T extends JavaPlugin> extends Command implements CommandExecutor, PluginIdentifiableCommand {
private static CommandMap commandMap;
static {
try {
Field f = Bukkit.getServer().getClass().getDeclaredField("commandMap");
f.setAccessible(true);
commandMap = (CommandMap) f.get(Bukkit.getServer());
} catch (IllegalAccessException | NoSuchFieldException e) {
e.printStackTrace();
}
}
private final T plugin;
private final HashMap<Integer, ArrayList<TabCommand>> tabComplete;
private boolean register = false;
/**
* @param plugin plugin responsible of the command.
* @param name name of the command.
*/
AMyCommand(T plugin, String name) {
super(name);
assert commandMap != null;
assert plugin != null;
assert name.length() > 0;
setLabel(name);
this.plugin = plugin;
tabComplete = new HashMap<>();
}
//<editor-fold desc="add / set">
/**
* @param aliases aliases of the command.
*/
protected void setAliases(String... aliases) {
if (aliases != null && (register || aliases.length > 0))
setAliases(Arrays.stream(aliases).collect(Collectors.toList()));
}
//<editor-fold desc="TabbComplete">
/**
* Add multiple arguments to an index with permission and words before
*
* @param indice index where the argument is in the command. /myCmd is at the index -1, so
* /myCmd index0 index1 ...
* @param permission permission to add (may be null)
* @param beforeText text preceding the argument (may be null)
* @param arg word to add
*/
protected void addTabbComplete(int indice, String permission, String[] beforeText, String... arg) {
if (arg != null && arg.length > 0 && indice >= 0) {
if (tabComplete.containsKey(indice)) {
tabComplete.get(indice).addAll(Arrays.stream(arg).collect(
ArrayList::new,
(tabCommands, s) -> tabCommands.add(new TabCommand(indice, s, permission, beforeText)),
ArrayList::addAll));
}else {
tabComplete.put(indice, Arrays.stream(arg).collect(
ArrayList::new,
(tabCommands, s) -> tabCommands.add(new TabCommand(indice, s, permission, beforeText)),
ArrayList::addAll)
);
}
}
}
/**
* Add multiple arguments to an index
*
* @param indice index where the argument is in the command. /myCmd is at the index -1, so
* /myCmd index0 index1 ...
* @param arg word to add
*/
protected void addTabbComplete(int indice, String... arg) {
addTabbComplete(indice, null, null, arg);
}
//</editor-fold>
//</editor-fold>
/**
* /!\ to do at the end /!\ to save the command.
*
* @return true if the command has been successfully registered
*/
protected boolean registerCommand() {
if (!register) {
register = commandMap.register(plugin.getName(), this);
}
return register;
}
//<editor-fold desc="get">
/**
* @return plugin responsible for the command
*/
@Override
public T getPlugin() {
return this.plugin;
}
/**
* @return tabComplete
*/
public HashMap<Integer, ArrayList<TabCommand>> getTabComplete() {
return tabComplete;
}
//</editor-fold>
//<editor-fold desc="Override">
/**
* @param commandSender sender
* @param command command
* @param arg argument of the command
*
* @return true if ok, false otherwise
*/
@Override
public boolean execute(CommandSender commandSender, String command, String[] arg) {
if (getPermission() != null) {
if (!commandSender.hasPermission(getPermission())) {
if (getPermissionMessage() == null) {
commandSender.sendMessage(ChatColor.RED + "no permit!");
}else {
commandSender.sendMessage(getPermissionMessage());
}
return false;
}
}
if (onCommand(commandSender, this, command, arg))
return true;
commandSender.sendMessage(ChatColor.RED + getUsage());
return false;
}
/**
* @param sender sender
* @param alias alias used
* @param args argument of the command
*
* @return a list of possible values
*/
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) {
int indice = args.length - 1;
if ((getPermission() != null && !sender.hasPermission(getPermission())) || tabComplete.size() == 0 || !tabComplete.containsKey(indice))
return super.tabComplete(sender, alias, args);
List<String> list = tabComplete.get(indice).stream()
.filter(tabCommand -> tabCommand.getTextAvant() == null || tabCommand.getTextAvant().contains(args[indice - 1]))
.filter(tabCommand -> tabCommand.getPermission() == null || sender.hasPermission(tabCommand.getPermission()))
.filter(tabCommand -> tabCommand.getText().startsWith(args[indice]))
.map(TabCommand::getText)
.sorted(String.CASE_INSENSITIVE_ORDER)
.collect(Collectors.toList());
return list.size() < 1 ? super.tabComplete(sender, alias, args) : list;
}
//</editor-fold>
//<editor-fold desc="class TabCommand">
private static class TabCommand {
private final int indice;
private final String text;
private final String permission;
private final ArrayList<String> textAvant;
private TabCommand(int indice, String text, String permission, String... textAvant) {
this.indice = indice;
this.text = text;
this.permission = permission;
if (textAvant == null || textAvant.length < 1) {
this.textAvant = null;
}else {
this.textAvant = Arrays.stream(textAvant).collect(ArrayList::new,
ArrayList::add,
ArrayList::addAll);
}
}
//<editor-fold desc="get&set">
public String getText() {
return text;
}
public int getIndice() {
return indice;
}
public String getPermission() {
return permission;
}
public ArrayList<String> getTextAvant() {
return textAvant;
}
//</editor-fold>
}
//</editor-fold>
}
MIT License
Copyright (c) 2018 redsarow
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
package your.package;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandMap;
import org.bukkit.plugin.java.JavaPlugin;
/**
* @author redsarow
*/
public class Main extends JavaPlugin{
@Override
public void onEnable() {
super.onEnable();
new MyCommand(this);
}
@Override
public void onDisable() {
super.onDisable();
}
}
package your.package;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.io.BukkitObjectInputStream;
import javax.annotation.Nonnull;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
/**
* @author redsarow
*/
public class MyCommand extends AMyCommand<Main> {
public MyCommand(CommandMap commandMap, JavaPlugin plugin) {
super(plugin, "myCommand");
setDescription("Lorem ipsum dolor sit amet, consectetur adipiscing elit. ");
setUsage("/myCommand <param1> <param2>");
setAliases("mc");
setPermission("perm.myCommand");
setPermissionMessage("nop!");
addTabbComplete(0, "test");// /commande test
addTabbComplete(0, "test2");// /commande test2
addTabbComplete(1, "subParam");// /commande <arg1> subParam
registerCommand();
}
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
if (commandSender instanceof Player){
Player sender = (Player) commandSender;
sender.sendMessage("player");
}else{
commandSender.sendMessage("no player");
}
return true;
}
}
@peterhenryd
Copy link

This is very useful! Thanks very much. :)

@DrSchnippel
Copy link

1 problem I found with the TabComplete

/command subcmd1 subsubcmd1
If I give /command and then 2 spaces, the tabcompleter give me directly subsubcmd1. That is unfavorable. Is there a way to change this so if two spaces are given, nothing else is suggested.

Sorry for my bad englisch, its not my native lang...

@ChocolatMilka
Copy link

ChocolatMilka commented Apr 18, 2020

Salut, peut-tu réviser le code à propos du

addOneTabbComplete(1, "test");

alors qu'à la définition il y a l'argument permission et textBefore stp ?

@ChocolatMilka
Copy link

ChocolatMilka commented Apr 18, 2020

j'ai ajouté cela tout en laissant la méthode avec les 4 arguments:

//<editor-fold desc="TabbComplete">
    /**
     * Adds an argument to an index with permission and the words before
     *
     * @param indice     index where the argument is in the command. /myCmd is at the index -1, so
     *                   /myCmd index0 index1 ...
     * @param arg        word to add
     *
     * @return AMyCommand, instance of the class
     */
    protected CommandManager addOneTabbComplete(int indice, String arg) {
        if (arg != null && indice >= 0) {
            if (tabComplete.containsKey(indice)) {
                tabComplete.get(indice).add(new TabCommand(indice, arg));
            } else {
                ArrayList<TabCommand> tabCommands = new ArrayList<>();
                tabCommands.add(new TabCommand(indice, arg));
                tabComplete.put(indice, tabCommands);
            }
        }
        return this;
    }

@Redoishi
Copy link
Author

Hello,

I updated the class.
In particular, I removed unnecessary methods.

Old name New name
addDescription setDescription
addUsage setUsage
addPermission setPermission
addPermissionMessage setPermissionMessage
addAliases setAliases

For add arguments use addTabbComplete(int indice, String permission, String[] beforeText, String... arg) or addTabbComplete(int indice, String... arg) .

@DrSchnippel:
This problem comes from Minecraft.
For example test with give command.

@360matt:
Effectivement j'aurai dû utiliser addListTabbComplete(int indice, String... arg).
Avec la nouvelle version vous pouvez utiliser addTabbComplete(int indice, String... arg) .

@MarcusSlover
Copy link

Hey, how would you unregister a specific command?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment