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!