Make reports timeout after 15 minutes of inactivity.

This commit is contained in:
Keir 2015-11-20 00:51:21 +00:00
parent bceb69bc12
commit 80c87fa1fc
5 changed files with 166 additions and 42 deletions

View File

@ -3,12 +3,15 @@ package mineplex.core.report;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import mineplex.serverdata.data.Data;
public class Report implements Data
{
private static final int TIMEOUT_MINS = 15;
private int _reportId;
public int getReportId() { return _reportId; }
@ -31,6 +34,9 @@ public class Report implements Data
private ReportCategory _category;
public ReportCategory getCategory() { return _category; }
private long _lastActivity;
public long getLastActivity() { return _lastActivity; }
public Report(int reportId, String playerName, String serverName, ReportCategory category)
{
_reportId = reportId;
@ -38,8 +44,26 @@ public class Report implements Data
_serverName = serverName;
_reportReasons = new HashMap<>();
_category = category;
updateLastActivity();
}
/**
* Checks if a report is still active.
* This is determined by checking if the last activity was within the last 15 minutes.
*
* @return true if active, false if expired
*/
public boolean isActive()
{
return _lastActivity + TimeUnit.MINUTES.toMillis(TIMEOUT_MINS) >= System.currentTimeMillis();
}
public void updateLastActivity()
{
_lastActivity = System.currentTimeMillis();
}
@Override
public String getDataId()
{

View File

@ -1,8 +1,8 @@
package mineplex.core.report;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import mineplex.core.account.CoreClient;
import mineplex.core.command.CommandCenter;
@ -16,6 +16,7 @@ import mineplex.core.preferences.PreferencesManager;
import mineplex.core.report.command.ReportHandlerNotification;
import mineplex.core.report.command.ReportNotificationCallback;
import mineplex.core.report.command.ReportNotification;
import mineplex.core.report.task.ReportHandlerMessageTask;
import mineplex.serverdata.Region;
import mineplex.serverdata.Utility;
import mineplex.serverdata.commands.ServerCommandManager;
@ -74,11 +75,11 @@ public class ReportManager {
public void closeReport(int reportId, Player reportCloser, String reason,
ReportResult result)
{
if (isActiveReport(reportId))
Report report = getReport(reportId);
if (report != null)
{
Report report = getReport(reportId);
_reportRepository.removeElement(String.valueOf(reportId)); // Remove report from redis database
removeActiveReport(reportId);
removeReport(reportId);
int closerId = reportCloser != null ? getPlayerAccount(reportCloser).getAccountId() : -1;
String playerName = report.getPlayerName();
@ -91,7 +92,7 @@ public class ReportManager {
CoreClient reporterAccount = getPlayerAccount(reporterName);
ReportProfile reportProfile = getReportProfile(String.valueOf(reporterAccount.getAccountId()));
reportProfile.onReportClose(result);
_reportProfiles.addElement(reportProfile);
saveReportProfile(reportProfile);
}
if (reportCloser != null)
@ -109,16 +110,16 @@ public class ReportManager {
public void handleReport(int reportId, Player reportHandler)
{
if (_reportRepository.elementExists(String.valueOf(reportId)))
{
Report report = getReport(reportId);
Report report = getReport(reportId);
if (report != null)
{
if (report.getHandler() != null) {
reportHandler.sendMessage(F.main(getReportPrefix(reportId), String.format("%s is already handling this report.", report.getHandler())));
} else {
String handlerName = reportHandler.getName();
report.setHandler(handlerName);
_reportRepository.addElement(report); // update existing value in Redis
saveReport(report);
sendStaffNotification(F.main(getReportPrefix(reportId), String.format("%s is handling this report.", handlerName)));
Portal.transferPlayer(reportHandler.getName(), report.getServerName());
@ -139,22 +140,21 @@ public class ReportManager {
if (reportProfile.canReport())
{
int reportId = getActiveReport(reportedPlayer.getName());
Report report = getReport(reportId);
Report report = getActiveReport(reportedPlayer.getName());
if (reportId != -1 && report.getCategory() == category)
if (report != null && report.getCategory() == category)
{
report.addReporter(reporter.getName(), reason);
}
else
{
reportId = generateReportId();
report = new Report(reportId, reportedPlayer.getName(), _serverName, category);
report = new Report(generateReportId(), reportedPlayer.getName(), _serverName, category);
report.addReporter(reporter.getName(), reason);
_activeReports.put(reportedPlayer.getName().toLowerCase(), report.getReportId());
}
_reportRepository.addElement(report); // add (or update) the report to Redis
int reportId = report.getReportId();
saveReport(report);
// only start notifying staff when
if (report.getReporters().size() >= category.getNotifyThreshold())
@ -197,9 +197,8 @@ public class ReportManager {
{
if (hasActiveReport(player))
{
int reportId = getActiveReport(player.getName());
Report report = getReport(reportId);
sendHandlerNotification(report, F.main(getReportPrefix(reportId), String.format("%s has re-joined the game.", player.getName())));
Report report = getActiveReport(player.getName());
sendHandlerNotification(report, F.main(getReportPrefix(report), String.format("%s has re-joined the game.", player.getName())));
}
}
@ -207,9 +206,8 @@ public class ReportManager {
{
if (hasActiveReport(player))
{
int reportId = getActiveReport(player.getName());
Report report = getReport(reportId);
sendHandlerNotification(report, F.main(getReportPrefix(reportId), String.format("%s has left the game.", player.getName())));
Report report = getActiveReport(player.getName());
sendHandlerNotification(report, F.main(getReportPrefix(report), String.format("%s has left the game.", player.getName())));
}
}
@ -266,19 +264,21 @@ public class ReportManager {
return _reportRepository.getElement(String.valueOf(reportId));
}
private CoreClient getPlayerAccount(Player player)
/**
* Updates the instance of a report in the repository.
* Also updates the last activity field.
*
* @param report the report to be saved
*/
public void saveReport(Report report)
{
return getPlayerAccount(player.getName());
report.updateLastActivity();
_reportRepository.addElement(report);
}
private CoreClient getPlayerAccount(String playerName)
public void removeReport(int reportId)
{
return CommandCenter.Instance.GetClientManager().Get(playerName);
}
private int getAccountId(String playerName)
{
return getPlayerAccount(playerName).getAccountId();
_reportRepository.removeElement(String.valueOf(reportId));
}
/**
@ -352,25 +352,26 @@ public class ReportManager {
* @return the report id for the active report corresponding with playerName, if one
* currently exists, -1 otherwise.
*/
public int getActiveReport(String playerName)
public Report getActiveReport(String playerName)
{
if (_activeReports.containsKey(playerName.toLowerCase()))
Integer reportId = _activeReports.get(playerName.toLowerCase());
if (reportId != null)
{
return _activeReports.get(playerName.toLowerCase());
return getReport(reportId);
}
return -1;
return null;
}
// TODO this and related methods only function on the server where the report was created
public boolean hasActiveReport(Player player)
{
return getActiveReport(player.getName()) != -1;
return getActiveReport(player.getName()) != null;
}
public boolean isActiveReport(int reportId)
{
for (Entry<String, Integer> activeReport : _activeReports.entrySet())
for (Map.Entry<String, Integer> activeReport : _activeReports.entrySet())
{
if (activeReport.getValue() == reportId)
{
@ -383,7 +384,7 @@ public class ReportManager {
public boolean removeActiveReport(int reportId)
{
for (Entry<String, Integer> activeReport : _activeReports.entrySet())
for (Map.Entry<String, Integer> activeReport : _activeReports.entrySet())
{
if (activeReport.getValue() == reportId)
{
@ -395,8 +396,35 @@ public class ReportManager {
return false;
}
public Collection<Integer> getActiveReports()
{
return _activeReports.values();
}
/* PRIVATE STATIC HELPERS */
private static String getReportPrefix(Report report)
{
return getReportPrefix(report.getReportId());
}
private static String getReportPrefix(int reportId)
{
return NAME + " #" + reportId;
}
private static CoreClient getPlayerAccount(Player player)
{
return getPlayerAccount(player.getName());
}
private static CoreClient getPlayerAccount(String playerName)
{
return CommandCenter.Instance.GetClientManager().Get(playerName);
}
private static int getAccountId(String playerName)
{
return getPlayerAccount(playerName).getAccountId();
}
}

View File

@ -4,6 +4,7 @@ import mineplex.core.MiniPlugin;
import mineplex.core.report.command.ReportCloseCommand;
import mineplex.core.report.command.ReportCommand;
import mineplex.core.report.command.ReportHandleCommand;
import mineplex.core.report.task.ReportPurgeTask;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
@ -13,12 +14,24 @@ import org.bukkit.plugin.java.JavaPlugin;
public class ReportPlugin extends MiniPlugin
{
private final ReportManager _reportManager;
private ReportPurgeTask _reportPurgeTask;
public ReportPlugin(JavaPlugin plugin, ReportManager reportManager)
{
super("Report", plugin);
_reportManager = reportManager;
// purge old reports every minute
// TODO does this need to be async?
_reportPurgeTask = new ReportPurgeTask(_reportManager);
_reportPurgeTask.runTaskTimer(getPlugin(), 20L * 10, 20L *60);
}
@Override
public void disable()
{
_reportPurgeTask.cancel();
}
public ReportManager getReportManager()

View File

@ -1,4 +1,4 @@
package mineplex.core.report;
package mineplex.core.report.task;
import java.util.Map;
@ -6,6 +6,8 @@ import org.bukkit.scheduler.BukkitRunnable;
import mineplex.core.common.jsonchat.JsonMessage;
import mineplex.core.common.util.C;
import mineplex.core.report.Report;
import mineplex.core.report.ReportManager;
import mineplex.core.report.command.ReportHandlerNotification;
import org.apache.commons.lang3.StringUtils;

View File

@ -0,0 +1,57 @@
package mineplex.core.report.task;
import org.bukkit.scheduler.BukkitRunnable;
import mineplex.core.report.Report;
import mineplex.core.report.ReportManager;
/**
* Checks reports "owned" by this instance for inactivity, purges inactive reports.
* @author iKeirNez
*/
public class ReportPurgeTask extends BukkitRunnable
{
private ReportManager _reportManager;
public ReportPurgeTask(ReportManager reportManager)
{
_reportManager = reportManager;
}
@Override
public void run()
{
for (int reportId : _reportManager.getActiveReports())
{
Report report = _reportManager.getReport(reportId);
if (report != null)
{
checkReportActive(report);
}
else
{
// report has been leftover for some reason
purgeReport(reportId);
}
}
}
public boolean checkReportActive(Report report)
{
if (!report.isActive())
{
int reportId = report.getReportId();
purgeReport(reportId);
return false;
}
return true;
}
public void purgeReport(int reportId)
{
_reportManager.removeReport(reportId);
_reportManager.removeActiveReport(reportId);
}
}