demoinfocs-golang icon indicating copy to clipboard operation
demoinfocs-golang copied to clipboard

Duplicate UniqueID/UniqueID2 For Tracking Grenades Over Time

Open David-Durst opened this issue 3 years ago • 17 comments
trafficstars

Describe the bug UniqueID and UniqueID2 aren't unique for different grenades.

I want to use e.Projectile.WeaponInstance.UniqueID2() in events.GrenadeProjectileThrow and e.Grenade.UniqueID2 in events.HeExplode (and similar events) to track grenades over time. Here is my full code: https://github.com/David-Durst/csknow/blob/4e115f7314cb23eb3ba6d4764611731ffe568c3e/demo_parser/internal/parse_tick_data.go#L196-L308

To Reproduce https://drive.google.com/file/d/1Qv7MoXoEIrA5leIfpzmOk1mRBdtDeqZQ/view?usp=sharing

Code:

	lastID := ulid.Make()
	p.RegisterEventHandler(func(e events.GrenadeProjectileThrow) {
		if lastID == e.Projectile.WeaponInstance.UniqueID2() {
			fmt.Printf("duplicate unique ids")
		}
		lastID = e.Projectile.WeaponInstance.UniqueID2()
	})

Expected behavior "duplicate unique ids" should never print.

Instead, there are duplicate ids, so they print out.

Library version v3.0.2-0.20220908193112-50f55785b7a0

Additional context Ubuntu 22.04

David-Durst avatar Sep 08 '22 23:09 David-Durst

Duplicate id's happen quite frequently (seems like 5-10% of grenades). In the old version of my parser, I kept a list of duplicate ids and assumed that grenades exploded in the same they are launched. This worked reasonably well, as it seems that most of the duplicates were flashes, and flashes have a fixed fuse length. However, that approach is janky. I would prefer if unique ids were actually unique.

David-Durst avatar Sep 08 '22 23:09 David-Durst

Here's another demo https://drive.google.com/file/d/1ajifwQNd0BPPg9CXl038NfNrjrOmwTr4/view?usp=sharing. It's much newer (so no demo file structure issues), but it has the same problem. In particular, see IngameTick 35082. Niko's first flash explodes just after he throws another flash. These flashes exist simultaneously but the parser assigns them the same UniqueID/UniqueID2. This is checked both with version v3.0.2-0.20220908193112-50f55785b7a0 and v2.13.0 (the old version of the library I used until my refactor this past week).

David-Durst avatar Sep 09 '22 00:09 David-Durst

interesting picture when looking at ticks

image

seems like there's always 2 events on those ticks - it's probably actually the same entity and we just get some dupe events

markus-wa avatar Sep 10 '22 21:09 markus-wa

seems to always be flashbangs image

I think this is because players can have 2 flashbangs in the inventory, and we just get the item from the player inventory by type

markus-wa avatar Sep 10 '22 21:09 markus-wa

I'm not seeing it on the same tick. I'm filtering out those duplicate events on same tick and still seeing the duplciate id issue.

The flashbang thing makes sense. I've only seen it when players throw flashes quickly one after another.

David-Durst avatar Sep 10 '22 21:09 David-Durst

Which demo are you using?

David-Durst avatar Sep 10 '22 21:09 David-Durst

right - I remember this now the tick doesn't matter actually

having 2 flashbangs counts as 1 weapon

think of it as a gun that can shoot flashbangs, and you have 2 ammo

so it makes sense that the two unique IDs are the same, because the flashbangs are coming from the same "stash"

markus-wa avatar Sep 10 '22 21:09 markus-wa

Is there a way to make uniqueid actually unique? like create a new one for each "flashbang bullet"?

David-Durst avatar Sep 10 '22 21:09 David-Durst

What's the underlying goal here? this seems like a XY problem

markus-wa avatar Sep 10 '22 21:09 markus-wa

can you use Projectile.UniqueID()?

might need to add a V2 there as well

markus-wa avatar Sep 10 '22 21:09 markus-wa

e.g. https://github.com/markus-wa/demoinfocs-golang/blob/master/examples/nade-trajectories/nade_trajectories.go#L69

markus-wa avatar Sep 10 '22 21:09 markus-wa

The goal is to record the ticks when a grenade is thrown, destroyed, it's effect is active, and it's effect expires. I also want to link the grenade to it's trajectory.

David-Durst avatar Sep 10 '22 21:09 David-Durst

There certainly are other approaches (like matching the trajectory starting points of the grenades), but the cleanest for me would be using Grenade.UniqueId(), so hoping there's a solution using that.

David-Durst avatar Sep 10 '22 21:09 David-Durst

I see - that makes sense and I agree currently there is no nice solution to this.

I think this is probably quite tricky to implement, but I'm certainly open for suggestions on how to do this,

I can think about it for a bit as well but tbh I'm stretched very thin right now and my priorities are currently elsewhere, so I may be a bit slow on this.

markus-wa avatar Sep 10 '22 21:09 markus-wa

Understood, thanks for your help!

Previously, I solved this by assuming that flashes had a constant fuse length. This enabled me to deduplciate the ids by assuming explosion order = throw order. Do you know if flashes always have a fixed fuse length? Or does bouncing/throw mode affect fuse length? If the fuse length is constant, I could go back to this approach in my code.

David-Durst avatar Sep 10 '22 22:09 David-Durst

I think the order is certainly guaranteed between duplicates as they come from the same thrower - and there's no way to make your second flash explode before your first one.

As for fuse length I would have expected it to be constant, but can neither confirm nor deny this for certain.

markus-wa avatar Sep 10 '22 22:09 markus-wa

https://davidbdurst.com/blog/csknow_flashbang_length.html fuse length is constant. I'll use this hack if nothing better comes up.

David-Durst avatar Sep 11 '22 00:09 David-Durst