├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── libs └── PaperSpigot-1.7.10-R0.1-SNAPSHOT.jar ├── pom.xml └── src └── main ├── java └── club │ └── frozed │ └── lunarutils │ ├── LunarClientUtils.java │ ├── commands │ ├── BackCommand.java │ └── LunarClientCommand.java │ ├── player │ └── PlayerListener.java │ └── utils │ ├── CC.java │ ├── Utils.java │ └── command │ ├── BaseCommand.java │ ├── BukkitCommand.java │ ├── BukkitCompleter.java │ ├── Command.java │ ├── CommandArgs.java │ ├── CommandFramework.java │ └── Completer.java └── resources └── plugin.yml /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | 11 | # Compiled class file 12 | *.class 13 | 14 | # Log file 15 | *.log 16 | 17 | # BlueJ files 18 | *.ctxt 19 | 20 | # Package Files # 21 | *.jar 22 | *.war 23 | *.nar 24 | *.ear 25 | *.zip 26 | *.tar.gz 27 | *.rar 28 | 29 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 30 | hs_err_pid* 31 | 32 | *~ 33 | 34 | # temporary files which can be created if a process still has a handle open of a deleted file 35 | .fuse_hidden* 36 | 37 | # KDE directory preferences 38 | .directory 39 | 40 | # Linux trash folder which might appear on any partition or disk 41 | .Trash-* 42 | 43 | # .nfs files are created when an open file is removed but is still being accessed 44 | .nfs* 45 | 46 | # General 47 | .DS_Store 48 | .AppleDouble 49 | .LSOverride 50 | 51 | # Icon must end with two \r 52 | Icon 53 | 54 | # Thumbnails 55 | ._* 56 | 57 | # Files that might appear in the root of a volume 58 | .DocumentRevisions-V100 59 | .fseventsd 60 | .Spotlight-V100 61 | .TemporaryItems 62 | .Trashes 63 | .VolumeIcon.icns 64 | .com.apple.timemachine.donotpresent 65 | 66 | # Directories potentially created on remote AFP share 67 | .AppleDB 68 | .AppleDesktop 69 | Network Trash Folder 70 | Temporary Items 71 | .apdisk 72 | 73 | # Windows thumbnail cache files 74 | Thumbs.db 75 | Thumbs.db:encryptable 76 | ehthumbs.db 77 | ehthumbs_vista.db 78 | 79 | # Dump file 80 | *.stackdump 81 | 82 | # Folder config file 83 | [Dd]esktop.ini 84 | 85 | # Recycle Bin used on file shares 86 | $RECYCLE.BIN/ 87 | 88 | # Windows Installer files 89 | *.cab 90 | *.msi 91 | *.msix 92 | *.msm 93 | *.msp 94 | 95 | # Windows shortcuts 96 | *.lnk 97 | 98 | target/ 99 | 100 | pom.xml.tag 101 | pom.xml.releaseBackup 102 | pom.xml.versionsBackup 103 | pom.xml.next 104 | 105 | release.properties 106 | dependency-reduced-pom.xml 107 | buildNumber.properties 108 | .mvn/timing.properties 109 | .mvn/wrapper/maven-wrapper.jar 110 | .flattened-pom.xml 111 | 112 | # Common working directory 113 | run/ 114 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | OS Frozed Club Development License 1.0 2 | Version 1.0, 30 November 2023 3 | https://frozed.club/license/ 4 | 5 | BY DOWNLOADING, CLONING, FORKING AND/OR USING THIS PROJECT YOU AGREE TO THE LICENSE 6 | 7 | 1. Definition. This license, referred to as the "OS Frozed Club Development License," 8 | governs the use, redistribution, and modification of the associated software. 9 | By downloading, cloning, forking, and/or using this project, users agree to 10 | adhere to the terms outlined in this license. 11 | 12 | 2. Redistribution. You may reproduce and distribute copies of this, 13 | use in source and binary forms, with or without modification, are 14 | permitted provided that each of the following conditions are met: 15 | 16 | (a) Redistributions of source code must retain the 17 | above copyright notice, this list of conditions and 18 | the following disclaimer. 19 | 20 | (b) Redistributions in binary form must reproduce the 21 | above copyright notice, this list of conditions and 22 | the following disclaimer in the documentation and/or 23 | other materials provided with the distribution. 24 | 25 | (c) Neither the name of Frozed Club Development contributors nor the names 26 | of the original author of this (Elb1to) may be used to endorse 27 | or promote products derived from this software 28 | without specific prior written permission. 29 | 30 | (d) The user, identified as 'iusemeteor,' is expressly prohibited 31 | from utilizing, redistributing, promoting, and/or extracting 32 | code from this repository under all circumstances. 33 | 34 | (e) An entity wishing to redistribute in binary form or 35 | include this software in their product without 36 | redistribution of this software's source code with the 37 | product must also submit to these conditions where 38 | applicable: 39 | • For every (1) unit distributed, one (1) or more 40 | persons affiliated with the entity must provide 41 | full original crediting to Elb1to and/or Frozed 42 | Club Development. 43 | 44 | (f) In order to acquire permission to redistribute this software 45 | you must ask for permission from Elb1to and be granted it 46 | before redistributing any code from this repository. 47 | 48 | 3. Trademarks. This License does not grant permission to use the trade 49 | names, trademarks, service marks, or product names of the Licensor, 50 | except as required for reasonable and customary use in describing the 51 | origin of the Work and reproducing the content of the LICENSE file. 52 | 53 | Copyright © 2023 Elb1to 54 | Licensed under the OS Frozed Club Development License, Version 1.0 (the "License"); 55 | 56 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 57 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 58 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 59 | SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 60 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 61 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 62 | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANYTHEORY OF LIABILITY, WHETHER IN 63 | CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 64 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 65 | DAMAGE. FROZED CLUB DEVELOPMENT ACCEPTS NO LIABILITY FOR ANY EXPENSES SUSTAINED IN 66 | THE ACT OF FULFILLING ANY OF THE ABOVE TERMS AND CONDITIONS, ACCIDENTAL OR OTHERWISE. 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LunarClientUtils - Example Plugin for LunarClient's Official API 2 | 3 | #### How to use 4 | 1. Download LunarClient's API Bukkit plugin jar [[Click Here]](https://maven.moonsworth.com/repository/lunarclient-public/com/lunarclient/bukkitapi/1.0-SNAPSHOT/bukkitapi-1.0-20200729.212152-7.jar) 5 | 2. Download the latest release version of LunarClientUtils [[Click Here]](https://github.com/FrozedClubDevelopment/LunarClientUtils/releases/download/v1.0/LunarClientUtils-1.0-SNAPSHOT.jar) 6 | 3. Add both jars into your server. 7 | 4. Have fun with it. 8 | 9 | #### General Information 10 | * In order to correctly get AntiCheat ON/OFF players, your server must be partnered with Lunar. 11 | * LunarClient Staff Modules only work on the 1.7.10 Version of Lunar Client. 12 | * Staff-Modules permission: "lunar.utils.staff-modules" 13 | * Command to get list of players on LunarClient: "/lc" 14 | 15 | #### LunarClientAPI Usage 16 | To use the API we get the instance of it firstly. 17 | 18 | ```java 19 | LunarClientAPI.getInstance(); 20 | ``` 21 | 22 | Once you have done that, you'll have access to all the methods currently available on LunarClient's Official API. 23 | I'll list some methods here, keep in mind the API isn't limited the methods I'll list here, of course it has more methods. 24 | 25 | ```java 26 | sendNotification(Player player, LCNotification notification); 27 | 28 | isRunningLunarClient(Player player); 29 | isRunningLunarClient(UUID playerUuid); 30 | 31 | isRunningAntiCheat(Player player); 32 | isRunningAntiCheat(UUID playerUuid); 33 | 34 | giveAllStaffModules(Player player); 35 | disableAllStaffModules(Player player); 36 | setStaffModuleState(Player player, StaffModule module, boolean state); 37 | 38 | sendCooldown(Player player, LCCooldown cooldown); 39 | clearCooldown(Player player, LCCooldown cooldown); 40 | ``` 41 | 42 | #### Contact 43 | * Discord: Elb1to#0001 44 | * Twitter: Elb1to 45 | -------------------------------------------------------------------------------- /libs/PaperSpigot-1.7.10-R0.1-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FrozedClubDevelopment/LunarClientUtils/3f11d95a8258cc01046eccb6db12cc1425f97322/libs/PaperSpigot-1.7.10-R0.1-SNAPSHOT.jar -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | club.frozed.lunarapi 8 | LunarClientUtils 9 | 1.2-SNAPSHOT 10 | jar 11 | 12 | LunarClientUtils 13 | Utils plugin made with LunarClient's Official API 14 | www.frozed.club 15 | 16 | 17 | 1.8 18 | UTF-8 19 | 20 | 21 | 22 | 23 | spigotmc-repo 24 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/ 25 | 26 | 27 | lunarclient-public 28 | https://maven.moonsworth.com/repository/lunarclient-public/ 29 | 30 | 31 | 32 | 33 | 34 | org.spigotmc 35 | spigot-1.7 36 | 1.7.10-R0.1-SNAPSHOT 37 | ${project.basedir}/libs/PaperSpigot-1.7.10-R0.1-SNAPSHOT.jar 38 | system 39 | 40 | 41 | com.lunarclient 42 | bukkitapi 43 | 1.0-20200729.212152-7 44 | compile 45 | 46 | 47 | org.projectlombok 48 | lombok 49 | 1.18.12 50 | provided 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.apache.maven.plugins 58 | maven-compiler-plugin 59 | 3.8.1 60 | 61 | ${java.version} 62 | ${java.version} 63 | 64 | 65 | 66 | org.apache.maven.plugins 67 | maven-shade-plugin 68 | 3.2.4 69 | 70 | 71 | package 72 | 73 | shade 74 | 75 | 76 | false 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | src/main/resources 85 | true 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/LunarClientUtils.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils; 2 | 3 | import club.frozed.lunarutils.commands.BackCommand; 4 | import club.frozed.lunarutils.commands.LunarClientCommand; 5 | import club.frozed.lunarutils.player.PlayerListener; 6 | import club.frozed.lunarutils.utils.command.CommandFramework; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | import org.bukkit.Bukkit; 10 | import org.bukkit.plugin.java.JavaPlugin; 11 | 12 | @Getter @Setter 13 | public final class LunarClientUtils extends JavaPlugin { 14 | 15 | @Getter public static LunarClientUtils instance; 16 | private CommandFramework commandFramework; 17 | 18 | @Override 19 | public void onEnable() { 20 | instance = this; 21 | 22 | commandFramework = new CommandFramework(this); 23 | commandFramework.registerCommands(new BackCommand()); 24 | commandFramework.registerCommands(new LunarClientCommand()); 25 | 26 | Bukkit.getPluginManager().registerEvents(new PlayerListener(), this); 27 | } 28 | 29 | @Override 30 | public void onDisable() { 31 | instance = null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/commands/BackCommand.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.commands; 2 | 3 | import club.frozed.lunarutils.utils.CC; 4 | import club.frozed.lunarutils.utils.command.BaseCommand; 5 | import club.frozed.lunarutils.utils.command.Command; 6 | import club.frozed.lunarutils.utils.command.CommandArgs; 7 | import org.bukkit.Location; 8 | import org.bukkit.entity.Player; 9 | 10 | import java.util.HashMap; 11 | import java.util.UUID; 12 | 13 | /** 14 | * Created by Elb1to 15 | * Project: LunarClientUtils 16 | * Date: 1/11/2021 @ 12:45 PM 17 | */ 18 | public class BackCommand extends BaseCommand { 19 | 20 | public static HashMap playerLocation = new HashMap<>(); 21 | 22 | @Command(name = "back", aliases = {"backpos", "goback"}) 23 | 24 | @Override 25 | public void onCommand(CommandArgs cmd) { 26 | Player player = cmd.getPlayer(); 27 | 28 | if (playerLocation.containsKey(player.getUniqueId())) { 29 | player.teleport(playerLocation.get(player.getUniqueId())); 30 | player.sendMessage(CC.translate("&aSending you back to your previous death location.")); 31 | } else { 32 | player.sendMessage(CC.translate("&cYou have already used the /back command.")); 33 | } 34 | 35 | playerLocation.remove(player.getUniqueId()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/commands/LunarClientCommand.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.commands; 2 | 3 | import club.frozed.lunarutils.LunarClientUtils; 4 | import club.frozed.lunarutils.utils.CC; 5 | import club.frozed.lunarutils.utils.Utils; 6 | import club.frozed.lunarutils.utils.command.BaseCommand; 7 | import club.frozed.lunarutils.utils.command.Command; 8 | import club.frozed.lunarutils.utils.command.CommandArgs; 9 | import com.lunarclient.bukkitapi.LunarClientAPI; 10 | import org.apache.commons.lang.StringUtils; 11 | import org.bukkit.entity.Player; 12 | 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * Created by Elb1to 18 | * Project: LunarClientUtils 19 | * Date: 09/17/2020 @ 21:47 20 | */ 21 | public class LunarClientCommand extends BaseCommand { 22 | @Command(name = "lunarclient", aliases = {"lc", "lc-api", "lcapi"}) 23 | 24 | @Override 25 | public void onCommand(CommandArgs cmd) { 26 | Player player = cmd.getPlayer(); 27 | 28 | player.sendMessage(CC.CHAT_BAR); 29 | player.sendMessage(CC.translate("&b&lLunarClientUtils &8- &7v" + LunarClientUtils.getInstance().getDescription().getVersion())); 30 | player.sendMessage(CC.translate(" ")); 31 | player.sendMessage(CC.translate("&3 ▶ &bPlayers using LunarClient &7[AC-OFF]&8: &f" + nonAntiCheatPlayers().size())); 32 | if (nonAntiCheatPlayers().isEmpty()) { 33 | player.sendMessage(CC.translate("&cNo players with LunarClient [AC-OFF]")); 34 | } else { 35 | player.sendMessage(CC.translate(StringUtils.join(nonAntiCheatPlayers(), "\n"))); 36 | } 37 | player.sendMessage(CC.translate(" ")); 38 | player.sendMessage(CC.translate("&3 ▶ &bPlayers using LunarClient &7[AC-ON]&8: &f" + antiCheatPlayers().size())); 39 | if (antiCheatPlayers().isEmpty()) { 40 | player.sendMessage(CC.translate("&4 ▶ &cNobody is using LunarClient [AC-ON]")); 41 | } else { 42 | player.sendMessage(CC.translate(StringUtils.join(antiCheatPlayers(), "\n"))); 43 | } 44 | player.sendMessage(CC.CHAT_BAR); 45 | } 46 | 47 | private List nonAntiCheatPlayers() { 48 | List players = new ArrayList<>(); 49 | for (Player player : Utils.getOnlinePlayers()) { 50 | if (LunarClientAPI.getInstance().isRunningLunarClient(player)) { 51 | if (!LunarClientAPI.getInstance().isRunningAntiCheat(player)) { 52 | players.add(CC.translate(" &7 ➥ " + player.getName())); 53 | } 54 | } 55 | } 56 | return players; 57 | } 58 | 59 | private List antiCheatPlayers() { 60 | List players = new ArrayList<>(); 61 | for (Player player : Utils.getOnlinePlayers()) { 62 | if (LunarClientAPI.getInstance().isRunningLunarClient(player)) { 63 | if (LunarClientAPI.getInstance().isRunningAntiCheat(player)) { 64 | players.add(CC.translate(" &7 ➥ " + player.getName())); 65 | } 66 | } 67 | } 68 | return players; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/player/PlayerListener.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.player; 2 | 3 | import club.frozed.lunarutils.commands.BackCommand; 4 | import club.frozed.lunarutils.utils.CC; 5 | import com.lunarclient.bukkitapi.LunarClientAPI; 6 | import com.lunarclient.bukkitapi.object.LCNotification; 7 | import com.lunarclient.bukkitapi.object.TitleType; 8 | import org.bukkit.Bukkit; 9 | import org.bukkit.entity.EntityType; 10 | import org.bukkit.entity.Player; 11 | import org.bukkit.event.EventHandler; 12 | import org.bukkit.event.Listener; 13 | import org.bukkit.event.entity.PlayerDeathEvent; 14 | import org.bukkit.event.player.PlayerInteractEvent; 15 | import org.bukkit.event.player.PlayerJoinEvent; 16 | 17 | import java.time.Duration; 18 | import java.util.UUID; 19 | 20 | /** 21 | * Created by Elb1to 22 | * Project: LunarClientUtils 23 | * Date: 09/17/2020 @ 21:47 24 | */ 25 | public class PlayerListener implements Listener { 26 | 27 | private final LunarClientAPI lunarClientAPI = LunarClientAPI.getInstance(); 28 | 29 | @EventHandler 30 | public void onPlayerJoin(PlayerJoinEvent event) { 31 | Player player = event.getPlayer(); 32 | 33 | /* 34 | * IMPORTANT: The Official LunarClient API (which is being used on this small project) 35 | * has all LunarClient methods available for development, but to check whether or not 36 | * a Player has LunarClient's AntiCheat ON or OFF, you may need to be PARTNERED with 37 | * LunarClient in order for the API to make those checks successfully. 38 | * 39 | * Also, LunarClient StaffModules ONLY work on the 1.7.10 LunarClient Version. 40 | * 41 | * This plugin is just made as a "base" or usage example of LunarClient's Official API. 42 | */ 43 | 44 | if (lunarClientAPI.isRunningLunarClient(player)) { 45 | player.sendMessage(CC.translate("&aSuccess! &7You've been authenticated for using &bLunar Client&7.")); 46 | player.sendMessage(CC.translate("&b&lNOTICE&7: &fYou're running LunarClient without the AntiCheat enabled.")); 47 | } else if (lunarClientAPI.isRunningAntiCheat(player)) { 48 | player.sendMessage(CC.translate("&aSuccess! &7You've been authenticated for using &bLunar Client&7.")); 49 | player.sendMessage(CC.translate("&b&lNOTICE&7: &fYou're running LunarClient with the AntiCheat enabled.")); 50 | } else { 51 | lunarClientAPI.sendNotification(player, new LCNotification("LunarClientAPI - Successfully authenticated.", Duration.ofSeconds(5L))); 52 | 53 | lunarClientAPI.sendTitle(player, TitleType.TITLE, CC.translate("&b&lLunarClient&bAPI"), 1.0F, Duration.ofSeconds(2L), Duration.ofSeconds(6L), Duration.ofSeconds(2L)); 54 | lunarClientAPI.sendTitle(player, TitleType.SUBTITLE, CC.translate("&aSuccessfully Authenticated"), 1.0F, Duration.ofSeconds(2L), Duration.ofSeconds(6L), Duration.ofSeconds(2L)); 55 | 56 | if (player.hasPermission("lunar.utils.staff-modules")) { 57 | lunarClientAPI.giveAllStaffModules(player); 58 | player.sendMessage(CC.translate("&8[&bLunarClient&8] &7You have received all Staff-Modules. ")); 59 | } 60 | } 61 | } 62 | 63 | @EventHandler 64 | public void onPlayerDeath(PlayerDeathEvent event) { 65 | Player player = Bukkit.getPlayer(event.getEntity().getUniqueId()); 66 | if (event.getEntity() == player) { 67 | BackCommand.playerLocation.put(player.getUniqueId(), player.getLocation()); 68 | } 69 | 70 | player.sendMessage(CC.CHAT_BAR); 71 | player.sendMessage(CC.translate("&4&lTe moriste pete XdxdxDXDXdXDxDXd.")); 72 | player.sendMessage(CC.translate(" ")); 73 | player.sendMessage(CC.translate("&cYou can only use the &o/back &ccommand &lONCE.")); 74 | player.sendMessage(CC.translate("&cThis will teleport you back to your death location.")); 75 | player.sendMessage(CC.CHAT_BAR); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/utils/CC.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.utils; 2 | 3 | import org.bukkit.ChatColor; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class CC { 9 | 10 | public static final String MENU_BAR = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH.toString() + "------------------------"; 11 | public static final String CHAT_BAR = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH.toString() + "------------------------------------------------"; 12 | public static final String SB_BAR = ChatColor.GRAY.toString() + ChatColor.STRIKETHROUGH.toString() + "----------------------"; 13 | 14 | /** 15 | * Translate string. 16 | * 17 | * @param in the in 18 | * @return the string 19 | */ 20 | public static String translate(String in) { 21 | return ChatColor.translateAlternateColorCodes('&', in); 22 | } 23 | 24 | /** 25 | * Translate list. 26 | * 27 | * @param lines the lines 28 | * @return the list 29 | */ 30 | public static List translate(List lines) { 31 | List toReturn = new ArrayList<>(); 32 | 33 | for (String line : lines) { 34 | toReturn.add(ChatColor.translateAlternateColorCodes('&', line)); 35 | } 36 | 37 | return toReturn; 38 | } 39 | 40 | /** 41 | * Translate list. 42 | * 43 | * @param lines the lines 44 | * @return the list 45 | */ 46 | public static List translate(String[] lines) { 47 | List toReturn = new ArrayList<>(); 48 | 49 | for (String line : lines) { 50 | if (line != null) { 51 | toReturn.add(ChatColor.translateAlternateColorCodes('&', line)); 52 | } 53 | } 54 | 55 | return toReturn; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.utils; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | /** 10 | * Created by Elb1to 11 | * Project: LunarClientUtils 12 | * Date: 09/17/2020 @ 21:47 13 | */ 14 | public class Utils { 15 | 16 | /** 17 | * Gets online players. 18 | * 19 | * @return the online players 20 | */ 21 | public static List getOnlinePlayers() { 22 | List players = new ArrayList<>(); 23 | for (Player player : Bukkit.getServer().getOnlinePlayers()) { 24 | players.add(player); 25 | } 26 | return players; 27 | } 28 | 29 | /** 30 | * Gets ping. 31 | * 32 | * @param player the player 33 | * @return the ping 34 | */ 35 | public static int getPing(Player player) { 36 | try { 37 | String version = Bukkit.getServer().getClass().getPackage().getName().substring(23); 38 | Class craftPlayer = Class.forName("org.bukkit.craftbukkit." + version + ".entity.CraftPlayer"); 39 | Object handle = craftPlayer.getMethod("getHandle", new Class[0]).invoke(player); 40 | return (Integer) handle.getClass().getDeclaredField("ping").get(handle); 41 | } catch (Exception e) { 42 | return -1; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/utils/command/BaseCommand.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.utils.command; 2 | 3 | import club.frozed.lunarutils.LunarClientUtils; 4 | 5 | /** 6 | * The type Base command. 7 | */ 8 | public abstract class BaseCommand { 9 | 10 | /** 11 | * The Plugin. 12 | */ 13 | public LunarClientUtils plugin = LunarClientUtils.getInstance(); 14 | 15 | /** 16 | * Instantiates a new Base command. 17 | */ 18 | public BaseCommand() { 19 | this.plugin.getCommandFramework().registerCommands(this); 20 | } 21 | 22 | /** 23 | * On command. 24 | * 25 | * @param cmd the cmd 26 | */ 27 | public abstract void onCommand(CommandArgs cmd); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/utils/command/BukkitCommand.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.utils.command; 2 | 3 | import org.apache.commons.lang.Validate; 4 | import org.bukkit.command.CommandException; 5 | import org.bukkit.command.CommandExecutor; 6 | import org.bukkit.command.CommandSender; 7 | import org.bukkit.command.TabCompleter; 8 | import org.bukkit.plugin.Plugin; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * Command Framework - BukkitCommand
14 | * An implementation of Bukkit's Command class allowing for registering of 15 | * commands without plugin.yml 16 | * 17 | * @author minnymin3 18 | */ 19 | public class BukkitCommand extends org.bukkit.command.Command { 20 | 21 | private final Plugin owningPlugin; 22 | private CommandExecutor executor; 23 | /** 24 | * The Completer. 25 | */ 26 | protected BukkitCompleter completer; 27 | 28 | /** 29 | * A slimmed down PluginCommand 30 | * 31 | * @param label the label 32 | * @param executor the executor 33 | * @param owner the owner 34 | */ 35 | protected BukkitCommand(String label, CommandExecutor executor, Plugin owner) { 36 | super(label); 37 | this.executor = executor; 38 | this.owningPlugin = owner; 39 | this.usageMessage = ""; 40 | } 41 | 42 | @Override 43 | public boolean execute(CommandSender sender, String commandLabel, String[] args) { 44 | boolean success = false; 45 | 46 | if (!owningPlugin.isEnabled()) { 47 | return false; 48 | } 49 | 50 | if (!testPermission(sender)) { 51 | return true; 52 | } 53 | 54 | try { 55 | success = executor.onCommand(sender, this, commandLabel, args); 56 | } catch (Throwable ex) { 57 | throw new CommandException("Unhandled exception executing command '" + commandLabel + "' in plugin " 58 | + owningPlugin.getDescription().getFullName(), ex); 59 | } 60 | 61 | if (!success && usageMessage.length() > 0) { 62 | for (String line : usageMessage.replace("", commandLabel).split("\n")) { 63 | sender.sendMessage(line); 64 | } 65 | } 66 | 67 | return success; 68 | } 69 | 70 | @Override 71 | public List tabComplete(CommandSender sender, String alias, String[] args) 72 | throws CommandException, IllegalArgumentException { 73 | Validate.notNull(sender, "Sender cannot be null"); 74 | Validate.notNull(args, "Arguments cannot be null"); 75 | Validate.notNull(alias, "Alias cannot be null"); 76 | 77 | List completions = null; 78 | try { 79 | if (completer != null) { 80 | completions = completer.onTabComplete(sender, this, alias, args); 81 | } 82 | if (completions == null && executor instanceof TabCompleter) { 83 | completions = ((TabCompleter) executor).onTabComplete(sender, this, alias, args); 84 | } 85 | } catch (Throwable ex) { 86 | StringBuilder message = new StringBuilder(); 87 | message.append("Unhandled exception during tab completion for command '/").append(alias).append(' '); 88 | for (String arg : args) { 89 | message.append(arg).append(' '); 90 | } 91 | message.deleteCharAt(message.length() - 1).append("' in plugin ") 92 | .append(owningPlugin.getDescription().getFullName()); 93 | throw new CommandException(message.toString(), ex); 94 | } 95 | 96 | if (completions == null) { 97 | return super.tabComplete(sender, alias, args); 98 | } 99 | return completions; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/utils/command/BukkitCompleter.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.utils.command; 2 | 3 | import org.bukkit.command.Command; 4 | import org.bukkit.command.CommandSender; 5 | import org.bukkit.command.TabCompleter; 6 | 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.lang.reflect.Method; 9 | import java.util.AbstractMap; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | import java.util.Map.Entry; 14 | 15 | /** 16 | * Command Framework - BukkitCompleter
17 | * An implementation of the TabCompleter class allowing for multiple tab 18 | * completers per command 19 | * 20 | * @author minnymin3 21 | */ 22 | public class BukkitCompleter implements TabCompleter { 23 | 24 | private Map> completers = new HashMap>(); 25 | 26 | /** 27 | * Add completer. 28 | * 29 | * @param label the label 30 | * @param m the m 31 | * @param obj the obj 32 | */ 33 | public void addCompleter(String label, Method m, Object obj) { 34 | completers.put(label, new AbstractMap.SimpleEntry(m, obj)); 35 | } 36 | 37 | @SuppressWarnings("unchecked") 38 | @Override 39 | public List onTabComplete(CommandSender sender, Command command, String label, String[] args) { 40 | for (int i = args.length; i >= 0; i--) { 41 | StringBuffer buffer = new StringBuffer(); 42 | buffer.append(label.toLowerCase()); 43 | for (int x = 0; x < i; x++) { 44 | if (!args[x].equals("") && !args[x].equals(" ")) { 45 | buffer.append("." + args[x].toLowerCase()); 46 | } 47 | } 48 | String cmdLabel = buffer.toString(); 49 | if (completers.containsKey(cmdLabel)) { 50 | Entry entry = completers.get(cmdLabel); 51 | try { 52 | return (List) entry.getKey().invoke(entry.getValue(), 53 | new CommandArgs(sender, command, label, args, cmdLabel.split("\\.").length - 1)); 54 | } catch (IllegalArgumentException e) { 55 | e.printStackTrace(); 56 | } catch (IllegalAccessException e) { 57 | e.printStackTrace(); 58 | } catch (InvocationTargetException e) { 59 | e.printStackTrace(); 60 | } 61 | } 62 | } 63 | return null; 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/utils/command/Command.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.utils.command; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Command Framework - Command
10 | * The command annotation used to designate methods as commands. All methods 11 | * should have a single CommandArgs argument 12 | * 13 | * @author minnymin3 14 | */ 15 | @Target(ElementType.METHOD) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | public @interface Command { 18 | 19 | /** 20 | * The name of the command. If it is a sub command then its values would be 21 | * separated by periods. ie. a command that would be a subcommand of test 22 | * would be 'test.subcommandname' 23 | * 24 | * @return string string 25 | */ 26 | public String name(); 27 | 28 | /** 29 | * Gets the required permission of the command 30 | * 31 | * @return string string 32 | */ 33 | public String permission() default ""; 34 | 35 | /** 36 | * The message sent to the player when they do not have permission to 37 | * execute it 38 | * 39 | * @return string string 40 | */ 41 | public String noPerm() default "§cYou do not have permission to perform that action"; 42 | 43 | /** 44 | * A list of alternate names that the command is executed under. See 45 | * name() for details on how names work 46 | * 47 | * @return string [ ] 48 | */ 49 | public String[] aliases() default {}; 50 | 51 | /** 52 | * The description that will appear in /help of the command 53 | * 54 | * @return string string 55 | */ 56 | public String description() default ""; 57 | 58 | /** 59 | * The usage that will appear in /help (commandname) 60 | * 61 | * @return string string 62 | */ 63 | public String usage() default ""; 64 | 65 | /** 66 | * Whether or not the command is available to players only 67 | * 68 | * @return boolean boolean 69 | */ 70 | public boolean inGameOnly() default false; 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/utils/command/CommandArgs.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.utils.command; 2 | 3 | import org.bukkit.command.CommandSender; 4 | import org.bukkit.entity.Player; 5 | 6 | /** 7 | * Command Framework - CommandArgs
8 | * This class is passed to the command methods and contains various utilities as 9 | * well as the command info. 10 | * 11 | * @author minnymin3 12 | */ 13 | public class CommandArgs { 14 | 15 | private CommandSender sender; 16 | private org.bukkit.command.Command command; 17 | private String label; 18 | private String[] args; 19 | 20 | /** 21 | * Instantiates a new Command args. 22 | * 23 | * @param sender the sender 24 | * @param command the command 25 | * @param label the label 26 | * @param args the args 27 | * @param subCommand the sub command 28 | */ 29 | protected CommandArgs(CommandSender sender, org.bukkit.command.Command command, String label, String[] args, 30 | int subCommand) { 31 | String[] modArgs = new String[args.length - subCommand]; 32 | for (int i = 0; i < args.length - subCommand; i++) { 33 | modArgs[i] = args[i + subCommand]; 34 | } 35 | 36 | StringBuffer buffer = new StringBuffer(); 37 | buffer.append(label); 38 | for (int x = 0; x < subCommand; x++) { 39 | buffer.append("." + args[x]); 40 | } 41 | String cmdLabel = buffer.toString(); 42 | this.sender = sender; 43 | this.command = command; 44 | this.label = cmdLabel; 45 | this.args = modArgs; 46 | } 47 | 48 | /** 49 | * Gets the command sender 50 | * 51 | * @return sender sender 52 | */ 53 | public CommandSender getSender() { 54 | return sender; 55 | } 56 | 57 | /** 58 | * Gets the original command object 59 | * 60 | * @return command command 61 | */ 62 | public org.bukkit.command.Command getCommand() { 63 | return command; 64 | } 65 | 66 | /** 67 | * Gets the label including sub command labels of this command 68 | * 69 | * @return Something like 'test.subcommand' 70 | */ 71 | public String getLabel() { 72 | return label; 73 | } 74 | 75 | /** 76 | * Gets all the arguments after the command's label. ie. if the command 77 | * label was test.subcommand and the arguments were subcommand foo foo, it 78 | * would only return 'foo foo' because 'subcommand' is part of the command 79 | * 80 | * @return string [ ] 81 | */ 82 | public String[] getArgs() { 83 | return args; 84 | } 85 | 86 | /** 87 | * Gets the argument at the specified index 88 | * 89 | * @param index The index to get 90 | * @return The string at the specified index 91 | */ 92 | public String getArgs(int index) { 93 | return args[index]; 94 | } 95 | 96 | /** 97 | * Returns the length of the command arguments 98 | * 99 | * @return int length of args 100 | */ 101 | public int length() { 102 | return args.length; 103 | } 104 | 105 | /** 106 | * Is player boolean. 107 | * 108 | * @return the boolean 109 | */ 110 | public boolean isPlayer() { 111 | return sender instanceof Player; 112 | } 113 | 114 | /** 115 | * Gets player. 116 | * 117 | * @return the player 118 | */ 119 | public Player getPlayer() { 120 | if (sender instanceof Player) { 121 | return (Player) sender; 122 | } else { 123 | return null; 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/utils/command/CommandFramework.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.utils.command; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.command.CommandExecutor; 5 | import org.bukkit.command.CommandMap; 6 | import org.bukkit.command.CommandSender; 7 | import org.bukkit.command.PluginCommand; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.help.GenericCommandHelpTopic; 10 | import org.bukkit.help.HelpTopic; 11 | import org.bukkit.help.HelpTopicComparator; 12 | import org.bukkit.help.IndexHelpTopic; 13 | import org.bukkit.plugin.Plugin; 14 | import org.bukkit.plugin.SimplePluginManager; 15 | 16 | import java.lang.reflect.Field; 17 | import java.lang.reflect.InvocationTargetException; 18 | import java.lang.reflect.Method; 19 | import java.util.*; 20 | import java.util.Map.Entry; 21 | 22 | /** 23 | * Command Framework - CommandFramework
24 | * The main command framework class used for controlling the framework. 25 | * 26 | * @author minnymin3 27 | */ 28 | public class CommandFramework implements CommandExecutor { 29 | 30 | private Map> commandMap = new HashMap>(); 31 | 32 | private List comandos = new ArrayList<>(); 33 | 34 | private CommandMap map; 35 | private Plugin plugin; 36 | 37 | /** 38 | * Initializes the command framework and sets up the command maps 39 | * 40 | * @param plugin the plugin 41 | */ 42 | public CommandFramework(Plugin plugin) { 43 | this.plugin = plugin; 44 | if (plugin.getServer().getPluginManager() instanceof SimplePluginManager) { 45 | SimplePluginManager manager = (SimplePluginManager) plugin.getServer().getPluginManager(); 46 | try { 47 | Field field = SimplePluginManager.class.getDeclaredField("commandMap"); 48 | field.setAccessible(true); 49 | map = (CommandMap) field.get(manager); 50 | } catch (IllegalArgumentException e) { 51 | e.printStackTrace(); 52 | } catch (SecurityException e) { 53 | e.printStackTrace(); 54 | } catch (IllegalAccessException e) { 55 | e.printStackTrace(); 56 | } catch (NoSuchFieldException e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | } 61 | 62 | @Override 63 | public boolean onCommand(CommandSender sender, org.bukkit.command.Command cmd, String label, String[] args) { 64 | return handleCommand(sender, cmd, label, args); 65 | } 66 | 67 | /** 68 | * Handles commands. Used in the onCommand method in your JavaPlugin class 69 | * 70 | * @param sender The {@link CommandSender} parsed from onCommand 71 | * @param cmd The {@link org.bukkit.command.Command} parsed from onCommand 72 | * @param label The label parsed from onCommand 73 | * @param args The arguments parsed from onCommand 74 | * @return Always returns true for simplicity's sake in onCommand 75 | */ 76 | public boolean handleCommand(CommandSender sender, org.bukkit.command.Command cmd, String label, String[] args) { 77 | for (int i = args.length; i >= 0; i--) { 78 | StringBuffer buffer = new StringBuffer(); 79 | buffer.append(label.toLowerCase()); 80 | for (int x = 0; x < i; x++) { 81 | buffer.append("." + args[x].toLowerCase()); 82 | } 83 | String cmdLabel = buffer.toString(); 84 | if (commandMap.containsKey(cmdLabel)) { 85 | Method method = commandMap.get(cmdLabel).getKey(); 86 | Object methodObject = commandMap.get(cmdLabel).getValue(); 87 | Command command = method.getAnnotation(Command.class); 88 | if (!command.permission().equals("") && !sender.hasPermission(command.permission())) { 89 | sender.sendMessage(command.noPerm()); 90 | return true; 91 | } 92 | if (command.inGameOnly() && !(sender instanceof Player)) { 93 | sender.sendMessage("This command is only performable in game"); 94 | return true; 95 | } 96 | try { 97 | method.invoke(methodObject, new CommandArgs(sender, cmd, label, args, 98 | cmdLabel.split("\\.").length - 1)); 99 | } catch (IllegalArgumentException e) { 100 | e.printStackTrace(); 101 | } catch (IllegalAccessException e) { 102 | e.printStackTrace(); 103 | } catch (InvocationTargetException e) { 104 | e.printStackTrace(); 105 | } 106 | return true; 107 | } 108 | } 109 | defaultCommand(new CommandArgs(sender, cmd, label, args, 0)); 110 | return true; 111 | } 112 | 113 | /** 114 | * Registers all command and completer methods inside of the object. Similar 115 | * to Bukkit's registerEvents method. 116 | * 117 | * @param obj The object to register the commands of 118 | */ 119 | public void registerCommands(Object obj) { 120 | comandos.add(obj.getClass().getAnnotation(Command.class)); 121 | for (Method m : obj.getClass().getMethods()) { 122 | if (m.getAnnotation(Command.class) != null) { 123 | Command command = m.getAnnotation(Command.class); 124 | if (m.getParameterTypes().length > 1 || m.getParameterTypes()[0] != CommandArgs.class) { 125 | System.out.println("Unable to register command " + m.getName() + ". Unexpected method arguments"); 126 | continue; 127 | } 128 | registerCommand(command, command.name(), m, obj); 129 | for (String alias : command.aliases()) { 130 | registerCommand(command, alias, m, obj); 131 | } 132 | } else if (m.getAnnotation(Completer.class) != null) { 133 | Completer comp = m.getAnnotation(Completer.class); 134 | if (m.getParameterTypes().length > 1 || m.getParameterTypes().length == 0 135 | || m.getParameterTypes()[0] != CommandArgs.class) { 136 | System.out.println("Unable to register tab completer " + m.getName() 137 | + ". Unexpected method arguments"); 138 | continue; 139 | } 140 | if (m.getReturnType() != List.class) { 141 | System.out.println("Unable to register tab completer " + m.getName() + ". Unexpected return type"); 142 | continue; 143 | } 144 | registerCompleter(comp.name(), m, obj); 145 | for (String alias : comp.aliases()) { 146 | registerCompleter(alias, m, obj); 147 | } 148 | } 149 | } 150 | } 151 | 152 | /** 153 | * Registers all the commands under the plugin's help 154 | */ 155 | public void registerHelp() { 156 | Set help = new TreeSet(HelpTopicComparator.helpTopicComparatorInstance()); 157 | for (String s : commandMap.keySet()) { 158 | if (!s.contains(".")) { 159 | org.bukkit.command.Command cmd = map.getCommand(s); 160 | HelpTopic topic = new GenericCommandHelpTopic(cmd); 161 | help.add(topic); 162 | } 163 | } 164 | IndexHelpTopic topic = new IndexHelpTopic(plugin.getName(), "All commands for " + plugin.getName(), null, help, 165 | "Below is a list of all " + plugin.getName() + " commands:"); 166 | Bukkit.getServer().getHelpMap().addTopic(topic); 167 | } 168 | 169 | /** 170 | * Register command. 171 | * 172 | * @param command the command 173 | * @param label the label 174 | * @param m the m 175 | * @param obj the obj 176 | */ 177 | public void registerCommand(Command command, String label, Method m, Object obj) { 178 | commandMap.put(label.toLowerCase(), new AbstractMap.SimpleEntry(m, obj)); 179 | commandMap.put(this.plugin.getName() + ':' + label.toLowerCase(), new AbstractMap.SimpleEntry(m, obj)); 180 | String cmdLabel = label.split("\\.")[0].toLowerCase(); 181 | if (map.getCommand(cmdLabel) == null) { 182 | org.bukkit.command.Command cmd = new BukkitCommand(cmdLabel, this, plugin); 183 | map.register(plugin.getName(), cmd); 184 | } 185 | if (!command.description().equalsIgnoreCase("") && cmdLabel.equals(label)) { 186 | map.getCommand(cmdLabel).setDescription(command.description()); 187 | } 188 | if (!command.usage().equalsIgnoreCase("") && cmdLabel.equals(label)) { 189 | map.getCommand(cmdLabel).setUsage(command.usage()); 190 | } 191 | } 192 | 193 | /** 194 | * Register completer. 195 | * 196 | * @param label the label 197 | * @param m the m 198 | * @param obj the obj 199 | */ 200 | public void registerCompleter(String label, Method m, Object obj) { 201 | String cmdLabel = label.split("\\.")[0].toLowerCase(); 202 | if (map.getCommand(cmdLabel) == null) { 203 | org.bukkit.command.Command command = new BukkitCommand(cmdLabel, this, plugin); 204 | map.register(plugin.getName(), command); 205 | } 206 | if (map.getCommand(cmdLabel) instanceof BukkitCommand) { 207 | BukkitCommand command = (BukkitCommand) map.getCommand(cmdLabel); 208 | if (command.completer == null) { 209 | command.completer = new BukkitCompleter(); 210 | } 211 | command.completer.addCompleter(label, m, obj); 212 | } else if (map.getCommand(cmdLabel) instanceof PluginCommand) { 213 | try { 214 | Object command = map.getCommand(cmdLabel); 215 | Field field = command.getClass().getDeclaredField("completer"); 216 | field.setAccessible(true); 217 | if (field.get(command) == null) { 218 | BukkitCompleter completer = new BukkitCompleter(); 219 | completer.addCompleter(label, m, obj); 220 | field.set(command, completer); 221 | } else if (field.get(command) instanceof BukkitCompleter) { 222 | BukkitCompleter completer = (BukkitCompleter) field.get(command); 223 | completer.addCompleter(label, m, obj); 224 | } else { 225 | System.out.println("Unable to register tab completer " + m.getName() 226 | + ". A tab completer is already registered for that command!"); 227 | } 228 | } catch (Exception ex) { 229 | ex.printStackTrace(); 230 | } 231 | } 232 | } 233 | 234 | private void defaultCommand(CommandArgs args) { 235 | args.getSender().sendMessage(args.getLabel() + " is not handled! Oh noes!"); 236 | } 237 | 238 | } -------------------------------------------------------------------------------- /src/main/java/club/frozed/lunarutils/utils/command/Completer.java: -------------------------------------------------------------------------------- 1 | package club.frozed.lunarutils.utils.command; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Command Framework - Completer
10 | * The completer annotation used to designate methods as command completers. All 11 | * methods should have a single CommandArgs argument and return a String List 12 | * object 13 | * 14 | * @author minnymin3 15 | */ 16 | @Target(ElementType.METHOD) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | public @interface Completer { 19 | 20 | /** 21 | * The command that this completer completes. If it is a sub command then 22 | * its values would be separated by periods. ie. a command that would be a 23 | * subcommand of test would be 'test.subcommandname' 24 | * 25 | * @return string string 26 | */ 27 | String name(); 28 | 29 | /** 30 | * A list of alternate names that the completer is executed under. See 31 | * name() for details on how names work 32 | * 33 | * @return string [ ] 34 | */ 35 | String[] aliases() default {}; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: LunarClientUtils 2 | version: ${project.version} 3 | main: club.frozed.lunarutils.LunarClientUtils 4 | authors: [Elb1to, FrozedClubDevelopment] 5 | description: Utils plugin made with LunarClient's Official API 6 | website: www.frozed.club 7 | --------------------------------------------------------------------------------