Files
AuxProtect-Folia/src/main/java/dev/heliosares/auxprotect/database/Results.java
2024-07-17 21:40:43 -04:00

352 lines
19 KiB
Java

package dev.heliosares.auxprotect.database;
import dev.heliosares.auxprotect.adapters.sender.SenderAdapter;
import dev.heliosares.auxprotect.core.APPermission;
import dev.heliosares.auxprotect.core.APPlayer;
import dev.heliosares.auxprotect.core.ActivityRecord;
import dev.heliosares.auxprotect.core.IAuxProtect;
import dev.heliosares.auxprotect.core.Language;
import dev.heliosares.auxprotect.core.Parameters;
import dev.heliosares.auxprotect.core.Parameters.Flag;
import dev.heliosares.auxprotect.exceptions.BusyException;
import dev.heliosares.auxprotect.spigot.AuxProtectSpigot;
import dev.heliosares.auxprotect.spigot.VeinManager;
import dev.heliosares.auxprotect.utils.InvSerialization;
import dev.heliosares.auxprotect.utils.TimeUtil;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.ItemTag;
import net.md_5.bungee.api.chat.hover.content.Item;
import net.md_5.bungee.api.chat.hover.content.Text;
import org.bukkit.inventory.ItemStack;
import java.io.IOException;
import java.sql.SQLException;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import java.util.TimeZone;
public class Results {
protected final SenderAdapter player;
final IAuxProtect plugin;
private final List<DbEntry> entries;
private final Parameters params;
private int perPage = 4;
private int currentPage = 0;
public Results(IAuxProtect plugin, List<DbEntry> entries, SenderAdapter player, Parameters params) {
this.entries = entries;
this.player = player;
this.plugin = plugin;
boolean allNullWorld = true;
int count = 0;
for (DbEntry entry : entries) {
if (entry.getWorld() != null && !entry.getWorld().equals("#null")) {
allNullWorld = false;
break;
}
if (count++ > 1000) {
break;
}
}
if (allNullWorld) {
setPerPage(10);
}
this.params = params;
}
public static void sendEntry(IAuxProtect plugin, SenderAdapter player, DbEntry entry, int index, boolean time, boolean coords, boolean showData) throws SQLException, BusyException {
String commandPrefix = "/" + plugin.getCommandPrefix();
ComponentBuilder message = new ComponentBuilder();
if (entry.getUser(false) == null) plugin.getSqlManager().execute(c -> entry.getUser(), 3000L);
if (entry.getTarget(false) == null) plugin.getSqlManager().execute(c -> entry.getTarget(), 3000L);
plugin.debug(entry.getTarget() + "(" + entry.getTargetId() + "): " + entry.getTargetUUID());
APPlayer<?> apPlayer = plugin.getAPPlayer(player);
TimeZone timeZone = time ? (apPlayer == null ? TimeZone.getDefault() : apPlayer.getTimeZone()) : null;
if (entry instanceof DbEntryGroup group) {
if (time) {
message.append(Language.L.RESULTS__TIME.translate(TimeUtil.millisToString(System.currentTimeMillis() - group.getFirstTime()) +
"-" + TimeUtil.millisToString(System.currentTimeMillis() - group.getLastTime())))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT,
new Text(TimeUtil.format(group.getFirstTime(), TimeUtil.entryTimeFormat, timeZone.toZoneId()) + " -\n" + TimeUtil.format(group.getLastTime(), TimeUtil.entryTimeFormat, apPlayer.getTimeZone().toZoneId())
+ "\n" + Language.L.RESULTS__CLICK_TO_COPY_TIME.translate(entry.getTime()))))
.event(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, group.getFormattedEpoch()));
}
message.append(" ").event((HoverEvent) null).event((ClickEvent) null);
message.append(Language.L.RESULTS__GROUPING_OF.translate(group.getNumEntries())).event(new ClickEvent(
ClickEvent.Action.RUN_COMMAND, commandPrefix + " lookup " + group.hash() + "g"));
} else {
if (time) entry.appendTime(message, timeZone);
String actionColor = ChatColor.COLOR_CHAR + "7-";
if (entry.getAction().hasDual) {
actionColor = entry.getState() ? ChatColor.COLOR_CHAR + "a+" : ChatColor.COLOR_CHAR + "c-";
}
message.append(" " + actionColor + " ").event((HoverEvent) null);
HoverEvent clickToCopy = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.L.RESULTS__CLICK_TO_COPY.translate()));
message.append(ChatColor.COLOR_CHAR + "9" + entry.getUser()).event(clickToCopy)
.event(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, entry.getUser()));
message.append(" " + ChatColor.COLOR_CHAR + "f" + entry.getAction().getText(entry.getState())).event((HoverEvent) null)
.event((ClickEvent) null);
if (entry.getTarget() != null && !entry.getTarget().isEmpty()) {
HoverEvent hoverEvent = null;
if (entry instanceof TransactionEntry transaction) {
if (transaction.getQuantity() > 0) {
message.append(ChatColor.BLUE + " " + transaction.getQuantity()).event((ClickEvent) null).event((HoverEvent) null);
}
if (transaction.getBlob() != null && transaction.getBlob().length > 0) {
try {
ItemStack item = InvSerialization.toItemStack(transaction.getBlob());
if (item.hasItemMeta()) {
ItemTag tag = ItemTag.ofNbt(Objects.requireNonNull(item.getItemMeta()).getAsString());
hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_ITEM, new Item(item.getType().getKey().getKey(), transaction.getQuantity(), tag));
}
} catch (ClassNotFoundException | IOException e) {
plugin.warning("Error while deserializing item " + transaction);
}
}
}
message.append(" " + (hoverEvent == null ? ChatColor.BLUE : (ChatColor.AQUA + "[")) + entry.getTarget() + (hoverEvent == null ? "" : "]"));
message.event(hoverEvent == null ? clickToCopy : hoverEvent);
message.event(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, entry.getTarget() /* Still using the base target here for TransactionEntry because I think it's the most useful. */));
} else {
message.event((ClickEvent) null).event((HoverEvent) null);
}
if (entry instanceof TransactionEntry transaction) {
String target2 = transaction.getTarget2();
if (target2 != null && !target2.isEmpty() && showData) {
String fromTo = entry.getState() ? "from" : "to";
message.append(ChatColor.COLOR_CHAR + "f " + fromTo + " ").event((ClickEvent) null).event((HoverEvent) null);
message.append(ChatColor.COLOR_CHAR + "9" + target2).event(clickToCopy).event(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, target2));
}
message.append(ChatColor.COLOR_CHAR + "f for ").event((ClickEvent) null).event((HoverEvent) null);
String cost = plugin.formatMoney(transaction.getCost());
message.append(ChatColor.COLOR_CHAR + "9" + cost).event(clickToCopy).event(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, cost));
if (showData) {
message.append(" " + ChatColor.DARK_GRAY + "[").event((ClickEvent) null).event((HoverEvent) null);
String balance = plugin.formatMoney(transaction.getBalance());
message.append(ChatColor.GRAY + "Balance: " + balance).event(clickToCopy).event(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, balance));
message.append(ChatColor.DARK_GRAY + "]").event((ClickEvent) null).event((HoverEvent) null);
}
}
if (showData) {
if (entry instanceof XrayEntry xray) {
String rating;
if (xray.getRating() == -2) {
rating = ChatColor.COLOR_CHAR + "5Ignored";
} else if (xray.getRating() == -1) {
rating = ChatColor.COLOR_CHAR + "7Unrated";
} else {
rating = xray.getRating() + "";
}
String color = VeinManager.getSeverityColor(xray.getRating());
message.append(String.format(" " + ChatColor.COLOR_CHAR + "8[%s%s" + ChatColor.COLOR_CHAR + "8]", color, rating)).event(new ClickEvent(
ClickEvent.Action.RUN_COMMAND, "/" + plugin.getCommandPrefix() + " xray rate " + entry.getTime()));
String hover = "";
if (xray.getRating() >= 0) {
hover += color + VeinManager.getSeverityDescription(xray.getRating()) + "\n\n";
}
hover += Language.translate(Language.L.XRAY_CLICK_TO_CHANGE);
message.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(hover)));
}
if (entry.hasBlob()) {
if (APPermission.INV.hasPermission(player)) {
message.append(" " + ChatColor.COLOR_CHAR + "a[" + Language.L.RESULTS__VIEW + "]")
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
String.format(commandPrefix + " inv %d", index)))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.L.RESULTS__CLICK_TO_VIEW.translate())));
}
}
if (entry.getAction().equals(EntryAction.KILL)) {
if (APPermission.INV.hasPermission(player) && !entry.getTarget().startsWith("#")) {
message.append(" " + ChatColor.COLOR_CHAR + "a[" + Language.L.RESULTS__VIEW_INV + "]")
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND,
String.format(commandPrefix + " l u:%s a:inventory target:death time:%de+-20e",
entry.getTarget(), entry.getTime())))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.L.RESULTS__CLICK_TO_VIEW.translate())));
}
}
if (entry instanceof SingleItemEntry sientry) {
message.append(" " + ChatColor.COLOR_CHAR + "8[" + ChatColor.COLOR_CHAR + "7x" + sientry.getQty() + (sientry.getDamage() > 0 ? ", " + sientry.getDamage() + " damage" : "") + ChatColor.COLOR_CHAR + "8]").event((HoverEvent) null).event((ClickEvent) null);
}
String data = entry.getData();
if (data != null && !data.isEmpty()) {
HoverEvent hoverEvent = clickToCopy;
if (entry.getAction().equals(EntryAction.ACTIVITY)) {
try {
ActivityRecord record = ActivityRecord.parse(data);
if (record != null) {
message.append(" " + org.bukkit.ChatColor.COLOR_CHAR + "a" + record.countScore());
hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.L.RESULTS__CLICK_TO_COPY.translate() + record.getHoverText()));
}
} catch (IllegalArgumentException ignored) {
}
}
if (entry.getAction().equals(EntryAction.SESSION) && !APPermission.LOOKUP_ACTION.dot(EntryAction.SESSION.toString().toLowerCase()).dot("ip").hasPermission(player)) {
message.append(" " + ChatColor.COLOR_CHAR + "8[" + ChatColor.COLOR_CHAR + "7" + Language.L.RESULTS__REDACTED.translate() + ChatColor.COLOR_CHAR + "8]");
message.event((ClickEvent) null).event((HoverEvent) null);
} else {
message.append(" " + ChatColor.COLOR_CHAR + "8[" + ChatColor.COLOR_CHAR + "7" + data + ChatColor.COLOR_CHAR + "8]");
message.event(hoverEvent).event(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, data));
}
}
if (entry.getAction().equals(EntryAction.ACTIVITY)) {
message.append(" " + ChatColor.COLOR_CHAR + "8[" + ChatColor.COLOR_CHAR + "7Copy Minute Range" + ChatColor.COLOR_CHAR + "8]");
ZonedDateTime zonedDateTime = Instant.ofEpochMilli(entry.getTime()).atZone(ZoneId.systemDefault());
ZonedDateTime start = zonedDateTime.withSecond(0).withNano(0);
ZonedDateTime end = start.plusMinutes(1).minusNanos(1000000);
message.event(clickToCopy).event(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, start.toInstant().toEpochMilli() + "e-" + end.toInstant().toEpochMilli() + "e"));
}
}
}
if (entry.getWorld() != null && !entry.getWorld().equals("$null") && coords) {
entry.appendCoordinates(player, message);
}
player.sendMessage(message.create());
}
public void setPerPage(int perPage) {
this.perPage = perPage;
}
protected void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public List<DbEntry> getEntries() {
return entries;
}
public DbEntry get(int i) {
return getEntries().get(i);
}
public void sendHeader() {
String headerColor = "&7";
StringBuilder line = new StringBuilder("&m");
line.append(String.valueOf((char) 65293).repeat(6));
line.append("&7");
if (new Random().nextDouble() < 0.001) {
headerColor = "&f"; // The header had these mismatched colors for over a year of development until
// v1.1.3. This is a tribute to that screw up
}
player.sendMessageRaw(headerColor + line + " " + Language.L.RESULTS__HEADER + "&7 " + line);
}
public void showPage(int page) throws SQLException, BusyException {
showPage(page, getPerPage());
}
public void showPage(int page, int perPage_) throws SQLException, BusyException {
int lastpage = getNumPages(perPage_);
if (page > lastpage || page < 1) {
player.sendLang(Language.L.COMMAND__LOOKUP__NOPAGE);
return;
}
setPerPage(perPage_);
setCurrentPage(page);
sendHeader();
for (int i = (page - 1) * getPerPage(); i < (page) * getPerPage() && i < getEntries().size(); i++) {
DbEntry en = getEntries().get(i);
sendEntry(en, i);
}
sendArrowKeys(page);
}
public void sendEntry(DbEntry entry, int index) throws SQLException, BusyException {
sendEntry(plugin, player, entry, index, true, !params.hasFlag(Flag.HIDE_COORDS), !params.hasFlag(Flag.HIDE_DATA));
}
protected String getCommandPrefix() {
return "/" + plugin.getCommandPrefix() + " l ";
}
protected String getCommand(int which) {
return switch (which) {
case -2 -> "1:" + getPerPage();
case -1 -> (currentPage - 1) + ":" + getPerPage();
case 1 -> (currentPage + 1) + ":" + getPerPage();
case 2 -> getNumPages(getPerPage()) + ":" + getPerPage();
default -> throw new IllegalArgumentException();
};
}
public void sendArrowKeys(int page) {
ComponentBuilder message = new ComponentBuilder();
int lastpage = getNumPages(getPerPage());
message.append(ChatColor.COLOR_CHAR + "7(");
if (page > 1) {
message.append(ChatColor.COLOR_CHAR + "9" + ChatColor.COLOR_CHAR + "l" + AuxProtectSpigot.LEFT_ARROW + AuxProtectSpigot.LEFT_ARROW)
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, getCommandPrefix() + getCommand(-2)))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.L.RESULTS__PAGE__FIRST.translate())));
message.append(" ").event((ClickEvent) null).event((HoverEvent) null);
message.append(ChatColor.COLOR_CHAR + "9" + ChatColor.COLOR_CHAR + "l" + AuxProtectSpigot.LEFT_ARROW)
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, getCommandPrefix() + getCommand(-1)))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.L.RESULTS__PAGE__PREVIOUS.translate())));
} else {
message.event(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, ""));
message.append(ChatColor.COLOR_CHAR + "8" + ChatColor.COLOR_CHAR + "l" + AuxProtectSpigot.LEFT_ARROW + AuxProtectSpigot.LEFT_ARROW).event((ClickEvent) null)
.event((HoverEvent) null);
message.append(" ");
message.append(ChatColor.COLOR_CHAR + "8" + ChatColor.COLOR_CHAR + "l" + AuxProtectSpigot.LEFT_ARROW);
}
message.append(" ").event((ClickEvent) null).event((HoverEvent) null);
if (page < lastpage) {
message.append(ChatColor.COLOR_CHAR + "9" + ChatColor.COLOR_CHAR + "l" + AuxProtectSpigot.RIGHT_ARROW)
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, getCommandPrefix() + getCommand(1)))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.L.RESULTS__PAGE__NEXT.translate())));
message.append(" ").event((ClickEvent) null).event((HoverEvent) null);
message.append(ChatColor.COLOR_CHAR + "9" + ChatColor.COLOR_CHAR + "l" + AuxProtectSpigot.RIGHT_ARROW + AuxProtectSpigot.RIGHT_ARROW)
.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, getCommandPrefix() + getCommand(2)))
.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(Language.L.RESULTS__PAGE__LAST.translate())));
} else {
message.append(ChatColor.COLOR_CHAR + "8" + ChatColor.COLOR_CHAR + "l" + AuxProtectSpigot.RIGHT_ARROW).event((ClickEvent) null).event((HoverEvent) null);
message.append(" ");
message.append(ChatColor.COLOR_CHAR + "8" + ChatColor.COLOR_CHAR + "l" + AuxProtectSpigot.RIGHT_ARROW + AuxProtectSpigot.RIGHT_ARROW);
}
message.append(ChatColor.COLOR_CHAR + "7) ").event((ClickEvent) null).event((HoverEvent) null);
Language.L lang;
if (entries.get(0) instanceof DbEntryGroup) {
lang = Language.L.COMMAND__LOOKUP__PAGE_FOOTER_GROUPS;
} else {
lang = Language.L.COMMAND__LOOKUP__PAGE_FOOTER;
}
message.append(Language.translate(lang, page, getNumPages(getPerPage()), getEntries().size()));
player.sendMessage(message.create());
}
public int getNumPages(int perpage) {
return (int) Math.ceil(getEntries().size() / (double) perpage);
}
public int getSize() {
return getEntries().size();
}
public int getPerPage() {
return perPage;
}
public int getCurrentPage() {
return currentPage;
}
}