Don't allow a user to handle more than one report simultaneously

This commit is contained in:
Keir Nellyer 2016-06-27 17:56:01 +01:00
parent dbf0bf35b4
commit 42bd2148e5
3 changed files with 95 additions and 28 deletions

View File

@ -1,12 +1,16 @@
package mineplex.core.report;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Function;
import java.util.logging.Level;
import com.google.common.base.Preconditions;
import com.sun.org.apache.xpath.internal.operations.Bool;
import mineplex.core.account.CoreClientManager;
import mineplex.core.chatsnap.Snapshot;
import mineplex.core.chatsnap.SnapshotManager;
@ -219,6 +223,26 @@ public class ReportManager
return calculatePriority(report).thenApply(priority -> priority > 0);
}
public CompletableFuture<Boolean> isHandlingReport(Player player)
{
return isHandlingReport(_clientManager.getAccountId(player));
}
public CompletableFuture<Boolean> isHandlingReport(int accountId)
{
return _reportRepository.getReportsHandling(accountId).thenApply(reportIds -> {
for (long reportId : reportIds)
{
if (isActiveReport(reportId).join())
{
return true;
}
}
return false;
});
}
public CompletableFuture<Double> calculatePriority(Report report)
{
return CompletableFuture.supplyAsync(() ->

View File

@ -73,6 +73,11 @@ public class ReportRepository extends MinecraftRepository
" AND reports.suspectId = ?" +
" AND reports.categoryId = ?;";
private static final String GET_REPORTS_HANDLING = "SELECT reports.id FROM reports, reportHandlers, reportResults" +
" WHERE reports.id = reportHandlers.reportId" +
" AND reports.id = reportResults.reportId" +
" AND reportHandlers.handlerId = ?;";
private static final String GET_USER_RESULT_COUNT = "SELECT COUNT(reports.id) AS resultCount" +
" FROM reports, reportReasons, reportResults" +
" WHERE reports.id = reportReasons.reportId" +
@ -137,6 +142,33 @@ public class ReportRepository extends MinecraftRepository
});
}
public CompletableFuture<List<Long>> getReportsHandling(int accountId)
{
return CompletableFuture.supplyAsync(() ->
{
List<Long> reportsHandling = new ArrayList<>();
try (Connection connection = DBPool.getAccount().getConnection())
{
PreparedStatement preparedStatement = connection.prepareStatement(GET_REPORTS_HANDLING);
preparedStatement.setInt(1, accountId);
ResultSet resultSet = preparedStatement.executeQuery();
while (resultSet.next())
{
reportsHandling.add(resultSet.getLong("reports.id"));
}
}
catch (SQLException e)
{
throw new RuntimeException(e);
}
return reportsHandling;
});
}
public CompletableFuture<List<Report>> getReports(Collection<Integer> reportIds)
{
return CompletableFuture.supplyAsync(() -> reportIds.parallelStream()

View File

@ -16,6 +16,7 @@ import mineplex.core.report.ReportManager;
import mineplex.core.report.ReportPlugin;
import mineplex.core.report.ReportRepository;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class ReportHandleCommand extends CommandBase<ReportPlugin>
@ -34,42 +35,52 @@ public class ReportHandleCommand extends CommandBase<ReportPlugin>
ReportManager reportManager = Plugin.getReportManager();
ReportRepository reportRepository = reportManager.getReportRepository();
// TODO check if already handling report
Map<Report, Double> reportPriorities = Collections.synchronizedMap(new HashMap<>());
// the below fetches the ids of all unhandled reports and gets a Report object for each of these ids
// the priority of the report is then calculated and the results placed in a map
reportRepository.getUnhandledReports().thenCompose(reportRepository::getReports).thenAccept(reports ->
CompletableFuture.allOf(reports.stream().map(report ->
reportManager.calculatePriority(report).thenAccept(priority ->
reportPriorities.put(report, priority)
)
).toArray(CompletableFuture[]::new)).join()
).thenApply(aVoid ->
reportManager.isHandlingReport(player).thenAccept(isHandlingReport ->
{
Map.Entry<Report, Double> mostImportant = null;
for (Map.Entry<Report, Double> entry : reportPriorities.entrySet())
if (!isHandlingReport)
{
if (mostImportant == null || entry.getValue() > mostImportant.getValue())
Map<Report, Double> reportPriorities = Collections.synchronizedMap(new HashMap<>());
// the below fetches the ids of all unhandled reports and gets a Report object for each of these ids
// the priority of the report is then calculated and the results placed in a map
reportRepository.getUnhandledReports().thenCompose(reportRepository::getReports).thenAccept(reports ->
CompletableFuture.allOf(reports.stream().map(report ->
reportManager.calculatePriority(report).thenAccept(priority ->
reportPriorities.put(report, priority)
)
).toArray(CompletableFuture[]::new)).join()
).thenApply(aVoid ->
{
mostImportant = entry;
}
}
Map.Entry<Report, Double> mostImportant = null;
return mostImportant == null ? null : mostImportant.getKey();
}).thenCompose(BukkitFuture.accept(report ->
{
if (report != null)
{
reportManager.handleReport(report, player);
for (Map.Entry<Report, Double> entry : reportPriorities.entrySet())
{
if (mostImportant == null || entry.getValue() > mostImportant.getValue())
{
mostImportant = entry;
}
}
return mostImportant == null ? null : mostImportant.getKey();
}).thenCompose(BukkitFuture.accept(report ->
{
if (report != null)
{
reportManager.handleReport(report, player);
}
else
{
UtilPlayer.message(player, F.main(Plugin.getName(), C.cRed + "No report found, report queue is empty."));
}
}));
}
else
{
UtilPlayer.message(player, F.main(Plugin.getName(), C.cRed + "No report found, report queue is empty."));
Bukkit.getScheduler().runTask(Plugin.getPlugin(), () ->
UtilPlayer.message(player, F.main(Plugin.getName(), C.cRed + "You are already handling a report.")));
}
}));
});
}
else
{