herostats 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE +7 -0
- data/README.md +34 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/herostats.gemspec +33 -0
- data/lib/heroprotocol/LICENSE +19 -0
- data/lib/heroprotocol/README.md +91 -0
- data/lib/heroprotocol/__init__.py +0 -0
- data/lib/heroprotocol/decoders.py +311 -0
- data/lib/heroprotocol/heroprotocol.py +136 -0
- data/lib/heroprotocol/mpyq/LICENSE +22 -0
- data/lib/heroprotocol/mpyq/MANIFEST.in +3 -0
- data/lib/heroprotocol/mpyq/README.md +202 -0
- data/lib/heroprotocol/mpyq/__init__.py +0 -0
- data/lib/heroprotocol/mpyq/mpyq.py +406 -0
- data/lib/heroprotocol/mpyq/setup.py +33 -0
- data/lib/heroprotocol/protocol29406.py +491 -0
- data/lib/heroprotocol/protocol30414.py +492 -0
- data/lib/heroprotocol/protocol30509.py +492 -0
- data/lib/heroprotocol/protocol30829.py +492 -0
- data/lib/heroprotocol/protocol30948.py +492 -0
- data/lib/heroprotocol/protocol31090.py +492 -0
- data/lib/heroprotocol/protocol31360.py +494 -0
- data/lib/heroprotocol/protocol31566.py +494 -0
- data/lib/heroprotocol/protocol31726.py +494 -0
- data/lib/heroprotocol/protocol31948.py +494 -0
- data/lib/heroprotocol/protocol32120.py +494 -0
- data/lib/heroprotocol/protocol32253.py +494 -0
- data/lib/heroprotocol/protocol32455.py +496 -0
- data/lib/heroprotocol/protocol32524.py +496 -0
- data/lib/heroprotocol/protocol33182.py +499 -0
- data/lib/heroprotocol/protocol33353.py +499 -0
- data/lib/heroprotocol/protocol33684.py +502 -0
- data/lib/heroprotocol/protocol34053.py +502 -0
- data/lib/heroprotocol/protocol34190.py +502 -0
- data/lib/heroprotocol/protocol34659.py +502 -0
- data/lib/heroprotocol/protocol34846.py +502 -0
- data/lib/heroprotocol/protocol35360.py +502 -0
- data/lib/heroprotocol/protocol35529.py +502 -0
- data/lib/heroprotocol/protocol35634.py +502 -0
- data/lib/heroprotocol/protocol35702.py +502 -0
- data/lib/heroprotocol/protocol36144.py +502 -0
- data/lib/heroprotocol/protocol36280.py +502 -0
- data/lib/heroprotocol/protocol36359.py +502 -0
- data/lib/heroprotocol/protocol36536.py +502 -0
- data/lib/heroprotocol/protocol36693.py +502 -0
- data/lib/heroprotocol/protocol37069.py +507 -0
- data/lib/heroprotocol/protocol37117.py +507 -0
- data/lib/heroprotocol/protocol37274.py +507 -0
- data/lib/heroprotocol/protocol37351.py +507 -0
- data/lib/heroprotocol/protocol37569.py +507 -0
- data/lib/heroprotocol/protocol37795.py +507 -0
- data/lib/heroprotocol/protocol38236.py +508 -0
- data/lib/heroprotocol/protocol38500.py +508 -0
- data/lib/heroprotocol/protocol38593.py +508 -0
- data/lib/heroprotocol/protocol38793.py +508 -0
- data/lib/heroprotocol/protocol39015.py +508 -0
- data/lib/heroprotocol/protocol39153.py +508 -0
- data/lib/heroprotocol/protocol39271.py +508 -0
- data/lib/heroprotocol/protocol39445.py +508 -0
- data/lib/heroprotocol/protocol39595.py +508 -0
- data/lib/heroprotocol/protocol39709.py +508 -0
- data/lib/heroprotocol/protocol39951.py +508 -0
- data/lib/heroprotocol/protocol40087.py +508 -0
- data/lib/heroprotocol/protocol40322.py +508 -0
- data/lib/heroprotocol/protocol40336.py +526 -0
- data/lib/heroprotocol/protocol40431.py +526 -0
- data/lib/heroprotocol/protocol40697.py +526 -0
- data/lib/heroprotocol/protocol40798.py +526 -0
- data/lib/herostats.rb +10 -0
- data/lib/herostats/exp_breakdown.rb +24 -0
- data/lib/herostats/game.rb +25 -0
- data/lib/herostats/init_data_parser.rb +45 -0
- data/lib/herostats/player.rb +25 -0
- data/lib/herostats/replay_parser.rb +34 -0
- data/lib/herostats/team.rb +10 -0
- data/lib/herostats/tracker_events_parser.rb +158 -0
- data/lib/herostats/version.rb +3 -0
- metadata +171 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
# Copyright (c) 2015 Blizzard Entertainment
|
|
2
|
+
#
|
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
8
|
+
# furnished to do so, subject to the following conditions:
|
|
9
|
+
#
|
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
|
11
|
+
# all copies or substantial portions of the Software.
|
|
12
|
+
#
|
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
19
|
+
# THE SOFTWARE.
|
|
20
|
+
|
|
21
|
+
from decoders import *
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Decoding instructions for each protocol type.
|
|
25
|
+
typeinfos = [
|
|
26
|
+
('_int',[(0,7)]), #0
|
|
27
|
+
('_int',[(0,4)]), #1
|
|
28
|
+
('_int',[(0,5)]), #2
|
|
29
|
+
('_int',[(0,6)]), #3
|
|
30
|
+
('_int',[(0,14)]), #4
|
|
31
|
+
('_int',[(0,22)]), #5
|
|
32
|
+
('_int',[(0,32)]), #6
|
|
33
|
+
('_choice',[(0,2),{0:('m_uint6',3),1:('m_uint14',4),2:('m_uint22',5),3:('m_uint32',6)}]), #7
|
|
34
|
+
('_struct',[[('m_userId',2,-1)]]), #8
|
|
35
|
+
('_blob',[(0,8)]), #9
|
|
36
|
+
('_int',[(0,8)]), #10
|
|
37
|
+
('_struct',[[('m_flags',10,0),('m_major',10,1),('m_minor',10,2),('m_revision',10,3),('m_build',6,4),('m_baseBuild',6,5)]]), #11
|
|
38
|
+
('_int',[(0,3)]), #12
|
|
39
|
+
('_bool',[]), #13
|
|
40
|
+
('_array',[(16,0),10]), #14
|
|
41
|
+
('_optional',[14]), #15
|
|
42
|
+
('_struct',[[('m_data',15,0)]]), #16
|
|
43
|
+
('_struct',[[('m_signature',9,0),('m_version',11,1),('m_type',12,2),('m_elapsedGameLoops',6,3),('m_useScaledTime',13,4),('m_ngdpRootKey',16,5),('m_dataBuildNum',6,6)]]), #17
|
|
44
|
+
('_fourcc',[]), #18
|
|
45
|
+
('_blob',[(0,7)]), #19
|
|
46
|
+
('_int',[(0,64)]), #20
|
|
47
|
+
('_struct',[[('m_region',10,0),('m_programId',18,1),('m_realm',6,2),('m_name',19,3),('m_id',20,4)]]), #21
|
|
48
|
+
('_struct',[[('m_a',10,0),('m_r',10,1),('m_g',10,2),('m_b',10,3)]]), #22
|
|
49
|
+
('_int',[(0,2)]), #23
|
|
50
|
+
('_optional',[10]), #24
|
|
51
|
+
('_struct',[[('m_name',9,0),('m_toon',21,1),('m_race',9,2),('m_color',22,3),('m_control',10,4),('m_teamId',1,5),('m_handicap',0,6),('m_observe',23,7),('m_result',23,8),('m_workingSetSlotId',24,9),('m_hero',9,10)]]), #25
|
|
52
|
+
('_array',[(0,5),25]), #26
|
|
53
|
+
('_optional',[26]), #27
|
|
54
|
+
('_blob',[(0,10)]), #28
|
|
55
|
+
('_blob',[(0,11)]), #29
|
|
56
|
+
('_struct',[[('m_file',29,0)]]), #30
|
|
57
|
+
('_optional',[13]), #31
|
|
58
|
+
('_int',[(-9223372036854775808,64)]), #32
|
|
59
|
+
('_blob',[(0,12)]), #33
|
|
60
|
+
('_blob',[(40,0)]), #34
|
|
61
|
+
('_array',[(0,6),34]), #35
|
|
62
|
+
('_optional',[35]), #36
|
|
63
|
+
('_array',[(0,6),29]), #37
|
|
64
|
+
('_optional',[37]), #38
|
|
65
|
+
('_struct',[[('m_playerList',27,0),('m_title',28,1),('m_difficulty',9,2),('m_thumbnail',30,3),('m_isBlizzardMap',13,4),('m_restartAsTransitionMap',31,16),('m_timeUTC',32,5),('m_timeLocalOffset',32,6),('m_description',33,7),('m_imageFilePath',29,8),('m_campaignIndex',10,15),('m_mapFileName',29,9),('m_cacheHandles',36,10),('m_miniSave',13,11),('m_gameSpeed',12,12),('m_defaultDifficulty',3,13),('m_modPaths',38,14)]]), #39
|
|
66
|
+
('_optional',[9]), #40
|
|
67
|
+
('_optional',[34]), #41
|
|
68
|
+
('_optional',[6]), #42
|
|
69
|
+
('_struct',[[('m_race',24,-1)]]), #43
|
|
70
|
+
('_struct',[[('m_team',24,-1)]]), #44
|
|
71
|
+
('_blob',[(0,9)]), #45
|
|
72
|
+
('_struct',[[('m_name',9,-18),('m_clanTag',40,-17),('m_clanLogo',41,-16),('m_highestLeague',24,-15),('m_combinedRaceLevels',42,-14),('m_randomSeed',6,-13),('m_racePreference',43,-12),('m_teamPreference',44,-11),('m_testMap',13,-10),('m_testAuto',13,-9),('m_examine',13,-8),('m_customInterface',13,-7),('m_testType',6,-6),('m_observe',23,-5),('m_hero',45,-4),('m_skin',45,-3),('m_mount',45,-2),('m_toonHandle',19,-1)]]), #46
|
|
73
|
+
('_array',[(0,5),46]), #47
|
|
74
|
+
('_struct',[[('m_lockTeams',13,-14),('m_teamsTogether',13,-13),('m_advancedSharedControl',13,-12),('m_randomRaces',13,-11),('m_battleNet',13,-10),('m_amm',13,-9),('m_competitive',13,-8),('m_practice',13,-7),('m_cooperative',13,-6),('m_noVictoryOrDefeat',13,-5),('m_fog',23,-4),('m_observers',23,-3),('m_userDifficulty',23,-2),('m_clientDebugFlags',20,-1)]]), #48
|
|
75
|
+
('_int',[(1,4)]), #49
|
|
76
|
+
('_int',[(1,8)]), #50
|
|
77
|
+
('_bitarray',[(0,6)]), #51
|
|
78
|
+
('_bitarray',[(0,8)]), #52
|
|
79
|
+
('_bitarray',[(0,2)]), #53
|
|
80
|
+
('_bitarray',[(0,7)]), #54
|
|
81
|
+
('_struct',[[('m_allowedColors',51,-6),('m_allowedRaces',52,-5),('m_allowedDifficulty',51,-4),('m_allowedControls',52,-3),('m_allowedObserveTypes',53,-2),('m_allowedAIBuilds',54,-1)]]), #55
|
|
82
|
+
('_array',[(0,5),55]), #56
|
|
83
|
+
('_struct',[[('m_randomValue',6,-26),('m_gameCacheName',28,-25),('m_gameOptions',48,-24),('m_gameSpeed',12,-23),('m_gameType',12,-22),('m_maxUsers',2,-21),('m_maxObservers',2,-20),('m_maxPlayers',2,-19),('m_maxTeams',49,-18),('m_maxColors',3,-17),('m_maxRaces',50,-16),('m_maxControls',10,-15),('m_mapSizeX',10,-14),('m_mapSizeY',10,-13),('m_mapFileSyncChecksum',6,-12),('m_mapFileName',29,-11),('m_mapAuthorName',9,-10),('m_modFileSyncChecksum',6,-9),('m_slotDescriptions',56,-8),('m_defaultDifficulty',3,-7),('m_defaultAIBuild',0,-6),('m_cacheHandles',35,-5),('m_hasExtensionMod',13,-4),('m_isBlizzardMap',13,-3),('m_isPremadeFFA',13,-2),('m_isCoopMode',13,-1)]]), #57
|
|
84
|
+
('_optional',[1]), #58
|
|
85
|
+
('_optional',[2]), #59
|
|
86
|
+
('_struct',[[('m_color',59,-1)]]), #60
|
|
87
|
+
('_array',[(0,17),6]), #61
|
|
88
|
+
('_array',[(0,9),6]), #62
|
|
89
|
+
('_struct',[[('m_control',10,-16),('m_userId',58,-15),('m_teamId',1,-14),('m_colorPref',60,-13),('m_racePref',43,-12),('m_difficulty',3,-11),('m_aiBuild',0,-10),('m_handicap',0,-9),('m_observe',23,-8),('m_hero',45,-7),('m_skin',45,-6),('m_mount',45,-5),('m_workingSetSlotId',24,-4),('m_rewards',61,-3),('m_toonHandle',19,-2),('m_licenses',62,-1)]]), #63
|
|
90
|
+
('_array',[(0,5),63]), #64
|
|
91
|
+
('_struct',[[('m_phase',12,-10),('m_maxUsers',2,-9),('m_maxObservers',2,-8),('m_slots',64,-7),('m_randomSeed',6,-6),('m_hostUserId',58,-5),('m_isSinglePlayer',13,-4),('m_gameDuration',6,-3),('m_defaultDifficulty',3,-2),('m_defaultAIBuild',0,-1)]]), #65
|
|
92
|
+
('_struct',[[('m_userInitialData',47,-3),('m_gameDescription',57,-2),('m_lobbyState',65,-1)]]), #66
|
|
93
|
+
('_struct',[[('m_syncLobbyState',66,-1)]]), #67
|
|
94
|
+
('_struct',[[('m_name',19,-1)]]), #68
|
|
95
|
+
('_blob',[(0,6)]), #69
|
|
96
|
+
('_struct',[[('m_name',69,-1)]]), #70
|
|
97
|
+
('_struct',[[('m_name',69,-3),('m_type',6,-2),('m_data',19,-1)]]), #71
|
|
98
|
+
('_struct',[[('m_type',6,-3),('m_name',69,-2),('m_data',33,-1)]]), #72
|
|
99
|
+
('_array',[(0,5),10]), #73
|
|
100
|
+
('_struct',[[('m_signature',73,-2),('m_toonHandle',19,-1)]]), #74
|
|
101
|
+
('_struct',[[('m_gameFullyDownloaded',13,-14),('m_developmentCheatsEnabled',13,-13),('m_multiplayerCheatsEnabled',13,-12),('m_syncChecksummingEnabled',13,-11),('m_isMapToMapTransition',13,-10),('m_startingRally',13,-9),('m_debugPauseEnabled',13,-8),('m_useGalaxyAsserts',13,-7),('m_platformMac',13,-6),('m_cameraFollow',13,-5),('m_baseBuildNum',6,-4),('m_buildNum',6,-3),('m_versionFlags',6,-2),('m_hotkeyProfile',45,-1)]]), #75
|
|
102
|
+
('_struct',[[]]), #76
|
|
103
|
+
('_int',[(0,16)]), #77
|
|
104
|
+
('_struct',[[('x',77,-2),('y',77,-1)]]), #78
|
|
105
|
+
('_struct',[[('m_which',12,-2),('m_target',78,-1)]]), #79
|
|
106
|
+
('_struct',[[('m_fileName',29,-5),('m_automatic',13,-4),('m_overwrite',13,-3),('m_name',9,-2),('m_description',28,-1)]]), #80
|
|
107
|
+
('_int',[(-2147483648,32)]), #81
|
|
108
|
+
('_struct',[[('x',81,-2),('y',81,-1)]]), #82
|
|
109
|
+
('_struct',[[('m_point',82,-4),('m_time',81,-3),('m_verb',28,-2),('m_arguments',28,-1)]]), #83
|
|
110
|
+
('_struct',[[('m_data',83,-1)]]), #84
|
|
111
|
+
('_int',[(0,21)]), #85
|
|
112
|
+
('_struct',[[('m_abilLink',77,-3),('m_abilCmdIndex',2,-2),('m_abilCmdData',24,-1)]]), #86
|
|
113
|
+
('_optional',[86]), #87
|
|
114
|
+
('_null',[]), #88
|
|
115
|
+
('_int',[(0,20)]), #89
|
|
116
|
+
('_struct',[[('x',89,-3),('y',89,-2),('z',81,-1)]]), #90
|
|
117
|
+
('_struct',[[('m_targetUnitFlags',77,-7),('m_timer',10,-6),('m_tag',6,-5),('m_snapshotUnitLink',77,-4),('m_snapshotControlPlayerId',58,-3),('m_snapshotUpkeepPlayerId',58,-2),('m_snapshotPoint',90,-1)]]), #91
|
|
118
|
+
('_choice',[(0,2),{0:('None',88),1:('TargetPoint',90),2:('TargetUnit',91),3:('Data',6)}]), #92
|
|
119
|
+
('_struct',[[('m_cmdFlags',85,-5),('m_abil',87,-4),('m_data',92,-3),('m_otherUnit',42,-2),('m_unitGroup',42,-1)]]), #93
|
|
120
|
+
('_int',[(0,9)]), #94
|
|
121
|
+
('_bitarray',[(0,9)]), #95
|
|
122
|
+
('_array',[(0,9),94]), #96
|
|
123
|
+
('_choice',[(0,2),{0:('None',88),1:('Mask',95),2:('OneIndices',96),3:('ZeroIndices',96)}]), #97
|
|
124
|
+
('_struct',[[('m_unitLink',77,-4),('m_subgroupPriority',10,-3),('m_intraSubgroupPriority',10,-2),('m_count',94,-1)]]), #98
|
|
125
|
+
('_array',[(0,9),98]), #99
|
|
126
|
+
('_struct',[[('m_subgroupIndex',94,-4),('m_removeMask',97,-3),('m_addSubgroups',99,-2),('m_addUnitTags',62,-1)]]), #100
|
|
127
|
+
('_struct',[[('m_controlGroupId',1,-2),('m_delta',100,-1)]]), #101
|
|
128
|
+
('_struct',[[('m_controlGroupIndex',1,-3),('m_controlGroupUpdate',23,-2),('m_mask',97,-1)]]), #102
|
|
129
|
+
('_struct',[[('m_count',94,-6),('m_subgroupCount',94,-5),('m_activeSubgroupIndex',94,-4),('m_unitTagsChecksum',6,-3),('m_subgroupIndicesChecksum',6,-2),('m_subgroupsChecksum',6,-1)]]), #103
|
|
130
|
+
('_struct',[[('m_controlGroupId',1,-2),('m_selectionSyncData',103,-1)]]), #104
|
|
131
|
+
('_array',[(0,3),81]), #105
|
|
132
|
+
('_struct',[[('m_recipientId',1,-2),('m_resources',105,-1)]]), #106
|
|
133
|
+
('_struct',[[('m_chatMessage',28,-1)]]), #107
|
|
134
|
+
('_int',[(-128,8)]), #108
|
|
135
|
+
('_struct',[[('x',81,-3),('y',81,-2),('z',81,-1)]]), #109
|
|
136
|
+
('_struct',[[('m_beacon',108,-9),('m_ally',108,-8),('m_flags',108,-7),('m_build',108,-6),('m_targetUnitTag',6,-5),('m_targetUnitSnapshotUnitLink',77,-4),('m_targetUnitSnapshotUpkeepPlayerId',108,-3),('m_targetUnitSnapshotControlPlayerId',108,-2),('m_targetPoint',109,-1)]]), #110
|
|
137
|
+
('_struct',[[('m_speed',12,-1)]]), #111
|
|
138
|
+
('_struct',[[('m_delta',108,-1)]]), #112
|
|
139
|
+
('_struct',[[('m_point',82,-4),('m_unit',6,-3),('m_pingedMinimap',13,-2),('m_option',81,-1)]]), #113
|
|
140
|
+
('_struct',[[('m_verb',28,-2),('m_arguments',28,-1)]]), #114
|
|
141
|
+
('_struct',[[('m_alliance',6,-2),('m_control',6,-1)]]), #115
|
|
142
|
+
('_struct',[[('m_unitTag',6,-1)]]), #116
|
|
143
|
+
('_struct',[[('m_unitTag',6,-2),('m_flags',10,-1)]]), #117
|
|
144
|
+
('_struct',[[('m_conversationId',81,-2),('m_replyId',81,-1)]]), #118
|
|
145
|
+
('_optional',[19]), #119
|
|
146
|
+
('_struct',[[('m_gameUserId',1,-6),('m_observe',23,-5),('m_name',9,-4),('m_toonHandle',119,-3),('m_clanTag',40,-2),('m_clanLogo',41,-1)]]), #120
|
|
147
|
+
('_array',[(0,5),120]), #121
|
|
148
|
+
('_int',[(0,1)]), #122
|
|
149
|
+
('_struct',[[('m_userInfos',121,-2),('m_method',122,-1)]]), #123
|
|
150
|
+
('_struct',[[('m_purchaseItemId',81,-1)]]), #124
|
|
151
|
+
('_struct',[[('m_difficultyLevel',81,-1)]]), #125
|
|
152
|
+
('_choice',[(0,3),{0:('None',88),1:('Checked',13),2:('ValueChanged',6),3:('SelectionChanged',81),4:('TextChanged',29),5:('MouseButton',6)}]), #126
|
|
153
|
+
('_struct',[[('m_controlId',81,-3),('m_eventType',81,-2),('m_eventData',126,-1)]]), #127
|
|
154
|
+
('_struct',[[('m_soundHash',6,-2),('m_length',6,-1)]]), #128
|
|
155
|
+
('_array',[(0,7),6]), #129
|
|
156
|
+
('_struct',[[('m_soundHash',129,-2),('m_length',129,-1)]]), #130
|
|
157
|
+
('_struct',[[('m_syncInfo',130,-1)]]), #131
|
|
158
|
+
('_struct',[[('m_queryId',77,-3),('m_lengthMs',6,-2),('m_finishGameLoop',6,-1)]]), #132
|
|
159
|
+
('_struct',[[('m_queryId',77,-2),('m_lengthMs',6,-1)]]), #133
|
|
160
|
+
('_struct',[[('m_animWaitQueryId',77,-1)]]), #134
|
|
161
|
+
('_struct',[[('m_sound',6,-1)]]), #135
|
|
162
|
+
('_struct',[[('m_transmissionId',81,-2),('m_thread',6,-1)]]), #136
|
|
163
|
+
('_struct',[[('m_transmissionId',81,-1)]]), #137
|
|
164
|
+
('_optional',[78]), #138
|
|
165
|
+
('_optional',[77]), #139
|
|
166
|
+
('_optional',[108]), #140
|
|
167
|
+
('_struct',[[('m_target',138,-6),('m_distance',139,-5),('m_pitch',139,-4),('m_yaw',139,-3),('m_reason',140,-2),('m_follow',13,-1)]]), #141
|
|
168
|
+
('_struct',[[('m_skipType',122,-1)]]), #142
|
|
169
|
+
('_int',[(0,11)]), #143
|
|
170
|
+
('_struct',[[('x',143,-2),('y',143,-1)]]), #144
|
|
171
|
+
('_struct',[[('m_button',6,-5),('m_down',13,-4),('m_posUI',144,-3),('m_posWorld',90,-2),('m_flags',108,-1)]]), #145
|
|
172
|
+
('_struct',[[('m_posUI',144,-3),('m_posWorld',90,-2),('m_flags',108,-1)]]), #146
|
|
173
|
+
('_struct',[[('m_achievementLink',77,-1)]]), #147
|
|
174
|
+
('_struct',[[('m_hotkey',6,-2),('m_down',13,-1)]]), #148
|
|
175
|
+
('_struct',[[('m_abilLink',77,-3),('m_abilCmdIndex',2,-2),('m_state',108,-1)]]), #149
|
|
176
|
+
('_struct',[[('m_soundtrack',6,-1)]]), #150
|
|
177
|
+
('_struct',[[('m_planetId',81,-1)]]), #151
|
|
178
|
+
('_struct',[[('m_key',108,-2),('m_flags',108,-1)]]), #152
|
|
179
|
+
('_struct',[[('m_resources',105,-1)]]), #153
|
|
180
|
+
('_struct',[[('m_fulfillRequestId',81,-1)]]), #154
|
|
181
|
+
('_struct',[[('m_cancelRequestId',81,-1)]]), #155
|
|
182
|
+
('_struct',[[('m_researchItemId',81,-1)]]), #156
|
|
183
|
+
('_struct',[[('m_mercenaryId',81,-1)]]), #157
|
|
184
|
+
('_struct',[[('m_battleReportId',81,-2),('m_difficultyLevel',81,-1)]]), #158
|
|
185
|
+
('_struct',[[('m_battleReportId',81,-1)]]), #159
|
|
186
|
+
('_int',[(0,19)]), #160
|
|
187
|
+
('_struct',[[('m_decrementMs',160,-1)]]), #161
|
|
188
|
+
('_struct',[[('m_portraitId',81,-1)]]), #162
|
|
189
|
+
('_struct',[[('m_functionName',19,-1)]]), #163
|
|
190
|
+
('_struct',[[('m_result',81,-1)]]), #164
|
|
191
|
+
('_struct',[[('m_gameMenuItemIndex',81,-1)]]), #165
|
|
192
|
+
('_struct',[[('m_purchaseCategoryId',81,-1)]]), #166
|
|
193
|
+
('_struct',[[('m_button',77,-1)]]), #167
|
|
194
|
+
('_struct',[[('m_cutsceneId',81,-2),('m_bookmarkName',19,-1)]]), #168
|
|
195
|
+
('_struct',[[('m_cutsceneId',81,-1)]]), #169
|
|
196
|
+
('_struct',[[('m_cutsceneId',81,-3),('m_conversationLine',19,-2),('m_altConversationLine',19,-1)]]), #170
|
|
197
|
+
('_struct',[[('m_cutsceneId',81,-2),('m_conversationLine',19,-1)]]), #171
|
|
198
|
+
('_struct',[[('m_observe',23,-6),('m_name',9,-5),('m_toonHandle',119,-4),('m_clanTag',40,-3),('m_clanLogo',41,-2),('m_hijack',13,-1)]]), #172
|
|
199
|
+
('_struct',[[('m_state',23,-1)]]), #173
|
|
200
|
+
('_struct',[[('m_managed',13,-3),('m_target',90,-2),('m_unitGroup',42,-1)]]), #174
|
|
201
|
+
('_struct',[[('m_managed',13,-3),('m_target',91,-2),('m_unitGroup',42,-1)]]), #175
|
|
202
|
+
('_struct',[[('m_catalog',10,-4),('m_entry',77,-3),('m_field',9,-2),('m_value',9,-1)]]), #176
|
|
203
|
+
('_struct',[[('m_index',6,-1)]]), #177
|
|
204
|
+
('_struct',[[('m_recipient',12,-2),('m_string',29,-1)]]), #178
|
|
205
|
+
('_struct',[[('m_recipient',12,-2),('m_point',82,-1)]]), #179
|
|
206
|
+
('_struct',[[('m_progress',81,-1)]]), #180
|
|
207
|
+
('_struct',[[('m_status',23,-1)]]), #181
|
|
208
|
+
('_struct',[[('m_scoreValueMineralsCurrent',81,0),('m_scoreValueVespeneCurrent',81,1),('m_scoreValueMineralsCollectionRate',81,2),('m_scoreValueVespeneCollectionRate',81,3),('m_scoreValueWorkersActiveCount',81,4),('m_scoreValueMineralsUsedInProgressArmy',81,5),('m_scoreValueMineralsUsedInProgressEconomy',81,6),('m_scoreValueMineralsUsedInProgressTechnology',81,7),('m_scoreValueVespeneUsedInProgressArmy',81,8),('m_scoreValueVespeneUsedInProgressEconomy',81,9),('m_scoreValueVespeneUsedInProgressTechnology',81,10),('m_scoreValueMineralsUsedCurrentArmy',81,11),('m_scoreValueMineralsUsedCurrentEconomy',81,12),('m_scoreValueMineralsUsedCurrentTechnology',81,13),('m_scoreValueVespeneUsedCurrentArmy',81,14),('m_scoreValueVespeneUsedCurrentEconomy',81,15),('m_scoreValueVespeneUsedCurrentTechnology',81,16),('m_scoreValueMineralsLostArmy',81,17),('m_scoreValueMineralsLostEconomy',81,18),('m_scoreValueMineralsLostTechnology',81,19),('m_scoreValueVespeneLostArmy',81,20),('m_scoreValueVespeneLostEconomy',81,21),('m_scoreValueVespeneLostTechnology',81,22),('m_scoreValueMineralsKilledArmy',81,23),('m_scoreValueMineralsKilledEconomy',81,24),('m_scoreValueMineralsKilledTechnology',81,25),('m_scoreValueVespeneKilledArmy',81,26),('m_scoreValueVespeneKilledEconomy',81,27),('m_scoreValueVespeneKilledTechnology',81,28),('m_scoreValueFoodUsed',81,29),('m_scoreValueFoodMade',81,30),('m_scoreValueMineralsUsedActiveForces',81,31),('m_scoreValueVespeneUsedActiveForces',81,32),('m_scoreValueMineralsFriendlyFireArmy',81,33),('m_scoreValueMineralsFriendlyFireEconomy',81,34),('m_scoreValueMineralsFriendlyFireTechnology',81,35),('m_scoreValueVespeneFriendlyFireArmy',81,36),('m_scoreValueVespeneFriendlyFireEconomy',81,37),('m_scoreValueVespeneFriendlyFireTechnology',81,38)]]), #182
|
|
209
|
+
('_struct',[[('m_playerId',1,0),('m_stats',182,1)]]), #183
|
|
210
|
+
('_struct',[[('m_unitTagIndex',6,0),('m_unitTagRecycle',6,1),('m_unitTypeName',28,2),('m_controlPlayerId',1,3),('m_upkeepPlayerId',1,4),('m_x',10,5),('m_y',10,6)]]), #184
|
|
211
|
+
('_struct',[[('m_unitTagIndex',6,0),('m_unitTagRecycle',6,1),('m_killerPlayerId',58,2),('m_x',10,3),('m_y',10,4),('m_killerUnitTagIndex',42,5),('m_killerUnitTagRecycle',42,6)]]), #185
|
|
212
|
+
('_struct',[[('m_unitTagIndex',6,0),('m_unitTagRecycle',6,1),('m_controlPlayerId',1,2),('m_upkeepPlayerId',1,3)]]), #186
|
|
213
|
+
('_struct',[[('m_unitTagIndex',6,0),('m_unitTagRecycle',6,1),('m_unitTypeName',28,2)]]), #187
|
|
214
|
+
('_struct',[[('m_playerId',1,0),('m_upgradeTypeName',28,1),('m_count',81,2)]]), #188
|
|
215
|
+
('_struct',[[('m_unitTagIndex',6,0),('m_unitTagRecycle',6,1)]]), #189
|
|
216
|
+
('_array',[(0,10),81]), #190
|
|
217
|
+
('_struct',[[('m_firstUnitIndex',6,0),('m_items',190,1)]]), #191
|
|
218
|
+
('_struct',[[('m_playerId',1,0),('m_type',6,1),('m_userId',42,2),('m_slotId',42,3)]]), #192
|
|
219
|
+
]
|
|
220
|
+
|
|
221
|
+
# Map from protocol NNet.Game.*Event eventid to (typeid, name)
|
|
222
|
+
game_event_types = {
|
|
223
|
+
5: (76, 'NNet.Game.SUserFinishedLoadingSyncEvent'),
|
|
224
|
+
7: (75, 'NNet.Game.SUserOptionsEvent'),
|
|
225
|
+
9: (68, 'NNet.Game.SBankFileEvent'),
|
|
226
|
+
10: (70, 'NNet.Game.SBankSectionEvent'),
|
|
227
|
+
11: (71, 'NNet.Game.SBankKeyEvent'),
|
|
228
|
+
12: (72, 'NNet.Game.SBankValueEvent'),
|
|
229
|
+
13: (74, 'NNet.Game.SBankSignatureEvent'),
|
|
230
|
+
14: (79, 'NNet.Game.SCameraSaveEvent'),
|
|
231
|
+
21: (80, 'NNet.Game.SSaveGameEvent'),
|
|
232
|
+
22: (76, 'NNet.Game.SSaveGameDoneEvent'),
|
|
233
|
+
23: (76, 'NNet.Game.SLoadGameDoneEvent'),
|
|
234
|
+
26: (84, 'NNet.Game.SGameCheatEvent'),
|
|
235
|
+
27: (93, 'NNet.Game.SCmdEvent'),
|
|
236
|
+
28: (101, 'NNet.Game.SSelectionDeltaEvent'),
|
|
237
|
+
29: (102, 'NNet.Game.SControlGroupUpdateEvent'),
|
|
238
|
+
30: (104, 'NNet.Game.SSelectionSyncCheckEvent'),
|
|
239
|
+
31: (106, 'NNet.Game.SResourceTradeEvent'),
|
|
240
|
+
32: (107, 'NNet.Game.STriggerChatMessageEvent'),
|
|
241
|
+
33: (110, 'NNet.Game.SAICommunicateEvent'),
|
|
242
|
+
34: (111, 'NNet.Game.SSetAbsoluteGameSpeedEvent'),
|
|
243
|
+
35: (112, 'NNet.Game.SAddAbsoluteGameSpeedEvent'),
|
|
244
|
+
36: (113, 'NNet.Game.STriggerPingEvent'),
|
|
245
|
+
37: (114, 'NNet.Game.SBroadcastCheatEvent'),
|
|
246
|
+
38: (115, 'NNet.Game.SAllianceEvent'),
|
|
247
|
+
39: (116, 'NNet.Game.SUnitClickEvent'),
|
|
248
|
+
40: (117, 'NNet.Game.SUnitHighlightEvent'),
|
|
249
|
+
41: (118, 'NNet.Game.STriggerReplySelectedEvent'),
|
|
250
|
+
43: (123, 'NNet.Game.SHijackReplayGameEvent'),
|
|
251
|
+
44: (76, 'NNet.Game.STriggerSkippedEvent'),
|
|
252
|
+
45: (128, 'NNet.Game.STriggerSoundLengthQueryEvent'),
|
|
253
|
+
46: (135, 'NNet.Game.STriggerSoundOffsetEvent'),
|
|
254
|
+
47: (136, 'NNet.Game.STriggerTransmissionOffsetEvent'),
|
|
255
|
+
48: (137, 'NNet.Game.STriggerTransmissionCompleteEvent'),
|
|
256
|
+
49: (141, 'NNet.Game.SCameraUpdateEvent'),
|
|
257
|
+
50: (76, 'NNet.Game.STriggerAbortMissionEvent'),
|
|
258
|
+
51: (124, 'NNet.Game.STriggerPurchaseMadeEvent'),
|
|
259
|
+
52: (76, 'NNet.Game.STriggerPurchaseExitEvent'),
|
|
260
|
+
53: (125, 'NNet.Game.STriggerPlanetMissionLaunchedEvent'),
|
|
261
|
+
54: (76, 'NNet.Game.STriggerPlanetPanelCanceledEvent'),
|
|
262
|
+
55: (127, 'NNet.Game.STriggerDialogControlEvent'),
|
|
263
|
+
56: (131, 'NNet.Game.STriggerSoundLengthSyncEvent'),
|
|
264
|
+
57: (142, 'NNet.Game.STriggerConversationSkippedEvent'),
|
|
265
|
+
58: (145, 'NNet.Game.STriggerMouseClickedEvent'),
|
|
266
|
+
59: (146, 'NNet.Game.STriggerMouseMovedEvent'),
|
|
267
|
+
60: (147, 'NNet.Game.SAchievementAwardedEvent'),
|
|
268
|
+
61: (148, 'NNet.Game.STriggerHotkeyPressedEvent'),
|
|
269
|
+
62: (149, 'NNet.Game.STriggerTargetModeUpdateEvent'),
|
|
270
|
+
63: (76, 'NNet.Game.STriggerPlanetPanelReplayEvent'),
|
|
271
|
+
64: (150, 'NNet.Game.STriggerSoundtrackDoneEvent'),
|
|
272
|
+
65: (151, 'NNet.Game.STriggerPlanetMissionSelectedEvent'),
|
|
273
|
+
66: (152, 'NNet.Game.STriggerKeyPressedEvent'),
|
|
274
|
+
67: (163, 'NNet.Game.STriggerMovieFunctionEvent'),
|
|
275
|
+
68: (76, 'NNet.Game.STriggerPlanetPanelBirthCompleteEvent'),
|
|
276
|
+
69: (76, 'NNet.Game.STriggerPlanetPanelDeathCompleteEvent'),
|
|
277
|
+
70: (153, 'NNet.Game.SResourceRequestEvent'),
|
|
278
|
+
71: (154, 'NNet.Game.SResourceRequestFulfillEvent'),
|
|
279
|
+
72: (155, 'NNet.Game.SResourceRequestCancelEvent'),
|
|
280
|
+
73: (76, 'NNet.Game.STriggerResearchPanelExitEvent'),
|
|
281
|
+
74: (76, 'NNet.Game.STriggerResearchPanelPurchaseEvent'),
|
|
282
|
+
75: (156, 'NNet.Game.STriggerResearchPanelSelectionChangedEvent'),
|
|
283
|
+
77: (76, 'NNet.Game.STriggerMercenaryPanelExitEvent'),
|
|
284
|
+
78: (76, 'NNet.Game.STriggerMercenaryPanelPurchaseEvent'),
|
|
285
|
+
79: (157, 'NNet.Game.STriggerMercenaryPanelSelectionChangedEvent'),
|
|
286
|
+
80: (76, 'NNet.Game.STriggerVictoryPanelExitEvent'),
|
|
287
|
+
81: (76, 'NNet.Game.STriggerBattleReportPanelExitEvent'),
|
|
288
|
+
82: (158, 'NNet.Game.STriggerBattleReportPanelPlayMissionEvent'),
|
|
289
|
+
83: (159, 'NNet.Game.STriggerBattleReportPanelPlaySceneEvent'),
|
|
290
|
+
84: (159, 'NNet.Game.STriggerBattleReportPanelSelectionChangedEvent'),
|
|
291
|
+
85: (125, 'NNet.Game.STriggerVictoryPanelPlayMissionAgainEvent'),
|
|
292
|
+
86: (76, 'NNet.Game.STriggerMovieStartedEvent'),
|
|
293
|
+
87: (76, 'NNet.Game.STriggerMovieFinishedEvent'),
|
|
294
|
+
88: (161, 'NNet.Game.SDecrementGameTimeRemainingEvent'),
|
|
295
|
+
89: (162, 'NNet.Game.STriggerPortraitLoadedEvent'),
|
|
296
|
+
90: (164, 'NNet.Game.STriggerCustomDialogDismissedEvent'),
|
|
297
|
+
91: (165, 'NNet.Game.STriggerGameMenuItemSelectedEvent'),
|
|
298
|
+
93: (124, 'NNet.Game.STriggerPurchasePanelSelectedPurchaseItemChangedEvent'),
|
|
299
|
+
94: (166, 'NNet.Game.STriggerPurchasePanelSelectedPurchaseCategoryChangedEvent'),
|
|
300
|
+
95: (167, 'NNet.Game.STriggerButtonPressedEvent'),
|
|
301
|
+
96: (76, 'NNet.Game.STriggerGameCreditsFinishedEvent'),
|
|
302
|
+
97: (168, 'NNet.Game.STriggerCutsceneBookmarkFiredEvent'),
|
|
303
|
+
98: (169, 'NNet.Game.STriggerCutsceneEndSceneFiredEvent'),
|
|
304
|
+
99: (170, 'NNet.Game.STriggerCutsceneConversationLineEvent'),
|
|
305
|
+
100: (171, 'NNet.Game.STriggerCutsceneConversationLineMissingEvent'),
|
|
306
|
+
101: (76, 'NNet.Game.SGameUserLeaveEvent'),
|
|
307
|
+
102: (172, 'NNet.Game.SGameUserJoinEvent'),
|
|
308
|
+
103: (173, 'NNet.Game.SCommandManagerStateEvent'),
|
|
309
|
+
104: (174, 'NNet.Game.SCmdUpdateTargetPointEvent'),
|
|
310
|
+
105: (175, 'NNet.Game.SCmdUpdateTargetUnitEvent'),
|
|
311
|
+
106: (132, 'NNet.Game.STriggerAnimLengthQueryByNameEvent'),
|
|
312
|
+
107: (133, 'NNet.Game.STriggerAnimLengthQueryByPropsEvent'),
|
|
313
|
+
108: (134, 'NNet.Game.STriggerAnimOffsetEvent'),
|
|
314
|
+
109: (176, 'NNet.Game.SCatalogModifyEvent'),
|
|
315
|
+
110: (177, 'NNet.Game.SHeroTalentSelectedEvent'),
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
# The typeid of the NNet.Game.EEventId enum.
|
|
319
|
+
game_eventid_typeid = 0
|
|
320
|
+
|
|
321
|
+
# Map from protocol NNet.Game.*Message eventid to (typeid, name)
|
|
322
|
+
message_event_types = {
|
|
323
|
+
0: (178, 'NNet.Game.SChatMessage'),
|
|
324
|
+
1: (179, 'NNet.Game.SPingMessage'),
|
|
325
|
+
2: (180, 'NNet.Game.SLoadingProgressMessage'),
|
|
326
|
+
3: (76, 'NNet.Game.SServerPingMessage'),
|
|
327
|
+
4: (181, 'NNet.Game.SReconnectNotifyMessage'),
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
# The typeid of the NNet.Game.EMessageId enum.
|
|
331
|
+
message_eventid_typeid = 1
|
|
332
|
+
|
|
333
|
+
# Map from protocol NNet.Replay.Tracker.*Event eventid to (typeid, name)
|
|
334
|
+
tracker_event_types = {
|
|
335
|
+
0: (183, 'NNet.Replay.Tracker.SPlayerStatsEvent'),
|
|
336
|
+
1: (184, 'NNet.Replay.Tracker.SUnitBornEvent'),
|
|
337
|
+
2: (185, 'NNet.Replay.Tracker.SUnitDiedEvent'),
|
|
338
|
+
3: (186, 'NNet.Replay.Tracker.SUnitOwnerChangeEvent'),
|
|
339
|
+
4: (187, 'NNet.Replay.Tracker.SUnitTypeChangeEvent'),
|
|
340
|
+
5: (188, 'NNet.Replay.Tracker.SUpgradeEvent'),
|
|
341
|
+
6: (184, 'NNet.Replay.Tracker.SUnitInitEvent'),
|
|
342
|
+
7: (189, 'NNet.Replay.Tracker.SUnitDoneEvent'),
|
|
343
|
+
8: (191, 'NNet.Replay.Tracker.SUnitPositionsEvent'),
|
|
344
|
+
9: (192, 'NNet.Replay.Tracker.SPlayerSetupEvent'),
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
# The typeid of the NNet.Replay.Tracker.EEventId enum.
|
|
348
|
+
tracker_eventid_typeid = 2
|
|
349
|
+
|
|
350
|
+
# The typeid of NNet.SVarUint32 (the type used to encode gameloop deltas).
|
|
351
|
+
svaruint32_typeid = 7
|
|
352
|
+
|
|
353
|
+
# The typeid of NNet.Replay.SGameUserId (the type used to encode player ids).
|
|
354
|
+
replay_userid_typeid = 8
|
|
355
|
+
|
|
356
|
+
# The typeid of NNet.Replay.SHeader (the type used to store replay game version and length).
|
|
357
|
+
replay_header_typeid = 17
|
|
358
|
+
|
|
359
|
+
# The typeid of NNet.Game.SDetails (the type used to store overall replay details).
|
|
360
|
+
game_details_typeid = 39
|
|
361
|
+
|
|
362
|
+
# The typeid of NNet.Replay.SInitData (the type used to store the inital lobby).
|
|
363
|
+
replay_initdata_typeid = 67
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
def _varuint32_value(value):
|
|
367
|
+
# Returns the numeric value from a SVarUint32 instance.
|
|
368
|
+
for k,v in value.iteritems():
|
|
369
|
+
return v
|
|
370
|
+
return 0
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def _decode_event_stream(decoder, eventid_typeid, event_types, decode_user_id):
|
|
374
|
+
# Decodes events prefixed with a gameloop and possibly userid
|
|
375
|
+
gameloop = 0
|
|
376
|
+
while not decoder.done():
|
|
377
|
+
start_bits = decoder.used_bits()
|
|
378
|
+
|
|
379
|
+
# decode the gameloop delta before each event
|
|
380
|
+
delta = _varuint32_value(decoder.instance(svaruint32_typeid))
|
|
381
|
+
gameloop += delta
|
|
382
|
+
|
|
383
|
+
# decode the userid before each event
|
|
384
|
+
if decode_user_id:
|
|
385
|
+
userid = decoder.instance(replay_userid_typeid)
|
|
386
|
+
|
|
387
|
+
# decode the event id
|
|
388
|
+
eventid = decoder.instance(eventid_typeid)
|
|
389
|
+
typeid, typename = event_types.get(eventid, (None, None))
|
|
390
|
+
if typeid is None:
|
|
391
|
+
raise CorruptedError('eventid(%d) at %s' % (eventid, decoder))
|
|
392
|
+
|
|
393
|
+
# decode the event struct instance
|
|
394
|
+
event = decoder.instance(typeid)
|
|
395
|
+
event['_event'] = typename
|
|
396
|
+
event['_eventid'] = eventid
|
|
397
|
+
|
|
398
|
+
# insert gameloop and userid
|
|
399
|
+
event['_gameloop'] = gameloop
|
|
400
|
+
if decode_user_id:
|
|
401
|
+
event['_userid'] = userid
|
|
402
|
+
|
|
403
|
+
# the next event is byte aligned
|
|
404
|
+
decoder.byte_align()
|
|
405
|
+
|
|
406
|
+
# insert bits used in stream
|
|
407
|
+
event['_bits'] = decoder.used_bits() - start_bits
|
|
408
|
+
|
|
409
|
+
yield event
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def decode_replay_game_events(contents):
|
|
413
|
+
"""Decodes and yields each game event from the contents byte string."""
|
|
414
|
+
decoder = BitPackedDecoder(contents, typeinfos)
|
|
415
|
+
for event in _decode_event_stream(decoder,
|
|
416
|
+
game_eventid_typeid,
|
|
417
|
+
game_event_types,
|
|
418
|
+
decode_user_id=True):
|
|
419
|
+
yield event
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
def decode_replay_message_events(contents):
|
|
423
|
+
"""Decodes and yields each message event from the contents byte string."""
|
|
424
|
+
decoder = BitPackedDecoder(contents, typeinfos)
|
|
425
|
+
for event in _decode_event_stream(decoder,
|
|
426
|
+
message_eventid_typeid,
|
|
427
|
+
message_event_types,
|
|
428
|
+
decode_user_id=True):
|
|
429
|
+
yield event
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
def decode_replay_tracker_events(contents):
|
|
433
|
+
"""Decodes and yields each tracker event from the contents byte string."""
|
|
434
|
+
decoder = VersionedDecoder(contents, typeinfos)
|
|
435
|
+
for event in _decode_event_stream(decoder,
|
|
436
|
+
tracker_eventid_typeid,
|
|
437
|
+
tracker_event_types,
|
|
438
|
+
decode_user_id=False):
|
|
439
|
+
yield event
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def decode_replay_header(contents):
|
|
443
|
+
"""Decodes and return the replay header from the contents byte string."""
|
|
444
|
+
decoder = VersionedDecoder(contents, typeinfos)
|
|
445
|
+
return decoder.instance(replay_header_typeid)
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
def decode_replay_details(contents):
|
|
449
|
+
"""Decodes and returns the game details from the contents byte string."""
|
|
450
|
+
decoder = VersionedDecoder(contents, typeinfos)
|
|
451
|
+
return decoder.instance(game_details_typeid)
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
def decode_replay_initdata(contents):
|
|
455
|
+
"""Decodes and return the replay init data from the contents byte string."""
|
|
456
|
+
decoder = BitPackedDecoder(contents, typeinfos)
|
|
457
|
+
return decoder.instance(replay_initdata_typeid)
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
def decode_replay_attributes_events(contents):
|
|
461
|
+
"""Decodes and yields each attribute from the contents byte string."""
|
|
462
|
+
buffer = BitPackedBuffer(contents, 'little')
|
|
463
|
+
attributes = {}
|
|
464
|
+
if not buffer.done():
|
|
465
|
+
attributes['source'] = buffer.read_bits(8)
|
|
466
|
+
attributes['mapNamespace'] = buffer.read_bits(32)
|
|
467
|
+
count = buffer.read_bits(32)
|
|
468
|
+
attributes['scopes'] = {}
|
|
469
|
+
while not buffer.done():
|
|
470
|
+
value = {}
|
|
471
|
+
value['namespace'] = buffer.read_bits(32)
|
|
472
|
+
value['attrid'] = attrid = buffer.read_bits(32)
|
|
473
|
+
scope = buffer.read_bits(8)
|
|
474
|
+
value['value'] = buffer.read_aligned_bytes(4)[::-1].strip('\x00')
|
|
475
|
+
if not scope in attributes['scopes']:
|
|
476
|
+
attributes['scopes'][scope] = {}
|
|
477
|
+
if not attrid in attributes['scopes'][scope]:
|
|
478
|
+
attributes['scopes'][scope][attrid] = []
|
|
479
|
+
attributes['scopes'][scope][attrid].append(value)
|
|
480
|
+
return attributes
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
def unit_tag(unitTagIndex, unitTagRecycle):
|
|
484
|
+
return (unitTagIndex << 18) + unitTagRecycle
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
def unit_tag_index(unitTag):
|
|
488
|
+
return (unitTag >> 18) & 0x00003fff
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
def unit_tag_recycle(unitTag):
|
|
492
|
+
return (unitTag) & 0x0003ffff
|