Example #1
0
func v1ParseLog(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "POST":

		var demoFile []byte
		if strings.Contains(r.Header.Get("Content-Type"), "multipart/form-data;") {
			form, _ := r.MultipartReader()
			part, _ := form.NextPart()
			demoFile, _ = ioutil.ReadAll(part)
		} else {
			demoFile, _ = ioutil.ReadAll(r.Body)
		}

		var gameTime time.Duration
		var preGameStartTime time.Duration
		var gameStartTime time.Duration
		var gameEndTime time.Duration

		var iPlayerResources map[int]time.Duration
		iPlayerResources = make(map[int]time.Duration)

		var iTeamData map[int]time.Duration
		iTeamData = make(map[int]time.Duration)

		var iHeroUnits map[int]time.Duration
		iHeroUnits = make(map[int]time.Duration)

		var owners map[uint32]int32
		owners = make(map[uint32]int32)

		var heroes map[int]int32
		heroes = make(map[int]int32)

		p, _ := manta.NewParser(demoFile)

		p.OnPacketEntity(func(pe *manta.PacketEntity, pet manta.EntityEventType) error {

			if pe.ClassName == "CDOTAGamerulesProxy" {
				if v, ok := pe.FetchFloat32("CDOTAGamerules.m_fGameTime"); ok {
					gameTime = time.Duration(v) * time.Second
				}
				if v, ok := pe.FetchFloat32("CDOTAGamerules.m_flPreGameStartTime"); ok {
					preGameStartTime = time.Duration(v) * time.Second
				}
				if v, ok := pe.FetchFloat32("CDOTAGamerules.m_flGameStartTime"); ok {
					gameStartTime = time.Duration(v) * time.Second
				}
				if v, ok := pe.FetchFloat32("CDOTAGamerules.m_flGameEndTime"); ok {
					gameEndTime = time.Duration(v) * time.Second
				}
			}

			if pe.ClassName == "CDOTA_PlayerResource" {
				for i := 0; i < 10; i++ {
					lastInterval := iPlayerResources[i]
					if gameTime.Seconds() > (lastInterval.Seconds() + 10) {
						iPlayerResources[i] = gameTime

						heroID, _ := pe.FetchInt32("m_vecPlayerTeamData.000" + strconv.Itoa(i) + ".m_nSelectedHeroID")
						if heroID > 0 {
							heroes[i] = heroID

							level, _ := pe.FetchInt32("m_vecPlayerTeamData.000" + strconv.Itoa(i) + ".m_iLevel")
							assists, _ := pe.FetchInt32("m_vecPlayerTeamData.000" + strconv.Itoa(i) + ".m_iAssists")
							deaths, _ := pe.FetchInt32("m_vecPlayerTeamData.000" + strconv.Itoa(i) + ".m_iDeaths")
							kills, _ := pe.FetchInt32("m_vecPlayerTeamData.000" + strconv.Itoa(i) + ".m_iKills")

							fmt.Fprintf(w, "{\"type\":2,\"time\":\"%s\",\"hero\":%d,\"level\":%d,\"kills\":%d,\"deaths\":%d,\"assists\":%d},", formatDuration(gameTime), heroID, level, kills, deaths, assists)
						}
					}
				}
			}

			if pe.ClassName == "CDOTA_DataDire" || pe.ClassName == "CDOTA_DataRadiant" {
				for i := 0; i < 5; i++ {
					var playerID = i
					if pe.ClassName == "CDOTA_DataDire" {
						playerID += 5
					}

					lastInterval := iTeamData[int(playerID)]
					if gameTime.Seconds() > (lastInterval.Seconds() + 5) {
						iTeamData[int(playerID)] = gameTime

						if heroID, ok := heroes[int(playerID)]; ok {

							healing, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_fHealing")
							stuns, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_fStuns")
							buybackCooldown, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_flBuybackCooldownTime")
							creepGold, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iCreepKillGold")
							denies, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iDenyCount")
							heroGold, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iHeroKillGold")
							incomeGold, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iIncomeGold")
							lastHits, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iLastHitCount")
							missCount, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iMissCount")
							nearbyCreepCount, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iNearbyCreepDeathCount")
							reliableGold, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iReliableGold")
							unreliableGold, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iUnreliableGold")
							sharedGold, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iSharedGold")
							gold, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iTotalEarnedGold")
							xp, _ := pe.FetchInt32("m_vecDataTeam.000" + strconv.Itoa(i) + ".m_iTotalEarnedXP")

							fmt.Fprintf(w, "{\"type\":3,\"time\":\"%s\",\"hero\":%d,\"healing\":%d,\"stuns\":%d,\"buyback\":%d,\"lasthits\":%d,\"denies\":%d,\"misses\":%d,\"nearby_creeps\":%d,\"gold_creeps\":%d,\"gold_heroes\":%d,\"gold_income\":%d,\"gold_reliable\":%d,\"gold_unreliable\":%d,\"gold_shared\":%d,\"gold\":%d,\"xp\":%d},", formatDuration(gameTime), heroID, healing, stuns, buybackCooldown, lastHits, denies, missCount, nearbyCreepCount, creepGold, heroGold, incomeGold, reliableGold, unreliableGold, sharedGold, gold, xp)
						}
					}
				}
			}

			if strings.HasPrefix(pe.ClassName, "CDOTA_Unit_Hero") {
				playerID, _ := pe.FetchInt32("m_iPlayerID")
				ownerID, _ := pe.Fetch("m_hOwnerEntity")

				lastInterval := iHeroUnits[int(playerID)]
				if gameTime.Seconds() > (lastInterval.Seconds() + 0) {
					iHeroUnits[int(playerID)] = gameTime

					if heroID, ok := heroes[int(playerID)]; ok {
						owners[ownerID.(uint32)] = heroID

						x, _ := pe.Fetch("CBodyComponentBaseAnimatingOverlay.m_cellX")
						y, _ := pe.Fetch("CBodyComponentBaseAnimatingOverlay.m_cellY")

						fmt.Fprintf(w, "{\"type\":4,\"time\":\"%s\",\"hero\":%d,\"x\":%d,\"y\":%d},", formatDuration(gameTime), heroID, x, y)
					}
				}
			}

			if pe.ClassName == "CDOTA_NPC_Observer_Ward" && pet == manta.EntityEventType_Create {
				x, _ := pe.Fetch("CBodyComponentBaseAnimatingOverlay.m_cellX")
				y, _ := pe.Fetch("CBodyComponentBaseAnimatingOverlay.m_cellY")
				ownerID, _ := pe.Fetch("m_hOwnerEntity")
				heroID := owners[ownerID.(uint32)]

				fmt.Fprintf(w, "{\"type\":5,\"time\":\"%s\",\"x\":%d,\"y\":%d,\"hero\":%d},", formatDuration(gameTime), x, y, heroID)
			}

			if pe.ClassName == "CDOTA_NPC_Observer_Ward_TrueSight" && pet == manta.EntityEventType_Create {
				x, _ := pe.Fetch("CBodyComponentBaseAnimatingOverlay.m_cellX")
				y, _ := pe.Fetch("CBodyComponentBaseAnimatingOverlay.m_cellY")
				ownerID, _ := pe.Fetch("m_hOwnerEntity")
				heroID := owners[ownerID.(uint32)]

				fmt.Fprintf(w, "{\"type\":6,\"time\":\"%s\",\"x\":%d,\"y\":%d,\"hero\":%d},", formatDuration(gameTime), x, y, heroID)
			}

			return nil
		})

		p.Callbacks.OnCUserMessageSayText2(func(m *dota.CUserMessageSayText2) error {
			fmt.Fprintf(w, "{\"type\":7,\"time\":\"%s\",\"player\":\"%s\",\"said\":\"%s\"},", formatDuration(gameTime), m.GetParam1(), m.GetParam2())
			return nil
		})

		p.Callbacks.OnCDOTAUserMsg_ChatEvent(func(e *dota.CDOTAUserMsg_ChatEvent) error {

			t := e.GetType()
			switch dota.DOTA_CHAT_MESSAGE(t) {
			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_HERO_KILL:
				// covered by combat log

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_HERO_DENY:
				// covered by combat log

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_BARRACKS_KILL:
				//They go in incremental powers of 2, starting by the Dire side to the Dire Side, Bottom to Top, Melee to Ranged
				//ex: Bottom Melee Dire Rax = 1 and Top Ranged Radiant Rax = 2048.
				fmt.Fprintf(w, "{\"type\":8,\"time\":\"%s\",\"barracks\":%d,\"player\":%d},", formatDuration(gameTime), e.GetValue(), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_TOWER_KILL:
				//player1 = slot of player who killed tower (-1 if nonplayer)
				//value (2/3 radiant/dire killed tower, recently 0/1?)
				fmt.Fprintf(w, "{\"type\":9,\"time\":\"%s\",\"tower\":%d,\"player\":%d},", formatDuration(gameTime), e.GetValue(), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_TOWER_DENY:
				fmt.Fprintf(w, "{\"type\":10,\"time\":\"%s\",\"tower\":%d,\"player\":%d},", formatDuration(gameTime), e.GetValue(), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_EFFIGY_KILL:
				fmt.Fprintf(w, "{\"type\":11,\"time\":\"%s\",\"player\":%d},", formatDuration(gameTime), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_FIRSTBLOOD:
				fmt.Fprintf(w, "{\"type\":12,\"time\":\"%s\",\"player\":%d},", formatDuration(gameTime), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_STREAK_KILL:
				// covered by combat log

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_BUYBACK:
				// covered by combat log

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_ROSHAN_KILL:
				//player1 = team that killed roshan? (2/3)
				fmt.Fprintf(w, "{\"type\":13,\"time\":\"%s\",\"team\":%d,\"value\":%d},", formatDuration(gameTime), e.GetPlayerid_1(), e.GetValue())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_AEGIS:
				//player1 = slot who picked up/denied/stole aegis
				fmt.Fprintf(w, "{\"type\":14,\"time\":\"%s\",\"player\":%d},", formatDuration(gameTime), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_AEGIS_STOLEN:
				fmt.Fprintf(w, "{\"type\":15,\"time\":\"%s\",\"player\":%d},", formatDuration(gameTime), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_DENIED_AEGIS:
				fmt.Fprintf(w, "{\"type\":16,\"time\":\"%s\",\"player\":%d},", formatDuration(gameTime), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_COURIER_LOST:
				//player1 = team that lost courier (2/3)
				fmt.Fprintf(w, "{\"type\":17,\"time\":\"%s\",\"team\":%d},", formatDuration(gameTime), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_COURIER_RESPAWNED:
				fmt.Fprintf(w, "{\"type\":18,\"time\":\"%s\",\"team\":%d},", formatDuration(gameTime), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_GLYPH_USED:
				// team that used glyph (2/3, or 0/1) ?
				fmt.Fprintf(w, "{\"type\":19,\"time\":\"%s\",\"team\":%d},", formatDuration(gameTime), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_ITEM_PURCHASE:
				// Not usefull dose not include all PURCHASES

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_RUNE_PICKUP:
				fmt.Fprintf(w, "{\"type\":20,\"time\":\"%s\",\"player\":%d,\"rune\":%d},", formatDuration(gameTime), e.GetPlayerid_1(), e.GetValue())
				//"0": "Double Damage", "1": "Haste", "2": "Illusion", "3": "Invisibility", "4": "Regeneration", "4": "Bounty"

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_RUNE_BOTTLE:
				fmt.Fprintf(w, "{\"type\":21,\"time\":\"%s\",\"player\":%d,\"rune\":%d},", formatDuration(gameTime), e.GetPlayerid_1(), e.GetValue())
				//"0": "Double Damage", "1": "Haste", "2": "Illusion", "3": "Invisibility", "4": "Regeneration", "4": "Bounty"

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_SUPER_CREEPS:
				fmt.Fprintf(w, "{\"type\":22,\"time\":\"%s\",\"team\":%d},", formatDuration(gameTime), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_CONNECT:
			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_DISCONNECT:
			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_RECONNECT:
			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_PLAYER_LEFT:
			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_SAFE_TO_LEAVE:
				// Is this needed?

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_PAUSED:
			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_UNPAUSED:
				// Maybe at some point?

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_INTHEBAG:
				fmt.Fprintf(w, "{\"type\":23,\"time\":\"%s\",\"player\":%d},", formatDuration(gameTime), e.GetPlayerid_1())

			case dota.DOTA_CHAT_MESSAGE_CHAT_MESSAGE_TAUNT:
				// Is this needed?
			}

			return nil
		})

		p.Callbacks.OnCMsgDOTACombatLogEntry(func(m *dota.CMsgDOTACombatLogEntry) error {

			t := m.GetType()
			switch dota.DOTA_COMBATLOG_TYPES(t) {
			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_DAMAGE:
				iat := m.GetIsAttackerIllusion()
				iah := m.GetIsAttackerHero()
				iti := m.GetIsTargetIllusion()
				ith := m.GetIsTargetHero()
				ivr := m.GetIsVisibleRadiant()
				ivd := m.GetIsVisibleDire()
				itb := m.GetIsTargetBuilding()

				target, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetName()))
				targetSource, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetSourceName()))
				attacker, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetAttackerName()))
				damageSource, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetDamageSourceName()))
				inflictor, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetInflictorName()))
				value := m.GetValue()

				fmt.Fprintf(w, "{\"type\":24,\"time\":\"%s\",\"iat\":%t,\"iah\":%t,\"iti\":%t,\"ith\":%t,\"ivr\":%t,\"ivd\":%t,\"itb\":%t,\"attacker\":\"%s\",\"target\":\"%s\",\"target_source\":\"%s\",\"damage_source\":\"%s\",\"inflictor\":\"%s\",\"value\":%d},", formatDuration(gameTime), iat, iah, iti, ith, ivr, ivd, itb, attacker, target, targetSource, damageSource, inflictor, value)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_HEAL:
				iat := m.GetIsAttackerIllusion()
				iah := m.GetIsAttackerHero()
				iti := m.GetIsTargetIllusion()
				ith := m.GetIsTargetHero()
				ivr := m.GetIsVisibleRadiant()
				ivd := m.GetIsVisibleDire()
				itb := m.GetIsTargetBuilding()

				target, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetName()))
				targetSource, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetSourceName()))
				attacker, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetAttackerName()))
				damageSource, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetDamageSourceName()))
				inflictor, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetInflictorName()))

				value := m.GetValue()
				fmt.Fprintf(w, "{\"type\":25,\"time\":\"%s\",\"iat\":%t,\"iah\":%t,\"iti\":%t,\"ith\":%t,\"ivr\":%t,\"ivd\":%t,\"itb\":%t,\"attacker\":\"%s\",\"target\":\"%s\",\"target_source\":\"%s\",\"damage_source\":\"%s\",\"inflictor\":\"%s\",\"value\":%d},", formatDuration(gameTime), iat, iah, iti, ith, ivr, ivd, itb, attacker, target, targetSource, damageSource, inflictor, value)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_DEATH:
				iat := m.GetIsAttackerIllusion()
				iah := m.GetIsAttackerHero()
				iti := m.GetIsTargetIllusion()
				ith := m.GetIsTargetHero()
				ivr := m.GetIsVisibleRadiant()
				ivd := m.GetIsVisibleDire()
				itb := m.GetIsTargetBuilding()

				target, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetName()))
				targetSource, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetSourceName()))
				attacker, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetAttackerName()))
				damageSource, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetDamageSourceName()))

				fmt.Fprintf(w, "{\"type\":26,\"time\":\"%s\",\"iat\":%t,\"iah\":%t,\"iti\":%t,\"ith\":%t,\"ivr\":%t,\"ivd\":%t,\"itb\":%t,\"attacker\":\"%s\",\"target\":\"%s\",\"target_source\":\"%s\",\"damage_source\":\"%s\"},", formatDuration(gameTime), iat, iah, iti, ith, ivr, ivd, itb, attacker, target, targetSource, damageSource)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_ABILITY:
				iat := m.GetIsAttackerIllusion()
				iah := m.GetIsAttackerHero()
				ivr := m.GetIsVisibleRadiant()
				ivd := m.GetIsVisibleDire()

				attacker, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetAttackerName()))
				inflictor, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetInflictorName()))
				level := m.GetAbilityLevel()

				fmt.Fprintf(w, "{\"type\":27,\"time\":\"%s\",\"iat\":%t,\"iah\":%t,\"ivr\":%t,\"ivd\":%t,\"attacker\":\"%s\",\"inflictor\":\"%s\",\"ability_level\":%d},", formatDuration(gameTime), iat, iah, ivr, ivd, attacker, inflictor, level)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_ITEM:
				attacker, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetAttackerName()))
				inflictor, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetInflictorName()))
				level := m.GetAbilityLevel()

				fmt.Fprintf(w, "{\"type\":28,\"time\":\"%s\",\"player\":\"%s\",\"item\":\"%s\",\"level\":%d},", formatDuration(gameTime), attacker, inflictor, level)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_PURCHASE:
				target, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetName()))
				item, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetValue()))

				fmt.Fprintf(w, "{\"type\":29,\"time\":\"%s\",\"player\":\"%s\",\"item\":\"%s\"},", formatDuration(gameTime), target, item)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_BUYBACK:
				source, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetValue()))

				fmt.Fprintf(w, "{\"type\":30,\"time\":\"%s\",\"player\":\"%s\"},", formatDuration(gameTime), source)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_GOLD:
				amount := m.GetValue()

				reason := m.GetGoldReason()
				// "0": "Other", "1":"Death", "2":"Buyback", "5": "Abandon", "6": "Sell", "11":"Structure", "12":"Hero", "13":"Creep", "14": "Roshan", "15":"Courier"

				target, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetName()))
				targetSource, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetSourceName()))

				fmt.Fprintf(w, "{\"type\":31,\"time\":\"%s\",\"target\":\"%s\",\"targetsource\":\"%s\",\"reason\":%d,\"amount\":%d},", formatDuration(gameTime), target, targetSource, reason, amount)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_XP:
				amount := m.GetValue()
				reason := m.GetXpReason()
				//"0": "Other", "1": "Hero", "2": "Creep", "3": "Roshan"

				target, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetName()))

				fmt.Fprintf(w, "{\"type\":32,\"time\":\"%s\",\"target\":\"%s\",\"reason\":%d,\"amount\":%d},", formatDuration(gameTime), target, reason, amount)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_TEAM_BUILDING_KILL:
				target, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetName()))

				value := m.GetValue()

				fmt.Fprintf(w, "{\"type\":33,\"time\":\"%s\",\"target\":\"%s\",\"value\":%d},", formatDuration(gameTime), target, value)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_NEUTRAL_CAMP_STACK:
				// Not used?

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_PICKUP_RUNE:
				// use Chat Event

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_FIRST_BLOOD:
				// use Chat Event

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_PLAYERSTATS:
			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_GAME_STATE:
			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_LOCATION:
				// Useless...

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_MULTIKILL:
				target, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetName()))
				targetSource, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetSourceName()))
				attacker, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetAttackerName()))

				value := m.GetValue()
				//"2": "Double Kill", "3": "Triple Kill", "4": "Ultra Kill", "5": "Rampage"

				fmt.Fprintf(w, "{\"type\":34,\"time\":\"%s\",\"attacker\":\"%s\",\"target\":\"%s\",\"target_source\":\"%s\",\"value\":%d},",
					formatDuration(gameTime),
					attacker,
					target,
					targetSource,
					value)

			case dota.DOTA_COMBATLOG_TYPES_DOTA_COMBATLOG_KILLSTREAK:
				target, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetName()))
				targetSource, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetTargetSourceName()))
				attacker, _ := p.LookupStringByIndex("CombatLogNames", int32(m.GetAttackerName()))
				value := m.GetValue()
				//"3": "Killing Spree", "4": "Dominating","5": "Mega Kill", "6": "Unstoppable", "7": "Wicked Sick", "8": "Monster Kill", "9": "Godlike", "10": "Beyond Godlike"

				fmt.Fprintf(w, "{\"type\":35,\"time\":\"%s\",\"attacker\":\"%s\",\"target\":\"%s\",\"target_source\":\"%s\",\"value\":%d},",
					formatDuration(gameTime),
					attacker,
					target,
					targetSource,
					value)

			}

			return nil
		})

		start := time.Now().UTC()
		fmt.Fprintf(w, "[{\"type\":0,\"version\":2,\"date\":\"%s\"},", start.Format(time.RFC1123Z))

		p.Start()

		elapsed := time.Since(start)
		fmt.Fprintf(w, "{\"type\":1,\"elapsed\":\"%s\",\"pregame_start\":\"%s\",\"game_start\":\"%s\",\"game_end\":\"%s\"}]", formatDuration(elapsed), formatDuration(preGameStartTime), formatDuration(gameStartTime), formatDuration(gameEndTime))

	default:
		http.Error(w, "Post the replay file you wish to parse.", http.StatusMethodNotAllowed)
		return
	}
}
Example #2
0
func main() {
	bytes, err := ioutil.ReadAll(os.Stdin)
	parser, err := manta.NewParser(bytes)
	//parser, err := manta.NewParserFromFile(arg)
	if err != nil {
		panic(err)
	}

	//things we need
	//entities for player interval data
	//entities for wards
	//every second, check for new wards
	//maintain a hash table of seen ward handles, output if we see a new ward
	//output playerresource entity state (gold/lh/xp/x/y)
	//CDOTAUserMsg_LocationPing for pings
	//CDOTAUserMsg_ChatEvent for chat events, objectives
	//CDemoFileInfo for epilogue, player names
	//get final player interval data for stuns

	//following is currently done by parser but could be done in JS
	//illusion_ should be prepended if illusion
	//item_ should be removed from item key names
	count := 0
	//chat
	/*
		parser.Callbacks.OnCUserMessageSayText2(func(m *dota.CUserMessageSayText2) error {
			fmt.Printf("(%s) | %s: %s\n", m.GetMessagename(), m.GetParam1(), m.GetParam2())
			return nil
		})
	*/
	/*
		parser.Callbacks.OnCDemoFileInfo(func(m *dota.CDemoFileInfo) error {
			fmt.Printf("%s\n", m);
			return nil
		})
	*/

	parser.Callbacks.OnAny(func(m interface{}) error {
		count += 1
		return nil
	})

	parser.Callbacks.OnCMsgSource1LegacyGameEventList(func(m *dota.CMsgSource1LegacyGameEventList) error {
		//fmt.Printf("%s\n", m)
		return nil
	})

	parser.Callbacks.OnCDemoStop(func(m *dota.CDemoStop) error {
		b, err := json.Marshal(nil)
		if err != nil {
			panic(err)
		}
		stringTable, ok := parser.StringTables.GetTableByName("CombatLogNames")
		if !ok {
			panic(!ok)
		}
		fmt.Printf("%s\n", stringTable.GetIndex())
		fmt.Printf("%s\n", b)

		return nil
	})

	parser.Callbacks.OnCDemoStringTables(func(m *dota.CDemoStringTables) error {
		return nil
	})

	/*
		parser.Callbacks.OnCDemoPacket(func(m *dota.CDemoPacket) error {
			fmt.Printf("%s\n", len(m.GetData()));
			panic("test")
			return nil
		})
	*/
	//actions
	/*
		parser.Callbacks.OnCDOTAUserMsg_SpectatorPlayerUnitOrders(func(m *dota.CDOTAUserMsg_SpectatorPlayerUnitOrders) error {
			fmt.Printf("%s\n", m)
			return nil
		})
	*/

	//combat log
	/*
		parser.GameEvents.OnDotaCombatlog(func(m *GameEventDotaCombatlog) error {
			fmt.Printf("%s\n", m)
			return nil
		})
	*/
	parser.Start()
	fmt.Printf("%s\n", count)
}