From 026d279556a8605f2fcf3acc7b944fe4a2aed410 Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Fri, 8 Jan 2021 15:43:32 -0500 Subject: [PATCH] Add option to only count online jailed time (#3705) Adds `jail-online-time` config option to only count a player's online time to the jail cap. This also fixes memory leak in `EssentialsTimer` which I found in the process of testing. Closes #429. --- .../earth2me/essentials/EssentialsTimer.java | 1 + .../com/earth2me/essentials/ISettings.java | 2 + .../com/earth2me/essentials/Settings.java | 5 +++ .../java/com/earth2me/essentials/User.java | 45 ++++++++++++------- .../com/earth2me/essentials/UserData.java | 17 +++++++ .../commands/Commandtogglejail.java | 13 ++++-- .../earth2me/essentials/utils/DateUtil.java | 11 ++++- Essentials/src/main/resources/config.yml | 4 ++ 8 files changed, 78 insertions(+), 20 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/EssentialsTimer.java b/Essentials/src/main/java/com/earth2me/essentials/EssentialsTimer.java index ef311aa81..fbc96e1d2 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/EssentialsTimer.java +++ b/Essentials/src/main/java/com/earth2me/essentials/EssentialsTimer.java @@ -44,6 +44,7 @@ public class EssentialsTimer implements Runnable { } lastPoll = startTime; int count = 0; + onlineUsers.clear(); for (final Player player : ess.getOnlinePlayers()) { count++; if (skip1 > 0) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java index 47d11b58e..549dcce25 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/ISettings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/ISettings.java @@ -355,6 +355,8 @@ public interface ISettings extends IConf { boolean isTeleportBackWhenFreedFromJail(); + boolean isJailOnlineTime(); + boolean isCompassTowardsHomePerm(); boolean isAllowWorldInBroadcastworld(); diff --git a/Essentials/src/main/java/com/earth2me/essentials/Settings.java b/Essentials/src/main/java/com/earth2me/essentials/Settings.java index e15185352..0267ead15 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/Settings.java +++ b/Essentials/src/main/java/com/earth2me/essentials/Settings.java @@ -1610,6 +1610,11 @@ public class Settings implements net.ess3.api.ISettings { return teleportBackWhenFreedFromJail; } + @Override + public boolean isJailOnlineTime() { + return config.getBoolean("jail-online-time", false); + } + private boolean _isCompassTowardsHomePerm() { return config.getBoolean("compass-towards-home-perm", false); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/User.java b/Essentials/src/main/java/com/earth2me/essentials/User.java index 905f4a420..69d58f9d2 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/User.java +++ b/Essentials/src/main/java/com/earth2me/essentials/User.java @@ -6,6 +6,7 @@ import com.earth2me.essentials.messaging.SimpleMessageRecipient; import com.earth2me.essentials.register.payment.Method; import com.earth2me.essentials.register.payment.Methods; import com.earth2me.essentials.utils.DateUtil; +import com.earth2me.essentials.utils.EnumUtil; import com.earth2me.essentials.utils.FormatUtil; import com.earth2me.essentials.utils.NumberUtil; import com.earth2me.essentials.utils.VersionUtil; @@ -18,6 +19,7 @@ import net.ess3.api.events.UserBalanceUpdateEvent; import net.essentialsx.api.v2.events.TransactionEvent; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.Statistic; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; @@ -41,6 +43,7 @@ import java.util.logging.Logger; import static com.earth2me.essentials.I18n.tl; public class User extends UserData implements Comparable, IMessageRecipient, net.ess3.api.IUser { + private static final Statistic PLAY_ONE_TICK = EnumUtil.getStatistic("PLAY_ONE_MINUTE", "PLAY_ONE_TICK"); private static final Logger logger = Logger.getLogger("Essentials"); private final IMessageRecipient messageRecipient; private transient final AsyncTeleport teleport; @@ -595,24 +598,34 @@ public class User extends UserData implements Comparable, IMessageRecipien //Returns true if status expired during this check public boolean checkJailTimeout(final long currentTime) { - if (getJailTimeout() > 0 && getJailTimeout() < currentTime && isJailed()) { - final JailStatusChangeEvent event = new JailStatusChangeEvent(this, null, false); - ess.getServer().getPluginManager().callEvent(event); + if (getJailTimeout() > 0) { - if (!event.isCancelled()) { - setJailTimeout(0); - setJailed(false); - sendMessage(tl("haveBeenReleased")); - setJail(null); - if (ess.getSettings().isTeleportBackWhenFreedFromJail()) { - final CompletableFuture future = new CompletableFuture<>(); - getAsyncTeleport().back(future); - future.exceptionally(e -> { - getAsyncTeleport().respawn(null, TeleportCause.PLUGIN, new CompletableFuture<>()); - return false; - }); + if (getOnlineJailedTime() > 0) { + if (getOnlineJailedTime() > getBase().getStatistic(PLAY_ONE_TICK)) { + return false; + } + } + + if (getJailTimeout() < currentTime && isJailed() ) { + 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); + if (ess.getSettings().isTeleportBackWhenFreedFromJail()) { + final CompletableFuture future = new CompletableFuture<>(); + getAsyncTeleport().back(future); + future.exceptionally(e -> { + getAsyncTeleport().respawn(null, TeleportCause.PLUGIN, new CompletableFuture<>()); + return false; + }); + } + return true; } - return true; } } return false; diff --git a/Essentials/src/main/java/com/earth2me/essentials/UserData.java b/Essentials/src/main/java/com/earth2me/essentials/UserData.java index 0e04a7768..d2732fdd6 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/UserData.java +++ b/Essentials/src/main/java/com/earth2me/essentials/UserData.java @@ -122,6 +122,7 @@ public abstract class UserData extends PlayerExtension implements IConf { muteReason = _getMuteReason(); jailed = _getJailed(); jailTimeout = _getJailTimeout(); + onlineJailed = _getOnlineJailedTime(); lastLogin = _getLastLogin(); lastLogout = _getLastLogout(); lastLoginAddress = _getLastLoginAddress(); @@ -660,6 +661,22 @@ public abstract class UserData extends PlayerExtension implements IConf { config.save(); } + private long onlineJailed; + + private long _getOnlineJailedTime() { + return config.getLong("timestamps.onlinejail", 0); + } + + public long getOnlineJailedTime() { + return onlineJailed; + } + + public void setOnlineJailedTime(long onlineJailed) { + this.onlineJailed = onlineJailed; + config.setProperty("timestamps.onlinejail", onlineJailed); + config.save(); + } + private long _getLastLogin() { return config.getLong("timestamps.login", 0); } diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtogglejail.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtogglejail.java index 576963259..25b43ea88 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtogglejail.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandtogglejail.java @@ -3,8 +3,10 @@ package com.earth2me.essentials.commands; import com.earth2me.essentials.CommandSource; import com.earth2me.essentials.User; import com.earth2me.essentials.utils.DateUtil; +import com.earth2me.essentials.utils.EnumUtil; import net.ess3.api.events.JailStatusChangeEvent; import org.bukkit.Server; +import org.bukkit.Statistic; import org.bukkit.event.player.PlayerTeleportEvent; import java.util.ArrayList; @@ -15,6 +17,8 @@ import java.util.concurrent.CompletableFuture; import static com.earth2me.essentials.I18n.tl; public class Commandtogglejail extends EssentialsCommand { + private static final Statistic PLAY_ONE_TICK = EnumUtil.getStatistic("PLAY_ONE_MINUTE", "PLAY_ONE_TICK"); + public Commandtogglejail() { super("togglejail"); } @@ -44,13 +48,15 @@ public class Commandtogglejail extends EssentialsCommand { ess.getServer().getPluginManager().callEvent(event); if (!event.isCancelled()) { + long displayTime = 0; long preTimeDiff = 0; if (args.length > 2) { final String time = getFinalArg(args, 2); - preTimeDiff = DateUtil.parseDateDiff(time, true); - + displayTime = DateUtil.parseDateDiff(time, true); + preTimeDiff = DateUtil.parseDateDiff(time, true, ess.getSettings().isJailOnlineTime()); } final long timeDiff = preTimeDiff; + final long finalDisplayTime = displayTime; final CompletableFuture future = getNewExceptionFuture(sender, commandLabel); future.thenAccept(success -> { if (success) { @@ -60,8 +66,9 @@ public class Commandtogglejail extends EssentialsCommand { player.setJail(args[1]); if (args.length > 2) { player.setJailTimeout(timeDiff); + player.setOnlineJailedTime(ess.getSettings().isJailOnlineTime() ? ((player.getBase().getStatistic(PLAY_ONE_TICK)) + (timeDiff / 50)) : 0); } - sender.sendMessage(timeDiff > 0 ? tl("playerJailedFor", player.getName(), DateUtil.formatDateDiff(timeDiff)) : tl("playerJailed", player.getName())); + sender.sendMessage(timeDiff > 0 ? tl("playerJailedFor", player.getName(), DateUtil.formatDateDiff(finalDisplayTime)) : tl("playerJailed", player.getName())); } }); if (player.getBase().isOnline()) { diff --git a/Essentials/src/main/java/com/earth2me/essentials/utils/DateUtil.java b/Essentials/src/main/java/com/earth2me/essentials/utils/DateUtil.java index becdf0178..59f15c1bc 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/utils/DateUtil.java +++ b/Essentials/src/main/java/com/earth2me/essentials/utils/DateUtil.java @@ -18,7 +18,11 @@ public final class DateUtil { return timePattern.matcher(input).replaceFirst("").trim(); } - public static long parseDateDiff(final String time, final boolean future) throws Exception { + public static long parseDateDiff(String time, boolean future) throws Exception { + return parseDateDiff(time, future, false); + } + + public static long parseDateDiff(String time, boolean future, boolean emptyEpoch) throws Exception { final Matcher m = timePattern.matcher(time); int years = 0; int months = 0; @@ -67,6 +71,11 @@ public final class DateUtil { throw new Exception(tl("illegalDate")); } final Calendar c = new GregorianCalendar(); + + if (emptyEpoch) { + c.setTimeInMillis(0); + } + if (years > 0) { if (years > maxYears) { years = maxYears; diff --git a/Essentials/src/main/resources/config.yml b/Essentials/src/main/resources/config.yml index 1a256932e..8947f0890 100644 --- a/Essentials/src/main/resources/config.yml +++ b/Essentials/src/main/resources/config.yml @@ -628,6 +628,10 @@ default-enabled-confirm-commands: # Whether or not to teleport a player back to their previous position after they have been freed from jail. teleport-back-when-freed-from-jail: true +# Whether or not jail time should only be counted while the user is online. +# If true, a jailed player's time will only decrement when they are online. +jail-online-time: false + # Set the timeout, in seconds for players to accept a tpa before the request is cancelled. # Set to 0 for no timeout. tpa-accept-cancellation: 120