Jump to content

[1.7.10] How to use a proxy?


czaarek99

Recommended Posts

Here is all my code (in the spoiler).

 

 

My main class:

package com.czaarek99.FrameMod;

/**
* Created by Czarek on 2014-08-09.
*/
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.PlayerEvent;
import net.minecraftforge.common.MinecraftForge;


import java.lang.String;




@Mod(modid = FrameMod.modid, version = FrameMod.version)
public class FrameMod {

    public static final String modid = "FrameMod";
    public static final String version = "1.0 ALPHA";


    EventHandler events = new EventHandler();


    @SidedProxy(clientSide = "com.czaarek99.FrameMod.ClientProxy",serverSide = "com.czaarek99.FrameMod.ServerProxy")
    public static ServerProxy proxy;



    @Mod.EventHandler
    public void PreLoad(FMLPreInitializationEvent event){
        proxy.registerRenderThings();
        FMLCommonHandler.instance().bus().register(events);
        MinecraftForge.EVENT_BUS.register(events);

    }
    }



 

My EventHandler class:

package com.czaarek99.FrameMod;

import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.event.entity.player.AttackEntityEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;


/**
* Created by Czarek on 2014-08-09.
*/
public class EventHandler {
    @SubscribeEvent
    public void getName(PlayerEvent.NameFormat event) {
        if(event.username.equals("epicjellybean3")) event.displayname="swagmaster";
    }

}



 

My Clientproxy class:

package com.czaarek99.FrameMod;

/**
* Created by Czarek on 2014-08-09.
*/
public class ClientProxy extends ServerProxy  {

    @Override
    public void registerRenderThings() {

    }

}

 

My serverproxy class

package com.czaarek99.FrameMod;

/**
* Created by Czarek on 2014-08-09.
*/
public class ServerProxy {

    public void registerRenderThings() {

    }

}

 

 

 

(The name of the mod is FrameMod because I was first going to do something with itemframes but I changed my mind and was too lazy to change names and stuff)

 

Anyway, as you can see I am trying to replace someones name with something else. This does work good in singleplayer. But it does not work in Multiplayer. I am nearly certain I have to do something with the proxy to get this to work. Just how? There are tutorials on how to code these classes but not the use.

 

How should I go about doing this?

Link to comment
Share on other sites

I just learned this proxy stuff last week, so I know just enough to be dangerous  ;)

 

By custom, the parent proxy is called "CommonProxy".  That's because there probably isn't anything that runs *only* on the server. Calling it CommonProxy will make it easier for the rest of us to read your code.

 

When Forge loads your mod, it will instantiate your proxy variable for you, using reflection to employ the client-side or server-side class that you specified. With your client-side class overriding the parent CommonProxy methods, it will do all of the "dirty work", assuring that SideOnly classes are only touched in the client.

 

If there's nothing bad happening in your parent's methods, then have your client methods call their supers.

 

Since "proxy" means "stand-in for my main mod class", you'll gain clarity if you name your proxy's methods in accordance with the methods (PreLoad, Load, PostLoad) in FrameMod. Then each of those event handlers can simply call its corresponding proxy method.

 

Note: In some cases (e.g. if you use reflection yourself), the mere presence of an unused import statement (of a client-only class) can blow up the server. I've seen a rule that client-only classes should only be imported into client proxies. However, runtime exception checker is usually more forgiving as long as you don't instantiate the client-only class or reflect  the importing class at runtime on the server. Just know that you'd be playing with fire.

 

PS: I had to do my event-listener bus-registrations in my PostInit, but I can't remember why. YMMV

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

I just learned this proxy stuff last week, so I know just enough to be dangerous  ;)

 

By custom, the parent proxy is called "CommonProxy".  That's because there probably isn't anything that runs *only* on the server. Calling it CommonProxy will make it easier for the rest of us to read your code.

 

When Forge loads your mod, it will instantiate your proxy variable for you, using reflection to employ the client-side or server-side class that you specified. With your client-side class overriding the parent CommonProxy methods, it will do all of the "dirty work", assuring that SideOnly classes are only touched in the client.

 

If there's nothing bad happening in your parent's methods, then have your client methods call their supers.

 

Since "proxy" means "stand-in for my main mod class", you'll gain clarity if you name your proxy's methods in accordance with the methods (PreLoad, Load, PostLoad) in FrameMod. Then each of those event handlers can simply call its corresponding proxy method.

 

Note: In some cases (e.g. if you use reflection yourself), the mere presence of an unused import statement (of a client-only class) can blow up the server. I've seen a rule that client-only classes should only be imported into client proxies. However, runtime exception checker is usually more forgiving as long as you don't instantiate the client-only class or reflect  the importing class at runtime on the server. Just know that you'd be playing with fire.

 

PS: I had to do my event-listener bus-registrations in my PostInit, but I can't remember why. YMMV

 

Maybe Im retarded, but could you show me some example code of how you would do what I am trying to do? Since I still can't get it to work :/

 

Since I only have basic java knowledge I don't really understand all these fancy words, showing me a piece of code would make me it easier for me to understand your point and I'd learn a lot more too :)

Link to comment
Share on other sites

You already have the code, but I'd suggest changing the name of your "ServerProxy" to "CommonProxy" , and rename your "registerRenderThings" to whatever event-handling method name calls it from your main mod class.

 

Then if possible, have each override-method in ClientProxy call the same-named method in CommonProxy like this:

 

  @Override
public class ClientProxy extends CommonProxy {
  public void init(FMLInitializationEvent e) {
    super.init (e);
    
    // Register client-specific stuff (e.g. renderer & packet-handler callback etc)
  }
}

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

You already have the code, but I'd suggest changing the name of your "ServerProxy" to "CommonProxy" , and rename your "registerRenderThings" to whatever event-handling method name calls it from your main mod class.

 

Then if possible, have each override-method in ClientProxy call the same-named method in CommonProxy like this:

 

  @Override
public class ClientProxy extends CommonProxy {
  public void init(FMLInitializationEvent e) {
    super.init (e);
    
    // Register client-specific stuff (e.g. renderer & packet-handler callback etc)
  }
}

Thanks, hmm. It doesn't seem to be possible to put these guys into the registerRenderThings method though?

And if I remove it the

 

proxy.registerRenderThings();

 

Line in my main class complains? Am I not supposed to have everything in that method? Anyway, is there any way to fix this?

Link to comment
Share on other sites

If you change the method name to "init" in the proxy class, then you would call proxy.init from within in your main's init method.

 

If that's news to you, then you need to take a timeout to get a one-quarter "Intro to Programming" course at school (or at a local Jr college). It doesn't need to be Java, but it should be at least an object-oriented language like C++. Alternatively, you might ask a programmer friend to partner with you, at least to start. Such a friend could help you to separate the programming concepts from the Minecraft and Forge concepts (and overcome them).

 

If you don't have some programming background on arrival here, then some folks might lose patience. As it says in the forum description, this is a Forge help forum, not a Java help forum. I'm not saying that to be snarky or mean but to give fair warning.

 

Incidentally, like my signature says, I arrived in mid-May with over 25 years of professional programming experience in over a dozen languages (including several O-O, but not Java), but even I found parts of the learning curve to be somewhat steep (I am still struggling to wrap my head around Java's "Reflection" even though I have already used it successfully).

 

A non-programmer coming into this is doomed. You have no basis by which to perceive which aspects of a tutorial are Java style and which are Forge necessity. Get your head above water: Learn the essentials of O-O programming.

 

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

What kind of stuff do you put in the proxy classes?

 

Any methods that need to behave differently on server versus client side, usually because they invoke Minecraft code that is "side only".

 

You can't just check for isRemote because the side only classes and methods aren't even loaded so the Java will fail if it sees code (even code paths that won't ever run) that contain classes that aren't loaded.

 

For example, renderer classes are side only.  But in many mods you need to register renderers.  In that case you might create a method called registerRenderers() and in the CommonProxy that method would not do anything, but in the ClientProxy you would @Override that class and actually register the renderers.

 

Again, in summary, you create two versions of methods with the client only stuff in the client version.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Well, it may not be that you need to learn Java but rather you have to learn to understand what Eclipse is telling you.

 

When it "turns red" if you hover over it Eclipse should pop up with an explanation, and often suggests some fixes (but don't just accept these without understanding why).

 

So what errors specifically are you getting when it turns red?

 

The most important things (after learning Java itself) is to learn to use your IDE to help you and second to learn to look through crash logs to understand what the problem is.  With your IDE, especially when modding, you can follow code back to its declaration, you can quickly find all methods by checking type hierachy, you can understand the use of something by checking the call hierarchy, etc.  Furthermore, with some settings like updating @Override annotations and imports on save can save you a lot of typing.

 

Anyway, be more specific about the errors and then we can help.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

I kinda shuffled everything around, trying to do what jeffrey told me to.

 

 

 

Main class:


package com.czaarek99.FrameMod;

/**
* Created by Czarek on 2014-08-09.
*/
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;



@Mod(modid = FrameMod.modid, version = FrameMod.version)
public class FrameMod {

    public static final String modid = "FrameMod";
    public static final String version = "1.0 ALPHA";



    @SidedProxy(clientSide = "com.czaarek99.FrameMod.ClientProxy")
    public static CommonProxy proxy;


    @Mod.EventHandler
    public void init(FMLInitializationEvent events){
        proxy.init(events);
        FMLCommonHandler.instance().bus().register(events);
        MinecraftForge.EVENT_BUS.register(events);

    }
    @SubscribeEvent
    public void getName(PlayerEvent.NameFormat event) {
        if (event.username.equals("epicjellybean3")) event.displayname = "Spy";
    }
}

CommonProxy class:

package com.czaarek99.FrameMod;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;

/**
* Created by Czarek on 2014-08-12.
*/
public class CommonProxy {
    @Mod.EventHandler
    public void init(FMLInitializationEvent events){
        FMLCommonHandler.instance().bus().register(events);
        MinecraftForge.EVENT_BUS.register(events);
    }

    @SubscribeEvent
    public void getName(PlayerEvent.NameFormat event) {
        if (event.username.equals("epicjellybean3")) event.displayname = "Spy";
    }

}

ClientProxy class:

package com.czaarek99.FrameMod;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;

/**
* Created by Czarek on 2014-08-12.
*/
public class ClientProxy extends CommonProxy {

    @Override
    public void init(FMLInitializationEvent events){
        super.init(events);
    }

    @Override
    public void getName(PlayerEvent.NameFormat event){
        super.getName(event);
    }
}

 

 

Oh, and there are no errors with this setup, it just doesn't work.

Link to comment
Share on other sites

@SidedProxy(clientSide = "com.czaarek99.FrameMod.ClientProxy")

 

Although you don't have a server-only proxy, you still need to define the serverSide , so you give it the CommonProxy like so:

 

@SidedProxy(clientSide = "com.czaarek99.FrameMod.ClientProxy", serverSide = "com.czaarek99.FrameMod.CommonProxy");

 

This way, the server runs just the common proxy, and the client can run both (because the clientProxy can both execute some statements of its own and call its parent's methods using "super"). The statements in the common proxy end up running on both the client and the server. That's why it's called a common proxy -- because its actions are common to both client and server.

 

You probably shouldn't put any @EventHandler attributes inside your proxies. Instead, put those on the methods in your main class and have those methods call their proxy counterparts.

 

Finally, your client proxy shouldn't be empty. Wasn't there something you wanted to do that could only run on the client side? Those statements (and the import statements to support them) belong in the client proxy and its methods.

The debugger is a powerful and necessary tool in any IDE, so learn how to use it. You'll be able to tell us more and get better help here if you investigate your runtime problems in the debugger before posting.

Link to comment
Share on other sites

If they are using IntelliJ IDEA, it auto-corrects it. Or they prefer the former.

-Mitchellbrine

 

Minecraft can do ANYTHING, it's coded in Java and you got the full power of Java behind you when you code. So nothing is impossible.

It may be freaking fucking hard though, but still possible ;)

 

If you create a topic on Modder Support, live by this motto:

I don't want your charity, I want your information
Link to comment
Share on other sites

If they are using IntelliJ IDEA, it auto-corrects it. Or they prefer the former.

Yea, Intelli complains if I put a normal eventhandler.

 

 

@SidedProxy(clientSide = "com.czaarek99.FrameMod.ClientProxy")

 

Although you don't have a server-only proxy, you still need to define the serverSide , so you give it the CommonProxy like so:

 

@SidedProxy(clientSide = "com.czaarek99.FrameMod.ClientProxy", serverSide = "com.czaarek99.FrameMod.CommonProxy");

 

This way, the server runs just the common proxy, and the client can run both (because the clientProxy can both execute some statements of its own and call its parent's methods using "super"). The statements in the common proxy end up running on both the client and the server. That's why it's called a common proxy -- because its actions are common to both client and server.

 

You probably shouldn't put any @EventHandler attributes inside your proxies. Instead, put those on the methods in your main class and have those methods call their proxy counterparts.

 

Finally, your client proxy shouldn't be empty. Wasn't there something you wanted to do that could only run on the client side? Those statements (and the import statements to support them) belong in the client proxy and its methods.

 

I believe I did that, but now forge errors me with this:

http://pastebin.com/cyYsGNqh

 

Anyway, here are my classes. I did everything you told me to.

Main:

 

 

package com.czaarek99.FrameMod;

/**
* Created by Czarek on 2014-08-09.
*/
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;



@Mod(modid = FrameMod.modid, version = FrameMod.version)
public class FrameMod {

    public static final String modid = "FrameMod";
    public static final String version = "1.0 ALPHA";



    @SidedProxy(clientSide = "com.czaarek99.FrameMod.ClientProxy", serverSide = "com.czaarek99.FrameMod.CommonProxy")
    public static CommonProxy proxy;


    @Mod.EventHandler
    public void init(FMLInitializationEvent events){
        proxy.init(events);
        FMLCommonHandler.instance().bus().register(events);
        MinecraftForge.EVENT_BUS.register(events);

    }
    @SubscribeEvent
    public void getName(PlayerEvent.NameFormat event) {
        ClientProxy.getName(event);
    }
}

ClientProxy:

package com.czaarek99.FrameMod;

import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;

/**
* Created by Czarek on 2014-08-12.
*/
public class ClientProxy extends CommonProxy {

    @Override
    public void init(FMLInitializationEvent events){
        super.init(events);
    }

    public static void getName(PlayerEvent.NameFormat event){
        if (event.username.equals("epicjellybean3")) event.displayname = "Spy";
    }
}

CommonProxy:

package com.czaarek99.FrameMod;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;

/**
* Created by Czarek on 2014-08-12.
*/
public class CommonProxy {

    public void init(FMLInitializationEvent events){
        init(events);
    }


}

 

 

I get where the error points, but why?

Link to comment
Share on other sites

You might want to note: package names do not contain or start with CAPITAL letters.

Thanks... But that isn't breaking my mod. Is it?

 

Edit:

I tried renaming it, Intelli did nothing about it. The package still had capital letters.

 

And I'd really like help with the proxies.

Link to comment
Share on other sites

Hi

 

You might find this link useful for some background (it is for 1.6.4 but the concepts are still the same)

 

http://greyminecraftcoder.blogspot.com.au/2013/11/how-forge-starts-up-your-code.html

 

Your error is caused by this

 

    public void init(FMLInitializationEvent events){

        init(events);

    }

 

the init function calls itself recursively.  i.e. it keeps calling itself in an infinite loop until it runs out of stack space.

 

-TGG

 

 

 

Link to comment
Share on other sites

Hi

 

You might find this link useful for some background (it is for 1.6.4 but the concepts are still the same)

 

http://greyminecraftcoder.blogspot.com.au/2013/11/how-forge-starts-up-your-code.html

 

Your error is caused by this

 

    public void init(FMLInitializationEvent events){

        init(events);

    }

 

the init function calls itself recursively.  i.e. it keeps calling itself in an infinite loop until it runs out of stack space.

 

-TGG

That helped fixed the error, thanks.

Now it seems like I have followed ALL the guidelines you guys have told me to but it still wont work?

Here are my classes again:

 

Main:

http://pastebin.com/Jjczu3eZ

ClientProxy:

http://pastebin.com/ygg8uqyV

CommonProxy:

http://pastebin.com/ApdpMMse

Link to comment
Share on other sites

Hi

 

Try following this howTo for events

http://www.minecraftforum.net/forums/archive/tutorials/931112-forge-4-x-events-howto

(Use @SubscribeEvent instead of @ForgeSubscribe)

 

This one is also helpful-

https://github.com/coolAlias/Forge_Tutorials/blob/master/EventHandlerTutorial.java

and

http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/1571567-1-7-2-1-6-4-eventhandler-and

 

You need to register your event handler on the correct bus, which you don't seem to be doing at all.

 

-TGG

Link to comment
Share on other sites

Hi

 

Try following this howTo for events

http://www.minecraftforum.net/forums/archive/tutorials/931112-forge-4-x-events-howto

(Use @SubscribeEvent instead of @ForgeSubscribe)

 

This one is also helpful-

https://github.com/coolAlias/Forge_Tutorials/blob/master/EventHandlerTutorial.java

and

http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/1571567-1-7-2-1-6-4-eventhandler-and

 

You need to register your event handler on the correct bus, which you don't seem to be doing at all.

 

-TGG

 

Hmmm. There is something strange I realized. I did the changes needed.

 

My new classes:

Main:

http://pastie.org/private/dyrw1mqfpdckxnegaiwchw

ClientProxy:

http://pastie.org/private/npsb9ve7dj4ymjxeqcxdja

CommonProxy:

http://pastie.org/private/w7xlokqibik4jcnu6by7a

 

I added some debug prints in the events... And the subscribe event or for the matter any other event doesn't fire when I join multiplayer? (Obviously the init events do but the others though).

When I join singleplayer all the events fire as expected?

Link to comment
Share on other sites

Okay, you're still a little confused.  This is Minecraft-specific stuff so I understand it takes a little time to wrap your head around it.  But you have several issues going on here.

 

First of all, your FrameMod class is your "main" class.  You shouldn't be creating any instances of it anywhere because there should only be one -- but when you registered it as the event handler you created two new instances.  Instead, for the event handler class to register you should make a separate event handler class, put all your methods in that and register that instead.

 

You should read my tutorial on events.  It is a bit long, but covers a lot of what you're getting wrong here: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-event-handling.html

 

Anyway, so basically:

1) create a class called MyEventHandler

2) change the registrations in the CommonProxy init() method to register MyEventHandler (instead of FrameMod)

3) move the getName() method (including the @SubscribeEvent) from the FrameMod class into the MyEventHandler class you just created.

4) Actually I would consider moving the getName() method out of the ClientProxy.  The NameFormat event doesn't have to be client only (or if it is the event would only fire on that side, so no problem).  You only need to put code into the ClientProxy if it *calls* code that is SideOnly for client side.

 

I think that might work.  At least make those changes, read my tutorial, and let's see how far you get.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Okay, you're still a little confused.  This is Minecraft-specific stuff so I understand it takes a little time to wrap your head around it.  But you have several issues going on here.

 

First of all, your FrameMod class is your "main" class.  You shouldn't be creating any instances of it anywhere because there should only be one -- but when you registered it as the event handler you created two new instances.  Instead, for the event handler class to register you should make a separate event handler class, put all your methods in that and register that instead.

 

You should read my tutorial on events.  It is a bit long, but covers a lot of what you're getting wrong here: http://jabelarminecraft.blogspot.com/p/minecraft-forge-172-event-handling.html

 

Anyway, so basically:

1) create a class called MyEventHandler

2) change the registrations in the CommonProxy init() method to register MyEventHandler (instead of FrameMod)

3) move the getName() method (including the @SubscribeEvent) from the FrameMod class into the MyEventHandler class you just created.

4) Actually I would consider moving the getName() method out of the ClientProxy.  The NameFormat event doesn't have to be client only (or if it is the event would only fire on that side, so no problem).  You only need to put code into the ClientProxy if it *calls* code that is SideOnly for client side.

 

I think that might work.  At least make those changes, read my tutorial, and let's see how far you get.

 

I read your tutorial, it showed pretty much the same thing as every other tutorial that I have read so far in 1. I have basically already seen all that. I did what you recommended but my events still refuse to fire in multiplayer. Is there a special way to register events in Multiplayer? Since that is what I am starting to think.

 

And no ones tutorial really shows how to use the events in multiplayer. I tried making a few other events. None fire in multiplayer, never?

 

Here are my classes once again:

package com.czaarek99.FrameMod;

/**
* Created by Czarek on 2014-08-09.
*/
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;



@Mod(modid = FrameMod.modid, version = FrameMod.version)
public class FrameMod {

    public static final String modid = "FrameMod";
    public static final String version = "1.0 ALPHA";



    @SidedProxy(clientSide = "com.czaarek99.FrameMod.ClientProxy", serverSide = "com.czaarek99.FrameMod.CommonProxy")
    public static CommonProxy proxy;



    @Mod.EventHandler
    public void init(FMLInitializationEvent event) {
        proxy.init(event);
        System.out.print("init fired!");
    }



}

 

package com.czaarek99.FrameMod;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;

/**
* Created by Czarek on 2014-08-12.
*/
public class CommonProxy{
    public void init(FMLInitializationEvent events){
        FMLCommonHandler.instance().bus().register(new MyEventHandler());
        MinecraftForge.EVENT_BUS.register(new MyEventHandler());
        System.out.print("common init fired!");


    }
}

 

package com.czaarek99.FrameMod;

import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;

/**
* Created by Czarek on 2014-08-12.
*/
public class ClientProxy extends CommonProxy {

    @Override
    public void init(FMLInitializationEvent events){
        super.init(events);
        System.out.print("client init fired!");

    }


}

 

package com.czaarek99.FrameMod;

import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;

/**
* Created by Czarek on 2014-08-14.
*/
public class MyEventHandler {

    @SubscribeEvent
    public void getName(PlayerEvent.NameFormat nameEvent){
        if (nameEvent.username.equals("epicjellybean3")) {
            nameEvent.displayname = "Spy";
            System.out.print("getname client fired!");
        }


    }

}

Link to comment
Share on other sites

By "multiplayer" do you mean this is a client-only mod?  Like it isn't installed on the server?

 

If that's what you mean, then I guess I'm not sure whether this particular event is fired.  It should be though I think because the call hierarchy for the event shows that it is used in the EntityPlayer class.  This should make it available to EntityPlayerMP because that extends EntityPlayer.

 

EDIT] Maybe one way to figure this out is to print out what side it is firing on.  You can print out event.entityPlayer.worldObj.isRemote() and then run this in the single player case and see what it says.  If it always shows "false" then it is only firing on the server.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

By "multiplayer" do you mean this is a client-only mod?  Like it isn't installed on the server?

 

If that's what you mean, then I guess I'm not sure whether this particular event is fired.  It should be though I think because the call hierarchy for the event shows that it is used in the EntityPlayer class.  This should make it available to EntityPlayerMP because that extends EntityPlayer.

 

EDIT] Maybe one way to figure this out is to print out what side it is firing on.  You can print out event.entityPlayer.worldObj.isRemote() and then run this in the single player case and see what it says.  If it always shows "false" then it is only firing on the server.

 

Yeah, it always prints false... So that means my mod is impossible and the server would need to have it installed?

 

Edit: And yeah, the server won't have the mod installed. Only the client.

 

I have seen hacked clients implementing friends list even without forge. Now, I'd just like to make a fancy friendslist for myself or whatever. I mean... It has to be possible. But what other event or how can I get it to fire?

 

Link to comment
Share on other sites

Okay, I think the next step would be to intercept what the client code regarding names.  Name format is funny because it isn't really cancelable anyway but instead you just change the field value to what you want.  Like for a funny example in my event tutorial I suggested putting the following in the NameEvent to change the way names are displayed:

if (event.username == "myUserName") // put your user name in the string
{
    event.displayname = event.username+" the Great and Powerful";
}        
else if (event.username == "myFriendsUserName") // put your friend's user name in the string
{
    event.displayname = event.username+" the Wise";
}    
else if (event.username == "myGirlFriendsUserName") // put your significant other's user name in the string
{
    event.displayname = event.username+" the Beautiful";
}    
else
{
    event.displayname = event.username+" the Ugly"; // for everyone else            
}

 

The comments say the following about the NameFormat event:

 

This event is fired whenever a player's name is retrieved in

    * EntityPlayer#getDisplayName() or EntityPlayer#refreshDisplayName().<br>

    * <br>

    * This event is fired via the {@link ForgeEventFactory#getPlayerDisplayName(EntityPlayer, String)}.<br>

    * <br>

 

If you follow the call hierarchy, all of this just updates a field in EntityPlayer called displayName.  It is private, but you can change it with Java reflection I think.

 

So what if you did a ClientTickHandler and used Java reflection to inspect and modify (if necessary) the displayName field?

 

I think this would still be limited to Client, so if you want other users to see the effect they'd have to use the mod too probably.

 

If that doesn't work, I think you'd have to try to intercept the chat and the player rendering where they display names.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Hey folks. I am working on a custom "Mecha" entity (extended from LivingEntity) that the player builds up from blocks that should get modular stats depending on the used blocks. e.g. depending on what will be used for the legs, the entity will have a different jump strength. However, something unexpected is happening when trying to override a few of LivingEntity's functions and using my new own "Mecha" specific fields: instead of their actual instance-specific value, the default value is used (0f for a float, null for an object...) This is especially strange as when executing with the same entity from a point in the code specific to the mecha entity, the correct value is used. Here are some code snippets to better illustrate what I mean: /* The main Mecha class, cut down for brevity */ public class Mecha extends LivingEntity { protected float jumpMultiplier; //somewhere later during the code when spawning the entity, jumpMultiplier is set to something like 1.5f //changing the access to public didn't help @Override //Overridden from LivingEntity, this function is only used in the jumpFromGround() function, used in the aiStep() function, used in the LivingEntity tick() function protected float getJumpPower() { //something is wrong with this function //for some reason I can't correctly access the fields and methods from the instanciated entity when I am in one of those overridden protected functions. this is very annoying LogUtils.getLogger().info(String.valueOf(this.jumpMultiplier))) //will print 0f return this.jumpMultiplier * super.getJumpPower(); } //The code above does not operate properly. Written as is, the entity will not jump, and adding debug logs shows that when executing the code, the value of this.jumpMultiplier is 0f //in contrast, it will be the correct value when done here: @Override public void tick() { super.tick(); //inherited LivingEntity logic //Custom logic LogUtils.getLogger().info(String.valueOf(this.jumpMultiplier))) //will print 1.5f } } My actual code is slightly different, as the jumpMuliplier is stored in another object (so I am calling "this.legModule.getJumpPower()" instead of the float), but even using a simple float exactly like in the code above didn't help. When running my usual code, the object I try to use is found to be null instead, leading to a crash from a nullPointerException. Here is the stacktrace of said crash: The full code can be viewed here. I have found a workaround in the case of jump strength, but have already found the same problem for another parameter I want to do, and I do not understand why the code is behaving as such, and I would very much like to be able to override those methods as intended - they seemed to work just fine like that for vanilla mobs... Any clues as to what may be happening here?
    • Please delete post. Had not noticed the newest edition for 1.20.6 which resolves the issue.
    • https://paste.ee/p/GTgAV Here's my debug log, I'm on 1.18.2 with forge 40.2.4 and I just want to get it to work!! I cant find any mod names in the error part and I would like some help from the pros!! I have 203 mods at the moment.
    • In 1.20.6 any potion brewed in the brewing stand disappears upon completion.
    • My game crashes whenever I click on Singleplayer then it crashes after the "Saving world". I'm playing on fabric 1.20.1 on forge for the easy instance loading. My game is using 12GB of RAM, I tried deleting the options.txt, and also renaming the saves file but neither worked. Here's the crash report link: https://mclo.gs/qByOqVK
  • Topics

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.