diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index 846dd5c..7b9d428 100644 --- a/src/de/steamwar/bungeecore/BungeeCore.java +++ b/src/de/steamwar/bungeecore/BungeeCore.java @@ -67,6 +67,7 @@ public class BungeeCore extends Plugin { @Override public void onEnable(){ getProxy().registerChannel("sw:bridge"); + getProxy().registerChannel("fabricmodsender:mods"); setInstance(this); loadConfig(); @@ -83,6 +84,7 @@ public class BungeeCore extends Plugin { new ModLoaderBlocker(); new WorldDownloader(); new BrandListener(); + new Fabric(); new Node.LocalNode(); //new Node.RemoteNode("lx"); @@ -102,7 +104,6 @@ public class BungeeCore extends Plugin { new JoinmeCommand(); new TpCommand(); new HelpCommand(); - new DenyCommand("watchcat", "wc"); new TeamCommand(); new ServerTeamchatCommand(); new DevCommand(); @@ -116,7 +117,6 @@ public class BungeeCore extends Plugin { new IgnoreCommand(); new UnIgnoreCommand(); new PollresultCommand(); - new ResourcereloadCommand(); new ListCommand(); new StatCommand(); new VerifyCommand(); diff --git a/src/de/steamwar/bungeecore/ServerStarter.java b/src/de/steamwar/bungeecore/ServerStarter.java index 622b7a4..1128b7d 100644 --- a/src/de/steamwar/bungeecore/ServerStarter.java +++ b/src/de/steamwar/bungeecore/ServerStarter.java @@ -26,6 +26,7 @@ public class ServerStarter { private static final String EVENT_PATH = BACKBONE + "event/"; public static final String TEMP_WORLD_PATH = BACKBONE + "arenaserver/"; public static final String TUTORIAL_PATH = BACKBONE + "tutorials/"; + public static final String WORLDS18_PATH = BACKBONE + "userworlds18/"; private File directory = null; private String worldDir = null; @@ -46,7 +47,7 @@ public class ServerStarter { public ServerStarter arena(ArenaMode mode, String map) { portrange = ARENA_PORTS; - serverNameProvider = port -> mode.getChatName() + (port - portrange.start); + serverNameProvider = port -> mode.getDisplayName() + (port - portrange.start); serverJar = mode.serverJar(); directory = new File(SERVER_PATH, mode.getFolder()); arguments.put("config", mode.getConfig()); @@ -100,6 +101,15 @@ public class ServerStarter { return this; } + public ServerStarter build18(UUID owner) { + directory = new File(SERVER_PATH, "Bau18"); + serverJar = "paper-1.18.2.jar"; + worldDir = WORLDS18_PATH; + worldName = String.valueOf(SteamwarUser.get(owner).getId()); + buildWithWorld(owner, new File(directory, "Bauwelt").getPath()); + return this; + } + public ServerStarter build15(UUID owner) { directory = new File(SERVER_PATH, "Bau15"); worldDir = BungeeCore.USERWORLDS15; diff --git a/src/de/steamwar/bungeecore/commands/BauCommand.java b/src/de/steamwar/bungeecore/commands/BauCommand.java index 5a58a73..93c4866 100644 --- a/src/de/steamwar/bungeecore/commands/BauCommand.java +++ b/src/de/steamwar/bungeecore/commands/BauCommand.java @@ -33,7 +33,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; public class BauCommand extends BasicCommand { public BauCommand(){ - super("bau", null, "b", "gs"); + super("bau", null, "b", "build", "gs"); } @Override @@ -44,58 +44,44 @@ public class BauCommand extends BasicCommand { ProxiedPlayer p = (ProxiedPlayer) sender; - if(args.length == 0){ - (bau15(p, args, 0) ? new ServerStarter().build15(p.getUniqueId()) : new ServerStarter().build12(p.getUniqueId())).send(p).start(); - return; - } - - switch(args[0].toLowerCase()){ - case "12": - case "1.12": - new ServerStarter().build12(p.getUniqueId()).send(p).start(); - break; - case "ws": - case "warship": - case "as": - case "airship": - case "mwg": - case "miniwargear": - case "wg": - case "wargear": - case "15": - case "1.15": - new ServerStarter().build15(p.getUniqueId()).send(p).start(); - break; - case "addmember": - addmember(p, args); - break; - case "tp": - case "teleport": - teleport(p, args); - break; - case "info": - p.chat("/bauinfo"); - break; - case "togglewe": - togglewe(p, args); - break; - case "toggleworld": - toggleworld(p, args); - break; - case "delmember": - delmember(p, args); - break; - case "resetall": - case "delete": - delete(p, args); - break; - case "testarena": - case "test": - testarena(p, args); - break; - default: - HelpCommand.sendBauHelp(p); - } + versionSelector(p, args, 0, + () -> new ServerStarter().build18(p.getUniqueId()).send(p).start(), + () -> new ServerStarter().build15(p.getUniqueId()).send(p).start(), + () -> new ServerStarter().build12(p.getUniqueId()).send(p).start(), + () -> { + switch (args[0].toLowerCase()) { + case "addmember": + addmember(p, args); + break; + case "tp": + case "teleport": + teleport(p, args); + break; + case "info": + p.chat("/bauinfo"); + break; + case "togglewe": + togglewe(p, args); + break; + case "toggleworld": + toggleworld(p, args); + break; + case "delmember": + delmember(p, args); + break; + case "resetall": + case "delete": + delete(p, args); + break; + case "testarena": + case "test": + testarena(p, args); + break; + default: + HelpCommand.sendBauHelp(p); + } + } + ); } private static void addmember(ProxiedPlayer p, String[] args){ @@ -140,19 +126,31 @@ public class BauCommand extends BasicCommand { return; } - (bau15(p, args, 2) ? new ServerStarter().build15(worldOwner.getUuid()) : new ServerStarter().build12(worldOwner.getUuid())).send(p).start(); + versionSelector(p, args, 2, + () -> new ServerStarter().build18(worldOwner.getUuid()).send(p).start(), + () -> new ServerStarter().build15(worldOwner.getUuid()).send(p).start(), + () -> new ServerStarter().build12(worldOwner.getUuid()).send(p).start(), + () -> HelpCommand.sendBauHelp(p)); } - private static boolean bau15(ProxiedPlayer p, String[] args, int pos){ - if(args.length <= pos) - return p.getPendingConnection().getVersion() > 340; // Version > 1.12.2 + private static void versionSelector(ProxiedPlayer p, String[] args, int pos, Runnable run18, Runnable run15, Runnable run12, Runnable runElse) { + if(args.length <= pos) { + int version = p.getPendingConnection().getVersion(); + if(version > 340) { // Version > 1.12.2 + run15.run(); + } else { + run12.run(); + } + return; + } - switch(args[pos].toLowerCase()){ + switch (args[pos].toLowerCase()) { + case "18": + case "1.18": + run18.run(); + break; case "ws": case "warship": - case "12": - case "1.12": - return false; case "as": case "airship": case "mwg": @@ -161,9 +159,14 @@ public class BauCommand extends BasicCommand { case "wargear": case "15": case "1.15": - return true; + run15.run(); + break; + case "12": + case "1.12": + run12.run(); + break; default: - return p.getPendingConnection().getVersion() > 340; // Version > 1.12.2 + runElse.run(); } } @@ -225,18 +228,22 @@ public class BauCommand extends BasicCommand { } private static void delete(ProxiedPlayer p, String[] args){ + SteamwarUser user = SteamwarUser.get(p.getUniqueId()); + versionSelector(p, args, 1, + () -> deleteConfirmation(p, () -> deleteWorld(p, ServerStarter.WORLDS18_PATH + user.getId())), + () -> deleteConfirmation(p, () -> deleteWorld(p, BungeeCore.USERWORLDS15 + user.getId())), + () -> deleteConfirmation(p, () -> deleteWorld(p, BungeeCore.WORLD_FOLDER + p.getUniqueId().toString())), + () -> HelpCommand.sendBauHelp(p)); + } + + private static void deleteConfirmation(ProxiedPlayer p, Runnable worldDeletion) { SWInventory inventory = new SWInventory(p, 9, Message.parse("BAU_DELETE_GUI_NAME", p)); inventory.addItem(8, new SWItem(Message.parse("BAU_DELETE_GUI_CANCEL", p), 1), click -> - inventory.close() + inventory.close() + ); + inventory.addItem(0, new SWItem(Message.parse("BAU_DELETE_GUI_DELETE", p), 10), click -> + worldDeletion.run() ); - inventory.addItem(0, new SWItem(Message.parse("BAU_DELETE_GUI_DELETE", p), 10), click -> { - if(bau15(p, args, 1)){ - SteamwarUser user = SteamwarUser.get(p.getUniqueId()); - deleteWorld(p, BungeeCore.USERWORLDS15 + user.getId()); - }else{ - deleteWorld(p, BungeeCore.WORLD_FOLDER + p.getUniqueId().toString()); - } - }); inventory.open(); } diff --git a/src/de/steamwar/bungeecore/commands/DenyCommand.java b/src/de/steamwar/bungeecore/commands/DenyCommand.java deleted file mode 100644 index b6738d8..0000000 --- a/src/de/steamwar/bungeecore/commands/DenyCommand.java +++ /dev/null @@ -1,39 +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.commands; - -import de.steamwar.bungeecore.Message; -import net.md_5.bungee.api.CommandSender; -import net.md_5.bungee.api.connection.ProxiedPlayer; - -public class DenyCommand extends BasicCommand { - - public DenyCommand(String cmd, String ...aliases) { - super(cmd, "", aliases); - } - - @Override - public void execute(CommandSender sender, String[] args) { - if(sender instanceof ProxiedPlayer){ - ProxiedPlayer player = (ProxiedPlayer) sender; - Message.send("UNKNOWN_COMMAND", player); - } - } -} diff --git a/src/de/steamwar/bungeecore/commands/GDPRQuery.java b/src/de/steamwar/bungeecore/commands/GDPRQuery.java index bb98fca..444a22c 100644 --- a/src/de/steamwar/bungeecore/commands/GDPRQuery.java +++ b/src/de/steamwar/bungeecore/commands/GDPRQuery.java @@ -60,7 +60,7 @@ public class GDPRQuery extends BasicCommand { sqlCSV(user, out, bauweltMember, "BuildMember.csv"); sqlCSV(user, out, bauweltMembers, "BuildMembers.csv"); sqlCSV(user, out, checkedSchems, "SchematicChecksessions.csv"); - sqlCSV(user, out, elo, "Elo.csv"); + sqlCSV(user, out, userElo, "UserElo.csv"); sqlCSV(user, out, fights, "Fights.csv"); sqlCSV(user, out, ignoredPlayers, "IgnoredPlayers.csv"); sqlCSV(user, out, ignoringPlayers, "IgnoringPlayers.csv"); @@ -88,8 +88,8 @@ public class GDPRQuery extends BasicCommand { private static final Statement bauweltMember = new Statement("SELECT BauweltID AS Bauwelt, WorldEdit, World FROM BauweltMember WHERE MemberID = ?"); private static final Statement bauweltMembers = new Statement("SELECT u.UserName AS 'User', m.WorldEdit AS WorldEdit, m.World AS World FROM BauweltMember m INNER JOIN UserData u ON m.MemberID = u.id WHERE m.BauweltID = ?"); private static final Statement checkedSchems = new Statement("SELECT NodeName AS Schematic, StartTime, EndTime, DeclineReason AS Result FROM CheckedSchematic WHERE NodeOwner = ? ORDER BY StartTime ASC"); - private static final Statement elo = new Statement("SELECT GameMode, Elo FROM Elo WHERE UserID = ?"); - private static final Statement fights = new Statement("SELECT p.Team AS Team, p.Kit AS Kit, p.Kills AS Kills, p.IsOut AS Died, f.GameMode AS GameMode, f.Server AS Server, f.Arena AS Arena, f.StartTime AS StartTime, f.Duration AS Duration, (f.BlueLeader = p.UserID) AS IsBlueLeader, (f.RedLeader = p.UserID) AS IsRedLeader, f.Win AS Winner, f.WinCondition AS WinCondition FROM Fight f INNER JOIN FightPlayer p ON f.FightID = p.FightID WHERE p.UserID = ? ORDER BY StartTime ASC"); + private static final Statement userElo = new Statement("SELECT GameMode, Elo, Season FROM Elo WHERE UserID = ?"); + private static final Statement fights = new Statement("SELECT p.Team AS Team, p.Kit AS Kit, p.Kills AS Kills, p.IsOut AS Died, f.GameMode AS GameMode, f.Server AS Server, f.StartTime AS StartTime, f.Duration AS Duration, (f.BlueLeader = p.UserID) AS IsBlueLeader, (f.RedLeader = p.UserID) AS IsRedLeader, f.Win AS Winner, f.WinCondition AS WinCondition FROM Fight f INNER JOIN FightPlayer p ON f.FightID = p.FightID WHERE p.UserID = ? ORDER BY StartTime ASC"); private static final Statement ignoredPlayers = new Statement("SELECT u.UserName AS IgnoredPlayer FROM IgnoredPlayers i INNER JOIN UserData u ON i.Ignored = u.id WHERE Ignorer = ?"); private static final Statement ignoringPlayers = new Statement("SELECT Ignorer AS IgnoringPlayers FROM IgnoredPlayers WHERE Ignored = ?"); private static final Statement schematicMember = new Statement("SELECT s.NodeName AS SchematicName, u.UserName AS SchematicOwner FROM NodeMember m INNER JOIN SchematicNode s ON m.NodeId = s.NodeId INNER JOIN UserData u ON s.NodeOwner = u.id WHERE m.UserId = ?"); diff --git a/src/de/steamwar/bungeecore/commands/ResourcereloadCommand.java b/src/de/steamwar/bungeecore/commands/ResourcereloadCommand.java deleted file mode 100644 index 0789c48..0000000 --- a/src/de/steamwar/bungeecore/commands/ResourcereloadCommand.java +++ /dev/null @@ -1,36 +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.commands; - -import net.md_5.bungee.api.CommandSender; - -import java.util.ResourceBundle; - -public class ResourcereloadCommand extends BasicCommand { - - public ResourcereloadCommand() { - super("resourcereload", "bungeecore.softreload", "rr"); - } - - @Override - public void execute(CommandSender commandSender, String[] strings) { - ResourceBundle.clearCache(); - } -} diff --git a/src/de/steamwar/bungeecore/commands/TutorialCommand.java b/src/de/steamwar/bungeecore/commands/TutorialCommand.java index 3a031e5..4f55742 100644 --- a/src/de/steamwar/bungeecore/commands/TutorialCommand.java +++ b/src/de/steamwar/bungeecore/commands/TutorialCommand.java @@ -129,7 +129,7 @@ public class TutorialCommand extends BasicCommand { List lore = new ArrayList<>(); lore.add(Message.parse("TUTORIAL_BY", player, tutorial.creator().getUserName())); - lore.add(Message.parse("TUTORIAL_STARS", player, tutorial.stars())); + lore.add(Message.parse("TUTORIAL_STARS", player, String.format("%.1f", tutorial.stars()))); if (personalHighlights) lore.add(Message.parse("TUTORIAL_DELETE", player)); diff --git a/src/de/steamwar/bungeecore/listeners/mods/Fabric.java b/src/de/steamwar/bungeecore/listeners/mods/Fabric.java new file mode 100644 index 0000000..90365cd --- /dev/null +++ b/src/de/steamwar/bungeecore/listeners/mods/Fabric.java @@ -0,0 +1,142 @@ +/* + 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.mods; + +import com.google.gson.*; +import de.steamwar.bungeecore.BungeeCore; +import de.steamwar.bungeecore.Message; +import de.steamwar.bungeecore.Storage; +import de.steamwar.bungeecore.listeners.BasicListener; +import de.steamwar.bungeecore.sql.Mod; +import de.steamwar.bungeecore.sql.Punishment; +import de.steamwar.bungeecore.sql.SteamwarUser; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.PluginMessageEvent; +import net.md_5.bungee.event.EventHandler; + +import java.nio.charset.StandardCharsets; +import java.nio.charset.UnsupportedCharsetException; +import java.sql.Timestamp; +import java.time.Instant; +import java.util.*; +import java.util.logging.Level; + +public class Fabric extends BasicListener { + + private final Set neededMods = new HashSet<>(); + + { + neededMods.add("java"); + neededMods.add("minecraft"); + neededMods.add("fabricloader"); + neededMods.add("steamwarmodsender"); + } + + @EventHandler + public void onPluginMessageEvent(PluginMessageEvent e){ + if(!e.getTag().equals("fabricmodsender:mods")) + return; + + if (!(e.getSender() instanceof ProxiedPlayer)) { + return; + } + + ProxiedPlayer player = (ProxiedPlayer) e.getSender(); + SteamwarUser user = SteamwarUser.get(player.getUniqueId()); + + List mods = new LinkedList<>(); + + byte[] data = e.getData(); + Utils.VarInt varInt = Utils.readVarInt(data,0); + + if(data.length != varInt.length + varInt.value) { + banPlayer(user,player); + return; + } + + data = Arrays.copyOfRange(data,varInt.length, data.length); + + String dataString; + + try{ + dataString = new String(data, StandardCharsets.UTF_8); + }catch (UnsupportedCharsetException exception) { + banPlayer(user, player); + return; + } + + JsonArray array; + + try { + array = new JsonParser().parse(dataString).getAsJsonArray(); + }catch (JsonSyntaxException exception) { + banPlayer(user, player); + return; + } + + for(JsonElement mod : array) { + mods.add(Mod.get(mod.getAsString(), Mod.Platform.FABRIC)); + } + + boolean isSorted = isSortedAlphabetically(mods); + + if(!isSorted) { + banPlayer(user, player); + return; + } + + if(!neededModsContained(mods)) { + banPlayer(user, player); + return; + } + + if(Utils.handleMods(player,mods)) { + Storage.fabricPlayers.remove(player); + Message.send("MODIFICATION_CHECK_SUCCESS", player); + } + } + + private boolean isSortedAlphabetically(List mods) { + boolean isSorted = true; + for(int i = 0; i < mods.size() - 1; i++) { + if(mods.get(i).getModName().compareToIgnoreCase(mods.get(i + 1).getModName()) > 0) { + isSorted = false; + break; + } + } + return isSorted; + } + + private boolean neededModsContained(List mods) { + return mods.stream() + .map(Mod::getModName) + .filter(neededMods::contains) + .count() == neededMods.size(); + } + + public void banPlayer(SteamwarUser user, ProxiedPlayer player) { + user.punish(Punishment.PunishmentType.Ban, + Timestamp.from(Instant.now()), + Message.parse("MODIFICATION_BAN_MESSAGE", player, user.getUserName(), user.getId()), + 0, + true); + BungeeCore.log(Level.SEVERE,Message.parse("MODIFICATION_BAN_LOG", player, user.getUserName())); + } +} diff --git a/src/de/steamwar/bungeecore/sql/Mod.java b/src/de/steamwar/bungeecore/sql/Mod.java index 9aad08b..dcd69ae 100644 --- a/src/de/steamwar/bungeecore/sql/Mod.java +++ b/src/de/steamwar/bungeecore/sql/Mod.java @@ -61,7 +61,8 @@ public class Mod { public enum Platform{ FORGE(0), - LABYMOD(1); + LABYMOD(1), + FABRIC(2); Platform(int value){ this.value = value; diff --git a/src/de/steamwar/bungeecore/sql/UserElo.java b/src/de/steamwar/bungeecore/sql/UserElo.java index ca7e723..6740966 100644 --- a/src/de/steamwar/bungeecore/sql/UserElo.java +++ b/src/de/steamwar/bungeecore/sql/UserElo.java @@ -26,15 +26,16 @@ import net.md_5.bungee.api.connection.ProxiedPlayer; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; public class UserElo { private UserElo() {} public static final int ELO_DEFAULT = 1000; - private static final Map>> gameModeUserEloCache = new HashMap<>(); - private static final Map maxEloCache = new HashMap<>(); - private static final Map emblemCache = new HashMap<>(); + private static final Map>> gameModeUserEloCache = new ConcurrentHashMap<>(); + private static final Map maxEloCache = new ConcurrentHashMap<>(); + private static final Map emblemCache = new ConcurrentHashMap<>(); private static final Statement elo = new Statement("SELECT Elo FROM UserElo WHERE UserID = ? AND GameMode = ? AND Season = ?"); private static final Statement setElo = new Statement("INSERT INTO UserElo (Season, GameMode, UserID, Elo) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE Elo = VALUES(Elo)"); diff --git a/src/de/steamwar/messages/BungeeCore.properties b/src/de/steamwar/messages/BungeeCore.properties index 19226ef..d8b87bf 100644 --- a/src/de/steamwar/messages/BungeeCore.properties +++ b/src/de/steamwar/messages/BungeeCore.properties @@ -583,3 +583,8 @@ RANK_UNPLACED=§eunplatziert RANK_PLACED=§e{0}§8. §7mit §e{1} §7Elo§8. RANK_EMBLEM=§eEmblem§8: {0} RANK_NEEDED_FIGHTS_LEFT={0} §8(§7noch §e{1}§7 Kämpfe nötig§8) + +#Fabric Mod Sender +MODIFICATION_BAN_MESSAGE=Du hast probiert den FabricModSender zu umgehen / zu modifizieren! +MODIFICATION_BAN_LOG={0} hat probiert den Fabric Mod Sender zu editieren / umzugehen! +MODIFICATION_CHECK_SUCCESS=§eDeine Mods wurden geprüft und du darfst nun auf Arenen joinen!