12
2

Commits vergleichen

..

14 Commits

Autor SHA1 Nachricht Datum
3b0e4aa5aa Fix SchematicSearch 2023-05-01 16:12:45 +02:00
d9ad5bd14a Merge branch 'master' into schemsearch 2023-05-01 13:53:46 +02:00
1c54b1c60f Add Copyright 2023-04-13 19:02:48 +02:00
ec0c06227f Remove TestCommand 2023-04-12 02:08:59 +02:00
3bd18531f5 Update CC 2023-04-12 02:08:09 +02:00
afece3008c Merge branch 'master' into schemsearch 2023-04-12 02:05:58 +02:00
a6dbf41feb Finish it up 2023-04-12 02:05:23 +02:00
e728483e5f Merge branch 'master' into schemsearch 2023-04-09 13:39:16 +02:00
b7d42a767a idk 2023-04-06 20:42:05 +02:00
badb5e5e1e Stop the dog 2023-04-06 17:30:18 +02:00
f624d2893d Add catch for IOException 2023-04-06 17:22:20 +02:00
edb108b7b3 Add Softreload cancel 2023-04-06 17:11:17 +02:00
81dbcc691a Add Softreload cancel 2023-04-06 17:07:16 +02:00
06d3aeb9d1 Basic SchemSearch 2023-04-06 14:23:26 +02:00
232 geänderte Dateien mit 11355 neuen und 10706 gelöschten Zeilen

@ -1 +1 @@
Subproject commit d000b8687d93eb43520bbf6685281099055eab9f
Subproject commit 5aca43b35e9b9fca5252ee107e3e0d08c3c9d7fa

Datei anzeigen

@ -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'
}

Datei anzeigen

@ -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;
}
}

Datei anzeigen

@ -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();
}
}

Datei anzeigen

@ -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();
}
}

Datei anzeigen

@ -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();
}
}

Datei anzeigen

@ -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);
}
}
}
}

Datei anzeigen

@ -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) {}
}

Datei anzeigen

@ -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
}

Datei anzeigen

@ -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<>();
}

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -17,24 +17,52 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import org.apache.tools.ant.taskdefs.condition.Os
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 +78,176 @@ 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:.*')
maven {
url = uri('https://steamwar.de/maven')
}
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'
annotationProcessor 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
compileOnly 'de.steamwar:velocity:RELEASE'
compileOnly project(":Persistent")
implementation project(":CommonCore")
implementation 'org.xerial:sqlite-jdbc:3.46.0.0'
implementation 'mysql:mysql-connector-java:8.0.33'
compileOnly 'org.projectlombok:lombok:1.18.22'
testCompileOnly 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.22'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
compileOnly 'de.steamwar:waterfall:RELEASE'
compileOnly 'de.steamwar:persistentbungeecore:RELEASE'
implementation("net.dv8tion:JDA:4.4.0_352") {
exclude module: 'opus-java'
}
implementation 'org.msgpack:msgpack-core:0.9.8' //AlpineClient
implementation project(":CommonCore")
}
implementation 'com.lunarclient:apollo-api:1.1.0'
implementation 'com.lunarclient:apollo-common:1.1.0'
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
}

Datei anzeigen

@ -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')

Datei anzeigen

@ -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

Datei anzeigen

@ -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'

Datei anzeigen

@ -0,0 +1,187 @@
/*
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.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 Map<String, String> lowerToRealMapNames = new HashMap<>();
private final boolean historic;
private final String internalName;
private final boolean ranked;
private final String schemType;
private ArenaMode(String internalName, Configuration config){
this.internalName = internalName;
this.folder = config.getString("Server.Folder");
this.serverJar = config.getString("Server.ServerJar");
this.config = internalName + ".yml";
this.maps = config.getStringList("Server.Maps");
maps.forEach(map -> lowerToRealMapNames.put(map.toLowerCase(), map));
this.displayName = config.getString("GameName", internalName);
this.chatNames = config.getStringList("Server.ChatNames");
this.schemType = config.getString("Schematic.Type", "").toLowerCase();
this.ranked = config.getBoolean("Server.Ranked", false);
this.historic = config.getBoolean("Server.Historic", false);
allModes.add(this);
byInternal.put(internalName, this);
for(String name : chatNames){
byChat.put(name.toLowerCase(), this);
}
if(!this.schemType.equals(""))
bySchemType.put(SchematicType.fromDB(this.schemType), this);
}
public String getDisplayName() {
return displayName;
}
public String serverJar() {
return serverJar;
}
public String getConfig(){
return config;
}
public String hasMap(String map){
for(String m : maps){
if(m.equalsIgnoreCase(map))
return m;
}
return null;
}
public String getFolder() {
return folder;
}
public String getRandomMap(){
return maps.get(random.nextInt(maps.size()));
}
public List<String> getMaps() {
return maps;
}
public String convertToRealMapName(String map){
return lowerToRealMapNames.get(map.toLowerCase());
}
public String getChatName(){
return chatNames.get(0);
}
public boolean withoutChatName(){
return chatNames.isEmpty();
}
public boolean isHistoric(){
return historic;
}
public boolean isRanked() {
return ranked;
}
public String getSchemType() {
return schemType;
}
public String getInternalName() {
return internalName;
}
}

Datei anzeigen

@ -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() && broadCastMsgs.length > 0)
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;
}
}

Datei anzeigen

@ -0,0 +1,358 @@
/*
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.listeners.*;
import de.steamwar.bungeecore.listeners.mods.*;
import de.steamwar.bungeecore.listeners.ping.PingListener;
import de.steamwar.bungeecore.network.BungeeNetworkHandler;
import de.steamwar.bungeecore.network.NetworkReceiver;
import de.steamwar.bungeecore.network.SWScriptSyntaxForwarder;
import de.steamwar.bungeecore.util.SchematicSearch;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserElo;
import de.steamwar.bungeecore.tablist.TablistManager;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.SWTypeMapperCreator;
import de.steamwar.command.TabCompletionCache;
import de.steamwar.command.TypeMapper;
import de.steamwar.sql.Team;
import de.steamwar.sql.internal.Statement;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.ConfigurationProvider;
import net.md_5.bungee.config.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.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 boolean MAIN_SERVER;
public static String CHAT_PREFIX;
public static String LOBBY_SERVER;
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<>();
public static Node local;
private ErrorLogger errorLogger;
private TablistManager tablistManager;
@Override
public void onEnable(){
getProxy().registerChannel("sw:bridge");
getProxy().registerChannel("fabricmodsender:mods");
getProxy().registerChannel("nochatreports:sync");
getProxy().registerChannel("sw:script_syntax");
setInstance(this);
MAIN_SERVER = ProxyServer.getInstance().getConfig().getListeners().stream().anyMatch(info -> ((InetSocketAddress) info.getSocketAddress()).getPort() == 25565);
loadConfig();
errorLogger = new ErrorLogger();
SWCommandUtils.init((SWTypeMapperCreator<TypeMapper<Object>, CommandSender, Object>) (mapper, tabCompleter) -> new TypeMapper<Object>() {
@Override
public Object map(CommandSender commandSender, String[] previousArguments, String s) {
return mapper.apply(s);
}
@Override
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
return tabCompleter.apply(sender, s);
}
});
BungeeCord.getInstance().getScheduler().schedule(this, TabCompletionCache::invalidateOldEntries, 1, 1, TimeUnit.SECONDS);
new NonFabricFabricCheck();
new SWScriptSyntaxForwarder();
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 PingListener();
new SchematicSearchListener();
local = new Node.LocalNode();
if(MAIN_SERVER) {
//new Node.RemoteNode("lx");
}
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();
HelpCommand helpCommand = new HelpCommand();
new TeamCommand();
new ServerTeamchatCommand();
new DevCommand();
new EventCommand();
new EventreloadCommand();
new EventRescheduleCommand();
new PollCommand();
new BugCommand();
new WhoisCommand();
new RegelnCommand();
new IgnoreCommand();
new UnIgnoreCommand();
new PollresultCommand();
new ListCommand();
new StatCommand();
new VerifyCommand();
new GDPRQuery();
new PlaytimeCommand();
new ArenaCommand();
new RankCommand();
new LocalCommand();
new SetLocaleCommand();
new BuilderCloudCommand();
new CalendarCommand();
new CalendarListener();
new ModCommand();
// Punishment Commands:
new PunishmentCommand("ban", Punishment.PunishmentType.Ban);
new PunishmentCommand("mute", Punishment.PunishmentType.Mute);
new PunishmentCommand("noschemreceiving", Punishment.PunishmentType.NoSchemReceiving);
new PunishmentCommand("noschemsharing", Punishment.PunishmentType.NoSchemSharing);
new PunishmentCommand("noschemsubmitting", Punishment.PunishmentType.NoSchemSubmitting);
new PunishmentCommand("nodev", Punishment.PunishmentType.NoDevServer);
new PunishmentCommand("nofight", Punishment.PunishmentType.NoFightServer);
new PunishmentCommand("noteamserver", Punishment.PunishmentType.NoTeamServer);
new PunishmentCommand("note", Punishment.PunishmentType.Note);
if(!EVENT_MODE){
new BauCommand(helpCommand);
new WebpasswordCommand();
new FightCommand();
new ChallengeCommand();
new HistoricCommand();
new CheckCommand();
new ReplayCommand();
new TutorialCommand();
new Broadcaster();
}else{
new EventModeListener();
}
new EventStarter();
new SessionManager();
new NetworkReceiver();
BungeeNetworkHandler.register();
tablistManager = new TablistManager();
new SettingsChangedListener();
getProxy().getScheduler().schedule(this, () -> {
SteamwarUser.clear();
UserElo.clear();
Team.clear();
}, 1, 1, TimeUnit.HOURS);
if (SteamwarDiscordBotConfig.loaded) {
try {
new SteamwarDiscordBot();
} catch (Throwable e) {
getLogger().log(Level.SEVERE, "Could not initialize discord bot", e);
}
}
}
@Override
public void onDisable(){
if (SteamwarDiscordBotConfig.loaded) {
try {
SteamwarDiscordBot.instance().getJda().shutdown();
} catch (Throwable e) {
getLogger().log(Level.SEVERE, "Could not shutdown discord bot", e);
}
}
if(tablistManager != null)
tablistManager.disable();
errorLogger.unregister();
Statement.closeAll();
SchematicSearch.abortAll();
}
public static BungeeCore get() {
return instance;
}
public static TextComponent stringToText(String msg){
return new TextComponent(TextComponent.fromLegacyText(msg));
}
public static void send(ProxiedPlayer player, String msg){
send(player, msg, null, null);
}
public static void send(CommandSender sender, String msg){
sender.sendMessage(stringToText(msg));
}
public static void send(ProxiedPlayer player, ChatMessageType type, String msg){
send(player, type, msg, null, null);
}
public static void send(ProxiedPlayer player, String msg, String onHover, ClickEvent onClick){
send(player, ChatMessageType.SYSTEM, msg, onHover, onClick);
}
public static void send(ProxiedPlayer player, ChatMessageType type, String msg, String onHover, ClickEvent onClick){
if(type == ChatMessageType.CHAT && player.getChatMode() != ProxiedPlayer.ChatMode.SHOWN)
return;
TextComponent message = stringToText(msg);
if(onHover != null)
message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(onHover)));
if(onClick != null)
message.setClickEvent(onClick);
player.sendMessage(type, message);
}
public static void broadcast(String msg){
ProxyServer.getInstance().broadcast(stringToText(msg));
}
public static void broadcast(String msg, String onHover, ClickEvent onClick){
TextComponent message = stringToText(msg);
if(onHover != null)
message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(onHover)));
if(onClick != null)
message.setClickEvent(onClick);
ProxyServer.getInstance().broadcast(message);
}
public static void log(final ServerInfo server, final String msg){
log(server.getName() + ": " + msg);
}
public static void log(final ProxiedPlayer player, final String msg){
log(player.getName() + ": " + msg);
}
public static void log(final String msg){
log(Level.INFO, msg);
}
public static void log(final Level logLevel, final String msg){
get().getLogger().log(logLevel, msg);
}
public static void log(final String msg, final Throwable e){
get().getLogger().log(Level.SEVERE, msg, e);
}
private static void loadConfig(){
Configuration config;
try{
if(!get().getDataFolder().exists() && !get().getDataFolder().mkdir())
throw new IOException();
File configFile = new File(get().getDataFolder().getPath(), "config.yml");
if(!configFile.exists()){
boolean created = configFile.createNewFile();
if(created)
ProxyServer.getInstance().stop("Config file not initialized");
else
ProxyServer.getInstance().stop("Could not save conig file");
return;
}
config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
}catch(Exception e){
log("Could not save/load config.yml", e);
ProxyServer.getInstance().stop();
return;
}
CHAT_PREFIX = config.getString("prefix");
LOBBY_SERVER = config.getString("lobbyserver");
EVENT_MODE = config.getBoolean("eventmode");
Broadcaster.setBroadCastMsgs(config.getStringList("broadcasts").toArray(new String[1]));
PollSystem.init(config.getString("poll.question"), config.getStringList("poll.answers"));
Persistent.setChatPrefix(CHAT_PREFIX);
Persistent.setLobbyServer(LOBBY_SERVER);
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);
}
}
File discordFile = new File(System.getProperty("user.home"), "discord.yml");
if(discordFile.exists() && !EVENT_MODE) {
try {
SteamwarDiscordBotConfig.loadConfig(ConfigurationProvider.getProvider(YamlConfiguration.class).load(discordFile));
} catch (IOException e) {
get().getLogger().log(Level.SEVERE, "Could not load discord bot configuration", e);
}
}
}
private static void setInstance(BungeeCore core){
instance = core;
}
}

Datei anzeigen

@ -0,0 +1,92 @@
/*
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.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 {
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("ErrorLogger")) {
return;
}
SWException.log(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("could not decode packet");
contains.add("Connection reset by peer");
contains.add("No client connected for pending server");
contains.add("Error occurred processing connection for");
contains.add("Server is online mode!");
contains.add(" took ");
contains.add("Could not translate packet ");
ignoreContains = Collections.unmodifiableList(contains);
}
}

Datei anzeigen

@ -17,41 +17,44 @@
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 de.steamwar.persistent.Subserver;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.Team;
import net.kyori.adventure.text.event.ClickEvent;
import de.steamwar.sql.Event;
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.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
import static de.steamwar.persistent.Storage.eventServer;
import static de.steamwar.bungeecore.Storage.eventServer;
public class EventStarter {
public class EventStarter implements Runnable {
private static final Map<Integer, String> spectatePorts = new HashMap<>();
private static ScheduledTask task = null;
public static void addSpectateServer(int port, String command) {
spectatePorts.put(port, command);
}
public EventStarter() {
EventStarter(){
EventFight.loadAllComingFights();
VelocityCore.schedule(this::run).delay(10, TimeUnit.SECONDS).schedule();
if(task != null)
task.cancel();
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this, 1, 10, TimeUnit.SECONDS);
}
public static Map<Integer, Subserver> getEventServer() {
return eventServer;
}
private void run() {
eventServer.entrySet().removeIf(entry -> Subserver.getSubserver(entry.getValue().getServer()) == null);
@Override
public void run() {
eventServer.entrySet().removeIf(entry -> !Subserver.getServerList().contains(entry.getValue()));
Queue<EventFight> fights = EventFight.getFights();
EventFight next;
@ -60,20 +63,23 @@ public class EventStarter {
Team red = Team.get(next.getTeamRed());
//Don't start EventServer if not the event bungee
String command;
if(VelocityCore.get().getConfig().isEventmode() || next.getSpectatePort() == 0) {
if(BungeeCore.EVENT_MODE || !Event.get(next.getEventID()).spectateSystem()) {
ServerStarter starter = new ServerStarter().event(next);
starter.callback(subserver -> {
eventServer.put(blue.getTeamId(), subserver);
eventServer.put(red.getTeamId(), subserver);
}).start();
ProxiedPlayer leiter = ProxyServer.getInstance().getPlayer(SteamwarUser.get(next.getKampfleiter()).getUUID());
if(leiter != null)
starter.send(leiter);
command = "/event " + blue.getTeamKuerzel();
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 {
command = "/" + spectatePorts.get(next.getSpectatePort());
Message.broadcast("EVENT_FIGHT_BROADCAST", "EVENT_FIGHT_BROADCAST_HOVER",
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/spectate"), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName());
}
Chatter.broadcast().system("EVENT_FIGHT_BROADCAST", "EVENT_FIGHT_BROADCAST_HOVER", ClickEvent.runCommand(command), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName());
}
}

Datei anzeigen

@ -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;
}
}

Datei anzeigen

@ -17,13 +17,12 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.velocitycore;
package de.steamwar.bungeecore;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.ProxyServer;
import java.io.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@ -31,13 +30,7 @@ import java.util.logging.Level;
public abstract class Node {
//-Xquickstart Langzeitperformance testen!
private static final List<String> OPENJ9_ARGS = Arrays.asList(
"-XX:+EnableCRIUSupport", "-XX:-CRIURestoreNonPortableMode",
"-Xgc:excessiveGCratio=80", "-Xdisableexplicitgc", "-Xnoclassgc", "-Xmos128M", "-Xmns48M", "-XX:+ExitOnOutOfMemoryError", // initial heap half values of memory observed by 1.19 spectate server
"-Xsyslog:none", "-Xtrace:none", "-Xverify:none", "-Xdump:system:none", "-Xdump:jit:none", "-Xdump:snap:none",
"-XX:+EnableDynamicAgentLoading", "-Dlog4j.configurationFile=log4j2.xml"
);
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", "-Dio.netty.allocator.numHeapArenas=1", "-Xmos128M", "-Xmns48M"); // initial heap half values of memory observed by 1.19 spectate server
private static final Set<String> JAVA_8 = new HashSet<>();
static {
JAVA_8.add("paper-1.8.8.jar");
@ -48,6 +41,7 @@ public abstract class Node {
}
private static final long MIN_FREE_MEM = 4 * 1024 * 1024L; // 4 GiB
private static final double MAX_LOAD = 0.8;
private static final List<Node> nodes = new ArrayList<>();
@ -71,10 +65,13 @@ public abstract class Node {
protected final String hostname;
protected volatile boolean belowLoadLimit = true;
private long previousCpuLoaded = 0;
private long previousCpuTotal = 0;
protected Node(String hostname) {
this.hostname = hostname;
nodes.add(this);
VelocityCore.schedule(this::calcLoadLimit).repeat(2, TimeUnit.SECONDS).schedule();
BungeeCord.getInstance().getScheduler().schedule(BungeeCore.get(), this::calcLoadLimit, 1, 2, TimeUnit.SECONDS);
}
public void execute(String... command) {
@ -83,7 +80,7 @@ public abstract class Node {
} catch (IOException e) {
throw new SecurityException("Could not execute command", e);
} catch (InterruptedException e) {
VelocityCore.getLogger().log(Level.SEVERE, "Interrupted during execution", e);
ProxyServer.getInstance().getLogger().log(Level.SEVERE, "Interrupted during execution", e);
Thread.currentThread().interrupt();
}
}
@ -99,18 +96,17 @@ public abstract class Node {
if (JAVA_8.contains(serverJar))
cmd.add("/usr/lib/jvm/java-8-openj9-amd64/bin/java");
else
cmd.add("/usr/lib/jvm/java-21-openj9-amd64/bin/java");
cmd.add("java");
for(String param : dParams){
cmd.add("-D" + param);
}
cmd.add("-Xshareclasses:nonfatal,name=" + directory.getName());
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("-XX:-CRIUSecProvider");
}
cmd.add("-jar");
cmd.add("/binarys/" + serverJar);
@ -124,18 +120,28 @@ public abstract class Node {
cmd.add("nogui");
}
protected void calcLoadLimit(BufferedReader meminfo) throws IOException {
protected void calcLoadLimit(BufferedReader stat, BufferedReader meminfo) throws IOException {
String[] cpuline = stat.readLine().split(" "); // 0-1: prefix, 2: user, 3: nice, 4: system, 5: idle, 6: iowait, 7: irq, 8: softirq, 9: steal, 10: guest, 11: guest_nice
long cpuLoaded = Long.parseLong(cpuline[2]) + Long.parseLong(cpuline[4]) + Long.parseLong(cpuline[6]) + Long.parseLong(cpuline[7]) + Long.parseLong(cpuline[8]) + Long.parseLong(cpuline[9]) + Long.parseLong(cpuline[10]) + Long.parseLong(cpuline[11]);
long cpuTotal = cpuLoaded + Long.parseLong(cpuline[3]) + Long.parseLong(cpuline[5]);
cpuLoaded -= previousCpuLoaded;
cpuTotal -= previousCpuTotal;
previousCpuLoaded += cpuLoaded;
previousCpuTotal += cpuTotal;
String line = meminfo.readLine();
while(!line.startsWith("MemAvailable")) {
line = meminfo.readLine();
}
long availableMem = Long.parseLong(line.replaceAll(" +", " ").split(" ")[1]);
belowLoadLimit = availableMem >= MIN_FREE_MEM;
belowLoadLimit = cpuLoaded / (double)cpuTotal <= MAX_LOAD && availableMem >= MIN_FREE_MEM;
}
public static class LocalNode extends Node {
private static final File MEMINFO = new File("/proc/meminfo");
private static final File STAT = new File("/proc/stat");
public LocalNode() {
super("sw");
@ -152,10 +158,12 @@ public abstract class Node {
@Override
protected void calcLoadLimit() {
try (BufferedReader meminfo = new BufferedReader(new InputStreamReader(Files.newInputStream(MEMINFO.toPath())))) {
calcLoadLimit(meminfo);
try (BufferedReader loadavg = new BufferedReader(new InputStreamReader(new FileInputStream(STAT)))) {
try (BufferedReader meminfo = new BufferedReader(new InputStreamReader(new FileInputStream(MEMINFO)))) {
calcLoadLimit(loadavg, meminfo);
}
} catch (IOException e) {
VelocityCore.getLogger().log(Level.SEVERE, "Could not read local load", e);
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not read local load", e);
belowLoadLimit = false;
}
}
@ -170,7 +178,7 @@ public abstract class Node {
public RemoteNode(String hostname) {
super(hostname);
VelocityCore.getLogger().log(Level.INFO, "Added node {0}", hostname);
BungeeCore.get().getLogger().log(Level.INFO, "Added node " + hostname);
}
@Override
@ -199,15 +207,17 @@ public abstract class Node {
@Override
protected void calcLoadLimit() {
try {
Process process = prepareExecution("cat /proc/meminfo").start();
Process process = prepareExecution("cat /proc/stat /proc/meminfo").start();
if(!process.waitFor(1, TimeUnit.SECONDS))
throw new IOException(hostname + " timeout");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
calcLoadLimit(reader);
if(reader == null)
throw new IOException("Why reader null? " + process.getInputStream());
calcLoadLimit(reader, reader);
}
} catch (IOException e) {
if(belowLoadLimit)
VelocityCore.getLogger().log(Level.SEVERE, "Could read remote load", e);
BungeeCore.get().getLogger().log(Level.SEVERE, "Could read remote load", e);
belowLoadLimit = false;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();

Datei anzeigen

@ -1,55 +1,36 @@
/*
* 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;
package de.steamwar.velocitycore;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.Team;
import de.steamwar.sql.Tutorial;
import de.steamwar.messages.ChatSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import com.velocitypowered.api.proxy.Player;
import de.steamwar.messages.Chatter;
import de.steamwar.persistent.Arenaserver;
import de.steamwar.persistent.Bauserver;
import de.steamwar.persistent.Builderserver;
import de.steamwar.persistent.Subserver;
import de.steamwar.sql.*;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ServerStarter {
private static final Portrange BAU_PORTS = VelocityCore.MAIN_SERVER ? new Portrange(10100, 20000) : new Portrange(2100, 2200);
private static final Portrange ARENA_PORTS = VelocityCore.MAIN_SERVER ? new Portrange(3000, 3100) : (VelocityCore.get().getConfig().isEventmode() ? new Portrange(4000, 5000) : BAU_PORTS);
private static final Portrange BAU_PORTS = BungeeCore.MAIN_SERVER ? new Portrange(10100, 20000) : new Portrange(2100, 2200);
private static final Portrange ARENA_PORTS = BungeeCore.MAIN_SERVER ? new Portrange(3000, 3100) : (BungeeCore.EVENT_MODE ? new Portrange(4000, 5000) : BAU_PORTS);
public static final String SERVER_PATH = "/servers/";
private static final String SERVER_PATH = "/servers/";
private static final String USER_HOME = System.getProperty("user.home") + "/";
private static final String EVENT_PATH = USER_HOME + "event/";
public static final String TEMP_WORLD_PATH = USER_HOME + "arenaserver/";
public static final String TUTORIAL_PATH = USER_HOME + "tutorials/";
public static final String WORLDS12_PATH = USER_HOME + "userworlds/";
public static final String WORLDS15_PATH = USER_HOME + "userworlds15/";
public static final String WORLDS19_PATH = USER_HOME + "userworlds19/";
public static final String WORLDS_BASE_PATH = USER_HOME + "userworlds";
public static final String BUILDER_BASE_PATH = USER_HOME + "builder";
private File directory = null;
@ -67,17 +48,15 @@ public class ServerStarter {
private boolean allowMerge = false;
private String fightMap = null;
private String gameMode = null;
private boolean checkpoint = false;
private ServerConstructor constructor = (serverName, port, builder, shutdownCallback, failureCallback) -> new Arenaserver(serverName, gameMode, fightMap, allowMerge, port, builder, shutdownCallback);
private Consumer<Subserver> callback = subserver -> {};
private ServerConstructor constructor = (serverName, port, builder, shutdownCallback) -> new Arenaserver(serverName, gameMode, fightMap, allowMerge, port, builder, shutdownCallback);
private final Set<Player> playersToSend = new HashSet<>();
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.getGameName() + (port - portrange.start);
serverJar = mode.getServerJar();
serverNameProvider = port -> mode.getDisplayName() + (port - portrange.start);
serverJar = mode.serverJar();
allowMerge = true;
fightMap = map;
gameMode = mode.getInternalName();
@ -89,7 +68,7 @@ public class ServerStarter {
public ServerStarter event(EventFight eventFight) {
arena(ArenaMode.getByInternal(eventFight.getSpielmodus()), eventFight.getMap());
node = VelocityCore.local;
node = BungeeCore.local;
worldDir = EVENT_PATH;
worldCleanup = () -> {};
arguments.put("fightID", String.valueOf(eventFight.getFightID()));
@ -102,7 +81,7 @@ public class ServerStarter {
return this;
}
public ServerStarter test(ArenaMode mode, String map, Player owner) {
public ServerStarter test(ArenaMode mode, String map, ProxiedPlayer owner) {
arena(mode, map);
buildWithTemp(owner);
portrange = BAU_PORTS;
@ -110,12 +89,12 @@ public class ServerStarter {
return send(owner);
}
public ServerStarter blueLeader(Player player) {
public ServerStarter blueLeader(ProxiedPlayer player) {
arguments.put("blueLeader", player.getUniqueId().toString());
return send(player);
}
public ServerStarter redLeader(Player player) {
public ServerStarter redLeader(ProxiedPlayer player) {
arguments.put("redLeader", player.getUniqueId().toString());
return send(player);
}
@ -135,46 +114,34 @@ public class ServerStarter {
return this;
}
public ServerStarter build(ServerVersion version, UUID owner) {
directory = version.getServerDirectory("Bau");
serverJar = version.getServerJar();
worldDir = version.getWorldFolder(WORLDS_BASE_PATH);
worldName = version != ServerVersion.SPIGOT_12 ? String.valueOf(SteamwarUser.get(owner).getId()) : owner.toString();
checkpoint = true;
build(owner);
worldSetup = () -> {
File world = new File(worldDir, worldName);
if (!world.exists())
copyWorld(node, new File(directory, "Bauwelt").getPath(), world.getPath());
};
// Send players to existing server
startCondition = () -> {
Bauserver subserver = Bauserver.get(owner);
if(subserver != null) {
for(Player p : playersToSend)
SubserverSystem.sendPlayer(subserver, p);
return false;
}
boolean atLeastOneSupervisor = playersToSend.stream().anyMatch(player -> {
if (player.getUniqueId().equals(owner)) return true;
BauweltMember bauweltMember = BauweltMember.getBauMember(owner, player.getUniqueId());
return bauweltMember.isSupervisor();
});
if (!atLeastOneSupervisor) {
for (Player p : playersToSend) {
Chatter.of(p).system("BAU_START_NOT_ALLOWED");
}
}
return atLeastOneSupervisor;
};
public ServerStarter build19(UUID owner) {
directory = new File(SERVER_PATH, "Bau19");
serverJar = "paper-1.19.3.jar";
worldDir = WORLDS19_PATH;
worldName = String.valueOf(SteamwarUser.get(owner).getId());
buildWithWorld(owner, new File(directory, "Bauwelt").getPath());
return this;
}
public ServerStarter tutorial(Player owner, Tutorial tutorial) {
public ServerStarter build15(UUID owner) {
directory = new File(SERVER_PATH, "Bau15");
worldDir = WORLDS15_PATH;
worldName = String.valueOf(SteamwarUser.get(owner).getId());
buildWithWorld(owner, new File(directory, "Bauwelt").getPath());
return this;
}
public ServerStarter build12(UUID owner) {
directory = new File(SERVER_PATH, "Bau12");
serverJar = "spigot-1.12.2.jar";
xmx = "256M";
worldDir = WORLDS12_PATH;
worldName = owner.toString();
buildWithWorld(owner, new File(directory, "Bauwelt").getPath());
return this;
}
public ServerStarter tutorial(ProxiedPlayer owner, Tutorial tutorial) {
directory = new File(SERVER_PATH, "Tutorial");
buildWithTemp(owner);
tempWorld(TUTORIAL_PATH + tutorial.getTutorialId());
@ -188,7 +155,29 @@ public class ServerStarter {
worldCleanup = () -> SubserverSystem.deleteFolder(node, worldDir + worldName);
}
private void buildWithTemp(Player owner) {
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
@ -196,35 +185,38 @@ public class ServerStarter {
if(startingBau(owner))
return false;
Bauserver subserver = Bauserver.get(owner.getUniqueId());
if(subserver != null && subserver.isStarted())
subserver.stop();
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, failureCallback) -> new Bauserver(serverName, owner, port, builder, shutdownCallback, failureCallback);
constructor = (serverName, port, builder, shutdownCallback) -> new Bauserver(serverName, owner, port, builder, shutdownCallback);
serverNameProvider = port -> bauServerName(SteamwarUser.get(owner));
}
public ServerStarter builder(ServerVersion version, String map, File generator) {
public ServerStarter builder(Version version, String map, File generator) {
serverJar = version.getServerJar();
directory = version.getServerDirectory("Builder");
worldDir = version.getWorldFolder(BUILDER_BASE_PATH);
worldName = map;
serverNameProvider = port -> "*" + map;
checkpoint = true;
constructor = (serverName, port, builder, shutdownCallback, failureCallback) -> new Builderserver(serverName, worldName, port, builder, shutdownCallback, failureCallback);
serverNameProvider = port -> "" + map;
constructor = (serverName, port, builder, shutdownCallback) -> new Builderserver(serverName, worldName, port, builder, shutdownCallback);
// Send players to existing server
startCondition = () -> {
Builderserver subserver = Builderserver.get(worldName);
if (subserver != null) {
for(Player p : playersToSend)
SubserverSystem.sendPlayer(subserver, p);
return false;
for(Subserver subserver : Subserver.getServerList()) {
if(subserver.getType() == Servertype.BUILDER && ((Builderserver)subserver).getMap().equals(worldName)) {
for(ProxiedPlayer p : playersToSend)
SubserverSystem.sendPlayer(subserver, p);
return false;
}
}
return true;
};
@ -243,19 +235,14 @@ public class ServerStarter {
return this;
}
public ServerStarter send(Player player) {
public ServerStarter send(ProxiedPlayer player) {
playersToSend.add(player);
return this;
}
public ServerStarter callback(Consumer<Subserver> callback) {
this.callback = callback;
return this;
}
public boolean start() {
public Subserver start() {
if(!startCondition.getAsBoolean())
return false;
return null;
int port = portrange.freePort();
String serverName = serverNameProvider.apply(port);
@ -263,10 +250,10 @@ public class ServerStarter {
if(node == null) {
node = Node.getNode();
if(node == null) {
for (Player p : playersToSend)
Chatter.of(p).system("SERVER_START_OVERLOAD");
for (ProxiedPlayer p : playersToSend)
ChatSender.of(p).system("SERVER_START_OVERLOAD");
return false;
return null;
}
}
if(worldName == null)
@ -275,45 +262,22 @@ public class ServerStarter {
worldSetup.run();
arguments.put("logPath", worldName);
File checkpointDir = new File("/tmp/" + System.getProperty("user.name") + ".checkpoints/" + directory.getName() + "/" + worldName);
if(checkpoint)
arguments.put("checkpoint", checkpointDir.getPath());
if(checkpoint && checkpointDir.exists()) {
try(DataOutputStream out = new DataOutputStream(Files.newOutputStream(new File(checkpointDir, "port").toPath()))) {
out.writeInt(port);
} catch (IOException e) {
throw new SecurityException(e);
}
postStart(constructor.construct(serverName, port, node.prepareExecution(
"criu", "restore", "-D", checkpointDir.getPath(), "--auto-dedup", "--shell-job", "-v"
), worldCleanup, e -> regularStart(serverName, port)));
} else {
regularStart(serverName, port);
}
return true;
}
private void regularStart(String serverName, int port) {
postStart(constructor.construct(serverName, port, node.startServer(
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, null));
}
), worldCleanup);
private void postStart(Subserver subserver) {
for(Player p : playersToSend)
for(ProxiedPlayer p : playersToSend)
SubserverSystem.sendPlayer(subserver, p);
callback.accept(subserver);
return subserver;
}
private static boolean startingBau(Player p) {
Bauserver subserver = Bauserver.get(p.getUniqueId());
if(subserver != null && !subserver.isStarted()) {
Chatter.of(p).system("BAU_START_ALREADY");
return true;
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;
}
@ -331,7 +295,7 @@ public class ServerStarter {
}
private interface ServerConstructor {
Subserver construct(String serverName, int port, ProcessBuilder builder, Runnable shutdownCallback, Consumer<Exception> failureCallback);
Subserver construct(String serverName, int port, ProcessBuilder builder, Runnable shutdownCallback);
}
private static class Portrange {
@ -357,7 +321,7 @@ public class ServerStarter {
Set<Integer> usedPorts;
synchronized (Subserver.getServerList()) {
usedPorts = Subserver.getServerList().stream().map(server -> server.getServer().getAddress().getPort()).collect(Collectors.toSet());
usedPorts = Subserver.getServerList().stream().map(server -> ((InetSocketAddress) server.getServer().getSocketAddress()).getPort()).collect(Collectors.toSet());
}
while(usedPorts.contains(current)) {
@ -370,4 +334,29 @@ public class ServerStarter {
}
}
public enum Version {
SPIGOT_12("spigot-1.12.2.jar", 12),
SPIGOT_15("spigot-1.15.2.jar", 15),
PAPER_19("paper-1.19.3.jar", 19);
private final String serverJar;
private final int versionSuffix;
Version(String serverJar, int versionSuffix) {
this.serverJar = serverJar;
this.versionSuffix = versionSuffix;
}
public String getServerJar() {
return serverJar;
}
public String getWorldFolder(String base) {
return base + versionSuffix + "/";
}
public File getServerDirectory(String base) {
return new File(SERVER_PATH, base + versionSuffix);
}
}
}

Datei anzeigen

@ -17,18 +17,16 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.velocitycore;
package de.steamwar.bungeecore;
import com.velocitypowered.api.proxy.Player;
import de.steamwar.velocitycore.network.NetworkSender;
import de.steamwar.velocitycore.network.handlers.FightInfoHandler;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.Message;
import de.steamwar.network.packets.server.StartingServerPacket;
import de.steamwar.persistent.Subserver;
import de.steamwar.bungeecore.network.NetworkSender;
import de.steamwar.bungeecore.network.handlers.FightInfoHandler;
import de.steamwar.sql.IgnoreSystem;
import de.steamwar.sql.SteamwarUser;
import net.kyori.adventure.text.event.ClickEvent;
import de.steamwar.network.packets.server.StartingServerPacket;
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;
@ -39,20 +37,23 @@ public class SubserverSystem {
node.execute("rm", "-r", worldName);
}
public static void sendDeniedMessage(Chatter p, UUID owner) {
if(IgnoreSystem.isIgnored(owner, p.user().getUUID())){
p.system("SERVER_IGNORED");
public static void sendDeniedMessage(ProxiedPlayer p, UUID owner){
ProxiedPlayer o = ProxyServer.getInstance().getPlayer(owner);
if(o == null)
return;
if(IgnoreSystem.isIgnored(owner, p.getUniqueId())){
Message.send("SERVER_IGNORED", p);
return;
}
Chatter o = Chatter.of(owner);
o.system("SERVER_ADD_MEMBER", p);
o.prefixless("SERVER_ADD_MESSAGE", new Message("SERVER_ADD_MESSAGE_HOVER"), ClickEvent.runCommand("/bau addmember " + p.user().getUserName()));
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, Player player) {
public static void sendPlayer(Subserver subserver, ProxiedPlayer player) {
subserver.sendPlayer(player);
if(!subserver.isStarted() && FightInfoHandler.onLobby(player))
if(!subserver.hasStarted() && FightInfoHandler.onLobby(player))
NetworkSender.send(player, new StartingServerPacket(SteamwarUser.get(player.getUniqueId()).getId()));
}
}

Datei anzeigen

@ -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.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;
}
}
}

Datei anzeigen

@ -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.messages.ChatSender;
import de.steamwar.sql.Event;
import lombok.Getter;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction;
import net.dv8tion.jda.api.utils.MemberCachePolicy;
import net.md_5.bungee.api.ProxyServer;
import javax.security.auth.login.LoginException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
public class SteamwarDiscordBot {
private static SteamwarDiscordBot INSTANCE;
public static SteamwarDiscordBot instance() {
return INSTANCE;
}
@Getter
private volatile AnnouncementListener announcementListener;
@Getter
private volatile DiscordChatListener ingameChatListener;
@Getter
private volatile DiscordChatListener serverTeamChatListener;
@Getter
private final JDA jda;
@Getter
private static Map<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);
}
}

Datei anzeigen

@ -0,0 +1,66 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <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.sql.SteamwarUser;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import java.sql.Timestamp;
public class BanCommand extends BasicDiscordCommand {
public BanCommand() {
super("ban", "Banne einen Nutzer, wenn du die Rechte hast.");
addOption(OptionType.STRING, "user", "Der Benutzer", true);
addOption(OptionType.STRING, "time", "Bis Wann", true);
addOption(OptionType.STRING, "reason", "Warum", true);
}
@Override
public void run(SlashCommandEvent event) {
if (!testPermission(event)) {
return;
}
SteamwarUser sender = SteamwarUser.get(event.getMember().getIdLong());
SteamwarUser target = PunishmentCommand.getOrCreateOfflinePlayer(event.getOption("user").getAsString());
if (target == null) {
event.reply("Angegebener User invalide").setEphemeral(true).queue();
return;
}
Timestamp time = PunishmentCommand.parseTime(null, event.getOption("time").getAsString());
if (time == null) {
event.reply("Angegebene Zeit invalide").setEphemeral(true).queue();
return;
}
String msg = event.getOption("reason").getAsString();
boolean isPerma = event.getOption("time").getAsString().equals("perma");
PunishmentCommand.ban(target, time, msg, sender, isPerma);
Message.team("BAN_TEAM", new Message("PREFIX"), target.getUserName(), sender.getUserName(), new Message((isPerma ? "BAN_PERMA" : "BAN_UNTIL"), time), msg);
event.reply("Erfolgreich " + target.getUserName() + (isPerma ? " permanent" : " bis " + time) + " gebannt").setEphemeral(true).queue();
}
}

Datei anzeigen

@ -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.sql.SteamwarUser;
import de.steamwar.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;
}
}

Datei anzeigen

@ -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();
}
}

Datei anzeigen

@ -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.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import java.sql.Timestamp;
public class MuteCommand extends BasicDiscordCommand {
public MuteCommand() {
super("mute", "Mute einen Nutzer, wenn du die Rechte hast.");
addOption(OptionType.STRING, "user", "Der Benutzer", true);
addOption(OptionType.STRING, "time", "Bis Wann", true);
addOption(OptionType.STRING, "reason", "Warum", true);
}
@Override
public void run(SlashCommandEvent event) {
if (!testPermission(event)) {
return;
}
SteamwarUser sender = SteamwarUser.get(event.getMember().getIdLong());
SteamwarUser target = PunishmentCommand.getOrCreateOfflinePlayer(event.getOption("user").getAsString());
if (target == null) {
event.reply("Angegebener User invalide").setEphemeral(true).complete();
return;
}
Timestamp time = PunishmentCommand.parseTime(null, event.getOption("time").getAsString());
if (time == null) {
event.reply("Angegebene Zeit invalide").setEphemeral(true).complete();
return;
}
String msg = event.getOption("reason").getAsString();
boolean isPerma = event.getOption("time").getAsString().equals("perma");
target.punish(Punishment.PunishmentType.Mute, time, msg, sender.getId(), isPerma);
Message.team("MUTE_TEAM", new Message("PREFIX"), target.getUserName(), sender.getUserName(), new Message((isPerma ? "BAN_PERMA" : "BAN_UNTIL"), time), msg);
event.reply("Erfolgreich " + target.getUserName() + (isPerma ? " permanent" : " bis " + time) + " gemutet").setEphemeral(true).queue();
}
}

Datei anzeigen

@ -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.sql.Event;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.Team;
import de.steamwar.sql.TeamTeilnahme;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.SubcommandData;
import net.md_5.bungee.api.ProxyServer;
import java.awt.*;
import java.util.List;
import java.util.stream.Collectors;
public class TeamCommand extends BasicDiscordCommand {
public TeamCommand() {
super("team", "Alle Team bezogenen Befehle");
addSubcommands(new SubcommandData("info", "Infos über das Team oder deins")
.addOption(OptionType.STRING, "team", "Name oder Kuerzel", false)
);
}
private Emoji emoji = Emoji.fromUnicode("U+1F7E2");
@Override
public void run(SlashCommandEvent event) {
SteamwarUser steamwarUser = getSteamwarUser(event);
if (event.getSubcommandName() != null) {
switch (event.getSubcommandName()) {
case "info":
OptionMapping optionMapping = event.getOption("team");
Team team;
if (optionMapping == null) {
if (steamwarUser == null) {
event.reply("Dein Discord ist nicht verknüpft").setEphemeral(true).queue();
return;
}
if (steamwarUser.getTeam() == 0) {
event.reply("Du bist in keinem Team").setEphemeral(true).queue();
return;
}
team = Team.get(steamwarUser.getTeam());
} else {
team = Team.get(optionMapping.getAsString());
}
if (team == null) {
event.reply("Unbekanntes Team").setEphemeral(true).queue();
return;
}
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setTitle("Team: " + team.getTeamName() + " [" + team.getTeamKuerzel() + "]");
embedBuilder.setColor(Color.GRAY);
List<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;
}
}

Datei anzeigen

@ -0,0 +1,62 @@
/*
* 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.commands.PunishmentCommand;
import de.steamwar.sql.BannedUserIPs;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import java.sql.Timestamp;
import java.util.Date;
public class UnbanCommand extends BasicDiscordCommand {
public UnbanCommand() {
super("unban", "Entbannt einen Nutzer, wenn du die Rechte hast.");
addOption(OptionType.STRING, "user", "Der Benutzer", true);
}
@Override
public void run(SlashCommandEvent event) {
if (!testPermission(event)) {
return;
}
SteamwarUser sender = SteamwarUser.get(event.getMember().getIdLong());
SteamwarUser target = PunishmentCommand.getOrCreateOfflinePlayer(event.getOption("user").getAsString());
if (target == null) {
event.reply("Angegebener User invalide").setEphemeral(true).queue();
return;
}
if (!target.isPunished(Punishment.PunishmentType.Ban)) {
event.reply("Angegebener User ist nicht gebannt").setEphemeral(true).queue();
return;
}
target.punish(Punishment.PunishmentType.Ban, Timestamp.from(new Date().toInstant()), "Unban", sender.getId(), false);
BannedUserIPs.unbanIPs(target.getId());
event.reply("Erfolgreich " + target.getUserName() + " entbannt").setEphemeral(true).queue();
}
}

Datei anzeigen

@ -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.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.Team;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.interactions.commands.OptionType;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.List;
public class WhoisCommand extends BasicDiscordCommand {
public WhoisCommand() {
super("whois", "Der whois Befehl");
addOption(OptionType.STRING, "user", "Der Benutzer", true);
}
@Override
public void run(SlashCommandEvent event) {
if (!testPermission(event)) {
return;
}
String s = event.getOption("user").getAsString();
SteamwarUser user = SteamwarUser.get(s);
if (user == null) {
try {
int id = Integer.parseInt(s);
user = SteamwarUser.get(id);
} catch (NumberFormatException ignored) {
// Ignored
}
}
if (user == null) {
try {
long id = Long.parseLong(s);
user = SteamwarUser.get(id);
} catch (NumberFormatException ignored) {
// Ignored
}
}
if (user == null) {
event.reply("Der angegebene Spieler ist unbekannt").setEphemeral(true).complete();
return;
}
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setTitle("Whois: " + user.getUserName());
StringBuilder st = new StringBuilder();
st.append("UUID: ").append(user.getUUID()).append("\n");
st.append("ID: ").append(user.getId()).append("\n");
if (user.getDiscordId() != null) {
st.append("DiscordID: ").append(user.getDiscordId()).append("\n");
}
Timestamp timestamp = user.getFirstjoin();
st.append("Beigetreten am: ").append(timestamp == null ? "0000-00-00 00:00:00" : timestamp.toString()).append("\n");
st.append("Online Time: ").append(new DecimalFormat("###.##").format(user.getOnlinetime() / (double) 3600)).append("h\n");
Team team = Team.get(user.getTeam());
st.append("Team: [").append(team.getTeamKuerzel()).append("] ").append(team.getTeamName());
embedBuilder.addField("Daten:", st.toString(), false);
List<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();
}
}

Datei anzeigen

@ -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));
}
}

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -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);
}
}

Datei anzeigen

@ -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.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;
}
}

Datei anzeigen

@ -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.bungeecore.bot.SteamwarDiscordBot;
import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.Team;
import de.steamwar.sql.TeamTeilnahme;
import de.steamwar.sql.Event;
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();
}
}
}

Datei anzeigen

@ -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.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();
}
}
}

Datei anzeigen

@ -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();
}
}

Datei anzeigen

@ -1,6 +1,6 @@
/*
/*
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
@ -15,15 +15,16 @@
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.velocitycore.listeners;
package de.steamwar.bungeecore.bot.listeners;
import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
public abstract class BasicListener {
public abstract class BasicDiscordListener extends ListenerAdapter {
protected BasicListener() {
VelocityCore.getProxy().getEventManager().register(VelocityCore.get(), this);
BasicDiscordListener() {
SteamwarDiscordBot.instance().addListener(this);
}
}

Datei anzeigen

@ -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.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();
}
}
}
}
}

Datei anzeigen

@ -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.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.messages.ChatSender;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import org.jetbrains.annotations.NotNull;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class DiscordChatListener extends BasicDiscordListener {
private final String channel;
private final String format;
private final Supplier<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();
}
}

Datei anzeigen

@ -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.sql.SteamwarUser;
import de.steamwar.sql.Team;
import de.steamwar.sql.TeamTeilnahme;
import de.steamwar.sql.Event;
import net.dv8tion.jda.api.events.interaction.SelectionMenuEvent;
import net.dv8tion.jda.api.interactions.components.Component;
import org.jetbrains.annotations.NotNull;
import java.time.Instant;
public class DiscordEventListener extends BasicDiscordListener {
@Override
public void onSelectionMenu(@NotNull SelectionMenuEvent event) {
if(event.getChannel().getId().equals(SteamwarDiscordBotConfig.EVENTS_CHANNEL) && event.getComponentType() == Component.Type.SELECTION_MENU) {
if(event.getSelectedOptions().isEmpty()) {
event.deferReply(true).queue();
return;
}
if(event.getSelectedOptions().get(0).getValue().matches("([0-9]+)")) {
SteamwarUser user = SteamwarUser.get(event.getUser().getIdLong());
if(user == null) {
event.reply("Du hast dein Minecraft nicht verknüpft").setEphemeral(true).queue();
return;
}
if(user.getTeam() == 0) {
event.reply("Du bist in keinem Team").setEphemeral(true).queue();
return;
}
if(!user.isLeader()) {
event.reply("Du bist kein Leader in deinem Team").setEphemeral(true).queue();
return;
}
if(Event.get() != null) {
event.reply("Du kannst dich nicht während einem Event an einem Event anmelden").setEphemeral(true).queue();
return;
}
Event swEvent = Event.get(Integer.decode(event.getSelectedOptions().get(0).getValue()));
if(swEvent == null){
event.reply("Das Event gibt es nicht").setEphemeral(true).queue();
return;
}
if(Instant.now().isAfter(swEvent.getDeadline().toInstant())){
event.reply("Du kannst dich nicht mehr an diesen Event anmelden").setEphemeral(true).queue();
return;
}
Team team = Team.get(user.getTeam());
if(TeamTeilnahme.nimmtTeil(team.getTeamId(), swEvent.getEventID())){
TeamTeilnahme.notTeilnehmen(team.getTeamId(), swEvent.getEventID());
event.reply("Dein Team **" + team.getTeamName() + "** nimmt nun nicht mehr an **" + swEvent.getEventName() + "** teil!").setEphemeral(true).queue();
}else{
TeamTeilnahme.teilnehmen(team.getTeamId(), swEvent.getEventID());
event.reply("Dein Team **" + team.getTeamName() + "** nimmt nun an **" + swEvent.getEventName() + "** teil!").setEphemeral(true).queue();
}
EventManager.update();
} else {
event.reply("Lefuq?").setEphemeral(true).queue();
}
}
}
}

Datei anzeigen

@ -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.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.getUniqueId());
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());
}
});
}
}
}
}

Datei anzeigen

@ -0,0 +1,80 @@
/*
* 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.sql.NodeData;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent;
import java.io.InputStream;
public class PrivateMessageListener extends BasicDiscordListener {
@Override
public void onPrivateMessageReceived(PrivateMessageReceivedEvent event) {
if(!event.getMessage().getAttachments().isEmpty()) {
SteamwarUser user = SteamwarUser.get(event.getAuthor().getIdLong());
if (user == null) {
event.getMessage().reply("Du must dein Minecraft Account mit dem Bot verbinden, gehe dazu auf dem SteamWar Discord in den `regeln-infos` Channel und Klicke auf `Minecraft Verknüpfen`").complete();
return;
}
if(user.isPunished(Punishment.PunishmentType.NoSchemReceiving)) {
event.getMessage().reply("Du darfst keine Schematics hochladen").complete();
return;
}
for (Message.Attachment attachment : event.getMessage().getAttachments()) {
if(attachment.getFileExtension() == null ||
(!attachment.getFileExtension().equalsIgnoreCase("schem") &&
!attachment.getFileExtension().equalsIgnoreCase("schematic"))) {
event.getMessage().reply("`" + attachment.getFileName() + "` wird ignoriert, da die Datei keine Schematic ist").queue();
continue;
}
boolean newFormat = attachment.getFileExtension().equalsIgnoreCase("schem");
int dot = attachment.getFileName().lastIndexOf(".");
String name = attachment.getFileName().substring(0, dot);
if(SchematicNode.invalidSchemName(new String[] {name})) {
event.getMessage().reply("`" + name + "` hat nicht zugelassene Zeichen im Namen").queue();
continue;
}
SchematicNode node = SchematicNode.getSchematicNode(user.getId(), name, (Integer) null);
if(node == null) {
node = SchematicNode.createSchematic(user.getId(), name, null);
}
try {
InputStream in = attachment.retrieveInputStream().get();
NodeData.get(node).saveFromStream(in, newFormat);
in.close();
event.getMessage().reply("`" + name + "` wurde erfolgreich hochgeladen").queue();
} catch (Exception e) {
event.getMessage().reply("`" + name + "` konnte nicht hochgeladen werden, bitte versuche es später nochmal oder wende dich an einen Developer").queue();
BungeeCore.log("Could not Upload Schem \"" + name + "\" from User \"" + user.getUserName() + "\"", e);
}
}
}
}
}

Datei anzeigen

@ -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();
}
}
}
}

Datei anzeigen

@ -0,0 +1,32 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore.bot.listeners;
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import org.jetbrains.annotations.NotNull;
public class SlashCommandListener extends BasicDiscordListener {
@Override
public void onSlashCommand(@NotNull SlashCommandEvent event) {
SteamwarDiscordBot.getDiscordCommandMap().get(event.getName()).run(event);
}
}

Datei anzeigen

@ -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.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);
}
}
});
}
}

Datei anzeigen

@ -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();
}
}
}

Datei anzeigen

@ -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();
}
}
}

Datei anzeigen

@ -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.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import lombok.experimental.UtilityClass;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.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
}
}
}
}

Datei anzeigen

@ -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;
}
}

Datei anzeigen

@ -17,30 +17,32 @@
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.discord.DiscordBot;
import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter;
import de.steamwar.sql.UserPerm;
import de.steamwar.messages.ChatSender;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
public class AlertCommand extends SWCommand {
public AlertCommand() {
super("alert", UserPerm.MODERATION, "broadcast", "bbc");
super("alert", "bungeecore.alert", "broadcast", "bbc");
}
@Register(description = "USAGE_ALERT")
public void broadcast(Chatter sender, @OptionalValue("") @StaticValue("-discord") String sendToDiscord, String... message) {
public void broadcast(CommandSender sender, @OptionalValue("") @StaticValue("-discord") String sendToDiscord, String... message) {
if (message.length == 0) {
sender.system("USAGE_ALERT");
ChatSender.of(sender).system(new Message("USAGE_ALERT"));
return;
}
String s = String.join(" ", message);
Chatter.broadcast().system("ALERT", s.replace('&', '§'));
if ("-discord".equals(sendToDiscord))
DiscordBot.withBot(bot -> bot.getAnnouncementChannel().send(s));
Message.broadcast("ALERT", ChatColor.translateAlternateColorCodes('&', s));
if ("-discord".equals(sendToDiscord) && SteamwarDiscordBot.instance() != null) {
SteamwarDiscordBot.instance().getAnnouncementListener().announce(s);
}
}
}

Datei anzeigen

@ -17,20 +17,19 @@
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.persistent.Servertype;
import de.steamwar.persistent.Subserver;
import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.command.PreviousArguments;
import de.steamwar.bungeecore.Servertype;
import de.steamwar.bungeecore.Subserver;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.PlayerChatter;
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.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class ArenaCommand extends SWCommand {
@ -39,32 +38,32 @@ public class ArenaCommand extends SWCommand {
}
@Register
public void arenaJoin(PlayerChatter sender, Subserver server) {
TpCommand.teleport(sender, server.getRegisteredServer());
public void arenaJoin(ProxiedPlayer player, Subserver server) {
TpCommand.teleport(player, server.getServer());
}
@ClassMapper(value = Subserver.class, local = true)
public TypeMapper<Subserver> serverInfoTypeMapper() {
return new TypeMapper<>() {
return new TypeMapper<Subserver>() {
@Override
public Subserver map(Chatter sender, PreviousArguments previousArguments, String s) {
return Subserver.getSubserver(VelocityCore.getProxy().getServer(s).map(RegisteredServer::getServerInfo).orElse(null));
public Subserver map(CommandSender commandSender, String[] previousArguments, String s) {
return Subserver.getSubserver(ProxyServer.getInstance().getServerInfo(s));
}
@Override
public boolean validate(Chatter sender, Subserver value, MessageSender messageSender) {
public boolean validate(CommandSender sender, Subserver value, MessageSender messageSender) {
if (value == null || value.getType() != Servertype.ARENA) {
sender.system("ARENA_NOT_FOUND");
messageSender.send("ARENA_NOT_FOUND");
return false;
}
return true;
}
@Override
public Collection<String> tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) {
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
List<Subserver> subserverList = Subserver.getServerList();
synchronized (subserverList) {
return subserverList.stream().filter(subserver -> subserver.getType() == Servertype.ARENA).map(subserver -> subserver.getServer().getName()).toList();
return subserverList.stream().filter(subserver -> subserver.getType() == Servertype.ARENA).map(subserver -> subserver.getServer().getName()).collect(Collectors.toList());
}
}
};

Datei anzeigen

@ -0,0 +1,336 @@
/*
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.network.NetworkSender;
import de.steamwar.bungeecore.util.BauLock;
import de.steamwar.bungeecore.util.Chat19;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
import de.steamwar.command.TypeValidator;
import de.steamwar.messages.ChatSender;
import de.steamwar.network.packets.server.BaumemberUpdatePacket;
import de.steamwar.bungeecore.util.BauLockState;
import de.steamwar.sql.BauweltMember;
import de.steamwar.sql.SteamwarUser;
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.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class BauCommand extends SWCommand {
private final HelpCommand command;
public BauCommand(HelpCommand command){
super("bau", null, "b", "build", "gs");
this.command = command;
}
@Register(noTabComplete = true)
public void genericHelp(ProxiedPlayer p, String... args) {
this.command.sendBauHelp(p);
}
@Register
public void toBau(ProxiedPlayer p, @Mapper("version") @OptionalValue(value = "", onlyUINIG = true) int version) {
versionSelector(version,
() -> new ServerStarter().build12(p.getUniqueId()).send(p).start(),
() -> new ServerStarter().build15(p.getUniqueId()).send(p).start(),
() -> new ServerStarter().build19(p.getUniqueId()).send(p).start()
);
}
public void versionSelector(int version, Runnable r12, Runnable r15, Runnable r19) {
switch (version) {
case 12:
r12.run();
break;
case 15:
r15.run();
break;
case 19:
r19.run();
break;
}
}
@Mapper(value = "version", local = true)
public TypeMapper<Integer> versionMapper() {
Map<String, Integer> versionMap = new HashMap<>();
versionMap.put("19", 19);
versionMap.put("1.19", 19);
versionMap.put("mwg", 19);
versionMap.put("miniwargear", 19);
versionMap.put("wg", 19);
versionMap.put("wargear", 19);
versionMap.put("ws", 15);
versionMap.put("15", 15);
versionMap.put("1.15", 15);
versionMap.put("warship", 15);
versionMap.put("as", 15);
versionMap.put("airship", 15);
versionMap.put("12", 12);
versionMap.put("1.12", 12);
return new TypeMapper<Integer>() {
@Override
public Integer map(CommandSender commandSender, String[] previousArguments, String s) {
if (commandSender == null) return null;
ProxiedPlayer player = (ProxiedPlayer) commandSender;
if (s.isEmpty()) {
int version = player.getPendingConnection().getVersion();
if (version > 578) { // Version > 1.15.2
return 19;
} else if (version > 340) { // Version > 1.12.2
return 15;
} else {
return 12;
}
}
return versionMap.get(s.toLowerCase());
}
@Override
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
return versionMap.keySet();
}
};
}
@Register(value = "addmember", description = "BAU_ADDMEMBER_USAGE")
public void addmember(ProxiedPlayer p, @Validator("addMemberTarget") SteamwarUser target) {
BauweltMember.addMember(p.getUniqueId(), target.getUUID());
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());
}
@Validator(value = "addMemberTarget", local = true)
public TypeValidator<SteamwarUser> addMemberTargetValidator() {
return (sender, value, messageSender) -> {
if (value == null) {
messageSender.send("UNKNOWN_PLAYER");
return false;
}
if (((ProxiedPlayer) sender).getUniqueId().equals(value.getUUID())) {
messageSender.send("BAU_ADDMEMBER_SELFADD");
return false;
}
if (BauweltMember.getBauMember(((ProxiedPlayer) sender).getUniqueId(), value.getUUID()) != null) {
messageSender.send("BAU_ADDMEMBER_ISADDED");
return false;
}
return true;
};
}
@Register(value = "tp", description = "BAU_TP_USAGE")
@Register("teleport")
public void teleport(ProxiedPlayer p, @Validator("teleportTarget") SteamwarUser worldOwner, @Mapper("version") @OptionalValue(value = "", onlyUINIG = true) int version) {
versionSelector(version,
() -> new ServerStarter().build12(worldOwner.getUUID()).send(p).start(),
() -> new ServerStarter().build15(worldOwner.getUUID()).send(p).start(),
() -> new ServerStarter().build19(worldOwner.getUUID()).send(p).start()
);
}
@Validator(value = "teleportTarget", local = true)
public TypeValidator<SteamwarUser> teleportTargetValidator() {
return (sender, value, messageSender) -> {
if (value == null) {
messageSender.send("UNKNOWN_PLAYER");
return false;
}
ProxiedPlayer p = (ProxiedPlayer) sender;
if (!p.getUniqueId().equals(value.getUUID()) && BauweltMember.getBauMember(value.getUUID(), p.getUniqueId()) == null) {
SubserverSystem.sendDeniedMessage(p, value.getUUID());
messageSender.send("BAU_TP_NOALLOWED");
return false;
}
if(BauLock.isLocked(value, SteamwarUser.get(p.getUniqueId()))) {
messageSender.send("BAU_LOCKED_NOALLOWED");
return false;
}
return true;
};
}
@Register("info")
public void info(ProxiedPlayer p) {
Chat19.chat(p, "/bauinfo");
}
@Register("togglewe")
public void togglewe(ProxiedPlayer p, @AllowNull @OptionalValue("") SteamwarUser user) {
if (user == null) {
Message.send("BAU_MEMBER_TOGGLE_USAGE", p, "togglewe");
return;
}
BauweltMember target = member(p, user);
if (target == null)
return;
target.setWorldEdit(!target.isWorldEdit());
clearMembercache(p);
isAllowedTo(target.isWorldEdit(), p, target, "BAU_MEMBER_TOGGLE_WORLD_EDIT");
}
@Register("toggleworld")
public void toggleworld(ProxiedPlayer p, @AllowNull @OptionalValue("") SteamwarUser user) {
if (user == null) {
Message.send("BAU_MEMBER_TOGGLE_USAGE", p, "toggleworld");
return;
}
BauweltMember target = member(p, user);
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 -> NetworkSender.send(player, new BaumemberUpdatePacket()));
break;
}
}
}
@Register(value = "delmember", description = "BAU_DELMEMBER_USAGE")
public void delmember(ProxiedPlayer p, SteamwarUser user) {
BauweltMember target = member(p, user);
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);
}
@Register("resetall")
@Register("delete")
public void delete(ProxiedPlayer p, @Mapper("version") @OptionalValue(value = "", onlyUINIG = true) int version) {
SteamwarUser user = SteamwarUser.get(p.getUniqueId());
versionSelector(version,
() -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS12_PATH + p.getUniqueId().toString())),
() -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS15_PATH + user.getId())),
() -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS19_PATH + user.getId()))
);
}
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.close();
});
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(BungeeCore.local, world);
Message.send("BAU_DELETE_DELETED", player);
});
}
@Register("test")
@Register("testarena")
public void testarena(ProxiedPlayer p, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
FightCommand.createArena(p, "/bau testarena ", false, arenaMode, map, false, (player, mode, m) -> {
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> new ServerStarter().test(mode, m, p).start());
});
}
@Register(value = "lock", description = "BAU_LOCKED_OPTIONS")
public void lock(ProxiedPlayer p, BauLockState bauLockState) {
BauLock.setLocked(p, bauLockState);
}
@Register("unlock")
public void unlock(ProxiedPlayer p) {
BauLock.setLocked(p, BauLockState.OPEN);
}
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 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));
}
}
}

Datei anzeigen

@ -17,23 +17,24 @@
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.sql.SWException;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.ChatSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class BugCommand extends SWCommand {
public BugCommand() {
super("bug");
super("bug", null);
}
@Register
public void bugMessage(Chatter sender, String... message) {
int id = SWException.logGetId(
String.join(" ", message),
sender.withPlayerOrOffline(player -> player.getCurrentServer().map(connection -> connection.getServerInfo().getName()).orElse("offline"), () -> "offline") + " " + sender.user().getUserName() + " " + sender.user().getId()
);
sender.system("BUG_MESSAGE", id);
public void bugMessage(ProxiedPlayer player, String... message) {
String server = player.getServer().getInfo().getName();
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
SWException.log(String.join(" ", message), server + " " + player.getName() + " " + user.getId());
ChatSender.of(player).system("BUG_MESSAGE");
}
}

Datei anzeigen

@ -0,0 +1,121 @@
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.ServerStarter;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;
public class BuilderCloudCommand extends SWCommand {
private final Map<String, ServerStarter.Version> versionMap = new HashMap<>();
public BuilderCloudCommand() {
super("buildercloud", "bungeecore.server.team");
versionMap.put("15", ServerStarter.Version.SPIGOT_15);
versionMap.put("1.15", ServerStarter.Version.SPIGOT_15);
versionMap.put("1.15.2", ServerStarter.Version.SPIGOT_15);
versionMap.put("19", ServerStarter.Version.PAPER_19);
versionMap.put("1.19", ServerStarter.Version.PAPER_19);
versionMap.put("1.19.2", ServerStarter.Version.PAPER_19);
}
@Register(description = "BUILDERCLOUD_USAGE")
public void genericCommand(ProxiedPlayer player, @ErrorMessage("BUILDERCLOUD_VERSION") ServerStarter.Version version, @Mapper("map") String map, @OptionalValue("") @Mapper("generator") @AllowNull File generator) {
new ServerStarter().builder(version, map, generator).send(player).start();
}
@ClassMapper(value = ServerStarter.Version.class, local = true)
private TypeMapper<ServerStarter.Version> versionTypeMapper() {
return new TypeMapper<ServerStarter.Version>() {
@Override
public ServerStarter.Version map(CommandSender commandSender, String[] previousArguments, String s) {
return versionMap.get(s);
}
@Override
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
return versionMap.keySet();
}
};
}
@Cached(global = true)
@Mapper(value = "map", local = true)
private TypeMapper<String> mapTypeMapper() {
return new TypeMapper<String>() {
@Override
public String map(CommandSender commandSender, String[] previousArguments, String s) {
File folder = getWorldFolder(previousArguments, 1);
if(folder == null)
return null;
File map = new File(folder, s);
if(!map.exists() && !map.mkdir())
return null;
return map.getName();
}
@Override
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
File folder = getWorldFolder(previousArguments, 1);
String[] files;
if(folder == null || (files = folder.list()) == null)
return Collections.emptyList();
return Arrays.stream(files).filter(file -> new File(folder, file).isDirectory()).collect(Collectors.toList());
}
};
}
@Cached(global = true)
@Mapper(value = "generator", local = true)
private TypeMapper<File> generatorTypeMapper() {
return new TypeMapper<File>() {
@Override
public File map(CommandSender commandSender, String[] previousArguments, String s) {
if(s.equals(""))
return null;
File folder = getWorldFolder(previousArguments, 2);
if(folder == null)
throw new SecurityException();
File generator = new File(folder, s + ".dat");
if(!generator.exists() || !generator.isFile())
throw new SecurityException();
return generator;
}
@Override
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
File folder = getWorldFolder(previousArguments, 2);
String[] files;
if(folder == null || (files = folder.list()) == null)
return Collections.emptyList();
return Arrays.stream(files).filter(file -> new File(folder, file).isFile()).filter(file -> file.endsWith(".dat")).map(file -> file.substring(0, file.length() - 4)).collect(Collectors.toList());
}
};
}
private File getWorldFolder(String[] previousArguments, int offset) {
ServerStarter.Version v = versionMap.get(previousArguments[previousArguments.length - offset]);
if(v == null)
return null;
return new File(v.getWorldFolder(ServerStarter.BUILDER_BASE_PATH));
}
}

Datei anzeigen

@ -0,0 +1,113 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.inventory.SWInventory;
import de.steamwar.bungeecore.inventory.SWItem;
import de.steamwar.sql.NodeMember;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.time.LocalDate;
import java.time.Month;
import java.util.*;
public class CalendarCommand extends SWCommand {
private static Map<Integer, Integer> dayToSchematicId = new HashMap<>();
static {
dayToSchematicId.put(1, 105386);
dayToSchematicId.put(2, 105463);
dayToSchematicId.put(3, 105438);
dayToSchematicId.put(4, 105383);
dayToSchematicId.put(5, 105381);
dayToSchematicId.put(6, 105396);
dayToSchematicId.put(7, 105462);
dayToSchematicId.put(8, 105457);
dayToSchematicId.put(9, 105388);
dayToSchematicId.put(10, 105390);
dayToSchematicId.put(11, 105385);
dayToSchematicId.put(12, 105397);
dayToSchematicId.put(13, 105455);
dayToSchematicId.put(14, 105389);
dayToSchematicId.put(15, 105454);
dayToSchematicId.put(16, 105394);
dayToSchematicId.put(17, 105459);
dayToSchematicId.put(18, 105384);
dayToSchematicId.put(19, 105392);
dayToSchematicId.put(20, 105465);
dayToSchematicId.put(21, 105393);
dayToSchematicId.put(22, 105464);
dayToSchematicId.put(23, 105380);
dayToSchematicId.put(24, 105505);
dayToSchematicId.put(25, 107355);
dayToSchematicId.put(26, 107355);
dayToSchematicId.put(31, 105507);
}
public CalendarCommand() {
super("calendar", null, "cal");
}
@Register
public void genericCommand(ProxiedPlayer player) {
LocalDate localDate = LocalDate.now();
int day = localDate.getDayOfMonth();
Month month = localDate.getMonth();
Random random = new Random(localDate.getYear());
if (month != Month.NOVEMBER && month != Month.DECEMBER && month != Month.JANUARY) {
return;
}
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
List<SWItem> items = new ArrayList<>();
for (Map.Entry<Integer, Integer> present : dayToSchematicId.entrySet()) {
boolean b = NodeMember.getNodeMember(present.getValue(), user.getId()) != null;
SWItem randomPresent = random.nextDouble() > 0.5 ? SWItem.getSkull("MHF_Present1") : SWItem.getSkull("MHF_Present2");
SWItem swItem = b ? SWItem.getSkull("MHF_Chest") : randomPresent;
swItem.setName(Message.parse("ADVENT_CALENDAR_DAY", player, present.getKey()));
swItem.setCallback(click -> {
if (b) return;
if (month != Month.DECEMBER) return;
if (present.getKey() != day) return;
if (NodeMember.getNodeMember(present.getValue(), user.getId()) != null) return;
NodeMember.createNodeMember(present.getValue(), user.getId());
Message.send("ADVENT_CALENDAR_OPEN", player, SchematicNode.getSchematicNode(present.getValue()).getName());
});
items.add(swItem);
}
Collections.shuffle(items, random);
SWInventory inventory = new SWInventory(player, 27, Message.parse("ADVENT_CALENDAR_TITLE", player));
for (int i = 0; i < items.size(); i++) {
inventory.addItem(i, items.get(i));
}
inventory.open();
}
public static boolean hasDay(int day) {
return dayToSchematicId.containsKey(day);
}
}

Datei anzeigen

@ -17,24 +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 com.velocitypowered.api.proxy.Player;
import de.steamwar.velocitycore.ArenaMode;
import de.steamwar.velocitycore.ServerStarter;
import de.steamwar.persistent.Servertype;
import de.steamwar.persistent.Subserver;
import de.steamwar.bungeecore.*;
import de.steamwar.sql.IgnoreSystem;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.Message;
import de.steamwar.messages.PlayerChatter;
import de.steamwar.sql.IgnoreSystem;
import net.kyori.adventure.text.event.ClickEvent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.LinkedList;
import static de.steamwar.persistent.Storage.challenges;
import static de.steamwar.bungeecore.Storage.challenges;
public class ChallengeCommand extends SWCommand {
@ -43,16 +37,17 @@ public class ChallengeCommand extends SWCommand {
}
@Register(description = "CHALLENGE_USAGE")
public void challenge(@Validator("arenaPlayer") PlayerChatter sender, @Validator("target") Player target, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
FightCommand.createArena(sender, "/challenge " + target.getUsername() + " ", false, arenaMode, map, false, (chatter, mode, m) -> {
Player p = sender.getPlayer();
public void challenge(@Validator("arenaPlayer") ProxiedPlayer player, @Validator("target") ProxiedPlayer target, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
FightCommand.createArena(player, "/challenge " + target.getName() + " ", false, arenaMode, map, false, (p, mode, m) -> {
if(challenges.containsKey(target) && challenges.get(target).contains(p)){
challenges.remove(target);
challenges.remove(p);
new ServerStarter().arena(mode, map).blueLeader(sender.getPlayer()).redLeader(target).callback(
arena -> Chatter.broadcast().system("CHALLENGE_BROADCAST", new Message("CHALLENGE_BROADCAST_HOVER"), ClickEvent.runCommand("/arena " + arena.getServer().getName()), mode.getGameName(), p, target)
).start();
Subserver arena = new ServerStarter().arena(mode, map).blueLeader(player).redLeader(target).start();
if(arena != null) {
Message.broadcast("CHALLENGE_BROADCAST", "CHALLENGE_BROADCAST_HOVER",
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName(), target.getName());
}
}else{
if(!challenges.containsKey(p)){
challenges.put(p, new LinkedList<>());
@ -60,16 +55,16 @@ public class ChallengeCommand extends SWCommand {
challenges.get(p).add(target);
sender.system("CHALLENGE_CHALLENGED", target, mode.getGameName());
Chatter.of(target).system("CHALLENGE_CHALLENGED_TARGET", p, mode.getGameName(), mode.getMaps().size() != 1 ? new Message("CHALLENGE_CHALLENGED_MAP", m) : "");
Message.send("CHALLENGE_CHALLENGED", p, target.getName(), mode.getDisplayName());
Message.send("CHALLENGE_CHALLENGED_TARGET", target, p.getName(), mode.getDisplayName(), mode.getMaps().size() != 1 ? Message.parse("CHALLENGE_CHALLENGED_MAP", target, m) : "");
Chatter.of(target).system("CHALLENGE_ACCEPT", new Message("CHALLENGE_ACCEPT_HOVER"), ClickEvent.runCommand("/challenge " + p.getUsername() + " " + mode.getChatName() + " " + m));
Message.send("CHALLENGE_ACCEPT", target, Message.parse("CHALLENGE_ACCEPT_HOVER", target), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/challenge " + p.getName() + " " + mode.getChatName() + " " + m));
}
});
}
@Validator(value = "target", local = true)
public TypeValidator<Player> targetValidator() {
public TypeValidator<ProxiedPlayer> targetValidator() {
return (sender, value, messageSender) -> {
if (value == null) {
messageSender.send("CHALLENGE_OFFLINE");
@ -79,7 +74,7 @@ public class ChallengeCommand extends SWCommand {
messageSender.send("CHALLENGE_SELF");
return false;
}
if (IgnoreSystem.isIgnored(value.getUniqueId(), sender.user().getUUID())) {
if (IgnoreSystem.isIgnored(value.getUniqueId(), ((ProxiedPlayer) sender).getUniqueId())) {
messageSender.send("CHALLENGE_IGNORED");
return false;
}
@ -93,7 +88,7 @@ public class ChallengeCommand extends SWCommand {
};
}
public static void remove(Player player){
public static void remove(ProxiedPlayer player){
challenges.remove(player);
}
}

Datei anzeigen

@ -0,0 +1,340 @@
/*
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.sql.CheckedSchematic;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SchematicType;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import net.md_5.bungee.api.ChatColor;
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.util.*;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
public class CheckCommand extends SWCommand {
private static final Map<SchematicType, SchematicType> fightTypes = new HashMap<>();
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 void addFightType(SchematicType checkType, SchematicType fightType) {
fightTypes.put(checkType, fightType);
}
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());
}
@Register(value = "list", description = "CHECK_HELP_LIST")
public 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());
}
}
}
@Register(value = "schematic", noTabComplete = true)
public 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);
}
@Register(value = "cancel", description = "CHECK_HELP_CANCEL")
@Register("abort")
public void abortCommand(ProxiedPlayer player) {
abort(player);
}
public static void abort(ProxiedPlayer player) {
if(notChecking(player))
return;
Message.send("CHECK_ABORT", player);
currentCheckers.get(player.getUniqueId()).abort();
}
@Register(value = "next", description = "CHECK_HELP_NEXT")
public void next(ProxiedPlayer player) {
next(player, new String[0]);
}
@Register(value = "accept")
public void accept(ProxiedPlayer player, @OptionalValue("") String rank) {
if (rank.equals("")) {
next(player, new String[0]);
} else {
next(player, new String[]{rank});
}
}
@Register(value = "decline", description = "CHECK_HELP_DECLINE")
public void decline(ProxiedPlayer player, String... message) {
if(notChecking(player))
return;
currentCheckers.get(player.getUniqueId()).decline(String.join(" ", message));
}
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 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 > 0){
try{
rank = Integer.parseInt(args[0]);
}catch(NumberFormatException e){
Message.send("CHECK_INVALID_RANK", player);
return;
}
}
currentCheckers.get(player.getUniqueId()).next(rank);
}
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(fightTypes.get(schematic.getSchemtype()));
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(createLog("freigegeben")) {
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(fightTypes.get(schematic.getSchemtype()).toDB());
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){
if(createLog(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(){
createLog("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());
}
private boolean createLog(String reason) {
if(SchematicNode.getSchematicNode(schematic.getId()) == null) // Schematic was deleted
return false;
CheckedSchematic.create(schematic, SteamwarUser.get(checker.getUniqueId()).getId(), startTime, Timestamp.from(Instant.now()), reason);
return true;
}
}
}

Datei anzeigen

@ -17,19 +17,16 @@
* 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 com.velocitypowered.api.proxy.server.ServerInfo;
import de.steamwar.messages.Message;
import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.command.SWCommand;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.TypeMapper;
import de.steamwar.command.TypeValidator;
import de.steamwar.messages.PlayerChatter;
import de.steamwar.bungeecore.Message;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.*;
import de.steamwar.messages.ChatSender;
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;
@ -39,50 +36,53 @@ import java.util.Map;
public class DevCommand extends SWCommand {
private final File devServerDir = new File("/configs/DevServer");
private final Map<String, RegisteredServer> devServers = new HashMap<>();
private final Map<String, ServerInfo> devServers = new HashMap<>();
public DevCommand() {
super("dev");
}
@Register
public void simpleCommand(@Validator PlayerChatter sender) {
public void simpleCommand(@Validator ProxiedPlayer player) {
updateDevServers();
ChatSender sender = ChatSender.of(player);
if (devServers.isEmpty()) {
sender.system("DEV_NO_SERVER");
return;
} else if (devServers.size() == 1) {
devServers.values().stream().findAny().ifPresent(server -> sender.getPlayer().createConnectionRequest(server).fireAndForget());
player.connect(devServers.values().stream().findAny().get());
return;
}
RegisteredServer server = devServers.get(sender.getPlayer().getUsername().toLowerCase());
if (server == null) {
ServerInfo info = devServers.get(player.getName().toLowerCase());
if (info == null) {
sender.system("DEV_UNKNOWN_SERVER");
return;
}
sender.getPlayer().createConnectionRequest(server).fireAndForget();
player.connect(info);
}
@Register
public void selectedCommand(@Validator PlayerChatter sender, @Mapper("dev") String name) {
public void selectedCommand(@Validator ProxiedPlayer player, @Mapper("dev") String name) {
updateDevServers();
RegisteredServer server = devServers.get(name.toLowerCase());
if (server == null) {
ChatSender sender = ChatSender.of(player);
ServerInfo info = devServers.get(name.toLowerCase());
if (info == null) {
sender.system("DEV_NO_SERVER");
return;
}
sender.getPlayer().createConnectionRequest(server).fireAndForget();
player.connect(info);
}
@ClassValidator(value = PlayerChatter.class, local = true)
public TypeValidator<PlayerChatter> punishmentGuardChecker() {
@ClassValidator(value = ProxiedPlayer.class, local = true)
public TypeValidator<ProxiedPlayer> punishmentGuardChecker() {
return (sender, value, messageSender) -> {
if (sender.user().isPunished(Punishment.PunishmentType.NoDevServer)) {
Message message = PunishmentCommand.punishmentMessage(sender.user(), Punishment.PunishmentType.NoDevServer);
messageSender.send(message.format(), message.params());
SteamwarUser user = SteamwarUser.get(value.getUniqueId());
if (user.isPunished(Punishment.PunishmentType.NoDevServer)) {
Message message = PunishmentCommand.punishmentMessage(user, Punishment.PunishmentType.NoDevServer);
messageSender.send(message.getFormat(), message.getParams());
return false;
}
return true;
@ -110,7 +110,7 @@ public class DevCommand extends SWCommand {
devServers.entrySet().removeIf(entry -> {
if (!devServerFiles.containsKey(entry.getKey())) {
VelocityCore.getProxy().unregisterServer(entry.getValue().getServerInfo());
ProxyServer.getInstance().getServers().remove(entry.getValue().getName());
return true;
}
return false;
@ -121,7 +121,9 @@ public class DevCommand extends SWCommand {
return;
SteamwarUser user = SteamwarUser.get(key);
devServers.put(user.getUserName().toLowerCase(), VelocityCore.getProxy().registerServer(new ServerInfo("Dev " + user.getUserName(), new InetSocketAddress("127.0.0.1", value))));
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);
});
}
}

Datei anzeigen

@ -0,0 +1,138 @@
/*
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.messages.ChatSender;
import de.steamwar.sql.*;
import de.steamwar.command.SWCommand;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.TypeMapper;
import de.steamwar.command.TypeValidator;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class EventCommand extends SWCommand {
public EventCommand() {
super("event");
}
@Validator("noEvent")
public TypeValidator<ProxiedPlayer> noEventValidator() {
return (sender, value, messageSender) -> Event.get() == null;
}
@Register
public void noCurrentEvent(@Validator("noEvent") 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());
}
SchematicType schemType = e.getSchematicType();
if (schemType != null) {
if (schemType.getDeadline() != null && now.isBefore(schemType.getDeadline().toInstant())) {
Message.send("EVENT_COMING_SCHEM_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());
}
}
}
}
@Register
public void eventOverview(@Validator(value = "noEvent", invert = true) ProxiedPlayer player) {
Event currentEvent = Event.get();
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());
}
}
@Register
public void eventWithTeam(@Validator(value = "noEvent", invert = true) ProxiedPlayer player, @ErrorMessage("EVENT_NO_TEAM") Team team) {
Subserver eventArena = EventStarter.getEventServer().get(team.getTeamId());
if(eventArena == null || !Subserver.getServerList().contains(eventArena)){
Message.send("EVENT_NO_FIGHT_TEAM", player);
return;
}
ChatSender sender = ChatSender.of(player);
if (!PunishmentCommand.isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer)) {
SubserverSystem.sendPlayer(eventArena, player);
}
}
@ClassMapper(Team.class)
@Cached(cacheDuration = 10, global = true)
public TypeMapper<Team> teamMapper() {
return SWCommandUtils.createMapper(Team::get, s -> EventStarter.getEventServer()
.keySet()
.stream()
.map(Team::get)
.map(t -> Arrays.asList(t.getTeamKuerzel(), t.getTeamColor()))
.flatMap(Collection::stream)
.collect(Collectors.toList()));
}
}

Datei anzeigen

@ -17,31 +17,36 @@
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.bungeecore.Message;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.Team;
import de.steamwar.sql.UserPerm;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
import de.steamwar.sql.Event;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.ListIterator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class EventRescheduleCommand extends SWCommand {
public EventRescheduleCommand() {
super("eventreschedule", UserPerm.MODERATION);
super("eventreschedule", "bungeecore.softreload");
}
@Register
public void reschedule(Chatter sender, Team teamBlue, Team teamRed) {
public void reschedule(ProxiedPlayer player, Team teamBlue, Team teamRed) {
Event event = Event.get();
if(event == null){
sender.system("EVENTRESCHEDULE_UNKNOWN_TEAM");
Message.send("EVENTRESCHEDULE_UNKNOWN_TEAM", player);
return;
}
@ -54,13 +59,31 @@ 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);
}
@ClassMapper(value = Team.class, local = true)
public TypeMapper<Team> teamTypeMapper() {
return new TypeMapper<Team>() {
@Override
public Team map(CommandSender commandSender, String[] previousArguments, String s) {
return Team.get(s);
}
@Override
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
Event event = Event.get();
if (event == null) return null;
List<EventFight> fights = EventFight.getEvent(event.getEventID());
return fights.stream().flatMap(fight -> Stream.of(fight.getTeamBlue(), fight.getTeamRed())).map(Team::get).map(Team::getTeamKuerzel).distinct().collect(Collectors.toList());
}
};
}
}

Datei anzeigen

@ -17,20 +17,19 @@
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.command.SWCommand;
import net.md_5.bungee.api.CommandSender;
public class EventreloadCommand extends SWCommand {
public EventreloadCommand() {
super("eventreload", UserPerm.MODERATION);
super("eventreload", "bungeecore.softreload");
}
@Register
public void execute(Chatter sender) {
public void execute(CommandSender sender) {
EventFight.loadAllComingFights();
}
}

Datei anzeigen

@ -0,0 +1,213 @@
/*
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.command.SWCommand;
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.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;
/**
* 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 SWCommand {
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.parseToPlain("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(ProxiedPlayer player, String precommand, boolean allowMerging, ArenaMode arenaMode, String map, boolean historic, FightCallback callback) {
ChatSender sender = ChatSender.of(player);
if(alreadyInArena(player))
return;
if (arenaMode == null) {
getModes(sender, precommand, historic);
return;
}
if (map == null) {
if (arenaMode.getMaps().size() == 1) {
map = arenaMode.getRandomMap();
} else {
getMaps(sender, precommand, arenaMode);
return;
}
} else if (map.equalsIgnoreCase("random")) {
map = arenaMode.getRandomMap();
}
if (!allowMerging) {
callback.run(player, arenaMode, map);
} else {
suggestMerging(player, arenaMode, 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()) && 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();
}
@Register
public void fight(@Validator("arenaPlayer") ProxiedPlayer player, @Mapper("nonHistoricArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
createArena(player, "/fight ", true, arenaMode, map, false, (p, mode, m) -> {
Subserver arena = new ServerStarter().arena(mode, m).blueLeader(p).start();
if(arena != null) {
Message.broadcast("FIGHT_BROADCAST", "FIGHT_BROADCAST_HOVER"
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName());
}
});
}
/**
* Is called when arena parameters are clear.
*/
interface FightCallback {
void run(ProxiedPlayer player, ArenaMode mode, String map);
}
}

Datei anzeigen

@ -1,31 +1,12 @@
/*
* 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.bungeecore.BungeeCore;
import de.steamwar.bungeecore.Message;
import de.steamwar.sql.internal.Statement;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.io.*;
import java.util.zip.ZipEntry;
@ -34,42 +15,48 @@ import java.util.zip.ZipOutputStream;
public class GDPRQuery extends SWCommand {
public GDPRQuery() {
super("gdprquery", UserPerm.ADMINISTRATION);
super("gdprquery", "bungeecore.softreload");
}
@Register
public void generate(PlayerChatter sender) {
generate(sender, sender.user());
public void generate(ProxiedPlayer player) {
generate(player, player);
}
@Register
public void generate(Chatter sender, SteamwarUser user) {
VelocityCore.schedule(() -> {
public void generate(ProxiedPlayer player, ProxiedPlayer forPlayer) {
SteamwarUser user = SteamwarUser.get(forPlayer.getUniqueId());
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");
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 +78,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 = ?");
@ -246,6 +233,11 @@ public class GDPRQuery extends SWCommand {
}
}
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);

Datei anzeigen

@ -17,24 +17,27 @@
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.bungeecore.Message;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.Message;
import net.kyori.adventure.text.event.ClickEvent;
import java.util.function.Function;
import de.steamwar.messages.ChatSender;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.protocol.packet.Chat;
public class HelpCommand extends SWCommand {
public HelpCommand() {
super("help", "?");
super("help", "", "?");
}
@Register
public void genericCommand(Chatter sender) {
printPage(sender, ClickEvent::runCommand,
public void genericCommand(ProxiedPlayer player) {
ChatSender sender = ChatSender.of(player);
printPage(sender, ClickEvent.Action.RUN_COMMAND,
"HELP_LOBBY", "/l",
"HELP_BAU", "/build",
"HELP_BAUSERVER", "/help build",
@ -47,32 +50,31 @@ public class HelpCommand extends SWCommand {
}
@Register({"build","world"})
public void buildWorld(Chatter sender) {
printPage(sender, "HELP_BAU_GROUP_WORLD_TITLE", "HELP_TNT", "HELP_FIRE", "HELP_FREEZE", "HELP_TPSLIMIT", "HELP_PROTECT", "HELP_RESET");
public void buildWorld(ProxiedPlayer player) {
printPage(ChatSender.of(player), "HELP_BAU_GROUP_WORLD_TITLE", "HELP_TNT", "HELP_FIRE", "HELP_FREEZE", "HELP_TPSLIMIT", "HELP_PROTECT", "HELP_RESET");
}
@Register({"build","player"})
public void buildPlayer(Chatter sender) {
printPage(sender, "HELP_BAU_GROUP_PLAYER_TITLE", "HELP_SPEED", "HELP_NV", "HELP_DEBUGSTICK", "HELP_TRACE", "HELP_LOADER");
public void buildPlayer(ProxiedPlayer player) {
printPage(ChatSender.of(player), "HELP_BAU_GROUP_PLAYER_TITLE", "HELP_SPEED", "HELP_NV", "HELP_WV", "HELP_DEBUGSTICK", "HELP_TRACE", "HELP_LOADER");
}
@Register({"build","worldedit"})
@Register({"build","we"})
@Register({"build","world-edit"})
@Register({"build","edit"})
public void buildWorldedit(Chatter sender) {
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");
public void buildWorldedit(ProxiedPlayer player) {
printPage(ChatSender.of(player), "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");
}
@Register({"build","other"})
public void buildOther(Chatter sender) {
printPage(sender, "HELP_BAU_GROUP_OTHER_TITLE", "HELP_TESTBLOCK", "HELP_SKULL", "HELP_BAUINFO");
sender.prefixless("HELP_SCHEMSUBMIT", new Message("HELP_SCHEMSUBMIT_HOVER"), ClickEvent.openUrl("https://www.youtube.com/watch?v=9QrQ3UBWveE"));
public void buildOther(ProxiedPlayer player) {
printPage(ChatSender.of(player), "HELP_BAU_GROUP_OTHER_TITLE", "HELP_TESTBLOCK", "HELP_SKULL", "HELP_BAUINFO");
}
@Register("build")
public void sendBauHelpGroup(Chatter sender) {
printPage(sender, ClickEvent::runCommand,
public void sendBauHelpGroup(ProxiedPlayer player) {
printPage(ChatSender.of(player), ClickEvent.Action.RUN_COMMAND,
"HELP_BAU_GROUP_ADMIN", "/help build admin",
"HELP_BAU_GROUP_WORLD", "/help build world",
"HELP_BAU_GROUP_PLAYER", "/help build player",
@ -84,31 +86,30 @@ public class HelpCommand extends SWCommand {
@Register({"build","admin"})
@Register({"build","owner"})
@Register({"build","bauwelt"})
public void sendBauHelp(Chatter sender) {
printPage(sender, ClickEvent::suggestCommand,
public void sendBauHelp(ProxiedPlayer player) {
printPage(ChatSender.of(player), ClickEvent.Action.SUGGEST_COMMAND,
"HELP_BAU_TP", "/build tp ",
"HELP_BAU_ADDMEMBER", "/build addmember ",
"HELP_BAU_DELMEMBER", "/build delmember ",
"HELP_BAU_SET_SPECTATOR", "/build setSpectator ",
"HELP_BAU_SET_BUILDER", "/build setBuilder ",
"HELP_BAU_SET_SUPERVISOR", "/build setSupervisor ",
"HELP_BAU_TOGGLEWE", "/build togglewe ",
"HELP_BAU_TOGGLEWORLD", "/build toggleworld ",
"HELP_BAU_DELETE", "/build delete ",
"HELP_BAU_TESTARENA", "/build testarena ",
"HELP_BAU_LOCK", "/build lock ",
"HELP_BAU_UNLOCK", "/build unlock");
}
private static void printPage(Chatter sender, Function<String, ClickEvent> action, String... args) {
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), action.apply(command));
sender.system(message, new Message(hoverMessage), new ClickEvent(action, command));
}
}
private static void printPage(Chatter sender, String title, String... messages) {
private static void printPage(ChatSender sender, String title, String... messages) {
sender.system(title);
for (String message : messages) {
sender.prefixless(message);

Datei anzeigen

@ -17,25 +17,29 @@
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.bungeecore.ArenaMode;
import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.ServerStarter;
import de.steamwar.bungeecore.Subserver;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.Message;
import de.steamwar.messages.PlayerChatter;
import de.steamwar.velocitycore.ArenaMode;
import de.steamwar.velocitycore.ServerStarter;
import net.kyori.adventure.text.event.ClickEvent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class HistoricCommand extends SWCommand {
public HistoricCommand() {
super("historic");
super("historic", null);
}
@Register
public void historic(@Validator("arenaPlayer") PlayerChatter player, @Mapper("historicArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
FightCommand.createArena(player, "/historic ", true, arenaMode, map, true, (p, mode, m) -> new ServerStarter().arena(mode, m).blueLeader(p.getPlayer()).callback(
arena -> Chatter.broadcast().system("HISTORIC_BROADCAST", new Message("HISTORIC_BROADCAST_HOVER"), ClickEvent.runCommand("/arena " + arena.getServer().getName()), mode.getGameName(), p.getPlayer())
).start());
public void historic(@Validator("arenaPlayer") ProxiedPlayer player, @Mapper("historicArenaMode") @OptionalValue("") @AllowNull ArenaMode arenaMode, @Mapper("arenaMap") @OptionalValue("") @AllowNull String map) {
FightCommand.createArena(player, "/historic ", true, arenaMode, map, true, (p, mode, m) -> {
Subserver arena = new ServerStarter().arena(mode, m).blueLeader(p).start();
if(arena != null) {
Message.broadcast("HISTORIC_BROADCAST", "HISTORIC_BROADCAST_HOVER",
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), p.getName());
}
});
}
}

Datei anzeigen

@ -17,33 +17,49 @@
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.bungeecore.Message;
import de.steamwar.sql.IgnoreSystem;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.TypeMapper;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.stream.Collectors;
public class IgnoreCommand extends SWCommand {
public IgnoreCommand() {
super("ignore");
super("ignore", null);
}
@Register(description = "USAGE_IGNORE")
public void genericCommand(Chatter player, @ErrorMessage("UNKNOWN_PLAYER") SteamwarUser target) {
SteamwarUser user = player.user();
public void genericCommand(ProxiedPlayer p, @Mapper("player") String toIgnore) {
SteamwarUser user = SteamwarUser.get(p.getUniqueId());
SteamwarUser target = SteamwarUser.get(toIgnore);
if(target == null){
Message.send("UNKNOWN_PLAYER", p);
return;
}
if(target.equals(user)){
player.system("IGNORE_YOURSELF");
Message.send("IGNORE_YOURSELF", p);
return;
}
if(IgnoreSystem.isIgnored(user, target)){
player.system("IGNORE_ALREADY");
Message.send("IGNORE_ALREADY", p);
return;
}
IgnoreSystem.ignore(user, target);
player.system("IGNORE_MESSAGE", target);
Message.send("IGNORE_MESSAGE", p, target.getUserName());
}
@Mapper(value = "player", local = true)
public TypeMapper<String> playerTypeMapper() {
return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()));
}
}

Datei anzeigen

@ -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.commands;
import de.steamwar.bungeecore.*;
import de.steamwar.sql.BauweltMember;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class JoinmeCommand extends SWCommand {
public JoinmeCommand() {
super("joinme");
}
@Register(description = "JOINME_USAGE")
public void genericCommand(ProxiedPlayer player) {
if (!player.hasPermission("bungeecore.joinme")) {
Message.send("JOINME_USAGE", player);
return;
}
Message.broadcast("JOINME_BROADCAST", "JOINME_BROADCAST_HOVER",
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join " + player.getName()), player.getName(), player.getServer().getInfo().getName());
}
@Register
public void genericCommand(ProxiedPlayer player, @Validator ProxiedPlayer target) {
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(type == Servertype.BUILDER && !player.hasPermission("bungeecore.server.team")) {
Message.send("JOIN_PLAYER_BLOCK", player);
} else {
SubserverSystem.sendPlayer(subserver, 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);
}
}
@ClassValidator(ProxiedPlayer.class)
public TypeValidator<ProxiedPlayer> playerMapper() {
return (sender, value, messageSender) -> {
if (value == null || !value.isConnected()) {
messageSender.send("JOINME_PLAYER_OFFLINE", sender);
return false;
}
return true;
};
}
}

Datei anzeigen

@ -0,0 +1,60 @@
/*
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.command.SWCommand;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.TypeMapper;
import net.md_5.bungee.BungeeCord;
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.stream.Collectors;
public class KickCommand extends SWCommand {
public KickCommand() {
super("kick", "bungeecore.kick");
}
@Register(description = "KICK_USAGE")
public void genericCommand(CommandSender sender, @Mapper("player") String player, String... message) {
ProxiedPlayer target = ProxyServer.getInstance().getPlayer(player);
if(target == null){
Message.send("KICK_OFFLINE", sender);
return;
}
if (message.length == 0) {
target.disconnect(Message.parseToComponent("KICK_NORMAL", true, target));
} else {
target.disconnect(BungeeCore.stringToText(BungeeCore.CHAT_PREFIX + "§c" + String.join(" ", message)));
}
Message.send("KICK_CONFIRM", sender, target.getName());
}
@Mapper(value = "player", local = true)
public TypeMapper<String> playerTypeMapper() {
return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()));
}
}

Datei anzeigen

@ -0,0 +1,75 @@
/*
* 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 de.steamwar.command.SWCommand;
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 SWCommand {
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;
}
@Register
public void genericCommand(CommandSender commandSender) {
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(", ")));
}
}
}

Datei anzeigen

@ -17,20 +17,21 @@
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.bungeecore.listeners.ChatListener;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.PlayerChatter;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class LocalCommand extends SWCommand {
public LocalCommand() {
super("local", "bc", "bauchat");
super("local", null, "bc", "bauchat");
}
@Register
public void genericCommand(PlayerChatter player, String... message) {
public void genericCommand(ProxiedPlayer player, String... message) {
ChatListener.localChat(player, String.join(" ", message));
}
}

Datei anzeigen

@ -0,0 +1,147 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2023 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.inventory.SWInventory;
import de.steamwar.bungeecore.inventory.SWItem;
import de.steamwar.bungeecore.inventory.SWListInv;
import de.steamwar.bungeecore.inventory.SWStreamInv;
import de.steamwar.command.SWCommand;
import de.steamwar.sql.Mod;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class ModCommand extends SWCommand {
public ModCommand() {
super("mod", "bungeecore.softreload", "mods");
}
public static final Map<ProxiedPlayer, Mod.ModType> playerFilterType = new HashMap<>();
@Register
public void genericCommand(ProxiedPlayer p) {
playerFilterType.putIfAbsent(p,Mod.ModType.UNKLASSIFIED);
openGui(p);
}
private void openGui(ProxiedPlayer p) {
SWStreamInv<Mod> swStreamInv = new SWStreamInv<>(p,Message.parse("MOD_COMMAND_GUI_TITLE",p), (click, element) -> {
openClassificationGui(p,element);
},page -> {
Mod.ModType filtertype = playerFilterType.get(p);
return Mod.getAllModsFiltered(page,45, filtertype).stream().map(mod -> new SWListInv.SWListEntry<>(getModItem(mod),mod)).collect(Collectors.toList());
});
swStreamInv.addItem(52,new SWItem("NAME_TAG","Filter"), click -> {
swStreamInv.close();
openFilterGui(p);
});
swStreamInv.open();
}
public void updateAndCloseGui(Mod.ModType modType, Mod mod, SWInventory toClose, ProxiedPlayer p) {
mod.setModType(modType);
toClose.close();
openGui(p);
}
private void openFilterGui(ProxiedPlayer p) {
SWInventory inv = new SWInventory(p, 9, "Filter");
inv.addItem(1, new SWItem(Message.parse("MOD_UNCLASSIFIED",p),8), click -> playerFilterType.replace(p, Mod.ModType.UNKLASSIFIED));
inv.addItem(2, new SWItem(Message.parse("MOD_ALLOWED",p),2), click -> playerFilterType.replace(p, Mod.ModType.GREEN));
inv.addItem(3, new SWItem(Message.parse("MOD_FORBIDDEN",p), 11), click -> playerFilterType.replace(p, Mod.ModType.YELLOW));
inv.addItem(4, new SWItem(Message.parse("MOD_AUTOBAN",p),1), click -> playerFilterType.replace(p, Mod.ModType.RED));
inv.addItem(5, new SWItem(Message.parse("MOD_YT",p),13), click -> playerFilterType.replace(p, Mod.ModType.YOUTUBER_ONLY));
inv.addItem(8, new SWItem("ARROW", Message.parse("MOD_ITEM_BACK",p)), click -> {
inv.close();
openGui(p);
});
inv.open();
}
private void openClassificationGui(ProxiedPlayer p,Mod element) {
SWInventory swInventory = new SWInventory(p,9,Message.parse("MOD_COMMAND_CLASSICIATION_GUI",p));
swInventory.addItem(2, new SWItem(Message.parse("MOD_UNCLASSIFIED",p),8), (click1 -> updateAndCloseGui(Mod.ModType.UNKLASSIFIED,element,swInventory,p)));
swInventory.addItem(3, new SWItem(Message.parse("MOD_ALLOWED",p), 2), (click1 -> updateAndCloseGui(Mod.ModType.GREEN,element,swInventory,p)));
swInventory.addItem(4, new SWItem(Message.parse("MOD_FORBIDDEN",p), 11), (click1 -> updateAndCloseGui(Mod.ModType.YELLOW,element,swInventory,p)));
swInventory.addItem(5, new SWItem(Message.parse("MOD_AUTOBAN",p),1), (click1 -> updateAndCloseGui(Mod.ModType.RED,element,swInventory,p)));
swInventory.addItem(6, new SWItem(Message.parse("MOD_YT",p), 13), (click1 -> updateAndCloseGui(Mod.ModType.YOUTUBER_ONLY,element,swInventory,p)));
swInventory.addItem(8,new SWItem("ARROW",Message.parse("MOD_ITEM_BACK",p)), click1 -> {
swInventory.close();
openGui(p);
});
swInventory.open();
}
private SWItem getModItem(Mod modEntry) {
SWItem item = new SWItem("NAME_TAG", modEntry.getModName());
item.addLore(modEntry.getPlatform().name());
return item;
}
@Register(value = {"set"},description = "MOD_COMMAND_SET_USAGE")
public void set(ProxiedPlayer p,String modName,Mod.Platform platform,Mod.ModType newModType) {
Mod mod = Mod.get(modName, platform);
if(mod == null) {
Message.send("MOD_COMMAND_NOT_FOUND_IN_DATABASE",p,modName, platform.name());
return;
}
mod.setModType(newModType);
Message.send("MOD_CHANGED_TYPE",p,modName,platform.name(),newModType.name());
}
@Register(value = {"get"},description = "MOD_COMMAND_GET_USAGE")
public void get(ProxiedPlayer p,String modName,Mod.Platform platform) {
Mod mod = Mod.get(modName, platform);
if(mod == null) {
Message.send("MOD_COMMAND_NOT_FOUND_IN_DATABASE", p, modName, platform.name());
return;
}
Message.send("MOD_COMMAND_INFO", p, modName, platform.name(), mod.getModType().name());
}
@Register(value = {"next"})
public void next(ProxiedPlayer p) {
Mod mod = Mod.findFirstMod();
if(mod == null) {
Message.send("MOD_NO_MORE_UNCLASSIFIED_MODS",p);
return;
}
Message.send("MOD_FOUND_NEXT_MOD",p,"MOD_OPEN_GUI",new ClickEvent(ClickEvent.Action.RUN_COMMAND,""),mod.getModName(),mod.getPlatform().name());
}
}

Datei anzeigen

@ -17,47 +17,48 @@
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.Player;
import de.steamwar.velocitycore.listeners.ChatListener;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.ChatterGroup;
import de.steamwar.messages.PlayerChatter;
import de.steamwar.bungeecore.listeners.ChatListener;
import de.steamwar.sql.IgnoreSystem;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.ChatSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import static de.steamwar.persistent.Storage.lastChats;
import java.util.stream.Stream;
import static de.steamwar.bungeecore.Storage.lastChats;
public class MsgCommand extends SWCommand {
public MsgCommand() {
super("msg", "w", "tell");
super("msg", "", "w", "tell");
}
@Register(description = "MSG_USAGE")
public void genericCommand(PlayerChatter sender, @ErrorMessage(value = "MSG_OFFLINE") Player target, @ErrorMessage(value = "MSG_USAGE", allowEAs = false) String... message) {
public void genericCommand(ProxiedPlayer sender, @ErrorMessage(value = "MSG_OFFLINE") ProxiedPlayer target, @ErrorMessage(value = "MSG_USAGE", allowEAs = false) String... message) {
msg(sender, target, message);
}
public static void msg(PlayerChatter sender, Player target, String[] args) {
if(target == null) {
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.getUniqueId(), sender.user().getUUID())) {
if (IgnoreSystem.isIgnored(target.getUniqueId(), player.getUniqueId())) {
sender.system("MSG_IGNORED");
return;
}
Chatter receiver = Chatter.of(target);
ChatListener.sendChat(sender, new ChatterGroup(sender, receiver), "CHAT_MSG", receiver, String.join(" ", args));
lastChats.put(sender.getPlayer(), target);
lastChats.put(target, sender.getPlayer());
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);
}
public static void remove(Player player){
public static void remove(ProxiedPlayer player){
lastChats.remove(player);
}
}

Datei anzeigen

@ -17,10 +17,11 @@
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.bungeecore.Message;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.PlayerChatter;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class PingCommand extends SWCommand {
@ -29,7 +30,7 @@ public class PingCommand extends SWCommand {
}
@Register
public void genericCommand(PlayerChatter sender) {
sender.system("PING_RESPONSE", sender.getPlayer().getPing());
public void genericCommand(ProxiedPlayer player) {
Message.send("PING_RESPONSE", player, player.getPing());
}
}

Datei anzeigen

@ -17,11 +17,12 @@
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.bungeecore.Message;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.text.NumberFormat;
@ -32,12 +33,11 @@ public class PlaytimeCommand extends SWCommand {
}
@Register
public void genericCommand(Chatter sender) {
SteamwarUser user = sender.user();
NumberFormat format = NumberFormat.getNumberInstance(user.getLocale());
public void genericCommand(ProxiedPlayer player) {
NumberFormat format = NumberFormat.getNumberInstance((player).getLocale());
format.setMaximumFractionDigits(2);
String formattedText = format.format((user.getOnlinetime() / 3600d));
String formattedText = format.format((SteamwarUser.get(player.getUniqueId()).getOnlinetime() / (double) 3600));
sender.system("HOURS_PLAYED", formattedText);
Message.send("HOURS_PLAYED", player, formattedText);
}
}

Datei anzeigen

@ -17,13 +17,15 @@
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.bungeecore.Message;
import de.steamwar.bungeecore.listeners.PollSystem;
import de.steamwar.sql.PollAnswer;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import de.steamwar.messages.Chatter;
import de.steamwar.sql.PollAnswer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class PollCommand extends SWCommand {
@ -32,33 +34,39 @@ public class PollCommand extends SWCommand {
}
@Register
public void genericCommand(@Validator Chatter sender) {
PollSystem.sendPoll(sender);
public void genericCommand(ProxiedPlayer player) {
PollSystem.sendPoll(player);
}
@Register(noTabComplete = true)
public void answerPoll(@Validator Chatter sender, String answerString) {
public void answerPoll(@Validator ProxiedPlayer player, 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");
Message.send("POLL_NO_ANSWER", player);
return;
}
PollAnswer pollAnswer = PollAnswer.get(sender.user().getId());
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();
@ClassValidator(value = ProxiedPlayer.class, local = true)
public TypeValidator<ProxiedPlayer> noPoll() {
return (sender, value, messageSender) -> {
if(PollSystem.noCurrentPoll()){
messageSender.send("POLL_NO_POLL");
return false;
}
return true;
};
}
}

Datei anzeigen

@ -17,34 +17,40 @@
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.bungeecore.Message;
import de.steamwar.bungeecore.listeners.PollSystem;
import de.steamwar.sql.PollAnswer;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import de.steamwar.messages.Chatter;
import de.steamwar.sql.PollAnswer;
import de.steamwar.sql.UserPerm;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.Map;
public class PollresultCommand extends SWCommand {
public PollresultCommand() {
super("pollresult", UserPerm.MODERATION);
super("pollresult", "bungeecore.pollresults");
}
@Register
public void genericCommand(@Validator Chatter sender) {
public void genericCommand(@Validator ProxiedPlayer player) {
Map<Integer, Integer> voted = PollAnswer.getCurrentResults();
sender.system("POLLRESULT_HEADER", voted.values().stream().reduce(Integer::sum).orElse(0), PollAnswer.getCurrentPoll());
Message.send("POLLRESULT_HEADER", player, voted.values().stream().reduce(Integer::sum).orElse(0), PollAnswer.getCurrentPoll());
for (Map.Entry<Integer, Integer> e: voted.entrySet()) {
sender.prefixless("POLLRESULT_LIST", PollSystem.getAnswer(e.getKey()), e.getValue());
Message.send("POLLRESULT_LIST", player, PollSystem.getAnswer(e.getKey()), e.getValue());
}
}
@ClassValidator(value = Chatter.class, local = true)
public TypeValidator<Chatter> noPoll() {
return PollSystem.noPoll();
@ClassValidator(value = ProxiedPlayer.class, local = true)
public TypeValidator<ProxiedPlayer> noPoll() {
return (sender, value, messageSender) -> {
if (PollSystem.noCurrentPoll()) {
messageSender.send("POLL_NO_POLL");
return false;
}
return true;
};
}
}

Datei anzeigen

@ -17,21 +17,20 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.velocitycore.commands;
package de.steamwar.bungeecore.commands;
import com.google.gson.JsonParser;
import com.velocitypowered.api.proxy.Player;
import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.velocitycore.listeners.IPSanitizer;
import de.steamwar.command.PreviousArguments;
import de.steamwar.bungeecore.BungeeCore;
import de.steamwar.bungeecore.Message;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.Message;
import de.steamwar.messages.ChatSender;
import de.steamwar.sql.BannedUserIPs;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserPerm;
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.connection.ProxiedPlayer;
import java.io.IOException;
import java.net.URL;
@ -41,14 +40,17 @@ import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.Date;
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.UUID;
import java.util.logging.Level;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class PunishmentCommand {
private static final String API_URL = "https://api.mojang.com/users/profiles/minecraft/";
private static final JsonParser jsonParser = new JsonParser();
public static SteamwarUser getOrCreateOfflinePlayer(String name) {
SteamwarUser user = SteamwarUser.get(name);
@ -67,17 +69,17 @@ public class PunishmentCommand {
private static UUID getUUIDofOfflinePlayer(String playerName) {
try {
final URL url = new URL(API_URL + playerName);
String uuid = JsonParser.parseString(new Scanner(url.openConnection().getInputStream()).nextLine()).getAsJsonObject().get("id").getAsString();
String uuid = jsonParser.parse(new Scanner(url.openConnection().getInputStream()).nextLine()).getAsJsonObject().get("id").getAsString();
return UUID.fromString(uuid.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
} catch (NoSuchElementException e) {
// ignore, player does not exist
} catch (IOException e) {
VelocityCore.getLogger().log(Level.SEVERE, "Could not get offline player UUID %s".formatted(playerName), e);
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not get offline player UUID " + playerName, e);
}
return null;
}
public static boolean isPunishedWithMessage(Chatter player, Punishment.PunishmentType punishment) {
public static boolean isPunishedWithMessage(ChatSender player, Punishment.PunishmentType punishment) {
SteamwarUser user = player.user();
if (!user.isPunished(punishment)) {
return false;
@ -87,17 +89,18 @@ public class PunishmentCommand {
}
public static void ban(SteamwarUser user, Timestamp time, String banReason, SteamwarUser punisher, boolean perma) {
Player player = VelocityCore.getProxy().getPlayer(user.getUUID()).orElse(null);
user.punish(Punishment.PunishmentType.Ban, time, banReason, punisher.getId(), perma);
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(user.getUUID());
if (player != null) {
String ip = IPSanitizer.getTrueAddress(player).getHostAddress();
Chatter.disconnect(player).system(punishmentMessage(user, Punishment.PunishmentType.Ban));
for (BannedUserIPs banned : BannedUserIPs.get(ip)) {
ChatSender.disconnect(player).system(punishmentMessage(user, Punishment.PunishmentType.Ban));
for (BannedUserIPs banned : BannedUserIPs.get(player.getAddress().getAddress().getHostAddress())) {
SteamwarUser bannedUser = SteamwarUser.get(banned.getUserID());
if (bannedUser.isPunished(Punishment.PunishmentType.Ban) && bannedUser.getPunishment(Punishment.PunishmentType.Ban).getEndTime().before(time)) {
bannedUser.punish(Punishment.PunishmentType.Ban, time, banReason, punisher.getId(), perma);
}
}
BannedUserIPs.banIP(user.getId(), ip);
BannedUserIPs.banIP(user.getId(), player.getAddress().getAddress().getHostAddress());
}
}
@ -111,17 +114,87 @@ public class PunishmentCommand {
}
public PunishmentCommand(String command, Punishment.PunishmentType punishmentType) {
new PunishCommand(command, punishmentType);
new SWCommand(command, "bungeecore.ban") {
if (punishmentType.getUnpunishmentMessage() == null)
@Register
public void genericCommand(ProxiedPlayer player, String toPunish, String date, @ErrorMessage(allowEAs = false, value = "PUNISHMENT_USAGE_REASON") String... message) {
SteamwarUser punisher = SteamwarUser.get(player.getUniqueId());
if (punishmentType.isNeedsAdmin() && !punisher.getUserGroup().isAdminGroup()) {
return;
}
SteamwarUser target = unsafeUser(player, toPunish);
if (target == null)
return;
Timestamp banTime = parseTime(player, date);
if (banTime == null)
return;
boolean isPerma = date.equalsIgnoreCase("perma");
String msg = String.join(" ", message);
if(punishmentType == Punishment.PunishmentType.Ban)
ban(target, banTime, msg, punisher, isPerma);
else
target.punish(punishmentType, banTime, msg, punisher.getId(), isPerma);
Message.team(punishmentType.getTeamMessage(), new Message("PREFIX"), target.getUserName(), player.getName(), new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg);
}
@Register
public void genericError(ProxiedPlayer player, String... args) {
ChatSender.of(player).send(true, ChatMessageType.CHAT, null, null, new Message("PUNISHMENT_USAGE", command));
}
};
if (punishmentType.getUnpunishmentMessage() == null) {
return;
}
String antiCommand = "un" + command;
new SWCommand(antiCommand, "bungeecore.ban") {
@Register
public void genericCommand(ProxiedPlayer player, String toUnpunish) {
if (punishmentType.isNeedsAdmin() && !SteamwarUser.get(player.getUniqueId()).getUserGroup().isAdminGroup()) {
return;
}
new UnpunishCommand("un" + command, punishmentType);
SteamwarUser target = existingUser(player, toUnpunish);
if (target == null)
return;
if (!target.isPunished(punishmentType)) {
Message.send(punishmentType.getUsageNotPunished(), player);
return;
}
Message.send(punishmentType.getUnpunishmentMessage(), player, target.getUserName());
target.punish(punishmentType, Timestamp.from(new Date().toInstant()), antiCommand, SteamwarUser.get(player.getName()).getId(), false);
if(punishmentType == Punishment.PunishmentType.Ban)
BannedUserIPs.unbanIPs(target.getId());
}
@Register
public void genericError(ProxiedPlayer player, String... args) {
ChatSender.of(player).send(true, ChatMessageType.CHAT, null, null, new Message("UNPUNISHMENT_USAGE", antiCommand));
}
};
}
private static final Pattern RELATIVE_PATTERN = Pattern.compile("([1-9]\\d*[hdwmy])+");
protected SteamwarUser existingUser(CommandSender sender, String arg){
SteamwarUser target = SteamwarUser.get(arg);
if(target == null)
Message.send("UNKNOWN_PLAYER", sender);
return target;
}
public static Timestamp parseTime(Chatter player, String arg) {
protected SteamwarUser unsafeUser(CommandSender sender, String arg){
SteamwarUser target = getOrCreateOfflinePlayer(arg);
if(target == null)
Message.send("UNKNOWN_PLAYER", sender);
return target;
}
private static Pattern RELATIVE_PATTERN = Pattern.compile("([1-9]\\d*[hdwmy])+");
public static Timestamp parseTime(CommandSender sender, String arg) {
if (arg.equalsIgnoreCase("perma")) {
return Punishment.PERMA_TIME;
} else {
@ -166,109 +239,12 @@ public class PunishmentCommand {
Date parsedDate = dateFormat.parse(arg.split("_")[0]);
return new java.sql.Timestamp(parsedDate.getTime());
} catch (ParseException exception) {
player.system("INVALID_TIME");
if (sender != null) {
Message.send("INVALID_TIME", sender);
}
return null;
}
}
}
}
private static class PunishCommand extends SWCommand {
private final String command;
private final Punishment.PunishmentType punishmentType;
private PunishCommand(String command, Punishment.PunishmentType punishmentType) {
super(command, UserPerm.TEAM);
this.command = command;
this.punishmentType = punishmentType;
}
private SteamwarUser unsafeUser(Chatter sender, String arg) {
SteamwarUser target = getOrCreateOfflinePlayer(arg);
if(target == null)
sender.system("UNKNOWN_PLAYER");
return target;
}
@Register
public void genericCommand(Chatter sender, @Mapper("toPunish") String toPunish, String date, @ErrorMessage(allowEAs = false, value = "PUNISHMENT_USAGE_REASON") String... message) {
SteamwarUser punisher = sender.user();
if (punishmentType.isNeedsAdmin() && !punisher.hasPerm(UserPerm.MODERATION))
return;
SteamwarUser target = unsafeUser(sender, toPunish);
if (target == null)
return;
Timestamp banTime = parseTime(sender, date);
if (banTime == null)
return;
boolean isPerma = date.equalsIgnoreCase("perma");
String msg = String.join(" ", message);
target.punish(punishmentType, banTime, msg, punisher.getId(), isPerma);
if(punishmentType == Punishment.PunishmentType.Ban)
ban(target, banTime, msg, punisher, isPerma);
Chatter.serverteam().system(punishmentType.getTeamMessage(), new Message("PREFIX"), target, sender, new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg);
}
@Register
public void genericError(Chatter sender, String... args) {
sender.system("PUNISHMENT_USAGE", command);
}
@Mapper(value = "toPunish", local = true)
public TypeMapper<String> allUsers() {
return new TypeMapper<String>() {
@Override
public String map(Chatter sender, PreviousArguments previousArguments, String s) {
return s;
}
@Override
public Collection<String> tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) {
List<String> players = VelocityCore.getProxy().getAllPlayers().stream()
.map(Player::getUsername)
.collect(Collectors.toList());
players.add(s);
return players;
}
};
}
}
private static class UnpunishCommand extends SWCommand {
private final String command;
private final Punishment.PunishmentType punishmentType;
private UnpunishCommand(String command, Punishment.PunishmentType punishmentType) {
super(command, UserPerm.TEAM);
this.command = command;
this.punishmentType = punishmentType;
}
@Register
public void genericCommand(Chatter sender, @ErrorMessage("UNKNOWN_PLAYER") SteamwarUser target) {
if (punishmentType.isNeedsAdmin() && !sender.user().hasPerm(UserPerm.MODERATION))
return;
if (!target.isPunished(punishmentType)) {
sender.system(punishmentType.getUsageNotPunished());
return;
}
target.punish(punishmentType, Timestamp.from(new Date().toInstant()), command, sender.user().getId(), false);
if(punishmentType == Punishment.PunishmentType.Ban)
BannedUserIPs.unbanIPs(target.getId());
sender.system(punishmentType.getUnpunishmentMessage(), target.getUserName());
}
@Register
public void genericError(Chatter sender, String... args) {
sender.system("UNPUNISHMENT_USAGE", command);
}
}
}

Datei anzeigen

@ -17,21 +17,21 @@
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 net.md_5.bungee.api.connection.ProxiedPlayer;
import static de.steamwar.persistent.Storage.lastChats;
import static de.steamwar.bungeecore.Storage.lastChats;
public class RCommand extends SWCommand {
public RCommand() {
super("r", "reply");
super("r", "", "reply");
}
@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);
public void genericCommand(ProxiedPlayer player, @ErrorMessage(value = "R_USAGE", allowEAs = false) String... message) {
MsgCommand.msg(player, lastChats.get(player), message);
}
}

Datei anzeigen

@ -0,0 +1,86 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.ArenaMode;
import de.steamwar.bungeecore.Message;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.UserElo;
import de.steamwar.command.SWCommand;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.TypeMapper;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.Optional;
import java.util.stream.Collectors;
public class RankCommand extends SWCommand {
public RankCommand() {
super("rank");
}
@Register
public void ownRank(ProxiedPlayer player) {
rank(player, player.getName());
}
@Register
public void rank(ProxiedPlayer player, @Mapper("player") String s) {
SteamwarUser user = SteamwarUser.get(s);
if (user == null) {
Message.send("RANK_PLAYER_NOT_FOUND", player);
return;
}
if (!player.getName().equals(s)) {
Message.send("RANK_PLAYER_FOUND", player, user.getUserName());
}
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, getEmblemProgression(player, mode.getChatName(), user.getId()));
}
}
private static String getEmblemProgression(ProxiedPlayer player, String gameMode, int userId) {
int fightsOfSeason = UserElo.getFightsOfSeason(userId, gameMode);
if (fightsOfSeason < 10)
return Message.parse("RANK_NEEDED_FIGHTS_LEFT", player, "§8✧ ✦ ✶ ✷ ✸ ✹ ❂", 10 - fightsOfSeason);
return UserElo.getEmblemProgression(gameMode, userId);
}
@Mapper(value = "player", local = true)
public TypeMapper<String> playerTypeMapper() {
return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()));
}
}

Datei anzeigen

@ -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.commands;
import de.steamwar.bungeecore.Message;
import de.steamwar.command.SWCommand;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class RegelnCommand extends SWCommand {
public RegelnCommand() {
super("regeln", null, "rules");
}
@Register
public void genericCommand(ProxiedPlayer player) {
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)));
Message.sendPrefixless("REGELN_CONDUCT", player, Message.parse("REGELN_CONDUCT_HOVER", player), new ClickEvent(ClickEvent.Action.OPEN_URL, Message.parse("REGELN_CONDUCT_URL", player)));
}
}

Datei anzeigen

@ -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.ArenaMode;
import de.steamwar.messages.Message;
import de.steamwar.velocitycore.ServerStarter;
import de.steamwar.velocitycore.inventory.SWItem;
import de.steamwar.velocitycore.inventory.SWListInv;
import de.steamwar.velocitycore.inventory.SWStreamInv;
import de.steamwar.bungeecore.*;
import de.steamwar.bungeecore.inventory.SWItem;
import de.steamwar.bungeecore.inventory.SWListInv;
import de.steamwar.bungeecore.inventory.SWStreamInv;
import de.steamwar.sql.Fight;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SchematicType;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.PlayerChatter;
import de.steamwar.sql.*;
import de.steamwar.messages.ChatSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ReplayCommand extends SWCommand {
@ -39,13 +42,15 @@ public class ReplayCommand extends SWCommand {
}
@Register
public void genericCommand(PlayerChatter sender, @OptionalValue("") String optionalMap) {
public void genericCommand(ProxiedPlayer player, @OptionalValue("") String optionalMap) {
ChatSender sender = ChatSender.of(player);
if (PunishmentCommand.isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer))
return;
new SWStreamInv<>(sender, new Message("REPLAY_TITLE"), (click, fight) -> {
new SWStreamInv<>(player, Message.parse("REPLAY_TITLE", player), (click, fight) -> {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
ArenaMode mode = ArenaMode.getBySchemType(fight.getSchemType());
ServerStarter starter = new ServerStarter().replay(fight.getFightID()).blueLeader(sender.getPlayer());
ServerStarter starter = new ServerStarter().replay(fight.getFightID()).blueLeader(player);
String map = mode.getRandomMap();
if (!optionalMap.equals("")) {
@ -53,27 +58,27 @@ public class ReplayCommand extends SWCommand {
if (tMap != null) map = tMap;
}
if (sender.user().hasPerm(UserPerm.MODERATION) && click.isShiftClick() && fight.replayExists()) {
starter.test(mode, map, sender.getPlayer()).start();
if (user.getUserGroup().isAdminGroup() && click.isShiftClick() && fight.replayExists()) {
starter.test(mode, map, player).start();
} else if(!fight.replayAllowed()) {
sender.system("REPLAY_UNAVAILABLE");
} else {
starter.arena(mode, map).start();
}
}, page -> Fight.getPage(page, 45).stream().map(fight -> new SWListInv.SWListEntry<>(getFightItem(fight), fight)).toList()).open();
}, page -> Fight.getPage(page, 45).stream().map(fight -> new SWListInv.SWListEntry<>(getFightItem(sender, fight), fight)).collect(Collectors.toList())).open();
}
private SWItem getFightItem(Fight fight) {
private SWItem getFightItem(ChatSender sender, Fight fight) {
SchematicType type = fight.getSchemType();
SWItem item = new SWItem(type != null ? type.getMaterial() : "BARRIER", parseLeader(fight.getBlueLeader(), fight.getBluePlayers().size(), fight.getWin() == 1));
SWItem item = new SWItem(type != null ? type.getMaterial() : "BARRIER", parseLeader(sender, fight.getBlueLeader(), fight.getBluePlayers().size(), fight.getWin() == 1));
List<Message> lore = new ArrayList<>();
lore.add(parseLeader(fight.getRedLeader(), fight.getRedPlayers().size(), fight.getWin() == 2));
lore.add(new Message("REPLAY_TIME", fight.getStartTime()));
lore.add(new Message("SPACER"));
lore.add(new Message("REPLAY_SERVER", fight.getServer()));
List<String> lore = new ArrayList<>();
lore.add(parseLeader(sender, fight.getRedLeader(), fight.getRedPlayers().size(), fight.getWin() == 2));
lore.add(sender.parseToLegacy("REPLAY_TIME", fight.getStartTime()));
lore.add("");
lore.add(sender.parseToLegacy("REPLAY_SERVER", fight.getServer()));
if(!fight.replayAllowed())
lore.add(new Message("REPLAY_UNAVAILABLE"));
lore.add(sender.parseToLegacy("REPLAY_UNAVAILABLE"));
item.setLore(lore);
if(fight.replayAllowed())
@ -82,7 +87,7 @@ public class ReplayCommand extends SWCommand {
return item;
}
private Message parseLeader(SteamwarUser leader, int players, boolean winner) {
return new Message("REPLAY_" + (players > 1 ? "" : "SOLO_") + (winner ? "WINNER" : "LOSER"), leader.getUserName(), players - 1);
private String parseLeader(ChatSender sender, SteamwarUser leader, int players, boolean winner) {
return sender.parseToLegacy(winner ? (players > 1 ? "REPLAY_WINNER" : "REPLAY_SOLO_WINNER") : (players > 1 ? "REPLAY_LOSER" : "REPLAY_SOLO_LOSER"), leader.getUserName(), players - 1);
}
}

Datei anzeigen

@ -17,24 +17,26 @@
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 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 ServerSwitchCommand extends SWCommand {
private final RegisteredServer server;
private String serverName;
public ServerSwitchCommand(String cmd, String name, String... aliases) {
super(cmd, null, aliases);
server = VelocityCore.getProxy().getServer(name).orElseThrow();
public ServerSwitchCommand(String cmd, String name, String permission, String... aliases) {
super(cmd, permission, aliases);
serverName = name;
}
@Register
public void genericCommand(PlayerChatter sender) {
sender.getPlayer().createConnectionRequest(server).fireAndForget();
public void genericCommand(ProxiedPlayer player) {
ServerInfo target = ProxyServer.getInstance().getServerInfo(serverName);
player.connect(target);
}
}

Datei anzeigen

@ -17,21 +17,21 @@
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.bungeecore.listeners.ChatListener;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter;
import de.steamwar.sql.UserPerm;
import de.steamwar.messages.ChatSender;
import net.md_5.bungee.api.CommandSender;
public class ServerTeamchatCommand extends SWCommand {
public ServerTeamchatCommand() {
super("stc", UserPerm.TEAM, "serverteamchat");
super("stc", "bungeecore.teamchat","serverteamchat");
}
@Register(description = "STC_USAGE")
public void genericCommand(Chatter sender, @ErrorMessage(value = "STC_USAGE", allowEAs = false) String... message) {
ChatListener.sendChat(sender, Chatter.serverteam(), "CHAT_SERVERTEAM", null, String.join(" ", message));
public void genericCommand(CommandSender commandSender, @ErrorMessage(value = "STC_USAGE", allowEAs = false) String... message) {
ChatListener.sendChat(ChatSender.of(commandSender), ChatSender.serverteamReceivers(), "CHAT_SERVERTEAM", null, String.join(" ", message));
}
}

Datei anzeigen

@ -17,25 +17,27 @@
* 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.network.NetworkSender;
import de.steamwar.bungeecore.network.NetworkSender;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.ChatSender;
import de.steamwar.network.packets.server.LocaleInvalidationPacket;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.Objects;
public class SetLocaleCommand extends SWCommand {
public SetLocaleCommand() {
super("setlocale", "setlanguage");
super("setlocale", null, "setlanguage");
}
@Register
public void genericCommand(Chatter sender) {
sender.user().setLocale(Objects.requireNonNull(sender.getLocale()), true);
sender.withPlayer(player -> NetworkSender.send(player, new LocaleInvalidationPacket(sender.user().getId())));
public void genericCommand(ProxiedPlayer player) {
ChatSender sender = ChatSender.of(player);
sender.user().setLocale(Objects.requireNonNull(player.getLocale()), true);
NetworkSender.send(player, new LocaleInvalidationPacket(sender.user().getId()));
sender.system("LOCK_LOCALE_CHANGED");
}
}

Datei anzeigen

@ -17,12 +17,13 @@
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.Node;
import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.Node;
import de.steamwar.bungeecore.util.SchematicSearch;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter;
import de.steamwar.sql.UserPerm;
import net.md_5.bungee.api.CommandSender;
import java.io.BufferedReader;
import java.io.InputStreamReader;
@ -32,11 +33,12 @@ import java.util.Map;
public class StatCommand extends SWCommand {
public StatCommand() {
super("stat", UserPerm.ADMINISTRATION, "stats");
super("stat", "bungeecore.softreload", "stats");
}
@Register
public void genericCommand(Chatter sender) {
public void genericCommand(CommandSender sender) {
Message.send("STAT_SEARCH_QUEUE", sender, SchematicSearch.getQueueSize());
Map<String, Integer> serverCount = new HashMap<>();
try {
Process process = new ProcessBuilder("ps", "x").start();
@ -52,6 +54,6 @@ public class StatCommand extends SWCommand {
throw new SecurityException(e.getMessage(), e);
}
Node.forEach(node -> sender.prefixless("STAT_SERVER", node.getName(), node.belowLoadLimit(), serverCount.getOrDefault(node.getName(), 0)));
Node.forEach(node -> Message.send("STAT_SERVER", sender, node.getName(), node.belowLoadLimit(), serverCount.getOrDefault(node.getName(), 0)));
}
}

Datei anzeigen

@ -0,0 +1,684 @@
/*
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.Storage;
import de.steamwar.bungeecore.inventory.SWItem;
import de.steamwar.bungeecore.inventory.SWListInv;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.Team;
import de.steamwar.sql.TeamTeilnahme;
import de.steamwar.command.PreviousArguments;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
import de.steamwar.messages.ChatSender;
import de.steamwar.sql.Event;
import net.md_5.bungee.BungeeCord;
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.ServerConnectRequest;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
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.event.ServerConnectEvent;
import java.net.*;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import static de.steamwar.bungeecore.Storage.teamInvitations;
public class TeamCommand extends SWCommand {
private static final List<SWListInv.SWListEntry<String>> COLOR_CODES = new ArrayList<>();
static {
addColor("4", 1);
addColor("c", 15);
addColor("6", 14);
addColor("e", 11);
addColor("2", 2);
addColor("a", 10);
addColor("b", 12);
addColor("3", 6);
addColor("1", 4);
addColor("9", 6);
addColor("d", 9);
addColor("5", 5);
addColor("f", 15);
addColor("7", 7);
addColor("8", 8);
addColor("0", 16);
}
private static void addColor(String color, int colorCode) {
COLOR_CODES.add(new SWListInv.SWListEntry(new SWItem("§" + color, colorCode), color));
}
public TeamCommand() {
super("team");
}
@Register(noTabComplete = true)
public void help(CommandSender sender, String... args){
Message.send("TEAM_HELP_HEADER", sender);
Message.send("TEAM_HELP_LIST", sender);
Message.send("TEAM_HELP_INFO", sender);
if(!(sender instanceof ProxiedPlayer))
return;
Message.send("TEAM_HELP_TP", sender);
ProxiedPlayer player = (ProxiedPlayer) sender;
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if(user.getTeam() == 0) {
Message.send("TEAM_HELP_CREATE", sender);
Message.send("TEAM_HELP_JOIN", sender);
}else{
Message.send("TEAM_HELP_CHAT", sender);
Message.send("TEAM_HELP_EVENT", sender);
Message.send("TEAM_HELP_LEAVE", sender);
if(user.isLeader()){
Message.send("TEAM_HELP_INVITE", sender);
Message.send("TEAM_HELP_REMOVE", sender);
Message.send("TEAM_HELP_KUERZEL", sender);
Message.send("TEAM_HELP_NAME", sender);
Message.send("TEAM_HELP_COLOR", sender);
Message.send("TEAM_HELP_LEADER", sender);
Message.send("TEAM_HELP_STEP_BACK", sender);
Message.send("TEAM_HELP_SERVER", sender);
}
}
}
@Register(value = "create", description = "TEAM_CREATE_USAGE")
public void create(ProxiedPlayer player, @Length(min = 2, max = 4) @ErrorMessage("TEAM_KUERZEL_LENGTH") String kuerzel, @Length(min = 4, max = 15) @ErrorMessage("TEAM_NAME_LENGTH") String name){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(unwantedInTeam(player, user))
return;
if(checkTeamKuerzel(player, team, kuerzel))
return;
if(checkTeamName(player, team, name))
return;
Team.create(kuerzel, name);
user.setTeam(Team.get(kuerzel).getTeamId());
user.setLeader(true);
Message.send("TEAM_CREATE_CREATED", player, name);
}
@Register("join")
public void join(ProxiedPlayer player, String... args){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if(unwantedInTeam(player, user))
return;
if(notDuringEvent(player))
return;
if(!teamInvitations.containsKey(user.getId())){
Message.send("TEAM_JOIN_NO_INVITE", player);
return;
}
List<Integer> invs = teamInvitations.get(user.getId());
Integer t = null;
if(invs.size() == 1){
t = invs.get(0);
}else{
if(args.length != 1){
Message.send("TEAM_JOIN_USAGE", player);
StringBuilder sb = new StringBuilder();
for(int inv : invs){
Team team = Team.get(inv);
sb.append(team.getTeamName()).append(" ");
}
Message.send("TEAM_JOIN_INVITED", player, sb.toString());
return;
}
for(int inv : invs){
Team team = Team.get(inv);
if(team.getTeamName().equals(args[0])){
t = inv;
break;
}
}
if(t == null){
Message.send("TEAM_JOIN_NOT_BY_TEAM", player);
return;
}
}
user.setTeam(t);
teamInvitations.remove(user.getId());
Message.send("TEAM_JOIN_JOINED", player, Team.get(t).getTeamName());
}
@Register("stepback")
public void stepBack(ProxiedPlayer player) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(notLeader(player, user))
return;
if(team.size() > 1 && team.getMembers().stream().map(SteamwarUser::get).filter(member -> user != member).noneMatch(SteamwarUser::isLeader)){
Message.send("TEAM_OTHER_LEADER_REQUIRED", player);
return;
}
user.setLeader(false);
Message.send("TEAM_STEP_BACK", player);
}
@Register("leave")
public void leave(ProxiedPlayer player){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(notInTeam(player, user))
return;
int teamSize = team.size();
if(teamSize > 1 && user.isLeader() && team.getMembers().stream().map(SteamwarUser::get).filter(member -> user != member).noneMatch(SteamwarUser::isLeader)){
Message.send("TEAM_OTHER_LEADER_REQUIRED", player);
return;
}
user.setTeam(0);
if(teamSize == 1){
team.disband(user);
}
Message.send("TEAM_LEAVE_LEFT", player);
}
@Register(value = "invite", description = "TEAM_INVITE_USAGE")
public void invite(ProxiedPlayer player, String toInvite){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(notLeader(player, user))
return;
if(notDuringEvent(player))
return;
SteamwarUser target = SteamwarUser.get(toInvite);
if(target == null){
Message.send("TEAM_INVITE_NO_PLAYER", player);
return;
}else if(target.getTeam() != 0){
Message.send("TEAM_INVITE_IN_TEAM", player);
return;
}
if(!teamInvitations.containsKey(target.getId()))
teamInvitations.put(target.getId(), new LinkedList<>());
if(teamInvitations.get(target.getId()).contains(team.getTeamId())){
Message.send("TEAM_INVITE_ALREADY_INVITED", player);
return;
}
teamInvitations.get(target.getId()).add(team.getTeamId());
Message.send("TEAM_INVITE_INVITED", player, toInvite);
ProxiedPlayer p = ProxyServer.getInstance().getPlayer(target.getUUID());
if(p != null)
Message.send("TEAM_INVITE_INVITED_TARGET", p, team.getTeamColor(), team.getTeamName());
}
@Register(value = "remove", description = "TEAM_REMOVE_USAGE")
public void remove(ProxiedPlayer player, String toRemove){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(notLeader(player, user))
return;
SteamwarUser target = SteamwarUser.get(toRemove);
if(target == null){
Message.send("TEAM_REMOVE_NOT_PLAYER", player);
return;
}
if (target.isLeader()) {
Message.send("TEAM_REMOVE_NOT_LEADER", player);
return;
}
if(teamInvitations.containsKey(target.getId())){
if(teamInvitations.get(target.getId()).remove((Integer) team.getTeamId())){
Message.send("TEAM_REMOVE_INVITE", player);
if(teamInvitations.get(target.getId()).isEmpty())
teamInvitations.remove(target.getId());
}else{
Message.send("TEAM_REMOVE_NO_INVITE", player);
}
return;
}
if(target.getTeam() != user.getTeam()){
Message.send("TEAM_REMOVE_NOT_IN_TEAM", player);
return;
}
target.setTeam(0);
Message.send("TEAM_REMOVE_REMOVED", player);
ProxiedPlayer p = ProxyServer.getInstance().getPlayer(target.getUUID());
if(p != null)
Message.send("TEAM_REMOVE_REMOVED_TARGET", player);
}
@Register(value = "changekurzel", description = "TEAM_KUERZEL_USAGE")
public void changekuerzel(ProxiedPlayer player, @Length(min = 2, max = 4) @ErrorMessage("TEAM_KUERZEL_LENGTH") String kuerzel){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(notLeader(player, user))
return;
if(notDuringEvent(player))
return;
if(checkTeamKuerzel(player, team, kuerzel))
return;
team.setTeamKuerzel(kuerzel);
Message.send("TEAM_KUERZEL_CHANGED", player);
}
@Register(value = "changename", description = "TEAM_NAME_USAGE")
public void changename(ProxiedPlayer player, @Length(min = 4, max = 15) @ErrorMessage("TEAM_NAME_LENGTH") String name){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(notLeader(player, user))
return;
if(notDuringEvent(player))
return;
if(checkTeamName(player, team, name))
return;
team.setTeamName(name);
Message.send("TEAM_NAME_CHANGED", player);
}
@Register(value = "promote", description = "TEAM_LEADER_USAGE")
public void promote(ProxiedPlayer player, String toPromote){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
if(notLeader(player, user))
return;
if(notDuringEvent(player))
return;
SteamwarUser target = SteamwarUser.get(toPromote);
if(target == null){
Message.send("TEAM_LEADER_NOT_USER", player, toPromote);
return;
}
if(target.getTeam() != user.getTeam()){
Message.send("TEAM_LEADER_NOT_MEMBER", player);
return;
}
target.setLeader(true);
Message.send("TEAM_LEADER_PROMOTED", player, toPromote);
}
private String playerName(SteamwarUser user){
return ProxyServer.getInstance().getPlayer(user.getUUID()) != null ? "§a" + user.getUserName() : "§e" + user.getUserName();
}
@Register("info")
public void info(ProxiedPlayer player, String... args){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(args.length == 0 && user.getTeam() == 0){
Message.send("TEAM_INFO_USAGE", player);
return;
}else if(user.getTeam() == 0 || args.length == 1){
team = Team.get(args[0]);
}
if(team == null){
Message.send("UNKNOWN_TEAM", player);
return;
}
Message.sendPrefixless("TEAM_INFO_TEAM", player, team.getTeamName(), team.getTeamColor(), team.getTeamKuerzel());
List<SteamwarUser> users = team.getMembers().stream().map(SteamwarUser::get).collect(Collectors.toList());
Message.sendPrefixless("TEAM_INFO_LEADER", player, getMemberList(users, true));
String members = getMemberList(users, false);
if(members.length() > 0) {
Message.sendPrefixless("TEAM_INFO_MEMBER", player, members);
}
Set<Event> events = TeamTeilnahme.getEvents(team.getTeamId());
if(!events.isEmpty()){
Message.sendPrefixless("TEAM_INFO_EVENTS", player, events.stream().map(Event::getEventName).collect(Collectors.joining(", ")));
}
}
private String getMemberList(List<SteamwarUser> users, boolean leaders) {
StringBuilder sb = new StringBuilder();
for(SteamwarUser user : users) {
if(user.isLeader() == leaders) {
sb.append(playerName(user)).append(" ");
}
}
return sb.toString();
}
@Register("list")
public void list(ProxiedPlayer player, @Min(intValue = 1) @OptionalValue("1") @ErrorMessage("TEAM_LIST_NOT_PAGE") int page){
final int TEAMS_PER_PAGE = 10;
List<Team> all = Team.getAll();
final int lastPage = ((all.size() - 1) / 10) + 1;
if(page < 1 || page > lastPage){
Message.send("TEAM_LIST_UNKNOWN_PAGE", player);
return;
}
Message.sendPrefixless("TEAM_LIST_HEADER", player, page, lastPage);
for(int i = (page-1) * TEAMS_PER_PAGE; i < (page-1) * TEAMS_PER_PAGE + TEAMS_PER_PAGE && i < all.size(); i++){
Team tm = all.get(i);
Message.sendPrefixless("TEAM_LIST_TEAM", player, Message.parse("TEAM_LIST_TEAM_HOVER", player),
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/team info " + tm.getTeamKuerzel()), tm.getTeamColor(), tm.getTeamKuerzel(), tm.getTeamName());
}
TextComponent beforePage = new TextComponent("««");
if(page > 1){
beforePage.setColor(ChatColor.YELLOW);
beforePage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Message.parse("TEAM_LIST_PREV", player)).create()));
beforePage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/team list " + (page - 1)));
}else
beforePage.setColor(ChatColor.DARK_GRAY);
TextComponent nextPage = new TextComponent(" " + Message.parse("TEAM_LIST_PAGE", player) +" »»");
if(page < lastPage){
nextPage.setColor(ChatColor.YELLOW);
nextPage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(Message.parse("TEAM_LIST_NEXT", player)).create()));
nextPage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/team list " + (page + 1)));
}else
nextPage.setColor(ChatColor.DARK_GRAY);
beforePage.addExtra(nextPage);
player.sendMessage(beforePage);
}
@Register("event")
public void event(ProxiedPlayer player) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(notInTeam(player, user))
return;
Message.send("TEAM_EVENT_USAGE", player);
Set<Event> events = TeamTeilnahme.getEvents(team.getTeamId());
if(!events.isEmpty()){
Message.send("TEAM_EVENT_HEADER", player);
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(Message.parse("EVENT_DATE_FORMAT", player));
for(Event e : events)
Message.sendPrefixless("TEAM_EVENT_EVENT", player, e.getStart().toLocalDateTime().format(dateFormat), e.getEventName());
}
}
@Register("event")
public void event(ProxiedPlayer player, Event event){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(notInTeam(player, user))
return;
if(notLeader(player, user))
return;
if(notDuringEvent(player))
return;
if(Instant.now().isAfter(event.getDeadline().toInstant())){
Message.send("TEAM_EVENT_OVER", player);
return;
}
if(TeamTeilnahme.nimmtTeil(team.getTeamId(), event.getEventID())){
TeamTeilnahme.notTeilnehmen(team.getTeamId(), event.getEventID());
Message.send("TEAM_EVENT_LEFT", player);
}else{
TeamTeilnahme.teilnehmen(team.getTeamId(), event.getEventID());
Message.send("TEAM_EVENT_JOINED", player, event.getEventName());
Message.sendPrefixless("TEAM_EVENT_HOW_TO_LEAVE", player);
}
}
@Register("tp")
public void tp(ProxiedPlayer player, String... args){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(args.length == 0){
if(notInTeam(player, user))
return;
tp(player, team);
return;
}
Team targetTeam = Team.get(args[0]);
if(targetTeam == null){
Message.send("TEAM_TP_NO_TEAM", player);
return;
}
tp(player, targetTeam);
}
private void tp(ProxiedPlayer player, Team targetTeam) {
if (targetTeam.getAddress() == null) {
Message.send("TEAM_NO_ADDRESS", player);
return;
}
ServerInfo serverInfo = Storage.teamServers.computeIfAbsent(targetTeam.getTeamId(), integer -> {
InetSocketAddress address = new InetSocketAddress(targetTeam.getAddress(), targetTeam.getPort());
ServerInfo info = ProxyServer.getInstance().constructServerInfo("Team " + targetTeam.getTeamKuerzel(), address, "SteamWar.de - Teamserver", false);
ProxyServer.getInstance().getServers().put(info.getName(), info);
return info;
});
player.connect(ServerConnectRequest.builder()
.target(serverInfo)
.connectTimeout(BungeeCord.getInstance().getConfig().getServerConnectTimeout())
.retry(false)
.reason(ServerConnectEvent.Reason.PLUGIN)
.callback((success, error) -> {
if (error != null) {
Message.send("TEAM_OFFLINE", player);
}
})
.build());
/*
((UserConnection) player).connect(serverInfo, (success, error) -> {
if (error != null) {
Message.send("TEAM_OFFLINE", player);
}
}, false, ServerConnectEvent.Reason.PLUGIN, BungeeCord.getInstance().getConfig().getServerConnectTimeout(), false);
*/
}
@Register(value = "server", description = "TEAM_SERVER_USAGE")
public void server(ProxiedPlayer player, String server, @Min(intValue = 1) @Max(intValue = 65535) @ErrorMessage("TEAM_SERVER_PORT_INVALID") int port){
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(notLeader(player, user))
return;
if (PunishmentCommand.isPunishedWithMessage(ChatSender.of(player), Punishment.PunishmentType.NoTeamServer)) {
return;
}
try {
if (isLocalhost(InetAddress.getByName(server))) {
Message.send("TEAM_SERVER_ADDRESS_INVALID", player);
return;
}
} catch (UnknownHostException e) {
Message.send("TEAM_SERVER_ADDRESS_INVALID", player);
return;
}
team.setAddress(server);
team.setPort(port);
Storage.teamServers.remove(team.getTeamId());
Message.send("TEAM_SERVER_SET", player);
}
public static boolean isLocalhost(InetAddress addr) {
// Check if the address is a valid special local or loop back
if (addr.isAnyLocalAddress() || addr.isLoopbackAddress())
return true;
// Check if the address is defined on any interface
try {
return NetworkInterface.getByInetAddress(addr) != null;
} catch (SocketException e) {
return false;
}
}
@Register("color")
public void changeColor(ProxiedPlayer player) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
if(notLeader(player, user))
return;
if(notDuringEvent(player))
return;
List<SWListInv.SWListEntry<String>> colors = new ArrayList<>();
COLOR_CODES.forEach(stringSWListEntry -> {
SWItem item = stringSWListEntry.getItem().clone();
item.setName(stringSWListEntry.getItem().getTitle() + Team.get(user.getTeam()).getTeamKuerzel());
colors.add(new SWListInv.SWListEntry<>(item, stringSWListEntry.getObject()));
});
SWListInv<String> inv = new SWListInv<>(player, Message.parse("TEAM_COLOR_TITLE", player), colors, (click, element) -> {});
inv.setCallback((click, element) -> {
inv.close();
team.setTeamColor(element);
});
inv.open();
}
@ClassMapper(Event.class)
public TypeMapper<Event> eventTypeMapper() {
return new TypeMapper<Event>() {
@Override
public Event map(CommandSender commandSender, String[] previousArguments, String s) {
return Event.get(s);
}
@Override
public boolean validate(CommandSender sender, Event value, MessageSender messageSender) {
if (value == null) {
messageSender.send("TEAM_EVENT_NO_EVENT", sender);
return false;
} else {
return true;
}
}
@Override
public Collection<String> tabCompletes(CommandSender sender, PreviousArguments previousArguments, String s) {
return Event.getComing().stream().map(Event::getEventName).collect(Collectors.toList());
}
};
}
private boolean checkTeamName(ProxiedPlayer player, Team team, String arg){
Team t = Team.get(arg);
if(t != null && t.getTeamId() != team.getTeamId()){
Message.send("TEAM_NAME_TAKEN", player);
return true;
}
return false;
}
private boolean checkTeamKuerzel(ProxiedPlayer player, Team team, String arg){
Team t = Team.get(arg);
if(t != null && (team == null || t.getTeamId() != team.getTeamId())){
Message.send("TEAM_KUERZEL_TAKEN", player);
return true;
}
return false;
}
private boolean unwantedInTeam(ProxiedPlayer player, SteamwarUser user){
if(user.getTeam() != 0){
Message.send("TEAM_IN_TEAM", player);
return true;
}
return false;
}
private boolean notInTeam(ProxiedPlayer player, SteamwarUser user){
if(user.getTeam() == 0){
Message.send("TEAM_NOT_IN_TEAM", player);
return true;
}
return false;
}
private boolean notLeader(ProxiedPlayer player, SteamwarUser user){
if(notInTeam(player, user))
return true;
if(!user.isLeader()){
Message.send("TEAM_NOT_LEADER", player);
return true;
}
return false;
}
private boolean notDuringEvent(ProxiedPlayer player){
if(Event.get() != null){
Message.send("TEAM_NOT_IN_EVENT", player);
return true;
}
return false;
}
}

Datei anzeigen

@ -17,22 +17,24 @@
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.Chatter;
import de.steamwar.messages.ChatterGroup;
import de.steamwar.bungeecore.listeners.ChatListener;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.ChatSender;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class TeamchatCommand extends SWCommand {
public TeamchatCommand() {
super("tc", "teamchat");
super("tc", "","teamchat");
}
@Register(description = "TC_USAGE")
public void genericCommand(Chatter sender, @ErrorMessage(value = "TC_USAGE", allowEAs = false) String... args) {
public void genericCommand(ProxiedPlayer player, @ErrorMessage(value = "TC_USAGE", allowEAs = false) String... args) {
ChatSender sender = ChatSender.of(player);
SteamwarUser user = sender.user();
if(user.getTeam() == 0){
@ -40,6 +42,6 @@ public class TeamchatCommand extends SWCommand {
return;
}
ChatListener.sendChat(sender, new ChatterGroup(Chatter.allStream().filter(p -> p.user().getTeam() == user.getTeam())), "CHAT_TEAM", null, String.join(" ", args));
ChatListener.sendChat(sender, ChatSender.allReceivers().filter(p -> p.user().getTeam() == user.getTeam()), "CHAT_TEAM", null, String.join(" ", args));
}
}

Datei anzeigen

@ -0,0 +1,162 @@
/*
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.sql.BauweltMember;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.Team;
import de.steamwar.bungeecore.util.BauLock;
import de.steamwar.bungeecore.util.Chat19;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper;
import de.steamwar.messages.ChatSender;
import de.steamwar.sql.Event;
import net.md_5.bungee.BungeeCord;
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.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class TpCommand extends SWCommand {
public TpCommand(){
super("join", null, "tp", "teleport");
}
@Register
public void genericCommand(ProxiedPlayer p) {
ChatSender.of(p).system(Event.get() == null ? "TP_USAGE" : "TP_USAGE_EVENT");
}
@Register
public void teleportCommand(ProxiedPlayer p, @Mapper("to") String to, String... rest) {
ServerInfo server = getTarget(to);
//Give control of teleport command to server
if (server == p.getServer().getInfo() || server == null) {
if (rest.length == 0) {
Chat19.chat(p, "/tp " + to);
} else {
Chat19.chat(p, "/tp " + to + " " + String.join(" ", rest));
}
return;
}
teleport(p, server);
}
@Mapper("to")
@Cached(cacheDuration = 10, global = true)
public TypeMapper<String> tabCompleter() {
return new TypeMapper<String>() {
@Override
public String map(CommandSender commandSender, String[] previousArguments, String s) {
return s;
}
@Override
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
List<String> list = new ArrayList<>();
for (ProxiedPlayer player : BungeeCord.getInstance().getPlayers()) {
list.add(player.getName());
}
if (Event.get() != null) {
EventStarter.getEventServer().keySet().forEach(teamId -> {
Team team = Team.get(teamId);
list.add(team.getTeamName());
list.add(team.getTeamKuerzel());
});
}
return list;
}
};
}
public static void teleport(ProxiedPlayer player, ServerInfo server){
ChatSender sender = ChatSender.of(player);
if(CheckCommand.isChecking(player)){
sender.system("CHECK_CHECKING");
return;
}
String serverPerm = BungeeCore.serverPermissions.get(server.getName());
Subserver subserver = Subserver.getSubserver(server);
if (subserver != null && subserver.getType() == Servertype.ARENA) {
if (!PunishmentCommand.isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer))
SubserverSystem.sendPlayer(subserver, player);
} else if(subserver instanceof Bauserver) {
Bauserver bauserver = (Bauserver) subserver;
ProxiedPlayer checker = BungeeCord.getInstance().getPlayer(bauserver.getOwner());
if (checker != null && CheckCommand.isChecking(checker)) {
SteamwarUser steamwarUser = SteamwarUser.get(player.getUniqueId());
if (steamwarUser.getUserGroup().isCheckSchematics() || CheckCommand.getCheckingSchem(checker).getOwner() == steamwarUser.getId()) {
SubserverSystem.sendPlayer(subserver, player);
} else {
sender.system("JOIN_PLAYER_BLOCK");
}
}else if (BauLock.isLocked(SteamwarUser.get(bauserver.getOwner()), sender.user())) {
Message.send("BAU_LOCKED_NOALLOWED", player);
}else if (bauserver.getOwner().equals(player.getUniqueId()) || BauweltMember.getBauMember(bauserver.getOwner(), player.getUniqueId()) != null) {
SubserverSystem.sendPlayer(subserver, player);
} else {
SubserverSystem.sendDeniedMessage(player, bauserver.getOwner());
sender.system("JOIN_PLAYER_BLOCK");
}
} else if(subserver instanceof Builderserver && !player.hasPermission("bungeecore.server.team")) {
sender.system("JOIN_PLAYER_BLOCK");
} else if (serverPerm != null && !player.hasPermission(serverPerm)) {
sender.system("JOIN_PLAYER_BLOCK");
} else if (serverPerm == null && !player.getGroups().contains("team")) {
sender.system("JOIN_PLAYER_BLOCK");
} else {
player.connect(server);
}
}
private static ServerInfo getTarget(String arg) {
ServerInfo server = null;
//Get target player server
ProxiedPlayer target = ProxyServer.getInstance().getPlayer(arg);
if(target != null)
server = target.getServer().getInfo();
//Get target team event arena
if(server == null){
Team team = Team.get(arg);
if(team != null){
Subserver eventArena = EventStarter.getEventServer().get(team.getTeamId());
if(eventArena != null && Subserver.getServerList().contains(eventArena))
server = eventArena.getServer();
}
}
return server;
}
}

Datei anzeigen

@ -0,0 +1,169 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2022 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.inventory.SWListInv;
import de.steamwar.bungeecore.inventory.SWStreamInv;
import de.steamwar.bungeecore.util.Chat19;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.sql.Tutorial;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
public class TutorialCommand extends SWCommand {
public TutorialCommand() {
super("tutorial", null);
}
@Register
public void genericCommand(ProxiedPlayer player) {
openInventory(player, true, false);
}
@Register("rate")
public void rate(ProxiedPlayer player) {
Chat19.chat(player, "/tutorial rate");
}
@Register("rate")
public void rate(ProxiedPlayer player, int id) {
Tutorial tutorial = Tutorial.get(id);
if(tutorial == null) {
Chat19.chat(player, "/tutorial rate"); // Catch players manually entering numbers
return;
}
rate(player, tutorial);
}
@Register(value = "create", description = "TUTORIAL_CREATE_HELP")
public void create(ProxiedPlayer player, String material, String... name) {
create(player, String.join(" ", name), material.toUpperCase());
}
@Register("own")
public void own(ProxiedPlayer player) {
openInventory(player, false, true);
}
@Register("unreleased")
public void unreleased(@Validator("unreleased") ProxiedPlayer player) {
openInventory(player, false, false);
}
@Validator("unreleased")
public TypeValidator<ProxiedPlayer> unreleasedChecker() {
return (sender, value, messageSender) -> {
return (SteamwarUser.get((value).getUniqueId()).getUserGroup().isTeamGroup());
};
}
private void openInventory(ProxiedPlayer player, boolean released, boolean own) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
new SWStreamInv<>(
player,
Message.parse("TUTORIAL_TITLE", player),
(click, tutorial) -> {
if(!released && click.isShiftClick() && user.getUserGroup().isTeamGroup() && user.getId() != tutorial.getCreator()) {
tutorial.release();
openInventory(player, released, own);
return;
} else if(own && click.isShiftClick() && click.isRightClick()) {
tutorial.delete();
SubserverSystem.deleteFolder(BungeeCore.local, world(tutorial).getPath());
openInventory(player, released, own);
return;
}
new ServerStarter().tutorial(player, tutorial).start();
},
page -> (own ? Tutorial.getOwn(user.getId(), page, 45) : Tutorial.getPage(page, 45, released)).stream().map(tutorial -> new SWListInv.SWListEntry<>(getTutorialItem(player, tutorial, own), tutorial)).collect(Collectors.toList())
).open();
}
private SWItem getTutorialItem(ProxiedPlayer player, Tutorial tutorial, boolean personalHighlights) {
SWItem item = new SWItem(tutorial.getItem(), Message.parse("TUTORIAL_NAME", player, tutorial.getName()));
item.setHideAttributes(true);
List<String> lore = new ArrayList<>();
lore.add(Message.parse("TUTORIAL_BY", player, SteamwarUser.get(tutorial.getCreator()).getUserName()));
lore.add(Message.parse("TUTORIAL_STARS", player, String.format("%.1f", tutorial.getStars())));
if (personalHighlights)
lore.add(Message.parse("TUTORIAL_DELETE", player));
item.setLore(lore);
if (personalHighlights && tutorial.isReleased())
item.setEnchanted(true);
return item;
}
private void rate(ProxiedPlayer player, Tutorial tutorial) {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
int[] rates = new int[]{1, 2, 3, 4, 5};
new SWListInv<>(player, Message.parse("TUTORIAL_RATE_TITLE", player), Arrays.stream(rates).mapToObj(rate -> new SWListInv.SWListEntry<>(new SWItem("NETHER_STAR", Message.parse("TUTORIAL_RATE", player, rate)), rate)).collect(Collectors.toList()), (click, rate) -> {
tutorial.rate(user.getId(), rate);
SWInventory.close(player);
}).open();
}
private void create(ProxiedPlayer player, String name, String item) {
Subserver subserver = Subserver.getSubserver(player);
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
File tempWorld = new File(ServerStarter.TEMP_WORLD_PATH, ServerStarter.serverToWorldName(ServerStarter.bauServerName(user)));
if(subserver == null || !subserver.hasStarted() || subserver.getType() != Servertype.BAUSERVER || !tempWorld.exists()) {
Message.send("TUTORIAL_CREATE_MISSING", player);
return;
}
subserver.execute("save-all");
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
Tutorial tutorial = Tutorial.create(user.getId(), name, item);
File tutorialWorld = world(tutorial);
if (tutorialWorld.exists())
SubserverSystem.deleteFolder(BungeeCore.local, tutorialWorld.getPath());
ServerStarter.copyWorld(BungeeCore.local, tempWorld.getPath(), tutorialWorld.getPath());
Message.send("TUTORIAL_CREATED", player);
}, 1, TimeUnit.SECONDS);
}
private File world(Tutorial tutorial) {
return new File(ServerStarter.TUTORIAL_PATH, String.valueOf(tutorial.getTutorialId()));
}
}

Datei anzeigen

@ -17,19 +17,22 @@
* 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.ArenaMode;
import de.steamwar.command.PreviousArguments;
import de.steamwar.bungeecore.ArenaMode;
import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker;
import de.steamwar.sql.Punishment;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.TypeMapper;
import de.steamwar.command.TypeValidator;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.PlayerChatter;
import de.steamwar.sql.Punishment;
import de.steamwar.messages.ChatSender;
import lombok.experimental.UtilityClass;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@UtilityClass
public class TypeMappers {
@ -41,38 +44,52 @@ public class TypeMappers {
SWCommandUtils.addMapper("arenaMap", arenaMapTypeMapper());
}
private static TypeValidator<PlayerChatter> arenaPlayer() {
return (sender, player, messageSender) -> !PunishmentCommand.isPunishedWithMessage(player, Punishment.PunishmentType.NoFightServer);
private static TypeValidator<ProxiedPlayer> arenaPlayer() {
return (sender, value, messageSender) -> {
ChatSender player = ChatSender.of(value);
if (PunishmentCommand.isPunishedWithMessage(player, Punishment.PunishmentType.NoFightServer)) {
return false;
}
if (ModLoaderBlocker.isFabric(value)) {
messageSender.send("MODLOADER_DENIED");
return false;
}
return true;
};
}
private static TypeMapper<ArenaMode> arenaModeTypeMapper(boolean historic) {
return new TypeMapper<>() {
return new TypeMapper<ArenaMode>() {
@Override
public ArenaMode map(Chatter sender, PreviousArguments previousArguments, String s) {
public ArenaMode map(CommandSender commandSender, String[] previousArguments, String s) {
return ArenaMode.getByChat(s);
}
@Override
public Collection<String> tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) {
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
return ArenaMode.getAllChatNames(historic);
}
};
}
private static TypeMapper<String> arenaMapTypeMapper() {
return new TypeMapper<>() {
return new TypeMapper<String>() {
@Override
public String map(Chatter sender, PreviousArguments previousArguments, String s) {
if (previousArguments.userArgs.length == 0) return null;
return ArenaMode.getByChat(previousArguments.userArgs[previousArguments.userArgs.length - 1]).convertToRealMapName(s);
public String map(CommandSender commandSender, String[] previousArguments, String s) {
if (previousArguments.length == 0) return null;
if (s.equalsIgnoreCase("random")) return "random";
return ArenaMode.getByChat(previousArguments[previousArguments.length - 1]).convertToRealMapName(s);
}
@Override
public Collection<String> tabCompletes(Chatter sender, PreviousArguments previousArguments, String s) {
if (previousArguments.userArgs.length == 0) return null;
ArenaMode arenaMode = ArenaMode.getByChat(previousArguments.userArgs[previousArguments.userArgs.length - 1]);
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
if (previousArguments.length == 0) return null;
ArenaMode arenaMode = ArenaMode.getByChat(previousArguments[previousArguments.length - 1]);
if (arenaMode == null) return null;
return arenaMode.getMaps();
List<String> stringList = new ArrayList<>(arenaMode.getMaps());
stringList.add("random");
return stringList;
}
};
}

Datei anzeigen

@ -17,12 +17,13 @@
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.bungeecore.Message;
import de.steamwar.sql.IgnoreSystem;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import net.md_5.bungee.api.connection.ProxiedPlayer;
public class UnIgnoreCommand extends SWCommand {
@ -31,15 +32,19 @@ public class UnIgnoreCommand extends SWCommand {
}
@Register(description = "UNIGNORE_USAGE")
public void genericCommand(Chatter sender, @ErrorMessage("UNIGNORE_NOT_PLAYER") SteamwarUser target) {
SteamwarUser user = sender.user();
public void genericCommand(ProxiedPlayer p, String toUnIgnore) {
SteamwarUser user = SteamwarUser.get(p.getUniqueId());
if(!IgnoreSystem.isIgnored(user, target)){
sender.system("UNIGNORE_NOT_IGNORED");
SteamwarUser target = SteamwarUser.get(toUnIgnore);
if(target == null){
Message.send("UNIGNORE_NOT_PLAYER", p);
return;
}else if(!IgnoreSystem.isIgnored(user, target)){
Message.send("UNIGNORE_NOT_IGNORED", p);
return;
}
IgnoreSystem.unIgnore(user, target);
sender.system("UNIGNORE_UNIGNORED", target.getUserName());
Message.send("UNIGNORE_UNIGNORED", p, target.getUserName());
}
}

Datei anzeigen

@ -17,16 +17,17 @@
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.VelocityCore;
import de.steamwar.velocitycore.discord.util.AuthManager;
import de.steamwar.bungeecore.BungeeCore;
import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.bot.AuthManager;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.Member;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.Base64;
import java.util.logging.Level;
public class VerifyCommand extends SWCommand {
@ -35,26 +36,29 @@ public class VerifyCommand extends SWCommand {
}
@Register(description = "VERIFY_USAGE")
public void genericCommand(Chatter sender, String code) {
public void genericCommand(ProxiedPlayer sender, String code) {
byte[] bytes;
try {
bytes = Base64.getDecoder().decode(code);
} catch (IllegalArgumentException e) {
sender.system("VERIFY_INVALID");
Message.send("VERIFY_INVALID", sender);
return;
}
if(bytes.length != 16) {
sender.system("VERIFY_INVALID");
Message.send("VERIFY_INVALID", sender);
return;
}
User user = AuthManager.connectAuth(sender.user(), code);
if(user != null) {
VelocityCore.getLogger().log(Level.INFO,"%s Verified with Discorduser: %s".formatted(sender.user().getUserName(), user.getIdLong()));
sender.system("VERIFY_SUCCESS", user.getAsTag());
if(bytes[0] == 'D' && bytes[1] == 'C') {
Member member = AuthManager.connectAuth(SteamwarUser.get(sender.getName()), code);
if(member != null) {
BungeeCore.log(sender.getName() + " Verified with Discorduser: " + member.getIdLong());
Message.send("VERIFY_SUCCESS", sender, member.getUser().getAsTag());
} else {
Message.send("VERIFY_INVALID", sender);
}
} else {
sender.system("VERIFY_INVALID");
Message.send("VERIFY_INVALID", sender);
}
}
}

Datei anzeigen

@ -17,10 +17,11 @@
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.messages.ChatSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.io.BufferedReader;
import java.io.IOException;
@ -29,18 +30,18 @@ import java.io.InputStreamReader;
public class WebpasswordCommand extends SWCommand {
public WebpasswordCommand() {
super("webpassword", "webpw", "web");
super("webpassword", null, "webpw", "web");
}
@Register(description = "WEB_USAGE")
public void genericCommand(Chatter sender, String password) {
public void genericCommand(ProxiedPlayer player, String password) {
if(password.length() < 8) {
sender.system("WEB_PASSWORD_LENGTH");
ChatSender.of(player).system("WEB_PASSWORD_LENGTH");
return;
}
ProcessBuilder pb = new ProcessBuilder("php", "/var/www/register.php", sender.user().getUserName(), password);
ProcessBuilder pb = new ProcessBuilder("php", "/var/www/register.php", player.getName(), password);
pb.redirectErrorStream(true);
try {
Process regProcess = pb.start();
@ -48,14 +49,14 @@ public class WebpasswordCommand extends SWCommand {
String errorLine;
if((errorLine = reader.readLine()) != null) {
if ("updated".equals(errorLine)) {
sender.system("WEB_UPDATED");
ChatSender.of(player).system("WEB_UPDATED");
return;
} else {
throw new SecurityException("Could not create webaccount " + errorLine);
}
}
sender.system("WEB_CREATED");
ChatSender.of(player).system("WEB_CREATED");
} catch (IOException e) {
throw new SecurityException("Could not create webaccount", e);
}

Datei anzeigen

@ -0,0 +1,190 @@
/*
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.Storage;
import de.steamwar.bungeecore.listeners.mods.Utils;
import de.steamwar.command.SWCommand;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.TypeMapper;
import de.steamwar.sql.*;
import lombok.Getter;
import net.md_5.bungee.BungeeCord;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class WhoisCommand extends SWCommand {
public WhoisCommand() {
super("whois");
}
@Register(description = "WHOIS_USAGE")
public void genericCommand(ProxiedPlayer player, @Mapper("player") String target, WhoisParameterTypes... parameters) {
SteamwarUser user = SteamwarUser.get(target);
if (user == null) {
try {
int id = Integer.parseInt(target);
user = SteamwarUser.get(id);
} catch (NumberFormatException ignored) {
}
}
if (user == null) {
try {
long id = Long.parseLong(target);
user = SteamwarUser.get(id);
} catch (NumberFormatException ignored) {
// Ignored
}
}
if (user == null) {
Message.send("UNKNOWN_PLAYER", player);
} else {
EnumSet<WhoisParameterTypes> set = parameters.length == 0 ? EnumSet.noneOf(WhoisParameterTypes.class) : EnumSet.copyOf(Arrays.asList(parameters));
sendUserinfo(player, user, set);
}
}
@Mapper(value = "player", local = true)
public TypeMapper<String> playerTypeMapper() {
return SWCommandUtils.createMapper(s -> s, s -> BungeeCord.getInstance().getPlayers().stream().map(ProxiedPlayer::getName).collect(Collectors.toList()));
}
private static void sendUserinfo(ProxiedPlayer player, SteamwarUser user, EnumSet<WhoisParameterTypes> parameterTypes) {
UserGroup userGroup = SteamwarUser.get(player.getUniqueId()).getUserGroup();
Message.send("WHOIS_USERNAME", player, user.getUserName());
Message.send("WHOIS_GROUP", player, user.getUserGroup().getColorCode(), user.getUserGroup().name());
Team team = Team.get(user.getTeam());
Message.send("WHOIS_TEAM", player, Message.parse("WHOIS_TEAM_HOVER", player, team.getTeamName()), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/team info " + team.getTeamKuerzel()), team.getTeamColor(), team.getTeamKuerzel(), team.getTeamName());
if (!userGroup.isTeamGroup()) return;
if (userGroup.isAdminGroup()) {
Message.send("WHOIS_UUID", player, Message.parse("WHOIS_UUID_HOVER", player), new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, user.getUUID().toString()), user.getUUID().toString());
Message.send("WHOIS_ID", player, user.getId());
if (user.getDiscordId() != null) {
Message.send("WHOIS_DISCORD_ID", player, user.getDiscordId());
}
}
Timestamp firstJoin = user.getFirstjoin();
if (firstJoin == null) {
Message.send("WHOIS_JOINED_FIRST", player, "0000-00-00 00:00:00");
} else {
Message.send("WHOIS_JOINED_FIRST", player, firstJoin.toString());
}
Message.send("WHOIS_HOURS_PLAYED", player, new DecimalFormat("###.##").format(user.getOnlinetime() / 3600d));
if(BungeeCord.getInstance().getPlayer(user.getUUID()) != null) {
ProxiedPlayer target = BungeeCord.getInstance().getPlayer(user.getUUID());
Message.send("WHOIS_CURRENT_PLAYED", player, new DecimalFormat("####.##").format((Instant.now().getEpochSecond() - Storage.sessions.get(target).toInstant().getEpochSecond()) / 60d));
Message.send("WHOIS_CURRENT_SERVER", player, target.getServer().getInfo().getName());
Message.send("WHOIS_CURRENT_PROTOCOL", player, target.getPendingConnection().getVersion());
}
if (Utils.playerModMap.containsKey(user.getUUID())) {
Mod.Platform modPlatform = Utils.playerModMap.get(user.getUUID()).get(0).getPlatform();
Message.send("WHOIS_PLATFORM", player, modPlatform.toString());
}
if (parameterTypes.contains(WhoisParameterTypes.MOD)) {
List<Mod> activeMods = Utils.playerModMap.get(user.getUUID());
if (activeMods != null && !activeMods.isEmpty()) {
Message.send("WHOIS_ACTIVE_MODS", player,activeMods.size());
String result = activeMods.stream().map(mod -> "§" + mod.getModType().getColorCode() + mod.getModName()).collect(Collectors.joining("§8, "));
Message.send("WHOIS_ACTIVE_MOD", player, result);
} else {
Message.send("WHOIS_NO_ACTIVE_MODS", player);
}
}
Message.send("WHOIS_PUNISHMENTS", player);
List<Punishment> punishmentList = Punishment.getAllPunishmentsOfPlayer(user.getId());
Set<Punishment.PunishmentType> found = new HashSet<>();
boolean isPunished = false;
boolean all = parameterTypes.contains(WhoisParameterTypes.ALL);
for (Punishment punishment : punishmentList) {
if (!all && !punishment.getType().isMulti() && !found.add(punishment.getType())) {
continue;
}
if (!all && !punishment.isCurrent()) {
continue;
}
Message.sendPrefixless("WHOIS_PUNISHMENT", player, SteamwarUser.get(punishment.getPunisher()).getUserName(), punishment.getType().name(), punishment.getBantime(punishment.getStartTime(), false), punishment.getBantime(punishment.getEndTime(), punishment.isPerma()), punishment.getReason());
isPunished = true;
}
if (!isPunished) {
Message.send(all ? "WHOIS_NO_ALL_PUNISHMENT" : "WHOIS_NO_PUNISHMENT", player);
}
}
@ClassMapper(value = WhoisParameterTypes.class, local = true)
public TypeMapper<WhoisParameterTypes> argumentTypeMapper() {
WhoisParameterTypes[] values = WhoisParameterTypes.values();
return new TypeMapper<WhoisParameterTypes>() {
@Override
public WhoisParameterTypes map(CommandSender commandSender, String[] previousArguments, String s) {
UserGroup userGroup = SteamwarUser.get(((ProxiedPlayer) commandSender).getUniqueId()).getUserGroup();
return Stream.of(values)
.filter(p -> p.userGroupSet.contains(userGroup))
.filter(p -> p.getTabCompletes().contains(s))
.findFirst()
.orElse(null);
}
@Override
public Collection<String> tabCompletes(CommandSender commandSender, String[] previousArguments, String s) {
UserGroup userGroup = SteamwarUser.get(((ProxiedPlayer) commandSender).getUniqueId()).getUserGroup();
return Stream.of(values)
.filter(p -> p.userGroupSet.contains(userGroup))
.flatMap(p -> p.getTabCompletes().stream())
.collect(Collectors.toList());
}
};
}
private enum WhoisParameterTypes {
ALL(Arrays.asList("-a", "-all"), UserGroup.Admin, UserGroup.Moderator, UserGroup.Developer, UserGroup.Supporter, UserGroup.Builder),
MOD(Arrays.asList("-m", "-mod", "-mods"), UserGroup.Admin, UserGroup.Moderator, UserGroup.Developer);
private final EnumSet<UserGroup> userGroupSet;
@Getter
private List<String> tabCompletes;
WhoisParameterTypes(List<String> tabCompletes, UserGroup... userGroups) {
this.userGroupSet = EnumSet.copyOf(Arrays.asList(userGroups));
this.tabCompletes = tabCompletes;
}
}
}

Datei anzeigen

@ -17,13 +17,13 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.velocitycore.inventory;
package de.steamwar.bungeecore.inventory;
public interface InvCallback {
void clicked(ClickType click);
enum ClickType {
public static enum ClickType {
LEFT,
SHIFT_LEFT,
RIGHT,

Datei anzeigen

@ -0,0 +1,158 @@
/*
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.inventory;
import de.steamwar.bungeecore.network.NetworkSender;
import de.steamwar.bungeecore.network.handlers.InventoryCallbackHandler;
import de.steamwar.sql.SteamwarUser;
import de.steamwar.network.packets.server.CloseInventoryPacket;
import de.steamwar.network.packets.server.InventoryPacket;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiFunction;
public class SWInventory {
private final Map<Integer, SWItem> itemMap;
private InvCallback close;
private ProxiedPlayer player;
private int size;
private String title;
private boolean next;
private final AtomicBoolean processingClick = new AtomicBoolean();
public SWInventory(ProxiedPlayer proxiedPlayer, int size, String title) {
itemMap = new HashMap<>();
InventoryCallbackHandler.inventoryHashMap.put(SteamwarUser.get(proxiedPlayer.getUniqueId()).getId(), this);
this.player = proxiedPlayer;
this.size = size;
this.title = title;
next = false;
}
public void addItem(int pos, SWItem item, InvCallback callback) {
addItem(pos, item, new ArrayList<>(), callback);
}
public void addItem(int pos, SWItem item, List<String> lore, InvCallback callback) {
item.setCallback(callback);
item.setLore(lore);
itemMap.put(pos, item);
}
public void addItem(int pos, SWItem item) {
itemMap.put(pos, item);
}
public void addItem(int pos, SWItem item, String name, InvCallback callback) {
item.setName(name);
item.setCallback(callback);
itemMap.put(pos, item);
}
public void removeItem(int position) {
itemMap.remove(position);
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public void setTitle(String title) {
this.title = title;
}
public void setCallback(int pos, InvCallback callback) {
itemMap.get(pos).setCallback(callback);
}
public void setNext(boolean next) {
this.next = next;
}
public boolean isNext() {
return next;
}
public Map<Integer, SWItem> getItems() {
return itemMap;
}
public void handleCallback(InvCallback.ClickType type, int pos) {
if(processingClick.compareAndSet(false, true)) {
itemMap.get(pos).getCallback().clicked(type);
processingClick.set(false);
}
}
public void handleClose() {
if(processingClick.compareAndSet(false, true)) {
InventoryCallbackHandler.inventoryHashMap.remove(SteamwarUser.get(player.getUniqueId()).getId(), this);
if(close != null)
close.clicked(null);
processingClick.set(false);
}
}
public void open() {
InventoryPacket inv = new InventoryPacket(title, SteamwarUser.get(player.getUniqueId()).getId(), size, map(itemMap, (integer, swItem) -> swItem.writeToString(integer).toString()));
NetworkSender.send(player, inv);
}
private static <T, K, J> Map<T, J> map(Map<T, K> map, BiFunction<T, K, J> function) {
Map<T, J> result = new HashMap<>();
map.forEach((key, value) -> result.put(key, function.apply(key, value)));
return result;
}
public void close() {
close(player);
}
public static void close(ProxiedPlayer player) {
NetworkSender.send(player, new CloseInventoryPacket(SteamwarUser.get(player.getUniqueId()).getId()));
}
public void setClose(InvCallback close) {
this.close = close;
}
public ProxiedPlayer getPlayer() {
return player;
}
public void setPlayer(ProxiedPlayer player) {
this.player = player;
}
public String getTitle() {
return title;
}
}

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen