diff --git a/src/de/steamwar/bungeecore/BungeeCore.java b/src/de/steamwar/bungeecore/BungeeCore.java index 846dd5c..6ba5f08 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"); 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/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!