Internal Placeholders are now working

It works, but it is more like a DIY patch thing. It has a few problems with the current implementation :
1. It doesn't suit our "code style" : it uses an Handler instead of a Manager, eg.
2. It is a bit laggy (I've got the feeling that it could be improved)
3. It doesn't hook to other Placeholder APIs for now
And a few other things.

I think this is more like a Proof of Concept : it will have to be improved in the next weeks.
This commit is contained in:
Florian CUNY 2018-02-10 13:54:27 +01:00
parent 65245a99f5
commit b04602302b
10 changed files with 154 additions and 139 deletions

View File

@ -3,6 +3,7 @@ package us.tastybento.bskyblock;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import us.tastybento.bskyblock.api.placeholders.PlaceholderHandler;
import us.tastybento.bskyblock.commands.AdminCommand; import us.tastybento.bskyblock.commands.AdminCommand;
import us.tastybento.bskyblock.commands.IslandCommand; import us.tastybento.bskyblock.commands.IslandCommand;
import us.tastybento.bskyblock.database.BSBDatabase; import us.tastybento.bskyblock.database.BSBDatabase;
@ -96,11 +97,11 @@ public class BSkyBlock extends JavaPlugin {
islandsManager.load(); islandsManager.load();
localesManager = new LocalesManager(plugin); localesManager = new LocalesManager(plugin);
PlaceholderHandler.register(plugin);
// Register Listeners // Register Listeners
registerListeners(); registerListeners();
// Load addons // Load addons
addonsManager = new AddonsManager(plugin); addonsManager = new AddonsManager(plugin);
addonsManager.enableAddons(); addonsManager.enableAddons();

View File

@ -17,6 +17,7 @@ import org.bukkit.inventory.PlayerInventory;
import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.permissions.PermissionAttachmentInfo;
import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.placeholders.PlaceholderHandler;
/** /**
* BSB's user object. Wraps Player. * BSB's user object. Wraps Player.
@ -172,6 +173,9 @@ public class User {
} }
} }
// Replace placeholders
translation = PlaceholderHandler.replacePlaceholders(this, translation);
return ChatColor.translateAlternateColorCodes('&', translation); return ChatColor.translateAlternateColorCodes('&', translation);
} }

View File

@ -0,0 +1,29 @@
package us.tastybento.bskyblock.api.placeholders;
import us.tastybento.bskyblock.api.commands.User;
/**
* @author Poslovitch
*/
public class Placeholder {
private String identifier;
private PlaceholderRequest request;
Placeholder(String identifier, PlaceholderRequest request) {
this.identifier = identifier;
this.request = request;
}
public String getIdentifier() {
return this.identifier;
}
public PlaceholderRequest getRequest() {
return request;
}
public interface PlaceholderRequest {
String request(User user);
}
}

View File

@ -1,40 +1,39 @@
package us.tastybento.bskyblock.util.placeholders; package us.tastybento.bskyblock.api.placeholders;
import org.bukkit.command.CommandSender;
import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.commands.User;
/** /**
* Simple interface for every Placeholder API. * Simple interface for every Placeholder API.
* *
* @author Poslovitch * @author Poslovitch
*/ */
public interface PlaceholderInterface { public interface PlaceholderAPIInterface {
/** /**
* Get the name of the Placeholder API * Gets the name of the Placeholder API
* @return name of the placeholder plugin * @return name of the placeholder plugin
*/ */
String getName(); String getName();
/** /**
* Register the placeholder API * Registers the placeholder API
* @param plugin * @param plugin
* @return true if registered * @return true if successfully registered
*/ */
boolean register(BSkyBlock plugin); boolean register(BSkyBlock plugin);
/** /**
* Unregister the placeholder API * Unregisters the placeholder API
* @param plugin * @param plugin
*/ */
void unregister(BSkyBlock plugin); void unregister(BSkyBlock plugin);
/** /**
* Replace placeholders in the message according to the receiver * Replace placeholders in the message according to the receiver
* @param sender * @param receiver
* @param message * @param message
* @return updated message * @return updated message
*/ */
String replacePlaceholders(CommandSender receiver, String message); String replacePlaceholders(User receiver, String message);
} }

View File

@ -0,0 +1,21 @@
package us.tastybento.bskyblock.api.placeholders;
public class PlaceholderBuilder {
private String identifier;
private Placeholder.PlaceholderRequest value;
public PlaceholderBuilder identifier(String identifier) {
this.identifier = identifier;
return this;
}
public PlaceholderBuilder value(Placeholder.PlaceholderRequest value) {
this.value = value;
return this;
}
public Placeholder build() {
return new Placeholder(identifier, value);
}
}

View File

@ -1,12 +1,12 @@
package us.tastybento.bskyblock.util.placeholders; package us.tastybento.bskyblock.api.placeholders;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import org.bukkit.command.CommandSender;
import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.commands.User;
import us.tastybento.bskyblock.lists.Placeholders;
/** /**
* Handles hooks with other Placeholder APIs. * Handles hooks with other Placeholder APIs.
@ -14,7 +14,7 @@ import us.tastybento.bskyblock.BSkyBlock;
* @author Poslovitch, Tastybento * @author Poslovitch, Tastybento
*/ */
public class PlaceholderHandler { public class PlaceholderHandler {
private static final String PACKAGE = "us.tastybento.bskyblock.util.placeholders.hooks."; private static final String PACKAGE = "us.tastybento.bskyblock.api.placeholders.hooks.";
/** /**
* List of API classes in the package specified above (except the Internal one) * List of API classes in the package specified above (except the Internal one)
*/ */
@ -22,7 +22,7 @@ public class PlaceholderHandler {
//TODO //TODO
}; };
private static List<PlaceholderInterface> apis = new ArrayList<>(); private static List<PlaceholderAPIInterface> apis = new ArrayList<>();
/** /**
* Register placeholders and hooks * Register placeholders and hooks
@ -30,12 +30,12 @@ public class PlaceholderHandler {
*/ */
public static void register(BSkyBlock plugin){ public static void register(BSkyBlock plugin){
// Register placeholders // Register placeholders
new Placeholders(plugin); new Placeholders();
// Load Internal Placeholder API // Load Internal Placeholder API
try{ try{
Class<?> clazz = Class.forName(PACKAGE + "InternalPlaceholderImpl"); Class<?> clazz = Class.forName(PACKAGE + "InternalPlaceholderImpl");
PlaceholderInterface internal = (PlaceholderInterface)clazz.newInstance(); PlaceholderAPIInterface internal = (PlaceholderAPIInterface)clazz.newInstance();
apis.add(internal); apis.add(internal);
} catch (Exception e){ } catch (Exception e){
// Should never happen. // Should never happen.
@ -47,7 +47,7 @@ public class PlaceholderHandler {
if(plugin.getServer().getPluginManager().isPluginEnabled(hook)){ if(plugin.getServer().getPluginManager().isPluginEnabled(hook)){
try{ try{
Class<?> clazz = Class.forName(PACKAGE + hook + "PlaceholderImpl"); Class<?> clazz = Class.forName(PACKAGE + hook + "PlaceholderImpl");
PlaceholderInterface api = (PlaceholderInterface)clazz.newInstance(); PlaceholderAPIInterface api = (PlaceholderAPIInterface)clazz.newInstance();
if(api.register(plugin)){ if(api.register(plugin)){
plugin.getLogger().info("Hooked placeholders into " + hook); plugin.getLogger().info("Hooked placeholders into " + hook);
apis.add(api); apis.add(api);
@ -66,9 +66,9 @@ public class PlaceholderHandler {
* @param plugin * @param plugin
*/ */
public static void unregister(BSkyBlock plugin){ public static void unregister(BSkyBlock plugin){
Iterator<PlaceholderInterface> it = apis.iterator(); Iterator<PlaceholderAPIInterface> it = apis.iterator();
while (it.hasNext()) { while (it.hasNext()) {
PlaceholderInterface api = it.next(); PlaceholderAPIInterface api = it.next();
api.unregister(plugin); api.unregister(plugin);
it.remove(); it.remove();
} }
@ -80,12 +80,8 @@ public class PlaceholderHandler {
* @param message * @param message
* @return updated message * @return updated message
*/ */
public static String replacePlaceholders(CommandSender receiver, String message){ public static String replacePlaceholders(User receiver, String message){
if(message == null || message.isEmpty()) { for(PlaceholderAPIInterface api : apis){
return "";
}
for(PlaceholderInterface api : apis){
message = api.replacePlaceholders(receiver, message); message = api.replacePlaceholders(receiver, message);
} }
@ -96,6 +92,6 @@ public class PlaceholderHandler {
* @return true if APIs are registered (including Internal), otherwise false * @return true if APIs are registered (including Internal), otherwise false
*/ */
public static boolean hasHooks(){ public static boolean hasHooks(){
return apis != null ? true : false; return apis != null;
} }
} }

View File

@ -0,0 +1,47 @@
package us.tastybento.bskyblock.api.placeholders.hooks;
import java.util.regex.Pattern;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.commands.User;
import us.tastybento.bskyblock.api.placeholders.Placeholder;
import us.tastybento.bskyblock.api.placeholders.PlaceholderAPIInterface;
import us.tastybento.bskyblock.lists.Placeholders;
/**
* Built-in placeholder API
*
* @author Poslovitch
*/
public class InternalPlaceholderImpl implements PlaceholderAPIInterface {
@Override
public String getName() {
return "Internal";
}
@Override
public boolean register(BSkyBlock plugin) {
return true;
}
@Override
public void unregister(BSkyBlock plugin) {
// Useless : it would disable the placeholders.
}
@Override
public String replacePlaceholders(User receiver, String message) {
if(message == null || message.isEmpty()) {
return "";
}
for(Placeholder placeholder : Placeholders.values()){
String identifier = "%" + placeholder.getIdentifier() + "%";
message = message.replaceAll(identifier, placeholder.getRequest().request(receiver));
}
return message;
}
}

View File

@ -0,0 +1,29 @@
package us.tastybento.bskyblock.lists;
import org.bukkit.Bukkit;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.placeholders.Placeholder;
import us.tastybento.bskyblock.api.placeholders.PlaceholderBuilder;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Placeholders {
public static final Placeholder PLUGIN_NAME = new PlaceholderBuilder().identifier("bsb_plugin_name").value((user) -> BSkyBlock.getInstance().getDescription().getName()).build();
/**
* @return List of all the flags in this class
*/
public static List<Placeholder> values() {
return Arrays.asList(Placeholders.class.getFields()).stream().map(field -> {
try {
return (Placeholder)field.get(null);
} catch (IllegalArgumentException | IllegalAccessException e) {
Bukkit.getLogger().severe("Could not get Placeholders values " + e.getMessage());
}
return null;
}).collect(Collectors.toList());
}
}

View File

@ -1,63 +0,0 @@
package us.tastybento.bskyblock.util.placeholders;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.command.CommandSender;
import us.tastybento.bskyblock.BSkyBlock;
/**
* Register placeholders
*
* @author Poslovitch
*/
public class Placeholders {
private static Set<Placeholder> placeholders = new HashSet<>();
private BSkyBlock plugin;
protected Placeholders(BSkyBlock plugin){
this.plugin = plugin;
register();
}
private void register(){
/* PLUGIN */
new Placeholder("bsb_name"){
@Override
public String onRequest(CommandSender receiver) {
return plugin.getDescription().getName();
}
};
new Placeholder("bsb_version") {
@Override
public String onRequest(CommandSender receiver) {
return plugin.getDescription().getVersion();
}
};
//TODO: add more placeholders
}
public static Set<Placeholder> getPlaceholders(){
return placeholders;
}
public abstract class Placeholder{
private String identifier;
protected Placeholder(String identifier){
this.identifier = identifier;
placeholders.add(this);
}
public String getIdentifier(){
return identifier;
}
public abstract String onRequest(CommandSender receiver);
}
}

View File

@ -1,48 +0,0 @@
package us.tastybento.bskyblock.util.placeholders.hooks;
import java.util.regex.Pattern;
import org.bukkit.command.CommandSender;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.util.placeholders.PlaceholderInterface;
import us.tastybento.bskyblock.util.placeholders.Placeholders;
import us.tastybento.bskyblock.util.placeholders.Placeholders.Placeholder;
/**
* Built-in placeholder API
*
* @author Poslovitch
*/
public class InternalPlaceholderImpl implements PlaceholderInterface{
@Override
public String getName() {
return "Internal";
}
@Override
public boolean register(BSkyBlock plugin) {
return true;
}
@Override
public void unregister(BSkyBlock plugin) {
// Useless : it would disable the placeholders.
}
@Override
public String replacePlaceholders(CommandSender receiver, String message) {
if(message == null || message.isEmpty()) {
return "";
}
for(Placeholder placeholder : Placeholders.getPlaceholders()){
String identifier = "{" + placeholder.getIdentifier() + "}";
message = message.replaceAll(Pattern.quote(identifier), placeholder.onRequest(receiver));
}
return message;
}
}