-
Notifications
You must be signed in to change notification settings - Fork 73
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
How to port the heroprotocol to Python 3 #57
Comments
See #59 |
Thanks. I have a follow-up question. Is there any kind of wiki that would help me find the info I am looking for? I found this javascript port of heroprotocol that has some sort of documentation but it really isn't too deep. My specific issue right now is how to find all deaths that happened over the course of the game and list them with player names, teams, etc. I would much rather dive in the file to try and find them myself but I don't really know where to start when I don't want just some basic info. |
Game Events hold most of that data i think, that or tracker events. |
Hm, I have these events in Game.Event and these in Tracker.Event Do you know where a death event could be? I can't seem to find it. |
SUnitDiedEvent, heroes are units. |
If you are comfortable with C#, you can use this with friendlier objects: https://github.com/barrett777/Heroes.ReplayParser/ |
@NaomiChan Of course, thanks. |
It would be nice if we had a repo dedicated just to annotating / documenting the replay file format. It seems like we're all independently learning it on our own for the most part and I think we'd end up saving each other a lot of time if we had a source of knowledge for this where we could share what we know. This would also probably make it easier to recognize if/when something has changed about the format. I'm not exactly sure what the best format for this documentation would be. If anyone has any ideas I'd be happy to take the initiative to create and/or contribute to this. |
You are 100% correct! So far I found only this documentation that is for JS protocol and has some info. But it's true that all of us could make use of a repo instead of figuring it out every time by ourselves. I think Ben could have the most info since he's done the most work with replays of all of us. But it's just a guess and I don't know if he wants to share it in case he has it. |
I have another question. In my quest to find out which hero died when I tried to combine SUnitDiedEvent and SUnitBornEvent to get the name of the unit dying; like this (it's really an ugly way but I didn't think of any better way to match the Tags to get the name): for event in (events for events in tracker_events if events['_event'] == NNet.Replay.Tracker.SUnitDiedEvent'):
for tr_event in (events2 for events2 in tracker_events2 if events2['_event'] == NNet.Replay.Tracker.SUnitBornEvent'):
if event['m_unitTagIndex'] == tr_event['m_unitTagIndex'] and \
event['m_unitTagRecycle'] == tr_event['m_unitTagRecycle']:
print tr_event['m_unitTypeName'] But for some reason the only result I get out of this is: Also jupyter notebook sort of doesn't work when I try to loop through the |
@Joko013 FYI you can put ``` around multiline code to make it more readable on GH: for event in (events for events in tracker_events if events['_event'] == 'NNet.Replay.Tracker.SUnitDiedEvent'):
for tr_event in (events2 for events2 in tracker_events2 if events2['_event'] == 'NNet.Replay.Tracker.SUnitBornEvent'):
if event['m_unitTagIndex'] == tr_event['m_unitTagIndex'] and event['m_unitTagRecycle'] == tr_event['m_unitTagRecycle']:
print tr_event['m_unitTypeName'] Also you you specify a language after the first ``` GH will style the code accordingly. |
Tracker events have probably 95% of the things you are interested in I only use game events for a handful of things Because of how unit tags recycle, you need to process all unit related events. Or at least all but UnitPositionsEvent. Here's where I loop through these in C#, you might be able to figure out what I'm doing even though it's C#. I loop through these events in chronological order: UnitBornEvent , UnitRevivedEvent, UnitDiedEvent, UnitOwnerChangeEvent, UnitPositionsEvent 'UnitBornEvent' has the name of the unit. I believe all hero units start with 'Hero' 'UnitDiedEvent' shows what other unit got the killing blow A lot of my code in that file is also using game events to supplement the position data available. In tracker events, unit positions are only reported about once every 15 seconds I believe, so if you are wanting positions more frequently, you can piece together more from game events such as move commands. |
@barrett777 Thanks Ben, I think I'm slowly getting to the results I want. I have one more question though: Where do you get the TimeSpan of an event? I don't see such parameter when looking at the info that is contained in events. To be clear right now I think I can get the Born/Died events correctly (still a little puzzled by how exactly does the Replay recycle the Ids) but I don't know how to determine when exactly an event occured. |
Each event has a 'ticks elapsed' since the last event, and in HotS 16 ticks
= 1 second. I'm not sure where you can find this in Python though :)
…On Tue, Nov 28, 2017, 11:05 PM Joko013 ***@***.***> wrote:
@barrett777 <https://github.com/barrett777> Thanks Ben, I think I'm
slowly getting to the results I want. I have one more question though:
Where do you get the TimeSpan of an event? I don't see such parameter when
looking at the info that is contained in events. To be clear right now I
think I can get the Born/Died events correctly (still a little puzzled by
how exactly does the Replay recycle the Ids) but I don't know how to
determine when exactly an event occured.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#57 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AIDkE9ScHZaCn1MFy87WntoYUT3YCmmCks5s7QJNgaJpZM4QaDiA>
.
|
Found it and it works just as you said, thanks Ben. If anyone is interested, for tracker_events you can find the time when an event occured (0 is when the match starts, so 35 sec before the games open) here: seconds_from_match_start = event['_gameloop']/16 |
If anyone is interested, I whipped together an (incomplete) site that is starting to document the protocol and how different data can be retrieved from it. You can find it here: https://nexus-devtools.github.io/heroprotocoldocs/#/ Feel free to PR any changes you think would help. |
With this, the tool supports Python 3. Addresses issue #57.
With this, the tool supports Python 3. Addresses issue #57.
Fixed in the next update |
Python 3, pypi package, and module support * Updates to support both Python 2.7 and Python 3.x * Package now publishes to PyPI (https://pypi.org/project/heroprotocol) * New method of invoke, instead of `python heroprotocol.py [...]`, run `python -m heroprotocol [...]`. This works either with the PyPI package installed, or running from source at the checkout root. Resolves #4, resolves #5, resolves #57, resolves #59, resolves #85, resolves #86, resolves #88.
Let me start with saying that I'm not super experienced with Python yet but I'm learning gradually. Can you please assist when I am trying to port the heroprotocol to Python 3? I installed the required library and when I try to run
header = protocol.decode_replay_header(mpq.header['user_data_header']['content'])
I get this error:TypeError: ord() expected string of length 1, but int found
. The error says that it's in the decoders.py file on the row 69. Just to clarify, I am using latest Anaconda release. Thanks for any help.The text was updated successfully, but these errors were encountered: