Make Discord report filing system asynchronous

This commit is contained in:
Allink 2023-07-25 03:45:22 +01:00
parent eb99dcd3a3
commit 011535cf16
No known key found for this signature in database
2 changed files with 96 additions and 103 deletions

View File

@ -1,6 +1,8 @@
package me.totalfreedom.totalfreedommod.command; package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.rank.Rank; import me.totalfreedom.totalfreedommod.rank.Rank;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
@ -8,11 +10,28 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;
@CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME, blockHostConsole = true) @CommandPermissions(level = Rank.OP, source = SourceType.ONLY_IN_GAME, blockHostConsole = true)
@CommandParameters(description = "Report a player for all admins to see.", usage = "/<command> <player> <reason>") @CommandParameters(description = "Report a player for all admins to see.", usage = "/<command> <player> <reason>")
public class Command_report extends FreedomCommand public class Command_report extends FreedomCommand
{ {
private void handleLog(final @Nullable Boolean value, final @Nullable Throwable ex, final CommandSender sender)
{
if (ex != null)
{
sender.sendMessage(Component.text("An error occurred while attempting to log your previously filed report to a Discord channel.", NamedTextColor.RED));
ex.printStackTrace();
return;
}
if (Boolean.FALSE.equals(value))
{
return;
}
sender.sendMessage(Component.text("The report you previously filed has been successfully logged to a Discord channel. Please note that spamming reports is not allowed, and you will be sanctioned if you are found to be doing it.", NamedTextColor.GRAY));
}
@Override @Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
@ -50,18 +69,16 @@ public class Command_report extends FreedomCommand
} }
String report = StringUtils.join(ArrayUtils.subarray(args, 1, args.length), " "); String report = StringUtils.join(ArrayUtils.subarray(args, 1, args.length), " ");
plugin.cm.reportAction(playerSender, (player == null) ? offlinePlayer.getName() : player.getName(), report); String reportedUsername = (player == null) ? offlinePlayer.getName() : player.getName();
plugin.cm.reportAction(playerSender, reportedUsername, report);
boolean logged = false; msg(ChatColor.GREEN + "Thank you, your report is being processed.");
if (plugin.dc.enabled) if (plugin.dc.enabled)
{ {
logged = (player == null) ? plugin.dc.sendReportOffline(playerSender, offlinePlayer, report) : plugin.dc.sendReport(playerSender, player, report); plugin.dc.sendReport(playerSender.getName(), reportedUsername, report).whenCompleteAsync((logged, ex) -> handleLog(logged, ex, sender));
} }
msg(ChatColor.GREEN + "Thank you, your report has been successfully logged."
+ (logged ? ChatColor.RED + "\nNote: This report has been logged to a discord channel, as with any report system, spamming reports can lead to you getting banned." : ""));
return true; return true;
} }
} }

View File

@ -3,10 +3,7 @@ package me.totalfreedom.totalfreedommod.discord;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import java.time.Instant; import java.time.Instant;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginException;
@ -26,11 +23,9 @@ import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageEmbed; import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.PrivateChannel;
import net.dv8tion.jda.api.entities.Role; import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.SelfUser; import net.dv8tion.jda.api.entities.SelfUser;
import net.dv8tion.jda.api.entities.TextChannel; import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.ReadyEvent; import net.dv8tion.jda.api.events.ReadyEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter; import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.requests.GatewayIntent;
@ -42,16 +37,18 @@ import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import org.apache.commons.lang.WordUtils; import org.apache.commons.lang.WordUtils;
import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.RandomStringUtils;
import org.bukkit.Bukkit;
import org.bukkit.GameRule; import org.bukkit.GameRule;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class Discord extends FreedomService public class Discord extends FreedomService
{ {
@ -402,7 +399,9 @@ public class Discord extends FreedomService
return true; return true;
} }
public boolean sendReportOffline(Player reporter, OfflinePlayer reported, String reason) public CompletableFuture<Boolean> sendReport(String reporterName, String reportedName, String reason)
{
return CompletableFuture.supplyAsync(() ->
{ {
if (!shouldISendReport()) if (!shouldISendReport())
{ {
@ -425,73 +424,49 @@ public class Discord extends FreedomService
return false; return false;
} }
final EmbedBuilder embedBuilder = new EmbedBuilder(); Player onlinePlayer = Bukkit.getPlayer(reportedName);
embedBuilder.setTitle("Report for " + reported.getName() + " (offline)"); boolean online = onlinePlayer != null;
embedBuilder.setDescription(reason);
embedBuilder.setFooter("Reported by " + reporter.getName(), "https://minotar.net/helm/" + reporter.getName() + ".png");
embedBuilder.setTimestamp(Instant.from(ZonedDateTime.now()));
if (plugin.esb.isEnabled())
{
com.earth2me.essentials.User user = plugin.esb.getEssentialsUser(reported.getName());
String location = "World: " + Objects.requireNonNull(user.getLastLocation().getWorld()).getName() + ", X: " + user.getLastLocation().getBlockX() + ", Y: " + user.getLastLocation().getBlockY() + ", Z: " + user.getLastLocation().getBlockZ();
embedBuilder.addField("Location", location, true);
embedBuilder.addField("God Mode", WordUtils.capitalizeFully(String.valueOf(user.isGodModeEnabled())), true);
if (user.getNickname() != null)
{
embedBuilder.addField("Nickname", user.getNickname(), true);
}
}
MessageEmbed embed = embedBuilder.build();
Message message = channel.sendMessageEmbeds(embed).complete();
if (!ConfigEntry.DISCORD_REPORT_ARCHIVE_CHANNEL_ID.getString().isEmpty())
{
message.addReaction("\uD83D\uDCCB").complete();
}
return true;
}
public boolean sendReport(Player reporter, Player reported, String reason)
{
if (!shouldISendReport())
{
return false;
}
final Guild server = bot.getGuildById(ConfigEntry.DISCORD_SERVER_ID.getString());
if (server == null)
{
FLog.severe("The guild ID specified in the config is invalid.");
return false;
}
final TextChannel channel = server.getTextChannelById(ConfigEntry.DISCORD_REPORT_CHANNEL_ID.getString());
if (channel == null)
{
FLog.severe("The report channel ID specified in the config is invalid.");
return false;
}
final EmbedBuilder embedBuilder = new EmbedBuilder(); final EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setTitle("Report for " + reported.getName()); embedBuilder.setTitle("Report for " + reportedName + (online ? "" : " (offline)"));
embedBuilder.setDescription(reason); embedBuilder.setDescription(reason);
embedBuilder.setFooter("Reported by " + reporter.getName(), "https://minotar.net/helm/" + reporter.getName() + ".png"); embedBuilder.setFooter("Reported by " + reporterName, "https://minotar.net/helm/" + reporterName + ".png");
embedBuilder.setTimestamp(Instant.from(ZonedDateTime.now())); embedBuilder.setTimestamp(Instant.from(ZonedDateTime.now()));
String location = "World: " + Objects.requireNonNull(reported.getLocation().getWorld()).getName() + ", X: " + reported.getLocation().getBlockX() + ", Y: " + reported.getLocation().getBlockY() + ", Z: " + reported.getLocation().getBlockZ();
embedBuilder.addField("Location", location, true); Location location = null;
embedBuilder.addField("Game Mode", WordUtils.capitalizeFully(reported.getGameMode().name()), true); Boolean godMode = null;
String nickName = null;
if (plugin.esb.isEnabled()) if (plugin.esb.isEnabled())
{ {
com.earth2me.essentials.User user = plugin.esb.getEssentialsUser(reported.getName()); com.earth2me.essentials.User user = plugin.esb.getEssentialsUser(reportedName);
embedBuilder.addField("God Mode", WordUtils.capitalizeFully(String.valueOf(user.isGodModeEnabled())), true); if (!online)
if (user.getNickname() != null)
{ {
embedBuilder.addField("Nickname", user.getNickname(), true); location = user.getLastLocation();
} }
godMode = user.isGodModeEnabled();
nickName = user.getNickname();
}
if (location == null && online)
{
location = onlinePlayer.getLocation();
}
if (location != null)
{
embedBuilder.addField("Location", "World: " + location.getWorld().getName() + ", X: " + location.getBlockX() + ", Y: " + location.getBlockY() + ", Z: " + location.getBlockZ(), true);
}
if (godMode != null)
{
embedBuilder.addField("God Mode", WordUtils.capitalizeFully(godMode.toString()), true);
}
if (nickName != null)
{
embedBuilder.addField("Nickname", nickName, true);
} }
MessageEmbed embed = embedBuilder.build(); MessageEmbed embed = embedBuilder.build();
@ -503,6 +478,7 @@ public class Discord extends FreedomService
} }
return true; return true;
});
} }
// Do no ask why this is here. I spent two hours trying to make a simple thing work // Do no ask why this is here. I spent two hours trying to make a simple thing work