Show the handler of the report a message every 10 seconds whilst they are handling a report. Any part of the message is clickable and when clicked shows the close report GUI.

Jazz-up messages sent to players.
Rename Category to ReportCategory.
This commit is contained in:
Keir 2015-11-13 01:23:33 +00:00
parent 27d5c76376
commit a6d3ba10c2
9 changed files with 228 additions and 58 deletions

View File

@ -1,8 +1,8 @@
package mineplex.core.report;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import mineplex.serverdata.data.Data;
@ -18,24 +18,25 @@ public class Report implements Data
private String _playerName;
public String getPlayerName() { return _playerName; }
// Set of account ids of players who contributed to reporting this player
private Set<String> _reporters;
public Set<String> getReporters() { return _reporters; }
public void addReporter(String reporter) { _reporters.add(reporter); }
// Set of player names and the reason they reported this player
private Map<String, String> _reportReasons;
public Map<String, String> getReportReasons() { return _reportReasons; }
public Set<String> getReporters() { return _reportReasons.keySet(); }
public void addReporter(String reporter, String reason) { _reportReasons.put(reporter, reason); }
private String _handler = null;
public void setHandler(String handler) { _handler = handler; }
public String getHandler() { return _handler; }
private Category _category;
public Category getCategory() { return _category; }
private ReportCategory _category;
public ReportCategory getCategory() { return _category; }
public Report(int reportId, String playerName, String serverName, Category category)
public Report(int reportId, String playerName, String serverName, ReportCategory category)
{
_reportId = reportId;
_playerName = playerName;
_serverName = serverName;
_reporters = new HashSet<String>();
_reportReasons = new HashMap<>();
_category = category;
}

View File

@ -11,7 +11,7 @@ import mineplex.core.common.util.C;
* Contains all the reasons a player can be reported for.
* @author iKeirNez
*/
public enum Category
public enum ReportCategory
{
// descriptions borrowed from PunishPage
@ -23,7 +23,7 @@ public enum Category
private String _title;
private List<String> _lore;
Category(int id, Material displayMaterial, String title, String... lore)
ReportCategory(int id, Material displayMaterial, String title, String... lore)
{
this._id = id;
this._displayMaterial = displayMaterial;
@ -46,19 +46,19 @@ public enum Category
return _displayMaterial;
}
public String getItemDisplayName()
public String getTitle()
{
return _title;
}
public List<String> getItemLore()
public List<String> getDescription()
{
return _lore;
}
public static Category fromId(int id)
public static ReportCategory fromId(int id)
{
for (Category category : values())
for (ReportCategory category : values())
{
if (category.getId() == id)
{

View File

@ -0,0 +1,71 @@
package mineplex.core.report;
import java.util.Map;
import org.bukkit.scheduler.BukkitRunnable;
import mineplex.core.common.jsonchat.JsonMessage;
import mineplex.core.common.util.C;
import mineplex.core.report.command.ReportHandlerNotification;
import org.apache.commons.lang3.StringUtils;
/**
* Displays a message containing up-to-date details of a report to it's handler.
* @author iKeirNez
*/
public class ReportHandlerMessageTask extends BukkitRunnable
{
private static final String BORDER = C.cAqua + "------------------------------------";
private ReportManager _reportManager;
private Report _report;
public ReportHandlerMessageTask(ReportManager reportManager, Report report)
{
_reportManager = reportManager;
_report = report;
}
@Override
public void run()
{
int reportId = _report.getReportId();
if (_reportManager.isActiveReport(reportId))
{
Report report = _reportManager.getReport(reportId);
JsonMessage jsonMessage = new JsonMessage(BORDER
+ "\n"
+ C.cAqua + "Reviewing Ticket " + C.cGold + "#" + reportId
+ "\n\n"
+ StringUtils.join(getReportReasons(), "\n")
+ "\n\n"
+ "Suspect: " + _report.getPlayerName()
+ "\n"
+ BORDER);
// TODO make clickable
new ReportHandlerNotification(report, jsonMessage).publish();
}
else
{
// report has been closed, so this task should be cancelled
cancel();
}
}
public String[] getReportReasons()
{
Map<String, String> reportReasons = _report.getReportReasons();
String[] output = new String[reportReasons.size()];
int count = 0;
for (Map.Entry<String, String> entry : reportReasons.entrySet())
{
// triple backslashes so this translates to valid JSON
output[count++] = "\\\"" + entry.getValue() + "\\\" - " + entry.getKey();
}
return output;
}
}

View File

@ -10,8 +10,10 @@ import mineplex.core.common.Rank;
import mineplex.core.common.jsonchat.ClickEvent;
import mineplex.core.common.jsonchat.JsonMessage;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.portal.Portal;
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.serverdata.Region;
@ -36,6 +38,9 @@ import redis.clients.jedis.exceptions.JedisConnectionException;
*/
public class ReportManager {
private static final String NAME = "Report";
private JavaPlugin _javaPlugin;
private PreferencesManager _preferencesManager;
private String _serverName;
@ -50,21 +55,24 @@ public class ReportManager {
// A mapping of PlayerName(String) to the ReportId(Integer) for all active reports on this server.
private Map<String, Integer> _activeReports;
public ReportManager(JavaPlugin plugin, PreferencesManager preferencesManager, String serverName)
public ReportManager(JavaPlugin javaPlugin, PreferencesManager preferencesManager, String serverName)
{
_javaPlugin = javaPlugin;
_preferencesManager = preferencesManager;
_serverName = serverName;
_reportRepository = new RedisDataRepository<Report>(Region.ALL, Report.class, "reports");
_reportProfiles = new RedisDataRepository<ReportProfile>(Region.ALL, ReportProfile.class, "reportprofiles");
_activeReports = new HashMap<String, Integer>();
_reportSqlRepository = new ReportRepository(plugin);
_reportSqlRepository = new ReportRepository(javaPlugin);
_reportSqlRepository.initialize();
ServerCommandManager.getInstance().registerCommandType("ReportNotification", ReportNotification.class, new ReportNotificationCallback(this));
ReportNotificationCallback callback = new ReportNotificationCallback(this);
ServerCommandManager.getInstance().registerCommandType("ReportNotification", ReportNotification.class, callback);
ServerCommandManager.getInstance().registerCommandType("ReportHandlerNotification", ReportHandlerNotification.class, callback);
}
public void closeReport(int reportId, Player reportCloser, String reason,
ReportResult result)
ReportResult result)
{
if (isActiveReport(reportId))
{
@ -89,8 +97,9 @@ public class ReportManager {
if (reportCloser != null)
{
// Notify staff that the report was closed.
sendReportNotification(String.format("[Report %d] %s closed this report for: %s (%s).", reportId,
reportCloser.getName(), reason, result.toDisplayMessage()));
sendReportNotification(
F.main(getReportPrefix(reportId), String.format("%s closed the report for: %s (%s).",
reportCloser.getName(), reason, result.toDisplayMessage() + C.mBody)));
CommandCenter.Instance.OnPlayerCommandPreprocess(
new PlayerCommandPreprocessEvent(reportCloser, "/punish " + playerName + " " + reason));
@ -105,16 +114,17 @@ public class ReportManager {
Report report = getReport(reportId);
if (report.getHandler() != null) {
reportHandler.sendMessage(C.cRed + "Someone is already handling this report.");
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
sendReportNotification(String.format("[Report %d] %s is handling this report.", reportId, handlerName));
sendReportNotification(F.main(getReportPrefix(reportId), String.format("%s is handling this report.", handlerName)));
Portal.transferPlayer(reportHandler.getName(), report.getServerName());
// TODO: Send display message to handler when they arrive on the server
// with info about the case/report.
// Show user details of the report every x seconds
new ReportHandlerMessageTask(this, report).runTaskTimer(_javaPlugin, 20L * 10, 20L * 10);
int handlerId = getPlayerAccount(reportHandler).getAccountId();
_reportSqlRepository.logReportHandling(reportId, handlerId); // Log handling into sql database
@ -122,7 +132,7 @@ public class ReportManager {
}
}
public Report reportPlayer(Player reporter, Player reportedPlayer, Category category, String reason)
public Report reportPlayer(Player reporter, Player reportedPlayer, ReportCategory category, String reason)
{
int reporterId = getPlayerAccount(reporter).getAccountId();
ReportProfile reportProfile = getReportProfile(String.valueOf(reporterId));
@ -134,33 +144,46 @@ public class ReportManager {
if (reportId != -1 && report.getCategory() == category)
{
report.addReporter(reporter.getName());
report.addReporter(reporter.getName(), reason);
}
else
{
reportId = generateReportId();
report = new Report(reportId, reportedPlayer.getName(), _serverName, category);
report.addReporter(reporter.getName());
report.addReporter(reporter.getName(), reason);
_activeReports.put(reportedPlayer.getName().toLowerCase(), report.getReportId());
_reportRepository.addElement(report);
}
_reportRepository.addElement(report); // add (or update) the report to Redis
// only start notifying staff when
if (report.getReporters().size() >= 1)
{
// [Report #42] [MrTwiggy] [Cheater102 - 5 - Speed hacking]
String message = String.format("[Report #%d] [%s] [%s - %d - %s]", report.getReportId(),
reporter.getName(), reportedPlayer.getName(),
report.getReporters().size(), reason);
String prefix = getReportPrefix(reportId);
JsonMessage clickableMessage = new JsonMessage("Click ")
.extra("here")
.bold()
.click(ClickEvent.RUN_COMMAND, "/reporthandle " + reportId)
.add(" to respond to ticket.");
// Report #2 > iKeirNez - Flying around in arcade game (Hacking)
// Report #2 > Reported by Chiss.
// Report #2 > 5 total reporter(s).
JsonMessage message = new JsonMessage(F.main(prefix, String.format("%s - %s (%s)",
C.cGoldB + report.getPlayerName() + C.mBody,
reason, C.cGoldB + report.getCategory().getTitle() + C.mBody))
+ "\n"
+ F.main(prefix, String.format("Reported by %s.", reporter.getName()))
+ "\n"
+ F.main(prefix, String.format("%d total reporter(s).", report.getReporters().size())));
sendReportNotification(message);
sendReportNotification(clickableMessage);
if (report.getHandler() == null)
{
// this needs to be 'equals' otherwise we get errors when attempting to send this (due to incomplete JSON)
message = message.extra("\n" + F.main(getReportPrefix(reportId), "Click to handle this ticket."))
.click(ClickEvent.RUN_COMMAND, "/reporthandle " + reportId);
sendReportNotification(message);
}
else
{
// TODO send to handler?
}
}
_reportSqlRepository.logReportSending(report.getReportId(), reporterId, category, reason);
@ -176,7 +199,7 @@ public class ReportManager {
{
int reportId = getActiveReport(player.getName());
this.closeReport(reportId, null, "Player Quit", ReportResult.UNDETERMINED);
sendReportNotification(String.format("[Report %d] %s has left the game.", reportId, player.getName()));
sendReportNotification(F.main(getReportPrefix(reportId), String.format("%s has left the game.", player.getName())));
}
}
@ -325,4 +348,9 @@ public class ReportManager {
return false;
}
private static String getReportPrefix(int reportId)
{
return NAME + " #" + reportId;
}
}

View File

@ -64,7 +64,7 @@ This will be used to determine if staff are handling
}), "Error logging report " + reportId + " as being handled by user " + handlerId + ".");
}
public void logReportSending(final int reportId, final int reporterId, final Category category, final String reason)
public void logReportSending(final int reportId, final int reporterId, final ReportCategory category, final String reason)
{
handleDatabaseCall(new DatabaseRunnable(new Runnable()
{

View File

@ -0,0 +1,43 @@
package mineplex.core.report.command;
import mineplex.core.common.jsonchat.JsonMessage;
import mineplex.core.report.Report;
/**
* A message regarding a report which is sent only to the player handling the report.
* @author iKeirNez
*/
public class ReportHandlerNotification extends ReportNotification
{
private int _reportId;
private String _server; // the server the incident took place on
public ReportHandlerNotification(Report report, String notification)
{
this(report, new JsonMessage(notification));
}
public ReportHandlerNotification(Report report, JsonMessage notification)
{
super(notification);
if (report.getHandler() == null)
{
throw new IllegalStateException("Report has no handler.");
}
_reportId = report.getReportId();
_server = report.getServerName();
setTargetServers(_server);
}
public int getReportId()
{
return _reportId;
}
public String getServer()
{
return _server;
}
}

View File

@ -1,9 +1,11 @@
package mineplex.core.report.command;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import mineplex.core.common.util.UtilServer;
import mineplex.core.report.Report;
import mineplex.core.report.ReportManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.ServerCommand;
@ -24,7 +26,27 @@ public class ReportNotificationCallback implements CommandCallback
@Override
public void run(ServerCommand command)
{
if (command instanceof ReportNotification)
if (command instanceof ReportHandlerNotification)
{
ReportHandlerNotification reportNotification = (ReportHandlerNotification) command;
Report report = _reportManager.getReport(reportNotification.getReportId());
if (report != null)
{
String handlerName = report.getHandler();
if (handlerName != null)
{
Player handler = Bukkit.getPlayerExact(handlerName);
if (handler != null)
{
sendRawMessage(handler, reportNotification.getNotification());
}
}
}
}
else if (command instanceof ReportNotification)
{
ReportNotification reportNotification = (ReportNotification) command;
@ -33,10 +55,15 @@ public class ReportNotificationCallback implements CommandCallback
{
if (_reportManager.hasReportNotifications(player))
{
Server server = UtilServer.getServer();
server.dispatchCommand(server.getConsoleSender(), "tellraw " + player.getName() + " " + reportNotification.getNotification());
sendRawMessage(player, reportNotification.getNotification());
}
}
}
}
private void sendRawMessage(Player player, String rawMessage)
{
Server server = UtilServer.getServer();
server.dispatchCommand(server.getConsoleSender(), "tellraw " + player.getName() + " " + rawMessage);
}
}

View File

@ -4,7 +4,7 @@ import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.meta.ItemMeta;
import mineplex.core.gui.SimpleGuiItem;
import mineplex.core.report.Category;
import mineplex.core.report.ReportCategory;
/**
* Represents a clickable button in a {@link ReportCategoryPage} which determines the type of infraction a player has committed.
@ -13,14 +13,14 @@ import mineplex.core.report.Category;
public class ReportCategoryButton extends SimpleGuiItem
{
private ReportCategoryPage _reportCategoryPage;
private Category _category;
private ReportCategory _category;
public ReportCategoryButton(ReportCategoryPage reportCategoryPage, Category category) {
public ReportCategoryButton(ReportCategoryPage reportCategoryPage, ReportCategory category) {
super(category.getItemMaterial(), 1, (short) 0);
ItemMeta itemMeta = getItemMeta();
itemMeta.setDisplayName(category.getItemDisplayName());
itemMeta.setLore(category.getItemLore());
itemMeta.setDisplayName(category.getTitle());
itemMeta.setLore(category.getDescription());
setItemMeta(itemMeta);
this._reportCategoryPage = reportCategoryPage;

View File

@ -9,7 +9,7 @@ import org.bukkit.event.HandlerList;
import mineplex.core.common.util.C;
import mineplex.core.gui.SimpleGui;
import mineplex.core.report.Category;
import mineplex.core.report.ReportCategory;
import mineplex.core.report.Report;
import mineplex.core.report.ReportPlugin;
@ -19,11 +19,11 @@ import mineplex.core.report.ReportPlugin;
*/
public class ReportCategoryPage extends SimpleGui
{
private static final Map<Integer, Category> CATEGORY_SLOTS = Collections.unmodifiableMap(new HashMap<Integer, Category>()
private static final Map<Integer, ReportCategory> CATEGORY_SLOTS = Collections.unmodifiableMap(new HashMap<Integer, ReportCategory>()
{{
int rowStartSlot = 9 * 2; // end of row 2
put(rowStartSlot + 3, Category.HACKING);
put(rowStartSlot + 5, Category.CHAT_ABUSE);
put(rowStartSlot + 3, ReportCategory.HACKING);
put(rowStartSlot + 5, ReportCategory.CHAT_ABUSE);
}});
private ReportPlugin _reportPlugin;
@ -45,14 +45,14 @@ public class ReportCategoryPage extends SimpleGui
private void buildPage()
{
for (Map.Entry<Integer, Category> entry : CATEGORY_SLOTS.entrySet())
for (Map.Entry<Integer, ReportCategory> entry : CATEGORY_SLOTS.entrySet())
{
Category category = entry.getValue();
ReportCategory category = entry.getValue();
setItem(entry.getKey(), new ReportCategoryButton(this, category));
}
}
public void addReport(Category category)
public void addReport(ReportCategory category)
{
Report report = _reportPlugin.getReportManager().reportPlayer(_reportee, _offender, category, _reason);
_reportee.closeInventory();