esx-framework / esx_core

Official Repo For core resources for esx-legacy
https://documentation.esx-framework.org/
GNU General Public License v3.0
362 stars 733 forks source link

bug(ex_extended): fails to set skin if health set to 0 on login #1272

Closed iSentrie closed 7 months ago

iSentrie commented 9 months ago

From my tests if you reconnect while dead, clothing fails to be applied to ped.

(While this happens for me all the time, it might need confirmation from others)

https://github.com/esx-framework/esx_core/blob/bcc1e876b6b7befa8630ee5fafc605b10dc290d3/%5Bcore%5D/es_extended/client/main.lua#L63-L65

Gellipapa commented 9 months ago

Hi! @iSentrie I don't really understand how a native would affect the clothing, it could be that ped is changed at death and it wouldn't be handled in the skin. But it can't be that either as it must be a ped that is checked off at /skin.

iSentrie commented 9 months ago

Hi! @iSentrie I don't really understand how a native would affect the clothing, it could be that ped is changed at death and it wouldn't be handled in the skin. But it can't be that either as it must be a ped that is checked off at /skin.

well it's because of death obviously... if i delay killing the ped, clothing applies just fine. made a Wait(1000) on this part, clothing applies fine, brought this to event handler when skin is loaded within skinchanger and clothing applies just fine.

if metadata.health then 
     SetEntityHealth(ESX.PlayerData.ped, metadata.health) 
 end 

i believe this brings issues with other scripts too, like ambulancejob, players are not recognized as dead by that script sometimes

Gellipapa commented 9 months ago

Ohh so on first login the skin doesn't work i thought that if you are dead the player afterwards review afterwards the skin command doesn't work, so i see we will investigate and fix

Gellipapa commented 9 months ago

@iSentrie Hi! Do you use multicharacter? I now testing and works very well.

Gellipapa commented 9 months ago

https://streamable.com/t6rp7o

iSentrie commented 8 months ago

@iSentrie Hi! Do you use multicharacter? I now testing and works very well.

hey, no I don't use multichar, tested only without it.

Gellipapa commented 8 months ago

@iSentrie Can you make some video because I don't understand what your problem is, I couldn't reproduce it without multichar.

iSentrie commented 8 months ago

@iSentrie Can you make some video because I don't understand what your problem is, I couldn't reproduce it without multichar.

honestly, i was digging since then and I might have found problem which was in my esx_identity, i had outdated one, since i mostly update framework only, looks like this one was crucial too. after updating this, this doesn't happen anymore, so far.

however, it seems that for killing the ped responsible was esx_ambulancejob https://github.com/esx-framework/esx_ambulancejob/blob/c6d0366a64137a233287e89553020628dfaf6cec/config.lua#L8C12-L8C12 and if this Config.SaveDeathStatus = false, then once i connect to the game it never sets my health to 0, i spawn with full hp (but u have to be dead and quit the game)

now in conclusion it means that PlayerPedId() have changed upon applying it, script waits for while ESX.PlayerData.ped == nil and then continues, but from my tests the PlayerPedId() changes again exact in that moment, which doesn't apply health... Adding a Wait(3000) just after that while loop kinda prooves this theory, because then it does kill the ped.

so tried this theory practically https://github.com/esx-framework/esx_core/blob/9c84a675d5a1c4c39150a388eb908b9cf070a92a/%5Bcore%5D/es_extended/client/main.lua#L54

    while ESX.PlayerData.ped == nil do Wait(20) end
    print('before 3s wait', ESX.PlayerData.ped)
    Wait(3000)
    print('after 3s wait', ESX.PlayerData.ped)

output was: before 3s wait 15106 after 3s wait 28162

so how many features could it affect more?

Gellipapa commented 8 months ago

@iSentrie Can you make some video because I don't understand what your problem is, I couldn't reproduce it without multichar.

honestly, i was digging since then and I might have found problem which was in my esx_identity, i had outdated one, since i mostly update framework only, looks like this one was crucial too. after updating this, this doesn't happen anymore, so far.

however, it seems that for killing the ped responsible was esx_ambulancejob https://github.com/esx-framework/esx_ambulancejob/blob/c6d0366a64137a233287e89553020628dfaf6cec/config.lua#L8C12-L8C12 and if this Config.SaveDeathStatus = false, then once i connect to the game it never sets my health to 0, i spawn with full hp (but u have to be dead and quit the game)

now in conclusion it means that PlayerPedId() have changed upon applying it, script waits for while ESX.PlayerData.ped == nil and then continues, but from my tests the PlayerPedId() changes again exact in that moment, which doesn't apply health... Adding a Wait(3000) just after that while loop kinda prooves this theory, because then it does kill the ped.

so tried this theory practically

https://github.com/esx-framework/esx_core/blob/9c84a675d5a1c4c39150a388eb908b9cf070a92a/%5Bcore%5D/es_extended/client/main.lua#L54

  while ESX.PlayerData.ped == nil do Wait(20) end
  print('before 3s wait', ESX.PlayerData.ped)
  Wait(3000)
  print('after 3s wait', ESX.PlayerData.ped)

output was: before 3s wait 15106 after 3s wait 28162

so how many features could it affect more?

Hm there is already a 3000 delay if multichar is applied, you will probably need it to avoid such errors, but I'll look into it more tomorrow.

image

But I recommend you to upgrade to the full core because there are other bugs, and unfortunately if you don't use multichar it can break the system, because there are some events that only work correctly if you have multichar (don't ask why, probably because of backwards compatibility it was not fixed.)

That's why it is recommended to use multichar limited to 1 character at most.

iSentrie commented 8 months ago

Ooof... Okay. It's worth mentioning that 3s. delay gives players enough time to exploit the system, which leads to reviving yourself.

Repro

  1. Player dies
  2. Player disconnects and reconnects
  3. Once you just loaded you have very short time to disconnect
  4. If you hit good timing metadata will save 200 HP and when you reconnect you will have full HP.

It's not that hard to do, tried this myself (without multichar, but seems like it does the same and with multichar and it should be even easier because of logout function).

But this can be prevented with Config.SaveDeathStatus = true set in esx_ambulancejob, I think. 🤔 That's what I came up with from all this tests, now it's for you to judge if it's worth fixing. 😁

Gellipapa commented 7 months ago

@iSentrie Hi! Yes here when the metadata is set you need to check if the player is dead based on the database and if he is dead set him to 0 so the metadata will automatically sync to 0 and he will not be able to use it.

https://github.com/esx-framework/esx_core/blob/9c84a675d5a1c4c39150a388eb908b9cf070a92a/%5Bcore%5D/es_extended/server/functions.lua#L167

Gellipapa commented 7 months ago

@Arctos2win Hi! Can you fix it here? #1288

Gellipapa commented 7 months ago

@iSentrie Hi! Yes the problem is exactly that the character is not killed by the system because the DeathStatus logic is not turned on and if you exit at the right time then yes the save cycle will set 200 HP.

I am still thinking about how to fix this.

But anyway, I don't know if you had this but if you do it with multicharacter then your coordinate will be at the character creator.

Gellipapa commented 7 months ago

@iSentrie Fixed this is now available in 1.10.3.

iSentrie commented 7 months ago

@iSentrie Fixed this is now available in 1.10.3.

This brought new issue, ped gets killed and player is not recognized as dead and cannot be revived by medics. I'll make a new issue.