Wrote standalone chatsnap handler and implemented required changes in Core.
This commit is contained in:
parent
c19baf5750
commit
ddf6037fc4
@ -5,6 +5,7 @@
|
|||||||
<module fileurl="file://$PROJECT_DIR$/Classpath.Dummy/Classpath.Dummy.iml" filepath="$PROJECT_DIR$/Classpath.Dummy/Classpath.Dummy.iml" group="Core" />
|
<module fileurl="file://$PROJECT_DIR$/Classpath.Dummy/Classpath.Dummy.iml" filepath="$PROJECT_DIR$/Classpath.Dummy/Classpath.Dummy.iml" group="Core" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/JedisTest/JedisTest.iml" filepath="$PROJECT_DIR$/JedisTest/JedisTest.iml" />
|
<module fileurl="file://$PROJECT_DIR$/JedisTest/JedisTest.iml" filepath="$PROJECT_DIR$/JedisTest/JedisTest.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/Mineplex.Bungee.Mineplexer/Mineplex.Bungee.Mineplexer.iml" filepath="$PROJECT_DIR$/Mineplex.Bungee.Mineplexer/Mineplex.Bungee.Mineplexer.iml" group="Bungee" />
|
<module fileurl="file://$PROJECT_DIR$/Mineplex.Bungee.Mineplexer/Mineplex.Bungee.Mineplexer.iml" filepath="$PROJECT_DIR$/Mineplex.Bungee.Mineplexer/Mineplex.Bungee.Mineplexer.iml" group="Bungee" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/Mineplex.ChatSnapManager/Mineplex.ChatSnapManager.iml" filepath="$PROJECT_DIR$/Mineplex.ChatSnapManager/Mineplex.ChatSnapManager.iml" group="Core" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/Mineplex.Core/Mineplex.Core.iml" filepath="$PROJECT_DIR$/Mineplex.Core/Mineplex.Core.iml" group="Core" />
|
<module fileurl="file://$PROJECT_DIR$/Mineplex.Core/Mineplex.Core.iml" filepath="$PROJECT_DIR$/Mineplex.Core/Mineplex.Core.iml" group="Core" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/Mineplex.Core.Common/Mineplex.Core.Common.iml" filepath="$PROJECT_DIR$/Mineplex.Core.Common/Mineplex.Core.Common.iml" group="Core" />
|
<module fileurl="file://$PROJECT_DIR$/Mineplex.Core.Common/Mineplex.Core.Common.iml" filepath="$PROJECT_DIR$/Mineplex.Core.Common/Mineplex.Core.Common.iml" group="Core" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/Mineplex.Database/Mineplex.Database.iml" filepath="$PROJECT_DIR$/Mineplex.Database/Mineplex.Database.iml" group="Core" />
|
<module fileurl="file://$PROJECT_DIR$/Mineplex.Database/Mineplex.Database.iml" filepath="$PROJECT_DIR$/Mineplex.Database/Mineplex.Database.iml" group="Core" />
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
Main-Class: mineplex.chatsnap.ChatSnapManager
|
||||||
|
|
@ -0,0 +1,49 @@
|
|||||||
|
package mineplex.chatsnap;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import redis.clients.jedis.Jedis;
|
||||||
|
import redis.clients.jedis.JedisPool;
|
||||||
|
import redis.clients.jedis.JedisPoolConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author iKeirNez
|
||||||
|
*/
|
||||||
|
public class ChatSnapManager
|
||||||
|
{
|
||||||
|
public static final String CHANNEL_DEPLOY = "chatsnap:deploy";
|
||||||
|
public static final String CHANNEL_DESTROY = "chatsnap:destroy";
|
||||||
|
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
new ChatSnapManager(new JedisPool(new JedisPoolConfig(), "host", 6379)); // TODO host
|
||||||
|
}
|
||||||
|
|
||||||
|
private JedisPool _jedisPool;
|
||||||
|
private File dataDirectory = new File("data");
|
||||||
|
|
||||||
|
public ChatSnapManager(JedisPool jedisPool)
|
||||||
|
{
|
||||||
|
_jedisPool = jedisPool;
|
||||||
|
|
||||||
|
if (dataDirectory.exists() && !dataDirectory.isDirectory())
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Not a directory: " + dataDirectory.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dataDirectory.exists() && !dataDirectory.mkdir())
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Unable to create directory: " + dataDirectory.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
registerHandler();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerHandler()
|
||||||
|
{
|
||||||
|
try (Jedis jedis = _jedisPool.getResource())
|
||||||
|
{
|
||||||
|
jedis.subscribe(new JedisPubSubHandler(dataDirectory), CHANNEL_DEPLOY, CHANNEL_DESTROY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package mineplex.chatsnap;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import redis.clients.jedis.JedisPubSub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author iKeirNez
|
||||||
|
*/
|
||||||
|
public class JedisPubSubHandler extends JedisPubSub
|
||||||
|
{
|
||||||
|
private File _directory;
|
||||||
|
|
||||||
|
private Gson _gson = new GsonBuilder()
|
||||||
|
.setPrettyPrinting()
|
||||||
|
.create();
|
||||||
|
|
||||||
|
public JedisPubSubHandler(File directory)
|
||||||
|
{
|
||||||
|
_directory = directory;
|
||||||
|
|
||||||
|
if (!directory.isDirectory())
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Not a directory.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(String channel, String dataString)
|
||||||
|
{
|
||||||
|
if (channel.equals(ChatSnapManager.CHANNEL_DEPLOY))
|
||||||
|
{
|
||||||
|
JsonObject data = _gson.fromJson(dataString, JsonObject.class);
|
||||||
|
String token = data.get("token").getAsString();
|
||||||
|
JsonArray snapshotArray = data.get("snapshots").getAsJsonArray();
|
||||||
|
|
||||||
|
File target = new File(_directory, token + ".json");
|
||||||
|
String json = _gson.toJson(snapshotArray);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Files.write(target.toPath(), Arrays.asList(json.split("\n")));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (channel.equals(ChatSnapManager.CHANNEL_DESTROY))
|
||||||
|
{
|
||||||
|
// dataString = token
|
||||||
|
File target = new File(_directory, dataString + ".json");
|
||||||
|
|
||||||
|
if (target.exists() && !target.delete())
|
||||||
|
{
|
||||||
|
System.out.println("Failed to delete: " + target.getPath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPMessage(String s, String s1, String s2)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(String s, int i)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUnsubscribe(String s, int i)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPUnsubscribe(String s, int i)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPSubscribe(String s, int i)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -23,11 +23,6 @@ public class MessageSnapshotManager
|
|||||||
.expireAfterWrite(30, TimeUnit.MINUTES)
|
.expireAfterWrite(30, TimeUnit.MINUTES)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
public MessageSnapshotManager()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keeps a snapshot in memory temporarily (30 minutes) and then discards it.
|
* Keeps a snapshot in memory temporarily (30 minutes) and then discards it.
|
||||||
* During this time, other modules (such as the Report module) can access it for their own use.
|
* During this time, other modules (such as the Report module) can access it for their own use.
|
||||||
|
@ -38,7 +38,7 @@ public class MessageSnapshotPlugin extends MiniPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void cacheChatMessage(AsyncPlayerChatEvent e)
|
public void onPlayerChat(AsyncPlayerChatEvent e)
|
||||||
{
|
{
|
||||||
_messageSnapshotManager.cacheSnapshot(getMessageSnap(e));
|
_messageSnapshotManager.cacheSnapshot(getMessageSnap(e));
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import java.util.Set;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import mineplex.serverdata.data.Data;
|
import mineplex.serverdata.data.Data;
|
||||||
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
|
|
||||||
public class Report implements Data
|
public class Report implements Data
|
||||||
{
|
{
|
||||||
@ -37,6 +38,8 @@ public class Report implements Data
|
|||||||
private long _lastActivity;
|
private long _lastActivity;
|
||||||
public long getLastActivity() { return _lastActivity; }
|
public long getLastActivity() { return _lastActivity; }
|
||||||
|
|
||||||
|
private String _token = null;
|
||||||
|
|
||||||
public Report(int reportId, String playerName, String serverName, ReportCategory category)
|
public Report(int reportId, String playerName, String serverName, ReportCategory category)
|
||||||
{
|
{
|
||||||
_reportId = reportId;
|
_reportId = reportId;
|
||||||
@ -64,6 +67,28 @@ public class Report implements Data
|
|||||||
_lastActivity = System.currentTimeMillis();
|
_lastActivity = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasChatSnapToken()
|
||||||
|
{
|
||||||
|
return _token != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a token in the format of reportId-randomCharacters.
|
||||||
|
* Currently this is only used for publishing chat abuse reports.
|
||||||
|
*
|
||||||
|
* @return the full token
|
||||||
|
*/
|
||||||
|
public String getChatSnapToken()
|
||||||
|
{
|
||||||
|
// since we don't always use this, only generate a token when we need it
|
||||||
|
if (_token == null)
|
||||||
|
{
|
||||||
|
_token = RandomStringUtils.randomAlphabetic(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _reportId + "-" + _token;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getDataId()
|
public String getDataId()
|
||||||
{
|
{
|
||||||
|
@ -3,8 +3,14 @@ package mineplex.core.report;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
import mineplex.core.account.CoreClient;
|
import mineplex.core.account.CoreClient;
|
||||||
|
import mineplex.core.chatsnap.MessageSnapshot;
|
||||||
import mineplex.core.chatsnap.MessageSnapshotManager;
|
import mineplex.core.chatsnap.MessageSnapshotManager;
|
||||||
import mineplex.core.command.CommandCenter;
|
import mineplex.core.command.CommandCenter;
|
||||||
import mineplex.core.common.Rank;
|
import mineplex.core.common.Rank;
|
||||||
@ -30,6 +36,7 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import mineplex.serverdata.servers.ServerManager;
|
||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
import redis.clients.jedis.JedisPool;
|
import redis.clients.jedis.JedisPool;
|
||||||
import redis.clients.jedis.exceptions.JedisConnectionException;
|
import redis.clients.jedis.exceptions.JedisConnectionException;
|
||||||
@ -43,6 +50,11 @@ import redis.clients.jedis.exceptions.JedisConnectionException;
|
|||||||
public class ReportManager {
|
public class ReportManager {
|
||||||
|
|
||||||
private static final String NAME = "Report";
|
private static final String NAME = "Report";
|
||||||
|
private static final String URL_PREFIX = "http://chatsnap.mineplex.com/";
|
||||||
|
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
|
||||||
|
public static final String CHANNEL_DEPLOY = "chatsnap:deploy";
|
||||||
|
public static final String CHANNEL_DESTROY = "chatsnap:destroy";
|
||||||
|
|
||||||
// statistic constants
|
// statistic constants
|
||||||
private static final String STAT_TOTAL_COUNT = "Global.TotalReportsCount";
|
private static final String STAT_TOTAL_COUNT = "Global.TotalReportsCount";
|
||||||
@ -53,6 +65,7 @@ public class ReportManager {
|
|||||||
private StatsManager _statsManager;
|
private StatsManager _statsManager;
|
||||||
private MessageSnapshotManager _messageSnapshotManager;
|
private MessageSnapshotManager _messageSnapshotManager;
|
||||||
private String _serverName;
|
private String _serverName;
|
||||||
|
private JedisPool _jedisPool;
|
||||||
|
|
||||||
// Holds active/open reports in a synchronized database.
|
// Holds active/open reports in a synchronized database.
|
||||||
private DataRepository<Report> _reportRepository;
|
private DataRepository<Report> _reportRepository;
|
||||||
@ -63,13 +76,15 @@ public class ReportManager {
|
|||||||
// A mapping of PlayerName(String) to the ReportId(Integer) for all active reports on this server.
|
// A mapping of PlayerName(String) to the ReportId(Integer) for all active reports on this server.
|
||||||
private Map<String, Integer> _activeReports;
|
private Map<String, Integer> _activeReports;
|
||||||
|
|
||||||
public ReportManager(JavaPlugin javaPlugin, PreferencesManager preferencesManager, StatsManager statsManager, MessageSnapshotManager messageSnapshotManager, String serverName)
|
public ReportManager(JavaPlugin javaPlugin, PreferencesManager preferencesManager, StatsManager statsManager,
|
||||||
|
MessageSnapshotManager messageSnapshotManager, String serverName)
|
||||||
{
|
{
|
||||||
_javaPlugin = javaPlugin;
|
_javaPlugin = javaPlugin;
|
||||||
_preferencesManager = preferencesManager;
|
_preferencesManager = preferencesManager;
|
||||||
_statsManager = statsManager;
|
_statsManager = statsManager;
|
||||||
_messageSnapshotManager = messageSnapshotManager;
|
_messageSnapshotManager = messageSnapshotManager;
|
||||||
_serverName = serverName;
|
_serverName = serverName;
|
||||||
|
_jedisPool = Utility.generatePool(ServerManager.getMasterConnection()); // TODO is this the best way?
|
||||||
_reportRepository = new RedisDataRepository<Report>(Region.ALL, Report.class, "reports");
|
_reportRepository = new RedisDataRepository<Report>(Region.ALL, Report.class, "reports");
|
||||||
_activeReports = new HashMap<String, Integer>();
|
_activeReports = new HashMap<String, Integer>();
|
||||||
_reportSqlRepository = new ReportRepository(javaPlugin);
|
_reportSqlRepository = new ReportRepository(javaPlugin);
|
||||||
@ -110,6 +125,11 @@ public class ReportManager {
|
|||||||
CommandCenter.Instance.OnPlayerCommandPreprocess(
|
CommandCenter.Instance.OnPlayerCommandPreprocess(
|
||||||
new PlayerCommandPreprocessEvent(reportCloser, "/punish " + playerName + " " + reason));
|
new PlayerCommandPreprocessEvent(reportCloser, "/punish " + playerName + " " + reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (report.getCategory() == ReportCategory.CHAT_ABUSE) // only chat abuse reports have chat logs published
|
||||||
|
{
|
||||||
|
unpublishChatLog(report.getChatSnapToken());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,6 +202,7 @@ public class ReportManager {
|
|||||||
// only start notifying staff when
|
// only start notifying staff when
|
||||||
if (report.getReporters().size() >= category.getNotifyThreshold())
|
if (report.getReporters().size() >= category.getNotifyThreshold())
|
||||||
{
|
{
|
||||||
|
publishChatLog(report.getChatSnapToken(), reportedPlayer.getUniqueId());
|
||||||
int reportId = report.getReportId();
|
int reportId = report.getReportId();
|
||||||
String prefix = getReportPrefix(reportId);
|
String prefix = getReportPrefix(reportId);
|
||||||
|
|
||||||
@ -206,11 +227,6 @@ public class ReportManager {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
message = message.extra("\n" + F.main(prefix, String.format(
|
|
||||||
"Type /reportclose %d <reason> to close this report.",
|
|
||||||
reportId)))
|
|
||||||
.click(ClickEvent.SUGGEST_COMMAND, "/reportclose " + reportId);
|
|
||||||
|
|
||||||
sendHandlerNotification(report, message);
|
sendHandlerNotification(report, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,6 +237,34 @@ public class ReportManager {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getChatLogUrl(String token)
|
||||||
|
{
|
||||||
|
return URL_PREFIX + token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void publishChatLog(String token, UUID playerUUID)
|
||||||
|
{
|
||||||
|
Set<MessageSnapshot> snapshots = _messageSnapshotManager.getSnapshotsFor(playerUUID);
|
||||||
|
|
||||||
|
JsonObject jsonObject = new JsonObject();
|
||||||
|
jsonObject.addProperty("token", token);
|
||||||
|
jsonObject.add("snapshots", GSON.toJsonTree(snapshots));
|
||||||
|
String json = GSON.toJson(snapshots);
|
||||||
|
|
||||||
|
try (Jedis jedis = _jedisPool.getResource())
|
||||||
|
{
|
||||||
|
jedis.publish(CHANNEL_DEPLOY, json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unpublishChatLog(String token)
|
||||||
|
{
|
||||||
|
try (Jedis jedis = _jedisPool.getResource())
|
||||||
|
{
|
||||||
|
jedis.publish(CHANNEL_DESTROY, token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void onPlayerJoin(Player player)
|
public void onPlayerJoin(Player player)
|
||||||
{
|
{
|
||||||
if (hasActiveReport(player))
|
if (hasActiveReport(player))
|
||||||
|
@ -24,7 +24,6 @@ public class ReportCommand extends CommandBase<ReportPlugin>
|
|||||||
if(args == null || args.length < 2)
|
if(args == null || args.length < 2)
|
||||||
{
|
{
|
||||||
UtilPlayer.message(player, F.main(Plugin.getName(), C.cRed + "Your arguments are inappropriate for this command!"));
|
UtilPlayer.message(player, F.main(Plugin.getName(), C.cRed + "Your arguments are inappropriate for this command!"));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -24,7 +24,6 @@ public class ReportHandleCommand extends CommandBase<ReportPlugin>
|
|||||||
if(args == null || args.length < 1)
|
if(args == null || args.length < 1)
|
||||||
{
|
{
|
||||||
UtilPlayer.message(player, F.main(Plugin.getName(), C.cRed + "Your arguments are inappropriate for this command!"));
|
UtilPlayer.message(player, F.main(Plugin.getName(), C.cRed + "Your arguments are inappropriate for this command!"));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user