Make use of Instant / Duration classes where possible for time handling

This commit is contained in:
Luck 2019-12-24 23:10:26 +00:00
parent 6e64f80c81
commit 96c53091d0
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
38 changed files with 311 additions and 340 deletions

View File

@ -40,6 +40,7 @@ import net.luckperms.api.node.types.WeightNode;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.Optional;
@ -162,8 +163,8 @@ public interface Node {
/**
* Gets the time when this node will expire.
*
* @return the {@link Instant} when this node will expire, or null if it
* doesn't have an expiry time
* @return the {@link Instant} when this node will expire, or
* {@code null} if it doesn't have an expiry time
*/
@Nullable Instant getExpiry();
@ -176,6 +177,17 @@ public interface Node {
*/
boolean hasExpired();
/**
* Gets the time until this node will expire.
*
* <p>Returns {@code null} if the node doesn't have an expiry time,
* and a {@link Duration#isNegative() negative} duration if it has already expired.</p>
*
* @return the duration until the nodes expiry
* @since 5.1
*/
@Nullable Duration getExpiryDuration();
/**
* Gets the contexts required for this node to apply.
*

View File

@ -32,6 +32,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAmount;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@ -85,7 +86,20 @@ public interface NodeBuilder<N extends ScopedNode<N, B>, B extends NodeBuilder<N
/**
* Sets the time when the node should expire.
*
* <p>The expiry timestamp is calculated relative to the current
* <p>The expiry time is calculated relative to the current
* system time.</p>
*
* @param duration how long the node should be added for
* @return the builder
* @see Node#getExpiry()
* @since 5.1
*/
@NonNull B expiry(@Nullable TemporalAmount duration);
/**
* Sets the time when the node should expire.
*
* <p>The expiry time is calculated relative to the current
* system time.</p>
*
* @param duration how long the node should be added for

View File

@ -42,6 +42,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.io.InputStream;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
@ -81,7 +82,7 @@ public class LPBukkitBootstrap extends JavaPlugin implements LuckPermsBootstrap
/**
* The time when the plugin was enabled
*/
private long startTime;
private Instant startTime;
// load/enable latches
private final CountDownLatch loadLatch = new CountDownLatch(1);
@ -149,7 +150,7 @@ public class LPBukkitBootstrap extends JavaPlugin implements LuckPermsBootstrap
return;
}
this.startTime = System.currentTimeMillis();
this.startTime = Instant.now();
try {
this.plugin.enable();
@ -192,7 +193,7 @@ public class LPBukkitBootstrap extends JavaPlugin implements LuckPermsBootstrap
}
@Override
public long getStartupTime() {
public Instant getStartupTime() {
return this.startTime;
}

View File

@ -39,6 +39,7 @@ import net.md_5.bungee.api.plugin.Plugin;
import java.io.InputStream;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
@ -72,7 +73,7 @@ public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap {
/**
* The time when the plugin was enabled
*/
private long startTime;
private Instant startTime;
// load/enable latches
private final CountDownLatch loadLatch = new CountDownLatch(1);
@ -119,7 +120,7 @@ public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap {
@Override
public void onEnable() {
this.startTime = System.currentTimeMillis();
this.startTime = Instant.now();
try {
this.plugin.enable();
} finally {
@ -150,7 +151,7 @@ public class LPBungeeBootstrap extends Plugin implements LuckPermsBootstrap {
}
@Override
public long getStartupTime() {
public Instant getStartupTime() {
return this.startTime;
}

View File

@ -42,6 +42,7 @@ import net.luckperms.api.context.DefaultContextKeys;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Comparator;
@ -92,6 +93,10 @@ public class LoggedAction implements Action {
return Instant.ofEpochSecond(this.timestamp);
}
public Duration getDurationSince() {
return Duration.between(getTimestamp(), Instant.now());
}
@Override
public @NonNull Source getSource() {
return this.source;

View File

@ -72,6 +72,6 @@ public class ApiPlatform implements Platform, PluginMetadata {
@Override
public @NonNull Instant getStartTime() {
return Instant.ofEpochMilli(this.plugin.getBootstrap().getStartupTime());
return this.plugin.getBootstrap().getStartupTime();
}
}

View File

@ -32,13 +32,16 @@ import me.lucko.luckperms.common.context.contextset.MutableContextSetImpl;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.storage.misc.DataConstraints;
import me.lucko.luckperms.common.util.DateParser;
import me.lucko.luckperms.common.util.DurationParser;
import net.luckperms.api.context.DefaultContextKeys;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.context.MutableContextSet;
import net.luckperms.api.model.data.TemporaryNodeMergeStrategy;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
@ -100,29 +103,29 @@ public class ArgumentParser {
return true;
}
public static long parseDuration(int index, List<String> args) throws ArgumentException {
long duration;
public static Duration parseDuration(int index, List<String> args) throws ArgumentException {
String input = args.get(index);
Duration duration;
try {
duration = Long.parseLong(args.get(index));
long number = Long.parseLong(input);
Instant now = Instant.now().truncatedTo(ChronoUnit.SECONDS);
duration = Duration.between(now, Instant.ofEpochSecond(number));
} catch (NumberFormatException e) {
try {
duration = DateParser.parseDate(args.get(index), true);
duration = DurationParser.parseDuration(input);
} catch (IllegalArgumentException e1) {
throw new InvalidDateException(args.get(index));
throw new InvalidDateException(input);
}
}
if (shouldExpire(duration)) {
if (duration.isNegative()) {
throw new PastDateException();
}
return duration;
}
private static boolean shouldExpire(long unixTime) {
return unixTime < (System.currentTimeMillis() / 1000L);
}
public static TemporaryNodeMergeStrategy parseTemporaryModifier(String s) {
switch (s.toLowerCase()) {
case "accumulate":

View File

@ -55,6 +55,7 @@ import net.luckperms.api.model.data.DataType;
import net.luckperms.api.model.data.TemporaryNodeMergeStrategy;
import net.luckperms.api.node.ChatMetaType;
import java.time.Duration;
import java.util.List;
public class MetaAddTempChatMeta extends SharedSubCommand {
@ -80,7 +81,7 @@ public class MetaAddTempChatMeta extends SharedSubCommand {
int priority = ArgumentParser.parsePriority(0, args);
String meta = ArgumentParser.parseString(1, args);
long duration = ArgumentParser.parseDuration(2, args);
Duration duration = ArgumentParser.parseDuration(2, args);
TemporaryNodeMergeStrategy modifier = ArgumentParser.parseTemporaryModifier(3, args).orElseGet(() -> plugin.getConfiguration().get(ConfigKeys.TEMPORARY_ADD_BEHAVIOUR));
MutableContextSet context = ArgumentParser.parseContext(3, args, plugin);
@ -93,9 +94,9 @@ public class MetaAddTempChatMeta extends SharedSubCommand {
DataMutateResult.WithMergedNode ret = holder.setNode(DataType.NORMAL, this.type.builder(meta, priority).expiry(duration).withContext(context).build(), modifier);
if (ret.getResult().wasSuccessful()) {
duration = ret.getMergedNode().getExpiry().getEpochSecond();
duration = ret.getMergedNode().getExpiryDuration();
TextComponent.Builder builder = Message.ADD_TEMP_CHATMETA_SUCCESS.asComponent(plugin.getLocaleManager(), holder.getFormattedDisplayName(), this.type.name().toLowerCase(), meta, priority, DurationFormatter.LONG.formatDateDiff(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context)).toBuilder();
TextComponent.Builder builder = Message.ADD_TEMP_CHATMETA_SUCCESS.asComponent(plugin.getLocaleManager(), holder.getFormattedDisplayName(), this.type.name().toLowerCase(), meta, priority, DurationFormatter.LONG.format(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context)).toBuilder();
HoverEvent event = HoverEvent.showText(TextUtils.fromLegacy(
"¥3Raw " + this.type.name().toLowerCase() + ": ¥r" + meta,
'¥'

View File

@ -57,6 +57,7 @@ import net.luckperms.api.node.Node;
import net.luckperms.api.node.NodeEqualityPredicate;
import net.luckperms.api.node.NodeType;
import java.time.Duration;
import java.util.List;
public class MetaSetTemp extends SharedSubCommand {
@ -73,7 +74,7 @@ public class MetaSetTemp extends SharedSubCommand {
String key = args.get(0);
String value = args.get(1);
long duration = ArgumentParser.parseDuration(2, args);
Duration duration = ArgumentParser.parseDuration(2, args);
TemporaryNodeMergeStrategy modifier = ArgumentParser.parseTemporaryModifier(3, args).orElseGet(() -> plugin.getConfiguration().get(ConfigKeys.TEMPORARY_ADD_BEHAVIOUR));
MutableContextSet context = ArgumentParser.parseContext(3, args, plugin);
@ -92,9 +93,9 @@ public class MetaSetTemp extends SharedSubCommand {
}
holder.removeIf(DataType.NORMAL, context, NodeType.META.predicate(n -> n.hasExpiry() && n.getMetaKey().equalsIgnoreCase(key)), false);
duration = holder.setNode(DataType.NORMAL, node, modifier).getMergedNode().getExpiry().getEpochSecond();
duration = holder.setNode(DataType.NORMAL, node, modifier).getMergedNode().getExpiryDuration();
TextComponent.Builder builder = Message.SET_META_TEMP_SUCCESS.asComponent(plugin.getLocaleManager(), key, value, holder.getFormattedDisplayName(), DurationFormatter.LONG.formatDateDiff(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context)).toBuilder();
TextComponent.Builder builder = Message.SET_META_TEMP_SUCCESS.asComponent(plugin.getLocaleManager(), key, value, holder.getFormattedDisplayName(), DurationFormatter.LONG.format(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context)).toBuilder();
HoverEvent event = HoverEvent.showText(TextUtils.fromLegacy(
TextUtils.joinNewline("¥3Raw key: ¥r" + key, "¥3Raw value: ¥r" + value),
'¥'

View File

@ -58,6 +58,7 @@ import net.luckperms.api.model.data.TemporaryNodeMergeStrategy;
import net.luckperms.api.node.ChatMetaType;
import net.luckperms.api.query.QueryOptions;
import java.time.Duration;
import java.util.List;
import java.util.OptionalInt;
@ -84,7 +85,7 @@ public class MetaSetTempChatMeta extends SharedSubCommand {
int priority = ArgumentParser.parseIntOrElse(0, args, Integer.MIN_VALUE);
String meta;
long duration;
Duration duration;
TemporaryNodeMergeStrategy modifier;
MutableContextSet context;
@ -133,9 +134,9 @@ public class MetaSetTempChatMeta extends SharedSubCommand {
DataMutateResult.WithMergedNode ret = holder.setNode(DataType.NORMAL, this.type.builder(meta, priority).expiry(duration).withContext(context).build(), modifier);
if (ret.getResult().wasSuccessful()) {
duration = ret.getMergedNode().getExpiry().getEpochSecond();
duration = ret.getMergedNode().getExpiryDuration();
TextComponent.Builder builder = Message.ADD_TEMP_CHATMETA_SUCCESS.asComponent(plugin.getLocaleManager(), holder.getFormattedDisplayName(), this.type.name().toLowerCase(), meta, priority, DurationFormatter.LONG.formatDateDiff(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context)).toBuilder();
TextComponent.Builder builder = Message.ADD_TEMP_CHATMETA_SUCCESS.asComponent(plugin.getLocaleManager(), holder.getFormattedDisplayName(), this.type.name().toLowerCase(), meta, priority, DurationFormatter.LONG.format(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context)).toBuilder();
HoverEvent event = HoverEvent.showText(TextUtils.fromLegacy(
"¥3Raw " + this.type.name().toLowerCase() + ": ¥r" + meta,
'¥'

View File

@ -53,6 +53,7 @@ import net.luckperms.api.model.data.DataMutateResult;
import net.luckperms.api.model.data.DataType;
import net.luckperms.api.model.data.TemporaryNodeMergeStrategy;
import java.time.Duration;
import java.util.List;
public class ParentAddTemp extends SharedSubCommand {
@ -68,7 +69,7 @@ public class ParentAddTemp extends SharedSubCommand {
}
String groupName = ArgumentParser.parseName(0, args);
long duration = ArgumentParser.parseDuration(1, args);
Duration duration = ArgumentParser.parseDuration(1, args);
TemporaryNodeMergeStrategy modifier = ArgumentParser.parseTemporaryModifier(2, args).orElseGet(() -> plugin.getConfiguration().get(ConfigKeys.TEMPORARY_ADD_BEHAVIOUR));
MutableContextSet context = ArgumentParser.parseContext(2, args, plugin);
@ -93,8 +94,8 @@ public class ParentAddTemp extends SharedSubCommand {
DataMutateResult.WithMergedNode ret = holder.setNode(DataType.NORMAL, Inheritance.builder(group.getName()).expiry(duration).withContext(context).build(), modifier);
if (ret.getResult().wasSuccessful()) {
duration = ret.getMergedNode().getExpiry().getEpochSecond();
Message.SET_TEMP_INHERIT_SUCCESS.send(sender, holder.getFormattedDisplayName(), group.getFormattedDisplayName(), DurationFormatter.LONG.formatDateDiff(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context));
duration = ret.getMergedNode().getExpiryDuration();
Message.SET_TEMP_INHERIT_SUCCESS.send(sender, holder.getFormattedDisplayName(), group.getFormattedDisplayName(), DurationFormatter.LONG.format(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context));
LoggedAction.build().source(sender).target(holder)
.description("parent", "addtemp", group.getName(), duration, context)

View File

@ -115,7 +115,7 @@ public class ParentInfo extends SharedSubCommand {
for (InheritanceNode node : content) {
String s = "&3> &a" + node.getGroupName() + MessageUtils.getAppendableNodeContextString(plugin.getLocaleManager(), node);
if (node.hasExpiry()) {
s += "\n&2 expires in " + DurationFormatter.LONG.formatDateDiff(node.getExpiry().getEpochSecond());
s += "\n&2 expires in " + DurationFormatter.LONG.format(node.getExpiryDuration());
}
TextComponent message = TextUtils.fromLegacy(s, TextUtils.AMPERSAND_CHAR).toBuilder().applyDeep(makeFancy(holder, label, node)).build();

View File

@ -115,7 +115,7 @@ public class PermissionInfo extends SharedSubCommand {
for (Node node : content) {
String s = "&3> " + (node.getValue() ? "&a" : "&c") + node.getKey() + (sender.isConsole() ? " &7(" + node.getValue() + "&7)" : "") + MessageUtils.getAppendableNodeContextString(plugin.getLocaleManager(), node);
if (node.hasExpiry()) {
s += "\n&2- expires in " + DurationFormatter.LONG.formatDateDiff(node.getExpiry().getEpochSecond());
s += "\n&2- expires in " + DurationFormatter.LONG.format(node.getExpiryDuration());
}
TextComponent message = TextUtils.fromLegacy(s, TextUtils.AMPERSAND_CHAR).toBuilder().applyDeep(makeFancy(holder, label, node)).build();

View File

@ -54,6 +54,7 @@ import net.luckperms.api.model.data.TemporaryNodeMergeStrategy;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.types.InheritanceNode;
import java.time.Duration;
import java.util.List;
public class PermissionSetTemp extends SharedSubCommand {
@ -70,7 +71,7 @@ public class PermissionSetTemp extends SharedSubCommand {
String node = ArgumentParser.parseString(0, args);
boolean value = ArgumentParser.parseBoolean(1, args);
long duration = ArgumentParser.parseDuration(2, args);
Duration duration = ArgumentParser.parseDuration(2, args);
TemporaryNodeMergeStrategy modifier = ArgumentParser.parseTemporaryModifier(3, args).orElseGet(() -> plugin.getConfiguration().get(ConfigKeys.TEMPORARY_ADD_BEHAVIOUR));
MutableContextSet context = ArgumentParser.parseContext(3, args, plugin);
@ -93,8 +94,8 @@ public class PermissionSetTemp extends SharedSubCommand {
DataMutateResult.WithMergedNode result = holder.setNode(DataType.NORMAL, builtNode, modifier);
if (result.getResult().wasSuccessful()) {
duration = result.getMergedNode().getExpiry().getEpochSecond();
Message.SETPERMISSION_TEMP_SUCCESS.send(sender, node, value, holder.getFormattedDisplayName(), DurationFormatter.LONG.formatDateDiff(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context));
duration = result.getMergedNode().getExpiryDuration();
Message.SETPERMISSION_TEMP_SUCCESS.send(sender, node, value, holder.getFormattedDisplayName(), DurationFormatter.LONG.format(duration), MessageUtils.contextSetToString(plugin.getLocaleManager(), context));
LoggedAction.build().source(sender).target(holder)
.description("permission", "settemp", node, value, duration, context)

View File

@ -84,7 +84,7 @@ public class GroupInfo extends SubCommand<Group> {
Message.INFO_TEMP_PARENT_HEADER.send(sender);
for (InheritanceNode node : tempParents) {
Message.INFO_PARENT_ENTRY.send(sender, node.getGroupName(), MessageUtils.getAppendableNodeContextString(plugin.getLocaleManager(), node));
Message.INFO_PARENT_ENTRY_EXPIRY.send(sender, DurationFormatter.LONG.formatDateDiff(node.getExpiry().getEpochSecond()));
Message.INFO_PARENT_ENTRY_EXPIRY.send(sender, DurationFormatter.LONG.format(node.getExpiryDuration()));
}
}
return CommandResult.SUCCESS;

View File

@ -157,7 +157,7 @@ public class GroupListMembers extends SubCommand<Group> {
return "";
}
return " &8(&7expires in " + DurationFormatter.LONG.formatDateDiff(node.getExpiry().getEpochSecond()) + "&8)";
return " &8(&7expires in " + DurationFormatter.LONG.format(node.getExpiryDuration()) + "&8)";
}
private static Consumer<ComponentBuilder<? ,?>> makeFancy(String holderName, HolderType holderType, String label, HeldNode<?> perm, LuckPermsPlugin plugin) {

View File

@ -94,12 +94,10 @@ public class LogGroupHistory extends SubCommand<Log> {
String name = ((Action) entries.values().stream().findAny().get()).getTarget().getName();
Message.LOG_HISTORY_GROUP_HEADER.send(sender, name, page, maxPage);
long now = System.currentTimeMillis() / 1000L;
for (Map.Entry<Integer, LoggedAction> e : entries.entrySet()) {
long time = e.getValue().getTimestamp().getEpochSecond();
Message.LOG_ENTRY.send(sender,
e.getKey(),
DurationFormatter.CONCISE_LOW_ACCURACY.format(now - time),
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.getValue().getDurationSince()),
e.getValue().getSourceFriendlyString(),
Character.toString(LoggedAction.getTypeCharacter(((Action) e.getValue()).getTarget().getType())),
e.getValue().getTargetFriendlyString(),

View File

@ -106,12 +106,10 @@ public class LogRecent extends SubCommand<Log> {
Message.LOG_RECENT_HEADER.send(sender, page, maxPage);
}
long now = System.currentTimeMillis() / 1000L;
for (Map.Entry<Integer, LoggedAction> e : entries.entrySet()) {
long time = e.getValue().getTimestamp().getEpochSecond();
Message.LOG_ENTRY.send(sender,
e.getKey(),
DurationFormatter.CONCISE_LOW_ACCURACY.format(now - time),
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.getValue().getDurationSince()),
e.getValue().getSourceFriendlyString(),
Character.toString(LoggedAction.getTypeCharacter(((Action) e.getValue()).getTarget().getType())),
e.getValue().getTargetFriendlyString(),

View File

@ -93,12 +93,10 @@ public class LogSearch extends SubCommand<Log> {
SortedMap<Integer, LoggedAction> entries = log.getPage(page, ENTRIES_PER_PAGE);
Message.LOG_SEARCH_HEADER.send(sender, query, page, maxPage);
long now = System.currentTimeMillis() / 1000L;
for (Map.Entry<Integer, LoggedAction> e : entries.entrySet()) {
long time = e.getValue().getTimestamp().getEpochSecond();
Message.LOG_ENTRY.send(sender,
e.getKey(),
DurationFormatter.CONCISE_LOW_ACCURACY.format(now - time),
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.getValue().getDurationSince()),
e.getValue().getSourceFriendlyString(),
Character.toString(LoggedAction.getTypeCharacter(((Action) e.getValue()).getTarget().getType())),
e.getValue().getTargetFriendlyString(),

View File

@ -94,12 +94,10 @@ public class LogTrackHistory extends SubCommand<Log> {
String name = ((Action) entries.values().stream().findAny().get()).getTarget().getName();
Message.LOG_HISTORY_TRACK_HEADER.send(sender, name, page, maxPage);
long now = System.currentTimeMillis() / 1000L;
for (Map.Entry<Integer, LoggedAction> e : entries.entrySet()) {
long time = e.getValue().getTimestamp().getEpochSecond();
Message.LOG_ENTRY.send(sender,
e.getKey(),
DurationFormatter.CONCISE_LOW_ACCURACY.format(now - time),
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.getValue().getDurationSince()),
e.getValue().getSourceFriendlyString(),
Character.toString(LoggedAction.getTypeCharacter(((Action) e.getValue()).getTarget().getType())),
e.getValue().getTargetFriendlyString(),

View File

@ -87,12 +87,10 @@ public class LogUserHistory extends SubCommand<Log> {
String name = ((Action) entries.values().stream().findAny().get()).getTarget().getName();
Message.LOG_HISTORY_USER_HEADER.send(sender, name, page, maxPage);
long now = System.currentTimeMillis() / 1000L;
for (Map.Entry<Integer, LoggedAction> e : entries.entrySet()) {
long time = e.getValue().getTimestamp().getEpochSecond();
Message.LOG_ENTRY.send(sender,
e.getKey(),
DurationFormatter.CONCISE_LOW_ACCURACY.format(now - time),
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.getValue().getDurationSince()),
e.getValue().getSourceFriendlyString(),
Character.toString(LoggedAction.getTypeCharacter(((Action) e.getValue()).getTarget().getType())),
e.getValue().getTargetFriendlyString(),

View File

@ -312,7 +312,7 @@ public class ApplyEditsCommand extends SingleCommand {
private static String formatNode(LocaleManager localeManager, Node n) {
return n.getKey() + " &7(" + (n.getValue() ? "&a" : "&c") + n.getValue() + "&7)" + MessageUtils.getAppendableNodeContextString(localeManager, n) +
(n.hasExpiry() ? " &7(" + DurationFormatter.CONCISE.formatDateDiff(n.getExpiry().getEpochSecond()) + ")" : "");
(n.hasExpiry() ? " &7(" + DurationFormatter.CONCISE.format(n.getExpiryDuration()) + ")" : "");
}
private static <T> Map.Entry<Set<T>, Set<T>> diff(Set<T> before, Set<T> after) {

View File

@ -41,6 +41,8 @@ import me.lucko.luckperms.common.util.Predicates;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.extension.Extension;
import java.time.Duration;
import java.time.Instant;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -80,7 +82,7 @@ public class InfoCommand extends SingleCommand {
staticContext.isEmpty() ? "None" : MessageUtils.contextSetToString(plugin.getLocaleManager(), staticContext),
plugin.getBootstrap().getPlayerCount(),
plugin.getConnectionListener().getUniqueConnections().size(),
DurationFormatter.CONCISE_LOW_ACCURACY.format((System.currentTimeMillis() - plugin.getBootstrap().getStartupTime()) / 1000L),
DurationFormatter.CONCISE_LOW_ACCURACY.format(Duration.between(plugin.getBootstrap().getStartupTime(), Instant.now())),
plugin.getUserManager().getAll().size(),
plugin.getGroupManager().getAll().size(),
plugin.getTrackManager().getAll().size()

View File

@ -165,7 +165,7 @@ public class SearchCommand extends SingleCommand {
return "";
}
return " &8(&7expires in " + DurationFormatter.LONG.formatDateDiff(node.getExpiry().getEpochSecond()) + "&8)";
return " &8(&7expires in " + DurationFormatter.LONG.format(node.getExpiryDuration()) + "&8)";
}
private static Consumer<ComponentBuilder<?, ?>> makeFancy(String holderName, HolderType holderType, String label, HeldNode<?> perm, LuckPermsPlugin plugin) {

View File

@ -95,7 +95,7 @@ public class UserInfo extends SubCommand<User> {
Message.INFO_TEMP_PARENT_HEADER.send(sender);
for (InheritanceNode node : tempParents) {
Message.INFO_PARENT_ENTRY.send(sender, node.getGroupName(), MessageUtils.getAppendableNodeContextString(plugin.getLocaleManager(), node));
Message.INFO_PARENT_ENTRY_EXPIRY.send(sender, DurationFormatter.LONG.formatDateDiff(node.getExpiry().getEpochSecond()));
Message.INFO_PARENT_ENTRY_EXPIRY.send(sender, DurationFormatter.LONG.format(node.getExpiryDuration()));
}
}

View File

@ -440,7 +440,7 @@ public abstract class PermissionHolder {
switch (mergeStrategy) {
case ADD_NEW_DURATION_TO_EXISTING: {
// Create a new Node with the same properties, but add the expiry dates together
long newExpiry = otherMatch.getExpiry().plus(Duration.between(Instant.now(), node.getExpiry())).getEpochSecond();
Instant newExpiry = otherMatch.getExpiry().plus(Duration.between(Instant.now(), node.getExpiry()));
newNode = node.toBuilder().expiry(newExpiry).build();
break;
}

View File

@ -40,7 +40,9 @@ import net.luckperms.api.node.types.PermissionNode;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@ -113,7 +115,18 @@ public abstract class AbstractNode<N extends ScopedNode<N, B>, B extends NodeBui
@Override
public boolean hasExpired() {
return hasExpiry() && this.expireAt < System.currentTimeMillis() / 1000L;
Instant expiry = getExpiry();
return expiry != null && expiry.isBefore(Instant.now());
}
@Override
public @Nullable Duration getExpiryDuration() {
Instant expiry = getExpiry();
if (expiry == null) {
return null;
}
Instant now = Instant.now().truncatedTo(ChronoUnit.SECONDS);
return Duration.between(now, expiry);
}
@Override

View File

@ -37,8 +37,11 @@ import net.luckperms.api.node.metadata.NodeMetadataKey;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.time.Instant;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalAmount;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
@ -93,6 +96,16 @@ public abstract class AbstractNodeBuilder<N extends ScopedNode<N, B>, B extends
return (B) this;
}
@Override
public @NonNull B expiry(@Nullable TemporalAmount duration) {
if (duration == null) {
return clearExpiry();
}
this.expireAt = Instant.now().truncatedTo(ChronoUnit.SECONDS).plus(duration).getEpochSecond();
return (B) this;
}
@Override
public @NonNull B clearExpiry() {
this.expireAt = 0L;

View File

@ -28,8 +28,6 @@ package me.lucko.luckperms.common.node.comparator;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.types.PermissionNode;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Comparator;
public class NodeComparator implements Comparator<Node> {
@ -65,8 +63,7 @@ public class NodeComparator implements Comparator<Node> {
}
if (o1.hasExpiry()) {
// note vvv
result = -Long.compare(ChronoUnit.MILLIS.between(Instant.now(), o1.getExpiry()), ChronoUnit.MILLIS.between(Instant.now(), o2.getExpiry()));
result = o1.getExpiry().compareTo(o2.getExpiry());
if (result != 0) {
return result;
}

View File

@ -61,6 +61,8 @@ import net.luckperms.api.LuckPerms;
import okhttp3.OkHttpClient;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Set;
@ -198,7 +200,8 @@ public abstract class AbstractLuckPermsPlugin implements LuckPermsPlugin {
// perform any platform-specific final setup tasks
performFinalSetup();
getLogger().info("Successfully enabled. (took " + (System.currentTimeMillis() - getBootstrap().getStartupTime()) + "ms)");
Duration timeTaken = Duration.between(getBootstrap().getStartupTime(), Instant.now());
getLogger().info("Successfully enabled. (took " + timeTaken.toMillis() + "ms)");
}
public final void disable() {

View File

@ -35,6 +35,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import java.io.InputStream;
import java.nio.file.Path;
import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@ -99,7 +100,7 @@ public interface LuckPermsBootstrap {
*
* @return the enable time
*/
long getStartupTime();
Instant getStartupTime();
/**
* Gets the platform type this instance of LuckPerms is running on.

View File

@ -1,135 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.util;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Translates unix timestamps / durations into a readable format
*
* @author khobbits, drtshock, vemacs
* see: https://github.com/drtshock/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/utils/DateUtil.java
*/
public final class DateParser {
private DateParser() {}
private static final Pattern TIME_PATTERN = Pattern.compile(Stream.of("y", "mo", "w", "d", "h", "m").map(i -> "(?:([0-9]+)\\s*" + i + "[a-z]*[,\\s]*)?").collect(Collectors.joining()) + "(?:([0-9]+)\\s*(?:s[a-z]*)?)?", Pattern.CASE_INSENSITIVE);
private static final int MAX_YEARS = 100000;
/**
* Converts a time string to a unix timestamp
*
* @param time the time string
* @param future if the date is in the future, as opposed to the past
* @return a unix timestamp
* @throws IllegalArgumentException if the date input was invalid
*/
public static long parseDate(String time, boolean future) throws IllegalArgumentException {
Matcher matcher = TIME_PATTERN.matcher(time);
int years = 0, months = 0, weeks = 0, days = 0, hours = 0, minutes = 0, seconds = 0;
boolean found = false;
while (matcher.find()) {
if (matcher.group() == null || matcher.group().isEmpty()) {
continue;
}
for (int i = 0; i < matcher.groupCount(); i++) {
if (matcher.group(i) != null && !matcher.group(i).isEmpty()) {
found = true;
break;
}
}
if (found) {
if (matcher.group(1) != null && !matcher.group(1).isEmpty()) {
years = Integer.parseInt(matcher.group(1));
}
if (matcher.group(2) != null && !matcher.group(2).isEmpty()) {
months = Integer.parseInt(matcher.group(2));
}
if (matcher.group(3) != null && !matcher.group(3).isEmpty()) {
weeks = Integer.parseInt(matcher.group(3));
}
if (matcher.group(4) != null && !matcher.group(4).isEmpty()) {
days = Integer.parseInt(matcher.group(4));
}
if (matcher.group(5) != null && !matcher.group(5).isEmpty()) {
hours = Integer.parseInt(matcher.group(5));
}
if (matcher.group(6) != null && !matcher.group(6).isEmpty()) {
minutes = Integer.parseInt(matcher.group(6));
}
if (matcher.group(7) != null && !matcher.group(7).isEmpty()) {
seconds = Integer.parseInt(matcher.group(7));
}
break;
}
}
if (!found) {
throw new IllegalArgumentException();
}
Calendar c = new GregorianCalendar();
if (years > 0) {
if (years > MAX_YEARS) {
years = MAX_YEARS;
}
c.add(Calendar.YEAR, years * (future ? 1 : -1));
}
if (months > 0) {
c.add(Calendar.MONTH, months * (future ? 1 : -1));
}
if (weeks > 0) {
c.add(Calendar.WEEK_OF_YEAR, weeks * (future ? 1 : -1));
}
if (days > 0) {
c.add(Calendar.DAY_OF_MONTH, days * (future ? 1 : -1));
}
if (hours > 0) {
c.add(Calendar.HOUR_OF_DAY, hours * (future ? 1 : -1));
}
if (minutes > 0) {
c.add(Calendar.MINUTE, minutes * (future ? 1 : -1));
}
if (seconds > 0) {
c.add(Calendar.SECOND, seconds * (future ? 1 : -1));
}
Calendar max = new GregorianCalendar();
max.add(Calendar.YEAR, 10);
if (c.after(max)) {
c = max;
}
return c.getTimeInMillis() / 1000;
}
}

View File

@ -25,157 +25,109 @@
package me.lucko.luckperms.common.util;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
/**
* Formats durations to a readable form
*
* @author khobbits, drtshock, vemacs
* see: https://github.com/drtshock/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/utils/DateUtil.java
*/
public enum DurationFormatter {
LONG,
CONCISE {
private final String[] names = new String[]{"y", "y", "m", "m", "d", "d", "h", "h", "m", "m", "s", "s"};
@Override
protected String formatUnitPlural(ChronoUnit unit) {
return String.valueOf(Character.toLowerCase(unit.name().charAt(0)));
}
@Override
public String format(Calendar from, Calendar to) {
return dateDiff(from, to, 4, this.names, true);
protected String formatUnitSingular(ChronoUnit unit) {
return formatUnitPlural(unit);
}
},
CONCISE_LOW_ACCURACY {
private final String[] names = new String[]{"y", "y", "m", "m", "d", "d", "h", "h", "m", "m", "s", "s"};
CONCISE_LOW_ACCURACY(3) {
@Override
public String format(Calendar from, Calendar to) {
return dateDiff(from, to, 2, this.names, true);
protected String formatUnitPlural(ChronoUnit unit) {
return String.valueOf(Character.toLowerCase(unit.name().charAt(0)));
}
},
LONG {
private final String[] names = new String[]{"year", "years", "month", "months", "day", "days", "hour", "hours", "minute", "minutes", "second", "seconds"};
@Override
public String format(Calendar from, Calendar to) {
return dateDiff(from, to, 4, this.names, false);
protected String formatUnitSingular(ChronoUnit unit) {
return formatUnitPlural(unit);
}
};
/**
* The calender type magic numbers to use when formatting
*/
private static final int[] CALENDAR_TYPES = new int[] {
Calendar.YEAR,
Calendar.MONTH,
Calendar.DAY_OF_MONTH,
Calendar.HOUR_OF_DAY,
Calendar.MINUTE,
Calendar.SECOND
private final Unit[] units = new Unit[]{
new Unit(ChronoUnit.YEARS),
new Unit(ChronoUnit.MONTHS),
new Unit(ChronoUnit.WEEKS),
new Unit(ChronoUnit.DAYS),
new Unit(ChronoUnit.HOURS),
new Unit(ChronoUnit.MINUTES),
new Unit(ChronoUnit.SECONDS)
};
private static final int MAX_YEARS = 100000;
private final int accuracy;
/**
* Formats the difference between two dates
*
* @param from the start date
* @param to the end date
* @param maxAccuracy how accurate the output should be (how many sections it'll have)
* @param names the names to use to format each of the corresponding {@link #CALENDAR_TYPES}
* @return a formatted string
*/
private static String dateDiff(Calendar from, Calendar to, int maxAccuracy, String[] names, boolean concise) {
if (to.equals(from)) {
return "now";
DurationFormatter() {
this(Integer.MAX_VALUE);
}
DurationFormatter(int accuracy) {
if (accuracy <= 0) {
throw new IllegalArgumentException("accuracy must be >= 1");
}
this.accuracy = accuracy;
}
protected String formatUnitPlural(ChronoUnit unit) {
return " " + unit.name().toLowerCase();
}
protected String formatUnitSingular(ChronoUnit unit) {
String s = unit.name().toLowerCase();
return " " + s.substring(0, s.length() - 1);
}
private final class Unit {
private final long duration;
private final String stringPlural;
private final String stringSingular;
Unit(ChronoUnit unit) {
this.duration = unit.getDuration().getSeconds();
this.stringPlural = formatUnitPlural(unit);
this.stringSingular = formatUnitSingular(unit);
}
boolean future = to.after(from);
public String toString(long n) {
return n == 1 ? this.stringSingular : this.stringPlural;
}
}
StringBuilder sb = new StringBuilder();
int accuracy = 0;
for (int i = 0; i < CALENDAR_TYPES.length; i++) {
if (accuracy > maxAccuracy) {
private String format(long seconds) {
StringBuilder output = new StringBuilder();
int outputSize = 0;
for (Unit unit : this.units) {
long n = seconds / unit.duration;
if (n > 0) {
seconds -= unit.duration * n;
output.append(' ').append(n).append(unit.toString(n));
outputSize++;
}
if (seconds <= 0 || outputSize >= this.accuracy) {
break;
}
int diff = dateDiff(CALENDAR_TYPES[i], from, to, future);
if (diff > 0) {
int plural = diff > 1 ? 1 : 0;
String unit = names[i * 2 + plural];
sb.append(" ");
sb.append(diff);
if (!concise) {
sb.append(" ");
}
sb.append(unit);
accuracy++;
}
}
if (sb.length() == 0) {
return "now";
if (output.length() == 0) {
return "0" + this.units[this.units.length - 1].stringPlural;
}
return sb.toString().trim();
return output.substring(1);
}
private static int dateDiff(int type, Calendar fromDate, Calendar toDate, boolean future) {
int fromYear = fromDate.get(Calendar.YEAR);
int toYear = toDate.get(Calendar.YEAR);
if (Math.abs(fromYear - toYear) > MAX_YEARS) {
toDate.set(Calendar.YEAR, fromYear + (future ? MAX_YEARS : -MAX_YEARS));
}
int diff = 0;
long savedDate = fromDate.getTimeInMillis();
while ((future && !fromDate.after(toDate)) || (!future && !fromDate.before(toDate))) {
savedDate = fromDate.getTimeInMillis();
fromDate.add(type, future ? 1 : -1);
diff++;
}
diff--;
fromDate.setTimeInMillis(savedDate);
return diff;
public String format(Duration duration) {
return format(duration.getSeconds());
}
/**
* Formats the time difference between two dates
*
* @param from the start date
* @param to the end date
* @return the formatted duration string
*/
public abstract String format(Calendar from, Calendar to);
/**
* Formats a duration, in seconds
*
* @param seconds the duration
* @return the formatted duration string
*/
public String format(long seconds) {
Calendar from = new GregorianCalendar();
from.setTimeInMillis(0);
Calendar to = new GregorianCalendar();
to.setTimeInMillis(seconds * 1000L);
return format(from, to);
}
/**
* Formats the duration between the current time and the given unix timestamp
*
* @param unixTimestamp the timestamp, in seconds
* @return the formatted duration string
*/
public String formatDateDiff(long unixTimestamp) {
long now = System.currentTimeMillis() / 1000L;
return format(unixTimestamp - now);
}
}

View File

@ -0,0 +1,91 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.util;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Parses durations from a string format
*/
public final class DurationParser {
private DurationParser() {}
private static final ChronoUnit[] UNITS = new ChronoUnit[]{
ChronoUnit.YEARS,
ChronoUnit.MONTHS,
ChronoUnit.WEEKS,
ChronoUnit.DAYS,
ChronoUnit.HOURS,
ChronoUnit.MINUTES,
ChronoUnit.SECONDS
};
private static final String PATTERN_STRING = Arrays.stream(UNITS)
.limit(UNITS.length - 1) // skip seconds
.map(unit -> {
if (unit == ChronoUnit.MONTHS) {
return "mo";
}
// use the first char as the abbreviation
return String.valueOf(Character.toLowerCase(unit.name().charAt(0)));
})
.map(abbreviation -> "(?:([0-9]+)\\s*" + abbreviation + "[a-z]*[,\\s]*)?")
.collect(Collectors.joining())
.concat("(?:([0-9]+)\\s*(?:s[a-z]*)?)?");
private static final Pattern PATTERN = Pattern.compile(PATTERN_STRING, Pattern.CASE_INSENSITIVE);
public static Duration parseDuration(String input) throws IllegalArgumentException {
Matcher matcher = PATTERN.matcher(input);
while (matcher.find()) {
if (matcher.group() == null || matcher.group().isEmpty()) {
continue;
}
Duration duration = Duration.ZERO;
for (int i = 0; i < UNITS.length; i++) {
ChronoUnit unit = UNITS[i];
int g = i + 1;
if (matcher.group(g) != null && !matcher.group(g).isEmpty()) {
int n = Integer.parseInt(matcher.group(g));
duration = duration.plus(n, unit);
}
}
return duration;
}
throw new IllegalArgumentException("unable to parse duration: " + input);
}
}

View File

@ -53,9 +53,10 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
@ -65,7 +66,7 @@ import java.util.zip.GZIPOutputStream;
* Accepts and processes {@link VerboseEvent}, passed from the {@link VerboseHandler}.
*/
public class VerboseListener {
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
// how much data should we store before stopping.
private static final int DATA_TRUNCATION = 10000;
@ -97,7 +98,7 @@ public class VerboseListener {
.build();
// the time when the listener was first registered
private final long startTime = System.currentTimeMillis();
private final Instant startTime = Instant.now();
// the sender to notify each time the listener processes a check which passes the filter
private final Sender notifiedSender;
// the filter
@ -255,10 +256,9 @@ public class VerboseListener {
public String uploadPasteData(BytebinClient bytebin) {
// retrieve variables
long now = System.currentTimeMillis();
String startDate = DATE_FORMAT.format(new Date(this.startTime));
String endDate = DATE_FORMAT.format(new Date(now));
long secondsTaken = (now - this.startTime) / 1000L;
String duration = DurationFormatter.CONCISE.format(secondsTaken);
String startDate = DATE_FORMAT.format(this.startTime);
String endDate = DATE_FORMAT.format(Instant.now());
String duration = DurationFormatter.CONCISE.format(Duration.between(this.startTime, Instant.now()));
boolean truncated = this.matchedCounter.get() > this.results.size();
JObject metadata = new JObject()

View File

@ -37,6 +37,7 @@ import cn.nukkit.plugin.PluginBase;
import java.io.InputStream;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
@ -70,7 +71,7 @@ public class LPNukkitBootstrap extends PluginBase implements LuckPermsBootstrap
/**
* The time when the plugin was enabled
*/
private long startTime;
private Instant startTime;
// load/enable latches
private final CountDownLatch loadLatch = new CountDownLatch(1);
@ -117,7 +118,7 @@ public class LPNukkitBootstrap extends PluginBase implements LuckPermsBootstrap
@Override
public void onEnable() {
this.startTime = System.currentTimeMillis();
this.startTime = Instant.now();
try {
this.plugin.enable();
} finally {
@ -148,7 +149,7 @@ public class LPNukkitBootstrap extends PluginBase implements LuckPermsBootstrap
}
@Override
public long getStartupTime() {
public Instant getStartupTime() {
return this.startTime;
}

View File

@ -57,6 +57,7 @@ import org.spongepowered.api.scheduler.SynchronousExecutor;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
@ -102,7 +103,7 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap {
/**
* The time when the plugin was enabled
*/
private long startTime;
private Instant startTime;
// load/enable latches
private final CountDownLatch loadLatch = new CountDownLatch(1);
@ -162,7 +163,7 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap {
@Listener(order = Order.FIRST)
public void onEnable(GamePreInitializationEvent event) {
this.startTime = System.currentTimeMillis();
this.startTime = Instant.now();
try {
this.plugin.load();
} finally {
@ -218,7 +219,7 @@ public class LPSpongeBootstrap implements LuckPermsBootstrap {
}
@Override
public long getStartupTime() {
public Instant getStartupTime() {
return this.startTime;
}

View File

@ -47,6 +47,7 @@ import org.slf4j.Logger;
import java.io.InputStream;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
@ -88,7 +89,7 @@ public class LPVelocityBootstrap implements LuckPermsBootstrap {
/**
* The time when the plugin was enabled
*/
private long startTime;
private Instant startTime;
// load/enable latches
private final CountDownLatch loadLatch = new CountDownLatch(1);
@ -130,7 +131,7 @@ public class LPVelocityBootstrap implements LuckPermsBootstrap {
@Subscribe(order = PostOrder.FIRST)
public void onEnable(ProxyInitializeEvent e) {
this.startTime = System.currentTimeMillis();
this.startTime = Instant.now();
try {
this.plugin.load();
} finally {
@ -173,7 +174,7 @@ public class LPVelocityBootstrap implements LuckPermsBootstrap {
}
@Override
public long getStartupTime() {
public Instant getStartupTime() {
return this.startTime;
}