diff --git a/.gitignore b/.gitignore index 958dc459..36e1257e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,15 @@ -lib +# Package Files +*.jar + +# Gradle +.gradle +**/build/ +!gradle/wrapper/gradle-wrapper.jar +steamwar.properties + +# IntelliJ IDEA .idea -target -dependency-reduced-pom.xml \ No newline at end of file +*.iml + +# Other +lib \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..083047ed --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "CommonCore"] + path = CommonCore + url = gitea@steamwar.de:SteamWar/CommonCore.git diff --git a/CommonCore b/CommonCore new file mode 160000 index 00000000..e83103d8 --- /dev/null +++ b/CommonCore @@ -0,0 +1 @@ +Subproject commit e83103d8afce8161a12d008d6ad99ba439243b27 diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..7b1f7967 --- /dev/null +++ b/build.gradle @@ -0,0 +1,251 @@ +/* + * 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 . + */ + + +import org.apache.tools.ant.taskdefs.condition.Os + +import java.util.function.BiConsumer + +plugins { + // Adding the base plugin fixes the following gradle warnings in IntelliJ: + // + // Warning: root project 'module-work-multi': Unable to resolve all content root directories + // Details: java.lang.IllegalStateException: No value has been specified for this provider. + // + // Warning: root project 'module-work-multi': Unable to resolve additional project configuration. + // Details: java.lang.IllegalStateException: No value has been specified for this provider. + id 'base' + id 'java' + id 'application' + + id 'com.github.johnrengelman.shadow' version '5.0.0' +} + +group 'de.steamwar' +version '' + +Properties steamwarProperties = new Properties() +if (file("steamwar.properties").exists()) { + steamwarProperties.load(file("steamwar.properties").newDataInputStream()) +} + +ext { + buildName = 'BungeeCore' + artifactName = 'bungeecore' + + uberJarName = "${buildName}-all.jar" + jarName = "${artifactName}.jar" + libs = "${buildDir}/libs" + + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + operatingSystem = "windows" + } else { + operatingSystem = "unix" + } +} + +compileJava.options.encoding = 'UTF-8' + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +mainClassName = '' + +sourceSets { + main { + java { + srcDirs = ['src/'] + } + resources { + srcDirs = ['src/'] + exclude '**/*.java', '**/*.kt' + } + } +} + +repositories { + mavenCentral() + maven { + url 'https://m2.dv8tion.net/releases' + } +} + +dependencies { + compileOnly 'org.projectlombok:lombok:1.18.22' + testCompileOnly 'org.projectlombok:lombok:1.18.22' + annotationProcessor 'org.projectlombok:lombok:1.18.22' + testAnnotationProcessor 'org.projectlombok:lombok:1.18.22' + + compileOnly files("${projectDir}/lib/BungeeCord.jar") + compileOnly files("${projectDir}/lib/PersistentBungeeCore.jar") + compileOnly files("${projectDir}/lib/BungeeTabListPlus.jar") + implementation("net.dv8tion:JDA:4.3.0_299") { + exclude module: 'opus-java' + } + + implementation project(":CommonCore") +} + +task buildProject { + description 'Build this project' + group "Steamwar" + + dependsOn build +} + +task finalizeProject { + description 'Finalize this project' + group "Steamwar" + + doLast { + if ("${buildDir}" == null) { + return + } + delete fileTree("${libs}").matching { + exclude("${uberJarName}") + } + file(libs + "/" + uberJarName).renameTo(file(libs + "/" + jarName)) + } +} +build.finalizedBy(finalizeProject) + +if (steamwarProperties.containsKey("hostname")) { + String hostname = steamwarProperties.get("hostname") + String uploadPath = steamwarProperties.getOrDefault("uploadPath", "~") + + String server = steamwarProperties.getOrDefault("server", "DevBungee") + String serverStartFlags = steamwarProperties.getOrDefault("serverStartFlags", "") + + task uploadProject { + description 'Upload this project' + group "Steamwar" + + doLast { + await(shell("scp ${libs}/${jarName} ${hostname}:${uploadPath}/${server}/plugins")) + if (steamwarProperties.getOrDefault("directStart", "false") == "false" && !answer("Start ${server} server?")) { + return + } + serverStart(server, serverStartFlags, hostname) + } + } + uploadProject.dependsOn(buildProject) + + task startDevServer { + description 'Start the DevBungee' + group "Steamwar" + + doLast { + serverStart(server, serverStartFlags, hostname) + } + } +} + +private def await(Process proc) { + def out = new StringBuilder() + def err = new StringBuilder() + proc.waitForProcessOutput(out, err) + return [out, err, proc.exitValue()] +} + +private def shell(String command) { + if (operatingSystem == "unix") { + return ['bash', '-c', command].execute() + } else { + return ["cmd", "/c", command].execute() + } +} + +private def serverStart(String serverName, String serverFlags, String hostname) { + def proc = shell("ssh -t ${hostname} \"./mc ${serverFlags} ${serverName}\"") + + Set 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 +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..dc56501c --- /dev/null +++ b/gradle.properties @@ -0,0 +1,22 @@ +# +# 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 . +# + +org.gradle.daemon = true +org.gradle.parallel = true +org.gradle.workers.max = 4 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..f3d88b1c Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..0f5795e5 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sat Apr 10 23:34:12 CEST 2021 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.1-all.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew new file mode 100755 index 00000000..2fe81a7d --- /dev/null +++ b/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..9618d8d9 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 8bb101a0..00000000 --- a/pom.xml +++ /dev/null @@ -1,104 +0,0 @@ - - - 4.0.0 - - de.steamwar - BungeeCore - 1.0 - jar - BungeeCore - - - UTF-8 - ${project.basedir} - - - - src - - - src - - **/*.java - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.6.1 - - 8 - 8 - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.4 - - - package - - shade - - - - - - bungeecore - - - - - dv8tion - m2-dv8tion - https://m2.dv8tion.net/releases - - - - - - steamwar - BungeeCord - 1.0 - system - ${main.basedir}/lib/BungeeCord.jar - - - steamwar - PersistentBungeeCore - 1.0 - system - ${main.basedir}/lib/PersistentBungeeCore.jar - - - steamwar - BungeeTabListPlus - 1.0 - system - ${main.basedir}/lib/BungeeTabListPlus.jar - - - net.dv8tion - JDA - 4.3.0_299 - compile - - - club.minnced - opus-java - - - - - org.projectlombok - lombok - 1.18.20 - provided - - - \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 00000000..4c2a7456 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,22 @@ +/* + * 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 . + */ + +rootProject.name = 'BungeeCore' + +include 'CommonCore' \ No newline at end of file diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index be531351..ffef1449 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -85,6 +85,7 @@ public class BungeeCore extends Plugin { new WorldDownloader(); new BrandListener(); new Fabric(); + new SubserverProtocolFixer(); new Node.LocalNode(); //new Node.RemoteNode("lx"); @@ -124,6 +125,7 @@ public class BungeeCore extends Plugin { new PlaytimeCommand(); new ArenaCommand(); new RankCommand(); + new LocalCommand(); // Punishment Commands: new PunishmentCommand("ban", Punishment.PunishmentType.Ban); diff --git a/src/de/steamwar/bungeecore/Message.java b/src/de/steamwar/bungeecore/Message.java index acaa1891..1f1213f9 100644 --- a/src/de/steamwar/bungeecore/Message.java +++ b/src/de/steamwar/bungeecore/Message.java @@ -19,68 +19,52 @@ package de.steamwar.bungeecore; -import de.steamwar.bungeecore.listeners.ConnectionListener; +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.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.connection.ProxiedPlayer; -import java.io.IOException; -import java.io.InputStream; import java.text.DateFormat; import java.text.MessageFormat; -import java.util.*; +import java.util.Date; +import java.util.Locale; +import java.util.ResourceBundle; public class Message { - private static final Map bundles = new HashMap<>(); - + @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 sender instanceof ProxiedPlayer ? ((ProxiedPlayer)sender).getLocale() : Locale.getDefault(); } - private static final String BASE_PATH = "/" + "de.steamwar.messages.BungeeCore".replace('.', '/'); - - private static ResourceBundle getResourceBundle(String locale, ResourceBundle parent) { - return bundles.computeIfAbsent(locale, locale1 -> { - InputStream inputStream = Message.class.getResourceAsStream(BASE_PATH + ("".equals(locale) ? "" : "_" + locale) + ".properties"); - if(inputStream == null) - return parent; - try { - return new SteamwarResourceBundle(inputStream, parent); - } catch (IOException e) { - return parent; - } - }); - } - - private static ResourceBundle getResourceBundle(Locale locale) { - return getResourceBundle(locale.toString(), getResourceBundle(locale.getLanguage(), getResourceBundle( "", (ResourceBundle) null))); - } - + @Deprecated private static String parse(String message, boolean prefixed, Locale locale, Object... params){ if(locale == null) locale = Locale.getDefault(); - ResourceBundle resourceBundle = getResourceBundle(locale); + ResourceBundle resourceBundle = SteamwarResourceBundle.getResourceBundle(locale); String pattern = ""; if(prefixed) pattern = resourceBundle.getObject("PREFIX") + " "; @@ -90,7 +74,7 @@ public class Message { for (int i = 0; i < params.length; i++) { if(params[i] instanceof Message) { Message msg = (Message) params[i]; - params[i] = parse(msg.getMessage(), false, locale, msg.getParams()); + 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]); } @@ -98,101 +82,65 @@ public class Message { 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); } - public static void send(String message, CommandSender sender, ChatMessageType type, Object... params){ - send(message, true, sender, type, null, null, params); - } - - public static void sendPrefixless(String message, CommandSender sender, ChatMessageType type, Object... params){ - send(message, false, sender, type, 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); } - public static void send(String message, boolean prefixed, CommandSender sender, ChatMessageType type, String onHover, ClickEvent onClick, Object... params){ - if(type == ChatMessageType.CHAT && sender instanceof ProxiedPlayer && ((ProxiedPlayer)sender).getChatMode() != ProxiedPlayer.ChatMode.SHOWN) + @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; - TextComponent msg = parseToComponent(message, prefixed, sender, params); - if(onHover != null) - msg.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, TextComponent.fromLegacyText(onHover))); - if(onClick != null) - msg.setClickEvent(onClick); - if(sender instanceof ProxiedPlayer) - ((ProxiedPlayer)sender).sendMessage(type, msg); - else - sender.sendMessage(msg); + + sender.send(prefixed, type, onHover != null ? new Message("PLAIN_STRING", onHover) : null, onClick, new Message(message, params)); } - public static void broadcast(String message, String onHover, ClickEvent onClick, Object... params){ - for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) - send(message, player, parse(onHover, player, params), onClick, params); + public static void broadcast(String message, Object... params) { + broadcast(message, null, null, params); } - public static void broadcast(String message, Object... params){ - for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()) - send(message, player, ChatMessageType.SYSTEM, 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 chat(String message, Object... params){ - for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()){ - Subserver server = Subserver.getSubserver(player); - if(server == null || server.getType() != Servertype.ARENA) - sendPrefixless(message, player, ChatMessageType.CHAT, params); - } + public static void team(String message, Object... params) { + team(message, null, null, params); } - public static void team(String message, Object... params){ - team(message, ChatMessageType.SYSTEM, 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)); } - public static void team(String message, ChatMessageType type, Object... params){ - for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()){ - if(player.getGroups().contains(ConnectionListener.TEAM_GROUP)) { - sendPrefixless(message, player, type, params); - } - } - } - - public static void team(String message, String onHover, ClickEvent onClick, Object... params){ - for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers()){ - if(player.getGroups().contains(ConnectionListener.TEAM_GROUP)) - sendPrefixless(message, player, Message.parse(onHover, player, params), onClick, params); - } - } - - private final String message; + private final String format; private final Object[] params; - public Message(String message, Object... params) { - this.message = message; + public Message(String format, Object... params) { + this.format = format; this.params = params; } - public String getMessage() { - return message; + public String getFormat() { + return format; } public Object[] getParams() { return params; } - private static class SteamwarResourceBundle extends PropertyResourceBundle { - public SteamwarResourceBundle(InputStream stream, ResourceBundle parent) throws IOException { - super(stream); - setParent(parent); - } - } } \ No newline at end of file diff --git a/src/de/steamwar/bungeecore/bot/SteamwarDiscordBot.java b/src/de/steamwar/bungeecore/bot/SteamwarDiscordBot.java index e1933923..3811c185 100644 --- a/src/de/steamwar/bungeecore/bot/SteamwarDiscordBot.java +++ b/src/de/steamwar/bungeecore/bot/SteamwarDiscordBot.java @@ -29,6 +29,7 @@ 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; @@ -59,10 +60,10 @@ public class SteamwarDiscordBot { private volatile AnnouncementListener announcementListener; @Getter - private volatile IngameChatListener ingameChatListener; + private volatile DiscordChatListener ingameChatListener; @Getter - private volatile ServerTeamChatListener serverTeamChatListener; + private volatile DiscordChatListener serverTeamChatListener; @Getter private final JDA jda; @@ -111,8 +112,8 @@ public class SteamwarDiscordBot { new DiscordEventListener(); new PrivateMessageListener(); announcementListener = new AnnouncementListener(); - ingameChatListener = new IngameChatListener(); - serverTeamChatListener = new ServerTeamChatListener(); + 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()); diff --git a/src/de/steamwar/bungeecore/bot/listeners/IngameChatListener.java b/src/de/steamwar/bungeecore/bot/listeners/DiscordChatListener.java similarity index 69% rename from src/de/steamwar/bungeecore/bot/listeners/IngameChatListener.java rename to src/de/steamwar/bungeecore/bot/listeners/DiscordChatListener.java index e7b709d9..70004ac4 100644 --- a/src/de/steamwar/bungeecore/bot/listeners/IngameChatListener.java +++ b/src/de/steamwar/bungeecore/bot/listeners/DiscordChatListener.java @@ -24,43 +24,45 @@ 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.bungeecore.sql.UserGroup; +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; -public class IngameChatListener extends BasicDiscordListener { +import java.util.function.Supplier; +import java.util.stream.Stream; + +public class DiscordChatListener extends BasicDiscordListener { + + private final String channel; + private final String format; + + private final Supplier> targets; + + public DiscordChatListener(String channel, String format, Supplier> targets) { + this.channel = channel; + this.format = format; + this.targets = targets; + } @Override public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { - if (!event.getChannel().getId().equals(SteamwarDiscordBotConfig.INGAME_CHANNEL)) { + if (!event.getChannel().getId().equals(channel) || event.getAuthor().isBot()) return; - } - if (event.getAuthor().isBot()) { - return; - } + Member member = event.getMember(); SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong()); - if (steamwarUser == null || event.getMessage().getContentRaw().length() > 250) { + if (steamwarUser == null || event.getMessage().getContentRaw().length() > 250 || steamwarUser.isPunished(Punishment.PunishmentType.Ban)) { event.getMessage().delete().queue(); } else { - String s = event.getMessage().getContentDisplay(); - if (steamwarUser.getUserGroup() == UserGroup.Member && (s.contains("http") || s.contains("www"))) { - event.getMessage().delete().queue(); - return; - } - if (steamwarUser.isPunished(Punishment.PunishmentType.Mute) || steamwarUser.isPunished(Punishment.PunishmentType.Ban)) { - event.getMessage().delete().queue(); - return; - } - ChatListener.discordChat(steamwarUser, event.getMessage().getContentDisplay().replaceAll("§[a-f0-9]", "").replace('\n', ' ')); + 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(SteamwarDiscordBotConfig.INGAME_CHANNEL); + 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`")); diff --git a/src/de/steamwar/bungeecore/bot/listeners/ServerTeamChatListener.java b/src/de/steamwar/bungeecore/bot/listeners/ServerTeamChatListener.java deleted file mode 100644 index 816da82b..00000000 --- a/src/de/steamwar/bungeecore/bot/listeners/ServerTeamChatListener.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * This file is a part of the SteamWar software. - * - * Copyright (C) 2020 SteamWar.de-Serverteam - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package de.steamwar.bungeecore.bot.listeners; - -import de.steamwar.bungeecore.bot.SteamwarDiscordBot; -import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig; -import de.steamwar.bungeecore.commands.ServerTeamchatCommand; -import de.steamwar.bungeecore.sql.SteamwarUser; -import net.dv8tion.jda.api.MessageBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; -import org.jetbrains.annotations.NotNull; - -public class ServerTeamChatListener extends BasicDiscordListener { - - @Override - public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { - if (!event.getChannel().getId().equals(SteamwarDiscordBotConfig.SERVER_TEAM_CHANNEL)) { - return; - } - if (event.getAuthor().isBot()) { - return; - } - Member member = event.getMember(); - SteamwarUser steamwarUser = SteamwarUser.get(member.getIdLong()); - if (steamwarUser == null) { - event.getMessage().delete().complete(); - } else { - ServerTeamchatCommand.sendToTeam(event.getMessage().getContentRaw(), steamwarUser); - } - } - - public void send(String message) { - TextChannel textChannel = SteamwarDiscordBot.instance().getJda().getGuildById(SteamwarDiscordBotConfig.GUILD).getTextChannelById(SteamwarDiscordBotConfig.SERVER_TEAM_CHANNEL); - assert textChannel != null; - MessageBuilder messageBuilder = new MessageBuilder(); - messageBuilder.append(message.replace("&", "")); - textChannel.sendMessage(messageBuilder.build()).queue(); - } -} diff --git a/src/de/steamwar/bungeecore/commands/ArenaCommand.java b/src/de/steamwar/bungeecore/commands/ArenaCommand.java index 66caf9fe..339c66ab 100644 --- a/src/de/steamwar/bungeecore/commands/ArenaCommand.java +++ b/src/de/steamwar/bungeecore/commands/ArenaCommand.java @@ -22,9 +22,6 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.Servertype; import de.steamwar.bungeecore.Subserver; -import de.steamwar.bungeecore.SubserverSystem; -import de.steamwar.bungeecore.sql.Punishment; -import de.steamwar.bungeecore.sql.SteamwarUser; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; @@ -42,23 +39,13 @@ public class ArenaCommand extends BasicCommand { return; ProxiedPlayer player = (ProxiedPlayer) sender; - SteamwarUser steamwarUser = SteamwarUser.get(player); - if (steamwarUser.isPunishedWithMessage(player, Punishment.PunishmentType.NoFightServer)) { - return; - } - ServerInfo server = ProxyServer.getInstance().getServerInfo(String.join(" ", args)); - if(server == null) { - Message.send("ARENA_NOT_FOUND", player); - return; - } - Subserver subserver = Subserver.getSubserver(server); - if(subserver == null || subserver.getType() != Servertype.ARENA) { + if(server == null || subserver == null || subserver.getType() != Servertype.ARENA) { Message.send("ARENA_NOT_FOUND", player); return; } - SubserverSystem.sendPlayer(subserver, player); + TpCommand.teleport(player, server); } } diff --git a/src/de/steamwar/bungeecore/commands/BauCommand.java b/src/de/steamwar/bungeecore/commands/BauCommand.java index 744d48fa..3c6b4a8e 100644 --- a/src/de/steamwar/bungeecore/commands/BauCommand.java +++ b/src/de/steamwar/bungeecore/commands/BauCommand.java @@ -25,6 +25,7 @@ import de.steamwar.bungeecore.inventory.SWInventory; import de.steamwar.bungeecore.inventory.SWItem; import de.steamwar.bungeecore.sql.BauweltMember; import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; @@ -78,7 +79,7 @@ public class BauCommand extends BasicCommand { testarena(p, args); break; default: - HelpCommand.sendBauHelp(p); + HelpCommand.sendBauHelp(ChatSender.of(p)); } } ); @@ -130,7 +131,7 @@ public class BauCommand extends BasicCommand { () -> new ServerStarter().build18(worldOwner.getUuid()).send(p).start(), () -> new ServerStarter().build15(worldOwner.getUuid()).send(p).start(), () -> new ServerStarter().build12(worldOwner.getUuid()).send(p).start(), - () -> HelpCommand.sendBauHelp(p)); + () -> HelpCommand.sendBauHelp(ChatSender.of(p))); } private static void versionSelector(ProxiedPlayer p, String[] args, int pos, Runnable run18, Runnable run15, Runnable run12, Runnable runElse) { @@ -233,7 +234,7 @@ public class BauCommand extends BasicCommand { () -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS18_PATH + user.getId())), () -> deleteConfirmation(p, () -> deleteWorld(p, BungeeCore.USERWORLDS15 + user.getId())), () -> deleteConfirmation(p, () -> deleteWorld(p, BungeeCore.WORLD_FOLDER + p.getUniqueId().toString())), - () -> HelpCommand.sendBauHelp(p)); + () -> HelpCommand.sendBauHelp(ChatSender.of(p))); } private static void deleteConfirmation(ProxiedPlayer p, Runnable worldDeletion) { diff --git a/src/de/steamwar/bungeecore/commands/DevCommand.java b/src/de/steamwar/bungeecore/commands/DevCommand.java index ce05e131..753fdc4d 100644 --- a/src/de/steamwar/bungeecore/commands/DevCommand.java +++ b/src/de/steamwar/bungeecore/commands/DevCommand.java @@ -19,9 +19,9 @@ 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.messages.ChatSender; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; @@ -44,25 +44,25 @@ public class DevCommand extends BasicCommand { } @Override - public void execute(CommandSender sender, String[] args) { - if (!(sender instanceof ProxiedPlayer)) + public void execute(CommandSender s, String[] args) { + if (!(s instanceof ProxiedPlayer)) return; - ProxiedPlayer player = (ProxiedPlayer) sender; + ProxiedPlayer player = (ProxiedPlayer) s; - SteamwarUser steamwarUser = SteamwarUser.get(player); - if (steamwarUser.isPunishedWithMessage(player, Punishment.PunishmentType.NoDevServer)) { + ChatSender sender = ChatSender.of(player); + if (sender.user().isPunishedWithMessage(sender, Punishment.PunishmentType.NoDevServer)) { return; } updateDevServers(); if(devServers.isEmpty()) { - Message.send("DEV_NO_SERVER", sender); + sender.system("DEV_NO_SERVER"); } else if (devServers.size() == 1) { player.connect(devServers.values().stream().findAny().get()); } else if (args.length == 0) { ServerInfo info = devServers.get(player.getName().toLowerCase()); if (info == null) { - Message.send("DEV_UNKNOWN_SERVER", player); + sender.system("DEV_UNKNOWN_SERVER"); return; } @@ -70,7 +70,7 @@ public class DevCommand extends BasicCommand { } else { ServerInfo info = devServers.get(args[0].toLowerCase()); if (info == null) { - Message.send("DEV_NO_SERVER", player); + sender.system("DEV_NO_SERVER"); return; } diff --git a/src/de/steamwar/bungeecore/commands/FightCommand.java b/src/de/steamwar/bungeecore/commands/FightCommand.java index e42e396d..32730168 100644 --- a/src/de/steamwar/bungeecore/commands/FightCommand.java +++ b/src/de/steamwar/bungeecore/commands/FightCommand.java @@ -24,13 +24,14 @@ 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.bungeecore.sql.SteamwarUser; +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.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.hover.content.Text; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.util.LinkedList; @@ -50,27 +51,27 @@ public class FightCommand extends BasicCommand { super("fight", "", "f"); } - static ArenaMode getMode(CommandSender sender, String arg){ + private static ArenaMode getMode(ChatSender sender, String arg){ ArenaMode mode = ArenaMode.getByChat(arg); if(mode != null) return mode; - Message.send("FIGHT_UNKNOWN_GAMEMODE", sender, arg); + sender.system("FIGHT_UNKNOWN_GAMEMODE", arg); return null; } - static String getMap(CommandSender sender, ArenaMode mode, String arg){ + 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(); - Message.send("FIGHT_UNKNOWN_ARENA", sender); + sender.system("FIGHT_UNKNOWN_ARENA"); return null; } - private static void getModes(CommandSender sender, String precommand, boolean historic){ + private static void getModes(ChatSender sender, String precommand, boolean historic){ TextComponent start = new TextComponent(); TextComponent current = start; for(ArenaMode mode : ArenaMode.getAllModes()){ @@ -80,25 +81,25 @@ public class FightCommand extends BasicCommand { current.setBold(true); current.setColor(ChatColor.GRAY); current.setText(mode.getChatName() + " "); - current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§e" + command).create())); + 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(start); + sender.sendMessage(ChatMessageType.SYSTEM, start); } - private static void getMaps(CommandSender sender, String precommand, ArenaMode mode){ + 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(Message.parse("FIGHT_ARENA_RANDOM", sender) + " "); - start.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§e" + command).create())); + start.setText(sender.parseToLegacy("FIGHT_ARENA_RANDOM") + " "); + start.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§e" + command))); start.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, command)); current = new TextComponent(); } @@ -108,14 +109,14 @@ public class FightCommand extends BasicCommand { current.setBold(true); current.setColor(ChatColor.GRAY); current.setText(map + " "); - current.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder("§e" + command).create())); + 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(start); + sender.sendMessage(ChatMessageType.SYSTEM, start); } private static boolean alreadyInArena(ProxiedPlayer player){ @@ -128,14 +129,14 @@ public class FightCommand extends BasicCommand { return false; } - static void createArena(CommandSender sender, String precommand, boolean allowMerging, String[] args, int startArg, boolean historic, FightCallback callback){ - if(!(sender instanceof ProxiedPlayer)) + static void createArena(CommandSender s, String precommand, boolean allowMerging, String[] args, int startArg, boolean historic, FightCallback callback){ + if(!(s instanceof ProxiedPlayer)) return; - ProxiedPlayer player = (ProxiedPlayer) sender; + ProxiedPlayer player = (ProxiedPlayer) s; - SteamwarUser steamwarUser = SteamwarUser.get(player); - if (steamwarUser.isPunishedWithMessage(player, Punishment.PunishmentType.NoFightServer)) { + ChatSender sender = ChatSender.of(player); + if (sender.user().isPunishedWithMessage(sender, Punishment.PunishmentType.NoFightServer)) { return; } @@ -143,7 +144,7 @@ public class FightCommand extends BasicCommand { return; if(ModLoaderBlocker.isFabric(player) && !precommand.equals("/bau testarena ")) { - Message.send("MODLOADER_DENIED", sender); + sender.system("MODLOADER_DENIED"); return; } diff --git a/src/de/steamwar/bungeecore/commands/HelpCommand.java b/src/de/steamwar/bungeecore/commands/HelpCommand.java index d2febdc4..7bcce929 100644 --- a/src/de/steamwar/bungeecore/commands/HelpCommand.java +++ b/src/de/steamwar/bungeecore/commands/HelpCommand.java @@ -20,10 +20,9 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.Message; -import net.md_5.bungee.api.ChatMessageType; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.chat.ClickEvent; -import net.md_5.bungee.api.connection.ProxiedPlayer; public class HelpCommand extends BasicCommand { @@ -32,32 +31,29 @@ public class HelpCommand extends BasicCommand { } @Override - public void execute(CommandSender sender, String[] args) { + public void execute(CommandSender s, String[] args) { + ChatSender sender = ChatSender.of(s); if (args.length < 1) { - Message.send("HELP_LOBBY", true, sender, ChatMessageType.SYSTEM, Message.parse("HELP_LOBBY_HOVER", sender), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/l")); - Message.send("HELP_BAU", true, sender, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_HOVER", sender), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/bau")); - Message.send("HELP_BAUSERVER", true, sender, ChatMessageType.SYSTEM, Message.parse("HELP_BAUSERVER_HOVER", sender), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help bau")); - Message.send("HELP_FIGHT", true, sender, ChatMessageType.SYSTEM, Message.parse("HELP_FIGHT_HOVER", sender), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/fight")); - Message.send("HELP_CHALLENGE", true, sender, ChatMessageType.SYSTEM, Message.parse("HELP_CHALLENGE_HOVER", sender), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/challenge")); - Message.send("HELP_HISTORIC", true, sender, ChatMessageType.SYSTEM, Message.parse("HELP_HISTORIC_HOVER", sender), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/historic")); - Message.send("HELP_TEAM", true, sender, ChatMessageType.SYSTEM, Message.parse("HELP_TEAM_HOVER", sender), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/team")); - Message.send("HELP_JOIN", true, sender, ChatMessageType.SYSTEM, Message.parse("HELP_JOIN_HOVER", sender), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join")); - Message.send("HELP_LOCAL", true, sender, ChatMessageType.SYSTEM, Message.parse("HELP_LOCAL_HOVER", sender), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/local")); - return; + printPage(sender, ClickEvent.Action.RUN_COMMAND, + "HELP_LOBBY", "/l", + "HELP_BAU", "/bau", + "HELP_BAUSERVER", "/help bau", + "HELP_FIGHT", "/fight", + "HELP_CHALLENGE", "/challenge", + "HELP_HISTORIC", "/historic", + "HELP_TEAM", "/team", + "HELP_JOIN", "/join", + "HELP_LOCAL", "/local"); + }else if (args[0].equalsIgnoreCase("bauserver")) { + sendBauHelp(sender); + }else if (args[0].equalsIgnoreCase("bau")) { + bauHelpGroup(sender, args); } - if (args[0].equalsIgnoreCase("bauserver")) { - sendBauHelp((ProxiedPlayer) sender); - } - if (args[0].equalsIgnoreCase("bau")) { - bauHelpGroup((ProxiedPlayer) sender, args); - return; - } - } - private static void bauHelpGroup(ProxiedPlayer p, String[] args) { + private static void bauHelpGroup(ChatSender sender, String[] args) { if (args.length < 2) { - sendBauHelpGroup(p); + sendBauHelpGroup(sender); return; } @@ -65,89 +61,63 @@ public class HelpCommand extends BasicCommand { case "admin": case "owner": case "bauwelt": - sendBauHelpAdmin(p); + sender.system("HELP_BAU_GROUP_ADMIN_TITLE"); + sendBauHelp(sender); return; case "world": - sendBauHelpWorld(p); + printPage(sender, "HELP_BAU_GROUP_WORLD_TITLE", "HELP_TNT", "HELP_FIRE", "HELP_FREEZE", "HELP_TPSLIMIT", "HELP_PROTECT", "HELP_RESET"); return; case "player": - sendBauHelpPlayer(p); + 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": - sendBauHelpWorldEdit(p); + 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": - sendBauHelpOther(p); + printPage(sender, "HELP_BAU_GROUP_OTHER_TITLE", "HELP_TESTBLOCK", "HELP_SKULL", "HELP_BAUINFO"); return; default: - sendBauHelpGroup(p); + sendBauHelpGroup(sender); } } - private static void sendBauHelpGroup(ProxiedPlayer p) { - Message.send("HELP_BAU_GROUP_ADMIN", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_GROUP_ADMIN_HOVER", p), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help bau admin")); - Message.send("HELP_BAU_GROUP_WORLD", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_GROUP_WORLD_HOVER", p), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help bau world")); - Message.send("HELP_BAU_GROUP_PLAYER", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_GROUP_PLAYER_HOVER", p), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help bau player")); - Message.send("HELP_BAU_GROUP_WE", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_GROUP_WE_HOVER", p), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help bau we")); - Message.send("HELP_BAU_GROUP_OTHER", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_GROUP_OTHER_HOVER", p), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/help bau other")); + private static void sendBauHelpGroup(ChatSender sender) { + printPage(sender, ClickEvent.Action.RUN_COMMAND, + "HELP_BAU_GROUP_ADMIN", "/help bau admin", + "HELP_BAU_GROUP_WORLD", "/help bau world", + "HELP_BAU_GROUP_PLAYER", "/help bau player", + "HELP_BAU_GROUP_WE", "/help bau we", + "HELP_BAU_GROUP_OTHER", "/help bau other"); } - static void sendBauHelp(ProxiedPlayer p) { - Message.send("HELP_BAU_TP", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_TP_HOVER", p), new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/bau tp ")); - Message.send("HELP_BAU_ADDMEMBER", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_ADDMEMBER_HOVER", p), new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/bau addmember ")); - Message.send("HELP_BAU_DELMEMBER", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_DELMEMBER_HOVER", p), new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/bau delmember ")); - Message.send("HELP_BAU_TOGGLEWE", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_TOGGLEWE_HOVER", p), new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/bau togglewe ")); - Message.send("HELP_BAU_TOGGLEWORLD", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_TOGGLEWORLD_HOVER", p), new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/bau toggleworld ")); - Message.send("HELP_BAU_DELETE", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_DELETE_HOVER", p), new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/bau delete ")); - Message.send("HELP_BAU_TESTARENA", true, p, ChatMessageType.SYSTEM, Message.parse("HELP_BAU_TESTARENA_HOVER", p), new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/bau testarena ")); + static void sendBauHelp(ChatSender sender) { + printPage(sender, ClickEvent.Action.SUGGEST_COMMAND, + "HELP_BAU_TP", "/bau tp ", + "HELP_BAU_ADDMEMBER", "/bau addmember ", + "HELP_BAU_DELMEMBER", "/bau delmember ", + "HELP_BAU_TOGGLEWE", "/bau togglewe ", + "HELP_BAU_TOGGLEWORLD", "/bau toggleworld ", + "HELP_BAU_DELETE", "/bau delete ", + "HELP_BAU_TESTARENA", "/bau testarena "); } - static void sendBauHelpWorld(ProxiedPlayer p) { - Message.send("HELP_BAU_GROUP_WORLD_TITLE", p); - Message.sendPrefixless("HELP_TNT", p); - Message.sendPrefixless("HELP_FIRE", p); - Message.sendPrefixless("HELP_FREEZE", p); - Message.sendPrefixless("HELP_TPSLIMIT", p); - Message.sendPrefixless("HELP_PROTECT", p); - Message.sendPrefixless("HELP_RESET", p); + 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)); + } } - static void sendBauHelpPlayer(ProxiedPlayer p) { - Message.sendPrefixless("HELP_BAU_GROUP_PLAYER_TITLE", p); - Message.sendPrefixless("HELP_SPEED", p); - Message.sendPrefixless("HELP_NV", p); - Message.sendPrefixless("HELP_WV", p); - Message.sendPrefixless("HELP_DEBUGSTICK", p); - Message.sendPrefixless("HELP_TRACE", p); - Message.sendPrefixless("HELP_LOADER", p); + private static void printPage(ChatSender sender, String title, String... messages) { + sender.system(title); + for (String message : messages) { + sender.prefixless(message); + } } - - static void sendBauHelpAdmin(ProxiedPlayer p) { - Message.send("HELP_BAU_GROUP_ADMIN_TITLE", p); - sendBauHelp(p); - } - - static void sendBauHelpWorldEdit(ProxiedPlayer p) { - Message.sendPrefixless("HELP_BAU_GROUP_WE_TITLE", p); - Message.sendPrefixless("HELP_WE_POS1", p); - Message.sendPrefixless("HELP_WE_POS2", p); - Message.sendPrefixless("HELP_WE_COPY", p); - Message.sendPrefixless("HELP_WE_PASTE", p); - Message.sendPrefixless("HELP_WE_FLOPY", p); - Message.sendPrefixless("HELP_WE_FLOPYP", p); - Message.sendPrefixless("HELP_WE_ROTATE_90", p); - Message.sendPrefixless("HELP_WE_ROTATE_180", p); - Message.sendPrefixless("HELP_WE_ROTATE_N90", p); - } - - static void sendBauHelpOther(ProxiedPlayer p) { - Message.sendPrefixless("HELP_BAU_GROUP_OTHER_TITLE", p); - Message.sendPrefixless("HELP_TESTBLOCK", p); - Message.sendPrefixless("HELP_SKULL", p); - Message.sendPrefixless("HELP_BAUINFO", p); - } - } diff --git a/src/de/steamwar/bungeecore/commands/LocalCommand.java b/src/de/steamwar/bungeecore/commands/LocalCommand.java new file mode 100644 index 00000000..28717f7b --- /dev/null +++ b/src/de/steamwar/bungeecore/commands/LocalCommand.java @@ -0,0 +1,39 @@ +/* + 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 . +*/ + +package de.steamwar.bungeecore.commands; + +import de.steamwar.bungeecore.listeners.ChatListener; +import net.md_5.bungee.api.CommandSender; +import net.md_5.bungee.api.connection.ProxiedPlayer; + +public class LocalCommand extends BasicCommand { + + public LocalCommand() { + super("local", null, "bc", "bauchat"); + } + + @Override + public void execute(CommandSender sender, String[] args) { + if(!(sender instanceof ProxiedPlayer)) + return; + + ChatListener.localChat((ProxiedPlayer) sender, String.join(" ", args)); + } +} diff --git a/src/de/steamwar/bungeecore/commands/MsgCommand.java b/src/de/steamwar/bungeecore/commands/MsgCommand.java index 67f7013c..0107b788 100644 --- a/src/de/steamwar/bungeecore/commands/MsgCommand.java +++ b/src/de/steamwar/bungeecore/commands/MsgCommand.java @@ -19,16 +19,16 @@ package de.steamwar.bungeecore.commands; -import de.steamwar.bungeecore.BungeeCore; -import de.steamwar.bungeecore.Message; +import de.steamwar.bungeecore.listeners.ChatListener; import de.steamwar.bungeecore.sql.IgnoreSystem; -import de.steamwar.bungeecore.sql.Punishment; -import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.connection.ProxiedPlayer; import java.util.ArrayList; +import java.util.Arrays; +import java.util.stream.Stream; import static de.steamwar.bungeecore.Storage.lastChats; @@ -40,45 +40,33 @@ public class MsgCommand extends BasicCommand { @Override public void execute(CommandSender sender, String[] args) { - if(sender instanceof ProxiedPlayer){ - ProxiedPlayer player = (ProxiedPlayer) sender; + if(!(sender instanceof ProxiedPlayer)) + return; - if (args.length < 2) { - Message.send("MSG_USAGE", player); - return; - } - - SteamwarUser user = SteamwarUser.get(player); - if (user.isPunishedWithMessage(player, Punishment.PunishmentType.Mute)) { - return; - } - - ProxiedPlayer target = ProxyServer.getInstance().getPlayer(args[0]); - if(target == null){ - Message.send("MSG_OFFLINE", player); - return; - }else if (IgnoreSystem.isIgnored(target, player)) { - Message.send("MSG_IGNORED", player); - return; - }else if(target.getChatMode() != ProxiedPlayer.ChatMode.SHOWN){ - Message.send("MSG_NOMESSAGE", player); - return; - }else if(target.equals(player)){ - Message.send("MSG_SELF", player); - return; - } - - StringBuilder msgBuilder = new StringBuilder(); - for (int i = 1; i < args.length; i++){ - msgBuilder.append(args[i]).append(" "); - } - Message.sendPrefixless("MSG_FORMAT", player, player.getName(), target.getName(), msgBuilder.toString()); - Message.sendPrefixless("MSG_FORMAT", target, player.getName(), target.getName(), msgBuilder.toString()); - BungeeCore.log(Message.parse("MSG_FORMAT", player, player.getName(), target.getName(), msgBuilder.toString())); - - lastChats.put(player, target); - lastChats.put(target, player); + if (args.length < 2) { + ChatSender.of(sender).system("MSG_USAGE"); + return; } + + msg((ProxiedPlayer) sender, ProxyServer.getInstance().getPlayer(args[0]), Arrays.copyOfRange(args, 1, args.length)); + } + + public static void msg(ProxiedPlayer player, ProxiedPlayer target, String[] args) { + ChatSender sender = ChatSender.of(player); + if(target == null || !target.isConnected()) { + sender.system("MSG_OFFLINE"); + return; + } + + if (IgnoreSystem.isIgnored(target, player)) { + sender.system("MSG_IGNORED"); + return; + } + + ChatSender receiver = ChatSender.of(target); + ChatListener.sendChat(sender, Stream.of(sender, receiver), "CHAT_MSG", receiver, String.join(" ", args)); + lastChats.put(player, target); + lastChats.put(target, player); } @Override diff --git a/src/de/steamwar/bungeecore/commands/RCommand.java b/src/de/steamwar/bungeecore/commands/RCommand.java index c9d70dd2..62e5af8b 100644 --- a/src/de/steamwar/bungeecore/commands/RCommand.java +++ b/src/de/steamwar/bungeecore/commands/RCommand.java @@ -19,11 +19,7 @@ package de.steamwar.bungeecore.commands; -import de.steamwar.bungeecore.BungeeCore; -import de.steamwar.bungeecore.Message; -import de.steamwar.bungeecore.sql.IgnoreSystem; -import de.steamwar.bungeecore.sql.Punishment; -import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -37,43 +33,14 @@ public class RCommand extends BasicCommand { @Override public void execute(CommandSender sender, String[] args) { - if(sender instanceof ProxiedPlayer){ - ProxiedPlayer player = (ProxiedPlayer) sender; - if(args.length == 0){ - Message.send("R_USAGE", player); - return; - } + if(!(sender instanceof ProxiedPlayer)) + return; - SteamwarUser user = SteamwarUser.get(player); - if (user.isPunishedWithMessage(player, Punishment.PunishmentType.Mute)) { - return; - } - - ProxiedPlayer target = lastChats.get(player); - if(target == null){ - Message.send("R_NOTHING", player); - return; - }else if(!target.isConnected()){ - Message.send("R_OFFLINE", player); - lastChats.remove(player); - return; - }else if (IgnoreSystem.isIgnored(target, player)) { - Message.send("R_BLOCKED", player); - return; - }else if(target.getChatMode() != ProxiedPlayer.ChatMode.SHOWN){ - Message.send("R_NO_CHAT", player); - return; - } - - StringBuilder msgBuilder = new StringBuilder(); - for (String arg : args){ - msgBuilder.append(arg).append(" "); - } - Message.sendPrefixless("MSG_FORMAT", player, player.getName(), target.getName(), msgBuilder.toString()); - Message.sendPrefixless("MSG_FORMAT", target, player.getName(), target.getName(), msgBuilder.toString()); - BungeeCore.log(Message.parse("MSG_FORMAT", player, player.getName(), target.getName(), msgBuilder.toString())); - - lastChats.put(target, player); + if(args.length == 0){ + ChatSender.of(sender).system("R_USAGE"); + return; } + + MsgCommand.msg((ProxiedPlayer) sender, lastChats.get(sender), args); } } diff --git a/src/de/steamwar/bungeecore/commands/ReplayCommand.java b/src/de/steamwar/bungeecore/commands/ReplayCommand.java index feb033ad..ac1d0039 100644 --- a/src/de/steamwar/bungeecore/commands/ReplayCommand.java +++ b/src/de/steamwar/bungeecore/commands/ReplayCommand.java @@ -27,6 +27,7 @@ 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.messages.ChatSender; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -41,15 +42,14 @@ public class ReplayCommand extends BasicCommand { } @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) + public void execute(CommandSender s, String[] args) { + if(!(s instanceof ProxiedPlayer)) return; - ProxiedPlayer player = (ProxiedPlayer) sender; + ProxiedPlayer player = (ProxiedPlayer) s; - SteamwarUser steamwarUser = SteamwarUser.get(player); - if (steamwarUser.isPunishedWithMessage(player, Punishment.PunishmentType.NoFightServer)) { + 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()); @@ -59,24 +59,24 @@ public class ReplayCommand extends BasicCommand { if (user.getUserGroup().isAdminGroup() && click.isShiftClick() && fight.replayExists()) { starter.test(mode, mode.getRandomMap(), player).start(); } else if(!fight.replayAllowed()) { - Message.send("REPLAY_UNAVAILABLE", player); + sender.system("REPLAY_UNAVAILABLE"); } else { starter.arena(mode, mode.getRandomMap()).start(); } - }, page -> Fight.getPage(page, 45).stream().map(fight -> new SWListInv.SWListEntry<>(getFightItem(player, fight), fight)).collect(Collectors.toList())).open(); + }, page -> Fight.getPage(page, 45).stream().map(fight -> new SWListInv.SWListEntry<>(getFightItem(sender, fight), fight)).collect(Collectors.toList())).open(); } - private SWItem getFightItem(ProxiedPlayer player, Fight fight) { + private SWItem getFightItem(ChatSender sender, Fight fight) { SchematicType type = fight.getSchemType(); - SWItem item = new SWItem(type != null ? type.getMaterial() : "BARRIER", parseLeader(player, fight.getBlueLeader(), fight.getBluePlayers().size(), fight.getWin() == 1)); + SWItem item = new SWItem(type != null ? type.getMaterial() : "BARRIER", parseLeader(sender, fight.getBlueLeader(), fight.getBluePlayers().size(), fight.getWin() == 1)); List lore = new ArrayList<>(); - lore.add(parseLeader(player, fight.getRedLeader(), fight.getRedPlayers().size(), fight.getWin() == 2)); - lore.add(Message.parse("REPLAY_TIME", player, fight.getStartTime())); + lore.add(parseLeader(sender, fight.getRedLeader(), fight.getRedPlayers().size(), fight.getWin() == 2)); + lore.add(sender.parseToLegacy("REPLAY_TIME", fight.getStartTime())); lore.add(""); - lore.add(Message.parse("REPLAY_SERVER", player, fight.getServer())); + lore.add(sender.parseToLegacy("REPLAY_SERVER", fight.getServer())); if(!fight.replayAllowed()) - lore.add(Message.parse("REPLAY_UNAVAILABLE", player)); + lore.add(sender.parseToLegacy("REPLAY_UNAVAILABLE")); item.setLore(lore); if(fight.replayAllowed()) @@ -85,7 +85,7 @@ public class ReplayCommand extends BasicCommand { return item; } - private String parseLeader(ProxiedPlayer player, SteamwarUser leader, int players, boolean winner) { - return Message.parse(winner ? (players > 1 ? "REPLAY_WINNER" : "REPLAY_SOLO_WINNER") : (players > 1 ? "REPLAY_LOSER" : "REPLAY_SOLO_LOSER"), player, leader.getUserName(), players - 1); + private String parseLeader(ChatSender sender, SteamwarUser leader, int players, boolean winner) { + return sender.parseToLegacy(winner ? (players > 1 ? "REPLAY_WINNER" : "REPLAY_SOLO_WINNER") : (players > 1 ? "REPLAY_LOSER" : "REPLAY_SOLO_LOSER"), leader.getUserName(), players - 1); } } diff --git a/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java b/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java index 7207e0a2..26b4db1d 100644 --- a/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java +++ b/src/de/steamwar/bungeecore/commands/ServerTeamchatCommand.java @@ -19,17 +19,9 @@ package de.steamwar.bungeecore.commands; -import de.steamwar.bungeecore.BungeeCore; -import de.steamwar.bungeecore.Message; -import de.steamwar.bungeecore.bot.SteamwarDiscordBot; import de.steamwar.bungeecore.listeners.ChatListener; -import de.steamwar.bungeecore.sql.SteamwarUser; -import net.md_5.bungee.api.ChatColor; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.CommandSender; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.connection.ProxiedPlayer; - -import java.util.logging.Level; public class ServerTeamchatCommand extends BasicCommand { @@ -38,48 +30,13 @@ public class ServerTeamchatCommand extends BasicCommand { } @Override - public void execute(CommandSender sender, String[] args) { - if(sender instanceof ProxiedPlayer){ - ProxiedPlayer player = (ProxiedPlayer) sender; - - if(args.length == 0){ - Message.sendPrefixless("STC_USAGE", player); - return; - } - - StringBuilder msgBuilder = new StringBuilder(); - for (String arg : args){ - msgBuilder.append(arg).append(" "); - } - String msg = msgBuilder.toString(); - msg = ChatColor.translateAlternateColorCodes('&', msg); - - if (SteamwarDiscordBot.instance() != null) { - try { - SteamwarDiscordBot.instance().getServerTeamChatListener().send(" " + (player.getName() + "» " + msg).replaceAll("§[a-f0-9r]", "")); - } catch (Exception e) { - BungeeCore.get().getLogger().log(Level.SEVERE, "Could not send stc message to discord", e); - } - } - sendToTeam(msg, player); + public void execute(CommandSender s, String[] args) { + ChatSender sender = ChatSender.of(s); + if(args.length == 0) { + sender.system("STC_USAGE"); + return; } - } - public static void sendToTeam(String message, SteamwarUser sender){ - for (ProxiedPlayer target : ProxyServer.getInstance().getPlayers()){ - if ((target.hasPermission("bungeecore.teamchat")) - && target.getChatMode() == ProxiedPlayer.ChatMode.SHOWN){ - Message.sendPrefixless("STC_FORMAT", target, sender.getUserName(), ChatListener.parseAtMessage(message, "§r", target)); - } - } - } - - public static void sendToTeam(String message, ProxiedPlayer sender){ - for (ProxiedPlayer target : ProxyServer.getInstance().getPlayers()){ - if ((target.hasPermission("bungeecore.teamchat")) - && target.getChatMode() == ProxiedPlayer.ChatMode.SHOWN){ - Message.sendPrefixless("STC_FORMAT", target, sender.getName(), ChatListener.parseAtMessage(message, "§r", target)); - } - } + ChatListener.sendChat(sender, ChatSender.serverteamReceivers(), "CHAT_SERVERTEAM", null, String.join(" ", args)); } } diff --git a/src/de/steamwar/bungeecore/commands/TeamCommand.java b/src/de/steamwar/bungeecore/commands/TeamCommand.java index 0cd0277d..d92b5dad 100644 --- a/src/de/steamwar/bungeecore/commands/TeamCommand.java +++ b/src/de/steamwar/bungeecore/commands/TeamCommand.java @@ -20,6 +20,7 @@ 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.Event; @@ -33,11 +34,16 @@ 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 java.net.InetSocketAddress; import java.time.Instant; import java.time.format.DateTimeFormatter; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; import java.util.stream.Collectors; import static de.steamwar.bungeecore.Storage.teamInvitations; @@ -77,6 +83,7 @@ public class TeamCommand extends BasicCommand { 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; @@ -90,7 +97,6 @@ public class TeamCommand extends BasicCommand { Message.send("TEAM_HELP_EVENT", sender); Message.send("TEAM_HELP_LEAVE", sender); - Team team = Team.get(user.getTeam()); if(user.isLeader()){ Message.send("TEAM_HELP_INVITE", sender); Message.send("TEAM_HELP_REMOVE", sender); @@ -99,6 +105,7 @@ public class TeamCommand extends BasicCommand { 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); } } } @@ -157,6 +164,12 @@ public class TeamCommand extends BasicCommand { 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); } @@ -549,6 +562,62 @@ public class TeamCommand extends BasicCommand { } } + 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(serverInfo); + } + + private void server(ProxiedPlayer player, SteamwarUser user, Team team, String[] args){ + if(notLeader(player, user, team)) + return; + if (args.length < 2) { + Message.send("TEAM_SERVER_USAGE", player); + return; + } + String server = args[1]; + 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); + } + private void changeColor(ProxiedPlayer player, SteamwarUser user, Team team) { if(notLeader(player, user, team)) return; @@ -649,11 +718,13 @@ public class TeamCommand extends BasicCommand { 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 coming = Event.getComing(); coming.forEach(event -> tab.add(event.getEventName())); - }else if(args[1].equalsIgnoreCase("join") || args[1].equalsIgnoreCase("info")){ + }else if(args[1].equalsIgnoreCase("join") || args[1].equalsIgnoreCase("info") || args[1].equalsIgnoreCase("tp")){ List teams = Team.getAll(); teams.forEach(team -> { tab.add(team.getTeamName()); diff --git a/src/de/steamwar/bungeecore/commands/TeamchatCommand.java b/src/de/steamwar/bungeecore/commands/TeamchatCommand.java index d85ac6ee..60e57dcb 100644 --- a/src/de/steamwar/bungeecore/commands/TeamchatCommand.java +++ b/src/de/steamwar/bungeecore/commands/TeamchatCommand.java @@ -19,13 +19,10 @@ package de.steamwar.bungeecore.commands; -import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.listeners.ChatListener; import de.steamwar.bungeecore.sql.SteamwarUser; -import net.md_5.bungee.api.ChatColor; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.CommandSender; -import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.connection.ProxiedPlayer; public class TeamchatCommand extends BasicCommand { @@ -34,35 +31,19 @@ public class TeamchatCommand extends BasicCommand { } @Override - public void execute(CommandSender sender, String[] args) { - if(sender instanceof ProxiedPlayer){ - ProxiedPlayer player = (ProxiedPlayer) sender; - SteamwarUser user = SteamwarUser.get(player.getUniqueId()); - - if(user.getTeam() == 0){ - Message.send("TC_NO_TEAM", player); - return; - } - - if(args.length == 0){ - Message.send("TC_USAGE", player); - return; - } - - StringBuilder msgBuilder = new StringBuilder(); - for (String arg : args){ - msgBuilder.append(arg).append(" "); - } - String msg = msgBuilder.toString(); - msg = ChatColor.translateAlternateColorCodes('&', msg); - - for (ProxiedPlayer target : ProxyServer.getInstance().getPlayers()){ - SteamwarUser targetuser = SteamwarUser.get(target.getUniqueId()); - if (targetuser.getTeam() == user.getTeam() - && target.getChatMode() == ProxiedPlayer.ChatMode.SHOWN){ - Message.sendPrefixless("TC_FORMAT", target, player.getName(), ChatListener.parseAtMessage(msg, "§f", target)); - } - } + public void execute(CommandSender s, String[] args) { + ChatSender sender = ChatSender.of(s); + if(args.length == 0){ + sender.system("TC_USAGE"); + return; } + + SteamwarUser user = sender.user(); + if(user.getTeam() == 0){ + sender.system("TC_NO_TEAM"); + return; + } + + ChatListener.sendChat(sender, ChatSender.allReceivers().filter(player -> player.user().getTeam() == user.getTeam()), "CHAT_TEAM", null, String.join(" ", args)); } } diff --git a/src/de/steamwar/bungeecore/commands/TpCommand.java b/src/de/steamwar/bungeecore/commands/TpCommand.java index 39a46c74..801ed2c2 100644 --- a/src/de/steamwar/bungeecore/commands/TpCommand.java +++ b/src/de/steamwar/bungeecore/commands/TpCommand.java @@ -20,64 +20,100 @@ package de.steamwar.bungeecore.commands; import de.steamwar.bungeecore.*; -import de.steamwar.bungeecore.sql.*; +import de.steamwar.bungeecore.sql.BauweltMember; +import de.steamwar.bungeecore.sql.Event; +import de.steamwar.bungeecore.sql.Punishment; +import de.steamwar.bungeecore.sql.Team; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.CommandSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.config.ServerInfo; import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.ChatEvent; import java.util.ArrayList; -import java.util.Arrays; public class TpCommand extends BasicCommand { - public static void onTp(ChatEvent e, String[] command){ - if(!(e.getSender() instanceof ProxiedPlayer)) - return; - if(onTp((ProxiedPlayer) e.getSender(), Arrays.copyOfRange(command, 1, command.length))) - e.setCancelled(true); - } - public TpCommand(){ - super("join", null); + super("join", null, "tp", "teleport"); } @Override - public void execute(CommandSender sender, String[] args) { - if(!(sender instanceof ProxiedPlayer)) + public void execute(CommandSender s, String[] args) { + if(!(s instanceof ProxiedPlayer)) return; + ProxiedPlayer player = (ProxiedPlayer) s; - if(!onTp((ProxiedPlayer) sender, args)) - Message.send("TP_NOT_FOUND", sender); + 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(player, args[0]); + + //Give control of teleport command to server + if(server == null) { + player.chat("/tp " + String.join(" ", args)); + return; + } + + teleport(player, server); } @Override public Iterable onTabComplete(CommandSender commandSender, String[] args) { - if(args.length == 1){ - return allPlayers(args[0]); - } + if(args.length > 0) + return allPlayers(args[args.length - 1]); return new ArrayList<>(); } - private static boolean onTp(ProxiedPlayer player, String[] args){ - if(args.length == 0){ - if(Event.get() == null) - Message.send("TP_USAGE", player); - else - Message.send("TP_USAGE_EVENT", player); - return true; - }else if(CheckCommand.isChecking(player)){ - Message.send("CHECK_CHECKING", player); - return true; + 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; + 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 (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(ProxiedPlayer player, String arg) { + ServerInfo server = null; + //Get target player server - ServerInfo server = getTargetPlayer(args[0]); + 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(args[0]); + Team team = Team.get(arg); if(team != null){ Subserver eventArena = EventStarter.getEventServer().get(team.getTeamId()); if(eventArena != null && Subserver.getServerList().contains(eventArena)) @@ -85,63 +121,9 @@ public class TpCommand extends BasicCommand { } } - //Give control of teleport command to server - if(server == null || server == player.getServer().getInfo()) - return false; + if(server == player.getServer().getInfo()) + server = null; - // Check if player is allowed to join fights - Subserver subserver = Subserver.getSubserver(server); - if (subserver != null && subserver.getType() == Servertype.ARENA) { - SteamwarUser steamwarUser = SteamwarUser.get(player); - if (steamwarUser.isPunishedWithMessage(player, Punishment.PunishmentType.NoFightServer)) { - return true; - } - } - - teleport(player, server); - return true; - } - - private static ServerInfo getTargetPlayer(String playerName){ - SteamwarUser user = SteamwarUser.get(playerName); - if(user == null) - return null; - - ProxiedPlayer target = ProxyServer.getInstance().getPlayer(user.getUuid()); - if(target == null) - return null; - - Subserver subserver = Subserver.getSubserver(target); - if(subserver != null) - return subserver.getServer(); - - return target.getServer().getInfo(); - } - - private static void teleport(ProxiedPlayer player, ServerInfo server){ - String serverPerm = BungeeCore.serverPermissions.get(server.getName()); - Subserver subserver = Subserver.getSubserver(server); - - if(subserver != null) { - Servertype type = subserver.getType(); - if (type == Servertype.ARENA) { - SubserverSystem.sendPlayer(subserver, player); - } else if (type == Servertype.BAUSERVER) { - Bauserver bauserver = (Bauserver) subserver; - if (bauserver.getOwner().equals(player.getUniqueId()) || - BauweltMember.getBauMember(bauserver.getOwner(), player.getUniqueId()) != null) { - SubserverSystem.sendPlayer(subserver, player); - } else { - SubserverSystem.sendDeniedMessage(player, bauserver.getOwner()); - Message.send("JOIN_PLAYER_BLOCK", player); - } - } - }else if(serverPerm != null && !player.hasPermission(serverPerm)){ - Message.send("JOIN_PLAYER_BLOCK", player); - }else if(serverPerm == null && !player.getGroups().contains("team")) { - Message.send("JOIN_PLAYER_BLOCK", player); - }else{ - player.connect(server); - } + return server; } } diff --git a/src/de/steamwar/bungeecore/listeners/BanListener.java b/src/de/steamwar/bungeecore/listeners/BanListener.java index 17432646..43a104f8 100644 --- a/src/de/steamwar/bungeecore/listeners/BanListener.java +++ b/src/de/steamwar/bungeecore/listeners/BanListener.java @@ -24,6 +24,7 @@ import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.sql.BannedUserIPs; import de.steamwar.bungeecore.sql.Punishment; import de.steamwar.bungeecore.sql.SteamwarUser; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; @@ -47,7 +48,7 @@ public class BanListener extends BasicListener { if (user.isPunished(Punishment.PunishmentType.Ban)) { user.updateBanIP(event.getConnection().getAddress().getAddress().getHostAddress()); event.setCancelled(true); - event.setCancelReason(user.punishmentMessage(Punishment.PunishmentType.Ban, ProxyServer.getInstance().getPlayer(event.getConnection().getUniqueId()))); + ChatSender.of(event).system(user.punishmentMessage(Punishment.PunishmentType.Ban)); return; } diff --git a/src/de/steamwar/bungeecore/listeners/BrandListener.java b/src/de/steamwar/bungeecore/listeners/BrandListener.java index cbc16a41..4c810de6 100644 --- a/src/de/steamwar/bungeecore/listeners/BrandListener.java +++ b/src/de/steamwar/bungeecore/listeners/BrandListener.java @@ -35,13 +35,18 @@ public class BrandListener extends BasicListener { @EventHandler public void onServerSwitch(PluginMessageEvent event) { - if(!event.getTag().equals("minecraft:brand") || !event.getTag().equals("MC|Brand")) { + if(!event.getTag().equals("minecraft:brand") && !event.getTag().equals("MC|Brand")) { return; } if(event.getReceiver().getAddress().getHostName().contains("localhost")) { return; } + event.setCancelled(true); + + if (!(event.getReceiver() instanceof ProxiedPlayer)) { + return; + } BungeeCore.get().getProxy().getScheduler().schedule(BungeeCore.get(), () -> { ProxiedPlayer player = (ProxiedPlayer) event.getReceiver(); diff --git a/src/de/steamwar/bungeecore/listeners/ChatListener.java b/src/de/steamwar/bungeecore/listeners/ChatListener.java index f2ff5a1b..f5656776 100644 --- a/src/de/steamwar/bungeecore/listeners/ChatListener.java +++ b/src/de/steamwar/bungeecore/listeners/ChatListener.java @@ -1,7 +1,7 @@ /* This file is a part of the SteamWar software. - Copyright (C) 2020 SteamWar.de-Serverteam + 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 @@ -21,11 +21,10 @@ package de.steamwar.bungeecore.listeners; import de.steamwar.bungeecore.*; import de.steamwar.bungeecore.bot.SteamwarDiscordBot; -import de.steamwar.bungeecore.commands.TpCommand; import de.steamwar.bungeecore.comms.packets.PingPacket; import de.steamwar.bungeecore.sql.*; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.*; -import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.event.ChatEvent; import net.md_5.bungee.api.event.TabCompleteEvent; @@ -33,242 +32,181 @@ import net.md_5.bungee.api.event.TabCompleteResponseEvent; import net.md_5.bungee.api.scheduler.TaskScheduler; import net.md_5.bungee.event.EventHandler; -import java.sql.Timestamp; -import java.time.Instant; -import java.util.List; +import java.util.*; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; +import java.util.stream.Stream; public class ChatListener extends BasicListener { - private static final Title LIXFEL = ProxyServer.getInstance().createTitle().fadeIn(5).fadeOut(20).stay(30).title(TextComponent.fromLegacyText("§4§lLIXFEL")); - private static final Title YOYONOW = ProxyServer.getInstance().createTitle().fadeIn(5).fadeOut(20).stay(30).title(TextComponent.fromLegacyText("§4§lYOYONOW")); + private static final Set coloredTeams = new HashSet<>(); + static { + coloredTeams.add(12); + coloredTeams.add(54); + coloredTeams.add(285); + } @EventHandler - public void onChatEvent(ChatEvent e){ - if(e.getMessage().contains("jndi:ldap")) { + public void onChatEvent(ChatEvent e) { + if(!(e.getSender() instanceof ProxiedPlayer)) + return; + ProxiedPlayer player = (ProxiedPlayer) e.getSender(); + String message = e.getMessage(); + + if (message.contains("jndi:ldap")) { e.setCancelled(true); - SteamwarUser.get(((ProxiedPlayer) e.getSender()).getUniqueId()).punishPerma(Punishment.PunishmentType.Ban, "Versuchte Exploit-Ausnutzung", 0); + SteamwarUser.get(player).punishPerma(Punishment.PunishmentType.Ban, "Versuchte Exploit-Ausnutzung", 0); return; } - sanitize7(e); - if(e.getMessage().startsWith("/")) - onCommand(e); - else if(e.getMessage().startsWith("+")) - onPlusMessage(e); - else - onChat(e); - } + message = sanitize7(message); - /* - * Replaces 7(7)command to /(/)command. - * */ - private void sanitize7(ChatEvent e){ - String begin = e.getMessage().split(" ", 2)[0]; - if(begin.startsWith("7") && begin.substring(1).matches("[A-Za-z]+")){ - e.setMessage("/" + e.getMessage().substring(1)); - }else if(begin.startsWith("77") && begin.substring(2).matches("[A-Za-z]+")){ - e.setMessage("//" + e.getMessage().substring(2)); - }else if(begin.startsWith("7/") && begin.substring(2).matches("[A-Za-z]+")){ - e.setMessage("//" + e.getMessage().substring(2)); - }else if(begin.startsWith("/7") && begin.substring(2).matches("[A-Za-z]+")){ - e.setMessage("//" + e.getMessage().substring(2)); - } - } - - private void onCommand(ChatEvent e){ - String [] command = e.getMessage().split(" "); - if(command[0].contains(":")){ - if(e.getSender() instanceof ProxiedPlayer) - Message.send("UNKNOWN_COMMAND", (CommandSender) e.getSender()); - e.setCancelled(true); - return; - } - - switch(command[0].toLowerCase()){ - case "/bc": - case "/bauchat": - case "/local": - localChat(e, command); - break; - case "/tp": - TpCommand.onTp(e, command); - break; - default: - //do nothing, let the normal command handlers proceed - } - } - - private void lixfelAlert(ProxiedPlayer sender) { - LIXFEL.send(sender); - Message.send("CHAT_LIXFEL_ACTION_BAR", sender, ChatMessageType.ACTION_BAR); - TaskScheduler scheduler = ProxyServer.getInstance().getScheduler(); - scheduler.schedule(BungeeCore.get(), () -> Message.sendPrefixless("MSG_FORMAT", sender, "Lixfel", sender.getDisplayName(), Message.parse("CHAT_LIXFEL_1", sender)), 3, TimeUnit.SECONDS); - scheduler.schedule(BungeeCore.get(), () -> Message.sendPrefixless("MSG_FORMAT", sender, "Lixfel", sender.getDisplayName(), Message.parse("CHAT_LIXFEL_2", sender)), 6, TimeUnit.SECONDS); - scheduler.schedule(BungeeCore.get(), () -> Message.sendPrefixless("MSG_FORMAT", sender, "Lixfel", sender.getDisplayName(), Message.parse("CHAT_LIXFEL_3", sender)), 11, TimeUnit.SECONDS); - scheduler.schedule(BungeeCore.get(), () -> Message.sendPrefixless("MSG_FORMAT", sender, "Lixfel", sender.getDisplayName(), Message.parse("CHAT_LIXFEL_4", sender)), 12, TimeUnit.SECONDS); - scheduler.schedule(BungeeCore.get(), () -> Message.sendPrefixless("MSG_FORMAT", sender, "Lixfel", sender.getDisplayName(), Message.parse("CHAT_LIXFEL_5", sender)), 15, TimeUnit.SECONDS); - } - - private void yoyonowAlert(ProxiedPlayer sender) { - YOYONOW.send(sender); - Message.send("CHAT_LIXFEL_ACTION_BAR", sender, ChatMessageType.ACTION_BAR); - TaskScheduler scheduler = ProxyServer.getInstance().getScheduler(); - scheduler.schedule(BungeeCore.get(), () -> Message.sendPrefixless("MSG_FORMAT", sender, "YoyoNow", sender.getDisplayName(), Message.parse("CHAT_YOYONOW_1", sender)), 3, TimeUnit.SECONDS); - scheduler.schedule(BungeeCore.get(), () -> Message.sendPrefixless("MSG_FORMAT", sender, "YoyoNow", sender.getDisplayName(), Message.parse("CHAT_YOYONOW_2", sender)), 6, TimeUnit.SECONDS); - scheduler.schedule(BungeeCore.get(), () -> Message.sendPrefixless("MSG_FORMAT", sender, "YoyoNow", sender.getDisplayName(), Message.parse("CHAT_YOYONOW_3", sender)), 11, TimeUnit.SECONDS); - scheduler.schedule(BungeeCore.get(), () -> Message.sendPrefixless("MSG_FORMAT", sender, "YoyoNow", sender.getDisplayName(), Message.parse("CHAT_YOYONOW_4", sender)), 12, TimeUnit.SECONDS); - } - - private void onPlusMessage(ChatEvent e) { - ProxiedPlayer p = (ProxiedPlayer) e.getSender(); - Subserver subserver = Subserver.getSubserver(p); - if(subserver instanceof Bauserver) { - String[] smolArgs = e.getMessage().substring(1).split(" "); - String[] args = new String[smolArgs.length + 1]; - args[0] = ""; - System.arraycopy(smolArgs, 0, args, 1, smolArgs.length); - localChat(e, args); + if (message.startsWith("/")) { + if(filteredCommand((CommandSender) e.getSender(), message)) + e.setCancelled(true); } else { - onChat(e); - } - } - - private void onChat(ChatEvent e){ - if(e.getSender() instanceof ProxiedPlayer){ - ProxiedPlayer sender = (ProxiedPlayer) e.getSender(); - - if (e.getMessage().contains("LIXFEL")) - lixfelAlert(sender); - if (e.getMessage().contains("YOYONOW")) - yoyonowAlert(sender); - - if(sender.getChatMode() != ProxiedPlayer.ChatMode.SHOWN){ - Message.send("CHAT_RECEIVE", sender); - e.setCancelled(true); - return; - } - - SteamwarUser user = SteamwarUser.get(sender); - if (user.isPunishedWithMessage(sender, Punishment.PunishmentType.Mute)) { - e.setCancelled(true); - return; - } - - if(!sender.hasPermission(ConnectionListener.TEAM_GROUP) && (e.getMessage().contains("http:") || e.getMessage().contains("https:") || e.getMessage().contains("www."))){ - Message.send("CHAT_NO_LINKS", sender); - e.setCancelled(true); - return; - } - - Subserver subserver = Subserver.getSubserver(sender); - if(subserver != null && subserver.getType() == Servertype.ARENA && subserver.getServer() == sender.getServer().getInfo()) - return; - e.setCancelled(true); - ProxyServer.getInstance().getScheduler().runAsync(BungeeCore.get(), () -> publicChat(user, sender, e.getMessage())); - } - } - public static void discordChat(SteamwarUser user, String message){ - String name = "§r" + user.getUserName() + "§r"; - if (user.getUserGroup() != UserGroup.Member) { - name = user.getUserGroup().getColorCode() + user.getUserGroup().getChatPrefix() + " " + user.getUserName() + "§r"; - } - String chatcolor = user.getUserGroup().getChatColorCode(); - - if(user.getUserGroup() != UserGroup.Member || user.getTeam() == 12 || user.getTeam() == 285 || user.getTeam() == 54) - message = ChatColor.translateAlternateColorCodes('&', message); - - String msg = name + "§7»" + chatcolor + " " + message; - if(user.getTeam() != 0){ - Team team = Team.get(user.getTeam()); - msg = "§" + team.getTeamColor() + team.getTeamKuerzel() + " §r" + msg; - } - msg = "§7Discord §r" + msg; - - for(ProxiedPlayer target : ProxyServer.getInstance().getPlayers()){ - Subserver targetServer = Subserver.getSubserver(target); - if(!(targetServer == null || targetServer.getType() != Servertype.ARENA || targetServer.getServer() != target.getServer().getInfo())) continue; - - BungeeCore.send(target, ChatMessageType.CHAT, parseAtMessage(msg, chatcolor, target)); - } - } - - private void publicChat(SteamwarUser user, ProxiedPlayer sender, String message) { - String name = UserElo.getEmblem(user) + sender.getDisplayName(); - String chatcolor = user.getUserGroup().getChatColorCode(); - - if(user.getUserGroup() != UserGroup.Member || user.getTeam() == 12 || user.getTeam() == 285 || user.getTeam() == 54) - message = ChatColor.translateAlternateColorCodes('&', message); - - String msg = name + "§7»" + chatcolor + " " + message; - if(user.getTeam() != 0){ - Team team = Team.get(user.getTeam()); - msg = "§" + team.getTeamColor() + team.getTeamKuerzel() + " §r" + msg; - } - - if (SteamwarDiscordBot.instance() != null) { - try { - SteamwarDiscordBot.instance().getIngameChatListener().send(" " + msg.replaceAll("§[a-f0-9r]", "")); - } catch (Exception e) { - BungeeCore.get().getLogger().log(Level.SEVERE, "Could not send chat message to discord", e); + Subserver subserver = Subserver.getSubserver(player); + if(subserver != null && subserver.getType() == Servertype.ARENA && subserver.getServer() == player.getServer().getInfo()) { + localChat(player, message); + } else if (message.startsWith("+")) { + localChat(player, message.substring(1)); + } else { + sendChat(ChatSender.of(player), ChatSender.globalReceivers(), "CHAT_GLOBAL", null, message); } } - for(ProxiedPlayer target : ProxyServer.getInstance().getPlayers()){ - Subserver targetServer = Subserver.getSubserver(target); - if(!(targetServer == null || targetServer.getType() != Servertype.ARENA || targetServer.getServer() != target.getServer().getInfo())) continue; - - BungeeCore.send(target, ChatMessageType.CHAT, parseAtMessage(msg, chatcolor, target)); - } - BungeeCore.log(sender.getServer().getInfo(), msg); } - private void localChat(ChatEvent e, String [] command){ - ProxiedPlayer sender = (ProxiedPlayer) e.getSender(); - BungeeCore.log(sender, e.getMessage()); - if(command.length == 1){ - Message.send("CHAT_BC_USAGE", sender, command[0].substring(1)); - e.setCancelled(true); + public static void sendChat(ChatSender sender, Stream receivers, String format, ChatSender msgReceiver, String message) { + String finalMessage = modifyFilter(sender, message); + if(finalMessage == null) + return; + + SteamwarUser user = sender.user(); + + AtomicBoolean noReceiver = new AtomicBoolean(true); + receivers.filter(ChatSender::chatShown).forEach(player -> { + if(sender.user().getId() != player.user().getId()) + noReceiver.set(false); + chatToReciever(player, msgReceiver, user, format, finalMessage); + }); + + chatToReciever(ChatSender.console(), msgReceiver, user, format, finalMessage); + + if(format.equals("CHAT_GLOBAL")) { + if (SteamwarDiscordBot.instance() != null) + chatToReciever(ChatSender.discordChannel(SteamwarDiscordBot.instance().getIngameChatListener()), msgReceiver, user, format, finalMessage); + } else if (format.equals("CHAT_SERVERTEAM")) { + if (SteamwarDiscordBot.instance() != null) + chatToReciever(ChatSender.discordChannel(SteamwarDiscordBot.instance().getServerTeamChatListener()), msgReceiver, user, format, finalMessage); + } else if (noReceiver.get()) { + sender.system("CHAT_NO_RECEIVER"); + } + } + + public static void localChat(ProxiedPlayer player, String message) { + ChatSender sender = ChatSender.of(player); + if(message.length() == 0){ + sender.system("CHAT_BC_USAGE"); return; } - SteamwarUser user = SteamwarUser.get(sender); - if (user.isPunishedWithMessage(sender, Punishment.PunishmentType.Mute)) { - e.setCancelled(true); + message = sanitize7(message); + + if(ChatListener.filteredCommand(player, message)) return; + if(!message.startsWith("/")) { + message = modifyFilter(sender, message); + if(message == null) + return; } - if(command[1].startsWith("/") && command[1].contains(":")){ + player.chat(message); + } + + private static String modifyFilter(ChatSender sender, String message) { + if(!sender.chatShown()) { + sender.system("CHAT_RECEIVE"); + return null; + } + + SteamwarUser user = sender.user(); + UserGroup group = user.getUserGroup(); + if(!group.isTeamGroup() && (message.contains("http:") || message.contains("https:") || message.contains("www."))){ + sender.system("CHAT_NO_LINKS"); + return null; + } + + if (user.isPunishedWithMessage(sender, Punishment.PunishmentType.Mute)) + return null; + + if(group != UserGroup.Member || coloredTeams.contains(user.getTeam())) + message = ChatColor.translateAlternateColorCodes('&', message); + + if (message.contains("LIXFEL")) + specialAlert(sender, "Lixfel", "CHAT_LIXFEL_", 3, 6, 11, 12, 15); + if (message.contains("YOYONOW")) + specialAlert(sender, "YoyoNow", "CHAT_YOYONOW_", 3, 6, 11, 12); + + return message; + } + + private static void chatToReciever(ChatSender receiver, ChatSender msgReceiver, SteamwarUser sender, String format, String message) { + UserGroup group = sender.getUserGroup(); + receiver.chat(new Message(format, + sender, + msgReceiver == null ? receiver : msgReceiver, + highlightMentions(message, group.getChatColorCode(), receiver), + sender.getTeam() == 0 ? "" : "§" + Team.get(sender.getTeam()).getTeamColor() + Team.get(sender.getTeam()).getTeamKuerzel() + " ", + UserElo.getEmblem(sender), + group.getColorCode(), + group.getChatPrefix().length() == 0 ? "§f" : group.getChatPrefix() + " ", + group.getChatColorCode())); + } + + private static String sanitize7(String message) { + String begin = message.split(" ", 2)[0]; + if(begin.startsWith("7") && begin.substring(1).matches("[A-Za-z]+")){ + message = "/" + message.substring(1); + }else if((begin.startsWith("77") || begin.startsWith("7/") || begin.startsWith("/7")) && begin.substring(2).matches("[A-Za-z]+")){ + message = "//" + message.substring(2); + } + + return message; + } + + private static boolean filteredCommand(CommandSender sender, String message) { + String command = message.split(" ", 2)[0]; + if(command.startsWith("/") && command.contains(":")) { Message.send("UNKNOWN_COMMAND", sender); - e.setCancelled(true); - return; + return true; } - - e.setMessage(e.getMessage().substring(command[0].length() + 1)); + return false; } - public static String parseAtMessage(String message, String returnColor, ProxiedPlayer player) { - if(!message.contains("@")) { - return message; + private static void specialAlert(ChatSender sender, String name, String baseMessage, int... delay) { + sender.system("CHAT_LIXFEL_ACTION_BAR"); + TaskScheduler scheduler = ProxyServer.getInstance().getScheduler(); + for(int i = 0; i < delay.length; i++) { + int finalI = i; + scheduler.schedule(BungeeCore.get(), () -> sender.prefixless("MSG_FORMAT", name, sender.user(), new Message(baseMessage + (finalI+1))), delay[i], TimeUnit.SECONDS); } + } - StringBuilder builder = new StringBuilder(); - for (String curr : message.split(" ")) { - if(curr.toLowerCase().startsWith("@" + player.getName().toLowerCase())) { - new PingPacket(SteamwarUser.get(player).getId()).send(player); - builder.append("§e@") - .append(player.getName()) - .append(returnColor) - .append(curr.substring(player.getName().length() + 1)) - .append(" "); - }else { - builder.append(curr) - .append(" "); + private static String highlightMentions(String message, String returnColor, ChatSender player) { + if(!message.contains("@")) + return message; + + String mark = "@" + player.user().getUserName(); + return Arrays.stream(message.split(" ")).map(cur -> { + if(cur.equalsIgnoreCase(mark)) { + new PingPacket(player.user().getId()).send(player.user().getPlayer()); + return "§e" + cur + returnColor; } - } - return builder.toString(); + return cur; + }).collect(Collectors.joining(" ")); } @EventHandler diff --git a/src/de/steamwar/bungeecore/listeners/SubserverProtocolFixer.java b/src/de/steamwar/bungeecore/listeners/SubserverProtocolFixer.java new file mode 100644 index 00000000..b87c9603 --- /dev/null +++ b/src/de/steamwar/bungeecore/listeners/SubserverProtocolFixer.java @@ -0,0 +1,63 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.bungeecore.listeners; + +import io.github.waterfallmc.waterfall.utils.UUIDUtils; +import net.md_5.bungee.BungeeCord; +import net.md_5.bungee.api.event.LoginEvent; +import net.md_5.bungee.connection.InitialHandler; +import net.md_5.bungee.connection.LoginResult; +import net.md_5.bungee.event.EventHandler; +import net.md_5.bungee.util.AddressUtil; + +import java.lang.reflect.Field; +import java.net.InetSocketAddress; +import java.util.logging.Level; + +public class SubserverProtocolFixer extends BasicListener { + + private final InetSocketAddress inetSocketAddress = new InetSocketAddress("127.127.127.127", 25565); + + private Field field; + + { + try { + field = InitialHandler.class.getDeclaredField("extraDataInHandshake"); + field.setAccessible(true); + } catch (NoSuchFieldException e) { + BungeeCord.getInstance().getLogger().log(Level.SEVERE, e.getMessage(), e); + } + } + + @EventHandler + public void loginEvent(LoginEvent e) { + InitialHandler initialHandler = ((InitialHandler) e.getConnection()); + LoginResult.Property[] properties = initialHandler.getLoginProfile().getProperties(); + try { + String extraData = "\00" + AddressUtil.sanitizeAddress(inetSocketAddress) + "\00" + UUIDUtils.undash(initialHandler.getUniqueId().toString()); + if (properties.length > 0) { + extraData += "\00" + BungeeCord.getInstance().gson.toJson(properties); + } + field.set(initialHandler, extraData); + } catch (IllegalAccessException ex) { + BungeeCord.getInstance().getLogger().log(Level.SEVERE, ex.getMessage(), ex); + } + } +} diff --git a/src/de/steamwar/bungeecore/sql/SteamwarUser.java b/src/de/steamwar/bungeecore/sql/SteamwarUser.java index f3a6764c..1cd6d8aa 100644 --- a/src/de/steamwar/bungeecore/sql/SteamwarUser.java +++ b/src/de/steamwar/bungeecore/sql/SteamwarUser.java @@ -24,8 +24,8 @@ import de.steamwar.bungeecore.BungeeCore; import de.steamwar.bungeecore.Message; import de.steamwar.bungeecore.commands.WebregisterCommand; import de.steamwar.bungeecore.listeners.ConnectionListener; +import de.steamwar.messages.ChatSender; import net.md_5.bungee.api.ProxyServer; -import net.md_5.bungee.api.chat.TextComponent; import net.md_5.bungee.api.connection.PendingConnection; import net.md_5.bungee.api.connection.ProxiedPlayer; @@ -36,7 +36,6 @@ import java.net.UnknownHostException; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Timestamp; -import java.time.format.DateTimeFormatter; import java.util.*; import java.util.logging.Level; import java.util.stream.Collectors; @@ -258,6 +257,10 @@ public class SteamwarUser { return team; } + public ProxiedPlayer getPlayer() { + return ProxyServer.getInstance().getPlayer(uuid); + } + public Punishment getPunishment(Punishment.PunishmentType type) { return punishments.getOrDefault(type, null); } @@ -289,11 +292,11 @@ public class SteamwarUser { return true; } - public boolean isPunishedWithMessage(ProxiedPlayer player, Punishment.PunishmentType punishment) { + public boolean isPunishedWithMessage(ChatSender player, Punishment.PunishmentType punishment) { if (!isPunished(punishment)) { return false; } - player.sendMessage(punishmentMessage(punishment, player)); + player.system(punishmentMessage(punishment)); return true; } @@ -312,7 +315,7 @@ public class SteamwarUser { ProxiedPlayer player = ProxyServer.getInstance().getPlayer(uuid); if (player != null) { updateBanIP(player.getAddress().getAddress().getHostAddress()); - player.disconnect(punishmentMessage(punishment, player)); + ChatSender.disconnect(player).system(punishmentMessage(punishment)); for (BannedUserIPs banned : BannedUserIPs.get(player.getAddress().getAddress().getHostAddress())) { SteamwarUser bannedUser = SteamwarUser.get(banned.getUserID()); if (isPunished(punishment) && bannedUser.getPunishment(punishment).getEndTime().before(time)) { @@ -324,12 +327,12 @@ public class SteamwarUser { } } - public TextComponent punishmentMessage(Punishment.PunishmentType punishment, ProxiedPlayer player) { + public Message punishmentMessage(Punishment.PunishmentType punishment) { Punishment currentPunishment = punishments.get(punishment); if (currentPunishment.isPerma()) { - return BungeeCore.stringToText(Message.parsePrefixed(punishment.getPlayerMessagePerma(), player, currentPunishment.getReason())); + return new Message(punishment.getPlayerMessagePerma(), currentPunishment.getReason()); } else { - return BungeeCore.stringToText(Message.parsePrefixed(punishment.getPlayerMessageUntil(), player, currentPunishment.getEndTime().toLocalDateTime().format(DateTimeFormatter.ofPattern(Message.parse("TIMEFORMAT", player))), currentPunishment.getReason())); + return new Message(punishment.getPlayerMessageUntil(), currentPunishment.getEndTime(), currentPunishment.getReason()); } } diff --git a/src/de/steamwar/bungeecore/sql/Team.java b/src/de/steamwar/bungeecore/sql/Team.java index be3bbec1..b00a64f4 100644 --- a/src/de/steamwar/bungeecore/sql/Team.java +++ b/src/de/steamwar/bungeecore/sql/Team.java @@ -29,7 +29,7 @@ public class Team { private static final Statement insert = new Statement("INSERT INTO Team (TeamKuerzel, TeamName) VALUES (?, ?)"); private static final Statement delete = new Statement("UPDATE Team SET TeamDeleted = 1 WHERE TeamID = ?"); - private static final Statement update = new Statement("INSERT INTO Team (TeamID, TeamKuerzel, TeamName, TeamColor) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE TeamName = VALUES(TeamName), TeamKuerzel = VALUES(TeamKuerzel), TeamColor = VALUES(TeamColor)"); + private static final Statement update = new Statement("INSERT INTO Team (TeamID, TeamKuerzel, TeamName, TeamColor, Address, Port) VALUES (?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE TeamName = VALUES(TeamName), TeamKuerzel = VALUES(TeamKuerzel), TeamColor = VALUES(TeamColor), Address = VALUES(Address), Port = VALUES(Port)"); private static final Statement getSize = new Statement("SELECT COUNT(id) FROM UserData WHERE Team = ?"); private static final Statement getMembers = new Statement("SELECT id FROM UserData WHERE Team = ?"); private static final Statement byId = new Statement("SELECT * FROM Team WHERE TeamID = ?"); @@ -37,14 +37,16 @@ public class Team { private static final Statement all = new Statement("SELECT * FROM Team WHERE NOT TeamDeleted"); private static final List teamCache = new LinkedList<>(); - private static final Team pub = new Team(0, "PUB", "Öffentlich", "8"); + private static final Team pub = new Team(0, "PUB", "Öffentlich", "8", null, 25565); private final int teamId; private String teamKuerzel; private String teamName; private String teamColor; + private String address; + private int port; - private Team(int id, String kuerzel, String name, String color){ + private Team(int id, String kuerzel, String name, String color, String address, int port){ teamId = id; teamKuerzel = kuerzel; teamName = name; @@ -52,10 +54,12 @@ public class Team { if (id != 0) { teamCache.add(this); } + this.address = address; + this.port = port; } private Team(ResultSet rs) throws SQLException { - this(rs.getInt("TeamID"), rs.getString("TeamKuerzel"), rs.getString("TeamName"), rs.getString("TeamColor")); + this(rs.getInt("TeamID"), rs.getString("TeamKuerzel"), rs.getString("TeamName"), rs.getString("TeamColor"), rs.getString("Address"), rs.getInt("Port")); } public static void create(String kuerzel, String name){ @@ -64,7 +68,7 @@ public class Team { public static Team get(int id){ if(id == -1) - return new Team(-1, "?", "?", "8"); + return new Team(-1, "?", "?", "8", null, 25565); if(id == 0) return pub; for(Team team : teamCache) @@ -101,7 +105,7 @@ public class Team { } private void updateDB(){ - update.update(teamId, teamKuerzel, teamName, teamColor); + update.update(teamId, teamKuerzel, teamName, teamColor, address, port); } public int getTeamId() { @@ -135,6 +139,24 @@ public class Team { updateDB(); } + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + updateDB(); + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + updateDB(); + } + public int size(){ return getSize.select(rs -> { rs.next(); diff --git a/src/de/steamwar/messages/BungeeCore.properties b/src/de/steamwar/messages/BungeeCore.properties index aa79d1a3..4546f4d6 100644 --- a/src/de/steamwar/messages/BungeeCore.properties +++ b/src/de/steamwar/messages/BungeeCore.properties @@ -1,6 +1,7 @@ PREFIX=§eSteam§8War» SPACER= -TIMEFORMAT=HH:mm dd.MM.yyyy +TIMEFORMAT=dd.MM.yyyy HH:mm +PLAIN_STRING={0} UNKNOWN_COMMAND=§cUnbekannter Befehl. UNKNOWN_PLAYER=§cDiesen Spieler gibt es nicht. @@ -294,11 +295,8 @@ KICK_NORMAL=§cDu wurdest gekickt. #MsgCommand MSG_USAGE=§8/§7msg §8[§eBenutzer§8] [§eNachricht§8] -MSG_OFFLINE=§cDieser Spieler ist derzeit nicht online! +MSG_OFFLINE=§cKein Gesprächspartner verfügbar! MSG_IGNORED=§cDieser Spieler hat dich geblockt! -MSG_NOMESSAGE=§cDieser Spieler empfängt derzeit keine Chatnachrichten! -MSG_SELF=§cNachrichten an dich selbst hast du wirklich nicht nötig! -MSG_FORMAT=§e{0}§8»§e{1} §r§7{2} #PingCommand PING_RESPONSE=§7Dein Ping beträgt §c{0}§7 ms! @@ -311,10 +309,6 @@ POLL_ANSWER_NEW=§aDeine Antwort wurde registriert. #RCommand R_USAGE=§8/§7r §8[§eAntwort§8] -R_NOTHING=§cDu hast bisher mit niemandem geschrieben! -R_OFFLINE=§cDieser Spieler ist derzeit nicht online! -R_BLOCKED=§cDieser Spieler hat dich geblockt! -R_NO_CHAT=§cDieser Spieler empfängt derzeit keine Chatnachrichten! #RegelnCommand REGELN_RULES=§7§lRegelwerke @@ -356,12 +350,10 @@ TUTORIAL_OWN_HELP=§8/§7tutorial own §8- §7Liste der eigenen Tutorials #ServerTeamchatCommand STC_USAGE=§8/§7stc §8[§eNachricht an das Team§8] -STC_FORMAT=§8STC §e{0}» §r{1} #TeamchatCommand TC_USAGE=§8/§7tc §8[§eNachricht an das Team§8] TC_NO_TEAM=§cDu bist in keinem Team. -TC_FORMAT=§8TC §e{0}§8» §r{1} #TeamCommand TEAM_IN_TEAM=§cDu bist bereits in einem Team. @@ -371,6 +363,7 @@ TEAM_NOT_IN_EVENT=§cDies ist während eines Events nicht möglich. TEAM_HELP_HEADER=§7Mit §e/team §7verwaltest du dein Team. TEAM_HELP_LIST=§8/§7team list §8- §7Liste alle Teams auf. TEAM_HELP_INFO=§8/§7team info §8- §7Informiere dich über ein Team. +TEAM_HELP_TP=§8/§7team tp §8(§7Team§8) §8- §7Teleportiert zum Teamserver. TEAM_HELP_CREATE=§8/§7team create §8- §7Erstelle dein eigenes Team. TEAM_HELP_JOIN=§8/§7team join §8- §7Trete einem Team bei. TEAM_HELP_CHAT=§8/§7teamchat §8- §7Sende Nachrichten an dein Team. @@ -383,6 +376,7 @@ TEAM_HELP_NAME=§8/§7team changename §8- §7Ändere deinen Teamnamen. TEAM_HELP_COLOR=§8/§7team changecolor §8- §7Ändere deine Teamfarbe. TEAM_HELP_LEADER=§8/§7team promote §8- §7Ernenne jemanden zum Teamleader. TEAM_HELP_STEP_BACK=§8/§7team stepback §8- §7Tritt als Leader zurück. +TEAM_HELP_SERVER=§8/§7team server §8[§eIP/Adresse§8] §8(§7Port§8) §8- §7Setzt Adresse des Teamservers. #Team Create TEAM_CREATE_USAGE=§8/§7team create §8[§eTeamkürzel§8] §8[§eTeamname§8] @@ -468,10 +462,16 @@ TEAM_EVENT_HOW_TO_LEAVE=§7Um die Teilnahme abzusagen, wiederhole den Befehl #Team Color TEAM_COLOR_TITLE=Farbe wählen +#Team Server +TEAM_SERVER_USAGE=§8/§7team server §8[§eIP/Adresse§8] §8(§7Port§8) §8- §7Setzt Adresse des Teamservers. +TEAM_SERVER_SET=§7Du hast die Teamserveradresse geändert§8! +TEAM_SERVER_PORT_INVALID=§cUnmögliche Portnummer. +TEAM_NO_ADDRESS=§cTeamserveradresse nicht gesetzt. +TEAM_TP_NO_TEAM=§cUnbekanntes Team. + #TpCommand TP_USAGE=§8/§7tp §8[§eSpieler§8] TP_USAGE_EVENT=§8/§7tp §8[§eSpieler §7oder §eTeam§8] -TP_NOT_FOUND=§cKonnte das angegebene Ziel nicht finden. #UnignoreCommand UNIGNORE_USAGE=§8/§7unignore §8[§eSpieler§8] @@ -492,7 +492,7 @@ WEB_EMAIL_SEND=§aEine E-Mail zum Setzen des Passworts wurde gesendet. CHAT_LIXFEL_ACTION_BAR=§4§lTechnische Probleme? CHAT_LIXFEL_1=Du hast mich gerufen! CHAT_LIXFEL_2=Leider bin ich nur ein Mensch und höre nicht alles. -CHAT_LIXFEL_3=Daher bitte ich dich, das Problem bzw. den Fehler im Forum in der Kategorie §eFehler melden §cmit einer ausreichenden Beschreibung zu hinterlegen. +CHAT_LIXFEL_3=Daher bitte ich dich, das Problem bzw. den Fehler im Forum in der Kategorie §eFehler melden §7mit einer ausreichenden Beschreibung zu hinterlegen. CHAT_LIXFEL_4=Vielen Dank. CHAT_LIXFEL_5=Ich wünsche dir noch weiterhin ein reibungsloses Spielerlebnis. CHAT_YOYONOW_1=Du hast mich gerufen! @@ -501,7 +501,14 @@ CHAT_YOYONOW_3=Vielen Dank. CHAT_YOYONOW_4=Ich wünsche dir noch weiterhin ein reibungsloses Spielerlebnis. CHAT_RECEIVE=§cUm Chatnachrichten versenden zu können, musst du auch welche empfangen! CHAT_NO_LINKS=§cDu darfst keine Links versenden. -CHAT_BC_USAGE=§8/§e{0} §8[§7Nachricht§8] +CHAT_BC_USAGE=§8/§7bc §8[§eNachricht§8] +CHAT_NO_RECEIVER=§cNiemand empfängt deine Nachricht + +CHAT_SERVERTEAM=§8STC §e{0}§8» §f{2} +CHAT_GLOBAL={3}{4}{5}{6}{0}§8» {7}{2} +CHAT_DISCORD_GLOBAL=§8Dc {5}{6}{0}§8» {7}{2} +CHAT_TEAM=§8TC §e{0}§8» §f{2} +CHAT_MSG=§e{0}§8»§e{1} §7{2} #CheckListner CHECK_UNCHECKED=§7Du hast noch §e{0} §7ungeprüfte Schematic§8(§7s§8)! diff --git a/src/de/steamwar/messages/ChatSender.java b/src/de/steamwar/messages/ChatSender.java new file mode 100644 index 00000000..de805415 --- /dev/null +++ b/src/de/steamwar/messages/ChatSender.java @@ -0,0 +1,290 @@ +/* + 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 . +*/ + +package de.steamwar.messages; + +import de.steamwar.bungeecore.*; +import de.steamwar.bungeecore.bot.listeners.DiscordChatListener; +import de.steamwar.bungeecore.sql.SteamwarUser; +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.BaseComponent; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.hover.content.Text; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.LoginEvent; +import net.md_5.bungee.command.ConsoleCommandSender; + +import java.text.DateFormat; +import java.text.MessageFormat; +import java.util.Date; +import java.util.Locale; +import java.util.ResourceBundle; +import java.util.function.BiConsumer; +import java.util.logging.Level; +import java.util.stream.Stream; + +public interface ChatSender { + + static Stream all() { + return ProxyServer.getInstance().getPlayers().stream(); + } + + static Stream allReceivers() { + return all().map(ChatSender::of); + } + + static Stream globalReceivers() { + return all().filter(player -> { + Subserver subserver = Subserver.getSubserver(player); + return subserver == null || !(subserver.getType() == Servertype.ARENA && subserver.getServer() == player.getServer().getInfo()); + }).map(ChatSender::of); + } + + static Stream serverteamReceivers() { + return allReceivers().filter(player -> player.user().getUserGroup().isTeamGroup()); + } + + SteamwarUser user(); + + Locale getLocale(); + boolean chatShown(); + void sendMessage(ChatMessageType type, BaseComponent... msg); + + default void chat(Message message) { + send(false, ChatMessageType.CHAT, null, null, message); + } + + default void system(String format, Object... params) { + system(new Message(format, params)); + } + + default void system(Message message) { + send(true, ChatMessageType.SYSTEM, null, null, message); + } + + default void system(String format, Message onHover, ClickEvent onClick, Object... params) { + send(true, ChatMessageType.SYSTEM, onHover, onClick, new Message(format, params)); + } + + default void prefixless(String format, Object... params) { + prefixless(format, null, null, params); + } + + default void prefixless(String format, Message onHover, ClickEvent onClick, Object... params) { + send(false, ChatMessageType.SYSTEM, onHover, onClick, new Message(format, params)); + } + + default void send(boolean prefixed, ChatMessageType type, Message onHover, ClickEvent onClick, Message message) { + TextComponent msg = parseToComponent(prefixed, message); + if(onHover != null) + msg.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text(parse(false, onHover)))); + if(onClick != null) + msg.setClickEvent(onClick); + sendMessage(type, msg); + } + + default TextComponent parseToComponent(boolean prefixed, Message message) { + return new TextComponent(parse(prefixed, message)); + } + + default String parseToLegacy(String format, Object... params) { + return parseToLegacy(new Message(format, params)); + } + + default String parseToLegacy(Message message) { + return parseToComponent(false, message).toLegacyText(); + } + + default BaseComponent[] parse(boolean prefixed, Message message) { + Locale locale = getLocale(); + ResourceBundle resourceBundle = SteamwarResourceBundle.getResourceBundle(locale); + String pattern = ""; + if(prefixed) + pattern = resourceBundle.getObject("PREFIX") + " "; + pattern += (String)resourceBundle.getObject(message.getFormat()); + + MessageFormat format = new MessageFormat(pattern, locale); + Object[] params = message.getParams(); + for (int i = 0; i < params.length; i++) { + if(params[i] instanceof Message) { + params[i] = parseToLegacy((Message) params[i]); + } else if(params[i] instanceof Date) { + params[i] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale).format((Date) params[i]); + } else if(params[i] instanceof SteamwarUser) { + params[i] = ((SteamwarUser) params[i]).getUserName(); + } else if(params[i] instanceof ProxiedPlayer) { + params[i] = ((ProxiedPlayer) params[i]).getName(); + } else if(params[i] instanceof ChatSender) { + params[i] = ((ChatSender) params[i]).user().getUserName(); + } + } + return TextComponent.fromLegacyText(format.format(params)); + } + + static ChatSender ofProxiedPlayer(ProxiedPlayer player, BiConsumer sendMessage) { + return new ChatSender() { + @Override + public SteamwarUser user() { + return SteamwarUser.get(player.getUniqueId()); + } + + @Override + public Locale getLocale() { + Locale locale = player.getLocale(); + if(locale == null) + locale = Locale.getDefault(); + return locale; + } + + @Override + public boolean chatShown() { + return player.getChatMode() == ProxiedPlayer.ChatMode.SHOWN; + } + + @Override + public void sendMessage(ChatMessageType type, BaseComponent... msg) { + sendMessage.accept(type, msg); + } + }; + } + + static ChatSender of(ProxiedPlayer player) { + return ofProxiedPlayer(player, player::sendMessage); + } + + static ChatSender disconnect(ProxiedPlayer player) { + return ofProxiedPlayer(player, (type, msg) -> player.disconnect(msg)); + } + + static ChatSender of(CommandSender sender) { + if(sender instanceof ProxiedPlayer) + return of((ProxiedPlayer) sender); + + //Console + return new ChatSender() { + @Override + public SteamwarUser user() { + return SteamwarUser.get(-1); + } + + @Override + public Locale getLocale() { + return Locale.getDefault(); + } + + @Override + public boolean chatShown() { + return true; + } + + @Override + public void sendMessage(ChatMessageType type, BaseComponent... msg) { + sender.sendMessage(msg); + } + }; + } + + static ChatSender console() { + return of(ConsoleCommandSender.getInstance()); + } + + static ChatSender of(LoginEvent event) { + return new ChatSender() { + @Override + public SteamwarUser user() { + return SteamwarUser.get(event.getConnection().getUniqueId()); + } + + @Override + public Locale getLocale() { + return Locale.getDefault(); + } + + @Override + public boolean chatShown() { + return false; + } + + @Override + public void sendMessage(ChatMessageType type, BaseComponent... msg) { + event.setCancelReason(msg); + } + }; + } + + static ChatSender discordChannel(DiscordChatListener channel) { + return new ChatSender() { + @Override + public SteamwarUser user() { + return SteamwarUser.get(-1); + } + + @Override + public Locale getLocale() { + return Locale.getDefault(); + } + + @Override + public boolean chatShown() { + return true; + } + + @Override + public void sendMessage(ChatMessageType type, BaseComponent... msg) { + try { + channel.send(" " + new TextComponent(msg).toPlainText()); + } catch (Exception e) { + BungeeCore.get().getLogger().log(Level.SEVERE, "Could not send chat message to discord", e); + } + } + }; + } + + static ChatSender of(net.dv8tion.jda.api.entities.Message message, SteamwarUser user) { + return new ChatSender() { + @Override + public SteamwarUser user() { + return user; + } + + @Override + public Locale getLocale() { + return Locale.getDefault(); + } + + @Override + public boolean chatShown() { + return true; + } + + @Override + public void sendMessage(ChatMessageType type, BaseComponent... msg) { + try { + message.delete().queue(); + } catch (Exception e) { + BungeeCore.get().getLogger().log(Level.SEVERE, "Could not send chat reply to discord user", e); + } + } + }; + } +} diff --git a/src/de/steamwar/messages/SteamwarResourceBundle.java b/src/de/steamwar/messages/SteamwarResourceBundle.java new file mode 100644 index 00000000..c2e71ab1 --- /dev/null +++ b/src/de/steamwar/messages/SteamwarResourceBundle.java @@ -0,0 +1,55 @@ +/* + 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 . +*/ + +package de.steamwar.messages; + +import de.steamwar.bungeecore.Message; + +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + +public class SteamwarResourceBundle extends PropertyResourceBundle { + + private static final String BASE_PATH = "/" + "de.steamwar.messages.BungeeCore".replace('.', '/'); + + private static final Map bundles = new HashMap<>(); + + public static ResourceBundle getResourceBundle(Locale locale) { + return getResourceBundle(locale.toString(), getResourceBundle(locale.getLanguage(), getResourceBundle( "", null))); + } + + private static ResourceBundle getResourceBundle(String locale, ResourceBundle parent) { + return bundles.computeIfAbsent(locale, locale1 -> { + InputStream inputStream = Message.class.getResourceAsStream(BASE_PATH + ("".equals(locale) ? "" : "_" + locale) + ".properties"); + if(inputStream == null) + return parent; + try { + return new SteamwarResourceBundle(inputStream, parent); + } catch (IOException e) { + return parent; + } + }); + } + + private SteamwarResourceBundle(InputStream stream, ResourceBundle parent) throws IOException { + super(stream); + setParent(parent); + } +} diff --git a/steamwarci.yml b/steamwarci.yml index 432a095c..21e3e3ef 100644 --- a/steamwarci.yml +++ b/steamwarci.yml @@ -1,6 +1,7 @@ build: - "ln -s /home/gitea/lib" - - "mvn package -B" + - "cp ~/gradle.properties ." + - "./gradlew buildProject" artifacts: - "/binarys/bungeecore.jar": "target/bungeecore.jar" + "/binarys/bungeecore.jar": "build/libs/bungeecore.jar"