Skip to content

Commit

Permalink
changed program layout so that each command (or command Group) is it'…
Browse files Browse the repository at this point in the history
…s own class and added a lot of comment and log outputs
  • Loading branch information
maxwai committed Jan 24, 2021
1 parent 46a314b commit f3184a2
Show file tree
Hide file tree
Showing 19 changed files with 1,396 additions and 1,023 deletions.
35 changes: 19 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,40 @@
[![GitHub license](https://badgen.net/github/license/maxwai/ATConnect_Bot)](LICENSE)
[![release](https://badgen.net/github/release/maxwai/ATConnect_Bot)](https://github.com/maxwai/ATConnect_Bot/releases)


# ATConnect Bot

The source code for the ATConnect Bot

## Getting Started

### Prerequisites

You will need Java Version 15 or later to make it work.
It may work with lower Java versions, but it was programmed using the Java 15 JDK.
You will need Java Version 15 or later to make it work. It may work with lower Java versions, but it
was programmed using the Java 15 JDK.

This Bot isa supposed to be running on only one Server at a Time.
**This Bot is supposed to be running on only one Server at a Time.**

### Installing

Download the jar file from the latest release and save it in a folder.
You will need to create at 2 files (These files will be created by the program if not present,
and you will be asked to fill them):
Download the jar file from the latest release and save it in a folder. You will need to create at 2
files (These files will be created by the program if not present, and you will be asked to fill
them):

* Token.cfg (contains only the Bot Token)
* Roles.cfg <br> Layout:
* Guild=\<ID of the Guild>
* Owner=\<ID of the Owner Role>
* Admin=\<ID of the Admin Role>
* Event_Organizer=\<ID of the Event_Organizer Role>
* Instructor=\<ID of the Instructor Role>
* Trained=\<ID of the Trained Roles>
* Guild=\<ID of the Guild>
* Owner=\<ID of the Owner Role>
* Admin=\<ID of the Admin Role>
* Event_Organizer=\<ID of the Event_Organizer Role>
* Instructor=\<ID of the Instructor Role>
* Trained=\<ID of the Trained Roles>

### How to Use

* start the jar file in a terminal with the command `java -jar ATConnect_Bot.jar` <br>
* Start the jar file in a terminal with the command `java -jar ATConnect_Bot.jar` <br>
(do not just double click it to open it)
* For now, all commands are only in Discord, command line commands are in the works
* All commands are only in Discord, command line commands are not necessary since the Bot is
supposed to be run as a daemon and a service for easiness

## TODO

Expand All @@ -45,4 +47,5 @@ and you will be asked to fill them):

## License [![GitHub license](https://badgen.net/github/license/maxwai/ATConnect_Bot)](LICENSE)

This project is licensed under the GNU General Public License - see the [LICENSE](LICENSE) file for details
This project is licensed under the GNU General Public License - see the [LICENSE](LICENSE) file for
details
2 changes: 1 addition & 1 deletion src/main/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Manifest-Version: 1.0
Main-Class: BotMain
Main-Class: Bot.BotMain

199 changes: 199 additions & 0 deletions src/main/java/Bot/BotEvents.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
package Bot;

import Commands.BotStatus;
import Commands.Countdowns;
import Commands.Help;
import Commands.Ping;
import Commands.Purge;
import Commands.Reload;
import Commands.Timezones;
import Commands.Trained;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateNicknameEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent;
import net.dv8tion.jda.api.hooks.SubscribeEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BotEvents {

/**
* Adds a Trashcan so that the Message can be easily deleted by users
*
* @param message The message where the Trashcan should be added
*/
public static void addTrashcan(Message message) {
message.addReaction("\uD83D\uDDD1")
.queue(); // add a reaction to make it easy to delete the post
}

/**
* Deletes the message after the given amount of time in Seconds
*
* @param message The message to delete
* @param seconds Time until the message should be deleted
*/
public static void deleteMessageAfterXTime(Message message, long seconds) {
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException ignored) {
}
message.delete().queue(); // delete the Message after X sec
}

/**
* Returns the Name of the User on the Server
*
* @param member User where we want the name
*
* @return Return the Nickname, or username if nickname is not available
*/
public static String getServerName(Member member) {
String nickname = member.getNickname();
if (nickname == null)
nickname = member.getEffectiveName();
return nickname;
}

/**
* Is triggered when an Emote is added / count is changed
*
* @param event Reaction add Event
*/
@SubscribeEvent
public void onEmoteAdded(GuildMessageReactionAddEvent event) {
if (event.getUser().isBot()) return; // don't react if the bot is adding this emote
Member authorMember = event.getGuild().getMember(event.getUser());
List<Role> rolesOfUser = authorMember != null ? authorMember.getRoles() : new ArrayList<>();
boolean isAdmin =
rolesOfUser.contains(event.getGuild().getRoleById(BotMain.ROLES.get("Admin"))) ||
event.getUser().getIdLong() == BotMain.ROLES.get("Owner");
event.retrieveMessage()
.queue(message -> { // only do something if he is admin or the wastebasket was already here from the bot
if (!message.getAuthor().isBot()) return; // delete only bot messages
if ((isAdmin || message.getReactions().get(0).isSelf())
&& event.getReactionEmote().isEmoji()) {
String emoji = event.getReactionEmote().getEmoji();
if (emoji.substring(0, emoji.length() - 1).equals("\uD83D\uDDD1")
|| emoji.equals("\uD83D\uDDD1")) { // :wastebasket:
LoggerFactory.getLogger("ReactionAdded")
.info("deleting message because of :wastebasket: reaction");
// check if this message was part of a Countdown
if (Countdowns.messageIds.contains(message.getId()))
// close that countdown since the message will be deleted
Countdowns.closeSpecificThread(message.getId());
message.delete().queue(); // delete the message
}
}
});
}

/**
* Is triggered when the Nickname of a User is changed
*
* @param event Nickname Update Event
*/
@SubscribeEvent
public void onNicknameChanged(GuildMemberUpdateNicknameEvent event) {
String newNickOG = event.getNewNickname();
User user = event.getUser();
if (!user.isBot() && newNickOG != null) { // User should not be a Bot
String newNick = newNickOG.toLowerCase(Locale.ROOT);
// User should not be an Alt account
if (newNick.contains("[z") && !newNick.contains("[alt")) {
String newOffset = newNick.substring(newNick.indexOf("[z"));
String oldNick = event.getOldNickname();
Logger logger = LoggerFactory.getLogger("NicknameChanged");
if (oldNick != null) {
oldNick = oldNick.toLowerCase(Locale.ROOT);
String oldOffset = oldNick.substring(oldNick.indexOf("[z"));
// don't change the timezone if the offset is the same
if (!newOffset.equals(oldOffset)) {
if (Timezones.updateSpecificTimezone(user.getIdLong(), newOffset))
logger.info("Updated Timezone of User: " + newNickOG);
else
logger.error("Could not save Timezone of User: " + newNickOG);
}
} else { // old nick could not be loaded but new nick is still there so load timezone anyway
if (Timezones.updateSpecificTimezone(user.getIdLong(), newOffset))
logger.info("Updated Timezone of User: " + event.getNewNickname());
else
logger.error("Could not save Timezone of User: " + event.getNewNickname());
}
}
}
}

/**
* Is triggered when a Message is written
*
* @param event Message Receive Event
*/
@SubscribeEvent
public void onReceiveMessage(MessageReceivedEvent event) {
if (event.getAuthor().isBot()) return;
Logger logger = LoggerFactory.getLogger("ReceivedMessage");
String content = event.getMessage().getContentRaw().toLowerCase(Locale.ROOT);
MessageChannel channel = event.getChannel();

// These boolean are always false if written in a personal message
boolean isAdmin = false;
boolean isEventOrganizer = false;
boolean isInstructor = false;

// if this message is from a Guild/Server then check the roles of the User
if (event.isFromGuild()) {
Member authorMember = event.getGuild().getMember(event.getAuthor());
List<Role> rolesOfUser =
authorMember != null ? authorMember.getRoles() : new ArrayList<>();
isAdmin = rolesOfUser
.contains(event.getGuild().getRoleById(BotMain.ROLES.get("Admin")));
isEventOrganizer = rolesOfUser
.contains(event.getGuild().getRoleById(BotMain.ROLES.get("Event_Organizer")));
isInstructor = rolesOfUser
.contains(event.getGuild().getRoleById(BotMain.ROLES.get("Instructor")));
}
boolean isOwner = event.getAuthor().getIdLong() == BotMain.ROLES.get("Owner");
isAdmin = isAdmin || isOwner; // Owner is also admin

if (content.length() != 0 && content.charAt(0) == '!') {
logger.info("Received Message from " + event.getAuthor().getName() + ": " + content);
String command;
content = content.substring(1);
if (content.indexOf(' ') != -1)
command = content.substring(0, content.indexOf(' '));
else
command = content;
switch (command) {
case "help" -> Help.showHelp(isInstructor, isEventOrganizer, isAdmin,
channel); // show Help Page
case "ping" -> Ping.makePing(channel); // make a ping test
case "time" -> Timezones
.getTimezoneOfUserCommand(event, content); // get the Timezone of a User
case "timezones" -> Timezones.getTimezoneOfAllUsersCommand(event.getGuild(),
channel); // print the Timezone of all Users
case "trained" -> Trained.makeUserTrained(isInstructor, event,
channel); // give a User the Trained Role
case "countdown" -> Countdowns.countdownCommand(isEventOrganizer, isOwner, event,
channel); // create a live countdown
case "restart" -> BotStatus
.restartBot(isAdmin, channel); // restarts the Bot connection
case "reload" -> Reload.reloadMain(isAdmin, event, channel,
content); // reload the Config files or Timezones
case "purge" -> Purge.purgeMessages(isOwner, channel,
content); // purges X Messages from the channel
case "stop" -> BotStatus
.stopBot(isOwner, channel); // stops the Bot, this takes a while
}
}
}

}
Loading

0 comments on commit f3184a2

Please sign in to comment.