Commits vergleichen
4 Commits
Autor | SHA1 | Datum | |
---|---|---|---|
|
00da5f673d | ||
|
e4551e9521 | ||
|
14052c5d01 | ||
|
1a54476cbe |
5
.gitignore
vendored
5
.gitignore
vendored
@ -9,4 +9,7 @@ steamwar.properties
|
||||
|
||||
# IntelliJ IDEA
|
||||
.idea
|
||||
*.iml
|
||||
*.iml
|
||||
|
||||
# Other
|
||||
lib
|
23
BUILDING.md
Normale Datei
23
BUILDING.md
Normale Datei
@ -0,0 +1,23 @@
|
||||
# Building
|
||||
|
||||
Building SteamWar.de software requires certain libraries,
|
||||
which cannot be provided over traditional ways (like maven)
|
||||
due to copyright issues with compiled Spigot packages.
|
||||
For building these libraries have to be named in a lib
|
||||
directory named like in the following list.
|
||||
A subset of the following libraries is required to build this software
|
||||
(this is the list for being able to build all SteamWar.de software):
|
||||
|
||||
- BungeeCord.jar https://ci.md-5.net/job/BungeeCord/
|
||||
- BungeeTabListPlus.jar https://www.spigotmc.org/resources/bungeetablistplus.313/
|
||||
- PersistentBungeeCore.jar https://steamwar.de/devlabs/SteamWar/PersistentBungeeCore
|
||||
- ProtocolLib.jar https://www.spigotmc.org/resources/protocollib.1997/
|
||||
- Spigot-1.8.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.8.9)
|
||||
- Spigot-1.9.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.9.4)
|
||||
- Spigot-1.10.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.10.2)
|
||||
- Spigot-1.12.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.12.2)
|
||||
- Spigot-1.14.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.14.4)
|
||||
- Spigot-1.15.jar https://hub.spigotmc.org/jenkins/job/BuildTools/ (1.15.2)
|
||||
- SpigotCore.jar https://steamwar.de/devlabs/SteamWar/SpigotCore
|
||||
- WorldEdit-1.12.jar https://dev.bukkit.org/projects/worldedit/files (6.1.9)
|
||||
- WorldEdit-1.15.jar https://dev.bukkit.org/projects/worldedit/files (newest)
|
@ -1 +1 @@
|
||||
Subproject commit d000b8687d93eb43520bbf6685281099055eab9f
|
||||
Subproject commit 0f03b57e437c1d843816b7202d95b79ff0a8d2df
|
@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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'
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<UUID, Bauserver> 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<Exception> 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();
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<String, Builderserver> 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<Exception> 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();
|
||||
}
|
||||
}
|
@ -1,203 +0,0 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<VelocityPluginManager> 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();
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.persistent;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@UtilityClass
|
||||
public class Reflection {
|
||||
public static class Field<C, T> {
|
||||
private final java.lang.reflect.Field f;
|
||||
|
||||
public Field(Class<C> 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<C> {
|
||||
private final java.lang.reflect.Method m;
|
||||
|
||||
public Method(Class<C> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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) {}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.persistent;
|
||||
|
||||
public enum Servertype {
|
||||
BAUSERVER,
|
||||
ARENA,
|
||||
BUILDER
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Player, List<Player>> challenges = new HashMap<>();
|
||||
|
||||
public static final Map<Player, Player> lastChats = new HashMap<>();
|
||||
|
||||
public static final Map<Integer, List<Integer>> teamInvitations = new HashMap<>(); // UserID -> List<TeamIDs>
|
||||
|
||||
public static final Map<Player, Timestamp> sessions = new HashMap<>(); // Contains session start timestamp
|
||||
|
||||
public static final Map<Integer, Subserver> eventServer = new HashMap<>(); // TeamID -> Subserver map
|
||||
|
||||
public static final Map<Player, Integer> fabricCheckedPlayers = new HashMap<>();
|
||||
|
||||
public static final Map<Player, Long> fabricExpectPluginMessage = new HashMap<>();
|
||||
|
||||
public static final Map<Integer, ServerInfo> teamServers = new HashMap<>(); // TeamID -> ServerInfo map
|
||||
|
||||
public static final Map<Player, Map<UUID, UpsertPlayerInfoPacket.Entry>> directTabItems = new HashMap<>();
|
||||
}
|
@ -1,263 +0,0 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Subserver> serverList = new LinkedList<>();
|
||||
private static final Map<ServerInfo, Subserver> 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<Exception> 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<Player> cachedPlayers = new LinkedList<>();
|
||||
@Getter
|
||||
private final Map<Player, String> tablistNames = new HashMap<>();
|
||||
|
||||
protected Subserver(Servertype type, String serverName, int port, ProcessBuilder processBuilder, Runnable shutdownCallback, Consumer<Exception> 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<String> 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);
|
||||
}
|
||||
}
|
254
build.gradle
254
build.gradle
@ -17,24 +17,53 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
import java.util.function.BiConsumer
|
||||
|
||||
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 '8.1.1'
|
||||
id 'de.steamwar.gradle' version 'RELEASE'
|
||||
id 'com.github.johnrengelman.shadow' version '5.0.0'
|
||||
}
|
||||
|
||||
group 'de.steamwar'
|
||||
version ''
|
||||
|
||||
Properties steamwarProperties = new Properties()
|
||||
if (file("steamwar.properties").exists()) {
|
||||
steamwarProperties.load(file("steamwar.properties").newDataInputStream())
|
||||
}
|
||||
|
||||
ext {
|
||||
buildName = 'BungeeCore'
|
||||
artifactName = 'bungeecore'
|
||||
|
||||
uberJarName = "${buildName}-all.jar"
|
||||
jarName = "${artifactName}.jar"
|
||||
libs = "${buildDir}/libs"
|
||||
|
||||
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
operatingSystem = "windows"
|
||||
} else {
|
||||
operatingSystem = "unix"
|
||||
}
|
||||
}
|
||||
|
||||
compileJava.options.encoding = 'UTF-8'
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
mainClassName = ''
|
||||
|
||||
@ -50,64 +79,175 @@ sourceSets {
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
url 'https://repo.papermc.io/repository/maven-public/'
|
||||
content {
|
||||
includeGroup 'com.velocitypowered'
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url 'https://m2.dv8tion.net/releases'
|
||||
content {
|
||||
includeGroup 'net.dv8tion'
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url 'https://repo.lunarclient.dev'
|
||||
content {
|
||||
includeGroup 'com.lunarclient'
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
url 'https://m2.dv8tion.net/releases'
|
||||
}
|
||||
}
|
||||
|
||||
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.32'
|
||||
testCompileOnly 'org.projectlombok:lombok:1.18.32'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.32'
|
||||
testAnnotationProcessor 'org.projectlombok:lombok:1.18.32'
|
||||
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'
|
||||
|
||||
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'
|
||||
|
||||
implementation("net.dv8tion:JDA:4.4.0_352") {
|
||||
compileOnly files("${projectDir}/lib/BungeeCord.jar")
|
||||
compileOnly files("${projectDir}/lib/PersistentBungeeCore.jar")
|
||||
compileOnly files("${projectDir}/lib/BungeeTabListPlus.jar")
|
||||
implementation("net.dv8tion:JDA:4.3.0_299") {
|
||||
exclude module: 'opus-java'
|
||||
}
|
||||
|
||||
implementation 'org.msgpack:msgpack-core:0.9.8' //AlpineClient
|
||||
implementation "com.sparkjava:spark-core:2.9.3"
|
||||
|
||||
implementation 'com.lunarclient:apollo-api:1.1.0'
|
||||
implementation 'com.lunarclient:apollo-common:1.1.0'
|
||||
implementation project(":CommonCore")
|
||||
}
|
||||
|
||||
task buildProject {
|
||||
description 'Build this project'
|
||||
group "Steamwar"
|
||||
|
||||
dependsOn build
|
||||
}
|
||||
|
||||
task finalizeProject {
|
||||
description 'Finalize this project'
|
||||
group "Steamwar"
|
||||
|
||||
doLast {
|
||||
if ("${buildDir}" == null) {
|
||||
return
|
||||
}
|
||||
delete fileTree("${libs}").matching {
|
||||
exclude("${uberJarName}")
|
||||
}
|
||||
file(libs + "/" + uberJarName).renameTo(file(libs + "/" + jarName))
|
||||
}
|
||||
}
|
||||
build.finalizedBy(finalizeProject)
|
||||
|
||||
if (steamwarProperties.containsKey("hostname")) {
|
||||
String hostname = steamwarProperties.get("hostname")
|
||||
String uploadPath = steamwarProperties.getOrDefault("uploadPath", "~")
|
||||
|
||||
String server = steamwarProperties.getOrDefault("server", "DevBungee")
|
||||
String serverStartFlags = steamwarProperties.getOrDefault("serverStartFlags", "")
|
||||
|
||||
task uploadProject {
|
||||
description 'Upload this project'
|
||||
group "Steamwar"
|
||||
|
||||
doLast {
|
||||
await(shell("scp ${libs}/${jarName} ${hostname}:${uploadPath}/${server}/plugins"))
|
||||
if (steamwarProperties.getOrDefault("directStart", "false") == "false" && !answer("Start ${server} server?")) {
|
||||
return
|
||||
}
|
||||
serverStart(server, serverStartFlags, hostname)
|
||||
}
|
||||
}
|
||||
uploadProject.dependsOn(buildProject)
|
||||
|
||||
task startDevServer {
|
||||
description 'Start the DevBungee'
|
||||
group "Steamwar"
|
||||
|
||||
doLast {
|
||||
serverStart(server, serverStartFlags, hostname)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def await(Process proc) {
|
||||
def out = new StringBuilder()
|
||||
def err = new StringBuilder()
|
||||
proc.waitForProcessOutput(out, err)
|
||||
return [out, err, proc.exitValue()]
|
||||
}
|
||||
|
||||
private def shell(String command) {
|
||||
if (operatingSystem == "unix") {
|
||||
return ['bash', '-c', command].execute()
|
||||
} else {
|
||||
return ["cmd", "/c", command].execute()
|
||||
}
|
||||
}
|
||||
|
||||
private def serverStart(String serverName, String serverFlags, String hostname) {
|
||||
def proc = shell("ssh -t ${hostname} \"./mc ${serverFlags} ${serverName}\"")
|
||||
|
||||
Set<String> strings = new HashSet<>()
|
||||
File file = new File("${projectDir}/ignoredlog");
|
||||
if (file.exists()) {
|
||||
new BufferedReader(new InputStreamReader(new FileInputStream(file))).readLines().forEach({ s ->
|
||||
strings.add(s)
|
||||
})
|
||||
}
|
||||
|
||||
Thread outputThread = new Thread({
|
||||
Reader reader = proc.getInputStream().newReader();
|
||||
Writer writer = System.out.newWriter();
|
||||
try {
|
||||
while (proc.alive) {
|
||||
String s = reader.readLine()
|
||||
if (s == null) {
|
||||
return
|
||||
}
|
||||
if (strings.stream().anyMatch({check -> s.contains(check)})) {
|
||||
continue
|
||||
}
|
||||
writer.write(s + "\n")
|
||||
writer.flush()
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignored
|
||||
}
|
||||
})
|
||||
outputThread.setName("${serverName} - OutputThread")
|
||||
outputThread.start()
|
||||
|
||||
Writer writer
|
||||
Thread inputThread = new Thread({
|
||||
Reader reader = System.in.newReader()
|
||||
writer = proc.getOutputStream().newWriter()
|
||||
try {
|
||||
while (proc.alive) {
|
||||
String s = reader.readLine()
|
||||
writer.write(s + "\n")
|
||||
writer.flush()
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignored
|
||||
}
|
||||
})
|
||||
inputThread.setName("${serverName} - InputThread")
|
||||
inputThread.start()
|
||||
|
||||
gradle.buildFinished { buildResult ->
|
||||
if (!proc.alive) {
|
||||
return
|
||||
}
|
||||
writer = proc.getOutputStream().newWriter()
|
||||
writer.write("stop\n")
|
||||
writer.flush()
|
||||
awaitClose(proc, outputThread, inputThread)
|
||||
}
|
||||
awaitClose(proc, outputThread, inputThread)
|
||||
};
|
||||
|
||||
private static def awaitClose(Process proc, Thread outputThread, Thread inputThread) {
|
||||
while (proc.alive) {
|
||||
Thread.sleep(10)
|
||||
}
|
||||
proc.closeStreams()
|
||||
outputThread.interrupt()
|
||||
inputThread.interrupt()
|
||||
}
|
||||
|
||||
private def answer(String question) {
|
||||
while (System.in.available() > 0) System.in.read()
|
||||
println(question)
|
||||
boolean valid = "Yy".contains(((char) System.in.read()).toString())
|
||||
while (System.in.available() > 0) System.in.read()
|
||||
return valid
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
import datetime
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tarfile
|
||||
from os import path
|
||||
|
||||
# Non stdlib
|
||||
from nbt import nbt
|
||||
from ruamel.yaml import YAML
|
||||
yaml = YAML()
|
||||
|
||||
if __name__ == "__main__":
|
||||
configfile = f'/configs/GameModes/{sys.argv[1]}'
|
||||
version = int(sys.argv[2])
|
||||
worldname = sys.argv[3]
|
||||
|
||||
with open(configfile, 'r') as file:
|
||||
gamemode = yaml.load(file)
|
||||
|
||||
builderworld = path.expanduser(f'~/builder{version}/{worldname}')
|
||||
arenaworld = f'/servers/{gamemode["Server"]["Folder"]}/arenas/{worldname}'
|
||||
|
||||
if path.exists(arenaworld):
|
||||
backupworld = path.expanduser(f'~/backup/arenas/{datetime.datetime.now()}-{worldname}-{version}.tar.xz')
|
||||
with tarfile.open(backupworld, 'w:xz') as tar:
|
||||
tar.add(arenaworld, arcname=worldname)
|
||||
|
||||
shutil.rmtree(arenaworld)
|
||||
else:
|
||||
gamemode['Server']['Maps'].append(worldname)
|
||||
|
||||
with open(configfile, 'w') as file:
|
||||
yaml.dump(gamemode, file)
|
||||
|
||||
|
||||
level = nbt.NBTFile(f'{builderworld}/level.dat')
|
||||
level['Data']['Difficulty'] = nbt.TAG_Byte(2)
|
||||
gameRules = level['Data']['GameRules']
|
||||
gameRules['announceAdvancements'] = nbt.TAG_String('false')
|
||||
gameRules['disableRaids'] = nbt.TAG_String('true')
|
||||
gameRules['doDaylightCycle'] = nbt.TAG_String('false')
|
||||
gameRules['doEntityDrops'] = nbt.TAG_String('false')
|
||||
gameRules['doFireTick'] = nbt.TAG_String('true')
|
||||
gameRules['doImmediateRespawn'] = nbt.TAG_String('true')
|
||||
gameRules['doInsomnia'] = nbt.TAG_String('false')
|
||||
gameRules['doLimitedCrafting'] = nbt.TAG_String('false')
|
||||
gameRules['doMobLoot'] = nbt.TAG_String('false')
|
||||
gameRules['doMobSpawning'] = nbt.TAG_String('false')
|
||||
gameRules['doPatrolSpawning'] = nbt.TAG_String('false')
|
||||
gameRules['doTileDrops'] = nbt.TAG_String('true')
|
||||
gameRules['doTraderSpawning'] = nbt.TAG_String('false')
|
||||
gameRules['doWardenSpawning'] = nbt.TAG_String('false')
|
||||
gameRules['doWeatherCycle'] = nbt.TAG_String('false')
|
||||
gameRules['drowningDamage'] = nbt.TAG_String('true')
|
||||
gameRules['fallDamage'] = nbt.TAG_String('true')
|
||||
gameRules['fireDamage'] = nbt.TAG_String('true')
|
||||
gameRules['freezeDamage'] = nbt.TAG_String('true')
|
||||
gameRules['keepInventory'] = nbt.TAG_String('true')
|
||||
gameRules['lavaSourceConversion'] = nbt.TAG_String('false')
|
||||
gameRules['maxEntityCramming'] = nbt.TAG_String('24')
|
||||
gameRules['mobGriefing'] = nbt.TAG_String('false')
|
||||
gameRules['naturalRegeneration'] = nbt.TAG_String('false')
|
||||
gameRules['randomTickSpeed'] = nbt.TAG_String('3')
|
||||
gameRules['reducedDebugInfo'] = nbt.TAG_String('true')
|
||||
gameRules['snowAccumulationHeight'] = nbt.TAG_String('1')
|
||||
gameRules['spawnRadius'] = nbt.TAG_String('0')
|
||||
gameRules['spectatorsGenerateChunks'] = nbt.TAG_String('true')
|
||||
gameRules['waterSourceConversion'] = nbt.TAG_String('true')
|
||||
level.write_file()
|
||||
|
||||
if path.exists(arenaworld):
|
||||
shutil.rmtree(arenaworld)
|
||||
|
||||
os.makedirs(f'{arenaworld}/backup')
|
||||
shutil.copy2(f'{builderworld}/level.dat', f'{arenaworld}/backup/level.dat')
|
||||
shutil.copytree(f'{builderworld}/region', f'{arenaworld}/backup/region')
|
||||
|
||||
shutil.copy2(f'{builderworld}/level.dat', f'{arenaworld}/level.dat')
|
||||
shutil.copytree(f'{builderworld}/region', f'{arenaworld}/region')
|
||||
shutil.copy2(f'{builderworld}/config.yml', f'{arenaworld}/config.yml')
|
||||
|
||||
if path.exists(f'{builderworld}/paper-world.yml'):
|
||||
shutil.copy2(f'{builderworld}/paper-world.yml', f'{arenaworld}/backup/paper-world.yml')
|
||||
shutil.copy2(f'{builderworld}/paper-world.yml', f'{arenaworld}/paper-world.yml')
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
#Sat Apr 10 23:34:12 CEST 2021
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-all.zip
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -17,16 +17,6 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven {
|
||||
url = uri("https://steamwar.de/maven/")
|
||||
}
|
||||
}
|
||||
}
|
||||
rootProject.name = 'BungeeCore'
|
||||
|
||||
rootProject.name = 'VelocityCore'
|
||||
|
||||
include 'CommonCore'
|
||||
include 'Persistent'
|
||||
include 'CommonCore'
|
181
src/de/steamwar/bungeecore/ArenaMode.java
Normale Datei
181
src/de/steamwar/bungeecore/ArenaMode.java
Normale Datei
@ -0,0 +1,181 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore;
|
||||
|
||||
import de.steamwar.bungeecore.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 Map<String, ArenaMode> byChat = new HashMap<>();
|
||||
private static final Map<String, ArenaMode> byInternal = new HashMap<>();
|
||||
private static final Map<SchematicType, ArenaMode> bySchemType = new HashMap<>();
|
||||
private static final List<ArenaMode> allModes = new LinkedList<>();
|
||||
private static final Random random = new Random();
|
||||
|
||||
static {
|
||||
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<String> getAllChatNames(boolean historic) {
|
||||
List<String> chatNames = new LinkedList<>();
|
||||
for(ArenaMode mode : byInternal.values()){
|
||||
if(historic == mode.historic)
|
||||
chatNames.addAll(mode.chatNames);
|
||||
}
|
||||
return chatNames;
|
||||
}
|
||||
|
||||
public static List<String> getAllRankedChatNames(){
|
||||
List<String> 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<ArenaMode> getAllModes(){
|
||||
return allModes;
|
||||
}
|
||||
|
||||
private final String displayName;
|
||||
private final String folder;
|
||||
private final List<String> chatNames;
|
||||
private final String serverJar;
|
||||
private final String config;
|
||||
private final List<String> maps;
|
||||
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");
|
||||
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<String> getMaps() {
|
||||
return maps;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -17,28 +17,29 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.velocitycore;
|
||||
package de.steamwar.bungeecore;
|
||||
|
||||
import de.steamwar.messages.Chatter;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
class Broadcaster {
|
||||
|
||||
private final List<String> broadcasts = VelocityCore.get().getConfig().getBroadcasts();
|
||||
private static String [] broadCastMsgs;
|
||||
private int lastBroadCast = 0;
|
||||
|
||||
Broadcaster() {
|
||||
if(!broadcasts.isEmpty())
|
||||
VelocityCore.schedule(this::broadcast).repeat(10, TimeUnit.MINUTES).schedule();
|
||||
Broadcaster(){
|
||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
||||
if(!ProxyServer.getInstance().getPlayers().isEmpty())
|
||||
BungeeCore.broadcast(BungeeCore.CHAT_PREFIX + broadCastMsgs[lastBroadCast]);
|
||||
lastBroadCast++;
|
||||
if(lastBroadCast == broadCastMsgs.length){
|
||||
lastBroadCast = 0;
|
||||
}
|
||||
}, 10, 10, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
private void broadcast() {
|
||||
if(!VelocityCore.getProxy().getAllPlayers().isEmpty())
|
||||
Chatter.broadcast().system("PLAIN_STRING", broadcasts.get(lastBroadCast++));
|
||||
|
||||
if(lastBroadCast == broadcasts.size())
|
||||
lastBroadCast = 0;
|
||||
static void setBroadCastMsgs(String[] broadCastMsgs) {
|
||||
Broadcaster.broadCastMsgs = broadCastMsgs;
|
||||
}
|
||||
}
|
307
src/de/steamwar/bungeecore/BungeeCore.java
Normale Datei
307
src/de/steamwar/bungeecore/BungeeCore.java
Normale Datei
@ -0,0 +1,307 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore;
|
||||
|
||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
import de.steamwar.bungeecore.commands.*;
|
||||
import de.steamwar.bungeecore.comms.SpigotReceiver;
|
||||
import de.steamwar.bungeecore.listeners.*;
|
||||
import de.steamwar.bungeecore.listeners.mods.*;
|
||||
import de.steamwar.bungeecore.sql.*;
|
||||
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.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class BungeeCore extends Plugin {
|
||||
|
||||
public static String CHAT_PREFIX;
|
||||
public static String WORLD_FOLDER;
|
||||
public static String BAUWELT_PROTOTYP;
|
||||
public static String LOBBY_SERVER;
|
||||
public static String USERWORLDS15;
|
||||
public static String BAUWELT15;
|
||||
public static boolean EVENT_MODE;
|
||||
|
||||
private static BungeeCore instance;
|
||||
|
||||
public static final Map<String, String> serverPermissions = new HashMap<>();
|
||||
public static final Map<String, String> commands = new HashMap<>();
|
||||
|
||||
private ErrorLogger errorLogger;
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
getProxy().registerChannel("sw:bridge");
|
||||
getProxy().registerChannel("fabricmodsender:mods");
|
||||
|
||||
setInstance(this);
|
||||
loadConfig();
|
||||
|
||||
errorLogger = new ErrorLogger();
|
||||
new ConnectionListener();
|
||||
new Forge();
|
||||
new Forge12();
|
||||
new LabyMod();
|
||||
new Badlion();
|
||||
new ChatListener();
|
||||
new BanListener();
|
||||
new CheckListener();
|
||||
new ModLoaderBlocker();
|
||||
new WorldDownloader();
|
||||
new BrandListener();
|
||||
new Fabric();
|
||||
new SubserverProtocolFixer();
|
||||
|
||||
new Node.LocalNode();
|
||||
//new Node.RemoteNode("lx");
|
||||
//new Node.RemoteNode("az");
|
||||
|
||||
commands.put("/tp", null);
|
||||
commands.put("/bc", null);
|
||||
commands.put("/bauchat", null);
|
||||
commands.put("/local", null);
|
||||
|
||||
new TeamchatCommand();
|
||||
new MsgCommand();
|
||||
new RCommand();
|
||||
new PingCommand();
|
||||
new AlertCommand();
|
||||
new KickCommand();
|
||||
new JoinmeCommand();
|
||||
new TpCommand();
|
||||
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();
|
||||
|
||||
// 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();
|
||||
new WebregisterCommand();
|
||||
new FightCommand();
|
||||
new ChallengeCommand();
|
||||
new HistoricCommand();
|
||||
new CheckCommand();
|
||||
new ReplayCommand();
|
||||
new TutorialCommand();
|
||||
|
||||
new Broadcaster();
|
||||
}else{
|
||||
new EventModeListener();
|
||||
}
|
||||
|
||||
new EventStarter();
|
||||
new SessionManager();
|
||||
new SpigotReceiver();
|
||||
new TablistManager();
|
||||
new SettingsChangedListener();
|
||||
|
||||
getProxy().getScheduler().schedule(this, () -> {
|
||||
SteamwarUser.clearCache();
|
||||
UserElo.clearCache();
|
||||
Team.clearCache();
|
||||
}, 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);
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
WORLD_FOLDER = config.getString("worldfolder");
|
||||
BAUWELT_PROTOTYP = config.getString("bauweltprototyp");
|
||||
LOBBY_SERVER = config.getString("lobbyserver");
|
||||
USERWORLDS15 = config.getString("userworlds15");
|
||||
BAUWELT15 = config.getString("bauwelt15");
|
||||
EVENT_MODE = config.getBoolean("eventmode");
|
||||
Broadcaster.setBroadCastMsgs(config.getStringList("broadcasts").toArray(new String[1]));
|
||||
PollSystem.init(config.getString("poll.question"), config.getStringList("poll.answers"));
|
||||
Persistent.setChatPrefix(CHAT_PREFIX);
|
||||
Persistent.setLobbyServer(LOBBY_SERVER);
|
||||
|
||||
if (config.contains("discord")) {
|
||||
SteamwarDiscordBotConfig.loadConfig(config.getSection("discord"));
|
||||
}
|
||||
|
||||
final Configuration servers = config.getSection("servers");
|
||||
for(final String serverName : servers.getKeys()){
|
||||
final Configuration server = servers.getSection(serverName);
|
||||
List<String> cmds = server.getStringList("commands");
|
||||
serverPermissions.put(serverName, "bungeecore.server." + server.getString("permission"));
|
||||
String cmd = cmds.remove(0);
|
||||
new ServerSwitchCommand(
|
||||
cmd,
|
||||
serverName,
|
||||
serverPermissions.get(serverName),
|
||||
cmds.toArray(new String[0])
|
||||
);
|
||||
if(server.getBoolean("modchecked", false)) {
|
||||
ModLoaderBlocker.addServer(serverName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setInstance(BungeeCore core){
|
||||
instance = core;
|
||||
}
|
||||
}
|
94
src/de/steamwar/bungeecore/ErrorLogger.java
Normale Datei
94
src/de/steamwar/bungeecore/ErrorLogger.java
Normale Datei
@ -0,0 +1,94 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore;
|
||||
|
||||
import de.steamwar.bungeecore.sql.SWException;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class ErrorLogger extends Handler {
|
||||
private int ddosRate = 0;
|
||||
|
||||
ErrorLogger(){
|
||||
Logger.getLogger("").addHandler(this);
|
||||
}
|
||||
|
||||
void unregister(){
|
||||
Logger.getLogger("").removeHandler(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publish(LogRecord logRecord) {
|
||||
if(logRecord.getLevel().intValue() < Level.WARNING.intValue())
|
||||
return;
|
||||
|
||||
String message = MessageFormat.format(logRecord.getMessage(), logRecord.getParameters());
|
||||
for(String reason : ignoreContains)
|
||||
if(message.contains(reason))
|
||||
return;
|
||||
|
||||
ByteArrayOutputStream stacktraceOutput = new ByteArrayOutputStream();
|
||||
if(logRecord.getThrown() != null)
|
||||
logRecord.getThrown().printStackTrace(new PrintStream(stacktraceOutput));
|
||||
String stacktrace = stacktraceOutput.toString();
|
||||
if(stacktrace.contains("Cannot request protocol")) {
|
||||
if(++ddosRate % 1000 == 0) {
|
||||
SWException.log("Bungee", "DDOS", ddosRate + "");
|
||||
}
|
||||
return;
|
||||
} else if (stacktrace.contains("ErrorLogger")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SWException.log("Bungee", message, stacktrace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
//ignored
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
//ignored
|
||||
}
|
||||
|
||||
private static final List<String> ignoreContains;
|
||||
|
||||
static {
|
||||
List<String> contains = new ArrayList<>();
|
||||
contains.add("Error authenticating ");
|
||||
contains.add("read timed out");
|
||||
contains.add("Connection reset by peer");
|
||||
contains.add("No client connected for pending server");
|
||||
contains.add("Error occurred processing connection for");
|
||||
ignoreContains = Collections.unmodifiableList(contains);
|
||||
}
|
||||
}
|
96
src/de/steamwar/bungeecore/EventStarter.java
Normale Datei
96
src/de/steamwar/bungeecore/EventStarter.java
Normale Datei
@ -0,0 +1,96 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore;
|
||||
|
||||
import de.steamwar.bungeecore.sql.Event;
|
||||
import de.steamwar.bungeecore.sql.EventFight;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.bungeecore.sql.Team;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.scheduler.ScheduledTask;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static de.steamwar.bungeecore.Storage.eventServer;
|
||||
|
||||
public class EventStarter implements Runnable {
|
||||
|
||||
private static ScheduledTask task = null;
|
||||
|
||||
EventStarter(){
|
||||
EventFight.loadAllComingFights();
|
||||
|
||||
if(task != null)
|
||||
task.cancel();
|
||||
|
||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this, 1, 10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public static Map<Integer, Subserver> getEventServer() {
|
||||
return eventServer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
eventServer.entrySet().removeIf(entry -> !Subserver.getServerList().contains(entry.getValue()));
|
||||
Queue<EventFight> fights = EventFight.getFights();
|
||||
|
||||
EventFight next;
|
||||
while((next = nextFight(fights)) != null){
|
||||
Team blue = Team.get(next.getTeamBlue());
|
||||
Team red = Team.get(next.getTeamRed());
|
||||
|
||||
//Don't start EventServer if not the event bungee
|
||||
if(BungeeCore.EVENT_MODE || !Event.get(next.getEventID()).spectateSystem()) {
|
||||
ServerStarter starter = new ServerStarter().event(next);
|
||||
|
||||
ProxiedPlayer leiter = ProxyServer.getInstance().getPlayer(SteamwarUser.get(next.getKampfleiter()).getUuid());
|
||||
if(leiter != null)
|
||||
starter.send(leiter);
|
||||
|
||||
Subserver subserver = starter.start();
|
||||
|
||||
eventServer.put(blue.getTeamId(), subserver);
|
||||
eventServer.put(red.getTeamId(), subserver);
|
||||
Message.broadcast("EVENT_FIGHT_BROADCAST", "EVENT_FIGHT_BROADCAST_HOVER",
|
||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/event " + blue.getTeamKuerzel()), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName());
|
||||
} else {
|
||||
Message.broadcast("EVENT_FIGHT_BROADCAST", "EVENT_FIGHT_BROADCAST_HOVER",
|
||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/spectate"), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private EventFight nextFight(Queue<EventFight> fights){
|
||||
EventFight next = fights.peek();
|
||||
if(next == null)
|
||||
return null;
|
||||
|
||||
if(!next.getStartTime().before(new Timestamp(System.currentTimeMillis())))
|
||||
return null;
|
||||
|
||||
return fights.poll();
|
||||
}
|
||||
}
|
145
src/de/steamwar/bungeecore/Message.java
Normale Datei
145
src/de/steamwar/bungeecore/Message.java
Normale Datei
@ -0,0 +1,145 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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().filter(player -> player.user().getUserGroup().isTeamGroup()).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;
|
||||
}
|
||||
|
||||
}
|
266
src/de/steamwar/bungeecore/Node.java
Normale Datei
266
src/de/steamwar/bungeecore/Node.java
Normale Datei
@ -0,0 +1,266 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore;
|
||||
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public abstract class Node {
|
||||
|
||||
private static final List<String> OPENJ9_ARGS = Arrays.asList("-Xgc:excessiveGCratio=80", "-Xsyslog:none", "-Xtrace:none", "-Xdisableexplicitgc", "-XX:+AlwaysPreTouch", "-XX:+CompactStrings", "-XX:-HeapDumpOnOutOfMemory", "-XX:+ExitOnOutOfMemoryError", "-Dlog4j.configurationFile=log4j2.xml");
|
||||
private static final double MIN_FREE_MEM = 4.0 * 1024 * 1024; // 4 GiB
|
||||
private static final Set<String> JAVA_8 = new HashSet<>();
|
||||
static {
|
||||
JAVA_8.add("paper-1.8.8.jar");
|
||||
JAVA_8.add("paper-1.10.2.jar");
|
||||
JAVA_8.add("spigot-1.8.8.jar");
|
||||
JAVA_8.add("spigot-1.9.4.jar");
|
||||
JAVA_8.add("spigot-1.10.2.jar");
|
||||
}
|
||||
|
||||
private static final List<Node> nodes = new ArrayList<>();
|
||||
public static Node local = null;
|
||||
|
||||
public static Node getNode() {
|
||||
Node node = local;
|
||||
double minLoad = local.getLoad();
|
||||
if(minLoad < 0.5)
|
||||
return local;
|
||||
|
||||
synchronized (nodes) {
|
||||
Iterator<Node> it = nodes.iterator();
|
||||
while(it.hasNext()) {
|
||||
Node n = it.next();
|
||||
double load = n.getLoad();
|
||||
if (load < minLoad) {
|
||||
minLoad = load;
|
||||
node = n;
|
||||
} else if (load == Double.POSITIVE_INFINITY) {
|
||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Removing " + n.getName() + " due to infinite load!");
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public static void forEach(Consumer<Node> consumer) {
|
||||
consumer.accept(local);
|
||||
synchronized (nodes) {
|
||||
nodes.forEach(consumer);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract ProcessBuilder startServer(String serverJar, File directory, String worldDir, String levelName, int port, String xmx, String... dParams);
|
||||
public abstract void execute(String... command);
|
||||
public abstract String getName();
|
||||
public abstract double getLoad();
|
||||
|
||||
protected void constructServerstart(File directory, List<String> cmd, String serverJar, String worldDir, String levelName, int port, String xmx, String... dParams) {
|
||||
if (JAVA_8.contains(serverJar))
|
||||
cmd.add("/usr/lib/jvm/java-8-openj9-amd64/bin/java");
|
||||
else
|
||||
cmd.add("java");
|
||||
|
||||
for(String param : dParams){
|
||||
cmd.add("-D" + param);
|
||||
}
|
||||
cmd.add("-Xmx" + xmx);
|
||||
cmd.add("-Xshareclasses:nonfatal,name=" + directory.getName());
|
||||
cmd.addAll(OPENJ9_ARGS);
|
||||
if (!JAVA_8.contains(serverJar)) {
|
||||
cmd.add("--add-opens");
|
||||
cmd.add("java.base/jdk.internal.misc=ALL-UNNAMED");
|
||||
}
|
||||
cmd.add("-jar");
|
||||
cmd.add("/binarys/" + serverJar);
|
||||
cmd.add("--log-strip-color");
|
||||
cmd.add("--world-dir");
|
||||
cmd.add(worldDir);
|
||||
cmd.add("--level-name");
|
||||
cmd.add(levelName);
|
||||
cmd.add("--port");
|
||||
cmd.add(String.valueOf(port));
|
||||
cmd.add("nogui");
|
||||
}
|
||||
|
||||
protected void execute(ProcessBuilder builder) {
|
||||
try {
|
||||
builder.start().waitFor();
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException("Could not execute command", e);
|
||||
} catch (InterruptedException e) {
|
||||
ProxyServer.getInstance().getLogger().log(Level.SEVERE, "Interrupted during execution", e);
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
public static class LocalNode extends Node {
|
||||
private static final File meminfo = new File("/proc/meminfo");
|
||||
private static final File loadavg = new File("/proc/loadavg");
|
||||
|
||||
private final int cores;
|
||||
|
||||
public LocalNode() {
|
||||
this.cores = Runtime.getRuntime().availableProcessors();
|
||||
local = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessBuilder startServer(String serverJar, File directory, String worldDir, String levelName, int port, String xmx, String... dParams) {
|
||||
List<String> cmd = new ArrayList<>();
|
||||
constructServerstart(directory, cmd, serverJar, worldDir, levelName, port, xmx, dParams);
|
||||
ProcessBuilder builder = new ProcessBuilder(cmd);
|
||||
builder.directory(directory);
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(String... command) {
|
||||
execute(new ProcessBuilder(command));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "local";
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLoad() {
|
||||
double totalMem;
|
||||
double freeMem;
|
||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(meminfo)))) {
|
||||
totalMem = Double.parseDouble(bufferedReader.readLine().replaceAll(" +", " ").split(" ")[1]);
|
||||
bufferedReader.readLine();
|
||||
freeMem = Double.parseDouble(bufferedReader.readLine().replaceAll(" +", " ").split(" ")[1]);
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException("Could not read local memory", e);
|
||||
}
|
||||
|
||||
double cpuLoad;
|
||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(loadavg)))) {
|
||||
cpuLoad = Double.parseDouble(bufferedReader.readLine().split(" ")[0]);
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException("Could not read local cpu", e);
|
||||
}
|
||||
|
||||
return cpuLoad / cores + (freeMem > MIN_FREE_MEM ? 0 : ((totalMem - freeMem) / totalMem));
|
||||
}
|
||||
}
|
||||
|
||||
public static class RemoteNode extends Node {
|
||||
private final int cores;
|
||||
private final String remote;
|
||||
|
||||
public RemoteNode(String remote) {
|
||||
this.remote = remote;
|
||||
|
||||
//Determine core count
|
||||
Process process;
|
||||
try {
|
||||
process = new ProcessBuilder("ssh", remote, "nproc").start();
|
||||
if(!process.waitFor(5, TimeUnit.SECONDS))
|
||||
throw new IOException("Timeout of " + remote + " on init");
|
||||
} catch (IOException e) {
|
||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not initialize " + remote);
|
||||
cores = 1;
|
||||
return;
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
cores = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
int c;
|
||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
c = Integer.parseInt(bufferedReader.readLine());
|
||||
} catch (IOException | NumberFormatException e) {
|
||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not read cores of" + remote, e);
|
||||
c = 1;
|
||||
}
|
||||
cores = c;
|
||||
BungeeCore.get().getLogger().log(Level.INFO, "Adding node " + remote + " with " + cores + " cores.");
|
||||
|
||||
synchronized (nodes) {
|
||||
nodes.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessBuilder startServer(String serverJar, File directory, String worldDir, String levelName, int port, String xmx, String... dParams) {
|
||||
List<String> cmd = new ArrayList<>();
|
||||
cmd.add("ssh");
|
||||
cmd.add("-L");
|
||||
cmd.add(port + ":localhost:" + port);
|
||||
cmd.add(remote);
|
||||
cmd.add("cd");
|
||||
cmd.add(directory.getPath());
|
||||
cmd.add(";");
|
||||
constructServerstart(directory, cmd, serverJar, worldDir, levelName, port, xmx, dParams);
|
||||
return new ProcessBuilder(cmd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(String... command) {
|
||||
List<String> cmd = new ArrayList<>();
|
||||
cmd.add("ssh");
|
||||
cmd.add(remote);
|
||||
cmd.addAll(Arrays.asList(command));
|
||||
execute(new ProcessBuilder(cmd));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return remote;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getLoad() {
|
||||
Process process;
|
||||
try {
|
||||
process = new ProcessBuilder("ssh", remote, "cat /proc/loadavg;cat /proc/meminfo").start();
|
||||
if(!process.waitFor(1, TimeUnit.SECONDS))
|
||||
return Double.POSITIVE_INFINITY;
|
||||
} catch (IOException e) {
|
||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could starting process to read load", e);
|
||||
return Double.POSITIVE_INFINITY;
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
|
||||
double cpuLoad = Double.parseDouble(bufferedReader.readLine().split(" ")[0]);
|
||||
double totalMem = Double.parseDouble(bufferedReader.readLine().replaceAll(" +", " ").split(" ")[1]);
|
||||
bufferedReader.readLine();
|
||||
double freeMem = Double.parseDouble(bufferedReader.readLine().replaceAll(" +", " ").split(" ")[1]);
|
||||
return cpuLoad / cores + (freeMem > MIN_FREE_MEM ? 0 : ((totalMem - freeMem) / totalMem));
|
||||
} catch (IOException e) {
|
||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could read load", e);
|
||||
return Double.POSITIVE_INFINITY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
290
src/de/steamwar/bungeecore/ServerStarter.java
Normale Datei
290
src/de/steamwar/bungeecore/ServerStarter.java
Normale Datei
@ -0,0 +1,290 @@
|
||||
package de.steamwar.bungeecore;
|
||||
|
||||
import de.steamwar.bungeecore.sql.EventFight;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.bungeecore.sql.Team;
|
||||
import de.steamwar.bungeecore.sql.Tutorial;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ServerStarter {
|
||||
|
||||
private static final boolean MAIN_SERVER = ProxyServer.getInstance().getConfig().getListeners().stream().anyMatch(info -> ((InetSocketAddress) info.getSocketAddress()).getPort() == 25565);
|
||||
private static final Portrange BAU_PORTS = MAIN_SERVER ? new Portrange(10100, 20000) : new Portrange(2100, 2200);
|
||||
private static final Portrange ARENA_PORTS = MAIN_SERVER ? new Portrange(3000, 3100) : (BungeeCore.EVENT_MODE ? new Portrange(4000, 5000) : BAU_PORTS);
|
||||
|
||||
private static final String BACKBONE = "/home/minecraft/";
|
||||
private static final String SERVER_PATH = BACKBONE + "server/";
|
||||
private static final String EVENT_PATH = BACKBONE + "event/";
|
||||
public static final String TEMP_WORLD_PATH = BACKBONE + "arenaserver/";
|
||||
public static final String TUTORIAL_PATH = BACKBONE + "tutorials/";
|
||||
public static final String WORLDS18_PATH = BACKBONE + "userworlds18/";
|
||||
|
||||
private File directory = null;
|
||||
private String worldDir = null;
|
||||
|
||||
private Node node = null;
|
||||
private String serverJar = "spigot-1.15.2.jar";
|
||||
private String xmx = "768M";
|
||||
private Portrange portrange = BAU_PORTS;
|
||||
private Function<Integer, String> serverNameProvider = port -> node.getName() + port;
|
||||
private BooleanSupplier startCondition = () -> true;
|
||||
private Runnable worldSetup = () -> {};
|
||||
private String worldName = null;
|
||||
private Runnable worldCleanup = () -> {};
|
||||
private boolean allowMerge = false;
|
||||
private String fightMap = null;
|
||||
private String gameMode = null;
|
||||
private ServerConstructor constructor = (serverName, port, builder, shutdownCallback) -> new Arenaserver(serverName, gameMode, fightMap, allowMerge, port, builder, shutdownCallback);
|
||||
|
||||
private final Set<ProxiedPlayer> playersToSend = new HashSet<>();
|
||||
private final Map<String, String> arguments = new HashMap<>();
|
||||
|
||||
public ServerStarter arena(ArenaMode mode, String map) {
|
||||
portrange = ARENA_PORTS;
|
||||
serverNameProvider = port -> mode.getDisplayName() + (port - portrange.start);
|
||||
serverJar = mode.serverJar();
|
||||
allowMerge = true;
|
||||
fightMap = map;
|
||||
gameMode = mode.getInternalName();
|
||||
directory = new File(SERVER_PATH, mode.getFolder());
|
||||
arguments.put("config", mode.getConfig());
|
||||
tempWorld(SERVER_PATH + mode.getFolder() + "/arenas/" + map);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter event(EventFight eventFight) {
|
||||
arena(eventFight.getSpielmodus(), eventFight.getMap());
|
||||
node = Node.local;
|
||||
worldDir = EVENT_PATH;
|
||||
worldCleanup = () -> {};
|
||||
arguments.put("fightID", String.valueOf(eventFight.getFightID()));
|
||||
fightMap = eventFight.getMap();
|
||||
gameMode = eventFight.getSpielmodus().getInternalName();
|
||||
|
||||
String serverName = Team.get(eventFight.getTeamBlue()).getTeamKuerzel() + " vs " + Team.get(eventFight.getTeamRed()).getTeamKuerzel();
|
||||
serverNameProvider = port -> serverName;
|
||||
worldName = serverToWorldName(serverName + eventFight.getStartTime().toLocalDateTime().format(DateTimeFormatter.ISO_TIME));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter test(ArenaMode mode, String map, ProxiedPlayer owner) {
|
||||
arena(mode, map);
|
||||
buildWithTemp(owner);
|
||||
portrange = BAU_PORTS;
|
||||
arguments.put("fightID", String.valueOf(-1));
|
||||
return send(owner);
|
||||
}
|
||||
|
||||
public ServerStarter blueLeader(ProxiedPlayer player) {
|
||||
arguments.put("blueLeader", player.getUniqueId().toString());
|
||||
return send(player);
|
||||
}
|
||||
|
||||
public ServerStarter redLeader(ProxiedPlayer player) {
|
||||
arguments.put("redLeader", player.getUniqueId().toString());
|
||||
return send(player);
|
||||
}
|
||||
|
||||
public ServerStarter check(int schemID) {
|
||||
arguments.put("checkSchemID", String.valueOf(schemID));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter prepare(int schemID) {
|
||||
arguments.put("prepareSchemID", String.valueOf(schemID));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter replay(int replayID) {
|
||||
arguments.put("replay", String.valueOf(replayID));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter build18(UUID owner) {
|
||||
directory = new File(SERVER_PATH, "Bau18");
|
||||
serverJar = "paper-1.18.2.jar";
|
||||
worldDir = WORLDS18_PATH;
|
||||
worldName = String.valueOf(SteamwarUser.get(owner).getId());
|
||||
buildWithWorld(owner, new File(directory, "Bauwelt").getPath());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter build15(UUID owner) {
|
||||
directory = new File(SERVER_PATH, "Bau15");
|
||||
worldDir = BungeeCore.USERWORLDS15;
|
||||
worldName = String.valueOf(SteamwarUser.get(owner).getId());
|
||||
buildWithWorld(owner, BungeeCore.BAUWELT15);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter build12(UUID owner) {
|
||||
directory = new File(SERVER_PATH, "UserBau");
|
||||
serverJar = "spigot-1.12.2.jar";
|
||||
xmx = "256M";
|
||||
worldDir = BungeeCore.WORLD_FOLDER;
|
||||
worldName = owner.toString();
|
||||
buildWithWorld(owner, BungeeCore.BAUWELT_PROTOTYP);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerStarter tutorial(ProxiedPlayer owner, Tutorial tutorial) {
|
||||
directory = new File(SERVER_PATH, "Tutorial");
|
||||
buildWithTemp(owner);
|
||||
tempWorld(TUTORIAL_PATH + tutorial.id());
|
||||
arguments.put("tutorial", String.valueOf(tutorial.id()));
|
||||
return send(owner);
|
||||
}
|
||||
|
||||
private void tempWorld(String template) {
|
||||
worldDir = TEMP_WORLD_PATH;
|
||||
worldSetup = () -> copyWorld(node, template, worldDir + worldName);
|
||||
worldCleanup = () -> SubserverSystem.deleteFolder(node, worldDir + worldName);
|
||||
}
|
||||
|
||||
private void buildWithWorld(UUID owner, String prototype) {
|
||||
build(owner);
|
||||
|
||||
worldSetup = () -> {
|
||||
File world = new File(worldDir, worldName);
|
||||
if (!world.exists())
|
||||
copyWorld(node, prototype, world.getPath());
|
||||
};
|
||||
|
||||
// Send players to existing server
|
||||
startCondition = () -> {
|
||||
for(Subserver subserver : Subserver.getServerList()) {
|
||||
if(subserver.getType() == Servertype.BAUSERVER && ((Bauserver)subserver).getOwner().equals(owner)) {
|
||||
for(ProxiedPlayer p : playersToSend)
|
||||
SubserverSystem.sendPlayer(subserver, p);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
private void buildWithTemp(ProxiedPlayer owner) {
|
||||
build(owner.getUniqueId());
|
||||
|
||||
// Stop existing build server
|
||||
startCondition = () -> {
|
||||
if(startingBau(owner))
|
||||
return false;
|
||||
|
||||
for (Subserver subserver : Subserver.getServerList()) {
|
||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(owner.getUniqueId()) && subserver.hasStarted()) {
|
||||
subserver.stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !startingBau(owner);
|
||||
};
|
||||
}
|
||||
|
||||
private void build(UUID owner) {
|
||||
constructor = (serverName, port, builder, shutdownCallback) -> new Bauserver(serverName, owner, port, builder, shutdownCallback);
|
||||
serverNameProvider = port -> bauServerName(SteamwarUser.get(owner));
|
||||
}
|
||||
|
||||
public ServerStarter send(ProxiedPlayer player) {
|
||||
playersToSend.add(player);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Subserver start() {
|
||||
if(!startCondition.getAsBoolean())
|
||||
return null;
|
||||
|
||||
int port = portrange.freePort();
|
||||
String serverName = serverNameProvider.apply(port);
|
||||
|
||||
if(node == null)
|
||||
node = Node.getNode();
|
||||
if(worldName == null)
|
||||
worldName = serverToWorldName(serverName);
|
||||
|
||||
worldSetup.run();
|
||||
arguments.put("logPath", worldName);
|
||||
|
||||
Subserver subserver = constructor.construct(serverName, port, node.startServer(
|
||||
serverJar, directory, worldDir, worldName, port, xmx, arguments.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray(String[]::new)
|
||||
), worldCleanup);
|
||||
|
||||
for(ProxiedPlayer p : playersToSend)
|
||||
SubserverSystem.sendPlayer(subserver, p);
|
||||
|
||||
return subserver;
|
||||
}
|
||||
|
||||
private static boolean startingBau(ProxiedPlayer p) {
|
||||
for (Subserver subserver : Subserver.getServerList()) {
|
||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(p.getUniqueId()) && !subserver.hasStarted()) {
|
||||
Message.send("BAU_START_ALREADY", p);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String bauServerName(SteamwarUser user) {
|
||||
return user.getUserName() + "s Bau";
|
||||
}
|
||||
|
||||
public static String serverToWorldName(String serverName) {
|
||||
return serverName.replace(' ', '_').replace("[", "").replace("]", "");
|
||||
}
|
||||
|
||||
public static void copyWorld(Node node, String template, String target) {
|
||||
node.execute("cp", "-r", template, target);
|
||||
}
|
||||
|
||||
private interface ServerConstructor {
|
||||
Subserver construct(String serverName, int port, ProcessBuilder builder, Runnable shutdownCallback);
|
||||
}
|
||||
|
||||
private static class Portrange {
|
||||
|
||||
private final int start;
|
||||
private final int end;
|
||||
private int current;
|
||||
|
||||
private Portrange(int start, int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
current = start;
|
||||
}
|
||||
|
||||
private void increment() {
|
||||
current++;
|
||||
|
||||
if(current == end)
|
||||
current = start;
|
||||
}
|
||||
|
||||
private synchronized int freePort() {
|
||||
Set<Integer> usedPorts;
|
||||
|
||||
synchronized (Subserver.getServerList()) {
|
||||
usedPorts = Subserver.getServerList().stream().map(server -> ((InetSocketAddress) server.getServer().getSocketAddress()).getPort()).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
while(usedPorts.contains(current)) {
|
||||
increment();
|
||||
}
|
||||
|
||||
int result = current;
|
||||
increment();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
58
src/de/steamwar/bungeecore/SubserverSystem.java
Normale Datei
58
src/de/steamwar/bungeecore/SubserverSystem.java
Normale Datei
@ -0,0 +1,58 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore;
|
||||
|
||||
import de.steamwar.bungeecore.comms.handlers.FightInfoHandler;
|
||||
import de.steamwar.bungeecore.comms.packets.StartingServerPacket;
|
||||
import de.steamwar.bungeecore.sql.IgnoreSystem;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class SubserverSystem {
|
||||
private SubserverSystem(){}
|
||||
|
||||
public static void deleteFolder(Node node, String worldName) {
|
||||
node.execute("rm", "-r", worldName);
|
||||
}
|
||||
|
||||
public static void sendDeniedMessage(ProxiedPlayer p, UUID owner){
|
||||
ProxiedPlayer o = ProxyServer.getInstance().getPlayer(owner);
|
||||
if(o == null)
|
||||
return;
|
||||
if(IgnoreSystem.isIgnored(o, p)){
|
||||
Message.send("SERVER_IGNORED", p);
|
||||
return;
|
||||
}
|
||||
|
||||
Message.send("SERVER_ADD_MEMBER", o, p.getName());
|
||||
Message.sendPrefixless("SERVER_ADD_MESSAGE", o, Message.parse("SERVER_ADD_MESSAGE_HOVER", o, p.getName()),
|
||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bau addmember " + p.getName()));
|
||||
}
|
||||
|
||||
public static void sendPlayer(Subserver subserver, ProxiedPlayer player) {
|
||||
subserver.sendPlayer(player);
|
||||
if(!subserver.hasStarted() && FightInfoHandler.onLobby(player))
|
||||
new StartingServerPacket(SteamwarUser.get(player.getUniqueId())).send(player);
|
||||
}
|
||||
}
|
45
src/de/steamwar/bungeecore/api/AuthUtils.java
Normale Datei
45
src/de/steamwar/bungeecore/api/AuthUtils.java
Normale Datei
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@UtilityClass
|
||||
public class AuthUtils {
|
||||
|
||||
public static Optional<Token> isAuthorized(Request request, Response response) {
|
||||
String authorization = request.headers("Authorization");
|
||||
if (authorization == null) {
|
||||
response.status(401);
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
try {
|
||||
return Optional.of(Token.decrypt(authorization));
|
||||
} catch (SecurityException e) {
|
||||
response.status(401);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
@ -17,8 +17,16 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.command;
|
||||
package de.steamwar.bungeecore.api;
|
||||
|
||||
import de.steamwar.messages.Chatter;
|
||||
import com.google.gson.JsonObject;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
public interface TypeValidator<T> extends AbstractValidator<Chatter, T> {}
|
||||
public interface EndPoint {
|
||||
|
||||
default String path() {
|
||||
return this.getClass().getTypeName().substring(27).replace("EndPoint", "").replaceAll("([A-Z])", "_\1").toLowerCase();
|
||||
}
|
||||
JsonObject result(Request request, Response response);
|
||||
}
|
164
src/de/steamwar/bungeecore/api/Token.java
Normale Datei
164
src/de/steamwar/bungeecore/api/Token.java
Normale Datei
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.*;
|
||||
import java.security.spec.DSAPrivateKeySpec;
|
||||
import java.security.spec.DSAPublicKeySpec;
|
||||
import java.util.Base64;
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
public class Token {
|
||||
|
||||
private static KeyPair pair;
|
||||
|
||||
private static KeyPair getKeyPair() {
|
||||
if (pair != null) return pair;
|
||||
|
||||
File publicKeyFile = new File("~/token_dsa.pub");
|
||||
File privateKeyFile = new File("~/token_dsa");
|
||||
|
||||
if (publicKeyFile.exists() && privateKeyFile.exists()) {
|
||||
PublicKey publicKey = null;
|
||||
try {
|
||||
JsonObject jsonObject = JsonParser.parseReader(new BufferedReader(new InputStreamReader(new FileInputStream(publicKeyFile)))).getAsJsonObject();
|
||||
BigInteger y = jsonObject.get("y").getAsBigInteger();
|
||||
BigInteger p = jsonObject.get("p").getAsBigInteger();
|
||||
BigInteger q = jsonObject.get("q").getAsBigInteger();
|
||||
BigInteger g = jsonObject.get("g").getAsBigInteger();
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
|
||||
publicKey = keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g));
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
PrivateKey privateKey = null;
|
||||
try {
|
||||
JsonObject jsonObject = JsonParser.parseReader(new BufferedReader(new InputStreamReader(new FileInputStream(privateKeyFile)))).getAsJsonObject();
|
||||
BigInteger x = jsonObject.get("x").getAsBigInteger();
|
||||
BigInteger p = jsonObject.get("p").getAsBigInteger();
|
||||
BigInteger q = jsonObject.get("q").getAsBigInteger();
|
||||
BigInteger g = jsonObject.get("g").getAsBigInteger();
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
|
||||
privateKey = keyFactory.generatePrivate(new DSAPrivateKeySpec(x, p, q, g));
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
pair = new KeyPair(publicKey, privateKey);
|
||||
return pair;
|
||||
}
|
||||
try {
|
||||
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("DSA");
|
||||
keyPairGen.initialize(2048);
|
||||
pair = keyPairGen.generateKeyPair();
|
||||
saveKeyPair();
|
||||
return pair;
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void saveKeyPair() {
|
||||
File publicKeyFile = new File("~/token_dsa.pub");
|
||||
File privateKeyFile = new File("~/token_dsa");
|
||||
|
||||
try {
|
||||
publicKeyFile.createNewFile();
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(pair.getPrivate().getAlgorithm());
|
||||
DSAPublicKeySpec dsaPublicKeySpec = keyFactory.getKeySpec(pair.getPublic(), DSAPublicKeySpec.class);
|
||||
|
||||
JsonObject privateKey = new JsonObject();
|
||||
privateKey.addProperty("y", dsaPublicKeySpec.getY());
|
||||
privateKey.addProperty("p", dsaPublicKeySpec.getP());
|
||||
privateKey.addProperty("q", dsaPublicKeySpec.getQ());
|
||||
privateKey.addProperty("g", dsaPublicKeySpec.getG());
|
||||
new JsonWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(publicKeyFile)))).close();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
privateKeyFile.createNewFile();
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(pair.getPrivate().getAlgorithm());
|
||||
DSAPrivateKeySpec dsaPrivateKeySpec = keyFactory.getKeySpec(pair.getPrivate(), DSAPrivateKeySpec.class);
|
||||
|
||||
JsonObject privateKey = new JsonObject();
|
||||
privateKey.addProperty("x", dsaPrivateKeySpec.getX());
|
||||
privateKey.addProperty("p", dsaPrivateKeySpec.getP());
|
||||
privateKey.addProperty("q", dsaPrivateKeySpec.getQ());
|
||||
privateKey.addProperty("g", dsaPrivateKeySpec.getG());
|
||||
new JsonWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(privateKeyFile)))).close();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private UUID uuid;
|
||||
private long creationDate;
|
||||
|
||||
public Token(SteamwarUser steamwarUser) {
|
||||
uuid = steamwarUser.getUuid();
|
||||
creationDate = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public Token(JsonObject jsonObject) {
|
||||
uuid = UUID.fromString(jsonObject.get("uuid").getAsString());
|
||||
creationDate = jsonObject.get("creationDate").getAsLong();
|
||||
}
|
||||
|
||||
public JsonObject toJSON() {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("uuid", uuid.toString());
|
||||
jsonObject.addProperty("creationDate", creationDate);
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
public String encrypt() {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, getKeyPair().getPublic());
|
||||
return Base64.getEncoder().encodeToString(cipher.doFinal(toJSON().toString().getBytes(StandardCharsets.UTF_8)));
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Token decrypt(String s) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, getKeyPair().getPrivate());
|
||||
byte[] bytes = cipher.doFinal(Base64.getDecoder().decode(s));
|
||||
JsonObject jsonObject = JsonParser.parseReader(new InputStreamReader(new ByteArrayInputStream(bytes))).getAsJsonObject();
|
||||
return new Token(jsonObject);
|
||||
} catch (Exception e) {
|
||||
throw new SecurityException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
68
src/de/steamwar/bungeecore/api/WebAPI.java
Normale Datei
68
src/de/steamwar/bungeecore/api/WebAPI.java
Normale Datei
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.v1.ServerstatusEndPoint;
|
||||
import de.steamwar.bungeecore.api.v1.ServerteamEndPoint;
|
||||
import de.steamwar.bungeecore.api.v1.statistics.*;
|
||||
import de.steamwar.bungeecore.api.v1.user.GetUsernameEndPoint;
|
||||
import de.steamwar.bungeecore.api.v1.user.GetUuidEndPoint;
|
||||
import de.steamwar.bungeecore.api.v1.website.LoginEndPoint;
|
||||
import de.steamwar.bungeecore.api.v1.website.LogoutEndPoint;
|
||||
|
||||
import static spark.Spark.port;
|
||||
import static spark.Spark.post;
|
||||
|
||||
public class WebAPI {
|
||||
|
||||
private static EndPoint[] endPointsV1 = new EndPoint[] {
|
||||
new FightsEndPoint(),
|
||||
new HoursContributedEndPoint(),
|
||||
new HoursPlayedEndPoint(),
|
||||
new SchematicsAcceptedEndPoint(),
|
||||
new UniqueJoinsEndPoint(),
|
||||
new GetUsernameEndPoint(),
|
||||
new GetUuidEndPoint(),
|
||||
new LoginEndPoint(),
|
||||
new LogoutEndPoint(),
|
||||
new ServerstatusEndPoint(),
|
||||
new ServerteamEndPoint(),
|
||||
};
|
||||
|
||||
private static void register(EndPoint[] endPoints) {
|
||||
for (EndPoint endPoint : endPoints) {
|
||||
post(endPoint.path(), (request, response) -> {
|
||||
JsonObject result = endPoint.result(request, response);
|
||||
if (result == null) {
|
||||
result = new JsonObject();
|
||||
}
|
||||
response.type("application/json");
|
||||
return result.toString();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void start() {
|
||||
port(1024);
|
||||
|
||||
register(endPointsV1);
|
||||
}
|
||||
}
|
38
src/de/steamwar/bungeecore/api/doc.txt
Normale Datei
38
src/de/steamwar/bungeecore/api/doc.txt
Normale Datei
@ -0,0 +1,38 @@
|
||||
```
|
||||
SteamWar Endpoints:
|
||||
|
||||
Serverteam-Endpoint:
|
||||
- UUID, Rang, InGame-Name
|
||||
|
||||
User-Endpoints:
|
||||
- UUID -> skin.png
|
||||
- UUID -> head.png
|
||||
- Token -> UUID
|
||||
- Token -> head.png
|
||||
- Token -> skin.png
|
||||
- Token -> InGame-Name
|
||||
|
||||
Website-User-Endpoints:
|
||||
- (UserName, hashedPW) -> Token
|
||||
- (Token) -> Void // Abmeldung
|
||||
|
||||
Serverstatus-Endpoint:
|
||||
- PlayerSize, MaxPlayerSize
|
||||
Response -> Status
|
||||
|
||||
Ranked-Endpoint:
|
||||
- (Modus, Season?) -> Ranglist
|
||||
- (UUID) -> Ränge
|
||||
Ranglist-Endpoint:
|
||||
- Modi // Alle Modi, welche eine Ranglist haben
|
||||
Schem-Endpoint:
|
||||
- (Modus, Season?) -> Public-Ranglist
|
||||
- (Modus, Season?, Token) -> Privat-Ranglist
|
||||
|
||||
Statistiken-Endpoints:
|
||||
- Modi, AnzahlFights // Anzahl Fights der letzten 7 Tage
|
||||
- AnzahlJoins // Anzahl Joins der letzten 7 Tage (total)
|
||||
- UniqueJoins // Anzahl uniquer PlayerJoins der letzten 7 Tage (total)
|
||||
- HoursPlayed // Anzahl gespielter Stunden für alle Spieler der letzten 7 Tage (total)
|
||||
|
||||
```
|
39
src/de/steamwar/bungeecore/api/v1/ServerstatusEndPoint.java
Normale Datei
39
src/de/steamwar/bungeecore/api/v1/ServerstatusEndPoint.java
Normale Datei
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api.v1;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
public class ServerstatusEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("players", BungeeCord.getInstance().getPlayers().size());
|
||||
jsonObject.addProperty("maxPlayers", BungeeCord.getInstance().getConfig().getPlayerLimit());
|
||||
|
||||
response.status(200);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
46
src/de/steamwar/bungeecore/api/v1/ServerteamEndPoint.java
Normale Datei
46
src/de/steamwar/bungeecore/api/v1/ServerteamEndPoint.java
Normale Datei
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api.v1;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
public class ServerteamEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
JsonArray jsonArray = new JsonArray();
|
||||
SteamwarUser.getServerTeam().forEach(steamwarUser -> {
|
||||
JsonObject user = new JsonObject();
|
||||
user.addProperty("name", steamwarUser.getUserName());
|
||||
user.addProperty("rank", steamwarUser.getUserGroup().name());
|
||||
jsonArray.add(user);
|
||||
});
|
||||
jsonObject.add("", jsonArray);
|
||||
|
||||
response.status(200);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
45
src/de/steamwar/bungeecore/api/v1/statistics/FightsEndPoint.java
Normale Datei
45
src/de/steamwar/bungeecore/api/v1/statistics/FightsEndPoint.java
Normale Datei
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api.v1.statistics;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import de.steamwar.bungeecore.sql.Statistics;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class FightsEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
Map<String, Map<String, Integer>> result = Statistics.getFightsPerDayPerGameMode();
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
result.forEach((s, stringIntegerMap) -> {
|
||||
JsonObject singleResult = new JsonObject();
|
||||
stringIntegerMap.forEach(singleResult::addProperty);
|
||||
jsonObject.add(s, singleResult);
|
||||
});
|
||||
|
||||
response.status(200);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api.v1.statistics;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import de.steamwar.bungeecore.sql.Statistics;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class HoursContributedEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
Map<String, Double> result = Statistics.getHoursContributedPerPlayer();
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
result.forEach(jsonObject::addProperty);
|
||||
|
||||
response.status(200);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api.v1.statistics;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import de.steamwar.bungeecore.sql.Statistics;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class HoursPlayedEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
Map<String, Double> result = Statistics.getHoursPlayedPerDay();
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
result.forEach(jsonObject::addProperty);
|
||||
|
||||
response.status(200);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api.v1.statistics;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import de.steamwar.bungeecore.sql.Statistics;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SchematicsAcceptedEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
Map<String, Map<String, Integer>> result = Statistics.getAcceptedSchematicsPerDayPerGameMode();
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
result.forEach((s, stringIntegerMap) -> {
|
||||
JsonObject singleResult = new JsonObject();
|
||||
stringIntegerMap.forEach(singleResult::addProperty);
|
||||
jsonObject.add(s, singleResult);
|
||||
});
|
||||
|
||||
response.status(200);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api.v1.statistics;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import de.steamwar.bungeecore.sql.Statistics;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class UniqueJoinsEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
Map<String, Integer> result = Statistics.getUniqueJoinsPerDay();
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
result.forEach(jsonObject::addProperty);
|
||||
|
||||
response.status(200);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
50
src/de/steamwar/bungeecore/api/v1/user/GetUsernameEndPoint.java
Normale Datei
50
src/de/steamwar/bungeecore/api/v1/user/GetUsernameEndPoint.java
Normale Datei
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api.v1.user;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.AuthUtils;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import de.steamwar.bungeecore.api.Token;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import static spark.Spark.post;
|
||||
|
||||
public class GetUsernameEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
Optional<Token> optionalToken = AuthUtils.isAuthorized(request, response);
|
||||
if (!optionalToken.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
Token token = optionalToken.get();
|
||||
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("username", SteamwarUser.get(token.getUuid()).getUserName());
|
||||
|
||||
response.status(200);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
47
src/de/steamwar/bungeecore/api/v1/user/GetUuidEndPoint.java
Normale Datei
47
src/de/steamwar/bungeecore/api/v1/user/GetUuidEndPoint.java
Normale Datei
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.api.v1.user;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.AuthUtils;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import de.steamwar.bungeecore.api.Token;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class GetUuidEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
Optional<Token> optionalToken = AuthUtils.isAuthorized(request, response);
|
||||
if (!optionalToken.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
Token token = optionalToken.get();
|
||||
|
||||
JsonObject jsonObject = new JsonObject();
|
||||
jsonObject.addProperty("uuid", token.getUuid().toString());
|
||||
|
||||
response.status(200);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
@ -17,13 +17,17 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.command;
|
||||
package de.steamwar.bungeecore.api.v1.website;
|
||||
|
||||
import de.steamwar.messages.Chatter;
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
public interface TypeMapper<T> extends AbstractTypeMapper<Chatter, T> {
|
||||
/**
|
||||
* The CommandSender can be null!
|
||||
*/
|
||||
T map(Chatter sender, PreviousArguments previousArguments, String s);
|
||||
public class LoginEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -17,9 +17,17 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.velocitycore.network;
|
||||
package de.steamwar.bungeecore.api.v1.website;
|
||||
|
||||
import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import de.steamwar.network.packets.MetaInfos;
|
||||
import com.google.gson.JsonObject;
|
||||
import de.steamwar.bungeecore.api.EndPoint;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
|
||||
public record ServerMetaInfo(ServerConnection sender) implements MetaInfos {}
|
||||
public class LogoutEndPoint implements EndPoint {
|
||||
|
||||
@Override
|
||||
public JsonObject result(Request request, Response response) {
|
||||
return null;
|
||||
}
|
||||
}
|
81
src/de/steamwar/bungeecore/bot/AuthManager.java
Normale Datei
81
src/de/steamwar/bungeecore/bot/AuthManager.java
Normale Datei
@ -0,0 +1,81 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot;
|
||||
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.dv8tion.jda.api.MessageBuilder;
|
||||
import net.dv8tion.jda.api.entities.Emoji;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||
import net.dv8tion.jda.api.interactions.components.Button;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AuthManager {
|
||||
|
||||
private static final Map<String, Long> 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;
|
||||
}
|
||||
}
|
||||
}
|
166
src/de/steamwar/bungeecore/bot/SteamwarDiscordBot.java
Normale Datei
166
src/de/steamwar/bungeecore/bot/SteamwarDiscordBot.java
Normale Datei
@ -0,0 +1,166 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot;
|
||||
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
import de.steamwar.bungeecore.bot.commands.*;
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
import de.steamwar.bungeecore.bot.events.EventManager;
|
||||
import de.steamwar.bungeecore.bot.events.SchematicsManager;
|
||||
import de.steamwar.bungeecore.bot.listeners.*;
|
||||
import de.steamwar.bungeecore.bot.util.DiscordRolesMessage;
|
||||
import de.steamwar.bungeecore.bot.util.DiscordRulesMessage;
|
||||
import de.steamwar.bungeecore.bot.util.DiscordTicketMessage;
|
||||
import de.steamwar.bungeecore.sql.Event;
|
||||
import de.steamwar.messages.ChatSender;
|
||||
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<String, BasicDiscordCommand> 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);
|
||||
}
|
||||
}
|
67
src/de/steamwar/bungeecore/bot/commands/BanCommand.java
Normale Datei
67
src/de/steamwar/bungeecore/bot/commands/BanCommand.java
Normale Datei
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
||||
import de.steamwar.bungeecore.sql.Punishment;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
public class BanCommand extends BasicDiscordCommand {
|
||||
|
||||
public BanCommand() {
|
||||
super("ban", "Banne einen Nutzer, wenn du die Rechte hast.");
|
||||
|
||||
addOption(OptionType.STRING, "user", "Der Benutzer", true);
|
||||
addOption(OptionType.STRING, "time", "Bis Wann", true);
|
||||
addOption(OptionType.STRING, "reason", "Warum", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(SlashCommandEvent event) {
|
||||
if (!testPermission(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SteamwarUser sender = SteamwarUser.get(event.getMember().getIdLong());
|
||||
SteamwarUser target = SteamwarUser.getOrCreateOfflinePlayer(event.getOption("user").getAsString());
|
||||
if (target == null) {
|
||||
event.reply("Angegebener User invalide").setEphemeral(true).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");
|
||||
|
||||
target.punish(Punishment.PunishmentType.Ban, time, msg, sender.getId(), 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();
|
||||
}
|
||||
}
|
54
src/de/steamwar/bungeecore/bot/commands/BasicDiscordCommand.java
Normale Datei
54
src/de/steamwar/bungeecore/bot/commands/BasicDiscordCommand.java
Normale Datei
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.commands;
|
||||
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.bungeecore.sql.UserGroup;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
|
||||
|
||||
public abstract class BasicDiscordCommand extends CommandData {
|
||||
|
||||
protected BasicDiscordCommand(String name, String description) {
|
||||
super(name, description);
|
||||
}
|
||||
|
||||
public abstract void run(SlashCommandEvent event);
|
||||
|
||||
protected SteamwarUser getSteamwarUser(SlashCommandEvent event) {
|
||||
Member member = event.getMember();
|
||||
SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
|
||||
if (steamwarUser == null) {
|
||||
return null;
|
||||
}
|
||||
return steamwarUser;
|
||||
}
|
||||
|
||||
protected boolean testPermission(SlashCommandEvent event) {
|
||||
Member member = event.getMember();
|
||||
SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
|
||||
if (steamwarUser == null || (!steamwarUser.getUserGroup().isTeamGroup() && steamwarUser.getUserGroup() != UserGroup.Builder)) {
|
||||
event.reply("Du hast für " + event.getName() + " keine Rechte oder es existiert keine Verknüpfung für dich.").setEphemeral(true).queue();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
43
src/de/steamwar/bungeecore/bot/commands/ListCommand.java
Normale Datei
43
src/de/steamwar/bungeecore/bot/commands/ListCommand.java
Normale Datei
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
67
src/de/steamwar/bungeecore/bot/commands/MuteCommand.java
Normale Datei
67
src/de/steamwar/bungeecore/bot/commands/MuteCommand.java
Normale Datei
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.commands.PunishmentCommand;
|
||||
import de.steamwar.bungeecore.sql.Punishment;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
public class MuteCommand extends BasicDiscordCommand {
|
||||
|
||||
public MuteCommand() {
|
||||
super("mute", "Mute einen Nutzer, wenn du die Rechte hast.");
|
||||
|
||||
addOption(OptionType.STRING, "user", "Der Benutzer", true);
|
||||
addOption(OptionType.STRING, "time", "Bis Wann", true);
|
||||
addOption(OptionType.STRING, "reason", "Warum", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(SlashCommandEvent event) {
|
||||
if (!testPermission(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SteamwarUser sender = SteamwarUser.get(event.getMember().getIdLong());
|
||||
SteamwarUser target = SteamwarUser.getOrCreateOfflinePlayer(event.getOption("user").getAsString());
|
||||
if (target == null) {
|
||||
event.reply("Angegebener User invalide").setEphemeral(true).complete();
|
||||
return;
|
||||
}
|
||||
|
||||
Timestamp time = 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();
|
||||
}
|
||||
}
|
96
src/de/steamwar/bungeecore/bot/commands/TeamCommand.java
Normale Datei
96
src/de/steamwar/bungeecore/bot/commands/TeamCommand.java
Normale Datei
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.commands;
|
||||
|
||||
import de.steamwar.bungeecore.sql.Event;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.bungeecore.sql.Team;
|
||||
import de.steamwar.bungeecore.sql.TeamTeilnahme;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.entities.Emoji;
|
||||
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class TeamCommand extends BasicDiscordCommand {
|
||||
|
||||
public TeamCommand() {
|
||||
super("team", "Alle Team bezogenen Befehle");
|
||||
|
||||
addSubcommands(new SubcommandData("info", "Infos über das Team oder deins")
|
||||
.addOption(OptionType.STRING, "team", "Name oder Kuerzel", false)
|
||||
);
|
||||
}
|
||||
|
||||
private Emoji emoji = Emoji.fromUnicode("U+1F7E2");
|
||||
|
||||
@Override
|
||||
public void run(SlashCommandEvent event) {
|
||||
SteamwarUser steamwarUser = getSteamwarUser(event);
|
||||
|
||||
if (event.getSubcommandName() != null) {
|
||||
switch (event.getSubcommandName()) {
|
||||
case "info":
|
||||
OptionMapping optionMapping = event.getOption("team");
|
||||
Team team;
|
||||
if (optionMapping == null) {
|
||||
if (steamwarUser == null) {
|
||||
event.reply("Dein Discord ist nicht verknüpft").setEphemeral(true).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<SteamwarUser> 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;
|
||||
}
|
||||
}
|
59
src/de/steamwar/bungeecore/bot/commands/UnbanCommand.java
Normale Datei
59
src/de/steamwar/bungeecore/bot/commands/UnbanCommand.java
Normale Datei
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.commands;
|
||||
|
||||
import de.steamwar.bungeecore.sql.Punishment;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Date;
|
||||
|
||||
public class UnbanCommand extends BasicDiscordCommand {
|
||||
|
||||
public UnbanCommand() {
|
||||
super("unban", "Entbannt einen Nutzer, wenn du die Rechte hast.");
|
||||
|
||||
addOption(OptionType.STRING, "user", "Der Benutzer", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(SlashCommandEvent event) {
|
||||
if (!testPermission(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SteamwarUser sender = SteamwarUser.get(event.getMember().getIdLong());
|
||||
SteamwarUser target = SteamwarUser.getOrCreateOfflinePlayer(event.getOption("user").getAsString());
|
||||
if (target == null) {
|
||||
event.reply("Angegebener User invalide").setEphemeral(true).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);
|
||||
event.reply("Erfolgreich " + target.getUserName() + " entbannt").setEphemeral(true).queue();
|
||||
}
|
||||
}
|
94
src/de/steamwar/bungeecore/bot/commands/WhoisCommand.java
Normale Datei
94
src/de/steamwar/bungeecore/bot/commands/WhoisCommand.java
Normale Datei
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.commands;
|
||||
|
||||
import de.steamwar.bungeecore.sql.Punishment;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.bungeecore.sql.Team;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.List;
|
||||
|
||||
public class WhoisCommand extends BasicDiscordCommand {
|
||||
|
||||
public WhoisCommand() {
|
||||
super("whois", "Der whois Befehl");
|
||||
|
||||
addOption(OptionType.STRING, "user", "Der Benutzer", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(SlashCommandEvent event) {
|
||||
if (!testPermission(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String s = event.getOption("user").getAsString();
|
||||
|
||||
SteamwarUser user = SteamwarUser.get(s);
|
||||
if (user == null) {
|
||||
try {
|
||||
int id = Integer.parseInt(s);
|
||||
user = SteamwarUser.get(id);
|
||||
} catch (NumberFormatException ignored) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
if (user == null) {
|
||||
try {
|
||||
long id = Long.parseLong(s);
|
||||
user = SteamwarUser.get(id);
|
||||
} catch (NumberFormatException ignored) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
|
||||
if (user == null) {
|
||||
event.reply("Der angegebene Spieler ist unbekannt").setEphemeral(true).complete();
|
||||
return;
|
||||
}
|
||||
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||
embedBuilder.setTitle("Whois: " + user.getUserName());
|
||||
StringBuilder st = new StringBuilder();
|
||||
st.append("UUID: ").append(user.getUuid()).append("\n");
|
||||
st.append("ID: ").append(user.getId()).append("\n");
|
||||
if (user.getDiscordId() != null) {
|
||||
st.append("DiscordID: ").append(user.getDiscordId()).append("\n");
|
||||
}
|
||||
Timestamp timestamp = user.getFirstjoin();
|
||||
st.append("Beigetreten am: ").append(timestamp == null ? "0000-00-00 00:00:00" : timestamp.toString()).append("\n");
|
||||
st.append("Online Time: ").append(new DecimalFormat("###.##").format(user.getOnlinetime() / (double) 3600)).append("h\n");
|
||||
Team team = Team.get(user.getTeam());
|
||||
st.append("Team: [").append(team.getTeamKuerzel()).append("] ").append(team.getTeamName());
|
||||
embedBuilder.addField("Daten:", st.toString(), false);
|
||||
|
||||
List<Punishment> 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();
|
||||
}
|
||||
}
|
39
src/de/steamwar/bungeecore/bot/config/DiscordRole.java
Normale Datei
39
src/de/steamwar/bungeecore/bot/config/DiscordRole.java
Normale Datei
@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
36
src/de/steamwar/bungeecore/bot/config/DiscordRulesLink.java
Normale Datei
36
src/de/steamwar/bungeecore/bot/config/DiscordRulesLink.java
Normale Datei
@ -0,0 +1,36 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
41
src/de/steamwar/bungeecore/bot/config/DiscordTicketType.java
Normale Datei
41
src/de/steamwar/bungeecore/bot/config/DiscordTicketType.java
Normale Datei
@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
116
src/de/steamwar/bungeecore/bot/config/SteamwarDiscordBotConfig.java
Normale Datei
116
src/de/steamwar/bungeecore/bot/config/SteamwarDiscordBotConfig.java
Normale Datei
@ -0,0 +1,116 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.config;
|
||||
|
||||
import de.steamwar.bungeecore.sql.UserGroup;
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SteamwarDiscordBotConfig {
|
||||
|
||||
public static 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<DiscordRole> ROLES;
|
||||
public static String RULES_CHANNEL;
|
||||
public static String RULES_TITLE;
|
||||
public static List<String> RULES_RULES;
|
||||
public static List<DiscordRulesLink> 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<String, DiscordTicketType> TICKET_TYPES;
|
||||
public static Map<UserGroup, String> RANKS;
|
||||
|
||||
public static void loadConfig(Configuration config) {
|
||||
TOKEN = config.getString("token");
|
||||
GUILD = config.getString("guild");
|
||||
ANNOUNCEMENTS_CHANNEL = config.getString("announcements-channel");
|
||||
EVENTS_CHANNEL = config.getString("events-channel");
|
||||
INGAME_CHANNEL = config.getString("ingame-channel");
|
||||
SERVER_TEAM_CHANNEL = config.getString("server-team-channel");
|
||||
SCHEMATICS_CHANNEL = config.getString("schematics-channel");
|
||||
Configuration rolesSection = config.getSection("roles-claim");
|
||||
ROLES_CHANNEL = rolesSection.getString("channel");
|
||||
ROLES_BASE_MESSAGE = rolesSection.getString("base");
|
||||
ROLES_ADDED = rolesSection.getString("added");
|
||||
ROLES_REMOVED = rolesSection.getString("removed");
|
||||
ROLES = new ArrayList<>();
|
||||
|
||||
for (String roles : rolesSection.getSection("roles").getKeys()) {
|
||||
Configuration role = rolesSection.getSection("roles").getSection(roles);
|
||||
ROLES.add(new DiscordRole(role.getString("emoji"),
|
||||
role.getString("label"),
|
||||
role.getString("roleId")));
|
||||
}
|
||||
|
||||
Configuration rulesSection = config.getSection("rules");
|
||||
RULES_CHANNEL = rulesSection.getString("channel");
|
||||
RULES_TITLE = rulesSection.getString("title");
|
||||
RULES_RULES = rulesSection.getStringList("rules");
|
||||
|
||||
RULES_LINKS = new ArrayList<>();
|
||||
|
||||
for (String links : rulesSection.getSection("links").getKeys()) {
|
||||
Configuration link = rulesSection.getSection("links").getSection(links);
|
||||
RULES_LINKS.add(new DiscordRulesLink(link.getString("label"),
|
||||
link.getString("url")));
|
||||
}
|
||||
|
||||
Configuration ticketSection = config.getSection("tickets");
|
||||
TICKET_CATEGORY = ticketSection.getString("category");
|
||||
TICKET_CHANNEL = ticketSection.getString("channel");
|
||||
TICKET_MESSAGE = ticketSection.getString("message");
|
||||
TICKET_CREATED = ticketSection.getString("created");
|
||||
TICKET_LOG = ticketSection.getString("log");
|
||||
TICKET_TYPES = new HashMap<>();
|
||||
|
||||
for (String types : ticketSection.getSection("types").getKeys()) {
|
||||
Configuration type = ticketSection.getSection("types").getSection(types);
|
||||
TICKET_TYPES.put(types, new DiscordTicketType(types,
|
||||
type.getString("emoji"),
|
||||
type.getString("label"),
|
||||
type.getString("color"),
|
||||
type.getString("pre")));
|
||||
}
|
||||
|
||||
RANKS = new HashMap<>();
|
||||
Configuration ranksSections = config.getSection("ranks");
|
||||
for (String type : ranksSections.getKeys()) {
|
||||
RANKS.put(UserGroup.getUsergroup(type), ranksSections.getString(type));
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
}
|
@ -17,16 +17,20 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.velocitycore.discord.channels;
|
||||
package de.steamwar.bungeecore.bot.events;
|
||||
|
||||
import de.steamwar.sql.Event;
|
||||
import de.steamwar.sql.EventFight;
|
||||
import de.steamwar.sql.Team;
|
||||
import de.steamwar.sql.TeamTeilnahme;
|
||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
import de.steamwar.bungeecore.sql.Event;
|
||||
import de.steamwar.bungeecore.sql.EventFight;
|
||||
import de.steamwar.bungeecore.sql.Team;
|
||||
import de.steamwar.bungeecore.sql.TeamTeilnahme;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.MessageBuilder;
|
||||
import net.dv8tion.jda.api.entities.Emoji;
|
||||
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.selections.SelectionMenu;
|
||||
|
||||
@ -38,28 +42,38 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@UtilityClass
|
||||
public class EventChannel {
|
||||
public class EventManager {
|
||||
|
||||
public MessageBuilder get() {
|
||||
if (Event.get() == null)
|
||||
return updateComing();
|
||||
private Message message;
|
||||
private TextChannel textChannel;
|
||||
|
||||
return updateCurrent();
|
||||
static {
|
||||
textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.EVENTS_CHANNEL);
|
||||
assert textChannel != null;
|
||||
if(textChannel.hasLatestMessage()) {
|
||||
message = textChannel.getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
private MessageBuilder updateComing() {
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder()
|
||||
.setColor(Color.GRAY)
|
||||
.setTitle("Zukünftige Events")
|
||||
.setAuthor("SteamWar", "https://www.steamwar.de");
|
||||
public void update() {
|
||||
if (Event.get() == null) {
|
||||
updateComing();
|
||||
} else {
|
||||
updateCurrent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SelectionMenu.Builder menuBuilder = SelectionMenu.create("eventName")
|
||||
.setPlaceholder("Wähle ein Event aus!")
|
||||
.setMinValues(1)
|
||||
.setMaxValues(1);
|
||||
private void updateComing() {
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||
embedBuilder.setColor(Color.GRAY);
|
||||
embedBuilder.setTitle("Zukünftige Events");
|
||||
embedBuilder.setAuthor("SteamWar", "https://www.steamwar.de");
|
||||
|
||||
Timestamp now = Timestamp.from(Instant.now());
|
||||
SelectionMenu.Builder menuBuilder = SelectionMenu.create("eventName");
|
||||
menuBuilder.setPlaceholder("Wähle ein Event aus!")
|
||||
.setMinValues(1)
|
||||
.setMaxValues(1);
|
||||
List<Event> events = Event.getComing();
|
||||
events.forEach(event -> {
|
||||
StringBuilder st = new StringBuilder();
|
||||
@ -77,21 +91,25 @@ public class EventChannel {
|
||||
}
|
||||
});
|
||||
|
||||
MessageBuilder messageBuilder = new MessageBuilder()
|
||||
.setEmbeds(embedBuilder.build());
|
||||
|
||||
MessageBuilder messageBuilder = new MessageBuilder();
|
||||
messageBuilder.setEmbeds(embedBuilder.build());
|
||||
if(events.stream().anyMatch(event -> event.getDeadline().after(Timestamp.from(Instant.now())))) {
|
||||
messageBuilder.setActionRows(ActionRow.of(menuBuilder.build()));
|
||||
}
|
||||
return messageBuilder;
|
||||
if (message == null) {
|
||||
message = textChannel.sendMessage(messageBuilder.build()).complete();
|
||||
} else {
|
||||
message.editMessage(messageBuilder.build()).complete();
|
||||
}
|
||||
}
|
||||
|
||||
private MessageBuilder updateCurrent() {
|
||||
private void updateCurrent() {
|
||||
Event event = Event.get();
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder()
|
||||
.setColor(Color.GRAY)
|
||||
.setTitle("Event: " + event.getEventName())
|
||||
.setAuthor("SteamWar", "https://www.steamwar.de");
|
||||
if (event == null) return;
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||
embedBuilder.setColor(Color.GRAY);
|
||||
embedBuilder.setTitle("Event: " + event.getEventName());
|
||||
embedBuilder.setAuthor("SteamWar", "https://www.steamwar.de");
|
||||
|
||||
Instant now = Instant.now();
|
||||
EventFight.getEvent(event.getEventID()).forEach(eventFight -> {
|
||||
@ -113,7 +131,13 @@ public class EventChannel {
|
||||
embedBuilder.addField(teamBlue.getTeamKuerzel() + " vs. " + teamRed.getTeamKuerzel(), st.toString(), true);
|
||||
});
|
||||
|
||||
return StaticMessageChannel.toMessageBuilder(embedBuilder);
|
||||
MessageBuilder messageBuilder = new MessageBuilder();
|
||||
messageBuilder.setEmbeds(embedBuilder.build());
|
||||
if (message == null) {
|
||||
textChannel.sendMessage(messageBuilder.build()).queue(message1 -> message = message1);
|
||||
} else {
|
||||
message.editMessage(messageBuilder.build()).complete();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
73
src/de/steamwar/bungeecore/bot/events/SchematicsManager.java
Normale Datei
73
src/de/steamwar/bungeecore/bot/events/SchematicsManager.java
Normale Datei
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.events;
|
||||
|
||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
import de.steamwar.bungeecore.commands.CheckCommand;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.MessageBuilder;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.entities.TextChannel;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@UtilityClass
|
||||
public class SchematicsManager {
|
||||
|
||||
private Message message;
|
||||
private TextChannel textChannel;
|
||||
|
||||
static {
|
||||
textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.SCHEMATICS_CHANNEL);
|
||||
assert textChannel != null;
|
||||
if(textChannel.hasLatestMessage()) {
|
||||
message = textChannel.getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||
embedBuilder.setColor(Color.GRAY);
|
||||
embedBuilder.setTitle("Check List");
|
||||
embedBuilder.setAuthor("SteamWar", "https://www.steamwar.de");
|
||||
|
||||
CheckCommand.getSchemsToCheck().forEach(schematic -> {
|
||||
StringBuilder st = new StringBuilder();
|
||||
st.append("Typ: ").append(schematic.getSchemtype().getKuerzel());
|
||||
st.append("\nVon: ").append(SteamwarUser.get(schematic.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();
|
||||
}
|
||||
}
|
||||
}
|
50
src/de/steamwar/bungeecore/bot/listeners/AnnouncementListener.java
Normale Datei
50
src/de/steamwar/bungeecore/bot/listeners/AnnouncementListener.java
Normale Datei
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
30
src/de/steamwar/bungeecore/bot/listeners/BasicDiscordListener.java
Normale Datei
30
src/de/steamwar/bungeecore/bot/listeners/BasicDiscordListener.java
Normale Datei
@ -0,0 +1,30 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.listeners;
|
||||
|
||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
|
||||
public abstract class BasicDiscordListener extends ListenerAdapter {
|
||||
|
||||
BasicDiscordListener() {
|
||||
SteamwarDiscordBot.instance().addListener(this);
|
||||
}
|
||||
}
|
59
src/de/steamwar/bungeecore/bot/listeners/DiscordAuthListener.java
Normale Datei
59
src/de/steamwar/bungeecore/bot/listeners/DiscordAuthListener.java
Normale Datei
@ -0,0 +1,59 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.listeners;
|
||||
|
||||
import de.steamwar.bungeecore.bot.AuthManager;
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.dv8tion.jda.api.entities.ChannelType;
|
||||
import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent;
|
||||
import net.dv8tion.jda.api.interactions.InteractionType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DiscordAuthListener extends BasicDiscordListener {
|
||||
|
||||
@Override
|
||||
public void onGenericComponentInteractionCreate(@NotNull GenericComponentInteractionCreateEvent event) {
|
||||
if(event.getType() == InteractionType.COMPONENT) {
|
||||
if(event.getChannel().getId().equals(SteamwarDiscordBotConfig.RULES_CHANNEL) && event.getComponentId().equals("auth")) {
|
||||
String authMessage = AuthManager.createDiscordAuthToken(event.getMember());
|
||||
if(authMessage != null) {
|
||||
event.reply("Gebe innerhalb der nächsten 10 Minuten ``/verify " + authMessage + "`` auf dem Minecraft Server ein").setEphemeral(true).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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
71
src/de/steamwar/bungeecore/bot/listeners/DiscordChatListener.java
Normale Datei
71
src/de/steamwar/bungeecore/bot/listeners/DiscordChatListener.java
Normale Datei
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.listeners;
|
||||
|
||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
import de.steamwar.bungeecore.listeners.ChatListener;
|
||||
import de.steamwar.bungeecore.sql.Punishment;
|
||||
import de.steamwar.bungeecore.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<Stream<ChatSender>> targets;
|
||||
|
||||
public DiscordChatListener(String channel, String format, Supplier<Stream<ChatSender>> 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();
|
||||
}
|
||||
}
|
93
src/de/steamwar/bungeecore/bot/listeners/DiscordEventListener.java
Normale Datei
93
src/de/steamwar/bungeecore/bot/listeners/DiscordEventListener.java
Normale Datei
@ -0,0 +1,93 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.listeners;
|
||||
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
import de.steamwar.bungeecore.bot.events.EventManager;
|
||||
import de.steamwar.bungeecore.sql.Event;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.bungeecore.sql.Team;
|
||||
import de.steamwar.bungeecore.sql.TeamTeilnahme;
|
||||
import net.dv8tion.jda.api.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
156
src/de/steamwar/bungeecore/bot/listeners/DiscordTicketListener.java
Normale Datei
156
src/de/steamwar/bungeecore/bot/listeners/DiscordTicketListener.java
Normale Datei
@ -0,0 +1,156 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.listeners;
|
||||
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.bot.config.DiscordTicketType;
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.MessageBuilder;
|
||||
import net.dv8tion.jda.api.Permission;
|
||||
import net.dv8tion.jda.api.entities.*;
|
||||
import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent;
|
||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
|
||||
import net.dv8tion.jda.api.interactions.InteractionType;
|
||||
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||
import net.dv8tion.jda.api.interactions.components.Button;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.time.Instant;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class DiscordTicketListener extends BasicDiscordListener {
|
||||
|
||||
@Override
|
||||
public void onGenericComponentInteractionCreate(@NotNull GenericComponentInteractionCreateEvent event) {
|
||||
if(event.getType() == InteractionType.COMPONENT && event.getChannelType() == ChannelType.TEXT && event.getTextChannel().getParent() != null && event.getTextChannel().getParent().getId().equals(SteamwarDiscordBotConfig.TICKET_CATEGORY)) {
|
||||
if(event.getTextChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_CHANNEL) && SteamwarDiscordBotConfig.TICKET_TYPES.containsKey(event.getComponentId())) {
|
||||
DiscordTicketType ticketType = SteamwarDiscordBotConfig.TICKET_TYPES.get(event.getComponentId());
|
||||
Category ct = event.getGuild().getCategoryById(SteamwarDiscordBotConfig.TICKET_CATEGORY);
|
||||
SteamwarUser swUser = SteamwarUser.get(event.getUser().getIdLong());
|
||||
TextChannel ticketChannel = ct.createTextChannel((swUser == null?event.getUser().getName():swUser.getUserName()) + "-" + event.getComponentId() + "-" + System.currentTimeMillis() % 1000).complete();
|
||||
ticketChannel.createPermissionOverride(event.getMember()).setAllow(Permission.VIEW_CHANNEL,
|
||||
Permission.MESSAGE_WRITE,
|
||||
Permission.MESSAGE_ATTACH_FILES,
|
||||
Permission.MESSAGE_ADD_REACTION,
|
||||
Permission.MESSAGE_READ,
|
||||
Permission.MESSAGE_EMBED_LINKS,
|
||||
Permission.MESSAGE_HISTORY).complete();
|
||||
ticketChannel.getManager().setTopic(event.getUser().getId()).complete();
|
||||
|
||||
MessageBuilder messageBuilder = new MessageBuilder();
|
||||
EmbedBuilder builder = new EmbedBuilder();
|
||||
builder.setDescription(ticketType.getPreMessage());
|
||||
builder.setTitle("Steamwar Ticket");
|
||||
builder.setColor(Color.GREEN);
|
||||
|
||||
Button closeButton = Button.danger("close-" + ticketChannel.getName(), "Schließen").withEmoji(Emoji.fromUnicode("U+26A0"));
|
||||
messageBuilder.setEmbeds(builder.build());
|
||||
messageBuilder.setActionRows(ActionRow.of(closeButton));
|
||||
|
||||
ticketChannel.sendMessage(messageBuilder.build()).complete();
|
||||
event.reply(SteamwarDiscordBotConfig.TICKET_CREATED.replace("%channel%", ticketChannel.getAsMention())).setEphemeral(true).complete();
|
||||
Message.team("DISCORD_TICKET_NEW", ticketChannel.getName());
|
||||
} else if(event.getComponentId().startsWith("close-")) {
|
||||
TextChannel logChannel = event.getGuild().getTextChannelById(SteamwarDiscordBotConfig.TICKET_LOG);
|
||||
|
||||
LinkedList<StringBuilder> 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("<t:").append(message.getTimeCreated().toInstant().getEpochSecond()).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 = "<t:" + Instant.now().getEpochSecond() + "> **" + 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);
|
||||
boolean sendMessage;
|
||||
if(user.getDiscordId() == null) {
|
||||
sendMessage = user.getUserGroup().isCheckSchematics();
|
||||
} else {
|
||||
if(event.getAuthor().getId().equals(user.getDiscordId())) return;
|
||||
sendMessage = user.getDiscordId().equals(event.getChannel().getTopic()) || user.getUserGroup().isCheckSchematics();
|
||||
}
|
||||
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());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
75
src/de/steamwar/bungeecore/bot/listeners/PrivateMessageListener.java
Normale Datei
75
src/de/steamwar/bungeecore/bot/listeners/PrivateMessageListener.java
Normale Datei
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* 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.
|
||||
* <p>
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.listeners;
|
||||
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
import de.steamwar.bungeecore.sql.Punishment;
|
||||
import de.steamwar.bungeecore.sql.SchematicNode;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.dv8tion.jda.api.entities.Message;
|
||||
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent;
|
||||
|
||||
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, 0);
|
||||
if(node == null) {
|
||||
node = SchematicNode.createSchematic(user.getId(), name, null);
|
||||
}
|
||||
|
||||
try {
|
||||
node.saveFromStream(attachment.retrieveInputStream().get(), newFormat);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is a part of the SteamWar software.
|
||||
*
|
||||
* Copyright (C) 2023 SteamWar.de-Serverteam
|
||||
* 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
|
||||
@ -17,21 +17,16 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.sql;
|
||||
package de.steamwar.bungeecore.bot.listeners;
|
||||
|
||||
import de.steamwar.velocitycore.VelocityCore;
|
||||
import de.steamwar.sql.internal.SQLConfig;
|
||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class SQLConfigImpl implements SQLConfig {
|
||||
@Override
|
||||
public Logger getLogger() {
|
||||
return VelocityCore.getLogger();
|
||||
}
|
||||
public class SlashCommandListener extends BasicDiscordListener {
|
||||
|
||||
@Override
|
||||
public int maxConnections() {
|
||||
return 4;
|
||||
public void onSlashCommand(@NotNull SlashCommandEvent event) {
|
||||
SteamwarDiscordBot.getDiscordCommandMap().get(event.getName()).run(event);
|
||||
}
|
||||
}
|
69
src/de/steamwar/bungeecore/bot/util/DiscordRanks.java
Normale Datei
69
src/de/steamwar/bungeecore/bot/util/DiscordRanks.java
Normale Datei
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.util;
|
||||
|
||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import 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<Role> roleList = member.getRoles();
|
||||
Set<String> strings = new HashSet<>(SteamwarDiscordBotConfig.RANKS.values());
|
||||
String needed = SteamwarDiscordBotConfig.RANKS.get(steamwarUser.getUserGroup());
|
||||
for (Role role : roleList) {
|
||||
if (!strings.contains(role.getId())) {
|
||||
continue;
|
||||
}
|
||||
if (role.getId().equals(needed)) {
|
||||
needed = "";
|
||||
continue;
|
||||
}
|
||||
guild.removeRoleFromMember(member, role).complete();
|
||||
}
|
||||
|
||||
if (needed != null && !needed.isEmpty()) {
|
||||
guild.addRoleToMember(member, guild.getRoleById(needed)).complete();
|
||||
}
|
||||
}, throwable -> {
|
||||
if(throwable instanceof ErrorResponseException) {
|
||||
ErrorResponseException e = (ErrorResponseException) throwable;
|
||||
if(e.getErrorCode() == 10007) {
|
||||
steamwarUser.setDiscordId(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
61
src/de/steamwar/bungeecore/bot/util/DiscordRolesMessage.java
Normale Datei
61
src/de/steamwar/bungeecore/bot/util/DiscordRolesMessage.java
Normale Datei
@ -0,0 +1,61 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<Button> buttons = new ArrayList<>();
|
||||
SteamwarDiscordBotConfig.ROLES.forEach(discordRole -> buttons.add(discordRole.toButton()));
|
||||
builder.setActionRows(ActionRow.of(buttons));
|
||||
|
||||
if(channel.hasLatestMessage()) {
|
||||
channel.getIterableHistory().queue(messages -> {
|
||||
Message message = messages.stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
|
||||
if (message != null) {
|
||||
message.editMessage(builder.build()).queue();
|
||||
} else {
|
||||
channel.sendMessage(builder.build()).queue();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel.sendMessage(builder.build()).queue();
|
||||
}
|
||||
}
|
||||
}
|
68
src/de/steamwar/bungeecore/bot/util/DiscordRulesMessage.java
Normale Datei
68
src/de/steamwar/bungeecore/bot/util/DiscordRulesMessage.java
Normale Datei
@ -0,0 +1,68 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.MessageBuilder;
|
||||
import net.dv8tion.jda.api.entities.Emoji;
|
||||
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.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@UtilityClass
|
||||
public class DiscordRulesMessage {
|
||||
|
||||
public void sendMessage() {
|
||||
TextChannel channel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.RULES_CHANNEL);
|
||||
assert channel != null;
|
||||
Message message = null;
|
||||
if(channel.hasLatestMessage()) {
|
||||
message = channel.getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
EmbedBuilder builder = new EmbedBuilder();
|
||||
builder.setDescription(SteamwarDiscordBotConfig.RULES_RULES.stream().reduce((s, s2) -> s + "\n" + s2).get());
|
||||
builder.setColor(Color.GRAY);
|
||||
builder.setAuthor("SteamWar", "https://www.steamwar.de");
|
||||
builder.setTitle(SteamwarDiscordBotConfig.RULES_TITLE);
|
||||
|
||||
List<Button> buttons = new ArrayList<>();
|
||||
SteamwarDiscordBotConfig.RULES_LINKS.forEach(discordRulesLink -> buttons.add(discordRulesLink.toButton()));
|
||||
|
||||
Button authButton = Button.primary("auth", Emoji.fromUnicode("U+2705")).withLabel("Minecraft verknüpfen");
|
||||
|
||||
MessageBuilder messageBuilder = new MessageBuilder();
|
||||
messageBuilder.setEmbeds(builder.build());
|
||||
messageBuilder.setActionRows(ActionRow.of(buttons), ActionRow.of(authButton));
|
||||
if (message != null) {
|
||||
message.editMessage(messageBuilder.build()).queue();
|
||||
} else {
|
||||
channel.sendMessage(messageBuilder.build()).queue();
|
||||
}
|
||||
}
|
||||
}
|
79
src/de/steamwar/bungeecore/bot/util/DiscordSchemAlert.java
Normale Datei
79
src/de/steamwar/bungeecore/bot/util/DiscordSchemAlert.java
Normale Datei
@ -0,0 +1,79 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.util;
|
||||
|
||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||
import de.steamwar.bungeecore.sql.SchematicNode;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.MessageBuilder;
|
||||
import net.dv8tion.jda.api.entities.Emoji;
|
||||
import net.dv8tion.jda.api.entities.User;
|
||||
import net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||
import net.dv8tion.jda.api.interactions.components.Button;
|
||||
|
||||
import java.awt.*;
|
||||
import java.time.Instant;
|
||||
|
||||
@UtilityClass
|
||||
public class DiscordSchemAlert {
|
||||
|
||||
public void sendDecline(SchematicNode schematic, SteamwarUser user, String reason) {
|
||||
if(user.getDiscordId() != null) {
|
||||
User dcUser = SteamwarDiscordBot.instance().getJda().retrieveUserById(user.getDiscordId()).complete();
|
||||
EmbedBuilder builder = new EmbedBuilder();
|
||||
builder.setAuthor("SteamWar", "https://steamwar.de", "https://cdn.discordapp.com/app-icons/869606970099904562/60c884000407c02671d91d8e7182b8a1.png");
|
||||
builder.setColor(Color.RED);
|
||||
builder.setTitle("SteamWar-Schematic Info");
|
||||
builder.setDescription("Deine Schematic **" + schematic.getName() + "** wurde abgelehnt. **Grund:** \n" + reason);
|
||||
builder.setTimestamp(Instant.now());
|
||||
|
||||
MessageBuilder messageBuilder = new MessageBuilder();
|
||||
messageBuilder.setEmbeds(builder.build());
|
||||
try {
|
||||
dcUser.openPrivateChannel().complete().sendMessage(messageBuilder.build()).queue();
|
||||
} catch (Exception e) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendAccept(SchematicNode schematic, SteamwarUser user) {
|
||||
if(user.getDiscordId() != null) {
|
||||
User dcUser = SteamwarDiscordBot.instance().getJda().retrieveUserById(user.getDiscordId()).complete();
|
||||
EmbedBuilder builder = new EmbedBuilder();
|
||||
builder.setAuthor("SteamWar", "https://steamwar.de", "https://cdn.discordapp.com/app-icons/869606970099904562/60c884000407c02671d91d8e7182b8a1.png");
|
||||
builder.setColor(Color.GREEN);
|
||||
builder.setTitle("SteamWar-Schematic Info");
|
||||
builder.setDescription("Deine Schematic **" + schematic.getName() + "** wurde angenommen.");
|
||||
builder.setTimestamp(Instant.now());
|
||||
|
||||
MessageBuilder messageBuilder = new MessageBuilder();
|
||||
messageBuilder.setEmbeds(builder.build());
|
||||
messageBuilder.setActionRows(ActionRow.of(Button.success("tada", Emoji.fromUnicode("U+1F389"))));
|
||||
try {
|
||||
dcUser.openPrivateChannel().complete().sendMessage(messageBuilder.build()).queue();
|
||||
} catch (Exception e) {
|
||||
// Ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
76
src/de/steamwar/bungeecore/bot/util/DiscordTicketMessage.java
Normale Datei
76
src/de/steamwar/bungeecore/bot/util/DiscordTicketMessage.java
Normale Datei
@ -0,0 +1,76 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.bot.util;
|
||||
|
||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||
import de.steamwar.bungeecore.bot.config.DiscordTicketType;
|
||||
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
||||
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 net.dv8tion.jda.api.interactions.components.ActionRow;
|
||||
import net.dv8tion.jda.api.interactions.components.Button;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@UtilityClass
|
||||
public class DiscordTicketMessage {
|
||||
|
||||
public void sendMessage() {
|
||||
TextChannel channel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.TICKET_CHANNEL);
|
||||
assert channel != null;
|
||||
Message message = null;
|
||||
if(channel.hasLatestMessage()) {
|
||||
message = channel.getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
EmbedBuilder builder = new EmbedBuilder();
|
||||
builder.setDescription(SteamwarDiscordBotConfig.TICKET_MESSAGE);
|
||||
builder.setTitle("Steamwar-Tickets");
|
||||
builder.setColor(Color.RED);
|
||||
|
||||
List<List<Button>> buttons = new ArrayList<>();
|
||||
chunked(new ArrayList<>(SteamwarDiscordBotConfig.TICKET_TYPES.values()), 5).forEach(discordTicketTypes -> {
|
||||
buttons.add(discordTicketTypes.stream().map(DiscordTicketType::toButton).collect(Collectors.toList()));
|
||||
});
|
||||
|
||||
MessageBuilder messageBuilder = new MessageBuilder();
|
||||
messageBuilder.setEmbeds(builder.build());
|
||||
messageBuilder.setActionRows(buttons.stream().map(ActionRow::of).collect(Collectors.toList()));
|
||||
if (message != null) {
|
||||
message.editMessage(messageBuilder.build()).queue();
|
||||
} else {
|
||||
channel.sendMessage(messageBuilder.build()).queue();
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> List<List<T>> chunked(List<T> list, int chunkSize) {
|
||||
List<List<T>> chunks = new ArrayList<>();
|
||||
for (int i = 0; i < list.size(); i += chunkSize) {
|
||||
chunks.add(list.subList(i, Math.min(i + chunkSize, list.size())));
|
||||
}
|
||||
return chunks;
|
||||
}
|
||||
}
|
69
src/de/steamwar/bungeecore/commands/AlertCommand.java
Normale Datei
69
src/de/steamwar/bungeecore/commands/AlertCommand.java
Normale Datei
@ -0,0 +1,69 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
|
||||
public class AlertCommand extends BasicCommand {
|
||||
|
||||
public AlertCommand() {
|
||||
super("alert", "bungeecore.alert", "broadcast", "bbc");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(args.length == 0){
|
||||
Message.send("USAGE_ALERT", sender);
|
||||
return;
|
||||
}
|
||||
|
||||
String s;
|
||||
boolean discordAnnounce = false;
|
||||
if (args[0].equals("-discord")) {
|
||||
if (args.length == 1) {
|
||||
Message.send("USAGE_ALERT", sender);
|
||||
return;
|
||||
}
|
||||
discordAnnounce = true;
|
||||
s = join(1, args);
|
||||
} else {
|
||||
s = join(0, args);
|
||||
}
|
||||
|
||||
Message.broadcast("ALERT", ChatColor.translateAlternateColorCodes('&', s));
|
||||
if (discordAnnounce && SteamwarDiscordBot.instance() != null) {
|
||||
SteamwarDiscordBot.instance().getAnnouncementListener().announce(s);
|
||||
}
|
||||
}
|
||||
|
||||
private String join(int startIndex, String... strings) {
|
||||
StringBuilder st = new StringBuilder();
|
||||
for (int i = startIndex; i < strings.length; i++) {
|
||||
if (i != startIndex) {
|
||||
st.append(" ");
|
||||
}
|
||||
st.append(strings[i]);
|
||||
}
|
||||
return st.toString();
|
||||
}
|
||||
}
|
51
src/de/steamwar/bungeecore/commands/ArenaCommand.java
Normale Datei
51
src/de/steamwar/bungeecore/commands/ArenaCommand.java
Normale Datei
@ -0,0 +1,51 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.Servertype;
|
||||
import de.steamwar.bungeecore.Subserver;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public class ArenaCommand extends BasicCommand {
|
||||
|
||||
public ArenaCommand() {
|
||||
super("arena", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
|
||||
ServerInfo server = ProxyServer.getInstance().getServerInfo(String.join(" ", args));
|
||||
Subserver subserver = Subserver.getSubserver(server);
|
||||
if(server == null || subserver == null || subserver.getType() != Servertype.ARENA) {
|
||||
Message.send("ARENA_NOT_FOUND", player);
|
||||
return;
|
||||
}
|
||||
|
||||
TpCommand.teleport(player, server);
|
||||
}
|
||||
}
|
69
src/de/steamwar/bungeecore/commands/BasicCommand.java
Normale Datei
69
src/de/steamwar/bungeecore/commands/BasicCommand.java
Normale Datei
@ -0,0 +1,69 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Command;
|
||||
import net.md_5.bungee.api.plugin.TabExecutor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
abstract class BasicCommand extends Command implements TabExecutor {
|
||||
|
||||
public BasicCommand(String name, String permission, String... aliases) {
|
||||
super(name, permission, aliases);
|
||||
BungeeCore.commands.put("/" + name, permission);
|
||||
ProxyServer.getInstance().getPluginManager().registerCommand(BungeeCore.get(), this);
|
||||
}
|
||||
|
||||
Iterable<String> allPlayers(String begin) {
|
||||
List<String> suggestions = new ArrayList<>();
|
||||
for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()){
|
||||
String playerName = player.getName();
|
||||
if(playerName.startsWith(begin))
|
||||
suggestions.add(playerName);
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
protected SteamwarUser existingUser(CommandSender sender, String arg){
|
||||
SteamwarUser target = SteamwarUser.get(arg);
|
||||
if(target == null)
|
||||
Message.send("UNKNOWN_PLAYER", sender);
|
||||
return target;
|
||||
}
|
||||
|
||||
protected SteamwarUser unsafeUser(CommandSender sender, String arg){
|
||||
SteamwarUser target = SteamwarUser.getOrCreateOfflinePlayer(arg);
|
||||
if(target == null)
|
||||
Message.send("UNKNOWN_PLAYER", sender);
|
||||
return target;
|
||||
}
|
||||
}
|
305
src/de/steamwar/bungeecore/commands/BauCommand.java
Normale Datei
305
src/de/steamwar/bungeecore/commands/BauCommand.java
Normale Datei
@ -0,0 +1,305 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.*;
|
||||
import de.steamwar.bungeecore.comms.packets.BaumemberUpdatePacket;
|
||||
import de.steamwar.bungeecore.inventory.SWInventory;
|
||||
import de.steamwar.bungeecore.inventory.SWItem;
|
||||
import de.steamwar.bungeecore.sql.BauweltMember;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.messages.ChatSender;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public class BauCommand extends BasicCommand {
|
||||
|
||||
public BauCommand(){
|
||||
super("bau", null, "b", "build", "gs");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
||||
|
||||
versionSelector(p, args, 0,
|
||||
() -> new ServerStarter().build18(p.getUniqueId()).send(p).start(),
|
||||
() -> new ServerStarter().build15(p.getUniqueId()).send(p).start(),
|
||||
() -> new ServerStarter().build12(p.getUniqueId()).send(p).start(),
|
||||
() -> {
|
||||
switch (args[0].toLowerCase()) {
|
||||
case "addmember":
|
||||
addmember(p, args);
|
||||
break;
|
||||
case "tp":
|
||||
case "teleport":
|
||||
teleport(p, args);
|
||||
break;
|
||||
case "info":
|
||||
p.chat("/bauinfo");
|
||||
break;
|
||||
case "togglewe":
|
||||
togglewe(p, args);
|
||||
break;
|
||||
case "toggleworld":
|
||||
toggleworld(p, args);
|
||||
break;
|
||||
case "delmember":
|
||||
delmember(p, args);
|
||||
break;
|
||||
case "resetall":
|
||||
case "delete":
|
||||
delete(p, args);
|
||||
break;
|
||||
case "testarena":
|
||||
case "test":
|
||||
testarena(p, args);
|
||||
break;
|
||||
default:
|
||||
HelpCommand.sendBauHelp(ChatSender.of(p));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private static void addmember(ProxiedPlayer p, String[] args){
|
||||
if (args.length == 1) {
|
||||
Message.send("BAU_ADDMEMBER_USAGE", p);
|
||||
return;
|
||||
}
|
||||
|
||||
SteamwarUser target = SteamwarUser.get(args[1]);
|
||||
if (target == null) {
|
||||
Message.send("UNKNOWN_PLAYER", p);
|
||||
return;
|
||||
}else if(target.getUuid().equals(p.getUniqueId())) {
|
||||
Message.send("BAU_ADDMEMBER_SELFADD", p);
|
||||
return;
|
||||
}else if (BauweltMember.getBauMember(p.getUniqueId(), target.getUuid()) != null) {
|
||||
Message.send("BAU_ADDMEMBER_ISADDED", p);
|
||||
return;
|
||||
}
|
||||
|
||||
new BauweltMember(p.getUniqueId(), target.getUuid(), false, false);
|
||||
Message.send("BAU_ADDMEMBER_ADDED", p);
|
||||
|
||||
ProxiedPlayer z = ProxyServer.getInstance().getPlayer(target.getUuid());
|
||||
if(z != null)
|
||||
Message.send("BAU_ADDMEMBER_ADDED_TARGET", z, p.getName());
|
||||
}
|
||||
|
||||
private static void teleport(ProxiedPlayer p, String[] args){
|
||||
if (args.length == 1) {
|
||||
Message.send("BAU_TP_USAGE", p);
|
||||
return;
|
||||
}
|
||||
|
||||
SteamwarUser worldOwner = SteamwarUser.get(args[1]);
|
||||
if (worldOwner == null) {
|
||||
Message.send("UNKNOWN_PLAYER", p);
|
||||
return;
|
||||
}else if (!p.getUniqueId().equals(worldOwner.getUuid()) && BauweltMember.getBauMember(worldOwner.getUuid(), p.getUniqueId()) == null){
|
||||
SubserverSystem.sendDeniedMessage(p, worldOwner.getUuid());
|
||||
Message.send("BAU_TP_NOALLOWED", p);
|
||||
return;
|
||||
}
|
||||
|
||||
versionSelector(p, args, 2,
|
||||
() -> new ServerStarter().build18(worldOwner.getUuid()).send(p).start(),
|
||||
() -> new ServerStarter().build15(worldOwner.getUuid()).send(p).start(),
|
||||
() -> new ServerStarter().build12(worldOwner.getUuid()).send(p).start(),
|
||||
() -> HelpCommand.sendBauHelp(ChatSender.of(p)));
|
||||
}
|
||||
|
||||
private static void versionSelector(ProxiedPlayer p, String[] args, int pos, Runnable run18, Runnable run15, Runnable run12, Runnable runElse) {
|
||||
if(args.length <= pos) {
|
||||
int version = p.getPendingConnection().getVersion();
|
||||
if(version > 340) { // Version > 1.12.2
|
||||
run15.run();
|
||||
} else {
|
||||
run12.run();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (args[pos].toLowerCase()) {
|
||||
case "18":
|
||||
case "1.18":
|
||||
run18.run();
|
||||
break;
|
||||
case "ws":
|
||||
case "warship":
|
||||
case "as":
|
||||
case "airship":
|
||||
case "mwg":
|
||||
case "miniwargear":
|
||||
case "wg":
|
||||
case "wargear":
|
||||
case "15":
|
||||
case "1.15":
|
||||
run15.run();
|
||||
break;
|
||||
case "12":
|
||||
case "1.12":
|
||||
run12.run();
|
||||
break;
|
||||
default:
|
||||
runElse.run();
|
||||
}
|
||||
}
|
||||
|
||||
private static void togglewe(ProxiedPlayer p, String[] args){
|
||||
BauweltMember target = toggle(p, args, "togglewe");
|
||||
if(target == null)
|
||||
return;
|
||||
|
||||
target.setWorldEdit(!target.isWorldEdit());
|
||||
clearMembercache(p);
|
||||
isAllowedTo(target.isWorldEdit(), p, target, "BAU_MEMBER_TOGGLE_WORLD_EDIT");
|
||||
}
|
||||
|
||||
private static void toggleworld(ProxiedPlayer p, String[] args){
|
||||
BauweltMember target = toggle(p, args, "toggleworld");
|
||||
if(target == null)
|
||||
return;
|
||||
|
||||
target.setWorld(!target.isWorld());
|
||||
clearMembercache(p);
|
||||
isAllowedTo(target.isWorld(), p, target, "BAU_MEMBER_TOGGLE_WORLD");
|
||||
}
|
||||
|
||||
private static void clearMembercache(ProxiedPlayer p){
|
||||
for(ServerInfo info : ProxyServer.getInstance().getServers().values()){
|
||||
Subserver server = Subserver.getSubserver(info);
|
||||
if(server != null && server.getType() == Servertype.BAUSERVER && ((Bauserver)server).getOwner().equals(p.getUniqueId())){
|
||||
info.getPlayers().stream().findAny().ifPresent(player -> new BaumemberUpdatePacket().send(player));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void delmember(ProxiedPlayer p, String[] args){
|
||||
if (args.length == 1) {
|
||||
Message.send("BAU_DELMEMBER_USAGE", p);
|
||||
return;
|
||||
}
|
||||
|
||||
BauweltMember target = member(p, SteamwarUser.get(args[1]));
|
||||
if(target == null)
|
||||
return;
|
||||
|
||||
if(SteamwarUser.get(target.getMemberID()).getUuid().equals(p.getUniqueId())) {
|
||||
Message.send("BAU_DELMEMBER_SELFDEL", p);
|
||||
return;
|
||||
}
|
||||
|
||||
target.remove();
|
||||
ProxiedPlayer toRemove = ProxyServer.getInstance().getPlayer(SteamwarUser.get(target.getMemberID()).getUuid());
|
||||
if(toRemove != null){
|
||||
Message.send("BAU_DELMEMBER_DELETED_TARGET", toRemove, p.getName());
|
||||
Subserver currentServer = Subserver.getSubserver(toRemove.getServer().getInfo());
|
||||
if (currentServer != null && currentServer.getType() == Servertype.BAUSERVER && ((Bauserver) currentServer).getOwner().equals(p.getUniqueId())) {
|
||||
toRemove.connect(ProxyServer.getInstance().getServerInfo(BungeeCore.LOBBY_SERVER));
|
||||
}
|
||||
}
|
||||
Message.send("BAU_DELMEMBER_DELETED", p);
|
||||
}
|
||||
|
||||
private static void delete(ProxiedPlayer p, String[] args){
|
||||
SteamwarUser user = SteamwarUser.get(p.getUniqueId());
|
||||
versionSelector(p, args, 1,
|
||||
() -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS18_PATH + user.getId())),
|
||||
() -> deleteConfirmation(p, () -> deleteWorld(p, BungeeCore.USERWORLDS15 + user.getId())),
|
||||
() -> deleteConfirmation(p, () -> deleteWorld(p, BungeeCore.WORLD_FOLDER + p.getUniqueId().toString())),
|
||||
() -> HelpCommand.sendBauHelp(ChatSender.of(p)));
|
||||
}
|
||||
|
||||
private static void deleteConfirmation(ProxiedPlayer p, Runnable worldDeletion) {
|
||||
SWInventory inventory = new SWInventory(p, 9, Message.parse("BAU_DELETE_GUI_NAME", p));
|
||||
inventory.addItem(8, new SWItem(Message.parse("BAU_DELETE_GUI_CANCEL", p), 1), click ->
|
||||
inventory.close()
|
||||
);
|
||||
inventory.addItem(0, new SWItem(Message.parse("BAU_DELETE_GUI_DELETE", p), 10), click ->
|
||||
worldDeletion.run()
|
||||
);
|
||||
inventory.open();
|
||||
}
|
||||
|
||||
private static void deleteWorld(ProxiedPlayer player, String world) {
|
||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
||||
for (Subserver subserver : Subserver.getServerList()) {
|
||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(player.getUniqueId())) {
|
||||
subserver.stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
SubserverSystem.deleteFolder(Node.local, world);
|
||||
Message.send("BAU_DELETE_DELETED", player);
|
||||
});
|
||||
}
|
||||
|
||||
private static void testarena(ProxiedPlayer p, String[] args){
|
||||
FightCommand.createArena(p, "/bau testarena ", false, args, 1, false, (player, mode, map) -> ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> new ServerStarter().test(mode, map, p).start()));
|
||||
}
|
||||
|
||||
private static BauweltMember member(ProxiedPlayer p, SteamwarUser member){
|
||||
if (member == null) {
|
||||
Message.send("UNKNOWN_PLAYER", p);
|
||||
return null;
|
||||
}
|
||||
|
||||
BauweltMember target = BauweltMember.getBauMember(p.getUniqueId(), member.getUuid());
|
||||
if (target == null) {
|
||||
Message.send("BAU_MEMBER_NOMEMBER", p);
|
||||
return null;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
private static BauweltMember toggle(ProxiedPlayer p, String[] args, String subcommand){
|
||||
if (args.length == 1) {
|
||||
Message.send("BAU_MEMBER_TOGGLE_USAGE", p, subcommand);
|
||||
return null;
|
||||
}
|
||||
|
||||
SteamwarUser member = SteamwarUser.get(args[1]);
|
||||
return member(p, member);
|
||||
}
|
||||
|
||||
private static void isAllowedTo(boolean permission, ProxiedPlayer p, BauweltMember target, String what){
|
||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(SteamwarUser.get(target.getMemberID()).getUuid());
|
||||
|
||||
if(permission){
|
||||
if(player != null)
|
||||
Message.send("BAU_MEMBER_TOGGLE_TARGET", player, p.getName(), Message.parse(what, player));
|
||||
Message.send("BAU_MEMBER_TOGGLE", p, Message.parse(what, p));
|
||||
}else{
|
||||
if(player != null)
|
||||
Message.send("BAU_MEMBER_TOGGLE_TARGET_OFF", player, p.getName(), Message.parse(what, player));
|
||||
Message.send("BAU_MEMBER_TOGGLE_OFF", p, Message.parse(what, p));
|
||||
}
|
||||
}
|
||||
}
|
45
src/de/steamwar/bungeecore/commands/BugCommand.java
Normale Datei
45
src/de/steamwar/bungeecore/commands/BugCommand.java
Normale Datei
@ -0,0 +1,45 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.sql.SWException;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public class BugCommand extends BasicCommand {
|
||||
public BugCommand() {
|
||||
super("bug", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
String server = player.getServer().getInfo().getName();
|
||||
String message = String.join(" ", args);
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
SWException.log(server, message, player.getName() + " " + user.getId());
|
||||
Message.send("BUG_MESSAGE", player);
|
||||
}
|
||||
}
|
107
src/de/steamwar/bungeecore/commands/ChallengeCommand.java
Normale Datei
107
src/de/steamwar/bungeecore/commands/ChallengeCommand.java
Normale Datei
@ -0,0 +1,107 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.*;
|
||||
import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker;
|
||||
import de.steamwar.bungeecore.sql.IgnoreSystem;
|
||||
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.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static de.steamwar.bungeecore.Storage.challenges;
|
||||
|
||||
public class ChallengeCommand extends BasicCommand {
|
||||
|
||||
public ChallengeCommand() {
|
||||
super("challenge", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(args.length < 1){
|
||||
Message.send("CHALLENGE_USAGE", sender);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
if(ModLoaderBlocker.isFabric((ProxiedPlayer) sender)) {
|
||||
Message.send("MODLOADER_DENIED", sender);
|
||||
return;
|
||||
}
|
||||
|
||||
ProxiedPlayer target = ProxyServer.getInstance().getPlayer(args[0]);
|
||||
if(target == null){
|
||||
Message.send("CHALLENGE_OFFLINE", sender);
|
||||
return;
|
||||
}else if(target == sender){
|
||||
Message.send("CHALLENGE_SELF", sender);
|
||||
return;
|
||||
}else if (IgnoreSystem.isIgnored(target, (ProxiedPlayer) sender)) {
|
||||
Message.send("CHALLENGE_IGNORED", sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Subserver subserver = Subserver.getSubserver(target);
|
||||
if(subserver != null && subserver.getType() == Servertype.ARENA){
|
||||
Message.send("CHALLENGE_INARENA", sender);
|
||||
return;
|
||||
}
|
||||
|
||||
FightCommand.createArena(sender, "/challenge " + target.getName() + " ", false, args, 1, false, (player, mode, map) -> {
|
||||
if(challenges.containsKey(target) && challenges.get(target).contains(player)){
|
||||
challenges.remove(target);
|
||||
challenges.remove(player);
|
||||
|
||||
Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).redLeader(target).start();
|
||||
Message.broadcast("CHALLENGE_BROADCAST", "CHALLENGE_BROADCAST_HOVER",
|
||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName(), target.getName());
|
||||
}else{
|
||||
if(!challenges.containsKey(player)){
|
||||
challenges.put(player, new LinkedList<>());
|
||||
}
|
||||
|
||||
challenges.get(player).add(target);
|
||||
|
||||
Message.send("CHALLENGE_CHALLENGED", player, target.getName(), mode.getDisplayName());
|
||||
Message.send("CHALLENGE_CHALLENGED_TARGET", target, player.getName(), mode.getDisplayName(), mode.getMaps().size()!=1?Message.parse("CHALLENGE_CHALLENGED_MAP", target, map):"");
|
||||
|
||||
Message.send("CHALLENGE_ACCEPT", target, Message.parse("CHALLENGE_ACCEPT_HOVER", target), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/challenge " + player.getName() + " " + mode.getChatName() + " " + map));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void remove(ProxiedPlayer player){
|
||||
challenges.remove(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
|
||||
if(args.length == 2)
|
||||
return ArenaMode.getAllChatNames(false);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
351
src/de/steamwar/bungeecore/commands/CheckCommand.java
Normale Datei
351
src/de/steamwar/bungeecore/commands/CheckCommand.java
Normale Datei
@ -0,0 +1,351 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.*;
|
||||
import de.steamwar.bungeecore.bot.util.DiscordSchemAlert;
|
||||
import de.steamwar.bungeecore.listeners.ConnectionListener;
|
||||
import de.steamwar.bungeecore.sql.CheckedSchematic;
|
||||
import de.steamwar.bungeecore.sql.SchematicNode;
|
||||
import de.steamwar.bungeecore.sql.SchematicType;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
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.TextComponent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.config.Configuration;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class CheckCommand extends BasicCommand {
|
||||
private static Map<SchematicType, List<String>> checkQuestions = new HashMap<>();
|
||||
private static Map<SchematicType, List<String>> ranks = new HashMap<>();
|
||||
|
||||
private static Map<UUID, CheckSession> currentCheckers = new HashMap<>();
|
||||
private static Map<Integer, CheckSession> currentSchems = new HashMap<>();
|
||||
|
||||
public static void setCheckQuestions(SchematicType checkType, Configuration config) {
|
||||
checkQuestions.put(checkType, config.getStringList("CheckQuestions"));
|
||||
if(!config.getStringList("Ranks").isEmpty())
|
||||
ranks.put(checkType, config.getStringList("Ranks"));
|
||||
}
|
||||
|
||||
public static boolean isChecking(ProxiedPlayer player){
|
||||
return currentCheckers.containsKey(player.getUniqueId());
|
||||
}
|
||||
|
||||
public static SchematicNode getCheckingSchem(ProxiedPlayer player) {
|
||||
return currentCheckers.get(player.getUniqueId()).schematic;
|
||||
}
|
||||
|
||||
public CheckCommand() {
|
||||
super("check", ConnectionListener.CHECK_PERMISSION);
|
||||
|
||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
||||
List<SchematicNode> schematics = getSchemsToCheck();
|
||||
if(schematics.size() != currentCheckers.size())
|
||||
Message.team("CHECK_REMINDER", "CHECK_REMINDER_HOVER", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check list"), schematics.size() - currentCheckers.size());
|
||||
}, 10, 10, TimeUnit.MINUTES);
|
||||
}
|
||||
public static void sendReminder(ProxiedPlayer player) {
|
||||
List<SchematicNode> schematics = getSchemsToCheck();
|
||||
if(schematics.size() != currentCheckers.size())
|
||||
Message.send("CHECK_REMINDER", player, Message.parse("CHECK_REMINDER_HOVER", player), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check list"), schematics.size() - currentCheckers.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
|
||||
if(args.length == 0){
|
||||
help(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(args[0].toLowerCase()){
|
||||
case "list":
|
||||
list(player);
|
||||
break;
|
||||
case "schematic":
|
||||
schematic(player, args[1]);
|
||||
break;
|
||||
case "next":
|
||||
case "accept":
|
||||
next(player, args);
|
||||
break;
|
||||
case "cancel":
|
||||
abort(player);
|
||||
break;
|
||||
case "decline":
|
||||
decline(player, args);
|
||||
break;
|
||||
default:
|
||||
help(player);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<SchematicNode> getSchemsToCheck(){
|
||||
List<SchematicNode> schematicList = new LinkedList<>();
|
||||
|
||||
for (SchematicType type : SchematicType.values()) {
|
||||
if (type.check())
|
||||
schematicList.addAll(SchematicNode.getAllSchematicsOfType(type.toDB()));
|
||||
}
|
||||
return schematicList;
|
||||
}
|
||||
|
||||
public static String getChecker(SchematicNode schematic) {
|
||||
if (currentSchems.get(schematic.getId()) == null) return null;
|
||||
return currentSchems.get(schematic.getId()).checker.getName();
|
||||
}
|
||||
|
||||
private void list(ProxiedPlayer player) {
|
||||
List<SchematicNode> schematicList = getSchemsToCheck();
|
||||
|
||||
Message.sendPrefixless("CHECK_LIST_HEADER", player, schematicList.size());
|
||||
|
||||
for (SchematicNode schematic : schematicList) {
|
||||
CheckSession current = currentSchems.get(schematic.getId());
|
||||
long waitedMillis = Timestamp.from(Instant.now()).getTime() - schematic.getLastUpdate().getTime();
|
||||
String color = waitedMillis > 14400000 ? (waitedMillis > 86400000 ? "§c" : "§e") : "§a";
|
||||
long hours = waitedMillis / 3600000;
|
||||
long minutes = (waitedMillis - hours * 3600000) / 60000;
|
||||
String waitTime = color + Message.parse("CHECK_LIST_WAIT", player, hours, (minutes < 10) ? "0" + minutes : minutes);
|
||||
if (current == null) {
|
||||
Message.sendPrefixless("CHECK_LIST_TO_CHECK", player,
|
||||
Message.parse("CHECK_LIST_TO_CHECK_HOVER", player),
|
||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check schematic " + schematic.getId()),
|
||||
waitTime,
|
||||
schematic.getSchemtype().getKuerzel(), SteamwarUser.get(schematic.getOwner()).getUserName(), schematic.getName());
|
||||
} else {
|
||||
Message.sendPrefixless("CHECK_LIST_CHECKING", player,
|
||||
Message.parse("CHECK_LIST_CHECKING_HOVER", player),
|
||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join " + current.checker.getName()),
|
||||
waitTime,
|
||||
schematic.getSchemtype().getKuerzel(), SteamwarUser.get(schematic.getOwner()).getUserName(), schematic.getName(), current.checker.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void schematic(ProxiedPlayer player, String schemID){
|
||||
if(isChecking(player)){
|
||||
Message.send("CHECK_SCHEMATIC_ALREADY_CHECKING", player);
|
||||
return;
|
||||
}
|
||||
|
||||
SchematicNode schem = SchematicNode.getSchematicNode(Integer.parseInt(schemID));
|
||||
if(!schem.getSchemtype().check()){
|
||||
ProxyServer.getInstance().getLogger().log(Level.SEVERE, player.getName() + " tried to check an uncheckable schematic!");
|
||||
return;
|
||||
}else if(schem.getOwner() == SteamwarUser.get(player.getUniqueId()).getId()) {
|
||||
Message.send("CHECK_SCHEMATIC_OWN", player);
|
||||
return;
|
||||
}
|
||||
|
||||
new CheckSession(player, schem);
|
||||
}
|
||||
|
||||
private static boolean notChecking(ProxiedPlayer player){
|
||||
if(!isChecking(player)){
|
||||
Message.send("CHECK_NOT_CHECKING", player);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void next(ProxiedPlayer player, String[] args){
|
||||
if(notChecking(player))
|
||||
return;
|
||||
|
||||
int rank = 0;
|
||||
if(args.length > 1){
|
||||
try{
|
||||
rank = Integer.parseInt(args[1]);
|
||||
}catch(NumberFormatException e){
|
||||
Message.send("CHECK_INVALID_RANK", player);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
currentCheckers.get(player.getUniqueId()).next(rank);
|
||||
}
|
||||
|
||||
public static void abort(ProxiedPlayer player){
|
||||
if(notChecking(player))
|
||||
return;
|
||||
|
||||
Message.send("CHECK_ABORT", player);
|
||||
currentCheckers.get(player.getUniqueId()).abort();
|
||||
}
|
||||
|
||||
private void decline(ProxiedPlayer player, String[] args){
|
||||
if(notChecking(player))
|
||||
return;
|
||||
|
||||
if(args.length < 2) {
|
||||
help(player);
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder message = new StringBuilder();
|
||||
for (int i = 1; i < args.length; i++)
|
||||
message.append(args[i]).append(" ");
|
||||
|
||||
currentCheckers.get(player.getUniqueId()).decline(message.toString());
|
||||
}
|
||||
|
||||
private void help(CommandSender sender){
|
||||
Message.sendPrefixless("CHECK_HELP_LIST", sender);
|
||||
Message.sendPrefixless("CHECK_HELP_NEXT", sender);
|
||||
Message.sendPrefixless("CHECK_HELP_DECLINE", sender);
|
||||
Message.sendPrefixless("CHECK_HELP_CANCEL", sender);
|
||||
}
|
||||
|
||||
private static class CheckSession{
|
||||
private final ProxiedPlayer checker;
|
||||
private final SchematicNode schematic;
|
||||
private final Timestamp startTime;
|
||||
private final ListIterator<String> checkList;
|
||||
|
||||
private CheckSession(ProxiedPlayer checker, SchematicNode schematic){
|
||||
this.checker = checker;
|
||||
this.schematic = schematic;
|
||||
this.startTime = Timestamp.from(Instant.now());
|
||||
this.checkList = checkQuestions.get(schematic.getSchemtype()).listIterator();
|
||||
|
||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
||||
ArenaMode mode = ArenaMode.getBySchemType(schematic.getSchemtype().fightType());
|
||||
if(new ServerStarter().test(mode, mode.getRandomMap(), checker).check(schematic.getId()).start() == null) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
currentCheckers.put(checker.getUniqueId(), this);
|
||||
currentSchems.put(schematic.getId(), this);
|
||||
for(CheckedSchematic previous : CheckedSchematic.previousChecks(schematic))
|
||||
Message.sendPrefixless("CHECK_SCHEMATIC_PREVIOUS", checker, previous.getEndTime(), SteamwarUser.get(previous.getValidator()).getUserName(), previous.getDeclineReason());
|
||||
next(0);
|
||||
});
|
||||
}
|
||||
|
||||
private void next(int rank) {
|
||||
if(!checkList.hasNext()){
|
||||
accept(rank);
|
||||
return;
|
||||
}
|
||||
|
||||
checker.sendMessage(TextComponent.fromLegacyText(checkList.next()));
|
||||
|
||||
TextComponent next = new TextComponent();
|
||||
next.setColor(ChatColor.GREEN);
|
||||
if(checkList.hasNext()){
|
||||
next.setText(Message.parse("CHECK_NEXT", checker));
|
||||
next.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check next"));
|
||||
}else if(ranks.containsKey(schematic.getSchemtype())){
|
||||
List<String> r = ranks.get(schematic.getSchemtype());
|
||||
for(int i = 0; i < r.size(); i++){
|
||||
Message.sendPrefixless("CHECK_RANK", checker,
|
||||
Message.parse("CHECK_RANK_HOVER", checker),
|
||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check accept " + (i+1)),
|
||||
i+1, r.get(i));
|
||||
Message.sendPrefixless("SPACER", checker);
|
||||
}
|
||||
}else{
|
||||
next.setText(Message.parse("CHECK_ACCEPT", checker));
|
||||
next.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check accept"));
|
||||
}
|
||||
|
||||
TextComponent decline = new TextComponent(" " + Message.parse("CHECK_DECLINE", checker));
|
||||
decline.setColor(ChatColor.RED);
|
||||
decline.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/check decline "));
|
||||
|
||||
next.addExtra(decline);
|
||||
checker.sendMessage(next);
|
||||
}
|
||||
|
||||
private void accept(int rank){
|
||||
if(ranks.containsKey(schematic.getSchemtype())){
|
||||
if(rank <= 0 || ranks.get(schematic.getSchemtype()).size() < rank){
|
||||
Message.send("CHECK_INVALID_RANK", checker);
|
||||
return;
|
||||
}
|
||||
schematic.setRank(rank);
|
||||
}
|
||||
|
||||
schematic.setType(schematic.getSchemtype().fightType().toDB());
|
||||
CheckedSchematic.create(schematic, SteamwarUser.get(checker.getUniqueId()).getId(), startTime, Timestamp.from(Instant.now()), "freigegeben");
|
||||
SteamwarUser user = SteamwarUser.get(schematic.getOwner());
|
||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(user.getUuid());
|
||||
if(player != null) {
|
||||
Message.send("CHECK_ACCEPTED", player, schematic.getSchemtype().name(), schematic.getName());
|
||||
} else {
|
||||
DiscordSchemAlert.sendAccept(schematic, user);
|
||||
}
|
||||
Message.team("CHECK_ACCEPTED_TEAM", schematic.getName(), user.getUserName());
|
||||
stop();
|
||||
}
|
||||
|
||||
private void decline(String reason){
|
||||
CheckedSchematic.create(schematic, SteamwarUser.get(checker.getUniqueId()).getId(), startTime, Timestamp.from(Instant.now()), reason);
|
||||
SteamwarUser user = SteamwarUser.get(schematic.getOwner());
|
||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(user.getUuid());
|
||||
if(player != null) {
|
||||
Message.send("CHECK_DECLINED", player, schematic.getSchemtype().name(), schematic.getName(), reason);
|
||||
} else {
|
||||
DiscordSchemAlert.sendDecline(schematic, user, reason);
|
||||
}
|
||||
Message.team("CHECK_DECLINED_TEAM", schematic.getName(), user.getUserName(), reason);
|
||||
schematic.setType(SchematicType.Normal.toDB());
|
||||
stop();
|
||||
}
|
||||
|
||||
private void abort(){
|
||||
CheckedSchematic.create(schematic, SteamwarUser.get(checker.getUniqueId()).getId(), startTime, Timestamp.from(Instant.now()), "Prüfvorgang abgebrochen");
|
||||
stop();
|
||||
}
|
||||
|
||||
private void stop(){
|
||||
currentCheckers.remove(checker.getUniqueId());
|
||||
currentSchems.remove(schematic.getId());
|
||||
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
||||
for (Subserver subserver : Subserver.getServerList()) {
|
||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(checker.getUniqueId())) {
|
||||
subserver.stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void remove() {
|
||||
currentCheckers.remove(checker.getUniqueId());
|
||||
currentSchems.remove(schematic.getId());
|
||||
}
|
||||
}
|
||||
}
|
123
src/de/steamwar/bungeecore/commands/DevCommand.java
Normale Datei
123
src/de/steamwar/bungeecore/commands/DevCommand.java
Normale Datei
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.sql.Punishment;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.messages.ChatSender;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DevCommand extends BasicCommand {
|
||||
|
||||
private final File devServerDir = new File("/configs/DevServer");
|
||||
private final Map<String, ServerInfo> devServers = new HashMap<>();
|
||||
|
||||
public DevCommand() {
|
||||
super("dev", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender s, String[] args) {
|
||||
if (!(s instanceof ProxiedPlayer))
|
||||
return;
|
||||
ProxiedPlayer player = (ProxiedPlayer) s;
|
||||
|
||||
ChatSender sender = ChatSender.of(player);
|
||||
if (sender.user().isPunishedWithMessage(sender, Punishment.PunishmentType.NoDevServer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateDevServers();
|
||||
if(devServers.isEmpty()) {
|
||||
sender.system("DEV_NO_SERVER");
|
||||
} else if (devServers.size() == 1) {
|
||||
player.connect(devServers.values().stream().findAny().get());
|
||||
} else if (args.length == 0) {
|
||||
ServerInfo info = devServers.get(player.getName().toLowerCase());
|
||||
if (info == null) {
|
||||
sender.system("DEV_UNKNOWN_SERVER");
|
||||
return;
|
||||
}
|
||||
|
||||
player.connect(info);
|
||||
} else {
|
||||
ServerInfo info = devServers.get(args[0].toLowerCase());
|
||||
if (info == null) {
|
||||
sender.system("DEV_NO_SERVER");
|
||||
return;
|
||||
}
|
||||
|
||||
player.connect(info);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender sender, String[] args) {
|
||||
if (!(sender instanceof ProxiedPlayer) || args.length > 1) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
updateDevServers();
|
||||
return devServers.keySet().stream().filter(s -> {
|
||||
if (args.length == 0) return true;
|
||||
return s.startsWith(args[0].toLowerCase());
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void updateDevServers() {
|
||||
String[] serverFiles = devServerDir.list();
|
||||
|
||||
Map<String, Integer> devServerFiles = new HashMap<>();
|
||||
if(serverFiles != null) {
|
||||
for(String serverFile : serverFiles) {
|
||||
String[] server = serverFile.split("\\.");
|
||||
devServerFiles.put(server[0], Integer.parseInt(server[1]));
|
||||
}
|
||||
}
|
||||
|
||||
devServers.entrySet().removeIf(entry -> {
|
||||
if(!devServerFiles.containsKey(entry.getKey())) {
|
||||
ProxyServer.getInstance().getServers().remove(entry.getValue().getName());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
devServerFiles.forEach((key, value) -> {
|
||||
if (devServers.containsKey(key))
|
||||
return;
|
||||
|
||||
SteamwarUser user = SteamwarUser.get(key);
|
||||
ServerInfo info = ProxyServer.getInstance().constructServerInfo("Dev " + user.getUserName(), new InetSocketAddress("127.0.0.1", value), "SteamWar.de - Subserver", false);
|
||||
ProxyServer.getInstance().getServers().put(info.getName(), info);
|
||||
devServers.put(user.getUserName().toLowerCase(), info);
|
||||
});
|
||||
}
|
||||
}
|
128
src/de/steamwar/bungeecore/commands/EventCommand.java
Normale Datei
128
src/de/steamwar/bungeecore/commands/EventCommand.java
Normale Datei
@ -0,0 +1,128 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.*;
|
||||
import de.steamwar.bungeecore.sql.Event;
|
||||
import de.steamwar.bungeecore.sql.EventFight;
|
||||
import de.steamwar.bungeecore.sql.Team;
|
||||
import de.steamwar.bungeecore.sql.TeamTeilnahme;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class EventCommand extends BasicCommand {
|
||||
|
||||
public EventCommand() {
|
||||
super("event", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
|
||||
Event currentEvent = Event.get();
|
||||
|
||||
if(currentEvent == null) {
|
||||
noCurrentEvent(player);
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length != 1){
|
||||
eventOverview(player, currentEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
Team team = Team.get(args[0]);
|
||||
if(team == null){
|
||||
Message.send("EVENT_NO_TEAM", player);
|
||||
return;
|
||||
}
|
||||
|
||||
Subserver eventArena = EventStarter.getEventServer().get(team.getTeamId());
|
||||
if(eventArena == null || !Subserver.getServerList().contains(eventArena)){
|
||||
Message.send("EVENT_NO_FIGHT_TEAM", player);
|
||||
return;
|
||||
}
|
||||
|
||||
SubserverSystem.sendPlayer(eventArena, player);
|
||||
}
|
||||
|
||||
private void noCurrentEvent(ProxiedPlayer player){
|
||||
Message.send("EVENT_NO_CURRENT", player);
|
||||
List<Event> coming = Event.getComing();
|
||||
Instant now = Instant.now();
|
||||
if(!coming.isEmpty()){
|
||||
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(Message.parse("EVENT_DATE_FORMAT", player));
|
||||
Message.send("EVENT_COMING", player);
|
||||
for(Event e : coming){
|
||||
Message.send("EVENT_COMING_EVENT", player, e.getStart().toLocalDateTime().format(dateFormat), e.getEnd().toLocalDateTime().format(dateFormat), e.getEventName());
|
||||
Set<Team> teams = TeamTeilnahme.getTeams(e.getEventID());
|
||||
if(now.isBefore(e.getDeadline().toInstant())) {
|
||||
Message.send("EVENT_COMING_DEADLINE", player, e.getDeadline());
|
||||
}
|
||||
if(!teams.isEmpty()){
|
||||
StringBuilder tline = new StringBuilder();
|
||||
for(Team t : teams){
|
||||
tline.append(' ').append(Message.parse("EVENT_COMING_TEAM", player, t.getTeamColor(), t.getTeamKuerzel()));
|
||||
}
|
||||
Message.send("EVENT_COMING_TEAMS", player, tline.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void eventOverview(ProxiedPlayer player, Event currentEvent){
|
||||
Message.send("EVENT_USAGE", player);
|
||||
|
||||
List<EventFight> fights = EventFight.getEvent(currentEvent.getEventID());
|
||||
|
||||
Message.send("EVENT_CURRENT_EVENT", player, currentEvent.getEventName());
|
||||
|
||||
DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern(Message.parse("EVENT_TIME_FORMAT", player));
|
||||
for(EventFight fight : fights){
|
||||
Team blue = Team.get(fight.getTeamBlue());
|
||||
Team red = Team.get(fight.getTeamRed());
|
||||
StringBuilder fline = new StringBuilder(Message.parse("EVENT_CURRENT_FIGHT", player, fight.getStartTime().toLocalDateTime().format(timeFormat), blue.getTeamColor(), blue.getTeamKuerzel(),
|
||||
red.getTeamColor(), red.getTeamKuerzel()));
|
||||
|
||||
if(fight.hasFinished()){
|
||||
switch(fight.getErgebnis()){
|
||||
case 1:
|
||||
fline.append(Message.parse("EVENT_CURRENT_FIGHT_WIN", player, blue.getTeamColor(), blue.getTeamKuerzel()));
|
||||
break;
|
||||
case 2:
|
||||
fline.append(Message.parse("EVENT_CURRENT_FIGHT_WIN", player, red.getTeamColor(), red.getTeamKuerzel()));
|
||||
break;
|
||||
default:
|
||||
fline.append(Message.parse("EVENT_CURRENT_FIGHT_DRAW", player));
|
||||
}
|
||||
}
|
||||
|
||||
BungeeCore.send(player, fline.toString());
|
||||
}
|
||||
}
|
||||
}
|
@ -17,31 +17,42 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.velocitycore.commands;
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.messages.Chatter;
|
||||
import de.steamwar.sql.Event;
|
||||
import de.steamwar.sql.EventFight;
|
||||
import de.steamwar.sql.Team;
|
||||
import de.steamwar.sql.UserPerm;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.sql.Event;
|
||||
import de.steamwar.bungeecore.sql.EventFight;
|
||||
import de.steamwar.bungeecore.sql.Team;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
public class EventRescheduleCommand extends SWCommand {
|
||||
public class EventRescheduleCommand extends BasicCommand {
|
||||
|
||||
public EventRescheduleCommand() {
|
||||
super("eventreschedule", UserPerm.MODERATION);
|
||||
super("eventreschedule", "bungeecore.softreload");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void reschedule(Chatter sender, Team teamBlue, Team teamRed) {
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
|
||||
if(args.length != 2){
|
||||
Message.send("EVENTRESCHEDULE_USAGE", player);
|
||||
return;
|
||||
}
|
||||
|
||||
Team teamBlue = Team.get(args[0]);
|
||||
Team teamRed = Team.get(args[1]);
|
||||
Event event = Event.get();
|
||||
if(event == null){
|
||||
sender.system("EVENTRESCHEDULE_UNKNOWN_TEAM");
|
||||
if(teamBlue == null || teamRed == null || event == null){
|
||||
Message.send("EVENTRESCHEDULE_UNKNOWN_TEAM", player);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -54,13 +65,13 @@ public class EventRescheduleCommand extends SWCommand {
|
||||
continue;
|
||||
|
||||
if(fight.getTeamBlue() == teamBlue.getTeamId() && fight.getTeamRed() == teamRed.getTeamId()){
|
||||
sender.system("EVENTRESCHEDULE_STARTING");
|
||||
Message.send("EVENTRESCHEDULE_STARTING", player);
|
||||
fight.reschedule();
|
||||
EventFight.loadAllComingFights();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
sender.system("EVENTRESCHEDULE_NO_FIGHT");
|
||||
Message.send("EVENTRESCHEDULE_NO_FIGHT", player);
|
||||
}
|
||||
}
|
@ -17,20 +17,18 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.velocitycore.commands;
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.messages.Chatter;
|
||||
import de.steamwar.sql.EventFight;
|
||||
import de.steamwar.sql.UserPerm;
|
||||
import de.steamwar.bungeecore.sql.EventFight;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
|
||||
public class EventreloadCommand extends SWCommand {
|
||||
public class EventreloadCommand extends BasicCommand {
|
||||
public EventreloadCommand() {
|
||||
super("eventreload", UserPerm.MODERATION);
|
||||
super("eventreload", "bungeecore.softreload");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void execute(Chatter sender) {
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
EventFight.loadAllComingFights();
|
||||
}
|
||||
}
|
247
src/de/steamwar/bungeecore/commands/FightCommand.java
Normale Datei
247
src/de/steamwar/bungeecore/commands/FightCommand.java
Normale Datei
@ -0,0 +1,247 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.*;
|
||||
import de.steamwar.bungeecore.inventory.SWInventory;
|
||||
import de.steamwar.bungeecore.inventory.SWItem;
|
||||
import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker;
|
||||
import de.steamwar.bungeecore.sql.Punishment;
|
||||
import de.steamwar.messages.ChatSender;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
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.HoverEvent;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.chat.hover.content.Text;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Jeder Fightcommand (auch bau testarena und challenge) haben folgende Optionskette:
|
||||
*
|
||||
* [ArenaMode] [Map]
|
||||
*
|
||||
* Sollte der ArenaMode fehlen, kann er mit getMode() bestimmt werden.
|
||||
* Sollte die Map fehlen, kann sie mit getMap() bestimmt werden.
|
||||
*/
|
||||
|
||||
public class FightCommand extends BasicCommand {
|
||||
|
||||
public FightCommand() {
|
||||
super("fight", "", "f");
|
||||
}
|
||||
|
||||
private static ArenaMode getMode(ChatSender sender, String arg){
|
||||
ArenaMode mode = ArenaMode.getByChat(arg);
|
||||
if(mode != null)
|
||||
return mode;
|
||||
|
||||
sender.system("FIGHT_UNKNOWN_GAMEMODE", arg);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String getMap(ChatSender sender, ArenaMode mode, String arg){
|
||||
String realMap = mode.hasMap(arg.toLowerCase());
|
||||
if(realMap != null)
|
||||
return realMap;
|
||||
if(arg.equalsIgnoreCase("Random"))
|
||||
return mode.getRandomMap();
|
||||
|
||||
sender.system("FIGHT_UNKNOWN_ARENA");
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void getModes(ChatSender sender, String precommand, boolean historic){
|
||||
TextComponent start = new TextComponent();
|
||||
TextComponent current = start;
|
||||
for(ArenaMode mode : ArenaMode.getAllModes()){
|
||||
if(mode.withoutChatName() || mode.isHistoric() != historic)
|
||||
continue;
|
||||
String command = precommand + mode.getChatName();
|
||||
current.setBold(true);
|
||||
current.setColor(ChatColor.GRAY);
|
||||
current.setText(mode.getChatName() + " ");
|
||||
current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§e" + command)));
|
||||
current.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command));
|
||||
if(current != start)
|
||||
start.addExtra(current);
|
||||
current = new TextComponent();
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatMessageType.SYSTEM, start);
|
||||
}
|
||||
|
||||
private static void getMaps(ChatSender sender, String precommand, ArenaMode mode){
|
||||
TextComponent start = new TextComponent();
|
||||
TextComponent current = start;
|
||||
if(mode.getMaps().size() > 1){
|
||||
String command = precommand + mode.getChatName() + " Random";
|
||||
start.setBold(true);
|
||||
start.setColor(ChatColor.GRAY);
|
||||
start.setText(sender.parseToLegacy("FIGHT_ARENA_RANDOM") + " ");
|
||||
start.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§e" + command)));
|
||||
start.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command));
|
||||
current = new TextComponent();
|
||||
}
|
||||
|
||||
for(String map : mode.getMaps()){
|
||||
String command = precommand + mode.getChatName() + " " + map;
|
||||
current.setBold(true);
|
||||
current.setColor(ChatColor.GRAY);
|
||||
current.setText(map + " ");
|
||||
current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§e" + command)));
|
||||
current.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command));
|
||||
if(current != start)
|
||||
start.addExtra(current);
|
||||
current = new TextComponent();
|
||||
}
|
||||
|
||||
sender.sendMessage(ChatMessageType.SYSTEM, start);
|
||||
}
|
||||
|
||||
private static boolean alreadyInArena(ProxiedPlayer player){
|
||||
Subserver subserver = Subserver.getSubserver(player);
|
||||
if(subserver != null && subserver.getType() == Servertype.ARENA){
|
||||
Message.send("FIGHT_IN_ARENA", player);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void createArena(CommandSender s, String precommand, boolean allowMerging, String[] args, int startArg, boolean historic, FightCallback callback){
|
||||
if(!(s instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
ProxiedPlayer player = (ProxiedPlayer) s;
|
||||
|
||||
ChatSender sender = ChatSender.of(player);
|
||||
if (sender.user().isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(alreadyInArena(player))
|
||||
return;
|
||||
|
||||
if(ModLoaderBlocker.isFabric(player) && !precommand.equals("/bau testarena ")) {
|
||||
sender.system("MODLOADER_DENIED");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length < startArg+1){
|
||||
getModes(sender, precommand, historic);
|
||||
return;
|
||||
}
|
||||
|
||||
ArenaMode mode = getMode(sender, args[startArg]);
|
||||
if(mode == null)
|
||||
return;
|
||||
|
||||
String map;
|
||||
if(mode.getMaps().size() == 1){
|
||||
map = mode.getRandomMap();
|
||||
}else if(args.length < startArg+2){
|
||||
getMaps(sender, precommand, mode);
|
||||
return;
|
||||
}else{
|
||||
map = getMap(sender, mode, args[startArg+1]);
|
||||
}
|
||||
|
||||
if(map == null)
|
||||
return;
|
||||
|
||||
if(!allowMerging) {
|
||||
callback.run(player, mode, map);
|
||||
} else {
|
||||
suggestMerging(player, mode, map, callback);
|
||||
}
|
||||
}
|
||||
|
||||
public static void suggestMerging(ProxiedPlayer player, ArenaMode mode, String map, FightCallback declineMerge) {
|
||||
Arenaserver mergable = null;
|
||||
synchronized (Subserver.getServerList()) {
|
||||
for (Subserver subserver : Subserver.getServerList()) {
|
||||
if(subserver instanceof Arenaserver) {
|
||||
Arenaserver arenaserver = (Arenaserver) subserver;
|
||||
if(mode.getInternalName().equals(arenaserver.getMode()) && map.equals(arenaserver.getMap()) && arenaserver.isAllowMerge() && arenaserver.getServer().getPlayers().size() == 1) {
|
||||
mergable = arenaserver;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mergable == null) {
|
||||
declineMerge.run(player, mode, map);
|
||||
return;
|
||||
}
|
||||
|
||||
SWInventory inventory = new SWInventory(player, 9, Message.parse("FIGHT_MERGE_TITLE", player));
|
||||
inventory.addItem(0, new SWItem(Message.parse("FIGHT_MERGE_DECLINE", player), 1), click -> {
|
||||
inventory.close();
|
||||
declineMerge.run(player, mode, map);
|
||||
});
|
||||
Arenaserver finalMergable = mergable;
|
||||
SWItem item = new SWItem(Message.parse("FIGHT_MERGE_INFO", player, mode.getDisplayName(), finalMergable.getMap()), 11);
|
||||
item.addLore(Message.parse("FIGHT_MERGE_INFO_LORE_1", player, finalMergable.getServer().getPlayers().toArray(new ProxiedPlayer[1])[0].getName()));
|
||||
inventory.addItem(4, item, click -> {});
|
||||
inventory.addItem(8, new SWItem(Message.parse("FIGHT_MERGE_ACCEPT", player), 10), click -> {
|
||||
if(Subserver.getServerList().contains(finalMergable)) {
|
||||
finalMergable.sendPlayer(player);
|
||||
} else {
|
||||
Message.send("FIGHT_MERGE_OFFLINE", player);
|
||||
declineMerge.run(player, mode, map);
|
||||
}
|
||||
});
|
||||
inventory.open();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
createArena(sender, "/fight ", true, args, 0, false, (player, mode, map) -> {
|
||||
Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).start();
|
||||
Message.broadcast("FIGHT_BROADCAST", "FIGHT_BROADCAST_HOVER"
|
||||
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
|
||||
if(args.length == 1){
|
||||
return ArenaMode.getAllChatNames(false);
|
||||
}else if(args.length == 2){
|
||||
ArenaMode mode = ArenaMode.getByChat(args[1]);
|
||||
if(mode == null)
|
||||
return new LinkedList<>();
|
||||
return mode.getMaps();
|
||||
}
|
||||
return new LinkedList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is called when arena parameters are clear.
|
||||
*/
|
||||
interface FightCallback {
|
||||
void run(ProxiedPlayer player, ArenaMode mode, String map);
|
||||
}
|
||||
}
|
@ -1,75 +1,61 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
package de.steamwar.velocitycore.commands;
|
||||
|
||||
import de.steamwar.velocitycore.VelocityCore;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.messages.Chatter;
|
||||
import de.steamwar.messages.PlayerChatter;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import de.steamwar.sql.UserPerm;
|
||||
import de.steamwar.sql.internal.Statement;
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.sql.Statement;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public class GDPRQuery extends SWCommand {
|
||||
public class GDPRQuery extends BasicCommand {
|
||||
|
||||
public GDPRQuery() {
|
||||
super("gdprquery", UserPerm.ADMINISTRATION);
|
||||
super("gdprquery", "bungeecore.softreload");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void generate(PlayerChatter sender) {
|
||||
generate(sender, sender.user());
|
||||
}
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
@Register
|
||||
public void generate(Chatter sender, SteamwarUser user) {
|
||||
VelocityCore.schedule(() -> {
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
SteamwarUser user = args.length == 0 ? SteamwarUser.get(player.getUniqueId()) : SteamwarUser.get(args[0]);
|
||||
if(user == null) {
|
||||
Message.send("UNKNOWN_PLAYER", player);
|
||||
return;
|
||||
}
|
||||
|
||||
BungeeCord.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
|
||||
try {
|
||||
createZip(sender, user);
|
||||
createZip(player, user);
|
||||
} catch (IOException e) {
|
||||
throw new SecurityException("Could not create zip", e);
|
||||
}
|
||||
}).schedule();
|
||||
});
|
||||
}
|
||||
|
||||
private void createZip(Chatter sender, SteamwarUser user) throws IOException {
|
||||
sender.system("GDPR_STATUS_WEBSITE");
|
||||
private void createZip(ProxiedPlayer player, SteamwarUser user) throws IOException {
|
||||
printUpdate(player, "GDPR_STATUS_WEBSITE");
|
||||
|
||||
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(user.getUserName() + ".zip"));
|
||||
|
||||
copy(getClass().getClassLoader().getResourceAsStream("GDPRQueryREADME.md"), out, "README.md");
|
||||
copy(getClass().getClassLoader().getResourceAsStream("GDPRQueryREADME.md"), out, "README.txt");
|
||||
|
||||
sender.system("GDPR_STATUS_WORLD");
|
||||
copyBauwelt(user, out, "/home/minecraft/userworlds/" + user.getUUID().toString(), "BuildWorld12");
|
||||
printUpdate(player, "GDPR_STATUS_WORLD");
|
||||
copyBauwelt(user, out, "/home/minecraft/userworlds/" + user.getUuid().toString(), "BuildWorld12");
|
||||
copyBauwelt(user, out, "/home/minecraft/userworlds15/" + user.getId(), "BuildWorld15");
|
||||
|
||||
sender.system("GDPR_STATUS_INVENTORIES");
|
||||
printUpdate(player, "GDPR_STATUS_INVENTORIES");
|
||||
copyPlayerdata(user, out, "/home/minecraft/userworlds", "BuildInventories12");
|
||||
copyPlayerdata(user, out, "/home/minecraft/userworlds15", "BuildInventories15");
|
||||
|
||||
sender.system("GDPR_STATUS_DATABASE");
|
||||
printUpdate(player, "GDPR_STATUS_DATABASE");
|
||||
sqlCSV(user, out, bannedIPs, "BannedIPs.csv");
|
||||
sqlCSV(user, out, bauweltMember, "BuildMember.csv");
|
||||
sqlCSV(user, out, bauweltMembers, "BuildMembers.csv");
|
||||
@ -91,11 +77,11 @@ public class GDPRQuery extends SWCommand {
|
||||
schematics(user, out);
|
||||
userConfig(user, out);
|
||||
|
||||
sender.system("GDPR_STATUS_LOGS");
|
||||
printUpdate(player, "GDPR_STATUS_LOGS");
|
||||
copyLogs(user, out, new File("/logs"), "logs");
|
||||
|
||||
out.close();
|
||||
sender.system("GDPR_STATUS_FINISHED");
|
||||
printUpdate(player, "GDPR_STATUS_FINISHED");
|
||||
}
|
||||
|
||||
private static final Statement bannedIPs = new Statement("SELECT Timestamp, IP FROM BannedUserIPs WHERE UserID = ?");
|
||||
@ -227,14 +213,14 @@ public class GDPRQuery extends SWCommand {
|
||||
}
|
||||
}
|
||||
|
||||
File playerdata = new File(world, "playerdata/" + user.getUUID().toString() + ".dat");
|
||||
File playerdata = new File(world, "playerdata/" + user.getUuid().toString() + ".dat");
|
||||
if(playerdata.exists())
|
||||
copy(playerdata, out, outDir + "/playerdata/" + user.getUUID().toString() + ".dat");
|
||||
copy(playerdata, out, outDir + "/playerdata/" + user.getUuid().toString() + ".dat");
|
||||
}
|
||||
|
||||
private void copyPlayerdata(SteamwarUser user, ZipOutputStream out, String inDir, String outDir) throws IOException {
|
||||
File worlds = new File(inDir);
|
||||
String path = "playerdata/" + user.getUUID().toString() + ".dat";
|
||||
String path = "playerdata/" + user.getUuid().toString() + ".dat";
|
||||
|
||||
int i = 0;
|
||||
for(File world : worlds.listFiles()) {
|
||||
@ -242,10 +228,15 @@ public class GDPRQuery extends SWCommand {
|
||||
if(!playerdata.exists())
|
||||
continue;
|
||||
|
||||
copy(playerdata, out, outDir + "/" + (i++) + "/" + user.getUUID().toString() + ".dat");
|
||||
copy(playerdata, out, outDir + "/" + (i++) + "/" + user.getUuid().toString() + ".dat");
|
||||
}
|
||||
}
|
||||
|
||||
private void printUpdate(ProxiedPlayer player, String message) {
|
||||
if (player.isConnected())
|
||||
Message.send(message, player);
|
||||
}
|
||||
|
||||
private void copy(File file, ZipOutputStream out, String path) throws IOException {
|
||||
try(FileInputStream in = new FileInputStream(file)) {
|
||||
copy(in, out, path);
|
123
src/de/steamwar/bungeecore/commands/HelpCommand.java
Normale Datei
123
src/de/steamwar/bungeecore/commands/HelpCommand.java
Normale Datei
@ -0,0 +1,123 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.messages.ChatSender;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
|
||||
public class HelpCommand extends BasicCommand {
|
||||
|
||||
public HelpCommand() {
|
||||
super("help", "", "?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender s, String[] args) {
|
||||
ChatSender sender = ChatSender.of(s);
|
||||
if (args.length < 1) {
|
||||
printPage(sender, ClickEvent.Action.RUN_COMMAND,
|
||||
"HELP_LOBBY", "/l",
|
||||
"HELP_BAU", "/bau",
|
||||
"HELP_BAUSERVER", "/help bau",
|
||||
"HELP_FIGHT", "/fight",
|
||||
"HELP_CHALLENGE", "/challenge",
|
||||
"HELP_HISTORIC", "/historic",
|
||||
"HELP_TEAM", "/team",
|
||||
"HELP_JOIN", "/join",
|
||||
"HELP_LOCAL", "/local");
|
||||
}else if (args[0].equalsIgnoreCase("bauserver")) {
|
||||
sendBauHelp(sender);
|
||||
}else if (args[0].equalsIgnoreCase("bau")) {
|
||||
bauHelpGroup(sender, args);
|
||||
}
|
||||
}
|
||||
|
||||
private static void bauHelpGroup(ChatSender sender, String[] args) {
|
||||
if (args.length < 2) {
|
||||
sendBauHelpGroup(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (args[1].toLowerCase()) {
|
||||
case "admin":
|
||||
case "owner":
|
||||
case "bauwelt":
|
||||
sender.system("HELP_BAU_GROUP_ADMIN_TITLE");
|
||||
sendBauHelp(sender);
|
||||
return;
|
||||
case "world":
|
||||
printPage(sender, "HELP_BAU_GROUP_WORLD_TITLE", "HELP_TNT", "HELP_FIRE", "HELP_FREEZE", "HELP_TPSLIMIT", "HELP_PROTECT", "HELP_RESET");
|
||||
return;
|
||||
case "player":
|
||||
printPage(sender, "HELP_BAU_GROUP_PLAYER_TITLE", "HELP_SPEED", "HELP_NV", "HELP_WV", "HELP_DEBUGSTICK", "HELP_TRACE", "HELP_LOADER");
|
||||
return;
|
||||
case "worldedit":
|
||||
case "we":
|
||||
case "world-edit":
|
||||
case "edit":
|
||||
printPage(sender, "HELP_BAU_GROUP_WE_TITLE", "HELP_WE_POS1", "HELP_WE_POS2", "HELP_WE_COPY", "HELP_WE_PASTE", "HELP_WE_FLOPY", "HELP_WE_FLOPYP", "HELP_WE_ROTATE_90", "HELP_WE_ROTATE_180", "HELP_WE_ROTATE_N90");
|
||||
return;
|
||||
case "other":
|
||||
printPage(sender, "HELP_BAU_GROUP_OTHER_TITLE", "HELP_TESTBLOCK", "HELP_SKULL", "HELP_BAUINFO");
|
||||
return;
|
||||
default:
|
||||
sendBauHelpGroup(sender);
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendBauHelpGroup(ChatSender sender) {
|
||||
printPage(sender, ClickEvent.Action.RUN_COMMAND,
|
||||
"HELP_BAU_GROUP_ADMIN", "/help bau admin",
|
||||
"HELP_BAU_GROUP_WORLD", "/help bau world",
|
||||
"HELP_BAU_GROUP_PLAYER", "/help bau player",
|
||||
"HELP_BAU_GROUP_WE", "/help bau we",
|
||||
"HELP_BAU_GROUP_OTHER", "/help bau other");
|
||||
}
|
||||
|
||||
static void sendBauHelp(ChatSender sender) {
|
||||
printPage(sender, ClickEvent.Action.SUGGEST_COMMAND,
|
||||
"HELP_BAU_TP", "/bau tp ",
|
||||
"HELP_BAU_ADDMEMBER", "/bau addmember ",
|
||||
"HELP_BAU_DELMEMBER", "/bau delmember ",
|
||||
"HELP_BAU_TOGGLEWE", "/bau togglewe ",
|
||||
"HELP_BAU_TOGGLEWORLD", "/bau toggleworld ",
|
||||
"HELP_BAU_DELETE", "/bau delete ",
|
||||
"HELP_BAU_TESTARENA", "/bau testarena ");
|
||||
}
|
||||
|
||||
private static void printPage(ChatSender sender, ClickEvent.Action action, String... args) {
|
||||
for(int i = 0; i < args.length; i += 2) {
|
||||
String message = args[i];
|
||||
String hoverMessage = message + "_HOVER";
|
||||
String command = args[i+1];
|
||||
|
||||
sender.system(message, new Message(hoverMessage), new ClickEvent(action, command));
|
||||
}
|
||||
}
|
||||
|
||||
private static void printPage(ChatSender sender, String title, String... messages) {
|
||||
sender.system(title);
|
||||
for (String message : messages) {
|
||||
sender.prefixless(message);
|
||||
}
|
||||
}
|
||||
}
|
57
src/de/steamwar/bungeecore/commands/HistoricCommand.java
Normale Datei
57
src/de/steamwar/bungeecore/commands/HistoricCommand.java
Normale Datei
@ -0,0 +1,57 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.ArenaMode;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.ServerStarter;
|
||||
import de.steamwar.bungeecore.Subserver;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class HistoricCommand extends BasicCommand {
|
||||
public HistoricCommand() {
|
||||
super("historic", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
FightCommand.createArena(sender, "/historic ", true, args, 0, true, (player, mode, map) -> {
|
||||
Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).start();
|
||||
Message.broadcast("HISTORIC_BROADCAST", "HISTORIC_BROADCAST_HOVER"
|
||||
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
|
||||
if(args.length == 1){
|
||||
return ArenaMode.getAllChatNames(true);
|
||||
}else if(args.length == 2){
|
||||
ArenaMode mode = ArenaMode.getByChat(args[1]);
|
||||
if(mode == null)
|
||||
return new LinkedList<>();
|
||||
return mode.getMaps();
|
||||
}
|
||||
return new LinkedList<>();
|
||||
}
|
||||
}
|
63
src/de/steamwar/bungeecore/commands/IgnoreCommand.java
Normale Datei
63
src/de/steamwar/bungeecore/commands/IgnoreCommand.java
Normale Datei
@ -0,0 +1,63 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.sql.IgnoreSystem;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public class IgnoreCommand extends BasicCommand {
|
||||
|
||||
public IgnoreCommand() {
|
||||
super("ignore", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(args.length < 1) {
|
||||
Message.send("USAGE_IGNORE", sender);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
||||
SteamwarUser user = SteamwarUser.get(p.getUniqueId());
|
||||
|
||||
SteamwarUser target = SteamwarUser.get(args[0]);
|
||||
if(target == null){
|
||||
Message.send("UNKNOWN_PLAYER", p);
|
||||
return;
|
||||
}
|
||||
if(target.equals(user)){
|
||||
Message.send("IGNORE_YOURSELF", p);
|
||||
return;
|
||||
}
|
||||
if(IgnoreSystem.isIgnored(user, target)){
|
||||
Message.send("IGNORE_ALREADY", p);
|
||||
return;
|
||||
}
|
||||
|
||||
IgnoreSystem.ignore(user, target);
|
||||
Message.send("IGNORE_MESSAGE", p, target.getUserName());
|
||||
}
|
||||
}
|
93
src/de/steamwar/bungeecore/commands/JoinmeCommand.java
Normale Datei
93
src/de/steamwar/bungeecore/commands/JoinmeCommand.java
Normale Datei
@ -0,0 +1,93 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.*;
|
||||
import de.steamwar.bungeecore.sql.BauweltMember;
|
||||
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.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class JoinmeCommand extends BasicCommand {
|
||||
|
||||
public JoinmeCommand() {
|
||||
super("joinme", "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(sender instanceof ProxiedPlayer) {
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
|
||||
if (args.length == 0 && player.hasPermission("bungeecore.joinme")) {
|
||||
Message.broadcast("JOINME_BROADCAST", "JOINME_BROADCAST_HOVER"
|
||||
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join " + player.getName()), player.getName(), player.getServer().getInfo().getName());
|
||||
} else if (args.length == 1) {
|
||||
ProxiedPlayer target = ProxyServer.getInstance().getPlayer(args[0]);
|
||||
if(target == null || !target.isConnected()){
|
||||
Message.send("JOINME_PLAYER_OFFLINE", player);
|
||||
return;
|
||||
}else if(target.equals(player)){
|
||||
Message.send("JOINME_PLAYER_SELF", player);
|
||||
return;
|
||||
}
|
||||
ServerInfo server = target.getServer().getInfo();
|
||||
String serverPerm = BungeeCore.serverPermissions.get(server.getName());
|
||||
Subserver subserver = Subserver.getSubserver(target);
|
||||
|
||||
if(subserver != null) {
|
||||
Servertype type = subserver.getType();
|
||||
if (type == Servertype.ARENA) {
|
||||
SubserverSystem.sendPlayer(subserver, player);
|
||||
} else if (type == Servertype.BAUSERVER) {
|
||||
Bauserver bauserver = (Bauserver) subserver;
|
||||
if (bauserver.getOwner().equals(player.getUniqueId()) ||
|
||||
BauweltMember.getBauMember(bauserver.getOwner(), player.getUniqueId()) != null) {
|
||||
SubserverSystem.sendPlayer(subserver, player);
|
||||
} else {
|
||||
SubserverSystem.sendDeniedMessage(player, bauserver.getOwner());
|
||||
Message.send("JOIN_PLAYER_BLOCK", player);
|
||||
}
|
||||
}
|
||||
}else if(serverPerm != null && !player.hasPermission(serverPerm)){
|
||||
Message.send("JOIN_PLAYER_BLOCK", player);
|
||||
}else if(serverPerm == null && !player.getGroups().contains("team")) {
|
||||
Message.send("JOIN_PLAYER_BLOCK", player);
|
||||
}else{
|
||||
player.connect(server);
|
||||
}
|
||||
} else {
|
||||
Message.send("JOINME_USAGE", player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
|
||||
if(args.length == 1){
|
||||
return allPlayers(args[0]);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
68
src/de/steamwar/bungeecore/commands/KickCommand.java
Normale Datei
68
src/de/steamwar/bungeecore/commands/KickCommand.java
Normale Datei
@ -0,0 +1,68 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class KickCommand extends BasicCommand {
|
||||
|
||||
public KickCommand() {
|
||||
super("kick", "bungeecore.kick");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(args.length == 0){
|
||||
Message.send("KICK_USAGE", sender);
|
||||
return;
|
||||
}
|
||||
|
||||
ProxiedPlayer target = ProxyServer.getInstance().getPlayer(args[0]);
|
||||
if(target == null){
|
||||
Message.send("KICK_OFFLINE", sender);
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.length == 1){
|
||||
target.disconnect(Message.parseToComponent("KICK_NORMAL", true, target));
|
||||
}else{
|
||||
StringBuilder msgBuilder = new StringBuilder();
|
||||
msgBuilder.append(BungeeCore.CHAT_PREFIX).append("§c");
|
||||
for (int i = 1; i < args.length; i++){
|
||||
msgBuilder.append(args[i]).append(" ");
|
||||
}
|
||||
target.disconnect(BungeeCore.stringToText(msgBuilder.toString()));
|
||||
}
|
||||
Message.send("KICK_CONFIRM", sender, target.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
|
||||
if(args.length == 1)
|
||||
return allPlayers(args[0]);
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
74
src/de/steamwar/bungeecore/commands/ListCommand.java
Normale Datei
74
src/de/steamwar/bungeecore/commands/ListCommand.java
Normale Datei
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.Servertype;
|
||||
import de.steamwar.bungeecore.Subserver;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.connection.Server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ListCommand extends BasicCommand {
|
||||
|
||||
public ListCommand() {
|
||||
super("list", "");
|
||||
}
|
||||
|
||||
public static synchronized TreeMap<String, List<ProxiedPlayer>> getCustomTablist(){
|
||||
TreeMap<String, List<ProxiedPlayer>> playerMap = new TreeMap<>();
|
||||
for (ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) {
|
||||
Server pserver = player.getServer();
|
||||
if (pserver == null) //Happens temporarily
|
||||
continue;
|
||||
|
||||
ServerInfo server = pserver.getInfo();
|
||||
String serverName = server.getName();
|
||||
|
||||
Subserver subserver = Subserver.getSubserver(server);
|
||||
if (subserver != null && subserver.getType() == Servertype.BAUSERVER) {
|
||||
playerMap.computeIfAbsent("Bau", s -> new ArrayList<>()).add(player);
|
||||
} else {
|
||||
playerMap.computeIfAbsent(serverName, s -> new ArrayList<>()).add(player);
|
||||
}
|
||||
}
|
||||
playerMap.forEach((server, players) -> players.sort((proxiedPlayer, t1) -> proxiedPlayer.getName().compareToIgnoreCase(t1.getName())));
|
||||
return playerMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender commandSender, String[] strings) {
|
||||
TreeMap<String, List<ProxiedPlayer>> playerMap = getCustomTablist();
|
||||
for (String server : playerMap.navigableKeySet()) {
|
||||
String serverName = server;
|
||||
if (server.equals("Bau")) {
|
||||
serverName = Message.parse("TABLIST_BAU", commandSender);
|
||||
}
|
||||
Message.send("LIST_COMMAND", commandSender, serverName, playerMap.get(server).stream().map(CommandSender::getName).collect(Collectors.joining(", ")));
|
||||
}
|
||||
}
|
||||
}
|
@ -17,20 +17,23 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.velocitycore.commands;
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.velocitycore.listeners.ChatListener;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.messages.PlayerChatter;
|
||||
import de.steamwar.bungeecore.listeners.ChatListener;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public class LocalCommand extends SWCommand {
|
||||
public class LocalCommand extends BasicCommand {
|
||||
|
||||
public LocalCommand() {
|
||||
super("local", "bc", "bauchat");
|
||||
super("local", null, "bc", "bauchat");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void genericCommand(PlayerChatter player, String... message) {
|
||||
ChatListener.localChat(player, String.join(" ", message));
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
ChatListener.localChat((ProxiedPlayer) sender, String.join(" ", args));
|
||||
}
|
||||
}
|
83
src/de/steamwar/bungeecore/commands/MsgCommand.java
Normale Datei
83
src/de/steamwar/bungeecore/commands/MsgCommand.java
Normale Datei
@ -0,0 +1,83 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.listeners.ChatListener;
|
||||
import de.steamwar.bungeecore.sql.IgnoreSystem;
|
||||
import de.steamwar.messages.ChatSender;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static de.steamwar.bungeecore.Storage.lastChats;
|
||||
|
||||
public class MsgCommand extends BasicCommand {
|
||||
|
||||
public MsgCommand() {
|
||||
super("msg", "", "w", "tell");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
if (args.length < 2) {
|
||||
ChatSender.of(sender).system("MSG_USAGE");
|
||||
return;
|
||||
}
|
||||
|
||||
msg((ProxiedPlayer) sender, ProxyServer.getInstance().getPlayer(args[0]), Arrays.copyOfRange(args, 1, args.length));
|
||||
}
|
||||
|
||||
public static void msg(ProxiedPlayer player, ProxiedPlayer target, String[] args) {
|
||||
ChatSender sender = ChatSender.of(player);
|
||||
if(target == null || !target.isConnected()) {
|
||||
sender.system("MSG_OFFLINE");
|
||||
return;
|
||||
}
|
||||
|
||||
if (IgnoreSystem.isIgnored(target, player)) {
|
||||
sender.system("MSG_IGNORED");
|
||||
return;
|
||||
}
|
||||
|
||||
ChatSender receiver = ChatSender.of(target);
|
||||
ChatListener.sendChat(sender, Stream.of(sender, receiver), "CHAT_MSG", receiver, String.join(" ", args));
|
||||
lastChats.put(player, target);
|
||||
lastChats.put(target, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
|
||||
if(args.length == 1){
|
||||
return allPlayers(args[0]);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public static void remove(ProxiedPlayer player){
|
||||
lastChats.remove(player);
|
||||
}
|
||||
}
|
@ -17,21 +17,23 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.velocitycore.commands;
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.messages.PlayerChatter;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import static de.steamwar.persistent.Storage.lastChats;
|
||||
public class PingCommand extends BasicCommand {
|
||||
|
||||
public class RCommand extends SWCommand {
|
||||
|
||||
public RCommand() {
|
||||
super("r", "reply");
|
||||
public PingCommand() {
|
||||
super("ping", "");
|
||||
}
|
||||
|
||||
@Register(description = "R_USAGE")
|
||||
public void genericCommand(PlayerChatter sender, @ErrorMessage(value = "R_USAGE", allowEAs = false) String... message) {
|
||||
MsgCommand.msg(sender, lastChats.get(sender.getPlayer()), message);
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(sender instanceof ProxiedPlayer){
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
Message.send("PING_RESPONSE", player, player.getPing());
|
||||
}
|
||||
}
|
||||
}
|
@ -17,27 +17,33 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.velocitycore.commands;
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.messages.Chatter;
|
||||
import de.steamwar.sql.SteamwarUser;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import org.apache.commons.lang3.LocaleUtils;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
public class PlaytimeCommand extends SWCommand {
|
||||
public class PlaytimeCommand extends BasicCommand{
|
||||
|
||||
public PlaytimeCommand() {
|
||||
super("playtime");
|
||||
super("playtime", null);
|
||||
}
|
||||
|
||||
@Register
|
||||
public void genericCommand(Chatter sender) {
|
||||
SteamwarUser user = sender.user();
|
||||
NumberFormat format = NumberFormat.getNumberInstance(user.getLocale());
|
||||
format.setMaximumFractionDigits(2);
|
||||
String formattedText = format.format((user.getOnlinetime() / 3600d));
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] strings) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
sender.system("HOURS_PLAYED", formattedText);
|
||||
NumberFormat format = NumberFormat.getNumberInstance(((ProxiedPlayer)sender).getLocale());
|
||||
format.setMaximumFractionDigits(2);
|
||||
String formattedText = format.format((SteamwarUser.get((ProxiedPlayer) sender).getOnlinetime() / (double) 3600));
|
||||
|
||||
Message.send("HOURS_PLAYED", sender, formattedText);
|
||||
}
|
||||
}
|
@ -17,48 +17,54 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.velocitycore.commands;
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.velocitycore.listeners.PollSystem;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.command.TypeValidator;
|
||||
import de.steamwar.messages.Chatter;
|
||||
import de.steamwar.sql.PollAnswer;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.listeners.PollSystem;
|
||||
import de.steamwar.bungeecore.sql.PollAnswer;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public class PollCommand extends SWCommand {
|
||||
public class PollCommand extends BasicCommand {
|
||||
|
||||
public PollCommand() {
|
||||
super("poll");
|
||||
super("poll", "");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void genericCommand(@Validator Chatter sender) {
|
||||
PollSystem.sendPoll(sender);
|
||||
}
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
@Register(noTabComplete = true)
|
||||
public void answerPoll(@Validator Chatter sender, String answerString) {
|
||||
int answer;
|
||||
try {
|
||||
answer = Integer.parseUnsignedInt(answerString);
|
||||
if(answer < 1 || answer > PollSystem.answers())
|
||||
throw new NumberFormatException();
|
||||
}catch(NumberFormatException e){
|
||||
sender.system("POLL_NO_ANSWER");
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
|
||||
if(PollSystem.noCurrentPoll()){
|
||||
Message.send("POLL_NO_POLL", player);
|
||||
return;
|
||||
}
|
||||
|
||||
PollAnswer pollAnswer = PollAnswer.get(sender.user().getId());
|
||||
if(args.length == 0){
|
||||
PollSystem.sendPoll(player);
|
||||
return;
|
||||
}
|
||||
|
||||
int answer;
|
||||
try {
|
||||
answer = Integer.parseUnsignedInt(args[0]);
|
||||
if(answer < 1 || answer > PollSystem.answers())
|
||||
throw new NumberFormatException();
|
||||
}catch(NumberFormatException e){
|
||||
Message.send("POLL_NO_ANSWER", player);
|
||||
return;
|
||||
}
|
||||
|
||||
PollAnswer pollAnswer = PollAnswer.get(SteamwarUser.get(player.getUniqueId()).getId());
|
||||
if(pollAnswer.hasAnswered())
|
||||
sender.system("POLL_ANSWER_REFRESH");
|
||||
Message.send("POLL_ANSWER_REFRESH", player);
|
||||
else
|
||||
sender.system("POLL_ANSWER_NEW");
|
||||
Message.send("POLL_ANSWER_NEW", player);
|
||||
|
||||
pollAnswer.setAnswer(answer);
|
||||
}
|
||||
|
||||
@ClassValidator(value = Chatter.class, local = true)
|
||||
public TypeValidator<Chatter> noPoll() {
|
||||
return PollSystem.noPoll();
|
||||
}
|
||||
}
|
54
src/de/steamwar/bungeecore/commands/PollresultCommand.java
Normale Datei
54
src/de/steamwar/bungeecore/commands/PollresultCommand.java
Normale Datei
@ -0,0 +1,54 @@
|
||||
/*
|
||||
This file is a part of the SteamWar software.
|
||||
|
||||
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.listeners.PollSystem;
|
||||
import de.steamwar.bungeecore.sql.PollAnswer;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class PollresultCommand extends BasicCommand {
|
||||
|
||||
public PollresultCommand() {
|
||||
super("pollresult", "bungeecore.pollresults");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] strings) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
if(PollSystem.noCurrentPoll()) {
|
||||
Message.send("POLLRESULT_NOPOLL", sender);
|
||||
return;
|
||||
}
|
||||
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
|
||||
Map<String, Integer> voted = PollAnswer.getCurrentResults();
|
||||
Message.send("POLLRESULT_HEADER", player, voted.values().stream().reduce(Integer::sum).orElse(0), PollSystem.getQuestion());
|
||||
for (Map.Entry<String, Integer> e: voted.entrySet()) {
|
||||
Message.send("POLLRESULT_LIST", sender, e.getKey(), e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
118
src/de/steamwar/bungeecore/commands/PunishmentCommand.java
Normale Datei
118
src/de/steamwar/bungeecore/commands/PunishmentCommand.java
Normale Datei
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.sql.Punishment;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
|
||||
public class PunishmentCommand {
|
||||
|
||||
public PunishmentCommand(String command, Punishment.PunishmentType punishmentType) {
|
||||
new BasicCommand(command, "bungeecore.ban") {
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if (punishmentType.isNeedsAdmin() && !SteamwarUser.get((ProxiedPlayer) sender).getUserGroup().isAdminGroup()) {
|
||||
return;
|
||||
}
|
||||
if (args.length < 3) {
|
||||
Message.send("PUNISHMENT_USAGE", sender, command);
|
||||
return;
|
||||
}
|
||||
|
||||
SteamwarUser target = unsafeUser(sender, args[0]);
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
Timestamp banTime = parseTime(sender, args[1]);
|
||||
if (banTime == null)
|
||||
return;
|
||||
|
||||
StringBuilder reason = new StringBuilder();
|
||||
for (int i = 2; i < args.length; i++) {
|
||||
reason.append(args[i]).append(" ");
|
||||
}
|
||||
boolean isPerma = args[1].equalsIgnoreCase("perma");
|
||||
String msg = reason.toString();
|
||||
target.punish(punishmentType, banTime, msg, SteamwarUser.get(sender.getName()).getId(), isPerma);
|
||||
Message.team(punishmentType.getTeamMessage(), new Message("PREFIX"), target.getUserName(), sender.getName(), new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg);
|
||||
}
|
||||
};
|
||||
if (punishmentType.getUnpunishmentMessage() == null) {
|
||||
return;
|
||||
}
|
||||
String antiCommand = "un" + command;
|
||||
new BasicCommand(antiCommand, "bungeecore.ban") {
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if (punishmentType.isNeedsAdmin() && !SteamwarUser.get((ProxiedPlayer) sender).getUserGroup().isAdminGroup()) {
|
||||
return;
|
||||
}
|
||||
if (args.length < 1) {
|
||||
Message.send("UNPUNISHMENT_USAGE", sender, antiCommand);
|
||||
return;
|
||||
}
|
||||
|
||||
SteamwarUser target = existingUser(sender, args[0]);
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
if (!target.isPunished(punishmentType)) {
|
||||
Message.send(punishmentType.getUsageNotPunished(), sender);
|
||||
return;
|
||||
}
|
||||
|
||||
Message.send(punishmentType.getUnpunishmentMessage(), sender, target.getUserName());
|
||||
target.punish(punishmentType, Timestamp.from(new Date().toInstant()), antiCommand, SteamwarUser.get(sender.getName()).getId(), false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Timestamp parseTime(CommandSender sender, String arg) {
|
||||
if (arg.equalsIgnoreCase("perma")) {
|
||||
return Punishment.PERMA_TIME;
|
||||
} else {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy_HH:mm");
|
||||
try {
|
||||
Date parsedDate = dateFormat.parse(arg);
|
||||
return new java.sql.Timestamp(parsedDate.getTime());
|
||||
} catch (ParseException e) {
|
||||
dateFormat = new SimpleDateFormat("dd.MM.yyyy");
|
||||
try {
|
||||
Date parsedDate = dateFormat.parse(arg.split("_")[0]);
|
||||
return new java.sql.Timestamp(parsedDate.getTime());
|
||||
} catch (ParseException exception) {
|
||||
if (sender != null) {
|
||||
Message.send("INVALID_TIME", sender);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -17,24 +17,30 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.velocitycore.commands;
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import de.steamwar.velocitycore.VelocityCore;
|
||||
import de.steamwar.command.SWCommand;
|
||||
import de.steamwar.messages.PlayerChatter;
|
||||
import de.steamwar.messages.ChatSender;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public class ServerSwitchCommand extends SWCommand {
|
||||
import static de.steamwar.bungeecore.Storage.lastChats;
|
||||
|
||||
private final RegisteredServer server;
|
||||
public class RCommand extends BasicCommand {
|
||||
|
||||
public ServerSwitchCommand(String cmd, String name, String... aliases) {
|
||||
super(cmd, null, aliases);
|
||||
server = VelocityCore.getProxy().getServer(name).orElseThrow();
|
||||
public RCommand() {
|
||||
super("r", "", "reply");
|
||||
}
|
||||
|
||||
@Register
|
||||
public void genericCommand(PlayerChatter sender) {
|
||||
sender.getPlayer().createConnectionRequest(server).fireAndForget();
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
if(args.length == 0){
|
||||
ChatSender.of(sender).system("R_USAGE");
|
||||
return;
|
||||
}
|
||||
|
||||
MsgCommand.msg((ProxiedPlayer) sender, lastChats.get(sender), args);
|
||||
}
|
||||
}
|
70
src/de/steamwar/bungeecore/commands/RankCommand.java
Normale Datei
70
src/de/steamwar/bungeecore/commands/RankCommand.java
Normale Datei
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.ArenaMode;
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||
import de.steamwar.bungeecore.sql.UserElo;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class RankCommand extends BasicCommand {
|
||||
|
||||
public RankCommand() {
|
||||
super("rank", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
if (args.length > 0) {
|
||||
SteamwarUser nUser = SteamwarUser.get(args[0]);
|
||||
if (nUser == null) {
|
||||
Message.send("RANK_PLAYER_NOT_FOUND", player);
|
||||
return;
|
||||
}
|
||||
Message.send("RANK_PLAYER_FOUND", player, nUser.getUserName());
|
||||
user = nUser;
|
||||
}
|
||||
for(ArenaMode mode : ArenaMode.getAllModes()) {
|
||||
if (!mode.isRanked())
|
||||
continue;
|
||||
|
||||
Message.send("RANK_HEADER", player, mode.getChatName());
|
||||
|
||||
Optional<Integer> elo = UserElo.getElo(user.getId(), mode.getSchemType());
|
||||
|
||||
if (elo.isPresent()) {
|
||||
int placement = UserElo.getPlacement(elo.get(), mode.getSchemType());
|
||||
Message.send("RANK_PLACED", player, placement, elo.get());
|
||||
} else {
|
||||
Message.send("RANK_UNPLACED", player);
|
||||
}
|
||||
Message.send("RANK_EMBLEM", player, UserElo.getEmblemProgression(player, mode.getChatName(), user.getId()));
|
||||
}
|
||||
}
|
||||
}
|
44
src/de/steamwar/bungeecore/commands/RegelnCommand.java
Normale Datei
44
src/de/steamwar/bungeecore/commands/RegelnCommand.java
Normale Datei
@ -0,0 +1,44 @@
|
||||
/*
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.steamwar.bungeecore.commands;
|
||||
|
||||
import de.steamwar.bungeecore.Message;
|
||||
import net.md_5.bungee.api.CommandSender;
|
||||
import net.md_5.bungee.api.chat.ClickEvent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
|
||||
public class RegelnCommand extends BasicCommand {
|
||||
public RegelnCommand() {
|
||||
super("regeln", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||
|
||||
Message.send("REGELN_RULES", player);
|
||||
Message.sendPrefixless("REGELN_AS", player, Message.parse("REGELN_AS_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_AS_URL", player)));
|
||||
Message.sendPrefixless("REGELN_MWG", player, Message.parse("REGELN_MWG_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_MWG_URL", player)));
|
||||
Message.sendPrefixless("REGELN_WG", player, Message.parse("REGELN_WG_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_WG_URL", player)));
|
||||
Message.sendPrefixless("REGELN_WS", player, Message.parse("REGELN_WS_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_WS_URL", player)));
|
||||
}
|
||||
}
|
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
In neuem Issue referenzieren
Einen Benutzer sperren