From 95c3b034ec429b3cb3f72295cafb5355b6e08a34 Mon Sep 17 00:00:00 2001 From: Zax71 <67716263+zax71@users.noreply.github.com> Date: Thu, 16 Mar 2023 12:18:36 +0000 Subject: [PATCH] feat: Add PlaceholderAPI Support (#2888) * feat:Add PlaceholderAPI Support Signed-off-by: zax71 * Implement requested changes Signed-off-by: zax71 * Add separate world functionality and half-baked i18n support. Signed-off-by: zax71 * refactor: Simplify papi world parsing * Fix spelling and remove unused i18n. Signed-off-by: zax71 * chore: Add warnings * chore: Remove unused imports * chore: Setup papi before log enable message --------- Signed-off-by: zax71 Co-authored-by: Ben Woo <30431861+benwoo1110@users.noreply.github.com> --- build.gradle | 7 + .../MultiverseCore/MultiverseCore.java | 9 +- .../MultiverseCorePlaceholders.java | 155 ++++++++++++++++++ .../resources/multiverse-core_en.properties | 1 + src/main/resources/plugin.yml | 2 +- 5 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/onarandombox/MultiverseCore/placeholders/MultiverseCorePlaceholders.java diff --git a/build.gradle b/build.gradle index 98d22ad0..15426427 100644 --- a/build.gradle +++ b/build.gradle @@ -55,6 +55,10 @@ repositories { name = 'glaremasters repo' url = 'https://repo.glaremasters.me/repository/towny/' } + maven { + name = 'PlaceholderAPI' + url = 'https://repo.extendedclip.com/content/repositories/placeholderapi/' + } } configurations { @@ -70,6 +74,9 @@ dependencies { 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' diff --git a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java index c03ecde5..8bf9e604 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java +++ b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java @@ -41,7 +41,6 @@ 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.commands.UsageCommand; import com.onarandombox.MultiverseCore.commandtools.MVCommandManager; import com.onarandombox.MultiverseCore.destination.DestinationsProvider; import com.onarandombox.MultiverseCore.destination.core.AnchorDestination; @@ -59,6 +58,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; @@ -169,6 +169,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore { this.setUpLocales(); this.registerDestinations(); this.setupMetrics(); + this.setupPlaceholderAPI(); this.saveMVConfig(); this.logEnableMessage(); } @@ -262,6 +263,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/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/resources/multiverse-core_en.properties b/src/main/resources/multiverse-core_en.properties index 483e4070..0cd452ea 100644 --- a/src/main/resources/multiverse-core_en.properties +++ b/src/main/resources/multiverse-core_en.properties @@ -113,3 +113,4 @@ 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}