diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 00000000..0de407b5 --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,2 @@ +prerelease: + - '*' diff --git a/.github/workflows/pr_labeler.yml b/.github/workflows/pr_labeler.yml new file mode 100644 index 00000000..69387def --- /dev/null +++ b/.github/workflows/pr_labeler.yml @@ -0,0 +1,17 @@ +name: "Pull Request Labeler" + +on: + pull_request_target: + types: [opened] + branches: [main] + +jobs: + prerelease_labeler: + permissions: + contents: read + pull-requests: write + runs-on: ubuntu-latest + steps: + - uses: actions/labeler@v4 + with: + repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/promote_release.yml b/.github/workflows/promote_release.yml new file mode 100644 index 00000000..5ee77d1d --- /dev/null +++ b/.github/workflows/promote_release.yml @@ -0,0 +1,90 @@ +name: Manually promote last prerelease to release + +on: + workflow_dispatch: + inputs: + version: + description: 'Version to promote' + required: true + version-bump: + description: 'Version bump to apply - should usually match the version bump used for the prerelease since last release' + required: true + type: choice + options: + - 'patch' + - 'minor' + - 'major' + +jobs: + manually_promote_release: + runs-on: ubuntu-latest + steps: + - name: Verify input version is prerelease + run: | + if [[ "${{ github.event.inputs.version }}" != *"pre"* ]]; then + echo "Version must be a prerelease" + exit 1 + fi + + - name: Get release info + id: get-release + uses: cardinalby/git-get-release-action@v1 + env: + GITHUB_TOKEN: ${{ github.token }} + with: + tag: ${{ github.event.inputs.version }} + + - uses: actions/checkout@v3 + with: + ref: ${{ steps.get-release.outputs.tag_name }} + + - uses: actions/setup-java@v3 + with: + java-version: '11' + distribution: 'adopt' + cache: gradle + + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 + + - name: Remove prerelease tag + run: | + echo "Removing prerelease tag from version" + echo "VERSION=$(echo ${{ steps.get-release.outputs.tag_name }} | sed -E 's/-pre.*//')" >> $GITHUB_ENV + + - name: Build + uses: gradle/gradle-build-action@v2 + with: + arguments: clean build -x test -x checkstyleMain -x checkstyleTest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_VERSION: ${{ env.VERSION }} + + - name: Create release + id: release + uses: Multiverse/release-on-push-action@skip_prs + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + bump_version_scheme: ${{ github.event.inputs.version-bump }} + tag_prefix: '' + release_name: "" + use_github_release_notes: true + ref: ${{ steps.get-release.outputs.target_commitish }} + skip_prs: true + + - name: Publish package + uses: gradle/gradle-build-action@v2 + with: + arguments: publish + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_VERSION: ${{ env.VERSION }} + + - name: Upload release artifact + uses: svenstaro/upload-release-action@v2 + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file: build/libs/multiverse-core-${{ env.VERSION }}.jar + asset_name: multiverse-core-${{ steps.release.outputs.tag_name }}.jar + tag: ${{ steps.release.outputs.tag_name }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 738878dc..5cecab08 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,27 +28,37 @@ jobs: - name: Create release id: release - uses: rymndhng/release-on-push-action@v0.27.0 + uses: Multiverse/release-on-push-action@support_prerelease env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: bump_version_scheme: norelease tag_prefix: '' - release_name: "Release " + release_name: "" use_github_release_notes: true + - name: Modify version scheme + run: | + if [[ "${{ steps.release.outputs.tag_name }}" == *"pre"* ]]; then + echo "Replacing prerelease version scheme with SNAPSHOT" + echo "VERSION=$(echo ${{ steps.release.outputs.tag_name }} | sed -E 's/-pre.*/-SNAPSHOT/')" >> $GITHUB_ENV + else + echo "Using release version scheme" + echo "VERSION=${{ steps.release.outputs.tag_name }}" >> $GITHUB_ENV + fi + - name: Publish package uses: gradle/gradle-build-action@v2 with: arguments: publish env: - GITHUB_VERSION: ${{ steps.release.outputs.tag_name }} + GITHUB_VERSION: ${{ env.VERSION }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Upload release artifact uses: svenstaro/upload-release-action@v2 with: repo_token: ${{ secrets.GITHUB_TOKEN }} - file: build/libs/multiverse-core-${{ steps.release.outputs.tag_name }}.jar + file: build/libs/multiverse-core-${{ env.VERSION }}.jar asset_name: multiverse-core-${{ steps.release.outputs.tag_name }}.jar tag: ${{ steps.release.outputs.tag_name }} diff --git a/.github/workflows/require_label.yml b/.github/workflows/require_label.yml index e4f9c293..13922340 100644 --- a/.github/workflows/require_label.yml +++ b/.github/workflows/require_label.yml @@ -15,4 +15,4 @@ jobs: with: mode: exactly count: 1 - labels: "release:major, release:minor, release:patch, no release" + labels: "release:major, release:minor, release:patch, no version bump" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fe2e3b1d..68d7ff4e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,4 +26,11 @@ jobs: with: arguments: build env: + GITHUB_VERSION: pr${{ github.event.pull_request.number }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Artifact output + uses: actions/upload-artifact@v3 + with: + name: multiverse-core-pr${{ github.event.pull_request.number }} + path: build/libs/multiverse-core-pr${{ github.event.pull_request.number }}.jar diff --git a/build.gradle b/build.gradle index 5351c7fb..85eef0af 100644 --- a/build.gradle +++ b/build.gradle @@ -5,16 +5,23 @@ plugins { id 'maven-publish' id 'checkstyle' id 'com.github.johnrengelman.shadow' version '7.1.2' + id "org.jetbrains.kotlin.jvm" version "1.8.10" } version = System.getenv('GITHUB_VERSION') ?: 'local' group = 'com.onarandombox.multiversecore' description = 'Multiverse-Core' -java.sourceCompatibility = JavaVersion.VERSION_11 +java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) + } +} repositories { mavenLocal() + mavenCentral() + maven { url = uri('https://hub.spigotmc.org/nexus/content/repositories/snapshots/') } @@ -48,19 +55,28 @@ repositories { name = 'glaremasters repo' url = 'https://repo.glaremasters.me/repository/towny/' } + maven { + name = 'PlaceholderAPI' + url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/' + } +} + +configurations { + oldTestImplementation.extendsFrom implementation + oldTestRuntime.extendsFrom runtime } dependencies { - // Spigot - implementation('org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT') { - exclude group: 'junit', module: 'junit' - } + compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT' // Economy implementation('com.github.MilkBowl:VaultAPI:1.7.1') { exclude group: 'org.bukkit', module: 'bukkit' } + // PlaceholderAPI + compileOnly 'me.clip:placeholderapi:2.11.2' + // Command Framework api 'co.aikar:acf-paper:0.5.1-SNAPSHOT' @@ -82,9 +98,21 @@ dependencies { api 'org.jetbrains:annotations:22.0.0' // Tests - testImplementation 'junit:junit:4.13.1' - testImplementation 'org.mockito:mockito-core:3.11.2' - testImplementation 'commons-io:commons-io:2.7' + testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10' + testImplementation 'com.github.seeseemelk:MockBukkit-v1.19:2.141.0' + testImplementation('com.googlecode.json-simple:json-simple:1.1.1') { + exclude group: 'junit', module: 'junit' + } + testImplementation 'org.jetbrains.kotlin:kotlin-test' + + // Old Tests + oldTestImplementation 'org.spigotmc:spigot-api:1.19.3-R0.1-SNAPSHOT' + oldTestImplementation('com.googlecode.json-simple:json-simple:1.1.1') { + exclude group: 'junit', module: 'junit' + } + oldTestImplementation 'junit:junit:4.13.1' + oldTestImplementation 'org.mockito:mockito-core:3.11.2' + oldTestImplementation 'commons-io:commons-io:2.7' } @@ -109,6 +137,19 @@ configurations { } } + +sourceSets { + oldTest { + java { + compileClasspath += main.output + runtimeClasspath += main.output + srcDir file('src/old-test/java') + } + resources.srcDir file('src/old-test/resources') + } +} + + publishing { publications { maven(MavenPublication) { @@ -143,6 +184,19 @@ compileJava { source = prepareSource.outputs } +compileKotlin { + // We're not using Kotlin in the plugin itself, just tests! + enabled = false +} +configurations { + compileOnly { + exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8' + } + runtimeOnly { + exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8' + } +} + processResources { def props = [version: "${project.version}"] inputs.properties props @@ -184,14 +238,17 @@ shadowJar { configurations = [project.configurations.api] archiveFileName = "$baseName-$version.$extension" + + dependencies { + exclude(dependency { + it.moduleGroup == 'org.jetbrains.kotlin' + }) + } } build.dependsOn shadowJar jar.enabled = false - -// Excludes all test -// TODO: Remove this when we have tests for MV5 test { - exclude '**/*' + useJUnitPlatform() } diff --git a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java index 27234463..9590c94f 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java +++ b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java @@ -33,6 +33,7 @@ import com.onarandombox.MultiverseCore.commands.LoadCommand; import com.onarandombox.MultiverseCore.commands.RegenCommand; import com.onarandombox.MultiverseCore.commands.ReloadCommand; import com.onarandombox.MultiverseCore.commands.RemoveCommand; +import com.onarandombox.MultiverseCore.commands.RootCommand; import com.onarandombox.MultiverseCore.commands.TeleportCommand; import com.onarandombox.MultiverseCore.commands.UnloadCommand; import com.onarandombox.MultiverseCore.commandtools.MVCommandManager; @@ -53,6 +54,7 @@ import com.onarandombox.MultiverseCore.listeners.MVPortalListener; import com.onarandombox.MultiverseCore.listeners.MVWeatherListener; import com.onarandombox.MultiverseCore.listeners.MVWorldInitListener; import com.onarandombox.MultiverseCore.listeners.MVWorldListener; +import com.onarandombox.MultiverseCore.placeholders.MultiverseCorePlaceholders; import com.onarandombox.MultiverseCore.teleportation.SimpleBlockSafety; import com.onarandombox.MultiverseCore.teleportation.SimpleLocationManipulation; import com.onarandombox.MultiverseCore.teleportation.SimpleSafeTTeleporter; @@ -155,8 +157,10 @@ public class MultiverseCore extends JavaPlugin implements MVCore { this.anchorManager.loadAnchors(); this.registerEvents(); this.registerCommands(); + this.setUpLocales(); this.registerDestinations(); this.setupMetrics(); + this.setupPlaceholderAPI(); this.saveMVConfig(); this.logEnableMessage(); } @@ -202,10 +206,20 @@ public class MultiverseCore extends JavaPlugin implements MVCore { this.commandManager.registerCommand(new RegenCommand(this)); this.commandManager.registerCommand(new ReloadCommand(this)); this.commandManager.registerCommand(new RemoveCommand(this)); + this.commandManager.registerCommand(new RootCommand(this)); this.commandManager.registerCommand(new TeleportCommand(this)); this.commandManager.registerCommand(new UnloadCommand(this)); } + /** + * Register locales + */ + private void setUpLocales() { + this.commandManager.usePerIssuerLocale(true, true); + this.commandManager.getLocales().addFileResClassLoader(this); + this.commandManager.getLocales().addMessageBundles("multiverse-core"); + } + /** * Register all the destinations. */ @@ -240,6 +254,12 @@ public class MultiverseCore extends JavaPlugin implements MVCore { } } + private void setupPlaceholderAPI() { + if(getServer().getPluginManager().getPlugin("PlaceholderAPI") != null) { + new MultiverseCorePlaceholders(this).register(); + } + } + /** * {@inheritDoc} */ diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/CheckCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/CheckCommand.java index 99ebb735..95064770 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/CheckCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/CheckCommand.java @@ -9,6 +9,7 @@ import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Syntax; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.destination.ParsedDestination; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -22,18 +23,20 @@ public class CheckCommand extends MultiverseCoreCommand { @CommandPermission("multiverse.core.check") @CommandCompletion("@players @destinations|@mvworlds") @Syntax(" ") - @Description("Checks if a player can teleport to a destination.") + @Description("{@@mv-core.check.description}") public void onCheckCommand(BukkitCommandIssuer issuer, @Syntax("") - @Description("Player to check destination on.") + @Description("{@@mv-core.check.player.description}") Player player, @Syntax("") - @Description("A destination location, e.g. a world name.") + @Description("{@@mv-core.check.destination.description}") ParsedDestination destination ) { - issuer.sendMessage("Checking " + player + " to " + destination + "..."); + issuer.sendInfo(MVCorei18n.CHECK_CHECKING, + "{player}", player.getName(), + "{destination}", destination.toString()); //TODO More detailed output on permissions required. this.plugin.getDestinationsProvider().checkTeleportPermissions(issuer, player, destination); } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/CloneCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/CloneCommand.java index 366db444..283902af 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/CloneCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/CloneCommand.java @@ -10,6 +10,7 @@ import co.aikar.commands.annotation.Single; import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Syntax; import com.onarandombox.MultiverseCore.MultiverseCore; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.bukkit.ChatColor; import org.jetbrains.annotations.NotNull; @@ -23,26 +24,29 @@ public class CloneCommand extends MultiverseCoreCommand { @CommandPermission("multiverse.core.clone") @CommandCompletion("@mvworlds:scope=both @empty") @Syntax(" ") - @Description("Clones a world.") + @Description("{@@mv-core.clone.description}") public void onCloneCommand(CommandIssuer issuer, @Conditions("validWorldName:scope=both") @Syntax("") - @Description("The target world to clone.") + @Description("{@@mv-core.clone.world.description}") String worldName, @Single @Conditions("validWorldName:scope=new") @Syntax("") - @Description("The new cloned world name.") + @Description("{@@mv-core.clone.newWorld.description}") String newWorldName ) { - issuer.sendMessage(String.format("Cloning world '%s' to '%s'...", worldName, newWorldName)); + issuer.sendInfo(MVCorei18n.CLONE_CLONING, + "{world}", worldName, + "{newWorld}", newWorldName); if (!this.plugin.getMVWorldManager().cloneWorld(worldName, newWorldName)) { - issuer.sendMessage(String.format("%sWorld could not be cloned! See console for more details.", ChatColor.RED)); + issuer.sendError(MVCorei18n.CLONE_FAILED); return; } - issuer.sendMessage(String.format("%sCloned world '%s'!", ChatColor.GREEN, newWorldName)); + issuer.sendInfo(MVCorei18n.CLONE_SUCCESS, + "{world}", newWorldName); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/ConfirmCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/ConfirmCommand.java index 24d09f17..a96e4368 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/ConfirmCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/ConfirmCommand.java @@ -16,7 +16,7 @@ public class ConfirmCommand extends MultiverseCoreCommand { @Subcommand("confirm") @CommandPermission("multiverse.core.confirm") - @Description("Confirms dangerous commands before executing them.") + @Description("{@@mv-core.confirm.description}") public void onConfirmCommand(@NotNull BukkitCommandIssuer issuer) { this.plugin.getMVCommandManager().getCommandQueueManager().runQueuedCommand(issuer.getIssuer()); } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java index b6111ffc..83b2bb2f 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/CreateCommand.java @@ -22,7 +22,7 @@ import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlag; import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagGroup; import com.onarandombox.MultiverseCore.commandtools.flags.CommandValueFlag; import com.onarandombox.MultiverseCore.commandtools.flags.ParsedCommandFlags; -import com.onarandombox.MultiverseCore.locale.MVCorei18n; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.WorldType; diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/DebugCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/DebugCommand.java index ef6bf56e..7daf93bc 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/DebugCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/DebugCommand.java @@ -9,7 +9,7 @@ import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Syntax; import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.MultiverseCore; -import com.onarandombox.MultiverseCore.locale.MVCorei18n; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.jetbrains.annotations.NotNull; @CommandAlias("mv") diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java index 667666c1..ee65b5c3 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/DeleteCommand.java @@ -1,6 +1,7 @@ package com.onarandombox.MultiverseCore.commands; import co.aikar.commands.BukkitCommandIssuer; +import co.aikar.commands.MessageType; import co.aikar.commands.annotation.CommandAlias; import co.aikar.commands.annotation.CommandCompletion; import co.aikar.commands.annotation.CommandPermission; @@ -10,7 +11,9 @@ import co.aikar.commands.annotation.Single; import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Syntax; import com.onarandombox.MultiverseCore.MultiverseCore; +import com.onarandombox.MultiverseCore.api.MVCore; import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.bukkit.ChatColor; import org.jetbrains.annotations.NotNull; @@ -24,7 +27,7 @@ public class DeleteCommand extends MultiverseCoreCommand { @CommandPermission("multiverse.core.delete") @CommandCompletion("@mvworlds:scope=both") @Syntax("") - @Description("Deletes a world on your server PERMANENTLY.") + @Description("{@@mv-core.delete.description}") public void onDeleteCommand(BukkitCommandIssuer issuer, @Single @@ -36,14 +39,21 @@ public class DeleteCommand extends MultiverseCoreCommand { this.plugin.getMVCommandManager().getCommandQueueManager().addToQueue(new QueuedCommand( issuer.getIssuer(), () -> { - issuer.sendMessage(String.format("Deleting world '%s'...", worldName)); + issuer.sendInfo(MVCorei18n.DELETE_DELETING, + "{world}", worldName); if (!this.plugin.getMVWorldManager().deleteWorld(worldName)) { - issuer.sendMessage(String.format("%sThere was an issue deleting '%s'! Please check console for errors.", ChatColor.RED, worldName)); + issuer.sendError(MVCorei18n.DELETE_FAILED, + "{world}", worldName); return; } - issuer.sendMessage(String.format("%sWorld %s was deleted!", ChatColor.GREEN, worldName)); + issuer.sendInfo(MVCorei18n.DELETE_SUCCESS, + "{world}", worldName); }, - "Are you sure you want to delete world '" + worldName + "'?" + this.plugin.getMVCommandManager().formatMessage( + issuer, + MessageType.INFO, + MVCorei18n.DELETE_PROMPT, + "{world}", worldName) )); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/GameruleCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/GameruleCommand.java index 003a453c..2a81f174 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/GameruleCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/GameruleCommand.java @@ -11,6 +11,7 @@ import co.aikar.commands.annotation.Syntax; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.api.MVWorld; import com.onarandombox.MultiverseCore.commandtools.context.GameRuleValue; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.bukkit.ChatColor; import org.bukkit.GameRule; import org.jetbrains.annotations.NotNull; @@ -25,20 +26,20 @@ public class GameruleCommand extends MultiverseCoreCommand { @CommandPermission("multiverse.core.gamerule") @CommandCompletion("@gamerules true|false|@range:1-10 @mvworlds:multiple|*") @Syntax(" [World or *]") - @Description("Changes a gamerule in one or more worlds") + @Description("{@@mv-core.gamerule.description}") public void onGameruleCommand(BukkitCommandIssuer issuer, @Syntax("") - @Description("Gamerule to set") + @Description("{@@mv-core.gamerule.gamerule.description}") GameRule gamerule, @Syntax("") - @Description("Value of gamerule") + @Description("{@@mv-core.gamerule.value.description}") GameRuleValue gameRuleValue, @Flags("resolve=issuerAware") @Syntax("[World or *]") - @Description("World to apply gamerule to, current world by default") + @Description("{@@mv-core.gamerule.world.description}") MVWorld[] worlds ) { Object value = gameRuleValue.getValue(); @@ -46,17 +47,27 @@ public class GameruleCommand extends MultiverseCoreCommand { for(MVWorld world : worlds) { // Set gamerules and add false to list if it fails if (!world.getCBWorld().setGameRule(gamerule, value)) { - issuer.sendMessage(ChatColor.RED + "Failed to set gamerule " + gamerule.getName() + " to " + value + " in " + world.getName() + ". It should be a " + gamerule.getType()); + issuer.sendError(MVCorei18n.GAMERULE_FAILED, + "{gamerule}", gamerule.getName(), + "{value}", value.toString(), + "{world}", world.getName(), + "{type}", gamerule.getType().getName()); success = false; } } // Tell user if it was successful if (success) { if (worlds.length == 1) { - issuer.sendMessage(ChatColor.GREEN + "Successfully set " + gamerule.getName() + " to " + value + " in " + worlds[0].getName()); + issuer.sendInfo(MVCorei18n.GAMERULE_SUCCESS_SINGLE, + "{gamerule}", gamerule.getName(), + "{value}", value.toString(), + "{world}", worlds[0].getName()); } else if (worlds.length > 1) { - issuer.sendMessage(ChatColor.GREEN + "Successfully set " + gamerule.getName() + " to " + value + " in " + worlds.length + " worlds."); + issuer.sendInfo(MVCorei18n.GAMERULE_SUCCESS_MULTIPLE, + "{gamerule}", gamerule.getName(), + "{value}", value.toString(), + "{count}", String.valueOf(worlds.length)); } } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/ImportCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/ImportCommand.java index 2cc80ef6..235b057d 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/ImportCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/ImportCommand.java @@ -13,10 +13,12 @@ import co.aikar.commands.annotation.Optional; import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Syntax; import com.onarandombox.MultiverseCore.MultiverseCore; +import com.onarandombox.MultiverseCore.api.MVCore; import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlag; import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagGroup; import com.onarandombox.MultiverseCore.commandtools.flags.CommandValueFlag; import com.onarandombox.MultiverseCore.commandtools.flags.ParsedCommandFlags; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.World; @@ -51,26 +53,27 @@ public class ImportCommand extends MultiverseCoreCommand { @CommandPermission("multiverse.core.import") @CommandCompletion("@mvworlds:scope=potential @flags:groupName=mvimport") @Syntax(" --generator [generator[:id]] --adjust-spawn") - @Description("Imports a existing world folder.") + @Description("{@@mv-core.import.description") public void onImportCommand(BukkitCommandIssuer issuer, @Conditions("validWorldName:scope=new") @Syntax("") - @Description("Name of the world folder.") + @Description("{@@mv-core.import.name.description}") String worldName, @Syntax("") - @Description("The world's environment. See: /mv env") + @Description("{@@mv-core.import.env.description}") World.Environment environment, @Optional @Syntax("--generator [generator[:id]] --adjust-spawn") - @Description("Other world settings. See: https://gg.gg/nn8c2") + @Description("{@@mv-core.import.other.description}") String[] flags) { ParsedCommandFlags parsedFlags = parseFlags(flags); - issuer.sendMessage(String.format("Starting import of world '%s'...", worldName)); + issuer.sendInfo(MVCorei18n.IMPORT_IMPORTING, + "{world}", worldName); if (!this.worldManager.addWorld( worldName, environment, @@ -80,9 +83,9 @@ public class ImportCommand extends MultiverseCoreCommand { parsedFlags.flagValue("--generator", String.class), parsedFlags.hasFlag("--adjust-spawn")) ) { - issuer.sendMessage(String.format("%sFailed! See console for more details.", ChatColor.RED)); + issuer.sendError(MVCorei18n.IMPORT_FAILED); return; } - issuer.sendMessage(String.format("%sComplete!", ChatColor.GREEN)); + issuer.sendInfo(MVCorei18n.IMPORT_SUCCESS); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/LoadCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/LoadCommand.java index 0e03eab4..0e8af06c 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/LoadCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/LoadCommand.java @@ -10,6 +10,7 @@ import co.aikar.commands.annotation.Single; import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Syntax; import com.onarandombox.MultiverseCore.MultiverseCore; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.jetbrains.annotations.NotNull; @CommandAlias("mv") @@ -22,21 +23,24 @@ public class LoadCommand extends MultiverseCoreCommand { @CommandPermission("multiverse.core.load") @CommandCompletion("@mvworlds:scope=unloaded") @Syntax("") - @Description("Loads a world. World must be already in worlds.yml, else please use /mv import.") + @Description("{@@mv-core.load.description}") public void onLoadCommand(BukkitCommandIssuer issuer, @Single @Conditions("validWorldName:scope=unloaded") @Syntax("") - @Description("Name of world you want to load.") + @Description("{@@mv-core.load.world.description}") String worldName ) { - issuer.sendMessage(String.format("Loading world '%s'...", worldName)); + issuer.sendInfo(MVCorei18n.LOAD_LOADING, + "{world}", worldName); if (!this.plugin.getMVWorldManager().loadWorld(worldName)) { - issuer.sendMessage(String.format("Error trying to load world '%s'!", worldName)); + issuer.sendError(MVCorei18n.LOAD_FAILED, + "{world}", worldName); return; } - issuer.sendMessage(String.format("Loaded world '%s'!", worldName)); + issuer.sendInfo(MVCorei18n.LOAD_SUCCESS, + "{world}", worldName); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/RegenCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/RegenCommand.java index 40102078..19ef73eb 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/RegenCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/RegenCommand.java @@ -4,6 +4,7 @@ import java.util.Collections; import java.util.Random; import co.aikar.commands.BukkitCommandIssuer; +import co.aikar.commands.MessageType; import co.aikar.commands.annotation.CommandAlias; import co.aikar.commands.annotation.CommandCompletion; import co.aikar.commands.annotation.CommandPermission; @@ -18,6 +19,7 @@ import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagGroup; import com.onarandombox.MultiverseCore.commandtools.flags.CommandValueFlag; import com.onarandombox.MultiverseCore.commandtools.flags.ParsedCommandFlags; import com.onarandombox.MultiverseCore.commandtools.queue.QueuedCommand; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.bukkit.ChatColor; import org.jetbrains.annotations.NotNull; @@ -42,17 +44,17 @@ public class RegenCommand extends MultiverseCoreCommand { @CommandPermission("multiverse.core.regen") @CommandCompletion("@mvworlds:scope=both @flags:groupName=mvregen") @Syntax(" --seed [seed] --keep-gamerules") - @Description("Regenerates a world on your server. The previous state will be lost PERMANENTLY.") + @Description("{@@mv-core.regen.description}") public void onRegenCommand(BukkitCommandIssuer issuer, @Conditions("validWorldName:scope=both") @Syntax("") - @Description("World that you want to regen.") + @Description("{@@mv-core.regen.world.description}") String worldName, @Optional @Syntax("--seed [seed] --keep-gamerules") - @Description("Other world settings. See: http://gg.gg/nn8lk") + @Description("{@@mv-core.regen.other.description}") String[] flags ) { ParsedCommandFlags parsedFlags = parseFlags(flags); @@ -60,7 +62,8 @@ public class RegenCommand extends MultiverseCoreCommand { this.plugin.getMVCommandManager().getCommandQueueManager().addToQueue(new QueuedCommand( issuer.getIssuer(), () -> { - issuer.sendMessage(String.format("Regenerating world '%s'...", worldName)); + issuer.sendInfo(MVCorei18n.REGEN_REGENERATING, + "{world}", worldName); if (!this.plugin.getMVWorldManager().regenWorld( worldName, parsedFlags.hasFlag("--seed"), @@ -68,12 +71,18 @@ public class RegenCommand extends MultiverseCoreCommand { parsedFlags.flagValue("--seed", String.class), parsedFlags.hasFlag("--keep-gamerules") )) { - issuer.sendMessage(String.format("%sThere was an issue regenerating '%s'! Please check console for errors.", ChatColor.RED, worldName)); + issuer.sendError(MVCorei18n.REGEN_FAILED, + "{world}", worldName); return; } - issuer.sendMessage(String.format("%sWorld %s was regenerated!", ChatColor.GREEN, worldName)); + issuer.sendInfo(MVCorei18n.REGEN_SUCCESS, + "{world}", worldName); }, - "Are you sure you want to regenerate world '" + worldName + "'?" + this.plugin.getMVCommandManager().formatMessage( + issuer, + MessageType.INFO, + MVCorei18n.REGEN_PROMPT, + "{world}", worldName) )); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/ReloadCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/ReloadCommand.java index 2f71394c..1adaba2a 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/ReloadCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/ReloadCommand.java @@ -10,6 +10,7 @@ import co.aikar.commands.annotation.Description; import co.aikar.commands.annotation.Subcommand; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.event.MVConfigReloadEvent; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.bukkit.ChatColor; import org.jetbrains.annotations.NotNull; @@ -21,9 +22,9 @@ public class ReloadCommand extends MultiverseCoreCommand { @Subcommand("reload") @CommandPermission("multiverse.core.reload") - @Description("Reloads config files for all multiverse modules.") + @Description("{@@mv-core.reload.description}") public void onReloadCommand(@NotNull BukkitCommandIssuer issuer) { - issuer.sendMessage(ChatColor.GOLD + "Reloading all Multiverse Plugin configs..."); + issuer.sendInfo(MVCorei18n.RELOAD_RELOADING); this.plugin.loadConfigs(); this.plugin.getAnchorManager().loadAnchors(); this.plugin.getMVWorldManager().loadWorlds(true); @@ -36,7 +37,8 @@ public class ReloadCommand extends MultiverseCoreCommand { MVConfigReloadEvent configReload = new MVConfigReloadEvent(configsLoaded); this.plugin.getServer().getPluginManager().callEvent(configReload); + // @TODO: replace this sendMessage and format the configsLoaded above, maybe? configReload.getAllConfigsLoaded().forEach(issuer::sendMessage); - issuer.sendMessage(String.format("%sReload Complete!", ChatColor.GREEN)); + issuer.sendInfo(MVCorei18n.RELOAD_SUCCESS); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/RemoveCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/RemoveCommand.java index e011a2ca..e4f8152c 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/RemoveCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/RemoveCommand.java @@ -10,6 +10,7 @@ import co.aikar.commands.annotation.Single; import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Syntax; import com.onarandombox.MultiverseCore.MultiverseCore; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.bukkit.ChatColor; import org.jetbrains.annotations.NotNull; @@ -23,19 +24,20 @@ public class RemoveCommand extends MultiverseCoreCommand { @CommandPermission("multiverse.core.remove") @CommandCompletion("@mvworlds:scope=both") @Syntax("") - @Description("Unloads a world from Multiverse and removes it from worlds.yml, this does NOT DELETE the world folder.") + @Description("{@@mv-core.remove.description}") public void onRemoveCommand(BukkitCommandIssuer issuer, @Single @Conditions("mvworlds:scope=both") @Syntax("") - @Description("World you want to remove from mv's knowledge.") + @Description("{@@mv-core.remove.world.description}") String worldName ) { if (!this.plugin.getMVWorldManager().removeWorldFromConfig(worldName)) { - issuer.sendMessage(String.format("%sError trying to remove world from config!", ChatColor.RED)); + issuer.sendError(MVCorei18n.REMOVE_FAILED); return; } - issuer.sendMessage(String.format("World '%s' is removed from config!", worldName)); + issuer.sendInfo(MVCorei18n.REMOVE_SUCCESS, + "{world}", worldName); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/RootCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/RootCommand.java new file mode 100644 index 00000000..8d63d32a --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/RootCommand.java @@ -0,0 +1,24 @@ +package com.onarandombox.MultiverseCore.commands; + +import co.aikar.commands.CommandIssuer; +import co.aikar.commands.annotation.CommandAlias; +import com.onarandombox.MultiverseCore.MultiverseCore; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; +import org.bukkit.ChatColor; +import org.bukkit.plugin.PluginDescriptionFile; +import org.jetbrains.annotations.NotNull; + +public class RootCommand extends MultiverseCoreCommand { + public RootCommand(@NotNull MultiverseCore plugin) { + super(plugin); + } + + @CommandAlias("mv") + public void onRootCommand(CommandIssuer issuer) { + PluginDescriptionFile description = this.plugin.getDescription(); + issuer.sendInfo(MVCorei18n.ROOT_TITLE, + "{name}", description.getName(), + "{version}", description.getVersion()); + issuer.sendInfo(MVCorei18n.ROOT_HELP); + } +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/TeleportCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/TeleportCommand.java index 78e507f5..6b72b7f6 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/TeleportCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/TeleportCommand.java @@ -10,6 +10,7 @@ import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Syntax; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.destination.ParsedDestination; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.bukkit.entity.Player; @CommandAlias("mv") @@ -21,23 +22,23 @@ public class TeleportCommand extends MultiverseCoreCommand { @Subcommand("teleport|tp") @CommandCompletion("@players|@mvworlds:playerOnly|@destinations:playerOnly @mvworlds|@destinations") @Syntax("[player] ") - @Description("Allows you to the teleport to a location on your server!") + @Description("{@@mv-core.teleport.description}") public void onTeleportCommand(BukkitCommandIssuer issuer, @Flags("resolve=issuerAware") @Syntax("[player]") - @Description("Target player to teleport.") + @Description("{@@mv-core.teleport.player.description}") Player[] players, @Syntax("") - @Description("Location, can be a world name.") + @Description("{@@mv-core.teleport.destination.description}") ParsedDestination destination ) { // TODO Add warning if teleporting too many players at once. for (Player player : players) { - issuer.sendMessage("Teleporting " - + (issuer.getPlayer() == player ? "you" : player.getName()) - + " to " + destination + "..."); + issuer.sendInfo(MVCorei18n.TELEPORT_SUCCESS, + "{player}", issuer.getPlayer() == player ? "you" : player.getName(), + "{destination}", destination.toString()); this.plugin.getDestinationsProvider().playerTeleport(issuer, player, destination); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/UnloadCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/UnloadCommand.java index 268788bc..720336bf 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/UnloadCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/UnloadCommand.java @@ -9,6 +9,7 @@ import co.aikar.commands.annotation.Subcommand; import co.aikar.commands.annotation.Syntax; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.api.MVWorld; +import com.onarandombox.MultiverseCore.utils.MVCorei18n; import org.jetbrains.annotations.NotNull; @CommandAlias("mv") @@ -21,20 +22,23 @@ public class UnloadCommand extends MultiverseCoreCommand { @CommandPermission("multiverse.core.unload") @CommandCompletion("@mvworlds") @Syntax("") - @Description("Unloads a world from Multiverse. This does NOT remove the world folder. This does NOT remove it from the config file.") + @Description("{@@mv-core.unload.description}") public void onUnloadCommand(BukkitCommandIssuer issuer, @Syntax("") - @Description("Name of the world you want to unload.") + @Description("{@@mv-core.unload.world.description}") MVWorld world ) { - issuer.sendMessage(String.format("Unloading world '%s'...", world.getColoredWorldString())); + issuer.sendInfo(MVCorei18n.UNLOAD_UNLOADING, + "{world}", world.getColoredWorldString()); //TODO API: Should be able to use MVWorld object directly if (!this.plugin.getMVWorldManager().unloadWorld(world.getName())) { - issuer.sendMessage(String.format("Error unloading world '%s'! See console for more details.", world.getColoredWorldString())); + issuer.sendError(MVCorei18n.UNLOAD_FAILURE, + "{world}", world.getColoredWorldString()); return; } - issuer.sendMessage(String.format("Unloaded world '%s'!", world.getColoredWorldString())); + issuer.sendInfo(MVCorei18n.UNLOAD_SUCCESS, + "{world}", world.getColoredWorldString()); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/UsageCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/UsageCommand.java new file mode 100644 index 00000000..b2e2acc4 --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/UsageCommand.java @@ -0,0 +1,33 @@ +package com.onarandombox.MultiverseCore.commands; + +import co.aikar.commands.CommandHelp; +import co.aikar.commands.annotation.CommandAlias; +import co.aikar.commands.annotation.CommandCompletion; +import co.aikar.commands.annotation.CommandPermission; +import co.aikar.commands.annotation.Description; +import co.aikar.commands.annotation.HelpCommand; +import co.aikar.commands.annotation.Subcommand; +import co.aikar.commands.annotation.Syntax; +import com.onarandombox.MultiverseCore.MultiverseCore; +import org.jetbrains.annotations.NotNull; + +@CommandAlias("mv") +public class UsageCommand extends MultiverseCoreCommand { + public UsageCommand(@NotNull MultiverseCore plugin) { + super(plugin); + } + + @HelpCommand + @Subcommand("help") + @CommandPermission("multiverse.core.help") + @CommandCompletion("@commands:mv") + @Syntax("[filter] [page]") + @Description("{@@mv-core.usage.description}") + public void onUsageCommand(CommandHelp help) { + if (help.getIssuer().isPlayer()) { + // Prevent flooding the chat + help.setPerPage(4); + } + this.plugin.getMVCommandManager().showUsage(help); + } +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/commandtools/MVCommandCompletions.java b/src/main/java/com/onarandombox/MultiverseCore/commandtools/MVCommandCompletions.java index 044dac90..ff5671d8 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commandtools/MVCommandCompletions.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commandtools/MVCommandCompletions.java @@ -5,12 +5,16 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import co.aikar.commands.BukkitCommandCompletionContext; import co.aikar.commands.BukkitCommandIssuer; +import co.aikar.commands.CommandIssuer; import co.aikar.commands.PaperCommandCompletions; +import co.aikar.commands.RegisteredCommand; +import co.aikar.commands.RootCommand; import com.google.common.collect.Sets; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.api.MVWorld; @@ -30,6 +34,7 @@ public class MVCommandCompletions extends PaperCommandCompletions { this.plugin = plugin; this.worldManager = plugin.getMVWorldManager(); + registerAsyncCompletion("commands", this::suggestCommands); registerAsyncCompletion("destinations", this::suggestDestinations); registerAsyncCompletion("flags", this::suggestFlags); registerStaticCompletion("gamerules", this::suggestGamerules); @@ -41,6 +46,33 @@ public class MVCommandCompletions extends PaperCommandCompletions { setDefaultCompletion("mvworlds", MVWorld.class); } + private Collection suggestCommands(BukkitCommandCompletionContext context) { + String rootCmdName = context.getConfig(); + if (rootCmdName == null) { + return Collections.emptyList(); + } + + RootCommand rootCommand = this.plugin.getMVCommandManager().getRegisteredRootCommands().stream() + .unordered() + .filter(c -> c.getCommandName().equals(rootCmdName)) + .findFirst() + .orElse(null); + + if (rootCommand == null) { + return Collections.emptyList(); + } + + return rootCommand.getSubCommands().entries().stream() + .filter(entry -> checkPerms(context.getIssuer(), entry.getValue())) + .map(Map.Entry::getKey) + .filter(cmdName -> !cmdName.startsWith("__")) + .collect(Collectors.toList()); + } + + private boolean checkPerms(CommandIssuer issuer, RegisteredCommand command) { + return this.plugin.getMVCommandManager().hasPermission(issuer, command.getRequiredPermissions()); + } + private Collection suggestDestinations(BukkitCommandCompletionContext context) { if (context.hasConfig("playerOnly") && !context.getIssuer().isPlayer()) { return Collections.emptyList(); diff --git a/src/main/java/com/onarandombox/MultiverseCore/commandtools/MVCommandManager.java b/src/main/java/com/onarandombox/MultiverseCore/commandtools/MVCommandManager.java index 73ea2752..8a1cd3a7 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commandtools/MVCommandManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commandtools/MVCommandManager.java @@ -1,11 +1,13 @@ package com.onarandombox.MultiverseCore.commandtools; -import java.util.Locale; +import java.util.List; import co.aikar.commands.BukkitCommandCompletionContext; import co.aikar.commands.BukkitCommandExecutionContext; import co.aikar.commands.CommandCompletions; import co.aikar.commands.CommandContexts; +import co.aikar.commands.CommandHelp; +import co.aikar.commands.HelpEntry; import co.aikar.commands.PaperCommandManager; import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.commandtools.flags.CommandFlagsManager; @@ -20,6 +22,7 @@ public class MVCommandManager extends PaperCommandManager { private final MultiverseCore plugin; private CommandFlagsManager flagsManager; private CommandQueueManager commandQueueManager; + private PluginLocales pluginLocales; public MVCommandManager(@NotNull MultiverseCore plugin) { super(plugin); @@ -27,11 +30,6 @@ public class MVCommandManager extends PaperCommandManager { // Setup conditions MVCommandConditions.load(this, plugin); - - // Setup locale - this.addSupportedLanguage(Locale.ENGLISH); - this.locales.addMessageBundles("multiverse-core"); - this.locales.loadLanguages(); } /** @@ -46,6 +44,21 @@ public class MVCommandManager extends PaperCommandManager { return flagsManager; } + /** + * Gets class responsible for locale handling. + * + * @return A not-null {@link PluginLocales}. + */ + @Override + public PluginLocales getLocales() { + if (this.pluginLocales == null) { + this.pluginLocales = new PluginLocales(this); + this.locales = pluginLocales; // For parent class + this.pluginLocales.loadLanguages(); + } + return this.pluginLocales; + } + /** * Manager for command that requires /mv confirm before execution. * @@ -83,4 +96,18 @@ public class MVCommandManager extends PaperCommandManager { } return this.completions; } + + /** + * Standardise usage command formatting for all mv modules. + * + * @param help The target {@link CommandHelp}. + */ + public void showUsage(@NotNull CommandHelp help) { + List entries = help.getHelpEntries(); + if (entries.size() == 1) { + this.plugin.getMVCommandManager().getHelpFormatter().showDetailedHelp(help, entries.get(0)); + return; + } + help.showHelp(); + } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/commandtools/PluginLocales.java b/src/main/java/com/onarandombox/MultiverseCore/commandtools/PluginLocales.java new file mode 100644 index 00000000..66c0f8c1 --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/commandtools/PluginLocales.java @@ -0,0 +1,45 @@ +package com.onarandombox.MultiverseCore.commandtools; + +import co.aikar.commands.BukkitCommandManager; +import co.aikar.commands.BukkitLocales; +import com.onarandombox.MultiverseCore.utils.file.FileResClassLoader; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +/** + * Locale manager with additional methods for loading locales from plugin's locales folder. + */ +public class PluginLocales extends BukkitLocales { + + private static final String DEFAULT_LOCALE_FOLDER_PATH = "locales"; + + /** + * Creates a new instance of {@link PluginLocales}. + * + * @param manager The command manager. + */ + public PluginLocales(BukkitCommandManager manager) { + super(manager); + } + + /** + * Adds a {@link FileResClassLoader} to the list of class loaders to load locales data from. + * + * @param plugin The plugin. + * @return True if the class loader was added successfully. + */ + public boolean addFileResClassLoader(@NotNull Plugin plugin) { + return this.addBundleClassLoader(new FileResClassLoader(plugin, DEFAULT_LOCALE_FOLDER_PATH)); + } + + /** + * Adds a {@link FileResClassLoader} to the list of class loaders to load locales data from. + * + * @param plugin The plugin. + * @param localesFolderPath The path to the folder containing the locales. + * @return True if the class loader was added successfully. + */ + public boolean addFileResClassLoader(@NotNull Plugin plugin, @NotNull String localesFolderPath) { + return this.addBundleClassLoader(new FileResClassLoader(plugin, localesFolderPath)); + } +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/locale/MVCorei18n.java b/src/main/java/com/onarandombox/MultiverseCore/locale/MVCorei18n.java deleted file mode 100644 index dab78959..00000000 --- a/src/main/java/com/onarandombox/MultiverseCore/locale/MVCorei18n.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.onarandombox.MultiverseCore.locale; - -import co.aikar.locales.MessageKey; -import co.aikar.locales.MessageKeyProvider; - -public enum MVCorei18n implements MessageKeyProvider { - CONFIG_SAVE_FAILED, - - CREATE_PROPERTIES, - CREATE_PROPERTIES_ENVIRONMENT, - CREATE_PROPERTIES_SEED, - CREATE_PROPERTIES_WORLDTYPE, - CREATE_PROPERTIES_ADJUSTSPAWN, - CREATE_PROPERTIES_GENERATOR, - CREATE_PROPERTIES_STRUCTURES, - CREATE_LOADING, - CREATE_FAILED, - CREATE_SUCCESS, - - DEBUG_INFO_OFF, - DEBUG_INFO_ON; - - private final MessageKey key = MessageKey.of("mv-core." + this.name().replace('_', '.').toLowerCase()); - - @Override - public MessageKey getMessageKey() { - return this.key; - } -} diff --git a/src/main/java/com/onarandombox/MultiverseCore/locale/package-info.java b/src/main/java/com/onarandombox/MultiverseCore/locale/package-info.java deleted file mode 100644 index dd0e53cb..00000000 --- a/src/main/java/com/onarandombox/MultiverseCore/locale/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * This package contains all the locale reference for Multiverse-Core. - */ -package com.onarandombox.MultiverseCore.locale; diff --git a/src/main/java/com/onarandombox/MultiverseCore/placeholders/MultiverseCorePlaceholders.java b/src/main/java/com/onarandombox/MultiverseCore/placeholders/MultiverseCorePlaceholders.java new file mode 100644 index 00000000..d768442e --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/placeholders/MultiverseCorePlaceholders.java @@ -0,0 +1,155 @@ +package com.onarandombox.MultiverseCore.placeholders; + +import java.util.Optional; + +import com.onarandombox.MultiverseCore.MultiverseCore; +import com.onarandombox.MultiverseCore.api.MVWorld; +import com.onarandombox.MultiverseCore.api.MVWorldManager; +import com.onarandombox.MultiverseCore.economy.MVEconomist; +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class MultiverseCorePlaceholders extends PlaceholderExpansion { + + private final MultiverseCore plugin; + private final MVWorldManager worldManager; + private final MVEconomist economist; + + public MultiverseCorePlaceholders(MultiverseCore plugin) { + this.plugin = plugin; + this.worldManager = plugin.getMVWorldManager(); + this.economist = plugin.getEconomist(); + } + + @Override + public @NotNull String getIdentifier() { + return "multiverse-core"; + } + + @Override + public @NotNull String getAuthor() { + return plugin.getAuthors(); + } + + @Override + public @NotNull String getVersion() { + return plugin.getDescription().getVersion(); + } + + @Override + public boolean persist() { + return true; + } + + /** + * Placeholder implementation, format: %multiverse-core_<placeholder>_[world]% world is optional. + * + * @param offlinePlayer Player to get the placeholder for + * @param params Placeholder to get + * @return Placeholder value + */ + @Override + public @Nullable String onRequest(OfflinePlayer offlinePlayer, @NotNull String params) { + // Split string in to an Array with underscores + String[] paramsArray = params.split("_", 2); + + // No placeholder defined + if (paramsArray.length < 1) { + warning("No placeholder defined"); + return null; + } + + final var placeholder = paramsArray[0]; + Optional targetWorld; + + // If no world is defined, use the player's world + if (paramsArray.length == 1) { + if (!offlinePlayer.isOnline()) { + return null; + } + targetWorld = Optional.ofNullable(worldManager.getMVWorld(((Player)offlinePlayer).getWorld())); + } else { + targetWorld = Optional.ofNullable(worldManager.getMVWorld(paramsArray[1])); + } + + // Fail if world is null + return targetWorld.map(world -> getWorldPlaceHolderValue(placeholder, world)) + .orElse(null); + } + + private @Nullable String getWorldPlaceHolderValue(@NotNull String placeholder, @NotNull MVWorld world) { + // Switch to find what specific placeholder we want + switch (placeholder.toLowerCase()) { + case "alias" -> { + return world.getColoredWorldString(); + } + case "animalspawn" -> { + return String.valueOf(world.canAnimalsSpawn()); + } + case "autoheal" -> { + return String.valueOf(world.getAutoHeal()); + } + case "blacklist" -> { + return String.join(", ", world.getWorldBlacklist()); + } + case "currency" -> { + return String.valueOf(world.getCurrency()); + } + case "difficulty" -> { + return world.getDifficulty().toString(); + } + case "entryfee" -> { + return economist.formatPrice(world.getPrice(), world.getCurrency()); + } + case "environment" -> { + return world.getEnvironment().toString().toLowerCase(); + } + case "flight" -> { + return String.valueOf(world.getAllowFlight()); + } + case "gamemode" -> { + return world.getGameMode().toString().toLowerCase(); + } + case "generator" -> { + return world.getGenerator(); + } + case "hunger" -> { + return String.valueOf(world.getHunger()); + } + case "monstersspawn" -> { + return String.valueOf(world.canMonstersSpawn()); + } + case "name" -> { + return world.getName(); + } + case "playerlimit" -> { + return String.valueOf(world.getPlayerLimit()); + } + case "price" -> { + return String.valueOf(world.getPrice()); + } + case "pvp" -> { + return String.valueOf(world.isPVPEnabled()); + } + case "seed" -> { + return String.valueOf(world.getSeed()); + } + case "time" -> { + return world.getTime(); + } + case "type" -> { + return world.getWorldType().toString().toLowerCase(); + } + case "weather" -> { + return String.valueOf(world.isWeatherEnabled()); + } + default -> { + warning("Unknown placeholder: " + placeholder); + return null; + } + } + } +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/MVCorei18n.java b/src/main/java/com/onarandombox/MultiverseCore/utils/MVCorei18n.java new file mode 100644 index 00000000..1dc79b9a --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/MVCorei18n.java @@ -0,0 +1,87 @@ +package com.onarandombox.MultiverseCore.utils; + +import co.aikar.locales.MessageKey; +import co.aikar.locales.MessageKeyProvider; + +public enum MVCorei18n implements MessageKeyProvider { + // config status + CONFIG_SAVE_FAILED, + + // check command + CHECK_CHECKING, + + // clone command + CLONE_CLONING, + CLONE_FAILED, + CLONE_SUCCESS, + + // create command + CREATE_PROPERTIES, + CREATE_PROPERTIES_ENVIRONMENT, + CREATE_PROPERTIES_SEED, + CREATE_PROPERTIES_WORLDTYPE, + CREATE_PROPERTIES_ADJUSTSPAWN, + CREATE_PROPERTIES_GENERATOR, + CREATE_PROPERTIES_STRUCTURES, + CREATE_LOADING, + CREATE_FAILED, + CREATE_SUCCESS, + + // delete command + DELETE_DELETING, + DELETE_FAILED, + DELETE_SUCCESS, + DELETE_PROMPT, + + // gamerule command + GAMERULE_FAILED, + GAMERULE_SUCCESS_SINGLE, + GAMERULE_SUCCESS_MULTIPLE, + + // import command + IMPORT_IMPORTING, + IMPORT_FAILED, + IMPORT_SUCCESS, + + // load command + LOAD_LOADING, + LOAD_FAILED, + LOAD_SUCCESS, + + // regen command + REGEN_REGENERATING, + REGEN_FAILED, + REGEN_SUCCESS, + REGEN_PROMPT, + + // reload command + RELOAD_RELOADING, + RELOAD_SUCCESS, + + // remove command + REMOVE_FAILED, + REMOVE_SUCCESS, + + // root MV command + ROOT_TITLE, + ROOT_HELP, + + // teleport command + TELEPORT_SUCCESS, + + // unload command + UNLOAD_UNLOADING, + UNLOAD_FAILURE, + UNLOAD_SUCCESS, + + // debug command + DEBUG_INFO_OFF, + DEBUG_INFO_ON; + + private final MessageKey key = MessageKey.of("mv-core." + this.name().replace('_', '.').toLowerCase()); + + @Override + public MessageKey getMessageKey() { + return this.key; + } +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/file/FileResClassLoader.java b/src/main/java/com/onarandombox/MultiverseCore/utils/file/FileResClassLoader.java new file mode 100644 index 00000000..3342841e --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/file/FileResClassLoader.java @@ -0,0 +1,59 @@ +package com.onarandombox.MultiverseCore.utils.file; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; + +import org.bukkit.plugin.Plugin; + +/** + * A class loader that loads resources from the plugin's locales folder. + */ +public class FileResClassLoader extends ClassLoader { + + private final transient File targetFolder; + + /** + * Creates a new FileResClassLoader. + * + * @param plugin The plugin to load resources from. + * @param subFolder The subfolder to load resources from. + */ + public FileResClassLoader(final Plugin plugin, final String subFolder) { + super(plugin.getClass().getClassLoader()); + this.targetFolder = new File(plugin.getDataFolder(), subFolder); + } + + /** + * {@inheritDoc} + */ + @Override + public URL getResource(final String string) { + final File file = new File(targetFolder, string); + if (file.exists()) { + try { + return file.toURI().toURL(); + } catch (final MalformedURLException ignored) { + } + } + return null; + } + + /** + * {@inheritDoc} + */ + @Override + public InputStream getResourceAsStream(final String string) { + final File file = new File(targetFolder, string); + if (file.exists()) { + try { + return new FileInputStream(file); + } catch (final FileNotFoundException ignored) { + } + } + return null; + } +} diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/FileUtils.java b/src/main/java/com/onarandombox/MultiverseCore/utils/file/FileUtils.java similarity index 98% rename from src/main/java/com/onarandombox/MultiverseCore/utils/FileUtils.java rename to src/main/java/com/onarandombox/MultiverseCore/utils/file/FileUtils.java index 571143bb..b62384fb 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/utils/FileUtils.java +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/file/FileUtils.java @@ -5,7 +5,7 @@ * with this project. * ******************************************************************************/ -package com.onarandombox.MultiverseCore.utils; +package com.onarandombox.MultiverseCore.utils.file; import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES; diff --git a/src/main/java/com/onarandombox/MultiverseCore/utils/file/package-info.java b/src/main/java/com/onarandombox/MultiverseCore/utils/file/package-info.java new file mode 100644 index 00000000..f74ce7d4 --- /dev/null +++ b/src/main/java/com/onarandombox/MultiverseCore/utils/file/package-info.java @@ -0,0 +1,4 @@ +/** + * This package contains all the classes that deal with files on disk. + */ +package com.onarandombox.MultiverseCore.utils.file; \ No newline at end of file diff --git a/src/main/java/com/onarandombox/MultiverseCore/world/SimpleMVWorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/world/SimpleMVWorldManager.java index 27a79b8b..188d44d5 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/world/SimpleMVWorldManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/world/SimpleMVWorldManager.java @@ -31,7 +31,7 @@ import com.onarandombox.MultiverseCore.api.MVWorld; import com.onarandombox.MultiverseCore.api.SafeTTeleporter; import com.onarandombox.MultiverseCore.api.WorldPurger; import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent; -import com.onarandombox.MultiverseCore.utils.FileUtils; +import com.onarandombox.MultiverseCore.utils.file.FileUtils; import org.bukkit.Bukkit; import org.bukkit.GameRule; import org.bukkit.Location; diff --git a/src/main/resources/multiverse-core_en.properties b/src/main/resources/multiverse-core_en.properties index dc28fe11..0cd452ea 100644 --- a/src/main/resources/multiverse-core_en.properties +++ b/src/main/resources/multiverse-core_en.properties @@ -1,23 +1,116 @@ -mv-core.config.save.failed=§cUnable to save Multiverse-Core config.yml. Your changes will be temporary! +# configuration +mv-core.config.save.failed=Unable to save Multiverse-Core config.yml. Your changes will be temporary! +# /mv check +mv-core.check.description=Checks if a player can teleport to a destination. +mv-core.check.player.description=Player to check destination on. +mv-core.check.destination.description=A destination location, e.g. a world name. +mv-core.check.checking=Checking {player} to {destination} .. + +# /mv clone +mv-core.clone.description=Clones a world. +mv-core.clone.world.description=The target world to clone. +mv-core.clone.newWorld.description=The new cloned world name. +mv-core.clone.cloning=Cloning world '{world}' to '{newworld}'... +mv-core.clone.failed=World could not be cloned! &fSee console for more details. +mv-core.clone.success=Cloned world '{world}'! + +# /mv confirm +mv-core.confirm.description=Confirms dangerous commands before executing them. + +# /mv create mv-core.create.description=Creates a new world and loads it. mv-core.create.name.description=New world name. mv-core.create.environment.description=The world's environment. See: /mv environments -mv-core.create.flags.description=Additional world settings. See http://gg.gg/nn8bl for all possible flags. +mv-core.create.flags.description=Additional world settings. See https://gg.gg/nn8bl for all possible flags. mv-core.create.properties=Creating world {worldName} with the following properties: -mv-core.create.properties.environment=- Environment: {environment} -mv-core.create.properties.seed=- Seed: {seed} -mv-core.create.properties.worldtype=- World Type: {worldType} -mv-core.create.properties.adjustspawn=- Adjust Spawn: {adjustSpawn} -mv-core.create.properties.generator=- Generator: {generator} -mv-core.create.properties.structures=- Structures: {structures} +mv-core.create.properties.environment=- Environment: &f{environment} +mv-core.create.properties.seed=- Seed: &f{seed} +mv-core.create.properties.worldtype=- World Type: &f{worldType} +mv-core.create.properties.adjustspawn=- Adjust Spawn: &f{adjustSpawn} +mv-core.create.properties.generator=- Generator: &f{generator} +mv-core.create.properties.structures=- Structures: &f{structures} mv-core.create.loading=Creating world... -mv-core.create.failed=§cFailed to create world '{worldName}'! See console for details. -mv-core.create.success=§aWorld '{worldName}' created successfully! +mv-core.create.failed=Failed to create world '{worldName}'! &fSee console for details. +mv-core.create.success=&aWorld '{worldName}' created successfully! +# /mv debug mv-core.debug.info.description=Show the current debug level. -mv-core.debug.info.off=§fMultiverse Debug mode is §cOFF§f. -mv-core.debug.info.on=§fMultiverse Debug mode is at §alevel {level}§f. +mv-core.debug.info.off=&fMultiverse Debug mode is &cOFF&f. +mv-core.debug.info.on=&fMultiverse Debug mode is at &alevel {level}&f. mv-core.debug.change.description=Change debug level. mv-core.debug.change.syntax=level mv-core.debug.change.level.description=Debug level to set to. + +# /mv delete +mv-core.delete.description=Deletes a world on your server PERMANENTLY. +mv-core.delete.deleting=Deleting world '{world}'... +mv-core.delete.failed=There was an issue deleting '{world}'! &fPlease check console for errors. +mv-core.delete.success=&aWorld {world} was deleted! +mv-core.delete.prompt=Are you sure you want to delete world '{world}'? + +# /mv gamerule +mv-core.gamerule.description=Changes a gamerule in one or more worlds +mv-core.gamerule.gamerule.description=Gamerule to set +mv-core.gamerule.value.description=Value of gamerule +mv-core.gamerule.world.description=World to apply gamerule to, current world by default +mv-core.gamerule.failed=Failed to set gamerule {gamerule} to {value} in {world}. &fIt should be a {type}. +mv-core.gamerule.success.single=&aSuccessfully set {gamerule} to {value} in {world}. +mv-core.gamerule.success.multiple=&aSuccessfully set {gamerule} to {value} in {count} worlds. + +# /mv import +mv-core.import.description=Imports an existing world folder. +mv-core.import.name.description=Name of the world folder. +mv-core.import.env.description=The world's environment. See: /mv env +mv-core.import.other.description=Other world settings. See: https://gg.gg/nn8c2 +mv-core.import.importing=Starting import of world '{world}'... +mv-core.import.failed=Failed! &fSee console for more details. +mv-core.import.success=&aComplete! + +# /mv load +mv-core.load.description=Loads a world. World must be already in worlds.yml, else please use /mv import. +mv-core.load.world.description=Name of world you want to load. +mv-core.load.loading=Loading world '{world}'... +mv-core.load.failed=Error trying to load world '{world}'! +mv-core.load.success=&aLoaded world '{world}'! + +# /mv regen +mv-core.regen.description=Regenerates a world on your server. The previous state will be lost PERMANENTLY. +mv-core.regen.world.description=World that you want to regen. +mv-core.regen.other.description=Other world settings. See: http://gg.gg/nn8lk +mv-core.regen.regenerating=Regenerating world '{world}'... +mv-core.regen.failed=There was an issue regenerating '{world}'! &fPlease check console for errors. +mv-core.regen.success=&aWorld {world} was regenerated! +mv-core.regen.prompt=Are you sure you want to regenerate world '{world}'? + +# /mv reload +mv-core.reload.description=Reloads config files for all Multiverse modules. +mv-core.reload.reloading=&6Reloading all Multiverse Plugin configs... +mv-core.reload.success=&aReload complete! + +# /mv remove +mv-core.remove.description=Unloads a world from Multiverse and removes it from worlds.yml. This does NOT delete the world folder. +mv-core.remove.world.description=World you want to remove from MV's knowledge. +mv-core.remove.failed=Error trying to remove world from config! +mv-core.remove.success=&aWorld '{world}' is removed from config! + +# /mv +mv-core.root.title=&a{name} version {version} +mv-core.root.help=&aSee &f/mv help&a for commands available. + +# /mv tp +mv-core.teleport.description=Allows you to teleport to a location on your server! +mv-core.teleport.player.description=Target player to teleport. +mv-core.teleport.destination.description=Location, can be a world name. +mv-core.teleport.success=Teleporting {player} to {destination}... + +# /mv unload +mv-core.unload.description=Unloads a world from Multiverse. This does NOT remove the world folder. This does NOT remove it from the config file. +mv-core.unload.world.description=Name of the world you want to unload. +mv-core.unload.unloading=Unloading world '{world}'... +mv-core.unload.failure=Error unloading world '{world}'! &fSee console for more details. +mv-core.unload.success=&aUnloaded world '{world}'! + +# /mv usage +mv-core.usage.description=Show Multiverse-Core command usage. + diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index e0fac966..0681cc4c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -2,6 +2,6 @@ name: Multiverse-Core main: com.onarandombox.MultiverseCore.MultiverseCore authors: ['dumptruckman', 'Rigby', 'fernferret', 'lithium3141', 'main--'] website: 'https://dev.bukkit.org/projects/multiverse-core' -softdepend: ['Vault'] +softdepend: ['Vault', 'PlaceholderAPI'] api-version: 1.13 version: ${version} diff --git a/src/test/java/com/onarandombox/MultiverseCore/TestDebugMode.java b/src/old-test/java/com/onarandombox/MultiverseCore/TestDebugMode.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/TestDebugMode.java rename to src/old-test/java/com/onarandombox/MultiverseCore/TestDebugMode.java diff --git a/src/test/java/com/onarandombox/MultiverseCore/TestEntitySpawnRules.java b/src/old-test/java/com/onarandombox/MultiverseCore/TestEntitySpawnRules.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/TestEntitySpawnRules.java rename to src/old-test/java/com/onarandombox/MultiverseCore/TestEntitySpawnRules.java diff --git a/src/test/java/com/onarandombox/MultiverseCore/TestEntryFeeConversion.java b/src/old-test/java/com/onarandombox/MultiverseCore/TestEntryFeeConversion.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/TestEntryFeeConversion.java rename to src/old-test/java/com/onarandombox/MultiverseCore/TestEntryFeeConversion.java diff --git a/src/test/java/com/onarandombox/MultiverseCore/TestModifyCommand.java b/src/old-test/java/com/onarandombox/MultiverseCore/TestModifyCommand.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/TestModifyCommand.java rename to src/old-test/java/com/onarandombox/MultiverseCore/TestModifyCommand.java diff --git a/src/test/java/com/onarandombox/MultiverseCore/TestWorldProperties.java b/src/old-test/java/com/onarandombox/MultiverseCore/TestWorldProperties.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/TestWorldProperties.java rename to src/old-test/java/com/onarandombox/MultiverseCore/TestWorldProperties.java diff --git a/src/test/java/com/onarandombox/MultiverseCore/TestWorldPurger.java b/src/old-test/java/com/onarandombox/MultiverseCore/TestWorldPurger.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/TestWorldPurger.java rename to src/old-test/java/com/onarandombox/MultiverseCore/TestWorldPurger.java diff --git a/src/test/java/com/onarandombox/MultiverseCore/TestWorldStuff.java b/src/old-test/java/com/onarandombox/MultiverseCore/TestWorldStuff.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/TestWorldStuff.java rename to src/old-test/java/com/onarandombox/MultiverseCore/TestWorldStuff.java diff --git a/src/test/java/com/onarandombox/MultiverseCore/utils/FileUtilsTest.java b/src/old-test/java/com/onarandombox/MultiverseCore/utils/FileUtilsTest.java similarity index 98% rename from src/test/java/com/onarandombox/MultiverseCore/utils/FileUtilsTest.java rename to src/old-test/java/com/onarandombox/MultiverseCore/utils/FileUtilsTest.java index 5dfb87f7..84e705ae 100644 --- a/src/test/java/com/onarandombox/MultiverseCore/utils/FileUtilsTest.java +++ b/src/old-test/java/com/onarandombox/MultiverseCore/utils/FileUtilsTest.java @@ -1,5 +1,6 @@ package com.onarandombox.MultiverseCore.utils; +import com.onarandombox.MultiverseCore.utils.file.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; diff --git a/src/test/java/com/onarandombox/MultiverseCore/utils/MVTestLogFormatter.java b/src/old-test/java/com/onarandombox/MultiverseCore/utils/MVTestLogFormatter.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/utils/MVTestLogFormatter.java rename to src/old-test/java/com/onarandombox/MultiverseCore/utils/MVTestLogFormatter.java diff --git a/src/test/java/com/onarandombox/MultiverseCore/utils/MockWorldFactory.java b/src/old-test/java/com/onarandombox/MultiverseCore/utils/MockWorldFactory.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/utils/MockWorldFactory.java rename to src/old-test/java/com/onarandombox/MultiverseCore/utils/MockWorldFactory.java diff --git a/src/test/java/com/onarandombox/MultiverseCore/utils/TestInstanceCreator.java b/src/old-test/java/com/onarandombox/MultiverseCore/utils/TestInstanceCreator.java similarity index 99% rename from src/test/java/com/onarandombox/MultiverseCore/utils/TestInstanceCreator.java rename to src/old-test/java/com/onarandombox/MultiverseCore/utils/TestInstanceCreator.java index 2ad96240..07e63562 100644 --- a/src/test/java/com/onarandombox/MultiverseCore/utils/TestInstanceCreator.java +++ b/src/old-test/java/com/onarandombox/MultiverseCore/utils/TestInstanceCreator.java @@ -20,6 +20,7 @@ import com.onarandombox.MultiverseCore.api.MVWorld; import com.onarandombox.MultiverseCore.listeners.MVEntityListener; import com.onarandombox.MultiverseCore.listeners.MVPlayerListener; import com.onarandombox.MultiverseCore.listeners.MVWeatherListener; +import com.onarandombox.MultiverseCore.utils.file.FileUtils; import com.onarandombox.MultiverseCore.world.SimpleMVWorldManager; import junit.framework.Assert; import org.bukkit.Bukkit; diff --git a/src/test/java/com/onarandombox/MultiverseCore/utils/Util.java b/src/old-test/java/com/onarandombox/MultiverseCore/utils/Util.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/utils/Util.java rename to src/old-test/java/com/onarandombox/MultiverseCore/utils/Util.java diff --git a/src/test/java/com/onarandombox/MultiverseCore/utils/WorldCreatorMatcher.java b/src/old-test/java/com/onarandombox/MultiverseCore/utils/WorldCreatorMatcher.java similarity index 100% rename from src/test/java/com/onarandombox/MultiverseCore/utils/WorldCreatorMatcher.java rename to src/old-test/java/com/onarandombox/MultiverseCore/utils/WorldCreatorMatcher.java diff --git a/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker b/src/old-test/resources/mockito-extensions/org.mockito.plugins.MockMaker similarity index 100% rename from src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker rename to src/old-test/resources/mockito-extensions/org.mockito.plugins.MockMaker diff --git a/src/test/java/org/mvplugins/multiverse/core/MockBukkitTest.kt b/src/test/java/org/mvplugins/multiverse/core/MockBukkitTest.kt new file mode 100644 index 00000000..894125bf --- /dev/null +++ b/src/test/java/org/mvplugins/multiverse/core/MockBukkitTest.kt @@ -0,0 +1,33 @@ +package org.mvplugins.multiverse.core + +import be.seeseemelk.mockbukkit.MockBukkit +import be.seeseemelk.mockbukkit.ServerMock +import com.onarandombox.MultiverseCore.MultiverseCore +import com.onarandombox.MultiverseCore.utils.TestingMode +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertNotNull + +class MockBukkitTest { + + lateinit var server: ServerMock + lateinit var plugin: MultiverseCore + + @BeforeTest + fun setUp() { + TestingMode.enable() + server = MockBukkit.mock() + plugin = MockBukkit.load(MultiverseCore::class.java) + } + + @AfterTest + fun tearDown() { + MockBukkit.unmock() + } + + @Test + fun `MockBukkit loads the plugin`() { + assertNotNull(plugin) + } +}