SteamWar/BungeeCore
Archiviert
13
2

Commits vergleichen

..

1 Commits

Autor SHA1 Nachricht Datum
yoyosource
f463c99eec Add some basic punishment stuff
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
2022-11-21 17:28:08 +01:00
258 geänderte Dateien mit 14154 neuen und 11395 gelöschten Zeilen

@ -1 +1 @@
Subproject commit d000b8687d93eb43520bbf6685281099055eab9f Subproject commit 0c68dfd19dc32a848be2cf399e00bc2863739b57

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/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import org.apache.tools.ant.taskdefs.condition.Os
plugins { 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 'base'
id 'java' id 'java'
id 'application' id 'application'
id 'com.github.johnrengelman.shadow' version '8.1.1' id 'com.github.johnrengelman.shadow' version '5.0.0'
id 'de.steamwar.gradle' version 'RELEASE'
} }
group 'de.steamwar' group 'de.steamwar'
version '' 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' compileJava.options.encoding = 'UTF-8'
java { sourceCompatibility = 1.8
sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = 1.8
targetCompatibility = JavaVersion.VERSION_17
}
mainClassName = '' mainClassName = ''
@ -50,64 +78,176 @@ sourceSets {
} }
} }
allprojects { repositories {
repositories {
mavenCentral() mavenCentral()
maven {
url 'https://repo.papermc.io/repository/maven-public/'
content {
includeGroup 'com.velocitypowered'
}
}
maven { maven {
url 'https://m2.dv8tion.net/releases' url 'https://m2.dv8tion.net/releases'
content {
includeGroup 'net.dv8tion'
} }
}
maven {
url 'https://repo.lunarclient.dev'
content {
includeGroup 'com.lunarclient'
}
}
}
}
shadowJar { maven {
exclude 'META-INF/*' url = uri('https://steamwar.de/maven')
exclude 'org/sqlite/native/FreeBSD/**', 'org/sqlite/native/Mac/**', 'org/sqlite/native/Windows/**', 'org/sqlite/native/Linux-Android/**', 'org/sqlite/native/Linux-Musl/**'
exclude 'org/sqlite/native/Linux/aarch64/**', 'org/sqlite/native/Linux/arm/**', 'org/sqlite/native/Linux/armv6/**', 'org/sqlite/native/Linux/armv7/**', 'org/sqlite/native/Linux/ppc64/**', 'org/sqlite/native/Linux/x86/**'
exclude 'org/slf4j/**'
//https://imperceptiblethoughts.com/shadow/configuration/minimizing/
minimize {
exclude project(':')
exclude dependency('mysql:mysql-connector-java:.*')
} }
duplicatesStrategy DuplicatesStrategy.INCLUDE
} }
dependencies { dependencies {
compileOnly 'org.projectlombok:lombok:1.18.32' compileOnly 'org.projectlombok:lombok:1.18.22'
testCompileOnly 'org.projectlombok:lombok:1.18.32' testCompileOnly 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'org.projectlombok:lombok:1.18.32' annotationProcessor 'org.projectlombok:lombok:1.18.22'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.32' testAnnotationProcessor 'org.projectlombok:lombok:1.18.22'
annotationProcessor 'com.velocitypowered:velocity-api:3.3.0-SNAPSHOT'
compileOnly 'de.steamwar:velocity:RELEASE'
compileOnly project(":Persistent")
implementation project(":CommonCore")
implementation 'org.xerial:sqlite-jdbc:3.46.0.0'
implementation 'mysql:mysql-connector-java:8.0.33'
compileOnly 'de.steamwar:waterfall:RELEASE'
compileOnly 'de.steamwar:persistentbungeecore:RELEASE'
implementation("net.dv8tion:JDA:4.4.0_352") { implementation("net.dv8tion:JDA:4.4.0_352") {
exclude module: 'opus-java' 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 #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 distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

Datei anzeigen

@ -17,16 +17,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
pluginManagement { rootProject.name = 'BungeeCore'
repositories {
gradlePluginPortal()
maven {
url = uri("https://steamwar.de/maven/")
}
}
}
rootProject.name = 'VelocityCore'
include 'CommonCore' include 'CommonCore'
include 'Persistent'

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.bungeecore.sql.SchematicType;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.config.Configuration;
import net.md_5.bungee.config.ConfigurationProvider;
import net.md_5.bungee.config.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class ArenaMode {
private static final Map<String, ArenaMode> byChat = new HashMap<>();
private static final Map<String, ArenaMode> byInternal = new HashMap<>();
private static final Map<SchematicType, ArenaMode> bySchemType = new HashMap<>();
private static final List<ArenaMode> allModes = new LinkedList<>();
private static final Random random = new Random();
static {
File folder = new File(ProxyServer.getInstance().getPluginsFolder(), "FightSystem");
for(File configFile : Arrays.stream(folder.listFiles((file, name) -> name.endsWith(".yml") && !name.endsWith(".kits.yml"))).sorted().collect(Collectors.toList())) {
Configuration config;
try {
config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
} catch (IOException e) {
throw new SecurityException("Could not load SchematicTypes", e);
}
if(config.contains("Server"))
new ArenaMode(configFile.getName().replace(".yml", ""), config);
}
}
public static ArenaMode getByChat(String name){
return byChat.get(name.toLowerCase());
}
public static ArenaMode getByInternal(String name){
return byInternal.get(name);
}
public static List<String> getAllChatNames(boolean historic) {
List<String> chatNames = new LinkedList<>();
for(ArenaMode mode : byInternal.values()){
if(historic == mode.historic)
chatNames.addAll(mode.chatNames);
}
return chatNames;
}
public static List<String> getAllRankedChatNames(){
List<String> chatNames = new LinkedList<>();
for(ArenaMode mode : byInternal.values()){
if(mode.isRanked())
chatNames.addAll(mode.chatNames);
}
return chatNames;
}
public static ArenaMode getBySchemType(SchematicType schemType){
return bySchemType.get(schemType);
}
public static List<ArenaMode> getAllModes(){
return allModes;
}
private final String displayName;
private final String folder;
private final List<String> chatNames;
private final String serverJar;
private final String config;
private final List<String> maps;
private final 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/>. 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; import java.util.concurrent.TimeUnit;
class Broadcaster { class Broadcaster {
private final List<String> broadcasts = VelocityCore.get().getConfig().getBroadcasts(); private static String [] broadCastMsgs;
private int lastBroadCast = 0; private int lastBroadCast = 0;
Broadcaster() { Broadcaster(){
if(!broadcasts.isEmpty()) ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
VelocityCore.schedule(this::broadcast).repeat(10, TimeUnit.MINUTES).schedule(); if(!ProxyServer.getInstance().getPlayers().isEmpty())
} BungeeCore.broadcast(BungeeCore.CHAT_PREFIX + broadCastMsgs[lastBroadCast]);
lastBroadCast++;
private void broadcast() { if(lastBroadCast == broadCastMsgs.length){
if(!VelocityCore.getProxy().getAllPlayers().isEmpty())
Chatter.broadcast().system("PLAIN_STRING", broadcasts.get(lastBroadCast++));
if(lastBroadCast == broadcasts.size())
lastBroadCast = 0; lastBroadCast = 0;
} }
}, 10, 10, TimeUnit.MINUTES);
}
static void setBroadCastMsgs(String[] broadCastMsgs) {
Broadcaster.broadCastMsgs = broadCastMsgs;
}
} }

Datei anzeigen

@ -0,0 +1,341 @@
/*
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.sql.*;
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 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");
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 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();
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();
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();
// Punishment Commands:
new PunishmentCommand("ban", Punishment.PunishmentType.Ban);
new PunishmentCommand("mute", Punishment.PunishmentType.Mute);
new PunishmentCommand("noschemreceiving", Punishment.PunishmentType.NoSchemReceiving);
new PunishmentCommand("noschemsharing", Punishment.PunishmentType.NoSchemSharing);
new PunishmentCommand("noschemsubmitting", Punishment.PunishmentType.NoSchemSubmitting);
new PunishmentCommand("nodev", Punishment.PunishmentType.NoDevServer);
new PunishmentCommand("nofight", Punishment.PunishmentType.NoFightServer);
new PunishmentCommand("noteamserver", Punishment.PunishmentType.NoTeamServer);
new PunishmentCommand("note", Punishment.PunishmentType.Note);
if(!EVENT_MODE){
new BauCommand();
new 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.clearCache();
UserElo.clearCache();
Team.clearCache();
}, 1, 1, TimeUnit.HOURS);
if (SteamwarDiscordBotConfig.loaded) {
try {
new SteamwarDiscordBot();
} catch (Throwable e) {
getLogger().log(Level.SEVERE, "Could not initialize discord bot", e);
}
}
}
@Override
public void onDisable(){
if (SteamwarDiscordBotConfig.loaded) {
try {
SteamwarDiscordBot.instance().getJda().shutdown();
} catch (Throwable e) {
getLogger().log(Level.SEVERE, "Could not shutdown discord bot", e);
}
}
if(tablistManager != null)
tablistManager.disable();
errorLogger.unregister();
Statement.closeAll();
}
public static BungeeCore get() {
return instance;
}
public static TextComponent stringToText(String msg){
return new TextComponent(TextComponent.fromLegacyText(msg));
}
public static void send(ProxiedPlayer player, String msg){
send(player, msg, null, null);
}
public static void send(CommandSender sender, String msg){
sender.sendMessage(stringToText(msg));
}
public static void send(ProxiedPlayer player, ChatMessageType type, String msg){
send(player, type, msg, null, null);
}
public static void send(ProxiedPlayer player, String msg, String onHover, ClickEvent onClick){
send(player, ChatMessageType.SYSTEM, msg, onHover, onClick);
}
public static void send(ProxiedPlayer player, ChatMessageType type, String msg, String onHover, ClickEvent onClick){
if(type == ChatMessageType.CHAT && player.getChatMode() != ProxiedPlayer.ChatMode.SHOWN)
return;
TextComponent message = stringToText(msg);
if(onHover != null)
message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(onHover)));
if(onClick != null)
message.setClickEvent(onClick);
player.sendMessage(type, message);
}
public static void broadcast(String msg){
ProxyServer.getInstance().broadcast(stringToText(msg));
}
public static void broadcast(String msg, String onHover, ClickEvent onClick){
TextComponent message = stringToText(msg);
if(onHover != null)
message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(onHover)));
if(onClick != null)
message.setClickEvent(onClick);
ProxyServer.getInstance().broadcast(message);
}
public static void log(final ServerInfo server, final String msg){
log(server.getName() + ": " + msg);
}
public static void log(final ProxiedPlayer player, final String msg){
log(player.getName() + ": " + msg);
}
public static void log(final String msg){
log(Level.INFO, msg);
}
public static void log(final Level logLevel, final String msg){
get().getLogger().log(logLevel, msg);
}
public static void log(final String msg, final Throwable e){
get().getLogger().log(Level.SEVERE, msg, e);
}
private static void loadConfig(){
Configuration config;
try{
if(!get().getDataFolder().exists() && !get().getDataFolder().mkdir())
throw new IOException();
File configFile = new File(get().getDataFolder().getPath(), "config.yml");
if(!configFile.exists()){
boolean created = configFile.createNewFile();
if(created)
ProxyServer.getInstance().stop("Config file not initialized");
else
ProxyServer.getInstance().stop("Could not save conig file");
return;
}
config = ConfigurationProvider.getProvider(YamlConfiguration.class).load(configFile);
}catch(Exception e){
log("Could not save/load config.yml", e);
ProxyServer.getInstance().stop();
return;
}
CHAT_PREFIX = config.getString("prefix");
LOBBY_SERVER = config.getString("lobbyserver");
EVENT_MODE = config.getBoolean("eventmode");
Broadcaster.setBroadCastMsgs(config.getStringList("broadcasts").toArray(new String[1]));
PollSystem.init(config.getString("poll.question"), config.getStringList("poll.answers"));
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()) {
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.bungeecore.sql.SWException;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
public class ErrorLogger extends Handler {
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("Bungee", message, stacktrace);
}
@Override
public void flush() {
//ignored
}
@Override
public void close() {
//ignored
}
private static final List<String> ignoreContains;
static {
List<String> contains = new ArrayList<>();
contains.add("Error authenticating ");
contains.add("read timed out");
contains.add("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

@ -0,0 +1,96 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore;
import de.steamwar.bungeecore.sql.Event;
import de.steamwar.bungeecore.sql.EventFight;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.bungeecore.sql.Team;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.scheduler.ScheduledTask;
import java.sql.Timestamp;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
import static de.steamwar.bungeecore.Storage.eventServer;
public class EventStarter implements Runnable {
private static ScheduledTask task = null;
EventStarter(){
EventFight.loadAllComingFights();
if(task != null)
task.cancel();
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), this, 1, 10, TimeUnit.SECONDS);
}
public static Map<Integer, Subserver> getEventServer() {
return eventServer;
}
@Override
public void run() {
eventServer.entrySet().removeIf(entry -> !Subserver.getServerList().contains(entry.getValue()));
Queue<EventFight> fights = EventFight.getFights();
EventFight next;
while((next = nextFight(fights)) != null){
Team blue = Team.get(next.getTeamBlue());
Team red = Team.get(next.getTeamRed());
//Don't start EventServer if not the event bungee
if(BungeeCore.EVENT_MODE || !Event.get(next.getEventID()).spectateSystem()) {
ServerStarter starter = new ServerStarter().event(next);
ProxiedPlayer leiter = ProxyServer.getInstance().getPlayer(SteamwarUser.get(next.getKampfleiter()).getUuid());
if(leiter != null)
starter.send(leiter);
Subserver subserver = starter.start();
eventServer.put(blue.getTeamId(), subserver);
eventServer.put(red.getTeamId(), subserver);
Message.broadcast("EVENT_FIGHT_BROADCAST", "EVENT_FIGHT_BROADCAST_HOVER",
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/event " + blue.getTeamKuerzel()), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName());
} else {
Message.broadcast("EVENT_FIGHT_BROADCAST", "EVENT_FIGHT_BROADCAST_HOVER",
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/spectate"), blue.getTeamColor(), blue.getTeamName(), red.getTeamColor(), red.getTeamName());
}
}
}
private EventFight nextFight(Queue<EventFight> fights){
EventFight next = fights.peek();
if(next == null)
return null;
if(!next.getStartTime().before(new Timestamp(System.currentTimeMillis())))
return null;
return fights.poll();
}
}

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/>. 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 net.md_5.bungee.BungeeCord;
import java.io.File; import net.md_5.bungee.api.ProxyServer;
import java.io.IOException;
import java.io.InputStreamReader; import java.io.*;
import java.nio.file.Files;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -31,13 +30,7 @@ import java.util.logging.Level;
public abstract class Node { public abstract class Node {
//-Xquickstart Langzeitperformance testen! private static final List<String> OPENJ9_ARGS = Arrays.asList("-Xgc:excessiveGCratio=80", "-Xsyslog:none", "-Xtrace:none", "-Xdisableexplicitgc", "-XX:+AlwaysPreTouch", "-XX:+CompactStrings", "-XX:-HeapDumpOnOutOfMemory", "-XX:+ExitOnOutOfMemoryError", "-Dlog4j.configurationFile=log4j2.xml");
private static final 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 Set<String> JAVA_8 = new HashSet<>(); private static final Set<String> JAVA_8 = new HashSet<>();
static { static {
JAVA_8.add("paper-1.8.8.jar"); 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 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<>(); private static final List<Node> nodes = new ArrayList<>();
@ -71,10 +65,13 @@ public abstract class Node {
protected final String hostname; protected final String hostname;
protected volatile boolean belowLoadLimit = true; protected volatile boolean belowLoadLimit = true;
private long previousCpuLoaded = 0;
private long previousCpuTotal = 0;
protected Node(String hostname) { protected Node(String hostname) {
this.hostname = hostname; this.hostname = hostname;
nodes.add(this); 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) { public void execute(String... command) {
@ -83,7 +80,7 @@ public abstract class Node {
} catch (IOException e) { } catch (IOException e) {
throw new SecurityException("Could not execute command", e); throw new SecurityException("Could not execute command", e);
} catch (InterruptedException 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(); Thread.currentThread().interrupt();
} }
} }
@ -99,18 +96,17 @@ public abstract class Node {
if (JAVA_8.contains(serverJar)) if (JAVA_8.contains(serverJar))
cmd.add("/usr/lib/jvm/java-8-openj9-amd64/bin/java"); cmd.add("/usr/lib/jvm/java-8-openj9-amd64/bin/java");
else else
cmd.add("/usr/lib/jvm/java-21-openj9-amd64/bin/java"); cmd.add("java");
for(String param : dParams){ for(String param : dParams){
cmd.add("-D" + param); cmd.add("-D" + param);
} }
cmd.add("-Xshareclasses:nonfatal,name=" + directory.getName());
cmd.add("-Xmx" + xmx); cmd.add("-Xmx" + xmx);
cmd.add("-Xshareclasses:nonfatal,name=" + directory.getName());
cmd.addAll(OPENJ9_ARGS); cmd.addAll(OPENJ9_ARGS);
if (!JAVA_8.contains(serverJar)) { if (!JAVA_8.contains(serverJar)) {
cmd.add("--add-opens"); cmd.add("--add-opens");
cmd.add("java.base/jdk.internal.misc=ALL-UNNAMED"); cmd.add("java.base/jdk.internal.misc=ALL-UNNAMED");
cmd.add("-XX:-CRIUSecProvider");
} }
cmd.add("-jar"); cmd.add("-jar");
cmd.add("/binarys/" + serverJar); cmd.add("/binarys/" + serverJar);
@ -124,18 +120,28 @@ public abstract class Node {
cmd.add("nogui"); 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(); String line = meminfo.readLine();
while(!line.startsWith("MemAvailable")) { while(!line.startsWith("MemAvailable")) {
line = meminfo.readLine(); line = meminfo.readLine();
} }
long availableMem = Long.parseLong(line.replaceAll(" +", " ").split(" ")[1]); 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 { public static class LocalNode extends Node {
private static final File MEMINFO = new File("/proc/meminfo"); private static final File MEMINFO = new File("/proc/meminfo");
private static final File STAT = new File("/proc/stat");
public LocalNode() { public LocalNode() {
super("sw"); super("sw");
@ -152,10 +158,12 @@ public abstract class Node {
@Override @Override
protected void calcLoadLimit() { protected void calcLoadLimit() {
try (BufferedReader meminfo = new BufferedReader(new InputStreamReader(Files.newInputStream(MEMINFO.toPath())))) { try (BufferedReader loadavg = new BufferedReader(new InputStreamReader(new FileInputStream(STAT)))) {
calcLoadLimit(meminfo); try (BufferedReader meminfo = new BufferedReader(new InputStreamReader(new FileInputStream(MEMINFO)))) {
calcLoadLimit(loadavg, meminfo);
}
} catch (IOException e) { } 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; belowLoadLimit = false;
} }
} }
@ -170,7 +178,7 @@ public abstract class Node {
public RemoteNode(String hostname) { public RemoteNode(String hostname) {
super(hostname); super(hostname);
VelocityCore.getLogger().log(Level.INFO, "Added node {0}", hostname); BungeeCore.get().getLogger().log(Level.INFO, "Added node " + hostname);
} }
@Override @Override
@ -199,15 +207,17 @@ public abstract class Node {
@Override @Override
protected void calcLoadLimit() { protected void calcLoadLimit() {
try { try {
Process process = prepareExecution("cat /proc/meminfo").start(); Process process = prepareExecution("cat /proc/stat /proc/meminfo").start();
if(!process.waitFor(1, TimeUnit.SECONDS)) if(!process.waitFor(1, TimeUnit.SECONDS))
throw new IOException(hostname + " timeout"); throw new IOException(hostname + " timeout");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) { 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) { } catch (IOException e) {
if(belowLoadLimit) 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; belowLoadLimit = false;
} catch (InterruptedException e) { } catch (InterruptedException e) {
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();

Datei anzeigen

@ -1,55 +1,36 @@
/* package de.steamwar.bungeecore;
* 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.velocitycore; import de.steamwar.bungeecore.sql.EventFight;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.bungeecore.sql.Team;
import de.steamwar.bungeecore.sql.Tutorial;
import 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.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.file.Files; import java.nio.file.Files;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.function.BooleanSupplier; import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class ServerStarter { public class ServerStarter {
private static final Portrange BAU_PORTS = VelocityCore.MAIN_SERVER ? new Portrange(10100, 20000) : new Portrange(2100, 2200); private static final Portrange BAU_PORTS = BungeeCore.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 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 USER_HOME = System.getProperty("user.home") + "/";
private static final String EVENT_PATH = USER_HOME + "event/"; private static final String EVENT_PATH = USER_HOME + "event/";
public static final String TEMP_WORLD_PATH = USER_HOME + "arenaserver/"; public static final String TEMP_WORLD_PATH = USER_HOME + "arenaserver/";
public static final String TUTORIAL_PATH = USER_HOME + "tutorials/"; 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"; public static final String BUILDER_BASE_PATH = USER_HOME + "builder";
private File directory = null; private File directory = null;
@ -67,17 +48,15 @@ public class ServerStarter {
private boolean allowMerge = false; private boolean allowMerge = false;
private String fightMap = null; private String fightMap = null;
private String gameMode = null; private String gameMode = null;
private boolean checkpoint = false; private ServerConstructor constructor = (serverName, port, builder, shutdownCallback) -> new Arenaserver(serverName, gameMode, fightMap, allowMerge, port, builder, shutdownCallback);
private ServerConstructor constructor = (serverName, port, builder, shutdownCallback, failureCallback) -> new Arenaserver(serverName, gameMode, fightMap, allowMerge, port, builder, shutdownCallback);
private Consumer<Subserver> callback = subserver -> {};
private final Set<Player> playersToSend = new HashSet<>(); private final Set<ProxiedPlayer> playersToSend = new HashSet<>();
private final Map<String, String> arguments = new HashMap<>(); private final Map<String, String> arguments = new HashMap<>();
public ServerStarter arena(ArenaMode mode, String map) { public ServerStarter arena(ArenaMode mode, String map) {
portrange = ARENA_PORTS; portrange = ARENA_PORTS;
serverNameProvider = port -> mode.getGameName() + (port - portrange.start); serverNameProvider = port -> mode.getDisplayName() + (port - portrange.start);
serverJar = mode.getServerJar(); serverJar = mode.serverJar();
allowMerge = true; allowMerge = true;
fightMap = map; fightMap = map;
gameMode = mode.getInternalName(); gameMode = mode.getInternalName();
@ -88,13 +67,13 @@ public class ServerStarter {
} }
public ServerStarter event(EventFight eventFight) { public ServerStarter event(EventFight eventFight) {
arena(ArenaMode.getByInternal(eventFight.getSpielmodus()), eventFight.getMap()); arena(eventFight.getSpielmodus(), eventFight.getMap());
node = VelocityCore.local; node = BungeeCore.local;
worldDir = EVENT_PATH; worldDir = EVENT_PATH;
worldCleanup = () -> {}; worldCleanup = () -> {};
arguments.put("fightID", String.valueOf(eventFight.getFightID())); arguments.put("fightID", String.valueOf(eventFight.getFightID()));
fightMap = eventFight.getMap(); fightMap = eventFight.getMap();
gameMode = eventFight.getSpielmodus(); gameMode = eventFight.getSpielmodus().getInternalName();
String serverName = Team.get(eventFight.getTeamBlue()).getTeamKuerzel() + " vs " + Team.get(eventFight.getTeamRed()).getTeamKuerzel(); String serverName = Team.get(eventFight.getTeamBlue()).getTeamKuerzel() + " vs " + Team.get(eventFight.getTeamRed()).getTeamKuerzel();
serverNameProvider = port -> serverName; serverNameProvider = port -> serverName;
@ -102,7 +81,7 @@ public class ServerStarter {
return this; return this;
} }
public ServerStarter test(ArenaMode mode, String map, Player owner) { public ServerStarter test(ArenaMode mode, String map, ProxiedPlayer owner) {
arena(mode, map); arena(mode, map);
buildWithTemp(owner); buildWithTemp(owner);
portrange = BAU_PORTS; portrange = BAU_PORTS;
@ -110,12 +89,12 @@ public class ServerStarter {
return send(owner); return send(owner);
} }
public ServerStarter blueLeader(Player player) { public ServerStarter blueLeader(ProxiedPlayer player) {
arguments.put("blueLeader", player.getUniqueId().toString()); arguments.put("blueLeader", player.getUniqueId().toString());
return send(player); return send(player);
} }
public ServerStarter redLeader(Player player) { public ServerStarter redLeader(ProxiedPlayer player) {
arguments.put("redLeader", player.getUniqueId().toString()); arguments.put("redLeader", player.getUniqueId().toString());
return send(player); return send(player);
} }
@ -135,50 +114,38 @@ public class ServerStarter {
return this; return this;
} }
public ServerStarter build(ServerVersion version, UUID owner) { public ServerStarter build19(UUID owner) {
directory = version.getServerDirectory("Bau"); directory = new File(SERVER_PATH, "Bau19");
serverJar = version.getServerJar(); serverJar = "paper-1.19.2.jar";
worldDir = version.getWorldFolder(WORLDS_BASE_PATH); worldDir = WORLDS19_PATH;
worldName = version != ServerVersion.SPIGOT_12 ? String.valueOf(SteamwarUser.get(owner).getId()) : owner.toString(); worldName = String.valueOf(SteamwarUser.get(owner).getId());
checkpoint = true; buildWithWorld(owner, new File(directory, "Bauwelt").getPath());
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;
};
return this; 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"); directory = new File(SERVER_PATH, "Tutorial");
buildWithTemp(owner); buildWithTemp(owner);
tempWorld(TUTORIAL_PATH + tutorial.getTutorialId()); tempWorld(TUTORIAL_PATH + tutorial.id());
arguments.put("tutorial", String.valueOf(tutorial.getTutorialId())); arguments.put("tutorial", String.valueOf(tutorial.id()));
return send(owner); return send(owner);
} }
@ -188,7 +155,29 @@ public class ServerStarter {
worldCleanup = () -> SubserverSystem.deleteFolder(node, worldDir + worldName); 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()); build(owner.getUniqueId());
// Stop existing build server // Stop existing build server
@ -196,36 +185,39 @@ public class ServerStarter {
if(startingBau(owner)) if(startingBau(owner))
return false; return false;
Bauserver subserver = Bauserver.get(owner.getUniqueId()); for (Subserver subserver : Subserver.getServerList()) {
if(subserver != null && subserver.isStarted()) if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(owner.getUniqueId()) && subserver.hasStarted()) {
subserver.stop(); subserver.stop();
break;
}
}
return !startingBau(owner); return !startingBau(owner);
}; };
} }
private void build(UUID 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)); 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(); serverJar = version.getServerJar();
directory = version.getServerDirectory("Builder"); directory = version.getServerDirectory("Builder");
worldDir = version.getWorldFolder(BUILDER_BASE_PATH); worldDir = version.getWorldFolder(BUILDER_BASE_PATH);
worldName = map; worldName = map;
serverNameProvider = port -> "*" + map; serverNameProvider = port -> "" + map;
checkpoint = true; constructor = (serverName, port, builder, shutdownCallback) -> new Builderserver(serverName, worldName, port, builder, shutdownCallback);
constructor = (serverName, port, builder, shutdownCallback, failureCallback) -> new Builderserver(serverName, worldName, port, builder, shutdownCallback, failureCallback);
// Send players to existing server // Send players to existing server
startCondition = () -> { startCondition = () -> {
Builderserver subserver = Builderserver.get(worldName); for(Subserver subserver : Subserver.getServerList()) {
if (subserver != null) { if(subserver.getType() == Servertype.BUILDER && ((Builderserver)subserver).getMap().equals(worldName)) {
for(Player p : playersToSend) for(ProxiedPlayer p : playersToSend)
SubserverSystem.sendPlayer(subserver, p); SubserverSystem.sendPlayer(subserver, p);
return false; return false;
} }
}
return true; return true;
}; };
@ -243,19 +235,14 @@ public class ServerStarter {
return this; return this;
} }
public ServerStarter send(Player player) { public ServerStarter send(ProxiedPlayer player) {
playersToSend.add(player); playersToSend.add(player);
return this; return this;
} }
public ServerStarter callback(Consumer<Subserver> callback) { public Subserver start() {
this.callback = callback;
return this;
}
public boolean start() {
if(!startCondition.getAsBoolean()) if(!startCondition.getAsBoolean())
return false; return null;
int port = portrange.freePort(); int port = portrange.freePort();
String serverName = serverNameProvider.apply(port); String serverName = serverNameProvider.apply(port);
@ -263,10 +250,10 @@ public class ServerStarter {
if(node == null) { if(node == null) {
node = Node.getNode(); node = Node.getNode();
if(node == null) { if(node == null) {
for (Player p : playersToSend) for (ProxiedPlayer p : playersToSend)
Chatter.of(p).system("SERVER_START_OVERLOAD"); ChatSender.of(p).system("SERVER_START_OVERLOAD");
return false; return null;
} }
} }
if(worldName == null) if(worldName == null)
@ -275,46 +262,23 @@ public class ServerStarter {
worldSetup.run(); worldSetup.run();
arguments.put("logPath", worldName); arguments.put("logPath", worldName);
File checkpointDir = new File("/tmp/" + System.getProperty("user.name") + ".checkpoints/" + directory.getName() + "/" + worldName); Subserver subserver = constructor.construct(serverName, port, node.startServer(
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(
serverJar, directory, worldDir, worldName, port, xmx, arguments.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray(String[]::new) 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(ProxiedPlayer p : playersToSend)
for(Player p : playersToSend)
SubserverSystem.sendPlayer(subserver, p); SubserverSystem.sendPlayer(subserver, p);
callback.accept(subserver); return subserver;
} }
private static boolean startingBau(Player p) { private static boolean startingBau(ProxiedPlayer p) {
Bauserver subserver = Bauserver.get(p.getUniqueId()); for (Subserver subserver : Subserver.getServerList()) {
if(subserver != null && !subserver.isStarted()) { if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(p.getUniqueId()) && !subserver.hasStarted()) {
Chatter.of(p).system("BAU_START_ALREADY"); Message.send("BAU_START_ALREADY", p);
return true; return true;
} }
}
return false; return false;
} }
@ -331,7 +295,7 @@ public class ServerStarter {
} }
private interface ServerConstructor { 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 { private static class Portrange {
@ -357,7 +321,7 @@ public class ServerStarter {
Set<Integer> usedPorts; Set<Integer> usedPorts;
synchronized (Subserver.getServerList()) { 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)) { 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.2.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/>. 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.bungeecore.network.NetworkSender;
import de.steamwar.velocitycore.network.NetworkSender; import de.steamwar.bungeecore.network.handlers.FightInfoHandler;
import de.steamwar.velocitycore.network.handlers.FightInfoHandler; import de.steamwar.bungeecore.sql.IgnoreSystem;
import de.steamwar.messages.Chatter; import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.messages.Message;
import de.steamwar.network.packets.server.StartingServerPacket; import de.steamwar.network.packets.server.StartingServerPacket;
import de.steamwar.persistent.Subserver; import net.md_5.bungee.api.ProxyServer;
import de.steamwar.sql.IgnoreSystem; import net.md_5.bungee.api.chat.ClickEvent;
import de.steamwar.sql.SteamwarUser; import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.kyori.adventure.text.event.ClickEvent;
import java.util.UUID; import java.util.UUID;
@ -39,20 +37,23 @@ public class SubserverSystem {
node.execute("rm", "-r", worldName); node.execute("rm", "-r", worldName);
} }
public static void sendDeniedMessage(Chatter p, UUID owner) { public static void sendDeniedMessage(ProxiedPlayer p, UUID owner){
if(IgnoreSystem.isIgnored(owner, p.user().getUUID())){ ProxiedPlayer o = ProxyServer.getInstance().getPlayer(owner);
p.system("SERVER_IGNORED"); if(o == null)
return;
if(IgnoreSystem.isIgnored(o, p)){
Message.send("SERVER_IGNORED", p);
return; return;
} }
Chatter o = Chatter.of(owner); Message.send("SERVER_ADD_MEMBER", o, p.getName());
o.system("SERVER_ADD_MEMBER", p); Message.sendPrefixless("SERVER_ADD_MESSAGE", o, Message.parse("SERVER_ADD_MESSAGE_HOVER", o, p.getName()),
o.prefixless("SERVER_ADD_MESSAGE", new Message("SERVER_ADD_MESSAGE_HOVER"), ClickEvent.runCommand("/bau addmember " + p.user().getUserName())); 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); 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())); 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.bungeecore.sql.SteamwarUser;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.Button;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class AuthManager {
private static final Map<String, Long> TOKENS = new HashMap<>();
private static final Random rand = new Random();
public static String createDiscordAuthToken(Member member) {
if(TOKENS.containsValue(member.getIdLong())) return null;
byte[] randBytes = new byte[16];
rand.nextBytes(randBytes);
randBytes[0] = 'D';
randBytes[1] = 'C';
String code = Base64.getEncoder().encodeToString(randBytes);
TOKENS.put(code, member.getIdLong());
BungeeCore.log("Created Discord Auth-Token: " + code + " for: " + member.getUser().getAsTag());
BungeeCore.get().getProxy().getScheduler().schedule(BungeeCore.get(), () -> TOKENS.remove(code), 10, TimeUnit.MINUTES);
return code;
}
public static Member connectAuth(SteamwarUser user, String code) {
if (TOKENS.containsKey(code)) {
Member member = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).retrieveMemberById(TOKENS.get(code).longValue()).complete();
if(member == null) return null;
user.setDiscordId(member.getIdLong());
MessageBuilder builder = new MessageBuilder();
builder.setContent(":white_check_mark: Dein Discord Konto wurde mit **" + user.getUserName() + "** verknüpft");
builder.setActionRows(ActionRow.of(Button.success("tada", Emoji.fromUnicode("U+1F389")), Button.danger("invalid", "Ich war das nicht")));
try {
member.getUser().openPrivateChannel().queue(privateChannel -> privateChannel.sendMessage(builder.build()).queue());
if (member.getNickname() == null) {
try {
member.getGuild().modifyNickname(member, user.getUserName()).queue();
} catch (Exception e) {
// Ignored
}
}
TOKENS.remove(code);
return member;
} catch (Exception e) {
return null;
}
} else {
return null;
}
}
}

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.bungeecore.sql.Event;
import de.steamwar.messages.ChatSender;
import lombok.Getter;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.OnlineStatus;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction;
import net.dv8tion.jda.api.utils.MemberCachePolicy;
import net.md_5.bungee.api.ProxyServer;
import javax.security.auth.login.LoginException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
public class SteamwarDiscordBot {
private static SteamwarDiscordBot INSTANCE;
public static SteamwarDiscordBot instance() {
return INSTANCE;
}
@Getter
private volatile AnnouncementListener announcementListener;
@Getter
private volatile DiscordChatListener ingameChatListener;
@Getter
private volatile DiscordChatListener serverTeamChatListener;
@Getter
private final JDA jda;
@Getter
private static Map<String, BasicDiscordCommand> discordCommandMap = new HashMap<>();
public SteamwarDiscordBot() {
INSTANCE = this;
JDABuilder builder = JDABuilder.createDefault(SteamwarDiscordBotConfig.TOKEN);
builder.setStatus(OnlineStatus.ONLINE);
builder.setMemberCachePolicy(MemberCachePolicy.ONLINE);
try {
jda = builder.build();
} catch (LoginException e) {
throw new SecurityException("Could not Login: " + SteamwarDiscordBotConfig.TOKEN, e);
}
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
try {
jda.awaitReady();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
activity();
} catch (Exception e) {
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not set initial activity to discord", e);
}
EventManager.update();
SchematicsManager.update();
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
try {
activity();
EventManager.update();
SchematicsManager.update();
} catch (ErrorResponseException e) {
//ignored
}
}, 30, 30, TimeUnit.SECONDS);
DiscordRolesMessage.sendMessage();
DiscordRulesMessage.sendMessage();
DiscordTicketMessage.sendMessage();
new RolesInteractionButtonListener();
new DiscordTicketListener();
new DiscordAuthListener();
new DiscordEventListener();
new PrivateMessageListener();
announcementListener = new AnnouncementListener();
ingameChatListener = new DiscordChatListener(SteamwarDiscordBotConfig.INGAME_CHANNEL, "CHAT_DISCORD_GLOBAL", ChatSender::globalReceivers);
serverTeamChatListener = new DiscordChatListener(SteamwarDiscordBotConfig.SERVER_TEAM_CHANNEL, "CHAT_SERVERTEAM", ChatSender::serverteamReceivers);
new SlashCommandListener();
jda.retrieveCommands().complete().forEach(command -> jda.deleteCommandById(command.getId()).queue());
Guild guild = jda.getGuildById(SteamwarDiscordBotConfig.GUILD);
guild.retrieveCommands().complete().forEach(command -> guild.deleteCommandById(command.getId()).complete());
CommandListUpdateAction commands = jda.getGuildById(SteamwarDiscordBotConfig.GUILD).updateCommands();
addCommand(commands, new MuteCommand());
addCommand(commands, new BanCommand());
addCommand(commands, new WhoisCommand());
addCommand(commands, new TeamCommand());
addCommand(commands, new ListCommand());
addCommand(commands, new UnbanCommand());
commands.complete();
});
}
private void addCommand(CommandListUpdateAction commands, BasicDiscordCommand basicDiscordCommand) {
commands.addCommands(basicDiscordCommand);
discordCommandMap.put(basicDiscordCommand.getName(), basicDiscordCommand);
}
private int index = 0;
private void activity() {
switch (index) {
case 0:
Event event = Event.get();
if (event != null) {
jda.getPresence().setActivity(Activity.competing("dem Event " + event.getEventName()));
} else {
jda.getPresence().setActivity(Activity.playing("auf SteamWar.de"));
}
break;
case 1:
int count = BungeeCore.get().getProxy().getOnlineCount();
if (count == 1) {
jda.getPresence().setActivity(Activity.playing("mit 1 Spieler"));
} else {
jda.getPresence().setActivity(Activity.playing("mit " + count + " Spielern"));
}
index = 0;
return;
}
index++;
}
public void addListener(ListenerAdapter listenerAdapter) {
jda.addEventListener(listenerAdapter);
}
}

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

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.bungeecore.sql.SteamwarUser;
import de.steamwar.bungeecore.sql.UserGroup;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
public abstract class BasicDiscordCommand extends CommandData {
protected BasicDiscordCommand(String name, String description) {
super(name, description);
}
public abstract void run(SlashCommandEvent event);
protected SteamwarUser getSteamwarUser(SlashCommandEvent event) {
Member member = event.getMember();
SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
if (steamwarUser == null) {
return null;
}
return steamwarUser;
}
protected boolean testPermission(SlashCommandEvent event) {
Member member = event.getMember();
SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
if (steamwarUser == null || (!steamwarUser.getUserGroup().isTeamGroup() && steamwarUser.getUserGroup() != UserGroup.Builder)) {
event.reply("Du hast für " + event.getName() + " keine Rechte oder es existiert keine Verknüpfung für dich.").setEphemeral(true).queue();
return false;
}
return true;
}
}

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

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

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

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

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.bungeecore.sql.UserGroup;
import net.md_5.bungee.config.Configuration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SteamwarDiscordBotConfig {
public static boolean loaded = false;
public static String TOKEN;
public static String GUILD;
public static String ANNOUNCEMENTS_CHANNEL;
public static String EVENTS_CHANNEL;
public static String INGAME_CHANNEL;
public static String SERVER_TEAM_CHANNEL;
public static String SCHEMATICS_CHANNEL;
public static String ROLES_CHANNEL;
public static String ROLES_BASE_MESSAGE;
public static String ROLES_ADDED;
public static String ROLES_REMOVED;
public static List<DiscordRole> ROLES;
public static String RULES_CHANNEL;
public static String RULES_TITLE;
public static List<String> RULES_RULES;
public static List<DiscordRulesLink> RULES_LINKS;
public static String TICKET_CATEGORY;
public static String TICKET_CHANNEL;
public static String TICKET_MESSAGE;
public static String TICKET_CREATED;
public static String TICKET_LOG;
public static Map<String, DiscordTicketType> TICKET_TYPES;
public static Map<UserGroup, String> RANKS;
public static void loadConfig(Configuration config) {
TOKEN = config.getString("token");
GUILD = config.getString("guild");
ANNOUNCEMENTS_CHANNEL = config.getString("announcements-channel");
EVENTS_CHANNEL = config.getString("events-channel");
INGAME_CHANNEL = config.getString("ingame-channel");
SERVER_TEAM_CHANNEL = config.getString("server-team-channel");
SCHEMATICS_CHANNEL = config.getString("schematics-channel");
Configuration rolesSection = config.getSection("roles-claim");
ROLES_CHANNEL = rolesSection.getString("channel");
ROLES_BASE_MESSAGE = rolesSection.getString("base");
ROLES_ADDED = rolesSection.getString("added");
ROLES_REMOVED = rolesSection.getString("removed");
ROLES = new ArrayList<>();
for (String roles : rolesSection.getSection("roles").getKeys()) {
Configuration role = rolesSection.getSection("roles").getSection(roles);
ROLES.add(new DiscordRole(role.getString("emoji"),
role.getString("label"),
role.getString("roleId")));
}
Configuration rulesSection = config.getSection("rules");
RULES_CHANNEL = rulesSection.getString("channel");
RULES_TITLE = rulesSection.getString("title");
RULES_RULES = rulesSection.getStringList("rules");
RULES_LINKS = new ArrayList<>();
for (String links : rulesSection.getSection("links").getKeys()) {
Configuration link = rulesSection.getSection("links").getSection(links);
RULES_LINKS.add(new DiscordRulesLink(link.getString("label"),
link.getString("url")));
}
Configuration ticketSection = config.getSection("tickets");
TICKET_CATEGORY = ticketSection.getString("category");
TICKET_CHANNEL = ticketSection.getString("channel");
TICKET_MESSAGE = ticketSection.getString("message");
TICKET_CREATED = ticketSection.getString("created");
TICKET_LOG = ticketSection.getString("log");
TICKET_TYPES = new HashMap<>();
for (String types : ticketSection.getSection("types").getKeys()) {
Configuration type = ticketSection.getSection("types").getSection(types);
TICKET_TYPES.put(types, new DiscordTicketType(types,
type.getString("emoji"),
type.getString("label"),
type.getString("color"),
type.getString("pre")));
}
RANKS = new HashMap<>();
Configuration ranksSections = config.getSection("ranks");
for (String type : ranksSections.getKeys()) {
RANKS.put(UserGroup.getUsergroup(type), ranksSections.getString(type));
}
loaded = true;
}
}

Datei anzeigen

@ -17,16 +17,20 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * 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.sql.EventFight; import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
import de.steamwar.sql.Team; import de.steamwar.bungeecore.sql.Event;
import de.steamwar.sql.TeamTeilnahme; import de.steamwar.bungeecore.sql.EventFight;
import de.steamwar.bungeecore.sql.Team;
import de.steamwar.bungeecore.sql.TeamTeilnahme;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder; import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Emoji; 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.ActionRow;
import net.dv8tion.jda.api.interactions.components.selections.SelectionMenu; import net.dv8tion.jda.api.interactions.components.selections.SelectionMenu;
@ -38,28 +42,38 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@UtilityClass @UtilityClass
public class EventChannel { public class EventManager {
public MessageBuilder get() { private Message message;
if (Event.get() == null) private TextChannel textChannel;
return updateComing();
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() { public void update() {
EmbedBuilder embedBuilder = new EmbedBuilder() if (Event.get() == null) {
.setColor(Color.GRAY) updateComing();
.setTitle("Zukünftige Events") } else {
.setAuthor("SteamWar", "https://www.steamwar.de"); updateCurrent();
}
}
private void updateComing() {
SelectionMenu.Builder menuBuilder = SelectionMenu.create("eventName") EmbedBuilder embedBuilder = new EmbedBuilder();
.setPlaceholder("Wähle ein Event aus!") embedBuilder.setColor(Color.GRAY);
.setMinValues(1) embedBuilder.setTitle("Zukünftige Events");
.setMaxValues(1); embedBuilder.setAuthor("SteamWar", "https://www.steamwar.de");
Timestamp now = Timestamp.from(Instant.now()); 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(); List<Event> events = Event.getComing();
events.forEach(event -> { events.forEach(event -> {
StringBuilder st = new StringBuilder(); StringBuilder st = new StringBuilder();
@ -77,21 +91,25 @@ public class EventChannel {
} }
}); });
MessageBuilder messageBuilder = new MessageBuilder() MessageBuilder messageBuilder = new MessageBuilder();
.setEmbeds(embedBuilder.build()); messageBuilder.setEmbeds(embedBuilder.build());
if(events.stream().anyMatch(event -> event.getDeadline().after(Timestamp.from(Instant.now())))) { if(events.stream().anyMatch(event -> event.getDeadline().after(Timestamp.from(Instant.now())))) {
messageBuilder.setActionRows(ActionRow.of(menuBuilder.build())); 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(); Event event = Event.get();
EmbedBuilder embedBuilder = new EmbedBuilder() if (event == null) return;
.setColor(Color.GRAY) EmbedBuilder embedBuilder = new EmbedBuilder();
.setTitle("Event: " + event.getEventName()) embedBuilder.setColor(Color.GRAY);
.setAuthor("SteamWar", "https://www.steamwar.de"); embedBuilder.setTitle("Event: " + event.getEventName());
embedBuilder.setAuthor("SteamWar", "https://www.steamwar.de");
Instant now = Instant.now(); Instant now = Instant.now();
EventFight.getEvent(event.getEventID()).forEach(eventFight -> { EventFight.getEvent(event.getEventID()).forEach(eventFight -> {
@ -113,7 +131,13 @@ public class EventChannel {
embedBuilder.addField(teamBlue.getTeamKuerzel() + " vs. " + teamRed.getTeamKuerzel(), st.toString(), true); 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.bungeecore.sql.SteamwarUser;
import lombok.experimental.UtilityClass;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import java.awt.*;
@UtilityClass
public class SchematicsManager {
private Message message;
private TextChannel textChannel;
static {
textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.SCHEMATICS_CHANNEL);
assert textChannel != null;
if(textChannel.hasLatestMessage()) {
message = textChannel.getIterableHistory().complete().stream().filter(m -> m.getAuthor().isBot()).findFirst().orElse(null);
}
}
public void update() {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setColor(Color.GRAY);
embedBuilder.setTitle("Check List");
embedBuilder.setAuthor("SteamWar", "https://www.steamwar.de");
CheckCommand.getSchemsToCheck().forEach(schematic -> {
StringBuilder st = new StringBuilder();
st.append("Typ: ").append(schematic.getSchemtype().getKuerzel());
st.append("\nVon: ").append(SteamwarUser.get(schematic.getOwner()).getUserName());
String checker = CheckCommand.getChecker(schematic);
if (checker != null) {
st.append("\nWird Geprüft von: ").append(checker);
}
embedBuilder.addField(schematic.getName(), st.toString(), true);
});
MessageBuilder messageBuilder = new MessageBuilder();
messageBuilder.setEmbeds(embedBuilder.build());
if (message == null) {
textChannel.sendMessage(messageBuilder.build()).queue(message1 -> message = message1);
} else {
message.editMessage(messageBuilder.build()).queue();
}
}
}

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

@ -15,15 +15,16 @@
You should have received a copy of the GNU Affero General Public License 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/>. 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() { BasicDiscordListener() {
VelocityCore.getProxy().getEventManager().register(VelocityCore.get(), this); 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.bungeecore.sql.SteamwarUser;
import net.dv8tion.jda.api.entities.ChannelType;
import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent;
import net.dv8tion.jda.api.interactions.InteractionType;
import org.jetbrains.annotations.NotNull;
public class DiscordAuthListener extends BasicDiscordListener {
@Override
public void onGenericComponentInteractionCreate(@NotNull GenericComponentInteractionCreateEvent event) {
if(event.getType() == InteractionType.COMPONENT) {
if(event.getChannel().getId().equals(SteamwarDiscordBotConfig.RULES_CHANNEL) && event.getComponentId().equals("auth")) {
String authMessage = AuthManager.createDiscordAuthToken(event.getMember());
if(authMessage != null) {
event.reply("Gebe innerhalb der nächsten 10 Minuten ``/verify " + authMessage + "`` auf dem Minecraft Server ein").setEphemeral(true).queue();
} else {
event.reply("Du hast bereits einen Code am laufen").setEphemeral(true).queue();
}
}
if(event.getComponentId().equals("tada") && event.getChannelType() == ChannelType.PRIVATE) {
event.reply(":tada:").setEphemeral(false).queue();
}
if(event.getComponentId().equals("invalid") && event.getChannelType() == ChannelType.PRIVATE) {
SteamwarUser user = SteamwarUser.get(event.getUser().getIdLong());
if(user == null) {
event.reply(":question: Da ist keine verknüpfung?").setEphemeral(false).queue();
} else {
user.setDiscordId(null);
event.reply(":x: Die Verknüpfung wurde beendet").setEphemeral(false).queue();
}
}
}
}
}

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.bungeecore.sql.Punishment;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.messages.ChatSender;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import org.jetbrains.annotations.NotNull;
import java.util.function.Supplier;
import java.util.stream.Stream;
public class DiscordChatListener extends BasicDiscordListener {
private final String channel;
private final String format;
private final Supplier<Stream<ChatSender>> targets;
public DiscordChatListener(String channel, String format, Supplier<Stream<ChatSender>> targets) {
this.channel = channel;
this.format = format;
this.targets = targets;
}
@Override
public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
if (!event.getChannel().getId().equals(channel) || event.getAuthor().isBot())
return;
Member member = event.getMember();
SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong());
if (steamwarUser == null || event.getMessage().getContentRaw().length() > 250 || steamwarUser.isPunished(Punishment.PunishmentType.Ban)) {
event.getMessage().delete().queue();
} else {
ChatListener.sendChat(ChatSender.of(event.getMessage(), steamwarUser), targets.get(), format, null, event.getMessage().getContentDisplay().replace('§', '&').replace('\n', ' '));
}
}
public void send(String message) {
TextChannel textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(channel);
assert textChannel != null;
MessageBuilder messageBuilder = new MessageBuilder();
messageBuilder.append(message.replace("&", "").replace("@everyone", "`@everyone`").replace("@here", "`@here`").replaceAll("<[@#]!?\\d+>", "`$0`"));
textChannel.sendMessage(messageBuilder.build()).queue();
}
}

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

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.bungeecore.sql.SteamwarUser;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.events.interaction.GenericComponentInteractionCreateEvent;
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent;
import net.dv8tion.jda.api.interactions.InteractionType;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.Button;
import net.md_5.bungee.api.chat.ClickEvent;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.time.Instant;
import java.util.LinkedList;
public class DiscordTicketListener extends BasicDiscordListener {
@Override
public void onGenericComponentInteractionCreate(@NotNull GenericComponentInteractionCreateEvent event) {
if(event.getType() == InteractionType.COMPONENT && event.getChannelType() == ChannelType.TEXT && event.getTextChannel().getParent() != null && event.getTextChannel().getParent().getId().equals(SteamwarDiscordBotConfig.TICKET_CATEGORY)) {
if(event.getTextChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_CHANNEL) && SteamwarDiscordBotConfig.TICKET_TYPES.containsKey(event.getComponentId())) {
DiscordTicketType ticketType = SteamwarDiscordBotConfig.TICKET_TYPES.get(event.getComponentId());
Category ct = event.getGuild().getCategoryById(SteamwarDiscordBotConfig.TICKET_CATEGORY);
SteamwarUser swUser = SteamwarUser.get(event.getUser().getIdLong());
TextChannel ticketChannel = ct.createTextChannel((swUser == null?event.getUser().getName():swUser.getUserName()) + "-" + event.getComponentId() + "-" + System.currentTimeMillis() % 1000).complete();
ticketChannel.createPermissionOverride(event.getMember()).setAllow(Permission.VIEW_CHANNEL,
Permission.MESSAGE_WRITE,
Permission.MESSAGE_ATTACH_FILES,
Permission.MESSAGE_ADD_REACTION,
Permission.MESSAGE_READ,
Permission.MESSAGE_EMBED_LINKS,
Permission.MESSAGE_HISTORY).complete();
ticketChannel.getManager().setTopic(event.getUser().getId()).complete();
MessageBuilder messageBuilder = new MessageBuilder();
EmbedBuilder builder = new EmbedBuilder();
builder.setDescription(ticketType.getPreMessage());
builder.setTitle("Steamwar Ticket");
builder.setColor(Color.GREEN);
Button closeButton = Button.danger("close-" + ticketChannel.getName(), "Schließen").withEmoji(Emoji.fromUnicode("U+26A0"));
messageBuilder.setEmbeds(builder.build());
messageBuilder.setActionRows(ActionRow.of(closeButton));
ticketChannel.sendMessage(messageBuilder.build()).complete();
event.reply(SteamwarDiscordBotConfig.TICKET_CREATED.replace("%channel%", ticketChannel.getAsMention())).setEphemeral(true).complete();
Message.team("DISCORD_TICKET_NEW", ticketChannel.getName());
} else if(event.getComponentId().startsWith("close-")) {
TextChannel logChannel = event.getGuild().getTextChannelById(SteamwarDiscordBotConfig.TICKET_LOG);
LinkedList<StringBuilder> stringBuilders = new LinkedList<>();
stringBuilders.add(new StringBuilder());
new LinkedList<>(event.getTextChannel().getIterableHistory().complete()).descendingIterator().forEachRemaining(message -> {
if(message.getAuthor().isSystem() || message.getAuthor().isBot()) return;
StringBuilder currentBuilder = new StringBuilder();
currentBuilder.append("<t:").append(message.getTimeCreated().toInstant().getEpochSecond()).append("> ")
.append("**")
.append(message.getAuthor().getName())
.append("**: ")
.append(message.getContentRaw());
if(!message.getAttachments().isEmpty()) {
currentBuilder.append("\n")
.append("Files: ").append("\n");
message.getAttachments().forEach(attachment -> currentBuilder.append(attachment.getUrl()).append("\n"));
}
currentBuilder.append("\n");
if(currentBuilder.length() >= 4096) {
stringBuilders.getLast().append(currentBuilder.substring(0, 4090));
stringBuilders.add(new StringBuilder(currentBuilder.substring(4090, currentBuilder.length() - 1)));
} else if (currentBuilder.length() + stringBuilders.getLast().length() >= 4096) {
stringBuilders.add(new StringBuilder(currentBuilder.toString()));
} else {
stringBuilders.getLast().append(currentBuilder);
}
});
String footer = "<t:" + Instant.now().getEpochSecond() + "> **" + event.getUser().getName() + "**: Ticket geschlossen";
if(stringBuilders.getLast().length() + footer.length() > 4090) {
stringBuilders.add(new StringBuilder(footer));
} else {
stringBuilders.getLast().append(footer);
}
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setColor(Color.GREEN);
User user = event.getJDA().retrieveUserById(event.getTextChannel().getTopic()).complete();
SteamwarUser swuser = SteamwarUser.get(user.getIdLong());
embedBuilder.setAuthor(user.getName(), swuser==null?"https://steamwar.de/":("https://steamwar.de/users/" + swuser.getUserName().toLowerCase() + "/"), user.getAvatarUrl());
embedBuilder.setTimestamp(Instant.now());
embedBuilder.setTitle(event.getTextChannel().getName());
stringBuilders.forEach(stringBuilder -> {
embedBuilder.setDescription(stringBuilder.toString());
MessageBuilder builder = new MessageBuilder();
builder.setEmbeds(embedBuilder.build());
logChannel.sendMessage(builder.build()).queue();
});
Message.team("DISCORD_TICKET_CLOSED", event.getTextChannel().getName());
event.getTextChannel().delete().reason("Closed").queue();
}
}
}
@Override
public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) {
if(event.getChannel().getParent() != null && event.getChannel().getParent().getId().equals(SteamwarDiscordBotConfig.TICKET_CATEGORY)) {
if(!event.getChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_CHANNEL) && !event.getChannel().getId().equals(SteamwarDiscordBotConfig.TICKET_LOG)) {
BungeeCore.get().getProxy().getPlayers().forEach(player -> {
if(event.getAuthor().isBot() || event.getAuthor().isSystem()) return;
SteamwarUser user = SteamwarUser.get(player);
boolean sendMessage;
if(user.getDiscordId() == null) {
sendMessage = user.getUserGroup().isCheckSchematics();
} else {
if(event.getAuthor().getId().equals(user.getDiscordId())) return;
sendMessage = user.getDiscordId().equals(event.getChannel().getTopic()) || user.getUserGroup().isCheckSchematics();
}
if(sendMessage) {
Message.sendPrefixless("DISCORD_TICKET_MESSAGE", player, "Zur nachricht", new ClickEvent(ClickEvent.Action.OPEN_URL, event.getMessage().getJumpUrl()), event.getChannel().getName(), event.getAuthor().getName(), event.getMessage().getContentRaw());
}
});
}
}
}
}

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.bungeecore.sql.Punishment;
import de.steamwar.bungeecore.sql.SchematicNode;
import de.steamwar.bungeecore.sql.SteamwarUser;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.events.message.priv.PrivateMessageReceivedEvent;
import java.io.InputStream;
import java.util.concurrent.CompletableFuture;
public class PrivateMessageListener extends BasicDiscordListener {
@Override
public void onPrivateMessageReceived(PrivateMessageReceivedEvent event) {
if(!event.getMessage().getAttachments().isEmpty()) {
SteamwarUser user = SteamwarUser.get(event.getAuthor().getIdLong());
if (user == null) {
event.getMessage().reply("Du must dein Minecraft Account mit dem Bot verbinden, gehe dazu auf dem SteamWar Discord in den `regeln-infos` Channel und Klicke auf `Minecraft Verknüpfen`").complete();
return;
}
if(user.isPunished(Punishment.PunishmentType.NoSchemReceiving)) {
event.getMessage().reply("Du darfst keine Schematics hochladen").complete();
return;
}
for (Message.Attachment attachment : event.getMessage().getAttachments()) {
if(attachment.getFileExtension() == null ||
(!attachment.getFileExtension().equalsIgnoreCase("schem") &&
!attachment.getFileExtension().equalsIgnoreCase("schematic"))) {
event.getMessage().reply("`" + attachment.getFileName() + "` wird ignoriert, da die Datei keine Schematic ist").queue();
continue;
}
boolean newFormat = attachment.getFileExtension().equalsIgnoreCase("schem");
int dot = attachment.getFileName().lastIndexOf(".");
String name = attachment.getFileName().substring(0, dot);
if(SchematicNode.invalidSchemName(new String[] {name})) {
event.getMessage().reply("`" + name + "` hat nicht zugelassene Zeichen im Namen").queue();
continue;
}
SchematicNode node = SchematicNode.getSchematicNode(user.getId(), name, 0);
if(node == null) {
node = SchematicNode.createSchematic(user.getId(), name, null);
}
try {
InputStream in = attachment.retrieveInputStream().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

@ -1,7 +1,7 @@
/* /*
* This file is a part of the SteamWar software. * This file is a part of the SteamWar software.
* *
* Copyright (C) 2023 SteamWar.de-Serverteam * Copyright (C) 2020 SteamWar.de-Serverteam
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU Affero General Public License as published by
@ -17,21 +17,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.steamwar.sql; package de.steamwar.bungeecore.bot.listeners;
import de.steamwar.velocitycore.VelocityCore; import de.steamwar.bungeecore.bot.SteamwarDiscordBot;
import de.steamwar.sql.internal.SQLConfig; import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import org.jetbrains.annotations.NotNull;
import java.util.logging.Logger; public class SlashCommandListener extends BasicDiscordListener {
public class SQLConfigImpl implements SQLConfig {
@Override
public Logger getLogger() {
return VelocityCore.getLogger();
}
@Override @Override
public int maxConnections() { public void onSlashCommand(@NotNull SlashCommandEvent event) {
return 4; 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.bungeecore.sql.SteamwarUser;
import lombok.experimental.UtilityClass;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@UtilityClass
public class DiscordRanks {
public void update(SteamwarUser steamwarUser) {
if (steamwarUser.getDiscordId() == null) {
return;
}
Guild guild = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD);
guild.retrieveMemberById(steamwarUser.getDiscordId()).queue(member -> {
List<Role> roleList = member.getRoles();
Set<String> strings = new HashSet<>(SteamwarDiscordBotConfig.RANKS.values());
String needed = SteamwarDiscordBotConfig.RANKS.get(steamwarUser.getUserGroup());
for (Role role : roleList) {
if (!strings.contains(role.getId())) {
continue;
}
if (role.getId().equals(needed)) {
needed = "";
continue;
}
guild.removeRoleFromMember(member, role).complete();
}
if (needed != null && !needed.isEmpty()) {
guild.addRoleToMember(member, guild.getRoleById(needed)).complete();
}
}, throwable -> {
if(throwable instanceof ErrorResponseException) {
ErrorResponseException e = (ErrorResponseException) throwable;
if(e.getErrorCode() == 10007) {
steamwarUser.setDiscordId(null);
}
}
});
}
}

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.bungeecore.sql.SchematicNode;
import de.steamwar.bungeecore.sql.SteamwarUser;
import lombok.experimental.UtilityClass;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Emoji;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.interactions.components.ActionRow;
import net.dv8tion.jda.api.interactions.components.Button;
import java.awt.*;
import java.time.Instant;
@UtilityClass
public class DiscordSchemAlert {
public void sendDecline(SchematicNode schematic, SteamwarUser user, String reason) {
if(user.getDiscordId() != null) {
User dcUser = SteamwarDiscordBot.instance().getJda().retrieveUserById(user.getDiscordId()).complete();
EmbedBuilder builder = new EmbedBuilder();
builder.setAuthor("SteamWar", "https://steamwar.de", "https://cdn.discordapp.com/app-icons/869606970099904562/60c884000407c02671d91d8e7182b8a1.png");
builder.setColor(Color.RED);
builder.setTitle("SteamWar-Schematic Info");
builder.setDescription("Deine Schematic **" + schematic.getName() + "** wurde abgelehnt. **Grund:** \n" + reason);
builder.setTimestamp(Instant.now());
MessageBuilder messageBuilder = new MessageBuilder();
messageBuilder.setEmbeds(builder.build());
try {
dcUser.openPrivateChannel().complete().sendMessage(messageBuilder.build()).queue();
} catch (Exception e) {
// Ignored
}
}
}
public void sendAccept(SchematicNode schematic, SteamwarUser user) {
if(user.getDiscordId() != null) {
User dcUser = SteamwarDiscordBot.instance().getJda().retrieveUserById(user.getDiscordId()).complete();
EmbedBuilder builder = new EmbedBuilder();
builder.setAuthor("SteamWar", "https://steamwar.de", "https://cdn.discordapp.com/app-icons/869606970099904562/60c884000407c02671d91d8e7182b8a1.png");
builder.setColor(Color.GREEN);
builder.setTitle("SteamWar-Schematic Info");
builder.setDescription("Deine Schematic **" + schematic.getName() + "** wurde angenommen.");
builder.setTimestamp(Instant.now());
MessageBuilder messageBuilder = new MessageBuilder();
messageBuilder.setEmbeds(builder.build());
messageBuilder.setActionRows(ActionRow.of(Button.success("tada", Emoji.fromUnicode("U+1F389"))));
try {
dcUser.openPrivateChannel().complete().sendMessage(messageBuilder.build()).queue();
} catch (Exception e) {
// Ignored
}
}
}
}

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

Datei anzeigen

@ -17,20 +17,19 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. 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.bungeecore.Servertype;
import de.steamwar.persistent.Servertype; import de.steamwar.bungeecore.Subserver;
import de.steamwar.persistent.Subserver;
import de.steamwar.velocitycore.VelocityCore;
import de.steamwar.command.PreviousArguments;
import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeMapper; import de.steamwar.command.TypeMapper;
import de.steamwar.messages.Chatter; import net.md_5.bungee.api.CommandSender;
import de.steamwar.messages.PlayerChatter; import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
public class ArenaCommand extends SWCommand { public class ArenaCommand extends SWCommand {
@ -39,32 +38,32 @@ public class ArenaCommand extends SWCommand {
} }
@Register @Register
public void arenaJoin(PlayerChatter sender, Subserver server) { public void arenaJoin(ProxiedPlayer player, Subserver server) {
TpCommand.teleport(sender, server.getRegisteredServer()); TpCommand.teleport(player, server.getServer());
} }
@ClassMapper(value = Subserver.class, local = true) @ClassMapper(value = Subserver.class, local = true)
public TypeMapper<Subserver> serverInfoTypeMapper() { public TypeMapper<Subserver> serverInfoTypeMapper() {
return new TypeMapper<>() { return new TypeMapper<Subserver>() {
@Override @Override
public Subserver map(Chatter sender, PreviousArguments previousArguments, String s) { public Subserver map(CommandSender commandSender, String[] previousArguments, String s) {
return Subserver.getSubserver(VelocityCore.getProxy().getServer(s).map(RegisteredServer::getServerInfo).orElse(null)); return Subserver.getSubserver(ProxyServer.getInstance().getServerInfo(s));
} }
@Override @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) { if (value == null || value.getType() != Servertype.ARENA) {
sender.system("ARENA_NOT_FOUND"); messageSender.send("ARENA_NOT_FOUND");
return false; return false;
} }
return true; return true;
} }
@Override @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(); List<Subserver> subserverList = Subserver.getServerList();
synchronized (subserverList) { 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,69 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.BungeeCore;
import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.sql.SteamwarUser;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.TabExecutor;
import java.util.ArrayList;
import java.util.List;
abstract class BasicCommand extends Command implements TabExecutor {
public BasicCommand(String name, String permission, String... aliases) {
super(name, permission, aliases);
BungeeCore.commands.put("/" + name, permission);
ProxyServer.getInstance().getPluginManager().registerCommand(BungeeCore.get(), this);
}
Iterable<String> allPlayers(String begin) {
List<String> suggestions = new ArrayList<>();
for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()){
String playerName = player.getName();
if(playerName.startsWith(begin))
suggestions.add(playerName);
}
return suggestions;
}
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
return new ArrayList<>();
}
protected SteamwarUser existingUser(CommandSender sender, String arg){
SteamwarUser target = SteamwarUser.get(arg);
if(target == null)
Message.send("UNKNOWN_PLAYER", sender);
return target;
}
protected SteamwarUser unsafeUser(CommandSender sender, String arg){
SteamwarUser target = SteamwarUser.getOrCreateOfflinePlayer(arg);
if(target == null)
Message.send("UNKNOWN_PLAYER", sender);
return target;
}
}

Datei anzeigen

@ -0,0 +1,330 @@
/*
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.sql.*;
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 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 {
public BauCommand(){
super("bau", null, "b", "build", "gs");
}
@Register(help = true)
public void genericHelp(ProxiedPlayer p, String... args) {
HelpCommand.sendBauHelp(ChatSender.of(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) {
new BauweltMember(p.getUniqueId(), target.getUuid(), false, false);
Message.send("BAU_ADDMEMBER_ADDED", p);
ProxiedPlayer z = ProxyServer.getInstance().getPlayer(target.getUuid());
if(z != null)
Message.send("BAU_ADDMEMBER_ADDED_TARGET", z, p.getName());
}
@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))) {
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, map, 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/>. 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.bungeecore.sql.SWException;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.command.SWCommand; 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 class BugCommand extends SWCommand {
public BugCommand() { public BugCommand() {
super("bug"); super("bug", null);
} }
@Register @Register
public void bugMessage(Chatter sender, String... message) { public void bugMessage(ProxiedPlayer player, String... message) {
int id = SWException.logGetId( String server = player.getServer().getInfo().getName();
String.join(" ", message), SteamwarUser user = SteamwarUser.get(player.getUniqueId());
sender.withPlayerOrOffline(player -> player.getCurrentServer().map(connection -> connection.getServerInfo().getName()).orElse("offline"), () -> "offline") + " " + sender.user().getUserName() + " " + sender.user().getId() SWException.log(server, String.join(" ", message), player.getName() + " " + user.getId());
); ChatSender.of(player).system("BUG_MESSAGE");
sender.system("BUG_MESSAGE", id);
} }
} }

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

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

Datei anzeigen

@ -0,0 +1,326 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.*;
import de.steamwar.bungeecore.bot.util.DiscordSchemAlert;
import de.steamwar.bungeecore.listeners.ConnectionListener;
import de.steamwar.bungeecore.sql.CheckedSchematic;
import de.steamwar.bungeecore.sql.SchematicNode;
import de.steamwar.bungeecore.sql.SchematicType;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.config.Configuration;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
public class CheckCommand extends SWCommand {
private static Map<SchematicType, List<String>> checkQuestions = new HashMap<>();
private static Map<SchematicType, List<String>> ranks = new HashMap<>();
private static Map<UUID, CheckSession> currentCheckers = new HashMap<>();
private static Map<Integer, CheckSession> currentSchems = new HashMap<>();
public static void setCheckQuestions(SchematicType checkType, Configuration config) {
checkQuestions.put(checkType, config.getStringList("CheckQuestions"));
if(!config.getStringList("Ranks").isEmpty())
ranks.put(checkType, config.getStringList("Ranks"));
}
public static boolean isChecking(ProxiedPlayer player){
return currentCheckers.containsKey(player.getUniqueId());
}
public static SchematicNode getCheckingSchem(ProxiedPlayer player) {
return currentCheckers.get(player.getUniqueId()).schematic;
}
public CheckCommand() {
super("check", ConnectionListener.CHECK_PERMISSION);
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
List<SchematicNode> schematics = getSchemsToCheck();
if(schematics.size() != currentCheckers.size())
Message.team("CHECK_REMINDER", "CHECK_REMINDER_HOVER", new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check list"), schematics.size() - currentCheckers.size());
}, 10, 10, TimeUnit.MINUTES);
}
public static void sendReminder(ProxiedPlayer player) {
List<SchematicNode> schematics = getSchemsToCheck();
if(schematics.size() != currentCheckers.size())
Message.send("CHECK_REMINDER", player, Message.parse("CHECK_REMINDER_HOVER", player), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check list"), schematics.size() - currentCheckers.size());
}
@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(schematic.getSchemtype().fightType());
if(new ServerStarter().test(mode, mode.getRandomMap(), checker).check(schematic.getId()).start() == null) {
remove();
return;
}
currentCheckers.put(checker.getUniqueId(), this);
currentSchems.put(schematic.getId(), this);
for(CheckedSchematic previous : CheckedSchematic.previousChecks(schematic))
Message.sendPrefixless("CHECK_SCHEMATIC_PREVIOUS", checker, previous.getEndTime(), SteamwarUser.get(previous.getValidator()).getUserName(), previous.getDeclineReason());
next(0);
});
}
private void next(int rank) {
if(!checkList.hasNext()){
accept(rank);
return;
}
checker.sendMessage(TextComponent.fromLegacyText(checkList.next()));
TextComponent next = new TextComponent();
next.setColor(ChatColor.GREEN);
if(checkList.hasNext()){
next.setText(Message.parse("CHECK_NEXT", checker));
next.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check next"));
}else if(ranks.containsKey(schematic.getSchemtype())){
List<String> r = ranks.get(schematic.getSchemtype());
for(int i = 0; i < r.size(); i++){
Message.sendPrefixless("CHECK_RANK", checker,
Message.parse("CHECK_RANK_HOVER", checker),
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check accept " + (i+1)),
i+1, r.get(i));
Message.sendPrefixless("SPACER", checker);
}
}else{
next.setText(Message.parse("CHECK_ACCEPT", checker));
next.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/check accept"));
}
TextComponent decline = new TextComponent(" " + Message.parse("CHECK_DECLINE", checker));
decline.setColor(ChatColor.RED);
decline.setClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/check decline "));
next.addExtra(decline);
checker.sendMessage(next);
}
private void accept(int rank){
if(ranks.containsKey(schematic.getSchemtype())){
if(rank <= 0 || ranks.get(schematic.getSchemtype()).size() < rank){
Message.send("CHECK_INVALID_RANK", checker);
return;
}
schematic.setRank(rank);
}
schematic.setType(schematic.getSchemtype().fightType().toDB());
CheckedSchematic.create(schematic, SteamwarUser.get(checker.getUniqueId()).getId(), startTime, Timestamp.from(Instant.now()), "freigegeben");
SteamwarUser user = SteamwarUser.get(schematic.getOwner());
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(user.getUuid());
if(player != null) {
Message.send("CHECK_ACCEPTED", player, schematic.getSchemtype().name(), schematic.getName());
} else {
DiscordSchemAlert.sendAccept(schematic, user);
}
Message.team("CHECK_ACCEPTED_TEAM", schematic.getName(), user.getUserName());
stop();
}
private void decline(String reason){
CheckedSchematic.create(schematic, SteamwarUser.get(checker.getUniqueId()).getId(), startTime, Timestamp.from(Instant.now()), reason);
SteamwarUser user = SteamwarUser.get(schematic.getOwner());
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(user.getUuid());
if(player != null) {
Message.send("CHECK_DECLINED", player, schematic.getSchemtype().name(), schematic.getName(), reason);
} else {
DiscordSchemAlert.sendDecline(schematic, user, reason);
}
Message.team("CHECK_DECLINED_TEAM", schematic.getName(), user.getUserName(), reason);
schematic.setType(SchematicType.Normal.toDB());
stop();
}
private void abort(){
CheckedSchematic.create(schematic, SteamwarUser.get(checker.getUniqueId()).getId(), startTime, Timestamp.from(Instant.now()), "Prüfvorgang abgebrochen");
stop();
}
private void stop(){
currentCheckers.remove(checker.getUniqueId());
currentSchems.remove(schematic.getId());
ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
for (Subserver subserver : Subserver.getServerList()) {
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(checker.getUniqueId())) {
subserver.stop();
break;
}
}
});
}
private void remove() {
currentCheckers.remove(checker.getUniqueId());
currentSchems.remove(schematic.getId());
}
}
}

Datei anzeigen

@ -17,19 +17,16 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * 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.bungeecore.Message;
import com.velocitypowered.api.proxy.server.ServerInfo; import de.steamwar.bungeecore.sql.Punishment;
import de.steamwar.messages.Message; import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.velocitycore.VelocityCore; import de.steamwar.command.*;
import de.steamwar.command.SWCommand; import de.steamwar.messages.ChatSender;
import de.steamwar.command.SWCommandUtils; import net.md_5.bungee.api.ProxyServer;
import de.steamwar.command.TypeMapper; import net.md_5.bungee.api.config.ServerInfo;
import de.steamwar.command.TypeValidator; import net.md_5.bungee.api.connection.ProxiedPlayer;
import de.steamwar.messages.PlayerChatter;
import de.steamwar.sql.Punishment;
import de.steamwar.sql.SteamwarUser;
import java.io.File; import java.io.File;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -39,50 +36,53 @@ import java.util.Map;
public class DevCommand extends SWCommand { public class DevCommand extends SWCommand {
private final File devServerDir = new File("/configs/DevServer"); 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() { public DevCommand() {
super("dev"); super("dev");
} }
@Register @Register
public void simpleCommand(@Validator PlayerChatter sender) { public void simpleCommand(@Validator ProxiedPlayer player) {
updateDevServers(); updateDevServers();
ChatSender sender = ChatSender.of(player);
if (devServers.isEmpty()) { if (devServers.isEmpty()) {
sender.system("DEV_NO_SERVER"); sender.system("DEV_NO_SERVER");
return; return;
} else if (devServers.size() == 1) { } else if (devServers.size() == 1) {
devServers.values().stream().findAny().ifPresent(server -> sender.getPlayer().createConnectionRequest(server).fireAndForget()); player.connect(devServers.values().stream().findAny().get());
return; return;
} }
RegisteredServer server = devServers.get(sender.getPlayer().getUsername().toLowerCase()); ServerInfo info = devServers.get(player.getName().toLowerCase());
if (server == null) { if (info == null) {
sender.system("DEV_UNKNOWN_SERVER"); sender.system("DEV_UNKNOWN_SERVER");
return; return;
} }
sender.getPlayer().createConnectionRequest(server).fireAndForget(); player.connect(info);
} }
@Register @Register
public void selectedCommand(@Validator PlayerChatter sender, @Mapper("dev") String name) { public void selectedCommand(@Validator ProxiedPlayer player, @Mapper("dev") String name) {
updateDevServers(); updateDevServers();
RegisteredServer server = devServers.get(name.toLowerCase()); ChatSender sender = ChatSender.of(player);
if (server == null) { ServerInfo info = devServers.get(name.toLowerCase());
if (info == null) {
sender.system("DEV_NO_SERVER"); sender.system("DEV_NO_SERVER");
return; return;
} }
sender.getPlayer().createConnectionRequest(server).fireAndForget(); player.connect(info);
} }
@ClassValidator(value = PlayerChatter.class, local = true) @ClassValidator(value = ProxiedPlayer.class, local = true)
public TypeValidator<PlayerChatter> punishmentGuardChecker() { public TypeValidator<ProxiedPlayer> punishmentGuardChecker() {
return (sender, value, messageSender) -> { return (sender, value, messageSender) -> {
if (sender.user().isPunished(Punishment.PunishmentType.NoDevServer)) { SteamwarUser user = SteamwarUser.get(value);
Message message = PunishmentCommand.punishmentMessage(sender.user(), Punishment.PunishmentType.NoDevServer); if (user.isPunished(Punishment.PunishmentType.NoDevServer)) {
messageSender.send(message.format(), message.params()); Message message = user.punishmentMessage(Punishment.PunishmentType.NoDevServer);
messageSender.send(message.getFormat(), message.getParams());
return false; return false;
} }
return true; return true;
@ -110,7 +110,7 @@ public class DevCommand extends SWCommand {
devServers.entrySet().removeIf(entry -> { devServers.entrySet().removeIf(entry -> {
if (!devServerFiles.containsKey(entry.getKey())) { if (!devServerFiles.containsKey(entry.getKey())) {
VelocityCore.getProxy().unregisterServer(entry.getValue().getServerInfo()); ProxyServer.getInstance().getServers().remove(entry.getValue().getName());
return true; return true;
} }
return false; return false;
@ -121,7 +121,9 @@ public class DevCommand extends SWCommand {
return; return;
SteamwarUser user = SteamwarUser.get(key); 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,132 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.*;
import de.steamwar.bungeecore.sql.*;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Set;
public class EventCommand extends BasicCommand {
public EventCommand() {
super("event", "");
}
@Override
public void execute(CommandSender sender, String[] args) {
if(!(sender instanceof ProxiedPlayer))
return;
ProxiedPlayer player = (ProxiedPlayer) sender;
Event currentEvent = Event.get();
if(currentEvent == null) {
noCurrentEvent(player);
return;
}
if(args.length != 1){
eventOverview(player, currentEvent);
return;
}
Team team = Team.get(args[0]);
if(team == null){
Message.send("EVENT_NO_TEAM", player);
return;
}
Subserver eventArena = EventStarter.getEventServer().get(team.getTeamId());
if(eventArena == null || !Subserver.getServerList().contains(eventArena)){
Message.send("EVENT_NO_FIGHT_TEAM", player);
return;
}
SubserverSystem.sendPlayer(eventArena, player);
}
private void noCurrentEvent(ProxiedPlayer player){
Message.send("EVENT_NO_CURRENT", player);
List<Event> coming = Event.getComing();
Instant now = Instant.now();
if(!coming.isEmpty()){
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(Message.parse("EVENT_DATE_FORMAT", player));
Message.send("EVENT_COMING", player);
for(Event e : coming){
Message.send("EVENT_COMING_EVENT", player, e.getStart().toLocalDateTime().format(dateFormat), e.getEnd().toLocalDateTime().format(dateFormat), e.getEventName());
Set<Team> teams = TeamTeilnahme.getTeams(e.getEventID());
if(now.isBefore(e.getDeadline().toInstant())) {
Message.send("EVENT_COMING_DEADLINE", player, e.getDeadline());
}
String schemType = e.getSchemType();
if (schemType != null) {
SchematicType schematicType = SchematicType.fromDB(schemType);
if (schematicType != null && schematicType.deadline() != null && now.isBefore(schematicType.deadline().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());
}
}
}
}
private void eventOverview(ProxiedPlayer player, Event currentEvent){
Message.send("EVENT_USAGE", player);
List<EventFight> fights = EventFight.getEvent(currentEvent.getEventID());
Message.send("EVENT_CURRENT_EVENT", player, currentEvent.getEventName());
DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern(Message.parse("EVENT_TIME_FORMAT", player));
for(EventFight fight : fights){
Team blue = Team.get(fight.getTeamBlue());
Team red = Team.get(fight.getTeamRed());
StringBuilder fline = new StringBuilder(Message.parse("EVENT_CURRENT_FIGHT", player, fight.getStartTime().toLocalDateTime().format(timeFormat), blue.getTeamColor(), blue.getTeamKuerzel(),
red.getTeamColor(), red.getTeamKuerzel()));
if(fight.hasFinished()){
switch(fight.getErgebnis()){
case 1:
fline.append(Message.parse("EVENT_CURRENT_FIGHT_WIN", player, blue.getTeamColor(), blue.getTeamKuerzel()));
break;
case 2:
fline.append(Message.parse("EVENT_CURRENT_FIGHT_WIN", player, red.getTeamColor(), red.getTeamKuerzel()));
break;
default:
fline.append(Message.parse("EVENT_CURRENT_FIGHT_DRAW", player));
}
}
BungeeCore.send(player, fline.toString());
}
}
}

Datei anzeigen

@ -17,31 +17,36 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. 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.bungeecore.sql.Event;
import de.steamwar.bungeecore.sql.EventFight;
import de.steamwar.bungeecore.sql.Team;
import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter; import de.steamwar.command.TypeMapper;
import de.steamwar.sql.Event; import net.md_5.bungee.api.CommandSender;
import de.steamwar.sql.EventFight; import net.md_5.bungee.api.connection.ProxiedPlayer;
import de.steamwar.sql.Team;
import de.steamwar.sql.UserPerm;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class EventRescheduleCommand extends SWCommand { public class EventRescheduleCommand extends SWCommand {
public EventRescheduleCommand() { public EventRescheduleCommand() {
super("eventreschedule", UserPerm.MODERATION); super("eventreschedule", "bungeecore.softreload");
} }
@Register @Register
public void reschedule(Chatter sender, Team teamBlue, Team teamRed) { public void reschedule(ProxiedPlayer player, Team teamBlue, Team teamRed) {
Event event = Event.get(); Event event = Event.get();
if(event == null){ if(event == null){
sender.system("EVENTRESCHEDULE_UNKNOWN_TEAM"); Message.send("EVENTRESCHEDULE_UNKNOWN_TEAM", player);
return; return;
} }
@ -54,13 +59,31 @@ public class EventRescheduleCommand extends SWCommand {
continue; continue;
if(fight.getTeamBlue() == teamBlue.getTeamId() && fight.getTeamRed() == teamRed.getTeamId()){ if(fight.getTeamBlue() == teamBlue.getTeamId() && fight.getTeamRed() == teamRed.getTeamId()){
sender.system("EVENTRESCHEDULE_STARTING"); Message.send("EVENTRESCHEDULE_STARTING", player);
fight.reschedule(); fight.reschedule();
EventFight.loadAllComingFights(); EventFight.loadAllComingFights();
return; 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/>. 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.sql.EventFight;
import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter; import net.md_5.bungee.api.CommandSender;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.UserPerm;
public class EventreloadCommand extends SWCommand { public class EventreloadCommand extends SWCommand {
public EventreloadCommand() { public EventreloadCommand() {
super("eventreload", UserPerm.MODERATION); super("eventreload", "bungeecore.softreload");
} }
@Register @Register
public void execute(Chatter sender) { public void execute(CommandSender sender) {
EventFight.loadAllComingFights(); EventFight.loadAllComingFights();
} }
} }

Datei anzeigen

@ -0,0 +1,216 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.*;
import de.steamwar.bungeecore.inventory.SWInventory;
import de.steamwar.bungeecore.inventory.SWItem;
import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker;
import de.steamwar.bungeecore.sql.Punishment;
import de.steamwar.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.CommandSender;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.chat.hover.content.Text;
import net.md_5.bungee.api.connection.ProxiedPlayer;
/**
* 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()) && map.equals(arenaserver.getMap()) && arenaserver.isAllowMerge() && arenaserver.getServer().getPlayers().size() == 1) {
mergable = arenaserver;
break;
}
}
}
}
if(mergable == null) {
declineMerge.run(player, mode, map);
return;
}
SWInventory inventory = new SWInventory(player, 9, Message.parse("FIGHT_MERGE_TITLE", player));
inventory.addItem(0, new SWItem(Message.parse("FIGHT_MERGE_DECLINE", player), 1), click -> {
inventory.close();
declineMerge.run(player, mode, map);
});
Arenaserver finalMergable = mergable;
SWItem item = new SWItem(Message.parse("FIGHT_MERGE_INFO", player, mode.getDisplayName(), finalMergable.getMap()), 11);
item.addLore(Message.parse("FIGHT_MERGE_INFO_LORE_1", player, finalMergable.getServer().getPlayers().toArray(new ProxiedPlayer[1])[0].getName()));
inventory.addItem(4, item, click -> {});
inventory.addItem(8, new SWItem(Message.parse("FIGHT_MERGE_ACCEPT", player), 10), click -> {
if(Subserver.getServerList().contains(finalMergable)) {
finalMergable.sendPlayer(player);
} else {
Message.send("FIGHT_MERGE_OFFLINE", player);
declineMerge.run(player, mode, map);
}
});
inventory.open();
}
@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,13 @@
/* package de.steamwar.bungeecore.commands;
* 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.velocitycore.commands; import de.steamwar.bungeecore.BungeeCore;
import de.steamwar.bungeecore.Message;
import de.steamwar.velocitycore.VelocityCore; import de.steamwar.bungeecore.sql.Statement;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter; import net.md_5.bungee.BungeeCord;
import de.steamwar.messages.PlayerChatter; import net.md_5.bungee.api.CommandSender;
import de.steamwar.sql.SteamwarUser; import net.md_5.bungee.api.connection.ProxiedPlayer;
import de.steamwar.sql.UserPerm;
import de.steamwar.sql.internal.Statement;
import java.io.*; import java.io.*;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
@ -34,42 +16,48 @@ import java.util.zip.ZipOutputStream;
public class GDPRQuery extends SWCommand { public class GDPRQuery extends SWCommand {
public GDPRQuery() { public GDPRQuery() {
super("gdprquery", UserPerm.ADMINISTRATION); super("gdprquery", "bungeecore.softreload");
} }
@Register @Register
public void generate(PlayerChatter sender) { public void generate(ProxiedPlayer player) {
generate(sender, sender.user()); generate(player, player);
} }
@Register @Register
public void generate(Chatter sender, SteamwarUser user) { public void generate(ProxiedPlayer player, ProxiedPlayer forPlayer) {
VelocityCore.schedule(() -> { SteamwarUser user = SteamwarUser.get(forPlayer);
if(user == null) {
Message.send("UNKNOWN_PLAYER", player);
return;
}
BungeeCord.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> {
try { try {
createZip(sender, user); createZip(player, user);
} catch (IOException e) { } catch (IOException e) {
throw new SecurityException("Could not create zip", e); throw new SecurityException("Could not create zip", e);
} }
}).schedule(); });
} }
private void createZip(Chatter sender, SteamwarUser user) throws IOException { private void createZip(ProxiedPlayer player, SteamwarUser user) throws IOException {
sender.system("GDPR_STATUS_WEBSITE"); printUpdate(player, "GDPR_STATUS_WEBSITE");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(user.getUserName() + ".zip")); 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.md");
copy(getClass().getClassLoader().getResourceAsStream("GDPRQueryREADME.md"), out, "README.txt"); 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/userworlds/" + user.getUuid().toString(), "BuildWorld12");
copyBauwelt(user, out, "/home/minecraft/userworlds15/" + user.getId(), "BuildWorld15"); 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/userworlds", "BuildInventories12");
copyPlayerdata(user, out, "/home/minecraft/userworlds15", "BuildInventories15"); 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, bannedIPs, "BannedIPs.csv");
sqlCSV(user, out, bauweltMember, "BuildMember.csv"); sqlCSV(user, out, bauweltMember, "BuildMember.csv");
sqlCSV(user, out, bauweltMembers, "BuildMembers.csv"); sqlCSV(user, out, bauweltMembers, "BuildMembers.csv");
@ -91,11 +79,11 @@ public class GDPRQuery extends SWCommand {
schematics(user, out); schematics(user, out);
userConfig(user, out); userConfig(user, out);
sender.system("GDPR_STATUS_LOGS"); printUpdate(player, "GDPR_STATUS_LOGS");
copyLogs(user, out, new File("/logs"), "logs"); copyLogs(user, out, new File("/logs"), "logs");
out.close(); 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 = ?"); private static final Statement bannedIPs = new Statement("SELECT Timestamp, IP FROM BannedUserIPs WHERE UserID = ?");
@ -227,14 +215,14 @@ public class GDPRQuery extends SWCommand {
} }
} }
File playerdata = new File(world, "playerdata/" + user.getUUID().toString() + ".dat"); File playerdata = new File(world, "playerdata/" + user.getUuid().toString() + ".dat");
if(playerdata.exists()) if(playerdata.exists())
copy(playerdata, out, outDir + "/playerdata/" + user.getUUID().toString() + ".dat"); copy(playerdata, out, outDir + "/playerdata/" + user.getUuid().toString() + ".dat");
} }
private void copyPlayerdata(SteamwarUser user, ZipOutputStream out, String inDir, String outDir) throws IOException { private void copyPlayerdata(SteamwarUser user, ZipOutputStream out, String inDir, String outDir) throws IOException {
File worlds = new File(inDir); File worlds = new File(inDir);
String path = "playerdata/" + user.getUUID().toString() + ".dat"; String path = "playerdata/" + user.getUuid().toString() + ".dat";
int i = 0; int i = 0;
for(File world : worlds.listFiles()) { for(File world : worlds.listFiles()) {
@ -242,10 +230,15 @@ public class GDPRQuery extends SWCommand {
if(!playerdata.exists()) if(!playerdata.exists())
continue; continue;
copy(playerdata, out, outDir + "/" + (i++) + "/" + user.getUUID().toString() + ".dat"); copy(playerdata, out, outDir + "/" + (i++) + "/" + user.getUuid().toString() + ".dat");
} }
} }
private void printUpdate(ProxiedPlayer player, String message) {
if (player.isConnected())
Message.send(message, player);
}
private void copy(File file, ZipOutputStream out, String path) throws IOException { private void copy(File file, ZipOutputStream out, String path) throws IOException {
try(FileInputStream in = new FileInputStream(file)) { try(FileInputStream in = new FileInputStream(file)) {
copy(in, out, path); copy(in, out, path);

Datei anzeigen

@ -0,0 +1,125 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.Message;
import de.steamwar.messages.ChatSender;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.ClickEvent;
public class HelpCommand extends BasicCommand {
public HelpCommand() {
super("help", "", "?");
}
@Override
public void execute(CommandSender s, String[] args) {
ChatSender sender = ChatSender.of(s);
if (args.length < 1) {
printPage(sender, ClickEvent.Action.RUN_COMMAND,
"HELP_LOBBY", "/l",
"HELP_BAU", "/build",
"HELP_BAUSERVER", "/help build",
"HELP_FIGHT", "/fight",
"HELP_CHALLENGE", "/challenge",
"HELP_HISTORIC", "/historic",
"HELP_TEAM", "/team",
"HELP_JOIN", "/join",
"HELP_LOCAL", "/local");
}else if (args[0].equalsIgnoreCase("buildserver")) {
sendBauHelp(sender);
}else if (args[0].equalsIgnoreCase("build")) {
bauHelpGroup(sender, args);
}
}
private static void bauHelpGroup(ChatSender sender, String[] args) {
if (args.length < 2) {
sendBauHelpGroup(sender);
return;
}
switch (args[1].toLowerCase()) {
case "admin":
case "owner":
case "bauwelt":
sender.system("HELP_BAU_GROUP_ADMIN_TITLE");
sendBauHelp(sender);
return;
case "world":
printPage(sender, "HELP_BAU_GROUP_WORLD_TITLE", "HELP_TNT", "HELP_FIRE", "HELP_FREEZE", "HELP_TPSLIMIT", "HELP_PROTECT", "HELP_RESET");
return;
case "player":
printPage(sender, "HELP_BAU_GROUP_PLAYER_TITLE", "HELP_SPEED", "HELP_NV", "HELP_WV", "HELP_DEBUGSTICK", "HELP_TRACE", "HELP_LOADER");
return;
case "worldedit":
case "we":
case "world-edit":
case "edit":
printPage(sender, "HELP_BAU_GROUP_WE_TITLE", "HELP_WE_POS1", "HELP_WE_POS2", "HELP_WE_COPY", "HELP_WE_PASTE", "HELP_WE_FLOPY", "HELP_WE_FLOPYP", "HELP_WE_ROTATE_90", "HELP_WE_ROTATE_180", "HELP_WE_ROTATE_N90");
return;
case "other":
printPage(sender, "HELP_BAU_GROUP_OTHER_TITLE", "HELP_TESTBLOCK", "HELP_SKULL", "HELP_BAUINFO");
return;
default:
sendBauHelpGroup(sender);
}
}
private static void sendBauHelpGroup(ChatSender sender) {
printPage(sender, ClickEvent.Action.RUN_COMMAND,
"HELP_BAU_GROUP_ADMIN", "/help build admin",
"HELP_BAU_GROUP_WORLD", "/help build world",
"HELP_BAU_GROUP_PLAYER", "/help build player",
"HELP_BAU_GROUP_WE", "/help build we",
"HELP_BAU_GROUP_OTHER", "/help build other");
}
static void sendBauHelp(ChatSender sender) {
printPage(sender, ClickEvent.Action.SUGGEST_COMMAND,
"HELP_BAU_TP", "/build tp ",
"HELP_BAU_ADDMEMBER", "/build addmember ",
"HELP_BAU_DELMEMBER", "/build delmember ",
"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(ChatSender sender, ClickEvent.Action action, String... args) {
for(int i = 0; i < args.length; i += 2) {
String message = args[i];
String hoverMessage = message + "_HOVER";
String command = args[i+1];
sender.system(message, new Message(hoverMessage), new ClickEvent(action, command));
}
}
private static void printPage(ChatSender sender, String title, String... messages) {
sender.system(title);
for (String message : messages) {
sender.prefixless(message);
}
}
}

Datei anzeigen

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

@ -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.commands;
import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.sql.IgnoreSystem;
import de.steamwar.bungeecore.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.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.stream.Collectors;
public class IgnoreCommand extends SWCommand {
public IgnoreCommand() {
super("ignore", null);
}
@Register(description = "USAGE_IGNORE")
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)){
Message.send("IGNORE_YOURSELF", p);
return;
}
if(IgnoreSystem.isIgnored(user, target)){
Message.send("IGNORE_ALREADY", p);
return;
}
IgnoreSystem.ignore(user, target);
Message.send("IGNORE_MESSAGE", p, target.getUserName());
}
@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,97 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.*;
import de.steamwar.bungeecore.sql.BauweltMember;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.ProxyServer;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.config.ServerInfo;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.ArrayList;
public class JoinmeCommand extends BasicCommand {
public JoinmeCommand() {
super("joinme", "");
}
@Override
public void execute(CommandSender sender, String[] args) {
if(sender instanceof ProxiedPlayer) {
ProxiedPlayer player = (ProxiedPlayer) sender;
if (args.length == 0 && player.hasPermission("bungeecore.joinme")) {
Message.broadcast("JOINME_BROADCAST", "JOINME_BROADCAST_HOVER"
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join " + player.getName()), player.getName(), player.getServer().getInfo().getName());
} else if (args.length == 1) {
ProxiedPlayer target = ProxyServer.getInstance().getPlayer(args[0]);
if(target == null || !target.isConnected()){
Message.send("JOINME_PLAYER_OFFLINE", player);
return;
}else if(target.equals(player)){
Message.send("JOINME_PLAYER_SELF", player);
return;
}
ServerInfo server = target.getServer().getInfo();
String serverPerm = BungeeCore.serverPermissions.get(server.getName());
Subserver subserver = Subserver.getSubserver(target);
if(subserver != null) {
Servertype type = subserver.getType();
if (type == Servertype.ARENA) {
SubserverSystem.sendPlayer(subserver, player);
} else if (type == Servertype.BAUSERVER) {
Bauserver bauserver = (Bauserver) subserver;
if (bauserver.getOwner().equals(player.getUniqueId()) ||
BauweltMember.getBauMember(bauserver.getOwner(), player.getUniqueId()) != null) {
SubserverSystem.sendPlayer(subserver, player);
} else {
SubserverSystem.sendDeniedMessage(player, bauserver.getOwner());
Message.send("JOIN_PLAYER_BLOCK", player);
}
} else if(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);
}
} else {
Message.send("JOINME_USAGE", player);
}
}
}
@Override
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
if(args.length == 1){
return allPlayers(args[0]);
}
return new ArrayList<>();
}
}

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/>. 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.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 class LocalCommand extends SWCommand {
public LocalCommand() { public LocalCommand() {
super("local", "bc", "bauchat"); super("local", null, "bc", "bauchat");
} }
@Register @Register
public void genericCommand(PlayerChatter player, String... message) { public void genericCommand(ProxiedPlayer player, String... message) {
ChatListener.localChat(player, String.join(" ", message)); ChatListener.localChat(player, String.join(" ", message));
} }
} }

Datei anzeigen

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

Datei anzeigen

@ -17,10 +17,11 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. 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.command.SWCommand;
import de.steamwar.messages.PlayerChatter; import net.md_5.bungee.api.connection.ProxiedPlayer;
public class PingCommand extends SWCommand { public class PingCommand extends SWCommand {
@ -29,7 +30,7 @@ public class PingCommand extends SWCommand {
} }
@Register @Register
public void genericCommand(PlayerChatter sender) { public void genericCommand(ProxiedPlayer player) {
sender.system("PING_RESPONSE", sender.getPlayer().getPing()); Message.send("PING_RESPONSE", player, player.getPing());
} }
} }

Datei anzeigen

@ -17,13 +17,18 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. 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.bungeecore.sql.SteamwarUser;
import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter; import net.md_5.bungee.api.CommandSender;
import de.steamwar.sql.SteamwarUser; import net.md_5.bungee.api.connection.ProxiedPlayer;
import org.apache.commons.lang3.LocaleUtils;
import java.text.DecimalFormat;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.Locale;
public class PlaytimeCommand extends SWCommand { public class PlaytimeCommand extends SWCommand {
@ -32,12 +37,11 @@ public class PlaytimeCommand extends SWCommand {
} }
@Register @Register
public void genericCommand(Chatter sender) { public void genericCommand(ProxiedPlayer player) {
SteamwarUser user = sender.user(); NumberFormat format = NumberFormat.getNumberInstance((player).getLocale());
NumberFormat format = NumberFormat.getNumberInstance(user.getLocale());
format.setMaximumFractionDigits(2); format.setMaximumFractionDigits(2);
String formattedText = format.format((user.getOnlinetime() / 3600d)); String formattedText = format.format((SteamwarUser.get(player).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/>. 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.bungeecore.sql.PollAnswer;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator; import de.steamwar.command.TypeValidator;
import de.steamwar.messages.Chatter; import net.md_5.bungee.api.connection.ProxiedPlayer;
import de.steamwar.sql.PollAnswer;
public class PollCommand extends SWCommand { public class PollCommand extends SWCommand {
@ -32,33 +34,39 @@ public class PollCommand extends SWCommand {
} }
@Register @Register
public void genericCommand(@Validator Chatter sender) { public void genericCommand(ProxiedPlayer player) {
PollSystem.sendPoll(sender); PollSystem.sendPoll(player);
} }
@Register(noTabComplete = true) @Register(noTabComplete = true)
public void answerPoll(@Validator Chatter sender, String answerString) { public void answerPoll(@Validator ProxiedPlayer player, String answerString) {
int answer; int answer;
try { try {
answer = Integer.parseUnsignedInt(answerString); answer = Integer.parseUnsignedInt(answerString);
if(answer < 1 || answer > PollSystem.answers()) if(answer < 1 || answer > PollSystem.answers())
throw new NumberFormatException(); throw new NumberFormatException();
}catch(NumberFormatException e){ }catch(NumberFormatException e){
sender.system("POLL_NO_ANSWER"); Message.send("POLL_NO_ANSWER", player);
return; return;
} }
PollAnswer pollAnswer = PollAnswer.get(sender.user().getId()); PollAnswer pollAnswer = PollAnswer.get(SteamwarUser.get(player.getUniqueId()).getId());
if(pollAnswer.hasAnswered()) if(pollAnswer.hasAnswered())
sender.system("POLL_ANSWER_REFRESH"); Message.send("POLL_ANSWER_REFRESH", player);
else else
sender.system("POLL_ANSWER_NEW"); Message.send("POLL_ANSWER_NEW", player);
pollAnswer.setAnswer(answer); pollAnswer.setAnswer(answer);
} }
@ClassValidator(value = Chatter.class, local = true) @ClassValidator(value = ProxiedPlayer.class, local = true)
public TypeValidator<Chatter> noPoll() { public TypeValidator<ProxiedPlayer> noPoll() {
return PollSystem.noPoll(); return (sender, value, messageSender) -> {
if(PollSystem.noCurrentPoll()){
messageSender.send("POLL_NO_POLL");
return false;
}
return true;
};
} }
} }

Datei anzeigen

@ -0,0 +1,56 @@
/*
This file is a part of the SteamWar software.
Copyright (C) 2020 SteamWar.de-Serverteam
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.listeners.PollSystem;
import de.steamwar.bungeecore.sql.PollAnswer;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.Map;
public class PollresultCommand extends SWCommand {
public PollresultCommand() {
super("pollresult", "bungeecore.pollresults");
}
@Register
public void genericCommand(@Validator ProxiedPlayer player) {
Map<String, Integer> voted = PollAnswer.getCurrentResults();
Message.send("POLLRESULT_HEADER", player, voted.values().stream().reduce(Integer::sum).orElse(0), PollSystem.getQuestion());
for (Map.Entry<String, Integer> e: voted.entrySet()) {
Message.send("POLLRESULT_LIST", player, e.getKey(), e.getValue());
}
}
@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

@ -0,0 +1,159 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2020 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.bungeecore.commands;
import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.sql.Punishment;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.command.SWCommand;
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.regex.MatchResult;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PunishmentCommand {
public PunishmentCommand(String command, Punishment.PunishmentType punishmentType) {
new SWCommand(command, "bungeecore.ban") {
@Register(description = "PUNISHMENT_USAGE")
public void genericCommand(ProxiedPlayer player, String toPunish, String date, String... message) {
if (punishmentType.isNeedsAdmin() && !SteamwarUser.get(player).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);
target.punish(punishmentType, banTime, msg, SteamwarUser.get(player.getName()).getId(), isPerma);
Message.team(punishmentType.getTeamMessage(), new Message("PREFIX"), target.getUserName(), player.getName(), new Message((isPerma ? "PUNISHMENT_PERMA" : "PUNISHMENT_UNTIL"), banTime), msg);
}
};
if (punishmentType.getUnpunishmentMessage() == null) {
return;
}
String antiCommand = "un" + command;
new SWCommand(antiCommand, "bungeecore.ban") {
@Register(description = "PUNISHMENT_USAGE")
public void genericCommand(ProxiedPlayer player, String toUnpunish) {
if (punishmentType.isNeedsAdmin() && !SteamwarUser.get(player).getUserGroup().isAdminGroup()) {
return;
}
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);
}
};
}
protected SteamwarUser existingUser(CommandSender sender, String arg){
SteamwarUser target = SteamwarUser.get(arg);
if(target == null)
Message.send("UNKNOWN_PLAYER", sender);
return target;
}
protected SteamwarUser unsafeUser(CommandSender sender, String arg){
SteamwarUser target = SteamwarUser.getOrCreateOfflinePlayer(arg);
if(target == null)
Message.send("UNKNOWN_PLAYER", sender);
return target;
}
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 {
if (RELATIVE_PATTERN.matcher(arg).matches()) {
Instant instant = Instant.now();
StringBuilder st = new StringBuilder();
for (int i = 0; i < arg.length(); i++) {
char c = arg.charAt(i);
if (Character.isDigit(c)) {
st.append(c);
continue;
}
int amount = Integer.parseInt(st.toString());
st = new StringBuilder();
switch (c) {
case 'h':
instant = instant.plus(amount, ChronoUnit.HOURS);
break;
case 'd':
instant = instant.plus(amount, ChronoUnit.DAYS);
break;
case 'w':
instant = instant.plus(Duration.ofSeconds(amount * ChronoUnit.WEEKS.getDuration().getSeconds()));
break;
case 'm':
instant = instant.plus(Duration.ofSeconds(amount * ChronoUnit.MONTHS.getDuration().getSeconds()));
break;
case 'y':
instant = instant.plus(Duration.ofSeconds(amount * ChronoUnit.YEARS.getDuration().getSeconds()));
break;
}
}
return Timestamp.from(instant);
}
SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy_HH:mm");
try {
Date parsedDate = dateFormat.parse(arg);
return new java.sql.Timestamp(parsedDate.getTime());
} catch (ParseException e) {
dateFormat = new SimpleDateFormat("dd.MM.yyyy");
try {
Date parsedDate = dateFormat.parse(arg.split("_")[0]);
return new java.sql.Timestamp(parsedDate.getTime());
} catch (ParseException exception) {
if (sender != null) {
Message.send("INVALID_TIME", sender);
}
return null;
}
}
}
}
}

Datei anzeigen

@ -17,21 +17,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. 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.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 class RCommand extends SWCommand {
public RCommand() { public RCommand() {
super("r", "reply"); super("r", "", "reply");
} }
@Register(description = "R_USAGE") @Register(description = "R_USAGE")
public void genericCommand(PlayerChatter sender, @ErrorMessage(value = "R_USAGE", allowEAs = false) String... message) { public void genericCommand(ProxiedPlayer player, @ErrorMessage(value = "R_USAGE", allowEAs = false) String... message) {
MsgCommand.msg(sender, lastChats.get(sender.getPlayer()), message); MsgCommand.msg(player, lastChats.get(player), message);
} }
} }

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.commands;
import de.steamwar.bungeecore.ArenaMode;
import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.bungeecore.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.CommandSender;
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, UserElo.getEmblemProgression(player, mode.getChatName(), user.getId()));
}
}
@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,40 @@
/*
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)));
}
}

Datei anzeigen

@ -0,0 +1,94 @@
/*
* 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.SWItem;
import de.steamwar.bungeecore.inventory.SWListInv;
import de.steamwar.bungeecore.inventory.SWStreamInv;
import de.steamwar.bungeecore.sql.Fight;
import de.steamwar.bungeecore.sql.Punishment;
import de.steamwar.bungeecore.sql.SchematicType;
import de.steamwar.bungeecore.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;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class ReplayCommand extends SWCommand {
public ReplayCommand() {
super("replay");
}
@Register
public void genericCommand(ProxiedPlayer player, @OptionalValue("") String optionalMap) {
ChatSender sender = ChatSender.of(player);
if (sender.user().isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer))
return;
new SWStreamInv<>(player, Message.parse("REPLAY_TITLE", player), (click, fight) -> {
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
ArenaMode mode = fight.getGameMode();
ServerStarter starter = new ServerStarter().replay(fight.getFightID()).blueLeader(player);
String map = mode.getRandomMap();
if (!optionalMap.equals("")) {
String tMap = mode.hasMap(optionalMap);
if (tMap != null) map = tMap;
}
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(sender, fight), fight)).collect(Collectors.toList())).open();
}
private SWItem getFightItem(ChatSender sender, Fight fight) {
SchematicType type = fight.getSchemType();
SWItem item = new SWItem(type != null ? type.getMaterial() : "BARRIER", parseLeader(sender, fight.getBlueLeader(), fight.getBluePlayers().size(), fight.getWin() == 1));
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(sender.parseToLegacy("REPLAY_UNAVAILABLE"));
item.setLore(lore);
if(fight.replayAllowed())
item.setEnchanted(true);
return item;
}
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/>. 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.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 { public class ServerSwitchCommand extends SWCommand {
private final RegisteredServer server; private String serverName;
public ServerSwitchCommand(String cmd, String name, String... aliases) { public ServerSwitchCommand(String cmd, String name, String permission, String... aliases) {
super(cmd, null, aliases); super(cmd, permission, aliases);
server = VelocityCore.getProxy().getServer(name).orElseThrow(); serverName = name;
} }
@Register @Register
public void genericCommand(PlayerChatter sender) { public void genericCommand(ProxiedPlayer player) {
sender.getPlayer().createConnectionRequest(server).fireAndForget(); 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/>. 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.command.SWCommand;
import de.steamwar.messages.Chatter; import de.steamwar.messages.ChatSender;
import de.steamwar.sql.UserPerm; import net.md_5.bungee.api.CommandSender;
public class ServerTeamchatCommand extends SWCommand { public class ServerTeamchatCommand extends SWCommand {
public ServerTeamchatCommand() { public ServerTeamchatCommand() {
super("stc", UserPerm.TEAM, "serverteamchat"); super("stc", "bungeecore.teamchat","serverteamchat");
} }
@Register(description = "STC_USAGE") @Register(description = "STC_USAGE")
public void genericCommand(Chatter sender, @ErrorMessage(value = "STC_USAGE", allowEAs = false) String... message) { public void genericCommand(CommandSender commandSender, @ErrorMessage(value = "STC_USAGE", allowEAs = false) String... message) {
ChatListener.sendChat(sender, Chatter.serverteam(), "CHAT_SERVERTEAM", null, String.join(" ", message)); ChatListener.sendChat(ChatSender.of(commandSender), ChatSender.serverteamReceivers(), "CHAT_SERVERTEAM", null, String.join(" ", message));
} }
} }

Datei anzeigen

@ -17,25 +17,24 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * 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.command.SWCommand; 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; import java.util.Objects;
public class SetLocaleCommand extends SWCommand { public class SetLocaleCommand extends SWCommand {
public SetLocaleCommand() { public SetLocaleCommand() {
super("setlocale", "setlanguage"); super("setlocale", null, "setlanguage");
} }
@Register @Register
public void genericCommand(Chatter sender) { public void genericCommand(ProxiedPlayer player) {
sender.user().setLocale(Objects.requireNonNull(sender.getLocale()), true); ChatSender sender = ChatSender.of(player);
sender.withPlayer(player -> NetworkSender.send(player, new LocaleInvalidationPacket(sender.user().getId()))); sender.user().setLocale(Objects.requireNonNull(player.getLocale()), true);
sender.system("LOCK_LOCALE_CHANGED"); sender.system("LOCK_LOCALE_CHANGED");
} }
} }

Datei anzeigen

@ -17,12 +17,12 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. 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.command.SWCommand; import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter; import net.md_5.bungee.api.CommandSender;
import de.steamwar.sql.UserPerm;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -32,11 +32,11 @@ import java.util.Map;
public class StatCommand extends SWCommand { public class StatCommand extends SWCommand {
public StatCommand() { public StatCommand() {
super("stat", UserPerm.ADMINISTRATION, "stats"); super("stat", "bungeecore.softreload", "stats");
} }
@Register @Register
public void genericCommand(Chatter sender) { public void genericCommand(CommandSender sender) {
Map<String, Integer> serverCount = new HashMap<>(); Map<String, Integer> serverCount = new HashMap<>();
try { try {
Process process = new ProcessBuilder("ps", "x").start(); Process process = new ProcessBuilder("ps", "x").start();
@ -52,6 +52,6 @@ public class StatCommand extends SWCommand {
throw new SecurityException(e.getMessage(), e); 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,796 @@
/*
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.bungeecore.sql.*;
import de.steamwar.messages.ChatSender;
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 BasicCommand {
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", "");
}
private void help(CommandSender sender){
Message.send("TEAM_HELP_HEADER", sender);
Message.send("TEAM_HELP_LIST", sender);
Message.send("TEAM_HELP_INFO", sender);
Message.send("TEAM_HELP_TP", sender);
if(!(sender instanceof ProxiedPlayer))
return;
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);
}
}
}
@Override
public void execute(CommandSender sender, String[] args){
if(args.length < 1){
help(sender);
return;
}
if(!(sender instanceof ProxiedPlayer))
return;
ProxiedPlayer player = (ProxiedPlayer) sender;
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
Team team = Team.get(user.getTeam());
switch(args[0].toLowerCase()){
case "create":
create(player, user, team, args);
break;
case "join":
join(player, user, args);
break;
case "stepback":
stepBack(player,user,team);
break;
case "leave":
leave(player, user, team);
break;
case "invite":
invite(player, user, team, args);
break;
case "remove":
remove(player, user, team, args);
break;
case "changekuerzel":
changekuerzel(player, user, team, args);
break;
case "changename":
changename(player, user, team, args);
break;
case "promote":
promote(player, user, team, args);
break;
case "changecolor":
changeColor(player, user, team);
break;
case "info":
info(player, user, team, args);
break;
case "list":
list(player, args);
break;
case "event":
event(player, user, team, args);
break;
case "tp":
tp(player, user, team, args);
break;
case "server":
server(player, user, team, args);
break;
default:
help(player);
}
}
private void create(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){
if(unwantedInTeam(player, user))
return;
if(args.length < 3){
Message.send("TEAM_CREATE_USAGE", player);
return;
}
if(checkTeamKuerzel(player, team, args[1]))
return;
if(checkTeamName(player, team, args[2]))
return;
Team.create(args[1], args[2]);
user.setTeam(Team.get(args[1]).getTeamId());
user.setLeader(true);
Message.send("TEAM_CREATE_CREATED", player, args[2]);
}
private void join(ProxiedPlayer player, SteamwarUser user, String[] args){
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 != 2){
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[1])){
t = inv;
break;
}
}
if(t == null){
Message.send("TEAM_JOIN_NOT_BY_TEAM", player);
return;
}
}
user.setTeam(t);
teamInvitations.remove(user.getId());
Team team = Team.get(t);
Message.send("TEAM_JOIN_JOINED", player, team.getTeamName());
if (Punishment.getPunishmentOfPlayer(user.getId(), Punishment.PunishmentType.NoEvent) != null) {
Event.getComing().forEach(event -> {
if (TeamTeilnahme.nimmtTeil(team.getTeamId(), event.getEventID())) {
TeamTeilnahme.notTeilnehmen(team.getTeamId(), event.getEventID());
}
});
}
}
private void stepBack(ProxiedPlayer player, SteamwarUser user, Team team) {
if(notLeader(player, user, team))
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);
}
private void leave(ProxiedPlayer player, SteamwarUser user, Team team){
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);
}
private void invite(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){
if(notLeader(player, user, team))
return;
if(notDuringEvent(player))
return;
if(args.length != 2){
Message.send("TEAM_INVITE_USAGE", player);
return;
}
SteamwarUser target = SteamwarUser.get(args[1]);
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 (Punishment.getPunishmentOfPlayer(target.getId(), Punishment.PunishmentType.NoEvent) != null) {
// TODO: Add warning message
}
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, args[1]);
ProxiedPlayer p = ProxyServer.getInstance().getPlayer(target.getUuid());
if(p != null)
Message.send("TEAM_INVITE_INVITED_TARGET", p, team.getTeamColor(), team.getTeamName());
}
private void remove(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){
if(notLeader(player, user, team))
return;
if(args.length != 2){
Message.send("TEAM_REMOVE_USAGE", player);
return;
}
SteamwarUser target = SteamwarUser.get(args[1]);
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);
}
private void changekuerzel(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){
if(notLeader(player, user, team))
return;
if(notDuringEvent(player))
return;
if(args.length < 2){
Message.send("TEAM_KUERZEL_USAGE", player);
return;
}
if(checkTeamKuerzel(player, team, args[1]))
return;
team.setTeamKuerzel(args[1]);
Message.send("TEAM_KUERZEL_CHANGED", player);
}
private void changename(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){
if(notLeader(player, user, team))
return;
if(notDuringEvent(player))
return;
if(args.length < 2){
Message.send("TEAM_NAME_USAGE", player);
return;
}
if(checkTeamName(player, team, args[1]))
return;
team.setTeamName(args[1]);
Message.send("TEAM_NAME_CHANGED", player);
}
private void promote(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){
if(notLeader(player, user, team))
return;
if(notDuringEvent(player))
return;
if(args.length < 2){
Message.send("TEAM_LEADER_USAGE", player);
return;
}
SteamwarUser target = SteamwarUser.get(args[1]);
if(target == null){
Message.send("TEAM_LEADER_NOT_USER", player, args[1]);
return;
}
if(target.getTeam() != user.getTeam()){
Message.send("TEAM_LEADER_NOT_MEMBER", player);
return;
}
target.setLeader(true);
Message.send("TEAM_LEADER_PROMOTED", player, args[1]);
}
private String playerName(SteamwarUser user){
return ProxyServer.getInstance().getPlayer(user.getUuid()) != null ? "§a" + user.getUserName() : "§e" + user.getUserName();
}
private void info(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){
if(args.length == 1 && user.getTeam() == 0){
Message.send("TEAM_INFO_USAGE", player);
return;
}else if(user.getTeam() == 0 || args.length == 2){
team = Team.get(args[1]);
}
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();
}
private void list(ProxiedPlayer player, String[] args){
final int TEAMS_PER_PAGE = 10;
int page;
if(args.length > 1){
try{
page = Integer.parseInt(args[1]);
}catch(NumberFormatException e){
Message.send("TEAM_LIST_NOT_PAGE", player);
return;
}
}else
page = 1;
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);
}
private void event(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){
if(notInTeam(player, user))
return;
if(args.length < 2){
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());
}
return;
}
if(notLeader(player, user, team))
return;
if(notDuringEvent(player))
return;
Event event = Event.get(args[1]);
if(event == null){
Message.send("TEAM_EVENT_NO_EVENT", player);
return;
}
if(Instant.now().isAfter(event.getDeadline().toInstant())){
Message.send("TEAM_EVENT_OVER", player);
return;
}
boolean hasPunishedPlayer = team.getMembers().stream()
.map(id -> Punishment.getPunishmentOfPlayer(id, Punishment.PunishmentType.NoEvent))
.anyMatch(Objects::nonNull);
if (hasPunishedPlayer) {
// TODO: Add message
}
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);
}
}
private void tp(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){
if(args.length == 1){
if(notInTeam(player, user))
return;
tp(player, team);
return;
}
Team targetTeam = Team.get(args[1]);
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);
*/
}
private void server(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){
if(notLeader(player, user, team))
return;
if (user.isPunishedWithMessage(ChatSender.of(player), Punishment.PunishmentType.NoTeamServer)) {
return;
}
if (args.length < 2) {
Message.send("TEAM_SERVER_USAGE", player);
return;
}
String server = args[1];
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;
}
int port = 25565;
if (args.length == 3) {
try {
port = Integer.parseInt(args[2]);
if (port < 1 || port > 65535) {
Message.send("TEAM_SERVER_PORT_INVALID", player);
return;
}
} catch (NumberFormatException e) {
Message.send("TEAM_SERVER_PORT_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;
}
}
private void changeColor(ProxiedPlayer player, SteamwarUser user, Team team) {
if(notLeader(player, user, team))
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();
}
private boolean checkTeamName(ProxiedPlayer player, Team team, String arg){
if(arg.length() < 4 || arg.length() > 15){
Message.send("TEAM_NAME_LENGHT", player);
return true;
}
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){
if(arg.length() < 2 || arg.length() > 4){
Message.send("TEAM_KUERZEL_LENGHT", player);
return true;
}
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, Team team){
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;
}
@Override
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args){
List<String> tab = new ArrayList<>();
if(args.length == 1){
tab.add("create");
tab.add("join");
tab.add("invite");
tab.add("stepback");
tab.add("leave");
tab.add("info");
tab.add("remove");
tab.add("event");
tab.add("changekuerzel");
tab.add("changename");
tab.add("promote");
tab.add("changecolor");
tab.add("tp");
tab.add("server");
}else if(args.length == 2){
if(args[1].equalsIgnoreCase("event")){
List<Event> coming = Event.getComing();
coming.forEach(event -> tab.add(event.getEventName()));
}else if(args[1].equalsIgnoreCase("join") || args[1].equalsIgnoreCase("info") || args[1].equalsIgnoreCase("tp")){
List<Team> teams = Team.getAll();
teams.forEach(team -> {
tab.add(team.getTeamName());
tab.add(team.getTeamKuerzel());
});
}
}
return tab;
}
}

Datei anzeigen

@ -17,29 +17,33 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. 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.bungeecore.sql.SteamwarUser;
import de.steamwar.messages.Chatter; import de.steamwar.messages.ChatSender;
import de.steamwar.messages.ChatterGroup; import net.md_5.bungee.api.CommandSender;
import de.steamwar.sql.SteamwarUser;
public class TeamchatCommand extends SWCommand { public class TeamchatCommand extends BasicCommand {
public TeamchatCommand() { public TeamchatCommand() {
super("tc", "teamchat"); super("tc", "","teamchat");
} }
@Register(description = "TC_USAGE") @Override
public void genericCommand(Chatter sender, @ErrorMessage(value = "TC_USAGE", allowEAs = false) String... args) { public void execute(CommandSender s, String[] args) {
SteamwarUser user = sender.user(); ChatSender sender = ChatSender.of(s);
if(args.length == 0){
sender.system("TC_USAGE");
return;
}
SteamwarUser user = sender.user();
if(user.getTeam() == 0){ if(user.getTeam() == 0){
sender.system("TC_NO_TEAM"); sender.system("TC_NO_TEAM");
return; 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(player -> player.user().getTeam() == user.getTeam()), "CHAT_TEAM", null, String.join(" ", args));
} }
} }

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.bungeecore.sql.*;
import de.steamwar.bungeecore.util.Chat19;
import de.steamwar.messages.ChatSender;
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;
public class TpCommand extends BasicCommand {
public TpCommand(){
super("join", null, "tp", "teleport");
}
@Override
public void execute(CommandSender s, String[] args) {
if(!(s instanceof ProxiedPlayer))
return;
ProxiedPlayer player = (ProxiedPlayer) s;
ChatSender sender = ChatSender.of(player);
if(args.length == 0){
if(Event.get() == null)
sender.system("TP_USAGE");
else
sender.system("TP_USAGE_EVENT");
return;
}
ServerInfo server = getTarget(args[0]);
boolean onTeamServer = Storage.teamServers.containsValue(player.getServer().getInfo());
//Give control of teleport command to server
if (server == player.getServer().getInfo() || onTeamServer || server == null) {
Chat19.chat(player, "/tp " + String.join(" ", args));
return;
}
teleport(player, server);
}
@Override
public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
if(args.length > 0)
return allPlayers(args[args.length - 1]);
return new ArrayList<>();
}
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 (!sender.user().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);
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,165 @@
/*
* 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.sql.SteamwarUser;
import de.steamwar.bungeecore.sql.Tutorial;
import de.steamwar.bungeecore.util.Chat19;
import de.steamwar.command.SWCommand;
import de.steamwar.command.TypeValidator;
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.logging.Level;
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) {
BungeeCore.get().getLogger().log(Level.SEVERE, "rate executed with nonexistent id: " + id);
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 != tutorial.creator()) {
tutorial.release();
openInventory(player, released, own);
return;
} else if(own && click.isShiftClick() && click.isRightClick()) {
tutorial.delete();
openInventory(player, released, own);
return;
}
new ServerStarter().tutorial(player, tutorial).start();
},
page -> (own ? Tutorial.getOwn(user, 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.item(), Message.parse("TUTORIAL_NAME", player, tutorial.name()));
item.setHideAttributes(true);
List<String> lore = new ArrayList<>();
lore.add(Message.parse("TUTORIAL_BY", player, tutorial.creator().getUserName()));
lore.add(Message.parse("TUTORIAL_STARS", player, String.format("%.1f", tutorial.stars())));
if (personalHighlights)
lore.add(Message.parse("TUTORIAL_DELETE", player));
item.setLore(lore);
if (personalHighlights && tutorial.released())
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, 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, name, item);
File tutorialWorld = tutorial.world();
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);
}
}

Datei anzeigen

@ -0,0 +1,97 @@
/*
* 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.listeners.mods.ModLoaderBlocker;
import de.steamwar.bungeecore.sql.Punishment;
import de.steamwar.command.SWCommandUtils;
import de.steamwar.command.TypeMapper;
import de.steamwar.command.TypeValidator;
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;
import java.util.stream.Collectors;
@UtilityClass
public class TypeMappers {
public static void init() {
SWCommandUtils.addValidator("arenaPlayer", arenaPlayer());
SWCommandUtils.addMapper("nonHistoricArenaMode", arenaModeTypeMapper(false));
SWCommandUtils.addMapper("historicArenaMode", arenaModeTypeMapper(true));
SWCommandUtils.addMapper("arenaMap", arenaMapTypeMapper());
}
private static TypeValidator<ProxiedPlayer> arenaPlayer() {
return (sender, value, messageSender) -> {
ChatSender player = ChatSender.of(value);
if (player.user().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<ArenaMode>() {
@Override
public ArenaMode map(CommandSender commandSender, String[] previousArguments, String s) {
return ArenaMode.getByChat(s);
}
@Override
public Collection<String> tabCompletes(CommandSender sender, String[] previousArguments, String s) {
return ArenaMode.getAllChatNames(historic);
}
};
}
private static TypeMapper<String> arenaMapTypeMapper() {
return new TypeMapper<String>() {
@Override
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(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;
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/>. 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.bungeecore.sql.IgnoreSystem;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter; import net.md_5.bungee.api.connection.ProxiedPlayer;
import de.steamwar.sql.IgnoreSystem;
import de.steamwar.sql.SteamwarUser;
public class UnIgnoreCommand extends SWCommand { public class UnIgnoreCommand extends SWCommand {
@ -31,15 +32,19 @@ public class UnIgnoreCommand extends SWCommand {
} }
@Register(description = "UNIGNORE_USAGE") @Register(description = "UNIGNORE_USAGE")
public void genericCommand(Chatter sender, @ErrorMessage("UNIGNORE_NOT_PLAYER") SteamwarUser target) { public void genericCommand(ProxiedPlayer p, String toUnIgnore) {
SteamwarUser user = sender.user(); SteamwarUser user = SteamwarUser.get(p.getUniqueId());
if(!IgnoreSystem.isIgnored(user, target)){ SteamwarUser target = SteamwarUser.get(toUnIgnore);
sender.system("UNIGNORE_NOT_IGNORED"); if(target == null){
Message.send("UNIGNORE_NOT_PLAYER", p);
return;
}else if(!IgnoreSystem.isIgnored(user, target)){
Message.send("UNIGNORE_NOT_IGNORED", p);
return; return;
} }
IgnoreSystem.unIgnore(user, target); 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/>. 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.bungeecore.BungeeCore;
import de.steamwar.velocitycore.discord.util.AuthManager; import de.steamwar.bungeecore.Message;
import de.steamwar.bungeecore.bot.AuthManager;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommand;
import de.steamwar.messages.Chatter; import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User; import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.util.Base64; import java.util.Base64;
import java.util.logging.Level;
public class VerifyCommand extends SWCommand { public class VerifyCommand extends SWCommand {
@ -35,26 +36,29 @@ public class VerifyCommand extends SWCommand {
} }
@Register(description = "VERIFY_USAGE") @Register(description = "VERIFY_USAGE")
public void genericCommand(Chatter sender, String code) { public void genericCommand(ProxiedPlayer sender, String code) {
byte[] bytes; byte[] bytes;
try { try {
bytes = Base64.getDecoder().decode(code); bytes = Base64.getDecoder().decode(code);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
sender.system("VERIFY_INVALID"); Message.send("VERIFY_INVALID", sender);
return; return;
} }
if(bytes.length != 16) { if(bytes.length != 16) {
sender.system("VERIFY_INVALID"); Message.send("VERIFY_INVALID", sender);
return; return;
} }
if(bytes[0] == 'D' && bytes[1] == 'C') {
User user = AuthManager.connectAuth(sender.user(), code); Member member = AuthManager.connectAuth(SteamwarUser.get(sender.getName()), code);
if(user != null) { if(member != null) {
VelocityCore.getLogger().log(Level.INFO,"%s Verified with Discorduser: %s".formatted(sender.user().getUserName(), user.getIdLong())); BungeeCore.log(sender.getName() + " Verified with Discorduser: " + member.getIdLong());
sender.system("VERIFY_SUCCESS", user.getAsTag()); Message.send("VERIFY_SUCCESS", sender, member.getUser().getAsTag());
} else { } else {
sender.system("VERIFY_INVALID"); Message.send("VERIFY_INVALID", sender);
}
} else {
Message.send("VERIFY_INVALID", sender);
} }
} }
} }

Datei anzeigen

@ -17,10 +17,11 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. 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.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.BufferedReader;
import java.io.IOException; import java.io.IOException;
@ -29,18 +30,18 @@ import java.io.InputStreamReader;
public class WebpasswordCommand extends SWCommand { public class WebpasswordCommand extends SWCommand {
public WebpasswordCommand() { public WebpasswordCommand() {
super("webpassword", "webpw", "web"); super("webpassword", null, "webpw", "web");
} }
@Register(description = "WEB_USAGE") @Register(description = "WEB_USAGE")
public void genericCommand(Chatter sender, String password) { public void genericCommand(ProxiedPlayer player, String password) {
if(password.length() < 8) { if(password.length() < 8) {
sender.system("WEB_PASSWORD_LENGTH"); ChatSender.of(player).system("WEB_PASSWORD_LENGTH");
return; 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); pb.redirectErrorStream(true);
try { try {
Process regProcess = pb.start(); Process regProcess = pb.start();
@ -48,14 +49,14 @@ public class WebpasswordCommand extends SWCommand {
String errorLine; String errorLine;
if((errorLine = reader.readLine()) != null) { if((errorLine = reader.readLine()) != null) {
if ("updated".equals(errorLine)) { if ("updated".equals(errorLine)) {
sender.system("WEB_UPDATED"); ChatSender.of(player).system("WEB_UPDATED");
return; return;
} else { } else {
throw new SecurityException("Could not create webaccount " + errorLine); throw new SecurityException("Could not create webaccount " + errorLine);
} }
} }
sender.system("WEB_CREATED"); ChatSender.of(player).system("WEB_CREATED");
} catch (IOException e) { } catch (IOException e) {
throw new SecurityException("Could not create webaccount", e); throw new SecurityException("Could not create webaccount", e);
} }

Datei anzeigen

@ -0,0 +1,124 @@
/*
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.sql.Punishment;
import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.bungeecore.sql.Team;
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.chat.ClickEvent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import java.net.InetSocketAddress;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.time.Instant;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class WhoisCommand extends SWCommand {
public WhoisCommand() {
super("whois", "bungeecore.teamchat");
}
@Register(description = "WHOIS_USAGE")
public void genericCommand(ProxiedPlayer player, @Mapper("player") String target, @OptionalValue("") @StaticValue(value = {"", "-all", "-a"}, allowISE = true) boolean all) {
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 {
sendUserinfo(player, user, all);
}
}
@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, boolean all) {
Message.send("WHOIS_USERNAME", player, user.getUserName());
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());
Message.send("WHOIS_GROUP", player, user.getUserGroup().getColorCode(), user.getUserGroup().name());
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());
}
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());
Message.send("WHOIS_PUNISHMENTS", player);
List<Punishment> punishmentList = Punishment.getAllPunishmentsOfPlayer(user.getId());
Set<Punishment.PunishmentType> found = new HashSet<>();
boolean isPunished = false;
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);
}
}
}

Datei anzeigen

@ -17,13 +17,13 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. 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 { public interface InvCallback {
void clicked(ClickType click); void clicked(ClickType click);
enum ClickType { public static enum ClickType {
LEFT, LEFT,
SHIFT_LEFT, SHIFT_LEFT,
RIGHT, RIGHT,

Datei anzeigen

@ -17,57 +17,94 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package de.steamwar.velocitycore.inventory; package de.steamwar.bungeecore.inventory;
import de.steamwar.messages.Message; import de.steamwar.bungeecore.network.NetworkSender;
import de.steamwar.velocitycore.network.NetworkSender; import de.steamwar.bungeecore.network.handlers.InventoryCallbackHandler;
import de.steamwar.velocitycore.network.handlers.InventoryCallbackHandler; import de.steamwar.bungeecore.sql.SteamwarUser;
import de.steamwar.messages.Chatter;
import de.steamwar.messages.PlayerChatter;
import de.steamwar.network.packets.server.CloseInventoryPacket; import de.steamwar.network.packets.server.CloseInventoryPacket;
import de.steamwar.network.packets.server.InventoryPacket; import de.steamwar.network.packets.server.InventoryPacket;
import lombok.Getter; import net.md_5.bungee.api.connection.ProxiedPlayer;
import lombok.Setter;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.BiFunction; import java.util.function.BiFunction;
public class SWInventory { public class SWInventory {
private final Map<Integer, SWItem> itemMap = new HashMap<>(); private final Map<Integer, SWItem> itemMap;
private final Chatter player;
private final int size;
private final Message title;
@Setter
private InvCallback close; private InvCallback close;
@Getter private ProxiedPlayer player;
@Setter private int size;
private boolean next = false; private String title;
private boolean next;
private final AtomicBoolean processingClick = new AtomicBoolean(); private final AtomicBoolean processingClick = new AtomicBoolean();
public SWInventory(PlayerChatter player, int size, Message title) { public SWInventory(ProxiedPlayer proxiedPlayer, int size, String title) {
InventoryCallbackHandler.inventoryHashMap.put(player.user().getId(), this); itemMap = new HashMap<>();
this.player = player; InventoryCallbackHandler.inventoryHashMap.put(SteamwarUser.get(proxiedPlayer).getId(), this);
this.player = proxiedPlayer;
this.size = size; this.size = size;
this.title = title; this.title = title;
next = false;
} }
public void addItem(int pos, SWItem item, InvCallback callback) { 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.setCallback(callback);
addItem(pos, item); item.setLore(lore);
itemMap.put(pos, item);
} }
public void addItem(int pos, SWItem item) { public void addItem(int pos, SWItem item) {
itemMap.put(pos, 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) { public void setCallback(int pos, InvCallback callback) {
itemMap.get(pos).setCallback(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) { public void handleCallback(InvCallback.ClickType type, int pos) {
if(processingClick.compareAndSet(false, true)) { if(processingClick.compareAndSet(false, true)) {
itemMap.get(pos).getCallback().clicked(type); itemMap.get(pos).getCallback().clicked(type);
@ -77,7 +114,7 @@ public class SWInventory {
public void handleClose() { public void handleClose() {
if(processingClick.compareAndSet(false, true)) { if(processingClick.compareAndSet(false, true)) {
InventoryCallbackHandler.inventoryHashMap.remove(player.user().getId(), this); InventoryCallbackHandler.inventoryHashMap.remove(SteamwarUser.get(player).getId(), this);
if(close != null) if(close != null)
close.clicked(null); close.clicked(null);
processingClick.set(false); processingClick.set(false);
@ -85,8 +122,8 @@ public class SWInventory {
} }
public void open() { public void open() {
InventoryPacket inv = new InventoryPacket(player.parseToLegacy(title), player.user().getId(), size, map(itemMap, (integer, swItem) -> swItem.writeToString(player, integer).toString())); InventoryPacket inv = new InventoryPacket(title, SteamwarUser.get(player).getId(), size, map(itemMap, (integer, swItem) -> swItem.writeToString(integer).toString()));
player.withPlayer(p -> NetworkSender.send(p, inv)); NetworkSender.send(player, inv);
} }
private static <T, K, J> Map<T, J> map(Map<T, K> map, BiFunction<T, K, J> function) { private static <T, K, J> Map<T, J> map(Map<T, K> map, BiFunction<T, K, J> function) {
@ -99,7 +136,23 @@ public class SWInventory {
close(player); close(player);
} }
public static void close(Chatter player) { public static void close(ProxiedPlayer player) {
player.withPlayer(p -> NetworkSender.send(p, new CloseInventoryPacket(player.user().getId()))); NetworkSender.send(player, new CloseInventoryPacket(SteamwarUser.get(player).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;
} }
} }

Datei anzeigen

@ -0,0 +1,173 @@
/*
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 com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.util.ArrayList;
import java.util.List;
public class SWItem {
private String material, title, skullOwner;
private boolean enchanted, hideAttributes;
private List<String> lore;
private InvCallback callback;
private int color;
public SWItem(String material, String title) {
this.material = material.toUpperCase();
lore = new ArrayList<>();
this.title = title;
color = 0;
}
public SWItem(String title, int color) {
this.material = "DYE";
lore = new ArrayList<>();
this.title = title;
this.color = color;
}
public static SWItem getSkull(String skullOwner) {
SWItem item = new SWItem("SKULL", skullOwner);
item.setSkullOwner(skullOwner);
return item;
}
public void setCallback(InvCallback callback) {
this.callback = callback;
}
public void setColor(int color) {
this.color = color;
}
public InvCallback getCallback() {
return callback;
}
public String getMaterial() {
return material;
}
public void setMaterial(String material) {
this.material = material.toUpperCase();
}
public String getSkullOwner() {
return skullOwner;
}
public void setSkullOwner(String skullOwner) {
this.skullOwner = skullOwner;
}
public boolean isEnchanted() {
return enchanted;
}
public void setEnchanted(boolean enchanted) {
this.enchanted = enchanted;
}
public boolean isHideAttributes() {
return hideAttributes;
}
public void setHideAttributes(boolean hideAttributes) {
this.hideAttributes = hideAttributes;
}
public SWItem setName(String name) {
title = name;
return this;
}
public String getTitle() {
return title;
}
public void addLore(String lore) {
this.lore.add(lore);
}
public JsonObject writeToString(int position) {
JsonObject object = new JsonObject();
object.addProperty("material", material);
object.addProperty("position", position);
object.addProperty("title", title);
if(skullOwner != null)
object.addProperty("skullOwner", skullOwner);
if(enchanted)
object.addProperty("enchanted", true);
if(hideAttributes)
object.addProperty("hideAttributes", true);
if(color != 0)
object.addProperty("color", color);
if(lore != null) {
JsonArray array = new JsonArray();
for (String lores:
lore) {
array.add(lores);
}
object.add("lore", array);
}
return object;
}
@Override
public boolean equals(Object o) {
if(!(o instanceof SWItem))
return false;
SWItem item = (SWItem) o;
if(item.enchanted != enchanted)
return false;
if(item.hideAttributes != hideAttributes)
return false;
if(!item.material.equals(material))
return false;
if(!item.lore.equals(lore))
return false;
if(!item.skullOwner.equals(skullOwner))
return false;
return true;
}
public void setLore(List<String> lore) {
this.lore = lore;
}
public SWItem clone() {
SWItem item;
if(color != 0) {
item = new SWItem(title, color);
}else {
item = new SWItem(material, title);
}
item.setLore(lore);
item.setCallback(callback);
item.setEnchanted(enchanted);
item.setHideAttributes(hideAttributes);
return item;
}
}

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