diff --git a/pom.xml b/pom.xml
index dbf2760..8bb101a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,10 +35,31 @@
8
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+ bungeecore
+
+
+ dv8tion
+ m2-dv8tion
+ https://m2.dv8tion.net/releases
+
+
+
steamwar
@@ -61,5 +82,23 @@
system${main.basedir}/lib/BungeeTabListPlus.jar
+
+ net.dv8tion
+ JDA
+ 4.3.0_299
+ compile
+
+
+ club.minnced
+ opus-java
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.20
+ provided
+
\ No newline at end of file
diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java
index e3a11b0..7dee2ca 100644
--- a/src/de/steamwar/bungeecore/BungeeCore.java
+++ b/src/de/steamwar/bungeecore/BungeeCore.java
@@ -19,16 +19,19 @@
package de.steamwar.bungeecore;
+import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
import de.steamwar.bungeecore.commands.*;
import de.steamwar.bungeecore.comms.SpigotReceiver;
import de.steamwar.bungeecore.listeners.*;
-import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker;
import de.steamwar.bungeecore.listeners.mods.Forge;
import de.steamwar.bungeecore.listeners.mods.LabyMod;
+import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker;
import de.steamwar.bungeecore.listeners.mods.WorldDownloader;
-import de.steamwar.bungeecore.sql.SQL;
+import de.steamwar.bungeecore.sql.Statement;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.bungeecore.sql.Team;
+import net.dv8tion.jda.api.JDA;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
@@ -108,6 +111,7 @@ public class BungeeCore extends Plugin {
new DenyCommand("watchcat", "wc");
new TeamCommand();
new ServerTeamchatCommand();
+ new DevCommand();
new EventCommand();
new EventreloadCommand();
new EventRescheduleCommand();
@@ -121,6 +125,9 @@ public class BungeeCore extends Plugin {
new UnIgnoreCommand();
new PollresultCommand();
new ResourcereloadCommand();
+ new ListCommand();
+ new StatCommand();
+ new VerifyCommand();
if(!EVENT_MODE){
new BauCommand();
@@ -145,12 +152,20 @@ public class BungeeCore extends Plugin {
SteamwarUser.clearCache();
Team.clearCache();
}, 1, 1, TimeUnit.HOURS);
+
+ new SteamwarDiscordBot();
}
@Override
public void onDisable(){
ErrorLogger.stop();
- SQL.close();
+ Statement.close();
+ try {
+ SteamwarDiscordBot.instance().getJda().shutdownNow();
+ SteamwarDiscordBot.instance().getJda().awaitStatus(JDA.Status.SHUTDOWN);
+ } catch (Exception e) {
+ // Ignored
+ }
}
public static BungeeCore get() {
@@ -245,13 +260,14 @@ public class BungeeCore extends Plugin {
Persistent.setChatPrefix(CHAT_PREFIX);
Persistent.setLobbyServer(LOBBY_SERVER);
- SQL.connect(
+ Statement.connect(
config.getString("db.url"),
config.getString("db.username"),
config.getString("db.password")
);
ArenaMode.init(config.getSection("games"));
+ SteamwarDiscordBotConfig.loadConfig(config.getSection("discord"));
final Configuration servers = config.getSection("servers");
for(final String serverName : servers.getKeys()){
diff --git a/src/de/steamwar/bungeecore/LoadEvaluation.java b/src/de/steamwar/bungeecore/LoadEvaluation.java
new file mode 100644
index 0000000..59fda6c
--- /dev/null
+++ b/src/de/steamwar/bungeecore/LoadEvaluation.java
@@ -0,0 +1,96 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2021 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore;
+
+import java.io.*;
+
+public class LoadEvaluation {
+ private LoadEvaluation(){}
+
+ private static final File meminfo = new File("/proc/meminfo");
+
+ public static double getRamPercentage() {
+ try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(meminfo)))) {
+ String memTotal = bufferedReader.readLine().replaceAll(" +", " ");
+ bufferedReader.readLine();
+ String memAvailable = bufferedReader.readLine().replaceAll(" +", " ");
+
+ long memTotalLong = getNumber(memTotal);
+ long memAvailableLong = getNumber(memAvailable);
+ return (memTotalLong - memAvailableLong) / (double) memTotalLong;
+ } catch (IOException e) {
+ return 1D;
+ }
+ }
+
+ public static double getRemoteRamPercentage(String remote) {
+ try {
+ // Attention:
+ // memInfo.sh needs to contain: cat /proc/meminfo
+ Process process = new ProcessBuilder("ssh", remote, "\"./memInfo.sh\"").start();
+ process.waitFor();
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ String memTotal = bufferedReader.readLine().replaceAll(" +", " ");
+ bufferedReader.readLine();
+ String memAvailable = bufferedReader.readLine().replaceAll(" +", " ");
+
+ long memTotalLong = getNumber(memTotal);
+ long memAvailableLong = getNumber(memAvailable);
+ return (memTotalLong - memAvailableLong) / (double) memTotalLong;
+ } catch (IOException e) {
+ return 1D;
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return 1D;
+ }
+ }
+
+ public static double getCPULoad() {
+ try {
+ Process process = new ProcessBuilder("bash", "-c", "cat <(grep 'cpu ' /proc/stat) <(sleep 1 && grep 'cpu ' /proc/stat) | awk -v RS=\"\" '{printf \"%.2f\\n\", ($13-$2+$15-$4)*100/($13-$2+$15-$4+$16-$5)}'").start();
+ process.waitFor();
+ return Double.parseDouble(new BufferedReader(new InputStreamReader(process.getInputStream())).readLine()) / 100.0;
+ } catch (IOException e) {
+ return 1D;
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return 1D;
+ }
+ }
+
+ public static double getRemoteCPULoad(String remote) {
+ try {
+ // Attention:
+ // cpuLoad.sh needs to contain: cat <(grep 'cpu ' /proc/stat) <(sleep 1 && grep 'cpu ' /proc/stat) | awk -v RS="" '{printf "%.2f\n", ($13-$2+$15-$4)*100/($13-$2+$15-$4+$16-$5)}'
+ Process process = new ProcessBuilder("ssh", remote, "\"./cpuLoad.sh\"").start();
+ process.waitFor();
+ return Double.parseDouble(new BufferedReader(new InputStreamReader(process.getInputStream())).readLine()) / 100.0;
+ } catch (IOException e) {
+ return 1D;
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ return 1D;
+ }
+ }
+
+ private static long getNumber(String s) {
+ return Long.parseLong(s.split(" ")[1]);
+ }
+}
diff --git a/src/de/steamwar/bungeecore/SubserverSystem.java b/src/de/steamwar/bungeecore/SubserverSystem.java
index 2812eb3..d5e85b0 100644
--- a/src/de/steamwar/bungeecore/SubserverSystem.java
+++ b/src/de/steamwar/bungeecore/SubserverSystem.java
@@ -89,7 +89,7 @@ public class SubserverSystem {
* @return
* The new started subserver.
*/
- public static Subserver startArena(ArenaMode modus, String map, int eventFightID, int checkSchemID, int prepareSchemID, String serverName, String mapName, UUID player1, UUID player2, boolean ranked){
+ public static synchronized Subserver startArena(ArenaMode modus, String map, int eventFightID, int checkSchemID, int prepareSchemID, String serverName, String mapName, UUID player1, UUID player2, boolean ranked){
//Generate missing parameters
int port = freePort(FIRST_ARENA_PORT);
@@ -118,8 +118,10 @@ public class SubserverSystem {
Thread.currentThread().interrupt();
}
+ File directory = new File(SERVER_PATH, modus.getFolder());
List cmd = serverStartCommand(
modus.serverJar(),
+ directory,
worldDir,
mapName,
port,
@@ -135,7 +137,7 @@ public class SubserverSystem {
//Start server
ProcessBuilder process = new ProcessBuilder(cmd);
- process.directory(new File(SERVER_PATH, modus.getFolder()));
+ process.directory(directory);
String finalMapName = mapName;
if(eventFightID == -1)
@@ -177,7 +179,7 @@ public class SubserverSystem {
startArena(m, map, -1, checkSchemId, prepareSchemId, p.getName() + "s Bau", p.getName(), p.getUniqueId(), null, false).sendPlayer(p);
}
- private static void sendToBau(ProxiedPlayer p, UUID owner, String prototype, String worldFolder, String serverJar, String worldDir, String worldName, String xmx, String serverName){
+ private static synchronized void sendToBau(ProxiedPlayer p, UUID owner, String prototype, String worldFolder, String serverJar, String worldDir, String worldName, String xmx, String serverName){
if(bauRunning(p, owner))
return;
@@ -185,8 +187,10 @@ public class SubserverSystem {
copyBauweltIfRequired(p, prototype, worldFolder + worldName);
int port = freePort(4000);
+ File directory = new File(SERVER_PATH, serverName);
List cmd = serverStartCommand(
serverJar,
+ directory,
worldDir,
worldName,
port,
@@ -195,7 +199,7 @@ public class SubserverSystem {
//Start server
ProcessBuilder process = new ProcessBuilder(cmd);
- process.directory(new File(SERVER_PATH, serverName));
+ process.directory(directory);
new Bauserver(user.getUserName() + "s Bau", owner, port, process, () -> {}).sendPlayer(p);
}
@@ -231,9 +235,30 @@ public class SubserverSystem {
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bau addmember " + p.getName()));
}
- private static List serverStartCommand(String serverJar, String worldDir, String levelName, int port, String xmx, String... dParams){
+ private static List serverStartCommand(String serverJar, File directory, String worldDir, String levelName, int port, String xmx, String... dParams){
List cmd = new ArrayList<>();
boolean jdk11 = serverJar.contains("1.15.2");
+
+ boolean fallback = false;
+ if (!steamwarStartAvailable()) {
+ cmd.add("ssh");
+ cmd.add("-L");
+ cmd.add(port + ":localhost:" + port);
+ if (remoteStartAvailable("lx")) {
+ cmd.add("lx");
+ } else if (remoteStartAvailable("az")) {
+ cmd.add("az");
+ } else {
+ fallback = true;
+ }
+ cmd.add("cd");
+ cmd.add(directory.getPath());
+ cmd.add(";");
+ }
+ if (fallback) {
+ cmd.clear();
+ }
+
if(jdk11)
cmd.add("/usr/lib/jvm/java-11-openjdk-amd64/bin/java");
else
@@ -259,6 +284,14 @@ public class SubserverSystem {
return cmd;
}
+ private static boolean steamwarStartAvailable(){
+ return LoadEvaluation.getCPULoad() < 0.7 && LoadEvaluation.getRamPercentage() < 0.8;
+ }
+
+ private static boolean remoteStartAvailable(String remote) {
+ return LoadEvaluation.getRemoteCPULoad(remote) < 0.7 && LoadEvaluation.getRemoteRamPercentage(remote) < 0.8;
+ }
+
private static boolean bauRunning(ProxiedPlayer p, UUID owner){
for(Subserver subserver : Subserver.getServerList()){
if(subserver.getType() == Servertype.BAUSERVER && ((Bauserver)subserver).getOwner().equals(owner)){
diff --git a/src/de/steamwar/bungeecore/bot/AuthManager.java b/src/de/steamwar/bungeecore/bot/AuthManager.java
new file mode 100644
index 0000000..1502b68
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/AuthManager.java
@@ -0,0 +1,86 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot;
+
+import de.steamwar.bungeecore.BungeeCore;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Emoji;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.interactions.components.ActionRow;
+import net.dv8tion.jda.api.interactions.components.Button;
+import net.md_5.bungee.api.scheduler.ScheduledTask;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+public class AuthManager {
+
+ private static final Map TOKENS = new HashMap<>();
+ private static final Random rand = new Random();
+
+ public static String createDiscordAuthToken(Member member) {
+ if(TOKENS.containsValue(member.getIdLong())) return null;
+
+ byte[] randBytes = new byte[16];
+ rand.nextBytes(randBytes);
+ randBytes[0] = 'D';
+ randBytes[1] = 'C';
+ String code = Base64.getEncoder().encodeToString(randBytes);
+
+ TOKENS.put(code, member.getIdLong());
+ BungeeCore.log("Created Discord Auth-Token: " + code + " for: " + member.getUser().getAsTag());
+ ScheduledTask[] task = new ScheduledTask[1];
+ task[0] = BungeeCore.get().getProxy().getScheduler().schedule(BungeeCore.get(), () -> {
+ TOKENS.remove(code);
+ task[0].cancel();
+ }, 10, 10, TimeUnit.MINUTES);
+ return code;
+ }
+
+ public static Member connectAuth(SteamwarUser user, String code) {
+ if (TOKENS.containsKey(code)) {
+ Member member = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).retrieveMemberById(TOKENS.get(code).longValue()).complete();
+ if(member == null) return null;
+ user.setDiscordId(member.getId());
+ MessageBuilder builder = new MessageBuilder();
+ builder.setContent(":white_check_mark: Dein Discord Konto wurde mit **" + user.getUserName() + "** verknüpft");
+ builder.setActionRows(ActionRow.of(Button.success("tada", Emoji.fromUnicode("U+1F389")), Button.danger("invalid", "Ich war das nicht")));
+
+ try {
+ member.getUser().openPrivateChannel().complete().sendMessage(builder.build()).complete();
+ if (member.getNickname() == null) {
+ try {
+ member.getGuild().modifyNickname(member, user.getUserName()).complete();
+ } catch (Exception e) {
+ // Ignored
+ }
+ }
+ TOKENS.remove(code);
+ return member;
+ } catch (Exception e) {
+ return null;
+ }
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/SteamwarDiscordBot.java b/src/de/steamwar/bungeecore/bot/SteamwarDiscordBot.java
new file mode 100644
index 0000000..7c5f1db
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/SteamwarDiscordBot.java
@@ -0,0 +1,153 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot;
+
+import de.steamwar.bungeecore.BungeeCore;
+import de.steamwar.bungeecore.bot.commands.*;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import de.steamwar.bungeecore.bot.events.EventManager;
+import de.steamwar.bungeecore.bot.events.SchematicsManager;
+import de.steamwar.bungeecore.bot.listeners.*;
+import de.steamwar.bungeecore.bot.util.DiscordRolesMessage;
+import de.steamwar.bungeecore.bot.util.DiscordRulesMessage;
+import de.steamwar.bungeecore.bot.util.DiscordTicketMessage;
+import de.steamwar.bungeecore.sql.Event;
+import lombok.Getter;
+import net.dv8tion.jda.api.JDA;
+import net.dv8tion.jda.api.JDABuilder;
+import net.dv8tion.jda.api.OnlineStatus;
+import net.dv8tion.jda.api.entities.Activity;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.hooks.ListenerAdapter;
+import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction;
+import net.dv8tion.jda.api.utils.MemberCachePolicy;
+import net.md_5.bungee.api.ProxyServer;
+
+import javax.security.auth.login.LoginException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class SteamwarDiscordBot {
+
+ private static SteamwarDiscordBot INSTANCE;
+
+ public static SteamwarDiscordBot instance() {
+ return INSTANCE;
+ }
+
+ @Getter
+ private AnnouncementListener announcementListener;
+
+ @Getter
+ private IngameChatListener ingameChatListener;
+
+ @Getter
+ private ServerTeamChatListener serverTeamChatListener;
+
+ @Getter
+ private final JDA jda;
+
+ @Getter
+ private static Map discordCommandMap = new HashMap<>();
+
+ public SteamwarDiscordBot() {
+ INSTANCE = this;
+ JDABuilder builder = JDABuilder.createDefault(SteamwarDiscordBotConfig.TOKEN);
+ builder.setStatus(OnlineStatus.ONLINE);
+ builder.setMemberCachePolicy(MemberCachePolicy.ONLINE);
+ try {
+ jda = builder.build();
+ } catch (LoginException e) {
+ throw new SecurityException("Could not Login: " + SteamwarDiscordBotConfig.TOKEN, e);
+ }
+ try {
+ jda.awaitReady();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ activity();
+ EventManager.update();
+ SchematicsManager.update();
+ ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
+ activity();
+ EventManager.update();
+ SchematicsManager.update();
+ }, 30, 30, TimeUnit.SECONDS);
+ DiscordRolesMessage.sendMessage();
+ DiscordRulesMessage.sendMessage();
+ DiscordTicketMessage.sendMessage();
+
+ new RolesInteractionButtonListener();
+ new DiscordTicketListener();
+ new DiscordAuthListener();
+ announcementListener = new AnnouncementListener();
+ ingameChatListener = new IngameChatListener();
+ serverTeamChatListener = new ServerTeamChatListener();
+ new SlashCommandListener();
+
+ jda.retrieveCommands().complete().forEach(command -> jda.deleteCommandById(command.getId()).complete());
+
+ Guild guild = jda.getGuildById(SteamwarDiscordBotConfig.GUILD);
+ guild.retrieveCommands().complete().forEach(command -> guild.deleteCommandById(command.getId()).complete());
+ CommandListUpdateAction commands = jda.getGuildById(SteamwarDiscordBotConfig.GUILD).updateCommands();
+ addCommand(commands, new MuteCommand());
+ addCommand(commands, new BanCommand());
+ addCommand(commands, new WhoisCommand());
+ addCommand(commands, new TeamCommand());
+ addCommand(commands, new ListCommand());
+ addCommand(commands, new UnbanCommand());
+ commands.complete();
+ }
+
+ private void addCommand(CommandListUpdateAction commands, BasicDiscordCommand basicDiscordCommand) {
+ commands.addCommands(basicDiscordCommand);
+ discordCommandMap.put(basicDiscordCommand.getName(), basicDiscordCommand);
+ }
+
+ private int index = 0;
+
+ private void activity() {
+ switch (index) {
+ case 0:
+ Event event = Event.get();
+ if (event != null) {
+ jda.getPresence().setActivity(Activity.competing("dem Event " + event.getEventName()));
+ } else {
+ jda.getPresence().setActivity(Activity.playing("auf SteamWar.de"));
+ }
+ break;
+ case 1:
+ int count = BungeeCore.get().getProxy().getOnlineCount();
+ if (count == 1) {
+ jda.getPresence().setActivity(Activity.playing("mit 1 Spieler"));
+ } else {
+ jda.getPresence().setActivity(Activity.playing("mit " + count + " Spielern"));
+ }
+ index = 0;
+ return;
+ }
+ index++;
+ }
+
+ public void addListener(ListenerAdapter listenerAdapter) {
+ jda.addEventListener(listenerAdapter);
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/commands/BanCommand.java b/src/de/steamwar/bungeecore/bot/commands/BanCommand.java
new file mode 100644
index 0000000..7d3772f
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/commands/BanCommand.java
@@ -0,0 +1,65 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.commands;
+
+import de.steamwar.bungeecore.Message;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+
+import java.sql.Timestamp;
+
+public class BanCommand extends BasicDiscordCommand {
+
+ public BanCommand() {
+ super("ban", "Banne einen Nutzer, wenn du die Rechte hast.");
+
+ addOption(OptionType.STRING, "user", "Der Benutzer", true);
+ addOption(OptionType.STRING, "time", "Bis Wann", true);
+ addOption(OptionType.STRING, "reason", "Warum", true);
+ }
+
+ @Override
+ public void run(SlashCommandEvent event) {
+ if (!testPermission(event)) {
+ return;
+ }
+
+ SteamwarUser sender = SteamwarUser.get(event.getMember().getIdLong());
+ SteamwarUser target = SteamwarUser.getOrCreateOfflinePlayer(event.getOption("user").getAsString());
+ if (target == null) {
+ event.reply("Angegebener User invalide").setEphemeral(true).complete();
+ return;
+ }
+
+ Timestamp time = de.steamwar.bungeecore.commands.BanCommand.parseTime(null, event.getOption("time").getAsString());
+ if (time == null) {
+ event.reply("Angegebene Zeit invalide").setEphemeral(true).complete();
+ return;
+ }
+
+ String msg = event.getOption("reason").getAsString();
+ boolean isPerma = event.getOption("time").getAsString().equals("perma");
+
+ target.ban(time, msg, sender.getId(), isPerma);
+ Message.team("BAN_TEAM_BANNED", new Message("PREFIX"), target.getUserName(), sender.getUserName(), new Message((isPerma ? "BAN_PERMA" : "BAN_UNTIL"), time), msg);
+ event.reply("Erfolgreich " + target.getUserName() + (isPerma ? " permanent" : " bis " + time) + " gebannt").setEphemeral(true).complete();
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/commands/BasicDiscordCommand.java b/src/de/steamwar/bungeecore/bot/commands/BasicDiscordCommand.java
new file mode 100644
index 0000000..a767eba
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/commands/BasicDiscordCommand.java
@@ -0,0 +1,54 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.commands;
+
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import de.steamwar.bungeecore.sql.UserGroup;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import net.dv8tion.jda.api.interactions.commands.build.CommandData;
+
+public abstract class BasicDiscordCommand extends CommandData {
+
+ protected BasicDiscordCommand(String name, String description) {
+ super(name, description);
+ }
+
+ public abstract void run(SlashCommandEvent event);
+
+ protected SteamwarUser getSteamwarUser(SlashCommandEvent event) {
+ Member member = event.getMember();
+ SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
+ if (steamwarUser == null) {
+ return null;
+ }
+ return steamwarUser;
+ }
+
+ protected boolean testPermission(SlashCommandEvent event) {
+ Member member = event.getMember();
+ SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
+ if (steamwarUser == null || (!steamwarUser.getUserGroup().isTeamGroup() && steamwarUser.getUserGroup() != UserGroup.Builder)) {
+ event.reply("Du hast für " + event.getName() + " keine Rechte oder es existiert keine Verknüpfung für dich.").setEphemeral(true).complete();
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/commands/ListCommand.java b/src/de/steamwar/bungeecore/bot/commands/ListCommand.java
new file mode 100644
index 0000000..2050180
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/commands/ListCommand.java
@@ -0,0 +1,43 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.commands;
+
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+
+import java.util.stream.Collectors;
+
+public class ListCommand extends BasicDiscordCommand {
+
+ public ListCommand() {
+ super("list", "Gebe eine Liste aller online Spieler");
+ }
+
+ @Override
+ public void run(SlashCommandEvent event) {
+ de.steamwar.bungeecore.commands.ListCommand.updateCustomTablist();
+ EmbedBuilder embedBuilder = new EmbedBuilder();
+ embedBuilder.setTitle("List");
+ de.steamwar.bungeecore.commands.ListCommand.getPlayerMap().forEach((s, proxiedPlayers) -> {
+ embedBuilder.addField(s, proxiedPlayers.stream().map(player -> "`" + player.getName() + "`").collect(Collectors.joining(", ")), true);
+ });
+ event.replyEmbeds(embedBuilder.build()).setEphemeral(true).complete();
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/commands/MuteCommand.java b/src/de/steamwar/bungeecore/bot/commands/MuteCommand.java
new file mode 100644
index 0000000..700baac
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/commands/MuteCommand.java
@@ -0,0 +1,66 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.commands;
+
+import de.steamwar.bungeecore.Message;
+import de.steamwar.bungeecore.commands.BanCommand;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+
+import java.sql.Timestamp;
+
+public class MuteCommand extends BasicDiscordCommand {
+
+ public MuteCommand() {
+ super("mute", "Mute einen Nutzer, wenn du die Rechte hast.");
+
+ addOption(OptionType.STRING, "user", "Der Benutzer", true);
+ addOption(OptionType.STRING, "time", "Bis Wann", true);
+ addOption(OptionType.STRING, "reason", "Warum", true);
+ }
+
+ @Override
+ public void run(SlashCommandEvent event) {
+ if (!testPermission(event)) {
+ return;
+ }
+
+ SteamwarUser sender = SteamwarUser.get(event.getMember().getIdLong());
+ SteamwarUser target = SteamwarUser.getOrCreateOfflinePlayer(event.getOption("user").getAsString());
+ if (target == null) {
+ event.reply("Angegebener User invalide").setEphemeral(true).complete();
+ return;
+ }
+
+ Timestamp time = BanCommand.parseTime(null, event.getOption("time").getAsString());
+ if (time == null) {
+ event.reply("Angegebene Zeit invalide").setEphemeral(true).complete();
+ return;
+ }
+
+ String msg = event.getOption("reason").getAsString();
+ boolean isPerma = event.getOption("time").getAsString().equals("perma");
+
+ target.mute(time, msg, sender.getId(), isPerma);
+ Message.team("MUTE_TEAM_MUTED", new Message("PREFIX"), target.getUserName(), sender.getUserName(), new Message((isPerma ? "BAN_PERMA" : "BAN_UNTIL"), time), msg);
+ event.reply("Erfolgreich " + target.getUserName() + (isPerma ? " permanent" : " bis " + time) + " gemutet").setEphemeral(true).complete();
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/commands/TeamCommand.java b/src/de/steamwar/bungeecore/bot/commands/TeamCommand.java
new file mode 100644
index 0000000..53d7039
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/commands/TeamCommand.java
@@ -0,0 +1,96 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.commands;
+
+import de.steamwar.bungeecore.sql.Event;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import de.steamwar.bungeecore.sql.Team;
+import de.steamwar.bungeecore.sql.TeamTeilnahme;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.entities.Emoji;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionMapping;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
+import net.md_5.bungee.api.ProxyServer;
+
+import java.awt.*;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class TeamCommand extends BasicDiscordCommand {
+
+ public TeamCommand() {
+ super("team", "Alle Team bezogenen Befehle");
+
+ addSubcommands(new SubcommandData("info", "Infos über das Team oder deins")
+ .addOption(OptionType.STRING, "team", "Name oder Kuerzel", false)
+ );
+ }
+
+ private Emoji emoji = Emoji.fromUnicode("U+1F7E2");
+
+ @Override
+ public void run(SlashCommandEvent event) {
+ SteamwarUser steamwarUser = getSteamwarUser(event);
+
+ if (event.getSubcommandName() != null) {
+ switch (event.getSubcommandName()) {
+ case "info":
+ OptionMapping optionMapping = event.getOption("team");
+ Team team;
+ if (optionMapping == null) {
+ if (steamwarUser == null) {
+ event.reply("Dein Discord ist nicht verknüpft").setEphemeral(true).complete();
+ return;
+ }
+ if (steamwarUser.getTeam() == 0) {
+ event.reply("Du bist in keinem Team").setEphemeral(true).complete();
+ return;
+ }
+ team = Team.get(steamwarUser.getTeam());
+ } else {
+ team = Team.get(optionMapping.getAsString());
+ }
+ if (team == null) {
+ event.reply("Unbekanntes Team").setEphemeral(true).complete();
+ return;
+ }
+ EmbedBuilder embedBuilder = new EmbedBuilder();
+ embedBuilder.setTitle("Team: " + team.getTeamName() + " [" + team.getTeamKuerzel() + "]");
+ embedBuilder.setColor(Color.GRAY);
+ List members = team.getMembers().stream().map(SteamwarUser::get).collect(Collectors.toList());
+
+ embedBuilder.addField("Leader", members.stream().filter(SteamwarUser::isLeader).map(user -> "`" + (isOnline(user) ? emoji.getAsMention() : "") + user.getUserName() + "`").collect(Collectors.joining(" ")), false);
+ embedBuilder.addField("Member", members.stream().filter(user -> !user.isLeader()).map(user -> "`" + (isOnline(user) ? emoji.getAsMention() : "") + user.getUserName() + "`").collect(Collectors.joining(" ")), false);
+ embedBuilder.addField("Events", "`" + TeamTeilnahme.getEvents(team.getTeamId()).stream().map(Event::getEventName).collect(Collectors.joining("` `")) + "`", false);
+ event.replyEmbeds(embedBuilder.build()).setEphemeral(true).complete();
+ return;
+ default:
+ event.reply("Unbekannter Befehl").setEphemeral(true).complete();
+ return;
+ }
+ }
+ }
+
+ private boolean isOnline(SteamwarUser user) {
+ return ProxyServer.getInstance().getPlayer(user.getUuid()) != null;
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/commands/UnbanCommand.java b/src/de/steamwar/bungeecore/bot/commands/UnbanCommand.java
new file mode 100644
index 0000000..7147108
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/commands/UnbanCommand.java
@@ -0,0 +1,59 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.commands;
+
+import de.steamwar.bungeecore.Message;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+
+import java.sql.Timestamp;
+import java.util.Date;
+
+public class UnbanCommand extends BasicDiscordCommand {
+
+ public UnbanCommand() {
+ super("unban", "Entbannt einen Nutzer, wenn du die Rechte hast.");
+
+ addOption(OptionType.STRING, "user", "Der Benutzer", true);
+ }
+
+ @Override
+ public void run(SlashCommandEvent event) {
+ if (!testPermission(event)) {
+ return;
+ }
+
+ SteamwarUser sender = SteamwarUser.get(event.getMember().getIdLong());
+ SteamwarUser target = SteamwarUser.getOrCreateOfflinePlayer(event.getOption("user").getAsString());
+ if (target == null) {
+ event.reply("Angegebener User invalide").setEphemeral(true).complete();
+ return;
+ }
+
+ if (!target.isBanned()) {
+ event.reply("Angegebener User ist nicht gebannt").setEphemeral(true).complete();
+ return;
+ }
+
+ target.ban(Timestamp.from(new Date().toInstant()), "Unban", sender.getId(), false);
+ event.reply("Erfolgreich " + target.getUserName() + " entbannt").setEphemeral(true).complete();
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/commands/WhoisCommand.java b/src/de/steamwar/bungeecore/bot/commands/WhoisCommand.java
new file mode 100644
index 0000000..b40c049
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/commands/WhoisCommand.java
@@ -0,0 +1,94 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.commands;
+
+import de.steamwar.bungeecore.sql.Punishment;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import de.steamwar.bungeecore.sql.Team;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import net.dv8tion.jda.api.interactions.commands.OptionType;
+
+import java.sql.Timestamp;
+import java.text.DecimalFormat;
+import java.util.List;
+
+public class WhoisCommand extends BasicDiscordCommand {
+
+ public WhoisCommand() {
+ super("whois", "Der whois Befehl");
+
+ addOption(OptionType.STRING, "user", "Der Benutzer", true);
+ }
+
+ @Override
+ public void run(SlashCommandEvent event) {
+ if (!testPermission(event)) {
+ return;
+ }
+
+ String s = event.getOption("user").getAsString();
+
+ SteamwarUser user = SteamwarUser.get(s);
+ if (user == null) {
+ try {
+ int id = Integer.parseInt(s);
+ user = SteamwarUser.get(id);
+ } catch (NumberFormatException ignored) {
+ // Ignored
+ }
+ }
+ if (user == null) {
+ try {
+ long id = Long.parseLong(s);
+ user = SteamwarUser.get(id);
+ } catch (NumberFormatException ignored) {
+ // Ignored
+ }
+ }
+
+ if (user == null) {
+ event.reply("Der angegebene Spieler ist unbekannt").setEphemeral(true).complete();
+ return;
+ }
+
+ EmbedBuilder embedBuilder = new EmbedBuilder();
+ embedBuilder.setTitle("Whois: " + user.getUserName());
+ StringBuilder st = new StringBuilder();
+ st.append("UUID: ").append(user.getUuid()).append("\n");
+ st.append("ID: ").append(user.getId()).append("\n");
+ if (user.getDiscordId() != null) {
+ st.append("DiscordID: ").append(user.getDiscordId()).append("\n");
+ }
+ Timestamp timestamp = user.getFirstjoin();
+ st.append("Beigetreten am: ").append(timestamp == null ? "0000-00-00 00:00:00" : timestamp.toString()).append("\n");
+ st.append("Online Time: ").append(new DecimalFormat("###.##").format(user.getOnlinetime() / (double) 3600)).append("h\n");
+ Team team = Team.get(user.getTeam());
+ st.append("Team: [").append(team.getTeamKuerzel()).append("] ").append(team.getTeamName());
+ embedBuilder.addField("Daten:", st.toString(), false);
+
+ List punishmentList = Punishment.getAllPunishmentsOfPlayer(user.getId());
+ for (Punishment punishment : punishmentList) {
+ embedBuilder.addField(punishment.getType().name() + " von " + SteamwarUser.get(punishment.getPunisher()).getUserName(), "Von: " + punishment.getBantime(punishment.getStartTime(), false) + "\nBis: " + punishment.getBantime(punishment.getEndTime(), punishment.isPerma()) + "\nGrund: " + punishment.getReason(), true);
+ }
+
+ event.replyEmbeds(embedBuilder.build()).setEphemeral(true).complete();
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/config/DiscordRole.java b/src/de/steamwar/bungeecore/bot/config/DiscordRole.java
new file mode 100644
index 0000000..68b57be
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/config/DiscordRole.java
@@ -0,0 +1,39 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.config;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import net.dv8tion.jda.api.entities.Emoji;
+import net.dv8tion.jda.api.interactions.components.Button;
+import net.dv8tion.jda.api.interactions.components.ButtonStyle;
+
+@Data
+@AllArgsConstructor
+public class DiscordRole {
+
+ private String emoji;
+ private String label;
+ private String roleId;
+
+ public Button toButton() {
+ return Button.of(ButtonStyle.SECONDARY, roleId, label, Emoji.fromUnicode(emoji));
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/config/DiscordRulesLink.java b/src/de/steamwar/bungeecore/bot/config/DiscordRulesLink.java
new file mode 100644
index 0000000..4f2ebe0
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/config/DiscordRulesLink.java
@@ -0,0 +1,36 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.config;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import net.dv8tion.jda.api.interactions.components.Button;
+
+@Data
+@AllArgsConstructor
+public class DiscordRulesLink {
+
+ private String label;
+ private String link;
+
+ public Button toButton() {
+ return Button.link(link, label);
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/config/DiscordTicketType.java b/src/de/steamwar/bungeecore/bot/config/DiscordTicketType.java
new file mode 100644
index 0000000..5ba4c65
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/config/DiscordTicketType.java
@@ -0,0 +1,41 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.config;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import net.dv8tion.jda.api.entities.Emoji;
+import net.dv8tion.jda.api.interactions.components.Button;
+import net.dv8tion.jda.api.interactions.components.ButtonStyle;
+
+@Data
+@AllArgsConstructor
+public class DiscordTicketType {
+
+ private String key;
+ private String emoji;
+ private String label;
+ private String color;
+ private String preMessage;
+
+ public Button toButton() {
+ return Button.of(ButtonStyle.valueOf(color), key, Emoji.fromUnicode(emoji)).withLabel(label);
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/config/SteamwarDiscordBotConfig.java b/src/de/steamwar/bungeecore/bot/config/SteamwarDiscordBotConfig.java
new file mode 100644
index 0000000..f69a3ac
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/config/SteamwarDiscordBotConfig.java
@@ -0,0 +1,114 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.config;
+
+import de.steamwar.bungeecore.sql.UserGroup;
+import net.md_5.bungee.config.Configuration;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SteamwarDiscordBotConfig {
+
+ public static String TOKEN;
+ public static String GUILD;
+ public static String ANNOUNCEMENTS_CHANNEL;
+ public static String EVENTS_CHANNEL;
+ public static String INGAME_CHANNEL;
+ public static String SERVER_TEAM_CHANNEL;
+ public static String SCHEMATICS_CHANNEL;
+ public static String ROLES_CHANNEL;
+ public static String ROLES_BASE_MESSAGE;
+ public static String ROLES_ADDED;
+ public static String ROLES_REMOVED;
+ public static List ROLES;
+ public static String RULES_CHANNEL;
+ public static String RULES_TITLE;
+ public static List RULES_RULES;
+ public static List RULES_LINKS;
+ public static String TICKET_CATEGORY;
+ public static String TICKET_CHANNEL;
+ public static String TICKET_MESSAGE;
+ public static String TICKET_CREATED;
+ public static String TICKET_LOG;
+ public static Map TICKET_TYPES;
+ public static Map RANKS;
+
+ public static void loadConfig(Configuration config) {
+ TOKEN = config.getString("token");
+ GUILD = config.getString("guild");
+ ANNOUNCEMENTS_CHANNEL = config.getString("announcements-channel");
+ EVENTS_CHANNEL = config.getString("events-channel");
+ INGAME_CHANNEL = config.getString("ingame-channel");
+ SERVER_TEAM_CHANNEL = config.getString("server-team-channel");
+ SCHEMATICS_CHANNEL = config.getString("schematics-channel");
+ Configuration rolesSection = config.getSection("roles-claim");
+ ROLES_CHANNEL = rolesSection.getString("channel");
+ ROLES_BASE_MESSAGE = rolesSection.getString("base");
+ ROLES_ADDED = rolesSection.getString("added");
+ ROLES_REMOVED = rolesSection.getString("removed");
+ ROLES = new ArrayList<>();
+
+ for (String roles : rolesSection.getSection("roles").getKeys()) {
+ Configuration role = rolesSection.getSection("roles").getSection(roles);
+ ROLES.add(new DiscordRole(role.getString("emoji"),
+ role.getString("label"),
+ role.getString("roleId")));
+ }
+
+ Configuration rulesSection = config.getSection("rules");
+ RULES_CHANNEL = rulesSection.getString("channel");
+ RULES_TITLE = rulesSection.getString("title");
+ RULES_RULES = rulesSection.getStringList("rules");
+
+ RULES_LINKS = new ArrayList<>();
+
+ for (String links : rulesSection.getSection("links").getKeys()) {
+ Configuration link = rulesSection.getSection("links").getSection(links);
+ RULES_LINKS.add(new DiscordRulesLink(link.getString("label"),
+ link.getString("url")));
+ }
+
+ Configuration ticketSection = config.getSection("tickets");
+ TICKET_CATEGORY = ticketSection.getString("category");
+ TICKET_CHANNEL = ticketSection.getString("channel");
+ TICKET_MESSAGE = ticketSection.getString("message");
+ TICKET_CREATED = ticketSection.getString("created");
+ TICKET_LOG = ticketSection.getString("log");
+ TICKET_TYPES = new HashMap<>();
+
+ for (String types : ticketSection.getSection("types").getKeys()) {
+ Configuration type = ticketSection.getSection("types").getSection(types);
+ TICKET_TYPES.put(types, new DiscordTicketType(types,
+ type.getString("emoji"),
+ type.getString("label"),
+ type.getString("color"),
+ type.getString("pre")));
+ }
+
+ RANKS = new HashMap<>();
+ Configuration ranksSections = config.getSection("ranks");
+ for (String type : ranksSections.getKeys()) {
+ RANKS.put(UserGroup.getUsergroup(type), ranksSections.getString(type));
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/events/EventManager.java b/src/de/steamwar/bungeecore/bot/events/EventManager.java
new file mode 100644
index 0000000..56f982c
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/events/EventManager.java
@@ -0,0 +1,128 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.events;
+
+import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import de.steamwar.bungeecore.sql.Event;
+import de.steamwar.bungeecore.sql.EventFight;
+import de.steamwar.bungeecore.sql.Team;
+import de.steamwar.bungeecore.sql.TeamTeilnahme;
+import lombok.experimental.UtilityClass;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Message;
+import net.dv8tion.jda.api.entities.TextChannel;
+
+import java.awt.*;
+import java.sql.Timestamp;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+import java.util.stream.Collectors;
+
+@UtilityClass
+public class EventManager {
+
+ private Message message;
+ private TextChannel textChannel;
+
+ static {
+ textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.EVENTS_CHANNEL);
+ assert textChannel != null;
+ if(textChannel.hasLatestMessage()) {
+ message = textChannel.getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
+ }
+ }
+
+ public void update() {
+ if (Event.get() == null) {
+ updateComing();
+ } else {
+ updateCurrent();
+ }
+ }
+
+ private void updateComing() {
+ EmbedBuilder embedBuilder = new EmbedBuilder();
+ embedBuilder.setColor(Color.GRAY);
+ embedBuilder.setTitle("Zukünftige Events");
+ embedBuilder.setAuthor("SteamWar", "https://www.steamwar.de");
+
+ Timestamp now = Timestamp.from(Instant.now());
+ Event.getComing().forEach(event -> {
+ StringBuilder st = new StringBuilder();
+ if (event.getDeadline().after(now)) {
+ st.append("Deadline: \n");
+ }
+ st.append("Start: ");
+ String teilname = TeamTeilnahme.getTeams(event.getEventID()).stream().map(Team::getTeamKuerzel).collect(Collectors.joining(", "));
+ if (!teilname.isEmpty()) {
+ st.append("\nAngemeldete Teams: ").append(teilname);
+ }
+ embedBuilder.addField(event.getEventName(), st.toString(), false);
+ });
+
+ MessageBuilder messageBuilder = new MessageBuilder();
+ messageBuilder.setEmbeds(embedBuilder.build());
+ if (message == null) {
+ message = textChannel.sendMessage(messageBuilder.build()).complete();
+ } else {
+ message.editMessage(messageBuilder.build()).complete();
+ }
+ }
+
+ private void updateCurrent() {
+ Event event = Event.get();
+ if (event == null) return;
+ EmbedBuilder embedBuilder = new EmbedBuilder();
+ embedBuilder.setColor(Color.GRAY);
+ embedBuilder.setTitle("Event: " + event.getEventName());
+ embedBuilder.setAuthor("SteamWar", "https://www.steamwar.de");
+
+ Instant now = Instant.now();
+ EventFight.getEvent(event.getEventID()).forEach(eventFight -> {
+ Team teamBlue = Team.get(eventFight.getTeamBlue());
+ Team teamRed = Team.get(eventFight.getTeamRed());
+
+ StringBuilder st = new StringBuilder();
+ st.append("Fightbeginn: ");
+ if(now.isAfter(eventFight.getStartTime().toInstant().plus(35, ChronoUnit.MINUTES))) {
+ st.append("\n");
+ if (eventFight.getErgebnis() == 1) {
+ st.append("Sieg ").append(teamBlue.getTeamKuerzel());
+ } else if (eventFight.getErgebnis() == 2) {
+ st.append("Sieg ").append(teamRed.getTeamKuerzel());
+ } else {
+ st.append("Unentschieden");
+ }
+ }
+ embedBuilder.addField(teamBlue.getTeamKuerzel() + " vs. " + teamRed.getTeamKuerzel(), st.toString(), true);
+ });
+
+ MessageBuilder messageBuilder = new MessageBuilder();
+ messageBuilder.setEmbeds(embedBuilder.build());
+ if (message == null) {
+ message = textChannel.sendMessage(messageBuilder.build()).complete();
+ } else {
+ message.editMessage(messageBuilder.build()).complete();
+ }
+ }
+
+}
diff --git a/src/de/steamwar/bungeecore/bot/events/SchematicsManager.java b/src/de/steamwar/bungeecore/bot/events/SchematicsManager.java
new file mode 100644
index 0000000..64809e1
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/events/SchematicsManager.java
@@ -0,0 +1,73 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.events;
+
+import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import de.steamwar.bungeecore.commands.CheckCommand;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import lombok.experimental.UtilityClass;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Message;
+import net.dv8tion.jda.api.entities.TextChannel;
+
+import java.awt.*;
+
+@UtilityClass
+public class SchematicsManager {
+
+ private Message message;
+ private TextChannel textChannel;
+
+ static {
+ textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.SCHEMATICS_CHANNEL);
+ assert textChannel != null;
+ if(textChannel.hasLatestMessage()) {
+ message = textChannel.getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
+ }
+ }
+
+ public void update() {
+ EmbedBuilder embedBuilder = new EmbedBuilder();
+ embedBuilder.setColor(Color.GRAY);
+ embedBuilder.setTitle("Check List");
+ embedBuilder.setAuthor("SteamWar", "https://www.steamwar.de");
+
+ CheckCommand.getSchemsToCheck().forEach(schematic -> {
+ StringBuilder st = new StringBuilder();
+ st.append("Typ: ").append(schematic.getSchemType().getKuerzel());
+ st.append("\nVon: ").append(SteamwarUser.get(schematic.getSchemOwner()).getUserName());
+ String checker = CheckCommand.getChecker(schematic);
+ if (checker != null) {
+ st.append("\nWird Geprüft von: ").append(checker);
+ }
+ embedBuilder.addField(schematic.getSchemName(), st.toString(), true);
+ });
+
+ MessageBuilder messageBuilder = new MessageBuilder();
+ messageBuilder.setEmbeds(embedBuilder.build());
+ if (message == null) {
+ message = textChannel.sendMessage(messageBuilder.build()).complete();
+ } else {
+ message.editMessage(messageBuilder.build()).queue();
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/listeners/AnnouncementListener.java b/src/de/steamwar/bungeecore/bot/listeners/AnnouncementListener.java
new file mode 100644
index 0000000..2877fbd
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/listeners/AnnouncementListener.java
@@ -0,0 +1,50 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.listeners;
+
+import de.steamwar.bungeecore.Message;
+import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
+import org.jetbrains.annotations.NotNull;
+
+public class AnnouncementListener extends BasicDiscordListener {
+
+ @Override
+ public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
+ if (!event.getChannel().getId().equals(SteamwarDiscordBotConfig.ANNOUNCEMENTS_CHANNEL)) {
+ return;
+ }
+ if (event.getAuthor().isBot()) {
+ return;
+ }
+ Message.broadcast("ALERT", event.getMessage().getContentDisplay());
+ }
+
+ public void announce(String message) {
+ TextChannel textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.ANNOUNCEMENTS_CHANNEL);
+ assert textChannel != null;
+ MessageBuilder messageBuilder = new MessageBuilder();
+ messageBuilder.append(message.replace("&", ""));
+ textChannel.sendMessage(messageBuilder.build()).complete();
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/listeners/BasicDiscordListener.java b/src/de/steamwar/bungeecore/bot/listeners/BasicDiscordListener.java
new file mode 100644
index 0000000..1c8a5ff
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/listeners/BasicDiscordListener.java
@@ -0,0 +1,30 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.listeners;
+
+import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
+import net.dv8tion.jda.api.hooks.ListenerAdapter;
+
+public abstract class BasicDiscordListener extends ListenerAdapter {
+
+ BasicDiscordListener() {
+ SteamwarDiscordBot.instance().addListener(this);
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/listeners/DiscordAuthListener.java b/src/de/steamwar/bungeecore/bot/listeners/DiscordAuthListener.java
new file mode 100644
index 0000000..514b193
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/listeners/DiscordAuthListener.java
@@ -0,0 +1,59 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.listeners;
+
+import de.steamwar.bungeecore.bot.AuthManager;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent;
+import net.dv8tion.jda.api.interactions.InteractionType;
+import org.jetbrains.annotations.NotNull;
+
+public class DiscordAuthListener extends BasicDiscordListener {
+
+ @Override
+ public void onGenericComponentInteractionCreate(@NotNull GenericComponentInteractionCreateEvent event) {
+ if(event.getType() == InteractionType.COMPONENT) {
+ if(event.getChannel().getId().equals(SteamwarDiscordBotConfig.RULES_CHANNEL) && event.getComponentId().equals("auth")) {
+ String authMessage = AuthManager.createDiscordAuthToken(event.getMember());
+ if(authMessage != null) {
+ event.reply("Gebe innerhalb der nächsten 10 Minuten ``/verify " + authMessage + "`` auf dem Minecraft Server ein").setEphemeral(true).complete();
+ } else {
+ event.reply("Du hast bereits einen Code am laufen").setEphemeral(true).complete();
+ }
+ }
+
+ if(event.getComponentId().equals("tada") && event.getChannelType() == ChannelType.PRIVATE) {
+ event.reply(":tada:").setEphemeral(false).complete();
+ }
+
+ if(event.getComponentId().equals("invalid") && event.getChannelType() == ChannelType.PRIVATE) {
+ SteamwarUser user = SteamwarUser.get(event.getUser().getIdLong());
+ if(user == null) {
+ event.reply(":question: Da ist keine verknüpfung?").setEphemeral(false).complete();
+ } else {
+ user.setDiscordId(null);
+ event.reply(":x: Die Verknüpfung wurde beendet").setEphemeral(false).complete();
+ }
+ }
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/listeners/DiscordTicketListener.java b/src/de/steamwar/bungeecore/bot/listeners/DiscordTicketListener.java
new file mode 100644
index 0000000..1ac4920
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/listeners/DiscordTicketListener.java
@@ -0,0 +1,144 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.listeners;
+
+import de.steamwar.bungeecore.BungeeCore;
+import de.steamwar.bungeecore.Message;
+import de.steamwar.bungeecore.bot.config.DiscordTicketType;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import net.dv8tion.jda.api.EmbedBuilder;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.Permission;
+import net.dv8tion.jda.api.entities.*;
+import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent;
+import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
+import net.dv8tion.jda.api.interactions.InteractionType;
+import net.dv8tion.jda.api.interactions.components.ActionRow;
+import net.dv8tion.jda.api.interactions.components.Button;
+import net.md_5.bungee.api.chat.ClickEvent;
+import org.jetbrains.annotations.NotNull;
+
+import java.awt.*;
+import java.time.Instant;
+import java.util.LinkedList;
+
+public class DiscordTicketListener extends BasicDiscordListener {
+
+ @Override
+ public void onGenericComponentInteractionCreate(@NotNull GenericComponentInteractionCreateEvent event) {
+ if(event.getType() == InteractionType.COMPONENT && event.getChannelType() == ChannelType.TEXT && event.getTextChannel().getParent() != null && event.getTextChannel().getParent().getId().equals(SteamwarDiscordBotConfig.TICKET_CATEGORY)) {
+ if(event.getTextChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_CHANNEL) && SteamwarDiscordBotConfig.TICKET_TYPES.containsKey(event.getComponentId())) {
+ DiscordTicketType ticketType = SteamwarDiscordBotConfig.TICKET_TYPES.get(event.getComponentId());
+ Category ct = event.getGuild().getCategoryById(SteamwarDiscordBotConfig.TICKET_CATEGORY);
+ SteamwarUser swUser = SteamwarUser.get(event.getUser().getIdLong());
+ TextChannel ticketChannel = ct.createTextChannel((swUser == null?event.getUser().getName():swUser.getUserName()) + "-" + event.getComponentId() + "-" + System.currentTimeMillis() % 1000).complete();
+ ticketChannel.createPermissionOverride(event.getMember()).setAllow(Permission.VIEW_CHANNEL,
+ Permission.MESSAGE_WRITE,
+ Permission.MESSAGE_ATTACH_FILES,
+ Permission.MESSAGE_ADD_REACTION,
+ Permission.MESSAGE_READ,
+ Permission.MESSAGE_EMBED_LINKS,
+ Permission.MESSAGE_HISTORY).complete();
+ ticketChannel.getManager().setTopic(event.getUser().getId()).complete();
+
+ MessageBuilder messageBuilder = new MessageBuilder();
+ EmbedBuilder builder = new EmbedBuilder();
+ builder.setDescription(ticketType.getPreMessage());
+ builder.setTitle("Steamwar Ticket");
+ builder.setColor(Color.GREEN);
+
+ Button closeButton = Button.danger("close-" + ticketChannel.getName(), "Schließen").withEmoji(Emoji.fromUnicode("U+26A0"));
+ messageBuilder.setEmbeds(builder.build());
+ messageBuilder.setActionRows(ActionRow.of(closeButton));
+
+ ticketChannel.sendMessage(messageBuilder.build()).complete();
+ event.reply(SteamwarDiscordBotConfig.TICKET_CREATED.replace("%channel%", ticketChannel.getAsMention())).setEphemeral(true).complete();
+ Message.team("DISCORD_TICKET_NEW", ticketChannel.getName());
+ } else if(event.getComponentId().startsWith("close-")) {
+ TextChannel logChannel = event.getGuild().getTextChannelById(SteamwarDiscordBotConfig.TICKET_LOG);
+
+ MessageBuilder builder = new MessageBuilder();
+ StringBuilder stringBuilder = new StringBuilder();
+
+ new LinkedList<>(event.getTextChannel().getIterableHistory().complete()).descendingIterator().forEachRemaining(message -> {
+ if(message.getAuthor().isSystem() || message.getAuthor().isBot()) return;
+ stringBuilder.append(" ")
+ .append("**")
+ .append(message.getAuthor().getName())
+ .append("**: ")
+ .append(message.getContentRaw());
+ if(!message.getAttachments().isEmpty()) {
+ stringBuilder.append("\n")
+ .append("Files: ").append("\n");
+ message.getAttachments().forEach(attachment -> stringBuilder.append(attachment.getUrl()).append("\n"));
+ }
+
+ stringBuilder.append("\n");
+ });
+
+ stringBuilder.append("\n");
+ stringBuilder.append(" ")
+ .append("**").append(event.getUser().getName()).append("**: ")
+ .append("Ticket geschlossen");
+
+ EmbedBuilder embedBuilder = new EmbedBuilder();
+ embedBuilder.setColor(Color.GREEN);
+ User user = event.getJDA().retrieveUserById(event.getTextChannel().getTopic()).complete();
+ SteamwarUser swuser = SteamwarUser.get(user.getIdLong());
+
+ embedBuilder.setAuthor(user.getName(), swuser==null?"https://steamwar.de/":("https://steamwar.de/users/" + swuser.getUserName().toLowerCase() + "/"), user.getAvatarUrl());
+ embedBuilder.setTimestamp(Instant.now());
+ embedBuilder.setTitle(event.getTextChannel().getName());
+ embedBuilder.setDescription(stringBuilder);
+
+ builder.setEmbeds(embedBuilder.build());
+
+ logChannel.sendMessage(builder.build()).complete();
+
+ Message.team("DISCORD_TICKET_CLOSED", event.getTextChannel().getName());
+ event.getTextChannel().delete().reason("Closed").complete();
+ }
+ }
+ }
+
+ @Override
+ public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
+ if(event.getChannel().getParent() != null && event.getChannel().getParent().getId().equals(SteamwarDiscordBotConfig.TICKET_CATEGORY)) {
+ if(!event.getChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_CHANNEL) && !event.getChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_LOG)) {
+ BungeeCore.get().getProxy().getPlayers().forEach(player -> {
+ if(event.getAuthor().isBot() || event.getAuthor().isSystem()) return;
+ SteamwarUser user = SteamwarUser.get(player);
+ if(user.getDiscordId() == null) {
+ if(user.getUserGroup().isTeamGroup()) {
+ Message.sendPrefixless("DISCORD_TICKET_MESSAGE", player, "Zur nachricht", new ClickEvent(ClickEvent.Action.OPEN_URL, event.getMessage().getJumpUrl()), event.getChannel().getName(), event.getAuthor().getName(), event.getMessage().getContentRaw());
+ }
+ } else {
+ if(event.getAuthor().getId().equals(user.getDiscordId())) return;
+ Member member = event.getGuild().retrieveMemberById(user.getDiscordId()).complete();
+ if(member.hasPermission(event.getChannel().getManager().getChannel(), Permission.MESSAGE_WRITE)) {
+ Message.sendPrefixless("DISCORD_TICKET_MESSAGE", player, "Zur nachricht", new ClickEvent(ClickEvent.Action.OPEN_URL, event.getMessage().getJumpUrl()), event.getChannel().getName(), event.getAuthor().getName(), event.getMessage().getContentRaw());
+ }
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/listeners/IngameChatListener.java b/src/de/steamwar/bungeecore/bot/listeners/IngameChatListener.java
new file mode 100644
index 0000000..ce635f3
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/listeners/IngameChatListener.java
@@ -0,0 +1,68 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.listeners;
+
+import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import de.steamwar.bungeecore.listeners.ChatListener;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import de.steamwar.bungeecore.sql.UserGroup;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
+import org.jetbrains.annotations.NotNull;
+
+public class IngameChatListener extends BasicDiscordListener {
+
+ @Override
+ public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
+ if (!event.getChannel().getId().equals(SteamwarDiscordBotConfig.INGAME_CHANNEL)) {
+ return;
+ }
+ if (event.getAuthor().isBot()) {
+ return;
+ }
+ Member member = event.getMember();
+ SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
+ if (steamwarUser == null || event.getMessage().getContentRaw().length() > 250) {
+ event.getMessage().delete().complete();
+ } else {
+ String s = event.getMessage().getContentDisplay();
+ if (steamwarUser.getUserGroup() == UserGroup.Member && (s.contains("http") || s.contains("www"))) {
+ event.getMessage().delete().complete();
+ return;
+ }
+ if (steamwarUser.isMuted() || steamwarUser.isBanned()) {
+ event.getMessage().delete().complete();
+ return;
+ }
+ ChatListener.discordChat(steamwarUser, event.getMessage().getContentDisplay().replaceAll("§[a-f0-9]", "").replace('\n', ' '));
+ }
+ }
+
+ public void send(String message) {
+ TextChannel textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.INGAME_CHANNEL);
+ assert textChannel != null;
+ MessageBuilder messageBuilder = new MessageBuilder();
+ messageBuilder.append(message.replace("&", "").replace("@everyone", "`@everyone`").replace("@here", "`@here`").replaceAll("<[@#]!?\\d+>", "`$0`"));
+ textChannel.sendMessage(messageBuilder.build()).queue();
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/listeners/RolesInteractionButtonListener.java b/src/de/steamwar/bungeecore/bot/listeners/RolesInteractionButtonListener.java
new file mode 100644
index 0000000..035cd77
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/listeners/RolesInteractionButtonListener.java
@@ -0,0 +1,42 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.listeners;
+
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import net.dv8tion.jda.api.entities.ChannelType;
+import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent;
+import net.dv8tion.jda.api.interactions.InteractionType;
+import org.jetbrains.annotations.NotNull;
+
+public class RolesInteractionButtonListener extends BasicDiscordListener {
+
+ @Override
+ public void onGenericComponentInteractionCreate(@NotNull GenericComponentInteractionCreateEvent event) {
+ if(event.getType() == InteractionType.COMPONENT && event.getChannelType() == ChannelType.TEXT && event.getTextChannel().getId().equals(SteamwarDiscordBotConfig.ROLES_CHANNEL) && SteamwarDiscordBotConfig.ROLES.stream().anyMatch(discordRole -> discordRole.getRoleId().equals(event.getComponentId()))) {
+ if (event.getMember().getRoles().stream().anyMatch(role -> role.getId().equals(event.getComponentId()))) {
+ event.getGuild().removeRoleFromMember(event.getMember(), event.getGuild().getRoleById(event.getComponentId())).complete();
+ event.reply(SteamwarDiscordBotConfig.ROLES_REMOVED.replace("%role%", event.getGuild().getRoleById(event.getComponentId()).getAsMention())).setEphemeral(true).complete();
+ } else {
+ event.getGuild().addRoleToMember(event.getMember(), event.getGuild().getRoleById(event.getComponentId())).complete();
+ event.reply(SteamwarDiscordBotConfig.ROLES_ADDED.replace("%role%", event.getGuild().getRoleById(event.getComponentId()).getAsMention())).setEphemeral(true).complete();
+ }
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/listeners/ServerTeamChatListener.java b/src/de/steamwar/bungeecore/bot/listeners/ServerTeamChatListener.java
new file mode 100644
index 0000000..0f82673
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/listeners/ServerTeamChatListener.java
@@ -0,0 +1,59 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.listeners;
+
+import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import de.steamwar.bungeecore.commands.ServerTeamchatCommand;
+import de.steamwar.bungeecore.listeners.ChatListener;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
+import org.jetbrains.annotations.NotNull;
+
+public class ServerTeamChatListener extends BasicDiscordListener {
+
+ @Override
+ public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
+ if (!event.getChannel().getId().equals(SteamwarDiscordBotConfig.SERVER_TEAM_CHANNEL)) {
+ return;
+ }
+ if (event.getAuthor().isBot()) {
+ return;
+ }
+ Member member = event.getMember();
+ SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
+ if (steamwarUser == null) {
+ event.getMessage().delete().complete();
+ } else {
+ ServerTeamchatCommand.sendToTeam(event.getMessage().getContentRaw(), steamwarUser);
+ }
+ }
+
+ public void send(String message) {
+ TextChannel textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.SERVER_TEAM_CHANNEL);
+ assert textChannel != null;
+ MessageBuilder messageBuilder = new MessageBuilder();
+ messageBuilder.append(message.replace("&", ""));
+ textChannel.sendMessage(messageBuilder.build()).queue();
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/listeners/SlashCommandListener.java b/src/de/steamwar/bungeecore/bot/listeners/SlashCommandListener.java
new file mode 100644
index 0000000..565ca44
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/listeners/SlashCommandListener.java
@@ -0,0 +1,32 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.listeners;
+
+import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
+import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
+import org.jetbrains.annotations.NotNull;
+
+public class SlashCommandListener extends BasicDiscordListener {
+
+ @Override
+ public void onSlashCommand(@NotNull SlashCommandEvent event) {
+ SteamwarDiscordBot.getDiscordCommandMap().get(event.getName()).run(event);
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/util/DiscordRanks.java b/src/de/steamwar/bungeecore/bot/util/DiscordRanks.java
new file mode 100644
index 0000000..dedf0a5
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/util/DiscordRanks.java
@@ -0,0 +1,67 @@
+/*
+ * This file is a part of the SteamWar software.
+ *
+ * Copyright (C) 2020 SteamWar.de-Serverteam
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.util;
+
+import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import de.steamwar.bungeecore.sql.SteamwarUser;
+import de.steamwar.bungeecore.sql.UserGroup;
+import lombok.experimental.UtilityClass;
+import net.dv8tion.jda.api.entities.Guild;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.Role;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@UtilityClass
+public class DiscordRanks {
+
+ public void update(SteamwarUser steamwarUser) {
+ if (steamwarUser.getDiscordId() == null) {
+ return;
+ }
+ Guild guild = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD);
+ Member member = guild.retrieveMemberById(steamwarUser.getDiscordId()).complete();
+ if (member == null) {
+ return;
+ }
+
+ List roleList = member.getRoles();
+ Set strings = new HashSet<>(SteamwarDiscordBotConfig.RANKS.values());
+ String needed = SteamwarDiscordBotConfig.RANKS.get(steamwarUser.getUserGroup());
+ for (Role role : roleList) {
+ if (!strings.contains(role.getId())) {
+ continue;
+ }
+ if (role.getId().equals(needed)) {
+ needed = "";
+ continue;
+ }
+ guild.removeRoleFromMember(member, role).complete();
+ }
+
+ if (needed != null && !needed.isEmpty()) {
+ guild.addRoleToMember(member, guild.getRoleById(needed)).complete();
+ }
+ }
+}
diff --git a/src/de/steamwar/bungeecore/bot/util/DiscordRolesMessage.java b/src/de/steamwar/bungeecore/bot/util/DiscordRolesMessage.java
new file mode 100644
index 0000000..baa8801
--- /dev/null
+++ b/src/de/steamwar/bungeecore/bot/util/DiscordRolesMessage.java
@@ -0,0 +1,58 @@
+/*
+ This file is a part of the SteamWar software.
+
+ Copyright (C) 2020 SteamWar.de-Serverteam
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+ */
+
+package de.steamwar.bungeecore.bot.util;
+
+import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
+import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
+import lombok.experimental.UtilityClass;
+import net.dv8tion.jda.api.MessageBuilder;
+import net.dv8tion.jda.api.entities.Message;
+import net.dv8tion.jda.api.entities.TextChannel;
+import net.dv8tion.jda.api.interactions.components.ActionRow;
+import net.dv8tion.jda.api.interactions.components.Button;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@UtilityClass
+public class DiscordRolesMessage {
+
+
+ public void sendMessage() {
+ TextChannel channel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.ROLES_CHANNEL);
+ assert channel != null;
+ Message message = null;
+ if(channel.hasLatestMessage()) {
+ message = channel.getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
+ }
+
+ MessageBuilder builder = new MessageBuilder();
+ builder.setContent(SteamwarDiscordBotConfig.ROLES_BASE_MESSAGE);
+ List