wip: trying to increase the number of versions this works with

Need to check other mc versions to make sure the debug packet is still processed right
This commit is contained in:
Sekwah 2024-11-21 09:30:25 +00:00
parent 60085d2c77
commit d42fbd67c5
No known key found for this signature in database
2 changed files with 118 additions and 4 deletions

View File

@ -37,6 +37,8 @@ shadowJar {
relocate 'org.aopalliance', 'com.sekwah.advancedportals.shadowed.aopalliance'
relocate 'org.checkerframework', 'com.sekwah.advancedportals.shadowed.checkerframework'
exclude 'io/netty/**'
minimize()
archiveClassifier.set('')

View File

@ -1,7 +1,16 @@
package com.sekwah.advancedportals.spigot.reflection;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.sekwah.advancedportals.spigot.AdvancedPortalsPlugin;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.bukkit.entity.Player;
/**
@ -12,6 +21,75 @@ import org.bukkit.entity.Player;
* showing visuals of the portals and such
*/
public class MinecraftCustomPayload {
public static Field playerConnectionField = null;
private static Field getFieldFromType(String fieldType, Object obj) throws IllegalAccessException, NoSuchFieldException {
for (var field : obj.getClass().getDeclaredFields()) {
if (field.getType().getName().equals(fieldType)) {
field.setAccessible(true);
return field;
}
}
throw new NoSuchFieldException("Field with type " + fieldType + " not found in object");
}
private static void outputAllMethodsToFile(Class clazz) throws IOException {
var pluginInstance = AdvancedPortalsPlugin.getInstance();
var dataFolder = pluginInstance.getDataFolder();
// Create a "debug" folder inside the plugin's data folder
File debugFolder = new File(dataFolder, "debug");
if (!debugFolder.exists() && !debugFolder.mkdirs()) {
pluginInstance.getLogger().severe("Failed to create debug folder!");
return;
}
// Name the file after the class name
String fileName = clazz.getSimpleName() + ".txt";
File outputFile = new File(debugFolder, fileName);
try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
// Output the class name
writer.write("Class: " + clazz.getName());
writer.newLine();
// Output constructors and their parameter types
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
writer.write("Constructor: " + constructor.getName());
writer.newLine();
for (Class<?> parameterType : constructor.getParameterTypes()) {
writer.write(" Parameter: " + parameterType.getName());
writer.newLine();
}
}
// Output each method and its parameter types
for (Method method : clazz.getDeclaredMethods()) {
writer.write("Method: " + method.getName());
writer.newLine();
for (Class<?> parameterType : method.getParameterTypes()) {
writer.write(" Parameter: " + parameterType.getName());
writer.newLine();
}
}
// Also output all of the fields
for (var field : clazz.getDeclaredFields()) {
writer.write("Field: " + field.getName());
writer.write(" Type: " + field.getType().getName());
writer.newLine();
}
} catch (IOException e) {
pluginInstance.getLogger().severe("Failed to write methods to file: " + e.getMessage());
e.printStackTrace();
}
}
private static void outputAllMethodsToFile(Object obj) throws IOException {
outputAllMethodsToFile(obj.getClass());
}
public static boolean sendCustomPayload(Player player, String channel,
byte[] data) {
try {
@ -20,10 +98,45 @@ public class MinecraftCustomPayload {
Class.forName("net.minecraft.resources.MinecraftKey");
Constructor<?> minecraftKeyConstructor =
minecraftKeyClass.getConstructor(String.class);
// Create an instance of MinecraftKey with the channel name
Object minecraftKey = minecraftKeyConstructor.newInstance(channel);
/*
// Call and get the value from player.getClass() getHandle
Method getHandleMethod = player.getClass().getDeclaredMethod("getHandle");
Object playerHandle = getHandleMethod.invoke(player);
outputAllMethodsToFile(playerHandle);
if(playerConnectionField == null) {
playerConnectionField = getFieldFromType("net.minecraft.server.network.PlayerConnection", playerHandle);
}
// Get the value of field with type net.minecraft.server.network.PlayerConnection
Object playerConnection = playerConnectionField.get(playerHandle);
Class<?> customPacketPayload =
Class.forName("net.minecraft.network.protocol.game.PacketPlayInCustomPayload");
Class<?> packetDataSerializer =
Class.forName("net.minecraft.network.PacketDataSerializer");
outputAllMethodsToFile(customPacketPayload);
outputAllMethodsToFile(packetDataSerializer);
var unpooledData = Unpooled.wrappedBuffer(data);
var packetData = packetDataSerializer.getConstructor(ByteBuf.class).newInstance(unpooledData);
Constructor<?> customPacketPayloadConstructor = customPacketPayload.getConstructor(minecraftKeyClass, packetDataSerializer);
Object customPayload = customPacketPayloadConstructor.newInstance(minecraftKey, packetData);
// Get method with name a and parameter types PacketPlayInCustomPayload
Method sendPacketMethod = playerConnection.getClass().getDeclaredMethod("a", customPacketPayload);
// Send the packet on this method
sendPacketMethod.invoke(playerConnection, customPayload);*/
// Access the sendCustomPayload method in the CraftPlayer class
Method sendCustomPayloadMethod =
player.getClass().getDeclaredMethod(
@ -36,11 +149,10 @@ public class MinecraftCustomPayload {
// data
sendCustomPayloadMethod.invoke(player, minecraftKey, data);
return true; // Successfully sent the custom payload
return true;
} catch (Exception e) {
// Catch any reflection-related errors
e.printStackTrace();
return false; // Return false if there was an error
return false;
}
}
}