Forge Mod detection #292
@ -78,6 +78,7 @@ public class BungeeCore extends Plugin {
|
||||
errorLogger = new ErrorLogger();
|
||||
new ConnectionListener();
|
||||
new Forge();
|
||||
new Forge12();
|
||||
new LabyMod();
|
||||
new Badlion();
|
||||
new ChatListener();
|
||||
|
@ -44,24 +44,26 @@ public class Message {
|
||||
};
|
||||
|
||||
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){
|
||||
return parse(message, true, sender, params);
|
||||
return parse(message, true, locale(sender), 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){
|
||||
Locale locale = null;
|
||||
if(sender instanceof ProxiedPlayer)
|
||||
locale = ((ProxiedPlayer)sender).getLocale();
|
||||
if(locale == null)
|
||||
locale = Locale.getDefault();
|
||||
public static String parse(String message, Locale locale, Object... params){
|
||||
return parse(message, false, locale, params);
|
||||
}
|
||||
|
||||
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){
|
||||
ResourceBundle resourceBundle = ResourceBundle.getBundle("de.steamwar.messages.BungeeCore", locale, CONTROL);
|
||||
String pattern = "";
|
||||
if(prefixed)
|
||||
@ -72,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(), sender, msg.getParams());
|
||||
params[i] = parse(msg.getMessage(), false, locale, msg.getParams());
|
||||
} else if(params[i] instanceof Date) {
|
||||
params[i] = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale).format((Date) params[i]);
|
||||
}
|
||||
@ -120,7 +122,7 @@ public class Message {
|
||||
|
||||
public static void broadcast(String message, String onHover, ClickEvent onClick, Object... params){
|
||||
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){
|
||||
|
86
src/de/steamwar/bungeecore/listeners/mods/FMLPing.java
Normale Datei
@ -0,0 +1,86 @@
|
||||
/*
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
|
||||
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;
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Man könnte noch argumentieren, dass es äußerst schade ist, dass wir hier für jeden Ping die ForeData neu erstellen und danach wieder verwerfen, aber das ist so schon in Ordnung. Man könnte noch argumentieren, dass es äußerst schade ist, dass wir hier für jeden Ping die ForeData neu erstellen und danach wieder verwerfen, aber das ist so schon in Ordnung.
YoyoNow
hat
Könnte man das nicht einfach mit einem 'static' beheben? Könnte man das nicht einfach mit einem 'static' beheben?
zOnlyKroks
hat
wird morgn als erledigt markiert. wird morgn als erledigt markiert.
|
||||
|
||||
Lixfel markierte diese Unterhaltung als gelöst
Veraltet
YoyoNow
hat
Also von einem static block war nicht die rede nur den static modifier. Also sowas wie 'private static ForgeData forgeData = new ForgeData();'. Also von einem static block war nicht die rede nur den static modifier. Also sowas wie 'private static ForgeData forgeData = new ForgeData();'.
YoyoNow
hat
Wo wird das überhaupt genutzt? Wo wird das überhaupt genutzt?
Lixfel
hat
GSON-Serializer des ServerListPings. Anmerkung meinerseits: Ob das korrekt serialisiert wird, wenn die ForgeData als static final deklariert wird, muss getestet werden. GSON-Serializer des ServerListPings.
Anmerkung meinerseits: Ob das korrekt serialisiert wird, wenn die ForgeData als static final deklariert wird, muss getestet werden.
YoyoNow
hat
Naja es ist static also gar nicht serializiert? Ansonsten mach halt mit einem instance ansatz, im ForgeData selber. Naja es ist static also gar nicht serializiert? Ansonsten mach halt mit einem instance ansatz, im ForgeData selber.
Lixfel
hat
Ist unbekannt ob, muss daher getestet werden. Ist unbekannt ob, muss daher getestet werden.
Lixfel
hat
Ich glaube, das muss weiterhin forgeData heißen, ansonsten erkennt Forge die Modliste nicht... du solltest auch mal probieren, mit Minecraft-Versionen anders als 1.15.2, ob dann immer noch die Kompatibilität gemeldet wird (da wir ja minecraft 1.15.2 als Mod drin haben... Ich glaube, das muss weiterhin forgeData heißen, ansonsten erkennt Forge die Modliste nicht... du solltest auch mal probieren, mit Minecraft-Versionen anders als 1.15.2, ob dann immer noch die Kompatibilität gemeldet wird (da wir ja minecraft 1.15.2 als Mod drin haben...
zOnlyKroks
hat
static mact hier in diesem Falle nur probleme static mact hier in diesem Falle nur probleme
zOnlyKroks
hat
Kompatibilität wird verneint. Forge 1.16.5 Kompatibilität wird verneint. Forge 1.16.5
|
||||
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<>();
|
||||
YoyoNow
hat
Style? Style?
|
||||
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;
|
||||
}
|
||||
Lixfel
hat
Wäre es nicht einfacher, statt dem Enum einfach direkt eine HashMap<Integer, String> zu machen? Wäre es nicht einfacher, statt dem Enum einfach direkt eine HashMap<Integer, String> zu machen?
|
||||
}
|
||||
}
|
||||
}
|
@ -22,102 +22,112 @@ 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.api.connection.PendingConnection;
|
||||
import net.md_5.bungee.api.event.LoginEvent;
|
||||
import net.md_5.bungee.api.event.ProxyPingEvent;
|
||||
import net.md_5.bungee.connection.InitialHandler;
|
||||
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.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class Forge extends BasicListener {
|
||||
|
||||
private static final String FMLHS = "FML|HS";
|
||||
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 String WRAPPER = "fml:loginwrapper";
|
||||
|
||||
private static final Field initialHandlerCh;
|
||||
static{
|
||||
ByteBuf buf = UnpooledByteBufAllocator.DEFAULT.directBuffer(7);
|
||||
buf.writeByte(6);
|
||||
buf.writeCharSequence(FMLHS, StandardCharsets.UTF_8);
|
||||
REGISTER = new byte[buf.readableBytes()];
|
||||
buf.readBytes(REGISTER);
|
||||
|
||||
buf.clear();
|
||||
buf.writeByte(13);
|
||||
buf.writeCharSequence(FMLHS13, StandardCharsets.UTF_8);
|
||||
REGISTER13 = new byte[buf.readableBytes()];
|
||||
buf.readBytes(REGISTER13);
|
||||
try {
|
||||
initialHandlerCh = InitialHandler.class.getDeclaredField("ch");
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new SecurityException("Could not initialize Reflection", e);
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Bitte nicht vergessen, den alten 1.13 Forge-Support auszubauen :) (Aber bitte den 1.12- Support drin lassen!) Du kannst dann auch ich glaube im Fabric-Modhandler? den Arenenblock für Forge-Spieler ausbauen. Bitte nicht vergessen, den alten 1.13 Forge-Support auszubauen :) (Aber bitte den 1.12- Support drin lassen!)
Du kannst dann auch ich glaube im Fabric-Modhandler? den Arenenblock für Forge-Spieler ausbauen.
|
||||
}
|
||||
initialHandlerCh.setAccessible(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPostLogin(PostLoginEvent event) {
|
||||
ProxiedPlayer player = event.getPlayer();
|
||||
public void onServerPing(ProxyPingEvent event) {
|
||||
event.setResponse(new FMLPing(event.getResponse(), event.getConnection().getVersion()));
|
||||
}
|
||||
|
||||
synchronized (unlocked) {
|
||||
if(unlocked.contains(player.getUniqueId())){
|
||||
unlocked.remove(player.getUniqueId());
|
||||
@EventHandler
|
||||
public void onServerConnected(LoginEvent event){
|
||||
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);
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Die Kommentarzeile (und ggf. noch die Zeilen drüber) können weg. Die Kommentarzeile (und ggf. noch die Zeilen drüber) können weg.
|
||||
} catch (IllegalAccessException e) {
|
||||
BungeeCore.get().getLogger().log(Level.SEVERE, "Could not get Channel", e);
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Hier vorher noch eine Prüfung, dass der Client 1.13 oder höhere Version hat (in dem Fall einfach return). 1.12 und niedriger kennt nämlich keine LoginPayloadRequests. Hier vorher noch eine Prüfung, dass der Client 1.13 oder höhere Version hat (in dem Fall einfach return). 1.12 und niedriger kennt nämlich keine LoginPayloadRequests.
|
||||
return;
|
||||
}
|
||||
|
||||
event.registerIntent(BungeeCore.get());
|
||||
wrapper.getHandle().pipeline().get(HandlerBoss.class).setHandler(new CustomPacketHandler(event));
|
||||
}
|
||||
|
||||
private static class CustomPacketHandler extends PacketHandler {
|
||||
private final LoginEvent event;
|
||||
|
||||
public CustomPacketHandler(LoginEvent event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Ach ja, hier einen ordentlichen Logger benutzen, so wie BungeeCore.get().getLogger().log(Level.SEVERE, "Could not get Channel", e); Und danach returnen. Und vllt. auch erst nach der Reflection den Intent registrieren... Ach ja, hier einen ordentlichen Logger benutzen, so wie BungeeCore.get().getLogger().log(Level.SEVERE, "Could not get Channel", e);
Und danach returnen.
Und vllt. auch erst nach der Reflection den Intent registrieren...
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
//for more information see https://wiki.vg/Minecraft_Forge_Handshake#FML2_protocol_.281.13_-_Current.29
|
||||
Utils.VarInt channelLength = Utils.readVarInt(data, 0);
|
||||
int pos = channelLength.length;
|
||||
assert new String(data, pos, channelLength.value).equals("fml:handshake");
|
||||
|
||||
@EventHandler
|
||||
public void onPluginMessageEvent(PluginMessageEvent e){
|
||||
if(!e.getTag().equals(FMLHS) && !e.getTag().equals(FMLHS13))
|
||||
return;
|
||||
Utils.VarInt length = Utils.readVarInt(data, pos);
|
||||
pos += length.length;
|
||||
assert channelLength.length + channelLength.value + length.length + length.value == data.length;
|
||||
|
||||
e.setCancelled(true);
|
||||
byte[] data = e.getData();
|
||||
Utils.VarInt packetId = Utils.readVarInt(data, pos);
|
||||
pos += packetId.length;
|
||||
assert packetId.value == 2;
|
||||
|
||||
Connection sender = e.getSender();
|
||||
if(!(sender instanceof ProxiedPlayer))
|
||||
return;
|
||||
ProxiedPlayer p = (ProxiedPlayer) sender;
|
||||
Utils.VarInt modCount = Utils.readVarInt(data, pos);
|
||||
pos += modCount.length;
|
||||
|
||||
if (data[0] == 2) {
|
||||
Utils.VarInt numMods = Utils.readVarInt(data, 1);
|
||||
List<Mod> mods = new LinkedList<>();
|
||||
List<Mod> mods = new ArrayList<>();
|
||||
for(int i = 0; i < modCount.value; i++) {
|
||||
Utils.VarInt nameLength = Utils.readVarInt(data, pos);
|
||||
pos += nameLength.length;
|
||||
|
||||
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));
|
||||
mods.add(Mod.get(new String(data, pos, nameLength.value), Mod.Platform.FORGE));
|
||||
pos += nameLength.value;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
PendingConnection connection = event.getConnection();
|
||||
if(Utils.handleMods(connection.getUniqueId(), Locale.getDefault(), connection::disconnect, mods))
|
||||
event.completeIntent(BungeeCore.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
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
|
||||
public void onDisconnect(PlayerDisconnectEvent e){
|
||||
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.Punishment;
|
||||
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 java.sql.Timestamp;
|
||||
@ -32,6 +34,9 @@ import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
class Utils {
|
||||
@ -55,9 +60,13 @@ class Utils {
|
||||
return new VarInt(numRead, result);
|
||||
}
|
||||
|
||||
static boolean handleMods(ProxiedPlayer player, List<Mod> mods){
|
||||
SteamwarUser user = SteamwarUser.get(player.getUniqueId());
|
||||
boolean privileged = player.hasPermission("bungeecore.youtubermods");
|
||||
static boolean handleMods(ProxiedPlayer player, List<Mod> mods) {
|
||||
return handleMods(player.getUniqueId(), player.getLocale(), player::disconnect, mods);
|
||||
}
|
||||
|
||||
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;
|
||||
Iterator<Mod> it = mods.iterator();
|
||||
@ -74,9 +83,9 @@ class Utils {
|
||||
|
||||
if(mods.size() == 1){
|
||||
if(max == ModType.YELLOW)
|
||||
player.disconnect(BungeeCore.stringToText(Message.parse("MOD_YELLOW_SING", player, mods.get(0).getModName())));
|
||||
disconnect.accept(TextComponent.fromLegacyText(Message.parse("MOD_YELLOW_SING", locale, mods.get(0).getModName())));
|
||||
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);
|
||||
user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), Message.parse("MOD_RED_SING", locale, 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{
|
||||
@ -84,10 +93,10 @@ class Utils {
|
||||
mods.forEach(mod -> sb.append(mod.getModName()).append('\n'));
|
||||
|
||||
if(max == ModType.YELLOW)
|
||||
player.disconnect(BungeeCore.stringToText(Message.parse("MOD_YELLOW_PLUR", player, sb.toString())));
|
||||
disconnect.accept(TextComponent.fromLegacyText(Message.parse("MOD_YELLOW_PLUR", locale, sb.toString())));
|
||||
else{
|
||||
user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), Message.parse("MOD_RED_PLUR", player, sb.toString()), 0, false);
|
||||
BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + sb.toString() + " gebannt.");
|
||||
user.punish(Punishment.PunishmentType.Ban, Timestamp.from(Instant.now().plus(7, ChronoUnit.DAYS)), Message.parse("MOD_RED_PLUR", locale, sb.toString()), 0, false);
|
||||
BungeeCore.log(Level.SEVERE, user.getUserName() + " " + user.getId() + " wurde automatisch wegen der Mods " + sb + " gebannt.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,26 +24,28 @@ import java.util.stream.Collectors;
|
||||
|
||||
public enum UserGroup {
|
||||
|
||||
Admin("§4", "§e", true, true, true),
|
||||
Developer("§3", "§f", true, true, true),
|
||||
Moderator("§c", "§f", true, true, true),
|
||||
Supporter("§9", "§f", false, true, true),
|
||||
Builder("§2", "§f", false, true, false),
|
||||
YouTuber("§5", "§f", false, false, false),
|
||||
Member("§7", "§7", false, false, false);
|
||||
Admin("§4", "§e", true, true, true, true),
|
||||
Developer("§3", "§f", true, true, true, true),
|
||||
Moderator("§c", "§f", true, true, true, true),
|
||||
Supporter("§9", "§f", false, true, true, true),
|
||||
Builder("§2", "§f", false, true, false, true),
|
||||
YouTuber("§5", "§f", false, false, false, true),
|
||||
Member("§7", "§7", false, false, false, false);
|
||||
|
||||
private final String colorCode;
|
||||
private final String chatColorCode;
|
||||
private final boolean adminGroup;
|
||||
private final boolean teamGroup;
|
||||
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.chatColorCode = chatColorCode;
|
||||
this.adminGroup = adminGroup;
|
||||
this.teamGroup = teamGroup;
|
||||
this.checkSchematics = checkSchematics;
|
||||
this.privilegedMods = privilegedMods;
|
||||
}
|
||||
|
||||
public String getColorCode() {
|
||||
@ -62,6 +64,10 @@ public enum UserGroup {
|
||||
return checkSchematics;
|
||||
}
|
||||
|
||||
public boolean privilegedMods() {
|
||||
return privilegedMods;
|
||||
}
|
||||
|
||||
public String getChatColorCode() {
|
||||
return chatColorCode;
|
||||
}
|
||||
|
Fehlender License-Header