Decouple Message class from replacement providers

- Instead of applying replacements by testing for a replacement that has the GeneralRegion type, it now checks for a ReplacementProvider instances (one step closer to making Message independent of AreaShop).
- Replacements are handled one by one with a switch-case instead of getting them from a map, helps performance a lot.
This commit is contained in:
Thijs Wiefferink 2016-10-25 20:57:58 +02:00
parent 5efe14b8e9
commit 293978f068
10 changed files with 278 additions and 224 deletions

View File

@ -85,55 +85,55 @@ public final class AreaShop extends JavaPlugin implements AreaShopInterface {
public static final int versionFilesCurrent = 3; public static final int versionFilesCurrent = 3;
// Keys for replacing parts of flags, commands, strings // Keys for replacing parts of flags, commands, strings
public static final String tagPlayerName = "%player%"; public static final String tagPlayerName = "player";
public static final String tagPlayerUUID = "%uuid%"; public static final String tagPlayerUUID = "uuid";
public static final String tagWorldName = "%world%"; public static final String tagWorldName = "world";
public static final String tagRegionName = "%region%"; public static final String tagRegionName = "region";
public static final String tagRegionType = "%type%"; public static final String tagRegionType = "type";
public static final String tagPrice = "%price%"; public static final String tagPrice = "price";
public static final String tagRawPrice = "%rawprice%"; public static final String tagRawPrice = "rawprice";
public static final String tagDuration = "%duration%"; public static final String tagDuration = "duration";
public static final String tagRentedUntil = "%until%"; public static final String tagRentedUntil = "until";
public static final String tagRentedUntilShort = "%untilshort%"; public static final String tagRentedUntilShort = "untilshort";
public static final String tagWidth = "%width%"; // x-axis public static final String tagWidth = "width"; // x-axis
public static final String tagHeight = "%height%"; // y-axis public static final String tagHeight = "height"; // y-axis
public static final String tagDepth = "%depth%"; // z-axis public static final String tagDepth = "depth"; // z-axis
public static final String tagTimeLeft = "%timeleft%"; public static final String tagTimeLeft = "timeleft";
public static final String tagClicker = "%clicker%"; public static final String tagClicker = "clicker";
public static final String tagResellPrice = "%resellprice%"; public static final String tagResellPrice = "resellprice";
public static final String tagRawResellPrice = "%rawresellprice%"; public static final String tagRawResellPrice = "rawresellprice";
public static final String tagFriends = "%friends%"; public static final String tagFriends = "friends";
public static final String tagFriendsUUID = "%friendsuuid%"; public static final String tagFriendsUUID = "friendsuuid";
public static final String tagMoneyBackPercentage = "%moneybackpercent%"; public static final String tagMoneyBackPercentage = "moneybackpercent";
public static final String tagMoneyBackAmount = "%moneyback%"; public static final String tagMoneyBackAmount = "moneyback";
public static final String tagRawMoneyBackAmount = "%rawmoneyback%"; public static final String tagRawMoneyBackAmount = "rawmoneyback";
public static final String tagMaxExtends = "%maxextends%"; public static final String tagMaxExtends = "maxextends";
public static final String tagExtendsLeft = "%extendsleft%"; public static final String tagExtendsLeft = "extendsleft";
public static final String tagMaxRentTime = "%maxrenttime%"; public static final String tagMaxRentTime = "maxrenttime";
public static final String tagMaxInactiveTime = "%inactivetime%"; public static final String tagMaxInactiveTime = "inactivetime";
public static final String tagLandlord = "%landlord%"; public static final String tagLandlord = "landlord";
public static final String tagLandlordUUID = "%landlorduuid%"; public static final String tagLandlordUUID = "landlorduuid";
public static final String tagDateTime = "%datetime%"; public static final String tagDateTime = "datetime";
public static final String tagDateTimeShort = "%datetimeshort%"; public static final String tagDateTimeShort = "datetimeshort";
public static final String tagYear = "%year%"; public static final String tagYear = "year";
public static final String tagMonth = "%month%"; public static final String tagMonth = "month";
public static final String tagDay = "%day%"; public static final String tagDay = "day";
public static final String tagHour = "%hour%"; public static final String tagHour = "hour";
public static final String tagMinute = "%minute%"; public static final String tagMinute = "minute";
public static final String tagSecond = "%second%"; public static final String tagSecond = "second";
public static final String tagMillisecond = "%millisecond%"; public static final String tagMillisecond = "millisecond";
public static final String tagEpoch = "%epoch%"; public static final String tagEpoch = "epoch";
public static final String tagTeleportX = "%tpx%"; public static final String tagTeleportX = "tpx";
public static final String tagTeleportY = "%tpy%"; public static final String tagTeleportY = "tpy";
public static final String tagTeleportZ = "%tpz%"; public static final String tagTeleportZ = "tpz";
public static final String tagTeleportBlockX = "%tpblockx%"; public static final String tagTeleportBlockX = "tpblockx";
public static final String tagTeleportBlockY = "%tpblocky%"; public static final String tagTeleportBlockY = "tpblocky";
public static final String tagTeleportBlockZ = "%tpblockz%"; public static final String tagTeleportBlockZ = "tpblockz";
public static final String tagTeleportPitch = "%tppitch%"; public static final String tagTeleportPitch = "tppitch";
public static final String tagTeleportYaw = "%tpyaw%"; public static final String tagTeleportYaw = "tpyaw";
public static final String tagTeleportPitchRound = "%tppitchround%"; public static final String tagTeleportPitchRound = "tppitchround";
public static final String tagTeleportYawRound = "%tpyawround%"; public static final String tagTeleportYawRound = "tpyawround";
public static final String tagTeleportWorld = "%tpworld%"; public static final String tagTeleportWorld = "tpworld";
public static AreaShop getInstance() { public static AreaShop getInstance() {
return AreaShop.instance; return AreaShop.instance;

View File

@ -75,7 +75,7 @@ public class Utils {
* @return A Message object containing the parts combined into one message * @return A Message object containing the parts combined into one message
*/ */
public static Message combinedMessage(Collection<?> replacements, String messagePart, String combiner) { public static Message combinedMessage(Collection<?> replacements, String messagePart, String combiner) {
Message result = Message.none(); Message result = Message.empty();
boolean first = true; boolean first = true;
for(Object part : replacements) { for(Object part : replacements) {
if(first) { if(first) {

View File

@ -85,7 +85,7 @@ public class FindCommand extends CommandAreaShop {
if(!results.isEmpty()) { if(!results.isEmpty()) {
// Draw a random one // Draw a random one
BuyRegion region = results.get(new Random().nextInt(results.size())); BuyRegion region = results.get(new Random().nextInt(results.size()));
Message onlyInGroup = Message.none(); Message onlyInGroup = Message.empty();
if(group != null) { if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]); onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
} }
@ -96,7 +96,7 @@ public class FindCommand extends CommandAreaShop {
} }
region.teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false); region.teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
} else { } else {
Message onlyInGroup = Message.none(); Message onlyInGroup = Message.empty();
if(group != null) { if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]); onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
} }
@ -119,7 +119,7 @@ public class FindCommand extends CommandAreaShop {
if(!results.isEmpty()) { if(!results.isEmpty()) {
// Draw a random one // Draw a random one
RentRegion region = results.get(new Random().nextInt(results.size())); RentRegion region = results.get(new Random().nextInt(results.size()));
Message onlyInGroup = Message.none(); Message onlyInGroup = Message.empty();
if(group != null) { if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]); onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
} }
@ -130,7 +130,7 @@ public class FindCommand extends CommandAreaShop {
} }
region.teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false); region.teleportPlayer(player, region.getBooleanSetting("general.findTeleportToSign"), false);
} else { } else {
Message onlyInGroup = Message.none(); Message onlyInGroup = Message.empty();
if(group != null) { if(group != null) {
onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]); onlyInGroup = Message.fromKey("find-onlyInGroup").replacements(args[3]);
} }

View File

@ -77,7 +77,7 @@ public class InfoCommand extends CommandAreaShop {
} }
}); });
// Header // Header
Message limitedToGroup = Message.none(); Message limitedToGroup = Message.empty();
if(filterGroup != null) { if(filterGroup != null) {
limitedToGroup = Message.fromKey("info-limitedToGroup").replacements(filterGroup.getName()); limitedToGroup = Message.fromKey("info-limitedToGroup").replacements(filterGroup.getName());
} }
@ -111,7 +111,7 @@ public class InfoCommand extends CommandAreaShop {
plugin.messageNoPrefix(sender, "info-entry"+state, region); plugin.messageNoPrefix(sender, "info-entry"+state, region);
linesPrinted++; linesPrinted++;
} }
Message footer = Message.none(); Message footer = Message.empty();
// Previous button // Previous button
if(page > 1) { if(page > 1) {
footer.append(Message.fromKey("info-pagePrevious").replacements(baseCommand+" "+(page-1))); footer.append(Message.fromKey("info-pagePrevious").replacements(baseCommand+" "+(page-1)));

View File

@ -134,7 +134,7 @@ public class StackCommand extends CommandAreaShop {
} else { } else {
type = "buy"; type = "buy";
} }
Message groupsMessage = Message.none(); Message groupsMessage = Message.empty();
if(group != null) { if(group != null) {
groupsMessage = Message.fromKey("stack-addToGroup").replacements(group.getName()); groupsMessage = Message.fromKey("stack-addToGroup").replacements(group.getName());
} }
@ -208,9 +208,9 @@ public class StackCommand extends CommandAreaShop {
if(current >= amount) { if(current >= amount) {
if(player.isOnline()) { if(player.isOnline()) {
int added = amount - tooLow - tooHigh; int added = amount - tooLow - tooHigh;
Message wrong = Message.none(); Message wrong = Message.empty();
if (tooHigh > 0) { if(tooHigh > 0) {
wrong.append(Message.fromKey("stack-tooHigh").replacements(tooHigh)); wrong.append(Message.fromKey("stack-tooHigh").replacements(tooHigh));
} }
if (tooLow > 0) { if (tooLow > 0) {
wrong.append(Message.fromKey("stack-tooLow").replacements(tooLow)); wrong.append(Message.fromKey("stack-tooLow").replacements(tooLow));

View File

@ -3,6 +3,7 @@ package me.wiefferink.areashop.features;
import me.wiefferink.areashop.AreaShop; import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.Utils; import me.wiefferink.areashop.Utils;
import me.wiefferink.areashop.events.notify.UpdateRegionEvent; import me.wiefferink.areashop.events.notify.UpdateRegionEvent;
import me.wiefferink.areashop.messages.Message;
import me.wiefferink.areashop.regions.GeneralRegion; import me.wiefferink.areashop.regions.GeneralRegion;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
@ -281,7 +282,7 @@ public class SignsFeature extends Feature {
signState.setLine(i, ""); signState.setLine(i, "");
continue; continue;
} }
signLines[i] = region.applyAllReplacements(signLines[i]); signLines[i] = Message.applyReplacements(signLines[i], region);
signLines[i] = Utils.applyColors(signLines[i]); signLines[i] = Utils.applyColors(signLines[i]);
signState.setLine(i, signLines[i]); signState.setLine(i, signLines[i]);
} }

View File

@ -2,7 +2,7 @@ package me.wiefferink.areashop.messages;
import me.wiefferink.areashop.AreaShop; import me.wiefferink.areashop.AreaShop;
import me.wiefferink.areashop.Utils; import me.wiefferink.areashop.Utils;
import me.wiefferink.areashop.regions.GeneralRegion; import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -40,7 +40,7 @@ public class Message {
* Empty message object * Empty message object
* @return this * @return this
*/ */
public static Message none() { public static Message empty() {
return new Message(); return new Message();
} }
@ -71,12 +71,22 @@ public class Message {
return new Message().setMessage(message); return new Message().setMessage(message);
} }
/**
* Apply replacements to a string
* @param message The string to apply replacements to
* @param replacements The replacements to apply
* @return The message with the replacements applied
*/
public static String applyReplacements(String message, Object... replacements) {
return Message.fromString(message).replacements(replacements).doReplacements().getSingleRaw();
}
/** /**
* Get the message with all replacements done * Get the message with all replacements done
* @return Message as a list * @return Message as a list
*/ */
public List<String> get() { public List<String> get() {
executeReplacements(); doReplacements();
return message; return message;
} }
@ -89,7 +99,7 @@ public class Message {
if(limit.reached()) { if(limit.reached()) {
return new ArrayList<>(); return new ArrayList<>();
} }
executeReplacements(limit); doReplacements(limit);
return message; return message;
} }
@ -101,12 +111,20 @@ public class Message {
return message; return message;
} }
/**
* Get raw message as string
* @return The raw message
*/
public String getSingleRaw() {
return StringUtils.join(message, "");
}
/** /**
* Get a plain string for the message (for example for using in the console) * Get a plain string for the message (for example for using in the console)
* @return The message as simple string * @return The message as simple string
*/ */
public String getPlain() { public String getPlain() {
executeReplacements(); doReplacements();
return FancyMessageFormat.convertToConsole(message); return FancyMessageFormat.convertToConsole(message);
} }
@ -177,7 +195,7 @@ public class Message {
if(message == null || message.size() == 0 || (message.size() == 1 && message.get(0).length() == 0) || target == null) { if(message == null || message.size() == 0 || (message.size() == 1 && message.get(0).length() == 0) || target == null) {
return this; return this;
} }
executeReplacements(); doReplacements();
if(target instanceof Player) { if(target instanceof Player) {
boolean sendPlain = true; boolean sendPlain = true;
if(AreaShop.getInstance().getConfig().getBoolean("useFancyMessages") && fancyWorks) { if(AreaShop.getInstance().getConfig().getBoolean("useFancyMessages") && fancyWorks) {
@ -257,12 +275,13 @@ public class Message {
/** /**
* Apply all replacements to the message * Apply all replacements to the message
* @return this
*/ */
private void executeReplacements() { public Message doReplacements() {
executeReplacements(new Limit(REPLACEMENTLIMIT, this)); return doReplacements(new Limit(REPLACEMENTLIMIT, this));
} }
private void executeReplacements(Limit limit) { private Message doReplacements(Limit limit) {
// Replace variables until they are all gone, or when the limit is reached // Replace variables until they are all gone, or when the limit is reached
Pattern variable = Pattern.compile(Pattern.quote(VARIABLESTART)+"[a-zA-Z]+"+Pattern.quote(VARIABLEEND)); Pattern variable = Pattern.compile(Pattern.quote(VARIABLESTART)+"[a-zA-Z]+"+Pattern.quote(VARIABLEEND));
@ -289,6 +308,7 @@ public class Message {
limit.notified = true; limit.notified = true;
AreaShop.error("Too many recursive replacements for message with key: "+limit.message.key+" (probably includes itself as replacement), start of the message: "+Utils.getMessageStart(limit.message, 100)); AreaShop.error("Too many recursive replacements for message with key: "+limit.message.key+" (probably includes itself as replacement), start of the message: "+Utils.getMessageStart(limit.message, 100));
} }
return this;
} }
/** /**
@ -301,23 +321,38 @@ public class Message {
if(message == null || message.size() == 0 || replacements == null || limit.reached()) { if(message == null || message.size() == 0 || replacements == null || limit.reached()) {
return; return;
} }
boolean result = false; Pattern variablePattern = Pattern.compile(Pattern.quote(VARIABLESTART)+"[a-zA-Z]+"+Pattern.quote(VARIABLEEND));
for(int i = 0; i < message.size(); i++) { for(int i = 0; i < message.size(); i++) {
int number = 0; int number = 0;
String line = message.get(i);
for(Object param : replacements) { for(Object param : replacements) {
if(param != null) { if(param != null) {
if(param instanceof GeneralRegion) { if(param instanceof ReplacementProvider) {
message.set(i, ((GeneralRegion)param).applyAllReplacements(message.get(i))); Matcher matcher = variablePattern.matcher(line);
if(matcher.find()) {
Object replacement = ((ReplacementProvider)param).provideReplacement(matcher.group().substring(1, matcher.group().length()-1));
if(replacement != null) {
String result = "";
if(matcher.start() > 0) {
result += line.substring(0, matcher.start());
}
result += replacement.toString();
if(matcher.end() < line.length()) {
result += line.substring(matcher.end());
}
message.set(i, result);
}
}
} else if(param instanceof Message) { } else if(param instanceof Message) {
Pattern variables = Pattern.compile(Pattern.quote(VARIABLESTART)+number+Pattern.quote(VARIABLEEND)); Pattern indexPattern = Pattern.compile(Pattern.quote(VARIABLESTART)+number+Pattern.quote(VARIABLEEND));
Matcher matches = variables.matcher(message.get(i)); Matcher matcher = indexPattern.matcher(line);
if(matches.find()) { // Only replaces one occurance of the variable, others will be done next round if(matcher.find()) { // Only replaces one occurance of the variable, others will be done next round
int startDiff = message.size()-i; int startDiff = message.size()-i;
List<String> insertMessage = ((Message)param).get(limit); List<String> insertMessage = ((Message)param).get(limit);
if(limit.reached()) { if(limit.reached()) {
return; return;
} }
FancyMessageFormat.insertMessage(message, insertMessage, i, matches.start(), matches.end()); FancyMessageFormat.insertMessage(message, insertMessage, i, matcher.start(), matcher.end());
// Skip to end of insert // Skip to end of insert
i = message.size()-startDiff; i = message.size()-startDiff;
} }
@ -353,10 +388,10 @@ public class Message {
String key; String key;
Object[] arguments = null; Object[] arguments = null;
if(variable.contains("|")) { if(variable.contains("|")) {
key = variable.substring(6, variable.indexOf("|")); key = variable.substring(VARIABLESTART.length()+LANGUAGEVARIABLE.length(), variable.indexOf("|"));
arguments = variable.substring(variable.indexOf("|")+1, variable.length()-1).split("\\|"); arguments = variable.substring(variable.indexOf("|")+1, variable.length()-VARIABLEEND.length()).split("\\|");
} else { } else {
key = variable.substring(6, variable.length()-1); key = variable.substring(VARIABLESTART.length()+LANGUAGEVARIABLE.length(), variable.length()-VARIABLEEND.length());
} }
Message insert = Message.fromKey(key); Message insert = Message.fromKey(key);
if(arguments != null) { if(arguments != null) {
@ -407,4 +442,16 @@ public class Message {
return left <= 0; return left <= 0;
} }
} }
/**
* Provide custom replacement for variables
*/
public interface ReplacementProvider {
/**
* Get the replacement for a variable
* @param variable The variable to replace
* @return The replacement for the variable, or null if empty
*/
Object provideReplacement(String variable);
}
} }

View File

@ -17,7 +17,6 @@ import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
public class BuyRegion extends GeneralRegion { public class BuyRegion extends GeneralRegion {
@ -207,27 +206,34 @@ public class BuyRegion extends GeneralRegion {
public String getFormattedMoneyBackAmount() { public String getFormattedMoneyBackAmount() {
return Utils.formatCurrency(getMoneyBackAmount()); return Utils.formatCurrency(getMoneyBackAmount());
} }
@Override @Override
public HashMap<String, Object> getSpecificReplacements() { public Object provideReplacement(String variable) {
// Fill the replacements map with things specific to a BuyRegion switch(variable) {
HashMap<String, Object> result = new HashMap<>(); case AreaShop.tagPrice:
result.put(AreaShop.tagPrice, getFormattedPrice()); return getFormattedPrice();
result.put(AreaShop.tagRawPrice, getPrice()); case AreaShop.tagRawPrice:
result.put(AreaShop.tagPlayerName, getPlayerName()); return getPrice();
result.put(AreaShop.tagPlayerUUID, getBuyer()); case AreaShop.tagPlayerName:
result.put(AreaShop.tagResellPrice, getFormattedResellPrice()); return getPlayerName();
result.put(AreaShop.tagRawResellPrice, getResellPrice()); case AreaShop.tagPlayerUUID:
result.put(AreaShop.tagMoneyBackAmount, getFormattedMoneyBackAmount()); return getBuyer();
result.put(AreaShop.tagRawMoneyBackAmount, getMoneyBackAmount()); case AreaShop.tagResellPrice:
double moneyBackPercent = getMoneyBackPercentage(); return getFormattedResellPrice();
if((moneyBackPercent%1.0) == 0.0) { case AreaShop.tagRawResellPrice:
result.put(AreaShop.tagMoneyBackPercentage, (int)moneyBackPercent); return getResellPrice();
} else { case AreaShop.tagMoneyBackAmount:
result.put(AreaShop.tagMoneyBackPercentage, moneyBackPercent); return getFormattedMoneyBackAmount();
case AreaShop.tagRawMoneyBackAmount:
return getMoneyBackAmount();
case AreaShop.tagMoneyBackPercentage:
return getMoneyBackPercentage()%1.0 == 0.0 ? (int)getMoneyBackPercentage() : getMoneyBackPercentage();
case AreaShop.tagMaxInactiveTime:
return this.getFormattedInactiveTimeUntilSell();
default:
return super.provideReplacement(variable);
} }
result.put(AreaShop.tagMaxInactiveTime, this.getFormattedInactiveTimeUntilSell());
return result;
} }
/** /**

View File

@ -27,7 +27,7 @@ import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
public abstract class GeneralRegion implements GeneralRegionInterface, Comparable<GeneralRegion> { public abstract class GeneralRegion implements GeneralRegionInterface, Comparable<GeneralRegion>, Message.ReplacementProvider {
YamlConfiguration config; YamlConfiguration config;
private static ArrayList<Material> canSpawnIn = new ArrayList<>(Arrays.asList(Material.WOOD_DOOR, Material.WOODEN_DOOR, Material.SIGN_POST, Material.WALL_SIGN, Material.STONE_PLATE, Material.IRON_DOOR_BLOCK, Material.WOOD_PLATE, Material.TRAP_DOOR, Material.REDSTONE_LAMP_OFF, Material.REDSTONE_LAMP_ON, Material.DRAGON_EGG, Material.GOLD_PLATE, Material.IRON_PLATE)); private static ArrayList<Material> canSpawnIn = new ArrayList<>(Arrays.asList(Material.WOOD_DOOR, Material.WOODEN_DOOR, Material.SIGN_POST, Material.WALL_SIGN, Material.STONE_PLATE, Material.IRON_DOOR_BLOCK, Material.WOOD_PLATE, Material.TRAP_DOOR, Material.REDSTONE_LAMP_OFF, Material.REDSTONE_LAMP_ON, Material.DRAGON_EGG, Material.GOLD_PLATE, Material.IRON_PLATE));
private static ArrayList<Material> cannotSpawnOn = new ArrayList<>(Arrays.asList(Material.PISTON_EXTENSION, Material.PISTON_MOVING_PIECE, Material.SIGN_POST, Material.WALL_SIGN, Material.STONE_PLATE, Material.IRON_DOOR_BLOCK, Material.WOOD_PLATE, Material.TRAP_DOOR, Material.REDSTONE_LAMP_OFF, Material.REDSTONE_LAMP_ON, Material.CACTUS, Material.IRON_FENCE, Material.FENCE_GATE, Material.THIN_GLASS, Material.NETHER_FENCE, Material.DRAGON_EGG, Material.GOLD_PLATE, Material.IRON_PLATE, Material.STAINED_GLASS_PANE)); private static ArrayList<Material> cannotSpawnOn = new ArrayList<>(Arrays.asList(Material.PISTON_EXTENSION, Material.PISTON_MOVING_PIECE, Material.SIGN_POST, Material.WALL_SIGN, Material.STONE_PLATE, Material.IRON_DOOR_BLOCK, Material.WOOD_PLATE, Material.TRAP_DOOR, Material.REDSTONE_LAMP_OFF, Material.REDSTONE_LAMP_ON, Material.CACTUS, Material.IRON_FENCE, Material.FENCE_GATE, Material.THIN_GLASS, Material.NETHER_FENCE, Material.DRAGON_EGG, Material.GOLD_PLATE, Material.IRON_PLATE, Material.STAINED_GLASS_PANE));
@ -36,9 +36,6 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
private boolean saveRequired = false; private boolean saveRequired = false;
private boolean deleted = false; private boolean deleted = false;
private HashMap<String, Object> replacementsCache = null;
private long replacementsCacheTime = 0;
// Features // Features
private FriendsFeature friendsFeature; private FriendsFeature friendsFeature;
private SignsFeature signsFeature; private SignsFeature signsFeature;
@ -222,13 +219,7 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
update(); update();
} }
/**
* Get the tag replacements, used in commands or signs
* @return A map with strings like '%region%' linking to the value to replace it with
*/
public abstract HashMap<String, Object> getSpecificReplacements();
/** /**
* Get the state of a region * Get the state of a region
* @return The RegionState of the region * @return The RegionState of the region
@ -508,85 +499,88 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
} }
return result; return result;
} }
/**
* Get all the replacements for this region
* @return Map with the keys that need to be replaced with the value of the object
*/
public HashMap<String, Object> getAllReplacements() {
// Reply with cache if we have one
if(replacementsCache != null && (Calendar.getInstance().getTimeInMillis() - replacementsCacheTime) < 1000) {
return replacementsCache;
}
HashMap<String, Object> result = getSpecificReplacements();
result.put(AreaShop.tagRegionName, getName());
result.put(AreaShop.tagRegionType, getType().getValue().toLowerCase());
result.put(AreaShop.tagWorldName, getWorldName());
result.put(AreaShop.tagWidth, getWidth());
result.put(AreaShop.tagDepth, getDepth());
result.put(AreaShop.tagHeight, getHeight());
result.put(AreaShop.tagFriends, Utils.createCommaSeparatedList(getFriendsFeature().getFriendNames()));
result.put(AreaShop.tagFriendsUUID, Utils.createCommaSeparatedList(getFriendsFeature().getFriends()));
result.put(AreaShop.tagLandlord, getLandlordName());
result.put(AreaShop.tagLandlordUUID, getLandlord());
// Date/time stuff
Calendar calendar = Calendar.getInstance();
result.put(AreaShop.tagEpoch, calendar.getTimeInMillis());
result.put(AreaShop.tagMillisecond, calendar.get(Calendar.MILLISECOND));
result.put(AreaShop.tagSecond, calendar.get(Calendar.SECOND));
result.put(AreaShop.tagMinute, calendar.get(Calendar.MINUTE));
result.put(AreaShop.tagHour, calendar.get(Calendar.HOUR_OF_DAY));
result.put(AreaShop.tagDay, calendar.get(Calendar.DAY_OF_MONTH));
result.put(AreaShop.tagMonth, calendar.get(Calendar.MONTH));
result.put(AreaShop.tagYear, calendar.get(Calendar.YEAR));
// In specified format
SimpleDateFormat date = new SimpleDateFormat(plugin.getConfig().getString("timeFormatChat"));
String dateString = date.format(Calendar.getInstance().getTime());
result.put(AreaShop.tagDateTime, dateString);
date = new SimpleDateFormat(plugin.getConfig().getString("timeFormatSign"));
dateString = date.format(Calendar.getInstance().getTime());
result.put(AreaShop.tagDateTimeShort, dateString);
// Teleport location
Location tp = getTeleportLocation();
if(tp != null) {
result.put(AreaShop.tagTeleportBlockX, tp.getBlockX());
result.put(AreaShop.tagTeleportBlockY, tp.getBlockY());
result.put(AreaShop.tagTeleportBlockZ, tp.getBlockZ());
result.put(AreaShop.tagTeleportX, tp.getX());
result.put(AreaShop.tagTeleportY, tp.getY());
result.put(AreaShop.tagTeleportZ, tp.getZ());
result.put(AreaShop.tagTeleportPitch, tp.getPitch());
result.put(AreaShop.tagTeleportYaw, tp.getYaw());
result.put(AreaShop.tagTeleportPitchRound, Math.round(tp.getPitch()));
result.put(AreaShop.tagTeleportYawRound, Math.round(tp.getYaw()));
result.put(AreaShop.tagTeleportWorld, tp.getWorld().getName());
}
replacementsCache = result; @Override
replacementsCacheTime = Calendar.getInstance().getTimeInMillis(); public Object provideReplacement(String variable) {
return result; switch(variable) {
}
// Basics
/** case AreaShop.tagRegionName:
* Applies all replacements to the given string return getName();
* @param source The source string to replace things in case AreaShop.tagRegionType:
* @return The result string with all the replacements applied return getType().getValue().toLowerCase();
*/ case AreaShop.tagWorldName:
public String applyAllReplacements(String source) { return getWorldName();
if(source == null || source.length() == 0) { case AreaShop.tagWidth:
return ""; return getWidth();
case AreaShop.tagDepth:
return getDepth();
case AreaShop.tagHeight:
return getHeight();
case AreaShop.tagFriends:
return Utils.createCommaSeparatedList(getFriendsFeature().getFriendNames());
case AreaShop.tagFriendsUUID:
return Utils.createCommaSeparatedList(getFriendsFeature().getFriends());
case AreaShop.tagLandlord:
return getLandlordName();
case AreaShop.tagLandlordUUID:
return getLandlord();
// Date/time
case AreaShop.tagEpoch:
return Calendar.getInstance().getTimeInMillis();
case AreaShop.tagMillisecond:
return Calendar.getInstance().get(Calendar.MILLISECOND);
case AreaShop.tagSecond:
return Calendar.getInstance().get(Calendar.SECOND);
case AreaShop.tagMinute:
return Calendar.getInstance().get(Calendar.MINUTE);
case AreaShop.tagHour:
return Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
case AreaShop.tagDay:
return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
case AreaShop.tagMonth:
return Calendar.getInstance().get(Calendar.MONTH);
case AreaShop.tagYear:
return Calendar.getInstance().get(Calendar.YEAR);
case AreaShop.tagDateTime:
return new SimpleDateFormat(plugin.getConfig().getString("timeFormatChat")).format(Calendar.getInstance().getTime());
case AreaShop.tagDateTimeShort:
return new SimpleDateFormat(plugin.getConfig().getString("timeFormatSign")).format(Calendar.getInstance().getTime());
// Teleport locations
default:
Location tp = getTeleportLocation();
if(tp == null) {
return null;
}
switch(variable) {
case AreaShop.tagTeleportBlockX:
return tp.getBlockX();
case AreaShop.tagTeleportBlockY:
return tp.getBlockY();
case AreaShop.tagTeleportBlockZ:
return tp.getBlockZ();
case AreaShop.tagTeleportX:
return tp.getX();
case AreaShop.tagTeleportY:
return tp.getY();
case AreaShop.tagTeleportZ:
return tp.getZ();
case AreaShop.tagTeleportPitch:
return tp.getPitch();
case AreaShop.tagTeleportYaw:
return tp.getYaw();
case AreaShop.tagTeleportPitchRound:
return Math.round(tp.getPitch());
case AreaShop.tagTeleportYawRound:
return Math.round(tp.getYaw());
case AreaShop.tagTeleportWorld:
return tp.getWorld().getName();
default:
return null;
}
} }
// Apply static replacements
HashMap<String, Object> replacements = getAllReplacements();
for(String tag : replacements.keySet()) {
Object replacement = replacements.get(tag);
if(replacement != null) {
source = source.replace(tag, replacement.toString());
}
}
return source;
} }
/** /**
@ -749,7 +743,6 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
* Indicate this region needs to be saved, saving will happen by a repeating task * Indicate this region needs to be saved, saving will happen by a repeating task
*/ */
public void saveRequired() { public void saveRequired() {
replacementsCache = null; // Remove cache
saveRequired = true; saveRequired = true;
} }
@ -1648,13 +1641,13 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
String restore = plugin.getConfig().getString("schematicProfiles." + getRestoreProfile() + "." + type.getValue() + ".restore"); String restore = plugin.getConfig().getString("schematicProfiles." + getRestoreProfile() + "." + type.getValue() + ".restore");
// Save the region if needed // Save the region if needed
if(save != null && save.length() != 0) { if(save != null && save.length() != 0) {
save = applyAllReplacements(save); save = Message.applyReplacements(save, this);
this.saveRegionBlocks(save); this.saveRegionBlocks(save);
} }
// Restore the region if needed // Restore the region if needed
if(restore != null && restore.length() != 0) { if(restore != null && restore.length() != 0) {
restore = applyAllReplacements(restore); restore = Message.applyReplacements(restore, this);
this.restoreRegionBlocks(restore); this.restoreRegionBlocks(restore);
} }
} }
@ -1672,8 +1665,8 @@ public abstract class GeneralRegion implements GeneralRegionInterface, Comparabl
for(String command : commands) { for(String command : commands) {
if(command == null || command.length() == 0) { if(command == null || command.length() == 0) {
continue; continue;
} }
command = applyAllReplacements(command); command = Message.applyReplacements(command, this);
boolean result; boolean result;
String error = null; String error = null;

View File

@ -18,7 +18,6 @@ import org.bukkit.entity.Player;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
import static me.wiefferink.areashop.Utils.millisToHumanFormat; import static me.wiefferink.areashop.Utils.millisToHumanFormat;
@ -129,36 +128,44 @@ public class RentRegion extends GeneralRegion {
setSetting("rent.timesExtended", times); setSetting("rent.timesExtended", times);
} }
} }
@Override @Override
public HashMap<String, Object> getSpecificReplacements() { public Object provideReplacement(String variable) {
// Fill the replacements map with things specific to a RentRegion switch(variable) {
HashMap<String, Object> result = new HashMap<>(); case AreaShop.tagPrice:
result.put(AreaShop.tagPrice, getFormattedPrice()); return getFormattedPrice();
result.put(AreaShop.tagRawPrice, getPrice()); case AreaShop.tagRawPrice:
result.put(AreaShop.tagDuration, getDurationString()); return getPrice();
result.put(AreaShop.tagPlayerName, getPlayerName()); case AreaShop.tagDuration:
result.put(AreaShop.tagPlayerUUID, getRenter()); return getDurationString();
SimpleDateFormat date = new SimpleDateFormat(plugin.getConfig().getString("timeFormatChat")); case AreaShop.tagPlayerName:
String dateString = date.format(new Date(getRentedUntil())); return getPlayerName();
result.put(AreaShop.tagRentedUntil, dateString); case AreaShop.tagPlayerUUID:
date = new SimpleDateFormat(plugin.getConfig().getString("timeFormatSign")); return getRenter();
dateString = date.format(new Date(getRentedUntil())); case AreaShop.tagRentedUntil:
result.put(AreaShop.tagRentedUntilShort, dateString); return new SimpleDateFormat(plugin.getConfig().getString("timeFormatChat")).format(new Date(getRentedUntil()));
result.put(AreaShop.tagTimeLeft, getTimeLeftString()); case AreaShop.tagRentedUntilShort:
result.put(AreaShop.tagMoneyBackAmount, getFormattedMoneyBackAmount()); return new SimpleDateFormat(plugin.getConfig().getString("timeFormatSign")).format(new Date(getRentedUntil()));
result.put(AreaShop.tagRawMoneyBackAmount, getMoneyBackAmount()); case AreaShop.tagTimeLeft:
double moneyBackPercent = getMoneyBackPercentage(); return getTimeLeftString();
if((moneyBackPercent%1.0) == 0.0) { case AreaShop.tagMoneyBackAmount:
result.put(AreaShop.tagMoneyBackPercentage, (int)moneyBackPercent); return getFormattedMoneyBackAmount();
} else { case AreaShop.tagRawMoneyBackAmount:
result.put(AreaShop.tagMoneyBackPercentage, moneyBackPercent); return getMoneyBackAmount();
case AreaShop.tagMoneyBackPercentage:
return getMoneyBackPercentage()%1.0 == 0.0 ? (int)getMoneyBackPercentage() : getMoneyBackPercentage();
case AreaShop.tagMaxExtends:
return this.getMaxExtends();
case AreaShop.tagExtendsLeft:
return getMaxExtends()-getTimesExtended();
case AreaShop.tagMaxRentTime:
return millisToHumanFormat(getMaxRentTime());
case AreaShop.tagMaxInactiveTime:
return this.getFormattedInactiveTimeUntilUnrent();
default:
return super.provideReplacement(variable);
} }
result.put(AreaShop.tagMaxExtends, this.getMaxExtends());
result.put(AreaShop.tagExtendsLeft, getMaxExtends() - getTimesExtended());
result.put(AreaShop.tagMaxRentTime, millisToHumanFormat(getMaxRentTime()));
result.put(AreaShop.tagMaxInactiveTime, this.getFormattedInactiveTimeUntilUnrent());
return result;
} }
/** /**