mirror of
https://github.com/TotalFreedomMC/TF-EssentialsX.git
synced 2025-08-05 12:02:53 +00:00
Add Baltop API (#3702)
Co-authored-by: Mariell <proximyst@proximyst.com> Co-authored-by: MD <1917406+mdcfe@users.noreply.github.com> This moves storage of balances from the baltop command into the UserMap. This was needed by Glare to able to get a hold of all users balances without causing jvm hell on the usermap. To access this API as an end user; ```java import net.essentialsx.api.v2.services.BalanceTop; //... BalanceTop api = Bukkit.getServer().getServicesManager().load(BalanceTop.class); ``` Closes #3100, closes #3540
This commit is contained in:
parent
191cea7fb3
commit
36422ab22b
7 changed files with 264 additions and 96 deletions
|
@ -0,0 +1,87 @@
|
||||||
|
package com.earth2me.essentials;
|
||||||
|
|
||||||
|
import net.ess3.api.IEssentials;
|
||||||
|
import net.essentialsx.api.v2.services.BalanceTop;
|
||||||
|
import org.bukkit.plugin.ServicePriority;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class BalanceTopImpl implements BalanceTop {
|
||||||
|
private final IEssentials ess;
|
||||||
|
private LinkedHashMap<UUID, BalanceTop.Entry> topCache = new LinkedHashMap<>();
|
||||||
|
private BigDecimal balanceTopTotal = BigDecimal.ZERO;
|
||||||
|
private long cacheAge = 0;
|
||||||
|
private CompletableFuture<Void> cacheLock;
|
||||||
|
|
||||||
|
public BalanceTopImpl(IEssentials ess) {
|
||||||
|
this.ess = ess;
|
||||||
|
ess.getServer().getServicesManager().register(BalanceTop.class, this, ess, ServicePriority.Normal);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateBalanceTopMap() {
|
||||||
|
final List<Entry> entries = new LinkedList<>();
|
||||||
|
BigDecimal newTotal = BigDecimal.ZERO;
|
||||||
|
for (UUID u : ess.getUserMap().getAllUniqueUsers()) {
|
||||||
|
final User user = ess.getUserMap().getUser(u);
|
||||||
|
if (user != null) {
|
||||||
|
if (!ess.getSettings().isNpcsInBalanceRanking() && user.isNPC()) {
|
||||||
|
// Don't list NPCs in output
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!user.isBaltopExempt()) {
|
||||||
|
final BigDecimal userMoney = user.getMoney();
|
||||||
|
user.updateMoneyCache(userMoney);
|
||||||
|
newTotal = newTotal.add(userMoney);
|
||||||
|
final String name = user.isHidden() ? user.getName() : user.getDisplayName();
|
||||||
|
entries.add(new BalanceTop.Entry(user.getBase().getUniqueId(), name, userMoney));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final LinkedHashMap<UUID, Entry> sortedMap = new LinkedHashMap<>();
|
||||||
|
entries.sort((entry1, entry2) -> entry2.getBalance().compareTo(entry1.getBalance()));
|
||||||
|
for (Entry entry : entries) {
|
||||||
|
sortedMap.put(entry.getUuid(), entry);
|
||||||
|
}
|
||||||
|
topCache = sortedMap;
|
||||||
|
balanceTopTotal = newTotal;
|
||||||
|
cacheAge = System.currentTimeMillis();
|
||||||
|
cacheLock.complete(null);
|
||||||
|
cacheLock = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CompletableFuture<Void> calculateBalanceTopMapAsync() {
|
||||||
|
if (cacheLock != null) {
|
||||||
|
return cacheLock;
|
||||||
|
}
|
||||||
|
cacheLock = new CompletableFuture<>();
|
||||||
|
ess.runTaskAsynchronously(this::calculateBalanceTopMap);
|
||||||
|
return cacheLock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<UUID, Entry> getBalanceTopCache() {
|
||||||
|
return Collections.unmodifiableMap(topCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCacheAge() {
|
||||||
|
return cacheAge;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BigDecimal getBalanceTopTotal() {
|
||||||
|
return balanceTopTotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCacheLocked() {
|
||||||
|
return cacheLock != null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -68,6 +68,7 @@ import net.ess3.provider.providers.PaperKnownCommandsProvider;
|
||||||
import net.ess3.provider.providers.PaperMaterialTagProvider;
|
import net.ess3.provider.providers.PaperMaterialTagProvider;
|
||||||
import net.ess3.provider.providers.PaperRecipeBookListener;
|
import net.ess3.provider.providers.PaperRecipeBookListener;
|
||||||
import net.ess3.provider.providers.PaperServerStateProvider;
|
import net.ess3.provider.providers.PaperServerStateProvider;
|
||||||
|
import net.essentialsx.api.v2.services.BalanceTop;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
@ -127,6 +128,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||||
private transient PermissionsHandler permissionsHandler;
|
private transient PermissionsHandler permissionsHandler;
|
||||||
private transient AlternativeCommandsHandler alternativeCommandsHandler;
|
private transient AlternativeCommandsHandler alternativeCommandsHandler;
|
||||||
private transient UserMap userMap;
|
private transient UserMap userMap;
|
||||||
|
private transient BalanceTopImpl balanceTop;
|
||||||
private transient ExecuteTimer execTimer;
|
private transient ExecuteTimer execTimer;
|
||||||
private transient I18n i18n;
|
private transient I18n i18n;
|
||||||
private transient MetricsWrapper metrics;
|
private transient MetricsWrapper metrics;
|
||||||
|
@ -181,6 +183,7 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||||
LOGGER.log(Level.INFO, dataFolder.toString());
|
LOGGER.log(Level.INFO, dataFolder.toString());
|
||||||
settings = new Settings(this);
|
settings = new Settings(this);
|
||||||
userMap = new UserMap(this);
|
userMap = new UserMap(this);
|
||||||
|
balanceTop = new BalanceTopImpl(this);
|
||||||
permissionsHandler = new PermissionsHandler(this, false);
|
permissionsHandler = new PermissionsHandler(this, false);
|
||||||
Economy.setEss(this);
|
Economy.setEss(this);
|
||||||
confList = new ArrayList<>();
|
confList = new ArrayList<>();
|
||||||
|
@ -246,6 +249,9 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||||
confList.add(userMap);
|
confList.add(userMap);
|
||||||
execTimer.mark("Init(Usermap)");
|
execTimer.mark("Init(Usermap)");
|
||||||
|
|
||||||
|
balanceTop = new BalanceTopImpl(this);
|
||||||
|
execTimer.mark("Init(BalanceTop)");
|
||||||
|
|
||||||
kits = new Kits(this);
|
kits = new Kits(this);
|
||||||
confList.add(kits);
|
confList.add(kits);
|
||||||
upgrade.convertKits();
|
upgrade.convertKits();
|
||||||
|
@ -968,6 +974,11 @@ public class Essentials extends JavaPlugin implements net.ess3.api.IEssentials {
|
||||||
return userMap;
|
return userMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BalanceTop getBalanceTop() {
|
||||||
|
return balanceTop;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public I18n getI18n() {
|
public I18n getI18n() {
|
||||||
return i18n;
|
return i18n;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import net.ess3.provider.KnownCommandsProvider;
|
||||||
import net.ess3.provider.ServerStateProvider;
|
import net.ess3.provider.ServerStateProvider;
|
||||||
import net.ess3.provider.SpawnerBlockProvider;
|
import net.ess3.provider.SpawnerBlockProvider;
|
||||||
import net.ess3.provider.SpawnerItemProvider;
|
import net.ess3.provider.SpawnerItemProvider;
|
||||||
|
import net.essentialsx.api.v2.services.BalanceTop;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
@ -95,6 +96,8 @@ public interface IEssentials extends Plugin {
|
||||||
|
|
||||||
UserMap getUserMap();
|
UserMap getUserMap();
|
||||||
|
|
||||||
|
BalanceTop getBalanceTop();
|
||||||
|
|
||||||
EssentialsTimer getTimer();
|
EssentialsTimer getTimer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1041,6 +1041,15 @@ public class User extends UserData implements Comparable<User>, IMessageRecipien
|
||||||
this.lastHomeConfirmationTimestamp = System.currentTimeMillis();
|
this.lastHomeConfirmationTimestamp = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isBaltopExempt() {
|
||||||
|
if (getBase().isOnline()) {
|
||||||
|
final boolean exempt = isAuthorized("essentials.balancetop.exclude");
|
||||||
|
setBaltopExemptCache(exempt);
|
||||||
|
return exempt;
|
||||||
|
}
|
||||||
|
return isBaltopExcludeCache();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Block getTargetBlock(int maxDistance) {
|
public Block getTargetBlock(int maxDistance) {
|
||||||
final Block block;
|
final Block block;
|
||||||
|
|
|
@ -70,6 +70,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||||
private Boolean confirmPay;
|
private Boolean confirmPay;
|
||||||
private Boolean confirmClear;
|
private Boolean confirmClear;
|
||||||
private boolean lastMessageReplyRecipient;
|
private boolean lastMessageReplyRecipient;
|
||||||
|
private boolean baltopExemptCache;
|
||||||
|
|
||||||
protected UserData(final Player base, final IEssentials ess) {
|
protected UserData(final Player base, final IEssentials ess) {
|
||||||
super(base);
|
super(base);
|
||||||
|
@ -141,6 +142,7 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||||
confirmPay = _getConfirmPay();
|
confirmPay = _getConfirmPay();
|
||||||
confirmClear = _getConfirmClear();
|
confirmClear = _getConfirmClear();
|
||||||
lastMessageReplyRecipient = _getLastMessageReplyRecipient();
|
lastMessageReplyRecipient = _getLastMessageReplyRecipient();
|
||||||
|
baltopExemptCache = _getBaltopExcludeCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal _getMoney() {
|
private BigDecimal _getMoney() {
|
||||||
|
@ -1027,6 +1029,20 @@ public abstract class UserData extends PlayerExtension implements IConf {
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean _getBaltopExcludeCache() {
|
||||||
|
return config.getBoolean("baltop-exempt", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isBaltopExcludeCache() {
|
||||||
|
return baltopExemptCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBaltopExemptCache(boolean baltopExempt) {
|
||||||
|
this.baltopExemptCache = baltopExempt;
|
||||||
|
config.setProperty("baltop-exempt", baltopExempt);
|
||||||
|
config.save();
|
||||||
|
}
|
||||||
|
|
||||||
public UUID getConfigUUID() {
|
public UUID getConfigUUID() {
|
||||||
return config.uuid;
|
return config.uuid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,35 @@
|
||||||
package com.earth2me.essentials.commands;
|
package com.earth2me.essentials.commands;
|
||||||
|
|
||||||
import com.earth2me.essentials.CommandSource;
|
import com.earth2me.essentials.CommandSource;
|
||||||
import com.earth2me.essentials.User;
|
|
||||||
import com.earth2me.essentials.textreader.SimpleTextInput;
|
import com.earth2me.essentials.textreader.SimpleTextInput;
|
||||||
import com.earth2me.essentials.textreader.TextPager;
|
import com.earth2me.essentials.textreader.TextPager;
|
||||||
import com.earth2me.essentials.utils.NumberUtil;
|
import com.earth2me.essentials.utils.NumberUtil;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import net.essentialsx.api.v2.services.BalanceTop;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import static com.earth2me.essentials.I18n.tl;
|
import static com.earth2me.essentials.I18n.tl;
|
||||||
|
|
||||||
public class Commandbalancetop extends EssentialsCommand {
|
public class Commandbalancetop extends EssentialsCommand {
|
||||||
public static final int MINUSERS = 50;
|
public static final int MINUSERS = 50;
|
||||||
private static final int CACHETIME = 2 * 60 * 1000;
|
private static final int CACHETIME = 2 * 60 * 1000;
|
||||||
private static final SimpleTextInput cache = new SimpleTextInput();
|
private static SimpleTextInput cache = new SimpleTextInput();
|
||||||
private static final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
|
||||||
private static long cacheage = 0;
|
|
||||||
|
|
||||||
public Commandbalancetop() {
|
public Commandbalancetop() {
|
||||||
super("balancetop");
|
super("balancetop");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void outputCache(final CommandSource sender, final int page) {
|
private void outputCache(final CommandSource sender, final int page) {
|
||||||
final Calendar cal = Calendar.getInstance();
|
final Calendar cal = Calendar.getInstance();
|
||||||
cal.setTimeInMillis(cacheage);
|
cal.setTimeInMillis(ess.getBalanceTop().getCacheAge());
|
||||||
final DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
|
final DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
|
||||||
sender.sendMessage(tl("balanceTop", format.format(cal.getTime())));
|
sender.sendMessage(tl("balanceTop", format.format(cal.getTime())));
|
||||||
new TextPager(cache).showPage(Integer.toString(page), null, "balancetop", sender);
|
new TextPager(cache).showPage(Integer.toString(page), null, "balancetop", sender);
|
||||||
|
@ -54,25 +49,17 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!force && lock.readLock().tryLock()) {
|
if (!force && ess.getBalanceTop().getCacheAge() > System.currentTimeMillis() - CACHETIME) {
|
||||||
try {
|
outputCache(sender, page);
|
||||||
if (cacheage > System.currentTimeMillis() - CACHETIME) {
|
return;
|
||||||
outputCache(sender, page);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (ess.getUserMap().getUniqueUsers() > MINUSERS) {
|
|
||||||
sender.sendMessage(tl("orderBalances", ess.getUserMap().getUniqueUsers()));
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
lock.readLock().unlock();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ess.getUserMap().getUniqueUsers() > MINUSERS) {
|
|
||||||
sender.sendMessage(tl("orderBalances", ess.getUserMap().getUniqueUsers()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ess.runTaskAsynchronously(new Viewer(sender, commandLabel, page, force));
|
|
||||||
|
|
||||||
|
// If there are less than 50 users in our usermap, there is no need to display a warning as these calculations should be done quickly
|
||||||
|
if (ess.getUserMap().getUniqueUsers() > MINUSERS) {
|
||||||
|
sender.sendMessage(tl("orderBalances", ess.getUserMap().getUniqueUsers()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ess.runTaskAsynchronously(new Viewer(sender, page, force));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -88,89 +75,42 @@ public class Commandbalancetop extends EssentialsCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Calculator implements Runnable {
|
|
||||||
private final transient Viewer viewer;
|
|
||||||
private final boolean force;
|
|
||||||
|
|
||||||
Calculator(final Viewer viewer, final boolean force) {
|
|
||||||
this.viewer = viewer;
|
|
||||||
this.force = force;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
lock.writeLock().lock();
|
|
||||||
try {
|
|
||||||
if (force || cacheage <= System.currentTimeMillis() - CACHETIME) {
|
|
||||||
cache.getLines().clear();
|
|
||||||
final Map<String, BigDecimal> balances = new HashMap<>();
|
|
||||||
BigDecimal totalMoney = BigDecimal.ZERO;
|
|
||||||
if (ess.getSettings().isEcoDisabled()) {
|
|
||||||
if (ess.getSettings().isDebug()) {
|
|
||||||
ess.getLogger().info("Internal economy functions disabled, aborting baltop.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (final UUID u : ess.getUserMap().getAllUniqueUsers()) {
|
|
||||||
final User user = ess.getUserMap().getUser(u);
|
|
||||||
if (user != null) {
|
|
||||||
if (!ess.getSettings().isNpcsInBalanceRanking() && user.isNPC()) {
|
|
||||||
// Don't list NPCs in output
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!user.isAuthorized("essentials.balancetop.exclude")) {
|
|
||||||
final BigDecimal userMoney = user.getMoney();
|
|
||||||
user.updateMoneyCache(userMoney);
|
|
||||||
totalMoney = totalMoney.add(userMoney);
|
|
||||||
final String name = user.isHidden() ? user.getName() : user.getDisplayName();
|
|
||||||
balances.put(name, userMoney);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final List<Map.Entry<String, BigDecimal>> sortedEntries = new ArrayList<>(balances.entrySet());
|
|
||||||
sortedEntries.sort((entry1, entry2) -> entry2.getValue().compareTo(entry1.getValue()));
|
|
||||||
|
|
||||||
cache.getLines().add(tl("serverTotal", NumberUtil.displayCurrency(totalMoney, ess)));
|
|
||||||
int pos = 1;
|
|
||||||
for (final Map.Entry<String, BigDecimal> entry : sortedEntries) {
|
|
||||||
cache.getLines().add(tl("balanceTopLine", pos, entry.getKey(), NumberUtil.displayCurrency(entry.getValue(), ess)));
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
cacheage = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
lock.writeLock().unlock();
|
|
||||||
}
|
|
||||||
ess.runTaskAsynchronously(viewer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Viewer implements Runnable {
|
private class Viewer implements Runnable {
|
||||||
private final transient CommandSource sender;
|
private final transient CommandSource sender;
|
||||||
private final transient int page;
|
private final transient int page;
|
||||||
private final transient boolean force;
|
private final transient boolean force;
|
||||||
private final transient String commandLabel;
|
|
||||||
|
|
||||||
Viewer(final CommandSource sender, final String commandLabel, final int page, final boolean force) {
|
Viewer(final CommandSource sender, final int page, final boolean force) {
|
||||||
this.sender = sender;
|
this.sender = sender;
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.force = force;
|
this.force = force;
|
||||||
this.commandLabel = commandLabel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
lock.readLock().lock();
|
if (ess.getSettings().isEcoDisabled()) {
|
||||||
try {
|
if (ess.getSettings().isDebug()) {
|
||||||
if (!force && cacheage > System.currentTimeMillis() - CACHETIME) {
|
ess.getLogger().info("Internal economy functions disabled, aborting baltop.");
|
||||||
outputCache(sender, page);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
} finally {
|
return;
|
||||||
lock.readLock().unlock();
|
|
||||||
}
|
}
|
||||||
ess.runTaskAsynchronously(new Calculator(new Viewer(sender, commandLabel, page, false), force));
|
|
||||||
|
final boolean fresh = force || ess.getBalanceTop().isCacheLocked() || ess.getBalanceTop().getCacheAge() <= System.currentTimeMillis() - CACHETIME;
|
||||||
|
final CompletableFuture<Void> future = fresh ? ess.getBalanceTop().calculateBalanceTopMapAsync() : CompletableFuture.completedFuture(null);
|
||||||
|
future.thenRun(() -> {
|
||||||
|
if (fresh) {
|
||||||
|
final SimpleTextInput newCache = new SimpleTextInput();
|
||||||
|
newCache.getLines().add(tl("serverTotal", NumberUtil.displayCurrency(ess.getBalanceTop().getBalanceTopTotal(), ess)));
|
||||||
|
int pos = 1;
|
||||||
|
for (final Map.Entry<UUID, BalanceTop.Entry> entry : ess.getBalanceTop().getBalanceTopCache().entrySet()) {
|
||||||
|
newCache.getLines().add(tl("balanceTopLine", pos, entry.getValue().getDisplayName(), NumberUtil.displayCurrency(entry.getValue().getBalance(), ess)));
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
cache = newCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputCache(sender, page);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
package net.essentialsx.api.v2.services;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class which provides numerous methods to interact with Essentials' balance top calculations.
|
||||||
|
* <p>
|
||||||
|
* Note: Implementations of this class should be thread-safe and thus do not need to be called from the server thread.
|
||||||
|
*/
|
||||||
|
public interface BalanceTop {
|
||||||
|
/**
|
||||||
|
* Re-calculates the balance top cache asynchronously.
|
||||||
|
* <p>
|
||||||
|
* This method will return a {@link CompletableFuture CompletableFuture<Void>} which
|
||||||
|
* will be completed upon the recalculation of the balance top map.
|
||||||
|
* After which you should run {@link BalanceTop#getBalanceTopCache()}
|
||||||
|
* to get the newly updated cache
|
||||||
|
*
|
||||||
|
* @return A future which completes after the balance top cache has been calculated.
|
||||||
|
*/
|
||||||
|
CompletableFuture<Void> calculateBalanceTopMapAsync();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the balance top cache or an empty list if one has not been calculated yet. The balance top cache is a {@link Map}
|
||||||
|
* which maps the UUID of the player to a {@link BalanceTop.Entry} object which stores the user's display name and balance.
|
||||||
|
* The returned map is sorted by greatest to least wealth.
|
||||||
|
* <p>
|
||||||
|
* There is no guarantee the returned cache is up to date. The balancetop command is directly responsible for updating
|
||||||
|
* this cache and does so every two minutes (if executed). See {@link BalanceTop#calculateBalanceTopMapAsync()} to
|
||||||
|
* manually update this cache yourself.
|
||||||
|
*
|
||||||
|
* @return The balance top cache.
|
||||||
|
* @see BalanceTop#calculateBalanceTopMapAsync()
|
||||||
|
*/
|
||||||
|
Map<UUID, Entry> getBalanceTopCache();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the epoch time (in mills.) that the baltop cache was last updated at. A value of zero indicates the cache
|
||||||
|
* has not been calculated yet at all.
|
||||||
|
*
|
||||||
|
* @return The epoch time (in mills.) since last cache update or zero.
|
||||||
|
*/
|
||||||
|
long getCacheAge();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the total amount of money in the economy at the point of the last balance top cache calculation or returns zero
|
||||||
|
* if no baltop calculation has been made as of yet.
|
||||||
|
*
|
||||||
|
* @return The total amount of money in the economy or zero.
|
||||||
|
* @see BalanceTop#getCacheAge() to find last baltop cache calculation
|
||||||
|
*/
|
||||||
|
BigDecimal getBalanceTopTotal();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if {@link BalanceTop#calculateBalanceTopMapAsync()} is still in the process of calculating the map.
|
||||||
|
*
|
||||||
|
* @return true if the balance top cache is still in the process of being calculated, otherwise false.
|
||||||
|
*/
|
||||||
|
boolean isCacheLocked();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents a user's name/balance in the balancetop cache.
|
||||||
|
*/
|
||||||
|
class Entry {
|
||||||
|
private final UUID uuid;
|
||||||
|
private final String displayName;
|
||||||
|
private final BigDecimal balance;
|
||||||
|
|
||||||
|
public Entry(UUID uuid, String displayName, BigDecimal balance) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the UUID of the user.
|
||||||
|
* @return The uuid of this user.
|
||||||
|
*/
|
||||||
|
public UUID getUuid() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the display name of the user at the time of cache population.
|
||||||
|
* @return The display name of this user.
|
||||||
|
*/
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the balance of the user at the time of cache population.
|
||||||
|
* @return The balance of this user.
|
||||||
|
*/
|
||||||
|
public BigDecimal getBalance() {
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue