Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Entity array property have values unreleated to the entity #593

Open
Labels
@LukasW1337

Description

Describe the bug
The m_Attributes property on gun entities, used to represent skin details, float value, StatTrak status, etc. - is sometimes populated with values that do not belong to the actual weapon entity. In several cases, items incorrectly appear to have attributes like StatTrak, or stickers that shouldn't be there.

This isn't a general thing as some guns are correctly marked, but the ones it gets wrong is consistent.

To Reproduce
Run this with map 1 from here - HLTV Match

go run bug.go -demo ence-vs-ecstatic-m1-dust2.dem

Code:

package main
import (
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
	dem "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs"
	events "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/events"
	sendtables "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/sendtables"
)
func main() {
	fl := new(flag.FlagSet)
	urlPtr := fl.String("demo", "", "Filepath to Demo file")
	err := fl.Parse(os.Args[1:])
	if err != nil {
		panic(err)
	}
	url := *urlPtr
	if url == "" {
		fmt.Println("Please provide a Demo file path via -demo")
		return
	}
	f, err := os.Open(url)
	if err != nil {
		log.Panic("failed to open demo file: ", err)
	}
	defer f.Close()
	p := dem.NewParser(f)
	defer p.Close()
	p.RegisterEventHandler(func(e events.DataTablesParsed) {
		// This event fires at the beginning of parsing, but we'll use it to initialize
		fmt.Println("Demo parsing started, weapon tracking initialized...")
		for _, serverclass := range p.ServerClasses().All() {
			if strings.Contains(serverclass.Name(), "CWeapon") {
				serverclass.OnEntityCreated(func(entity sendtables.Entity) {
					entity.Property("m_Attributes").OnUpdate(func(pv sendtables.PropertyValue) {
						itemId := fetchItemID(entity)
						if itemId == 22389739547 { //Specific SSG i found to replicate the bug
							fmt.Printf("Update for entity %d: itemId=%v\n", entity.ID(), itemId)
							if len(pv.S2Array()) > 0 {
								for _, attr := range pv.S2Array() {
									fmt.Printf("Attribute for entity %d: %v\n", entity.ID(), attr)
								}
							} else {
								fmt.Printf("No attributes found for entity %d\n", entity.ID())
							}
						}
					})
				})
			}
		}
	})
	// Parse demo
	err = p.ParseToEnd()
	if err != nil {
		log.Panic("failed to parse demo: ", err)
	}
}
// Helper function to get item ID
func fetchItemID(w sendtables.Entity) uint64 {
	if w == nil {
		return 0
	}
	var itemID uint64 = 0
	itemHigh, itemHighFound := w.PropertyValue("m_iItemIDHigh")
	itemLow, itemLowFound := w.PropertyValue("m_iItemIDLow")
	if itemHighFound && itemLowFound {
		var itemIDHigh, itemIDLow uint32
		// Convert high value
		switch v := itemHigh.Any.(type) {
		case uint32:
			itemIDHigh = v
		case uint64:
			itemIDHigh = uint32(v)
		case int:
			itemIDHigh = uint32(v)
		case int32:
			itemIDHigh = uint32(v)
		case int64:
			itemIDHigh = uint32(v)
		case float32:
			itemIDHigh = uint32(v)
		case float64:
			itemIDHigh = uint32(v)
		default:
			itemIDHigh = 0
		}
		// Convert low value
		switch v := itemLow.Any.(type) {
		case uint32:
			itemIDLow = v
		case uint64:
			itemIDLow = uint32(v)
		case int:
			itemIDLow = uint32(v)
		case int32:
			itemIDLow = uint32(v)
		case int64:
			itemIDLow = uint32(v)
		case float32:
			itemIDLow = uint32(v)
		case float64:
			itemIDLow = uint32(v)
		default:
			itemIDLow = 0
		}
		// Combine high and low into full item ID
		itemID = (uint64(itemIDHigh) << 32) | uint64(itemIDLow)
	}
	return itemID
}

Expected behavior
The test above fetches this gun from the demo, and logs the attributes everytime it's updated. (seems like it's only once when it's created?)

It should have 6 - 7 - 8 - 75

Thinking this was a mistake in the demo itself i cross checked it using Clarity, and that correctly only shows 4 entries in the array. (notice how the last m_attributes is index 75)

Image

The code above should only output:

Update for entity 89: itemId=22389739547
Attribute for entity 89: &{[6 624 624 0 false <nil> <nil> <nil>]}
Attribute for entity 89: &{[7 948.8936 948.8936 0 false <nil> <nil> <nil>]}
Attribute for entity 89: &{[8 0.069185875 0.069185875 0 false <nil> <nil> <nil>]}
Attribute for entity 89: &{[75 4.9426443e+19 4.9426443e+19 0 false <nil> <nil> <nil>]}

(Last entry is index 75)

And NOT

Update for entity 89: itemId=22389739547
Attribute for entity 89: &{[6 624 624 0 false <nil> <nil> <nil>]}
Attribute for entity 89: &{[7 948.8936 948.8936 0 false <nil> <nil> <nil>]}
Attribute for entity 89: &{[8 0.069185875 0.069185875 0 false <nil> <nil> <nil>]}
Attribute for entity 89: &{[75 4.9426443e+19 4.9426443e+19 0 false <nil> <nil> <nil>]}
Attribute for entity 89: &{[80 6.28e-43 6.28e-43 0 false <nil> <nil> <nil>]} //Related to stattrak, and the gun isn't stattrak
Attribute for entity 89: &{[81 0 0 0 false <nil> <nil> <nil>]} //Related to stattrak, and the gun isn't stattrak
Attribute for entity 89: &{[113 9.675e-42 9.675e-42 0 false <nil> <nil> <nil>]} //Related to Stickers, and gun doesn't have any
Attribute for entity 89: &{[121 9.916e-42 9.916e-42 0 false <nil> <nil> <nil>]} //Related to Stickers, and gun doesn't have any

I tried accessing the entities in a lot of different ways, player inventory etc. - they all have "wrong" m_Attributes for the affected guns.

This isn't to say m_Attributes is always wrong. A lot of guns does get correct values, somehow it just hallucinates other values into some guns.

Library version
Tested with V5 and V4

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

        AltStyle によって変換されたページ (->オリジナル) /