Beispiel #1
0
func (helper *StateHelper) updateInstanceBaselineItem(item *StringTableItem) {
	classId, err := strconv.Atoi(item.Str)
	if err != nil {
		panic(err)
	}

	className := helper.ClassInfosNameMapping[classId]
	if className == "DT_DOTAPlayer" {
		return
	}

	mapping := helper.Mapping[classId]
	multiples := helper.Multiples[classId]
	if len(mapping) == 0 || len(multiples) == 0 {
		helper.pendingBaseline = append(helper.pendingBaseline, item)
		return
	}

	baseline, found := helper.Baseline[classId]
	if !found {
		baseline = map[string]interface{}{}
		helper.Baseline[classId] = baseline
	}

	br := utils.NewBitReader(item.Data)
	indices := br.ReadPropertiesIndex()
	baseValues := br.ReadPropertiesValues(mapping, multiples, indices)
	for key, value := range baseValues {
		baseline[key] = value
	}
	helper.Baseline[classId] = baseline
}
func (p *Parser) ParsePacket(packet *parser.ParserBaseItem) {
	pe := (packet.Object).(*dota.CSVCMsg_PacketEntities)
	br := utils.NewBitReader(pe.GetEntityData())
	currentIndex := -1
	for i := 0; i < int(pe.GetUpdatedEntries()); i++ {
		currentIndex = br.ReadNextEntityIndex(currentIndex)
		switch ReadUpdateType(br) {
		case Preserve:
			p.EntityPreserve(br, currentIndex, packet.Tick)
		case Create:
			p.EntityCreate(br, currentIndex, packet.Tick)
		case Delete:
			p.EntityDelete(br, currentIndex, packet.Tick)
		}
	}
}
Beispiel #3
0
func (p *Parser) ParsePacket(tick int, pe *dota.CSVCMsg_PacketEntities) {
	br := utils.NewBitReader(pe.GetEntityData())
	currentIndex := -1

	createPackets := []*packet_entities.PacketEntity{}
	preservePackets := []*packet_entities.PacketEntity{}
	deletePackets := []*packet_entities.PacketEntity{}

	for i := 0; i < int(pe.GetUpdatedEntries()); i++ {
		currentIndex = br.ReadNextEntityIndex(currentIndex)
		uType := packet_entities.ReadUpdateType(br)

		switch uType {
		case packet_entities.Create:
			createPackets = append(createPackets, p.entityCreate(br, currentIndex, tick))
		case packet_entities.Preserve:
			preservePackets = append(preservePackets, p.entityPreserve(br, currentIndex, tick))
		case packet_entities.Delete:
			deletePackets = append(deletePackets, p.entityDelete(br, currentIndex, tick))
		}
	}

	for _, pe := range createPackets {
		p.Entities[pe.Index] = pe
		p.ByHandle[pe.Handle()] = pe
		if p.OnEntityCreated != nil {
			p.OnEntityCreated(pe)
		}
	}

	for _, pe := range preservePackets {
		if p.OnEntityPreserved != nil {
			p.OnEntityPreserved(pe)
		}
	}

	for _, pe := range deletePackets {
		if p.OnEntityDeleted != nil {
			p.OnEntityDeleted(pe)
		}
		// p.Entities[pe.Index] = nil
		// delete(p.ByHandle, pe.Handle())
	}
}
func NewParser(items parser.ParserBaseItems) {
	p := Parser{
		entities: make([]*PacketEntity, 0, 2048),
	}

	var serverInfo *dota.CSVCMsg_ServerInfo
	packets := parser.ParserBaseItems{}
	for _, item := range items {
		switch value := item.Object.(type) {
		case *dota.CSVCMsg_ServerInfo:
			serverInfo = value
		case *dota.CSVCMsg_PacketEntities:
			if item.From == dota.EDemoCommands_DEM_Packet {
				packets = append(packets, item)
			}
		}
	}
	sort.Sort(packets)
	p.packets = packets

	p.classIdNumBits = int(math.Log(float64(serverInfo.GetMaxClasses()))/math.Log(2)) + 1

	var classInfos *dota.CDemoClassInfo
	var instanceBaseline *dota.CDemoStringTablesTableT
	sendTables := map[string]*dota.CSVCMsg_SendTable{}

	for _, item := range items {
		switch value := item.Object.(type) {
		case *dota.CDemoClassInfo:
			if classInfos == nil {
				classInfos = value
			}
		case *dota.CSVCMsg_SendTable:
			sendTables[value.GetNetTableName()] = value
		case *dota.CDemoStringTables:
			for _, table := range value.GetTables() {
				if table.GetTableName() == "instancebaseline" {
					instanceBaseline = table
				}
			}
		}
	}

	for _, info := range classInfos.GetClasses() {
		id, name := int(info.GetClassId()), info.GetTableName()
		p.classInfosNameMapping[id] = name
		p.classInfosIdMapping[name] = id
		props := p.sendTablesHelper.LoadSendTable(name)
		p.mapping[id] = props

		m := map[string]int{}
		for _, prop := range props {
			m[prop.DtName+"."+prop.VarName] += 1
		}
		p.multiples[id] = m
	}

	for _, item := range instanceBaseline.GetItems() {
		classId, err := strconv.Atoi(item.GetStr())
		if err != nil {
			panic(err)
		}
		br := utils.NewBitReader(item.GetData())
		indices := br.ReadPropertiesIndex()
		p.baseline[classId] = br.ReadPropertiesValues(
			p.mapping[classId],
			p.multiples[classId],
			indices,
		)
	}
}
Beispiel #5
0
func Parse(data []byte, numEntries, maxEntries, dataSizeBits int, dataFixedSize bool) map[int]*StringTableItem {
	br := utils.NewBitReader(data)

	bitsPerIndex := int(math.Log(float64(maxEntries)) / math.Log(2))
	keyHistory := make([]string, 0, KeyHistorySize)
	result := map[int]*StringTableItem{}
	mysteryFlag := br.ReadBoolean()
	index := -1
	nameBuf := ""

	for len(result) < numEntries {
		if br.ReadBoolean() {
			index++
		} else {
			index = int(br.ReadUBits(bitsPerIndex))
		}
		nameBuf = ""
		if br.ReadBoolean() {
			if mysteryFlag && br.ReadBoolean() {
				panic("mysteryFlag assertion failed!")
			}
			if br.ReadBoolean() {
				basis := br.ReadUBits(5)
				length := br.ReadUBits(5)
				if int(basis) >= len(keyHistory) {
					// spew.Dump("Ignoring invalid history index...", keyHistory, basis, length)
					nameBuf += br.ReadStringN(MaxNameLength)
				} else {
					s := keyHistory[basis]
					if int(length) > len(s) {
						spew.Dump(s, length)
						nameBuf += s + br.ReadStringN(int(MaxNameLength))
					} else {
						nameBuf += s[0:length] + br.ReadStringN(int(MaxNameLength-length))
					}
				}
			} else {
				nameBuf += br.ReadStringN(MaxNameLength)
			}
			if len(keyHistory) >= KeyHistorySize {
				copy(keyHistory[0:], keyHistory[1:])
				keyHistory[len(keyHistory)-1] = "" // or the zero value of T
				keyHistory = keyHistory[:len(keyHistory)-1]
			}
			keyHistory = append(keyHistory, nameBuf)
		}
		value := []byte{}
		if br.ReadBoolean() {
			bitLength := 0
			if dataFixedSize {
				bitLength = dataSizeBits
			} else {
				bitLength = int(br.ReadUBits(14) * 8)
			}
			value = append(value, br.ReadBitsAsBytes(bitLength)...)
		}
		result[index] = &StringTableItem{Str: nameBuf, Data: value}
	}

	return result
}