Forge Mod detection #292
44
src/de/steamwar/bungeecore/listeners/mods/CustomPacketHandler.java
Normale Datei
@ -0,0 +1,44 @@
|
||||
package de.steamwar.bungeecore.listeners.mods;
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
|
||||
|
||||
import de.steamwar.bungeecore.BungeeCore;
|
||||
import de.steamwar.bungeecore.sql.Mod;
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.LoginEvent;
|
||||
import net.md_5.bungee.api.event.PreLoginEvent;
|
||||
import net.md_5.bungee.api.plugin.Event;
|
||||
import net.md_5.bungee.netty.ChannelWrapper;
|
||||
import net.md_5.bungee.netty.PacketHandler;
|
||||
import net.md_5.bungee.protocol.packet.LoginPayloadResponse;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class CustomPacketHandler extends PacketHandler {
|
||||
|
||||
private LoginEvent event;
|
||||
private ChannelWrapper wrapper;
|
||||
|
||||
public CustomPacketHandler(LoginEvent event, ChannelWrapper wrapper) {
|
||||
this.event = event;
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void handle(LoginPayloadResponse response){
|
||||
if(response.getData() == null) {
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Besteht hier wirklich die Notwendigkeit, toString zu überschreiben? Besteht hier wirklich die Notwendigkeit, toString zu überschreiben?
zOnlyKroks
hat
ja, ansonsten meckert intellij rum. ja, ansonsten meckert intellij rum.
|
||||
System.out.println("Data is null with id: " + response.getId() + " , which means Client has no installed mods!");
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Diese Zeile bitte in der Production-Fassung entfernen. Diese Zeile bitte in der Production-Fassung entfernen.
|
||||
event.completeIntent(BungeeCore.get());
|
||||
return;
|
||||
}
|
||||
|
||||
Lixfel
hat
Noch fehlende Modprüfung :) Noch fehlende Modprüfung :)
|
||||
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Ich finde es hier gefährlich, dass du hier den PacketHandler nicht zurück auf den InitialHandler setzt (deshalb hat es wahrscheinlich auch nicht mit dem PreLoginEvent geklappt). Es dürfte aber durch dadurch, dass LoginEvent.completeIntent dazu führt, dass es dann entweder einen Disconnect oder direkt den PlayHandler gibt, egal sein. Daher entweder den Packethandler zurücksetzen oder sich gar nicht hier den Wrapper merken (wozu brauchst du den sonst hier). Ich finde es hier gefährlich, dass du hier den PacketHandler nicht zurück auf den InitialHandler setzt (deshalb hat es wahrscheinlich auch nicht mit dem PreLoginEvent geklappt).
Es dürfte aber durch dadurch, dass LoginEvent.completeIntent dazu führt, dass es dann entweder einen Disconnect oder direkt den PlayHandler gibt, egal sein. Daher entweder den Packethandler zurücksetzen oder sich gar nicht hier den Wrapper merken (wozu brauchst du den sonst hier).
|
||||
event.completeIntent(BungeeCore.get());
|
||||
}
|
||||
}
|
48
src/de/steamwar/bungeecore/listeners/mods/FMLPing.java
Normale Datei
@ -0,0 +1,48 @@
|
||||
package de.steamwar.bungeecore.listeners.mods;
|
||||
zOnlyKroks markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Fehlender License-Header Fehlender License-Header
|
||||
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FMLPing extends ServerPing {
|
||||
private final ForgeData forgeData = new ForgeData();
|
||||
|
||||
public FMLPing(ServerPing existing) {
|
||||
super(existing.getVersion(), existing.getPlayers(), existing.getDescriptionComponent(), existing.getFaviconObject());
|
||||
}
|
||||
|
||||
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() {
|
||||
channels.add(new ForgeChannel("minecraft:unregister"));
|
||||
channels.add(new ForgeChannel("minecraft:register"));
|
||||
channels.add(new ForgeChannel("fml:handshake"));
|
||||
mods.add(new ForgeMod("minecraft", "1.15.2"));
|
||||
mods.add(new ForgeMod("forge", "ANY"));
|
||||
}
|
||||
|
||||
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.
|
||||
private static class ForgeChannel {
|
||||
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
|
||||
private final String res;
|
||||
private final String version = "FML2";
|
||||
private final boolean required = true;
|
||||
|
||||
private ForgeChannel(String res) {
|
||||
this.res = res;
|
||||
}
|
||||
}
|
||||
YoyoNow
hat
Style? Style?
|
||||
|
||||
private static class ForgeMod {
|
||||
private final String modId;
|
||||
private final String modmarker;
|
||||
|
||||
private ForgeMod(String modId, String modmarker) {
|
||||
this.modId = modId;
|
||||
this.modmarker = modmarker;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -27,10 +27,17 @@ 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.LoginEvent;
|
||||
import net.md_5.bungee.api.event.PluginMessageEvent;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
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.protocol.packet.LoginPayloadRequest;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -39,6 +46,7 @@ public class Forge extends BasicListener {
|
||||
|
||||
private static final String FMLHS = "FML|HS";
|
||||
private static final String FMLHS13 = "fml:handshake";
|
||||
private static final String WRAPPER = "fml:loginwrapper";
|
||||
private static final byte[] REGISTER;
|
||||
private static final byte[] REGISTER13;
|
||||
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.
|
||||
private static final byte[] HELLO = new byte[]{0, 2, 0, 0, 0, 0};
|
||||
@ -58,6 +66,36 @@ public class Forge extends BasicListener {
|
||||
buf.readBytes(REGISTER13);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onServerConnected(LoginEvent event){
|
||||
//Wir senden Packet ID 1
|
||||
//Wir wollen empfangen Packet ID 2
|
||||
//(FMLHS13, new byte[]{4, 1, 0, 0, 0});
|
||||
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.
|
||||
//13,102,109,108,58,104,97,110,100,115,104,97,107,101 = 13 + "fml:handshake"
|
||||
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}));
|
||||
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.
|
||||
event.registerIntent(BungeeCore.get());
|
||||
|
||||
|
||||
InitialHandler handler = (InitialHandler) event.getConnection();
|
||||
|
||||
Field ch;
|
||||
ChannelWrapper wrapper = null;
|
||||
|
||||
try{
|
||||
ch = handler.getClass().getDeclaredField("ch");
|
||||
ch.setAccessible(true);
|
||||
wrapper = (ChannelWrapper) ch.get(handler);
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
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...
|
||||
}
|
||||
wrapper.getHandle().pipeline().get(HandlerBoss.class).setHandler(new CustomPacketHandler(event, wrapper));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onServerPing(ProxyPingEvent event) {
|
||||
event.setResponse(new FMLPing(event.getResponse()));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPostLogin(PostLoginEvent event) {
|
||||
ProxiedPlayer player = event.getPlayer();
|
||||
|
Fehlender License-Header