Add the ability to resolve reports

This commit is contained in:
Telesphoreo 2024-05-31 15:18:21 -05:00
parent 050b432293
commit 5ff6f526d3
8 changed files with 173 additions and 13 deletions

View File

@ -6,7 +6,7 @@ plugins {
}
group = "dev.plex"
version = "1.0-SNAPSHOT"
version = "1.1"
description = "Medina"
repositories {

View File

@ -46,6 +46,7 @@ public class ReportCommand extends MedinaCommand
player.getName(),
ZonedDateTime.now(),
reason,
false,
false);
plugin.getSqlReports().addReport(report);

View File

@ -13,19 +13,50 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@CommandParameters(name = "reports", usage = "/<command> <player> <list | delete <id>>", description = "View existing reports on a player", permission = "medina.reports", source = RequiredCommandSource.ANY)
@CommandParameters(name = "reports", usage = "/<command> [<player> list | <player> delete <id> | resolve <id>]", description = "View existing reports on a player", permission = "medina.reports", source = RequiredCommandSource.ANY)
public class ReportsCommand extends MedinaCommand
{
@Override
protected Component execute(@NotNull CommandSender sender, @Nullable Player playerSender, @NotNull String[] args)
{
if (args.length < 2)
if (args.length == 0)
{
return usage();
plugin.getSqlReports().getUnresolvedReports().whenComplete((reports, ex) ->
{
// we don't want to include deleted reports in the logic
long count = reports.stream()
.filter(report -> !report.isDeleted())
.count();
if (count <= 0)
{
send(sender, messageComponent("noUnresolvedReports"));
return;
}
listUnresolvedReports(sender, reports);
});
return null;
}
if (args[0].equalsIgnoreCase("resolve"))
{
if (args.length < 2)
{
return usage();
}
int reportId = parseInt(sender, args[1]);
plugin.getSqlReports().resolveReport(reportId).whenComplete((reports, ex) ->
{
send(sender, messageComponent("resolvedReport", reportId));
});
return null;
}
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayerIfCached(args[0]);
@ -34,6 +65,11 @@ public class ReportsCommand extends MedinaCommand
return messageComponent("playerNotFound");
}
if (args.length == 1)
{
return usage();
}
switch (args[1].toLowerCase())
{
case "list":
@ -54,6 +90,24 @@ public class ReportsCommand extends MedinaCommand
return null;
}
case "read":
{
if (args.length < 3)
{
return usage();
}
int reportId = parseInt(sender, args[2]);
plugin.getSqlReports().getReport(reportId).whenComplete((report, ex) ->
{
if (report.isDeleted())
{
send(sender, messageComponent("reportDoesntExist"));
return;
}
readReport(sender, offlinePlayer, report);
});
return null;
}
case "delete":
{
if (args.length < 3)
@ -61,7 +115,7 @@ public class ReportsCommand extends MedinaCommand
return usage();
}
int id = parseInt(sender, args[2]);
plugin.getSqlReports().getReports(id).whenComplete(((report, ex) ->
plugin.getSqlReports().getReport(id).whenComplete(((report, ex) ->
{
if (report == null)
{
@ -108,14 +162,44 @@ public class ReportsCommand extends MedinaCommand
send(sender, reportList.get());
}
private void readReport(@NotNull CommandSender sender, OfflinePlayer player, Report report)
{
AtomicReference<Component> reportList = new AtomicReference<>(Component.empty());
Component reportLine = messageComponent("reportPrefix", report.getReportId(), player.getName(), MedinaUtils.useTimezone(report.getTimestamp()));
reportLine = reportLine.append(messageComponent("reportLine", report.getReason()));
reportLine = reportLine.append(Component.newline());
reportLine = reportLine.append(messageComponent("clickToResolve", report.getReportId()));
reportList.set(reportList.get().append(reportLine));
send(sender, reportList.get());
}
private void listUnresolvedReports(@NotNull CommandSender sender, List<Report> reports)
{
AtomicReference<Component> reportList = new AtomicReference<>(messageComponent("unresolvedReports"));
for (Report report : reports)
{
if (report.isDeleted())
{
continue;
}
Component reportLine = messageComponent("reportSummary", report.getReportId(), report.getReporterName(), report.getReportedName());
reportList.set(reportList.get().append(Component.newline()));
reportList.set(reportList.get().append(reportLine));
}
send(sender, reportList.get());
}
@Override
public @NotNull List<String> smartTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException
{
if (args.length == 1 && sender.hasPermission("medina.reports"))
{
return MedinaUtils.getPlayerNameList();
List<String> options = new ArrayList<>();
options.add("resolve");
options.addAll(MedinaUtils.getPlayerNameList());
return options;
}
if (args.length == 2 && sender.hasPermission("medina.reports"))
if (args.length == 2 && !args[0].equals("resolve") && sender.hasPermission("medina.reports"))
{
return List.of("list", "delete");
}

View File

@ -33,6 +33,9 @@ public class Report
@Getter
private final String reason;
@Getter
private final boolean resolved;
@Getter
private final boolean deleted;

View File

@ -56,6 +56,7 @@ public class SQLConnection implements MedinaBase
"`reportedName` VARCHAR(18), " +
"`timestamp` BIGINT, " +
"`reason` VARCHAR(2000), " +
"`resolved` BOOLEAN, " +
"`deleted` BOOLEAN, " +
"PRIMARY KEY (`reportId`));").execute();
}

View File

@ -18,10 +18,12 @@ public class SQLReports implements MedinaBase
{
private static final String SELECT = "SELECT * FROM `reports` WHERE reportedUUID=?";
private static final String SELECT_ID = "SELECT * FROM `reports` WHERE reportId=?";
private static final String INSERT = "INSERT INTO `reports` (`reporterUUID`, `reporterName`, `reportedUUID`, `reportedName`, `timestamp`, `reason`, `deleted`) VALUES(?, ?, ?, ?, ?, ?, ?)";
private static final String SELECT_UNRESOLVED = "SELECT * FROM `reports` WHERE resolved=?";
private static final String RESOLVE = "UPDATE `reports` SET `resolved`=true WHERE reportId=?";
private static final String INSERT = "INSERT INTO `reports` (`reporterUUID`, `reporterName`, `reportedUUID`, `reportedName`, `timestamp`, `reason`, `resolved`, `deleted`) VALUES(?, ?, ?, ?, ?, ?, ?, ?)";
private static final String DELETE = "UPDATE `reports` SET `deleted`=true WHERE reportId=? AND reportedUUID=?";
public CompletableFuture<Report> getReports(int reportedId)
public CompletableFuture<Report> getReport(int reportedId)
{
return CompletableFuture.supplyAsync(() ->
{
@ -41,6 +43,7 @@ public class SQLReports implements MedinaBase
set.getString("reportedName"),
ZonedDateTime.ofInstant(Instant.ofEpochMilli(set.getLong("timestamp")), ZoneId.systemDefault()),
set.getString("reason"),
set.getBoolean("resolved"),
set.getBoolean("deleted"));
return report;
}
@ -54,6 +57,57 @@ public class SQLReports implements MedinaBase
});
}
public CompletableFuture<List<Report>> getUnresolvedReports()
{
return CompletableFuture.supplyAsync(() ->
{
List<Report> reports = Lists.newArrayList();
try (Connection con = plugin.getSqlConnection().getCon())
{
PreparedStatement statement = con.prepareStatement(SELECT_UNRESOLVED);
statement.setBoolean(1, false);
ResultSet set = statement.executeQuery();
while (set.next())
{
Report report = new Report(
set.getInt("reportId"),
UUID.fromString(set.getString("reporterUUID")),
set.getString("reporterName"),
UUID.fromString(set.getString("reportedUUID")),
set.getString("reportedName"),
ZonedDateTime.ofInstant(Instant.ofEpochMilli(set.getLong("timestamp")), ZoneId.systemDefault()),
set.getString("reason"),
set.getBoolean("resolved"),
set.getBoolean("deleted"));
reports.add(report);
}
}
catch (Throwable e)
{
e.printStackTrace();
return reports;
}
return reports;
});
}
public CompletableFuture<Void> resolveReport(int reportId)
{
return CompletableFuture.runAsync(() ->
{
try (Connection con = plugin.getSqlConnection().getCon())
{
PreparedStatement statement = con.prepareStatement(RESOLVE);
statement.setInt(1, reportId);
statement.execute();
}
catch (Throwable e)
{
e.printStackTrace();
}
});
}
public CompletableFuture<List<Report>> getReports(UUID reportedUUID)
{
return CompletableFuture.supplyAsync(() ->
@ -74,6 +128,7 @@ public class SQLReports implements MedinaBase
set.getString("reportedName"),
ZonedDateTime.ofInstant(Instant.ofEpochMilli(set.getLong("timestamp")), ZoneId.systemDefault()),
set.getString("reason"),
set.getBoolean("resolved"),
set.getBoolean("deleted"));
reports.add(report);
}
@ -120,7 +175,8 @@ public class SQLReports implements MedinaBase
statement.setString(4, report.getReportedName());
statement.setLong(5, report.getTimestamp().toInstant().toEpochMilli());
statement.setString(6, report.getReason());
statement.setBoolean(7, report.isDeleted());
statement.setBoolean(7, report.isResolved());
statement.setBoolean(8, report.isDeleted());
statement.execute();
}
catch (Throwable e)

View File

@ -19,7 +19,7 @@ import java.util.stream.Collectors;
public class MedinaUtils implements MedinaBase
{
private static final MiniMessage MINI_MESSAGE = MiniMessage.miniMessage();
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("MM/dd/yyyy 'at' hh:mm:ss a z");
private static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("MM/dd/yyyy 'at' hh:mm:ss a");
public static Component mmDeserialize(String input)
{

View File

@ -29,7 +29,7 @@ reportHeader: "<gold>Player reports for: <yellow>{0}"
# 0 - Report ID
# 1 - Author of the note
# 2 - Timestamp
reportPrefix: "<gold><!italic>{0} - Written by: {1} on {2}"
reportPrefix: "<gold><!italic>{0} - Reported by: {1} on {2}"
# 0 - The content of the report
reportLine: "<newline><yellow># {0}"
@ -44,4 +44,19 @@ reportDoesntExist: "<red>There is no report with this ID belonging to that playe
# 2 - The reason for the report
notifyReport: "<dark_gray>[<yellow>REPORT<dark_gray>] <gold>{0} reported {1} for {2}"
cantReportYourself: "<red>You cannot report yourself."
cantReportYourself: "<red>You cannot report yourself."
# 0 - The report ID
resolvedReport: "<green>Report with ID: {0} has been resolved!"
unresolvedReports: "<gold>--- Unresolved Reports ---"
# 0 - The report ID
# 1 - The reporter name
# 2 - The reported name
reportSummary: "<gold>ID: <yellow>{0}<gold>, <yellow>{1}<gold> reported <yellow>{2}<gold> - <green><click:run_command:/reports {2} read {0}>Click to view</click>"
noUnresolvedReports: "<red>There are no unresolved reports."
# 0 - The report ID
clickToResolve: "<green><click:run_command:/reports resolve {0}>Click to resolve</click>"