Added everything needed for adding the discordBot to the plugin
Shared pom
This commit is contained in:
parent
4e4ebce88d
commit
db46624712
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,7 +1,7 @@
|
|||
.idea/
|
||||
*.iml
|
||||
*.bat
|
||||
*.xml
|
||||
dependency-reduced-pom.xml
|
||||
target/
|
||||
src/test/
|
||||
src/main/resources/
|
||||
118
pom.xml
Normal file
118
pom.xml
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>ProxyDiscordLink</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>maven-snapshots</id>
|
||||
<url>https://repository.apache.org/content/repositories/snapshots/</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean package</defaultGoal>
|
||||
<finalName>${project.name}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<configuration>
|
||||
<source>16</source>
|
||||
<target>16</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>net.kyori.adventure.text.minimessage</pattern>
|
||||
<shadedPattern>com.alttd.proxyutils.libs.net.kyori.adventure.text.minimessage</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>net.dv8tion</pattern>
|
||||
<shadedPattern>com.alttd.proxyutils.libs.net.dv8tion</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>velocity</id>
|
||||
<url>https://repo.velocitypowered.com/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.velocitypowered</groupId>
|
||||
<artifactId>velocity-api</artifactId>
|
||||
<version>1.1.5</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.luckperms</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>5.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.inject</groupId>
|
||||
<artifactId>guice</artifactId>
|
||||
<version>4.1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.26</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.kyori</groupId>
|
||||
<artifactId>adventure-text-minimessage</artifactId>
|
||||
<version>4.1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.dv8tion</groupId>
|
||||
<artifactId>JDA</artifactId>
|
||||
<version>4.2.0_168</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.30</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.alttd.proxydiscordlink;
|
||||
|
||||
import com.alttd.proxydiscordlink.commands.DiscordCommand;
|
||||
import com.alttd.proxydiscordlink.bot.Bot;
|
||||
import com.alttd.proxydiscordlink.commands.MinecraftCommand;
|
||||
import com.alttd.proxydiscordlink.config.Config;
|
||||
import com.alttd.proxydiscordlink.database.Database;
|
||||
import com.alttd.proxydiscordlink.database.DatabaseConnection;
|
||||
|
|
@ -8,6 +9,7 @@ import com.alttd.proxydiscordlink.listeners.PlayerJoin;
|
|||
import com.alttd.proxydiscordlink.listeners.PlayerLeave;
|
||||
import com.alttd.proxydiscordlink.util.ALogger;
|
||||
import com.alttd.proxydiscordlink.util.Cache;
|
||||
import com.alttd.proxydiscordlink.util.JarLoader;
|
||||
import com.google.inject.Inject;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
|
|
@ -32,6 +34,7 @@ public class DiscordLink {
|
|||
private final Path dataDirectory;
|
||||
private final Database database;
|
||||
private final Cache cache;
|
||||
private Bot bot;
|
||||
|
||||
@Inject
|
||||
public DiscordLink(ProxyServer proxyServer, Logger proxyLogger, @DataDirectory Path proxydataDirectory)
|
||||
|
|
@ -58,6 +61,7 @@ public class DiscordLink {
|
|||
}
|
||||
loadCommands();
|
||||
loadEvents();
|
||||
loadBot();
|
||||
}
|
||||
|
||||
public void reloadConfig() {
|
||||
|
|
@ -66,7 +70,7 @@ public class DiscordLink {
|
|||
}
|
||||
|
||||
public void loadCommands() {// all (proxy)commands go here
|
||||
server.getCommandManager().register("discord", new DiscordCommand(), "discordlink");
|
||||
server.getCommandManager().register("discord", new MinecraftCommand(), "discordlink");
|
||||
}
|
||||
|
||||
public void loadEvents() {
|
||||
|
|
@ -74,6 +78,21 @@ public class DiscordLink {
|
|||
server.getEventManager().register(this, new PlayerLeave());
|
||||
}
|
||||
|
||||
public void loadBot() {
|
||||
// String JDAVersion = "4.2.0";
|
||||
// String JDABuild = "168";
|
||||
// String JDAUrl = "https://github.com/DV8FromTheWorld/JDA/releases/download/v" + JDAVersion + "/JDA-" + JDAVersion + "_" + JDABuild + "-withDependencies.jar";
|
||||
// String JDAFile = "jda-" + JDAVersion + "_" + JDABuild + ".jar";
|
||||
// if (new JarLoader().loadJar(JDAUrl, new File(new File(getDataDirectory(), "libs"), JDAFile))) {
|
||||
// ALogger.info("JDA successfully loaded");
|
||||
// } else {
|
||||
// ALogger.error("JDA could not be loaded!");
|
||||
// }
|
||||
bot = new Bot();
|
||||
bot.connect();
|
||||
}
|
||||
|
||||
|
||||
public File getDataDirectory() {
|
||||
return dataDirectory.toFile();
|
||||
}
|
||||
|
|
@ -97,4 +116,8 @@ public class DiscordLink {
|
|||
public Cache getCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
public Bot getBot() {
|
||||
return bot;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
85
src/main/java/com/alttd/proxydiscordlink/bot/Bot.java
Normal file
85
src/main/java/com/alttd/proxydiscordlink/bot/Bot.java
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
package com.alttd.proxydiscordlink.bot;
|
||||
|
||||
import com.alttd.proxydiscordlink.config.BotConfig;
|
||||
import com.alttd.proxydiscordlink.util.ALogger;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.JDABuilder;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class Bot {
|
||||
private JDA jda = null;
|
||||
|
||||
public void connect() {
|
||||
disconnect();
|
||||
try {
|
||||
jda = JDABuilder.createDefault(BotConfig.BOT_TOKEN).build();
|
||||
jda.setAutoReconnect(true);
|
||||
jda.addEventListener(new JDAListener());
|
||||
DiscordCommand.loadCommands();
|
||||
} catch (LoginException e) {
|
||||
jda = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
if (jda != null) {
|
||||
JDA tmp = jda;
|
||||
jda = null;
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException ignore) {
|
||||
}
|
||||
tmp.shutdownNow();
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessageToDiscord(String channelid, String message) {
|
||||
//sendMessageToDiscord(client.getTextChannelById(channel), message, blocking);
|
||||
TextChannel channel = jda.getTextChannelById(channelid);
|
||||
if (jda == null) return;
|
||||
|
||||
if (channel == null) return;
|
||||
|
||||
if (message == null) return;
|
||||
|
||||
// is this even used/needed?
|
||||
//message = ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', message));
|
||||
|
||||
if (message.isEmpty()) return;
|
||||
|
||||
try {
|
||||
channel.sendMessage(message).queue();
|
||||
} catch (Exception e) {
|
||||
ALogger.error("caught some exception, " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendEmbedToDiscord(String channelid, EmbedBuilder embedBuilder, long secondsTillDelete) {
|
||||
//sendMessageToDiscord(client.getTextChannelById(channel), message, blocking);
|
||||
TextChannel channel = jda.getTextChannelById(channelid);
|
||||
if (jda == null) return;
|
||||
|
||||
if (channel == null) return;
|
||||
|
||||
if (embedBuilder == null) return;
|
||||
|
||||
if (!embedBuilder.isValidLength()) return;
|
||||
|
||||
if (embedBuilder.isEmpty()) return;
|
||||
try {
|
||||
if (secondsTillDelete < 0){
|
||||
channel.sendMessage(embedBuilder.build()).queue();
|
||||
} else {
|
||||
channel.sendMessage(embedBuilder.build()).queue(message -> message.delete().queueAfter(secondsTillDelete, TimeUnit.SECONDS));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ALogger.error("caught some exception, " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package com.alttd.proxydiscordlink.bot;
|
||||
|
||||
import com.alttd.proxydiscordlink.bot.commands.DiscordServerList;
|
||||
import com.alttd.proxydiscordlink.bot.commands.DiscordStaffList;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class DiscordCommand {
|
||||
|
||||
private static List<DiscordCommand> commands;
|
||||
|
||||
public abstract String getCommand();
|
||||
public abstract String getPermission();// TODO discord and LP permissions
|
||||
public abstract String getDescription();
|
||||
public abstract String getSyntax();
|
||||
|
||||
public abstract void handleCommand(Message message, String sender, String command, String[] args);
|
||||
|
||||
protected static void loadCommands() {
|
||||
commands = new ArrayList<>();
|
||||
|
||||
loadCommand(new DiscordStaffList(),
|
||||
new DiscordServerList()
|
||||
);
|
||||
}
|
||||
|
||||
private static void loadCommand(DiscordCommand ... discordCommands) {
|
||||
Collections.addAll(commands, discordCommands);
|
||||
}
|
||||
|
||||
protected static List<DiscordCommand> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.alttd.proxydiscordlink.bot;
|
||||
|
||||
import com.alttd.proxydiscordlink.DiscordLink;
|
||||
import com.alttd.proxydiscordlink.config.BotConfig;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class JDAListener extends ListenerAdapter {
|
||||
|
||||
private DiscordLink plugin;
|
||||
private final Bot bot;
|
||||
|
||||
public JDAListener() {
|
||||
plugin = DiscordLink.getPlugin();
|
||||
bot = plugin.getBot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuildMessageReceived(GuildMessageReceivedEvent event) {
|
||||
if (event.getAuthor() == event.getJDA().getSelfUser()) {
|
||||
return;
|
||||
}
|
||||
if (event.isWebhookMessage()) {
|
||||
return;
|
||||
}
|
||||
if (event.getMessage().getChannel().getId().equals(BotConfig.COMMAND_CHANNEL)) {
|
||||
String content = event.getMessage().getContentRaw();
|
||||
if (content.startsWith("!") && content.length() > 1) {
|
||||
String[] split = content.split(" ");
|
||||
String cmd = split[0].substring(1).toLowerCase();
|
||||
String[] args = Arrays.copyOfRange(split, 1, split.length);
|
||||
for(DiscordCommand command : DiscordCommand.getCommands()) {
|
||||
if(!command.getCommand().equalsIgnoreCase(cmd)) {
|
||||
continue;
|
||||
}
|
||||
if(command.getPermission() != null) {
|
||||
// TODO permission check? do we need this?
|
||||
}
|
||||
command.handleCommand(event.getMessage(), event.getAuthor().getName(), cmd, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.alttd.proxydiscordlink.bot.api;
|
||||
|
||||
import com.alttd.proxydiscordlink.DiscordLink;
|
||||
import com.alttd.proxydiscordlink.bot.Bot;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public class DiscordSendMessage {
|
||||
public static void sendMessage(String channelId, String message)
|
||||
{
|
||||
Bot bot = DiscordLink.getPlugin().getBot();
|
||||
|
||||
bot.sendMessageToDiscord(channelId, message);
|
||||
}
|
||||
|
||||
public static void sendEmbed(String channelId, String title, String description)
|
||||
{
|
||||
Bot bot = DiscordLink.getPlugin().getBot();
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||
|
||||
embedBuilder.setColor(Color.CYAN);
|
||||
embedBuilder.setTitle(title);
|
||||
embedBuilder.setDescription(description);
|
||||
|
||||
bot.sendEmbedToDiscord(channelId, embedBuilder, -1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.alttd.proxydiscordlink.bot.commands;
|
||||
|
||||
import com.alttd.proxydiscordlink.DiscordLink;
|
||||
import com.alttd.proxydiscordlink.bot.Bot;
|
||||
import com.alttd.proxydiscordlink.bot.DiscordCommand;
|
||||
import com.alttd.proxydiscordlink.config.BotConfig;
|
||||
import com.alttd.proxydiscordlink.util.Utilities;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
|
||||
public class DiscordBroadCast extends DiscordCommand {
|
||||
|
||||
private DiscordLink plugin;
|
||||
private final Bot bot;
|
||||
|
||||
public DiscordBroadCast() {
|
||||
plugin = DiscordLink.getPlugin();
|
||||
bot = plugin.getBot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommand() {
|
||||
return "broadcast";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermission() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Broadcast a message to all online players";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "!broadcast";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(Message message, String sender, String command, String[] args) {
|
||||
//TODO also send this to the bot channel, optional command args for color and decoration?
|
||||
String msg = String.join(" ", args);
|
||||
bot.sendMessageToDiscord(BotConfig.COMMAND_CHANNEL, msg);
|
||||
Utilities.broadcast(msg);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
package com.alttd.proxydiscordlink.bot.commands;
|
||||
|
||||
import com.alttd.proxydiscordlink.DiscordLink;
|
||||
import com.alttd.proxydiscordlink.bot.Bot;
|
||||
import com.alttd.proxydiscordlink.bot.DiscordCommand;
|
||||
import com.alttd.proxydiscordlink.config.BotConfig;
|
||||
import com.alttd.proxydiscordlink.util.Utilities;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerInfo;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.model.user.User;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DiscordServerList extends DiscordCommand {
|
||||
|
||||
private DiscordLink plugin;
|
||||
private final Bot bot;
|
||||
|
||||
public DiscordServerList() {
|
||||
plugin = DiscordLink.getPlugin();
|
||||
bot = plugin.getBot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommand() {
|
||||
return "serverlist";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermission() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Lists all online players on the server or a specific server";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "!serverlist";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(Message message, String sender, String command, String[] args) {
|
||||
String serverName = "Altitude";
|
||||
Collection<Player> onlinePlayer = plugin.getProxy().getAllPlayers();
|
||||
ServerInfo server;
|
||||
if (args.length != 0) {
|
||||
Optional<RegisteredServer> registeredServer = plugin.getProxy().getServer(args[0]);
|
||||
if (registeredServer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
onlinePlayer = registeredServer.get().getPlayersConnected();
|
||||
serverName = registeredServer.get().getServerInfo().getName();
|
||||
}
|
||||
LuckPerms luckPerms = Utilities.getLuckPerms();
|
||||
List<User> players = onlinePlayer
|
||||
.stream()
|
||||
.map(player -> luckPerms.getUserManager().getUser(player.getUniqueId()))
|
||||
.sorted((o1, o2) -> {
|
||||
int i = Integer.compare(luckPerms.getGroupManager().getGroup(o2.getPrimaryGroup()).getWeight().orElse(0), luckPerms.getGroupManager().getGroup(o1.getPrimaryGroup()).getWeight().orElse(0));
|
||||
return i != 0 ? i : o1.getUsername().compareToIgnoreCase(o2.getUsername());
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||
String title = "Players online on " + serverName + ": " + players.size();
|
||||
embedBuilder.setTitle(title);
|
||||
String separator = "\n";
|
||||
String rankname = "";
|
||||
StringBuilder currentFieldText = new StringBuilder();
|
||||
int entryCounter = 0;
|
||||
int totalCharacters = title.length();
|
||||
int fieldCounter = 0;
|
||||
|
||||
Iterator<User> iterator = players.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
User user = iterator.next();
|
||||
if(user != null) {
|
||||
if(!rankname.equalsIgnoreCase(user.getPrimaryGroup())) {
|
||||
if (currentFieldText.length() != 0) {
|
||||
totalCharacters += rankname.length() + currentFieldText.length();
|
||||
fieldCounter++;
|
||||
if (totalCharacters > 6000 || fieldCounter > 25) {
|
||||
bot.sendEmbedToDiscord(BotConfig.COMMAND_CHANNEL, embedBuilder, 300);
|
||||
embedBuilder.clearFields();
|
||||
totalCharacters = title.length() + rankname.length() + currentFieldText.length();
|
||||
fieldCounter = 1;
|
||||
}
|
||||
embedBuilder.addField(rankname, currentFieldText.toString(), true);
|
||||
entryCounter = 0;
|
||||
currentFieldText = new StringBuilder();
|
||||
}
|
||||
rankname = Utilities.capitalize(user.getPrimaryGroup());
|
||||
} else if(rankname.equalsIgnoreCase(user.getPrimaryGroup())) {
|
||||
currentFieldText.append(separator);
|
||||
}
|
||||
if (entryCounter <= 50) {
|
||||
Optional<Player> optionalPlayer = plugin.getProxy().getPlayer(user.getUniqueId());
|
||||
if(optionalPlayer.isPresent()) {
|
||||
Player player = optionalPlayer.get();
|
||||
currentFieldText.append("`").append(player.getUsername()).append("`");
|
||||
}
|
||||
} else if (entryCounter == 51){
|
||||
currentFieldText.append("...");
|
||||
}
|
||||
entryCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentFieldText.length() > 0) {
|
||||
totalCharacters = title.length() + rankname.length() + currentFieldText.length();
|
||||
fieldCounter++;
|
||||
if (totalCharacters > 6000 || fieldCounter > 25) {
|
||||
bot.sendEmbedToDiscord(BotConfig.COMMAND_CHANNEL, embedBuilder, 300);
|
||||
embedBuilder.clearFields();
|
||||
}
|
||||
embedBuilder.addField(rankname, currentFieldText.toString(), true);
|
||||
}
|
||||
|
||||
message.delete().queueAfter(300, TimeUnit.SECONDS);
|
||||
bot.sendEmbedToDiscord(BotConfig.COMMAND_CHANNEL, embedBuilder, 300);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
package com.alttd.proxydiscordlink.bot.commands;
|
||||
|
||||
import com.alttd.proxydiscordlink.DiscordLink;
|
||||
import com.alttd.proxydiscordlink.bot.Bot;
|
||||
import com.alttd.proxydiscordlink.bot.DiscordCommand;
|
||||
import com.alttd.proxydiscordlink.config.BotConfig;
|
||||
import com.alttd.proxydiscordlink.util.Utilities;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.model.user.User;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DiscordStaffList extends DiscordCommand {
|
||||
|
||||
private DiscordLink plugin;
|
||||
private final Bot bot;
|
||||
|
||||
public DiscordStaffList() {
|
||||
plugin = DiscordLink.getPlugin();
|
||||
bot = plugin.getBot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommand() {
|
||||
return "stafflist";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPermission() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "Lists all online staff on the server";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSyntax() {
|
||||
return "!StaffList";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCommand(Message message, String sender, String command, String[] args) {
|
||||
LuckPerms luckPerms = Utilities.getLuckPerms();
|
||||
List<User> staff = plugin.getProxy().getAllPlayers()
|
||||
.stream().filter(player-> player.hasPermission("group." + BotConfig.SL_MINIMUMRANK))
|
||||
.map(player -> luckPerms.getUserManager().getUser(player.getUniqueId()))
|
||||
.sorted((o1, o2) -> {
|
||||
int i = Integer.compare(luckPerms.getGroupManager().getGroup(o2.getPrimaryGroup()).getWeight().orElse(0), luckPerms.getGroupManager().getGroup(o1.getPrimaryGroup()).getWeight().orElse(0));
|
||||
return i != 0 ? i : o1.getUsername().compareToIgnoreCase(o2.getUsername());
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||
String title = "Online Staff: " + staff.size() + " - Online Players: " + plugin.getProxy().getAllPlayers().size();
|
||||
embedBuilder.setTitle(title);
|
||||
String separator = "\n";
|
||||
String rankname = "";
|
||||
|
||||
Map<String, Integer> onlineStaff = new HashMap<>();
|
||||
StringBuilder currentFieldText = new StringBuilder();
|
||||
int entryCounter = 0;
|
||||
int totalCharacters = title.length();
|
||||
int fieldCounter = 0;
|
||||
|
||||
Iterator<User> iterator = staff.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
User user = iterator.next();
|
||||
if(user != null) {
|
||||
if(!rankname.equalsIgnoreCase(user.getPrimaryGroup())) {
|
||||
if (currentFieldText.length() != 0) {
|
||||
totalCharacters += rankname.length() + currentFieldText.length();
|
||||
fieldCounter++;
|
||||
if (totalCharacters > 6000 || fieldCounter > 25) {
|
||||
bot.sendEmbedToDiscord(BotConfig.COMMAND_CHANNEL, embedBuilder, -1);
|
||||
embedBuilder.clearFields();
|
||||
totalCharacters = title.length() + rankname.length() + currentFieldText.length();
|
||||
fieldCounter = 1;
|
||||
}
|
||||
embedBuilder.addField(rankname, currentFieldText.toString(), true);
|
||||
entryCounter = 0;
|
||||
currentFieldText = new StringBuilder();
|
||||
}
|
||||
rankname = Utilities.capitalize(user.getPrimaryGroup());
|
||||
} else if(rankname.equalsIgnoreCase(user.getPrimaryGroup())) {
|
||||
currentFieldText.append(separator);
|
||||
}
|
||||
|
||||
Optional<Player> optionalPlayer = plugin.getProxy().getPlayer(user.getUniqueId());
|
||||
if(optionalPlayer.isPresent()) {
|
||||
Player player = optionalPlayer.get();
|
||||
String currentServerName = player.getCurrentServer().isPresent() ? player.getCurrentServer().get().getServerInfo().getName() : "";
|
||||
if (onlineStaff.containsKey(currentServerName)){
|
||||
onlineStaff.put(currentServerName, onlineStaff.get(currentServerName) + 1);
|
||||
} else {
|
||||
onlineStaff.put(currentServerName, 1);
|
||||
}
|
||||
|
||||
if (entryCounter <= 50) {
|
||||
currentFieldText.append("`").append(player.getUsername()).append("`");
|
||||
} else if (entryCounter == 51){
|
||||
currentFieldText.append("...");
|
||||
}
|
||||
entryCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentFieldText.length() > 0) {
|
||||
totalCharacters = title.length() + rankname.length() + currentFieldText.length();
|
||||
fieldCounter++;
|
||||
if (totalCharacters > 6000 || fieldCounter > 25) {
|
||||
bot.sendEmbedToDiscord(BotConfig.COMMAND_CHANNEL, embedBuilder, -1);
|
||||
embedBuilder.clearFields();
|
||||
}
|
||||
embedBuilder.addField(rankname, currentFieldText.toString(), true);
|
||||
currentFieldText = new StringBuilder();
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Integer> entry : onlineStaff.entrySet()){
|
||||
String serverName = entry.getKey();
|
||||
Integer amountOfStaff = entry.getValue();
|
||||
// this might error:/
|
||||
int playerCount = plugin.getProxy().getServer(serverName).isPresent() ? plugin.getProxy().getServer(serverName).get().getPlayersConnected().size() - amountOfStaff : 1;
|
||||
currentFieldText.append(serverName).append(" online staff per player ")
|
||||
.append(amountOfStaff).append(" / ").append(Math.max(playerCount, 0)).append(" = ")
|
||||
.append(playerCount > 0 ? Math.round(((double)amountOfStaff / playerCount) * 100.0) / 100.0 : "-").append("\n");
|
||||
}
|
||||
|
||||
if (currentFieldText.length() > 0) {
|
||||
rankname = "Staff per server";
|
||||
totalCharacters = title.length() + rankname.length() + currentFieldText.length();
|
||||
fieldCounter++;
|
||||
if (totalCharacters > 6000 || fieldCounter > 25) {
|
||||
bot.sendEmbedToDiscord(BotConfig.COMMAND_CHANNEL, embedBuilder, -1);
|
||||
embedBuilder.clearFields();
|
||||
}
|
||||
embedBuilder.addField(rankname, currentFieldText.toString(), true);
|
||||
}
|
||||
|
||||
bot.sendEmbedToDiscord(BotConfig.COMMAND_CHANNEL, embedBuilder, -1);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,12 +17,12 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class DiscordCommand implements SimpleCommand {
|
||||
public class MinecraftCommand implements SimpleCommand {
|
||||
|
||||
private final List<SubCommand> subCommands;
|
||||
private final MiniMessage miniMessage;
|
||||
|
||||
public DiscordCommand() {
|
||||
public MinecraftCommand() {
|
||||
subCommands = Arrays.asList(new CheckLinked(), new Link(), new Unlink(), new Reload());
|
||||
miniMessage = MiniMessage.get();
|
||||
}
|
||||
181
src/main/java/com/alttd/proxydiscordlink/config/BotConfig.java
Normal file
181
src/main/java/com/alttd/proxydiscordlink/config/BotConfig.java
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
package com.alttd.proxydiscordlink.config;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
import ninja.leaping.configurate.ConfigurationOptions;
|
||||
import ninja.leaping.configurate.objectmapping.ObjectMappingException;
|
||||
import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class BotConfig {
|
||||
private static final Pattern PATH_PATTERN = Pattern.compile("\\.");
|
||||
private static final String HEADER = "";
|
||||
|
||||
private static File CONFIG_FILE;
|
||||
public static ConfigurationNode config;
|
||||
public static YAMLConfigurationLoader configLoader;
|
||||
|
||||
static int version;
|
||||
static boolean verbose;
|
||||
|
||||
public static File CONFIGPATH;
|
||||
|
||||
public static void init() { // todo setup share for the config
|
||||
CONFIGPATH = new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs" + File.separator + "DiscordLink");
|
||||
CONFIG_FILE = new File(CONFIGPATH, "bot-config.yml");
|
||||
|
||||
configLoader = YAMLConfigurationLoader.builder()
|
||||
.setFile(CONFIG_FILE)
|
||||
.setFlowStyle(DumperOptions.FlowStyle.BLOCK)
|
||||
.build();
|
||||
if (!CONFIG_FILE.getParentFile().exists()) {
|
||||
if (!CONFIG_FILE.getParentFile().mkdirs()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!CONFIG_FILE.exists()) {
|
||||
try {
|
||||
if (!CONFIG_FILE.createNewFile()) {
|
||||
return;
|
||||
}
|
||||
} catch (IOException error) {
|
||||
error.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
config = configLoader.load(ConfigurationOptions.defaults().setHeader(HEADER));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
verbose = getBoolean("verbose", true);
|
||||
version = getInt("config-version", 1);
|
||||
|
||||
readConfig(Config.class, null);
|
||||
try {
|
||||
configLoader.save(config);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void readConfig(Class<?> clazz, Object instance) {
|
||||
for (Method method : clazz.getDeclaredMethods()) {
|
||||
if (Modifier.isPrivate(method.getModifiers())) {
|
||||
if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) {
|
||||
try {
|
||||
method.setAccessible(true);
|
||||
method.invoke(instance);
|
||||
} catch (InvocationTargetException | IllegalAccessException ex) {
|
||||
throw Throwables.propagate(ex.getCause());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
configLoader.save(config);
|
||||
} catch (IOException ex) {
|
||||
throw Throwables.propagate(ex.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveConfig() {
|
||||
try {
|
||||
configLoader.save(config);
|
||||
} catch (IOException ex) {
|
||||
throw Throwables.propagate(ex.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
private static Object[] splitPath(String key) {
|
||||
return PATH_PATTERN.split(key);
|
||||
}
|
||||
|
||||
private static void set(String path, Object def) {
|
||||
if (config.getNode(splitPath(path)).isVirtual())
|
||||
config.getNode(splitPath(path)).setValue(def);
|
||||
}
|
||||
|
||||
private static void setString(String path, String def) {
|
||||
try {
|
||||
if (config.getNode(splitPath(path)).isVirtual())
|
||||
config.getNode(splitPath(path)).setValue(TypeToken.of(String.class), def);
|
||||
} catch (ObjectMappingException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean getBoolean(String path, boolean def) {
|
||||
set(path, def);
|
||||
return config.getNode(splitPath(path)).getBoolean(def);
|
||||
}
|
||||
|
||||
private static double getDouble(String path, double def) {
|
||||
set(path, def);
|
||||
return config.getNode(splitPath(path)).getDouble(def);
|
||||
}
|
||||
|
||||
private static int getInt(String path, int def) {
|
||||
set(path, def);
|
||||
return config.getNode(splitPath(path)).getInt(def);
|
||||
}
|
||||
|
||||
private static String getString(String path, String def) {
|
||||
setString(path, def);
|
||||
return config.getNode(splitPath(path)).getString(def);
|
||||
}
|
||||
|
||||
private static Long getLong(String path, Long def) {
|
||||
set(path, def);
|
||||
return config.getNode(splitPath(path)).getLong(def);
|
||||
}
|
||||
|
||||
private static <T> List<String> getList(String path, T def) {
|
||||
try {
|
||||
set(path, def);
|
||||
return config.getNode(splitPath(path)).getList(TypeToken.of(String.class));
|
||||
} catch (ObjectMappingException ex) {
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
private static ConfigurationNode getNode(String path) {
|
||||
if (config.getNode(splitPath(path)).isVirtual()) {
|
||||
//new RegexConfig("Dummy");
|
||||
}
|
||||
config.getChildrenMap();
|
||||
return config.getNode(splitPath(path));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ONLY EDIT ANYTHING BELOW THIS LINE
|
||||
**/
|
||||
|
||||
public static String BOT_TOKEN = "";
|
||||
public static String COMMAND_CHANNEL = "";
|
||||
private static void settings()
|
||||
{
|
||||
BOT_TOKEN = getString("settings.token", BOT_TOKEN);
|
||||
COMMAND_CHANNEL = getString("settings.command_channel", COMMAND_CHANNEL);
|
||||
}
|
||||
|
||||
public static String SL_MINIMUMRANK = "trainee";
|
||||
public static String SL_HOVERMESSAGE = "Click here to message %player% on %servername%.";
|
||||
public static String SL_CLICKCOMMAND = "/msg %player%";
|
||||
private static void Stafflist() {
|
||||
SL_MINIMUMRANK = getString("commands.staff-list.minimum-rank", SL_MINIMUMRANK);
|
||||
SL_HOVERMESSAGE = getString("commands.staff-list.hover-message", SL_HOVERMESSAGE);
|
||||
SL_CLICKCOMMAND = getString("commands.staff-list.click-command", SL_CLICKCOMMAND);
|
||||
}
|
||||
}
|
||||
131
src/main/java/com/alttd/proxydiscordlink/util/JarLoader.java
Normal file
131
src/main/java/com/alttd/proxydiscordlink/util/JarLoader.java
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
package com.alttd.proxydiscordlink.util;
|
||||
|
||||
import com.alttd.proxydiscordlink.DiscordLink;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
|
||||
public class JarLoader {
|
||||
|
||||
private static final Method ADD_URL_METHOD;
|
||||
|
||||
static {
|
||||
try {
|
||||
ADD_URL_METHOD = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
|
||||
ADD_URL_METHOD.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
|
||||
private URLClassLoader classLoader;
|
||||
|
||||
public JarLoader() {
|
||||
classLoader = ((URLClassLoader) DiscordLink.getPlugin().getClass().getClassLoader());
|
||||
}
|
||||
|
||||
public boolean loadJar(String url, File file) {
|
||||
try {
|
||||
if (!file.getParentFile().exists()) {
|
||||
if (!file.getParentFile().mkdirs()) {
|
||||
ALogger.warn("Could not create directory: " + file.getParentFile().getAbsolutePath());
|
||||
}
|
||||
}
|
||||
|
||||
if (file.exists() && file.isDirectory()) {
|
||||
Files.delete(file.toPath());
|
||||
}
|
||||
|
||||
if (!file.exists()) {
|
||||
ALogger.info("Jar not found! (" + file.getName() + ")");
|
||||
ALogger.info("Downloading jar from " + url);
|
||||
downloadJar(url, file);
|
||||
}
|
||||
|
||||
ADD_URL_METHOD.invoke(classLoader, file.toPath().toUri().toURL());
|
||||
return true;
|
||||
} catch (IOException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void downloadJar(String url, File file) throws IOException {
|
||||
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
|
||||
conn.setInstanceFollowRedirects(true);
|
||||
|
||||
boolean redirect;
|
||||
|
||||
do {
|
||||
int status = conn.getResponseCode();
|
||||
redirect = status == HttpURLConnection.HTTP_MOVED_TEMP ||
|
||||
status == HttpURLConnection.HTTP_MOVED_PERM ||
|
||||
status == HttpURLConnection.HTTP_SEE_OTHER;
|
||||
|
||||
if (redirect) {
|
||||
String newUrl = conn.getHeaderField("Location");
|
||||
String cookies = conn.getHeaderField("Set-Cookie");
|
||||
|
||||
conn = (HttpURLConnection) new URL(newUrl).openConnection();
|
||||
conn.setRequestProperty("Cookie", cookies);
|
||||
conn.addRequestProperty("Accept-Language", "en-US,en;q=0.8");
|
||||
}
|
||||
} while (redirect);
|
||||
|
||||
Progress progress = new Progress(conn.getContentLength());
|
||||
progress.start();
|
||||
|
||||
try (BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(file)) {
|
||||
byte[] dataBuffer = new byte[1024];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
|
||||
progress.current += bytesRead;
|
||||
fileOutputStream.write(dataBuffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
|
||||
progress.interrupt();
|
||||
}
|
||||
|
||||
private class Progress extends Thread {
|
||||
private final long total;
|
||||
private long current;
|
||||
|
||||
private Progress(long total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
//noinspection InfiniteLoopStatement
|
||||
while (true) {
|
||||
logProgress();
|
||||
sleep(1000);
|
||||
}
|
||||
} catch (InterruptedException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interrupt() {
|
||||
logProgress();
|
||||
super.interrupt();
|
||||
}
|
||||
|
||||
private void logProgress() {
|
||||
ALogger.info(String.format("progress: %s%% (%s/%s)",
|
||||
(int) ((((double) current) / ((double) total)) * 100D),
|
||||
current, total));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package com.alttd.proxydiscordlink.util;
|
||||
|
||||
import com.alttd.proxydiscordlink.DiscordLink;
|
||||
import com.alttd.proxydiscordlink.config.Config;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.Template;
|
||||
import net.luckperms.api.LuckPerms;
|
||||
import net.luckperms.api.LuckPermsProvider;
|
||||
import net.luckperms.api.model.user.User;
|
||||
|
|
@ -86,4 +86,16 @@ public class Utilities {
|
|||
public static String getRankName(Player player) {
|
||||
return getLuckPerms().getUserManager().getUser(player.getUniqueId()).getPrimaryGroup();
|
||||
}
|
||||
|
||||
public static String capitalize(String str) {
|
||||
if(str == null || str.isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
||||
}
|
||||
|
||||
public static void broadcast(String message) {
|
||||
ProxyServer server = DiscordLink.getPlugin().getProxy();
|
||||
server.sendMessage(miniMessage.parse(message));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user