2011-03-30 06:03:21 +02:00
|
|
|
package com.earth2me.essentials;
|
|
|
|
|
|
|
|
import com.earth2me.essentials.commands.IEssentialsCommand;
|
2021-05-10 21:36:09 +02:00
|
|
|
import com.earth2me.essentials.economy.EconomyLayer;
|
|
|
|
import com.earth2me.essentials.economy.EconomyLayers;
|
2015-10-27 18:34:59 +01:00
|
|
|
import com.earth2me.essentials.messaging.IMessageRecipient;
|
|
|
|
import com.earth2me.essentials.messaging.SimpleMessageRecipient;
|
2013-06-08 23:31:19 +02:00
|
|
|
import com.earth2me.essentials.utils.DateUtil;
|
2021-01-08 21:43:32 +01:00
|
|
|
import com.earth2me.essentials.utils.EnumUtil;
|
2013-06-08 23:31:19 +02:00
|
|
|
import com.earth2me.essentials.utils.FormatUtil;
|
2013-10-11 04:44:41 +02:00
|
|
|
import com.earth2me.essentials.utils.NumberUtil;
|
2021-07-01 17:23:32 +02:00
|
|
|
import com.earth2me.essentials.utils.TriState;
|
2018-12-31 12:28:05 +01:00
|
|
|
import com.earth2me.essentials.utils.VersionUtil;
|
2021-02-19 16:13:49 +01:00
|
|
|
import com.google.common.collect.Lists;
|
2013-10-11 04:44:41 +02:00
|
|
|
import net.ess3.api.IEssentials;
|
2014-02-02 17:07:32 +01:00
|
|
|
import net.ess3.api.MaxMoneyException;
|
2013-12-31 18:18:04 +01:00
|
|
|
import net.ess3.api.events.AfkStatusChangeEvent;
|
2015-10-28 16:27:10 +01:00
|
|
|
import net.ess3.api.events.JailStatusChangeEvent;
|
2016-08-21 03:13:26 +02:00
|
|
|
import net.ess3.api.events.MuteStatusChangeEvent;
|
2013-11-26 18:46:23 +01:00
|
|
|
import net.ess3.api.events.UserBalanceUpdateEvent;
|
2021-01-02 04:45:52 +01:00
|
|
|
import net.essentialsx.api.v2.events.TransactionEvent;
|
2021-07-01 17:23:32 +02:00
|
|
|
import net.essentialsx.api.v2.services.mail.MailSender;
|
2011-08-23 04:42:32 +02:00
|
|
|
import org.bukkit.Location;
|
2017-12-13 07:06:25 +01:00
|
|
|
import org.bukkit.Material;
|
2021-01-08 21:43:32 +01:00
|
|
|
import org.bukkit.Statistic;
|
2020-11-09 17:38:02 +01:00
|
|
|
import org.bukkit.block.Block;
|
This is a big refactoring of the user class and more.
Many commands have been cleaned.
File changes:
- all user data has been moved from users.yml to userdata folder
- all files in userdata folder are lower case
Both changes should be done automatically.
Class changes:
- Moved all user data functions to UserData class
- Moved all user teleport functions to Teleport class
- Moved the user list to Essentials class
- Less static functions for better testing
- EssentialsCommand now has ess Property (Essentials class)
- New NotEnoughArgumentsException, that will show command description and syntax
New commands:
- /seen, shows the last login or logout
- /tempban, temporarily ban someone
- /tjail and mute, temporarily option added
Other changes:
- ban reason is saved
- don't show "You have xxx mail" on login, if user doesn't have essentials.mail permission
- time will be parsed: years, months (mo), weeks, days, hours, minutes (m), seconds, these can be shortened and combined, example: 2 days 5h 30m
git-svn-id: https://svn.java.net/svn/essentials~svn/trunk@1300 e251c2fe-e539-e718-e476-b85c1f46cddb
2011-05-01 23:07:30 +02:00
|
|
|
import org.bukkit.entity.Player;
|
2012-08-28 03:06:11 +02:00
|
|
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
2016-07-23 00:56:26 +02:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import org.bukkit.inventory.PlayerInventory;
|
2021-11-24 15:57:55 +01:00
|
|
|
import org.bukkit.metadata.FixedMetadataValue;
|
2013-01-01 22:12:26 +01:00
|
|
|
import org.bukkit.potion.PotionEffect;
|
|
|
|
import org.bukkit.potion.PotionEffectType;
|
2021-12-04 15:40:06 +01:00
|
|
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
2011-03-30 06:03:21 +02:00
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
import java.math.BigDecimal;
|
2022-02-06 19:18:40 +01:00
|
|
|
import java.util.ArrayList;
|
2020-06-27 21:17:35 +02:00
|
|
|
import java.util.Calendar;
|
2021-12-04 15:40:06 +01:00
|
|
|
import java.util.Collection;
|
2022-02-06 19:18:40 +01:00
|
|
|
import java.util.Collections;
|
2020-06-27 21:17:35 +02:00
|
|
|
import java.util.GregorianCalendar;
|
2021-12-04 15:40:06 +01:00
|
|
|
import java.util.LinkedHashMap;
|
2020-06-27 21:17:35 +02:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Locale;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.UUID;
|
|
|
|
import java.util.WeakHashMap;
|
2020-06-24 10:52:25 +02:00
|
|
|
import java.util.concurrent.CompletableFuture;
|
2021-12-04 15:40:06 +01:00
|
|
|
import java.util.concurrent.TimeUnit;
|
2015-04-15 06:06:16 +02:00
|
|
|
import java.util.logging.Level;
|
|
|
|
|
|
|
|
import static com.earth2me.essentials.I18n.tl;
|
|
|
|
|
2015-10-27 18:34:59 +01:00
|
|
|
public class User extends UserData implements Comparable<User>, IMessageRecipient, net.ess3.api.IUser {
|
2021-01-08 21:43:32 +01:00
|
|
|
private static final Statistic PLAY_ONE_TICK = EnumUtil.getStatistic("PLAY_ONE_MINUTE", "PLAY_ONE_TICK");
|
2021-12-04 15:40:06 +01:00
|
|
|
|
|
|
|
// User modules
|
2020-04-25 14:08:57 +02:00
|
|
|
private final IMessageRecipient messageRecipient;
|
2020-10-03 19:46:05 +02:00
|
|
|
private transient final AsyncTeleport teleport;
|
|
|
|
private transient final Teleport legacyTeleport;
|
2021-12-04 15:40:06 +01:00
|
|
|
|
|
|
|
// User command confirmation strings
|
2020-10-03 19:46:05 +02:00
|
|
|
private final Map<User, BigDecimal> confirmingPayments = new WeakHashMap<>();
|
2021-12-04 15:40:06 +01:00
|
|
|
|
|
|
|
// User teleport variables
|
|
|
|
private final transient LinkedHashMap<String, TpaRequest> teleportRequestQueue = new LinkedHashMap<>();
|
|
|
|
|
|
|
|
// User properties
|
2015-04-15 06:06:16 +02:00
|
|
|
private transient boolean vanished;
|
|
|
|
private boolean hidden = false;
|
2022-07-24 00:35:14 +02:00
|
|
|
private boolean leavingHidden = false;
|
2015-04-15 06:06:16 +02:00
|
|
|
private boolean rightClickJump = false;
|
|
|
|
private boolean invSee = false;
|
|
|
|
private boolean recipeSee = false;
|
|
|
|
private boolean enderSee = false;
|
2015-07-29 03:45:33 +02:00
|
|
|
private boolean ignoreMsg = false;
|
2021-12-04 15:40:06 +01:00
|
|
|
|
|
|
|
// User afk variables
|
2016-06-18 18:44:17 +02:00
|
|
|
private String afkMessage;
|
2016-07-26 02:36:29 +02:00
|
|
|
private long afkSince;
|
2021-12-04 15:40:06 +01:00
|
|
|
private transient Location afkPosition = null;
|
|
|
|
|
|
|
|
// Misc
|
|
|
|
private transient long lastOnlineActivity;
|
|
|
|
private transient long lastThrottledAction;
|
|
|
|
private transient long lastActivity = System.currentTimeMillis();
|
|
|
|
private transient long teleportInvulnerabilityTimestamp = 0;
|
2017-11-12 17:44:53 +01:00
|
|
|
private String confirmingClearCommand;
|
2017-06-22 23:54:51 +02:00
|
|
|
private long lastNotifiedAboutMailsMs;
|
2020-07-01 23:03:22 +02:00
|
|
|
private String lastHomeConfirmation;
|
|
|
|
private long lastHomeConfirmationTimestamp;
|
2021-09-29 02:31:44 +02:00
|
|
|
private Boolean toggleShout;
|
2021-02-19 16:13:49 +01:00
|
|
|
private transient final List<String> signCopy = Lists.newArrayList("", "", "", "");
|
2022-06-04 03:43:12 +02:00
|
|
|
private transient long lastVanishTime = System.currentTimeMillis();
|
2015-04-15 06:06:16 +02:00
|
|
|
|
|
|
|
public User(final Player base, final IEssentials ess) {
|
|
|
|
super(base, ess);
|
2020-06-24 10:52:25 +02:00
|
|
|
teleport = new AsyncTeleport(this, ess);
|
|
|
|
legacyTeleport = new Teleport(this, ess);
|
2015-04-15 06:06:16 +02:00
|
|
|
if (isAfk()) {
|
|
|
|
afkPosition = this.getLocation();
|
|
|
|
}
|
|
|
|
if (this.getBase().isOnline()) {
|
|
|
|
lastOnlineActivity = System.currentTimeMillis();
|
|
|
|
}
|
2015-10-27 18:34:59 +01:00
|
|
|
this.messageRecipient = new SimpleMessageRecipient(ess, this);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
2022-09-04 16:42:43 +02:00
|
|
|
public void update(final Player base) {
|
2015-04-15 06:06:16 +02:00
|
|
|
setBase(base);
|
|
|
|
}
|
|
|
|
|
2022-02-13 21:54:19 +01:00
|
|
|
public IEssentials getEssentials() {
|
|
|
|
return ess;
|
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
@Override
|
|
|
|
public boolean isAuthorized(final IEssentialsCommand cmd) {
|
|
|
|
return isAuthorized(cmd, "essentials.");
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isAuthorized(final IEssentialsCommand cmd, final String permissionPrefix) {
|
|
|
|
return isAuthorized(permissionPrefix + (cmd.getName().equals("r") ? "msg" : cmd.getName()));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isAuthorized(final String node) {
|
|
|
|
final boolean result = isAuthorizedCheck(node);
|
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
ess.getLogger().log(Level.INFO, "checking if " + base.getName() + " has " + node + " - " + result);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-06-09 16:56:58 +02:00
|
|
|
@Override
|
|
|
|
public boolean isPermissionSet(final String node) {
|
2021-07-01 15:43:35 +02:00
|
|
|
final boolean result = isPermSetCheck(node);
|
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
ess.getLogger().log(Level.INFO, "checking if " + base.getName() + " has " + node + " (set-explicit) - " + result);
|
|
|
|
}
|
|
|
|
return result;
|
2019-06-09 16:56:58 +02:00
|
|
|
}
|
|
|
|
|
2021-05-28 19:35:33 +02:00
|
|
|
/**
|
|
|
|
* Checks if the given permission is explicitly defined and returns its value, otherwise
|
|
|
|
* {@link TriState#UNSET}.
|
|
|
|
*/
|
|
|
|
public TriState isAuthorizedExact(final String node) {
|
|
|
|
return isAuthorizedExactCheck(node);
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
|
2021-05-28 19:35:33 +02:00
|
|
|
private boolean isAuthorizedCheck(final String node) {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (base instanceof OfflinePlayer) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
return ess.getPermissionsHandler().hasPermission(base, node);
|
2020-10-03 19:46:05 +02:00
|
|
|
} catch (final Exception ex) {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage(), ex);
|
|
|
|
} else {
|
|
|
|
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage());
|
2019-06-09 16:56:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isPermSetCheck(final String node) {
|
|
|
|
if (base instanceof OfflinePlayer) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
return ess.getPermissionsHandler().isPermissionSet(base, node);
|
2020-10-03 19:46:05 +02:00
|
|
|
} catch (final Exception ex) {
|
2019-06-09 16:56:58 +02:00
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage(), ex);
|
|
|
|
} else {
|
|
|
|
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage());
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-28 19:35:33 +02:00
|
|
|
private TriState isAuthorizedExactCheck(final String node) {
|
|
|
|
if (base instanceof OfflinePlayer) {
|
|
|
|
return TriState.UNSET;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
return ess.getPermissionsHandler().isPermissionSetExact(base, node);
|
|
|
|
} catch (final Exception ex) {
|
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage(), ex);
|
|
|
|
} else {
|
|
|
|
ess.getLogger().log(Level.SEVERE, "Permission System Error: " + ess.getPermissionsHandler().getName() + " returned: " + ex.getMessage());
|
|
|
|
}
|
|
|
|
|
|
|
|
return TriState.UNSET;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
@Override
|
|
|
|
public void healCooldown() throws Exception {
|
|
|
|
final Calendar now = new GregorianCalendar();
|
|
|
|
if (getLastHealTimestamp() > 0) {
|
|
|
|
final double cooldown = ess.getSettings().getHealCooldown();
|
|
|
|
final Calendar cooldownTime = new GregorianCalendar();
|
|
|
|
cooldownTime.setTimeInMillis(getLastHealTimestamp());
|
|
|
|
cooldownTime.add(Calendar.SECOND, (int) cooldown);
|
|
|
|
cooldownTime.add(Calendar.MILLISECOND, (int) ((cooldown * 1000.0) % 1000.0));
|
|
|
|
if (cooldownTime.after(now) && !isAuthorized("essentials.heal.cooldown.bypass")) {
|
|
|
|
throw new Exception(tl("timeBeforeHeal", DateUtil.formatDateDiff(cooldownTime.getTimeInMillis())));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setLastHealTimestamp(now.getTimeInMillis());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void giveMoney(final BigDecimal value) throws MaxMoneyException {
|
2015-06-03 22:11:56 +02:00
|
|
|
giveMoney(value, null);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void giveMoney(final BigDecimal value, final CommandSource initiator) throws MaxMoneyException {
|
2019-12-23 14:16:34 +01:00
|
|
|
giveMoney(value, initiator, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
public void giveMoney(final BigDecimal value, final CommandSource initiator, final UserBalanceUpdateEvent.Cause cause) throws MaxMoneyException {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (value.signum() == 0) {
|
|
|
|
return;
|
|
|
|
}
|
2019-12-23 14:16:34 +01:00
|
|
|
setMoney(getMoney().add(value), cause);
|
2015-04-15 06:06:16 +02:00
|
|
|
sendMessage(tl("addedToAccount", NumberUtil.displayCurrency(value, ess)));
|
|
|
|
if (initiator != null) {
|
|
|
|
initiator.sendMessage(tl("addedToOthersAccount", NumberUtil.displayCurrency(value, ess), this.getDisplayName(), NumberUtil.displayCurrency(getMoney(), ess)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2016-12-02 09:04:16 +01:00
|
|
|
public void payUser(final User reciever, final BigDecimal value) throws Exception {
|
2019-12-23 14:16:34 +01:00
|
|
|
payUser(reciever, value, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
public void payUser(final User reciever, final BigDecimal value, final UserBalanceUpdateEvent.Cause cause) throws Exception {
|
2016-12-02 09:04:16 +01:00
|
|
|
if (value.compareTo(BigDecimal.ZERO) < 1) {
|
|
|
|
throw new Exception(tl("payMustBePositive"));
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
2016-12-02 09:04:16 +01:00
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
if (canAfford(value)) {
|
2020-03-13 08:39:21 +01:00
|
|
|
setMoney(getMoney().subtract(value), cause);
|
|
|
|
reciever.setMoney(reciever.getMoney().add(value), cause);
|
2015-04-15 06:06:16 +02:00
|
|
|
sendMessage(tl("moneySentTo", NumberUtil.displayCurrency(value, ess), reciever.getDisplayName()));
|
|
|
|
reciever.sendMessage(tl("moneyRecievedFrom", NumberUtil.displayCurrency(value, ess), getDisplayName()));
|
2021-01-02 04:45:52 +01:00
|
|
|
final TransactionEvent transactionEvent = new TransactionEvent(this.getSource(), reciever, value);
|
|
|
|
ess.getServer().getPluginManager().callEvent(transactionEvent);
|
2015-04-15 06:06:16 +02:00
|
|
|
} else {
|
|
|
|
throw new ChargeException(tl("notEnoughMoney", NumberUtil.displayCurrency(value, ess)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void takeMoney(final BigDecimal value) {
|
2015-06-03 22:11:56 +02:00
|
|
|
takeMoney(value, null);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void takeMoney(final BigDecimal value, final CommandSource initiator) {
|
2019-12-23 14:16:34 +01:00
|
|
|
takeMoney(value, initiator, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
public void takeMoney(final BigDecimal value, final CommandSource initiator, final UserBalanceUpdateEvent.Cause cause) {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (value.signum() == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
try {
|
2019-12-23 14:16:34 +01:00
|
|
|
setMoney(getMoney().subtract(value), cause);
|
2020-10-03 19:46:05 +02:00
|
|
|
} catch (final MaxMoneyException ex) {
|
2015-04-15 06:06:16 +02:00
|
|
|
ess.getLogger().log(Level.WARNING, "Invalid call to takeMoney, total balance can't be more than the max-money limit.", ex);
|
|
|
|
}
|
|
|
|
sendMessage(tl("takenFromAccount", NumberUtil.displayCurrency(value, ess)));
|
|
|
|
if (initiator != null) {
|
|
|
|
initiator.sendMessage(tl("takenFromOthersAccount", NumberUtil.displayCurrency(value, ess), this.getDisplayName(), NumberUtil.displayCurrency(getMoney(), ess)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean canAfford(final BigDecimal cost) {
|
|
|
|
return canAfford(cost, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canAfford(final BigDecimal cost, final boolean permcheck) {
|
|
|
|
if (cost.signum() <= 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
final BigDecimal remainingBalance = getMoney().subtract(cost);
|
|
|
|
if (!permcheck || isAuthorized("essentials.eco.loan")) {
|
2020-10-03 19:46:05 +02:00
|
|
|
return remainingBalance.compareTo(ess.getSettings().getMinMoney()) >= 0;
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
2020-10-03 19:46:05 +02:00
|
|
|
return remainingBalance.signum() >= 0;
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void dispose() {
|
2020-04-25 14:08:57 +02:00
|
|
|
ess.runTaskAsynchronously(this::_dispose);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void _dispose() {
|
|
|
|
if (!base.isOnline()) {
|
|
|
|
this.base = new OfflinePlayer(getConfigUUID(), ess.getServer());
|
|
|
|
}
|
|
|
|
cleanup();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-12-13 07:06:25 +01:00
|
|
|
public Boolean canSpawnItem(final Material material) {
|
2018-12-31 12:28:05 +01:00
|
|
|
if (ess.getSettings().permissionBasedItemSpawn()) {
|
|
|
|
final String name = material.toString().toLowerCase(Locale.ENGLISH).replace("_", "");
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
if (isAuthorized("essentials.itemspawn.item-all") || isAuthorized("essentials.itemspawn.item-" + name))
|
|
|
|
return true;
|
2018-12-31 12:28:05 +01:00
|
|
|
|
2022-02-13 21:33:51 +01:00
|
|
|
if (VersionUtil.PRE_FLATTENING) {
|
2018-12-31 12:28:05 +01:00
|
|
|
final int id = material.getId();
|
|
|
|
if (isAuthorized("essentials.itemspawn.item-" + id)) return true;
|
|
|
|
}
|
2021-04-03 17:38:04 +02:00
|
|
|
|
|
|
|
return false;
|
2018-12-31 12:28:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return isAuthorized("essentials.itemspawn.exempt") || !ess.getSettings().itemSpawnBlacklist().contains(material);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setLastLocation() {
|
|
|
|
setLastLocation(this.getLocation());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setLogoutLocation() {
|
|
|
|
setLogoutLocation(this.getLocation());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void requestTeleport(final User player, final boolean here) {
|
2021-12-04 15:40:06 +01:00
|
|
|
final TpaRequest request = teleportRequestQueue.getOrDefault(player.getName(), new TpaRequest(player.getName(), player.getUUID()));
|
|
|
|
request.setTime(System.currentTimeMillis());
|
|
|
|
request.setHere(here);
|
|
|
|
request.setLocation(here ? player.getLocation() : this.getLocation());
|
|
|
|
|
|
|
|
// Handle max queue size
|
|
|
|
teleportRequestQueue.remove(request.getName());
|
|
|
|
if (teleportRequestQueue.size() >= ess.getSettings().getTpaMaxRequests()) {
|
2022-02-06 19:18:40 +01:00
|
|
|
final List<String> keys = new ArrayList<>(teleportRequestQueue.keySet());
|
|
|
|
teleportRequestQueue.remove(keys.get(keys.size() - 1));
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
2021-12-04 15:40:06 +01:00
|
|
|
|
|
|
|
// Add request to queue
|
|
|
|
teleportRequestQueue.put(request.getName(), request);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
2016-11-22 21:39:31 +01:00
|
|
|
@Override
|
2021-12-04 15:40:06 +01:00
|
|
|
@Deprecated
|
2016-11-22 21:39:31 +01:00
|
|
|
public boolean hasOutstandingTeleportRequest() {
|
2021-12-04 15:40:06 +01:00
|
|
|
return getNextTpaRequest(false, false, false) != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Collection<String> getPendingTpaKeys() {
|
|
|
|
return teleportRequestQueue.keySet();
|
2016-11-22 21:39:31 +01:00
|
|
|
}
|
|
|
|
|
2021-12-04 15:40:06 +01:00
|
|
|
@Override
|
|
|
|
public boolean hasPendingTpaRequests(boolean inform, boolean excludeHere) {
|
|
|
|
return getNextTpaRequest(inform, false, excludeHere) != null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasOutstandingTpaRequest(String playerUsername, boolean here) {
|
|
|
|
final TpaRequest request = getOutstandingTpaRequest(playerUsername, false);
|
|
|
|
return request != null && request.isHere() == here;
|
|
|
|
}
|
|
|
|
|
|
|
|
public @Nullable TpaRequest getOutstandingTpaRequest(String playerUsername, boolean inform) {
|
|
|
|
if (!teleportRequestQueue.containsKey(playerUsername)) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
final long timeout = ess.getSettings().getTpaAcceptCancellation();
|
|
|
|
final TpaRequest request = teleportRequestQueue.get(playerUsername);
|
|
|
|
if (timeout < 1 || System.currentTimeMillis() - request.getTime() <= timeout * 1000) {
|
|
|
|
return request;
|
|
|
|
}
|
|
|
|
teleportRequestQueue.remove(playerUsername);
|
|
|
|
if (inform) {
|
|
|
|
sendMessage(tl("requestTimedOutFrom", ess.getUser(request.getRequesterUuid()).getDisplayName()));
|
|
|
|
}
|
|
|
|
return null;
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
2021-12-04 15:40:06 +01:00
|
|
|
public TpaRequest removeTpaRequest(String playerUsername) {
|
|
|
|
return teleportRequestQueue.remove(playerUsername);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
2021-12-04 15:40:06 +01:00
|
|
|
@Override
|
2022-02-06 19:18:40 +01:00
|
|
|
public TpaRequest getNextTpaRequest(boolean inform, boolean ignoreExpirations, boolean excludeHere) {
|
2021-12-04 15:40:06 +01:00
|
|
|
if (teleportRequestQueue.isEmpty()) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
final long timeout = ess.getSettings().getTpaAcceptCancellation();
|
2022-02-06 19:18:40 +01:00
|
|
|
final List<String> keys = new ArrayList<>(teleportRequestQueue.keySet());
|
|
|
|
Collections.reverse(keys);
|
|
|
|
|
2021-12-04 15:40:06 +01:00
|
|
|
TpaRequest nextRequest = null;
|
2022-02-06 19:18:40 +01:00
|
|
|
for (final String key : keys) {
|
|
|
|
final TpaRequest request = teleportRequestQueue.get(key);
|
2021-12-04 15:40:06 +01:00
|
|
|
if (timeout < 1 || (System.currentTimeMillis() - request.getTime()) <= TimeUnit.SECONDS.toMillis(timeout)) {
|
|
|
|
if (excludeHere && request.isHere()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-02-06 19:18:40 +01:00
|
|
|
if (ignoreExpirations) {
|
2021-12-04 15:40:06 +01:00
|
|
|
return request;
|
|
|
|
} else if (nextRequest == null) {
|
|
|
|
nextRequest = request;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (inform) {
|
|
|
|
sendMessage(tl("requestTimedOutFrom", ess.getUser(request.getRequesterUuid()).getDisplayName()));
|
|
|
|
}
|
2022-02-06 19:18:40 +01:00
|
|
|
teleportRequestQueue.remove(key);
|
2021-12-04 15:40:06 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nextRequest;
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
2020-08-11 20:09:22 +02:00
|
|
|
public String getNick() {
|
|
|
|
return getNick(true, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Needed for backwards compatibility.
|
|
|
|
*/
|
2015-04-15 06:06:16 +02:00
|
|
|
public String getNick(final boolean longnick) {
|
2020-08-11 20:09:22 +02:00
|
|
|
return getNick(true, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Needed for backwards compatibility.
|
|
|
|
*/
|
2020-10-03 19:46:05 +02:00
|
|
|
public String getNick(final boolean longnick, final boolean withPrefix, final boolean withSuffix) {
|
2020-08-11 20:09:22 +02:00
|
|
|
return getNick(withPrefix, withSuffix);
|
2016-07-28 18:17:26 +02:00
|
|
|
}
|
|
|
|
|
2020-08-11 20:09:22 +02:00
|
|
|
public String getNick(final boolean withPrefix, final boolean withSuffix) {
|
2015-04-15 06:06:16 +02:00
|
|
|
final StringBuilder prefix = new StringBuilder();
|
2020-10-03 19:46:05 +02:00
|
|
|
final String nickname;
|
2015-04-15 06:06:16 +02:00
|
|
|
String suffix = "";
|
|
|
|
final String nick = getNickname();
|
|
|
|
if (ess.getSettings().isCommandDisabled("nick") || nick == null || nick.isEmpty() || nick.equals(getName())) {
|
|
|
|
nickname = getName();
|
|
|
|
} else if (nick.equalsIgnoreCase(getName())) {
|
|
|
|
nickname = nick;
|
|
|
|
} else {
|
2022-10-25 08:44:05 +02:00
|
|
|
if (isAuthorized("essentials.nick.hideprefix")) {
|
|
|
|
nickname = nick;
|
|
|
|
} else {
|
|
|
|
nickname = FormatUtil.replaceFormat(ess.getSettings().getNicknamePrefix()) + nick;
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
suffix = "§r";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.getBase().isOp()) {
|
|
|
|
try {
|
2020-06-27 21:17:35 +02:00
|
|
|
final String opPrefix = ess.getSettings().getOperatorColor();
|
|
|
|
if (opPrefix != null && !opPrefix.isEmpty()) {
|
|
|
|
prefix.insert(0, opPrefix);
|
2015-04-15 06:06:16 +02:00
|
|
|
suffix = "§r";
|
|
|
|
}
|
2020-10-03 19:46:05 +02:00
|
|
|
} catch (final Exception e) {
|
2020-06-27 21:17:35 +02:00
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ess.getSettings().addPrefixSuffix()) {
|
|
|
|
//These two extra toggles are not documented, because they are mostly redundant #EasterEgg
|
2017-01-20 16:08:13 +01:00
|
|
|
if (withPrefix || !ess.getSettings().disablePrefix()) {
|
2020-06-28 17:36:17 +02:00
|
|
|
final String ptext = FormatUtil.replaceFormat(ess.getPermissionsHandler().getPrefix(base));
|
2015-04-15 06:06:16 +02:00
|
|
|
prefix.insert(0, ptext);
|
|
|
|
suffix = "§r";
|
|
|
|
}
|
2017-01-20 16:08:13 +01:00
|
|
|
if (withSuffix || !ess.getSettings().disableSuffix()) {
|
2020-06-28 17:36:17 +02:00
|
|
|
final String stext = FormatUtil.replaceFormat(ess.getPermissionsHandler().getSuffix(base));
|
2015-04-15 06:06:16 +02:00
|
|
|
suffix = stext + "§r";
|
2020-06-28 17:36:17 +02:00
|
|
|
// :YEP: WHAT ARE THEY DOING?
|
|
|
|
// :YEP: STILL. LEGACY CODE.
|
|
|
|
// :YEP: BUT WHY?
|
|
|
|
// :YEP: I CAN'T BELIEVE THIS!
|
|
|
|
// Code from 1542 BC #EasterEgg
|
|
|
|
suffix = suffix.replace("§f§r", "§r").replace("§r§r", "§r");
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
final String strPrefix = prefix.toString();
|
|
|
|
String output = strPrefix + nickname + suffix;
|
|
|
|
if (output.charAt(output.length() - 1) == '§') {
|
|
|
|
output = output.substring(0, output.length() - 1);
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setDisplayNick() {
|
|
|
|
if (base.isOnline() && ess.getSettings().changeDisplayName()) {
|
|
|
|
this.getBase().setDisplayName(getNick(true));
|
2016-08-06 18:45:54 +02:00
|
|
|
if (isAfk()) {
|
|
|
|
updateAfkListName();
|
|
|
|
} else if (ess.getSettings().changePlayerListName()) {
|
2020-10-03 19:46:05 +02:00
|
|
|
final String name = getNick(ess.getSettings().isAddingPrefixInPlayerlist(), ess.getSettings().isAddingSuffixInPlayerlist());
|
2015-04-15 06:06:16 +02:00
|
|
|
try {
|
|
|
|
this.getBase().setPlayerListName(name);
|
2020-10-03 19:46:05 +02:00
|
|
|
} catch (final IllegalArgumentException e) {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (ess.getSettings().isDebug()) {
|
2022-06-27 20:54:10 +02:00
|
|
|
ess.getLogger().log(Level.INFO, "Playerlist for " + name + " was not updated. Name clashed with another online player.");
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-11 20:09:22 +02:00
|
|
|
@Override
|
2015-04-15 06:06:16 +02:00
|
|
|
public String getDisplayName() {
|
2018-12-09 12:02:45 +01:00
|
|
|
return super.getBase().getDisplayName() == null || (ess.getSettings().hideDisplayNameInVanish() && isHidden()) ? super.getBase().getName() : super.getBase().getDisplayName();
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
2021-03-29 19:07:55 +02:00
|
|
|
@Override
|
|
|
|
public String getFormattedNickname() {
|
|
|
|
final String rawNickname = getNickname();
|
|
|
|
if (rawNickname == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return FormatUtil.replaceFormat(ess.getSettings().getNicknamePrefix() + rawNickname);
|
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
@Override
|
2020-06-24 10:52:25 +02:00
|
|
|
public AsyncTeleport getAsyncTeleport() {
|
2015-04-15 06:06:16 +02:00
|
|
|
return teleport;
|
|
|
|
}
|
|
|
|
|
2020-06-24 10:52:25 +02:00
|
|
|
/**
|
|
|
|
* @deprecated This API is not asynchronous. Use {@link User#getAsyncTeleport()}
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
@Deprecated
|
|
|
|
public Teleport getTeleport() {
|
|
|
|
return legacyTeleport;
|
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
public long getLastOnlineActivity() {
|
|
|
|
return lastOnlineActivity;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setLastOnlineActivity(final long timestamp) {
|
|
|
|
lastOnlineActivity = timestamp;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public BigDecimal getMoney() {
|
|
|
|
final long start = System.nanoTime();
|
|
|
|
final BigDecimal value = _getMoney();
|
|
|
|
final long elapsed = System.nanoTime() - start;
|
|
|
|
if (elapsed > ess.getSettings().getEconomyLagWarning()) {
|
|
|
|
ess.getLogger().log(Level.INFO, "Lag Notice - Slow Economy Response - Request took over {0}ms!", elapsed / 1000000.0);
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
@Override
|
|
|
|
public void setMoney(final BigDecimal value) throws MaxMoneyException {
|
|
|
|
setMoney(value, UserBalanceUpdateEvent.Cause.UNKNOWN);
|
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
private BigDecimal _getMoney() {
|
|
|
|
if (ess.getSettings().isEcoDisabled()) {
|
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
ess.getLogger().info("Internal economy functions disabled, aborting balance check.");
|
|
|
|
}
|
|
|
|
return BigDecimal.ZERO;
|
|
|
|
}
|
2021-05-10 21:36:09 +02:00
|
|
|
final EconomyLayer layer = EconomyLayers.getSelectedLayer();
|
|
|
|
if (layer != null && (layer.hasAccount(getBase()) || layer.createPlayerAccount(getBase()))) {
|
|
|
|
return layer.getBalance(getBase());
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
return super.getMoney();
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
public void setMoney(final BigDecimal value, final UserBalanceUpdateEvent.Cause cause) throws MaxMoneyException {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (ess.getSettings().isEcoDisabled()) {
|
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
ess.getLogger().info("Internal economy functions disabled, aborting balance change.");
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
final BigDecimal oldBalance = _getMoney();
|
2019-12-23 14:16:34 +01:00
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
final UserBalanceUpdateEvent updateEvent = new UserBalanceUpdateEvent(this.getBase(), oldBalance, value, cause);
|
2016-06-18 19:33:51 +02:00
|
|
|
ess.getServer().getPluginManager().callEvent(updateEvent);
|
2020-10-03 19:46:05 +02:00
|
|
|
final BigDecimal newBalance = updateEvent.getNewBalance();
|
2019-12-23 14:16:34 +01:00
|
|
|
|
2021-05-10 21:36:09 +02:00
|
|
|
final EconomyLayer layer = EconomyLayers.getSelectedLayer();
|
|
|
|
if (layer != null && (layer.hasAccount(getBase()) || layer.createPlayerAccount(getBase()))) {
|
|
|
|
layer.set(getBase(), newBalance);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
2016-06-18 19:33:51 +02:00
|
|
|
super.setMoney(newBalance, true);
|
2021-01-02 06:12:53 +01:00
|
|
|
Trade.log("Update", "Set", "API", getName(), new Trade(newBalance, ess), null, null, null, newBalance, ess);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void updateMoneyCache(final BigDecimal value) {
|
2021-05-10 21:36:09 +02:00
|
|
|
if (ess.getSettings().isEcoDisabled() || !EconomyLayers.isLayerSelected() || super.getMoney().equals(value)) {
|
2015-04-15 06:06:16 +02:00
|
|
|
return;
|
|
|
|
}
|
2021-05-10 21:36:09 +02:00
|
|
|
try {
|
|
|
|
super.setMoney(value, false);
|
|
|
|
} catch (final MaxMoneyException ex) {
|
|
|
|
// We don't want to throw any errors here, just updating a cache
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setAfk(final boolean set) {
|
2020-03-13 03:08:11 +01:00
|
|
|
setAfk(set, AfkStatusChangeEvent.Cause.UNKNOWN);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-10-03 19:46:05 +02:00
|
|
|
public void setAfk(final boolean set, final AfkStatusChangeEvent.Cause cause) {
|
2020-03-13 03:08:11 +01:00
|
|
|
final AfkStatusChangeEvent afkEvent = new AfkStatusChangeEvent(this, set, cause);
|
2015-04-15 06:06:16 +02:00
|
|
|
ess.getServer().getPluginManager().callEvent(afkEvent);
|
|
|
|
if (afkEvent.isCancelled()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-07-11 07:28:08 +02:00
|
|
|
this.getBase().setSleepingIgnored(this.isAuthorized("essentials.sleepingignored") || (set && ess.getSettings().sleepIgnoresAfkPlayers()));
|
2015-04-15 06:06:16 +02:00
|
|
|
if (set && !isAfk()) {
|
|
|
|
afkPosition = this.getLocation();
|
2016-07-26 02:36:29 +02:00
|
|
|
this.afkSince = System.currentTimeMillis();
|
2015-04-15 06:06:16 +02:00
|
|
|
} else if (!set && isAfk()) {
|
|
|
|
afkPosition = null;
|
2016-06-18 18:44:17 +02:00
|
|
|
this.afkMessage = null;
|
2016-07-26 02:36:29 +02:00
|
|
|
this.afkSince = 0;
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
2016-08-06 18:45:54 +02:00
|
|
|
_setAfk(set);
|
|
|
|
updateAfkListName();
|
|
|
|
}
|
2020-03-13 03:08:11 +01:00
|
|
|
|
2016-08-06 18:45:54 +02:00
|
|
|
private void updateAfkListName() {
|
2016-01-20 15:15:53 +01:00
|
|
|
if (ess.getSettings().isAfkListName()) {
|
2020-10-03 19:46:05 +02:00
|
|
|
if (isAfk()) {
|
|
|
|
final String afkName = ess.getSettings().getAfkListName().replace("{PLAYER}", getDisplayName()).replace("{USERNAME}", getName());
|
2016-01-20 15:15:53 +01:00
|
|
|
getBase().setPlayerListName(afkName);
|
|
|
|
} else {
|
|
|
|
getBase().setPlayerListName(null);
|
2020-08-29 17:03:49 +02:00
|
|
|
setDisplayNick();
|
2016-01-20 15:15:53 +01:00
|
|
|
}
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
2020-03-13 03:08:11 +01:00
|
|
|
@Deprecated
|
2015-04-15 06:06:16 +02:00
|
|
|
public boolean toggleAfk() {
|
2020-03-13 03:08:11 +01:00
|
|
|
return toggleAfk(AfkStatusChangeEvent.Cause.UNKNOWN);
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
public boolean toggleAfk(final AfkStatusChangeEvent.Cause cause) {
|
2020-03-13 03:08:11 +01:00
|
|
|
setAfk(!isAfk(), cause);
|
2015-04-15 06:06:16 +02:00
|
|
|
return isAfk();
|
|
|
|
}
|
|
|
|
|
2020-11-09 13:25:16 +01:00
|
|
|
@Override
|
|
|
|
public boolean isHiddenFrom(Player player) {
|
|
|
|
return !player.canSee(getBase());
|
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
@Override
|
|
|
|
public boolean isHidden() {
|
|
|
|
return hidden;
|
|
|
|
}
|
|
|
|
|
2022-07-24 00:35:14 +02:00
|
|
|
@Override
|
|
|
|
public boolean isLeavingHidden() {
|
|
|
|
return leavingHidden;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setLeavingHidden(boolean leavingHidden) {
|
|
|
|
this.leavingHidden = leavingHidden;
|
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
@Override
|
|
|
|
public void setHidden(final boolean hidden) {
|
|
|
|
this.hidden = hidden;
|
2020-04-25 14:08:57 +02:00
|
|
|
if (hidden) {
|
2015-04-15 06:06:16 +02:00
|
|
|
setLastLogout(getLastOnlineActivity());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
public boolean isHidden(final Player player) {
|
|
|
|
return hidden || !player.canSee(getBase());
|
|
|
|
}
|
|
|
|
|
2021-01-23 23:41:24 +01:00
|
|
|
@Override
|
|
|
|
public String getFormattedJailTime() {
|
2021-02-16 14:56:57 +01:00
|
|
|
return DateUtil.formatDateDiff(getOnlineJailedTime() > 0 ? getOnlineJailExpireTime() : getJailTimeout());
|
|
|
|
}
|
|
|
|
|
|
|
|
private long getOnlineJailExpireTime() {
|
|
|
|
return ((getOnlineJailedTime() - getBase().getStatistic(PLAY_ONE_TICK)) * 50) + System.currentTimeMillis();
|
2021-01-23 23:41:24 +01:00
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
//Returns true if status expired during this check
|
|
|
|
public boolean checkJailTimeout(final long currentTime) {
|
2021-01-08 21:43:32 +01:00
|
|
|
if (getJailTimeout() > 0) {
|
2015-10-28 16:27:10 +01:00
|
|
|
|
2021-01-08 21:43:32 +01:00
|
|
|
if (getOnlineJailedTime() > 0) {
|
|
|
|
if (getOnlineJailedTime() > getBase().getStatistic(PLAY_ONE_TICK)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-10 21:36:09 +02:00
|
|
|
if (getJailTimeout() < currentTime && isJailed()) {
|
2021-01-08 21:43:32 +01:00
|
|
|
final JailStatusChangeEvent event = new JailStatusChangeEvent(this, null, false);
|
|
|
|
ess.getServer().getPluginManager().callEvent(event);
|
|
|
|
|
|
|
|
if (!event.isCancelled()) {
|
|
|
|
setJailTimeout(0);
|
|
|
|
setOnlineJailedTime(0);
|
|
|
|
setJailed(false);
|
|
|
|
sendMessage(tl("haveBeenReleased"));
|
|
|
|
setJail(null);
|
2021-06-09 03:04:30 +02:00
|
|
|
if (ess.getSettings().getTeleportWhenFreePolicy() == ISettings.TeleportWhenFreePolicy.BACK) {
|
2021-01-08 21:43:32 +01:00
|
|
|
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
|
|
|
getAsyncTeleport().back(future);
|
|
|
|
future.exceptionally(e -> {
|
|
|
|
getAsyncTeleport().respawn(null, TeleportCause.PLUGIN, new CompletableFuture<>());
|
|
|
|
return false;
|
|
|
|
});
|
2021-06-09 03:04:30 +02:00
|
|
|
} else if (ess.getSettings().getTeleportWhenFreePolicy() == ISettings.TeleportWhenFreePolicy.SPAWN) {
|
|
|
|
getAsyncTeleport().respawn(null, TeleportCause.PLUGIN, new CompletableFuture<>());
|
2021-01-08 21:43:32 +01:00
|
|
|
}
|
|
|
|
return true;
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//Returns true if status expired during this check
|
|
|
|
public boolean checkMuteTimeout(final long currentTime) {
|
|
|
|
if (getMuteTimeout() > 0 && getMuteTimeout() < currentTime && isMuted()) {
|
2020-04-23 17:28:08 +02:00
|
|
|
final MuteStatusChangeEvent event = new MuteStatusChangeEvent(this, null, false, getMuteTimeout(), getMuteReason());
|
2016-08-21 03:13:26 +02:00
|
|
|
ess.getServer().getPluginManager().callEvent(event);
|
2020-10-03 19:46:05 +02:00
|
|
|
|
2016-08-21 03:13:26 +02:00
|
|
|
if (!event.isCancelled()) {
|
|
|
|
setMuteTimeout(0);
|
|
|
|
sendMessage(tl("canTalkAgain"));
|
|
|
|
setMuted(false);
|
2017-12-27 01:09:46 +01:00
|
|
|
setMuteReason(null);
|
2016-08-21 03:13:26 +02:00
|
|
|
return true;
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-03-13 03:08:11 +01:00
|
|
|
@Deprecated
|
2015-04-15 06:06:16 +02:00
|
|
|
public void updateActivity(final boolean broadcast) {
|
2020-03-13 03:08:11 +01:00
|
|
|
updateActivity(broadcast, AfkStatusChangeEvent.Cause.UNKNOWN);
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
public void updateActivity(final boolean broadcast, final AfkStatusChangeEvent.Cause cause) {
|
2018-03-26 09:50:42 +02:00
|
|
|
if (isAfk()) {
|
2020-03-13 03:08:11 +01:00
|
|
|
setAfk(false, cause);
|
2021-02-21 14:54:02 +01:00
|
|
|
if (broadcast && !isHidden() && !isAfk()) {
|
2015-04-15 06:06:16 +02:00
|
|
|
setDisplayNick();
|
|
|
|
final String msg = tl("userIsNotAway", getDisplayName());
|
2020-04-14 12:56:17 +02:00
|
|
|
final String selfmsg = tl("userIsNotAwaySelf", getDisplayName());
|
2020-04-13 15:33:37 +02:00
|
|
|
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
|
|
|
|
// exclude user from receiving general AFK announcement in favor of personal message
|
|
|
|
ess.broadcastMessage(this, msg, u -> u == this);
|
|
|
|
}
|
|
|
|
if (!selfmsg.isEmpty()) {
|
|
|
|
this.sendMessage(selfmsg);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lastActivity = System.currentTimeMillis();
|
|
|
|
}
|
|
|
|
|
2018-03-26 09:50:42 +02:00
|
|
|
public void updateActivityOnMove(final boolean broadcast) {
|
2020-10-03 19:46:05 +02:00
|
|
|
if (ess.getSettings().cancelAfkOnMove()) {
|
2020-03-13 03:08:11 +01:00
|
|
|
updateActivity(broadcast, AfkStatusChangeEvent.Cause.MOVE);
|
2018-03-26 09:50:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updateActivityOnInteract(final boolean broadcast) {
|
2020-10-03 19:46:05 +02:00
|
|
|
if (ess.getSettings().cancelAfkOnInteract()) {
|
2020-03-13 03:08:11 +01:00
|
|
|
updateActivity(broadcast, AfkStatusChangeEvent.Cause.INTERACT);
|
2018-03-26 09:50:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-01 01:20:08 +01:00
|
|
|
public void updateActivityOnChat(final boolean broadcast) {
|
|
|
|
if (ess.getSettings().cancelAfkOnChat()) {
|
|
|
|
//Chat happens async, make sure we have a sync context
|
|
|
|
ess.scheduleSyncDelayedTask(() -> {
|
|
|
|
updateActivity(broadcast, AfkStatusChangeEvent.Cause.CHAT);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
public void checkActivity() {
|
2016-01-02 11:16:34 +01:00
|
|
|
// Graceful time before the first afk check call.
|
|
|
|
if (System.currentTimeMillis() - lastActivity <= 10000) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
final long autoafkkick = ess.getSettings().getAutoAfkKick();
|
2016-07-28 20:58:04 +02:00
|
|
|
if (autoafkkick > 0
|
2021-05-10 21:36:09 +02:00
|
|
|
&& lastActivity > 0 && (lastActivity + (autoafkkick * 1000)) < System.currentTimeMillis()
|
|
|
|
&& !isAuthorized("essentials.kick.exempt")
|
|
|
|
&& !isAuthorized("essentials.afk.kickexempt")) {
|
2015-04-15 06:06:16 +02:00
|
|
|
final String kickReason = tl("autoAfkKickReason", autoafkkick / 60.0);
|
|
|
|
lastActivity = 0;
|
|
|
|
this.getBase().kickPlayer(kickReason);
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
for (final User user : ess.getOnlineUsers()) {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (user.isAuthorized("essentials.kick.notify")) {
|
2020-12-11 17:29:48 +01:00
|
|
|
user.sendMessage(tl("playerKicked", Console.DISPLAY_NAME, getName(), kickReason));
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final long autoafk = ess.getSettings().getAutoAfk();
|
|
|
|
if (!isAfk() && autoafk > 0 && lastActivity + autoafk * 1000 < System.currentTimeMillis() && isAuthorized("essentials.afk.auto")) {
|
2020-03-13 03:08:11 +01:00
|
|
|
setAfk(true, AfkStatusChangeEvent.Cause.ACTIVITY);
|
2021-02-21 14:54:02 +01:00
|
|
|
if (isAfk() && !isHidden()) {
|
2015-04-15 06:06:16 +02:00
|
|
|
setDisplayNick();
|
|
|
|
final String msg = tl("userIsAway", getDisplayName());
|
2020-04-14 12:56:17 +02:00
|
|
|
final String selfmsg = tl("userIsAwaySelf", getDisplayName());
|
2020-04-13 15:33:37 +02:00
|
|
|
if (!msg.isEmpty() && ess.getSettings().broadcastAfkMessage()) {
|
|
|
|
// exclude user from receiving general AFK announcement in favor of personal message
|
|
|
|
ess.broadcastMessage(this, msg, u -> u == this);
|
|
|
|
}
|
|
|
|
if (!selfmsg.isEmpty()) {
|
|
|
|
this.sendMessage(selfmsg);
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public Location getAfkPosition() {
|
|
|
|
return afkPosition;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isGodModeEnabled() {
|
2016-07-12 01:03:08 +02:00
|
|
|
if (super.isGodModeEnabled()) {
|
|
|
|
// This enables the no-god-in-worlds functionality where the actual player god mode state is never modified in disabled worlds,
|
|
|
|
// but this method gets called every time the player takes damage. In the case that the world has god-mode disabled then this method
|
|
|
|
// will return false and the player will take damage, even though they are in god mode (isGodModeEnabledRaw()).
|
2016-07-12 01:46:08 +02:00
|
|
|
if (!ess.getSettings().getNoGodWorlds().contains(this.getLocation().getWorld().getName())) {
|
|
|
|
return true;
|
2016-07-12 01:03:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isAfk()) {
|
|
|
|
// Protect AFK players by representing them in a god mode state to render them invulnerable to damage.
|
2020-04-25 14:08:57 +02:00
|
|
|
return ess.getSettings().getFreezeAfkPlayers();
|
2016-07-12 01:03:08 +02:00
|
|
|
}
|
|
|
|
return false;
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isGodModeEnabledRaw() {
|
|
|
|
return super.isGodModeEnabled();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getGroup() {
|
|
|
|
final String result = ess.getPermissionsHandler().getGroup(base);
|
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
ess.getLogger().log(Level.INFO, "looking up groupname of " + base.getName() + " - " + result);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean inGroup(final String group) {
|
|
|
|
final boolean result = ess.getPermissionsHandler().inGroup(base, group);
|
|
|
|
if (ess.getSettings().isDebug()) {
|
|
|
|
ess.getLogger().log(Level.INFO, "checking if " + base.getName() + " is in group " + group + " - " + result);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean canBuild() {
|
|
|
|
if (this.getBase().isOp()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return ess.getPermissionsHandler().canBuild(base, getGroup());
|
|
|
|
}
|
|
|
|
|
2021-12-04 15:40:06 +01:00
|
|
|
@Override
|
|
|
|
@Deprecated
|
2015-04-15 06:06:16 +02:00
|
|
|
public long getTeleportRequestTime() {
|
2021-12-04 15:40:06 +01:00
|
|
|
final TpaRequest request = getNextTpaRequest(false, false, false);
|
|
|
|
return request == null ? 0L : request.getTime();
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isInvSee() {
|
|
|
|
return invSee;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setInvSee(final boolean set) {
|
|
|
|
invSee = set;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isEnderSee() {
|
|
|
|
return enderSee;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setEnderSee(final boolean set) {
|
|
|
|
enderSee = set;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void enableInvulnerabilityAfterTeleport() {
|
|
|
|
final long time = ess.getSettings().getTeleportInvulnerability();
|
|
|
|
if (time > 0) {
|
|
|
|
teleportInvulnerabilityTimestamp = System.currentTimeMillis() + time;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void resetInvulnerabilityAfterTeleport() {
|
|
|
|
if (teleportInvulnerabilityTimestamp != 0 && teleportInvulnerabilityTimestamp < System.currentTimeMillis()) {
|
|
|
|
teleportInvulnerabilityTimestamp = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean hasInvulnerabilityAfterTeleport() {
|
|
|
|
return teleportInvulnerabilityTimestamp != 0 && teleportInvulnerabilityTimestamp >= System.currentTimeMillis();
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean canInteractVanished() {
|
|
|
|
return isAuthorized("essentials.vanish.interact");
|
|
|
|
}
|
|
|
|
|
2015-07-29 03:45:33 +02:00
|
|
|
@Override
|
|
|
|
public boolean isIgnoreMsg() {
|
|
|
|
return ignoreMsg;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-10-03 19:46:05 +02:00
|
|
|
public void setIgnoreMsg(final boolean ignoreMsg) {
|
2015-07-29 03:45:33 +02:00
|
|
|
this.ignoreMsg = ignoreMsg;
|
|
|
|
}
|
|
|
|
|
2015-04-15 06:06:16 +02:00
|
|
|
@Override
|
|
|
|
public boolean isVanished() {
|
|
|
|
return vanished;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setVanished(final boolean set) {
|
|
|
|
vanished = set;
|
|
|
|
if (set) {
|
2020-10-03 19:46:05 +02:00
|
|
|
for (final User user : ess.getOnlineUsers()) {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (!user.isAuthorized("essentials.vanish.see")) {
|
|
|
|
user.getBase().hidePlayer(getBase());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setHidden(true);
|
2022-06-04 03:43:12 +02:00
|
|
|
lastVanishTime = System.currentTimeMillis();
|
2018-03-25 23:12:36 +02:00
|
|
|
ess.getVanishedPlayersNew().add(getName());
|
2021-11-24 15:57:55 +01:00
|
|
|
this.getBase().setMetadata("vanished", new FixedMetadataValue(ess, true));
|
2015-04-15 06:06:16 +02:00
|
|
|
if (isAuthorized("essentials.vanish.effect")) {
|
|
|
|
this.getBase().addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 1, false));
|
|
|
|
}
|
2021-06-06 23:05:16 +02:00
|
|
|
if (ess.getSettings().sleepIgnoresVanishedPlayers()) {
|
|
|
|
getBase().setSleepingIgnored(true);
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
} else {
|
2020-10-03 19:46:05 +02:00
|
|
|
for (final Player p : ess.getOnlinePlayers()) {
|
2015-04-15 06:06:16 +02:00
|
|
|
p.showPlayer(getBase());
|
|
|
|
}
|
|
|
|
setHidden(false);
|
2018-03-25 23:12:36 +02:00
|
|
|
ess.getVanishedPlayersNew().remove(getName());
|
2021-11-24 15:57:55 +01:00
|
|
|
this.getBase().setMetadata("vanished", new FixedMetadataValue(ess, false));
|
2015-04-15 06:06:16 +02:00
|
|
|
if (isAuthorized("essentials.vanish.effect")) {
|
|
|
|
this.getBase().removePotionEffect(PotionEffectType.INVISIBILITY);
|
|
|
|
}
|
2021-06-07 01:12:07 +02:00
|
|
|
if (ess.getSettings().sleepIgnoresVanishedPlayers() && !isAuthorized("essentials.sleepingignored")) {
|
2021-06-06 23:05:16 +02:00
|
|
|
getBase().setSleepingIgnored(false);
|
|
|
|
}
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean checkSignThrottle() {
|
|
|
|
if (isSignThrottled()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
updateThrottle();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isSignThrottled() {
|
|
|
|
final long minTime = lastThrottledAction + (1000 / ess.getSettings().getSignUsePerSecond());
|
2020-10-03 19:46:05 +02:00
|
|
|
return System.currentTimeMillis() < minTime;
|
2015-04-15 06:06:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void updateThrottle() {
|
|
|
|
lastThrottledAction = System.currentTimeMillis();
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isFlyClickJump() {
|
|
|
|
return rightClickJump;
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
public void setRightClickJump(final boolean rightClickJump) {
|
2015-04-15 06:06:16 +02:00
|
|
|
this.rightClickJump = rightClickJump;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isIgnoreExempt() {
|
|
|
|
return this.isAuthorized("essentials.chat.ignoreexempt");
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isRecipeSee() {
|
|
|
|
return recipeSee;
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
public void setRecipeSee(final boolean recipeSee) {
|
2015-04-15 06:06:16 +02:00
|
|
|
this.recipeSee = recipeSee;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-10-03 19:46:05 +02:00
|
|
|
public void sendMessage(final String message) {
|
2015-04-15 06:06:16 +02:00
|
|
|
if (!message.isEmpty()) {
|
|
|
|
base.sendMessage(message);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int compareTo(final User other) {
|
|
|
|
return FormatUtil.stripFormat(getDisplayName()).compareToIgnoreCase(FormatUtil.stripFormat(other.getDisplayName()));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(final Object object) {
|
|
|
|
if (!(object instanceof User)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return this.getName().equalsIgnoreCase(((User) object).getName());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
return this.getName().hashCode();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public CommandSource getSource() {
|
|
|
|
return new CommandSource(getBase());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getName() {
|
|
|
|
return this.getBase().getName();
|
|
|
|
}
|
2020-10-03 19:46:05 +02:00
|
|
|
|
2021-07-01 17:23:32 +02:00
|
|
|
@Override
|
|
|
|
public UUID getUUID() {
|
2021-12-04 15:40:06 +01:00
|
|
|
return this.getBase().getUniqueId();
|
2021-07-01 17:23:32 +02:00
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
@Override
|
|
|
|
public boolean isReachable() {
|
2015-10-30 20:58:30 +01:00
|
|
|
return getBase().isOnline();
|
|
|
|
}
|
2015-10-27 18:34:59 +01:00
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
@Override
|
|
|
|
public MessageResponse sendMessage(final IMessageRecipient recipient, final String message) {
|
2015-10-27 18:34:59 +01:00
|
|
|
return this.messageRecipient.sendMessage(recipient, message);
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
@Override
|
|
|
|
public MessageResponse onReceiveMessage(final IMessageRecipient sender, final String message) {
|
2015-10-27 18:34:59 +01:00
|
|
|
return this.messageRecipient.onReceiveMessage(sender, message);
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
@Override
|
|
|
|
public IMessageRecipient getReplyRecipient() {
|
2015-10-27 18:34:59 +01:00
|
|
|
return this.messageRecipient.getReplyRecipient();
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
@Override
|
|
|
|
public void setReplyRecipient(final IMessageRecipient recipient) {
|
2015-10-27 18:34:59 +01:00
|
|
|
this.messageRecipient.setReplyRecipient(recipient);
|
|
|
|
}
|
2016-06-18 18:44:17 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String getAfkMessage() {
|
|
|
|
return this.afkMessage;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2020-10-03 19:46:05 +02:00
|
|
|
public void setAfkMessage(final String message) {
|
2016-06-18 18:44:17 +02:00
|
|
|
if (isAfk()) {
|
|
|
|
this.afkMessage = message;
|
|
|
|
}
|
|
|
|
}
|
2016-07-23 00:56:26 +02:00
|
|
|
|
2016-07-26 02:36:29 +02:00
|
|
|
@Override
|
|
|
|
public long getAfkSince() {
|
|
|
|
return afkSince;
|
|
|
|
}
|
|
|
|
|
2016-12-18 16:03:03 +01:00
|
|
|
@Override
|
|
|
|
public Map<User, BigDecimal> getConfirmingPayments() {
|
|
|
|
return confirmingPayments;
|
|
|
|
}
|
|
|
|
|
2017-11-12 17:44:53 +01:00
|
|
|
public String getConfirmingClearCommand() {
|
|
|
|
return confirmingClearCommand;
|
|
|
|
}
|
2020-10-03 19:46:05 +02:00
|
|
|
|
|
|
|
public void setConfirmingClearCommand(final String command) {
|
2017-11-12 17:44:53 +01:00
|
|
|
this.confirmingClearCommand = command;
|
|
|
|
}
|
|
|
|
|
2016-07-23 00:56:26 +02:00
|
|
|
/**
|
|
|
|
* Returns the {@link ItemStack} in the main hand or off-hand. If the main hand is empty then the offhand item is returned - also nullable.
|
|
|
|
*/
|
|
|
|
public ItemStack getItemInHand() {
|
2019-01-03 21:32:35 +01:00
|
|
|
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_9_R01)) {
|
2016-07-23 00:56:26 +02:00
|
|
|
return getBase().getInventory().getItemInHand();
|
|
|
|
} else {
|
2020-10-03 19:46:05 +02:00
|
|
|
final PlayerInventory inventory = getBase().getInventory();
|
2016-07-23 00:56:26 +02:00
|
|
|
return inventory.getItemInMainHand() != null ? inventory.getItemInMainHand() : inventory.getItemInOffHand();
|
|
|
|
}
|
|
|
|
}
|
2020-10-03 19:46:05 +02:00
|
|
|
|
2021-07-01 17:23:32 +02:00
|
|
|
@Override
|
|
|
|
public void sendMail(MailSender sender, String message) {
|
|
|
|
sendMail(sender, message, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void sendMail(MailSender sender, String message, long expireAt) {
|
|
|
|
ess.getMail().sendMail(this, sender, message, expireAt);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@Deprecated
|
|
|
|
public void addMail(String mail) {
|
|
|
|
ess.getMail().sendLegacyMail(this, mail);
|
|
|
|
}
|
|
|
|
|
2017-06-22 23:54:51 +02:00
|
|
|
public void notifyOfMail() {
|
2021-07-01 17:23:32 +02:00
|
|
|
final int unread = getUnreadMailAmount();
|
|
|
|
if (unread != 0) {
|
2020-10-03 19:46:05 +02:00
|
|
|
final int notifyPlayerOfMailCooldown = ess.getSettings().getNotifyPlayerOfMailCooldown() * 1000;
|
2017-06-22 23:54:51 +02:00
|
|
|
if (System.currentTimeMillis() - lastNotifiedAboutMailsMs >= notifyPlayerOfMailCooldown) {
|
2021-07-01 17:23:32 +02:00
|
|
|
sendMessage(tl("youHaveNewMail", unread));
|
2017-06-22 23:54:51 +02:00
|
|
|
lastNotifiedAboutMailsMs = System.currentTimeMillis();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-07-01 23:03:22 +02:00
|
|
|
|
|
|
|
public String getLastHomeConfirmation() {
|
|
|
|
return lastHomeConfirmation;
|
|
|
|
}
|
|
|
|
|
2020-10-03 19:46:05 +02:00
|
|
|
public void setLastHomeConfirmation(final String lastHomeConfirmation) {
|
2020-07-01 23:03:22 +02:00
|
|
|
this.lastHomeConfirmation = lastHomeConfirmation;
|
|
|
|
}
|
|
|
|
|
|
|
|
public long getLastHomeConfirmationTimestamp() {
|
|
|
|
return lastHomeConfirmationTimestamp;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setLastHomeConfirmationTimestamp() {
|
|
|
|
this.lastHomeConfirmationTimestamp = System.currentTimeMillis();
|
|
|
|
}
|
2020-11-09 17:38:02 +01:00
|
|
|
|
2021-02-19 16:13:49 +01:00
|
|
|
public List<String> getSignCopy() {
|
|
|
|
return signCopy;
|
|
|
|
}
|
|
|
|
|
2021-02-15 16:43:10 +01:00
|
|
|
public boolean isBaltopExempt() {
|
|
|
|
if (getBase().isOnline()) {
|
|
|
|
final boolean exempt = isAuthorized("essentials.balancetop.exclude");
|
|
|
|
setBaltopExemptCache(exempt);
|
|
|
|
return exempt;
|
|
|
|
}
|
|
|
|
return isBaltopExcludeCache();
|
|
|
|
}
|
|
|
|
|
2022-06-04 03:43:12 +02:00
|
|
|
public long getLastVanishTime() {
|
|
|
|
return lastVanishTime;
|
|
|
|
}
|
|
|
|
|
2020-11-09 17:38:02 +01:00
|
|
|
@Override
|
|
|
|
public Block getTargetBlock(int maxDistance) {
|
|
|
|
final Block block;
|
|
|
|
if (VersionUtil.getServerBukkitVersion().isLowerThan(VersionUtil.v1_13_2_R01) || (block = base.getTargetBlockExact(maxDistance)) == null) {
|
|
|
|
return base.getTargetBlock(null, maxDistance);
|
|
|
|
}
|
|
|
|
return block;
|
|
|
|
}
|
2021-02-20 17:37:16 +01:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setToggleShout(boolean toggleShout) {
|
|
|
|
this.toggleShout = toggleShout;
|
2021-09-29 02:31:44 +02:00
|
|
|
if (ess.getSettings().isPersistShout()) {
|
|
|
|
setShouting(toggleShout);
|
|
|
|
}
|
2021-02-20 17:37:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isToggleShout() {
|
2021-09-29 02:31:44 +02:00
|
|
|
if (ess.getSettings().isPersistShout()) {
|
|
|
|
return toggleShout = isShouting();
|
|
|
|
}
|
|
|
|
return toggleShout == null ? toggleShout = ess.getSettings().isShoutDefault() : toggleShout;
|
2021-02-20 17:37:16 +01:00
|
|
|
}
|
2011-07-08 13:29:06 +02:00
|
|
|
}
|