44 "math/rand"
55 "strings"
66
7+ "github.com/oklog/ulid/v2"
8+
79 st "github.com/markus-wa/demoinfocs-golang/v3/pkg/demoinfocs/sendtables"
810)
911
@@ -288,7 +290,8 @@ type Equipment struct {
288290 Owner * Player // The player carrying the equipment, not necessarily the buyer.
289291 OriginalString string // E.g. 'models/weapons/w_rif_m4a1_s.mdl'. Used internally to differentiate alternative weapons (M4A4 / M4A1-S etc.).
290292
291- uniqueID int64
293+ uniqueID int64 // Deprecated, use uniqueID2, see UniqueID() for why
294+ uniqueID2 ulid.ULID
292295}
293296
294297// String returns a human readable name for the equipment.
@@ -303,13 +306,23 @@ func (e *Equipment) Class() EquipmentClass {
303306 return e .Type .Class ()
304307}
305308
306- // UniqueID returns the unique id of the equipment element.
309+ // UniqueID returns a randomly generated unique id of the equipment element.
307310// The unique id is a random int generated internally by this library and can be used to differentiate
308311// equipment from each other. This is needed because demo-files reuse entity ids.
312+ // Deprecated: Use UniqueID2 instead. Since UniqueID is randomly generated, duplicate IDs are possible.
313+ // See the birthday problem for why repeatedly generating random 64 bit integers is likely to produce a collision.
309314func (e * Equipment ) UniqueID () int64 {
310315 return e .uniqueID
311316}
312317
318+ // UniqueID2 returns a unique id of the equipment element that can be sorted efficiently.
319+ // UniqueID2 is a value generated internally by this library and can be used to differentiate
320+ // equipment from each other. This is needed because demo-files reuse entity ids.
321+ // Unlike UniqueID, UniqueID2 is guaranteed to be unique.
322+ func (e * Equipment ) UniqueID2 () ulid.ULID {
323+ return e .uniqueID2
324+ }
325+
313326// AmmoInMagazine returns the ammo left in the magazine.
314327// Returns CWeaponCSBase.m_iClip1 for most weapons and 1 for grenades.
315328func (e * Equipment ) AmmoInMagazine () int {
@@ -375,7 +388,7 @@ func (e *Equipment) AmmoReserve() int {
375388//
376389// Intended for internal use only.
377390func NewEquipment (wep EquipmentType ) * Equipment {
378- return & Equipment {Type : wep , uniqueID : rand .Int63 ()} //nolint:gosec
391+ return & Equipment {Type : wep , uniqueID : rand .Int63 (), uniqueID2 : ulid . Make () } //nolint:gosec
379392}
380393
381394var equipmentToAlternative = map [EquipmentType ]EquipmentType {
0 commit comments