diff --git a/Persistent/build.gradle b/Persistent/build.gradle new file mode 100644 index 0000000..12f875c --- /dev/null +++ b/Persistent/build.gradle @@ -0,0 +1,55 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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 . + */ + +plugins { + id 'java' +} + +group 'de.steamwar' +version '' + +compileJava.options.encoding = 'UTF-8' + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +sourceSets { + main { + java { + srcDirs = ['src/'] + include '**/*.java', '**/*.kt' + } + resources { + srcDirs = ['src/'] + exclude '**/*.java', '**/*.kt' + } + } +} + +dependencies { + compileOnly 'org.projectlombok:lombok:1.18.32' + testCompileOnly 'org.projectlombok:lombok:1.18.32' + annotationProcessor 'org.projectlombok:lombok:1.18.32' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.32' + + compileOnly 'de.steamwar:velocity:RELEASE' + annotationProcessor 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT' +} diff --git a/Persistent/src/de/steamwar/persistent/Arenaserver.java b/Persistent/src/de/steamwar/persistent/Arenaserver.java new file mode 100644 index 0000000..c283090 --- /dev/null +++ b/Persistent/src/de/steamwar/persistent/Arenaserver.java @@ -0,0 +1,37 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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.persistent; + +import lombok.Getter; + +@Getter +public class Arenaserver extends Subserver { + + private final String mode; + private final String map; + private final boolean allowMerge; + + public Arenaserver(String serverName, String mode, String map, boolean allowMerge, int port, ProcessBuilder processBuilder, Runnable shutdownCallback) { + super(Servertype.ARENA, serverName, port, processBuilder, shutdownCallback, null); + this.mode = mode; + this.map = map; + this.allowMerge = allowMerge; + } +} diff --git a/Persistent/src/de/steamwar/persistent/Bauserver.java b/Persistent/src/de/steamwar/persistent/Bauserver.java new file mode 100644 index 0000000..fecd1ae --- /dev/null +++ b/Persistent/src/de/steamwar/persistent/Bauserver.java @@ -0,0 +1,60 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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.persistent; + +import lombok.Getter; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.function.Consumer; + +@Getter +public class Bauserver extends Subserver { + private static final Map servers = new HashMap<>(); + public static Bauserver get(UUID owner) { + synchronized (servers) { + return servers.get(owner); + } + } + + private final UUID owner; + + public Bauserver(String serverName, UUID owner, int port, ProcessBuilder processBuilder, Runnable shutdownCallback){ + this(serverName, owner, port, processBuilder, shutdownCallback, null); + } + + public Bauserver(String serverName, UUID owner, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer failureCallback){ + super(Servertype.BAUSERVER, serverName, port, processBuilder, shutdownCallback, failureCallback); + this.owner = owner; + + synchronized (servers) { + servers.put(owner, this); + } + } + + @Override + protected void unregister() { + synchronized (servers) { + servers.remove(owner); + } + super.unregister(); + } +} diff --git a/Persistent/src/de/steamwar/persistent/Builderserver.java b/Persistent/src/de/steamwar/persistent/Builderserver.java new file mode 100644 index 0000000..ad90b8a --- /dev/null +++ b/Persistent/src/de/steamwar/persistent/Builderserver.java @@ -0,0 +1,59 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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.persistent; + +import lombok.Getter; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +@Getter +public class Builderserver extends Subserver { + + private static final Map servers = new HashMap<>(); + public static Builderserver get(String map) { + synchronized (servers) { + return servers.get(map); + } + } + + private final String map; + public Builderserver(String serverName, String map, int port, ProcessBuilder processBuilder, Runnable shutdownCallback){ + this(serverName, map, port, processBuilder, shutdownCallback, null); + } + + public Builderserver(String serverName, String map, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer failureCallback){ + super(Servertype.BUILDER, serverName, port, processBuilder, shutdownCallback, failureCallback); + this.map = map; + + synchronized (servers) { + servers.put(map, this); + } + } + + @Override + protected void unregister() { + synchronized (servers) { + servers.remove(map); + } + super.unregister(); + } +} diff --git a/Persistent/src/de/steamwar/persistent/Persistent.java b/Persistent/src/de/steamwar/persistent/Persistent.java new file mode 100644 index 0000000..a07b197 --- /dev/null +++ b/Persistent/src/de/steamwar/persistent/Persistent.java @@ -0,0 +1,203 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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.persistent; + +import com.google.inject.AbstractModule; +import com.google.inject.Inject; +import com.google.inject.Module; +import com.google.inject.name.Names; +import com.mojang.brigadier.Command; +import com.velocitypowered.api.command.BrigadierCommand; +import com.velocitypowered.api.command.CommandManager; +import com.velocitypowered.api.command.CommandMeta; +import com.velocitypowered.api.event.EventManager; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; +import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.plugin.PluginContainer; +import com.velocitypowered.api.plugin.PluginDescription; +import com.velocitypowered.api.plugin.PluginManager; +import com.velocitypowered.api.plugin.annotation.DataDirectory; +import com.velocitypowered.api.proxy.ProxyServer; +import com.velocitypowered.api.scheduler.ScheduledTask; +import com.velocitypowered.proxy.plugin.PluginClassLoader; +import com.velocitypowered.proxy.plugin.VelocityPluginManager; +import com.velocitypowered.proxy.plugin.loader.VelocityPluginContainer; +import com.velocitypowered.proxy.plugin.loader.java.JavaPluginLoader; +import lombok.Getter; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.NoSuchElementException; +import java.util.ResourceBundle; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +@Plugin( + id = "persistentvelocitycore", + name = "PersistentVelocityCore" +) +public class Persistent { + + private static final Reflection.Method registerPlugin = new Reflection.Method<>(VelocityPluginManager.class, "registerPlugin", PluginContainer.class); + + @Getter + private static Persistent instance; + + @Getter + private final ProxyServer proxy; + @Getter + private final Logger logger; + private final Path directory; + + @Inject + public Persistent(ProxyServer proxy, Logger logger, @DataDirectory Path dataDirectory) { + instance = this; + this.proxy = proxy; + this.logger = logger; + this.directory = dataDirectory; + } + + @Subscribe + public void onEnable(ProxyInitializeEvent event) { + proxy.getCommandManager().register( + new BrigadierCommand( + BrigadierCommand.literalArgumentBuilder("softreload") + .requires(commandSource -> commandSource.hasPermission("bungeecore.softreload")) + .executes(commandContext -> softreload()) + .build() + ) + ); + } + + @Subscribe + public void onDisable(ProxyShutdownEvent event) { + Subserver.shutdown(); + } + + public int softreload() { + PluginContainer container = null; + ReloadablePlugin plugin = null; + try { + container = proxy.getPluginManager().getPlugin("velocitycore").orElseThrow(); + plugin = (ReloadablePlugin) container.getInstance().orElseThrow(); + } catch (NoSuchElementException e) { + logger.log(Level.WARNING, "Could not find loaded VelocityCore, continuing without unloading."); + } + + PluginContainer newContainer; + try { + newContainer = prepareLoad(); + } catch (Exception e) { + logger.log(Level.SEVERE, "Could not instantiate new VelocityCore, aborting softreload.", e); + return Command.SINGLE_SUCCESS; + } + + broadcast("§eNetwork update is starting§8."); + try { + if(container != null && plugin != null) { + plugin.onProxyShutdown(new ProxyShutdownEvent()); + unload(container, plugin); + } + + registerPlugin.invoke((VelocityPluginManager) proxy.getPluginManager(), newContainer); + ((ReloadablePlugin) newContainer.getInstance().orElseThrow()).onProxyInitialization(new ProxyInitializeEvent()); + } catch (Throwable t) { + logger.log(Level.SEVERE, "Error during softreload", t); + broadcast("§cNetwork update failed§8, §cexpect network restart soon§8."); + return Command.SINGLE_SUCCESS; + } + + broadcast("§eNetwork update complete§8."); + return Command.SINGLE_SUCCESS; + } + + private void broadcast(String message) { + Component component = LegacyComponentSerializer.legacySection().deserialize("§eSteam§8War» " + message); + proxy.getAllPlayers().forEach(player -> player.sendMessage(component)); + proxy.getConsoleCommandSource().sendMessage(component); + } + + private PluginContainer prepareLoad() throws Exception { + Path plugins = directory.getParent(); + JavaPluginLoader loader = new JavaPluginLoader(proxy, plugins); + PluginDescription description = loader.createPluginFromCandidate(loader.loadCandidate(plugins.resolve("velocitycore.jar"))); + PluginContainer container = new VelocityPluginContainer(description); + + AbstractModule commonModule = new AbstractModule() { + @Override + protected void configure() { + this.bind(ProxyServer.class).toInstance(proxy); + this.bind(PluginManager.class).toInstance(proxy.getPluginManager()); + this.bind(EventManager.class).toInstance(proxy.getEventManager()); + this.bind(CommandManager.class).toInstance(proxy.getCommandManager()); + this.bind(PluginContainer.class).annotatedWith(Names.named(container.getDescription().getId())).toInstance(container); + } + }; + + Module module = loader.createModule(container); + loader.createPlugin(container, module, commonModule); + + return container; + } + + private void unload(PluginContainer container, Object plugin) throws InterruptedException, IOException { + PluginClassLoader classLoader = ((PluginClassLoader) plugin.getClass().getClassLoader()); + + CommandManager commandManager = proxy.getCommandManager(); + for(String alias : commandManager.getAliases()) { + CommandMeta meta = commandManager.getCommandMeta(alias); + if(meta != null && meta.getPlugin() == plugin) + commandManager.unregister(meta); + } + + proxy.getEventManager().unregisterListeners(plugin); + proxy.getScheduler().tasksByPlugin(plugin).forEach(ScheduledTask::cancel); + + container.getExecutorService().shutdown(); + if(!container.getExecutorService().awaitTermination(100, TimeUnit.MILLISECONDS)) + logger.log(Level.WARNING, "ExecutorService termination took longer than 100ms, continuing."); + + for(Thread thread : Thread.getAllStackTraces().keySet()) { + if(thread.getClass().getClassLoader() != classLoader) + continue; + + thread.interrupt(); + thread.join(100); + + if (thread.isAlive()) + logger.log(Level.WARNING, "Could not stop thread %s of plugin %s. Still running".formatted(thread.getName(), container.getDescription().getId())); + } + + //TODO close all log handlers + /*for (Handler handler : plugin.getLogger().getHandlers()) { + handler.close(); + }*/ + + + //Clear resource bundle cache + ResourceBundle.clearCache(classLoader); + classLoader.close(); + } +} diff --git a/Persistent/src/de/steamwar/persistent/Reflection.java b/Persistent/src/de/steamwar/persistent/Reflection.java new file mode 100644 index 0000000..416a369 --- /dev/null +++ b/Persistent/src/de/steamwar/persistent/Reflection.java @@ -0,0 +1,75 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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.persistent; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class Reflection { + public static class Field { + private final java.lang.reflect.Field f; + + public Field(Class target, String name) { + try { + f = target.getDeclaredField(name); + f.setAccessible(true); + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException("Cannot find field with name " + name, e); + } + } + + public T get(C target) { + try { + return (T) f.get(target); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException("Cannot access reflection.", e); + } + } + + public void set(C target, T value) { + try { + f.set(target, value); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException("Cannot access reflection.", e); + } + } + } + + public static class Method { + private final java.lang.reflect.Method m; + + public Method(Class clazz, String methodName, Class... params) { + try { + m = clazz.getDeclaredMethod(methodName, params); + m.setAccessible(true); + } catch (NoSuchMethodException e) { + throw new IllegalArgumentException("Cannot find method with name " + methodName, e); + } + } + + public Object invoke(C target, Object... arguments) { + try { + return m.invoke(target, arguments); + } catch (Exception e) { + throw new IllegalArgumentException("Cannot invoke method " + m, e); + } + } + } +} diff --git a/Persistent/src/de/steamwar/persistent/ReloadablePlugin.java b/Persistent/src/de/steamwar/persistent/ReloadablePlugin.java new file mode 100644 index 0000000..95bfc4b --- /dev/null +++ b/Persistent/src/de/steamwar/persistent/ReloadablePlugin.java @@ -0,0 +1,28 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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.persistent; + +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; + +public interface ReloadablePlugin { + void onProxyInitialization(ProxyInitializeEvent event); + default void onProxyShutdown(ProxyShutdownEvent event) {} +} diff --git a/Persistent/src/de/steamwar/persistent/Servertype.java b/Persistent/src/de/steamwar/persistent/Servertype.java new file mode 100644 index 0000000..4731a2e --- /dev/null +++ b/Persistent/src/de/steamwar/persistent/Servertype.java @@ -0,0 +1,26 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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.persistent; + +public enum Servertype { + BAUSERVER, + ARENA, + BUILDER +} diff --git a/Persistent/src/de/steamwar/persistent/Storage.java b/Persistent/src/de/steamwar/persistent/Storage.java new file mode 100644 index 0000000..a32a577 --- /dev/null +++ b/Persistent/src/de/steamwar/persistent/Storage.java @@ -0,0 +1,52 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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.persistent; + +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.server.ServerInfo; +import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfoPacket; +import lombok.experimental.UtilityClass; + +import java.sql.Timestamp; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@UtilityClass +public class Storage { + public static final Map> challenges = new HashMap<>(); + + public static final Map lastChats = new HashMap<>(); + + public static final Map> teamInvitations = new HashMap<>(); // UserID -> List + + public static final Map sessions = new HashMap<>(); // Contains session start timestamp + + public static final Map eventServer = new HashMap<>(); // TeamID -> Subserver map + + public static final Map fabricCheckedPlayers = new HashMap<>(); + + public static final Map fabricExpectPluginMessage = new HashMap<>(); + + public static final Map teamServers = new HashMap<>(); // TeamID -> ServerInfo map + + public static final Map> directTabItems = new HashMap<>(); +} diff --git a/Persistent/src/de/steamwar/persistent/Subserver.java b/Persistent/src/de/steamwar/persistent/Subserver.java new file mode 100644 index 0000000..5d262cc --- /dev/null +++ b/Persistent/src/de/steamwar/persistent/Subserver.java @@ -0,0 +1,263 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2024 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.persistent; + +import com.velocitypowered.api.proxy.Player; +import com.velocitypowered.api.proxy.server.RegisteredServer; +import com.velocitypowered.api.proxy.server.ServerInfo; +import lombok.Getter; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; + +import java.io.*; +import java.net.InetSocketAddress; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.logging.Level; +import java.util.logging.Logger; + +@SuppressWarnings("unused") +public class Subserver { + + private static final Component PREFIX = Component + .text("Steam").color(NamedTextColor.YELLOW) + .append(Component.text("War» ").color(NamedTextColor.DARK_GRAY)); + + private static final Logger logger = Persistent.getInstance().getLogger(); + + @Getter + private static final List serverList = new LinkedList<>(); + private static final Map infoToServer = new HashMap<>(); + + public static Subserver getSubserver(Player p) { + synchronized (serverList) { + for (int i = serverList.size() - 1; i >= 0; i--) { + if (serverList.get(i).onServer(p)) + return serverList.get(i); + } + } + return null; + } + + public static Subserver getSubserver(ServerInfo server) { + synchronized (serverList) { + return infoToServer.get(server); + } + } + + static void shutdown() { + while (!serverList.isEmpty()) { + Subserver server = serverList.get(0); + server.stop(); + } + } + + private final String serverName; + private final boolean checkpoint; + private final Runnable shutdownCallback; + private final Consumer failureCallback; + private final Process process; + private final PrintWriter writer; + @Getter + private final ServerInfo server; + @Getter + private RegisteredServer registeredServer; + @Getter + private final Servertype type; + private final Thread thread; + @Getter + private boolean started; + + private final List cachedPlayers = new LinkedList<>(); + @Getter + private final Map tablistNames = new HashMap<>(); + + protected Subserver(Servertype type, String serverName, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer failureCallback) { + this.started = false; + this.serverName = serverName; + this.type = type; + this.shutdownCallback = shutdownCallback; + this.failureCallback = failureCallback == null ? this::fatalError : failureCallback; + this.checkpoint = processBuilder.command().contains("criu"); + + try { + this.process = processBuilder.start(); + } catch (IOException e) { + throw new SecurityException("Server could not be started", e); + } + + InetSocketAddress address = new InetSocketAddress("127.0.0.1", port); + this.server = new ServerInfo(serverName, address); + this.writer = new PrintWriter(process.getOutputStream(), true); + + this.thread = new Thread(this::run, "Subserver " + serverName); + this.thread.start(); + } + + public void sendPlayer(Player p) { + if (!started) { + p.sendActionBar(generateBar(0)); + cachedPlayers.add(p); + } else { + p.createConnectionRequest(registeredServer).connect(); + } + } + + public void execute(String command) { + writer.println(command); + } + + public void stop() { + try { + long pid = process.pid(); + if (checkpoint) + pid = process.children().findAny().map(ProcessHandle::pid).orElse(pid); + + Runtime.getRuntime().exec(new String[]{"kill", "-SIGUSR1", Long.toString(pid)}); + } catch (IOException e) { + logger.log(Level.SEVERE, "Failed to send SIGUSR1 to subserver.", e); + } + + try { + if (!process.waitFor(1, TimeUnit.MINUTES)) { + logger.log(Level.SEVERE, () -> serverName + " did not stop correctly, forcibly stopping!"); + process.destroyForcibly(); + } + + thread.join(); + } catch (InterruptedException e) { + logger.log(Level.SEVERE, "Subserver stop interrupted!", e); + Thread.currentThread().interrupt(); + } + } + + private boolean onServer(Player p) { + return cachedPlayers.contains(p) || (registeredServer != null && registeredServer.getPlayersConnected().contains(p)); + } + + private void fatalError(Exception e) { + logger.log(Level.SEVERE, e, () -> serverName + " did not run correctly!"); + + for (Player cached : cachedPlayers) + cached.sendMessage(PREFIX.append(Component.text("Unexpected error during server startup.").color(NamedTextColor.RED))); + if (registeredServer != null) { + for (Player player : registeredServer.getPlayersConnected()) + player.sendMessage(PREFIX.append(Component.text("Lost connection to server.").color(NamedTextColor.RED))); + } + } + + private void start(InputStream stream, Predicate test) throws IOException { + try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { + String line = ""; + while (!started && (line = reader.readLine()) != null) { + started = test.test(line); + } + + if (line == null) + throw new IOException(serverName + " did not start correctly!"); + } + } + + protected void register() { + if (Persistent.getInstance().getProxy().getServer(serverName).isPresent()) { + SecurityException e = new SecurityException("Server already registered: " + serverName); + stop(); + failureCallback.accept(e); + throw e; + } + + synchronized (serverList) { + registeredServer = Persistent.getInstance().getProxy().registerServer(server); + serverList.add(this); + infoToServer.put(server, this); + } + } + + protected void unregister() { + synchronized (serverList) { + infoToServer.remove(server); + serverList.remove(this); + Persistent.getInstance().getProxy().unregisterServer(server); + registeredServer = null; + } + } + + private void run() { + register(); + + Exception ex = null; + try { + if (checkpoint) { + start(process.getErrorStream(), line -> line.contains("Restore finished successfully.")); + } else { + start(process.getInputStream(), line -> { + if (line.contains("Loading libraries, please wait")) + sendProgress(2); + else if (line.contains("Starting Minecraft server on")) + sendProgress(4); + else if (line.contains("Preparing start region")) + sendProgress(6); + return line.contains("Finished mapping loading"); + }); + } + + if (!started) + return; + + sendProgress(8); + + Thread.sleep(300); + + sendProgress(10); + for (Player cachedPlayer : cachedPlayers) { + sendPlayer(cachedPlayer); + } + cachedPlayers.clear(); + + process.waitFor(); + } catch (IOException e) { + ex = e; + } catch (InterruptedException e) { + ex = e; + Thread.currentThread().interrupt(); + } finally { + unregister(); + shutdownCallback.run(); + if (ex != null) + failureCallback.accept(ex); + } + } + + private Component generateBar(int progress) { + return Component.text("⬛".repeat(Math.max(0, progress))).color(NamedTextColor.YELLOW) + .append(Component.text("⬛".repeat(Math.max(0, 10 - progress))).color(NamedTextColor.DARK_GRAY)); + } + + private void sendProgress(int progress) { + Component tc = generateBar(progress); + for (Player cached : cachedPlayers) + cached.sendActionBar(tc); + } +} diff --git a/build.gradle b/build.gradle index c88301d..c2d38ca 100644 --- a/build.gradle +++ b/build.gradle @@ -18,18 +18,11 @@ */ plugins { - // Adding the base plugin fixes the following gradle warnings in IntelliJ: - // - // Warning: root project 'module-work-multi': Unable to resolve all content root directories - // Details: java.lang.IllegalStateException: No value has been specified for this provider. - // - // Warning: root project 'module-work-multi': Unable to resolve additional project configuration. - // Details: java.lang.IllegalStateException: No value has been specified for this provider. id 'base' id 'java' id 'application' - id 'com.github.johnrengelman.shadow' version '5.0.0' + id 'com.github.johnrengelman.shadow' version '8.1.1' id 'de.steamwar.gradle' version 'RELEASE' } @@ -38,8 +31,10 @@ version '' compileJava.options.encoding = 'UTF-8' -sourceCompatibility = 1.8 -targetCompatibility = 1.8 +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} mainClassName = '' @@ -55,44 +50,63 @@ sourceSets { } } -repositories { - mavenCentral() - maven { - url 'https://m2.dv8tion.net/releases' - content { - includeGroup 'net.dv8tion' +allprojects { + repositories { + mavenCentral() + maven { + url 'https://repo.papermc.io/repository/maven-public/' + content { + includeGroup 'com.velocitypowered' + } } - } - maven { - url 'https://repo.lunarclient.dev' - content { - includeGroup 'com.lunarclient' + maven { + url 'https://m2.dv8tion.net/releases' + content { + includeGroup 'net.dv8tion' + } + } + maven { + url 'https://repo.lunarclient.dev' + content { + includeGroup 'com.lunarclient' + } } } } shadowJar { exclude 'META-INF/*' + exclude 'org/sqlite/native/FreeBSD/**', 'org/sqlite/native/Mac/**', 'org/sqlite/native/Windows/**', 'org/sqlite/native/Linux-Android/**', 'org/sqlite/native/Linux-Musl/**' + exclude 'org/sqlite/native/Linux/aarch64/**', 'org/sqlite/native/Linux/arm/**', 'org/sqlite/native/Linux/armv6/**', 'org/sqlite/native/Linux/armv7/**', 'org/sqlite/native/Linux/ppc64/**', 'org/sqlite/native/Linux/x86/**' + exclude 'org/slf4j/**' //https://imperceptiblethoughts.com/shadow/configuration/minimizing/ minimize { exclude project(':') + exclude dependency('mysql:mysql-connector-java:.*') } duplicatesStrategy DuplicatesStrategy.INCLUDE } dependencies { - compileOnly 'org.projectlombok:lombok:1.18.22' - testCompileOnly 'org.projectlombok:lombok:1.18.22' - annotationProcessor 'org.projectlombok:lombok:1.18.22' - testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' + compileOnly 'org.projectlombok:lombok:1.18.32' + testCompileOnly 'org.projectlombok:lombok:1.18.32' + annotationProcessor 'org.projectlombok:lombok:1.18.32' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.32' + + annotationProcessor 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT' + compileOnly 'de.steamwar:velocity:RELEASE' + + compileOnly project(":Persistent") + implementation project(":CommonCore") + + implementation 'org.xerial:sqlite-jdbc:3.46.0.0' + implementation 'mysql:mysql-connector-java:8.0.33' - compileOnly 'de.steamwar:waterfall:RELEASE' - compileOnly 'de.steamwar:persistentbungeecore:RELEASE' implementation("net.dv8tion:JDA:4.4.0_352") { exclude module: 'opus-java' } - implementation project(":CommonCore") + implementation 'org.msgpack:msgpack-core:0.9.8' //AlpineClient implementation 'com.lunarclient:apollo-api:1.1.0' implementation 'com.lunarclient:apollo-common:1.1.0' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0f5795e..5432a49 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ #Sat Apr 10 23:34:12 CEST 2021 -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-all.zip distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStorePath=wrapper/dists diff --git a/settings.gradle b/settings.gradle index ca75fd7..f18b899 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,6 +26,7 @@ pluginManagement { } } -rootProject.name = 'BungeeCore' +rootProject.name = 'VelocityCore' -include 'CommonCore' \ No newline at end of file +include 'CommonCore' +include 'Persistent' diff --git a/src/de/steamwar/bungeecore/ArenaMode.java b/src/de/steamwar/bungeecore/ArenaMode.java deleted file mode 100644 index d3a8d8b..0000000 --- a/src/de/steamwar/bungeecore/ArenaMode.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - 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; - -import de.steamwar.sql.SchematicType; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.config.Configuration; -import net.md_5.bungee.config.ConfigurationProvider; -import net.md_5.bungee.config.YamlConfiguration; - -import java.io.File; -import java.io.IOException; -import java.util.*; -import java.util.stream.Collectors; - -public class ArenaMode { - - private static final Random random = new Random(); - - private static final Map byChat = new HashMap<>(); - private static final Map byInternal = new HashMap<>(); - private static final Map bySchemType = new HashMap<>(); - private static final List allModes = new LinkedList<>(); - - static { - init(); - } - - public static void init() { - byChat.clear(); - byInternal.clear(); - bySchemType.clear(); - allModes.clear(); - - File folder = new File(ProxyServer.getInstance().getPluginsFolder(), "FightSystem"); - - for(File configFile : Arrays.stream(folder.listFiles((file, name) -> name.endsWith(".yml") && !name.endsWith(".kits.yml"))).sorted().collect(Collectors.toList())) { - Configuration config; - try { - config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile); - } catch (IOException e) { - throw new SecurityException("Could not load SchematicTypes", e); - } - - if(config.contains("Server")) - new ArenaMode(configFile.getName().replace(".yml", ""), config); - } - } - - public static ArenaMode getByChat(String name){ - return byChat.get(name.toLowerCase()); - } - - public static ArenaMode getByInternal(String name){ - return byInternal.get(name); - } - - public static List getAllChatNames(boolean historic) { - List chatNames = new LinkedList<>(); - for(ArenaMode mode : byInternal.values()){ - if(historic == mode.historic) - chatNames.addAll(mode.chatNames); - } - return chatNames; - } - - public static List getAllRankedChatNames(){ - List chatNames = new LinkedList<>(); - for(ArenaMode mode : byInternal.values()){ - if(mode.isRanked()) - chatNames.addAll(mode.chatNames); - } - return chatNames; - } - - public static ArenaMode getBySchemType(SchematicType schemType){ - return bySchemType.get(schemType); - } - - public static List getAllModes(){ - return allModes; - } - - private final String displayName; - private final String folder; - private final List chatNames; - private final String serverJar; - private final String config; - private final List maps; - private final Map lowerToRealMapNames = new HashMap<>(); - private final boolean historic; - private final String internalName; - - private final boolean ranked; - private final String schemType; - - private ArenaMode(String internalName, Configuration config){ - this.internalName = internalName; - this.folder = config.getString("Server.Folder"); - this.serverJar = config.getString("Server.ServerJar"); - this.config = internalName + ".yml"; - this.maps = config.getStringList("Server.Maps"); - maps.forEach(map -> lowerToRealMapNames.put(map.toLowerCase(), map)); - this.displayName = config.getString("GameName", internalName); - this.chatNames = config.getStringList("Server.ChatNames"); - this.schemType = config.getString("Schematic.Type", "").toLowerCase(); - - this.ranked = config.getBoolean("Server.Ranked", false); - this.historic = config.getBoolean("Server.Historic", false); - - allModes.add(this); - byInternal.put(internalName, this); - for(String name : chatNames){ - byChat.put(name.toLowerCase(), this); - } - - if(!this.schemType.equals("")) - bySchemType.put(SchematicType.fromDB(this.schemType), this); - } - - public String getDisplayName() { - return displayName; - } - - public String serverJar() { - return serverJar; - } - - public String getConfig(){ - return config; - } - - public String hasMap(String map){ - for(String m : maps){ - if(m.equalsIgnoreCase(map)) - return m; - } - return null; - } - - public String getFolder() { - return folder; - } - - public String getRandomMap(){ - return maps.get(random.nextInt(maps.size())); - } - - public List getMaps() { - return maps; - } - - public String convertToRealMapName(String map){ - return lowerToRealMapNames.get(map.toLowerCase()); - } - - public String getChatName(){ - return chatNames.get(0); - } - - public boolean withoutChatName(){ - return chatNames.isEmpty(); - } - - public boolean isHistoric(){ - return historic; - } - - public boolean isRanked() { - return ranked; - } - - public String getSchemType() { - return schemType; - } - - public String getInternalName() { - return internalName; - } -} diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java deleted file mode 100644 index f6de66b..0000000 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - 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; - -import de.steamwar.bungeecore.bot.SteamwarDiscordBot; -import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig; -import de.steamwar.bungeecore.commands.*; -import de.steamwar.bungeecore.listeners.*; -import de.steamwar.bungeecore.mods.ServerListPing; -import de.steamwar.bungeecore.mods.*; -import de.steamwar.bungeecore.network.BungeeNetworkHandler; -import de.steamwar.bungeecore.tablist.TablistManager; -import de.steamwar.command.SWCommandUtils; -import de.steamwar.command.SWTypeMapperCreator; -import de.steamwar.command.TabCompletionCache; -import de.steamwar.command.TypeMapper; -import de.steamwar.sql.Punishment; -import de.steamwar.sql.SteamwarUser; -import de.steamwar.sql.Team; -import de.steamwar.sql.UserElo; -import de.steamwar.sql.internal.Statement; -import net.md_5.bungee.api.ChatMessageType; -import net.md_5.bungee.api.CommandSender; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.chat.ClickEvent; -import net.md_5.bungee.api.chat.HoverEvent; -import net.md_5.bungee.api.chat.TextComponent; -import net.md_5.bungee.api.config.ServerInfo; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.plugin.Plugin; -import net.md_5.bungee.config.Configuration; -import net.md_5.bungee.config.ConfigurationProvider; -import net.md_5.bungee.config.YamlConfiguration; - -import java.io.File; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; - -public class BungeeCore extends Plugin { - - public static boolean MAIN_SERVER; - - public static String CHAT_PREFIX; - public static String LOBBY_SERVER; - public static boolean EVENT_MODE; - - private static BungeeCore instance; - - public static Node local; - private ErrorLogger errorLogger; - private TablistManager tablistManager; - - @Override - public void onEnable(){ - setInstance(this); - MAIN_SERVER = ProxyServer.getInstance().getConfig().getListeners().stream().anyMatch(info -> ((InetSocketAddress) info.getSocketAddress()).getPort() == 25565); - loadConfig(); - - errorLogger = new ErrorLogger(); - - SWCommandUtils.init((SWTypeMapperCreator, CommandSender, Object>) (mapper, tabCompleter) -> new TypeMapper() { - @Override - public Object map(CommandSender commandSender, String[] previousArguments, String s) { - return mapper.apply(s); - } - - @Override - public Collection tabCompletes(CommandSender sender, String[] previousArguments, String s) { - return tabCompleter.apply(sender, s); - } - }); - ProxyServer.getInstance().getScheduler().schedule(this, TabCompletionCache::invalidateOldEntries, 1, 1, TimeUnit.SECONDS); - - new Hostname(); - new ServerListPing(); - new PluginMessage(); - new Schematica(); - new Badlion(); - new FabricModSender(); - new ReplayMod(); - new FML2(); - - new ConnectionListener(); - new ChatListener(); - new BanListener(); - new CheckListener(); - new IPSanitizer(); - - local = new Node.LocalNode(); - if(MAIN_SERVER) { - //new Node.RemoteNode("lx"); - } - - new TeamchatCommand(); - new MsgCommand(); - new RCommand(); - new PingCommand(); - new AlertCommand(); - new KickCommand(); - new JoinmeCommand(); - new TpCommand(); - HelpCommand helpCommand = new HelpCommand(); - new TeamCommand(); - new ServerTeamchatCommand(); - new DevCommand(); - new EventCommand(); - new EventreloadCommand(); - new EventRescheduleCommand(); - new PollCommand(); - new BugCommand(); - new WhoisCommand(); - new RegelnCommand(); - new IgnoreCommand(); - new UnIgnoreCommand(); - new PollresultCommand(); - new ListCommand(); - new StatCommand(); - new VerifyCommand(); - new GDPRQuery(); - new PlaytimeCommand(); - new ArenaCommand(); - new RankCommand(); - new LocalCommand(); - new SetLocaleCommand(); - new BuilderCloudCommand(); - - new ModCommand(); - - // Punishment Commands: - new PunishmentCommand("ban", Punishment.PunishmentType.Ban); - new PunishmentCommand("mute", Punishment.PunishmentType.Mute); - new PunishmentCommand("noschemreceiving", Punishment.PunishmentType.NoSchemReceiving); - new PunishmentCommand("noschemsharing", Punishment.PunishmentType.NoSchemSharing); - new PunishmentCommand("noschemsubmitting", Punishment.PunishmentType.NoSchemSubmitting); - new PunishmentCommand("nodev", Punishment.PunishmentType.NoDevServer); - new PunishmentCommand("nofight", Punishment.PunishmentType.NoFightServer); - new PunishmentCommand("noteamserver", Punishment.PunishmentType.NoTeamServer); - new PunishmentCommand("note", Punishment.PunishmentType.Note); - - if(!EVENT_MODE){ - new BauCommand(helpCommand); - new WebpasswordCommand(); - new FightCommand(); - new ChallengeCommand(); - new HistoricCommand(); - new CheckCommand(); - new ReplayCommand(); - new TutorialCommand(); - - new Broadcaster(); - }else{ - new EventModeListener(); - } - - new EventStarter(); - new SessionManager(); - BungeeNetworkHandler.register(); - tablistManager = new TablistManager(); - new SettingsChangedListener(); - - getProxy().getScheduler().schedule(this, () -> { - SteamwarUser.clear(); - UserElo.clear(); - Team.clear(); - }, 1, 1, TimeUnit.HOURS); - - if (SteamwarDiscordBotConfig.loaded) { - try { - new SteamwarDiscordBot(); - } catch (Throwable e) { - getLogger().log(Level.SEVERE, "Could not initialize discord bot", e); - } - } - } - - @Override - public void onDisable(){ - if (SteamwarDiscordBotConfig.loaded) { - try { - SteamwarDiscordBot.instance().getJda().shutdown(); - } catch (Throwable e) { - getLogger().log(Level.SEVERE, "Could not shutdown discord bot", e); - } - } - - if(tablistManager != null) - tablistManager.disable(); - errorLogger.unregister(); - Statement.closeAll(); - } - - public static BungeeCore get() { - return instance; - } - - public static TextComponent stringToText(String msg){ - return new TextComponent(TextComponent.fromLegacyText(msg)); - } - public static void send(ProxiedPlayer player, String msg){ - send(player, msg, null, null); - } - public static void send(CommandSender sender, String msg){ - sender.sendMessage(stringToText(msg)); - } - public static void send(ProxiedPlayer player, ChatMessageType type, String msg){ - send(player, type, msg, null, null); - } - public static void send(ProxiedPlayer player, String msg, String onHover, ClickEvent onClick){ - send(player, ChatMessageType.SYSTEM, msg, onHover, onClick); - } - public static void send(ProxiedPlayer player, ChatMessageType type, String msg, String onHover, ClickEvent onClick){ - if(type == ChatMessageType.CHAT && player.getChatMode() != ProxiedPlayer.ChatMode.SHOWN) - return; - TextComponent message = stringToText(msg); - if(onHover != null) - message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(onHover))); - if(onClick != null) - message.setClickEvent(onClick); - player.sendMessage(type, message); - } - public static void broadcast(String msg){ - ProxyServer.getInstance().broadcast(stringToText(msg)); - } - public static void broadcast(String msg, String onHover, ClickEvent onClick){ - TextComponent message = stringToText(msg); - if(onHover != null) - message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(onHover))); - if(onClick != null) - message.setClickEvent(onClick); - ProxyServer.getInstance().broadcast(message); - } - - public static void log(final ServerInfo server, final String msg){ - log(server.getName() + ": " + msg); - } - public static void log(final ProxiedPlayer player, final String msg){ - log(player.getName() + ": " + msg); - } - public static void log(final String msg){ - log(Level.INFO, msg); - } - public static void log(final Level logLevel, final String msg){ - get().getLogger().log(logLevel, msg); - } - public static void log(final String msg, final Throwable e){ - get().getLogger().log(Level.SEVERE, msg, e); - } - - - private static void loadConfig(){ - Configuration config; - try{ - if(!get().getDataFolder().exists() && !get().getDataFolder().mkdir()) - throw new IOException(); - File configFile = new File(get().getDataFolder().getPath(), "config.yml"); - if(!configFile.exists()){ - boolean created = configFile.createNewFile(); - if(created) - ProxyServer.getInstance().stop("Config file not initialized"); - else - ProxyServer.getInstance().stop("Could not save conig file"); - return; - } - config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile); - }catch(Exception e){ - log("Could not save/load config.yml", e); - ProxyServer.getInstance().stop(); - return; - } - - CHAT_PREFIX = config.getString("prefix"); - LOBBY_SERVER = config.getString("lobbyserver"); - EVENT_MODE = config.getBoolean("eventmode"); - Broadcaster.setBroadCastMsgs(config.getStringList("broadcasts").toArray(new String[1])); - PollSystem.init(config.getString("poll.question"), config.getStringList("poll.answers")); - - final Configuration servers = config.getSection("servers"); - for(final String serverName : servers.getKeys()){ - final Configuration server = servers.getSection(serverName); - List cmds = server.getStringList("commands"); - String cmd = cmds.remove(0); - - if(server.contains("spectatePort")) - EventStarter.addSpectateServer(server.getInt("spectatePort"), cmd); - - new ServerSwitchCommand( - cmd, - serverName, - cmds.toArray(new String[0]) - ); - } - - File discordFile = new File(System.getProperty("user.home"), "discord.yml"); - if(discordFile.exists() && !EVENT_MODE) { - try { - SteamwarDiscordBotConfig.loadConfig(ConfigurationProvider.getProvider(YamlConfiguration.class).load(discordFile)); - } catch (IOException e) { - get().getLogger().log(Level.SEVERE, "Could not load discord bot configuration", e); - } - } - } - - private static void setInstance(BungeeCore core){ - instance = core; - } -} diff --git a/src/de/steamwar/bungeecore/Message.java b/src/de/steamwar/bungeecore/Message.java deleted file mode 100644 index 683b9ed..0000000 --- a/src/de/steamwar/bungeecore/Message.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - 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; - -import de.steamwar.messages.ChatSender; -import de.steamwar.messages.SteamwarResourceBundle; -import net.md_5.bungee.api.ChatMessageType; -import net.md_5.bungee.api.CommandSender; -import net.md_5.bungee.api.chat.ClickEvent; -import net.md_5.bungee.api.chat.TextComponent; - -import java.text.DateFormat; -import java.text.MessageFormat; -import java.util.Date; -import java.util.Locale; -import java.util.ResourceBundle; - -public class Message { - - @Deprecated - public static TextComponent parseToComponent(String message, boolean prefixed, CommandSender sender, Object... params){ - return new TextComponent(TextComponent.fromLegacyText(parse(message, prefixed, locale(sender), params))); - } - - @Deprecated - public static String parsePrefixed(String message, CommandSender sender, Object... params){ - return parse(message, true, locale(sender), params); - } - - @Deprecated - public static String parse(String message, CommandSender sender, Object... params){ - return parse(message, false, locale(sender), params); - } - - @Deprecated - public static String parse(String message, Locale locale, Object... params){ - return parse(message, false, locale, params); - } - - @Deprecated - private static Locale locale(CommandSender sender) { - return ChatSender.of(sender).getLocale(); - } - - @Deprecated - private static String parse(String message, boolean prefixed, Locale locale, Object... params){ - if(locale == null) - locale = Locale.getDefault(); - ResourceBundle resourceBundle = SteamwarResourceBundle.getResourceBundle(locale); - String pattern = ""; - if(prefixed) - pattern = resourceBundle.getObject("PREFIX") + " "; - pattern += (String)resourceBundle.getObject(message); - - MessageFormat format = new MessageFormat(pattern, locale); - for (int i = 0; i < params.length; i++) { - if(params[i] instanceof Message) { - Message msg = (Message) params[i]; - params[i] = parse(msg.getFormat(), false, locale, msg.getParams()); - } else if(params[i] instanceof Date) { - params[i] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale).format((Date) params[i]); - } - } - return format.format(params); - } - - @Deprecated - public static void send(String message, CommandSender sender, Object... params){ - send(message, true, sender, ChatMessageType.SYSTEM, null, null, params); - } - - @Deprecated - public static void sendPrefixless(String message, CommandSender sender, Object... params){ - send(message, false, sender, ChatMessageType.SYSTEM, null, null, params); - } - - @Deprecated - public static void send(String message, CommandSender sender, String onHover, ClickEvent onClick, Object... params){ - send(message, true, sender, ChatMessageType.SYSTEM, onHover, onClick, params); - } - - @Deprecated - public static void sendPrefixless(String message, CommandSender sender, String onHover, ClickEvent onClick, Object... params){ - send(message, false, sender, ChatMessageType.SYSTEM, onHover, onClick, params); - } - - @Deprecated - private static void send(String message, boolean prefixed, CommandSender s, ChatMessageType type, String onHover, ClickEvent onClick, Object... params){ - ChatSender sender = ChatSender.of(s); - if(type == ChatMessageType.CHAT && !sender.chatShown()) - return; - - sender.send(prefixed, type, onHover != null ? new Message("PLAIN_STRING", onHover) : null, onClick, new Message(message, params)); - } - - public static void broadcast(String message, Object... params) { - broadcast(message, null, null, params); - } - - public static void broadcast(String message, String onHover, ClickEvent onClick, Object... params) { - ChatSender.allReceivers().forEach(player -> player.system(message, onHover != null ? new Message(onHover, params) : null, onClick, params)); - } - - public static void team(String message, Object... params) { - team(message, null, null, params); - } - - public static void team(String message, String onHover, ClickEvent onClick, Object... params) { - ChatSender.serverteamReceivers().forEach(player -> player.prefixless(message, onHover != null ? new Message(onHover, params) : null, onClick, params)); - } - - private final String format; - private final Object[] params; - - public Message(String format, Object... params) { - this.format = format; - this.params = params; - } - - public String getFormat() { - return format; - } - - public Object[] getParams() { - return params; - } - -} \ No newline at end of file diff --git a/src/de/steamwar/bungeecore/bot/AuthManager.java b/src/de/steamwar/bungeecore/bot/AuthManager.java deleted file mode 100644 index 8500f12..0000000 --- a/src/de/steamwar/bungeecore/bot/AuthManager.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - 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.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 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()); - BungeeCore.get().getProxy().getScheduler().schedule(BungeeCore.get(), () -> TOKENS.remove(code), 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.getIdLong()); - 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().queue(privateChannel -> privateChannel.sendMessage(builder.build()).queue()); - if (member.getNickname() == null) { - try { - member.getGuild().modifyNickname(member, user.getUserName()).queue(); - } 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 deleted file mode 100644 index 759edcc..0000000 --- a/src/de/steamwar/bungeecore/bot/SteamwarDiscordBot.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - 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.messages.ChatSender; -import de.steamwar.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.exceptions.ErrorResponseException; -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; -import java.util.logging.Level; - -public class SteamwarDiscordBot { - - private static SteamwarDiscordBot INSTANCE; - - public static SteamwarDiscordBot instance() { - return INSTANCE; - } - - @Getter - private volatile AnnouncementListener announcementListener; - - @Getter - private volatile DiscordChatListener ingameChatListener; - - @Getter - private volatile DiscordChatListener 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); - } - ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> { - try { - jda.awaitReady(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - try { - activity(); - } catch (Exception e) { - BungeeCore.get().getLogger().log(Level.SEVERE, "Could not set initial activity to discord", e); - } - EventManager.update(); - SchematicsManager.update(); - ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> { - try { - activity(); - EventManager.update(); - SchematicsManager.update(); - } catch (ErrorResponseException e) { - //ignored - } - }, 30, 30, TimeUnit.SECONDS); - DiscordRolesMessage.sendMessage(); - DiscordRulesMessage.sendMessage(); - DiscordTicketMessage.sendMessage(); - new RolesInteractionButtonListener(); - new DiscordTicketListener(); - new DiscordAuthListener(); - new DiscordEventListener(); - new PrivateMessageListener(); - announcementListener = new AnnouncementListener(); - ingameChatListener = new DiscordChatListener(SteamwarDiscordBotConfig.INGAME_CHANNEL, "CHAT_DISCORD_GLOBAL", ChatSender::globalReceivers); - serverTeamChatListener = new DiscordChatListener(SteamwarDiscordBotConfig.SERVER_TEAM_CHANNEL, "CHAT_SERVERTEAM", ChatSender::serverteamReceivers); - new SlashCommandListener(); - jda.retrieveCommands().complete().forEach(command -> jda.deleteCommandById(command.getId()).queue()); - - 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 deleted file mode 100644 index ed6569e..0000000 --- a/src/de/steamwar/bungeecore/bot/commands/BanCommand.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.PunishmentCommand; -import de.steamwar.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 = PunishmentCommand.getOrCreateOfflinePlayer(event.getOption("user").getAsString()); - if (target == null) { - event.reply("Angegebener User invalide").setEphemeral(true).queue(); - return; - } - - Timestamp time = PunishmentCommand.parseTime(null, event.getOption("time").getAsString()); - if (time == null) { - event.reply("Angegebene Zeit invalide").setEphemeral(true).queue(); - return; - } - - String msg = event.getOption("reason").getAsString(); - boolean isPerma = event.getOption("time").getAsString().equals("perma"); - - PunishmentCommand.ban(target, time, msg, sender, isPerma); - Message.team("BAN_TEAM", 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).queue(); - } -} diff --git a/src/de/steamwar/bungeecore/bot/commands/BasicDiscordCommand.java b/src/de/steamwar/bungeecore/bot/commands/BasicDiscordCommand.java deleted file mode 100644 index 16df83d..0000000 --- a/src/de/steamwar/bungeecore/bot/commands/BasicDiscordCommand.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.sql.SteamwarUser; -import de.steamwar.sql.UserPerm; -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.hasPerm(UserPerm.TEAM))) { - event.reply("Du hast für " + event.getName() + " keine Rechte oder es existiert keine Verknüpfung für dich.").setEphemeral(true).queue(); - return false; - } - return true; - } -} diff --git a/src/de/steamwar/bungeecore/bot/commands/ListCommand.java b/src/de/steamwar/bungeecore/bot/commands/ListCommand.java deleted file mode 100644 index 746bb02..0000000 --- a/src/de/steamwar/bungeecore/bot/commands/ListCommand.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.getCustomTablist(); - EmbedBuilder embedBuilder = new EmbedBuilder(); - embedBuilder.setTitle("List"); - de.steamwar.bungeecore.commands.ListCommand.getCustomTablist().forEach((s, proxiedPlayers) -> { - embedBuilder.addField(s, proxiedPlayers.stream().map(player -> "`" + player.getName() + "`").collect(Collectors.joining(", ")), true); - }); - event.replyEmbeds(embedBuilder.build()).setEphemeral(true).queue(); - } -} diff --git a/src/de/steamwar/bungeecore/bot/commands/MuteCommand.java b/src/de/steamwar/bungeecore/bot/commands/MuteCommand.java deleted file mode 100644 index 3c296f4..0000000 --- a/src/de/steamwar/bungeecore/bot/commands/MuteCommand.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.PunishmentCommand; -import de.steamwar.sql.Punishment; -import de.steamwar.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 = PunishmentCommand.getOrCreateOfflinePlayer(event.getOption("user").getAsString()); - if (target == null) { - event.reply("Angegebener User invalide").setEphemeral(true).complete(); - return; - } - - Timestamp time = PunishmentCommand.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.punish(Punishment.PunishmentType.Mute, time, msg, sender.getId(), isPerma); - Message.team("MUTE_TEAM", 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).queue(); - } -} diff --git a/src/de/steamwar/bungeecore/bot/commands/TeamCommand.java b/src/de/steamwar/bungeecore/bot/commands/TeamCommand.java deleted file mode 100644 index c07dbf2..0000000 --- a/src/de/steamwar/bungeecore/bot/commands/TeamCommand.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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.sql.Event; -import de.steamwar.sql.SteamwarUser; -import de.steamwar.sql.Team; -import de.steamwar.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).queue(); - return; - } - if (steamwarUser.getTeam() == 0) { - event.reply("Du bist in keinem Team").setEphemeral(true).queue(); - return; - } - team = Team.get(steamwarUser.getTeam()); - } else { - team = Team.get(optionMapping.getAsString()); - } - if (team == null) { - event.reply("Unbekanntes Team").setEphemeral(true).queue(); - 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).queue(); - return; - default: - event.reply("Unbekannter Befehl").setEphemeral(true).queue(); - 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 deleted file mode 100644 index 61d5c0d..0000000 --- a/src/de/steamwar/bungeecore/bot/commands/UnbanCommand.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.commands.PunishmentCommand; -import de.steamwar.sql.BannedUserIPs; -import de.steamwar.sql.Punishment; -import de.steamwar.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 = PunishmentCommand.getOrCreateOfflinePlayer(event.getOption("user").getAsString()); - if (target == null) { - event.reply("Angegebener User invalide").setEphemeral(true).queue(); - return; - } - - if (!target.isPunished(Punishment.PunishmentType.Ban)) { - event.reply("Angegebener User ist nicht gebannt").setEphemeral(true).queue(); - return; - } - - target.punish(Punishment.PunishmentType.Ban, Timestamp.from(new Date().toInstant()), "Unban", sender.getId(), false); - BannedUserIPs.unbanIPs(target.getId()); - event.reply("Erfolgreich " + target.getUserName() + " entbannt").setEphemeral(true).queue(); - } -} diff --git a/src/de/steamwar/bungeecore/bot/commands/WhoisCommand.java b/src/de/steamwar/bungeecore/bot/commands/WhoisCommand.java deleted file mode 100644 index d253372..0000000 --- a/src/de/steamwar/bungeecore/bot/commands/WhoisCommand.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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.sql.Punishment; -import de.steamwar.sql.SteamwarUser; -import de.steamwar.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).queue(); - } -} diff --git a/src/de/steamwar/bungeecore/bot/config/DiscordRole.java b/src/de/steamwar/bungeecore/bot/config/DiscordRole.java deleted file mode 100644 index 68b57be..0000000 --- a/src/de/steamwar/bungeecore/bot/config/DiscordRole.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - 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 deleted file mode 100644 index 4f2ebe0..0000000 --- a/src/de/steamwar/bungeecore/bot/config/DiscordRulesLink.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - 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 deleted file mode 100644 index 5ba4c65..0000000 --- a/src/de/steamwar/bungeecore/bot/config/DiscordTicketType.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - 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 deleted file mode 100644 index c85a438..0000000 --- a/src/de/steamwar/bungeecore/bot/config/SteamwarDiscordBotConfig.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - 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.sql.UserPerm; -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 boolean loaded = false; - 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(UserPerm.valueOf(type.toUpperCase()), ranksSections.getString(type)); - } - loaded = true; - } -} diff --git a/src/de/steamwar/bungeecore/bot/events/SchematicsManager.java b/src/de/steamwar/bungeecore/bot/events/SchematicsManager.java deleted file mode 100644 index e53bf9a..0000000 --- a/src/de/steamwar/bungeecore/bot/events/SchematicsManager.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.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.getOwner()).getUserName()); - String checker = CheckCommand.getChecker(schematic); - if (checker != null) { - st.append("\nWird Geprüft von: ").append(checker); - } - embedBuilder.addField(schematic.getName(), st.toString(), true); - }); - - MessageBuilder messageBuilder = new MessageBuilder(); - messageBuilder.setEmbeds(embedBuilder.build()); - if (message == null) { - textChannel.sendMessage(messageBuilder.build()).queue(message1 -> message = message1); - } 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 deleted file mode 100644 index ab4be19..0000000 --- a/src/de/steamwar/bungeecore/bot/listeners/AnnouncementListener.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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()).queue(); - } -} diff --git a/src/de/steamwar/bungeecore/bot/listeners/DiscordAuthListener.java b/src/de/steamwar/bungeecore/bot/listeners/DiscordAuthListener.java deleted file mode 100644 index 947ed5e..0000000 --- a/src/de/steamwar/bungeecore/bot/listeners/DiscordAuthListener.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - 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.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).queue(); - } else { - event.reply("Du hast bereits einen Code am laufen").setEphemeral(true).queue(); - } - } - - if(event.getComponentId().equals("tada") && event.getChannelType() == ChannelType.PRIVATE) { - event.reply(":tada:").setEphemeral(false).queue(); - } - - 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).queue(); - } else { - user.setDiscordId(null); - event.reply(":x: Die Verknüpfung wurde beendet").setEphemeral(false).queue(); - } - } - } - } -} diff --git a/src/de/steamwar/bungeecore/bot/listeners/DiscordChatListener.java b/src/de/steamwar/bungeecore/bot/listeners/DiscordChatListener.java deleted file mode 100644 index 13b5fca..0000000 --- a/src/de/steamwar/bungeecore/bot/listeners/DiscordChatListener.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.sql.Punishment; -import de.steamwar.sql.SteamwarUser; -import de.steamwar.messages.ChatSender; -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; - -import java.util.function.Supplier; -import java.util.stream.Stream; - -public class DiscordChatListener extends BasicDiscordListener { - - private final String channel; - private final String format; - - private final Supplier> targets; - - public DiscordChatListener(String channel, String format, Supplier> targets) { - this.channel = channel; - this.format = format; - this.targets = targets; - } - - @Override - public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { - if (!event.getChannel().getId().equals(channel) || event.getAuthor().isBot()) - return; - - Member member = event.getMember(); - SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong()); - if (steamwarUser == null || event.getMessage().getContentRaw().length() > 250 || steamwarUser.isPunished(Punishment.PunishmentType.Ban)) { - event.getMessage().delete().queue(); - } else { - ChatListener.sendChat(ChatSender.of(event.getMessage(), steamwarUser), targets.get(), format, null, event.getMessage().getContentDisplay().replace('§', '&').replace('\n', ' ')); - } - } - - public void send(String message) { - TextChannel textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(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/DiscordEventListener.java b/src/de/steamwar/bungeecore/bot/listeners/DiscordEventListener.java deleted file mode 100644 index b21f427..0000000 --- a/src/de/steamwar/bungeecore/bot/listeners/DiscordEventListener.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - 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 de.steamwar.bungeecore.bot.events.EventManager; -import de.steamwar.sql.SteamwarUser; -import de.steamwar.sql.Team; -import de.steamwar.sql.TeamTeilnahme; -import de.steamwar.sql.Event; -import net.dv8tion.jda.api.events.interaction.SelectionMenuEvent; -import net.dv8tion.jda.api.interactions.components.Component; -import org.jetbrains.annotations.NotNull; - -import java.time.Instant; - -public class DiscordEventListener extends BasicDiscordListener { - - - @Override - public void onSelectionMenu(@NotNull SelectionMenuEvent event) { - if(event.getChannel().getId().equals(SteamwarDiscordBotConfig.EVENTS_CHANNEL) && event.getComponentType() == Component.Type.SELECTION_MENU) { - if(event.getSelectedOptions().isEmpty()) { - event.deferReply(true).queue(); - return; - } - if(event.getSelectedOptions().get(0).getValue().matches("([0-9]+)")) { - SteamwarUser user = SteamwarUser.get(event.getUser().getIdLong()); - if(user == null) { - event.reply("Du hast dein Minecraft nicht verknüpft").setEphemeral(true).queue(); - return; - } - - if(user.getTeam() == 0) { - event.reply("Du bist in keinem Team").setEphemeral(true).queue(); - return; - } - - if(!user.isLeader()) { - event.reply("Du bist kein Leader in deinem Team").setEphemeral(true).queue(); - return; - } - - if(Event.get() != null) { - event.reply("Du kannst dich nicht während einem Event an einem Event anmelden").setEphemeral(true).queue(); - return; - } - - Event swEvent = Event.get(Integer.decode(event.getSelectedOptions().get(0).getValue())); - if(swEvent == null){ - event.reply("Das Event gibt es nicht").setEphemeral(true).queue(); - return; - } - - if(Instant.now().isAfter(swEvent.getDeadline().toInstant())){ - event.reply("Du kannst dich nicht mehr an diesen Event anmelden").setEphemeral(true).queue(); - return; - } - - Team team = Team.get(user.getTeam()); - - if(TeamTeilnahme.nimmtTeil(team.getTeamId(), swEvent.getEventID())){ - TeamTeilnahme.notTeilnehmen(team.getTeamId(), swEvent.getEventID()); - event.reply("Dein Team **" + team.getTeamName() + "** nimmt nun nicht mehr an **" + swEvent.getEventName() + "** teil!").setEphemeral(true).queue(); - }else{ - TeamTeilnahme.teilnehmen(team.getTeamId(), swEvent.getEventID()); - event.reply("Dein Team **" + team.getTeamName() + "** nimmt nun an **" + swEvent.getEventName() + "** teil!").setEphemeral(true).queue(); - } - - EventManager.update(); - } else { - event.reply("Lefuq?").setEphemeral(true).queue(); - } - } - } -} diff --git a/src/de/steamwar/bungeecore/bot/listeners/DiscordTicketListener.java b/src/de/steamwar/bungeecore/bot/listeners/DiscordTicketListener.java deleted file mode 100644 index e41342e..0000000 --- a/src/de/steamwar/bungeecore/bot/listeners/DiscordTicketListener.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - 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.sql.SteamwarUser; -import de.steamwar.sql.UserPerm; -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); - - LinkedList stringBuilders = new LinkedList<>(); - stringBuilders.add(new StringBuilder()); - - new LinkedList<>(event.getTextChannel().getIterableHistory().complete()).descendingIterator().forEachRemaining(message -> { - if(message.getAuthor().isSystem() || message.getAuthor().isBot()) return; - StringBuilder currentBuilder = new StringBuilder(); - currentBuilder.append(" ") - .append("**") - .append(message.getAuthor().getName()) - .append("**: ") - .append(message.getContentRaw()); - if(!message.getAttachments().isEmpty()) { - currentBuilder.append("\n") - .append("Files: ").append("\n"); - message.getAttachments().forEach(attachment -> currentBuilder.append(attachment.getUrl()).append("\n")); - } - - currentBuilder.append("\n"); - if(currentBuilder.length() >= 4096) { - stringBuilders.getLast().append(currentBuilder.substring(0, 4090)); - stringBuilders.add(new StringBuilder(currentBuilder.substring(4090, currentBuilder.length() - 1))); - } else if (currentBuilder.length() + stringBuilders.getLast().length() >= 4096) { - stringBuilders.add(new StringBuilder(currentBuilder.toString())); - } else { - stringBuilders.getLast().append(currentBuilder); - } - }); - - String footer = " **" + event.getUser().getName() + "**: Ticket geschlossen"; - if(stringBuilders.getLast().length() + footer.length() > 4090) { - stringBuilders.add(new StringBuilder(footer)); - } else { - stringBuilders.getLast().append(footer); - } - - 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()); - stringBuilders.forEach(stringBuilder -> { - embedBuilder.setDescription(stringBuilder.toString()); - MessageBuilder builder = new MessageBuilder(); - builder.setEmbeds(embedBuilder.build()); - - logChannel.sendMessage(builder.build()).queue(); - }); - - Message.team("DISCORD_TICKET_CLOSED", event.getTextChannel().getName()); - event.getTextChannel().delete().reason("Closed").queue(); - } - } - } - - @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.getUniqueId()); - boolean sendMessage; - if(user.getDiscordId() == null) { - sendMessage = user.hasPerm(UserPerm.CHECK); - } else { - if(event.getAuthor().getId().equals(user.getDiscordId())) return; - sendMessage = user.getDiscordId().equals(event.getChannel().getTopic()) || user.hasPerm(UserPerm.CHECK); - } - if(sendMessage) { - 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/PrivateMessageListener.java b/src/de/steamwar/bungeecore/bot/listeners/PrivateMessageListener.java deleted file mode 100644 index 58800d0..0000000 --- a/src/de/steamwar/bungeecore/bot/listeners/PrivateMessageListener.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.bot.listeners; - -import de.steamwar.bungeecore.BungeeCore; -import de.steamwar.sql.NodeData; -import de.steamwar.sql.Punishment; -import de.steamwar.sql.SchematicNode; -import de.steamwar.sql.SteamwarUser; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent; - -import java.io.InputStream; - -public class PrivateMessageListener extends BasicDiscordListener { - - @Override - public void onPrivateMessageReceived(PrivateMessageReceivedEvent event) { - if(!event.getMessage().getAttachments().isEmpty()) { - SteamwarUser user = SteamwarUser.get(event.getAuthor().getIdLong()); - if (user == null) { - event.getMessage().reply("Du must dein Minecraft Account mit dem Bot verbinden, gehe dazu auf dem SteamWar Discord in den `regeln-infos` Channel und Klicke auf `Minecraft Verknüpfen`").complete(); - return; - } - - if(user.isPunished(Punishment.PunishmentType.NoSchemReceiving)) { - event.getMessage().reply("Du darfst keine Schematics hochladen").complete(); - return; - } - - for (Message.Attachment attachment : event.getMessage().getAttachments()) { - if(attachment.getFileExtension() == null || - (!attachment.getFileExtension().equalsIgnoreCase("schem") && - !attachment.getFileExtension().equalsIgnoreCase("schematic"))) { - event.getMessage().reply("`" + attachment.getFileName() + "` wird ignoriert, da die Datei keine Schematic ist").queue(); - continue; - } - - boolean newFormat = attachment.getFileExtension().equalsIgnoreCase("schem"); - int dot = attachment.getFileName().lastIndexOf("."); - String name = attachment.getFileName().substring(0, dot); - if(SchematicNode.invalidSchemName(new String[] {name})) { - event.getMessage().reply("`" + name + "` hat nicht zugelassene Zeichen im Namen").queue(); - continue; - } - - SchematicNode node = SchematicNode.getSchematicNode(user.getId(), name, (Integer) null); - if(node == null) { - node = SchematicNode.createSchematic(user.getId(), name, null); - } - - try { - InputStream in = attachment.retrieveInputStream().get(); - NodeData.get(node).saveFromStream(in, newFormat); - in.close(); - event.getMessage().reply("`" + name + "` wurde erfolgreich hochgeladen").queue(); - } catch (Exception e) { - event.getMessage().reply("`" + name + "` konnte nicht hochgeladen werden, bitte versuche es später nochmal oder wende dich an einen Developer").queue(); - BungeeCore.log("Could not Upload Schem \"" + name + "\" from User \"" + user.getUserName() + "\"", e); - } - } - } - } -} diff --git a/src/de/steamwar/bungeecore/bot/listeners/RolesInteractionButtonListener.java b/src/de/steamwar/bungeecore/bot/listeners/RolesInteractionButtonListener.java deleted file mode 100644 index ae0e44d..0000000 --- a/src/de/steamwar/bungeecore/bot/listeners/RolesInteractionButtonListener.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - 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).queue(); - } 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).queue(); - } - } - } -} diff --git a/src/de/steamwar/bungeecore/bot/listeners/SlashCommandListener.java b/src/de/steamwar/bungeecore/bot/listeners/SlashCommandListener.java deleted file mode 100644 index 565ca44..0000000 --- a/src/de/steamwar/bungeecore/bot/listeners/SlashCommandListener.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 deleted file mode 100644 index f62dea0..0000000 --- a/src/de/steamwar/bungeecore/bot/util/DiscordRanks.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.sql.SteamwarUser; -import lombok.experimental.UtilityClass; -import net.dv8tion.jda.api.entities.Guild; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.exceptions.ErrorResponseException; - -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); - guild.retrieveMemberById(steamwarUser.getDiscordId()).queue(member -> { - List roleList = member.getRoles(); - Set strings = new HashSet<>(SteamwarDiscordBotConfig.RANKS.values()); - String needed = SteamwarDiscordBotConfig.RANKS.get(steamwarUser.prefix()); - 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(); - } - }, throwable -> { - if(throwable instanceof ErrorResponseException) { - ErrorResponseException e = (ErrorResponseException) throwable; - if(e.getErrorCode() == 10007) { - steamwarUser.setDiscordId(null); - } - } - }); - } -} diff --git a/src/de/steamwar/bungeecore/bot/util/DiscordRolesMessage.java b/src/de/steamwar/bungeecore/bot/util/DiscordRolesMessage.java deleted file mode 100644 index 1486deb..0000000 --- a/src/de/steamwar/bungeecore/bot/util/DiscordRolesMessage.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - 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; - - MessageBuilder builder = new MessageBuilder(); - builder.setContent(SteamwarDiscordBotConfig.ROLES_BASE_MESSAGE); - List