Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discord Integration (Resolves #1833) #2170

Open
wants to merge 2 commits into
base: TFM1.13-Alpha
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@
<version>6.1.0-TF</version>
</dependency>

<dependency>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[ERROR] Failed to execute goal on project totalfreedom: Could not resolve dependencies for project me.totalfreedom:totalfreedom:jar:5.0.2: Failure to find net.dv8tion:JDA:jar:3.8.0_423 in http://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced -> [Help 1]

<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>3.8.0_423</version>
<scope>provided</scope>
</dependency>

</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import me.totalfreedom.totalfreedommod.caging.Cager;
import me.totalfreedom.totalfreedommod.command.CommandLoader;
import me.totalfreedom.totalfreedommod.config.MainConfig;
import me.totalfreedom.totalfreedommod.discord.Discord;
import me.totalfreedom.totalfreedommod.freeze.Freezer;
import me.totalfreedom.totalfreedommod.fun.ItemFun;
import me.totalfreedom.totalfreedommod.fun.Jumppads;
Expand Down Expand Up @@ -74,6 +75,7 @@ public class TotalFreedomMod extends AeroPlugin<TotalFreedomMod>
public PlayerList pl;
public Announcer an;
public ChatManager cm;
public Discord dc;
public BanManager bm;
public PermbanList pm;
public ProtectArea pa;
Expand Down Expand Up @@ -167,6 +169,7 @@ public void enable()
pl = services.registerService(PlayerList.class);
an = services.registerService(Announcer.class);
cm = services.registerService(ChatManager.class);
dc = services.registerService(Discord.class);
bm = services.registerService(BanManager.class);
pm = services.registerService(PermbanList.class);
pa = services.registerService(ProtectArea.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public class Admin implements ConfigLoadable, ConfigSavable, Validatable
@Getter
@Setter
private String loginMessage = null;
@Getter
@Setter
private String discordID = null;

public Admin(Player player)
{
Expand All @@ -62,7 +65,8 @@ public String toString()
.append("- Last Login: ").append(FUtil.dateToString(lastLogin)).append("\n")
.append("- Custom Login Message: ").append(loginMessage).append("\n")
.append("- Rank: ").append(rank.getName()).append("\n")
.append("- Is Active: ").append(active);
.append("- Is Active: ").append(active)
.append("- Discord ID: ").append(discordID).append("\n");

return output.toString();
}
Expand All @@ -85,6 +89,7 @@ public void loadFrom(ConfigurationSection cs)
ips.addAll(cs.getStringList("ips"));
lastLogin = FUtil.stringToDate(cs.getString("last_login"));
loginMessage = cs.getString("login_message", null);
discordID = cs.getString("discord_id", null);
}

@Override
Expand All @@ -97,6 +102,7 @@ public void saveTo(ConfigurationSection cs)
cs.set("ips", Lists.newArrayList(ips));
cs.set("last_login", FUtil.dateToString(lastLogin));
cs.set("login_message", loginMessage);
cs.set("discord_id", discordID);
}

public boolean isAtLeast(Rank pRank)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package me.totalfreedom.totalfreedommod.command;

import java.util.Random;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.discord.Discord;
import me.totalfreedom.totalfreedommod.rank.Rank;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Link your Discord account to your Minecraft account", usage = "/<command>")
public class Command_linkdiscord extends FreedomCommand
{

@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (!plugin.dc.enabled)
{
msg("The Discord verification system is currently disabled.", ChatColor.RED);
return true;
}

Admin admin = plugin.al.getAdmin(playerSender);
if (admin.getDiscordID() != null)
{
msg("Your Minecraft account is already linked to a Discord account.", ChatColor.RED);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens in the event you want to over-write your discord ID? I'd be inclined to allow it? OR at the very least we tell people on the command to un-link first?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlink and re-link

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ZeroEpoch1969 Have players been confused around this before or just tend to get that they need to un-link and re-link?

return true;
}

if (Discord.LINK_CODES.containsValue(admin))
{
msg("Your linking code is " + ChatColor.GREEN + Discord.getCode(admin), ChatColor.AQUA);
}
else
{
String code = "";
Random random = new Random();
for (int i = 0; i < 5; i++)
{
code += random.nextInt(10);
}
Discord.LINK_CODES.put(code, admin);
msg("Your linking code is " + ChatColor.GREEN + code, ChatColor.AQUA);
}
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package me.totalfreedom.totalfreedommod.command;

import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.rank.Rank;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

@CommandPermissions(level = Rank.SUPER_ADMIN, source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Unlink your Discord account to your Minecraft account", usage = "/<command>")
public class Command_unlinkdiscord extends FreedomCommand
{

@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (!plugin.dc.enabled)
{
msg("The Discord verification system is currently disabled.", ChatColor.RED);
return true;
}

Admin admin = plugin.al.getAdmin(playerSender);
if (admin.getDiscordID() == null)
{
msg("Your Minecraft account is not linked to a Discord account.", ChatColor.RED);
return true;
}
admin.setDiscordID(null);
plugin.al.save();
msg("Your Minecraft account has been successfully unlinked from the Discord account.", ChatColor.GREEN);
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package me.totalfreedom.totalfreedommod.command;

import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.util.FUtil;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.discord.Discord;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.ChatColor;
import java.util.Random;
import java.util.Date;
import net.pravian.aero.util.Ips;

@CommandPermissions(level = Rank.IMPOSTOR, source = SourceType.ONLY_IN_GAME)
@CommandParameters(description = "Sends a verification code to the player, or the player can input the sent code.", usage = "/<command> [code]")
public class Command_verify extends FreedomCommand
{

@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{
if (!plugin.dc.enabled)
{
msg("The discord verification system is currently disabled", ChatColor.RED);
return true;
}

if (!plugin.al.isAdminImpostor(playerSender))
{
msg("You are not an imposter, therefore you do not need to verify.", ChatColor.RED);
return true;
}

Admin admin = plugin.al.getEntryByName(playerSender.getName());

if (admin.getDiscordID() == null)
{
msg("You do not have a discord account linked to your minecraft account, please verify the manual way.", ChatColor.RED);
return true;
}

if (args.length < 1)
{
String code = "";
Random random = new Random();
for (int i = 0; i < 10; i++)
{
code += random.nextInt(10);
}
Discord.VERIFY_CODES.add(code);
Discord.bot.getUserById(admin.getDiscordID()).openPrivateChannel().complete().sendMessage("A user with the ip `" + Ips.getIp(playerSender) + "` has sent a verification request. Please run the following in-game command: `/verify " + code + "`").complete();
msg("A verification code has been sent to your account, please copy the code and run /verify <code>", ChatColor.GREEN);
}
else
{
String code = args[0];
if (!Discord.VERIFY_CODES.contains(code))
{
msg("You have entered an invalid verification code", ChatColor.RED);
return true;
}
else
{
Discord.VERIFY_CODES.remove(code);
FUtil.bcastMsg(playerSender.getName() + " has verified themself!", ChatColor.GOLD);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we word this something like "Has verified themselves through the Discord verification method" or something like that?

FUtil.adminAction(ConfigEntry.SERVER_NAME.getString(), "Readding " + admin.getName() + " to the admin list", true);
admin.setName(playerSender.getName());
admin.addIp(Ips.getIp(playerSender));
admin.setActive(true);
admin.setLastLogin(new Date());
plugin.al.save();
plugin.al.updateTables();
final FPlayer fPlayer = plugin.pl.getPlayer(playerSender);
if (fPlayer.getFreezeData().isFrozen())
{
fPlayer.getFreezeData().setFrozen(false);
msg("You have been unfrozen.");
}
}
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public enum ConfigEntry
SERVER_BAN_URL(String.class, "server.ban_url"),
SERVER_PERMBAN_URL(String.class, "server.permban_url"),
//
DISCORD_TOKEN(String.class, "discord.token"),
//
ADMINLIST_CLEAN_THESHOLD_HOURS(Integer.class, "adminlist.clean_threshold_hours"),
ADMINLIST_CONSOLE_IS_SENIOR(Boolean.class, "adminlist.console_is_senior"),
//
Expand Down
85 changes: 85 additions & 0 deletions src/main/java/me/totalfreedom/totalfreedommod/discord/Discord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package me.totalfreedom.totalfreedommod.discord;

import com.google.common.base.Strings;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.security.auth.login.LoginException;
import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.util.FLog;
import net.dv8tion.jda.core.AccountType;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.JDABuilder;

public class Discord extends FreedomService
{
public static HashMap<String, Admin> LINK_CODES = new HashMap<>();
public static List<String> VERIFY_CODES = new ArrayList();
public static JDA bot = null;
public Boolean enabled = false;

public Discord(TotalFreedomMod plugin)
{
super(plugin);
}

public void startBot()
{
enabled = !Strings.isNullOrEmpty(ConfigEntry.DISCORD_TOKEN.getString());
if (!enabled)
{
return;
}
if (bot != null)
{
for (Object object : bot.getRegisteredListeners())
{
bot.removeEventListener(object);
}
}
try
{
bot = new JDABuilder(AccountType.BOT).setToken(ConfigEntry.DISCORD_TOKEN.getString()).addEventListener(new MessageListener()).setAudioEnabled(false).setAutoReconnect(true).buildBlocking();
FLog.info("Discord verification bot has successfully enabled!");
}
catch (LoginException e)
{
FLog.warning("An invalid token for the discord verification bot, the bot will not enable.");
}
catch (IllegalArgumentException | InterruptedException e)
{
FLog.warning("Discord verification bot failed to start.");
}
}

@Override
protected void onStart()
{
startBot();
}

public static String getCode(Admin admin)
{
for (String code : LINK_CODES.keySet())
{
if (LINK_CODES.get(code).equals(admin))
{
return code;
}
}
return null;
}

@Override
protected void onStop()
{
if (bot != null)
{
bot.shutdown();
}
FLog.info("Discord verification bot has successfully shutdown.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package me.totalfreedom.totalfreedommod.discord;

import me.totalfreedom.totalfreedommod.admin.Admin;
import net.dv8tion.jda.core.events.message.priv.PrivateMessageReceivedEvent;
import net.dv8tion.jda.core.hooks.ListenerAdapter;

public class MessageListener extends ListenerAdapter
{
public void onPrivateMessageReceived(PrivateMessageReceivedEvent event)
{
if (!event.getAuthor().getId().equals(Discord.bot.getSelfUser().getId()))
{
// Handle link code
if (event.getMessage().getContentRaw().matches("[0-9][0-9][0-9][0-9][0-9]"))
{
String code = event.getMessage().getContentRaw();
if (Discord.LINK_CODES.get(code) != null)
{
Admin admin = Discord.LINK_CODES.get(code);
admin.setDiscordID(event.getMessage().getAuthor().getId());
Discord.LINK_CODES.remove(code);
event.getChannel().sendMessage("Link successful. Now this Discord account is linked with the Minecraft account `" + admin.getName() + "`.\n "
+ "Now when you are an impostor on the server, you may use `/verify` to verify.").complete();
}
}
}
}
}
5 changes: 5 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ server:
# URL players should appeal for permanent bans at
permban_url: http://bit.ly/TF_PermBan

# Discord
discord:
# If you do not have a token, make a bot account and get one at https://discordapp.com/developers/applications/me
token: ''

# Admin list
adminlist:

Expand Down