mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-11-24 03:25:19 +01:00
Optimize ActionLog and Paginated util
This commit is contained in:
parent
a1c91b9007
commit
9984d4be42
@ -100,6 +100,7 @@ public interface PlayerAdapter<T> {
|
|||||||
default @NonNull CachedPermissionData getPermissionData(@NonNull T player) {
|
default @NonNull CachedPermissionData getPermissionData(@NonNull T player) {
|
||||||
return getUser(player).getCachedData().getPermissionData(getQueryOptions(player));
|
return getUser(player).getCachedData().getPermissionData(getQueryOptions(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current {@link CachedMetaData} for the {@code player},
|
* Gets the current {@link CachedMetaData} for the {@code player},
|
||||||
* using their {@link #getQueryOptions(Object) active query options}.
|
* using their {@link #getQueryOptions(Object) active query options}.
|
||||||
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* 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.actionlog;
|
||||||
|
|
||||||
|
import net.luckperms.api.actionlog.Action;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
final class ActionComparator implements Comparator<Action> {
|
||||||
|
public static final Comparator<Action> INSTANCE = new ActionComparator();
|
||||||
|
|
||||||
|
private ActionComparator() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(Action o1, Action o2) {
|
||||||
|
int cmp = o1.getTimestamp().compareTo(o2.getTimestamp());
|
||||||
|
if (cmp != 0) {
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Action.Source o1Source = o1.getSource();
|
||||||
|
Action.Source o2Source = o2.getSource();
|
||||||
|
|
||||||
|
cmp = o1Source.getUniqueId().compareTo(o2Source.getUniqueId());
|
||||||
|
if (cmp != 0) {
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmp = o1Source.getName().compareTo(o2Source.getName());
|
||||||
|
if (cmp != 0) {
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
Action.Target o1Target = o1.getTarget();
|
||||||
|
Action.Target o2Target = o2.getTarget();
|
||||||
|
|
||||||
|
cmp = o1Target.getType().compareTo(o2Target.getType());
|
||||||
|
if (cmp != 0) {
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmp = o1Target.getType().compareTo(o2Target.getType());
|
||||||
|
if (cmp != 0) {
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmp = compareOptionals(o1Target.getUniqueId(), o2Target.getUniqueId());
|
||||||
|
if (cmp != 0) {
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmp = o1Source.getName().compareTo(o2Source.getName());
|
||||||
|
if (cmp != 0) {
|
||||||
|
return cmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return o1.getDescription().compareTo(o2.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({"OptionalUsedAsFieldOrParameterType", "OptionalIsPresent"})
|
||||||
|
private static <T extends Comparable<T>> int compareOptionals(Optional<T> a, Optional<T> b) {
|
||||||
|
if (!a.isPresent()) {
|
||||||
|
return b.isPresent() ? -1 : 0;
|
||||||
|
} else if (!b.isPresent()) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return a.get().compareTo(b.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,36 +25,33 @@
|
|||||||
|
|
||||||
package me.lucko.luckperms.common.actionlog;
|
package me.lucko.luckperms.common.actionlog;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableSortedSet;
|
import com.google.common.collect.ImmutableSortedSet;
|
||||||
|
|
||||||
import me.lucko.luckperms.common.util.ImmutableCollectors;
|
import me.lucko.luckperms.common.util.ImmutableCollectors;
|
||||||
|
|
||||||
import net.luckperms.api.actionlog.Action;
|
import net.luckperms.api.actionlog.Action;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class Log {
|
public class Log {
|
||||||
private static Log empty = null;
|
private static final Log EMPTY = new Log(ImmutableList.of());
|
||||||
|
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized Log empty() {
|
public static Log empty() {
|
||||||
if (empty == null) {
|
return EMPTY;
|
||||||
empty = builder().build();
|
|
||||||
}
|
|
||||||
return empty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final SortedSet<LoggedAction> content;
|
private final SortedSet<LoggedAction> content;
|
||||||
|
|
||||||
public Log(SortedSet<LoggedAction> content) {
|
Log(List<LoggedAction> content) {
|
||||||
this.content = ImmutableSortedSet.copyOfSorted(content);
|
this.content = ImmutableSortedSet.copyOf(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SortedSet<LoggedAction> getContent() {
|
public SortedSet<LoggedAction> getContent() {
|
||||||
@ -64,38 +61,38 @@ public class Log {
|
|||||||
public SortedSet<LoggedAction> getContent(UUID actor) {
|
public SortedSet<LoggedAction> getContent(UUID actor) {
|
||||||
return this.content.stream()
|
return this.content.stream()
|
||||||
.filter(e -> e.getSource().getUniqueId().equals(actor))
|
.filter(e -> e.getSource().getUniqueId().equals(actor))
|
||||||
.collect(Collectors.toCollection(TreeSet::new));
|
.collect(ImmutableCollectors.toSortedSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public SortedSet<LoggedAction> getUserHistory(UUID uniqueId) {
|
public SortedSet<LoggedAction> getUserHistory(UUID uniqueId) {
|
||||||
return this.content.stream()
|
return this.content.stream()
|
||||||
.filter(e -> e.getTarget().getType() == Action.Target.Type.USER)
|
.filter(e -> e.getTarget().getType() == Action.Target.Type.USER)
|
||||||
.filter(e -> e.getTarget().getUniqueId().isPresent() && e.getTarget().getUniqueId().get().equals(uniqueId))
|
.filter(e -> e.getTarget().getUniqueId().isPresent() && e.getTarget().getUniqueId().get().equals(uniqueId))
|
||||||
.collect(ImmutableCollectors.toSortedSet(Comparator.naturalOrder()));
|
.collect(ImmutableCollectors.toSortedSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public SortedSet<LoggedAction> getGroupHistory(String name) {
|
public SortedSet<LoggedAction> getGroupHistory(String name) {
|
||||||
return this.content.stream()
|
return this.content.stream()
|
||||||
.filter(e -> e.getTarget().getType() == Action.Target.Type.GROUP)
|
.filter(e -> e.getTarget().getType() == Action.Target.Type.GROUP)
|
||||||
.filter(e -> e.getTarget().getName().equals(name))
|
.filter(e -> e.getTarget().getName().equals(name))
|
||||||
.collect(ImmutableCollectors.toSortedSet(Comparator.naturalOrder()));
|
.collect(ImmutableCollectors.toSortedSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public SortedSet<LoggedAction> getTrackHistory(String name) {
|
public SortedSet<LoggedAction> getTrackHistory(String name) {
|
||||||
return this.content.stream()
|
return this.content.stream()
|
||||||
.filter(e -> e.getTarget().getType() == Action.Target.Type.TRACK)
|
.filter(e -> e.getTarget().getType() == Action.Target.Type.TRACK)
|
||||||
.filter(e -> e.getTarget().getName().equals(name))
|
.filter(e -> e.getTarget().getName().equals(name))
|
||||||
.collect(ImmutableCollectors.toSortedSet(Comparator.naturalOrder()));
|
.collect(ImmutableCollectors.toSortedSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public SortedSet<LoggedAction> getSearch(String query) {
|
public SortedSet<LoggedAction> getSearch(String query) {
|
||||||
return this.content.stream()
|
return this.content.stream()
|
||||||
.filter(e -> e.matchesSearch(query))
|
.filter(e -> e.matchesSearch(query))
|
||||||
.collect(ImmutableCollectors.toSortedSet(Comparator.naturalOrder()));
|
.collect(ImmutableCollectors.toSortedSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
private final SortedSet<LoggedAction> content = new TreeSet<>();
|
private final List<LoggedAction> content = new ArrayList<>();
|
||||||
|
|
||||||
public Builder add(LoggedAction e) {
|
public Builder add(LoggedAction e) {
|
||||||
this.content.add(e);
|
this.content.add(e);
|
||||||
@ -103,6 +100,9 @@ public class Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Log build() {
|
public Log build() {
|
||||||
|
if (this.content.isEmpty()) {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
return new Log(this.content);
|
return new Log(this.content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,6 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
@ -58,15 +57,6 @@ import java.util.UUID;
|
|||||||
*/
|
*/
|
||||||
public class LoggedAction implements Action {
|
public class LoggedAction implements Action {
|
||||||
|
|
||||||
private static final Comparator<Action> COMPARATOR = Comparator
|
|
||||||
.<Action>comparingLong(a -> a.getTimestamp().getEpochSecond())
|
|
||||||
.thenComparing(a -> a.getSource().getUniqueId())
|
|
||||||
.thenComparing(a -> a.getSource().getName(), String.CASE_INSENSITIVE_ORDER)
|
|
||||||
.thenComparing(a -> a.getTarget().getType())
|
|
||||||
.thenComparing(e -> e.getTarget().getUniqueId().map(UUID::toString).orElse(""))
|
|
||||||
.thenComparing(a -> a.getTarget().getName(), String.CASE_INSENSITIVE_ORDER)
|
|
||||||
.thenComparing(Action::getDescription);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new log entry builder
|
* Creates a new log entry builder
|
||||||
*
|
*
|
||||||
@ -131,7 +121,7 @@ public class LoggedAction implements Action {
|
|||||||
@Override
|
@Override
|
||||||
public int compareTo(@NonNull Action other) {
|
public int compareTo(@NonNull Action other) {
|
||||||
Objects.requireNonNull(other, "other");
|
Objects.requireNonNull(other, "other");
|
||||||
return COMPARATOR.compare(this, other);
|
return ActionComparator.INSTANCE.compare(this, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matchesSearch(String query) {
|
public boolean matchesSearch(String query) {
|
||||||
@ -171,13 +161,7 @@ public class LoggedAction implements Action {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
final int PRIME = 59;
|
return Objects.hash(getTimestamp(), getSource(), getTarget(), getDescription());
|
||||||
int result = 1;
|
|
||||||
result = result * PRIME + getTimestamp().hashCode();
|
|
||||||
result = result * PRIME + getSource().hashCode();
|
|
||||||
result = result * PRIME + getTarget().hashCode();
|
|
||||||
result = result * PRIME + getDescription().hashCode();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class SourceImpl implements Source {
|
private static final class SourceImpl implements Source {
|
||||||
|
@ -43,11 +43,7 @@ import me.lucko.luckperms.common.util.DurationFormatter;
|
|||||||
import me.lucko.luckperms.common.util.Paginated;
|
import me.lucko.luckperms.common.util.Paginated;
|
||||||
import me.lucko.luckperms.common.util.Predicates;
|
import me.lucko.luckperms.common.util.Predicates;
|
||||||
|
|
||||||
import net.luckperms.api.actionlog.Action;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.SortedMap;
|
|
||||||
|
|
||||||
public class LogGroupHistory extends ChildCommand<Log> {
|
public class LogGroupHistory extends ChildCommand<Log> {
|
||||||
private static final int ENTRIES_PER_PAGE = 10;
|
private static final int ENTRIES_PER_PAGE = 10;
|
||||||
@ -90,18 +86,18 @@ public class LogGroupHistory extends ChildCommand<Log> {
|
|||||||
return CommandResult.INVALID_ARGS;
|
return CommandResult.INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SortedMap<Integer, LoggedAction> entries = log.getPage(page, ENTRIES_PER_PAGE);
|
List<Paginated.Entry<LoggedAction>> entries = log.getPage(page, ENTRIES_PER_PAGE);
|
||||||
String name = ((Action) entries.values().stream().findAny().get()).getTarget().getName();
|
String name = entries.stream().findAny().get().value().getTarget().getName();
|
||||||
Message.LOG_HISTORY_GROUP_HEADER.send(sender, name, page, maxPage);
|
Message.LOG_HISTORY_GROUP_HEADER.send(sender, name, page, maxPage);
|
||||||
|
|
||||||
for (Map.Entry<Integer, LoggedAction> e : entries.entrySet()) {
|
for (Paginated.Entry<LoggedAction> e : entries) {
|
||||||
Message.LOG_ENTRY.send(sender,
|
Message.LOG_ENTRY.send(sender,
|
||||||
e.getKey(),
|
e.position(),
|
||||||
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.getValue().getDurationSince()),
|
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.value().getDurationSince()),
|
||||||
e.getValue().getSourceFriendlyString(),
|
e.value().getSourceFriendlyString(),
|
||||||
Character.toString(LoggedAction.getTypeCharacter(((Action) e.getValue()).getTarget().getType())),
|
Character.toString(LoggedAction.getTypeCharacter(e.value().getTarget().getType())),
|
||||||
e.getValue().getTargetFriendlyString(),
|
e.value().getTargetFriendlyString(),
|
||||||
e.getValue().getDescription()
|
e.value().getDescription()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,11 +40,7 @@ import me.lucko.luckperms.common.util.DurationFormatter;
|
|||||||
import me.lucko.luckperms.common.util.Paginated;
|
import me.lucko.luckperms.common.util.Paginated;
|
||||||
import me.lucko.luckperms.common.util.Predicates;
|
import me.lucko.luckperms.common.util.Predicates;
|
||||||
|
|
||||||
import net.luckperms.api.actionlog.Action;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.SortedMap;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class LogRecent extends ChildCommand<Log> {
|
public class LogRecent extends ChildCommand<Log> {
|
||||||
@ -95,9 +91,9 @@ public class LogRecent extends ChildCommand<Log> {
|
|||||||
return CommandResult.INVALID_ARGS;
|
return CommandResult.INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SortedMap<Integer, LoggedAction> entries = log.getPage(page, ENTRIES_PER_PAGE);
|
List<Paginated.Entry<LoggedAction>> entries = log.getPage(page, ENTRIES_PER_PAGE);
|
||||||
if (specificUser) {
|
if (specificUser) {
|
||||||
String name = ((Action) entries.values().stream().findAny().get()).getSource().getName();
|
String name = entries.stream().findAny().get().value().getSource().getName();
|
||||||
if (name.contains("@")) {
|
if (name.contains("@")) {
|
||||||
name = name.split("@")[0];
|
name = name.split("@")[0];
|
||||||
}
|
}
|
||||||
@ -106,14 +102,14 @@ public class LogRecent extends ChildCommand<Log> {
|
|||||||
Message.LOG_RECENT_HEADER.send(sender, page, maxPage);
|
Message.LOG_RECENT_HEADER.send(sender, page, maxPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<Integer, LoggedAction> e : entries.entrySet()) {
|
for (Paginated.Entry<LoggedAction> e : entries) {
|
||||||
Message.LOG_ENTRY.send(sender,
|
Message.LOG_ENTRY.send(sender,
|
||||||
e.getKey(),
|
e.position(),
|
||||||
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.getValue().getDurationSince()),
|
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.value().getDurationSince()),
|
||||||
e.getValue().getSourceFriendlyString(),
|
e.value().getSourceFriendlyString(),
|
||||||
Character.toString(LoggedAction.getTypeCharacter(((Action) e.getValue()).getTarget().getType())),
|
Character.toString(LoggedAction.getTypeCharacter(e.value().getTarget().getType())),
|
||||||
e.getValue().getTargetFriendlyString(),
|
e.value().getTargetFriendlyString(),
|
||||||
e.getValue().getDescription()
|
e.value().getDescription()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return CommandResult.SUCCESS;
|
return CommandResult.SUCCESS;
|
||||||
|
@ -39,11 +39,7 @@ import me.lucko.luckperms.common.util.DurationFormatter;
|
|||||||
import me.lucko.luckperms.common.util.Paginated;
|
import me.lucko.luckperms.common.util.Paginated;
|
||||||
import me.lucko.luckperms.common.util.Predicates;
|
import me.lucko.luckperms.common.util.Predicates;
|
||||||
|
|
||||||
import net.luckperms.api.actionlog.Action;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.SortedMap;
|
|
||||||
|
|
||||||
public class LogSearch extends ChildCommand<Log> {
|
public class LogSearch extends ChildCommand<Log> {
|
||||||
private static final int ENTRIES_PER_PAGE = 10;
|
private static final int ENTRIES_PER_PAGE = 10;
|
||||||
@ -90,17 +86,17 @@ public class LogSearch extends ChildCommand<Log> {
|
|||||||
return CommandResult.INVALID_ARGS;
|
return CommandResult.INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SortedMap<Integer, LoggedAction> entries = log.getPage(page, ENTRIES_PER_PAGE);
|
List<Paginated.Entry<LoggedAction>> entries = log.getPage(page, ENTRIES_PER_PAGE);
|
||||||
Message.LOG_SEARCH_HEADER.send(sender, query, page, maxPage);
|
Message.LOG_SEARCH_HEADER.send(sender, query, page, maxPage);
|
||||||
|
|
||||||
for (Map.Entry<Integer, LoggedAction> e : entries.entrySet()) {
|
for (Paginated.Entry<LoggedAction> e : entries) {
|
||||||
Message.LOG_ENTRY.send(sender,
|
Message.LOG_ENTRY.send(sender,
|
||||||
e.getKey(),
|
e.position(),
|
||||||
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.getValue().getDurationSince()),
|
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.value().getDurationSince()),
|
||||||
e.getValue().getSourceFriendlyString(),
|
e.value().getSourceFriendlyString(),
|
||||||
Character.toString(LoggedAction.getTypeCharacter(((Action) e.getValue()).getTarget().getType())),
|
Character.toString(LoggedAction.getTypeCharacter(e.value().getTarget().getType())),
|
||||||
e.getValue().getTargetFriendlyString(),
|
e.value().getTargetFriendlyString(),
|
||||||
e.getValue().getDescription()
|
e.value().getDescription()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,11 +43,7 @@ import me.lucko.luckperms.common.util.DurationFormatter;
|
|||||||
import me.lucko.luckperms.common.util.Paginated;
|
import me.lucko.luckperms.common.util.Paginated;
|
||||||
import me.lucko.luckperms.common.util.Predicates;
|
import me.lucko.luckperms.common.util.Predicates;
|
||||||
|
|
||||||
import net.luckperms.api.actionlog.Action;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.SortedMap;
|
|
||||||
|
|
||||||
public class LogTrackHistory extends ChildCommand<Log> {
|
public class LogTrackHistory extends ChildCommand<Log> {
|
||||||
private static final int ENTRIES_PER_PAGE = 10;
|
private static final int ENTRIES_PER_PAGE = 10;
|
||||||
@ -90,18 +86,18 @@ public class LogTrackHistory extends ChildCommand<Log> {
|
|||||||
return CommandResult.INVALID_ARGS;
|
return CommandResult.INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SortedMap<Integer, LoggedAction> entries = log.getPage(page, ENTRIES_PER_PAGE);
|
List<Paginated.Entry<LoggedAction>> entries = log.getPage(page, ENTRIES_PER_PAGE);
|
||||||
String name = ((Action) entries.values().stream().findAny().get()).getTarget().getName();
|
String name = entries.stream().findAny().get().value().getTarget().getName();
|
||||||
Message.LOG_HISTORY_TRACK_HEADER.send(sender, name, page, maxPage);
|
Message.LOG_HISTORY_TRACK_HEADER.send(sender, name, page, maxPage);
|
||||||
|
|
||||||
for (Map.Entry<Integer, LoggedAction> e : entries.entrySet()) {
|
for (Paginated.Entry<LoggedAction> e : entries) {
|
||||||
Message.LOG_ENTRY.send(sender,
|
Message.LOG_ENTRY.send(sender,
|
||||||
e.getKey(),
|
e.position(),
|
||||||
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.getValue().getDurationSince()),
|
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.value().getDurationSince()),
|
||||||
e.getValue().getSourceFriendlyString(),
|
e.value().getSourceFriendlyString(),
|
||||||
Character.toString(LoggedAction.getTypeCharacter(((Action) e.getValue()).getTarget().getType())),
|
Character.toString(LoggedAction.getTypeCharacter(e.value().getTarget().getType())),
|
||||||
e.getValue().getTargetFriendlyString(),
|
e.value().getTargetFriendlyString(),
|
||||||
e.getValue().getDescription()
|
e.value().getDescription()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,11 +40,7 @@ import me.lucko.luckperms.common.util.DurationFormatter;
|
|||||||
import me.lucko.luckperms.common.util.Paginated;
|
import me.lucko.luckperms.common.util.Paginated;
|
||||||
import me.lucko.luckperms.common.util.Predicates;
|
import me.lucko.luckperms.common.util.Predicates;
|
||||||
|
|
||||||
import net.luckperms.api.actionlog.Action;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.SortedMap;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class LogUserHistory extends ChildCommand<Log> {
|
public class LogUserHistory extends ChildCommand<Log> {
|
||||||
@ -83,18 +79,18 @@ public class LogUserHistory extends ChildCommand<Log> {
|
|||||||
return CommandResult.INVALID_ARGS;
|
return CommandResult.INVALID_ARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
SortedMap<Integer, LoggedAction> entries = log.getPage(page, ENTRIES_PER_PAGE);
|
List<Paginated.Entry<LoggedAction>> entries = log.getPage(page, ENTRIES_PER_PAGE);
|
||||||
String name = ((Action) entries.values().stream().findAny().get()).getTarget().getName();
|
String name = entries.stream().findAny().get().value().getTarget().getName();
|
||||||
Message.LOG_HISTORY_USER_HEADER.send(sender, name, page, maxPage);
|
Message.LOG_HISTORY_USER_HEADER.send(sender, name, page, maxPage);
|
||||||
|
|
||||||
for (Map.Entry<Integer, LoggedAction> e : entries.entrySet()) {
|
for (Paginated.Entry<LoggedAction> e : entries) {
|
||||||
Message.LOG_ENTRY.send(sender,
|
Message.LOG_ENTRY.send(sender,
|
||||||
e.getKey(),
|
e.position(),
|
||||||
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.getValue().getDurationSince()),
|
DurationFormatter.CONCISE_LOW_ACCURACY.format(e.value().getDurationSince()),
|
||||||
e.getValue().getSourceFriendlyString(),
|
e.value().getSourceFriendlyString(),
|
||||||
Character.toString(LoggedAction.getTypeCharacter(((Action) e.getValue()).getTarget().getType())),
|
Character.toString(LoggedAction.getTypeCharacter(e.value().getTarget().getType())),
|
||||||
e.getValue().getTargetFriendlyString(),
|
e.value().getTargetFriendlyString(),
|
||||||
e.getValue().getDescription()
|
e.value().getDescription()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ import java.util.stream.Collectors;
|
|||||||
public interface Sender {
|
public interface Sender {
|
||||||
|
|
||||||
/** The uuid used by the console sender. */
|
/** The uuid used by the console sender. */
|
||||||
UUID CONSOLE_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000");
|
UUID CONSOLE_UUID = new UUID(0, 0); // 00000000-0000-0000-0000-000000000000
|
||||||
/** The name used by the console sender. */
|
/** The name used by the console sender. */
|
||||||
String CONSOLE_NAME = "Console";
|
String CONSOLE_NAME = "Console";
|
||||||
|
|
||||||
|
@ -72,6 +72,15 @@ public final class ImmutableCollectors {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <E extends Comparable<? super E>> Collector<E, ?, ImmutableSortedSet<E>> toSortedSet() {
|
||||||
|
return Collector.of(
|
||||||
|
ImmutableSortedSet::<E>naturalOrder,
|
||||||
|
ImmutableSortedSet.Builder::add,
|
||||||
|
(l, r) -> l.addAll(r.build()),
|
||||||
|
ImmutableSortedSet.Builder::build
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static <E> Collector<E, ?, ImmutableSortedSet<E>> toSortedSet(Comparator<? super E> comparator) {
|
public static <E> Collector<E, ?, ImmutableSortedSet<E>> toSortedSet(Comparator<? super E> comparator) {
|
||||||
return Collector.of(
|
return Collector.of(
|
||||||
() -> new ImmutableSortedSet.Builder<E>(comparator),
|
() -> new ImmutableSortedSet.Builder<E>(comparator),
|
||||||
|
@ -27,11 +27,9 @@ package me.lucko.luckperms.common.util;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.SortedMap;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple pagination utility
|
* A simple pagination utility
|
||||||
@ -45,10 +43,6 @@ public class Paginated<T> {
|
|||||||
this.content = ImmutableList.copyOf(content);
|
this.content = ImmutableList.copyOf(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Paginated(Stream<T> content) {
|
|
||||||
this.content = content.collect(ImmutableCollectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<T> getContent() {
|
public List<T> getContent() {
|
||||||
return this.content;
|
return this.content;
|
||||||
}
|
}
|
||||||
@ -57,32 +51,48 @@ public class Paginated<T> {
|
|||||||
return (int) Math.ceil((double) this.content.size() / (double) entriesPerPage);
|
return (int) Math.ceil((double) this.content.size() / (double) entriesPerPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SortedMap<Integer, T> getPage(int pageNo, int entries) {
|
public List<Entry<T>> getPage(int pageNo, int pageSize) {
|
||||||
if (pageNo < 1) {
|
if (pageNo < 1) {
|
||||||
throw new IllegalArgumentException("pageNo cannot be less than 1: " + pageNo);
|
throw new IllegalArgumentException("pageNo cannot be less than 1: " + pageNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int minimumEntries = ((pageNo * entries) - entries) + 1;
|
int first = ((pageNo - 1) * pageSize);
|
||||||
if (this.content.size() < minimumEntries) {
|
if (this.content.size() <= first) {
|
||||||
throw new IllegalStateException("Content does not contain that many elements. " +
|
throw new IllegalStateException("Content does not contain that many elements. (requested page: " + pageNo +
|
||||||
"Requested: " + minimumEntries + ", Size: " + this.content.size());
|
", page size: " + pageSize + ", page first index: " + first + ", content size: " + this.content.size() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
final SortedMap<Integer, T> out = new TreeMap<>();
|
int last = first + pageSize - 1;
|
||||||
|
List<Entry<T>> out = new ArrayList<>(pageSize);
|
||||||
|
|
||||||
final int max = minimumEntries + entries - 1;
|
for (int i = first; i <= last && i < this.content.size(); i++) {
|
||||||
int index = 0;
|
out.add(new Entry<>(i + 1, this.content.get(i)));
|
||||||
for (T e : this.content) {
|
|
||||||
index++;
|
|
||||||
if (index >= minimumEntries) {
|
|
||||||
out.put(index, e);
|
|
||||||
}
|
|
||||||
if (index == max) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class Entry<T> {
|
||||||
|
private final int position;
|
||||||
|
private final T value;
|
||||||
|
|
||||||
|
public Entry(int position, T value) {
|
||||||
|
this.position = position;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int position() {
|
||||||
|
return this.position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T value() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.position + ": " + this.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user