commit
cbc9aeedc6
@ -20,6 +20,8 @@ import mineplex.core.report.data.Report;
|
||||
*/
|
||||
public class SnapshotManager
|
||||
{
|
||||
public static final int MAX_SNAPSHOTS = 5;
|
||||
|
||||
// There aren't any List or Set caching implementations
|
||||
// For an easy work around, we store values as the Key
|
||||
// For the value we just use some dummy object
|
||||
@ -38,7 +40,7 @@ public class SnapshotManager
|
||||
_snapshotRepository = snapshotRepository;
|
||||
}
|
||||
|
||||
public SnapshotRepository getSnapshotRepository()
|
||||
public SnapshotRepository getRepository()
|
||||
{
|
||||
return _snapshotRepository;
|
||||
}
|
||||
@ -74,21 +76,21 @@ public class SnapshotManager
|
||||
* Does not include PMs unless sender or receiver is in the exclusions collection.
|
||||
*
|
||||
* @param accountId the account to search for messages involved in
|
||||
* @param pmIdWhitelist a list of account ids of which to include PMs of
|
||||
* @param pmWhitelistIds a list of account ids of which to include PMs of
|
||||
* @return the messages that the account is involved in
|
||||
*/
|
||||
public Set<SnapshotMessage> getMessagesInvolving(int accountId, Collection<Integer> pmIdWhitelist)
|
||||
public Set<SnapshotMessage> getMessagesInvolving(int accountId, Collection<Integer> pmWhitelistIds)
|
||||
{
|
||||
return getMessagesInvolving(accountId).stream()
|
||||
.filter(message -> includeMessage(message, pmIdWhitelist))
|
||||
.filter(message -> includeMessage(message, pmWhitelistIds))
|
||||
.collect(Collectors.toCollection(TreeSet::new));
|
||||
}
|
||||
|
||||
private boolean includeMessage(SnapshotMessage message, Collection<Integer> pmExclusions)
|
||||
private boolean includeMessage(SnapshotMessage message, Collection<Integer> pmWhitelistIds)
|
||||
{
|
||||
return message.getType() != MessageType.PM ||
|
||||
pmExclusions.contains(message.getSenderId()) ||
|
||||
!Collections.disjoint(message.getRecipientIds(), pmExclusions);
|
||||
pmWhitelistIds.contains(message.getSenderId()) ||
|
||||
!Collections.disjoint(message.getRecipientIds(), pmWhitelistIds);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,18 +136,19 @@ public class SnapshotManager
|
||||
|
||||
public CompletableFuture<SnapshotMetadata> saveReportSnapshot(Report report, Collection<SnapshotMessage> messages)
|
||||
{
|
||||
return _snapshotRepository
|
||||
.saveReportSnapshot(report, messages)
|
||||
.whenComplete((snapshotMetadata, throwable) ->
|
||||
{
|
||||
if (throwable == null)
|
||||
{
|
||||
report.setSnapshotMetadata(snapshotMetadata);
|
||||
}
|
||||
else
|
||||
{
|
||||
_javaPlugin.getLogger().log(Level.SEVERE, "Error whilst saving snapshot.", throwable);
|
||||
}
|
||||
});
|
||||
SnapshotMetadata snapshotMetadata = report.getSnapshotMetadata().orElseThrow(() ->
|
||||
new IllegalStateException("Report does not have associated snapshot."));
|
||||
|
||||
return _snapshotRepository.insertMessages(snapshotMetadata.getId(), messages).whenComplete(((aVoid, throwable) ->
|
||||
{
|
||||
if (throwable == null)
|
||||
{
|
||||
report.setSnapshotMetadata(snapshotMetadata);
|
||||
}
|
||||
else
|
||||
{
|
||||
_javaPlugin.getLogger().log(Level.SEVERE, "Error whilst saving snapshot.", throwable);
|
||||
}
|
||||
})).thenApply(aVoid -> snapshotMetadata);
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.chatsnap.command.ChatSnapCommand;
|
||||
import mineplex.core.message.PrivateMessageEvent;
|
||||
|
||||
/**
|
||||
@ -36,7 +37,7 @@ public class SnapshotPlugin extends MiniPlugin
|
||||
@Override
|
||||
public void addCommands()
|
||||
{
|
||||
|
||||
addCommand(new ChatSnapCommand(this));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
|
@ -6,15 +6,16 @@ import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.report.data.Report;
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
|
||||
/**
|
||||
@ -65,13 +66,14 @@ public class SnapshotRepository
|
||||
return token;
|
||||
}
|
||||
|
||||
private static final String INSERT_SNAPSHOT = "INSERT INTO snapshots (token, creator) VALUES (?, ?);";
|
||||
private static final String INSERT_SNAPSHOT = "INSERT INTO snapshots (token, creatorId) VALUES (?, ?);";
|
||||
private static final String INSERT_MESSAGE = "INSERT INTO snapshotMessages (senderId, `server`, `time`, message, snapshotType) VALUES (?, ?, ?, ?, ?);";
|
||||
private static final String INSERT_MESSAGE_RECIPIENT = "INSERT INTO snapshotRecipients (messageId, recipientId) VALUES (?, ?);";
|
||||
private static final String INSERT_MESSAGE_MAPPING = "INSERT INTO snapshotMessageMap (snapshotId, messageId) VALUES (?, ?);";
|
||||
private static final String GET_ID_FROM_TOKEN = "SELECT snapshots.id FROM snapshots WHERE snapshots.token = ?;";
|
||||
private static final String GET_METADATA = "SELECT token, creator FROM snapshots WHERE id = ?;";
|
||||
private static final String GET_METADATA = "SELECT token, creatorId FROM snapshots WHERE id = ?;";
|
||||
private static final String SET_TOKEN = "UPDATE snapshots SET token = ? WHERE id = ?;";
|
||||
private static final String GET_USER_SNAPSHOTS = "SELECT snapshots.id FROM snapshots WHERE snapshots.creatorId = ?;";
|
||||
|
||||
private final String _serverName;
|
||||
private final Logger _logger;
|
||||
@ -82,42 +84,6 @@ public class SnapshotRepository
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public CompletableFuture<SnapshotMetadata> saveReportSnapshot(Report report, Collection<SnapshotMessage> messages)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
SnapshotMetadata snapshotMetadata = report.getSnapshotMetadata().orElseThrow(() ->
|
||||
new IllegalStateException("Report does not have associated snapshot."));
|
||||
|
||||
insertMessages(snapshotMetadata.getId(), messages, connection);
|
||||
return snapshotMetadata;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<SnapshotMetadata> saveSnapshot(Collection<SnapshotMessage> messages)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
SnapshotMetadata snapshotMetadata = createSnapshot(connection, null);
|
||||
insertMessages(snapshotMetadata.getId(), messages, connection);
|
||||
return snapshotMetadata;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<SnapshotMetadata> createSnapshot(Integer creatorAccountId)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
@ -218,7 +184,7 @@ public class SnapshotRepository
|
||||
setToken(connection, snapshotId, token);
|
||||
}
|
||||
|
||||
Integer creatorId = resultSet.getInt("creator");
|
||||
Integer creatorId = resultSet.getInt("creatorId");
|
||||
if (resultSet.wasNull()) creatorId = null;
|
||||
|
||||
return new SnapshotMetadata(snapshotId, token, creatorId);
|
||||
@ -244,6 +210,40 @@ public class SnapshotRepository
|
||||
return future;
|
||||
}
|
||||
|
||||
public CompletableFuture<List<Integer>> getUserSnapshots(int creatorId)
|
||||
{
|
||||
CompletableFuture<List<Integer>> future = CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(GET_USER_SNAPSHOTS);
|
||||
preparedStatement.setInt(1, creatorId);
|
||||
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
List<Integer> snapshotIds = new ArrayList<>();
|
||||
|
||||
while (resultSet.next())
|
||||
{
|
||||
snapshotIds.add(resultSet.getInt("id"));
|
||||
}
|
||||
|
||||
return snapshotIds;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
future.exceptionally(throwable ->
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error getting snapshots for user " + creatorId + ".");
|
||||
return new ArrayList<>();
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
private void setToken(Connection connection, int snapshotId, String token) throws SQLException
|
||||
{
|
||||
try (PreparedStatement setTokenStatement = connection.prepareStatement(SET_TOKEN))
|
||||
@ -254,36 +254,9 @@ public class SnapshotRepository
|
||||
}
|
||||
}
|
||||
|
||||
private void insertMessages(int snapshotId, Collection<SnapshotMessage> messages, Connection connection) throws SQLException
|
||||
public CompletableFuture<Void> insertMessages(int snapshotId, Collection<SnapshotMessage> messages)
|
||||
{
|
||||
try (PreparedStatement insertSnapshotStatement = connection.prepareStatement(INSERT_MESSAGE, new String[]{"id"}))
|
||||
{
|
||||
try (PreparedStatement insertRecipientStatement = connection.prepareStatement(INSERT_MESSAGE_RECIPIENT))
|
||||
{
|
||||
try (PreparedStatement insertMappingStatement = connection.prepareStatement(INSERT_MESSAGE_MAPPING))
|
||||
{
|
||||
for (SnapshotMessage message : messages)
|
||||
{
|
||||
try
|
||||
{
|
||||
insertMessage(insertSnapshotStatement, insertRecipientStatement, insertMappingStatement, snapshotId, message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error inserting snapshot message.", e);
|
||||
}
|
||||
}
|
||||
|
||||
insertRecipientStatement.executeBatch();
|
||||
insertMappingStatement.executeBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> insertMessage(int snapshotId, SnapshotMessage message)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
CompletableFuture<Void> future = CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
@ -293,7 +266,21 @@ public class SnapshotRepository
|
||||
{
|
||||
try (PreparedStatement insertMappingStatement = connection.prepareStatement(INSERT_MESSAGE_MAPPING))
|
||||
{
|
||||
insertMessage(insertSnapshotStatement, insertRecipientStatement, insertMappingStatement, snapshotId, message);
|
||||
for (SnapshotMessage message : messages)
|
||||
{
|
||||
try
|
||||
{
|
||||
insertMessage(insertSnapshotStatement, insertRecipientStatement, insertMappingStatement, snapshotId, message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error inserting snapshot message.", e);
|
||||
}
|
||||
}
|
||||
|
||||
insertRecipientStatement.executeBatch();
|
||||
insertMappingStatement.executeBatch();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -302,9 +289,15 @@ public class SnapshotRepository
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
future.exceptionally(throwable ->
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error whilst inserting messages into snapshot.", throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
private void insertMessage(PreparedStatement insertSnapshotStatement, PreparedStatement insertRecipientStatement, PreparedStatement insertMappingStatement, int snapshotId, SnapshotMessage message) throws SQLException
|
||||
|
@ -0,0 +1,71 @@
|
||||
package mineplex.core.chatsnap.command;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.chatsnap.SnapshotManager;
|
||||
import mineplex.core.chatsnap.SnapshotMessage;
|
||||
import mineplex.core.chatsnap.SnapshotPlugin;
|
||||
import mineplex.core.chatsnap.SnapshotRepository;
|
||||
import mineplex.core.command.CommandBase;
|
||||
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.common.util.UtilPlayer;
|
||||
|
||||
/**
|
||||
* A command which when executed will create a chat log which will be viewable online.
|
||||
*/
|
||||
public class ChatSnapCommand extends CommandBase<SnapshotPlugin>
|
||||
{
|
||||
public ChatSnapCommand(SnapshotPlugin plugin)
|
||||
{
|
||||
super(plugin, Rank.TITAN, "chatsnap");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player player, String[] args)
|
||||
{
|
||||
if (args == null || args.length == 0)
|
||||
{
|
||||
SnapshotManager manager = Plugin.getSnapshotManager();
|
||||
SnapshotRepository repository = manager.getRepository();
|
||||
int accountId = _commandCenter.GetClientManager().getAccountId(player);
|
||||
|
||||
Plugin.getSnapshotManager().getRepository().getUserSnapshots(accountId).thenAccept(snapshotIds ->
|
||||
{
|
||||
if (snapshotIds.size() < SnapshotManager.MAX_SNAPSHOTS)
|
||||
{
|
||||
Set<SnapshotMessage> messages = manager.getMessagesInvolving(accountId);
|
||||
|
||||
repository.createSnapshot(accountId).thenAccept(snapshotMetadata ->
|
||||
{
|
||||
String token = snapshotMetadata.getToken().orElseThrow(() ->
|
||||
new IllegalStateException("Snapshot doesn't have a token."));
|
||||
|
||||
repository.insertMessages(snapshotMetadata.getId(), messages).join();
|
||||
|
||||
UtilPlayer.message(player, F.main(Plugin.getName(), "Snapshot successfully created."));
|
||||
|
||||
new JsonMessage(F.main(Plugin.getName(), "Your snapshot token is: "))
|
||||
.extra(F.elem(token))
|
||||
.click(ClickEvent.OPEN_URL, SnapshotRepository.getURL(token))
|
||||
.sendToPlayer(player);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(player, F.main(Plugin.getName(),
|
||||
C.cRed + "Cannot create snapshot, you have reached the limit."));
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(player, F.main(Plugin.getName(), C.cRed + "Invalid Usage: " + F.elem("/" + _aliasUsed)));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package mineplex.core.chatsnap.command;
|
||||
package mineplex.core.chatsnap.redis;
|
||||
|
||||
import java.util.Set;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package mineplex.core.chatsnap.command;
|
||||
package mineplex.core.chatsnap.redis;
|
||||
|
||||
import java.util.Set;
|
||||
import mineplex.core.chatsnap.SnapshotMessage;
|
||||
@ -35,7 +35,7 @@ public class PushSnapshotsHandler implements CommandCallback
|
||||
|
||||
if (messages.size() > 0)
|
||||
{
|
||||
_reportManager.getReportRepository().getReport(reportId).thenAccept(reportOptional ->
|
||||
_reportManager.getRepository().getReport(reportId).thenAccept(reportOptional ->
|
||||
{
|
||||
if (reportOptional.isPresent())
|
||||
{
|
@ -38,7 +38,7 @@ public class ReportHandlerTask extends BukkitRunnable
|
||||
|
||||
private CompletableFuture<Optional<Report>> getReport()
|
||||
{
|
||||
return _reportManager.getReportRepository().getReport(_reportId);
|
||||
return _reportManager.getRepository().getReport(_reportId);
|
||||
}
|
||||
|
||||
public void start(JavaPlugin plugin)
|
||||
@ -70,7 +70,7 @@ public class ReportHandlerTask extends BukkitRunnable
|
||||
{
|
||||
if (isActive)
|
||||
{
|
||||
_reportManager.getReportRepository().getAccountName(report.getSuspectId())
|
||||
_reportManager.getRepository().getAccountName(report.getSuspectId())
|
||||
.thenAccept(suspectName ->
|
||||
{
|
||||
String prefix = F.main(ReportManager.getReportPrefix(reportId), "");
|
||||
@ -121,7 +121,7 @@ public class ReportHandlerTask extends BukkitRunnable
|
||||
int handlerId = handlerIdOptional.get();
|
||||
JsonMessage finalJsonMessage = jsonMessage;
|
||||
|
||||
_reportManager.getReportRepository().getAccountUUID(handlerId).thenAccept(handlerUUID ->
|
||||
_reportManager.getRepository().getAccountUUID(handlerId).thenAccept(handlerUUID ->
|
||||
{
|
||||
if (handlerUUID != null)
|
||||
{
|
||||
@ -165,7 +165,7 @@ public class ReportHandlerTask extends BukkitRunnable
|
||||
for (ReportMessage reportMessage : reportMessages)
|
||||
{
|
||||
// this is blocking, but that's okay as it will only be called asynchronously
|
||||
String reporterName = _reportManager.getReportRepository().getAccountName(reportMessage.getReporterId()).join();
|
||||
String reporterName = _reportManager.getRepository().getAccountName(reportMessage.getReporterId()).join();
|
||||
|
||||
// triple backslashes so this translates to valid JSON
|
||||
output[count++] = String.format("%4$s(%d%4$s) %s%s%s - \\\"%s%s%4$s\\\"", count, C.cGold, reporterName, C.cGray, C.cPurple, reportMessage.getMessage());
|
||||
|
@ -20,8 +20,8 @@ import mineplex.core.account.CoreClient;
|
||||
import mineplex.core.account.CoreClientManager;
|
||||
import mineplex.core.chatsnap.SnapshotManager;
|
||||
import mineplex.core.chatsnap.SnapshotMetadata;
|
||||
import mineplex.core.chatsnap.command.PushSnapshotsCommand;
|
||||
import mineplex.core.chatsnap.command.PushSnapshotsHandler;
|
||||
import mineplex.core.chatsnap.redis.PushSnapshotsCommand;
|
||||
import mineplex.core.chatsnap.redis.PushSnapshotsHandler;
|
||||
import mineplex.core.command.CommandCenter;
|
||||
import mineplex.core.common.jsonchat.ChildJsonMessage;
|
||||
import mineplex.core.common.jsonchat.JsonMessage;
|
||||
@ -34,6 +34,7 @@ import mineplex.core.portal.Portal;
|
||||
import mineplex.core.punish.Category;
|
||||
import mineplex.core.punish.Punish;
|
||||
import mineplex.core.punish.PunishClient;
|
||||
import mineplex.core.report.data.metrics.ReportMetricsRepository;
|
||||
import mineplex.core.report.redis.HandlerNotification;
|
||||
import mineplex.core.report.data.Report;
|
||||
import mineplex.core.report.data.ReportMessage;
|
||||
@ -41,6 +42,7 @@ import mineplex.core.report.data.ReportUser;
|
||||
import mineplex.core.report.data.ReportUserRepository;
|
||||
import mineplex.core.report.data.ReportRepository;
|
||||
import mineplex.core.report.redis.ReportersNotification;
|
||||
import mineplex.serverdata.Region;
|
||||
import mineplex.serverdata.commands.ServerCommandManager;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@ -52,32 +54,36 @@ public class ReportManager
|
||||
private static final String NAME = "Report";
|
||||
private static final int INITIAL_PRIORITY = 15;
|
||||
private static final int ABUSE_BAN_THRESHOLD = 3;
|
||||
public static final int MAXIMUM_REPORTS = 5;
|
||||
|
||||
private final JavaPlugin _plugin;
|
||||
private final SnapshotManager _snapshotManager;
|
||||
private final CoreClientManager _clientManager;
|
||||
private final IncognitoManager _incognitoManager;
|
||||
private final Punish _punish;
|
||||
private final Region _region;
|
||||
private final String _serverName;
|
||||
private final int _serverWeight;
|
||||
|
||||
private final ReportRepository _reportRepository;
|
||||
private final ReportUserRepository _reportUserRepository;
|
||||
private final ReportUserRepository _userRepository;
|
||||
private final ReportMetricsRepository _metricsRepository;
|
||||
|
||||
public ReportManager(JavaPlugin plugin, SnapshotManager snapshotManager, CoreClientManager clientManager,
|
||||
IncognitoManager incognitoManager, Punish punish, String serverName, int serverWeight)
|
||||
IncognitoManager incognitoManager, Punish punish, Region region, String serverName, int serverWeight)
|
||||
{
|
||||
_plugin = plugin;
|
||||
_snapshotManager = snapshotManager;
|
||||
_clientManager = clientManager;
|
||||
_incognitoManager = incognitoManager;
|
||||
_punish = punish;
|
||||
_region = region;
|
||||
_serverName = serverName;
|
||||
_serverWeight = serverWeight;
|
||||
|
||||
_reportRepository = new ReportRepository(this, _plugin.getLogger());
|
||||
|
||||
_reportUserRepository = new ReportUserRepository(plugin);
|
||||
_reportRepository = new ReportRepository(this, region, _plugin.getLogger());
|
||||
_userRepository = new ReportUserRepository(plugin);
|
||||
_metricsRepository = new ReportMetricsRepository(_plugin.getLogger());
|
||||
|
||||
ServerCommandManager commandManager = ServerCommandManager.getInstance();
|
||||
ReportRedisManager notificationCallback = new ReportRedisManager(this, _serverName);
|
||||
@ -93,15 +99,35 @@ public class ReportManager
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link ReportRepository} we are using.
|
||||
* Gets the {@link ReportRepository} this instance is using.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public ReportRepository getReportRepository()
|
||||
public ReportRepository getRepository()
|
||||
{
|
||||
return _reportRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link ReportUserRepository} this instance is using.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public ReportUserRepository getUserRepository()
|
||||
{
|
||||
return _userRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link ReportMetricsRepository} this instance is using.
|
||||
*
|
||||
* @return the repository
|
||||
*/
|
||||
public ReportMetricsRepository getMetricsRepository()
|
||||
{
|
||||
return _metricsRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new report or adds to an existing one.
|
||||
*
|
||||
@ -149,7 +175,7 @@ public class ReportManager
|
||||
// create snapshot id ahead of time
|
||||
if (category == ReportCategory.CHAT_ABUSE)
|
||||
{
|
||||
SnapshotMetadata snapshotMetadata = _snapshotManager.getSnapshotRepository().createSnapshot(null).join();
|
||||
SnapshotMetadata snapshotMetadata = _snapshotManager.getRepository().createSnapshot(null).join();
|
||||
report.setSnapshotMetadata(snapshotMetadata);
|
||||
}
|
||||
|
||||
@ -168,12 +194,12 @@ public class ReportManager
|
||||
reportOptional.orElseGet(() ->
|
||||
{
|
||||
_plugin.getLogger().log(Level.WARNING, "Report #%d couldn't be fetched, opening new report.");
|
||||
return new Report(suspectId, category);
|
||||
return new Report(suspectId, category, _region);
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
return CompletableFuture.completedFuture(new Report(suspectId, category));
|
||||
return CompletableFuture.completedFuture(new Report(suspectId, category, _region));
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -219,15 +245,18 @@ public class ReportManager
|
||||
new ReportHandlerTask(this, reportId).start(_plugin);
|
||||
});
|
||||
|
||||
if (!_incognitoManager.Get(reportHandler).Status)
|
||||
if (report.getCategory() != ReportCategory.CHAT_ABUSE)
|
||||
{
|
||||
_incognitoManager.toggle(reportHandler);
|
||||
}
|
||||
if (!_incognitoManager.Get(reportHandler).Status)
|
||||
{
|
||||
_incognitoManager.toggle(reportHandler);
|
||||
}
|
||||
|
||||
String lastServer = report.getLatestMessage().getServer();
|
||||
if (!_serverName.equals(lastServer))
|
||||
{
|
||||
Portal.transferPlayer(reportHandler.getName(), lastServer);
|
||||
String lastServer = report.getLatestMessage().getServer();
|
||||
if (!_serverName.equals(lastServer))
|
||||
{
|
||||
Portal.transferPlayer(reportHandler.getName(), lastServer);
|
||||
}
|
||||
}
|
||||
|
||||
reportHandler.sendMessage(
|
||||
@ -314,12 +343,10 @@ public class ReportManager
|
||||
}
|
||||
|
||||
jsonMessage = jsonMessage.add(F.main(prefix, "Reason: " + F.elem(reason)));
|
||||
|
||||
new ReportersNotification(ids, jsonMessage).publish();
|
||||
_reportRepository.clearCache(reportId);
|
||||
});
|
||||
});
|
||||
|
||||
_reportRepository.clearCache(reportId);
|
||||
}
|
||||
catch (Throwable throwable)
|
||||
{
|
||||
@ -446,7 +473,7 @@ public class ReportManager
|
||||
*/
|
||||
public CompletableFuture<Boolean> isActiveReport(long reportId)
|
||||
{
|
||||
return getReportRepository().getReport(reportId).thenCompose(reportOptional ->
|
||||
return getRepository().getReport(reportId).thenCompose(reportOptional ->
|
||||
{
|
||||
if (reportOptional.isPresent())
|
||||
{
|
||||
@ -546,26 +573,41 @@ public class ReportManager
|
||||
.thenApply(UtilCollections::unboxPresent)
|
||||
.thenApply(reports ->
|
||||
{
|
||||
Report report = null;
|
||||
int size = reports.size();
|
||||
|
||||
if (size == 1)
|
||||
if (size == 0)
|
||||
{
|
||||
report = reports.get(0);
|
||||
return Optional.empty();
|
||||
}
|
||||
else if (size > 1)
|
||||
else if (size == 1)
|
||||
{
|
||||
return Optional.of(reports.get(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalStateException("Account is handling multiple reports.");
|
||||
}
|
||||
|
||||
return Optional.ofNullable(report);
|
||||
});
|
||||
|
||||
future.exceptionally(throwable -> Optional.empty());
|
||||
future.exceptionally(throwable ->
|
||||
{
|
||||
_plugin.getLogger().log(Level.SEVERE, "Error whilst fetching report being handled by: " + accountId + ".");
|
||||
return Optional.empty();
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
public CompletableFuture<List<Report>> getOpenReports(int reporterId)
|
||||
{
|
||||
return _reportRepository.getOpenReports(reporterId)
|
||||
.thenApply(reportIds ->
|
||||
reportIds.stream().map(_reportRepository::getReport).collect(Collectors.toList()))
|
||||
.thenCompose(UtilFuture::sequence)
|
||||
.thenApply(UtilCollections::unboxPresent)
|
||||
.thenCompose(reports -> UtilFuture.filter(reports, this::isActiveReport));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the priority of a report.
|
||||
* This takes many parameters into account including:
|
||||
@ -587,7 +629,7 @@ public class ReportManager
|
||||
for (Map.Entry<Integer, ReportMessage> entry : report.getMessages().entrySet())
|
||||
{
|
||||
int accountId = entry.getKey();
|
||||
ReportUser user = _reportUserRepository.getUser(accountId).join();
|
||||
ReportUser user = _userRepository.getUser(accountId).join();
|
||||
int categoryReputation = user.getReputation(report.getCategory());
|
||||
|
||||
ReportMessage message = entry.getValue();
|
||||
|
@ -10,24 +10,25 @@ import mineplex.core.report.command.ReportCloseCommand;
|
||||
import mineplex.core.report.command.ReportCommand;
|
||||
import mineplex.core.report.command.ReportHandleCommand;
|
||||
import mineplex.core.report.command.ReportInfoCommand;
|
||||
import mineplex.core.report.command.ReportStatsCommand;
|
||||
import mineplex.core.report.command.ReportHistoryCommand;
|
||||
import mineplex.core.report.command.ReportMetricsCommand;
|
||||
|
||||
/**
|
||||
* Main class for this module, handles initialization and disabling of the module.
|
||||
*/
|
||||
public class ReportPlugin extends MiniPlugin
|
||||
{
|
||||
private final ReportManager _reportManager;
|
||||
private final ReportManager _manager;
|
||||
|
||||
public ReportPlugin(JavaPlugin plugin, ReportManager reportManager)
|
||||
public ReportPlugin(JavaPlugin plugin, ReportManager manager)
|
||||
{
|
||||
super("Report", plugin);
|
||||
_reportManager = reportManager;
|
||||
_manager = manager;
|
||||
}
|
||||
|
||||
public ReportManager getReportManager()
|
||||
public ReportManager getManager()
|
||||
{
|
||||
return _reportManager;
|
||||
return _manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -36,19 +37,20 @@ public class ReportPlugin extends MiniPlugin
|
||||
addCommand(new ReportCommand(this));
|
||||
addCommand(new ReportHandleCommand(this));
|
||||
addCommand(new ReportCloseCommand(this));
|
||||
addCommand(new ReportStatsCommand(this));
|
||||
addCommand(new ReportHistoryCommand(this));
|
||||
addCommand(new ReportInfoCommand(this));
|
||||
addCommand(new ReportMetricsCommand(this));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent e)
|
||||
{
|
||||
_reportManager.onPlayerJoin(e.getPlayer());
|
||||
_manager.onPlayerJoin(e.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent e)
|
||||
{
|
||||
_reportManager.onPlayerQuit(e.getPlayer());
|
||||
_manager.onPlayerQuit(e.getPlayer());
|
||||
}
|
||||
}
|
||||
|
@ -33,13 +33,13 @@ public class ReportRedisManager implements CommandCallback
|
||||
{
|
||||
HandlerNotification reportNotification = (HandlerNotification) command;
|
||||
|
||||
_reportManager.getReportRepository().getReport(reportNotification.getReportId()).thenAccept(report ->
|
||||
_reportManager.getRepository().getReport(reportNotification.getReportId()).thenAccept(report ->
|
||||
{
|
||||
if (report != null)
|
||||
{
|
||||
int handlerId = reportNotification.getHandlerId();
|
||||
|
||||
_reportManager.getReportRepository().getAccountUUID(handlerId).thenAccept(handlerUUID ->
|
||||
_reportManager.getRepository().getAccountUUID(handlerId).thenAccept(handlerUUID ->
|
||||
{
|
||||
if (handlerUUID != null)
|
||||
{
|
||||
|
@ -7,23 +7,23 @@ import org.apache.commons.lang3.text.WordUtils;
|
||||
*/
|
||||
public enum ReportResultType
|
||||
{
|
||||
ACCEPTED(0, false),
|
||||
DENIED(1, false),
|
||||
ABUSIVE(2, true),
|
||||
EXPIRED(3, true);
|
||||
ACCEPTED((short) 0, false),
|
||||
DENIED((short) 1, false),
|
||||
ABUSIVE((short) 2, true),
|
||||
EXPIRED((short) 3, true);
|
||||
|
||||
private final int _id;
|
||||
private final short _id;
|
||||
private final boolean _globalStat;
|
||||
private final String _name;
|
||||
|
||||
ReportResultType(int id, boolean globalStat)
|
||||
ReportResultType(short id, boolean globalStat)
|
||||
{
|
||||
_id = id;
|
||||
_globalStat = globalStat;
|
||||
_name = WordUtils.capitalizeFully(name().replace('_', ' '));
|
||||
}
|
||||
|
||||
public int getId()
|
||||
public short getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ public class ReportCloseCommand extends CommandBase<ReportPlugin>
|
||||
else
|
||||
{
|
||||
String reason = F.combine(args, 0, null, false);
|
||||
ReportManager reportManager = Plugin.getReportManager();
|
||||
ReportManager reportManager = Plugin.getManager();
|
||||
|
||||
reportManager.getReportHandling(player).whenComplete((reportOptional, throwable) ->
|
||||
{
|
||||
@ -45,7 +45,7 @@ public class ReportCloseCommand extends CommandBase<ReportPlugin>
|
||||
{
|
||||
Report report = reportOptional.get();
|
||||
|
||||
reportManager.getReportRepository().getAccountName(report.getSuspectId()).thenCompose(BukkitFuture.accept(suspectName ->
|
||||
reportManager.getRepository().getAccountName(report.getSuspectId()).thenCompose(BukkitFuture.accept(suspectName ->
|
||||
{
|
||||
ReportResultPage reportResultPage = new ReportResultPage(Plugin, report, player, suspectName, reason);
|
||||
reportResultPage.openInventory(); // report is closed when player selects the result
|
||||
|
@ -1,5 +1,7 @@
|
||||
package mineplex.core.report.command;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.account.CoreClient;
|
||||
@ -35,7 +37,7 @@ public class ReportCommand extends CommandBase<ReportPlugin>
|
||||
}
|
||||
else
|
||||
{
|
||||
ReportManager reportManager = Plugin.getReportManager();
|
||||
ReportManager reportManager = Plugin.getManager();
|
||||
boolean canReport = reportManager.canReport(reporter);
|
||||
|
||||
if (canReport)
|
||||
@ -51,34 +53,55 @@ public class ReportCommand extends CommandBase<ReportPlugin>
|
||||
Player suspect = UtilPlayer.searchOnline(reporter, playerName, false);
|
||||
String reason = F.combine(args, 1, null, false);
|
||||
|
||||
if (suspect != null)
|
||||
reportManager.getOpenReports(reporterId).whenComplete((reports, throwable) ->
|
||||
{
|
||||
// allow developer (iKeirNez) to report himself (for easy testing reasons)
|
||||
if (suspect == reporter && !reportManager.isDevMode(reporter.getUniqueId()))
|
||||
if (throwable == null)
|
||||
{
|
||||
UtilPlayer.message(reporter, F.main(Plugin.getName(), C.cRed + "You cannot report yourself."));
|
||||
}
|
||||
else
|
||||
{
|
||||
CoreClient suspectClient = clientManager.Get(suspect);
|
||||
new ReportCreatePage(Plugin, reporter, reporterId, suspectClient, reason).openInventory();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clientManager.loadClientByName(playerName, suspectClient ->
|
||||
{
|
||||
if (suspectClient != null)
|
||||
if (reports.size() < ReportManager.MAXIMUM_REPORTS)
|
||||
{
|
||||
new ReportCreatePage(Plugin, reporter, reporterId, suspectClient, reason).openInventory();
|
||||
if (suspect != null)
|
||||
{
|
||||
// allow developer (iKeirNez) to report himself (for easy testing reasons)
|
||||
if (suspect == reporter && !reportManager.isDevMode(reporter.getUniqueId()))
|
||||
{
|
||||
UtilPlayer.message(reporter, F.main(Plugin.getName(),
|
||||
C.cRed + "You cannot report yourself."));
|
||||
}
|
||||
else
|
||||
{
|
||||
CoreClient suspectClient = clientManager.Get(suspect);
|
||||
new ReportCreatePage(Plugin, reporter, reporterId, suspectClient, reason).openInventory();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clientManager.loadClientByName(playerName, suspectClient ->
|
||||
{
|
||||
if (suspectClient != null)
|
||||
{
|
||||
new ReportCreatePage(Plugin, reporter, reporterId, suspectClient, reason).openInventory();
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(reporter, F.main(Plugin.getName(),
|
||||
C.cRed + "Unable to find player '" + playerName + "'!"));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(reporter, F.main(Plugin.getName(), C.cRed + "Unable to find player '"
|
||||
+ playerName + "'!"));
|
||||
UtilPlayer.message(reporter, F.main(Plugin.getName(),
|
||||
C.cRed + "Cannot create report, you have reached the limit."));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(reporter, F.main(Plugin.getName(),
|
||||
C.cRed + "An error occurred, please try again."));
|
||||
Plugin.getPlugin().getLogger().log(Level.SEVERE, "Error whilst fetching open reports.", throwable);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -18,11 +18,11 @@ import mineplex.core.report.ReportRole;
|
||||
/**
|
||||
* A staff command for viewing report related statistics of a player.
|
||||
*/
|
||||
public class ReportStatsCommand extends CommandBase<ReportPlugin>
|
||||
public class ReportHistoryCommand extends CommandBase<ReportPlugin>
|
||||
{
|
||||
public ReportStatsCommand(ReportPlugin reportPlugin)
|
||||
public ReportHistoryCommand(ReportPlugin reportPlugin)
|
||||
{
|
||||
super(reportPlugin, Rank.MODERATOR, "reportstats", "rs");
|
||||
super(reportPlugin, Rank.MODERATOR, "reporthistory", "rhis");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -32,15 +32,15 @@ public class ReportStatsCommand extends CommandBase<ReportPlugin>
|
||||
{
|
||||
String playerName = args[0];
|
||||
|
||||
Plugin.getReportManager().getReportRepository().getAccountId(playerName).thenAccept(accountIdOptional ->
|
||||
Plugin.getManager().getRepository().getAccountId(playerName).thenAccept(accountIdOptional ->
|
||||
{
|
||||
if (accountIdOptional.isPresent())
|
||||
{
|
||||
int accountId = accountIdOptional.get();
|
||||
|
||||
Plugin.getReportManager().getReportRepository().getAccountStatistics(accountId).thenCompose(BukkitFuture.accept(stats ->
|
||||
Plugin.getManager().getRepository().getAccountStatistics(accountId).thenCompose(BukkitFuture.accept(stats ->
|
||||
{
|
||||
UtilPlayer.message(player, F.main(Plugin.getName(), "Report Statistics for " + F.elem(playerName)));
|
||||
UtilPlayer.message(player, F.main(Plugin.getName(), "Report History for " + F.elem(playerName)));
|
||||
|
||||
for (ReportRole role : ReportRole.values())
|
||||
{
|
@ -42,8 +42,8 @@ public class ReportInfoCommand extends CommandBase<ReportPlugin>
|
||||
{
|
||||
long reportId = Long.parseLong(args[0]);
|
||||
|
||||
ReportManager reportManager = Plugin.getReportManager();
|
||||
ReportRepository repository = reportManager.getReportRepository();
|
||||
ReportManager reportManager = Plugin.getManager();
|
||||
ReportRepository repository = reportManager.getRepository();
|
||||
|
||||
repository.getReport(reportId).thenAccept(reportOptional ->
|
||||
{
|
||||
|
@ -0,0 +1,123 @@
|
||||
package mineplex.core.report.command;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.BukkitFuture;
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.report.ReportPlugin;
|
||||
import mineplex.core.report.data.metrics.ReportMetrics;
|
||||
|
||||
/**
|
||||
* Displays various report-related metrics on a player.
|
||||
*/
|
||||
public class ReportMetricsCommand extends CommandBase<ReportPlugin>
|
||||
{
|
||||
private static final String PREFIX = "Report Metrics";
|
||||
private static final int MAX_DAYS = 30;
|
||||
|
||||
public ReportMetricsCommand(ReportPlugin plugin)
|
||||
{
|
||||
super(plugin, Rank.MODERATOR, "reportmetrics");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player player, String[] args)
|
||||
{
|
||||
if (args.length > 0 && args.length <= 2)
|
||||
{
|
||||
Integer days = parseDaysArgument(player, args[0]);
|
||||
|
||||
if (days != null)
|
||||
{
|
||||
if (args.length >= 2) // has target argument
|
||||
{
|
||||
String targetName = args[1];
|
||||
|
||||
Plugin.getManager().getRepository().getAccountId(targetName).thenAccept(targetIdOptional ->
|
||||
{
|
||||
if (targetIdOptional.isPresent())
|
||||
{
|
||||
int targetId = targetIdOptional.get();
|
||||
displayUserMetrics(player, targetName, targetId, days);
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(player, F.main(Plugin.getName(), C.cRed + "Player not found."));
|
||||
}
|
||||
});
|
||||
}
|
||||
else // display global metrics
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Report Metrics", F.elem("Global Metrics") + " (" + F.elem(days + " days") + ")"));
|
||||
displayGlobalMetrics(player, days);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UtilPlayer.message(player,
|
||||
F.main(Plugin.getName(), C.cRed + "Invalid Usage: "
|
||||
+ F.elem("/" + _aliasUsed + " <days> [player]")));
|
||||
}
|
||||
}
|
||||
|
||||
public Integer parseDaysArgument(Player sender, String daysString)
|
||||
{
|
||||
Integer days;
|
||||
|
||||
try
|
||||
{
|
||||
days = Integer.parseInt(daysString);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
UtilPlayer.message(sender, F.main(PREFIX, F.elem(daysString) + C.cRed + " is not a valid integer."));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (days > MAX_DAYS)
|
||||
{
|
||||
UtilPlayer.message(sender, F.main(PREFIX,
|
||||
C.cRed + "Cannot view metrics for longer than " + F.elem(MAX_DAYS + " days") + C.cRed + "."));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return days;
|
||||
}
|
||||
|
||||
public void displayGlobalMetrics(Player player, int days)
|
||||
{
|
||||
Plugin.getManager().getMetricsRepository().getGlobalMetrics(days).thenCompose(
|
||||
BukkitFuture.accept(globalMetrics ->
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Report Metrics", "Submitted: " + F.elem(globalMetrics.getSubmitted())));
|
||||
UtilPlayer.message(player, F.main("Report Metrics", "Expired: " + F.elem(globalMetrics.getExpired())));
|
||||
displayMetrics(player, globalMetrics);
|
||||
}));
|
||||
}
|
||||
|
||||
public void displayUserMetrics(Player player, String targetName, int targetId, int days)
|
||||
{
|
||||
Plugin.getManager().getMetricsRepository().getUserMetrics(targetId, days).thenCompose(
|
||||
BukkitFuture.accept(userMetrics ->
|
||||
{
|
||||
UtilPlayer.message(player,
|
||||
F.main("Report Metrics",
|
||||
F.elem(targetName) + " (" + F.elem(days + " days") + ")"));
|
||||
|
||||
displayMetrics(player, userMetrics);
|
||||
}));
|
||||
}
|
||||
|
||||
public void displayMetrics(Player player, ReportMetrics reportMetrics)
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Report Metrics", "Accepted: " + F.elem(reportMetrics.getAccepted())));
|
||||
UtilPlayer.message(player, F.main("Report Metrics", "Denied: " + F.elem(reportMetrics.getDenied())));
|
||||
UtilPlayer.message(player, F.main("Report Metrics", "Flagged Abusive: " + F.elem(reportMetrics.getFlagged())));
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import mineplex.core.report.ReportCategory;
|
||||
import mineplex.core.report.ReportHandlerTask;
|
||||
import mineplex.core.report.ReportResult;
|
||||
import mineplex.core.report.ReportTeam;
|
||||
import mineplex.serverdata.Region;
|
||||
|
||||
/**
|
||||
* Holds data for a Report.
|
||||
@ -19,6 +20,7 @@ public class Report
|
||||
protected Long _reportId;
|
||||
private final int _suspectId;
|
||||
private final ReportCategory _category;
|
||||
private final Region _region;
|
||||
// set of player account ids and the reason they reported this player
|
||||
private final Map<Integer, ReportMessage> _reportMessages = new HashMap<>();
|
||||
private Integer _handlerId = null;
|
||||
@ -28,16 +30,17 @@ public class Report
|
||||
|
||||
private ReportHandlerTask _handlerTask = null;
|
||||
|
||||
public Report(int suspectId, ReportCategory category)
|
||||
public Report(int suspectId, ReportCategory category, Region region)
|
||||
{
|
||||
this(null, suspectId, category);
|
||||
this(null, suspectId, category, region);
|
||||
}
|
||||
|
||||
protected Report(Long reportId, int suspectId, ReportCategory category)
|
||||
protected Report(Long reportId, int suspectId, ReportCategory category, Region region)
|
||||
{
|
||||
_reportId = reportId;
|
||||
_suspectId = suspectId;
|
||||
_category = category;
|
||||
_region = region;
|
||||
}
|
||||
|
||||
public Optional<Long> getId()
|
||||
@ -55,6 +58,11 @@ public class Report
|
||||
return _category;
|
||||
}
|
||||
|
||||
public Optional<Region> getRegion()
|
||||
{
|
||||
return Optional.ofNullable(_region);
|
||||
}
|
||||
|
||||
public Map<Integer, ReportMessage> getMessages()
|
||||
{
|
||||
return _reportMessages;
|
||||
|
@ -38,6 +38,7 @@ import mineplex.core.report.ReportResult;
|
||||
import mineplex.core.report.ReportResultType;
|
||||
import mineplex.core.report.ReportRole;
|
||||
import mineplex.core.report.ReportTeam;
|
||||
import mineplex.serverdata.Region;
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@ -46,8 +47,8 @@ import org.apache.commons.lang3.StringUtils;
|
||||
*/
|
||||
public class ReportRepository
|
||||
{
|
||||
private static final String INSERT_REPORT = "INSERT INTO reports (suspectId, categoryId, snapshotId, assignedTeam)\n" +
|
||||
"VALUES (?, ?, ?, ?);";
|
||||
private static final String INSERT_REPORT = "INSERT INTO reports (suspectId, categoryId, snapshotId, assignedTeam, region)\n" +
|
||||
"VALUES (?, ?, ?, ?, ?);";
|
||||
|
||||
private static final String UPDATE_REPORT = "UPDATE reports SET snapshotId = ?, assignedTeam = ? WHERE id = ?;";
|
||||
|
||||
@ -79,6 +80,7 @@ public class ReportRepository
|
||||
" LEFT JOIN reportHandlers ON reports.id = reportHandlers.reportId\n" +
|
||||
" LEFT JOIN reportReasons ON reports.id = reportReasons.reportId\n" +
|
||||
"WHERE reports.categoryId = ?\n" +
|
||||
" AND (reports.region IS NULL OR reports.region = ?)\n" +
|
||||
" AND reportResults.reportId IS NULL\n" +
|
||||
" /* Bypass for testing purposes or check player isn't suspect */\n" +
|
||||
" AND (? IS TRUE OR reports.suspectId != ?)\n" +
|
||||
@ -92,23 +94,32 @@ public class ReportRepository
|
||||
" /* Bypass for testing purposes or check player isn't a reporter */\n" +
|
||||
" AND (? IS TRUE OR SUM(IF(reportReasons.reporterId != ?, 1, 0)) = COUNT(reportReasons.reporterId));";
|
||||
|
||||
private static final String GET_ONGOING_REPORT = "SELECT reports.id FROM reports" +
|
||||
" LEFT JOIN reportResults ON reports.id = reportResults.reportId" +
|
||||
" WHERE reportResults.reportId IS NULL" +
|
||||
" AND reports.suspectId = ?;";
|
||||
private static final String GET_ONGOING_REPORT = "SELECT reports.id FROM reports\n" +
|
||||
" LEFT JOIN reportResults ON reports.id = reportResults.reportId\n" +
|
||||
"WHERE reportResults.reportId IS NULL\n" +
|
||||
" AND reports.suspectId = ?\n" +
|
||||
" AND (reports.region IS NULL OR reports.region = ?);";
|
||||
|
||||
private static final String GET_ONGOING_REPORT_CATEGORY = "SELECT reports.id FROM reports" +
|
||||
" LEFT JOIN reportResults ON reports.id = reportResults.reportId" +
|
||||
" WHERE reportResults.reportId IS NULL" +
|
||||
" AND reports.suspectId = ?" +
|
||||
" AND reports.categoryId = ?;";
|
||||
private static final String GET_ONGOING_REPORT_CATEGORY = "SELECT reports.id FROM reports\n" +
|
||||
" LEFT JOIN reportResults ON reports.id = reportResults.reportId\n" +
|
||||
"WHERE reportResults.reportId IS NULL\n" +
|
||||
" AND reports.suspectId = ?\n" +
|
||||
" AND reports.categoryId = ?\n" +
|
||||
" AND (reports.region IS NULL OR reports.region = ?);";
|
||||
|
||||
private static final String GET_REPORTS_HANDLING = "SELECT reports.id FROM reports" +
|
||||
" LEFT JOIN reportResults ON reports.id = reportResults.reportId" +
|
||||
" INNER JOIN reportHandlers ON reports.id = reportHandlers.reportId" +
|
||||
" AND reportHandlers.aborted IS FALSE" +
|
||||
" WHERE reportResults.reportId IS NULL" +
|
||||
" AND reportHandlers.handlerId = ?;";
|
||||
private static final String GET_REPORTS_HANDLING = "SELECT reports.id FROM reports\n" +
|
||||
" LEFT JOIN reportResults ON reports.id = reportResults.reportId\n" +
|
||||
" INNER JOIN reportHandlers ON reports.id = reportHandlers.reportId\n" +
|
||||
"WHERE reportResults.reportId IS NULL\n" +
|
||||
" AND reportHandlers.handlerId = ?\n" +
|
||||
" AND reportHandlers.aborted IS FALSE\n" +
|
||||
" AND (reports.region IS NULL OR reports.region = ?);";
|
||||
|
||||
private static final String GET_USER_OPEN_REPORTS = "SELECT reports.id FROM reports\n" +
|
||||
" INNER JOIN reportReasons ON reports.id = reportReasons.reportId\n" +
|
||||
" LEFT JOIN reportResults ON reports.id = reportResults.reportId\n" +
|
||||
"WHERE reportResults.reportId IS NULL\n" +
|
||||
" AND reportReasons.reporterId = ?;";
|
||||
|
||||
private static final String GET_USER_RESULT_COUNT = "SELECT COUNT(reports.id) AS resultCount" +
|
||||
" FROM reports, reportReasons, reportResults" +
|
||||
@ -117,16 +128,23 @@ public class ReportRepository
|
||||
" AND reportReasons.reporterId = ?" +
|
||||
" AND reportResults.resultId = ?;";
|
||||
|
||||
private static final String GET_ACCOUNT_NAME = "SELECT id, `name` FROM accounts" +
|
||||
" WHERE id = ?" +
|
||||
" LIMIT 1;";
|
||||
// We order by lastLogin in the below queries to resolve cases whereby two account
|
||||
// entries exist with the same name (online and offline mode versions), to get
|
||||
// around this, we simply picked the one that logged in most recently
|
||||
|
||||
private static final String GET_ACCOUNT_ID = "SELECT id, `name` FROM accounts\n" +
|
||||
"WHERE `name` = ?\n" +
|
||||
"ORDER BY lastLogin DESC\n" +
|
||||
"LIMIT 1;";
|
||||
|
||||
private static final String GET_ACCOUNT_NAME = "SELECT id, `name` FROM accounts\n" +
|
||||
"WHERE id = ?\n" +
|
||||
"ORDER BY lastLogin DESC\n" +
|
||||
"LIMIT 1;";
|
||||
|
||||
private static final String GET_ACCOUNT_UUID = "SELECT id, uuid FROM accounts" +
|
||||
" WHERE id IN (%s);";
|
||||
|
||||
private static final String GET_ACCOUNT_ID = "SELECT id, `name` FROM accounts\n" +
|
||||
"WHERE `name` = ?;";
|
||||
|
||||
/** STATISTICS **/
|
||||
|
||||
private static final String STATISTICS_GET_REPORTS_MADE = "SELECT reports.id FROM reports, reportReasons\n" +
|
||||
@ -142,6 +160,7 @@ public class ReportRepository
|
||||
"WHERE reports.suspectId = ?;";
|
||||
|
||||
private final ReportManager _reportManager;
|
||||
private final Region _region;
|
||||
private final Logger _logger;
|
||||
|
||||
private final Cache<Long, Report> _cachedReports = CacheBuilder.newBuilder()
|
||||
@ -149,20 +168,21 @@ public class ReportRepository
|
||||
.expireAfterAccess(5, TimeUnit.MINUTES)
|
||||
.build();
|
||||
|
||||
public ReportRepository(ReportManager reportManager, Logger logger)
|
||||
public ReportRepository(ReportManager reportManager, Region region, Logger logger)
|
||||
{
|
||||
_reportManager = reportManager;
|
||||
_region = region;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ids of unhandled reports that the supplied user is allowed to handle.
|
||||
*
|
||||
* @param accountId the id of the account carrying out the search
|
||||
* @param handlerId the id of the account carrying out the search
|
||||
* @param devMode if true, allows various restrictions to be bypassed
|
||||
* @return the ids of unhandled reports the supplied account is allowed to handle
|
||||
*/
|
||||
public CompletableFuture<List<Long>> getUnhandledReports(int accountId, ReportCategory category, boolean devMode)
|
||||
public CompletableFuture<List<Long>> getUnhandledReports(int handlerId, ReportCategory category, boolean devMode)
|
||||
{
|
||||
CompletableFuture<List<Long>> future = CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
@ -172,12 +192,13 @@ public class ReportRepository
|
||||
{
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(GET_UNHANDLED_REPORTS);
|
||||
preparedStatement.setShort(1, category.getId());
|
||||
preparedStatement.setBoolean(2, devMode);
|
||||
preparedStatement.setInt(3, accountId);
|
||||
preparedStatement.setInt(4, accountId);
|
||||
preparedStatement.setInt(5, accountId);
|
||||
preparedStatement.setBoolean(6, devMode);
|
||||
preparedStatement.setInt(7, accountId);
|
||||
preparedStatement.setString(2, _region.name());
|
||||
preparedStatement.setBoolean(3, devMode);
|
||||
preparedStatement.setInt(4, handlerId);
|
||||
preparedStatement.setInt(5, handlerId);
|
||||
preparedStatement.setInt(6, handlerId);
|
||||
preparedStatement.setBoolean(7, devMode);
|
||||
preparedStatement.setInt(8, handlerId);
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
|
||||
while (resultSet.next())
|
||||
@ -204,10 +225,10 @@ public class ReportRepository
|
||||
|
||||
/**
|
||||
* Gets a list containing the ids of reports the account is handling
|
||||
* @param accountId the id of the account
|
||||
* @param handlerId the id of the account
|
||||
* @return a list containing the ids of reports being handled
|
||||
*/
|
||||
public CompletableFuture<List<Long>> getReportsHandling(int accountId)
|
||||
public CompletableFuture<List<Long>> getReportsHandling(int handlerId)
|
||||
{
|
||||
CompletableFuture<List<Long>> future = CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
@ -216,7 +237,8 @@ public class ReportRepository
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(GET_REPORTS_HANDLING);
|
||||
preparedStatement.setInt(1, accountId);
|
||||
preparedStatement.setInt(1, handlerId);
|
||||
preparedStatement.setString(2, _region.name());
|
||||
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
|
||||
@ -255,14 +277,22 @@ public class ReportRepository
|
||||
|
||||
for (long reportId : reportIds)
|
||||
{
|
||||
preparedStatement.setLong(1, reportId);
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
Report report = loadReport(connection, resultSet);
|
||||
Report report = _cachedReports.getIfPresent(reportId);
|
||||
|
||||
if (report != null)
|
||||
if (report == null)
|
||||
{
|
||||
reports.add(report);
|
||||
preparedStatement.setLong(1, reportId);
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
|
||||
report = loadReport(connection, resultSet);
|
||||
|
||||
if (report == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
reports.add(report);
|
||||
}
|
||||
|
||||
return reports;
|
||||
@ -333,13 +363,15 @@ public class ReportRepository
|
||||
long reportId = resultSet.getLong("id");
|
||||
int suspectId = resultSet.getInt("suspectId");
|
||||
ReportCategory reportCategory = ReportCategory.getById(resultSet.getInt("categoryId"));
|
||||
String regionName = resultSet.getString("region");
|
||||
Region region = !resultSet.wasNull() ? Region.valueOf(regionName) : null;
|
||||
|
||||
Report report = new Report(reportId, suspectId, reportCategory);
|
||||
Report report = new Report(reportId, suspectId, reportCategory, region);
|
||||
|
||||
int snapshotId = resultSet.getInt("snapshotId");
|
||||
if (!resultSet.wasNull())
|
||||
{
|
||||
SnapshotMetadata snapshotMetadata = _reportManager.getSnapshotManager().getSnapshotRepository()
|
||||
SnapshotMetadata snapshotMetadata = _reportManager.getSnapshotManager().getRepository()
|
||||
.getSnapshotMetadata(snapshotId).join();
|
||||
|
||||
report.setSnapshotMetadata(snapshotMetadata);
|
||||
@ -392,7 +424,7 @@ public class ReportRepository
|
||||
return null;
|
||||
}
|
||||
|
||||
public CompletableFuture<List<Report>> getOngoingReports(int accountId)
|
||||
public CompletableFuture<List<Report>> getOngoingReports(int suspectId)
|
||||
{
|
||||
CompletableFuture<List<Report>> future = CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
@ -400,7 +432,8 @@ public class ReportRepository
|
||||
{
|
||||
List<Report> reports = new ArrayList<>();
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(GET_ONGOING_REPORT);
|
||||
preparedStatement.setInt(1, accountId);
|
||||
preparedStatement.setInt(1, suspectId);
|
||||
preparedStatement.setString(2, _region.name());
|
||||
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
while (resultSet.next())
|
||||
@ -436,22 +469,23 @@ public class ReportRepository
|
||||
|
||||
future.exceptionally(throwable ->
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error getting ongoing report for account: " + accountId + ".", throwable);
|
||||
_logger.log(Level.SEVERE, "Error getting ongoing report for account: " + suspectId + ".", throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
public CompletableFuture<List<Long>> getOngoingReports(int accountId, ReportCategory category)
|
||||
public CompletableFuture<List<Long>> getOngoingReports(int suspectId, ReportCategory category)
|
||||
{
|
||||
CompletableFuture<List<Long>> future = CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(GET_ONGOING_REPORT_CATEGORY);
|
||||
preparedStatement.setInt(1, accountId);
|
||||
preparedStatement.setInt(1, suspectId);
|
||||
preparedStatement.setInt(2, category.getId());
|
||||
preparedStatement.setString(3, _region.name());
|
||||
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
List<Long> reports = new ArrayList<>();
|
||||
@ -470,13 +504,39 @@ public class ReportRepository
|
||||
|
||||
future.exceptionally(throwable ->
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error fetching ongoing report for account: " + accountId + ", category: " + category + ".", throwable);
|
||||
_logger.log(Level.SEVERE, "Error fetching ongoing report for account: " + suspectId + ", category: " + category + ".", throwable);
|
||||
return new ArrayList<>();
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
public CompletableFuture<List<Long>> getOpenReports(int reporterId)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(GET_USER_OPEN_REPORTS);
|
||||
preparedStatement.setInt(1, reporterId);
|
||||
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
List<Long> reports = new ArrayList<>();
|
||||
|
||||
while (resultSet.next())
|
||||
{
|
||||
reports.add(resultSet.getLong("id"));
|
||||
}
|
||||
|
||||
return reports;
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Set<ReportMessage> getReportReasons(Connection connection, long reportId)
|
||||
{
|
||||
Set<ReportMessage> reportMessages = new HashSet<>();
|
||||
@ -507,13 +567,13 @@ public class ReportRepository
|
||||
return reportMessages;
|
||||
}
|
||||
|
||||
public CompletableFuture<Integer> getResultCount(int accountId, ReportResultType resultType)
|
||||
public CompletableFuture<Integer> getResultCount(int reporterId, ReportResultType resultType)
|
||||
{
|
||||
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(GET_USER_RESULT_COUNT);
|
||||
preparedStatement.setInt(1, accountId);
|
||||
preparedStatement.setInt(1, reporterId);
|
||||
preparedStatement.setInt(2, resultType.getId());
|
||||
|
||||
ResultSet resultSet = preparedStatement.executeQuery();
|
||||
@ -532,7 +592,7 @@ public class ReportRepository
|
||||
|
||||
future.exceptionally(throwable ->
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error fetching result count for account: " + accountId + ", type: " + resultType + ".", throwable);
|
||||
_logger.log(Level.SEVERE, "Error fetching result count for account: " + reporterId + ", type: " + resultType + ".", throwable);
|
||||
return 0;
|
||||
});
|
||||
|
||||
@ -546,6 +606,7 @@ public class ReportRepository
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
Optional<Long> reportIdOptional = report.getId();
|
||||
Optional<Region> regionOptional = report.getRegion();
|
||||
Optional<Integer> snapshotIdOptional = report.getSnapshotMetadata().map(SnapshotMetadata::getId);
|
||||
Optional<ReportTeam> teamOptional = report.getAssignedTeam();
|
||||
long reportId;
|
||||
@ -603,6 +664,15 @@ public class ReportRepository
|
||||
insertReportStatement.setNull(4, Types.TINYINT);
|
||||
}
|
||||
|
||||
if (regionOptional.isPresent())
|
||||
{
|
||||
insertReportStatement.setString(5, regionOptional.get().name());
|
||||
}
|
||||
else
|
||||
{
|
||||
insertReportStatement.setNull(5, Types.VARCHAR);
|
||||
}
|
||||
|
||||
insertReportStatement.executeUpdate();
|
||||
|
||||
ResultSet resultSet = insertReportStatement.getGeneratedKeys();
|
||||
@ -618,6 +688,8 @@ public class ReportRepository
|
||||
}
|
||||
}
|
||||
|
||||
_cachedReports.put(reportId, report); // cache the report
|
||||
|
||||
PreparedStatement setReportMessageStatement = connection.prepareStatement(SET_REPORT_MESSAGE);
|
||||
|
||||
for (Map.Entry<Integer, ReportMessage> entry : report.getMessages().entrySet())
|
||||
|
@ -0,0 +1,37 @@
|
||||
package mineplex.core.report.data.metrics;
|
||||
|
||||
/**
|
||||
* Extends the standard report metrics class to hold global-scope metrics.
|
||||
*/
|
||||
public class ReportGlobalMetrics extends ReportMetrics
|
||||
{
|
||||
private final long _submitted;
|
||||
private final long _expired;
|
||||
|
||||
public ReportGlobalMetrics(long submitted, long expired, long accepted, long denied, long flagged)
|
||||
{
|
||||
super(accepted, denied, flagged);
|
||||
_submitted = submitted;
|
||||
_expired = expired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of reports submitted.
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public long getSubmitted()
|
||||
{
|
||||
return _submitted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of reports expired.
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public long getExpired()
|
||||
{
|
||||
return _expired;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package mineplex.core.report.data.metrics;
|
||||
|
||||
/**
|
||||
* Holds report-related metrics which can be applied to a user or global scope.
|
||||
*/
|
||||
public class ReportMetrics
|
||||
{
|
||||
private final long _accepted;
|
||||
private final long _denied;
|
||||
private final long _flagged;
|
||||
|
||||
public ReportMetrics(long accepted, long denied, long flagged)
|
||||
{
|
||||
_accepted = accepted;
|
||||
_denied = denied;
|
||||
_flagged = flagged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of reports accepted.
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public long getAccepted()
|
||||
{
|
||||
return _accepted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of reports denied.
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public long getDenied()
|
||||
{
|
||||
return _denied;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the amount of reports flagged (marked as spam).
|
||||
*
|
||||
* @return the amount
|
||||
*/
|
||||
public long getFlagged()
|
||||
{
|
||||
return _flagged;
|
||||
}
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
package mineplex.core.report.data.metrics;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import mineplex.core.report.ReportResultType;
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
|
||||
/**
|
||||
* Handles all fetching of report-related metrics.
|
||||
*/
|
||||
public class ReportMetricsRepository
|
||||
{
|
||||
private static final String GET_GLOBAL_SUBMITTED = "SELECT COUNT(DISTINCT reportReasons.reportId) AS submitted FROM reportReasons\n" +
|
||||
" WHERE reportReasons.time BETWEEN NOW() - INTERVAL ? DAY AND NOW();";
|
||||
|
||||
private static final String GET_GLOBAL_RESULT = "SELECT COUNT(reportResults.reportId) AS amount FROM reportResults\n" +
|
||||
" WHERE reportResults.resultId = ?\n" +
|
||||
" AND reportResults.closedTime BETWEEN NOW() - INTERVAL ? DAY AND NOW();";
|
||||
|
||||
private static final String GET_USER_RESULT = "SELECT COUNT(reportResults.reportId) AS amount FROM reportResults\n" +
|
||||
" LEFT JOIN reportHandlers ON reportResults.reportId = reportHandlers.reportId AND reportHandlers.aborted IS FALSE\n" +
|
||||
" WHERE reportHandlers.handlerId = ?\n" +
|
||||
" AND reportResults.resultId = ?\n" +
|
||||
" AND reportResults.closedTime BETWEEN NOW() - INTERVAL ? DAY AND NOW();";
|
||||
|
||||
private final Logger _logger;
|
||||
|
||||
public ReportMetricsRepository(Logger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public CompletableFuture<ReportGlobalMetrics> getGlobalMetrics(int days)
|
||||
{
|
||||
CompletableFuture<ReportGlobalMetrics> future = CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
long submitted = getGlobalSubmitted(connection, days);
|
||||
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(GET_GLOBAL_RESULT))
|
||||
{
|
||||
long expired = getGlobalResult(preparedStatement, ReportResultType.EXPIRED, days);
|
||||
long accepted = getGlobalResult(preparedStatement, ReportResultType.ACCEPTED, days);
|
||||
long denied = getGlobalResult(preparedStatement, ReportResultType.DENIED, days);
|
||||
long flagged = getGlobalResult(preparedStatement, ReportResultType.ABUSIVE, days);
|
||||
|
||||
return new ReportGlobalMetrics(submitted, expired, accepted, denied, flagged);
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
future.exceptionally(throwable ->
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error fetching global metrics.", throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
private long getGlobalSubmitted(Connection connection, int days) throws SQLException
|
||||
{
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(GET_GLOBAL_SUBMITTED);
|
||||
preparedStatement.setInt(1, days);
|
||||
|
||||
try (ResultSet resultSet = preparedStatement.executeQuery())
|
||||
{
|
||||
if (resultSet.next())
|
||||
{
|
||||
return resultSet.getLong("submitted");
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long getGlobalResult(PreparedStatement preparedStatement, ReportResultType resultType, int days) throws SQLException
|
||||
{
|
||||
preparedStatement.setShort(1, resultType.getId());
|
||||
preparedStatement.setInt(2, days);
|
||||
|
||||
try (ResultSet resultSet = preparedStatement.executeQuery())
|
||||
{
|
||||
if (resultSet.next())
|
||||
{
|
||||
return resultSet.getLong("amount");
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CompletableFuture<ReportMetrics> getUserMetrics(int accountId, int days)
|
||||
{
|
||||
CompletableFuture<ReportMetrics> future = CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection connection = DBPool.getAccount().getConnection())
|
||||
{
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement(GET_USER_RESULT))
|
||||
{
|
||||
long accepted = getUserResult(preparedStatement, accountId, ReportResultType.ACCEPTED, days);
|
||||
long denied = getUserResult(preparedStatement, accountId, ReportResultType.DENIED, days);
|
||||
long flagged = getUserResult(preparedStatement, accountId, ReportResultType.ABUSIVE, days);
|
||||
|
||||
return new ReportMetrics(accepted, denied, flagged);
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
future.exceptionally(throwable ->
|
||||
{
|
||||
_logger.log(Level.SEVERE, "Error fetching user metrics.", throwable);
|
||||
return null;
|
||||
});
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
private long getUserResult(PreparedStatement preparedStatement, int accountId, ReportResultType resultType, int days) throws SQLException
|
||||
{
|
||||
preparedStatement.setInt(1, accountId);
|
||||
preparedStatement.setShort(2, resultType.getId());
|
||||
preparedStatement.setInt(3, days);
|
||||
|
||||
try (ResultSet resultSet = preparedStatement.executeQuery())
|
||||
{
|
||||
if (resultSet.next())
|
||||
{
|
||||
return resultSet.getLong("amount");
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -69,7 +69,7 @@ public class ReportCreatePage extends SimpleGui implements ReportCategoryCallba
|
||||
|
||||
private boolean hasSentMessage(int accountId)
|
||||
{
|
||||
SnapshotManager snapshotManager = _plugin.getReportManager().getSnapshotManager();
|
||||
SnapshotManager snapshotManager = _plugin.getManager().getSnapshotManager();
|
||||
int suspectId = _suspect.getAccountId();
|
||||
List<SnapshotMessage> suspectMessages = snapshotManager.getMessagesFrom(accountId).stream()
|
||||
.filter(message -> message.getSenderId() == suspectId || message.getRecipientIds().contains(suspectId))
|
||||
@ -80,7 +80,7 @@ public class ReportCreatePage extends SimpleGui implements ReportCategoryCallba
|
||||
|
||||
private void createReport(ReportCategory category)
|
||||
{
|
||||
_plugin.getReportManager().createReport(_reporterId, _suspect.getAccountId(), category, _reason)
|
||||
_plugin.getManager().createReport(_reporterId, _suspect.getAccountId(), category, _reason)
|
||||
.thenAccept(report -> {
|
||||
boolean error = true;
|
||||
|
||||
|
@ -56,8 +56,8 @@ public class ReportHandlePage extends SimpleGui implements ReportCategoryCallbac
|
||||
|
||||
public void handleReport(ReportCategory category)
|
||||
{
|
||||
ReportManager reportManager = _plugin.getReportManager();
|
||||
ReportRepository reportRepository = reportManager.getReportRepository();
|
||||
ReportManager reportManager = _plugin.getManager();
|
||||
ReportRepository reportRepository = reportManager.getRepository();
|
||||
|
||||
reportManager.isHandlingReport(_handler).whenComplete((handlingReport, throwable) ->
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ public class ReportResultPage extends SimpleGui
|
||||
{
|
||||
super(plugin.getPlugin(), reportCloser, "Close Report", 9 * 4);
|
||||
_plugin = plugin;
|
||||
_reportManager = plugin.getReportManager();
|
||||
_reportManager = plugin.getManager();
|
||||
_report = report;
|
||||
_suspectName = suspectName;
|
||||
_reason = reason;
|
||||
|
@ -239,7 +239,7 @@ public class Clans extends JavaPlugin
|
||||
|
||||
SnapshotManager snapshotManager = new SnapshotManager(this, new SnapshotRepository(serverStatusManager.getCurrentServerName(), getLogger()));
|
||||
new SnapshotPlugin(this, snapshotManager, _clientManager);
|
||||
new ReportPlugin(this, new ReportManager(this, snapshotManager, _clientManager, incognito, punish, serverStatusManager.getCurrentServerName(), 1));
|
||||
new ReportPlugin(this, new ReportManager(this, snapshotManager, _clientManager, incognito, punish, serverStatusManager.getRegion(), serverStatusManager.getCurrentServerName(), 1));
|
||||
|
||||
// Enable custom-gear related managers
|
||||
new CustomTagFix(this, packetHandler);
|
||||
|
@ -187,7 +187,7 @@ public class Hub extends JavaPlugin implements IRelation
|
||||
//new Replay(this, packetHandler);
|
||||
|
||||
SnapshotManager snapshotManager = new SnapshotManager(this, new SnapshotRepository(serverStatusManager.getCurrentServerName(), getLogger()));
|
||||
ReportManager reportManager = new ReportManager(this, snapshotManager, clientManager, incognito, punish, serverStatusManager.getCurrentServerName(), 3);
|
||||
ReportManager reportManager = new ReportManager(this, snapshotManager, clientManager, incognito, punish, serverStatusManager.getRegion(), serverStatusManager.getCurrentServerName(), 3);
|
||||
new SnapshotPlugin(this, snapshotManager, clientManager);
|
||||
new ReportPlugin(this, reportManager);
|
||||
|
||||
|
3
Plugins/Mineplex.ReportSite/sql/5-region-lock.sql
Normal file
3
Plugins/Mineplex.ReportSite/sql/5-region-lock.sql
Normal file
@ -0,0 +1,3 @@
|
||||
ALTER TABLE Account.reports ADD region VARCHAR(5) NULL;
|
||||
ALTER TABLE Account.reports
|
||||
MODIFY COLUMN region VARCHAR(5) AFTER categoryId;
|
71
Plugins/Mineplex.ReportSite/sql/6-cleanup-task.sql
Normal file
71
Plugins/Mineplex.ReportSite/sql/6-cleanup-task.sql
Normal file
@ -0,0 +1,71 @@
|
||||
-- RENAME COLUMN `creator` to `creatorId`
|
||||
ALTER TABLE Account.snapshots CHANGE creator creatorId INT(11);
|
||||
|
||||
-- STORE DATETIME SNAPSHOT CREATED (CLEANUP PURPOSES)
|
||||
ALTER TABLE Account.snapshots ADD created DATETIME DEFAULT NOW() NOT NULL;
|
||||
ALTER TABLE Account.snapshots
|
||||
MODIFY COLUMN creatorId INT(11) AFTER created;
|
||||
|
||||
-- CASCADE HANDLERS TABLE
|
||||
ALTER TABLE Account.reportHandlers DROP FOREIGN KEY reportHandlers_reports_id_fk;
|
||||
ALTER TABLE Account.reportHandlers
|
||||
ADD CONSTRAINT reportHandlers_reports_id_fk
|
||||
FOREIGN KEY (reportId) REFERENCES reports (id) ON DELETE CASCADE;
|
||||
|
||||
-- CASCADE REASONS/REPORTERS TABLE
|
||||
ALTER TABLE Account.reportReasons DROP FOREIGN KEY reportReasons_reports_id_fk;
|
||||
ALTER TABLE Account.reportReasons
|
||||
ADD CONSTRAINT reportReasons_reports_id_fk
|
||||
FOREIGN KEY (reportId) REFERENCES reports (id) ON DELETE CASCADE;
|
||||
|
||||
-- CASCADE RESULTS TABLE
|
||||
ALTER TABLE Account.reportResults DROP FOREIGN KEY reportResults_reports_id_fk;
|
||||
ALTER TABLE Account.reportResults
|
||||
ADD CONSTRAINT reportResults_reports_id_fk
|
||||
FOREIGN KEY (reportId) REFERENCES reports (id) ON DELETE CASCADE;
|
||||
|
||||
-- CASCADE SNAPSHOT MESSAGE MAP
|
||||
ALTER TABLE Account.snapshotMessageMap DROP FOREIGN KEY snapshotMessageMap_snapshots_id_fk;
|
||||
ALTER TABLE Account.snapshotMessageMap
|
||||
ADD CONSTRAINT snapshotMessageMap_snapshots_id_fk
|
||||
FOREIGN KEY (snapshotId) REFERENCES snapshots (id) ON DELETE CASCADE;
|
||||
ALTER TABLE Account.snapshotMessageMap DROP FOREIGN KEY snapshotMessageMap_snapshotMessages_id_fk;
|
||||
ALTER TABLE Account.snapshotMessageMap
|
||||
ADD CONSTRAINT snapshotMessageMap_snapshotMessages_id_fk
|
||||
FOREIGN KEY (messageId) REFERENCES snapshotMessages (id) ON DELETE CASCADE;
|
||||
|
||||
-- CASCADE SNAPSHOT RECIPIENTS TABLE
|
||||
ALTER TABLE Account.snapshotRecipients DROP FOREIGN KEY snapshotRecipients_snapshotMessages_id_fk;
|
||||
ALTER TABLE Account.snapshotRecipients
|
||||
ADD CONSTRAINT snapshotRecipients_snapshotMessages_id_fk
|
||||
FOREIGN KEY (messageId) REFERENCES snapshotMessages (id) ON DELETE CASCADE;
|
||||
|
||||
-- CREATE CLEANUP TASK
|
||||
DELIMITER //
|
||||
|
||||
-- CREATE EVENT TO RUN EVERY DAY AT 00:00
|
||||
CREATE EVENT `report_cleanup`
|
||||
ON SCHEDULE
|
||||
EVERY 1 DAY
|
||||
-- FORCE TASK TO RUN AT 00:00 DAILY
|
||||
STARTS (TIMESTAMP(CURRENT_DATE) + INTERVAL 1 DAY)
|
||||
ON COMPLETION PRESERVE
|
||||
COMMENT 'Cleans up old report and snapshot data.'
|
||||
DO BEGIN
|
||||
-- DELETE REPORTS (AND ASSOCIATED SNAPSHOT IF ANY) CLOSED > 30 DAYS AGO
|
||||
DELETE reports, snapshots FROM reports
|
||||
LEFT JOIN reportResults ON reports.id = reportResults.reportId
|
||||
LEFT JOIN snapshots ON reports.snapshotId = snapshots.id
|
||||
WHERE reportResults.closedTime NOT BETWEEN NOW() - INTERVAL 30 DAY AND NOW();
|
||||
|
||||
-- DELETE SNAPSHOTS NOT LINKED TO REPORT AND OLDER THAN 30 DAYS
|
||||
DELETE snapshots FROM snapshots
|
||||
LEFT JOIN reports ON snapshots.id = reports.snapshotId
|
||||
WHERE reports.id IS NULL
|
||||
AND snapshots.created NOT BETWEEN NOW() - INTERVAL 30 DAY AND NOW();
|
||||
|
||||
-- DELETE ORPHANED SNAPSHOT MESSAGES
|
||||
DELETE snapshotMessages FROM snapshotMessages
|
||||
LEFT JOIN snapshotMessageMap ON snapshotMessages.id = snapshotMessageMap.messageId
|
||||
WHERE snapshotMessageMap.snapshotId IS NULL;
|
||||
END//
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
require_once('snapshot.php');
|
||||
require_once('report.php');
|
||||
require_once('message.php');
|
||||
@ -126,7 +125,7 @@
|
||||
{
|
||||
$connection = getConnection('ACCOUNT');
|
||||
$statement = $connection->prepare('SELECT id FROM snapshots WHERE token = ?;');
|
||||
$statement->bind_param('s', $token); // TODO: correct data type
|
||||
$statement->bind_param('s', $token);
|
||||
$statement->execute();
|
||||
$statement->bind_result($snapshotId);
|
||||
$statement->store_result();
|
||||
@ -286,13 +285,11 @@ WHERE snapshotMessageMap.snapshotId = snapshots.id
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Snapshot $snapshot
|
||||
* @param Report $report
|
||||
* @return User[]
|
||||
*/
|
||||
function getInvolvedUsers($snapshot, $report)
|
||||
function getInvolvedUsers($report)
|
||||
{
|
||||
$involvedUsers = $snapshot->getPlayers();
|
||||
$involvedUsers[$report->getSuspect()->getId()] = $report->getSuspect();
|
||||
|
||||
foreach ($report->getReporters() as $reporterReason) {
|
||||
@ -384,6 +381,7 @@ WHERE snapshotMessageMap.snapshotId = snapshots.id
|
||||
$validToken = isset($_GET['token']);
|
||||
$errorMsg = "";
|
||||
|
||||
$title = 'Report & Snapshot System';
|
||||
$token = null;
|
||||
$expanded = null;
|
||||
$report = null;
|
||||
@ -401,15 +399,16 @@ WHERE snapshotMessageMap.snapshotId = snapshots.id
|
||||
$snapshot = getSnapshot($snapshotId);
|
||||
$messages = $snapshot->getMessages();
|
||||
$reportId = getSnapshotReportId($snapshotId);
|
||||
$report = null;
|
||||
|
||||
if ($reportId)
|
||||
{
|
||||
$report = getReport($reportId);
|
||||
$title = "Report #$reportId";
|
||||
}
|
||||
else
|
||||
{
|
||||
$validToken = false;
|
||||
$errorMsg = 'Associated report not found.'; // TODO: Allow snapshots without reports in future
|
||||
$title = "Snapshot #$snapshotId";
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -428,13 +427,7 @@ WHERE snapshotMessageMap.snapshotId = snapshots.id
|
||||
<link href='https://fonts.googleapis.com/css?family=Crete+Round' rel='stylesheet' type='text/css'>
|
||||
<link href='https://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>
|
||||
<title>
|
||||
<?php if ($validToken): ?>
|
||||
Report #<?= $report->getId() ?>
|
||||
<?php else: ?>
|
||||
Report System
|
||||
<?php endif; ?>
|
||||
|
||||
· Mineplex
|
||||
<?= $title ?> · Mineplex
|
||||
</title>
|
||||
</head>
|
||||
<body>
|
||||
@ -471,7 +464,7 @@ WHERE snapshotMessageMap.snapshotId = snapshots.id
|
||||
<div>
|
||||
<hr>
|
||||
<h2 style="font-family: 'Oswald', sans-serif; text-align: center;">
|
||||
Report #<?= $report->getId() ?>
|
||||
<?= $title ?>
|
||||
</h2>
|
||||
<hr>
|
||||
</div>
|
||||
@ -481,21 +474,23 @@ WHERE snapshotMessageMap.snapshotId = snapshots.id
|
||||
<hr>
|
||||
<div id="log">
|
||||
<?php
|
||||
// INITIALIZE
|
||||
$messageCount = count($messages);
|
||||
$displayAmount = $expanded || $messageCount <= collapsedMessageCount ? $messageCount : collapsedMessageCount;
|
||||
$involvedUsers = null;
|
||||
|
||||
// Put all reporter usernames in array for easy access later
|
||||
$reporterUsernames = array();
|
||||
foreach ($report->getReporters() as $reporterReason)
|
||||
if ($report != null)
|
||||
{
|
||||
$reporterUsernames[count($reporterUsernames)] = $reporterReason->getUser()->getUsername();
|
||||
$involvedUsers = getInvolvedUsers($report);
|
||||
}
|
||||
else
|
||||
{
|
||||
$involvedUsers = array();
|
||||
}
|
||||
|
||||
$involvedUsers = getInvolvedUsers($snapshot, $report);
|
||||
|
||||
$reportCreationTime = $report->getTimeCreated();
|
||||
$age = approximateHumanInterval($reportCreationTime->diff(new DateTime('now', $reportCreationTime->getTimezone())));
|
||||
foreach ($snapshot->getPlayers() as $player)
|
||||
{
|
||||
$involvedUsers[$player->getId()] = $player;
|
||||
}
|
||||
|
||||
if($displayAmount == 0): ?>
|
||||
<span class="black">No chat log available for this report.</span>
|
||||
@ -517,7 +512,7 @@ WHERE snapshotMessageMap.snapshotId = snapshots.id
|
||||
<?php endif; ?>
|
||||
|
||||
<span class="remove-whitespace">
|
||||
<span class="<?= ($message->getSender() == $report->getSuspect() ? 'suspect' : 'black') ?>"><?= $message->getSender()->getUsername() ?></span>
|
||||
<span class="<?= ($report != null && $message->getSender() == $report->getSuspect() ? 'suspect' : 'black') ?>"><?= $message->getSender()->getUsername() ?></span>
|
||||
|
||||
<?php if ($isPM): ?>
|
||||
-> <?= $message->getRecipients()[0]->getUsername() ?>
|
||||
@ -540,39 +535,51 @@ WHERE snapshotMessageMap.snapshotId = snapshots.id
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div id="users" class="col-lg-5">
|
||||
<h4><i class="fa fa-info-circle"></i> Information</h4>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<i class="fa fa-clock-o fa-fw"></i>
|
||||
<span class="label label-pill label-default" title="Last Report: <?= $reportCreationTime->format('Y/m/d H:i:s T') ?>"><?= $age . ' ago' ?></span>
|
||||
<br>
|
||||
<?php if ($report != null): ?>
|
||||
<h4><i class="fa fa-info-circle"></i> Information</h4>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
<?php
|
||||
// Put all reporter usernames in array for easy access later
|
||||
$reporterUsernames = array();
|
||||
foreach ($report->getReporters() as $reporterReason)
|
||||
{
|
||||
$reporterUsernames[count($reporterUsernames)] = $reporterReason->getUser()->getUsername();
|
||||
}
|
||||
|
||||
<i class="fa fa-sitemap fa-fw"></i>
|
||||
<span class="label label-pill label-primary"><?= $categories[$report->getCategory()] ?></span>
|
||||
<br>
|
||||
$reportCreationTime = $report->getTimeCreated();
|
||||
$age = approximateHumanInterval($reportCreationTime->diff(new DateTime('now', $reportCreationTime->getTimezone())));
|
||||
?>
|
||||
<i class="fa fa-clock-o fa-fw"></i>
|
||||
<span class="label label-pill label-default" title="Last Report: <?= $reportCreationTime->format('Y/m/d H:i:s T') ?>"><?= $age . ' ago' ?></span>
|
||||
<br>
|
||||
|
||||
<i class="fa fa-user-plus fa-fw"></i>
|
||||
<span class="label label-pill label-success">Reported by <?= implode(", ", $reporterUsernames) ?></span>
|
||||
<br>
|
||||
<i class="fa fa-sitemap fa-fw"></i>
|
||||
<span class="label label-pill label-primary"><?= $categories[$report->getCategory()] ?></span>
|
||||
<br>
|
||||
|
||||
<i class="fa fa-user-times fa-fw"></i>
|
||||
<span class="label label-pill label-danger">Suspect is <?= $report->getSuspect()->getUsername() ?></span>
|
||||
<br>
|
||||
<i class="fa fa-user-plus fa-fw"></i>
|
||||
<span class="label label-pill label-success">Reported by <?= implode(", ", $reporterUsernames) ?></span>
|
||||
<br>
|
||||
|
||||
<i class="fa fa-gavel fa-fw"></i>
|
||||
<span class="label label-pill label-warning">
|
||||
<?php if ($report->getHandler() != null): ?>
|
||||
Staff Member assigned is <?= $report->getHandler()->getUsername() ?>
|
||||
<?php else: ?>
|
||||
No Staff Member assigned
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<br>
|
||||
<i class="fa fa-user-times fa-fw"></i>
|
||||
<span class="label label-pill label-danger">Suspect is <?= $report->getSuspect()->getUsername() ?></span>
|
||||
<br>
|
||||
|
||||
<i class="fa fa-gavel fa-fw"></i>
|
||||
<span class="label label-pill label-warning">
|
||||
<?php if ($report->getHandler() != null): ?>
|
||||
Staff Member assigned is <?= $report->getHandler()->getUsername() ?>
|
||||
<?php else: ?>
|
||||
No Staff Member assigned
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<br>
|
||||
<?php endif; ?>
|
||||
<h4><i class="fa fa-users"></i> Users</h4>
|
||||
<hr>
|
||||
<?php foreach($involvedUsers as $user): ?>
|
||||
|
@ -161,7 +161,7 @@ public class Arcade extends JavaPlugin
|
||||
new MessageManager(this, incognito, _clientManager, preferenceManager, ignoreManager, punish, friendManager, chat);
|
||||
|
||||
SnapshotManager snapshotManager = new SnapshotManager(this, new SnapshotRepository(serverStatusManager.getCurrentServerName(), getLogger()));
|
||||
ReportManager reportManager = new ReportManager(this, snapshotManager, _clientManager, incognito, punish, serverStatusManager.getCurrentServerName(), 1);
|
||||
ReportManager reportManager = new ReportManager(this, snapshotManager, _clientManager, incognito, punish, serverStatusManager.getRegion(), serverStatusManager.getCurrentServerName(), 1);
|
||||
new SnapshotPlugin(this, snapshotManager, _clientManager);
|
||||
new ReportPlugin(this, reportManager);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user