psforever / PSF-LoginServer

Emulated PlanetSide 1 world and login server by the PSForever project.
https://psforever.net
GNU General Public License v3.0
75 stars 45 forks source link

No XP from CE while dead #1195

Closed Dethdeath closed 5 months ago

Dethdeath commented 5 months ago

There's often no XP given for mine and spitfire kills when the owner is dead or respawning.

Fate-JH commented 5 months ago

That's surprisingly accurate to vanilla, maybe unintentionally. Every so often, but usually when close to a respawn event, you'd maybe see an experience message in chat that was zero or null (blank space, no value). I'll look into it all the same.

Fate-JH commented 5 months ago

On that note, are you basing this on missing chat messages or by lack of change to the experience value bar?

Dethdeath commented 5 months ago

Missing XP messages and BEP seem to happen more often when the person is already at the spawn select screen. And it's based on both.

ScrawnyRonnie commented 5 months ago

I've been testing with mines and even while the mine layer is alive, sometimes it is not granting a kill or xp. For the player that died, it isn't counting every death either. image This might be why it's not counting them. Saw this error in the test server logs: image

Fate-JH commented 5 months ago

Hurray, stack trace!

Fate-JH commented 5 months ago

So the line in question is val lastDeath = killer.progress.prior.flatMap(_.death). lastDeath will be an optional value.

killer is a PlayerSource entity and can't be null because it's a method param (fixed value) and has already been used once before this in the method (confirmed value). progress could be null but it should be assigned some value every time the PlayerSource is constructed. The major possibility here is when using the main constructor rather than the overloaded constructors. prior and death are both optional values that flatten into optional values but either could potentially be set to null in the process of resolving one's score elsewhere.

So, conveniently, in MineDeployableControl is a function called trippedMineReason that generates a DamageReason for the mines when they explode and it conveniently makes use of the full PlayerSource contructor. progress is set to PlayerSource.Nobody's progress value, and that is just a basic Life without any bells and whistles. I honestly feel like this is wrong in some way but it's only wrong because it's all I had to work with right then.

Fate-JH commented 5 months ago

Regardless of the exception above, I've discovered one of the possible reasons that BEP is not being updated correctly. AvatarActor has a function called setBepOnly whose purpose is to alert the database about the change in BEP and report back to the client. It returns a Future[Long] that will cause UI updates and such upon completion. It doesn't always report success and, in the case of mines, it seems to fail outright for some reason more often than not. I did not encounter this NullPointerException at any point during all of my testing so I think my repairs have resolved this issue at least.

I managed to trigger a state where players won't trigger mines. I thought it had something to do with reconstruction and made certain that all zone interactions were allowed after that, but then I discovered a state where players took no mine explosion damage. The mines still exploded under the test character's feet while walking around freely but she took no damage. To continue testing I had to kill my mine layer character by coaxing the explosion using the mine-immune player until they too bugged and testing could not continue during the session.