Event Handling

I was wondering if someone could explain how the forge to sponge event mapping worked? I’m looking to write in some event handling code for the chat event handler. But the implementation seems to use ASM quite a bit and I’m having trouble figuring out how the code works.

So if someone could both explain exactly what ASM is doing and how the implementation maps events that’s what I need.

Note: Perhaps this was unclear, but I’m looking for details about the current Sponge implementation, not how a plugin would do it.

You could look at the example file:
https://github.com/SpongePowered/SpongeAPI/blob/master/src/main/example/main/java/org/spongepowered/example/ExamplePlugin.java

But for chat you need something like this:

    @SpongeEventHandler
    public void onChat(AsyncPlayerChatEvent event) {
        logger.info("A Player said something!");
    }

So far I know it doesn’t matter where you place the method, and you also don’t have to register it. (correct me when I am wrong).

I’m not talking about for making a plugin, that event can’t register yet because the current Sponge implementation doesn’t handle a forge chat event. I’m looking at how the current Sponge implementation can be extended to map the forge event.

Oh got ya,
Well I did it before, you need something like this:

Basicly you say what class the forge event has to implement. But don’t be surprised if you get abstractmethodexception because most of the methods aren’t created yet. You could use mixings to make them work.

1 Like

Can you explain that a bit more? I’m pretty new to low level java like this, so I’m trying to learn it. What are mixins exactly? I’ve looked at that file before, but I’m not sure what exactly it’s doing. How do I match up the arguments for the events?

Mixins make it possible to change minecraft base classes without writing the bytecode. Sponge uses mixins because managing bytecode is not funny and maintainable. Also you will have to change brand if you want to use them.

It may be better if you read the description on the example file for mixins:
https://github.com/SpongePowered/Sponge/blob/feature/mixins/src/main/java/org/spongepowered/mixin/impl/MixinWorld.java

Also when playing with mixins don’t forget to register your mixing class here:
https://github.com/SpongePowered/Sponge/blob/feature/mixins/src/main/resources/mixins.sponge.json

1 Like

Ah thanks, very helpful. We should keep a post like this pinned for people who want to start working on this. No need to duplicate this effort.

Also mixins aren’t part of sponge by default, it’s still in a branch, any reason for this?

I wouldn’t know I am not a Sponge Dev :wink:. I suppose they made this feature on a different branch because they where unsure how they would do it.

Also its on PR, But I would be surprised if it doesn’t get accepted.

I just started messing around with the pre-existing event mapping stuff, but lets say I wanted to make a command listening event that just forwarded the whole string to the event handler. How would I map the methods to the forge event? Sorry about all the questions, I’ve never really looked into this class mapping and ASM stuff.

events.put("net.minecraftforge.event.ServerChatEvent", AsyncPlayerChatEvent.class);

Seems you are unaware of the selection ability of gist xD. What is fine it also took me a while to notice it. If you click the link you will see that line 70 is selected :wink:.

And then if I needed to modify the forge event to fit the Sponge event? Do I have to use mixins to do that?

Yes for the methods you need a mixin I guess. I wrote a mixin class to explain (not tested, but this is as it should work). Be aware that you don’t need to implement methods from the Event class. The event transformer already implement those.

package org.spongepowered.mixin.impl;

import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraftforge.event.ServerChatEvent;
import org.spongepowered.api.entity.Player;
import org.spongepowered.api.event.player.AsyncPlayerChatEvent;
import org.spongepowered.mod.mixin.Mixin;
import org.spongepowered.mod.mixin.Shadow;


@Mixin(ServerChatEvent.class)
public abstract class MixinServerChatEvent implements AsyncPlayerChatEvent {

    @Shadow public String message;
    @Shadow public EntityPlayerMP player;
    
    @Override
    public String getMessage() {
        return message; //this will work
    }

    @Override
    public Player getPlayer() {
        return (Player) player; //This will crash until Player has a mixin 
    }
} 
1 Like

Awesome thanks, I can’t wait for Mixins to become core.

Me either :cat: xD. But ya they are waiting on Forge 1.8. As it is unknown of the events will still be there (I suppose they will).

Also note: For the chat event this implementation is wrong. Because the event should be asynchronous.

Finally got the chat event to work without mixins. Turns out I have to add the registration in two places to get it to be ASM transformed.

1 Like

Now I just want to know what the BlockEvent class visitor is doing.

Sorry I can’t find that part.

https://github.com/SpongePowered/Sponge/blob/master/src/main/java/org/spongepowered/mod/asm/util/ASMEventListenerHolderFactory.java

You’ll have to open the truncated file, but this is the file.

Honestly no idea what it is doing. Looks hacky. Meaby @Raphfrk could explain it?