Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Property 'm_iHealth' not found. Disconnected players are not properly handled. #551

Open
gregor256 opened this issue Jul 8, 2024 · 1 comment

Comments

@gregor256
Copy link

Description
Hi, I've tried to parse a demo from match containing disconnected player. The code just gets the health of every player on every game tick. I've got panic error property 'm_iHealth' not found.
I provide my ideas at the end of issue.

Stacktrace
            2024/07/08 22:51:59 failed to parse demo: property 'm_iHealth' not found
	
            stacktrace:
	goroutine 18 [running]:
	runtime/debug.Stack()
	/usr/local/go/src/runtime/debug/stack.go:24 +0x5e
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs.NewParserWithConfig.func1({0x6f77e0, 0xc002fe8a00})
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/parser.go:403 +0x2a
	github.com/markus-wa/godispatch.(*Dispatcher).dispatchWithRecover.func1()
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:197 +0x3b
	panic({0x6f77e0?, 0xc002fe8a00?})
	/usr/local/go/src/runtime/panic.go:770 +0x132
	github.com/markus-wa/godispatch.callConsumerCode.func1()
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:122 +0x54
	panic({0x6f77e0?, 0xc002fe89f0?})
	/usr/local/go/src/runtime/panic.go:770 +0x132
	github.com/markus-wa/godispatch.callConsumerCode.func1()
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:122 +0x54
	panic({0x69f800?, 0xc002fe89e0?})
	/usr/local/go/src/runtime/panic.go:770 +0x132
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/sendtables2.(*Entity).PropertyValueMust(0x3?, {0x7ad272, 0x9})
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/sendtables2/entity.go:170 +0x134
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/common.getInt(...)
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/common/entity_util.go:10
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/common.(*Player).Health(0xc0009136c0)
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/common/player.go:373 +0x129
	main.testExtractReplays.func1({0x0?, 0x466913?})
	/home/gregor/issue/example.go:29 +0x56
	reflect.Value.call({0x6a0500?, 0xc00014e360?, 0x0?}, {0x7abdcb, 0x4}, {0xc0005a5178, 0x1, 0x6b7600?})
	/usr/local/go/src/reflect/value.go:596 +0xca6
	reflect.Value.Call({0x6a0500?, 0xc00014e360?, 0x40f822?}, {0xc0005a5178?, 0x10?, 0x780000c0005a5108?})
	/usr/local/go/src/reflect/value.go:380 +0xb9
	github.com/markus-wa/godispatch.callConsumerCode({0x6a0500?, 0xc00014e360?, 0xc0005a5190?}, {0xc0005a5178?, 0x713fef2455e8?, 0xc0004854e0?})
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:125 +0x3f
	github.com/markus-wa/godispatch.(*Dispatcher).Dispatch(0xc0000ca300, {0x6e19c0, 0xc0009136c0})
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:111 +0x20c
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs.(*parser).bindNewPlayerControllerS2.func1({{0x0, 0x0, 0x0}, 0x0, 0x0, {0x0, 0x0, 0x0}, {0x7fb848, 0x0}, ...})
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/datatables.go:587 +0xf2
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/sendtables2.(*Entity).readFields(0xc0003e8ee0, 0xc0030a31d0, 0xc0005a55f0)
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/sendtables2/entity.go:454 +0x319
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/sendtables2.(*Parser).OnPacketEntities(0xc0000f0280, 0xc000b1a360)
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/sendtables2/entity.go:562 +0x68c
	reflect.Value.call({0x6abde0?, 0xc0000d6438?, 0x0?}, {0x7abdcb, 0x4}, {0xc0005a5ef0, 0x1, 0xdea19000?})
	/usr/local/go/src/reflect/value.go:596 +0xca6
	reflect.Value.Call({0x6abde0?, 0xc0000d6438?, 0x40f822?}, {0xc0005a5ef0?, 0x21f66fd6105?, 0x6e00000000000000?})
	/usr/local/go/src/reflect/value.go:380 +0xb9
	github.com/markus-wa/godispatch.callConsumerCode({0x6abde0?, 0xc0000d6438?, 0xc0005a5f08?}, {0xc0005a5ef0?, 0xc0005a5ec0?, 0xc0005a5ec0?})
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:125 +0x3f
	github.com/markus-wa/godispatch.(*Dispatcher).Dispatch(0xc0000ca2a0, {0x798a80, 0xc000b1a360})
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:111 +0x20c
	github.com/markus-wa/godispatch.(*Dispatcher).dispatchWithRecover(0xc0000ca2b8?, {0x798a80?, 0xc000b1a360?})
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:202 +0x4f
	github.com/markus-wa/godispatch.(*Dispatcher).dispatchQueue(0xc0000ca2a0, 0xc0000ca360)
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:177 +0xd0
	created by github.com/markus-wa/godispatch.(*Dispatcher).AddQueues in goroutine 1
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:162 +0x18a
	panic: failed to parse demo: property 'm_iHealth' not found
	stacktrace:
	goroutine 18 [running]:
	runtime/debug.Stack()
	/usr/local/go/src/runtime/debug/stack.go:24 +0x5e
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs.NewParserWithConfig.func1({0x6f77e0, 0xc002fe8a00})
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/parser.go:403 +0x2a
	github.com/markus-wa/godispatch.(*Dispatcher).dispatchWithRecover.func1()
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:197 +0x3b
	panic({0x6f77e0?, 0xc002fe8a00?})
	/usr/local/go/src/runtime/panic.go:770 +0x132
	github.com/markus-wa/godispatch.callConsumerCode.func1()
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:122 +0x54
	panic({0x6f77e0?, 0xc002fe89f0?})
	/usr/local/go/src/runtime/panic.go:770 +0x132
	github.com/markus-wa/godispatch.callConsumerCode.func1()
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:122 +0x54
	panic({0x69f800?, 0xc002fe89e0?})
	/usr/local/go/src/runtime/panic.go:770 +0x132
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/sendtables2.(*Entity).PropertyValueMust(0x3?, {0x7ad272, 0x9})
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/sendtables2/entity.go:170 +0x134
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/common.getInt(...)
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/common/entity_util.go:10
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/common.(*Player).Health(0xc0009136c0)
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/common/player.go:373 +0x129
	main.testExtractReplays.func1({0x0?, 0x466913?})
	/home/gregor/issue/example.go:29 +0x56
	reflect.Value.call({0x6a0500?, 0xc00014e360?, 0x0?}, {0x7abdcb, 0x4}, {0xc0005a5178, 0x1, 0x6b7600?})
	/usr/local/go/src/reflect/value.go:596 +0xca6
	reflect.Value.Call({0x6a0500?, 0xc00014e360?, 0x40f822?}, {0xc0005a5178?, 0x10?, 0x780000c0005a5108?})
	/usr/local/go/src/reflect/value.go:380 +0xb9
	github.com/markus-wa/godispatch.callConsumerCode({0x6a0500?, 0xc00014e360?, 0xc0005a5190?}, {0xc0005a5178?, 0x713fef2455e8?, 0xc0004854e0?})
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:125 +0x3f
	github.com/markus-wa/godispatch.(*Dispatcher).Dispatch(0xc0000ca300, {0x6e19c0, 0xc0009136c0})
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:111 +0x20c
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs.(*parser).bindNewPlayerControllerS2.func1({{0x0, 0x0, 0x0}, 0x0, 0x0, {0x0, 0x0, 0x0}, {0x7fb848, 0x0}, ...})
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/datatables.go:587 +0xf2
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/sendtables2.(*Entity).readFields(0xc0003e8ee0, 0xc0030a31d0, 0xc0005a55f0)
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/sendtables2/entity.go:454 +0x319
	github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs/sendtables2.(*Parser).OnPacketEntities(0xc0000f0280, 0xc000b1a360)
	/home/gregor/go/pkg/mod/github.com/markus-wa/demoinfocs-golang/[email protected]/pkg/demoinfocs/sendtables2/entity.go:562 +0x68c
	reflect.Value.call({0x6abde0?, 0xc0000d6438?, 0x0?}, {0x7abdcb, 0x4}, {0xc0005a5ef0, 0x1, 0xdea19000?})
	/usr/local/go/src/reflect/value.go:596 +0xca6
	reflect.Value.Call({0x6abde0?, 0xc0000d6438?, 0x40f822?}, {0xc0005a5ef0?, 0x21f66fd6105?, 0x6e00000000000000?})
	/usr/local/go/src/reflect/value.go:380 +0xb9
	github.com/markus-wa/godispatch.callConsumerCode({0x6abde0?, 0xc0000d6438?, 0xc0005a5f08?}, {0xc0005a5ef0?, 0xc0005a5ec0?, 0xc0005a5ec0?})
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:125 +0x3f
	github.com/markus-wa/godispatch.(*Dispatcher).Dispatch(0xc0000ca2a0, {0x798a80, 0xc000b1a360})
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:111 +0x20c
	github.com/markus-wa/godispatch.(*Dispatcher).dispatchWithRecover(0xc0000ca2b8?, {0x798a80?, 0xc000b1a360?})
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:202 +0x4f
	github.com/markus-wa/godispatch.(*Dispatcher).dispatchQueue(0xc0000ca2a0, 0xc0000ca360)
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:177 +0xd0
	created by github.com/markus-wa/godispatch.(*Dispatcher).AddQueues in goroutine 1
	/home/gregor/go/pkg/mod/github.com/markus-wa/[email protected]/dispatch.go:162 +0x18a
            goroutine 1 [running]:
	log.Panicf({0x7b2710?, 0x6a0500?}, {0xc0018caf10?, 0x0?, 0x0?})
	/usr/local/go/src/log/log.go:439 +0x65
	main.testExtractReplays()
	/home/gregor/issue/example.go:37 +0x1ed
	main.main()
	/home/gregor/issue/example.go:12 +0xf
	exit status 2

To Reproduce
To Reproduce you may download demo: disconnected_de_anubis.dem and run the following code.

Code:

package main

import (
	"fmt"
	"log"
	"os"

	dem "github.com/markus-wa/demoinfocs-golang/v4/pkg/demoinfocs"
)

func main() {
	testExtractReplays()
}

func testExtractReplays() error {
	reader, _ := os.Open("disconnected_de_anubis.dem")
	parser := dem.NewParser(reader)
	defer parser.Close()
	var dummy int
	parser.RegisterEventHandler(func(any) {
		gs := parser.GameState()
		for _, player := range gs.Participants().Playing() {
			dummy = player.Health()
		}
	})
	err := parser.ParseToEnd()
	if err != nil {
		if err != dem.ErrInvalidFileType {
			log.Panicf("failed to parse demo: %v", err)
		}
	}
	fmt.Println(dummy)
	return nil
}

Expected behavior
Clear parsing to end without errors printing 0 as last player health.

Library version
v4.2.3

My solution
Main problem is that user with steamId = 76561198886630731 is listed in participants. He is disconnected, but all methods are tried to be applied to him. But his "entity" doesn't contain needed properties.
This patch #489 does not solve the problem because this player has property p.Entity.PropertyValue("m_hPawn"). This checking does not find that he is disconnected.

For me helped adding this checking:

parser.RegisterEventHandler(func(any) {
	gs := parser.GameState()
	for _, player := range gs.Participants().Playing() {
		if player == nil || player.PlayerPawnEntity() == nil ||
			player.PlayerPawnEntity().ServerClass().Name() != "CCSPlayerPawn" {
			continue
		}
		dummy = player.Health()
	}
})

Maybe this checking should be made in all places mentioned in #489.

@markus-wa
Copy link
Owner

Yeah we should definitely add these checks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants