Format to Daddy code style

This commit is contained in:
extendedclip 2020-07-31 22:52:07 -04:00
parent cee6984818
commit dcc8dad4ea
60 changed files with 3481 additions and 3835 deletions

View File

@ -10,43 +10,43 @@ on:
# Only trigger when the push changes any files in the wiki-folder. # Only trigger when the push changes any files in the wiki-folder.
# #
paths: paths:
- 'wiki/**' - 'wiki/**'
branches: branches:
- 'docs/wiki' - 'docs/wiki'
# #
# Releases cause this action to also fire. # Releases cause this action to also fire.
# Using this prevents this problem. # Using this prevents this problem.
# #
tags-ignore: tags-ignore:
- '**' - '**'
jobs: jobs:
update: update:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: 'Checkout Code' - name: 'Checkout Code'
uses: actions/Checkout@v2 uses: actions/Checkout@v2
- name: 'Update Wiki' - name: 'Update Wiki'
uses: docker://decathlon/wiki-page-creator-action:latest uses: docker://decathlon/wiki-page-creator-action:latest
env: env:
# #
# We can use the E-Mail and Name of the GitHub Actions account # We can use the E-Mail and Name of the GitHub Actions account
# for our convenience. # for our convenience.
# #
ACTION_MAIL: 'actions@github.com' ACTION_MAIL: 'actions@github.com'
ACTION_NAME: 'github-actions[bot]' ACTION_NAME: 'github-actions[bot]'
# #
# We (sadly) have to use a PAT (Personal Access Token) for this action. # We (sadly) have to use a PAT (Personal Access Token) for this action.
# #
GH_PAT: '${{ secrets.WORKFLOWPAT }}' GH_PAT: '${{ secrets.WORKFLOWPAT }}'
OWNER: 'PlaceholderAPI' OWNER: 'PlaceholderAPI'
REPO_NAME: 'PlaceholderAPI' REPO_NAME: 'PlaceholderAPI'
# #
# We only want to target files in the wiki folder # We only want to target files in the wiki folder
# #
MD_FOLDER: 'wiki' MD_FOLDER: 'wiki'
WIKI_PUSH_MESSAGE: '${{ github.event.commits[0].message }}' WIKI_PUSH_MESSAGE: '${{ github.event.commits[0].message }}'
# #
# We skip/ignore the README.md file in the Wiki folder # We skip/ignore the README.md file in the Wiki folder
# #
SKIP_MD: README.md SKIP_MD: README.md

View File

@ -1,8 +1,8 @@
plugins { plugins {
id "java" id "java"
id "maven-publish" id "maven-publish"
id "net.minecrell.licenser" version "0.4.1" id "net.minecrell.licenser" version "0.4.1"
id "com.github.johnrengelman.shadow" version "6.0.0" id "com.github.johnrengelman.shadow" version "6.0.0"
} }
group "me.clip" group "me.clip"
@ -11,99 +11,99 @@ version "2.10.8-DEV-${System.getProperty("BUILD_NUMBER")}"
description "An awesome placeholder provider!" description "An awesome placeholder provider!"
repositories { repositories {
mavenCentral() mavenCentral()
maven({ url = "https://repo.codemc.org/repository/maven-public" }) maven({ url = "https://repo.codemc.org/repository/maven-public" })
maven({ url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" }) maven({ url = "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" })
} }
dependencies { dependencies {
implementation "com.google.code.gson:gson:2.8.6" implementation "com.google.code.gson:gson:2.8.6"
implementation "org.bstats:bstats-bukkit:1.5" implementation "org.bstats:bstats-bukkit:1.5"
compileOnly "org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT" compileOnly "org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT"
compileOnly "org.jetbrains:annotations:19.0.0" compileOnly "org.jetbrains:annotations:19.0.0"
testImplementation "org.openjdk.jmh:jmh-core:1.23" testImplementation "org.openjdk.jmh:jmh-core:1.23"
testImplementation "org.openjdk.jmh:jmh-generator-annprocess:1.23" testImplementation "org.openjdk.jmh:jmh-generator-annprocess:1.23"
testCompile "org.junit.jupiter:junit-jupiter-engine:5.6.2" testCompile "org.junit.jupiter:junit-jupiter-engine:5.6.2"
testRuntime "org.junit.jupiter:junit-jupiter-engine:5.6.2" testRuntime "org.junit.jupiter:junit-jupiter-engine:5.6.2"
} }
processResources { processResources {
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [name: rootProject.name, version: project.version.toString(), description: project.description] filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [name: rootProject.name, version: project.version.toString(), description: project.description]
} }
} }
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
options.encoding = "UTF-8" options.encoding = "UTF-8"
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8
} }
shadowJar { shadowJar {
archiveClassifier.set("") archiveClassifier.set("")
relocate "org.bstats", "me.clip.placeholderapi.metrics" relocate "org.bstats", "me.clip.placeholderapi.metrics"
relocate "com.google.gson", "me.clip.placeholderapi.libs.gson" relocate "com.google.gson", "me.clip.placeholderapi.libs.gson"
} }
license { license {
include '**/*.java' include '**/*.java'
matching('**/*.java') { matching('**/*.java') {
header = file('headers/main.txt') header = file('headers/main.txt')
} }
matching('**/JSONMessage.java') { matching('**/JSONMessage.java') {
header = file('headers/jsonmessage.txt') header = file('headers/jsonmessage.txt')
} }
ext { ext {
year = 2020 year = 2020
} }
} }
test { test {
useJUnitPlatform() useJUnitPlatform()
} }
sourceSets { sourceSets {
test.compileClasspath += configurations.compileOnly test.compileClasspath += configurations.compileOnly
test.runtimeClasspath += configurations.compileOnly test.runtimeClasspath += configurations.compileOnly
} }
publishing { publishing {
repositories { repositories {
maven { maven {
if (version.contains("-DEV-")) { if (version.contains("-DEV-")) {
url = uri("https://repo.extendedclip.com/content/repositories/dev/") url = uri("https://repo.extendedclip.com/content/repositories/dev/")
} else { } else {
url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/") url = uri("https://repo.extendedclip.com/content/repositories/placeholderapi/")
} }
credentials { credentials {
username = System.getenv("JENKINS_USER") username = System.getenv("JENKINS_USER")
password = System.getenv("JENKINS_PASS") password = System.getenv("JENKINS_PASS")
} }
} }
} }
publications {
mavenJava(MavenPublication) {
artifactId = "placeholderapi"
from components.java publications {
mavenJava(MavenPublication) {
artifactId = "placeholderapi"
pom.withXml { from components.java
asNode().appendNode("packaging", "jar")
asNode().remove(asNode().get("dependencies")) pom.withXml {
} asNode().appendNode("packaging", "jar")
} asNode().remove(asNode().get("dependencies"))
} }
}
}
} }
publish.dependsOn clean, test, jar publish.dependsOn clean, test, jar

View File

@ -220,16 +220,15 @@ public final class PlaceholderAPI {
* *
* @return Map of registered placeholders * @return Map of registered placeholders
* @deprecated Use {@link me.clip.placeholderapi.PlaceholderAPIPlugin().getLocalExpansionManager() * @deprecated Use {@link me.clip.placeholderapi.PlaceholderAPIPlugin().getLocalExpansionManager()
* .getExpansions()} instead. * .getExpansions()} instead.
*/ */
@NotNull @NotNull
@Deprecated @Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0") @ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
public static Map<String, PlaceholderHook> getPlaceholders() public static Map<String, PlaceholderHook> getPlaceholders() {
{
return PlaceholderAPIPlugin.getInstance().getLocalExpansionManager() return PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()
.getExpansions().stream() .getExpansions().stream()
.collect(Collectors.toMap(PlaceholderExpansion::getIdentifier, ex -> ex)); .collect(Collectors.toMap(PlaceholderExpansion::getIdentifier, ex -> ex));
} }
/** /**

View File

@ -20,6 +20,10 @@
package me.clip.placeholderapi; package me.clip.placeholderapi;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import me.clip.placeholderapi.commands.PlaceholderCommandRouter; import me.clip.placeholderapi.commands.PlaceholderCommandRouter;
import me.clip.placeholderapi.configuration.PlaceholderAPIConfig; import me.clip.placeholderapi.configuration.PlaceholderAPIConfig;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
@ -36,243 +40,200 @@ import org.bukkit.event.HandlerList;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
/** /**
* Yes I have a shit load of work to do... * Yes I have a shit load of work to do...
* *
* @author Ryan McCarthy * @author Ryan McCarthy
*/ */
public final class PlaceholderAPIPlugin extends JavaPlugin public final class PlaceholderAPIPlugin extends JavaPlugin {
{
@NotNull @NotNull
private static final Version VERSION; private static final Version VERSION;
private static PlaceholderAPIPlugin instance;
static static {
{ final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
final String version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3];
boolean isSpigot; boolean isSpigot;
try try {
{ Class.forName("org.spigotmc.SpigotConfig");
Class.forName("org.spigotmc.SpigotConfig"); isSpigot = true;
isSpigot = true; } catch (final ExceptionInInitializerError | ClassNotFoundException ignored) {
} isSpigot = false;
catch (final ExceptionInInitializerError | ClassNotFoundException ignored) }
{
isSpigot = false;
}
VERSION = new Version(version, isSpigot); VERSION = new Version(version, isSpigot);
} }
private static PlaceholderAPIPlugin instance; @NotNull
private final PlaceholderAPIConfig config = new PlaceholderAPIConfig(this);
@NotNull @NotNull
private final PlaceholderAPIConfig config = new PlaceholderAPIConfig(this); private final LocalExpansionManager localExpansionManager = new LocalExpansionManager(this);
@NotNull
private final CloudExpansionManager cloudExpansionManager = new CloudExpansionManager(this);
@NotNull /**
private final LocalExpansionManager localExpansionManager = new LocalExpansionManager(this); * Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API
@NotNull * class, this is the main class that extends JavaPlugin. For most API methods, use static methods
private final CloudExpansionManager cloudExpansionManager = new CloudExpansionManager(this); * available from the class: {@link PlaceholderAPI}
*
* @return PlaceholderAPIPlugin instance
*/
@NotNull
public static PlaceholderAPIPlugin getInstance() {
return instance;
}
/**
* Get the configurable {@linkplain String} value that should be returned when a boolean is true
*
* @return string value of true
*/
@NotNull
public static String booleanTrue() {
return getInstance().getPlaceholderAPIConfig().booleanTrue();
}
@Override /**
public void onLoad() * Get the configurable {@linkplain String} value that should be returned when a boolean is false
{ *
instance = this; * @return string value of false
*/
@NotNull
public static String booleanFalse() {
return getInstance().getPlaceholderAPIConfig().booleanFalse();
}
saveDefaultConfig(); /**
} * Get the configurable {@linkplain SimpleDateFormat} object that is used to parse time for
* generic time based placeholders
*
* @return date format
*/
@NotNull
public static SimpleDateFormat getDateFormat() {
try {
return new SimpleDateFormat(getInstance().getPlaceholderAPIConfig().dateFormat());
} catch (final IllegalArgumentException ex) {
getInstance().getLogger().log(Level.WARNING, "configured date format is invalid", ex);
return new SimpleDateFormat("MM/dd/yy HH:mm:ss");
}
}
@Override public static Version getServerVersion() {
public void onEnable() return VERSION;
{ }
setupCommand();
setupMetrics();
setupExpansions();
if (config.isCloudEnabled()) @Override
{ public void onLoad() {
getCloudExpansionManager().load(); instance = this;
}
if (config.checkUpdates()) saveDefaultConfig();
{ }
new UpdateChecker(this).fetch();
}
}
@Override @Override
public void onDisable() public void onEnable() {
{ setupCommand();
getCloudExpansionManager().kill(); setupMetrics();
getLocalExpansionManager().kill(); setupExpansions();
HandlerList.unregisterAll(this); if (config.isCloudEnabled()) {
getCloudExpansionManager().load();
}
Bukkit.getScheduler().cancelTasks(this); if (config.checkUpdates()) {
new UpdateChecker(this).fetch();
}
}
instance = null; @Override
} public void onDisable() {
getCloudExpansionManager().kill();
getLocalExpansionManager().kill();
HandlerList.unregisterAll(this);
public void reloadConf(@NotNull final CommandSender sender) Bukkit.getScheduler().cancelTasks(this);
{
getLocalExpansionManager().kill();
reloadConfig(); instance = null;
}
getLocalExpansionManager().load(sender); public void reloadConf(@NotNull final CommandSender sender) {
getLocalExpansionManager().kill();
if (config.isCloudEnabled()) reloadConfig();
{
getCloudExpansionManager().load();
}
else
{
getCloudExpansionManager().kill();
}
}
getLocalExpansionManager().load(sender);
@NotNull if (config.isCloudEnabled()) {
public LocalExpansionManager getLocalExpansionManager() getCloudExpansionManager().load();
{ } else {
return localExpansionManager; getCloudExpansionManager().kill();
} }
}
@NotNull @NotNull
public CloudExpansionManager getCloudExpansionManager() public LocalExpansionManager getLocalExpansionManager() {
{ return localExpansionManager;
return cloudExpansionManager; }
}
@NotNull
public CloudExpansionManager getCloudExpansionManager() {
return cloudExpansionManager;
}
/** /**
* Obtain the configuration class for PlaceholderAPI. * Obtain the configuration class for PlaceholderAPI.
* *
* @return PlaceholderAPIConfig instance * @return PlaceholderAPIConfig instance
*/ */
@NotNull @NotNull
public PlaceholderAPIConfig getPlaceholderAPIConfig() public PlaceholderAPIConfig getPlaceholderAPIConfig() {
{ return config;
return config; }
}
private void setupCommand() {
final PluginCommand pluginCommand = getCommand("placeholderapi");
if (pluginCommand == null) {
return;
}
private void setupCommand() final PlaceholderCommandRouter router = new PlaceholderCommandRouter(this);
{ pluginCommand.setExecutor(router);
final PluginCommand pluginCommand = getCommand("placeholderapi"); pluginCommand.setTabCompleter(router);
if (pluginCommand == null) }
{
return;
}
final PlaceholderCommandRouter router = new PlaceholderCommandRouter(this); private void setupMetrics() {
pluginCommand.setExecutor(router); final Metrics metrics = new Metrics(this);
pluginCommand.setTabCompleter(router); metrics.addCustomChart(new Metrics.SimplePie("using_expansion_cloud",
} () -> getPlaceholderAPIConfig().isCloudEnabled() ? "yes" : "no"));
private void setupMetrics() metrics.addCustomChart(
{ new Metrics.SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no"));
final Metrics metrics = new Metrics(this);
metrics.addCustomChart(new Metrics.SimplePie("using_expansion_cloud", () -> getPlaceholderAPIConfig().isCloudEnabled() ? "yes" : "no"));
metrics.addCustomChart(new Metrics.SimplePie("using_spigot", () -> getServerVersion().isSpigot() ? "yes" : "no")); metrics.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> {
final Map<String, Integer> values = new HashMap<>();
metrics.addCustomChart(new Metrics.AdvancedPie("expansions_used", () -> { for (final PlaceholderExpansion expansion : getLocalExpansionManager().getExpansions()) {
final Map<String, Integer> values = new HashMap<>(); values.put(expansion.getRequiredPlugin() == null ? expansion.getIdentifier()
: expansion.getRequiredPlugin(), 1);
}
for (final PlaceholderExpansion expansion : getLocalExpansionManager().getExpansions()) return values;
{ }));
values.put(expansion.getRequiredPlugin() == null ? expansion.getIdentifier() : expansion.getRequiredPlugin(), 1); }
}
return values; private void setupExpansions() {
})); Bukkit.getPluginManager().registerEvents(getLocalExpansionManager(), this);
}
private void setupExpansions() try {
{ Class.forName("org.bukkit.event.server.ServerLoadEvent");
Bukkit.getPluginManager().registerEvents(getLocalExpansionManager(), this); new ServerLoadEventListener(this);
} catch (final ExceptionInInitializerError | ClassNotFoundException ignored) {
try Bukkit.getScheduler()
{ .runTaskLater(this, () -> getLocalExpansionManager().load(Bukkit.getConsoleSender()), 1);
Class.forName("org.bukkit.event.server.ServerLoadEvent"); }
new ServerLoadEventListener(this); }
}
catch (final ExceptionInInitializerError | ClassNotFoundException ignored)
{
Bukkit.getScheduler().runTaskLater(this, () -> getLocalExpansionManager().load(Bukkit.getConsoleSender()), 1);
}
}
/**
* Gets the static instance of the main class for PlaceholderAPI. This class is not the actual API
* class, this is the main class that extends JavaPlugin. For most API methods, use static methods
* available from the class: {@link PlaceholderAPI}
*
* @return PlaceholderAPIPlugin instance
*/
@NotNull
public static PlaceholderAPIPlugin getInstance()
{
return instance;
}
/**
* Get the configurable {@linkplain String} value that should be returned when a boolean is true
*
* @return string value of true
*/
@NotNull
public static String booleanTrue()
{
return getInstance().getPlaceholderAPIConfig().booleanTrue();
}
/**
* Get the configurable {@linkplain String} value that should be returned when a boolean is false
*
* @return string value of false
*/
@NotNull
public static String booleanFalse()
{
return getInstance().getPlaceholderAPIConfig().booleanFalse();
}
/**
* Get the configurable {@linkplain SimpleDateFormat} object that is used to parse time for
* generic time based placeholders
*
* @return date format
*/
@NotNull
public static SimpleDateFormat getDateFormat()
{
try
{
return new SimpleDateFormat(getInstance().getPlaceholderAPIConfig().dateFormat());
}
catch (final IllegalArgumentException ex)
{
getInstance().getLogger().log(Level.WARNING, "configured date format is invalid", ex);
return new SimpleDateFormat("MM/dd/yy HH:mm:ss");
}
}
public static Version getServerVersion()
{
return VERSION;
}
} }

View File

@ -27,33 +27,31 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
/** /**
* @deprecated This class will be completely removed in the next release, please use {@link me.clip.placeholderapi.expansion.PlaceholderExpansion} * @deprecated This class will be completely removed in the next release, please use {@link
* me.clip.placeholderapi.expansion.PlaceholderExpansion}
*/ */
@Deprecated @Deprecated
@ApiStatus.NonExtendable @ApiStatus.NonExtendable
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0") @ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
public abstract class PlaceholderHook public abstract class PlaceholderHook {
{
@Nullable @Nullable
public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params) public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params) {
{ if (player != null && player.isOnline()) {
if (player != null && player.isOnline()) return onPlaceholderRequest((Player) player, params);
{ }
return onPlaceholderRequest((Player) player, params);
}
return onPlaceholderRequest(null, params); return onPlaceholderRequest(null, params);
} }
/** /**
* @deprecated This method will be completely removed, please use {@link me.clip.placeholderapi.expansion.PlaceholderExpansion#onRequest(OfflinePlayer, String)} * @deprecated This method will be completely removed, please use {@link
*/ * me.clip.placeholderapi.expansion.PlaceholderExpansion#onRequest(OfflinePlayer, String)}
@Nullable */
@Deprecated @Nullable
public String onPlaceholderRequest(@Nullable final Player player, @NotNull final String params) @Deprecated
{ public String onPlaceholderRequest(@Nullable final Player player, @NotNull final String params) {
return null; return null;
} }
} }

View File

@ -22,97 +22,86 @@ package me.clip.placeholderapi.commands;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public abstract class PlaceholderCommand {
import java.util.Set;
import java.util.stream.Stream;
public abstract class PlaceholderCommand @NotNull
{ private final String label;
@NotNull
private final Set<String> alias;
@NotNull @Nullable
private final String label; private String permission;
@NotNull
private final Set<String> alias;
@Nullable
private String permission;
protected PlaceholderCommand(@NotNull final String label, @NotNull final String... alias) protected PlaceholderCommand(@NotNull final String label, @NotNull final String... alias) {
{ this.label = label;
this.label = label; this.alias = Sets.newHashSet(alias);
this.alias = Sets.newHashSet(alias);
setPermission("placeholderapi." + label); setPermission("placeholderapi." + label);
} }
@NotNull
public static Stream<PlaceholderCommand> filterByPermission(@NotNull final CommandSender sender,
@NotNull final Stream<PlaceholderCommand> commands) {
return commands.filter(
target -> target.getPermission() == null || sender.hasPermission(target.getPermission()));
}
@NotNull public static void suggestByParameter(@NotNull final Stream<String> possible,
public final String getLabel() @NotNull final List<String> suggestions, @Nullable final String parameter) {
{ if (parameter == null) {
return label; possible.forEach(suggestions::add);
} } else {
possible.filter(suggestion -> suggestion.toLowerCase().startsWith(parameter.toLowerCase()))
.forEach(suggestions::add);
}
}
@NotNull @NotNull
@Unmodifiable public final String getLabel() {
public final Set<String> getAlias() return label;
{ }
return ImmutableSet.copyOf(alias);
}
@NotNull @NotNull
@Unmodifiable @Unmodifiable
public final Set<String> getLabels() public final Set<String> getAlias() {
{ return ImmutableSet.copyOf(alias);
return ImmutableSet.<String>builder().add(label).addAll(alias).build(); }
}
@NotNull
@Unmodifiable
public final Set<String> getLabels() {
return ImmutableSet.<String>builder().add(label).addAll(alias).build();
}
@Nullable @Nullable
public final String getPermission() public final String getPermission() {
{ return permission;
return permission; }
}
public void setPermission(@NotNull final String permission) public void setPermission(@NotNull final String permission) {
{ this.permission = permission;
this.permission = permission; }
}
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params) {
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) }
{
} public void complete(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) }
{
}
@NotNull
public static Stream<PlaceholderCommand> filterByPermission(@NotNull final CommandSender sender, @NotNull final Stream<PlaceholderCommand> commands)
{
return commands.filter(target -> target.getPermission() == null || sender.hasPermission(target.getPermission()));
}
public static void suggestByParameter(@NotNull final Stream<String> possible, @NotNull final List<String> suggestions, @Nullable final String parameter)
{
if (parameter == null)
{
possible.forEach(suggestions::add);
}
else
{
possible.filter(suggestion -> suggestion.toLowerCase().startsWith(parameter.toLowerCase())).forEach(suggestions::add);
}
}
} }

View File

@ -22,6 +22,13 @@ package me.clip.placeholderapi.commands;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.impl.cloud.CommandECloud; import me.clip.placeholderapi.commands.impl.cloud.CommandECloud;
import me.clip.placeholderapi.commands.impl.local.CommandDump; import me.clip.placeholderapi.commands.impl.local.CommandDump;
@ -41,103 +48,95 @@ import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.*; public final class PlaceholderCommandRouter implements CommandExecutor, TabCompleter {
import java.util.stream.Stream;
public final class PlaceholderCommandRouter implements CommandExecutor, TabCompleter @Unmodifiable
{ private static final List<PlaceholderCommand> COMMANDS = ImmutableList.of(new CommandHelp(),
new CommandInfo(),
@Unmodifiable new CommandList(),
private static final List<PlaceholderCommand> COMMANDS = ImmutableList.of(new CommandHelp(), new CommandDump(),
new CommandInfo(), new CommandECloud(),
new CommandList(), new CommandParse(),
new CommandDump(), new CommandReload(),
new CommandECloud(), new CommandVersion(),
new CommandParse(), new CommandExpansionRegister(),
new CommandReload(), new CommandExpansionUnregister());
new CommandVersion(),
new CommandExpansionRegister(),
new CommandExpansionUnregister());
@NotNull @NotNull
private final PlaceholderAPIPlugin plugin; private final PlaceholderAPIPlugin plugin;
@NotNull @NotNull
@Unmodifiable @Unmodifiable
private final Map<String, PlaceholderCommand> commands; private final Map<String, PlaceholderCommand> commands;
public PlaceholderCommandRouter(@NotNull final PlaceholderAPIPlugin plugin) public PlaceholderCommandRouter(@NotNull final PlaceholderAPIPlugin plugin) {
{ this.plugin = plugin;
this.plugin = plugin;
final ImmutableMap.Builder<String, PlaceholderCommand> commands = ImmutableMap.builder(); final ImmutableMap.Builder<String, PlaceholderCommand> commands = ImmutableMap.builder();
for (final PlaceholderCommand command : COMMANDS) for (final PlaceholderCommand command : COMMANDS) {
{ command.getLabels().forEach(label -> commands.put(label, command));
command.getLabels().forEach(label -> commands.put(label, command)); }
}
this.commands = commands.build(); this.commands = commands.build();
} }
@Override @Override
public boolean onCommand(@NotNull final CommandSender sender, @NotNull final Command command, @NotNull final String alias, @NotNull final String[] args) public boolean onCommand(@NotNull final CommandSender sender, @NotNull final Command command,
{ @NotNull final String alias, @NotNull final String[] args) {
if (args.length == 0) if (args.length == 0) {
{ final PlaceholderCommand fallback = commands.get("version");
final PlaceholderCommand fallback = commands.get("version"); if (fallback != null) {
if (fallback != null) fallback.evaluate(plugin, sender, "", Collections.emptyList());
{ }
fallback.evaluate(plugin, sender, "", Collections.emptyList());
}
return true; return true;
} }
final String search = args[0].toLowerCase(); final String search = args[0].toLowerCase();
final PlaceholderCommand target = commands.get(search); final PlaceholderCommand target = commands.get(search);
if (target == null) if (target == null) {
{ Msg.msg(sender, "&cUnknown command &7" + search);
Msg.msg(sender, "&cUnknown command &7" + search); return true;
return true; }
}
final String permission = target.getPermission(); final String permission = target.getPermission();
if (permission != null && !permission.isEmpty() && !sender.hasPermission(permission)) if (permission != null && !permission.isEmpty() && !sender.hasPermission(permission)) {
{ Msg.msg(sender, "&cYou do not have permission to do this!");
Msg.msg(sender, "&cYou do not have permission to do this!"); return true;
return true; }
}
target.evaluate(plugin, sender, search, Arrays.asList(Arrays.copyOfRange(args, 1, args.length))); target
.evaluate(plugin, sender, search, Arrays.asList(Arrays.copyOfRange(args, 1, args.length)));
return true; return true;
} }
@Override @Override
public List<String> onTabComplete(@NotNull final CommandSender sender, @NotNull final Command command, @NotNull final String alias, @NotNull final String[] args) public List<String> onTabComplete(@NotNull final CommandSender sender,
{ @NotNull final Command command, @NotNull final String alias, @NotNull final String[] args) {
final List<String> suggestions = new ArrayList<>(); final List<String> suggestions = new ArrayList<>();
if (args.length > 1) if (args.length > 1) {
{ final PlaceholderCommand target = this.commands.get(args[0].toLowerCase());
final PlaceholderCommand target = this.commands.get(args[0].toLowerCase());
if (target != null) if (target != null) {
{ target.complete(plugin, sender, args[0].toLowerCase(),
target.complete(plugin, sender, args[0].toLowerCase(), Arrays.asList(Arrays.copyOfRange(args, 1, args.length)), suggestions); Arrays.asList(Arrays.copyOfRange(args, 1, args.length)), suggestions);
} }
return suggestions; return suggestions;
} }
final Stream<String> targets = PlaceholderCommand.filterByPermission(sender, commands.values().stream()).map(PlaceholderCommand::getLabels).flatMap(Collection::stream); final Stream<String> targets = PlaceholderCommand
PlaceholderCommand.suggestByParameter(targets, suggestions, args.length == 0 ? null : args[0]); .filterByPermission(sender, commands.values().stream()).map(PlaceholderCommand::getLabels)
.flatMap(Collection::stream);
PlaceholderCommand.suggestByParameter(targets, suggestions, args.length == 0 ? null : args[0]);
return suggestions; return suggestions;
} }
} }

View File

@ -22,6 +22,10 @@ package me.clip.placeholderapi.commands.impl.cloud;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.util.Msg; import me.clip.placeholderapi.util.Msg;
@ -29,126 +33,117 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.Collection; public final class CommandECloud extends PlaceholderCommand {
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
public final class CommandECloud extends PlaceholderCommand @Unmodifiable
{ private static final List<PlaceholderCommand> COMMANDS = ImmutableList
.of(new CommandECloudClear(),
new CommandECloudToggle(),
new CommandECloudStatus(),
new CommandECloudUpdate(),
new CommandECloudRefresh(),
new CommandECloudDownload(),
new CommandECloudExpansionInfo(),
new CommandECloudExpansionList(),
new CommandECloudExpansionPlaceholders());
@Unmodifiable static {
private static final List<PlaceholderCommand> COMMANDS = ImmutableList.of(new CommandECloudClear(), COMMANDS
new CommandECloudToggle(), .forEach(command -> command.setPermission("placeholderapi.ecloud." + command.getLabel()));
new CommandECloudStatus(), }
new CommandECloudUpdate(),
new CommandECloudRefresh(),
new CommandECloudDownload(),
new CommandECloudExpansionInfo(),
new CommandECloudExpansionList(),
new CommandECloudExpansionPlaceholders());
static @NotNull
{ @Unmodifiable
COMMANDS.forEach(command -> command.setPermission("placeholderapi.ecloud." + command.getLabel())); private final Map<String, PlaceholderCommand> commands;
}
@NotNull
@Unmodifiable
private final Map<String, PlaceholderCommand> commands;
public CommandECloud() public CommandECloud() {
{ super("ecloud");
super("ecloud");
final ImmutableMap.Builder<String, PlaceholderCommand> commands = ImmutableMap.builder(); final ImmutableMap.Builder<String, PlaceholderCommand> commands = ImmutableMap.builder();
for (final PlaceholderCommand command : COMMANDS) for (final PlaceholderCommand command : COMMANDS) {
{ command.getLabels().forEach(label -> commands.put(label, command));
command.getLabels().forEach(label -> commands.put(label, command)); }
}
this.commands = commands.build(); this.commands = commands.build();
} }
@Override @Override
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
{ @NotNull final CommandSender sender, @NotNull final String alias,
if (params.isEmpty()) @NotNull @Unmodifiable final List<String> params) {
{ if (params.isEmpty()) {
Msg.msg(sender, Msg.msg(sender,
"&b&lPlaceholderAPI &8- &7eCloud Help Menu &8- ", "&b&lPlaceholderAPI &8- &7eCloud Help Menu &8- ",
" ", " ",
"&b/papi &fenable/disable/toggle", "&b/papi &fenable/disable/toggle",
" &7&oEnable or disable the eCloud", " &7&oEnable or disable the eCloud",
"&b/papi &fecloud status", "&b/papi &fecloud status",
" &7&oView status of the eCloud", " &7&oView status of the eCloud",
"&b/papi &fecloud list <all/{author}/installed> {page}", "&b/papi &fecloud list <all/{author}/installed> {page}",
" &7&oList all/author specific available expansions", " &7&oList all/author specific available expansions",
"&b/papi &fecloud info <expansion name> {version}", "&b/papi &fecloud info <expansion name> {version}",
" &7&oView information about a specific expansion available on the eCloud", " &7&oView information about a specific expansion available on the eCloud",
"&b/papi &fecloud placeholders <expansion name>", "&b/papi &fecloud placeholders <expansion name>",
" &7&oView placeholders for an expansion", " &7&oView placeholders for an expansion",
"&b/papi &fecloud download <expansion name> {version}", "&b/papi &fecloud download <expansion name> {version}",
" &7&oDownload an expansion from the eCloud", " &7&oDownload an expansion from the eCloud",
"&b/papi &fecloud update <expansion name/all>", "&b/papi &fecloud update <expansion name/all>",
" &7&oUpdate a specific/all installed expansions", " &7&oUpdate a specific/all installed expansions",
"&b/papi &fecloud refresh", "&b/papi &fecloud refresh",
" &7&oFetch the most up to date list of expansions available.", " &7&oFetch the most up to date list of expansions available.",
"&b/papi &fecloud clear", "&b/papi &fecloud clear",
" &7&oClear the expansion cloud cache."); " &7&oClear the expansion cloud cache.");
return; return;
} }
final String search = params.get(0).toLowerCase(); final String search = params.get(0).toLowerCase();
final PlaceholderCommand target = commands.get(search); final PlaceholderCommand target = commands.get(search);
if (target == null) if (target == null) {
{ Msg.msg(sender, "&cUnknown command &7ecloud " + search);
Msg.msg(sender, "&cUnknown command &7ecloud " + search); return;
return; }
}
final String permission = target.getPermission(); final String permission = target.getPermission();
if (permission != null && !permission.isEmpty() && !sender.hasPermission(permission)) if (permission != null && !permission.isEmpty() && !sender.hasPermission(permission)) {
{ Msg.msg(sender, "&cYou do not have permission to do this!");
Msg.msg(sender, "&cYou do not have permission to do this!"); return;
return; }
}
if (!(target instanceof CommandECloudToggle) && !plugin.getPlaceholderAPIConfig().isCloudEnabled()) if (!(target instanceof CommandECloudToggle) && !plugin.getPlaceholderAPIConfig()
{ .isCloudEnabled()) {
Msg.msg(sender, Msg.msg(sender,
"&cThe eCloud Manager is not enabled!"); "&cThe eCloud Manager is not enabled!");
return; return;
} }
target.evaluate(plugin, sender, search, params.subList(1, params.size())); target.evaluate(plugin, sender, search, params.subList(1, params.size()));
} }
@Override @Override
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) public void complete(@NotNull final PlaceholderAPIPlugin plugin,
{ @NotNull final CommandSender sender, @NotNull final String alias,
if (params.size() <= 1) @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
{ if (params.size() <= 1) {
final Stream<String> targets = filterByPermission(sender, commands.values().stream()).map(PlaceholderCommand::getLabels).flatMap(Collection::stream); final Stream<String> targets = filterByPermission(sender, commands.values().stream())
suggestByParameter(targets, suggestions, params.isEmpty() ? null : params.get(0)); .map(PlaceholderCommand::getLabels).flatMap(Collection::stream);
suggestByParameter(targets, suggestions, params.isEmpty() ? null : params.get(0));
return; // send sub commands return; // send sub commands
} }
final String search = params.get(0).toLowerCase(); final String search = params.get(0).toLowerCase();
final PlaceholderCommand target = commands.get(search); final PlaceholderCommand target = commands.get(search);
if (target == null) if (target == null) {
{ return;
return; }
}
target.complete(plugin, sender, search, params.subList(1, params.size()), suggestions); target.complete(plugin, sender, search, params.subList(1, params.size()), suggestions);
} }
} }

View File

@ -20,6 +20,7 @@
package me.clip.placeholderapi.commands.impl.cloud; package me.clip.placeholderapi.commands.impl.cloud;
import java.util.List;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.util.Msg; import me.clip.placeholderapi.util.Msg;
@ -27,22 +28,19 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandECloudClear extends PlaceholderCommand {
public final class CommandECloudClear extends PlaceholderCommand public CommandECloudClear() {
{ super("clear");
}
public CommandECloudClear() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("clear"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
plugin.getCloudExpansionManager().clean();
@Override Msg.msg(sender,
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) "&aThe eCloud cache has been cleared!");
{ }
plugin.getCloudExpansionManager().clean();
Msg.msg(sender,
"&aThe eCloud cache has been cleared!");
}
} }

View File

@ -20,6 +20,9 @@
package me.clip.placeholderapi.commands.impl.cloud; package me.clip.placeholderapi.commands.impl.cloud;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.cloud.CloudExpansion; import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
@ -28,98 +31,89 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandECloudDownload extends PlaceholderCommand {
import java.util.Optional;
import java.util.stream.Stream;
public final class CommandECloudDownload extends PlaceholderCommand public CommandECloudDownload() {
{ super("download");
}
public CommandECloudDownload() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("download"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
if (params.isEmpty()) {
Msg.msg(sender,
"&cYou must supply the name of an expansion.");
return;
}
@Override final CloudExpansion expansion = plugin.getCloudExpansionManager()
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) .findCloudExpansionByName(params.get(0)).orElse(null);
{ if (expansion == null) {
if (params.isEmpty()) Msg.msg(sender,
{ "&cFailed to find an expansion named: &f" + params.get(0));
Msg.msg(sender, return;
"&cYou must supply the name of an expansion."); }
return;
}
final CloudExpansion expansion = plugin.getCloudExpansionManager().findCloudExpansionByName(params.get(0)).orElse(null); final CloudExpansion.Version version;
if (expansion == null) if (params.size() < 2) {
{ version = expansion.getVersion(expansion.getLatestVersion());
Msg.msg(sender, if (version == null) {
"&cFailed to find an expansion named: &f" + params.get(0)); Msg.msg(sender,
return; "&cCould not find latest version for expansion.");
} return;
}
} else {
version = expansion.getVersion(params.get(1));
if (version == null) {
Msg.msg(sender,
"&cCould not find specified version: &f" + params.get(1),
"&7Available versions: &f" + expansion.getAvailableVersions());
return;
}
}
final CloudExpansion.Version version; plugin.getCloudExpansionManager().downloadExpansion(expansion, version)
if (params.size() < 2) .whenComplete((file, exception) -> {
{ if (exception != null) {
version = expansion.getVersion(expansion.getLatestVersion()); Msg.msg(sender,
if (version == null) "&cFailed to download expansion: &f" + exception.getMessage());
{ return;
Msg.msg(sender, }
"&cCould not find latest version for expansion.");
return;
}
}
else
{
version = expansion.getVersion(params.get(1));
if (version == null)
{
Msg.msg(sender,
"&cCould not find specified version: &f" + params.get(1),
"&7Available versions: &f" + expansion.getAvailableVersions());
return;
}
}
plugin.getCloudExpansionManager().downloadExpansion(expansion, version).whenComplete((file, exception) -> { Msg.msg(sender,
if (exception != null) "&aSuccessfully downloaded expansion &f" + expansion.getName() + " [" + version
{ .getVersion() + "] &ato file: &f" + file.getName(),
Msg.msg(sender, "&aMake sure to type &f/papi reload &ato enable your new expansion!");
"&cFailed to download expansion: &f" + exception.getMessage());
return;
}
Msg.msg(sender, plugin.getCloudExpansionManager().clean();
"&aSuccessfully downloaded expansion &f" + expansion.getName() + " [" + version.getVersion() + "] &ato file: &f" + file.getName(), plugin.getCloudExpansionManager()
"&aMake sure to type &f/papi reload &ato enable your new expansion!"); .fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
});
}
plugin.getCloudExpansionManager().clean(); @Override
plugin.getCloudExpansionManager().fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); public void complete(@NotNull final PlaceholderAPIPlugin plugin,
}); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
if (params.size() > 2) {
return;
}
@Override if (params.size() <= 1) {
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) final Stream<String> names = plugin.getCloudExpansionManager().getCloudExpansions().values()
{ .stream().map(CloudExpansion::getName).map(name -> name.replace(' ', '_'));
if (params.size() > 2) suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(0));
{ return;
return; }
}
if (params.size() <= 1) final Optional<CloudExpansion> expansion = plugin.getCloudExpansionManager()
{ .findCloudExpansionByName(params.get(0));
final Stream<String> names = plugin.getCloudExpansionManager().getCloudExpansions().values().stream().map(CloudExpansion::getName).map(name -> name.replace(' ', '_')); if (!expansion.isPresent()) {
suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(0)); return;
return; }
}
final Optional<CloudExpansion> expansion = plugin.getCloudExpansionManager().findCloudExpansionByName(params.get(0)); suggestByParameter(expansion.get().getAvailableVersions().stream(), suggestions, params.get(1));
if (!expansion.isPresent()) }
{
return;
}
suggestByParameter(expansion.get().getAvailableVersions().stream(), suggestions, params.get(1));
}
} }

View File

@ -20,6 +20,9 @@
package me.clip.placeholderapi.commands.impl.cloud; package me.clip.placeholderapi.commands.impl.cloud;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.cloud.CloudExpansion; import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
@ -28,109 +31,99 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandECloudExpansionInfo extends PlaceholderCommand {
import java.util.Optional;
import java.util.stream.Stream;
public final class CommandECloudExpansionInfo extends PlaceholderCommand public CommandECloudExpansionInfo() {
{ super("info");
}
public CommandECloudExpansionInfo() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("info"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
if (params.isEmpty()) {
Msg.msg(sender,
"&cYou must specify the name of the expansion.");
return;
}
@Override final CloudExpansion expansion = plugin.getCloudExpansionManager()
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) .findCloudExpansionByName(params.get(0)).orElse(null);
{ if (expansion == null) {
if (params.isEmpty()) Msg.msg(sender,
{ "&cThere is no expansion with the name: &f" + params.get(0));
Msg.msg(sender, return;
"&cYou must specify the name of the expansion."); }
return;
}
final CloudExpansion expansion = plugin.getCloudExpansionManager().findCloudExpansionByName(params.get(0)).orElse(null); final StringBuilder builder = new StringBuilder();
if (expansion == null)
{
Msg.msg(sender,
"&cThere is no expansion with the name: &f" + params.get(0));
return;
}
final StringBuilder builder = new StringBuilder(); builder.append("&bExpansion: &f")
.append(expansion.shouldUpdate() ? "&e" : "&a")
.append(expansion.getName())
.append('\n')
.append("&bAuthor: &f")
.append(expansion.getAuthor())
.append('\n')
.append("&bVerified: ")
.append(expansion.isVerified() ? "&a&l✔" : "&c&l❌")
.append('\n');
builder.append("&bExpansion: &f") if (params.size() < 2) {
.append(expansion.shouldUpdate() ? "&e" : "&a") builder.append("&bLatest Version: &f")
.append(expansion.getName()) .append(expansion.getLatestVersion())
.append('\n') .append('\n')
.append("&bAuthor: &f") .append("&bReleased: &f")
.append(expansion.getAuthor()) .append(expansion.getTimeSinceLastUpdate())
.append('\n') .append(" ago")
.append("&bVerified: ") .append('\n')
.append(expansion.isVerified() ? "&a&l✔" : "&c&l❌") .append("&bRelease Notes: &f")
.append('\n'); .append(expansion.getVersion().getReleaseNotes())
.append('\n');
} else {
final CloudExpansion.Version version = expansion.getVersion(params.get(1));
if (version == null) {
Msg.msg(sender,
"&cCould not find specified version: &f" + params.get(1),
"&aVersions: &f" + expansion.getAvailableVersions());
return;
}
if (params.size() < 2) builder.append("&bVersion: &f")
{ .append(version.getVersion())
builder.append("&bLatest Version: &f") .append('\n')
.append(expansion.getLatestVersion()) .append("&bRelease Notes: &f")
.append('\n') .append(version.getReleaseNotes())
.append("&bReleased: &f") .append('\n')
.append(expansion.getTimeSinceLastUpdate()) .append("&bDownload URL: &f")
.append(" ago") .append(version.getUrl())
.append('\n') .append('\n');
.append("&bRelease Notes: &f") }
.append(expansion.getVersion().getReleaseNotes())
.append('\n');
}
else
{
final CloudExpansion.Version version = expansion.getVersion(params.get(1));
if (version == null)
{
Msg.msg(sender,
"&cCould not find specified version: &f" + params.get(1),
"&aVersions: &f" + expansion.getAvailableVersions());
return;
}
builder.append("&bVersion: &f") Msg.msg(sender, builder.toString());
.append(version.getVersion()) }
.append('\n')
.append("&bRelease Notes: &f")
.append(version.getReleaseNotes())
.append('\n')
.append("&bDownload URL: &f")
.append(version.getUrl())
.append('\n');
}
Msg.msg(sender, builder.toString()); @Override
} public void complete(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
if (params.size() > 2) {
return;
}
@Override if (params.size() <= 1) {
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) final Stream<String> names = plugin.getCloudExpansionManager().getCloudExpansions().values()
{ .stream().map(CloudExpansion::getName).map(name -> name.replace(' ', '_'));
if (params.size() > 2) suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(0));
{ return;
return; }
}
if (params.size() <= 1) final Optional<CloudExpansion> expansion = plugin.getCloudExpansionManager()
{ .findCloudExpansionByName(params.get(0));
final Stream<String> names = plugin.getCloudExpansionManager().getCloudExpansions().values().stream().map(CloudExpansion::getName).map(name -> name.replace(' ', '_')); if (!expansion.isPresent()) {
suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(0)); return;
return; }
}
final Optional<CloudExpansion> expansion = plugin.getCloudExpansionManager().findCloudExpansionByName(params.get(0)); suggestByParameter(expansion.get().getAvailableVersions().stream(), suggestions, params.get(1));
if (!expansion.isPresent()) }
{
return;
}
suggestByParameter(expansion.get().getAvailableVersions().stream(), suggestions, params.get(1));
}
} }

View File

@ -25,6 +25,19 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.configuration.ExpansionSort; import me.clip.placeholderapi.configuration.ExpansionSort;
@ -39,322 +52,297 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.text.SimpleDateFormat; public final class CommandECloudExpansionList extends PlaceholderCommand {
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public final class CommandECloudExpansionList extends PlaceholderCommand private static final int PAGE_SIZE = 10;
{
private static final int PAGE_SIZE = 10; @NotNull
private static final Function<CloudExpansion, Object> EXPANSION_NAME =
@NotNull expansion -> (expansion.shouldUpdate() ? "&6" : expansion.hasExpansion() ? "&a" : "&7")
private static final Function<CloudExpansion, Object> EXPANSION_NAME = + expansion.getName();
expansion -> (expansion.shouldUpdate() ? "&6" : expansion.hasExpansion() ? "&a" : "&7") + expansion.getName(); @NotNull
@NotNull private static final Function<CloudExpansion, Object> EXPANSION_AUTHOR =
private static final Function<CloudExpansion, Object> EXPANSION_AUTHOR = expansion -> "&f" + expansion.getAuthor();
expansion -> "&f" + expansion.getAuthor(); @NotNull
@NotNull private static final Function<CloudExpansion, Object> EXPANSION_VERIFIED =
private static final Function<CloudExpansion, Object> EXPANSION_VERIFIED = expansion -> expansion.isVerified() ? "&aY" : "&cN";
expansion -> expansion.isVerified() ? "&aY" : "&cN"; @NotNull
@NotNull private static final Function<CloudExpansion, Object> EXPANSION_LATEST_VERSION =
private static final Function<CloudExpansion, Object> EXPANSION_LATEST_VERSION = expansion -> "&f" + expansion.getLatestVersion();
expansion -> "&f" + expansion.getLatestVersion(); @NotNull
@NotNull private static final Function<CloudExpansion, Object> EXPANSION_CURRENT_VERSION =
private static final Function<CloudExpansion, Object> EXPANSION_CURRENT_VERSION = expansion -> "&f" + PlaceholderAPIPlugin.getInstance().getLocalExpansionManager()
expansion -> "&f" + PlaceholderAPIPlugin.getInstance().getLocalExpansionManager().findExpansionByName(expansion.getName()).map(PlaceholderExpansion::getVersion).orElse("Unknown"); .findExpansionByName(expansion.getName()).map(PlaceholderExpansion::getVersion)
.orElse("Unknown");
@Unmodifiable @Unmodifiable
private static final Set<String> OPTIONS = ImmutableSet.of("all", "installed"); private static final Set<String> OPTIONS = ImmutableSet.of("all", "installed");
public CommandECloudExpansionList() public CommandECloudExpansionList() {
{ super("list");
super("list"); }
}
@Override @NotNull
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) private static Collection<CloudExpansion> getExpansions(@NotNull final String target,
{ @NotNull final PlaceholderAPIPlugin plugin) {
if (params.isEmpty()) switch (target.toLowerCase()) {
{ case "all":
Msg.msg(sender, return plugin.getCloudExpansionManager().getCloudExpansions().values();
"&cYou must specify an option. [all, {author}, installed]"); case "installed":
return; return plugin.getCloudExpansionManager().getCloudExpansionsInstalled().values();
} default:
return plugin.getCloudExpansionManager().getCloudExpansionsByAuthor(target).values();
}
}
@NotNull
private static List<CloudExpansion> getPage(@NotNull final List<CloudExpansion> expansions,
final int page) {
final int head = (page * PAGE_SIZE);
final int tail = Math.min(expansions.size(), head + PAGE_SIZE);
final boolean installed = params.get(0).equalsIgnoreCase("installed"); if (expansions.size() < head) {
final List<CloudExpansion> expansions = Lists.newArrayList(getExpansions(params.get(0), plugin)); return Collections.emptyList();
}
if (expansions.isEmpty()) return expansions.subList(head, tail);
{ }
Msg.msg(sender,
"&cNo expansions available to list.");
return;
}
expansions.sort(plugin.getPlaceholderAPIConfig().getExpansionSort().orElse(ExpansionSort.LATEST)); public static void addExpansionTitle(@NotNull final StringBuilder builder,
@NotNull final String target, final int page) {
switch (target.toLowerCase()) {
case "all":
builder.append("&bAll Expansions");
break;
case "installed":
builder.append("&bInstalled Expansions");
break;
default:
builder.append("&bExpansions by &f")
.append(target);
break;
}
if (!(sender instanceof Player) && params.size() < 2) if (page == -1) {
{ builder.append('\n');
final StringBuilder builder = new StringBuilder(); return;
}
addExpansionTitle(builder, params.get(0), -1); builder.append(" &bPage&7: &a")
addExpansionTable(expansions, .append(page)
builder, .append("&r")
1, .append('\n');
installed ? "&9Version" : "&9Latest Version", }
installed ? EXPANSION_CURRENT_VERSION : EXPANSION_LATEST_VERSION);
Msg.msg(sender, builder.toString()); @NotNull
return; private static JSONMessage getMessage(@NotNull final List<CloudExpansion> expansions,
} final int page, final int limit, @NotNull final String target) {
final SimpleDateFormat format = PlaceholderAPIPlugin.getDateFormat();
final int page; final StringBuilder tooltip = new StringBuilder();
final JSONMessage message = JSONMessage.create();
if (params.size() < 2) for (int index = 0; index < expansions.size(); index++) {
{ final CloudExpansion expansion = expansions.get(index);
page = 1;
}
else
{
//noinspection UnstableApiUsage
final Integer parsed = Ints.tryParse(params.get(1));
if (parsed == null)
{
Msg.msg(sender,
"&cPage number must be an integer.");
return;
}
final int limit = (int) Math.ceil((double) expansions.size() / PAGE_SIZE); tooltip.append("&bClick to download this expansion!")
.append('\n')
.append('\n')
.append("&bAuthor: &f")
.append(expansion.getAuthor())
.append('\n')
.append("&bVerified: ")
.append(expansion.isVerified() ? "&a&l✔&r" : "&c&l❌&r")
.append('\n')
.append("&bLatest Version: &f")
.append(expansion.getLatestVersion())
.append('\n')
.append("&bReleased: &f")
.append(format.format(expansion.getLastUpdate()));
if (parsed < 1 || parsed > limit) final String description = expansion.getDescription();
{ if (description != null && !description.isEmpty()) {
Msg.msg(sender, tooltip.append('\n')
"&cPage number must be in the range &8[&a1&7..&a" + limit + "&8]"); .append('\n')
return; .append("&f")
} .append(description.replace("\r", "").trim());
}
page = parsed; message.then(Msg.color(
} "&8" + (index + ((page - 1) * PAGE_SIZE) + 1) + ".&r " + (expansion.shouldUpdate() ? "&6"
: expansion.hasExpansion() ? "&a" : "&7") + expansion.getName()));
final StringBuilder builder = new StringBuilder(); message.tooltip(Msg.color(tooltip.toString()));
final List<CloudExpansion> values = getPage(expansions, page - 1); message.suggestCommand("/papi ecloud download " + expansion.getName());
addExpansionTitle(builder, params.get(0), page); if (index < expansions.size() - 1) {
message.newline();
}
if (!(sender instanceof Player)) tooltip.setLength(0);
{ }
addExpansionTable(values,
builder,
((page - 1) * PAGE_SIZE) + 1,
installed ? "&9Version" : "&9Latest Version",
installed ? EXPANSION_CURRENT_VERSION : EXPANSION_LATEST_VERSION);
Msg.msg(sender, builder.toString()); if (limit > 1) {
message.newline();
return; message.then("")
} .color(page > 1 ? ChatColor.GRAY : ChatColor.DARK_GRAY);
if (page > 1) {
message.runCommand("/papi ecloud list " + target + " " + (page - 1));
}
Msg.msg(sender, builder.toString()); message.then(" " + page + " ").color(ChatColor.GREEN);
final int limit = (int) Math.ceil((double) expansions.size() / PAGE_SIZE); message.then("")
.color(page < limit ? ChatColor.GRAY : ChatColor.DARK_GRAY);
if (page < limit) {
message.runCommand("/papi ecloud list " + target + " " + (page + 1));
}
}
final JSONMessage message = getMessage(values, page, limit, params.get(0)); return message;
message.send(((Player) sender)); }
}
@Override private static void addExpansionTable(@NotNull final List<CloudExpansion> expansions,
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) @NotNull final StringBuilder message, final int startIndex,
{ @NotNull final String versionTitle,
if (params.size() > 2) @NotNull final Function<CloudExpansion, Object> versionFunction) {
{ final Map<String, Function<CloudExpansion, Object>> functions = new LinkedHashMap<>();
return;
}
if (params.size() <= 1) final AtomicInteger counter = new AtomicInteger(startIndex);
{ functions.put("&f", expansion -> "&8" + counter.getAndIncrement() + ".");
suggestByParameter(Sets.union(OPTIONS, plugin.getCloudExpansionManager().getCloudExpansionAuthors()).stream(), suggestions, params.isEmpty() ? null : params.get(0));
return;
}
suggestByParameter(IntStream.rangeClosed(1, (int) Math.ceil((double) getExpansions(params.get(0), plugin).size() / PAGE_SIZE)).mapToObj(Objects::toString), suggestions, params.get(1)); functions.put("&9Name", EXPANSION_NAME);
} functions.put("&9Author", EXPANSION_AUTHOR);
functions.put("&9Verified", EXPANSION_VERIFIED);
functions.put(versionTitle, versionFunction);
final List<List<String>> rows = new ArrayList<>();
@NotNull rows.add(0, new ArrayList<>(functions.keySet()));
private static Collection<CloudExpansion> getExpansions(@NotNull final String target, @NotNull final PlaceholderAPIPlugin plugin)
{
switch (target.toLowerCase())
{
case "all":
return plugin.getCloudExpansionManager().getCloudExpansions().values();
case "installed":
return plugin.getCloudExpansionManager().getCloudExpansionsInstalled().values();
default:
return plugin.getCloudExpansionManager().getCloudExpansionsByAuthor(target).values();
}
}
@NotNull for (final CloudExpansion expansion : expansions) {
private static List<CloudExpansion> getPage(@NotNull final List<CloudExpansion> expansions, final int page) rows.add(functions.values().stream().map(function -> function.apply(expansion))
{ .map(Objects::toString).collect(Collectors.toList()));
final int head = (page * PAGE_SIZE); }
final int tail = Math.min(expansions.size(), head + PAGE_SIZE);
if (expansions.size() < head) final List<String> table = Format.tablify(Format.Align.LEFT, rows)
{ .orElse(Collections.emptyList());
return Collections.emptyList(); if (table.isEmpty()) {
} return;
}
return expansions.subList(head, tail); table.add(1, "&8" + Strings.repeat("-", table.get(0).length() - (rows.get(0).size() * 2)));
}
public static void addExpansionTitle(@NotNull final StringBuilder builder, @NotNull final String target, final int page) message.append(String.join("\n", table));
{ }
switch (target.toLowerCase())
{
case "all":
builder.append("&bAll Expansions");
break;
case "installed":
builder.append("&bInstalled Expansions");
break;
default:
builder.append("&bExpansions by &f")
.append(target);
break;
}
if (page == -1) @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
builder.append('\n'); @NotNull final CommandSender sender, @NotNull final String alias,
return; @NotNull @Unmodifiable final List<String> params) {
} if (params.isEmpty()) {
Msg.msg(sender,
"&cYou must specify an option. [all, {author}, installed]");
return;
}
builder.append(" &bPage&7: &a") final boolean installed = params.get(0).equalsIgnoreCase("installed");
.append(page) final List<CloudExpansion> expansions = Lists
.append("&r") .newArrayList(getExpansions(params.get(0), plugin));
.append('\n');
}
if (expansions.isEmpty()) {
Msg.msg(sender,
"&cNo expansions available to list.");
return;
}
@NotNull expansions
private static JSONMessage getMessage(@NotNull final List<CloudExpansion> expansions, final int page, final int limit, @NotNull final String target) .sort(plugin.getPlaceholderAPIConfig().getExpansionSort().orElse(ExpansionSort.LATEST));
{
final SimpleDateFormat format = PlaceholderAPIPlugin.getDateFormat();
final StringBuilder tooltip = new StringBuilder(); if (!(sender instanceof Player) && params.size() < 2) {
final JSONMessage message = JSONMessage.create(); final StringBuilder builder = new StringBuilder();
for (int index = 0; index < expansions.size(); index++) addExpansionTitle(builder, params.get(0), -1);
{ addExpansionTable(expansions,
final CloudExpansion expansion = expansions.get(index); builder,
1,
installed ? "&9Version" : "&9Latest Version",
installed ? EXPANSION_CURRENT_VERSION : EXPANSION_LATEST_VERSION);
tooltip.append("&bClick to download this expansion!") Msg.msg(sender, builder.toString());
.append('\n') return;
.append('\n') }
.append("&bAuthor: &f")
.append(expansion.getAuthor())
.append('\n')
.append("&bVerified: ")
.append(expansion.isVerified() ? "&a&l✔&r" : "&c&l❌&r")
.append('\n')
.append("&bLatest Version: &f")
.append(expansion.getLatestVersion())
.append('\n')
.append("&bReleased: &f")
.append(format.format(expansion.getLastUpdate()));
final String description = expansion.getDescription(); final int page;
if (description != null && !description.isEmpty())
{
tooltip.append('\n')
.append('\n')
.append("&f")
.append(description.replace("\r", "").trim());
}
message.then(Msg.color("&8" + (index + ((page - 1) * PAGE_SIZE) + 1) + ".&r " + (expansion.shouldUpdate() ? "&6" : expansion.hasExpansion() ? "&a" : "&7") + expansion.getName())); if (params.size() < 2) {
page = 1;
} else {
//noinspection UnstableApiUsage
final Integer parsed = Ints.tryParse(params.get(1));
if (parsed == null) {
Msg.msg(sender,
"&cPage number must be an integer.");
return;
}
message.tooltip(Msg.color(tooltip.toString())); final int limit = (int) Math.ceil((double) expansions.size() / PAGE_SIZE);
message.suggestCommand("/papi ecloud download " + expansion.getName());
if (index < expansions.size() - 1) if (parsed < 1 || parsed > limit) {
{ Msg.msg(sender,
message.newline(); "&cPage number must be in the range &8[&a1&7..&a" + limit + "&8]");
} return;
}
tooltip.setLength(0); page = parsed;
} }
if (limit > 1) final StringBuilder builder = new StringBuilder();
{ final List<CloudExpansion> values = getPage(expansions, page - 1);
message.newline();
message.then("") addExpansionTitle(builder, params.get(0), page);
.color(page > 1 ? ChatColor.GRAY : ChatColor.DARK_GRAY);
if (page > 1)
{
message.runCommand("/papi ecloud list " + target + " " + (page - 1));
}
message.then(" " + page + " ").color(ChatColor.GREEN); if (!(sender instanceof Player)) {
addExpansionTable(values,
builder,
((page - 1) * PAGE_SIZE) + 1,
installed ? "&9Version" : "&9Latest Version",
installed ? EXPANSION_CURRENT_VERSION : EXPANSION_LATEST_VERSION);
message.then("") Msg.msg(sender, builder.toString());
.color(page < limit ? ChatColor.GRAY : ChatColor.DARK_GRAY);
if (page < limit)
{
message.runCommand("/papi ecloud list " + target + " " + (page + 1));
}
}
return message; return;
} }
private static void addExpansionTable(@NotNull final List<CloudExpansion> expansions, @NotNull final StringBuilder message, final int startIndex, @NotNull final String versionTitle, @NotNull final Function<CloudExpansion, Object> versionFunction) Msg.msg(sender, builder.toString());
{
final Map<String, Function<CloudExpansion, Object>> functions = new LinkedHashMap<>();
final AtomicInteger counter = new AtomicInteger(startIndex); final int limit = (int) Math.ceil((double) expansions.size() / PAGE_SIZE);
functions.put("&f", expansion -> "&8" + counter.getAndIncrement() + ".");
functions.put("&9Name", EXPANSION_NAME); final JSONMessage message = getMessage(values, page, limit, params.get(0));
functions.put("&9Author", EXPANSION_AUTHOR); message.send(((Player) sender));
functions.put("&9Verified", EXPANSION_VERIFIED); }
functions.put(versionTitle, versionFunction);
final List<List<String>> rows = new ArrayList<>(); @Override
public void complete(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
if (params.size() > 2) {
return;
}
rows.add(0, new ArrayList<>(functions.keySet())); if (params.size() <= 1) {
suggestByParameter(
Sets.union(OPTIONS, plugin.getCloudExpansionManager().getCloudExpansionAuthors())
.stream(), suggestions, params.isEmpty() ? null : params.get(0));
return;
}
for (final CloudExpansion expansion : expansions) suggestByParameter(IntStream.rangeClosed(1,
{ (int) Math.ceil((double) getExpansions(params.get(0), plugin).size() / PAGE_SIZE))
rows.add(functions.values().stream().map(function -> function.apply(expansion)).map(Objects::toString).collect(Collectors.toList())); .mapToObj(Objects::toString), suggestions, params.get(1));
} }
final List<String> table = Format.tablify(Format.Align.LEFT, rows).orElse(Collections.emptyList());
if (table.isEmpty())
{
return;
}
table.add(1, "&8" + Strings.repeat("-", table.get(0).length() - (rows.get(0).size() * 2)));
message.append(String.join("\n", table));
}
} }

View File

@ -21,6 +21,9 @@
package me.clip.placeholderapi.commands.impl.cloud; package me.clip.placeholderapi.commands.impl.cloud;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.cloud.CloudExpansion; import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
@ -29,68 +32,63 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandECloudExpansionPlaceholders extends PlaceholderCommand {
import java.util.stream.Collectors;
import java.util.stream.Stream;
public final class CommandECloudExpansionPlaceholders extends PlaceholderCommand public CommandECloudExpansionPlaceholders() {
{ super("placeholders");
}
public CommandECloudExpansionPlaceholders() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("placeholders"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
if (params.isEmpty()) {
Msg.msg(sender,
"&cYou must specify the name of the expansion.");
return;
}
@Override final CloudExpansion expansion = plugin.getCloudExpansionManager()
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) .findCloudExpansionByName(params.get(0)).orElse(null);
{ if (expansion == null) {
if (params.isEmpty()) Msg.msg(sender,
{ "&cThere is no expansion with the name: &f" + params.get(0));
Msg.msg(sender, return;
"&cYou must specify the name of the expansion."); }
return;
}
final CloudExpansion expansion = plugin.getCloudExpansionManager().findCloudExpansionByName(params.get(0)).orElse(null); final List<String> placeholders = expansion.getPlaceholders();
if (expansion == null) if (placeholders == null || placeholders.isEmpty()) {
{ Msg.msg(sender,
Msg.msg(sender, "&cThe expansion specified does not have placeholders listed.");
"&cThere is no expansion with the name: &f" + params.get(0)); return;
return; }
}
final List<String> placeholders = expansion.getPlaceholders(); final List<List<String>> partitions = Lists
if (placeholders == null || placeholders.isEmpty()) .partition(placeholders.stream().sorted().collect(Collectors.toList()), 10);
{
Msg.msg(sender,
"&cThe expansion specified does not have placeholders listed.");
return;
}
final List<List<String>> partitions = Lists.partition(placeholders.stream().sorted().collect(Collectors.toList()), 10); Msg.msg(sender,
"&6" + placeholders.size() + "&7 placeholders: &a",
partitions.stream().map(partition -> String.join(", ", partition))
.collect(Collectors.joining("\n")));
Msg.msg(sender, }
"&6" + placeholders.size() + "&7 placeholders: &a",
partitions.stream().map(partition -> String.join(", ", partition)).collect(Collectors.joining("\n")));
} @Override
public void complete(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
if (params.size() > 1) {
return;
}
@Override final Stream<String> names = plugin.getCloudExpansionManager()
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) .getCloudExpansions()
{ .values()
if (params.size() > 1) .stream()
{ .map(CloudExpansion::getName)
return; .map(name -> name.replace(' ', '_'));
}
final Stream<String> names = plugin.getCloudExpansionManager() suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(0));
.getCloudExpansions() }
.values()
.stream()
.map(CloudExpansion::getName)
.map(name -> name.replace(' ', '_'));
suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(0));
}
} }

View File

@ -20,6 +20,7 @@
package me.clip.placeholderapi.commands.impl.cloud; package me.clip.placeholderapi.commands.impl.cloud;
import java.util.List;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.util.Msg; import me.clip.placeholderapi.util.Msg;
@ -27,24 +28,22 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandECloudRefresh extends PlaceholderCommand {
public final class CommandECloudRefresh extends PlaceholderCommand public CommandECloudRefresh() {
{ super("refresh");
}
public CommandECloudRefresh() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("refresh"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
plugin.getCloudExpansionManager().clean();
plugin.getCloudExpansionManager()
.fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
@Override Msg.msg(sender,
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) "&aThe eCloud manager has been refreshed!");
{ }
plugin.getCloudExpansionManager().clean();
plugin.getCloudExpansionManager().fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
Msg.msg(sender,
"&aThe eCloud manager has been refreshed!");
}
} }

View File

@ -20,6 +20,7 @@
package me.clip.placeholderapi.commands.impl.cloud; package me.clip.placeholderapi.commands.impl.cloud;
import java.util.List;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.manager.CloudExpansionManager; import me.clip.placeholderapi.expansion.manager.CloudExpansionManager;
@ -28,36 +29,36 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandECloudStatus extends PlaceholderCommand {
public final class CommandECloudStatus extends PlaceholderCommand public CommandECloudStatus() {
{ super("status");
}
public CommandECloudStatus() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("status"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
final CloudExpansionManager manager = plugin.getCloudExpansionManager();
@Override final int updateCount = manager.getCloudUpdateCount();
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) final int authorCount = manager.getCloudExpansionAuthorCount();
{ final int expansionCount = manager.getCloudExpansions().size();
final CloudExpansionManager manager = plugin.getCloudExpansionManager();
final int updateCount = manager.getCloudUpdateCount(); final StringBuilder builder = new StringBuilder();
final int authorCount = manager.getCloudExpansionAuthorCount();
final int expansionCount = manager.getCloudExpansions().size();
final StringBuilder builder = new StringBuilder(); builder.append("&bThere are &a").append(expansionCount)
.append("&b expansions available on the eCloud.").append('\n');
builder.append("&7A total of &f").append(authorCount)
.append("&7 authors have contributed to the eCloud.").append('\n');
builder.append("&bThere are &a").append(expansionCount).append("&b expansions available on the eCloud.").append('\n'); if (updateCount > 0) {
builder.append("&7A total of &f").append(authorCount).append("&7 authors have contributed to the eCloud.").append('\n'); builder.append("&eYou have &f").append(updateCount)
.append(updateCount > 1 ? "&e expansions" : "&e expansion").append("installed that ")
.append(updateCount > 1 ? "have an" : "has an").append(" update available.");
}
if (updateCount > 0) Msg.msg(sender, builder.toString());
{ }
builder.append("&eYou have &f").append(updateCount).append(updateCount > 1 ? "&e expansions" : "&e expansion").append("installed that ").append(updateCount > 1 ? "have an" : "has an").append(" update available.");
}
Msg.msg(sender,builder.toString());
}
} }

View File

@ -20,6 +20,7 @@
package me.clip.placeholderapi.commands.impl.cloud; package me.clip.placeholderapi.commands.impl.cloud;
import java.util.List;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.util.Msg; import me.clip.placeholderapi.util.Msg;
@ -27,53 +28,45 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandECloudToggle extends PlaceholderCommand {
public final class CommandECloudToggle extends PlaceholderCommand public CommandECloudToggle() {
{ super("toggle", "enable", "disable");
}
public CommandECloudToggle() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("toggle", "enable", "disable"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
final boolean desiredState;
final boolean currentState = plugin.getPlaceholderAPIConfig().isCloudEnabled();
@Override switch (alias.toLowerCase()) {
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) case "enable":
{ desiredState = true;
final boolean desiredState; break;
final boolean currentState = plugin.getPlaceholderAPIConfig().isCloudEnabled(); case "disable":
desiredState = false;
break;
default:
desiredState = !currentState;
break;
}
switch (alias.toLowerCase()) if (desiredState == currentState) {
{ Msg.msg(sender, "&7The eCloud Manager is already " + (desiredState ? "enabled" : "disabled"));
case "enable": return;
desiredState = true; }
break;
case "disable":
desiredState = false;
break;
default:
desiredState = !currentState;
break;
}
if (desiredState == currentState) plugin.getPlaceholderAPIConfig().setCloudEnabled(desiredState);
{
Msg.msg(sender, "&7The eCloud Manager is already " + (desiredState ? "enabled" : "disabled"));
return;
}
plugin.getPlaceholderAPIConfig().setCloudEnabled(desiredState); if (desiredState) {
plugin.getCloudExpansionManager().load();
} else {
plugin.getCloudExpansionManager().kill();
}
if (desiredState) Msg.msg(sender, "&aThe eCloud Manager has been " + (desiredState ? "enabled" : "disabled"));
{ }
plugin.getCloudExpansionManager().load();
}
else
{
plugin.getCloudExpansionManager().kill();
}
Msg.msg(sender, "&aThe eCloud Manager has been " + (desiredState ? "enabled" : "disabled"));
}
} }

View File

@ -21,6 +21,12 @@
package me.clip.placeholderapi.commands.impl.cloud; package me.clip.placeholderapi.commands.impl.cloud;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
@ -32,114 +38,103 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
/** /**
* please don't flame me for this code, I will fix this shit later. * please don't flame me for this code, I will fix this shit later.
*/ */
public final class CommandECloudUpdate extends PlaceholderCommand public final class CommandECloudUpdate extends PlaceholderCommand {
{
public CommandECloudUpdate() public CommandECloudUpdate() {
{ super("update");
super("update"); }
}
private static CompletableFuture<List<@Nullable Class<? extends PlaceholderExpansion>>> downloadAndDiscover(
@NotNull final List<CloudExpansion> expansions, @NotNull final PlaceholderAPIPlugin plugin) {
return expansions.stream()
.map(expansion -> plugin.getCloudExpansionManager()
.downloadExpansion(expansion, expansion.getVersion()))
.map(future -> future.thenCompose(plugin.getLocalExpansionManager()::findExpansionInFile))
.collect(Futures.collector());
}
@Override @Override
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
{ @NotNull final CommandSender sender, @NotNull final String alias,
if (params.isEmpty()) @NotNull @Unmodifiable final List<String> params) {
{ if (params.isEmpty()) {
Msg.msg(sender, Msg.msg(sender,
"&cYou must define 'all' or the name of an expansion to update."); "&cYou must define 'all' or the name of an expansion to update.");
return; return;
} }
final boolean multiple = params.get(0).equalsIgnoreCase("all"); final boolean multiple = params.get(0).equalsIgnoreCase("all");
final List<CloudExpansion> expansions = new ArrayList<>(); final List<CloudExpansion> expansions = new ArrayList<>();
// gather target expansions // gather target expansions
if (multiple) if (multiple) {
{ expansions.addAll(plugin.getCloudExpansionManager().getCloudExpansionsInstalled().values());
expansions.addAll(plugin.getCloudExpansionManager().getCloudExpansionsInstalled().values()); } else {
} plugin.getCloudExpansionManager().findCloudExpansionByName(params.get(0))
else .ifPresent(expansions::add);
{ }
plugin.getCloudExpansionManager().findCloudExpansionByName(params.get(0)).ifPresent(expansions::add);
}
// remove the ones that are the latest version // remove the ones that are the latest version
expansions.removeIf(expansion -> !expansion.shouldUpdate()); expansions.removeIf(expansion -> !expansion.shouldUpdate());
if (expansions.isEmpty()) if (expansions.isEmpty()) {
{ Msg.msg(sender,
Msg.msg(sender, "&cNo updates available for " + (!multiple ? "this expansion."
"&cNo updates available for " + (!multiple ? "this expansion." : "your active expansions.")); : "your active expansions."));
return; return;
} }
Msg.msg(sender, Msg.msg(sender,
"&aUpdating expansions: " + expansions.stream().map(CloudExpansion::getName).collect(Collectors.joining("&7, &6", "&8[&6", "&8]&r"))); "&aUpdating expansions: " + expansions.stream().map(CloudExpansion::getName)
.collect(Collectors.joining("&7, &6", "&8[&6", "&8]&r")));
Futures.onMainThread(plugin, downloadAndDiscover(expansions, plugin), (classes, exception) -> {
if (exception != null) {
Msg.msg(sender,
"&cFailed to update expansions: &e" + exception.getMessage());
return;
}
Futures.onMainThread(plugin, downloadAndDiscover(expansions, plugin), (classes, exception) -> { Msg.msg(sender,
if (exception != null) "&aSuccessfully downloaded updates, registering new versions.");
{
Msg.msg(sender,
"&cFailed to update expansions: &e" + exception.getMessage());
return;
}
Msg.msg(sender, final String message = classes.stream()
"&aSuccessfully downloaded updates, registering new versions."); .filter(Objects::nonNull)
.map(plugin.getLocalExpansionManager()::register)
.filter(Optional::isPresent)
.map(Optional::get)
.map(expansion -> " &a" + expansion.getName() + " &f" + expansion.getVersion())
.collect(Collectors.joining("\n"));
Msg.msg(sender,
"&7Registered expansions:", message);
final String message = classes.stream() });
.filter(Objects::nonNull) }
.map(plugin.getLocalExpansionManager()::register)
.filter(Optional::isPresent)
.map(Optional::get)
.map(expansion -> " &a" + expansion.getName() + " &f" + expansion.getVersion())
.collect(Collectors.joining("\n"));
Msg.msg(sender, @Override
"&7Registered expansions:", message); public void complete(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
if (params.size() > 1) {
return;
}
}); final List<CloudExpansion> installed = Lists
} .newArrayList(plugin.getCloudExpansionManager().getCloudExpansionsInstalled().values());
installed.removeIf(expansion -> !expansion.shouldUpdate());
@Override if (!installed.isEmpty() && (params.isEmpty() || "all"
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) .startsWith(params.get(0).toLowerCase()))) {
{ suggestions.add("all");
if (params.size() > 1) }
{
return;
}
final List<CloudExpansion> installed = Lists.newArrayList(plugin.getCloudExpansionManager().getCloudExpansionsInstalled().values()); suggestByParameter(
installed.removeIf(expansion -> !expansion.shouldUpdate()); installed.stream().map(CloudExpansion::getName).map(name -> name.replace(" ", "_")),
suggestions, params.isEmpty() ? null : params.get(0));
if (!installed.isEmpty() && (params.isEmpty() || "all".startsWith(params.get(0).toLowerCase()))) }
{
suggestions.add("all");
}
suggestByParameter(installed.stream().map(CloudExpansion::getName).map(name -> name.replace(" ", "_")), suggestions, params.isEmpty() ? null : params.get(0));
}
private static CompletableFuture<List<@Nullable Class<? extends PlaceholderExpansion>>> downloadAndDiscover(@NotNull final List<CloudExpansion> expansions, @NotNull final PlaceholderAPIPlugin plugin)
{
return expansions.stream()
.map(expansion -> plugin.getCloudExpansionManager().downloadExpansion(expansion, expansion.getVersion()))
.map(future -> future.thenCompose(plugin.getLocalExpansionManager()::findExpansionInFile))
.collect(Futures.collector());
}
} }

View File

@ -22,15 +22,6 @@ package me.clip.placeholderapi.commands.impl.local;
import com.google.common.io.CharStreams; import com.google.common.io.CharStreams;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -50,164 +41,165 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.util.Msg;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
public final class CommandDump extends PlaceholderCommand public final class CommandDump extends PlaceholderCommand {
{
@NotNull
@NotNull private static final String URL = "https://paste.helpch.at/";
private static final String URL = "https://paste.helpch.at/";
@NotNull
@NotNull private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG) .ofLocalizedDateTime(FormatStyle.LONG)
.withLocale(Locale.US) .withLocale(Locale.US)
.withZone(ZoneId.of("UTC")); .withZone(ZoneId.of("UTC"));
public CommandDump() public CommandDump() {
{ super("dump");
super("dump"); }
}
@Override
@Override public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) @NotNull final CommandSender sender, @NotNull final String alias,
{ @NotNull @Unmodifiable final List<String> params) {
postDump(makeDump(plugin)).whenComplete((key, exception) -> { postDump(makeDump(plugin)).whenComplete((key, exception) -> {
if (exception != null) if (exception != null) {
{ plugin.getLogger().log(Level.WARNING, "failed to post dump details", exception);
plugin.getLogger().log(Level.WARNING, "failed to post dump details", exception);
Msg.msg(sender,
Msg.msg(sender, "&cFailed to post dump details, check console.");
"&cFailed to post dump details, check console."); return;
return; }
}
Msg.msg(sender,
Msg.msg(sender, "&aSuccessfully posted dump: " + URL + key);
"&aSuccessfully posted dump: " + URL + key); });
}); }
}
@NotNull
@NotNull private CompletableFuture<String> postDump(@NotNull final String dump) {
private CompletableFuture<String> postDump(@NotNull final String dump) return CompletableFuture.supplyAsync(() -> {
{ try {
return CompletableFuture.supplyAsync(() -> { final HttpURLConnection connection = ((HttpURLConnection) new URL(URL + "documents")
try .openConnection());
{ connection.setRequestMethod("POST");
final HttpURLConnection connection = ((HttpURLConnection) new URL(URL + "documents").openConnection()); connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
connection.setRequestMethod("POST"); connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
connection.setDoOutput(true); connection.connect();
connection.connect(); try (final OutputStream stream = connection.getOutputStream()) {
stream.write(dump.getBytes(StandardCharsets.UTF_8));
try (final OutputStream stream = connection.getOutputStream()) }
{
stream.write(dump.getBytes(StandardCharsets.UTF_8)); try (final InputStream stream = connection.getInputStream()) {
} //noinspection UnstableApiUsage
final String json = CharStreams
try (final InputStream stream = connection.getInputStream()) .toString(new InputStreamReader(stream, StandardCharsets.UTF_8));
{ return JsonParser.parseString(json).getAsJsonObject().get("key").getAsString();
//noinspection UnstableApiUsage }
final String json = CharStreams.toString(new InputStreamReader(stream, StandardCharsets.UTF_8)); } catch (final IOException ex) {
return JsonParser.parseString(json).getAsJsonObject().get("key").getAsString(); throw new CompletionException(ex);
} }
} });
catch (final IOException ex) }
{
throw new CompletionException(ex); @NotNull
} private String makeDump(@NotNull final PlaceholderAPIPlugin plugin) {
}); final StringBuilder builder = new StringBuilder();
}
builder.append("Generated: ")
@NotNull .append(DATE_FORMAT.format(Instant.now()))
private String makeDump(@NotNull final PlaceholderAPIPlugin plugin) .append("\n\n");
{
final StringBuilder builder = new StringBuilder(); builder.append("PlaceholderAPI: ")
.append(plugin.getDescription().getVersion())
builder.append("Generated: ") .append("\n\n");
.append(DATE_FORMAT.format(Instant.now()))
.append("\n\n"); builder.append("Expansions Registered:")
.append('\n');
builder.append("PlaceholderAPI: ")
.append(plugin.getDescription().getVersion()) final List<PlaceholderExpansion> expansions = plugin.getLocalExpansionManager()
.append("\n\n"); .getExpansions()
.stream()
builder.append("Expansions Registered:") .sorted(Comparator.comparing(PlaceholderExpansion::getIdentifier))
.append('\n'); .sorted(Comparator.comparing(PlaceholderExpansion::getAuthor))
.collect(Collectors.toList());
final List<PlaceholderExpansion> expansions = plugin.getLocalExpansionManager()
.getExpansions() int size = 0;
.stream()
.sorted(Comparator.comparing(PlaceholderExpansion::getIdentifier)) for (final String name : expansions.stream().map(PlaceholderExpansion::getIdentifier)
.sorted(Comparator.comparing(PlaceholderExpansion::getAuthor)) .collect(Collectors.toList())) {
.collect(Collectors.toList()); if (name.length() > size) {
size = name.length();
int size = 0; }
}
for(final String name : expansions.stream().map(PlaceholderExpansion::getIdentifier).collect(Collectors.toList())){
if (name.length() > size) { for (final PlaceholderExpansion expansion : expansions) {
size = name.length(); builder.append(" ")
} .append(String.format("%-" + size + "s", expansion.getIdentifier()))
} .append(" [Author: ")
.append(expansion.getAuthor())
for (final PlaceholderExpansion expansion : expansions) { .append(", Version: ")
builder.append(" ") .append(expansion.getVersion())
.append(String.format("%-" + size + "s", expansion.getIdentifier())) .append("]\n");
.append(" [Author: ")
.append(expansion.getAuthor()) }
.append(", Version: ")
.append(expansion.getVersion()) builder.append('\n');
.append("]\n");
builder.append("Expansions Directory:")
} .append('\n');
builder.append('\n'); final String[] jars = plugin.getLocalExpansionManager()
.getExpansionsFolder()
builder.append("Expansions Directory:") .list((dir, name) -> name.toLowerCase().endsWith(".jar"));
.append('\n');
for (final String jar : jars) {
final String[] jars = plugin.getLocalExpansionManager() builder.append(" ")
.getExpansionsFolder() .append(jar)
.list((dir, name) -> name.toLowerCase().endsWith(".jar")); .append('\n');
}
for (final String jar : jars)
{ builder.append('\n');
builder.append(" ")
.append(jar) builder.append("Server Info: ")
.append('\n'); .append(plugin.getServer().getBukkitVersion())
} .append('/')
.append(plugin.getServer().getVersion())
builder.append('\n'); .append("\n\n");
builder.append("Plugin Info:")
builder.append("Server Info: ") .append('\n');
.append(plugin.getServer().getBukkitVersion())
.append('/') List<Plugin> plugins = Arrays.stream(plugin.getServer().getPluginManager().getPlugins())
.append(plugin.getServer().getVersion()) .sorted(Comparator.comparing(Plugin::getName))
.append("\n\n"); .collect(Collectors.toList());
builder.append("Plugin Info:") for (final String pluginName : plugins.stream().map(Plugin::getName)
.append('\n'); .collect(Collectors.toList())) {
if (pluginName.length() > size) {
List<Plugin> plugins = Arrays.stream(plugin.getServer().getPluginManager().getPlugins()) size = pluginName.length();
.sorted(Comparator.comparing(Plugin::getName)) }
.collect(Collectors.toList()); }
for (final String pluginName : plugins.stream().map(Plugin::getName).collect(Collectors.toList())) { for (final Plugin other : plugins) {
if (pluginName.length() > size) { builder.append(" ")
size = pluginName.length(); .append(String.format("%-" + size + "s", other.getName()))
} .append(" [Version: ")
} .append(other.getDescription().getVersion())
.append("]")
for (final Plugin other : plugins) .append("\n");
{ }
builder.append(" ")
.append(String.format("%-" + size + "s", other.getName())) return builder.toString();
.append(" [Version: ") }
.append(other.getDescription().getVersion())
.append("]")
.append("\n");
}
return builder.toString();
}
} }

View File

@ -20,6 +20,11 @@
package me.clip.placeholderapi.commands.impl.local; package me.clip.placeholderapi.commands.impl.local;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
@ -30,88 +35,76 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.io.File; public final class CommandExpansionRegister extends PlaceholderCommand {
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.logging.Level;
public final class CommandExpansionRegister extends PlaceholderCommand public CommandExpansionRegister() {
{ super("register");
}
public CommandExpansionRegister() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("register"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
if (params.size() < 1) {
Msg.msg(sender,
"&cYou must specify the name of an expansion file.");
return;
}
@Override final LocalExpansionManager manager = plugin.getLocalExpansionManager();
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params)
{
if (params.size() < 1)
{
Msg.msg(sender,
"&cYou must specify the name of an expansion file.");
return;
}
final File file = new File(manager.getExpansionsFolder(), params.get(0));
if (!file.exists()) {
Msg.msg(sender,
"&cThe file &f" + file.getName() + "&c doesn't exist!");
return;
}
final LocalExpansionManager manager = plugin.getLocalExpansionManager(); Futures.onMainThread(plugin, manager.findExpansionInFile(file), (clazz, exception) -> {
if (exception != null) {
Msg.msg(sender,
"&cFailed to find expansion in file: &f" + file);
final File file = new File(manager.getExpansionsFolder(), params.get(0)); plugin.getLogger()
if (!file.exists()) .log(Level.WARNING, "failed to find expansion in file: " + file, exception);
{ return;
Msg.msg(sender, }
"&cThe file &f" + file.getName() + "&c doesn't exist!");
return;
}
Futures.onMainThread(plugin, manager.findExpansionInFile(file), (clazz, exception) -> { if (clazz == null) {
if (exception != null) Msg.msg(sender,
{ "&cNo expansion class found in file: &f" + file);
Msg.msg(sender, return;
"&cFailed to find expansion in file: &f" + file); }
plugin.getLogger().log(Level.WARNING, "failed to find expansion in file: " + file, exception); final Optional<PlaceholderExpansion> expansion = manager.register(clazz);
return; if (!expansion.isPresent()) {
} Msg.msg(sender,
"&cFailed to register expansion from &f" + params.get(0));
return;
}
if (clazz == null) Msg.msg(sender,
{ "&aSuccessfully registered expansion: &f" + expansion.get().getName());
Msg.msg(sender,
"&cNo expansion class found in file: &f" + file);
return;
}
});
}
final Optional<PlaceholderExpansion> expansion = manager.register(clazz); @Override
if (!expansion.isPresent()) public void complete(@NotNull final PlaceholderAPIPlugin plugin,
{ @NotNull final CommandSender sender, @NotNull final String alias,
Msg.msg(sender, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
"&cFailed to register expansion from &f" + params.get(0)); if (params.size() > 1) {
return; return;
} }
Msg.msg(sender, final String[] fileNames = plugin.getLocalExpansionManager().getExpansionsFolder()
"&aSuccessfully registered expansion: &f" + expansion.get().getName()); .list((dir, name) -> name.endsWith(".jar"));
if (fileNames == null || fileNames.length == 0) {
return;
}
}); suggestByParameter(Arrays.stream(fileNames), suggestions,
} params.isEmpty() ? null : params.get(0));
}
@Override
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions)
{
if (params.size() > 1)
{
return;
}
final String[] fileNames = plugin.getLocalExpansionManager().getExpansionsFolder().list((dir, name) -> name.endsWith(".jar"));
if (fileNames == null || fileNames.length == 0)
{
return;
}
suggestByParameter(Arrays.stream(fileNames), suggestions, params.isEmpty() ? null : params.get(0));
}
} }

View File

@ -20,6 +20,8 @@
package me.clip.placeholderapi.commands.impl.local; package me.clip.placeholderapi.commands.impl.local;
import java.util.List;
import java.util.Optional;
import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
@ -29,52 +31,47 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandExpansionUnregister extends PlaceholderCommand {
import java.util.Optional;
public final class CommandExpansionUnregister extends PlaceholderCommand public CommandExpansionUnregister() {
{ super("unregister");
}
public CommandExpansionUnregister() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("unregister"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
if (params.isEmpty()) {
Msg.msg(sender,
"&cYou must specify the name of the expansion.");
return;
}
@Override final Optional<PlaceholderExpansion> expansion = plugin.getLocalExpansionManager()
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) .findExpansionByName(params.get(0));
{ if (!expansion.isPresent()) {
if (params.isEmpty()) Msg.msg(sender,
{ "&cThere is no expansion loaded with the identifier: &f" + params.get(0));
Msg.msg(sender, return;
"&cYou must specify the name of the expansion."); }
return;
}
final Optional<PlaceholderExpansion> expansion = plugin.getLocalExpansionManager().findExpansionByName(params.get(0)); final String message = !expansion.get().unregister() ?
if (!expansion.isPresent()) "&cFailed to unregister expansion: &f" :
{ "&aSuccessfully unregistered expansion: &f";
Msg.msg(sender,
"&cThere is no expansion loaded with the identifier: &f" + params.get(0));
return;
}
Msg.msg(sender, message + expansion.get().getName());
}
final String message = !expansion.get().unregister() ? @Override
"&cFailed to unregister expansion: &f" : public void complete(@NotNull final PlaceholderAPIPlugin plugin,
"&aSuccessfully unregistered expansion: &f"; @NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
if (params.size() > 1) {
return;
}
Msg.msg(sender, message + expansion.get().getName()); suggestByParameter(PlaceholderAPI.getRegisteredIdentifiers().stream(), suggestions,
} params.isEmpty() ? null : params.get(0));
}
@Override
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions)
{
if (params.size() > 1)
{
return;
}
suggestByParameter(PlaceholderAPI.getRegisteredIdentifiers().stream(), suggestions, params.isEmpty() ? null : params.get(0));
}
} }

View File

@ -20,6 +20,7 @@
package me.clip.placeholderapi.commands.impl.local; package me.clip.placeholderapi.commands.impl.local;
import java.util.List;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.util.Msg; import me.clip.placeholderapi.util.Msg;
@ -28,47 +29,44 @@ import org.bukkit.plugin.PluginDescriptionFile;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandHelp extends PlaceholderCommand {
public final class CommandHelp extends PlaceholderCommand public CommandHelp() {
{ super("help");
}
public CommandHelp()
{
super("help");
}
@Override @Override
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
{ @NotNull final CommandSender sender, @NotNull final String alias,
final PluginDescriptionFile description = plugin.getDescription(); @NotNull @Unmodifiable final List<String> params) {
final PluginDescriptionFile description = plugin.getDescription();
Msg.msg(sender, Msg.msg(sender,
"&b&lPlaceholderAPI &8- &7Help Menu &8- &7(&f" + description.getVersion() + "&7)", "&b&lPlaceholderAPI &8- &7Help Menu &8- &7(&f" + description.getVersion() + "&7)",
" ", " ",
"&b/papi &fbcparse &9<me/player name> <message>", "&b/papi &fbcparse &9<me/player name> <message>",
" &7&oParse a message with placeholders and broadcast it", " &7&oParse a message with placeholders and broadcast it",
"&b/papi &fcmdparse &9<me/player> <command with placeholders>", "&b/papi &fcmdparse &9<me/player> <command with placeholders>",
" &7&oParse a message with relational placeholders", " &7&oParse a message with relational placeholders",
"&b/papi &fdump", "&b/papi &fdump",
" &7&oDump all relevant information needed to help debug issues into a paste link.", " &7&oDump all relevant information needed to help debug issues into a paste link.",
"&b/papi &finfo &9<placeholder name>", "&b/papi &finfo &9<placeholder name>",
" &7&oView information for a specific expansion", " &7&oView information for a specific expansion",
"&b/papi &flist", "&b/papi &flist",
" &7&oList active expansions", " &7&oList active expansions",
"&b/papi &fparse &9<me/player name> <message>", "&b/papi &fparse &9<me/player name> <message>",
" &7&oParse a message with placeholders", " &7&oParse a message with placeholders",
"&b/papi &fparserel &9<player one> <player two> <message>", "&b/papi &fparserel &9<player one> <player two> <message>",
" &7&oParse a message with relational placeholders", " &7&oParse a message with relational placeholders",
"&b/papi &fregister &9<file name>", "&b/papi &fregister &9<file name>",
" &7&oRegister an expansion by the name of the file", " &7&oRegister an expansion by the name of the file",
"&b/papi &freload", "&b/papi &freload",
" &7&oReload the config of PAPI", " &7&oReload the config of PAPI",
"&b/papi &funregister &9<expansion name>", "&b/papi &funregister &9<expansion name>",
" &7&oUnregister an expansion by name", " &7&oUnregister an expansion by name",
"&b/papi &fversion", "&b/papi &fversion",
" &7&oView plugin info/version"); " &7&oView plugin info/version");
} }
} }

View File

@ -20,6 +20,7 @@
package me.clip.placeholderapi.commands.impl.local; package me.clip.placeholderapi.commands.impl.local;
import java.util.List;
import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
@ -29,92 +30,84 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandInfo extends PlaceholderCommand {
public final class CommandInfo extends PlaceholderCommand public CommandInfo() {
{ super("info");
}
public CommandInfo() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("info"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
if (params.isEmpty()) {
Msg.msg(sender,
"&cYou must specify the name of the expansion.");
return;
}
@Override final PlaceholderExpansion expansion = plugin.getLocalExpansionManager()
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) .findExpansionByName(params.get(0)).orElse(null);
{ if (expansion == null) {
if (params.isEmpty()) Msg.msg(sender,
{ "&cThere is no expansion loaded with the identifier: &f" + params.get(0));
Msg.msg(sender, return;
"&cYou must specify the name of the expansion."); }
return;
}
final PlaceholderExpansion expansion = plugin.getLocalExpansionManager().findExpansionByName(params.get(0)).orElse(null); final StringBuilder builder = new StringBuilder();
if (expansion == null)
{
Msg.msg(sender,
"&cThere is no expansion loaded with the identifier: &f" + params.get(0));
return;
}
final StringBuilder builder = new StringBuilder(); builder.append("&7Placeholder expansion info for: &r")
.append(expansion.getName())
.append('\n')
.append("&7Status: &r")
.append(expansion.isRegistered() ? "&aRegistered" : "7cNotRegistered")
.append('\n');
builder.append("&7Placeholder expansion info for: &r") final String author = expansion.getAuthor();
.append(expansion.getName()) if (author != null) {
.append('\n') builder.append("&7Author: &r")
.append("&7Status: &r") .append(author)
.append(expansion.isRegistered() ? "&aRegistered" : "7cNotRegistered") .append('\n');
.append('\n'); }
final String author = expansion.getAuthor(); final String version = expansion.getVersion();
if (author != null) if (version != null) {
{ builder.append("&7Version: &r")
builder.append("&7Author: &r") .append(version)
.append(author) .append('\n');
.append('\n'); }
}
final String version = expansion.getVersion(); final String requiredPlugin = expansion.getRequiredPlugin();
if (version != null) if (requiredPlugin != null) {
{ builder.append("&7Requires plugin: &r")
builder.append("&7Version: &r") .append(requiredPlugin)
.append(version) .append('\n');
.append('\n'); }
}
final String requiredPlugin = expansion.getRequiredPlugin(); final List<String> placeholders = expansion.getPlaceholders();
if (requiredPlugin != null) if (placeholders != null && !placeholders.isEmpty()) {
{ builder.append("&8&m-- &7Placeholders &8&m--&r")
builder.append("&7Requires plugin: &r") .append('\n');
.append(requiredPlugin)
.append('\n');
}
final List<String> placeholders = expansion.getPlaceholders(); for (final String placeholder : placeholders) {
if (placeholders != null && !placeholders.isEmpty()) builder.append(placeholder)
{ .append('\n');
builder.append("&8&m-- &7Placeholders &8&m--&r") }
.append('\n'); }
for (final String placeholder : placeholders) Msg.msg(sender, builder.toString());
{ }
builder.append(placeholder)
.append('\n');
}
}
Msg.msg(sender, builder.toString()); @Override
} public void complete(@NotNull final PlaceholderAPIPlugin plugin,
@NotNull final CommandSender sender, @NotNull final String alias,
@NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
if (params.size() > 1) {
return;
}
@Override suggestByParameter(PlaceholderAPI.getRegisteredIdentifiers().stream(), suggestions,
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) params.isEmpty() ? null : params.get(0));
{ }
if (params.size() > 1)
{
return;
}
suggestByParameter(PlaceholderAPI.getRegisteredIdentifiers().stream(), suggestions, params.isEmpty() ? null : params.get(0));
}
} }

View File

@ -21,6 +21,9 @@
package me.clip.placeholderapi.commands.impl.local; package me.clip.placeholderapi.commands.impl.local;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
@ -29,34 +32,30 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandList extends PlaceholderCommand {
import java.util.Set;
import java.util.stream.Collectors;
public final class CommandList extends PlaceholderCommand public CommandList() {
{ super("list");
}
public CommandList()
{
super("list");
}
@Override @Override
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
{ @NotNull final CommandSender sender, @NotNull final String alias,
final Set<String> identifiers = PlaceholderAPI.getRegisteredIdentifiers(); @NotNull @Unmodifiable final List<String> params) {
if (identifiers.isEmpty()) final Set<String> identifiers = PlaceholderAPI.getRegisteredIdentifiers();
{ if (identifiers.isEmpty()) {
Msg.msg(sender, "&cThere are no placeholder hooks active!"); Msg.msg(sender, "&cThere are no placeholder hooks active!");
return; return;
} }
final List<List<String>> partitions = Lists.partition(identifiers.stream().sorted().collect(Collectors.toList()), 10); final List<List<String>> partitions = Lists
.partition(identifiers.stream().sorted().collect(Collectors.toList()), 10);
Msg.msg(sender, Msg.msg(sender,
"&7A total of &f" + identifiers.size() + "&7 placeholder hook(s) are active: &a", "&7A total of &f" + identifiers.size() + "&7 placeholder hook(s) are active: &a",
partitions.stream().map(partition -> String.join("&7, &a", partition)).collect(Collectors.joining("\n"))); partitions.stream().map(partition -> String.join("&7, &a", partition))
} .collect(Collectors.joining("\n")));
}
} }

View File

@ -20,6 +20,10 @@
package me.clip.placeholderapi.commands.impl.local; package me.clip.placeholderapi.commands.impl.local;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
@ -34,210 +38,187 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.Collection; public final class CommandParse extends PlaceholderCommand {
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
public final class CommandParse extends PlaceholderCommand public CommandParse() {
{ super("parse", "bcparse", "parserel", "cmdparse");
}
public CommandParse()
{
super("parse", "bcparse", "parserel", "cmdparse");
}
@Override @Override
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
{ @NotNull final CommandSender sender, @NotNull final String alias,
switch (alias.toLowerCase()) @NotNull @Unmodifiable final List<String> params) {
{ switch (alias.toLowerCase()) {
case "parserel": case "parserel":
evaluateParseRelation(sender, params); evaluateParseRelation(sender, params);
break; break;
case "parse": case "parse":
evaluateParseSingular(sender, params, false, false); evaluateParseSingular(sender, params, false, false);
break; break;
case "bcparse": case "bcparse":
evaluateParseSingular(sender, params, true, false); evaluateParseSingular(sender, params, true, false);
break; break;
case "cmdparse": case "cmdparse":
evaluateParseSingular(sender, params, false, true); evaluateParseSingular(sender, params, false, true);
break; break;
} }
} }
@Override @Override
public void complete(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) public void complete(@NotNull final PlaceholderAPIPlugin plugin,
{ @NotNull final CommandSender sender, @NotNull final String alias,
switch (alias.toLowerCase()) @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
{ switch (alias.toLowerCase()) {
case "parserel": case "parserel":
completeParseRelation(params, suggestions); completeParseRelation(params, suggestions);
break; break;
case "parse": case "parse":
case "bcparse": case "bcparse":
case "cmdparse": case "cmdparse":
completeParseSingular(sender, params, suggestions); completeParseSingular(sender, params, suggestions);
break; break;
} }
} }
private void evaluateParseSingular(@NotNull final CommandSender sender, @NotNull @Unmodifiable final List<String> params, final boolean broadcast, final boolean command) private void evaluateParseSingular(@NotNull final CommandSender sender,
{ @NotNull @Unmodifiable final List<String> params, final boolean broadcast,
if (params.size() < 2) final boolean command) {
{ if (params.size() < 2) {
Msg.msg(sender, "&cYou must supply a target, and a message: &b/papi " + (broadcast ? "bcparse" : "parse") + " &7{target} &a{message}"); Msg.msg(sender,
return; "&cYou must supply a target, and a message: &b/papi " + (broadcast ? "bcparse" : "parse")
} + " &7{target} &a{message}");
return;
}
@NotNull final OfflinePlayer player; @NotNull final OfflinePlayer player;
if ("me".equalsIgnoreCase(params.get(0))) if ("me".equalsIgnoreCase(params.get(0))) {
{ if (!(sender instanceof Player)) {
if (!(sender instanceof Player)) Msg.msg(sender, "&cYou must be a player to use &7me&c as a target!");
{ return;
Msg.msg(sender, "&cYou must be a player to use &7me&c as a target!"); }
return;
}
player = ((Player) sender); player = ((Player) sender);
} } else {
else final OfflinePlayer target = resolvePlayer(params.get(0));
{ if (target == null) {
final OfflinePlayer target = resolvePlayer(params.get(0)); Msg.msg(sender, "&cFailed to find player: &7" + params.get(0));
if (target == null) return;
{ }
Msg.msg(sender, "&cFailed to find player: &7" + params.get(0));
return;
}
player = target; player = target;
} }
final String message = PlaceholderAPI.setPlaceholders(player, String.join(" ", params.subList(1, params.size()))); final String message = PlaceholderAPI
.setPlaceholders(player, String.join(" ", params.subList(1, params.size())));
if (command) if (command) {
{ Bukkit.dispatchCommand(sender, message);
Bukkit.dispatchCommand(sender, message); return;
return; }
}
if (broadcast) if (broadcast) {
{ Msg.broadcast(message);
Msg.broadcast(message); } else {
} if (!(sender instanceof Player)) {
else Msg.msg(sender, message);
{ } else {
if (!(sender instanceof Player)) ((Player) sender).spigot().sendMessage(TextComponent.fromLegacyText(message));
{ }
Msg.msg(sender, message); }
} }
else
{
((Player) sender).spigot().sendMessage(TextComponent.fromLegacyText(message));
}
}
}
private void evaluateParseRelation(@NotNull final CommandSender sender, @NotNull @Unmodifiable final List<String> params) private void evaluateParseRelation(@NotNull final CommandSender sender,
{ @NotNull @Unmodifiable final List<String> params) {
if (params.size() < 3) if (params.size() < 3) {
{ Msg.msg(sender,
Msg.msg(sender, "&cYou must supply two targets, and a message: &b/papi parserel &7{target one} {target two} &a{message}"); "&cYou must supply two targets, and a message: &b/papi parserel &7{target one} {target two} &a{message}");
return; return;
} }
final OfflinePlayer targetOne = resolvePlayer(params.get(0)); final OfflinePlayer targetOne = resolvePlayer(params.get(0));
if (targetOne == null || !targetOne.isOnline()) if (targetOne == null || !targetOne.isOnline()) {
{ Msg.msg(sender, "&cFailed to find player: &f" + params.get(0));
Msg.msg(sender, "&cFailed to find player: &f" + params.get(0)); return;
return; }
}
final OfflinePlayer targetTwo = resolvePlayer(params.get(1)); final OfflinePlayer targetTwo = resolvePlayer(params.get(1));
if (targetTwo == null || !targetTwo.isOnline()) if (targetTwo == null || !targetTwo.isOnline()) {
{ Msg.msg(sender, "&cFailed to find player: &f" + params.get(1));
Msg.msg(sender, "&cFailed to find player: &f" + params.get(1)); return;
return; }
}
final String message = PlaceholderAPI.setRelationalPlaceholders(((Player) targetOne), ((Player) targetTwo), String.join(" ", params.subList(2, params.size()))); final String message = PlaceholderAPI
Msg.msg(sender, message); .setRelationalPlaceholders(((Player) targetOne), ((Player) targetTwo),
} String.join(" ", params.subList(2, params.size())));
Msg.msg(sender, message);
}
private void completeParseSingular(@NotNull final CommandSender sender, @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) private void completeParseSingular(@NotNull final CommandSender sender,
{ @NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) {
if (params.size() <= 1) if (params.size() <= 1) {
{ if (sender instanceof Player && (params.isEmpty() || "me"
if (sender instanceof Player && (params.isEmpty() || "me".startsWith(params.get(0).toLowerCase()))) .startsWith(params.get(0).toLowerCase()))) {
{ suggestions.add("me");
suggestions.add("me"); }
}
final Stream<String> names = Bukkit.getOnlinePlayers().stream().map(Player::getName); final Stream<String> names = Bukkit.getOnlinePlayers().stream().map(Player::getName);
suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(0)); suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(0));
return; return;
} }
final String name = params.get(params.size() - 1); final String name = params.get(params.size() - 1);
if (!name.startsWith("%") || name.endsWith("%")) if (!name.startsWith("%") || name.endsWith("%")) {
{ return;
return; }
}
final int index = name.indexOf('_'); final int index = name.indexOf('_');
if (index == -1) if (index == -1) {
{ return; // no arguments supplied yet
return; // no arguments supplied yet }
}
final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance().getLocalExpansionManager().findExpansionByIdentifier(name.substring(1, index)).orElse(null); final PlaceholderExpansion expansion = PlaceholderAPIPlugin.getInstance()
if (expansion == null) .getLocalExpansionManager().findExpansionByIdentifier(name.substring(1, index))
{ .orElse(null);
return; if (expansion == null) {
} return;
}
final Set<String> possible = new HashSet<>(expansion.getPlaceholders()); final Set<String> possible = new HashSet<>(expansion.getPlaceholders());
PlaceholderAPIPlugin.getInstance() PlaceholderAPIPlugin.getInstance()
.getCloudExpansionManager() .getCloudExpansionManager()
.findCloudExpansionByName(expansion.getName()) .findCloudExpansionByName(expansion.getName())
.ifPresent(cloud -> possible.addAll(cloud.getPlaceholders())); .ifPresent(cloud -> possible.addAll(cloud.getPlaceholders()));
suggestByParameter(possible.stream(), suggestions, params.get(params.size() - 1)); suggestByParameter(possible.stream(), suggestions, params.get(params.size() - 1));
} }
private void completeParseRelation(@NotNull @Unmodifiable final List<String> params, @NotNull final List<String> suggestions) private void completeParseRelation(@NotNull @Unmodifiable final List<String> params,
{ @NotNull final List<String> suggestions) {
if (params.size() > 2) if (params.size() > 2) {
{ return;
return; }
}
final Stream<String> names = Bukkit.getOnlinePlayers().stream().map(Player::getName); final Stream<String> names = Bukkit.getOnlinePlayers().stream().map(Player::getName);
suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(params.size() - 1)); suggestByParameter(names, suggestions, params.isEmpty() ? null : params.get(params.size() - 1));
} }
@Nullable @Nullable
private OfflinePlayer resolvePlayer(@NotNull final String name) private OfflinePlayer resolvePlayer(@NotNull final String name) {
{ OfflinePlayer target = Bukkit.getPlayer(name);
OfflinePlayer target = Bukkit.getPlayer(name);
if (target == null) if (target == null) {
{ target = Bukkit.getOfflinePlayer(name); // this is probably not a great idea.
target = Bukkit.getOfflinePlayer(name); // this is probably not a great idea. }
}
return target.hasPlayedBefore() ? target : null; return target.hasPlayedBefore() ? target : null;
} }
} }

View File

@ -20,26 +20,24 @@
package me.clip.placeholderapi.commands.impl.local; package me.clip.placeholderapi.commands.impl.local;
import java.util.List;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandReload extends PlaceholderCommand {
public final class CommandReload extends PlaceholderCommand public CommandReload() {
{ super("reload");
}
public CommandReload() @Override
{ public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
super("reload"); @NotNull final CommandSender sender, @NotNull final String alias,
} @NotNull @Unmodifiable final List<String> params) {
plugin.reloadConf(sender);
@Override }
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params)
{
plugin.reloadConf(sender);
}
} }

View File

@ -20,6 +20,7 @@
package me.clip.placeholderapi.commands.impl.local; package me.clip.placeholderapi.commands.impl.local;
import java.util.List;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.commands.PlaceholderCommand; import me.clip.placeholderapi.commands.PlaceholderCommand;
import me.clip.placeholderapi.util.Msg; import me.clip.placeholderapi.util.Msg;
@ -28,27 +29,24 @@ import org.bukkit.plugin.PluginDescriptionFile;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.util.List; public final class CommandVersion extends PlaceholderCommand {
public final class CommandVersion extends PlaceholderCommand public CommandVersion() {
{ super("version");
}
public CommandVersion()
{
super("version");
}
@Override @Override
public void evaluate(@NotNull final PlaceholderAPIPlugin plugin, @NotNull final CommandSender sender, @NotNull final String alias, @NotNull @Unmodifiable final List<String> params) public void evaluate(@NotNull final PlaceholderAPIPlugin plugin,
{ @NotNull final CommandSender sender, @NotNull final String alias,
final PluginDescriptionFile description = plugin.getDescription(); @NotNull @Unmodifiable final List<String> params) {
final PluginDescriptionFile description = plugin.getDescription();
Msg.msg(sender, Msg.msg(sender,
"&b&lPlaceholderAPI &7(&f" + description.getVersion() + "&7)", "&b&lPlaceholderAPI &7(&f" + description.getVersion() + "&7)",
"&7Author: &f" + description.getAuthors(), "&7Author: &f" + description.getAuthors(),
"&7PAPI Commands: &b/papi &fhelp", "&7PAPI Commands: &b/papi &fhelp",
"&7eCloud Commands&8: &b/papi &fecloud"); "&7eCloud Commands&8: &b/papi &fecloud");
} }
} }

View File

@ -20,32 +20,28 @@
package me.clip.placeholderapi.configuration; package me.clip.placeholderapi.configuration;
import java.util.Comparator;
import me.clip.placeholderapi.expansion.cloud.CloudExpansion; import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Comparator; public enum ExpansionSort implements Comparator<CloudExpansion> {
public enum ExpansionSort implements Comparator<CloudExpansion> NAME(Comparator.comparing(CloudExpansion::getName)),
{ AUTHOR(Comparator.comparing(CloudExpansion::getAuthor)),
LATEST(Comparator.comparing(CloudExpansion::getLastUpdate).reversed());
NAME(Comparator.comparing(CloudExpansion::getName)),
AUTHOR(Comparator.comparing(CloudExpansion::getAuthor)),
LATEST(Comparator.comparing(CloudExpansion::getLastUpdate).reversed());
@NotNull @NotNull
private final Comparator<CloudExpansion> comparator; private final Comparator<CloudExpansion> comparator;
ExpansionSort(@NotNull final Comparator<CloudExpansion> comparator) ExpansionSort(@NotNull final Comparator<CloudExpansion> comparator) {
{ this.comparator = comparator;
this.comparator = comparator; }
}
@Override @Override
public final int compare(final CloudExpansion expansion1, final CloudExpansion expansion2) public final int compare(final CloudExpansion expansion1, final CloudExpansion expansion2) {
{ return comparator.compare(expansion1, expansion2);
return comparator.compare(expansion1, expansion2); }
}
} }

View File

@ -20,88 +20,74 @@
package me.clip.placeholderapi.configuration; package me.clip.placeholderapi.configuration;
import java.util.Optional;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Optional; public final class PlaceholderAPIConfig {
public final class PlaceholderAPIConfig @NotNull
{ private final PlaceholderAPIPlugin plugin;
@NotNull public PlaceholderAPIConfig(@NotNull final PlaceholderAPIPlugin plugin) {
private final PlaceholderAPIPlugin plugin; this.plugin = plugin;
}
public PlaceholderAPIConfig(@NotNull final PlaceholderAPIPlugin plugin)
{
this.plugin = plugin;
}
public boolean checkUpdates() public boolean checkUpdates() {
{ return plugin.getConfig().getBoolean("check_updates");
return plugin.getConfig().getBoolean("check_updates"); }
}
public boolean cloudAllowUnverifiedExpansions() public boolean cloudAllowUnverifiedExpansions() {
{ return plugin.getConfig().getBoolean("cloud_allow_unverified_expansions");
return plugin.getConfig().getBoolean("cloud_allow_unverified_expansions"); }
}
public boolean isCloudEnabled() public boolean isCloudEnabled() {
{ return plugin.getConfig().getBoolean("cloud_enabled");
return plugin.getConfig().getBoolean("cloud_enabled"); }
}
public void setCloudEnabled(boolean state) public void setCloudEnabled(boolean state) {
{ plugin.getConfig().set("cloud_enabled", state);
plugin.getConfig().set("cloud_enabled", state); plugin.saveConfig();
plugin.saveConfig(); }
}
public boolean isDebugMode() public boolean isDebugMode() {
{ return plugin.getConfig().getBoolean("debug", false);
return plugin.getConfig().getBoolean("debug", false); }
}
public Optional<ExpansionSort> getExpansionSort() public Optional<ExpansionSort> getExpansionSort() {
{ final String option = plugin.getConfig()
final String option = plugin.getConfig().getString("cloud_sorting", ExpansionSort.LATEST.name()); .getString("cloud_sorting", ExpansionSort.LATEST.name());
try try {
{ //noinspection ConstantConditions (bad spigot annotation)
//noinspection ConstantConditions (bad spigot annotation) return Optional.of(ExpansionSort.valueOf(option.toUpperCase()));
return Optional.of(ExpansionSort.valueOf(option.toUpperCase())); } catch (final IllegalArgumentException ignored) {
} return Optional.empty();
catch (final IllegalArgumentException ignored) }
{ }
return Optional.empty();
}
}
@NotNull @NotNull
public String dateFormat() public String dateFormat() {
{ //noinspection ConstantConditions (bad spigot annotation)
//noinspection ConstantConditions (bad spigot annotation) return plugin.getConfig().getString("date_format", "MM/dd/yy HH:mm:ss");
return plugin.getConfig().getString("date_format", "MM/dd/yy HH:mm:ss"); }
}
@NotNull @NotNull
public String booleanTrue() public String booleanTrue() {
{ //noinspection ConstantConditions (bad spigot annotation)
//noinspection ConstantConditions (bad spigot annotation) return plugin.getConfig().getString("boolean.true", "true");
return plugin.getConfig().getString("boolean.true", "true"); }
}
@NotNull @NotNull
public String booleanFalse() public String booleanFalse() {
{ //noinspection ConstantConditions (bad spigot annotation)
//noinspection ConstantConditions (bad spigot annotation) return plugin.getConfig().getString("boolean.false", "false");
return plugin.getConfig().getString("boolean.false", "false"); }
}
} }

View File

@ -26,55 +26,42 @@ import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public final class ExpansionRegisterEvent extends Event implements Cancellable public final class ExpansionRegisterEvent extends Event implements Cancellable {
{
@NotNull @NotNull
private static final HandlerList HANDLERS = new HandlerList(); private static final HandlerList HANDLERS = new HandlerList();
@NotNull
private final PlaceholderExpansion expansion;
private boolean cancelled;
public ExpansionRegisterEvent(@NotNull final PlaceholderExpansion expansion) {
this.expansion = expansion;
}
private boolean cancelled; @NotNull
@NotNull public static HandlerList getHandlerList() {
private final PlaceholderExpansion expansion; return HANDLERS;
}
public ExpansionRegisterEvent(@NotNull final PlaceholderExpansion expansion) @NotNull
{ public PlaceholderExpansion getExpansion() {
this.expansion = expansion; return expansion;
} }
@Override
public boolean isCancelled() {
return cancelled;
}
@NotNull @Override
public PlaceholderExpansion getExpansion() public void setCancelled(boolean cancelled) {
{ this.cancelled = cancelled;
return expansion; }
}
@NotNull
@Override @Override
public boolean isCancelled() public HandlerList getHandlers() {
{ return HANDLERS;
return cancelled; }
}
@Override
public void setCancelled(boolean cancelled)
{
this.cancelled = cancelled;
}
@NotNull
@Override
public HandlerList getHandlers()
{
return HANDLERS;
}
@NotNull
public static HandlerList getHandlerList()
{
return HANDLERS;
}
} }

View File

@ -25,41 +25,33 @@ import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public final class ExpansionUnregisterEvent extends Event public final class ExpansionUnregisterEvent extends Event {
{
@NotNull @NotNull
private static final HandlerList HANDLERS = new HandlerList(); private static final HandlerList HANDLERS = new HandlerList();
@NotNull @NotNull
private final PlaceholderExpansion expansion; private final PlaceholderExpansion expansion;
public ExpansionUnregisterEvent(@NotNull final PlaceholderExpansion expansion) public ExpansionUnregisterEvent(@NotNull final PlaceholderExpansion expansion) {
{ this.expansion = expansion;
this.expansion = expansion; }
}
@NotNull
public static HandlerList getHandlerList() {
return HANDLERS;
}
@NotNull @NotNull
public PlaceholderExpansion getExpansion() public PlaceholderExpansion getExpansion() {
{ return expansion;
return expansion; }
}
@NotNull
@NotNull @Override
@Override public HandlerList getHandlers() {
public HandlerList getHandlers() return HANDLERS;
{ }
return HANDLERS;
}
@NotNull
public static HandlerList getHandlerList()
{
return HANDLERS;
}
} }

View File

@ -29,49 +29,42 @@ import org.jetbrains.annotations.NotNull;
* @deprecated This event is no longer used. * @deprecated This event is no longer used.
*/ */
@Deprecated @Deprecated
public final class PlaceholderHookUnloadEvent extends Event public final class PlaceholderHookUnloadEvent extends Event {
{
@NotNull @NotNull
private static final HandlerList HANDLERS = new HandlerList(); private static final HandlerList HANDLERS = new HandlerList();
@NotNull @NotNull
private final String plugin; private final String plugin;
@NotNull @NotNull
private final PlaceholderHook placeholderHook; private final PlaceholderHook placeholderHook;
public PlaceholderHookUnloadEvent(@NotNull final String plugin, @NotNull final PlaceholderHook placeholderHook) public PlaceholderHookUnloadEvent(@NotNull final String plugin,
{ @NotNull final PlaceholderHook placeholderHook) {
this.plugin = plugin; this.plugin = plugin;
this.placeholderHook = placeholderHook; this.placeholderHook = placeholderHook;
} }
@NotNull @NotNull
public String getHookName() public static HandlerList getHandlerList() {
{ return HANDLERS;
return plugin; }
}
@NotNull @NotNull
public PlaceholderHook getHook() public String getHookName() {
{ return plugin;
return placeholderHook; }
}
@NotNull
public PlaceholderHook getHook() {
return placeholderHook;
}
@NotNull @NotNull
@Override @Override
public HandlerList getHandlers() public HandlerList getHandlers() {
{ return HANDLERS;
return HANDLERS; }
}
@NotNull
public static HandlerList getHandlerList()
{
return HANDLERS;
}
} }

View File

@ -21,8 +21,9 @@
package me.clip.placeholderapi.exceptions; package me.clip.placeholderapi.exceptions;
public final class NoDefaultCommandException extends RuntimeException { public final class NoDefaultCommandException extends RuntimeException {
public NoDefaultCommandException(final String message) {
super(message); public NoDefaultCommandException(final String message) {
} super(message);
}
} }

View File

@ -29,8 +29,8 @@ package me.clip.placeholderapi.expansion;
*/ */
public interface Cacheable { public interface Cacheable {
/** /**
* Called when the implementing class is unregistered from PlaceholderAPI * Called when the implementing class is unregistered from PlaceholderAPI
*/ */
void clear(); void clear();
} }

View File

@ -31,10 +31,10 @@ import org.bukkit.entity.Player;
*/ */
public interface Cleanable { public interface Cleanable {
/** /**
* Called when a player leaves the server * Called when a player leaves the server
* *
* @param p (@link Player} who left the server * @param p (@link Player} who left the server
*/ */
void cleanup(Player p); void cleanup(Player p);
} }

View File

@ -30,14 +30,14 @@ import java.util.Map;
*/ */
public interface Configurable { public interface Configurable {
/** /**
* This method will be called before the implementing class is registered to obtain a map of * This method will be called before the implementing class is registered to obtain a map of
* configuration options that the implementing class needs These paths and values will be added to * configuration options that the implementing class needs These paths and values will be added to
* the PlaceholderAPI config.yml in the configuration section expansions.(placeholder * the PlaceholderAPI config.yml in the configuration section expansions.(placeholder
* identifier).(your key): (your value) * identifier).(your key): (your value)
* *
* @return Map of config path / values which need to be added / removed from the PlaceholderAPI * @return Map of config path / values which need to be added / removed from the PlaceholderAPI
* config.yml file * config.yml file
*/ */
Map<String, Object> getDefaults(); Map<String, Object> getDefaults();
} }

View File

@ -41,24 +41,24 @@ public enum NMSVersion {
SPIGOT_1_15_R1("v1_15_R1"), SPIGOT_1_15_R1("v1_15_R1"),
SPIGOT_1_16_R1("v1_16_R1"); SPIGOT_1_16_R1("v1_16_R1");
private final String version; private final String version;
NMSVersion(String version) { NMSVersion(String version) {
this.version = version; this.version = version;
}
public static NMSVersion getVersion(String version) {
for (NMSVersion v : values()) {
if (v.getVersion().equalsIgnoreCase(version)) {
return v;
}
} }
public static NMSVersion getVersion(String version) { return NMSVersion.UNKNOWN;
for (NMSVersion v : values()) { }
if (v.getVersion().equalsIgnoreCase(version)) {
return v;
}
}
return NMSVersion.UNKNOWN; public String getVersion() {
} return version;
}
public String getVersion() {
return version;
}
} }

View File

@ -20,6 +20,9 @@
package me.clip.placeholderapi.expansion; package me.clip.placeholderapi.expansion;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.PlaceholderHook; import me.clip.placeholderapi.PlaceholderHook;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -30,270 +33,240 @@ import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections; public abstract class PlaceholderExpansion extends PlaceholderHook {
import java.util.List;
import java.util.Objects;
public abstract class PlaceholderExpansion extends PlaceholderHook /**
{ * The placeholder identifier of this expansion
*
* @return placeholder identifier that is associated with this expansion
*/
@NotNull
public abstract String getIdentifier();
/** /**
* The placeholder identifier of this expansion * The author of this expansion
* *
* @return placeholder identifier that is associated with this expansion * @return name of the author for this expansion
*/ */
@NotNull @NotNull
public abstract String getIdentifier(); public abstract String getAuthor();
/** /**
* The author of this expansion * The version of this expansion
* *
* @return name of the author for this expansion * @return current version of this expansion
*/ */
@NotNull @NotNull
public abstract String getAuthor(); public abstract String getVersion();
/** @Nullable
* The version of this expansion @Override /* override for now >:) */
* public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params) {
* @return current version of this expansion return super.onRequest(player, params);
*/ }
@NotNull
public abstract String getVersion();
@Nullable
@Override /* override for now >:) */
public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params)
{
return super.onRequest(player, params);
}
/** /**
* The name of this expansion * The name of this expansion
* *
* @return {@link #getIdentifier()} by default, name of this expansion if specified * @return {@link #getIdentifier()} by default, name of this expansion if specified
*/ */
@NotNull @NotNull
public String getName() public String getName() {
{ return getIdentifier();
return getIdentifier(); }
}
/** /**
* The name of the plugin that this expansion hooks into. by default will null * The name of the plugin that this expansion hooks into. by default will null
* *
* @return plugin name that this expansion requires to function * @return plugin name that this expansion requires to function
*/ */
@Nullable @Nullable
public String getRequiredPlugin() public String getRequiredPlugin() {
{ return getPlugin();
return getPlugin(); }
}
/** /**
* The placeholders associated with this expansion * The placeholders associated with this expansion
* *
* @return placeholder list that this expansion provides * @return placeholder list that this expansion provides
*/ */
@NotNull @NotNull
public List<String> getPlaceholders() public List<String> getPlaceholders() {
{ return Collections.emptyList();
return Collections.emptyList(); }
}
/** /**
* Expansions that do not use the ecloud and instead register from the dependency should set this * Expansions that do not use the ecloud and instead register from the dependency should set this
* to true to ensure that your placeholder expansion is not unregistered when the papi reload * to true to ensure that your placeholder expansion is not unregistered when the papi reload
* command is used * command is used
* *
* @return if this expansion should persist through placeholder reloads * @return if this expansion should persist through placeholder reloads
*/ */
public boolean persist() public boolean persist() {
{ return false;
return false; }
}
/** /**
* Check if this placeholder identifier has already been registered * Check if this placeholder identifier has already been registered
* *
* @return true if the identifier for this expansion is already registered * @return true if the identifier for this expansion is already registered
*/ */
public final boolean isRegistered() public final boolean isRegistered() {
{ return getPlaceholderAPI().getLocalExpansionManager().findExpansionByIdentifier(getIdentifier())
return getPlaceholderAPI().getLocalExpansionManager().findExpansionByIdentifier(getIdentifier()).map(it -> it.equals(this)).orElse(false); .map(it -> it.equals(this)).orElse(false);
} }
/** /**
* If any requirements need to be checked before this expansion should register, you can check * If any requirements need to be checked before this expansion should register, you can check
* them here * them here
* *
* @return true if this hook meets all the requirements to register * @return true if this hook meets all the requirements to register
*/ */
public boolean canRegister() public boolean canRegister() {
{ return getRequiredPlugin() == null
return getRequiredPlugin() == null || Bukkit.getPluginManager().getPlugin(getRequiredPlugin()) != null; || Bukkit.getPluginManager().getPlugin(getRequiredPlugin()) != null;
} }
/** /**
* Attempt to register this PlaceholderExpansion * Attempt to register this PlaceholderExpansion
* *
* @return true if this expansion is now registered with PlaceholderAPI * @return true if this expansion is now registered with PlaceholderAPI
*/ */
public boolean register() public boolean register() {
{ return canRegister() && getPlaceholderAPI().getLocalExpansionManager().register(this);
return canRegister() && getPlaceholderAPI().getLocalExpansionManager().register(this); }
}
/** /**
* Attempt to unregister this PlaceholderExpansion * Attempt to unregister this PlaceholderExpansion
* *
* @return true if this expansion is now unregistered with PlaceholderAPI * @return true if this expansion is now unregistered with PlaceholderAPI
*/ */
public final boolean unregister() public final boolean unregister() {
{ return getPlaceholderAPI().getLocalExpansionManager().unregister(this);
return getPlaceholderAPI().getLocalExpansionManager().unregister(this); }
}
/** /**
* Quick getter for the {@link PlaceholderAPIPlugin} instance * Quick getter for the {@link PlaceholderAPIPlugin} instance
* *
* @return {@link PlaceholderAPIPlugin} instance * @return {@link PlaceholderAPIPlugin} instance
*/ */
@NotNull @NotNull
public final PlaceholderAPIPlugin getPlaceholderAPI() public final PlaceholderAPIPlugin getPlaceholderAPI() {
{ return PlaceholderAPIPlugin.getInstance();
return PlaceholderAPIPlugin.getInstance(); }
}
// === Configuration ===
// === Configuration === @Nullable
public final ConfigurationSection getConfigSection() {
return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier());
}
@Nullable @Nullable
public final ConfigurationSection getConfigSection() public final ConfigurationSection getConfigSection(@NotNull final String path) {
{ final ConfigurationSection section = getConfigSection();
return getPlaceholderAPI().getConfig().getConfigurationSection("expansions." + getIdentifier()); return section == null ? null : section.getConfigurationSection(path);
} }
@Nullable @Nullable
public final ConfigurationSection getConfigSection(@NotNull final String path) @Contract("_, !null -> !null")
{ public final Object get(@NotNull final String path, final Object def) {
final ConfigurationSection section = getConfigSection(); final ConfigurationSection section = getConfigSection();
return section == null ? null : section.getConfigurationSection(path); return section == null ? def : section.get(path, def);
} }
@Nullable public final int getInt(@NotNull final String path, final int def) {
@Contract("_, !null -> !null") final ConfigurationSection section = getConfigSection();
public final Object get(@NotNull final String path, final Object def) return section == null ? def : section.getInt(path, def);
{ }
final ConfigurationSection section = getConfigSection();
return section == null ? def : section.get(path, def);
}
public final int getInt(@NotNull final String path, final int def) public final long getLong(@NotNull final String path, final long def) {
{ final ConfigurationSection section = getConfigSection();
final ConfigurationSection section = getConfigSection(); return section == null ? def : section.getLong(path, def);
return section == null ? def : section.getInt(path, def); }
}
public final long getLong(@NotNull final String path, final long def) public final double getDouble(@NotNull final String path, final double def) {
{ final ConfigurationSection section = getConfigSection();
final ConfigurationSection section = getConfigSection(); return section == null ? def : section.getDouble(path, def);
return section == null ? def : section.getLong(path, def); }
}
public final double getDouble(@NotNull final String path, final double def) @Nullable
{ @Contract("_, !null -> !null")
final ConfigurationSection section = getConfigSection(); public final String getString(@NotNull final String path, @Nullable final String def) {
return section == null ? def : section.getDouble(path, def); final ConfigurationSection section = getConfigSection();
} return section == null ? def : section.getString(path, def);
}
@Nullable @NotNull
@Contract("_, !null -> !null") public final List<String> getStringList(@NotNull final String path) {
public final String getString(@NotNull final String path, @Nullable final String def) final ConfigurationSection section = getConfigSection();
{ return section == null ? Collections.emptyList() : section.getStringList(path);
final ConfigurationSection section = getConfigSection(); }
return section == null ? def : section.getString(path, def);
}
@NotNull public final boolean configurationContains(@NotNull final String path) {
public final List<String> getStringList(@NotNull final String path) final ConfigurationSection section = getConfigSection();
{ return section != null && section.contains(path);
final ConfigurationSection section = getConfigSection(); }
return section == null ? Collections.emptyList() : section.getStringList(path);
}
public final boolean configurationContains(@NotNull final String path) @Override
{ public final boolean equals(final Object o) {
final ConfigurationSection section = getConfigSection(); if (this == o) {
return section != null && section.contains(path); return true;
} }
if (!(o instanceof PlaceholderExpansion)) {
return false;
}
@Override final PlaceholderExpansion expansion = (PlaceholderExpansion) o;
public final boolean equals(final Object o)
{
if (this == o)
{
return true;
}
if (!(o instanceof PlaceholderExpansion))
{
return false;
}
final PlaceholderExpansion expansion = (PlaceholderExpansion) o; return getIdentifier().equals(expansion.getIdentifier()) &&
getAuthor().equals(expansion.getAuthor()) &&
getVersion().equals(expansion.getVersion());
}
return getIdentifier().equals(expansion.getIdentifier()) && @Override
getAuthor().equals(expansion.getAuthor()) && public final int hashCode() {
getVersion().equals(expansion.getVersion()); return Objects.hash(getIdentifier(), getAuthor(), getVersion());
} }
@Override @Override
public final int hashCode() public final String toString() {
{ return String.format("PlaceholderExpansion[name: '%s', author: '%s', version: '%s']", getName(),
return Objects.hash(getIdentifier(), getAuthor(), getVersion()); getAuthor(), getVersion());
} }
@Override // === Deprecated API ===
public final String toString()
{
return String.format("PlaceholderExpansion[name: '%s', author: '%s', version: '%s']", getName(), getAuthor(), getVersion());
}
// === Deprecated API === /**
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()}
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
public String getPlugin() {
return null;
}
/** /**
* @deprecated As of versions greater than 2.8.7, use {@link #getRequiredPlugin()} * @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description
*/ */
@Deprecated @Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0") @ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
public String getPlugin() public String getDescription() {
{ return null;
return null; }
}
/** /**
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to show a description * @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link
*/ */
@Deprecated @Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0") @ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
public String getDescription() public String getLink() {
{ return null;
return null; }
}
/**
* @deprecated As of versions greater than 2.8.7, use the expansion cloud to display a link
*/
@Deprecated
@ApiStatus.ScheduledForRemoval(inVersion = "2.11.0")
public String getLink()
{
return null;
}
} }

View File

@ -24,5 +24,5 @@ import org.bukkit.entity.Player;
public interface Relational { public interface Relational {
String onPlaceholderRequest(Player one, Player two, String identifier); String onPlaceholderRequest(Player one, Player two, String identifier);
} }

View File

@ -23,15 +23,15 @@ package me.clip.placeholderapi.expansion;
public interface Taskable { public interface Taskable {
/** /**
* Called when the implementing class has successfully been registered to the placeholder map * Called when the implementing class has successfully been registered to the placeholder map
* Tasks that need to be performed when this expansion is registered should go here * Tasks that need to be performed when this expansion is registered should go here
*/ */
void start(); void start();
/** /**
* Called when the implementing class has been unregistered from PlaceholderAPI Tasks that need to * Called when the implementing class has been unregistered from PlaceholderAPI Tasks that need to
* be performed when this expansion has unregistered should go here * be performed when this expansion has unregistered should go here
*/ */
void stop(); void stop();
} }

View File

@ -22,24 +22,24 @@ package me.clip.placeholderapi.expansion;
public final class Version { public final class Version {
private final boolean isSpigot; private final boolean isSpigot;
private final String version; private final String version;
public Version(String version, boolean isSpigot) { public Version(String version, boolean isSpigot) {
this.version = version; this.version = version;
this.isSpigot = isSpigot; this.isSpigot = isSpigot;
} }
public String getVersion() { public String getVersion() {
return version == null ? "unknown" : version; return version == null ? "unknown" : version;
} }
public boolean isSpigot() { public boolean isSpigot() {
return isSpigot; return isSpigot;
} }
public boolean compareTo(String version) { public boolean compareTo(String version) {
return getVersion().equalsIgnoreCase(version); return getVersion().equalsIgnoreCase(version);
} }
} }

View File

@ -30,11 +30,11 @@ package me.clip.placeholderapi.expansion;
*/ */
public interface VersionSpecific { public interface VersionSpecific {
/** /**
* This method is called before the expansion is attempted to be registered The server version * This method is called before the expansion is attempted to be registered The server version
* will be passed to this method so you know what version the server is currently running. * will be passed to this method so you know what version the server is currently running.
* *
* @return true if your expansion is compatible with the version the server is running. * @return true if your expansion is compatible with the version the server is running.
*/ */
boolean isCompatibleWith(Version v); boolean isCompatibleWith(Version v);
} }

View File

@ -20,183 +20,183 @@
package me.clip.placeholderapi.expansion.cloud; package me.clip.placeholderapi.expansion.cloud;
import me.clip.placeholderapi.util.TimeUtil;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import me.clip.placeholderapi.util.TimeUtil;
public class CloudExpansion { public class CloudExpansion {
private String name, private String name,
author, author,
latest_version, latest_version,
description, description,
source_url, source_url,
dependency_url; dependency_url;
private boolean hasExpansion, private boolean hasExpansion,
shouldUpdate, shouldUpdate,
verified; verified;
private long last_update, private long last_update,
ratings_count; ratings_count;
private double average_rating; private double average_rating;
private List<String> placeholders; private List<String> placeholders;
private List<Version> versions; private List<Version> versions;
public CloudExpansion() { public CloudExpansion() {
}
public String getTimeSinceLastUpdate() {
int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - getLastUpdate());
return TimeUtil.getTime(time);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Version getVersion() {
return getLatestVersion() == null ? null : getVersion(getLatestVersion());
}
public Version getVersion(String version) {
return versions == null ? null : versions.stream()
.filter(v -> v.getVersion().equals(version))
.findFirst()
.orElse(null);
}
public List<String> getAvailableVersions() {
return versions.stream().map(Version::getVersion).collect(Collectors.toList());
}
public String getLatestVersion() {
return latest_version;
}
public void setLatestVersion(String latest_version) {
this.latest_version = latest_version;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getSourceUrl() {
return source_url;
}
public void setSourceUrl(String source_url) {
this.source_url = source_url;
}
public String getDependencyUrl() {
return dependency_url;
}
public void setDependencyUrl(String dependency_url) {
this.dependency_url = dependency_url;
}
public boolean hasExpansion() {
return hasExpansion;
}
public void setHasExpansion(boolean hasExpansion) {
this.hasExpansion = hasExpansion;
}
public boolean shouldUpdate() {
return shouldUpdate;
}
public void setShouldUpdate(boolean shouldUpdate) {
this.shouldUpdate = shouldUpdate;
}
public boolean isVerified() {
return verified;
}
public long getLastUpdate() {
return last_update;
}
public void setLastUpdate(long last_update) {
this.last_update = last_update;
}
public long getRatingsCount() {
return ratings_count;
}
public double getAverage_rating() {
return average_rating;
}
public List<String> getPlaceholders() {
return placeholders;
}
public void setPlaceholders(List<String> placeholders) {
this.placeholders = placeholders;
}
public List<Version> getVersions() {
return versions;
}
public void setVersions(List<Version> versions) {
this.versions = versions;
}
public class Version {
private String url, version, release_notes;
public String getUrl() {
return url;
} }
public String getTimeSinceLastUpdate() { public void setUrl(String url) {
int time = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - getLastUpdate()); this.url = url;
return TimeUtil.getTime(time);
} }
public String getName() { public String getVersion() {
return name; return version;
} }
public void setName(String name) { public void setVersion(String version) {
this.name = name; this.version = version;
} }
public String getAuthor() { public String getReleaseNotes() {
return author; return release_notes;
} }
public void setAuthor(String author) { public void setReleaseNotes(String release_notes) {
this.author = author; this.release_notes = release_notes;
}
public Version getVersion() {
return getLatestVersion() == null ? null : getVersion(getLatestVersion());
}
public Version getVersion(String version) {
return versions == null ? null : versions.stream()
.filter(v -> v.getVersion().equals(version))
.findFirst()
.orElse(null);
}
public List<String> getAvailableVersions() {
return versions.stream().map(Version::getVersion).collect(Collectors.toList());
}
public String getLatestVersion() {
return latest_version;
}
public void setLatestVersion(String latest_version) {
this.latest_version = latest_version;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getSourceUrl() {
return source_url;
}
public void setSourceUrl(String source_url) {
this.source_url = source_url;
}
public String getDependencyUrl() {
return dependency_url;
}
public void setDependencyUrl(String dependency_url) {
this.dependency_url = dependency_url;
}
public boolean hasExpansion() {
return hasExpansion;
}
public void setHasExpansion(boolean hasExpansion) {
this.hasExpansion = hasExpansion;
}
public boolean shouldUpdate() {
return shouldUpdate;
}
public void setShouldUpdate(boolean shouldUpdate) {
this.shouldUpdate = shouldUpdate;
}
public boolean isVerified() {
return verified;
}
public long getLastUpdate() {
return last_update;
}
public void setLastUpdate(long last_update) {
this.last_update = last_update;
}
public long getRatingsCount() {
return ratings_count;
}
public double getAverage_rating() {
return average_rating;
}
public List<String> getPlaceholders() {
return placeholders;
}
public void setPlaceholders(List<String> placeholders) {
this.placeholders = placeholders;
}
public List<Version> getVersions() {
return versions;
}
public void setVersions(List<Version> versions) {
this.versions = versions;
}
public class Version {
private String url, version, release_notes;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getReleaseNotes() {
return release_notes;
}
public void setReleaseNotes(String release_notes) {
this.release_notes = release_notes;
}
} }
}
} }

View File

@ -24,12 +24,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.io.Resources; import com.google.common.io.Resources;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
@ -38,7 +32,11 @@ import java.net.URL;
import java.nio.channels.Channels; import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -46,243 +44,216 @@ import java.util.function.Function;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.stream.Collector; import java.util.stream.Collector;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Unmodifiable;
public final class CloudExpansionManager public final class CloudExpansionManager {
{
@NotNull @NotNull
private static final String API_URL = "http://api.extendedclip.com/v2/"; private static final String API_URL = "http://api.extendedclip.com/v2/";
@NotNull @NotNull
private static final Gson GSON = new Gson(); private static final Gson GSON = new Gson();
@NotNull @NotNull
private static final Type TYPE = new TypeToken<Map<String, CloudExpansion>>() {}.getType(); private static final Type TYPE = new TypeToken<Map<String, CloudExpansion>>() {}.getType();
@NotNull @NotNull
private final Collector<CloudExpansion, ?, Map<String, CloudExpansion>> INDEXED_NAME_COLLECTOR = Collectors.toMap(CloudExpansionManager::toIndexName, Function.identity()); private final Collector<CloudExpansion, ?, Map<String, CloudExpansion>> INDEXED_NAME_COLLECTOR = Collectors
.toMap(CloudExpansionManager::toIndexName, Function.identity());
@NotNull @NotNull
private final PlaceholderAPIPlugin plugin; private final PlaceholderAPIPlugin plugin;
@NotNull @NotNull
private final Map<String, CloudExpansion> cache = new HashMap<>(); private final Map<String, CloudExpansion> cache = new HashMap<>();
@NotNull @NotNull
private final Map<String, CompletableFuture<File>> await = new ConcurrentHashMap<>(); private final Map<String, CompletableFuture<File>> await = new ConcurrentHashMap<>();
public CloudExpansionManager(@NotNull final PlaceholderAPIPlugin plugin) public CloudExpansionManager(@NotNull final PlaceholderAPIPlugin plugin) {
{ this.plugin = plugin;
this.plugin = plugin; }
}
@NotNull
private static String toIndexName(@NotNull final String name) {
return name.toLowerCase().replace(' ', '_');
}
public void load() @NotNull
{ private static String toIndexName(@NotNull final CloudExpansion expansion) {
clean(); return toIndexName(expansion.getName());
fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions()); }
}
public void kill() public void load() {
{ clean();
clean(); fetch(plugin.getPlaceholderAPIConfig().cloudAllowUnverifiedExpansions());
} }
public void kill() {
clean();
}
@NotNull @NotNull
@Unmodifiable @Unmodifiable
public Map<String, CloudExpansion> getCloudExpansions() public Map<String, CloudExpansion> getCloudExpansions() {
{ return ImmutableMap.copyOf(cache);
return ImmutableMap.copyOf(cache); }
}
@NotNull @NotNull
@Unmodifiable @Unmodifiable
public Map<String, CloudExpansion> getCloudExpansionsInstalled() public Map<String, CloudExpansion> getCloudExpansionsInstalled() {
{ if (cache.isEmpty()) {
if (cache.isEmpty()) return Collections.emptyMap();
{ }
return Collections.emptyMap();
}
return cache.values() return cache.values()
.stream() .stream()
.filter(CloudExpansion::hasExpansion) .filter(CloudExpansion::hasExpansion)
.collect(INDEXED_NAME_COLLECTOR); .collect(INDEXED_NAME_COLLECTOR);
} }
@NotNull @NotNull
@Unmodifiable @Unmodifiable
public Map<String, CloudExpansion> getCloudExpansionsByAuthor(@NotNull final String author) public Map<String, CloudExpansion> getCloudExpansionsByAuthor(@NotNull final String author) {
{ if (cache.isEmpty()) {
if (cache.isEmpty()) return Collections.emptyMap();
{ }
return Collections.emptyMap();
}
return cache.values() return cache.values()
.stream() .stream()
.filter(expansion -> author.equalsIgnoreCase(expansion.getAuthor())) .filter(expansion -> author.equalsIgnoreCase(expansion.getAuthor()))
.collect(INDEXED_NAME_COLLECTOR); .collect(INDEXED_NAME_COLLECTOR);
} }
@NotNull @NotNull
@Unmodifiable @Unmodifiable
public Set<String> getCloudExpansionAuthors() public Set<String> getCloudExpansionAuthors() {
{ return cache.values().stream().map(CloudExpansion::getAuthor).collect(Collectors.toSet());
return cache.values().stream().map(CloudExpansion::getAuthor).collect(Collectors.toSet()); }
}
public int getCloudExpansionAuthorCount() {
return getCloudExpansionAuthors().size();
}
public int getCloudExpansionAuthorCount() public int getCloudUpdateCount() {
{ return ((int) plugin.getLocalExpansionManager()
return getCloudExpansionAuthors().size(); .getExpansions()
} .stream()
.filter(expansion -> findCloudExpansionByName(expansion.getName())
.map(CloudExpansion::shouldUpdate).orElse(false))
.count());
}
public int getCloudUpdateCount() @NotNull
{ public Optional<CloudExpansion> findCloudExpansionByName(@NotNull final String name) {
return ((int) plugin.getLocalExpansionManager() return Optional.ofNullable(cache.get(toIndexName(name)));
.getExpansions() }
.stream()
.filter(expansion -> findCloudExpansionByName(expansion.getName()).map(CloudExpansion::shouldUpdate).orElse(false))
.count());
}
public void clean() {
cache.clear();
@NotNull await.values().forEach(future -> future.cancel(true));
public Optional<CloudExpansion> findCloudExpansionByName(@NotNull final String name) await.clear();
{ }
return Optional.ofNullable(cache.get(toIndexName(name)));
}
public void fetch(final boolean allowUnverified) {
plugin.getLogger().info("Fetching available expansion information...");
public void clean() CompletableFuture<Map<String, CloudExpansion>> future = CompletableFuture.supplyAsync(() -> {
{ final Map<String, CloudExpansion> values = new HashMap<>();
cache.clear();
await.values().forEach(future -> future.cancel(true)); try {
await.clear(); //noinspection UnstableApiUsage
} final String json = Resources.toString(new URL(API_URL), StandardCharsets.UTF_8);
values.putAll(GSON.fromJson(json, TYPE));
} catch (final IOException ex) {
throw new CompletionException(ex);
}
public void fetch(final boolean allowUnverified) values.values().removeIf(value -> value.getLatestVersion() == null
{ || value.getVersion(value.getLatestVersion()) == null);
plugin.getLogger().info("Fetching available expansion information...");
CompletableFuture<Map<String, CloudExpansion>> future = CompletableFuture.supplyAsync(() -> { return values;
final Map<String, CloudExpansion> values = new HashMap<>(); });
try if (!allowUnverified) {
{ future = future.thenApplyAsync((values) -> {
//noinspection UnstableApiUsage values.values().removeIf(expansion -> !expansion.isVerified());
final String json = Resources.toString(new URL(API_URL), StandardCharsets.UTF_8); return values;
values.putAll(GSON.fromJson(json, TYPE)); });
} }
catch (final IOException ex)
{
throw new CompletionException(ex);
}
values.values().removeIf(value -> value.getLatestVersion() == null || value.getVersion(value.getLatestVersion()) == null); future = future.thenApplyAsync((values) -> {
return values; values.forEach((name, expansion) -> {
}); expansion.setName(name);
final Optional<PlaceholderExpansion> local = plugin.getLocalExpansionManager()
.findExpansionByName(name);
if (local.isPresent() && local.get().isRegistered()) {
expansion.setHasExpansion(true);
expansion.setShouldUpdate(!local.get().getVersion().equals(expansion.getLatestVersion()));
}
});
if (!allowUnverified) return values;
{ });
future = future.thenApplyAsync((values) -> {
values.values().removeIf(expansion -> !expansion.isVerified());
return values;
});
}
future.whenComplete((expansions, exception) -> {
future = future.thenApplyAsync((values) -> { if (exception != null) {
plugin.getLogger()
.log(Level.WARNING, "failed to download expansion information", exception);
return;
}
values.forEach((name, expansion) -> { for (final CloudExpansion expansion : expansions.values()) {
expansion.setName(name); this.cache.put(toIndexName(expansion), expansion);
}
});
}
final Optional<PlaceholderExpansion> local = plugin.getLocalExpansionManager().findExpansionByName(name); public boolean isDownloading(@NotNull final CloudExpansion expansion) {
if (local.isPresent() && local.get().isRegistered()) return await.containsKey(toIndexName(expansion));
{ }
expansion.setHasExpansion(true);
expansion.setShouldUpdate(!local.get().getVersion().equals(expansion.getLatestVersion()));
}
});
return values; @NotNull
}); public CompletableFuture<File> downloadExpansion(@NotNull final CloudExpansion expansion,
@NotNull final CloudExpansion.Version version) {
final CompletableFuture<File> previous = await.get(toIndexName(expansion));
if (previous != null) {
return previous;
}
future.whenComplete((expansions, exception) -> { final File file = new File(plugin.getLocalExpansionManager().getExpansionsFolder(),
"Expansion-" + toIndexName(expansion) + ".jar");
if (exception != null) final CompletableFuture<File> download = CompletableFuture.supplyAsync(() -> {
{ try (final ReadableByteChannel source = Channels.newChannel(new URL(version.getUrl())
plugin.getLogger().log(Level.WARNING, "failed to download expansion information", exception); .openStream()); final FileOutputStream target = new FileOutputStream(file)) {
return; target.getChannel().transferFrom(source, 0, Long.MAX_VALUE);
} } catch (final IOException ex) {
throw new CompletionException(ex);
}
return file;
});
for (final CloudExpansion expansion : expansions.values()) download.whenCompleteAsync((value, exception) -> {
{ await.remove(toIndexName(expansion));
this.cache.put(toIndexName(expansion), expansion);
}
});
}
if (exception != null) {
plugin.getLogger().log(Level.SEVERE,
"failed to download " + expansion.getName() + ":" + version.getVersion(), exception);
}
});
public boolean isDownloading(@NotNull final CloudExpansion expansion) await.put(toIndexName(expansion), download);
{
return await.containsKey(toIndexName(expansion));
}
return download;
@NotNull }
public CompletableFuture<File> downloadExpansion(@NotNull final CloudExpansion expansion, @NotNull final CloudExpansion.Version version)
{
final CompletableFuture<File> previous = await.get(toIndexName(expansion));
if (previous != null)
{
return previous;
}
final File file = new File(plugin.getLocalExpansionManager().getExpansionsFolder(), "Expansion-" + toIndexName(expansion) + ".jar");
final CompletableFuture<File> download = CompletableFuture.supplyAsync(() -> {
try (final ReadableByteChannel source = Channels.newChannel(new URL(version.getUrl()).openStream()); final FileOutputStream target = new FileOutputStream(file))
{
target.getChannel().transferFrom(source, 0, Long.MAX_VALUE);
}
catch (final IOException ex)
{
throw new CompletionException(ex);
}
return file;
});
download.whenCompleteAsync((value, exception) -> {
await.remove(toIndexName(expansion));
if (exception != null)
{
plugin.getLogger().log(Level.SEVERE, "failed to download " + expansion.getName() + ":" + version.getVersion(), exception);
}
});
await.put(toIndexName(expansion), download);
return download;
}
@NotNull
private static String toIndexName(@NotNull final String name)
{
return name.toLowerCase().replace(' ', '_');
}
@NotNull
private static String toIndexName(@NotNull final CloudExpansion expansion)
{
return toIndexName(expansion.getName());
}
} }

View File

@ -22,10 +22,25 @@ package me.clip.placeholderapi.expansion.manager;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.logging.Level;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.events.ExpansionRegisterEvent; import me.clip.placeholderapi.events.ExpansionRegisterEvent;
import me.clip.placeholderapi.events.ExpansionUnregisterEvent; import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
import me.clip.placeholderapi.expansion.*; import me.clip.placeholderapi.expansion.Cacheable;
import me.clip.placeholderapi.expansion.Cleanable;
import me.clip.placeholderapi.expansion.Configurable;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.Taskable;
import me.clip.placeholderapi.expansion.VersionSpecific;
import me.clip.placeholderapi.expansion.cloud.CloudExpansion; import me.clip.placeholderapi.expansion.cloud.CloudExpansion;
import me.clip.placeholderapi.util.FileUtil; import me.clip.placeholderapi.util.FileUtil;
import me.clip.placeholderapi.util.Futures; import me.clip.placeholderapi.util.Futures;
@ -44,381 +59,318 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
import java.io.File; public final class LocalExpansionManager implements Listener {
import java.util.Arrays;
import java.util.Collection; @NotNull
import java.util.HashMap; private static final String EXPANSIONS_FOLDER_NAME = "expansions";
import java.util.List;
import java.util.Map;
import java.util.Optional; @NotNull
import java.util.concurrent.CompletableFuture; private final File folder;
import java.util.concurrent.CompletionException; @NotNull
import java.util.logging.Level; private final PlaceholderAPIPlugin plugin;
public final class LocalExpansionManager implements Listener @NotNull
{ private final Map<String, PlaceholderExpansion> expansions = new HashMap<>();
@NotNull
private static final String EXPANSIONS_FOLDER_NAME = "expansions"; public LocalExpansionManager(@NotNull final PlaceholderAPIPlugin plugin) {
this.plugin = plugin;
this.folder = new File(plugin.getDataFolder(), EXPANSIONS_FOLDER_NAME);
@NotNull
private final File folder; if (!this.folder.exists() && !folder.mkdirs()) {
@NotNull plugin.getLogger().log(Level.WARNING, "failed to create expansions folder!");
private final PlaceholderAPIPlugin plugin; }
}
@NotNull
private final Map<String, PlaceholderExpansion> expansions = new HashMap<>(); public void load(@NotNull final CommandSender sender) {
registerAll(sender);
}
public LocalExpansionManager(@NotNull final PlaceholderAPIPlugin plugin)
{ public void kill() {
this.plugin = plugin; unregisterAll();
this.folder = new File(plugin.getDataFolder(), EXPANSIONS_FOLDER_NAME); }
if (!this.folder.exists() && !folder.mkdirs())
{ @NotNull
plugin.getLogger().log(Level.WARNING, "failed to create expansions folder!"); public File getExpansionsFolder() {
} return folder;
} }
public void load(@NotNull final CommandSender sender) public int getExpansionsCount() {
{ return expansions.size();
registerAll(sender); }
}
public void kill() @NotNull
{ @Unmodifiable
unregisterAll(); public Collection<String> getIdentifiers() {
} return ImmutableSet.copyOf(expansions.keySet());
}
@NotNull @NotNull
public File getExpansionsFolder() @Unmodifiable
{ public Collection<PlaceholderExpansion> getExpansions() {
return folder; return ImmutableSet.copyOf(expansions.values());
} }
public int getExpansionsCount()
{ @Nullable
return expansions.size(); public PlaceholderExpansion getExpansion(@NotNull final String identifier) {
} return expansions.get(identifier.toLowerCase());
}
@NotNull
@Unmodifiable @NotNull
public Collection<String> getIdentifiers() public Optional<PlaceholderExpansion> findExpansionByName(@NotNull final String name) {
{ return expansions.values().stream()
return ImmutableSet.copyOf(expansions.keySet()); .filter(expansion -> name.equalsIgnoreCase(expansion.getName())).findFirst();
} }
@NotNull @NotNull
@Unmodifiable public Optional<PlaceholderExpansion> findExpansionByIdentifier(
public Collection<PlaceholderExpansion> getExpansions() @NotNull final String identifier) {
{ return Optional.ofNullable(getExpansion(identifier));
return ImmutableSet.copyOf(expansions.values()); }
}
public Optional<PlaceholderExpansion> register(
@Nullable @NotNull final Class<? extends PlaceholderExpansion> clazz) {
public PlaceholderExpansion getExpansion(@NotNull final String identifier) try {
{ final PlaceholderExpansion expansion = createExpansionInstance(clazz);
return expansions.get(identifier.toLowerCase()); if (expansion == null || !expansion.register()) {
} return Optional.empty();
}
@NotNull return Optional.of(expansion);
public Optional<PlaceholderExpansion> findExpansionByName(@NotNull final String name) } catch (final LinkageError ex) {
{ plugin.getLogger().severe("expansion class " + clazz.getSimpleName() + " is outdated: \n" +
return expansions.values().stream().filter(expansion -> name.equalsIgnoreCase(expansion.getName())).findFirst(); "Failed to load due to a [" + ex.getClass().getSimpleName() + "], attempted to use " + ex
} .getMessage());
}
@NotNull
public Optional<PlaceholderExpansion> findExpansionByIdentifier(@NotNull final String identifier) return Optional.empty();
{ }
return Optional.ofNullable(getExpansion(identifier));
} /**
* Do not call this method yourself, use {@link PlaceholderExpansion#register()}
*/
public Optional<PlaceholderExpansion> register(@NotNull final Class<? extends PlaceholderExpansion> clazz) @ApiStatus.Internal
{ public boolean register(@NotNull final PlaceholderExpansion expansion) {
try final String identifier = expansion.getIdentifier().toLowerCase();
{
final PlaceholderExpansion expansion = createExpansionInstance(clazz); if (expansion instanceof Configurable) {
if (expansion == null || !expansion.register()) Map<String, Object> defaults = ((Configurable) expansion).getDefaults();
{ String pre = "expansions." + identifier + ".";
return Optional.empty(); FileConfiguration cfg = plugin.getConfig();
} boolean save = false;
return Optional.of(expansion); if (defaults != null) {
} for (Map.Entry<String, Object> entries : defaults.entrySet()) {
catch (final LinkageError ex) if (entries.getKey() == null || entries.getKey().isEmpty()) {
{ continue;
plugin.getLogger().severe("expansion class " + clazz.getSimpleName() + " is outdated: \n" + }
"Failed to load due to a [" + ex.getClass().getSimpleName() + "], attempted to use " + ex.getMessage());
} if (entries.getValue() == null) {
if (cfg.contains(pre + entries.getKey())) {
return Optional.empty(); save = true;
} cfg.set(pre + entries.getKey(), null);
}
/** } else {
* Do not call this method yourself, use {@link PlaceholderExpansion#register()} if (!cfg.contains(pre + entries.getKey())) {
*/ save = true;
@ApiStatus.Internal cfg.set(pre + entries.getKey(), entries.getValue());
public boolean register(@NotNull final PlaceholderExpansion expansion) }
{ }
final String identifier = expansion.getIdentifier().toLowerCase(); }
}
if (expansion instanceof Configurable)
{ if (save) {
Map<String, Object> defaults = ((Configurable) expansion).getDefaults(); plugin.saveConfig();
String pre = "expansions." + identifier + "."; plugin.reloadConfig();
FileConfiguration cfg = plugin.getConfig(); }
boolean save = false; }
if (defaults != null) if (expansion instanceof VersionSpecific) {
{ VersionSpecific nms = (VersionSpecific) expansion;
for (Map.Entry<String, Object> entries : defaults.entrySet()) if (!nms.isCompatibleWith(PlaceholderAPIPlugin.getServerVersion())) {
{ plugin.getLogger().info(
if (entries.getKey() == null || entries.getKey().isEmpty()) "Your server version is not compatible with expansion: " + expansion.getIdentifier()
{ + " version: " + expansion.getVersion());
continue; return false;
} }
}
if (entries.getValue() == null)
{ final PlaceholderExpansion removed = expansions.get(identifier);
if (cfg.contains(pre + entries.getKey())) if (removed != null && !removed.unregister()) {
{ return false;
save = true; }
cfg.set(pre + entries.getKey(), null);
} final ExpansionRegisterEvent event = new ExpansionRegisterEvent(expansion);
} Bukkit.getPluginManager().callEvent(event);
else
{ if (event.isCancelled()) {
if (!cfg.contains(pre + entries.getKey())) return false;
{ }
save = true;
cfg.set(pre + entries.getKey(), entries.getValue()); expansions.put(identifier, expansion);
}
} if (expansion instanceof Listener) {
} Bukkit.getPluginManager().registerEvents(((Listener) expansion), plugin);
} }
if (save) plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier());
{
plugin.saveConfig(); if (expansion instanceof Taskable) {
plugin.reloadConfig(); ((Taskable) expansion).start();
} }
}
if (plugin.getPlaceholderAPIConfig().isCloudEnabled()) {
if (expansion instanceof VersionSpecific) final Optional<CloudExpansion> cloudExpansion = plugin.getCloudExpansionManager()
{ .findCloudExpansionByName(identifier);
VersionSpecific nms = (VersionSpecific) expansion; if (cloudExpansion.isPresent()) {
if (!nms.isCompatibleWith(PlaceholderAPIPlugin.getServerVersion())) cloudExpansion.get().setHasExpansion(true);
{ cloudExpansion.get().setShouldUpdate(
plugin.getLogger().info("Your server version is not compatible with expansion: " + expansion.getIdentifier() + " version: " + expansion.getVersion()); !cloudExpansion.get().getLatestVersion().equals(expansion.getVersion()));
return false; }
} }
}
return true;
final PlaceholderExpansion removed = expansions.get(identifier); }
if (removed != null && !removed.unregister())
{ /**
return false; * Do not call this method yourself, use {@link PlaceholderExpansion#unregister()}
} */
@ApiStatus.Internal
final ExpansionRegisterEvent event = new ExpansionRegisterEvent(expansion); public boolean unregister(@NotNull final PlaceholderExpansion expansion) {
Bukkit.getPluginManager().callEvent(event); if (expansions.remove(expansion.getIdentifier()) == null) {
return false;
if (event.isCancelled()) }
{
return false; Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(expansion));
}
if (expansion instanceof Listener) {
expansions.put(identifier, expansion); HandlerList.unregisterAll((Listener) expansion);
}
if (expansion instanceof Listener)
{ if (expansion instanceof Taskable) {
Bukkit.getPluginManager().registerEvents(((Listener) expansion), plugin); ((Taskable) expansion).stop();
} }
plugin.getLogger().info("Successfully registered expansion: " + expansion.getIdentifier()); if (expansion instanceof Cacheable) {
((Cacheable) expansion).clear();
if (expansion instanceof Taskable) }
{
((Taskable) expansion).start(); if (plugin.getPlaceholderAPIConfig().isCloudEnabled()) {
} plugin.getCloudExpansionManager().findCloudExpansionByName(expansion.getName())
.ifPresent(cloud -> {
if (plugin.getPlaceholderAPIConfig().isCloudEnabled()) cloud.setHasExpansion(false);
{ cloud.setShouldUpdate(false);
final Optional<CloudExpansion> cloudExpansion = plugin.getCloudExpansionManager().findCloudExpansionByName(identifier); });
if (cloudExpansion.isPresent()) }
{
cloudExpansion.get().setHasExpansion(true); return true;
cloudExpansion.get().setShouldUpdate(!cloudExpansion.get().getLatestVersion().equals(expansion.getVersion())); }
}
}
private void registerAll(@NotNull final CommandSender sender) {
return true; plugin.getLogger().info("Placeholder expansion registration initializing...");
}
Futures.onMainThread(plugin, findExpansionsOnDisk(), (classes, exception) -> {
/** if (exception != null) {
* Do not call this method yourself, use {@link PlaceholderExpansion#unregister()} plugin.getLogger().log(Level.SEVERE, "failed to load class files of expansions", exception);
*/ return;
@ApiStatus.Internal }
public boolean unregister(@NotNull final PlaceholderExpansion expansion)
{ final long registered = classes.stream().map(this::register).filter(Optional::isPresent)
if (expansions.remove(expansion.getIdentifier()) == null) .count();
{
return false; Msg.msg(sender,
} registered == 0 ? "&6No expansions were registered!"
: registered + "&a placeholder hooks successfully registered!");
});
Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(expansion)); }
private void unregisterAll() {
if (expansion instanceof Listener) for (final PlaceholderExpansion expansion : Sets.newHashSet(expansions.values())) {
{ if (expansion.persist()) {
HandlerList.unregisterAll((Listener) expansion); continue;
} }
if (expansion instanceof Taskable) expansion.unregister();
{ }
((Taskable) expansion).stop(); }
}
if (expansion instanceof Cacheable) @NotNull
{ public CompletableFuture<@NotNull List<@NotNull Class<? extends PlaceholderExpansion>>> findExpansionsOnDisk() {
((Cacheable) expansion).clear(); return Arrays.stream(folder.listFiles((dir, name) -> name.endsWith(".jar")))
} .map(this::findExpansionInFile)
.collect(Futures.collector());
if (plugin.getPlaceholderAPIConfig().isCloudEnabled()) }
{
plugin.getCloudExpansionManager().findCloudExpansionByName(expansion.getName()).ifPresent(cloud -> { @NotNull
cloud.setHasExpansion(false); public CompletableFuture<@Nullable Class<? extends PlaceholderExpansion>> findExpansionInFile(
cloud.setShouldUpdate(false); @NotNull final File file) {
}); return CompletableFuture.supplyAsync(() -> {
} try {
return FileUtil.findClass(file, PlaceholderExpansion.class);
return true; } catch (final VerifyError ex) {
} plugin.getLogger().severe("expansion file " + file.getName() + " is outdated: \n" +
"Failed to load due to a [" + ex.getClass().getSimpleName() + "], attempted to use" + ex
.getMessage().substring(ex.getMessage().lastIndexOf(' ')));
private void registerAll(@NotNull final CommandSender sender) return null;
{ } catch (final Exception ex) {
plugin.getLogger().info("Placeholder expansion registration initializing..."); throw new CompletionException(ex);
}
Futures.onMainThread(plugin, findExpansionsOnDisk(), (classes, exception) -> { });
if (exception != null) }
{
plugin.getLogger().log(Level.SEVERE, "failed to load class files of expansions", exception);
return; @Nullable
} public PlaceholderExpansion createExpansionInstance(
@NotNull final Class<? extends PlaceholderExpansion> clazz) throws LinkageError {
final long registered = classes.stream().map(this::register).filter(Optional::isPresent).count(); try {
return clazz.getDeclaredConstructor().newInstance();
Msg.msg(sender, } catch (final Exception ex) {
registered == 0 ? "&6No expansions were registered!" : registered + "&a placeholder hooks successfully registered!"); if (ex.getCause() instanceof LinkageError) {
}); throw ((LinkageError) ex.getCause());
} }
private void unregisterAll() plugin.getLogger()
{ .log(Level.SEVERE, "Failed to load placeholder expansion from class: " + clazz.getName(),
for (final PlaceholderExpansion expansion : Sets.newHashSet(expansions.values())) ex);
{ return null;
if (expansion.persist()) }
{ }
continue;
}
@EventHandler
expansion.unregister(); public void onQuit(@NotNull final PlayerQuitEvent event) {
} for (final PlaceholderExpansion expansion : getExpansions()) {
} if (!(expansion instanceof Cleanable)) {
continue;
}
@NotNull
public CompletableFuture<@NotNull List<@NotNull Class<? extends PlaceholderExpansion>>> findExpansionsOnDisk() ((Cleanable) expansion).cleanup(event.getPlayer());
{ }
return Arrays.stream(folder.listFiles((dir, name) -> name.endsWith(".jar"))) }
.map(this::findExpansionInFile)
.collect(Futures.collector()); @EventHandler(priority = EventPriority.HIGH)
} public void onPluginDisable(@NotNull final PluginDisableEvent event) {
final String name = event.getPlugin().getName();
@NotNull if (name.equals(plugin.getName())) {
public CompletableFuture<@Nullable Class<? extends PlaceholderExpansion>> findExpansionInFile(@NotNull final File file) return;
{ }
return CompletableFuture.supplyAsync(() -> {
try for (final PlaceholderExpansion expansion : getExpansions()) {
{ if (!name.equalsIgnoreCase(expansion.getRequiredPlugin())) {
return FileUtil.findClass(file, PlaceholderExpansion.class); continue;
} }
catch (final VerifyError ex)
{ expansion.unregister();
plugin.getLogger().severe("expansion file " + file.getName() + " is outdated: \n" + plugin.getLogger().info("Unregistered placeholder expansion: " + expansion.getName());
"Failed to load due to a [" + ex.getClass().getSimpleName() + "], attempted to use" + ex.getMessage().substring(ex.getMessage().lastIndexOf(' '))); }
return null; }
}
catch (final Exception ex)
{
throw new CompletionException(ex);
}
});
}
@Nullable
public PlaceholderExpansion createExpansionInstance(@NotNull final Class<? extends PlaceholderExpansion> clazz) throws LinkageError
{
try
{
return clazz.getDeclaredConstructor().newInstance();
}
catch (final Exception ex)
{
if (ex.getCause() instanceof LinkageError)
{
throw ((LinkageError) ex.getCause());
}
plugin.getLogger().log(Level.SEVERE, "Failed to load placeholder expansion from class: " + clazz.getName(), ex);
return null;
}
}
@EventHandler
public void onQuit(@NotNull final PlayerQuitEvent event)
{
for (final PlaceholderExpansion expansion : getExpansions())
{
if (!(expansion instanceof Cleanable))
{
continue;
}
((Cleanable) expansion).cleanup(event.getPlayer());
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onPluginDisable(@NotNull final PluginDisableEvent event)
{
final String name = event.getPlugin().getName();
if (name.equals(plugin.getName()))
{
return;
}
for (final PlaceholderExpansion expansion : getExpansions())
{
if (!name.equalsIgnoreCase(expansion.getRequiredPlugin()))
{
continue;
}
expansion.unregister();
plugin.getLogger().info("Unregistered placeholder expansion: " + expansion.getName());
}
}
} }

View File

@ -17,11 +17,6 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
@ -32,15 +27,19 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import java.util.Vector; import java.util.Vector;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
/** /**
* This is a complete JSON message builder class. To create a new JSONMessage do * This is a complete JSON message builder class. To create a new JSONMessage do {@link
* {@link #create(String)} * #create(String)}
* *
* @author Rayzr * @author Rayzr
*/ */
@SuppressWarnings({"WeakerAccess", "unused"}) @SuppressWarnings({"WeakerAccess", "unused"})
public class JSONMessage { public class JSONMessage {
private static final BiMap<ChatColor, String> stylesToNames; private static final BiMap<ChatColor, String> stylesToNames;
static { static {
@ -107,7 +106,8 @@ public class JSONMessage {
* @param players The players you want to send it to * @param players The players you want to send it to
*/ */
public static void actionbar(String message, Player... players) { public static void actionbar(String message, Player... players) {
ReflectionHelper.sendPacket(ReflectionHelper.createActionbarPacket(ChatColor.translateAlternateColorCodes('&', message)), players); ReflectionHelper.sendPacket(ReflectionHelper
.createActionbarPacket(ChatColor.translateAlternateColorCodes('&', message)), players);
} }
/** /**
@ -143,8 +143,8 @@ public class JSONMessage {
} }
/** /**
* Converts this {@link JSONMessage} object to a String representation of the JSON. * Converts this {@link JSONMessage} object to a String representation of the JSON. This is an
* This is an alias of {@code toJSON().toString()}. * alias of {@code toJSON().toString()}.
*/ */
@Override @Override
public String toString() { public String toString() {
@ -152,8 +152,8 @@ public class JSONMessage {
} }
/** /**
* Converts this {@link JSONMessage} object to the legacy formatting system, which * Converts this {@link JSONMessage} object to the legacy formatting system, which uses formatting
* uses formatting codes (like &amp;6, &amp;l, &amp;4, etc.) * codes (like &amp;6, &amp;l, &amp;4, etc.)
* *
* @return This {@link JSONMessage} instance {@link JSONMessage} in legacy format * @return This {@link JSONMessage} instance {@link JSONMessage} in legacy format
*/ */
@ -184,18 +184,20 @@ public class JSONMessage {
/** /**
* Sends this as a title to all the players specified * Sends this as a title to all the players specified
* *
* @param fadeIn How many ticks to fade in * @param fadeIn How many ticks to fade in
* @param stay How many ticks to stay * @param stay How many ticks to stay
* @param fadeOut How many ticks to fade out * @param fadeOut How many ticks to fade out
* @param players The players to send this to * @param players The players to send this to
*/ */
public void title(int fadeIn, int stay, int fadeOut, Player... players) { public void title(int fadeIn, int stay, int fadeOut, Player... players) {
ReflectionHelper.sendPacket(ReflectionHelper.createTitleTimesPacket(fadeIn, stay, fadeOut), players); ReflectionHelper
.sendPacket(ReflectionHelper.createTitleTimesPacket(fadeIn, stay, fadeOut), players);
ReflectionHelper.sendPacket(ReflectionHelper.createTitlePacket(toString()), players); ReflectionHelper.sendPacket(ReflectionHelper.createTitlePacket(toString()), players);
} }
/** /**
* Sends this as a subtitle to all the players specified. Must be used after sending a {@link #title(int, int, int, Player...) title}. * Sends this as a subtitle to all the players specified. Must be used after sending a {@link
* #title(int, int, int, Player...) title}.
* *
* @param players The players to send this to * @param players The players to send this to
*/ */
@ -219,8 +221,9 @@ public class JSONMessage {
* @return This {@link JSONMessage} instance * @return This {@link JSONMessage} instance
*/ */
public JSONMessage color(ChatColor color) { public JSONMessage color(ChatColor color) {
if (!color.isColor()) if (!color.isColor()) {
throw new IllegalArgumentException(color.name() + " is not a color."); throw new IllegalArgumentException(color.name() + " is not a color.");
}
last().setColor(color); last().setColor(color);
return this; return this;
@ -228,7 +231,8 @@ public class JSONMessage {
/** /**
* Sets the color of the current message part. * Sets the color of the current message part.
* <br>If the provided color is a hex color ({@code #rrggbb}) but the major version of MC is older than 1.16 will this * <br>If the provided color is a hex color ({@code #rrggbb}) but the major version of MC is older
* than 1.16 will this
* default to the color WHITE. * default to the color WHITE.
* *
* @param color The color to set * @param color The color to set
@ -240,16 +244,18 @@ public class JSONMessage {
/** /**
* Sets the color of the current message part. * Sets the color of the current message part.
* <br>If the provided color is a hex color ({@code #rrggbb}) but the major version of MC is older than 1.16 will the provided * <br>If the provided color is a hex color ({@code #rrggbb}) but the major version of MC is older
* than 1.16 will the provided
* default ChatColor be used instead. * default ChatColor be used instead.
* *
* @param color The color to set * @param color The color to set
* @param def The default ChatColor to use, when MC version is older than 1.16 * @param def The default ChatColor to use, when MC version is older than 1.16
* @return This {@link JSONMessage} instance * @return This {@link JSONMessage} instance
*/ */
public JSONMessage color(String color, ChatColor def) { public JSONMessage color(String color, ChatColor def) {
if (color.startsWith("#") && ReflectionHelper.MAJOR_VER < 16) if (color.startsWith("#") && ReflectionHelper.MAJOR_VER < 16) {
return color(def); return color(def);
}
last().setColor(color); last().setColor(color);
return this; return this;
@ -263,8 +269,9 @@ public class JSONMessage {
* @return This {@link JSONMessage} instance * @return This {@link JSONMessage} instance
*/ */
public JSONMessage font(String font) { public JSONMessage font(String font) {
if (ReflectionHelper.MAJOR_VER < 16) if (ReflectionHelper.MAJOR_VER < 16) {
return this; return this;
}
last().setFont(font); last().setFont(font);
return this; return this;
@ -316,7 +323,8 @@ public class JSONMessage {
/** /**
* Copies the provided text to the Clipboard of the player. * Copies the provided text to the Clipboard of the player.
* <br>When this is used on versions older than 1.15 will this default to {@link #suggestCommand(String) suggestCommand(String)}. * <br>When this is used on versions older than 1.15 will this default to {@link
* #suggestCommand(String) suggestCommand(String)}.
* *
* @param text The text to copy * @param text The text to copy
* @return This {@link JSONMessage} instance * @return This {@link JSONMessage} instance
@ -327,8 +335,8 @@ public class JSONMessage {
} }
/** /**
* Changes the page of a book. Using this in a non-book context is useless * Changes the page of a book. Using this in a non-book context is useless and will probably
* and will probably error. * error.
* *
* @param page The page to change to * @param page The page to change to
* @return This {@link JSONMessage} instance * @return This {@link JSONMessage} instance
@ -399,12 +407,13 @@ public class JSONMessage {
* @return This {@link JSONMessage} instance * @return This {@link JSONMessage} instance
*/ */
public JSONMessage bar(int length) { public JSONMessage bar(int length) {
return then(Strings.repeat("-", length)).color(ChatColor.DARK_GRAY).style(ChatColor.STRIKETHROUGH); return then(Strings.repeat("-", length)).color(ChatColor.DARK_GRAY)
.style(ChatColor.STRIKETHROUGH);
} }
/** /**
* Adds a horizontal bar to the message that's 53 characters long. This is * Adds a horizontal bar to the message that's 53 characters long. This is the default width of
* the default width of the player's chat window. * the player's chat window.
* *
* @return This {@link JSONMessage} instance * @return This {@link JSONMessage} instance
*/ */
@ -451,7 +460,8 @@ public class JSONMessage {
if (current >= parts.size() || totalLineLength + rawLength >= 53) { if (current >= parts.size() || totalLineLength + rawLength >= 53) {
int padding = Math.max(0, (53 - totalLineLength) / 2); int padding = Math.max(0, (53 - totalLineLength) / 2);
currentLine.firstElement().setText(Strings.repeat(" ", padding) + currentLine.firstElement().getText()); currentLine.firstElement()
.setText(Strings.repeat(" ", padding) + currentLine.firstElement().getText());
currentLine.lastElement().setText(currentLine.lastElement().getText() + "\n"); currentLine.lastElement().setText(currentLine.lastElement().getText() + "\n");
currentLine.clear(); currentLine.clear();
break; break;
@ -502,7 +512,8 @@ public class JSONMessage {
* MC 1.16 changed "value" to "contents", but only for Hover events... Don't ask why. * MC 1.16 changed "value" to "contents", but only for Hover events... Don't ask why.
* Since this lib only has tooltip and achievement can we simply check if action starts with "show_" * Since this lib only has tooltip and achievement can we simply check if action starts with "show_"
*/ */
String valueType = (ReflectionHelper.MAJOR_VER >= 16 && action.startsWith("show_")) ? "contents" : "value"; String valueType =
(ReflectionHelper.MAJOR_VER >= 16 && action.startsWith("show_")) ? "contents" : "value";
if (value instanceof JsonElement) { if (value instanceof JsonElement) {
obj.add(valueType, (JsonElement) value); obj.add(valueType, (JsonElement) value);
@ -586,14 +597,16 @@ public class JSONMessage {
/** /**
* Copies the provided text to the clipboard of the player. * Copies the provided text to the clipboard of the player.
* <br>When used on versions older than 1.15 will this {@link #suggestCommand(String) suggest the text} instead. * <br>When used on versions older than 1.15 will this {@link #suggestCommand(String) suggest
* the text} instead.
* *
* @param text The text to copy. * @param text The text to copy.
* @return The {@link MessageEvent} * @return The {@link MessageEvent}
*/ */
public static MessageEvent copyText(String text) { public static MessageEvent copyText(String text) {
if (ReflectionHelper.MAJOR_VER < 15) if (ReflectionHelper.MAJOR_VER < 15) {
return suggestCommand(text); return suggestCommand(text);
}
return new MessageEvent("copy_to_clipboard", text); return new MessageEvent("copy_to_clipboard", text);
} }
@ -682,7 +695,8 @@ public class JSONMessage {
if (MAJOR_VER < 8) { if (MAJOR_VER < 8) {
stringToChat = getClass("{nms}.ChatSerializer").getMethod("a", String.class); stringToChat = getClass("{nms}.ChatSerializer").getMethod("a", String.class);
} else { } else {
stringToChat = getClass("{nms}.IChatBaseComponent$ChatSerializer").getMethod("a", String.class); stringToChat = getClass("{nms}.IChatBaseComponent$ChatSerializer")
.getMethod("a", String.class);
} }
GET_HANDLE = MethodHandles.lookup().unreflect(getHandle); GET_HANDLE = MethodHandles.lookup().unreflect(getHandle);
@ -698,7 +712,8 @@ public class JSONMessage {
Class<?> titleAction = getClass("{nms}.PacketPlayOutTitle$EnumTitleAction"); Class<?> titleAction = getClass("{nms}.PacketPlayOutTitle$EnumTitleAction");
titlePacketConstructor = packetPlayOutTitle.getConstructor(titleAction, iChatBaseComponent); titlePacketConstructor = packetPlayOutTitle.getConstructor(titleAction, iChatBaseComponent);
titleTimesPacketConstructor = packetPlayOutTitle.getConstructor(int.class, int.class, int.class); titleTimesPacketConstructor = packetPlayOutTitle
.getConstructor(int.class, int.class, int.class);
enumActionTitle = titleAction.getField("TITLE").get(null); enumActionTitle = titleAction.getField("TITLE").get(null);
enumActionSubtitle = titleAction.getField("SUBTITLE").get(null); enumActionSubtitle = titleAction.getField("SUBTITLE").get(null);
@ -833,7 +848,8 @@ public class JSONMessage {
* Attempts to convert a String representing a JSON message into a usable object * Attempts to convert a String representing a JSON message into a usable object
* *
* @param json The JSON to attempt to parse * @param json The JSON to attempt to parse
* @return The object representing the text in JSON form, or <code>null</code> if something went wrong converting the String to JSON data * @return The object representing the text in JSON form, or <code>null</code> if something went
* wrong converting the String to JSON data
*/ */
static Object fromJson(String json) { static Object fromJson(String json) {
assertIsSetup(); assertIsSetup();
@ -857,7 +873,8 @@ public class JSONMessage {
} }
private static Class<?> getClass(String path) throws ClassNotFoundException { private static Class<?> getClass(String path) throws ClassNotFoundException {
return Class.forName(path.replace("{nms}", "net.minecraft.server." + version).replace("{obc}", "org.bukkit.craftbukkit." + version)); return Class.forName(path.replace("{nms}", "net.minecraft.server." + version)
.replace("{obc}", "org.bukkit.craftbukkit." + version));
} }
private static void setFieldValue(Field field, Object instance, Object value) { private static void setFieldValue(Field field, Object instance, Object value) {
@ -890,7 +907,8 @@ public class JSONMessage {
} }
/** /**
* Defines a section of the message, and represents the format that all JSON messages must follow in Minecraft. * Defines a section of the message, and represents the format that all JSON messages must follow
* in Minecraft.
* <br> * <br>
* <br> * <br>
* <a href="http://minecraft.gamepedia.com/Commands#Raw_JSON_text">Reference</a> * <a href="http://minecraft.gamepedia.com/Commands#Raw_JSON_text">Reference</a>
@ -1009,8 +1027,10 @@ public class JSONMessage {
return legacyColor; return legacyColor;
} }
if (this.color.startsWith("#") && ReflectionHelper.MAJOR_VER < 16) if (this.color.startsWith("#") && ReflectionHelper.MAJOR_VER < 16) {
throw new IllegalStateException("Custom Hex colors can only be used in Minecraft 1.16 or newer!"); throw new IllegalStateException(
"Custom Hex colors can only be used in Minecraft 1.16 or newer!");
}
try { try {
return ChatColor.valueOf(this.color.toUpperCase()); return ChatColor.valueOf(this.color.toUpperCase());
@ -1029,15 +1049,6 @@ public class JSONMessage {
setLegacyColor(color); setLegacyColor(color);
} }
/**
* @param color The legacy ChatColor to set
* @deprecated Use {@link #setColor(String)} instead
*/
@Deprecated
public void setLegacyColor(ChatColor color) {
legacyColor = color;
}
/** /**
* @param color The color to set * @param color The color to set
*/ */
@ -1048,6 +1059,15 @@ public class JSONMessage {
this.color = color; this.color = color;
} }
/**
* @param color The legacy ChatColor to set
* @deprecated Use {@link #setColor(String)} instead
*/
@Deprecated
public void setLegacyColor(ChatColor color) {
legacyColor = color;
}
/** /**
* @return The list of styles * @return The list of styles
*/ */

View File

@ -28,34 +28,31 @@ import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerLoadEvent; import org.bukkit.event.server.ServerLoadEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public final class ServerLoadEventListener implements Listener public final class ServerLoadEventListener implements Listener {
{
@NotNull @NotNull
private final PlaceholderAPIPlugin plugin; private final PlaceholderAPIPlugin plugin;
public ServerLoadEventListener(@NotNull final PlaceholderAPIPlugin plugin) public ServerLoadEventListener(@NotNull final PlaceholderAPIPlugin plugin) {
{ this.plugin = plugin;
this.plugin = plugin;
Bukkit.getPluginManager().registerEvents(this, plugin); Bukkit.getPluginManager().registerEvents(this, plugin);
} }
/** /**
* This method will be called when the server is first loaded * This method will be called when the server is first loaded
* <p> * <p>
* The goal of the method is to register all the expansions as soon as possible * The goal of the method is to register all the expansions as soon as possible especially before
* especially before players can join * players can join
* <p> * <p>
* This will ensure no issues with expansions and hooks. * This will ensure no issues with expansions and hooks.
* *
* @param event the server load event * @param event the server load event
*/ */
@EventHandler @EventHandler
public void onServerLoad(@NotNull final ServerLoadEvent event) public void onServerLoad(@NotNull final ServerLoadEvent event) {
{ HandlerList.unregisterAll(this);
HandlerList.unregisterAll(this); plugin.getLocalExpansionManager().load(Bukkit.getConsoleSender());
plugin.getLocalExpansionManager().load(Bukkit.getConsoleSender()); }
}
} }

View File

@ -20,181 +20,155 @@
package me.clip.placeholderapi.replacer; package me.clip.placeholderapi.replacer;
import java.util.function.Function;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.function.Function; public final class CharsReplacer implements Replacer {
public final class CharsReplacer implements Replacer @NotNull
{ private final Closure closure;
@NotNull public CharsReplacer(@NotNull final Closure closure) {
private final Closure closure; this.closure = closure;
}
public CharsReplacer(@NotNull final Closure closure)
{
this.closure = closure;
}
@NotNull @NotNull
@Override @Override
public String apply(@NotNull final String text, @Nullable final OfflinePlayer player, @NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) public String apply(@NotNull final String text, @Nullable final OfflinePlayer player,
{ @NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) {
final char[] chars = text.toCharArray(); final char[] chars = text.toCharArray();
final StringBuilder builder = new StringBuilder(text.length()); final StringBuilder builder = new StringBuilder(text.length());
final StringBuilder identifier = new StringBuilder(); final StringBuilder identifier = new StringBuilder();
final StringBuilder parameters = new StringBuilder(); final StringBuilder parameters = new StringBuilder();
for (int i = 0; i < chars.length; i++) for (int i = 0; i < chars.length; i++) {
{ final char l = chars[i];
final char l = chars[i];
if (l == '&' && ++i < chars.length) if (l == '&' && ++i < chars.length) {
{ final char c = Character.toLowerCase(chars[i]);
final char c = Character.toLowerCase(chars[i]);
if (c != '0' && c != '1' && c != '2' && c != '3' && c != '4' && c != '5' && c != '6' && c != '7' && c != '8' && c != '9' && c != 'a' && c != 'b' && c != 'c' && c != 'd' && c != 'e' && c != 'f' && c != 'k' && c != 'l' && c != 'm' && c != 'o' && c != 'r' && c != 'x') if (c != '0' && c != '1' && c != '2' && c != '3' && c != '4' && c != '5' && c != '6'
{ && c != '7' && c != '8' && c != '9' && c != 'a' && c != 'b' && c != 'c' && c != 'd'
builder.append(l).append(chars[i]); && c != 'e' && c != 'f' && c != 'k' && c != 'l' && c != 'm' && c != 'o' && c != 'r'
} && c != 'x') {
else builder.append(l).append(chars[i]);
{ } else {
builder.append(ChatColor.COLOR_CHAR); builder.append(ChatColor.COLOR_CHAR);
if (c != 'x') if (c != 'x') {
{ builder.append(chars[i]);
builder.append(chars[i]); continue;
continue; }
}
if ((i > 1 && chars[i - 2] == '\\') /*allow escaping &x*/) if ((i > 1 && chars[i - 2] == '\\') /*allow escaping &x*/) {
{ builder.setLength(builder.length() - 2);
builder.setLength(builder.length() - 2); builder.append('&').append(chars[i]);
builder.append('&').append(chars[i]); continue;
continue; }
}
builder.append(c); builder.append(c);
int j = 0; int j = 0;
while (++j <= 6) while (++j <= 6) {
{ if (i + j >= chars.length) {
if (i + j >= chars.length) break;
{ }
break;
}
final char x = chars[i + j]; final char x = chars[i + j];
builder.append(ChatColor.COLOR_CHAR).append(x); builder.append(ChatColor.COLOR_CHAR).append(x);
} }
if (j == 7) if (j == 7) {
{ i += 6;
i += 6; } else {
} builder.setLength(builder.length() - (j * 2)); // undo &x parsing
else }
{ }
builder.setLength(builder.length() - (j * 2)); // undo &x parsing continue;
} }
}
continue;
}
if (l != closure.head || i + 1 >= chars.length) if (l != closure.head || i + 1 >= chars.length) {
{ builder.append(l);
builder.append(l); continue;
continue; }
}
boolean identified = false; boolean identified = false;
boolean oopsitsbad = true; boolean oopsitsbad = true;
while (++i < chars.length) while (++i < chars.length) {
{ final char p = chars[i];
final char p = chars[i];
if (p == ' ' && !identified) if (p == ' ' && !identified) {
{ break;
break; }
} if (p == closure.tail) {
if (p == closure.tail) oopsitsbad = false;
{ break;
oopsitsbad = false; }
break;
}
if (p == '_' && !identified) if (p == '_' && !identified) {
{ identified = true;
identified = true; continue;
continue; }
}
if (identified) if (identified) {
{ parameters.append(p);
parameters.append(p); } else {
} identifier.append(p);
else }
{ }
identifier.append(p);
}
}
final String identifierString = identifier.toString().toLowerCase(); final String identifierString = identifier.toString().toLowerCase();
final String parametersString = parameters.toString(); final String parametersString = parameters.toString();
identifier.setLength(0); identifier.setLength(0);
parameters.setLength(0); parameters.setLength(0);
if (oopsitsbad) if (oopsitsbad) {
{ builder.append(closure.head).append(identifierString);
builder.append(closure.head).append(identifierString);
if (identified) if (identified) {
{ builder.append('_').append(parametersString);
builder.append('_').append(parametersString); }
}
builder.append(' '); builder.append(' ');
continue; continue;
} }
final PlaceholderExpansion placeholder = lookup.apply(identifierString); final PlaceholderExpansion placeholder = lookup.apply(identifierString);
if (placeholder == null) if (placeholder == null) {
{ builder.append(closure.head).append(identifierString);
builder.append(closure.head).append(identifierString);
if (identified) if (identified) {
{ builder.append('_');
builder.append('_'); }
}
builder.append(parametersString).append(closure.tail); builder.append(parametersString).append(closure.tail);
continue; continue;
} }
final String replacement = placeholder.onRequest(player, parametersString); final String replacement = placeholder.onRequest(player, parametersString);
if (replacement == null) if (replacement == null) {
{ builder.append(closure.head).append(identifierString);
builder.append(closure.head).append(identifierString);
if (identified) if (identified) {
{ builder.append('_');
builder.append('_'); }
}
builder.append(parametersString).append(closure.tail); builder.append(parametersString).append(closure.tail);
continue; continue;
} }
builder.append(ChatColor.translateAlternateColorCodes('&', replacement)); builder.append(ChatColor.translateAlternateColorCodes('&', replacement));
} }
return builder.toString(); return builder.toString();
} }
} }

View File

@ -20,57 +20,53 @@
package me.clip.placeholderapi.replacer; package me.clip.placeholderapi.replacer;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.function.Function; public final class RegexReplacer implements Replacer {
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public final class RegexReplacer implements Replacer @NotNull
{ private final Pattern pattern;
@NotNull public RegexReplacer(@NotNull final Closure closure) {
private final Pattern pattern; this.pattern = Pattern.compile(String
.format("\\%s((?<identifier>[a-zA-Z0-9]+)_)(?<parameters>[^%s%s]+)\\%s", closure.head,
public RegexReplacer(@NotNull final Closure closure) closure.head, closure.tail, closure.tail));
{ }
this.pattern = Pattern.compile(String.format("\\%s((?<identifier>[a-zA-Z0-9]+)_)(?<parameters>[^%s%s]+)\\%s", closure.head, closure.head, closure.tail, closure.tail));
}
@NotNull @NotNull
@Override @Override
public String apply(@NotNull final String text, @Nullable final OfflinePlayer player, @NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) public String apply(@NotNull final String text, @Nullable final OfflinePlayer player,
{ @NotNull final Function<String, @Nullable PlaceholderExpansion> lookup) {
final Matcher matcher = pattern.matcher(text); final Matcher matcher = pattern.matcher(text);
if (!matcher.find()) if (!matcher.find()) {
{ return text;
return text; }
}
final StringBuffer builder = new StringBuffer(); final StringBuffer builder = new StringBuffer();
do do {
{ final String identifier = matcher.group("identifier");
final String identifier = matcher.group("identifier"); final String parameters = matcher.group("parameters");
final String parameters = matcher.group("parameters");
final PlaceholderExpansion expansion = lookup.apply(identifier); final PlaceholderExpansion expansion = lookup.apply(identifier);
if (expansion == null) if (expansion == null) {
{ continue;
continue; }
}
final String requested = expansion.onRequest(player, parameters); final String requested = expansion.onRequest(player, parameters);
matcher.appendReplacement(builder, requested != null ? requested : matcher.group(0)); matcher.appendReplacement(builder, requested != null ? requested : matcher.group(0));
} }
while (matcher.find()); while (matcher.find());
return ChatColor.translateAlternateColorCodes('&', matcher.appendTail(builder).toString()); return ChatColor.translateAlternateColorCodes('&', matcher.appendTail(builder).toString());
} }
} }

View File

@ -20,33 +20,30 @@
package me.clip.placeholderapi.replacer; package me.clip.placeholderapi.replacer;
import java.util.function.Function;
import me.clip.placeholderapi.expansion.PlaceholderExpansion; import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.function.Function; public interface Replacer {
public interface Replacer @NotNull
{ String apply(@NotNull final String text, @Nullable final OfflinePlayer player,
@NotNull final Function<String, @Nullable PlaceholderExpansion> lookup);
@NotNull
String apply(@NotNull final String text, @Nullable final OfflinePlayer player, @NotNull final Function<String, @Nullable PlaceholderExpansion> lookup);
enum Closure enum Closure {
{ BRACKET('{', '}'),
BRACKET('{', '}'), PERCENT('%', '%');
PERCENT('%', '%');
public final char head, tail; public final char head, tail;
Closure(final char head, final char tail) Closure(final char head, final char tail) {
{ this.head = head;
this.head = head; this.tail = tail;
this.tail = tail; }
} }
}
} }

View File

@ -20,6 +20,10 @@
package me.clip.placeholderapi.updatechecker; package me.clip.placeholderapi.updatechecker;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.PlaceholderAPIPlugin;
import me.clip.placeholderapi.util.Msg; import me.clip.placeholderapi.util.Msg;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -28,90 +32,85 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
public class UpdateChecker implements Listener { public class UpdateChecker implements Listener {
private final int RESOURCE_ID = 6245; private final int RESOURCE_ID = 6245;
private final PlaceholderAPIPlugin plugin; private final PlaceholderAPIPlugin plugin;
private final String pluginVersion; private final String pluginVersion;
private String spigotVersion; private String spigotVersion;
private boolean updateAvailable; private boolean updateAvailable;
public UpdateChecker(PlaceholderAPIPlugin i) { public UpdateChecker(PlaceholderAPIPlugin i) {
plugin = i; plugin = i;
pluginVersion = i.getDescription().getVersion(); pluginVersion = i.getDescription().getVersion();
}
public boolean hasUpdateAvailable() {
return updateAvailable;
}
public String getSpigotVersion() {
return spigotVersion;
}
public void fetch() {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
try {
HttpsURLConnection con = (HttpsURLConnection) new URL(
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection();
con.setRequestMethod("GET");
spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine();
} catch (Exception ex) {
plugin.getLogger().info("Failed to check for updates on spigot.");
return;
}
if (spigotVersion == null || spigotVersion.isEmpty()) {
return;
}
updateAvailable = spigotIsNewer();
if (!updateAvailable) {
return;
}
Bukkit.getScheduler().runTask(plugin, () -> {
plugin.getLogger()
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
plugin.getLogger()
.info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/");
Bukkit.getPluginManager().registerEvents(this, plugin);
});
});
}
private boolean spigotIsNewer() {
if (spigotVersion == null || spigotVersion.isEmpty()) {
return false;
} }
public boolean hasUpdateAvailable() { String plV = toReadable(pluginVersion);
return updateAvailable; String spV = toReadable(spigotVersion);
return plV.compareTo(spV) < 0;
}
private String toReadable(String version) {
if (version.contains("-DEV-")) {
version = version.split("-DEV-")[0];
} }
public String getSpigotVersion() { return version.replaceAll("\\.", "");
return spigotVersion; }
}
@EventHandler(priority = EventPriority.MONITOR)
public void fetch() { public void onJoin(PlayerJoinEvent e) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
try { Msg.msg(e.getPlayer(),
HttpsURLConnection con = (HttpsURLConnection) new URL( "&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion()
"https://api.spigotmc.org/legacy/update.php?resource=" + RESOURCE_ID).openConnection(); + "&e)"
con.setRequestMethod("GET"); , "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID
spigotVersion = new BufferedReader(new InputStreamReader(con.getInputStream())).readLine(); + "/");
} catch (Exception ex) {
plugin.getLogger().info("Failed to check for updates on spigot.");
return;
}
if (spigotVersion == null || spigotVersion.isEmpty()) {
return;
}
updateAvailable = spigotIsNewer();
if (!updateAvailable) {
return;
}
Bukkit.getScheduler().runTask(plugin, () -> {
plugin.getLogger()
.info("An update for PlaceholderAPI (v" + getSpigotVersion() + ") is available at:");
plugin.getLogger()
.info("https://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID + "/");
Bukkit.getPluginManager().registerEvents(this, plugin);
});
});
}
private boolean spigotIsNewer() {
if (spigotVersion == null || spigotVersion.isEmpty()) {
return false;
}
String plV = toReadable(pluginVersion);
String spV = toReadable(spigotVersion);
return plV.compareTo(spV) < 0;
}
private String toReadable(String version) {
if (version.contains("-DEV-")) {
version = version.split("-DEV-")[0];
}
return version.replaceAll("\\.", "");
}
@EventHandler(priority = EventPriority.MONITOR)
public void onJoin(PlayerJoinEvent e) {
if (e.getPlayer().hasPermission("placeholderapi.updatenotify")) {
Msg.msg(e.getPlayer(),
"&bAn update for &fPlaceholder&7API &e(&fPlaceholder&7API &fv" + getSpigotVersion()
+ "&e)"
, "&bis available at &ehttps://www.spigotmc.org/resources/placeholderapi." + RESOURCE_ID
+ "/");
}
} }
}
} }

View File

@ -20,9 +20,6 @@
package me.clip.placeholderapi.util; package me.clip.placeholderapi.util;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
@ -31,54 +28,48 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarInputStream; import java.util.jar.JarInputStream;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class FileUtil public class FileUtil {
{
@Nullable @Nullable
public static <T> Class<? extends T> findClass(@NotNull final File file, @NotNull final Class<T> clazz) throws IOException, ClassNotFoundException public static <T> Class<? extends T> findClass(@NotNull final File file,
{ @NotNull final Class<T> clazz) throws IOException, ClassNotFoundException {
if (!file.exists()) if (!file.exists()) {
{ return null;
return null; }
}
final URL jar = file.toURI().toURL(); final URL jar = file.toURI().toURL();
final List<String> matches = new ArrayList<>(); final List<String> matches = new ArrayList<>();
final List<Class<? extends T>> classes = new ArrayList<>(); final List<Class<? extends T>> classes = new ArrayList<>();
try (final JarInputStream stream = new JarInputStream(
jar.openStream()); final URLClassLoader loader = new URLClassLoader(new URL[]{jar},
clazz.getClassLoader())) {
JarEntry entry;
while ((entry = stream.getNextJarEntry()) != null) {
final String name = entry.getName();
if (name == null || name.isEmpty() || !name.endsWith(".class")) {
continue;
}
try (final JarInputStream stream = new JarInputStream(jar.openStream()); final URLClassLoader loader = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader())) matches.add(name.substring(0, name.lastIndexOf('.')).replace('/', '.'));
{ }
JarEntry entry;
while ((entry = stream.getNextJarEntry()) != null)
{
final String name = entry.getName();
if (name == null || name.isEmpty() || !name.endsWith(".class"))
{
continue;
}
matches.add(name.substring(0, name.lastIndexOf('.')).replace('/', '.')); for (final String match : matches) {
} try {
final Class<?> loaded = loader.loadClass(match);
if (clazz.isAssignableFrom(loaded)) {
classes.add(loaded.asSubclass(clazz));
}
} catch (final NoClassDefFoundError ignored) {
}
}
}
for (final String match : matches) return classes.isEmpty() ? null : classes.get(0);
{ }
try
{
final Class<?> loaded = loader.loadClass(match);
if (clazz.isAssignableFrom(loaded))
{
classes.add(loaded.asSubclass(clazz));
}
}
catch (final NoClassDefFoundError ignored)
{ }
}
}
return classes.isEmpty() ? null : classes.get(0);
}
} }

View File

@ -20,11 +20,6 @@
package me.clip.placeholderapi.util; package me.clip.placeholderapi.util;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Optional;
import static java.lang.Math.max; import static java.lang.Math.max;
import static java.lang.Math.min; import static java.lang.Math.min;
import static java.util.Arrays.stream; import static java.util.Arrays.stream;
@ -32,47 +27,44 @@ import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import static java.util.stream.IntStream.range; import static java.util.stream.IntStream.range;
import java.util.List;
import java.util.Optional;
import org.jetbrains.annotations.NotNull;
/** /**
* For the record, I am not sorry. * For the record, I am not sorry.
*/ */
public final class Format public final class Format {
{
private Format() private Format() {}
{}
@NotNull
public static Optional<List<String>> tablify(@NotNull final Align align,
@NotNull final List<List<String>> rows) {
return findSpacing(rows)
.map(spacing -> buildFormat(align, spacing))
.map(format -> rows.stream()
.map(
row -> String.format(format, row.toArray()).substring(align == Align.RIGHT ? 2 : 0))
.collect(toList()));
}
public enum Align @NotNull
{ private static String buildFormat(@NotNull final Align align, @NotNull final int[] spacing) {
LEFT, RIGHT return stream(spacing)
} .mapToObj(space -> "%" + (align == Align.LEFT ? "-" : "") + (space + 2) + "s")
.collect(joining());
}
@NotNull
private static Optional<int[]> findSpacing(@NotNull final List<List<String>> rows) {
return rows.stream()
.map(row -> row.stream().mapToInt(String::length).toArray())
.reduce((l, r) -> range(0, min(l.length, r.length)).map(i -> max(l[i], r[i])).toArray());
}
@NotNull public enum Align {
public static Optional<List<String>> tablify(@NotNull final Align align, @NotNull final List<List<String>> rows) LEFT, RIGHT
{ }
return findSpacing(rows)
.map(spacing -> buildFormat(align, spacing))
.map(format -> rows.stream()
.map(row -> String.format(format, row.toArray()).substring(align == Align.RIGHT ? 2 : 0))
.collect(toList()));
}
@NotNull
private static String buildFormat(@NotNull final Align align, @NotNull final int[] spacing)
{
return stream(spacing)
.mapToObj(space -> "%" + (align == Align.LEFT ? "-" : "") + (space + 2) + "s")
.collect(joining());
}
@NotNull
private static Optional<int[]> findSpacing(@NotNull final List<List<String>> rows)
{
return rows.stream()
.map(row -> row.stream().mapToInt(String::length).toArray())
.reduce((l, r) -> range(0, min(l.length, r.length)).map(i -> max(l[i], r[i])).toArray());
}
} }

View File

@ -20,10 +20,6 @@
package me.clip.placeholderapi.util; package me.clip.placeholderapi.util;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@ -31,53 +27,51 @@ import java.util.function.BiConsumer;
import java.util.stream.Collector; import java.util.stream.Collector;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
public final class Futures public final class Futures {
{
private Futures() private Futures() {}
{}
public static <T> void onMainThread(@NotNull final Plugin plugin, @NotNull final CompletableFuture<T> future, @NotNull final BiConsumer<T, Throwable> consumer) public static <T> void onMainThread(@NotNull final Plugin plugin,
{ @NotNull final CompletableFuture<T> future,
future.whenComplete((value, exception) -> { @NotNull final BiConsumer<T, Throwable> consumer) {
if (Bukkit.isPrimaryThread()) future.whenComplete((value, exception) -> {
{ if (Bukkit.isPrimaryThread()) {
consumer.accept(value, exception); consumer.accept(value, exception);
} } else {
else Bukkit.getScheduler().runTask(plugin, () -> consumer.accept(value, exception));
{ }
Bukkit.getScheduler().runTask(plugin, () -> consumer.accept(value, exception)); });
} }
});
}
@NotNull @NotNull
public static <T> Collector<CompletableFuture<T>, ?, CompletableFuture<List<T>>> collector() public static <T> Collector<CompletableFuture<T>, ?, CompletableFuture<List<T>>> collector() {
{ return Collectors.collectingAndThen(Collectors.toList(), Futures::of);
return Collectors.collectingAndThen(Collectors.toList(), Futures::of); }
}
@NotNull @NotNull
public static <T> CompletableFuture<List<T>> of(@NotNull final Stream<CompletableFuture<T>> futures) public static <T> CompletableFuture<List<T>> of(
{ @NotNull final Stream<CompletableFuture<T>> futures) {
return of(futures.collect(Collectors.toList())); return of(futures.collect(Collectors.toList()));
} }
@NotNull @NotNull
public static <T> CompletableFuture<List<T>> of(@NotNull final Collection<CompletableFuture<T>> futures) public static <T> CompletableFuture<List<T>> of(
{ @NotNull final Collection<CompletableFuture<T>> futures) {
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApplyAsync($ -> awaitCompletion(futures)); .thenApplyAsync($ -> awaitCompletion(futures));
} }
@NotNull @NotNull
private static <T> List<T> awaitCompletion(@NotNull final Collection<CompletableFuture<T>> futures) private static <T> List<T> awaitCompletion(
{ @NotNull final Collection<CompletableFuture<T>> futures) {
return futures.stream().map(CompletableFuture::join).collect(Collectors.toList()); return futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
} }
} }

View File

@ -20,40 +20,34 @@
package me.clip.placeholderapi.util; package me.clip.placeholderapi.util;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Arrays; public final class Msg {
import java.util.stream.Collectors;
public final class Msg public static void msg(@NotNull final CommandSender sender, @NotNull final String... messages) {
{ if (messages.length == 0) {
return;
}
public static void msg(@NotNull final CommandSender sender, @NotNull final String... messages) sender.sendMessage(Arrays.stream(messages).map(Msg::color).collect(Collectors.joining("\n")));
{ }
if (messages.length == 0)
{
return;
}
sender.sendMessage(Arrays.stream(messages).map(Msg::color).collect(Collectors.joining("\n"))); public static void broadcast(@NotNull final String... messages) {
} if (messages.length == 0) {
return;
}
public static void broadcast(@NotNull final String... messages) Bukkit.broadcastMessage(
{ Arrays.stream(messages).map(Msg::color).collect(Collectors.joining("\n")));
if (messages.length == 0) }
{
return;
}
Bukkit.broadcastMessage(Arrays.stream(messages).map(Msg::color).collect(Collectors.joining("\n"))); public static String color(@NotNull final String text) {
} return ChatColor.translateAlternateColorCodes('&', text);
}
public static String color(@NotNull final String text)
{
return ChatColor.translateAlternateColorCodes('&', text);
}
} }

View File

@ -21,8 +21,8 @@
package me.clip.placeholderapi.util; package me.clip.placeholderapi.util;
public enum TimeFormat { public enum TimeFormat {
DAYS, DAYS,
HOURS, HOURS,
MINUTES, MINUTES,
SECONDS SECONDS
} }

View File

@ -25,146 +25,147 @@ import java.time.temporal.ChronoUnit;
public class TimeUtil { public class TimeUtil {
public static String getRemaining(int seconds, TimeFormat type) { public static String getRemaining(int seconds, TimeFormat type) {
if (seconds < 60) { if (seconds < 60) {
switch (type) { switch (type) {
case DAYS: case DAYS:
case HOURS: case HOURS:
case MINUTES: case MINUTES:
return "0"; return "0";
case SECONDS: case SECONDS:
return String.valueOf(seconds); return String.valueOf(seconds);
} }
return String.valueOf(seconds); return String.valueOf(seconds);
}
int minutes = seconds / 60;
int s = 60 * minutes;
int secondsLeft = seconds - s;
if (minutes < 60) {
switch (type) {
case DAYS:
case HOURS:
return "0";
case MINUTES:
return String.valueOf(minutes);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
}
if (minutes < 1440) {
int hours = minutes / 60;
int inMins = 60 * hours;
int leftOver = minutes - inMins;
switch (type) {
case DAYS:
return "0";
case HOURS:
return String.valueOf(hours);
case MINUTES:
return String.valueOf(leftOver);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
}
int days = minutes / 1440;
int inMins = 1440 * days;
int leftOver = minutes - inMins;
if (leftOver < 60) {
switch (type) {
case DAYS:
return String.valueOf(days);
case HOURS:
return String.valueOf(0);
case MINUTES:
return String.valueOf(leftOver);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
} else {
int hours = leftOver / 60;
int hoursInMins = 60 * hours;
int minsLeft = leftOver - hoursInMins;
switch (type) {
case DAYS:
return String.valueOf(days);
case HOURS:
return String.valueOf(hours);
case MINUTES:
return String.valueOf(minsLeft);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
}
} }
public static String getTime(int seconds) { int minutes = seconds / 60;
return getTime(Duration.ofSeconds(seconds)); int s = 60 * minutes;
int secondsLeft = seconds - s;
if (minutes < 60) {
switch (type) {
case DAYS:
case HOURS:
return "0";
case MINUTES:
return String.valueOf(minutes);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
} }
/** if (minutes < 1440) {
* Format the given value with s, m, h and d (seconds, minutes, hours and days) int hours = minutes / 60;
* int inMins = 60 * hours;
* @param duration {@link Duration} (eg, Duration.of(20, {@link ChronoUnit#SECONDS}) for 20 seconds) int leftOver = minutes - inMins;
* @return formatted time
*/
public static String getTime(final Duration duration) {
final StringBuilder builder = new StringBuilder();
long seconds = duration.getSeconds(); switch (type) {
long minutes = seconds / 60; case DAYS:
long hours = minutes / 60; return "0";
long days = hours / 24; case HOURS:
return String.valueOf(hours);
case MINUTES:
return String.valueOf(leftOver);
case SECONDS:
return String.valueOf(secondsLeft);
}
seconds %= 60; return String.valueOf(seconds);
minutes %= 60;
hours %= 60;
days %= 24;
if (seconds > 0) {
builder.insert(0, seconds + "s");
}
if (minutes > 0) {
if (builder.length() > 0) {
builder.insert(0, ' ');
}
builder.insert(0, minutes + "m");
}
if (hours > 0) {
if (builder.length() > 0) {
builder.insert(0, ' ');
}
builder.insert(0, hours + "h");
}
if (days > 0) {
if (builder.length() > 0) {
builder.insert(0, ' ');
}
builder.insert(0, days + "d");
}
return builder.toString();
} }
int days = minutes / 1440;
int inMins = 1440 * days;
int leftOver = minutes - inMins;
if (leftOver < 60) {
switch (type) {
case DAYS:
return String.valueOf(days);
case HOURS:
return String.valueOf(0);
case MINUTES:
return String.valueOf(leftOver);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
} else {
int hours = leftOver / 60;
int hoursInMins = 60 * hours;
int minsLeft = leftOver - hoursInMins;
switch (type) {
case DAYS:
return String.valueOf(days);
case HOURS:
return String.valueOf(hours);
case MINUTES:
return String.valueOf(minsLeft);
case SECONDS:
return String.valueOf(secondsLeft);
}
return String.valueOf(seconds);
}
}
public static String getTime(int seconds) {
return getTime(Duration.ofSeconds(seconds));
}
/**
* Format the given value with s, m, h and d (seconds, minutes, hours and days)
*
* @param duration {@link Duration} (eg, Duration.of(20, {@link ChronoUnit#SECONDS}) for 20
* seconds)
* @return formatted time
*/
public static String getTime(final Duration duration) {
final StringBuilder builder = new StringBuilder();
long seconds = duration.getSeconds();
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;
seconds %= 60;
minutes %= 60;
hours %= 60;
days %= 24;
if (seconds > 0) {
builder.insert(0, seconds + "s");
}
if (minutes > 0) {
if (builder.length() > 0) {
builder.insert(0, ' ');
}
builder.insert(0, minutes + "m");
}
if (hours > 0) {
if (builder.length() > 0) {
builder.insert(0, ' ');
}
builder.insert(0, hours + "h");
}
if (days > 0) {
if (builder.length() > 0) {
builder.insert(0, ' ');
}
builder.insert(0, days + "d");
}
return builder.toString();
}
} }

View File

@ -21,15 +21,15 @@ permissions:
placeholderapi.admin: placeholderapi.admin:
description: "Ability to use all PAPI commands" description: "Ability to use all PAPI commands"
children: children:
placeholderapi.help: true placeholderapi.help: true
placeholderapi.info: true placeholderapi.info: true
placeholderapi.list: true placeholderapi.list: true
placeholderapi.parse: true placeholderapi.parse: true
placeholderapi.reload: true placeholderapi.reload: true
placeholderapi.version: true placeholderapi.version: true
placeholderapi.register: true placeholderapi.register: true
placeholderapi.unregister: true placeholderapi.unregister: true
placeholderapi.updatenotify: true placeholderapi.updatenotify: true
placeholderapi.ecloud.*: placeholderapi.ecloud.*:
description: "Ability to use all PAPI ecloud commands" description: "Ability to use all PAPI ecloud commands"
children: children:

View File

@ -29,75 +29,67 @@ import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public interface Values public interface Values {
{
String SMALL_TEXT = "My name is %player_name%"; String SMALL_TEXT = "My name is %player_name%";
String LARGE_TEXT = "My name is %player_name% and my location is (%player_x%, %player_y%, %player_z%), this placeholder is invalid %server_name%"; String LARGE_TEXT = "My name is %player_name% and my location is (%player_x%, %player_y%, %player_z%), this placeholder is invalid %server_name%";
ImmutableMap<String, PlaceholderExpansion> PLACEHOLDERS = ImmutableMap.<String, PlaceholderExpansion>builder() ImmutableMap<String, PlaceholderExpansion> PLACEHOLDERS = ImmutableMap.<String, PlaceholderExpansion>builder()
.put("player", new MockPlayerPlaceholderExpansion()) .put("player", new MockPlayerPlaceholderExpansion())
.build(); .build();
Replacer CHARS_REPLACER = new CharsReplacer(Replacer.Closure.PERCENT); Replacer CHARS_REPLACER = new CharsReplacer(Replacer.Closure.PERCENT);
Replacer REGEX_REPLACER = new RegexReplacer(Replacer.Closure.PERCENT); Replacer REGEX_REPLACER = new RegexReplacer(Replacer.Closure.PERCENT);
final class MockPlayerPlaceholderExpansion extends PlaceholderExpansion final class MockPlayerPlaceholderExpansion extends PlaceholderExpansion {
{
public static final String PLAYER_X = "10"; public static final String PLAYER_X = "10";
public static final String PLAYER_Y = "20"; public static final String PLAYER_Y = "20";
public static final String PLAYER_Z = "30"; public static final String PLAYER_Z = "30";
public static final String PLAYER_NAME = "Sxtanna"; public static final String PLAYER_NAME = "Sxtanna";
@NotNull @NotNull
@Override @Override
public String getIdentifier() public String getIdentifier() {
{ return "player";
return "player"; }
}
@NotNull @NotNull
@Override @Override
public String getAuthor() public String getAuthor() {
{ return "Sxtanna";
return "Sxtanna"; }
}
@NotNull @NotNull
@Override @Override
public String getVersion() public String getVersion() {
{ return "1.0";
return "1.0"; }
}
@Override @Override
public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params) public String onRequest(@Nullable final OfflinePlayer player, @NotNull final String params) {
{ final String[] parts = params.split("_");
final String[] parts = params.split("_"); if (parts.length == 0) {
if (parts.length == 0) return null;
{ }
return null;
}
switch (parts[0]) switch (parts[0]) {
{ case "name":
case "name": return PLAYER_NAME;
return PLAYER_NAME; case "x":
case "x": return PLAYER_X;
return PLAYER_X; case "y":
case "y": return PLAYER_Y;
return PLAYER_Y; case "z":
case "z": return PLAYER_Z;
return PLAYER_Z; }
}
return null; return null;
} }
} }
} }

View File

@ -23,31 +23,26 @@ package me.clip.placeholderapi.replacer;
import me.clip.placeholderapi.Values; import me.clip.placeholderapi.Values;
import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Benchmark;
public class ReplacerBenchmarks public class ReplacerBenchmarks {
{
@Benchmark @Benchmark
public void measureCharsReplacerSmallText() public void measureCharsReplacerSmallText() {
{ Values.CHARS_REPLACER.apply(Values.SMALL_TEXT, null, Values.PLACEHOLDERS::get);
Values.CHARS_REPLACER.apply(Values.SMALL_TEXT, null, Values.PLACEHOLDERS::get); }
}
@Benchmark @Benchmark
public void measureRegexReplacerSmallText() public void measureRegexReplacerSmallText() {
{ Values.REGEX_REPLACER.apply(Values.SMALL_TEXT, null, Values.PLACEHOLDERS::get);
Values.REGEX_REPLACER.apply(Values.SMALL_TEXT, null, Values.PLACEHOLDERS::get); }
}
@Benchmark @Benchmark
public void measureCharsReplacerLargeText() public void measureCharsReplacerLargeText() {
{ Values.CHARS_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get);
Values.CHARS_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get); }
}
@Benchmark @Benchmark
public void measureRegexReplacerLargeText() public void measureRegexReplacerLargeText() {
{ Values.REGEX_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get);
Values.REGEX_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get); }
}
} }

View File

@ -20,76 +20,80 @@
package me.clip.placeholderapi.replacer; package me.clip.placeholderapi.replacer;
import me.clip.placeholderapi.Values;
import org.junit.jupiter.api.Test;
import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_NAME; import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_NAME;
import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_X; import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_X;
import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_Y; import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_Y;
import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_Z; import static me.clip.placeholderapi.Values.MockPlayerPlaceholderExpansion.PLAYER_Z;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
public final class ReplacerUnitTester import me.clip.placeholderapi.Values;
{ import org.junit.jupiter.api.Test;
@Test public final class ReplacerUnitTester {
void testCharsReplacerProducesExpectedSingleValue()
{
assertEquals(PLAYER_NAME, Values.CHARS_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get));
}
@Test @Test
void testRegexReplacerProducesExpectedSingleValue() void testCharsReplacerProducesExpectedSingleValue() {
{ assertEquals(PLAYER_NAME,
assertEquals(PLAYER_NAME, Values.REGEX_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get)); Values.CHARS_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get));
} }
@Test @Test
void testCharsReplacerProducesExpectedSentence() void testRegexReplacerProducesExpectedSingleValue() {
{ assertEquals(PLAYER_NAME,
assertEquals(String.format("My name is %s and my location is (%s, %s, %s), this placeholder is invalid %%server_name%%", PLAYER_NAME, PLAYER_X, PLAYER_Y, PLAYER_Z), Values.CHARS_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get)); Values.REGEX_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get));
} }
@Test @Test
void testRegexReplacerProducesExpectedSentence() void testCharsReplacerProducesExpectedSentence() {
{ assertEquals(String.format(
assertEquals(String.format("My name is %s and my location is (%s, %s, %s), this placeholder is invalid %%server_name%%", PLAYER_NAME, PLAYER_X, PLAYER_Y, PLAYER_Z), Values.REGEX_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get)); "My name is %s and my location is (%s, %s, %s), this placeholder is invalid %%server_name%%",
} PLAYER_NAME, PLAYER_X, PLAYER_Y, PLAYER_Z),
Values.CHARS_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get));
}
@Test @Test
void testResultsAreTheSameAsReplacement() void testRegexReplacerProducesExpectedSentence() {
{ assertEquals(String.format(
final String resultChars = Values.CHARS_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get); "My name is %s and my location is (%s, %s, %s), this placeholder is invalid %%server_name%%",
final String resultRegex = Values.REGEX_REPLACER.apply("%player_name%", null, Values.PLACEHOLDERS::get); PLAYER_NAME, PLAYER_X, PLAYER_Y, PLAYER_Z),
Values.REGEX_REPLACER.apply(Values.LARGE_TEXT, null, Values.PLACEHOLDERS::get));
}
assertEquals(resultChars, resultRegex); @Test
void testResultsAreTheSameAsReplacement() {
final String resultChars = Values.CHARS_REPLACER
.apply("%player_name%", null, Values.PLACEHOLDERS::get);
final String resultRegex = Values.REGEX_REPLACER
.apply("%player_name%", null, Values.PLACEHOLDERS::get);
assertEquals(PLAYER_NAME, resultChars); assertEquals(resultChars, resultRegex);
}
@Test assertEquals(PLAYER_NAME, resultChars);
void testResultsAreTheSameNoReplacement() }
{
final String resultChars = Values.CHARS_REPLACER.apply("%player_location%", null, Values.PLACEHOLDERS::get);
final String resultRegex = Values.REGEX_REPLACER.apply("%player_location%", null, Values.PLACEHOLDERS::get);
assertEquals(resultChars, resultRegex); @Test
} void testResultsAreTheSameNoReplacement() {
final String resultChars = Values.CHARS_REPLACER
.apply("%player_location%", null, Values.PLACEHOLDERS::get);
final String resultRegex = Values.REGEX_REPLACER
.apply("%player_location%", null, Values.PLACEHOLDERS::get);
@Test assertEquals(resultChars, resultRegex);
void testCharsReplacerIgnoresMalformed() }
{
final String text = "10% and %hello world 15%";
assertEquals(text, Values.CHARS_REPLACER.apply(text, null, Values.PLACEHOLDERS::get)); @Test
} void testCharsReplacerIgnoresMalformed() {
final String text = "10% and %hello world 15%";
@Test assertEquals(text, Values.CHARS_REPLACER.apply(text, null, Values.PLACEHOLDERS::get));
void testCharsReplacerHandlesEscapedHex() }
{
final String text = "\\&xffffffThis should not change.";
assertEquals(text.substring(1), Values.CHARS_REPLACER.apply(text, null, Values.PLACEHOLDERS::get)); @Test
} void testCharsReplacerHandlesEscapedHex() {
final String text = "\\&xffffffThis should not change.";
assertEquals(text.substring(1),
Values.CHARS_REPLACER.apply(text, null, Values.PLACEHOLDERS::get));
}
} }