summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKHobbits <rob@khobbits.co.uk>2013-08-31 23:01:47 +0100
committerKHobbits <rob@khobbits.co.uk>2013-08-31 23:11:08 +0100
commit36c61eaa06620d3d5c8daa660de290891f808c8d (patch)
treec75f5ce66f826091e440f84e6e3a90faba5e2418
parent9908eb0619f43a578a0bf496d6f201da7ebcc1a5 (diff)
downloadEssentials-36c61eaa06620d3d5c8daa660de290891f808c8d.tar
Essentials-36c61eaa06620d3d5c8daa660de290891f808c8d.tar.gz
Essentials-36c61eaa06620d3d5c8daa660de290891f808c8d.tar.lz
Essentials-36c61eaa06620d3d5c8daa660de290891f808c8d.tar.xz
Essentials-36c61eaa06620d3d5c8daa660de290891f808c8d.zip
New enum cached, lazy generated KeywordReplacer
This runs before the pager, so keywords on other pages will still be parsed.
-rw-r--r--Essentials/src/com/earth2me/essentials/textreader/KeywordReplacer.java399
1 files changed, 280 insertions, 119 deletions
diff --git a/Essentials/src/com/earth2me/essentials/textreader/KeywordReplacer.java b/Essentials/src/com/earth2me/essentials/textreader/KeywordReplacer.java
index b77b5c45e..448ceb5ba 100644
--- a/Essentials/src/com/earth2me/essentials/textreader/KeywordReplacer.java
+++ b/Essentials/src/com/earth2me/essentials/textreader/KeywordReplacer.java
@@ -20,8 +20,13 @@ import org.bukkit.plugin.Plugin;
import static com.earth2me.essentials.I18n._;
import com.earth2me.essentials.PlayerList;
-import static com.earth2me.essentials.PlayerList.getMergedList;
+import static com.earth2me.essentials.textreader.KeywordType.DISPLAYNAME;
+import static com.earth2me.essentials.textreader.KeywordType.PLAYER;
+import java.util.EnumMap;
+import java.util.HashMap;
import java.util.logging.Level;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class KeywordReplacer implements IText
@@ -31,6 +36,9 @@ public class KeywordReplacer implements IText
private final transient IEssentials ess;
private final transient boolean extended;
private transient ExecuteTimer execTimer;
+ private final static Pattern KEYWORD = Pattern.compile("\\{([^\\{\\}]+)\\}");
+ private final static Pattern KEYWORDSPLIT = Pattern.compile("\\:");
+ private final EnumMap<KeywordType, Object> keywordCache = new EnumMap<KeywordType, Object>(KeywordType.class);
public KeywordReplacer(final IText input, final CommandSender sender, final IEssentials ess)
{
@@ -52,161 +60,269 @@ public class KeywordReplacer implements IText
private void replaceKeywords(final CommandSender sender)
{
- String displayName, ipAddress, balance, mails, world;
- String worlds, online, unique, onlineList, date, time;
- String worldTime12, worldTime24, worldDate, plugins;
- String userName, version, address, tps, uptime;
- String coords;
execTimer = new ExecuteTimer();
execTimer.start();
+ User user = null;
if (sender instanceof Player)
{
- final User user = ess.getUser(sender);
+ user = ess.getUser(sender);
+ //This is just so any displayname lookups below show the correct nickname
user.setDisplayNick();
- displayName = user.getDisplayName();
- ipAddress = user.getAddress() == null || user.getAddress().getAddress() == null ? "" : user.getAddress().getAddress().toString();
- address = user.getAddress() == null ? "" : user.getAddress().toString();
- execTimer.mark("User Grab");
- balance = NumberUtil.displayCurrency(user.getMoney(), ess);
- execTimer.mark("Economy");
- mails = Integer.toString(user.getMails().size());
- final Location location = user.getLocation();
- world = location == null || location.getWorld() == null ? "" : location.getWorld().getName();
- worldTime12 = DescParseTickFormat.format12(user.getWorld() == null ? 0 : user.getWorld().getTime());
- worldTime24 = DescParseTickFormat.format24(user.getWorld() == null ? 0 : user.getWorld().getTime());
- worldDate = DateFormat.getDateInstance(DateFormat.MEDIUM, ess.getI18n().getCurrentLocale()).format(DescParseTickFormat.ticksToDate(user.getWorld() == null ? 0 : user.getWorld().getFullTime()));
- coords = _("coordsKeyword", location.getBlockX(), location.getBlockY(), location.getBlockZ());
}
- else
- {
- displayName = address = ipAddress = balance = mails = world = worldTime12 = worldTime24 = worldDate = coords = "";
- }
- execTimer.mark("Player variables");
- Map<String, List<User>> playerList = PlayerList.getPlayerLists(ess, extended);
+ execTimer.mark("User Grab");
- userName = sender.getName();
- int playerHidden = 0;
- for (Player p : ess.getServer().getOnlinePlayers())
+ for (int i = 0; i < input.getLines().size(); i++)
{
- if (ess.getUser(p).isHidden())
+ String line = input.getLines().get(i);
+ final Matcher matcher = KEYWORD.matcher(line);
+
+ while (matcher.find())
{
- playerHidden++;
+ final String fullMatch = matcher.group(0);
+ final String keywordMatch = matcher.group(1);
+ final String[] matchTokens = KEYWORDSPLIT.split(keywordMatch);
+ line = replaceLine(line, fullMatch, matchTokens, user);
}
+ replaced.add(line);
}
- online = Integer.toString(ess.getServer().getOnlinePlayers().length - playerHidden);
- unique = Integer.toString(ess.getUserMap().getUniqueUsers());
- execTimer.mark("Player list");
- final StringBuilder worldsBuilder = new StringBuilder();
- for (World w : ess.getServer().getWorlds())
+ execTimer.mark("Text Replace");
+ final String timeroutput = execTimer.end();
+ if (ess.getSettings().isDebug())
{
- if (worldsBuilder.length() > 0)
- {
- worldsBuilder.append(", ");
- }
- worldsBuilder.append(w.getName());
+ ess.getLogger().log(Level.INFO, "Keyword Replacer " + timeroutput);
}
- worlds = worldsBuilder.toString();
+ }
- final StringBuilder playerlistBuilder = new StringBuilder();
- for (Player p : ess.getServer().getOnlinePlayers())
+ private String replaceLine(String line, final String fullMatch, final String[] matchTokens, final User user)
+ {
+ final String keyword = matchTokens[0];
+ try
{
- if (ess.getUser(p).isHidden())
+ String replacer = null;
+ KeywordType validKeyword = KeywordType.valueOf(keyword);
+ if (validKeyword.getType().equals(KeywordCachable.CACHEABLE) && keywordCache.containsKey(validKeyword))
{
- continue;
+ replacer = keywordCache.get(validKeyword).toString();
}
- if (playerlistBuilder.length() > 0)
+ else if (validKeyword.getType().equals(KeywordCachable.SUBVALUE))
{
- playerlistBuilder.append(", ");
- }
- playerlistBuilder.append(p.getDisplayName());
- }
- onlineList = playerlistBuilder.toString();
+ String subKeyword = "";
+ if (matchTokens.length > 1)
+ {
+ subKeyword = matchTokens[1];
+ }
- final StringBuilder pluginlistBuilder = new StringBuilder();
- for (Plugin p : ess.getServer().getPluginManager().getPlugins())
- {
- if (pluginlistBuilder.length() > 0)
- {
- pluginlistBuilder.append(", ");
+ if (keywordCache.containsKey(validKeyword))
+ {
+ Map<String, String> values = (Map<String, String>)keywordCache.get(validKeyword);
+ if (values.containsKey(subKeyword))
+ {
+ replacer = values.get(subKeyword);
+ }
+ }
}
- pluginlistBuilder.append(p.getDescription().getName());
- }
- plugins = pluginlistBuilder.toString();
-
- execTimer.mark("List builders");
-
- date = DateFormat.getDateInstance(DateFormat.MEDIUM, ess.getI18n().getCurrentLocale()).format(new Date());
- time = DateFormat.getTimeInstance(DateFormat.MEDIUM, ess.getI18n().getCurrentLocale()).format(new Date());
- version = ess.getServer().getVersion();
-
- tps = Double.toString(ess.getTimer().getAverageTPS());
- uptime = DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime());
-
- execTimer.mark("Server Dates");
+ if (replacer == null)
+ {
+ replacer = "";
+ switch (validKeyword)
+ {
+ case PLAYER:
+ case DISPLAYNAME:
+ if (user != null)
+ {
+ replacer = user.getDisplayName();
+ }
+ break;
+ case USERNAME:
+ if (user != null)
+ {
+ replacer = user.getName();
+ }
+ break;
+ case BALANCE:
+ if (user != null)
+ {
+ replacer = NumberUtil.displayCurrency(user.getMoney(), ess);
+ }
+ break;
+ case MAILS:
+ if (user != null)
+ {
+ replacer = Integer.toString(user.getMails().size());
+ }
+ break;
+ case WORLD:
+ if (user != null)
+ {
+ final Location location = user.getLocation();
+ replacer = location == null || location.getWorld() == null ? "" : location.getWorld().getName();
+ }
+ break;
+ case ONLINE:
+ int playerHidden = 0;
+ for (Player p : ess.getServer().getOnlinePlayers())
+ {
+ if (ess.getUser(p).isHidden())
+ {
+ playerHidden++;
+ }
+ }
+ replacer = Integer.toString(ess.getServer().getOnlinePlayers().length - playerHidden);
+ break;
+ case UNIQUE:
+ replacer = Integer.toString(ess.getUserMap().getUniqueUsers());
+ break;
+ case WORLDS:
+ final StringBuilder worldsBuilder = new StringBuilder();
+ for (World w : ess.getServer().getWorlds())
+ {
+ if (worldsBuilder.length() > 0)
+ {
+ worldsBuilder.append(", ");
+ }
+ worldsBuilder.append(w.getName());
+ }
+ replacer = worldsBuilder.toString();
+ break;
+ case PLAYERLIST:
+ final Map<String, String> outputList;
+ if (keywordCache.containsKey(validKeyword))
+ {
+ outputList = (Map<String, String>)keywordCache.get(validKeyword);
+ }
+ else
+ {
+ //First lets build the per group playerlist
+ final Map<String, List<User>> playerList = PlayerList.getPlayerLists(ess, extended);
+ outputList = new HashMap<String, String>();
+ for (String groupName : playerList.keySet())
+ {
+ final List<User> groupUsers = playerList.get(groupName);
+ if (groupUsers != null && !groupUsers.isEmpty())
+ {
+ outputList.put(groupName, PlayerList.listUsers(ess, groupUsers, " "));
+ }
+ }
- for (int i = 0; i < input.getLines().size(); i++)
- {
- String line = input.getLines().get(i);
+ //Now lets build the all user playerlist
+ final StringBuilder playerlistBuilder = new StringBuilder();
+ for (Player p : ess.getServer().getOnlinePlayers())
+ {
+ if (ess.getUser(p).isHidden())
+ {
+ continue;
+ }
+ if (playerlistBuilder.length() > 0)
+ {
+ playerlistBuilder.append(", ");
+ }
+ playerlistBuilder.append(p.getDisplayName());
+ }
+ outputList.put("", playerlistBuilder.toString());
+ keywordCache.put(validKeyword, outputList);
+ }
- line = line.replace("{PLAYER}", displayName);
- line = line.replace("{DISPLAYNAME}", displayName);
- line = line.replace("{USERNAME}", userName);
- line = line.replace("{BALANCE}", balance);
- line = line.replace("{MAILS}", mails);
- line = line.replace("{WORLD}", world);
- line = line.replace("{ONLINE}", online);
- line = line.replace("{UNIQUE}", unique);
- line = line.replace("{WORLDS}", worlds);
- line = line.replace("{PLAYERLIST}", onlineList);
- line = line.replace("{TIME}", time);
- line = line.replace("{DATE}", date);
- line = line.replace("{WORLDTIME12}", worldTime12);
- line = line.replace("{WORLDTIME24}", worldTime24);
- line = line.replace("{WORLDDATE}", worldDate);
- line = line.replace("{COORDS}", coords);
- line = line.replace("{TPS}", tps);
- line = line.replace("{UPTIME}", uptime);
-
- if (extended)
- {
- line = line.replace("{IP}", ipAddress);
- line = line.replace("{ADDRESS}", address);
- line = line.replace("{PLUGINS}", plugins);
- line = line.replace("{VERSION}", version);
+ //Now thats all done, output the one we want and cache the rest.
+ if (matchTokens.length == 1)
+ {
+ replacer = outputList.get("");
+ }
+ else if (outputList.containsKey(matchTokens[1]))
+ {
+ replacer = outputList.get(matchTokens[1]);
+ }
+ else if (matchTokens.length > 2)
+ {
+ replacer = matchTokens[2];
+ }
- for (String groupName : playerList.keySet())
- {
- final List<User> groupUsers = playerList.get(groupName);
- if (groupUsers != null && !groupUsers.isEmpty())
+ keywordCache.put(validKeyword, outputList);
+ break;
+ case TIME:
+ replacer = DateFormat.getTimeInstance(DateFormat.MEDIUM, ess.getI18n().getCurrentLocale()).format(new Date());
+ break;
+ case DATE:
+ replacer = DateFormat.getDateInstance(DateFormat.MEDIUM, ess.getI18n().getCurrentLocale()).format(new Date());
+ break;
+ case WORLDTIME12:
+ if (user != null)
+ {
+ replacer = DescParseTickFormat.format12(user.getWorld() == null ? 0 : user.getWorld().getTime());
+ }
+ break;
+ case WORLDTIME24:
+ if (user != null)
+ {
+ replacer = DescParseTickFormat.format24(user.getWorld() == null ? 0 : user.getWorld().getTime());
+ }
+ break;
+ case WORLDDATE:
+ if (user != null)
+ {
+ replacer = DateFormat.getDateInstance(DateFormat.MEDIUM, ess.getI18n().getCurrentLocale()).format(DescParseTickFormat.ticksToDate(user.getWorld() == null ? 0 : user.getWorld().getFullTime()));
+ }
+ break;
+ case COORDS:
+ if (user != null)
+ {
+ final Location location = user.getLocation();
+ replacer = _("coordsKeyword", location.getBlockX(), location.getBlockY(), location.getBlockZ());
+ }
+ break;
+ case TPS:
+ replacer = NumberUtil.formatDouble(ess.getTimer().getAverageTPS());
+ break;
+ case UPTIME:
+ replacer = DateUtil.formatDateDiff(ManagementFactory.getRuntimeMXBean().getStartTime());
+ break;
+ case IP:
+ if (user != null)
{
- line = line.replaceAll("\\{PLAYERLIST\\:" + groupName.toUpperCase() + "(?:\\:([^\\{\\}]*))?\\}",
- PlayerList.listUsers(ess, groupUsers, " "));
+ replacer = user.getAddress() == null || user.getAddress().getAddress() == null ? "" : user.getAddress().getAddress().toString();
}
+ break;
+ case ADDRESS:
+ if (user != null)
+ {
+ replacer = user.getAddress() == null ? "" : user.getAddress().toString();
+ }
+ break;
+ case PLUGINS:
+ final StringBuilder pluginlistBuilder = new StringBuilder();
+ for (Plugin p : ess.getServer().getPluginManager().getPlugins())
+ {
+ if (pluginlistBuilder.length() > 0)
+ {
+ pluginlistBuilder.append(", ");
+ }
+ pluginlistBuilder.append(p.getDescription().getName());
+ }
+ replacer = pluginlistBuilder.toString();
+ break;
+ case VERSION:
+ replacer = ess.getServer().getVersion();
+ break;
+ default:
+ replacer = "N/A";
+ break;
}
- boolean doReplace = true;
- while (doReplace)
+ //If this is just a regular keyword, lets throw it into the cache
+ if (validKeyword.getType().equals(KeywordCachable.CACHEABLE))
{
- final String newLine = line.replaceAll("\\{PLAYERLIST\\:\\w*(?:\\:([^\\{\\}]*))?\\}", "$1");
- if (newLine.equals(line))
- {
- doReplace = false;
- }
- line = newLine;
+ keywordCache.put(validKeyword, replacer);
}
}
- replaced.add(line);
+ line = line.replace(fullMatch, replacer);
}
- execTimer.mark("String replace");
- final String timeroutput = execTimer.end();
- if (ess.getSettings().isDebug())
+ catch (IllegalArgumentException ex)
{
- ess.getLogger().log(Level.INFO, "Keyword Replacer " + timeroutput);
}
+ return line;
}
@Override
@@ -227,3 +343,48 @@ public class KeywordReplacer implements IText
return input.getBookmarks();
}
}
+
+//When adding a keyword here, you also need to add the implementation above
+enum KeywordType
+{
+ PLAYER(KeywordCachable.CACHEABLE),
+ DISPLAYNAME(KeywordCachable.CACHEABLE),
+ USERNAME(KeywordCachable.NOTCACHEABLE),
+ BALANCE(KeywordCachable.CACHEABLE),
+ MAILS(KeywordCachable.CACHEABLE),
+ WORLD(KeywordCachable.CACHEABLE),
+ ONLINE(KeywordCachable.CACHEABLE),
+ UNIQUE(KeywordCachable.CACHEABLE),
+ WORLDS(KeywordCachable.CACHEABLE),
+ PLAYERLIST(KeywordCachable.SUBVALUE),
+ TIME(KeywordCachable.CACHEABLE),
+ DATE(KeywordCachable.CACHEABLE),
+ WORLDTIME12(KeywordCachable.CACHEABLE),
+ WORLDTIME24(KeywordCachable.CACHEABLE),
+ WORLDDATE(KeywordCachable.CACHEABLE),
+ COORDS(KeywordCachable.CACHEABLE),
+ TPS(KeywordCachable.CACHEABLE),
+ UPTIME(KeywordCachable.CACHEABLE),
+ IP(KeywordCachable.CACHEABLE),
+ ADDRESS(KeywordCachable.CACHEABLE),
+ PLUGINS(KeywordCachable.CACHEABLE),
+ VERSION(KeywordCachable.CACHEABLE);
+ private final KeywordCachable type;
+
+ KeywordType(KeywordCachable type)
+ {
+ this.type = type;
+ }
+
+ public KeywordCachable getType()
+ {
+ return type;
+ }
+}
+
+enum KeywordCachable
+{
+ CACHEABLE, // This keyword can be cached as a string
+ SUBVALUE, // This keyword can be cached as a map
+ NOTCACHEABLE; // This keyword should never be cached
+} \ No newline at end of file