Dieser Commit ist enthalten in:
Commit
3b640f99d3
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
lib
|
lib
|
||||||
.idea
|
.idea
|
||||||
target
|
target
|
||||||
|
dependency-reduced-pom.xml
|
@ -24,10 +24,7 @@ import de.steamwar.bungeecore.bot.config.SteamwarDiscordBotConfig;
|
|||||||
import de.steamwar.bungeecore.commands.*;
|
import de.steamwar.bungeecore.commands.*;
|
||||||
import de.steamwar.bungeecore.comms.SpigotReceiver;
|
import de.steamwar.bungeecore.comms.SpigotReceiver;
|
||||||
import de.steamwar.bungeecore.listeners.*;
|
import de.steamwar.bungeecore.listeners.*;
|
||||||
import de.steamwar.bungeecore.listeners.mods.Forge;
|
import de.steamwar.bungeecore.listeners.mods.*;
|
||||||
import de.steamwar.bungeecore.listeners.mods.LabyMod;
|
|
||||||
import de.steamwar.bungeecore.listeners.mods.ModLoaderBlocker;
|
|
||||||
import de.steamwar.bungeecore.listeners.mods.WorldDownloader;
|
|
||||||
import de.steamwar.bungeecore.sql.Punishment;
|
import de.steamwar.bungeecore.sql.Punishment;
|
||||||
import de.steamwar.bungeecore.sql.Statement;
|
import de.steamwar.bungeecore.sql.Statement;
|
||||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||||
@ -80,7 +77,9 @@ public class BungeeCore extends Plugin {
|
|||||||
errorLogger = new ErrorLogger();
|
errorLogger = new ErrorLogger();
|
||||||
new ConnectionListener();
|
new ConnectionListener();
|
||||||
new Forge();
|
new Forge();
|
||||||
|
new Forge12();
|
||||||
new LabyMod();
|
new LabyMod();
|
||||||
|
new Badlion();
|
||||||
new ChatListener();
|
new ChatListener();
|
||||||
new BanListener();
|
new BanListener();
|
||||||
new CheckListener();
|
new CheckListener();
|
||||||
@ -127,6 +126,8 @@ public class BungeeCore extends Plugin {
|
|||||||
new VerifyCommand();
|
new VerifyCommand();
|
||||||
new ReplayCommand();
|
new ReplayCommand();
|
||||||
new GDPRQuery();
|
new GDPRQuery();
|
||||||
|
new PlaytimeCommand();
|
||||||
|
new ArenaCommand();
|
||||||
|
|
||||||
// Punishment Commands:
|
// Punishment Commands:
|
||||||
new PunishmentCommand("ban", Punishment.PunishmentType.Ban);
|
new PunishmentCommand("ban", Punishment.PunishmentType.Ban);
|
||||||
|
@ -91,6 +91,7 @@ public class ErrorLogger extends Handler {
|
|||||||
contains.add("DownstreamBridge");
|
contains.add("DownstreamBridge");
|
||||||
contains.add(" took ");
|
contains.add(" took ");
|
||||||
contains.add("No client connected for pending server!");
|
contains.add("No client connected for pending server!");
|
||||||
|
contains.add("Error authenticating ");
|
||||||
ignoreContains = Collections.unmodifiableList(contains);
|
ignoreContains = Collections.unmodifiableList(contains);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,24 +44,28 @@ public class Message {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public static TextComponent parseToComponent(String message, boolean prefixed, CommandSender sender, Object... params){
|
public static TextComponent parseToComponent(String message, boolean prefixed, CommandSender sender, Object... params){
|
||||||
return new TextComponent(TextComponent.fromLegacyText(parse(message, prefixed, sender, params)));
|
return new TextComponent(TextComponent.fromLegacyText(parse(message, prefixed, locale(sender), params)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String parsePrefixed(String message, CommandSender sender, Object... params){
|
public static String parsePrefixed(String message, CommandSender sender, Object... params){
|
||||||
return parse(message, true, sender, params);
|
return parse(message, true, locale(sender), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String parse(String message, CommandSender sender, Object... params){
|
public static String parse(String message, CommandSender sender, Object... params){
|
||||||
return parse(message, false, sender, params);
|
return parse(message, false, locale(sender), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String parse(String message, boolean prefixed, CommandSender sender, Object... params){
|
public static String parse(String message, Locale locale, Object... params){
|
||||||
Locale locale = null;
|
return parse(message, false, locale, params);
|
||||||
if(sender instanceof ProxiedPlayer)
|
}
|
||||||
locale = ((ProxiedPlayer)sender).getLocale();
|
|
||||||
|
private static Locale locale(CommandSender sender) {
|
||||||
|
return sender instanceof ProxiedPlayer ? ((ProxiedPlayer)sender).getLocale() : Locale.getDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String parse(String message, boolean prefixed, Locale locale, Object... params){
|
||||||
if(locale == null)
|
if(locale == null)
|
||||||
locale = Locale.getDefault();
|
locale = Locale.getDefault();
|
||||||
|
|
||||||
ResourceBundle resourceBundle = ResourceBundle.getBundle("de.steamwar.messages.BungeeCore", locale, CONTROL);
|
ResourceBundle resourceBundle = ResourceBundle.getBundle("de.steamwar.messages.BungeeCore", locale, CONTROL);
|
||||||
String pattern = "";
|
String pattern = "";
|
||||||
if(prefixed)
|
if(prefixed)
|
||||||
@ -72,7 +76,7 @@ public class Message {
|
|||||||
for (int i = 0; i < params.length; i++) {
|
for (int i = 0; i < params.length; i++) {
|
||||||
if(params[i] instanceof Message) {
|
if(params[i] instanceof Message) {
|
||||||
Message msg = (Message) params[i];
|
Message msg = (Message) params[i];
|
||||||
params[i] = parse(msg.getMessage(), sender, msg.getParams());
|
params[i] = parse(msg.getMessage(), false, locale, msg.getParams());
|
||||||
} else if(params[i] instanceof Date) {
|
} else if(params[i] instanceof Date) {
|
||||||
params[i] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale).format((Date) params[i]);
|
params[i] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale).format((Date) params[i]);
|
||||||
}
|
}
|
||||||
@ -120,7 +124,7 @@ public class Message {
|
|||||||
|
|
||||||
public static void broadcast(String message, String onHover, ClickEvent onClick, Object... params){
|
public static void broadcast(String message, String onHover, ClickEvent onClick, Object... params){
|
||||||
for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers())
|
for(ProxiedPlayer player : ProxyServer.getInstance().getPlayers())
|
||||||
send(message, player, parse(onHover, false, player, params), onClick, params);
|
send(message, player, parse(onHover, player, params), onClick, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void broadcast(String message, Object... params){
|
public static void broadcast(String message, Object... params){
|
||||||
|
@ -22,10 +22,7 @@ package de.steamwar.bungeecore;
|
|||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -34,6 +31,14 @@ public abstract class Node {
|
|||||||
|
|
||||||
private static final List<String> OPENJ9_ARGS = Arrays.asList("-Xgc:excessiveGCratio=80", "-Xsyslog:none", "-Xtrace:none", "-Xdisableexplicitgc", "-XX:+AlwaysPreTouch", "-XX:+CompactStrings", "-XX:-HeapDumpOnOutOfMemory", "-XX:+ExitOnOutOfMemoryError", "-Dlog4j.configurationFile=log4j2.xml");
|
private static final List<String> OPENJ9_ARGS = Arrays.asList("-Xgc:excessiveGCratio=80", "-Xsyslog:none", "-Xtrace:none", "-Xdisableexplicitgc", "-XX:+AlwaysPreTouch", "-XX:+CompactStrings", "-XX:-HeapDumpOnOutOfMemory", "-XX:+ExitOnOutOfMemoryError", "-Dlog4j.configurationFile=log4j2.xml");
|
||||||
private static final double MIN_FREE_MEM = 4.0 * 1024 * 1024; // 4 GiB
|
private static final double MIN_FREE_MEM = 4.0 * 1024 * 1024; // 4 GiB
|
||||||
|
private static final Set<String> JAVA_8 = new HashSet<>();
|
||||||
|
static {
|
||||||
|
JAVA_8.add("paper-1.8.8.jar");
|
||||||
|
JAVA_8.add("paper-1.10.2.jar");
|
||||||
|
JAVA_8.add("spigot-1.8.8.jar");
|
||||||
|
JAVA_8.add("spigot-1.9.4.jar");
|
||||||
|
JAVA_8.add("spigot-1.10.2.jar");
|
||||||
|
}
|
||||||
|
|
||||||
private static final List<Node> nodes = new ArrayList<>();
|
private static final List<Node> nodes = new ArrayList<>();
|
||||||
public static Node local = null;
|
public static Node local = null;
|
||||||
@ -74,6 +79,9 @@ public abstract class Node {
|
|||||||
public abstract double getLoad();
|
public abstract double getLoad();
|
||||||
|
|
||||||
protected void constructServerstart(File directory, List<String> cmd, String serverJar, String worldDir, String levelName, int port, String xmx, String... dParams) {
|
protected void constructServerstart(File directory, List<String> cmd, String serverJar, String worldDir, String levelName, int port, String xmx, String... dParams) {
|
||||||
|
if (JAVA_8.contains(serverJar))
|
||||||
|
cmd.add("/usr/lib/jvm/java-8-openj9-amd64/bin/java");
|
||||||
|
else
|
||||||
cmd.add("java");
|
cmd.add("java");
|
||||||
|
|
||||||
for(String param : dParams){
|
for(String param : dParams){
|
||||||
@ -82,6 +90,10 @@ public abstract class Node {
|
|||||||
cmd.add("-Xmx" + xmx);
|
cmd.add("-Xmx" + xmx);
|
||||||
cmd.add("-Xshareclasses:nonfatal,name=" + directory.getName());
|
cmd.add("-Xshareclasses:nonfatal,name=" + directory.getName());
|
||||||
cmd.addAll(OPENJ9_ARGS);
|
cmd.addAll(OPENJ9_ARGS);
|
||||||
|
if (!JAVA_8.contains(serverJar)) {
|
||||||
|
cmd.add("--add-opens");
|
||||||
|
cmd.add("java.base/jdk.internal.misc=ALL-UNNAMED");
|
||||||
|
}
|
||||||
cmd.add("-jar");
|
cmd.add("-jar");
|
||||||
cmd.add("/binarys/" + serverJar);
|
cmd.add("/binarys/" + serverJar);
|
||||||
cmd.add("--log-strip-color");
|
cmd.add("--log-strip-color");
|
||||||
|
56
src/de/steamwar/bungeecore/commands/ArenaCommand.java
Normale Datei
56
src/de/steamwar/bungeecore/commands/ArenaCommand.java
Normale Datei
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
This file is a part of the SteamWar software.
|
||||||
|
|
||||||
|
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
|
import de.steamwar.bungeecore.Message;
|
||||||
|
import de.steamwar.bungeecore.Servertype;
|
||||||
|
import de.steamwar.bungeecore.Subserver;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
|
public class ArenaCommand extends BasicCommand {
|
||||||
|
|
||||||
|
public ArenaCommand() {
|
||||||
|
super("arena", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String[] args) {
|
||||||
|
if(!(sender instanceof ProxiedPlayer))
|
||||||
|
return;
|
||||||
|
ProxiedPlayer player = (ProxiedPlayer) sender;
|
||||||
|
|
||||||
|
ServerInfo server = ProxyServer.getInstance().getServerInfo(String.join(" ", args));
|
||||||
|
if(server == null) {
|
||||||
|
Message.send("ARENA_NOT_FOUND", player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Subserver subserver = Subserver.getSubserver(server);
|
||||||
|
if(subserver == null || subserver.getType() != Servertype.ARENA) {
|
||||||
|
Message.send("ARENA_NOT_FOUND", player);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
subserver.sendPlayer(player);
|
||||||
|
}
|
||||||
|
}
|
@ -119,7 +119,7 @@ public class BauCommand extends BasicCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new BauweltMember(p.getUniqueId(), target.getUuid(), true, false);
|
new BauweltMember(p.getUniqueId(), target.getUuid(), false, false);
|
||||||
Message.send("BAU_ADDMEMBER_ADDED", p);
|
Message.send("BAU_ADDMEMBER_ADDED", p);
|
||||||
|
|
||||||
ProxiedPlayer z = ProxyServer.getInstance().getPlayer(target.getUuid());
|
ProxiedPlayer z = ProxyServer.getInstance().getPlayer(target.getUuid());
|
||||||
@ -259,16 +259,22 @@ public class BauCommand extends BasicCommand {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean stopBauserver(ProxiedPlayer p){
|
private static boolean startingBau(ProxiedPlayer p) {
|
||||||
for (Subserver subserver : Subserver.getServerList()) {
|
for (Subserver subserver : Subserver.getServerList()) {
|
||||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(p.getUniqueId()) && !subserver.hasStarted()) {
|
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(p.getUniqueId()) && !subserver.hasStarted()) {
|
||||||
Message.send("BAU_START_ALREADY", p);
|
Message.send("BAU_START_ALREADY", p);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static boolean stopBauserver(ProxiedPlayer p){
|
||||||
|
if(startingBau(p))
|
||||||
|
return false;
|
||||||
|
|
||||||
for (Subserver subserver : Subserver.getServerList()) {
|
for (Subserver subserver : Subserver.getServerList()) {
|
||||||
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(p.getUniqueId())) {
|
if (subserver.getType() == Servertype.BAUSERVER && ((Bauserver) subserver).getOwner().equals(p.getUniqueId()) && subserver.hasStarted()) {
|
||||||
subserver.stop();
|
subserver.stop();
|
||||||
try {
|
try {
|
||||||
Thread.sleep(200); // Wait until possible testarena-World has been deleted
|
Thread.sleep(200); // Wait until possible testarena-World has been deleted
|
||||||
@ -278,7 +284,8 @@ public class BauCommand extends BasicCommand {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
return !startingBau(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void testarena(ProxiedPlayer p, String[] args){
|
private static void testarena(ProxiedPlayer p, String[] args){
|
||||||
|
@ -82,7 +82,7 @@ public class ChallengeCommand extends BasicCommand {
|
|||||||
arena.sendPlayer(target);
|
arena.sendPlayer(target);
|
||||||
|
|
||||||
Message.broadcast("CHALLENGE_BROADCAST", "CHALLENGE_BROADCAST_HOVER",
|
Message.broadcast("CHALLENGE_BROADCAST", "CHALLENGE_BROADCAST_HOVER",
|
||||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join " + player.getName()), mode.getDisplayName(), player.getName(), target.getName());
|
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName(), target.getName());
|
||||||
}else{
|
}else{
|
||||||
if(!challenges.containsKey(player)){
|
if(!challenges.containsKey(player)){
|
||||||
challenges.put(player, new LinkedList<>());
|
challenges.put(player, new LinkedList<>());
|
||||||
|
@ -301,7 +301,6 @@ public class CheckCommand extends BasicCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void decline(String reason){
|
private void decline(String reason){
|
||||||
schematic.setType(SchematicType.Normal.toDB());
|
|
||||||
CheckedSchematic.create(schematic, SteamwarUser.get(checker.getUniqueId()).getId(), startTime, Timestamp.from(Instant.now()), reason);
|
CheckedSchematic.create(schematic, SteamwarUser.get(checker.getUniqueId()).getId(), startTime, Timestamp.from(Instant.now()), reason);
|
||||||
SteamwarUser user = SteamwarUser.get(schematic.getOwner());
|
SteamwarUser user = SteamwarUser.get(schematic.getOwner());
|
||||||
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(user.getUuid());
|
ProxiedPlayer player = ProxyServer.getInstance().getPlayer(user.getUuid());
|
||||||
@ -311,6 +310,7 @@ public class CheckCommand extends BasicCommand {
|
|||||||
DiscordSchemAlert.sendDecline(schematic, user, reason);
|
DiscordSchemAlert.sendDecline(schematic, user, reason);
|
||||||
}
|
}
|
||||||
Message.team("CHECK_DECLINED_TEAM", schematic.getName(), user.getUserName(), reason);
|
Message.team("CHECK_DECLINED_TEAM", schematic.getName(), user.getUserName(), reason);
|
||||||
|
schematic.setType(SchematicType.Normal.toDB());
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ public class FightCommand extends BasicCommand {
|
|||||||
Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, 0, null, null, player.getUniqueId(), null, false);
|
Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, 0, null, null, player.getUniqueId(), null, false);
|
||||||
arena.sendPlayer(player);
|
arena.sendPlayer(player);
|
||||||
Message.broadcast("FIGHT_BROADCAST", "FIGHT_BROADCAST_HOVER"
|
Message.broadcast("FIGHT_BROADCAST", "FIGHT_BROADCAST_HOVER"
|
||||||
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join " + player.getName()), mode.getDisplayName(), player.getName());
|
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ public class HistoricCommand extends BasicCommand {
|
|||||||
Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, 0, null, null, player.getUniqueId(), null, false);
|
Subserver arena = SubserverSystem.startArena(mode, map, 0, 0, 0, 0, null, null, player.getUniqueId(), null, false);
|
||||||
arena.sendPlayer(player);
|
arena.sendPlayer(player);
|
||||||
Message.broadcast("HISTORIC_BROADCAST", "HISTORIC_BROADCAST_HOVER"
|
Message.broadcast("HISTORIC_BROADCAST", "HISTORIC_BROADCAST_HOVER"
|
||||||
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join " + player.getName()), mode.getDisplayName(), player.getName());
|
, new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), player.getName());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
49
src/de/steamwar/bungeecore/commands/PlaytimeCommand.java
Normale Datei
49
src/de/steamwar/bungeecore/commands/PlaytimeCommand.java
Normale Datei
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
This file is a part of the SteamWar software.
|
||||||
|
|
||||||
|
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.commands;
|
||||||
|
|
||||||
|
import de.steamwar.bungeecore.Message;
|
||||||
|
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||||
|
import net.md_5.bungee.api.CommandSender;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import org.apache.commons.lang3.LocaleUtils;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class PlaytimeCommand extends BasicCommand{
|
||||||
|
|
||||||
|
public PlaytimeCommand() {
|
||||||
|
super("playtime", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(CommandSender sender, String[] strings) {
|
||||||
|
if(!(sender instanceof ProxiedPlayer))
|
||||||
|
return;
|
||||||
|
|
||||||
|
NumberFormat format = NumberFormat.getNumberInstance(((ProxiedPlayer)sender).getLocale());
|
||||||
|
format.setMaximumFractionDigits(2);
|
||||||
|
String formattedText = format.format((SteamwarUser.get((ProxiedPlayer) sender).getOnlinetime() / (double) 3600));
|
||||||
|
|
||||||
|
Message.send("HOURS_PLAYED", sender, formattedText);
|
||||||
|
}
|
||||||
|
}
|
@ -173,7 +173,7 @@ public class RankedCommand extends BasicCommand {
|
|||||||
arena.sendPlayer(wp2.player);
|
arena.sendPlayer(wp2.player);
|
||||||
|
|
||||||
Message.broadcast("RANKED_BROADCAST", "RANKED_BROADCAST_HOVER",
|
Message.broadcast("RANKED_BROADCAST", "RANKED_BROADCAST_HOVER",
|
||||||
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/join " + wp1.player.getName()), mode.getDisplayName(), wp1.player.getName(), wp2.player.getName());
|
new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/arena " + arena.getServer().getName()), mode.getDisplayName(), wp1.player.getName(), wp2.player.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -647,7 +647,7 @@ public class TeamCommand extends BasicCommand {
|
|||||||
tab.add("event");
|
tab.add("event");
|
||||||
tab.add("changekuerzel");
|
tab.add("changekuerzel");
|
||||||
tab.add("changename");
|
tab.add("changename");
|
||||||
tab.add("changeleader");
|
tab.add("promote");
|
||||||
tab.add("changecolor");
|
tab.add("changecolor");
|
||||||
}else if(args.length == 2){
|
}else if(args.length == 2){
|
||||||
if(args[1].equalsIgnoreCase("event")){
|
if(args[1].equalsIgnoreCase("event")){
|
||||||
|
@ -40,7 +40,15 @@ public class VerifyCommand extends BasicCommand {
|
|||||||
Message.send("VERIFY_USAGE", sender);
|
Message.send("VERIFY_USAGE", sender);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
byte[] bytes = Base64.getDecoder().decode(strings[0]);
|
|
||||||
|
byte[] bytes;
|
||||||
|
try {
|
||||||
|
bytes = Base64.getDecoder().decode(strings[0]);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Message.send("VERIFY_INVALID", sender);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(bytes.length != 16) {
|
if(bytes.length != 16) {
|
||||||
Message.send("VERIFY_INVALID", sender);
|
Message.send("VERIFY_INVALID", sender);
|
||||||
return;
|
return;
|
||||||
|
@ -26,6 +26,7 @@ public class PacketIdManager {
|
|||||||
public static final byte TABLIST_NAME = 0x02;
|
public static final byte TABLIST_NAME = 0x02;
|
||||||
public static final byte PREPARE_SCHEM = 0x03;
|
public static final byte PREPARE_SCHEM = 0x03;
|
||||||
public static final byte BAUMEMBER_UPDATE = 0x04;
|
public static final byte BAUMEMBER_UPDATE = 0x04;
|
||||||
|
public static final byte EXECUTE_COMMAND = 0x05;
|
||||||
|
|
||||||
//0x1(X) Bungee Inventory
|
//0x1(X) Bungee Inventory
|
||||||
public static final byte INVENTORY_PACKET = 0x10;
|
public static final byte INVENTORY_PACKET = 0x10;
|
||||||
|
@ -58,5 +58,6 @@ public class SpigotReceiver extends BasicListener {
|
|||||||
registerHandler(PacketIdManager.PREPARE_SCHEM, new PrepareSchemHandler());
|
registerHandler(PacketIdManager.PREPARE_SCHEM, new PrepareSchemHandler());
|
||||||
registerHandler(PacketIdManager.I_AM_A_LOBBY, new ImALobbyHandler());
|
registerHandler(PacketIdManager.I_AM_A_LOBBY, new ImALobbyHandler());
|
||||||
registerHandler(PacketIdManager.FIGHT_INFO, new FightInfoHandler());
|
registerHandler(PacketIdManager.FIGHT_INFO, new FightInfoHandler());
|
||||||
|
registerHandler(PacketIdManager.EXECUTE_COMMAND, new ExecuteCommandHandler());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
src/de/steamwar/bungeecore/comms/handlers/ExecuteCommandHandler.java
Normale Datei
36
src/de/steamwar/bungeecore/comms/handlers/ExecuteCommandHandler.java
Normale Datei
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
This file is a part of the SteamWar software.
|
||||||
|
|
||||||
|
Copyright (C) 2021 SteamWar.de-Serverteam
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.comms.handlers;
|
||||||
|
|
||||||
|
import com.google.common.io.ByteArrayDataInput;
|
||||||
|
import de.steamwar.bungeecore.comms.SpigotHandler;
|
||||||
|
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.config.ServerInfo;
|
||||||
|
|
||||||
|
public class ExecuteCommandHandler implements SpigotHandler {
|
||||||
|
@Override
|
||||||
|
public void handle(ByteArrayDataInput in, ServerInfo info) {
|
||||||
|
SteamwarUser target = SteamwarUser.get(in.readInt());
|
||||||
|
String command = in.readUTF();
|
||||||
|
|
||||||
|
ProxyServer.getInstance().getPluginManager().dispatchCommand(ProxyServer.getInstance().getPlayer(target.getUuid()), command);
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ public class Badlion extends BasicListener {
|
|||||||
public void onPostLogin(PostLoginEvent event) {
|
public void onPostLogin(PostLoginEvent event) {
|
||||||
/*
|
/*
|
||||||
{
|
{
|
||||||
|
"modsDisallowed": {
|
||||||
"Clear Glass":{"disabled":true},
|
"Clear Glass":{"disabled":true},
|
||||||
"ClearWater":{"disabled":true},
|
"ClearWater":{"disabled":true},
|
||||||
"FOV Changer":{"disabled":true},
|
"FOV Changer":{"disabled":true},
|
||||||
@ -20,20 +21,12 @@ public class Badlion extends BasicListener {
|
|||||||
"Replay":{"disabled":true},
|
"Replay":{"disabled":true},
|
||||||
"Schematica":{"disabled":true},
|
"Schematica":{"disabled":true},
|
||||||
"ToggleSneak":{"disabled":true},
|
"ToggleSneak":{"disabled":true},
|
||||||
"ToggleSprint":{"disabled":true}
|
"ToggleSprint":{"disabled":true},
|
||||||
|
"TNT Time":{"disabled":true}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
event.getPlayer().unsafe().sendPacket(new PluginMessage("badlion:mods", ("{" +
|
|
||||||
"\"Clear Glass\":{\"disabled\":true}," +
|
event.getPlayer().unsafe().sendPacket(new PluginMessage("badlion:mods", ("{\"Clear Glass\":{\"disabled\":true},\"ClearWater\":{\"disabled\":true},\"FOV Changer\":{\"disabled\":true},\"Hitboxes\":{\"disabled\":true},\"MiniMap\":{\"disabled\":true},\"MLG Cobweb\":{\"disabled\":true},\"Replay\":{\"disabled\":true},\"Schematica\":{\"disabled\":true},\"ToggleSneak\":{\"disabled\":true},\"ToggleSprint\":{\"disabled\":true},\"TNT Time\":{\"disabled\":true}}").getBytes(), false));
|
||||||
"\"ClearWater\":{\"disabled\":true}," +
|
|
||||||
"\"FOV Changer\":{\"disabled\":true}," +
|
|
||||||
"\"Hitboxes\":{\"disabled\":true}," +
|
|
||||||
"\"MiniMap\":{\"disabled\":true}," +
|
|
||||||
"\"MLG Cobweb\":{\"disabled\":true}," +
|
|
||||||
"\"Replay\":{\"disabled\":true}," +
|
|
||||||
"\"Schematica\":{\"disabled\":true}," +
|
|
||||||
"\"ToggleSneak\":{\"disabled\":true}," +
|
|
||||||
"\"ToggleSprint\":{\"disabled\":true}" +
|
|
||||||
"}").getBytes(), false));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
86
src/de/steamwar/bungeecore/listeners/mods/FMLPing.java
Normale Datei
86
src/de/steamwar/bungeecore/listeners/mods/FMLPing.java
Normale Datei
@ -0,0 +1,86 @@
|
|||||||
|
/*
|
||||||
|
This file is a part of the SteamWar software.
|
||||||
|
|
||||||
|
Copyright (C) 2020 SteamWar.de-Serverteam
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package de.steamwar.bungeecore.listeners.mods;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ServerPing;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class FMLPing extends ServerPing {
|
||||||
|
|
||||||
|
private final ForgeData forgeData;
|
||||||
|
|
||||||
|
public FMLPing(ServerPing existing, int version) {
|
||||||
|
super(existing.getVersion(), existing.getPlayers(), existing.getDescriptionComponent(), existing.getFaviconObject());
|
||||||
|
forgeData = new ForgeData(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ForgeData {
|
||||||
|
private final List<ForgeChannel> channels = new ArrayList<>();
|
||||||
|
private final List<ForgeMod> mods = new ArrayList<>();
|
||||||
|
private final int fmlNetworkVersion = 2;
|
||||||
|
|
||||||
|
public ForgeData(int versionNumber) {
|
||||||
|
channels.add(new ForgeChannel("minecraft:unregister"));
|
||||||
|
channels.add(new ForgeChannel("minecraft:register"));
|
||||||
|
channels.add(new ForgeChannel("fml:handshake"));
|
||||||
|
mods.add(new ForgeMod("minecraft", ProtocolVersion.getVersion(versionNumber)));
|
||||||
|
mods.add(new ForgeMod("forge", "ANY"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static class ProtocolVersion {
|
||||||
|
|
||||||
|
private static final HashMap<Integer, String> versions;
|
||||||
|
|
||||||
|
static {
|
||||||
|
versions = new HashMap();
|
||||||
|
versions.put(757, "1.18");
|
||||||
|
versions.put(756, "1.17.1");
|
||||||
|
versions.put(754, "1.16.5");
|
||||||
|
versions.put(578, "1.15.2");
|
||||||
|
versions.put(498, "1.14.1");
|
||||||
|
versions.put(393, "1.13");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getVersion(int version) {
|
||||||
|
return versions.get(version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ForgeChannel {
|
||||||
|
private final String res;
|
||||||
|
private final String version = "FML2";
|
||||||
|
private final boolean required = true;
|
||||||
|
|
||||||
|
private ForgeChannel(String res) {
|
||||||
|
this.res = res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ForgeMod {
|
||||||
|
private final String modId;
|
||||||
|
private final String modmarker;
|
||||||
|
|
||||||
|
private ForgeMod(String modId, String modmarker) {
|
||||||
|
this.modId = modId;
|
||||||
|
this.modmarker = modmarker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -22,102 +22,125 @@ package de.steamwar.bungeecore.listeners.mods;
|
|||||||
import de.steamwar.bungeecore.BungeeCore;
|
import de.steamwar.bungeecore.BungeeCore;
|
||||||
import de.steamwar.bungeecore.listeners.BasicListener;
|
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||||
import de.steamwar.bungeecore.sql.Mod;
|
import de.steamwar.bungeecore.sql.Mod;
|
||||||
import io.netty.buffer.ByteBuf;
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
import io.netty.buffer.UnpooledByteBufAllocator;
|
import net.md_5.bungee.api.connection.PendingConnection;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.event.LoginEvent;
|
||||||
import net.md_5.bungee.api.connection.Connection;
|
import net.md_5.bungee.api.event.ProxyPingEvent;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.connection.InitialHandler;
|
||||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
|
||||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
|
||||||
import net.md_5.bungee.event.EventHandler;
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
import net.md_5.bungee.netty.ChannelWrapper;
|
||||||
|
import net.md_5.bungee.netty.HandlerBoss;
|
||||||
|
import net.md_5.bungee.netty.PacketHandler;
|
||||||
|
import net.md_5.bungee.protocol.packet.LoginPayloadRequest;
|
||||||
|
import net.md_5.bungee.protocol.packet.LoginPayloadResponse;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.lang.reflect.Field;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class Forge extends BasicListener {
|
public class Forge extends BasicListener {
|
||||||
|
|
||||||
private static final String FMLHS = "FML|HS";
|
private static final String WRAPPER = "fml:loginwrapper";
|
||||||
private static final String FMLHS13 = "fml:handshake";
|
|
||||||
private static final byte[] REGISTER;
|
|
||||||
private static final byte[] REGISTER13;
|
|
||||||
private static final byte[] HELLO = new byte[]{0, 2, 0, 0, 0, 0};
|
|
||||||
private static final Set<UUID> unlocked = new HashSet<>();
|
|
||||||
|
|
||||||
|
private static final Field initialHandlerCh;
|
||||||
static{
|
static{
|
||||||
ByteBuf buf = UnpooledByteBufAllocator.DEFAULT.directBuffer(7);
|
try {
|
||||||
buf.writeByte(6);
|
initialHandlerCh = InitialHandler.class.getDeclaredField("ch");
|
||||||
buf.writeCharSequence(FMLHS, StandardCharsets.UTF_8);
|
} catch (NoSuchFieldException e) {
|
||||||
REGISTER = new byte[buf.readableBytes()];
|
throw new SecurityException("Could not initialize Reflection", e);
|
||||||
buf.readBytes(REGISTER);
|
}
|
||||||
|
initialHandlerCh.setAccessible(true);
|
||||||
buf.clear();
|
|
||||||
buf.writeByte(13);
|
|
||||||
buf.writeCharSequence(FMLHS13, StandardCharsets.UTF_8);
|
|
||||||
REGISTER13 = new byte[buf.readableBytes()];
|
|
||||||
buf.readBytes(REGISTER13);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPostLogin(PostLoginEvent event) {
|
public void onServerPing(ProxyPingEvent event) {
|
||||||
ProxiedPlayer player = event.getPlayer();
|
event.setResponse(new FMLPing(event.getResponse(), event.getConnection().getVersion()));
|
||||||
|
|
||||||
synchronized (unlocked) {
|
|
||||||
if(unlocked.contains(player.getUniqueId())){
|
|
||||||
unlocked.remove(player.getUniqueId());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(player.getPendingConnection().getVersion() > 340) {
|
|
||||||
player.sendData("minecraft:register", REGISTER13); //1.13+
|
|
||||||
player.sendData(FMLHS13, Forge.HELLO);
|
|
||||||
}else{
|
|
||||||
player.sendData("REGISTER", REGISTER); //1.12-
|
|
||||||
player.sendData(FMLHS, Forge.HELLO);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPluginMessageEvent(PluginMessageEvent e){
|
public void onServerConnected(LoginEvent event){
|
||||||
if(!e.getTag().equals(FMLHS) && !e.getTag().equals(FMLHS13))
|
if(event.getConnection().getVersion() < 340) return; //1.13+
|
||||||
|
|
||||||
|
//fml:handshake without mods, channels and registries
|
||||||
|
//for more information see https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29
|
||||||
|
event.getConnection().unsafe().sendPacket(new LoginPayloadRequest(1, WRAPPER, new byte[]{13,102,109,108,58,104,97,110,100,115,104,97,107,101,4,1,0,0,0}));
|
||||||
|
|
||||||
|
InitialHandler handler = (InitialHandler) event.getConnection();
|
||||||
|
|
||||||
|
ChannelWrapper wrapper;
|
||||||
|
try{
|
||||||
|
wrapper = (ChannelWrapper) initialHandlerCh.get(handler);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not get Channel", e);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
e.setCancelled(true);
|
event.registerIntent(BungeeCore.get());
|
||||||
byte[] data = e.getData();
|
wrapper.getHandle().pipeline().get(HandlerBoss.class).setHandler(new CustomPacketHandler(event));
|
||||||
|
}
|
||||||
|
|
||||||
Connection sender = e.getSender();
|
private static class CustomPacketHandler extends PacketHandler {
|
||||||
if(!(sender instanceof ProxiedPlayer))
|
private final LoginEvent event;
|
||||||
|
|
||||||
|
public CustomPacketHandler(LoginEvent event) {
|
||||||
|
this.event = event;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "SteamWar Forge Handler";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(LoginPayloadResponse response){
|
||||||
|
byte[] data = response.getData();
|
||||||
|
if(data == null) {
|
||||||
|
event.completeIntent(BungeeCore.get());
|
||||||
return;
|
return;
|
||||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
|
||||||
|
|
||||||
if (data[0] == 2) {
|
|
||||||
Utils.VarInt numMods = Utils.readVarInt(data, 1);
|
|
||||||
List<Mod> mods = new LinkedList<>();
|
|
||||||
|
|
||||||
int bytePos = 1 + numMods.length;
|
|
||||||
for (int i = 0; i < numMods.value; i++) {
|
|
||||||
byte[] name = Arrays.copyOfRange(data, bytePos + 1, bytePos + data[bytePos] + 1);
|
|
||||||
bytePos += 1 + data[bytePos];
|
|
||||||
//Version information is unused
|
|
||||||
bytePos += 1 + data[bytePos];
|
|
||||||
|
|
||||||
mods.add(Mod.get(new String(name), Mod.Platform.FORGE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Utils.handleMods(p, mods)) {
|
//for more information see https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29
|
||||||
synchronized (unlocked) {
|
Utils.VarInt channelLength = Utils.readVarInt(data, 0);
|
||||||
unlocked.add(p.getUniqueId());
|
int pos = channelLength.length;
|
||||||
|
if(!new String(data, pos, channelLength.value).equals("fml:handshake")) {
|
||||||
|
event.getConnection().disconnect(TextComponent.fromLegacyText("Invalid forge registry response (0x00)"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(),
|
pos += channelLength.value;
|
||||||
() -> p.disconnect(BungeeCore.stringToText("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten")),
|
|
||||||
2, TimeUnit.SECONDS);
|
Utils.VarInt length = Utils.readVarInt(data, pos);
|
||||||
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
pos += length.length;
|
||||||
synchronized (unlocked) {
|
if(channelLength.length + channelLength.value + length.length + length.value != data.length) {
|
||||||
unlocked.remove(p.getUniqueId());
|
event.getConnection().disconnect(TextComponent.fromLegacyText("Invalid forge registry response (0x01)"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}, 30, TimeUnit.SECONDS);
|
|
||||||
|
Utils.VarInt packetId = Utils.readVarInt(data, pos);
|
||||||
|
pos += packetId.length;
|
||||||
|
if(packetId.value != 2) {
|
||||||
|
event.getConnection().disconnect(TextComponent.fromLegacyText("Invalid forge registry response (0x02)"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Utils.VarInt modCount = Utils.readVarInt(data, pos);
|
||||||
|
pos += modCount.length;
|
||||||
|
|
||||||
|
List<Mod> mods = new ArrayList<>();
|
||||||
|
for(int i = 0; i < modCount.value; i++) {
|
||||||
|
Utils.VarInt nameLength = Utils.readVarInt(data, pos);
|
||||||
|
pos += nameLength.length;
|
||||||
|
|
||||||
|
mods.add(Mod.get(new String(data, pos, nameLength.value), Mod.Platform.FORGE));
|
||||||
|
pos += nameLength.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
PendingConnection connection = event.getConnection();
|
||||||
|
if(!Utils.handleMods(connection.getUniqueId(), Locale.getDefault(), event::setCancelReason, mods)) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
event.completeIntent(BungeeCore.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
113
src/de/steamwar/bungeecore/listeners/mods/Forge12.java
Normale Datei
113
src/de/steamwar/bungeecore/listeners/mods/Forge12.java
Normale Datei
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
This file is a part of the SteamWar software.
|
||||||
|
|
||||||
|
Copyright (C) 2022 SteamWar.de-Serverteam
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.bungeecore.listeners.mods;
|
||||||
|
|
||||||
|
import de.steamwar.bungeecore.BungeeCore;
|
||||||
|
import de.steamwar.bungeecore.listeners.BasicListener;
|
||||||
|
import de.steamwar.bungeecore.sql.Mod;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
import net.md_5.bungee.api.connection.Connection;
|
||||||
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||||
|
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||||
|
import net.md_5.bungee.event.EventHandler;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class Forge12 extends BasicListener {
|
||||||
|
private static final String FMLHS = "FML|HS";
|
||||||
|
private static final byte[] REGISTER;
|
||||||
|
private static final byte[] HELLO = new byte[]{0, 2, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
private static final Set<UUID> unlocked = new HashSet<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
ByteBuf buf = UnpooledByteBufAllocator.DEFAULT.directBuffer(7);
|
||||||
|
buf.writeByte(6);
|
||||||
|
buf.writeCharSequence(FMLHS, StandardCharsets.UTF_8);
|
||||||
|
REGISTER = new byte[buf.readableBytes()];
|
||||||
|
buf.readBytes(REGISTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPostLogin(PostLoginEvent event) {
|
||||||
|
ProxiedPlayer player = event.getPlayer();
|
||||||
|
|
||||||
|
synchronized (unlocked) {
|
||||||
|
if(unlocked.contains(player.getUniqueId())){
|
||||||
|
unlocked.remove(player.getUniqueId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(player.getPendingConnection().getVersion() <= 340) {
|
||||||
|
player.sendData("REGISTER", REGISTER); //1.12-
|
||||||
|
player.sendData(FMLHS, HELLO);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPluginMessageEvent(PluginMessageEvent e){
|
||||||
|
if(!e.getTag().equals(FMLHS))
|
||||||
|
return;
|
||||||
|
|
||||||
|
e.setCancelled(true);
|
||||||
|
byte[] data = e.getData();
|
||||||
|
|
||||||
|
Connection sender = e.getSender();
|
||||||
|
if(!(sender instanceof ProxiedPlayer))
|
||||||
|
return;
|
||||||
|
ProxiedPlayer p = (ProxiedPlayer) sender;
|
||||||
|
|
||||||
|
if (data[0] == 2) {
|
||||||
|
Utils.VarInt numMods = Utils.readVarInt(data, 1);
|
||||||
|
List<Mod> mods = new LinkedList<>();
|
||||||
|
|
||||||
|
int bytePos = 1 + numMods.length;
|
||||||
|
for (int i = 0; i < numMods.value; i++) {
|
||||||
|
byte[] name = Arrays.copyOfRange(data, bytePos + 1, bytePos + data[bytePos] + 1);
|
||||||
|
bytePos += 1 + data[bytePos];
|
||||||
|
//Version information is unused
|
||||||
|
bytePos += 1 + data[bytePos];
|
||||||
|
|
||||||
|
mods.add(Mod.get(new String(name), Mod.Platform.FORGE));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Utils.handleMods(p, mods)) {
|
||||||
|
synchronized (unlocked) {
|
||||||
|
unlocked.add(p.getUniqueId());
|
||||||
|
}
|
||||||
|
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(),
|
||||||
|
() -> p.disconnect(BungeeCore.stringToText("§7Deine installierten Mods wurden überprüft\n§aDu kannst nun §eSteam§8War §abetreten")),
|
||||||
|
2, TimeUnit.SECONDS);
|
||||||
|
ProxyServer.getInstance().getScheduler().schedule(BungeeCore.get(), () -> {
|
||||||
|
synchronized (unlocked) {
|
||||||
|
unlocked.remove(p.getUniqueId());
|
||||||
|
}
|
||||||
|
}, 30, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -56,26 +56,6 @@ public class ModLoaderBlocker extends BasicListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPluginMessage(PluginMessageEvent e){
|
|
||||||
if(!e.getTag().equals("minecraft:register"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Connection sender = e.getSender();
|
|
||||||
if(!(sender instanceof ProxiedPlayer))
|
|
||||||
return;
|
|
||||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
|
||||||
|
|
||||||
if(p.getPendingConnection().getVersion() <= 340)
|
|
||||||
return;
|
|
||||||
|
|
||||||
String registered = new String(e.getData(), StandardCharsets.UTF_8);
|
|
||||||
if(registered.contains("fml:loginwrapper") || registered.contains("fml:handshake") || registered.contains("fml:play")){
|
|
||||||
Storage.fabricPlayers.add(p);
|
|
||||||
Message.send("MODLOADER_INSTALLED", p, "Forge");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onDisconnect(PlayerDisconnectEvent e){
|
public void onDisconnect(PlayerDisconnectEvent e){
|
||||||
Storage.fabricPlayers.remove(e.getPlayer());
|
Storage.fabricPlayers.remove(e.getPlayer());
|
||||||
|
@ -25,6 +25,8 @@ import de.steamwar.bungeecore.sql.Mod;
|
|||||||
import de.steamwar.bungeecore.sql.Mod.ModType;
|
import de.steamwar.bungeecore.sql.Mod.ModType;
|
||||||
import de.steamwar.bungeecore.sql.Punishment;
|
import de.steamwar.bungeecore.sql.Punishment;
|
||||||
import de.steamwar.bungeecore.sql.SteamwarUser;
|
import de.steamwar.bungeecore.sql.SteamwarUser;
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
@ -32,7 +34,11 @@ import java.time.Instant;
|
|||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
class Utils {
|
class Utils {
|
||||||
private Utils(){}
|
private Utils(){}
|
||||||
@ -55,9 +61,13 @@ class Utils {
|
|||||||
return new VarInt(numRead, result);
|
return new VarInt(numRead, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean handleMods(ProxiedPlayer player, List<Mod> mods){
|
static boolean handleMods(ProxiedPlayer player, List<Mod> mods) {
|
||||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
return handleMods(player.getUniqueId(), player.getLocale(), player::disconnect, mods);
|
||||||
boolean privileged = player.hasPermission("bungeecore.youtubermods");
|
}
|
||||||
|
|
||||||
|
static boolean handleMods(UUID uuid, Locale locale, Consumer<BaseComponent[]> disconnect, List<Mod> mods){
|
||||||
|
SteamwarUser user = SteamwarUser.get(uuid);
|
||||||
|
boolean privileged = user.getUserGroup().privilegedMods();
|
||||||
|
|
||||||
ModType max = ModType.YELLOW;
|
ModType max = ModType.YELLOW;
|
||||||
Iterator<Mod> it = mods.iterator();
|
Iterator<Mod> it = mods.iterator();
|
||||||
@ -72,25 +82,22 @@ class Utils {
|
|||||||
if(mods.isEmpty())
|
if(mods.isEmpty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(mods.size() == 1){
|
ModType finalMax = max;
|
||||||
if(max == ModType.YELLOW)
|
String modList = mods.stream().filter(mod -> finalMax == ModType.YELLOW || mod.getModType() == ModType.RED).map(Mod::getModName).collect(Collectors.joining("\n"));
|
||||||
player.disconnect(BungeeCore.stringToText(Message.parse("MOD_YELLOW_SING", player, mods.get(0).getModName())));
|
String message;
|
||||||
else{
|
|
||||||
user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), Message.parse("MOD_RED_SING", player, mods.get(0).getModName()), 0, false);
|
|
||||||
BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen des Mods " + mods.get(0).getModName() + " gebannt.");
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
mods.forEach(mod -> sb.append(mod.getModName()).append('\n'));
|
|
||||||
|
|
||||||
if(max == ModType.YELLOW)
|
if(mods.size() == 1) {
|
||||||
player.disconnect(BungeeCore.stringToText(Message.parse("MOD_YELLOW_PLUR", player, sb.toString())));
|
message = Message.parse(max == ModType.RED ? "MOD_RED_SING" : "MOD_YELLOW_SING", locale, modList);
|
||||||
else{
|
} else {
|
||||||
user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), Message.parse("MOD_RED_PLUR", player, sb.toString()), 0, false);
|
message = Message.parse(max == ModType.RED ? "MOD_RED_PLUR" : "MOD_YELLOW_PLUR", locale, modList);
|
||||||
BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + sb.toString() + " gebannt.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(max == ModType.RED) {
|
||||||
|
user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), message, 0, false);
|
||||||
|
BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + modList + " gebannt.");
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnect.accept(TextComponent.fromLegacyText(message));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,10 +224,12 @@ public class SteamwarUser {
|
|||||||
final URL url = new URL(API_URL + playerName);
|
final URL url = new URL(API_URL + playerName);
|
||||||
String uuid = jsonParser.parse(new Scanner(url.openConnection().getInputStream()).nextLine()).getAsJsonObject().get("id").getAsString();
|
String uuid = jsonParser.parse(new Scanner(url.openConnection().getInputStream()).nextLine()).getAsJsonObject().get("id").getAsString();
|
||||||
return UUID.fromString(uuid.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
|
return UUID.fromString(uuid.replaceFirst("(\\w{8})(\\w{4})(\\w{4})(\\w{4})(\\w{12})", "$1-$2-$3-$4-$5"));
|
||||||
} catch (NoSuchElementException | IOException e) {
|
} catch (NoSuchElementException e) {
|
||||||
|
// ignore, player does not exist
|
||||||
|
} catch (IOException e) {
|
||||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not get offline player UUID " + playerName, e);
|
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not get offline player UUID " + playerName, e);
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTeam(int team) {
|
public void setTeam(int team) {
|
||||||
|
@ -146,6 +146,7 @@ public class Team {
|
|||||||
user.setLeader(false);
|
user.setLeader(false);
|
||||||
delete.update(teamId);
|
delete.update(teamId);
|
||||||
teamCache.remove(this);
|
teamCache.remove(this);
|
||||||
|
TeamTeilnahme.deleteFuture(teamId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> getMembers(){
|
public List<Integer> getMembers(){
|
||||||
|
@ -28,6 +28,7 @@ public class TeamTeilnahme {
|
|||||||
|
|
||||||
private static final Statement insert = new Statement("INSERT INTO TeamTeilnahme (TeamID, EventID) VALUES (?, ?)");
|
private static final Statement insert = new Statement("INSERT INTO TeamTeilnahme (TeamID, EventID) VALUES (?, ?)");
|
||||||
private static final Statement delete = new Statement("DELETE FROM TeamTeilnahme WHERE TeamID = ? AND EventID = ?");
|
private static final Statement delete = new Statement("DELETE FROM TeamTeilnahme WHERE TeamID = ? AND EventID = ?");
|
||||||
|
private static final Statement deleteFuture = new Statement("DELETE t FROM TeamTeilnahme t INNER JOIN Event e ON t.EventID = e.EventID WHERE t.TeamID = ? AND e.Start > NOW()");
|
||||||
private static final Statement byEventTeam = new Statement("SELECT * FROM TeamTeilnahme WHERE TeamID = ? AND EventID = ?");
|
private static final Statement byEventTeam = new Statement("SELECT * FROM TeamTeilnahme WHERE TeamID = ? AND EventID = ?");
|
||||||
private static final Statement byEvent = new Statement("SELECT * FROM TeamTeilnahme WHERE EventID = ?");
|
private static final Statement byEvent = new Statement("SELECT * FROM TeamTeilnahme WHERE EventID = ?");
|
||||||
private static final Statement byTeam = new Statement("SELECT * FROM TeamTeilnahme WHERE TeamID = ?");
|
private static final Statement byTeam = new Statement("SELECT * FROM TeamTeilnahme WHERE TeamID = ?");
|
||||||
@ -44,6 +45,10 @@ public class TeamTeilnahme {
|
|||||||
return byEventTeam.select(ResultSet::next, teamID, eventID);
|
return byEventTeam.select(ResultSet::next, teamID, eventID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void deleteFuture(int teamID) {
|
||||||
|
deleteFuture.update(teamID);
|
||||||
|
}
|
||||||
|
|
||||||
public static Set<Team> getTeams(int eventID){
|
public static Set<Team> getTeams(int eventID){
|
||||||
return byEvent.select(rs -> {
|
return byEvent.select(rs -> {
|
||||||
Set<Team> teams = new HashSet<>();
|
Set<Team> teams = new HashSet<>();
|
||||||
|
@ -24,26 +24,28 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public enum UserGroup {
|
public enum UserGroup {
|
||||||
|
|
||||||
Admin("§4", "§e", true, true, true),
|
Admin("§4", "§e", true, true, true, true),
|
||||||
Developer("§3", "§f", true, true, true),
|
Developer("§3", "§f", true, true, true, true),
|
||||||
Moderator("§c", "§f", true, true, true),
|
Moderator("§c", "§f", true, true, true, true),
|
||||||
Supporter("§9", "§f", false, true, true),
|
Supporter("§9", "§f", false, true, true, true),
|
||||||
Builder("§2", "§f", false, true, false),
|
Builder("§2", "§f", false, true, false, true),
|
||||||
YouTuber("§5", "§f", false, false, false),
|
YouTuber("§5", "§f", false, false, false, true),
|
||||||
Member("§7", "§7", false, false, false);
|
Member("§7", "§7", false, false, false, false);
|
||||||
|
|
||||||
private final String colorCode;
|
private final String colorCode;
|
||||||
private final String chatColorCode;
|
private final String chatColorCode;
|
||||||
private final boolean adminGroup;
|
private final boolean adminGroup;
|
||||||
private final boolean teamGroup;
|
private final boolean teamGroup;
|
||||||
private final boolean checkSchematics;
|
private final boolean checkSchematics;
|
||||||
|
private final boolean privilegedMods;
|
||||||
|
|
||||||
UserGroup(String colorCode, String chatColorCode, boolean adminGroup, boolean teamGroup, boolean checkSchematics) {
|
UserGroup(String colorCode, String chatColorCode, boolean adminGroup, boolean teamGroup, boolean checkSchematics, boolean privilegedMods) {
|
||||||
this.colorCode = colorCode;
|
this.colorCode = colorCode;
|
||||||
this.chatColorCode = chatColorCode;
|
this.chatColorCode = chatColorCode;
|
||||||
this.adminGroup = adminGroup;
|
this.adminGroup = adminGroup;
|
||||||
this.teamGroup = teamGroup;
|
this.teamGroup = teamGroup;
|
||||||
this.checkSchematics = checkSchematics;
|
this.checkSchematics = checkSchematics;
|
||||||
|
this.privilegedMods = privilegedMods;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getColorCode() {
|
public String getColorCode() {
|
||||||
@ -62,6 +64,10 @@ public enum UserGroup {
|
|||||||
return checkSchematics;
|
return checkSchematics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean privilegedMods() {
|
||||||
|
return privilegedMods;
|
||||||
|
}
|
||||||
|
|
||||||
public String getChatColorCode() {
|
public String getChatColorCode() {
|
||||||
return chatColorCode;
|
return chatColorCode;
|
||||||
}
|
}
|
||||||
|
@ -537,7 +537,7 @@ SERVER_WORLD_ERROR=§cDas Erstellen der Welt ist fehlgeschlagen.
|
|||||||
|
|
||||||
|
|
||||||
#WhoisCommand
|
#WhoisCommand
|
||||||
WHOIS_USAGE=§c/whois [Spieler/ID] {-a}
|
WHOIS_USAGE=§c/whois [Spieler/ID] <-a>
|
||||||
WHOIS_USERNAME=§7Username§8: §e{0}
|
WHOIS_USERNAME=§7Username§8: §e{0}
|
||||||
WHOIS_UUID=§7UUID§8: §e{0}
|
WHOIS_UUID=§7UUID§8: §e{0}
|
||||||
WHOIS_UUID_HOVER=§eUUID Kopieren
|
WHOIS_UUID_HOVER=§eUUID Kopieren
|
||||||
@ -569,3 +569,9 @@ GDPR_STATUS_INVENTORIES=§7Suche und packe Inventare...
|
|||||||
GDPR_STATUS_DATABASE=§7Packe Datenbankinhalte...
|
GDPR_STATUS_DATABASE=§7Packe Datenbankinhalte...
|
||||||
GDPR_STATUS_LOGS=§7Suche und packe logs...
|
GDPR_STATUS_LOGS=§7Suche und packe logs...
|
||||||
GDPR_STATUS_FINISHED=§7Packen abgeschlossen
|
GDPR_STATUS_FINISHED=§7Packen abgeschlossen
|
||||||
|
|
||||||
|
#Playtime Command
|
||||||
|
HOURS_PLAYED=§7Deine Spielzeit beträgt§8: §e{0}h
|
||||||
|
|
||||||
|
#Arena command
|
||||||
|
ARENA_NOT_FOUND=§cDie angegebene Arena konnte nicht gefunden werden
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren