Jump to content

[Solved]Problem with Event ordering[1.10] (How to properly update Capability for GUI on client)


Recommended Posts

Posted (edited)

I've made my custom Capability, everything is working pretty well. I have an error though where when I enter a world, my custom Mana bar will just be set to the default value for mana on the client side. Which means that the Mana bar that I've made shows 0 mana untill I use an mana consuming item and force an update. 

 

I've written a Packet to update my client with the server information and this packet works marvelous. Whenever the game launches my client needs to have the Capability attached again while the server retrieves the information from the NBT file, that's why I'm sending a packet that updates the client with all the server information. 

 

The problem I'm running in to is that I'm trying to run an PlayerLoggedInEvent to update my client with all the information needed. But this PlayerLoggedInEvent fires BEFORE Capabilities are added. 

 


[23:40:15] [Server thread/INFO]: [com.cheese.rpvp.capabilities.handlers.CustomDataHandlerBar:loggedIn:68]: Message sent login, mana = 90 maxmana 100
[23:40:16] [Client thread/INFO]: [com.cheese.rpvp.capabilities.handlers.CustomDataHandlerBar:attachCapabilities:37]: Custom ability Bar added
[23:40:16] [Client thread/INFO]: [com.cheese.rpvp.capabilities.handlers.CustomAdventurerHandler:attachCapabilities:31]: Custom ability Adv added
[23:40:16] [Client thread/INFO]: [com.cheese.rpvp.capabilities.handlers.CustomItemBar:attachCapabilities:34]: Capability added

 

Now I've already tried setting my playerLoggedInEvent to the lowest priority: 

    @SubscribeEvent(priority = EventPriority.LOWEST)
    public void loggedIn(PlayerLoggedInEvent event){
        if(!event.player.worldObj.isRemote) {
            if (event.player.hasCapability(CAPABILITY_BAR, EnumFacing.DOWN)) {
                final IBarHandler instance = getHandler(event.player);
                final NBTTagCompound tag = new NBTTagCompound();
                tag.setInteger("maxmana", instance.getMaxMana());
                tag.setInteger("maxhealth", instance.getMaxHealth());
                tag.setInteger("mana", instance.getMana());
                tag.setInteger("health", instance.getHealth());
                tag.setInteger("fatigue", instance.getFatigue());
                tag.setInteger("job", instance.getJob());
                Main.packetHandler.barWrapper.sendTo(new BarMessage(tag), (EntityPlayerMP)event.player);
                System.out.println("Message sent login, mana = " + instance.getMana() + " maxmana " + instance.getMaxMana());

            }
        }
    }

 

while setting my AttachCapabilities to the highest. 

    @SubscribeEvent(priority = EventPriority.HIGH)
    public void attachCapabilities(AttachCapabilitiesEvent<Entity> event){
        if(event.getObject() instanceof EntityPlayer) {
                System.out.println("Custom ability Bar added");
                event.addCapability(new ResourceLocation(Main.MODID, "BARS"), new BarProvider());
            }
        }

 

 

to no Avail. The order keeps the same and when my player logs in his manabar looks completely empty, even if on the server side he has plenty of mana.

 

 

What I'm wondering now is: Is there any Event that I can call that will fire AFTER my capability is added. I need an EntityPlayer to attach to the message so I can properly update my Capabilities. If there's a way to make my Capability fire first that'll work too.  

 

 

Problem description:

 

My Messagehandler OnPlayerLoggedInEvent which updates my client capability is sent BEFORE the capability is attached to the client. I'm looking for a different event to call when my client joins the server that will pop AFTER capabilities are added, but preferably within a second of joining a world. EntityJoinWorldEvent with instanceof EntityPlayer also doesn't work.

 

The events all work seperately, and I can call the method that updates the info after the capability is added and it works fine, so that's not the problem. I just can't get them to operate in the wanted order.

 

SOLLUTION:

Quote

Edit: I Made a variable in my GuiHandler using a ClientConnectedToServerEvent to make sure that the client would request an update every time it connected To make sure I didn't send a message every tick the client would check if the player had access to my Mana and then if the variable was True, set it to false after a use. The ClientConnectedToServerEvent made sure the variable was properly set every time I logged in again.. Then I created a simple packet from the client to the server to ask for an update, on which the server send back a packet with the relevant, updated information.

 

No tickhandler required, no funky workaround. I'm quite frankly not sure why I didn't try this in the first place. 

 

Edited by oldcheese
Posted

When I run into these sort of things I often just simply set a "timer" that delays the action a tick or two.  You can just create a boolean field called something like packetSent that defaults to false and is also set to false in the player joins world event and then in the player tick event you can check if it is false and if so (and on the server) you send the packet and set packetSent to true. If the player tick event is too soon as well, you can make the field a counter and set it to something like 2 and count down to delay the packet a couple ticks. If you're worried that two players might join in exactly the same tick you should use a map of booleans instead, but hopefully you get the idea.

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

Posted

Would players be able to inherit information from eachother if I delayed it too much and another player joined? I'd assumed that when I get an entity from a joinworldevent it'd be a specific player, not an object redirecting me to the latest player. Maybe I'm misreading this.

 

But your sollution is to register a new tickhandler for playerTickEvent and not send the update packet untill the Capability is attached? That seems like as good as a workaround as any, though I've been a bit reluctant to use too many tickhandlers myself. 

 

Thanks for the help. When I get back from college I'll start rewriting my code and post updates if I solve it. For future readers.

Posted

This is completely off the top of my head but isn't there an event called something like GatherCapabilitiesEvent that fires after the AttachCapabilitiesEvents?

Failing that what's wrong with EntityJoinWorldEvent? It's all right for me

Posted (edited)
4 hours ago, FredTargaryen said:

This is completely off the top of my head but isn't there an event called something like GatherCapabilitiesEvent that fires after the AttachCapabilitiesEvents?

Failing that what's wrong with EntityJoinWorldEvent? It's all right for me

Well, my EntityJoinWorldEvent fires BEFORE the Attach capability event. That's where it fails. I want to update my client by sending them a packet. But if the packet attempts to update before the capability is attached to the client, there's not much use. 

 

I can try to use the gather capabilities event. But if you have an implementation of a packet where it successfully updates the client side after logging in using EntityJoinWorldEvent I'd love to see how you did it. Fixing something I did wrong would be easier than trying to workaround using tick handlers 

 

Sorry if the spelling sucks. I'm typing from my phone still. 

 

 

Update: I created a playerTickHandler with a few booleans. One boolean from my GuiHandler that draws the actual element that turns to true when things aren't properly loaded on the client side. Then a boolean near the Eventhandler to make sure that the load isn't called a second time. This ensures that whenever my capabilities DO exist (Or my GUI couldn't access them) the tickhandler updates the player once, giving them the proper resources.

 

Edit: This only works in single player now that I test it. Back into the fray I go.

 

 

Edit: Made a variable in my GuiHandler using a ClientConnectedToServerEvent to make sure that the client would request an update every time it connected. Then I created a simple packet from the client to the server to ask for an update, on which the server send back a packet with the relevant, updated information.

 

No tickhandler required, no funky workaround. I'm quite frankly not sure why I didn't try this in the first place. 

Edited by oldcheese
Sollution. Kinda.
  • Like 1
Posted

Yeah sometimes turning a problem around can be simpler.

 

I  think you kinda made my suggestion more complicated than it needed to be. I think it may not have worked because you confused the client and server side processing (usually if something works in single player and not in multiplayer it is a problem with side management). But looks like you made a real attempt and I know packets to sync client can be a pain.

 

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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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