diff --git a/build.gradle b/build.gradle index f0ee93a..29c0524 100644 --- a/build.gradle +++ b/build.gradle @@ -34,8 +34,8 @@ spigot { authors = [project.property("author")] apiVersion = project.property("apiVersion") load = STARTUP - // depends = [''] - // softDepends = ['' + // depends = [''] + // softDepends = [] } compileJava { @@ -48,30 +48,42 @@ compileJava { archivesBaseName = project.property("pluginName") repositories { + mavenLocal() mavenCentral() spigot() maven { url = 'https://jitpack.io' } + maven { url = 'https://repo.aikar.co/content/groups/aikar/' } + maven { url = 'https://repo.dmulloy2.net/repository/public/' } + maven { url 'https://hub.spigotmc.org/nexus/content/repositories/public/' } + maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/' } } dependencies { + // using spigot-api implementation spigot(mcVersion) + // or using paper-api + // implementation "io.papermc.paper:paper-api:${mcVersion}-R0.1-SNAPSHOT" - //Add dependencies here + // Add your dependencies here + // Here are some opinionated dependencies that might help you with your plugin development: - //Test dependencies + // Annotation Command Framework: https://github.com/aikar/commands + implementation "co.aikar:acf-paper:0.5.0-SNAPSHOT" + + // Test dependencies testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1' testImplementation 'org.mockito:mockito-core:4.0.0' - testImplementation 'com.github.seeseemelk:MockBukkit-v1.16:1.5.2' + testImplementation 'com.github.seeseemelk:MockBukkit-v1.17:1.7.0' testImplementation 'org.assertj:assertj-core:3.21.0' } shadowJar { classifier = '' -// dependencies { -// include(dependency('co.aikar:acf-paper:0.5.0-SNAPSHOT')) -// } -// relocate 'co.aikar.commands', "${packageName}.acf" -// relocate 'co.aikar.locales', "${packageName}.locales" + dependencies { + include(dependency('co.aikar:acf-paper:0.5.0-SNAPSHOT')) + } + relocate 'co.aikar.commands', "${packageName}.acf" + relocate 'co.aikar.locales', "${packageName}.locales" } tasks.build.dependsOn(shadowJar) diff --git a/gradle.properties b/gradle.properties index 05cdccc..17c01ac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,5 @@ group = net.silthus +packageName = net.silthus.template pluginName = PluginName author = Silthus mcVersion = 1.17.1 diff --git a/src/main/java/net/silthus/template/Constants.java b/src/main/java/net/silthus/template/Constants.java new file mode 100644 index 0000000..19cbf58 --- /dev/null +++ b/src/main/java/net/silthus/template/Constants.java @@ -0,0 +1,7 @@ +package net.silthus.template; + +public final class Constants { + + public static final String ACF_BASE_KEY = "commands"; + public static final String INFO_CMD_PERMISSION = "stemplate.admin.info"; +} diff --git a/src/main/java/net/silthus/template/TemplatePlugin.java b/src/main/java/net/silthus/template/TemplatePlugin.java index 0e8cebd..15d5cba 100644 --- a/src/main/java/net/silthus/template/TemplatePlugin.java +++ b/src/main/java/net/silthus/template/TemplatePlugin.java @@ -1,8 +1,11 @@ package net.silthus.template; +import co.aikar.commands.PaperCommandManager; import kr.entree.spigradle.annotations.PluginMain; import lombok.Getter; import lombok.experimental.Accessors; +import net.silthus.template.commands.TemplateCommands; +import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; @@ -11,6 +14,8 @@ import org.bukkit.plugin.java.JavaPluginLoader; import java.io.File; +import java.io.IOException; +import java.util.Locale; @PluginMain public class TemplatePlugin extends JavaPlugin implements Listener { @@ -18,6 +23,7 @@ public class TemplatePlugin extends JavaPlugin implements Listener { @Getter @Accessors(fluent = true) private static TemplatePlugin instance; + private PaperCommandManager commandManager; public TemplatePlugin() { instance = this; @@ -33,6 +39,8 @@ public TemplatePlugin( public void onEnable() { saveDefaultConfig(); + setupCommands(); + getServer().getPluginManager().registerEvents(this, this); } @@ -40,4 +48,27 @@ public void onEnable() { public void onPlayerJoin(PlayerJoinEvent event) { getLogger().info("Player joined."); } + + private void setupCommands() { + commandManager = new PaperCommandManager(this); + commandManager.enableUnstableAPI("help"); + + loadCommandLocales(commandManager); + + commandManager.registerCommand(new TemplateCommands()); + } + + // see https://github.com/aikar/commands/wiki/Locales + private void loadCommandLocales(PaperCommandManager commandManager) { + try { + saveResource("lang_en.yaml", true); + commandManager.getLocales().setDefaultLocale(Locale.ENGLISH); + commandManager.getLocales().loadYamlLanguageFile("lang_en.yaml", Locale.ENGLISH); + // this will detect the client locale and use it where possible + commandManager.usePerIssuerLocale(true); + } catch (IOException | InvalidConfigurationException e) { + getLogger().severe("Failed to load language config 'lang_en.yaml': " + e.getMessage()); + e.printStackTrace(); + } + } } diff --git a/src/main/java/net/silthus/template/commands/TemplateCommands.java b/src/main/java/net/silthus/template/commands/TemplateCommands.java new file mode 100644 index 0000000..c7bfa9d --- /dev/null +++ b/src/main/java/net/silthus/template/commands/TemplateCommands.java @@ -0,0 +1,49 @@ +package net.silthus.template.commands; + +import co.aikar.commands.BaseCommand; +import co.aikar.commands.CommandHelp; +import co.aikar.commands.MessageType; +import co.aikar.commands.annotation.*; +import co.aikar.locales.MessageKey; +import org.bukkit.Statistic; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import static net.silthus.template.Constants.ACF_BASE_KEY; +import static net.silthus.template.Constants.INFO_CMD_PERMISSION; + +@CommandAlias("stemplate") +public class TemplateCommands extends BaseCommand { + + // see https://github.com/aikar/commands/wiki/Locales + static MessageKey key(String key) { + return MessageKey.of(ACF_BASE_KEY + "." + key); + } + + // see https://github.com/aikar/commands/wiki/Command-Help + @HelpCommand + @Subcommand("help") + public void showHelp(CommandSender sender, CommandHelp help) { + help.showHelp(); + } + + @Subcommand("info|i") + @CommandAlias("info") + @Description("{@@commands.descriptions.info}") + @CommandCompletion("@players") + @CommandPermission(INFO_CMD_PERMISSION) + public void info(@Flags("self") Player player) { + success("info", + "{player}", player.getName(), + "{play_time}", player.getStatistic(Statistic.PLAY_ONE_MINUTE) + " Minutes" + ); + } + + private void success(String key, String... replacements) { + getCurrentCommandIssuer().sendMessage(MessageType.INFO, key(key), replacements); + } + + private void error(String key, String... replacements) { + getCurrentCommandIssuer().sendMessage(MessageType.ERROR, key(key), replacements); + } +} diff --git a/src/main/resources/lang_en.yaml b/src/main/resources/lang_en.yaml new file mode 100644 index 0000000..1c0103e --- /dev/null +++ b/src/main/resources/lang_en.yaml @@ -0,0 +1,5 @@ +# See https://github.com/aikar/commands/wiki/Locales +commands: + descriptions: + info: 'Prints out the players name and play time.' + info: 'Your name is: {player}. Playtime: {play_time}.' \ No newline at end of file diff --git a/src/test/java/net/silthus/template/commands/TemplateCommandsTests.java b/src/test/java/net/silthus/template/commands/TemplateCommandsTests.java new file mode 100644 index 0000000..0e00735 --- /dev/null +++ b/src/test/java/net/silthus/template/commands/TemplateCommandsTests.java @@ -0,0 +1,32 @@ +package net.silthus.template.commands; + +import be.seeseemelk.mockbukkit.entity.PlayerMock; +import net.silthus.template.Constants; +import net.silthus.template.TestBase; +import org.bukkit.Statistic; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class TemplateCommandsTests extends TestBase { + + private PlayerMock player; + + @Override + @BeforeEach + public void setUp() { + super.setUp(); + + player = server.addPlayer(); + player.addAttachment(plugin, Constants.INFO_CMD_PERMISSION, true); + } + + @Test + void info_forSelf_printsOwnPlayerName() { + player.performCommand("stemplate info"); + + int minutesPlayed = player.getStatistic(Statistic.PLAY_ONE_MINUTE); + assertThat(player.nextMessage()).contains("Your name is: Player0. Playtime: " + minutesPlayed); + } +}