Yes, my title sounds like I'm insane, but bear with me.
I'm trying to log everything a Minecraft Forge mod sends via its SimpleNetworkWrapper
instance. To do this, I'm wrapping the instance in a dummy class and inserting the dummy instance into the mod via reflection.
Dummy class:
package net.benjaminurquhart.decimated;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.Packet;
public class FakeNetworkWrapper extends SimpleNetworkWrapper {
private SimpleNetworkWrapper real;
public FakeNetworkWrapper() {
super("ctx");
}
protected void setChannel(SimpleNetworkWrapper channel) {
this.real = channel;
}
@Override
public Packet getPacketFrom(IMessage message) {
return real.getPacketFrom(message);
}
@Override
public void sendToAll(IMessage message) {
real.sendToAll(message);
}
@Override
public void sendTo(IMessage message, EntityPlayerMP player) {
real.sendTo(message, player);
}
@Override
public void sendToServer(IMessage message) {
// Intercept messages here, do logging stuff
real.sendToServer(message);
}
}
The problem is, the superclass constructor creates a new packet channel with the given name (in this case, ctx
). This breaks the real channel, since I'm creating a new channel with the same name. I can't omit the super call since there's no default constructor, and I prefer not to make a new unused channel with a different name.
Currently, I'm getting around the constructor by using Unsafe
:
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
unsafe = (Unsafe) unsafeField.get(null);
FakeNetworkWrapper wrapper = (FakeNetworkWrapper) unsafe.allocateInstance(FakeNetworkWrapper.class);
wrapper.setChannel(mod.getPacketChannel());
Obviously, I'd like to not use internal classes.
A quick google search shows that I can use serialization or ReflectionFactory
instead of Unsafe
. ReflectionFactory
is also an internal class and serialization seems overkill. I'd also like to not include dependencies not provided by Forge (like this answer suggests).
Is there a way to somehow bypass a call to the superclass constructor without using internal methods or serialization? Again, I understand this is something I shouldn't be doing, but I don't see another way.
Aucun commentaire:
Enregistrer un commentaire