BungeeMain / src / main / java / com / lifeknight / relaymcbungeemain / utilities / Report.java
Report.java
Raw
package com.lifeknight.relaymcbungeemain.utilities;

import com.lifeknight.relaymcbungeemain.player.SmartPlayer;
import com.lifeknight.relayutils.RelayUtils;
import com.lifeknight.relayutils.basic.Miscellaneous;
import com.lifeknight.relayutils.basic.Text;
import com.lifeknight.relayutils.player.Group;
import com.lifeknight.relayutils.utilities.ComponentBuilder;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Sound;

import java.awt.*;
import java.util.ArrayList;
import java.util.List;

import static com.lifeknight.relayutils.basic.Text.toComparable;
import static net.md_5.bungee.api.ChatColor.*;

public class Report {
    public static final List<Report> REPORTS = new ArrayList<>();

    private final int id;
    private final long time;
    private final SmartPlayer reporter;
    private final SmartPlayer reported;
    private final ReportType reportType;
    private final Server server;
    private final String reason;
    private boolean dismissed = false;
    private SmartPlayer dismisser;
    private boolean accepted;
    private String dismissMessage;
    private int tokensRewarded = 0;

    public Report(SmartPlayer reporter, SmartPlayer reported, ReportType reportType, Server server, String reason) {
        this.time = System.currentTimeMillis();
        this.reporter = reporter;
        this.reported = reported;
        this.server = server;
        this.reportType = reportType;
        this.reason = reason;
        this.id = REPORTS.size();
        REPORTS.add(this);

        onReport(this);
    }

    public long getTime() {
        return this.time;
    }

    public SmartPlayer getReporter() {
        return this.reporter;
    }

    public SmartPlayer getReported() {
        return this.reported;
    }

    public ReportType getReportType() {
        return this.reportType;
    }

    public String getReason() {
        return this.reason;
    }

    public int getId() {
        return this.id;
    }

    public boolean isDismissed() {
        return this.dismissed;
    }

    public boolean isAccepted() {
        return this.accepted;
    }

    public String getDismissMessage() {
        return this.dismissMessage;
    }

    public int getTokensRewarded() {
        return this.tokensRewarded;
    }

    public void dismiss(SmartPlayer dismisser, boolean accepted, String dismissMessage, int creditsRewarded) {
        this.dismissed = true;
        this.dismisser = dismisser;
        this.accepted = accepted;
        this.dismissMessage = dismissMessage;
        this.tokensRewarded = creditsRewarded;

        this.reporter.onReportDismiss(this);
    }

    public SmartPlayer getDismisser() {
        return this.dismisser;
    }

    public boolean hasReason() {
        return this.reason != null;
    }

    public boolean hasDismisser() {
        return this.dismisser != null;
    }

    public boolean hasDismissMessage() {
        return this.dismissMessage != null;
    }

    public BaseComponent getComponent(boolean indiscriminate) {
        ComponentBuilder componentBuilder = new ComponentBuilder();

        componentBuilder.append("%s[%s%d%s]", GRAY, WHITE, this.id, GRAY).append(" ");

        componentBuilder.append(GRAY).append("[");
        if (this.dismissed) {
            componentBuilder.color(Color.DARK_GRAY.brighter()).append("DISMISSED");
        } else {
            componentBuilder.color(ComponentBuilder.GREEN).append("ACTIVE");
        }
        componentBuilder.append(GRAY).append("] ");

        if (indiscriminate) {
            componentBuilder.append("%s[", GRAY).color(this.reportType.getColor()).append(this.reportType.toString().toUpperCase()).append("%s] ", GRAY);
        }

        if (this.reported != null) {
            componentBuilder.command(this.reported.getFormattedName(), "/spectate " + this.reported.getName(), "Spectate " + this.reported.getName() + WHITE + ".");
        }

        componentBuilder.newLine();
        componentBuilder.color(ComponentBuilder.YELLOW_GREEN).append(" - Time: ").color(Color.PINK).append(Text.getTimeString(this.time)).newLine();
        componentBuilder.color(ComponentBuilder.YELLOW_GREEN).append(" - Reporter: ").append(this.reporter.getFormattedName()).newLine();
        componentBuilder.color(ComponentBuilder.YELLOW_GREEN).append(" - Server: ");
        net.md_5.bungee.api.chat.TextComponent hover = new TextComponent(RelayUtils.format("%s[%s%s%s] ", ChatColor.GRAY, this.server.getChatColorForName(), this.server.getName(), ChatColor.GRAY));
        hover.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new net.md_5.bungee.api.chat.hover.content.Text(new BaseComponent[]{this.server.getHover()})));
        hover.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/server " + this.server.getName()));
        componentBuilder.appendComponent(hover).newLine();
        componentBuilder.color(ComponentBuilder.YELLOW_GREEN).append(" - Reason: ").color(Color.WHITE).append(this.hasReason() ? this.reason : "None");

        if (this.dismissed) {
            componentBuilder.newLine();
            componentBuilder.color(ComponentBuilder.GREEN).append(" - Dismisser: ").append(this.hasDismisser() ? this.dismisser.getFormattedName() : "Console").newLine();
            componentBuilder.color(ComponentBuilder.GREEN).append(" - Accepted: ").color(this.accepted ? ComponentBuilder.GREEN.darker() : ComponentBuilder.RED).append(Text.prettify(this.accepted)).newLine();
            componentBuilder.color(ComponentBuilder.GREEN).append(" - Message ").color(Color.WHITE).append(this.hasDismissMessage() ? this.dismissMessage : "None").newLine();
            componentBuilder.color(ComponentBuilder.GREEN).append(" - Tokens Rewarded: ").color(GOLD).append(this.tokensRewarded);
        }

        return componentBuilder.getResult();
    }

    public Server getServer() {
        return server;
    }

    public static synchronized List<Report> getReportsOfType(Object filter, boolean activeOnly) {
        if (filter instanceof SmartPlayer) {
            return Miscellaneous.filter(REPORTS, report -> report.reported == filter && (!activeOnly || !report.dismissed));
        }

        return Miscellaneous.filter(REPORTS, report -> ((filter == null && (report.reportType != ReportType.BUG || !activeOnly)) || report.reportType == filter) && (!activeOnly || !report.dismissed));
    }

    public static void onReport(Report report) {
        ComponentBuilder componentBuilder = new ComponentBuilder();
        componentBuilder.color(ComponentBuilder.RED).line().newLine();
        componentBuilder.color(Color.PINK).append("New Report:").newLine();
        componentBuilder.append(report.getComponent(true)).newLine();
        componentBuilder.color(ComponentBuilder.RED).line();

        for (SmartPlayer onlineSmartPlayer : SmartPlayer.getOnlineSmartPlayers()) {
            if (onlineSmartPlayer.isReceiveReportMessages() && onlineSmartPlayer.isStaff() && (report.reportType != ReportType.BUG || onlineSmartPlayer.isInGroup(Group.DEVELOPER))) {
                onlineSmartPlayer.sendMessage(componentBuilder);
                onlineSmartPlayer.playSound(Sound.BLOCK_NOTE_BLOCK_BIT);
            }
        }

        BotUtils.report(report);
    }

    public static synchronized int clearReports(String type) {
        int previousSize = REPORTS.size();
        REPORTS.removeIf(report -> Text.toComparable(report.reportType).equals(Text.toComparable(type)) || Text.toComparable(report.reporter.getName()).equals(Text.toComparable(type)));
        return previousSize - REPORTS.size();
    }

    public static synchronized boolean dismissReport(SmartPlayer dismisser, Integer id, boolean accepted, String reason, int tokensRewarded) {
        Report report = Miscellaneous.match(REPORTS, report1 -> report1.id == id);

        if (report == null || report.dismissed) {
            return false;
        }

        report.dismiss(dismisser, accepted, reason, tokensRewarded);

        BotUtils.onReportManaged(report);

        return true;
    }

    private static final int REPORTS_PAGE_LENGTH = 6;

    public static synchronized int getMaxReportsPage(Object reportType, boolean activeOnly) {
        return (int) Math.ceil(getReportsOfType(reportType, activeOnly).size() / (double) REPORTS_PAGE_LENGTH);
    }

    public static synchronized BaseComponent getReportsComponent(Object reportType, int page, boolean activeOnly) {
        ComponentBuilder componentBuilder = new ComponentBuilder();

        String baseCommand = "/reports " + (activeOnly ? "view" : "viewall") + " ";

        if (reportType != null) {
            if (reportType instanceof SmartPlayer) {
                baseCommand += ((SmartPlayer) reportType).getName() + " ";
            } else {
                baseCommand += toComparable(reportType) + " ";
            }
        }

        if (page > 1) {
            componentBuilder.command(GOLD + "<<", baseCommand + (page - 1), AQUA + "Click here to view the previous page.");
        } else {
            componentBuilder.append(GOLD + "||");
        }
        componentBuilder.append(" ");

        componentBuilder.gradientLine(PlayerUtilities.HALF_LINE_LENGTH, ComponentBuilder.RED, ComponentBuilder.PINK_RED).append(" %s[%d] ", GOLD, page).gradientLine(PlayerUtilities.HALF_LINE_LENGTH, ComponentBuilder.PINK_RED, ComponentBuilder.RED).append(" ");

        if (page < getMaxReportsPage(reportType, activeOnly)) {
            componentBuilder.command(GOLD + ">>", baseCommand + (page + 1), AQUA + "Click here to view the next page.");
        } else {
            componentBuilder.append(GOLD + "||");
        }

        componentBuilder.newLine();

        for (Report report : getReportsPage(reportType, page, activeOnly)) {
            componentBuilder.append(report.getComponent(reportType == null)).newLine();
        }

        componentBuilder.gradientLine(ComponentBuilder.RED, ComponentBuilder.PINK_RED, ComponentBuilder.RED);

        return componentBuilder.getResult();
    }

    public static synchronized List<Report> getReportsPage(Object reportType, int page, boolean activeOnly) {
        List<Report> queried = getReportsOfType(reportType, activeOnly);
        List<Report> results = new ArrayList<>();
        int startingIndex = REPORTS_PAGE_LENGTH * (page - 1);

        for (int i = 0; i < REPORTS_PAGE_LENGTH; i++) {
            int index = startingIndex + i;
            if (index >= queried.size()) {
                break;
            }
            results.add(queried.get(index));
        }

        return results;
    }
}