MissingIdentifier/src/main/java/Modules/AutoSelect.java

429 lines
22 KiB
Java

package Modules;
import Controll.GuildController;
import Controll.SuperModule;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageReaction;
import net.dv8tion.jda.api.entities.PermissionOverride;
import net.dv8tion.jda.api.events.GenericEvent;
import net.dv8tion.jda.api.events.guild.GenericGuildEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionRemoveEvent;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AutoSelect extends SuperModule {
private static final String WAITING_FOR_REACTION_ROLE= "Okay! Please React to a Message you want to bind the Role to!";
private static final String WAITING_FOR_REACTION_TEXTCHANNEL = "Okay! Please React to a Message you want to bind the TextChannel to!";
private static final String WAITING_FOR_REACTION_CATEGORY= "Okay! Please React to a Message you want to bind the Category to!";
private static final String WAITING_FOR_REACTION_VOICECHANNEL = "Okay! Please React to a Message you want to bind the VoiceChannel to!";
private static final String WAITING_FOR_REACTION_REMOVE = "Okay, please react/unreact to a activ Connection to remove it!!";
private static final String ERROR_NO_VALID_INPUT_ID = "That is not a valid Category ID or VoiceChannel ID!";
private static final String ERROR_NO_VALID_INPUT_GENERAL = "That is not a valid input! \n Please mention exact one Role / TextChannel / CategoryID / VoiceChannelID";
private static final String ERROR_ALREADY_EXISTS = "Connection already exists! Abort.";
private static final String CONFIRM_DELETE = "Connection deleted!";
private static final String CONFIRM_ADDED= "Connection Added!";
private final Logger logger = LoggerFactory.getLogger(AutoSelect.class);
public static final String COMMAND = "AutoSelect";
private HashMap<Long, TmpData> awatingReactionFrom;
public AutoSelect(GuildController guildController, JSONObject config){
super(COMMAND, guildController, config);
awatingReactionFrom = new HashMap<Long, TmpData>();
if (!config.containsKey("connections")){
config.put("connections", new JSONArray());
safeConfig(getConfig());
}
}
@Override
public String getCommand() {
return COMMAND;
}
@Override
public String getDescription(){
return "Setup Roles/Channels/Categories Members can self assign.\nFor Channels/Categories bot assigns View, Read, write, connect, speak rights. Rest have to be managed by your self.\n" +
"`AutoSelect new <@ROLE | #TEXTCHANNEL | CATEGORYID | VOICECHANNELID>` add a connection" +
"`AutoSelect remove` remove a connection";
}
@Override
public void execute(GenericEvent event) {
//////////////////
// On DELETE
//////////////////
if (event instanceof GuildMessageDeleteEvent){
logger.debug(COMMAND + "triggered");
GuildMessageDeleteEvent thisEvent = (GuildMessageDeleteEvent) event;
JSONArray connections = (JSONArray)getConfig().get("connections");
for (Object o : connections){ // Go through every entry
JSONObject connection = (JSONObject) o;
if (connection.get("messageID").toString().equals(thisEvent.getMessageId())){
logger.info("Delete Connection:" + connection.get("targetID") + " | " + connection.get("messageID") + " | " + connection.get("reactionEmote"));
connections.remove(o);
safeConfig();
}
}
//////////////////
// On MESSAGE
//////////////////
} else if (event instanceof GuildMessageReceivedEvent) {
GuildMessageReceivedEvent thisEvent = (GuildMessageReceivedEvent) event;
if (!isCommand(thisEvent.getMessage()))
return;
logger.debug(COMMAND + "triggered");
if (checkForAdmin(thisEvent.getMember())){
//////////////////
// Init New Connection
//////////////////
if (checkForCommand(thisEvent.getMessage().getContentRaw(), "new")){
if (thisEvent.getMessage().getMentionedRoles().size() == 1){ // Process for roles
addWaitState(thisEvent.getMember().getIdLong(), // add to waitList
new TmpData(
thisEvent.getChannel().sendMessage(
WAITING_FOR_REACTION_ROLE).complete(),
thisEvent.getMessage().getMentionedRoles().get(0).getIdLong(),
"role"
)
);
} else if (thisEvent.getMessage().getMentionedChannels().size() == 1) { // Process for Channels
addWaitState(thisEvent.getMember().getIdLong(), // add to waitList
new TmpData(
thisEvent.getChannel().sendMessage(
WAITING_FOR_REACTION_TEXTCHANNEL).complete(),
thisEvent.getMessage().getMentionedChannels().get(0).getIdLong(),
"text-channel"
)
);
} else if (thisEvent.getMessage().getContentRaw().matches("(?is:.*[0-9]+$)")) { // Process for Category
Matcher m = Pattern.compile("[0-9]+$").matcher(thisEvent.getMessage().getContentRaw());
if (m.find()){ // Just to make sure, lol
if (thisEvent.getGuild().getCategoryById(m.group(0)) != null){ // check if found ID is a Category ID
addWaitState(thisEvent.getMember().getIdLong(), // add to waitList
new TmpData(
thisEvent.getChannel().sendMessage(
WAITING_FOR_REACTION_CATEGORY).complete(),
Long.parseLong(m.group(0)),
"category"
)
);
} else if (thisEvent.getGuild().getVoiceChannelById(m.group(0)) != null) { // check if found ID is a VoiceChannel ID
addWaitState(thisEvent.getMember().getIdLong(), // add to waitList
new TmpData(
thisEvent.getChannel().sendMessage(
WAITING_FOR_REACTION_VOICECHANNEL).complete(),
Long.parseLong(m.group(0)),
"voice-channel"
)
);
} else { // If ID is not a Category ID send error
thisEvent.getChannel().sendMessage(ERROR_NO_VALID_INPUT_ID).queue(msg -> msg.delete().queueAfter(1, TimeUnit.MINUTES));
}
}
} else {
thisEvent.getChannel().sendMessage(ERROR_NO_VALID_INPUT_GENERAL).queue(m -> m.delete().queueAfter(1, TimeUnit.MINUTES));
}
//////////////////
// Init remove Connection
//////////////////
} if (checkForCommand(thisEvent.getMessage().getContentRaw(), "remove")){
// Setup wait state
addWaitState(thisEvent.getMember().getIdLong(),
new TmpData(
thisEvent.getChannel().sendMessage(WAITING_FOR_REACTION_REMOVE).complete()
,0
,"delete")
);
}
} else
//delete for no spam
thisEvent.getMessage().delete().queue();
//////////////////
// On REACTION ADD
//////////////////
} else if (event instanceof GuildMessageReactionAddEvent) {
logger.debug(COMMAND + "triggered");
GuildMessageReactionAddEvent thisEvent = (GuildMessageReactionAddEvent)event;
if (awatingReactionFrom.containsKey(thisEvent.getUserIdLong())){ // check if reaction is by user we wait for
if (awatingReactionFrom.get(thisEvent.getUserIdLong()).targetType.equalsIgnoreCase("delete")){ // check if we have to delete
// REMOVE CONNECTION
removeConnection(thisEvent.getMessageId(), thisEvent.getReactionEmote(), thisEvent.getChannel().getIdLong());
awatingReactionFrom.get(thisEvent.getUserIdLong()).message.editMessage(CONFIRM_DELETE).queue(m -> m.delete().queueAfter(1, TimeUnit.MINUTES));
awatingReactionFrom.remove(thisEvent.getUserIdLong());
} else {
// ADD CONNECTION
JSONObject newConnection = new JSONObject();
newConnection.put("targetID", awatingReactionFrom.get(thisEvent.getUserIdLong()).targetID);
newConnection.put("messageID", thisEvent.getMessageIdLong());
newConnection.put("reactionEmote", thisEvent.getReactionEmote().getName());
newConnection.put("targetType", awatingReactionFrom.get(thisEvent.getUserIdLong()).targetType);
//Check if reaction already connected to a role
JSONArray connections = (JSONArray)getConfig().get("connections");
for (Object o : connections){
JSONObject connection = (JSONObject) o;
if (connection.get("messageID").toString().equals(thisEvent.getMessageId())
&& connection.get("reactionEmote").toString().equals(thisEvent.getReactionEmote().getName())){
awatingReactionFrom.get(thisEvent.getUserIdLong()).message.editMessage(ERROR_ALREADY_EXISTS).complete();
return;
}
}
logger.info("Create Connection:" + newConnection.get("targetID") + " | " + newConnection.get("messageID") + " | " + newConnection.get("reactionEmote"));
connections.add(newConnection);
awatingReactionFrom.remove(thisEvent.getUserIdLong()).message.editMessage(CONFIRM_ADDED).queue(m -> m.delete().queueAfter(1, TimeUnit.MINUTES));
//switch for emojo or Emote
if (thisEvent.getReactionEmote().isEmoji())
thisEvent.getChannel().addReactionById(thisEvent.getMessageIdLong(), thisEvent.getReactionEmote().getName()).queue();
else
thisEvent.getChannel().addReactionById(thisEvent.getMessageIdLong(), thisEvent.getReactionEmote().getEmote()).queue();
safeConfig();
}
} else {
// CHECK IF CONNECTED REACTION AND ADD
JSONArray connections = (JSONArray)getConfig().get("connections");
for (Object o : connections){
JSONObject connection = (JSONObject) o;
if (connection.get("messageID").toString().equals(thisEvent.getMessageId())
&& connection.get("reactionEmote").toString().equals(thisEvent.getReactionEmote().getName())){
PermissionOverride po; // Permission Override Object to avoid conflicting scopes
switch (connection.get("targetType").toString()){
case "role":
thisEvent.getGuild().addRoleToMember(thisEvent.getMember(), thisEvent.getGuild().getRoleById(connection.get("targetID").toString())).queue();
break;
case "text-channel":
thisEvent.getGuild().getTextChannelById(connection.get("targetID").toString()).upsertPermissionOverride(thisEvent.getMember()).complete()
.getManager().setAllow(Permission.MESSAGE_WRITE,
Permission.MESSAGE_READ,
Permission.VIEW_CHANNEL).queue();
break;
case "voice-channel":
thisEvent.getGuild().getVoiceChannelById(connection.get("targetID").toString()).upsertPermissionOverride(thisEvent.getMember()).complete()
.getManager().setAllow(Permission.VOICE_CONNECT,
Permission.VIEW_CHANNEL,
Permission.VOICE_SPEAK).queue();
break;
case "category":
thisEvent.getGuild().getCategoryById(connection.get("targetID").toString()).upsertPermissionOverride(thisEvent.getMember()).complete()
.getManager().setAllow(Permission.VOICE_CONNECT,
Permission.VIEW_CHANNEL,
Permission.VOICE_SPEAK,
Permission.MESSAGE_READ,
Permission.MESSAGE_WRITE).queue();
break;
}
logger.info("ADDED target " + connection.get("targetID") + " to User" + thisEvent.getMember().getId());
}
}
}
//////////////////
// On REACTION REMOVE
//////////////////
} else if (event instanceof GuildMessageReactionRemoveEvent){
logger.debug(COMMAND + "triggered");
GuildMessageReactionRemoveEvent thisEvent = (GuildMessageReactionRemoveEvent) event;
if (awatingReactionFrom.containsKey(thisEvent.getUserIdLong())){
if (awatingReactionFrom.get(thisEvent.getUserIdLong()).targetType.equalsIgnoreCase("delete")){
// REMOVE CONNECTION
removeConnection(thisEvent.getMessageId(), thisEvent.getReactionEmote(), thisEvent.getChannel().getIdLong());
awatingReactionFrom.remove(thisEvent.getUserIdLong()).message.editMessage(CONFIRM_DELETE).queue(m -> m.delete().queueAfter(1, TimeUnit.MINUTES));
}
} else {
// CHECK IF CONNECTED REACTION AND REMOVE
JSONArray connections = (JSONArray)getConfig().get("connections");
for (Object o : connections){
JSONObject connection = (JSONObject) o;
if (connection.get("messageID").toString().equals(thisEvent.getMessageId())
&& connection.get("reactionEmote").toString().equals(thisEvent.getReactionEmote().getName())){
PermissionOverride po; // Permission Override Object to avoid conflicting scopes
Member member = thisEvent.retrieveMember().complete();
switch (connection.get("targetType").toString()){
case "role":
if (thisEvent.getGuild().getRoleById(connection.get("targetID").toString()) != null) {
thisEvent.getGuild().removeRoleFromMember(member, thisEvent.getGuild().getRoleById(connection.get("targetID").toString())).queue();
} else { // REMOVE DEPRECATED CONNECTION
((JSONArray)getConfig().get("connections")).remove(o);
safeConfig();
}
break;
case "text-channel":
if (thisEvent.getGuild().getTextChannelById(connection.get("targetID").toString()) != null) {
thisEvent.getGuild().getTextChannelById(connection.get("targetID").toString()).getPermissionOverride(member).delete().queue();
} else { // REMOVE DEPRECATED CONNECTION
((JSONArray)getConfig().get("connections")).remove(o);
safeConfig();
}
break;
case "voice-channel":
if (thisEvent.getGuild().getVoiceChannelById(connection.get("targetID").toString()) != null) {
thisEvent.getGuild().getVoiceChannelById(connection.get("targetID").toString()).getPermissionOverride(member).delete().queue();
} else { // REMOVE DEPRECATED CONNECTION
((JSONArray)getConfig().get("connections")).remove(o);
safeConfig();
}
break;
case "category":
if (thisEvent.getGuild().getCategoryById(connection.get("targetID").toString()) != null) {
thisEvent.getGuild().getCategoryById(connection.get("targetID").toString()).getPermissionOverride(member).delete().queue();
} else { // REMOVE DEPRECATED CONNECTION
((JSONArray)getConfig().get("connections")).remove(o);
safeConfig();
}
break;
}
logger.info("REMOVED target " + connection.get("targetID") + " to User" + member.getUser().getId());
break;
}
}
}
}
}
private void removeConnection(String messageId, MessageReaction.ReactionEmote reactionEmote, long channelID) {
JSONArray connections = (JSONArray)getConfig().get("connections");
for (Object o : connections) {
JSONObject connection = (JSONObject) o;
try {
if (reactionEmote.isEmoji()) {
reactionEmote.getJDA().getGuildById(getGuildController().getGUILD_ID()).getTextChannelById(channelID).clearReactionsById(messageId, reactionEmote.getName());
} else {
reactionEmote.getJDA().getGuildById(getGuildController().getGUILD_ID()).getTextChannelById(channelID).clearReactionsById(messageId, reactionEmote.getEmote());
}
} catch (NullPointerException e) {
//
}
if (connection.get("messageID").toString().equalsIgnoreCase(messageId)
&& connection.get("reactionEmote").toString().equals(reactionEmote.getName())) {
logger.info("Delete Connection:" + connection.get("targetID") + " | " + connection.get("messageID") + " | " + connection.get("reactionEmote"));
connections.remove(o);
safeConfig();
}
}
}
@Override
public String showSettings() {
return "NUMBER OF CONNECTIONS: `" + ((JSONArray)getConfig().get("connections")).size() + "`";
}
private class TmpData{
public Message message;
public long targetID;
public String reactionEmote;
public String targetType;
public TmpData(Message message, long targetID, String targetType){
this.message = message;
this.targetID = targetID;
this.targetType = targetType;
}
}
private void addWaitState(long userID, TmpData tmpData){
// Setup wait state
awatingReactionFrom.put(userID, tmpData);
// Setup timer to remove waitstate
new Timer().schedule(new TimerTask(){
public void run(){
awatingReactionFrom.remove(userID).message.editMessage("TimeOut!").queue(m -> m.delete().queueAfter(1, TimeUnit.MINUTES));
}
}, TimeUnit.SECONDS.toMillis(60));
}
}