Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
dda41fb
Fix up event names and hierarchy.
GraylinKim Sep 22, 2013
24c0acf
Flesh out the ping class.
GraylinKim Sep 22, 2013
bb8f9d2
Misc. documentation improvements.
GraylinKim Sep 22, 2013
1d03283
First pass at replay resume support. refs #91
GraylinKim Sep 22, 2013
e672168
Remove unused player_names. closes #158.
GraylinKim Nov 17, 2013
a3153db
Remove map specific attributes from the listing.
GraylinKim Dec 2, 2013
6fb12e8
Raise an informative error on corrupt tracker file
GraylinKim Dec 2, 2013
caeb6ca
Fix python3 bug in plugin error handling routine.
GraylinKim Dec 2, 2013
2b35c07
Fixes #160 with non back compatible changes.
GraylinKim Dec 2, 2013
72da6ae
Remove some old % style string formatting.
GraylinKim Dec 2, 2013
6d13524
And this is why you run tests before pushing.
GraylinKim Dec 2, 2013
665cc12
Make note of the additional changes in the log.
GraylinKim Dec 2, 2013
1d9c141
adding a missing change from the list
StoicLoofah Dec 6, 2013
52e5be9
Merge pull request #163 from StoicLoofah/update-0.7-changelog
GraylinKim Dec 7, 2013
fe86668
Remove a couple more defunct replay attributes.
GraylinKim Dec 11, 2013
9283c33
Use generic UnitType and Ability classes for data.
GraylinKim Dec 11, 2013
4d068bf
datapacks is a better word than builds here.
GraylinKim Dec 11, 2013
0e6286f
Replace all references to gateway with region.
GraylinKim Dec 11, 2013
d9df519
Fix typo.
GraylinKim Dec 11, 2013
bd2a8cf
Use a regular dict for raw data results.
GraylinKim Dec 11, 2013
f58daf7
Remove stray reference.
GraylinKim Dec 11, 2013
b968b57
Misc import and documentation improvements.
GraylinKim Dec 11, 2013
81809e5
Don't forget the tests.
GraylinKim Dec 11, 2013
03bbdae
Our readers and lambdas can't be pickled.
GraylinKim Dec 11, 2013
b421a7c
Initial pass at PTR 2.1 support.
GraylinKim Dec 11, 2013
38dfa77
Fix small bugs in PTR support.
GraylinKim Dec 12, 2013
ba404a5
Clarify the highest leauge user attribute.
GraylinKim Dec 12, 2013
94263a5
The clan logo is a DepotFile location, not a string.
GraylinKim Dec 13, 2013
f012566
Fixes #165, properly parse mouse click events.
GraylinKim Dec 13, 2013
4b45b62
Fix initdata parsing for base_build 23260 replays.
GraylinKim Dec 13, 2013
53e5678
Add killer logic to ContextLoader, refine the API.
GraylinKim Dec 19, 2013
e5001a3
added a replay thats failing for GGTracker, but surprisingly it turns…
dsjoerg Jan 5, 2014
00411e3
Bump mpyq version.
GraylinKim Jan 8, 2014
18ca54c
fix name of 'ControlGroupEvent' in comments
eqy Jan 30, 2014
a303fd7
Merge pull request #167 from eqy/patch-1
GraylinKim Jan 30, 2014
9277ec4
No more lints.
Apr 13, 2014
d275182
Merge pull request #168 from MakozFriends/master
GraylinKim Apr 15, 2014
214cd7c
Fixes SelectionTracker plugin with new handler names.
Apr 23, 2014
1a6220b
Merge pull request #169 from MakozFriends/hotfix/selectiontracker
GraylinKim May 5, 2014
b35d88c
new failing test for replays that started by loading a saved game
dsjoerg Jun 30, 2014
c860d8e
fix for replays that started with a load from a saved game
dsjoerg Jun 30, 2014
89f4eee
amended author info
dsjoerg Sep 26, 2014
6f30900
fix for 2.1.4
dsjoerg Sep 26, 2014
6580ebb
Fix various issues related to issue #180.
GraylinKim Dec 29, 2014
0dbe561
Fix gameheart plugin handling of teams and observers. Closes #174.
GraylinKim Dec 29, 2014
83d3809
Add option to print observers to sc2printer.
GraylinKim Dec 29, 2014
26c569e
Harden up the code for processing s2ma files.
GraylinKim Dec 29, 2014
6c48e8a
This is a polish translation.
GraylinKim Dec 29, 2014
a194b67
Remove PersonDict and AttributeDict implementations.
GraylinKim Dec 31, 2014
3e1cea3
Remove dead code.
GraylinKim Jan 5, 2015
722ae4f
Bump version to a pre-release (for clarity).
GraylinKim Jan 5, 2015
c5d22d6
decoding this so that it reads as a string not bytes in python 3
StoicLoofah Feb 11, 2015
4b3bd9b
Merge pull request #183 from StoicLoofah/decode_upgrade_type_name
GraylinKim Mar 3, 2015
20156ec
Fix ancient typo in struct decoder. refs #184
GraylinKim Mar 15, 2015
2139abc
remove debugging print statement
dsjoerg Oct 7, 2015
d69feb4
add failing test for 3.0
dsjoerg Oct 7, 2015
d5eb61a
Merge remote-tracking branch 'upstream/master' into ggtracker/upstream
StoicLoofah Nov 18, 2016
e6ca55b
fixing tests from graylinkim/ggtracker merge
StoicLoofah Nov 18, 2016
c86eb5a
fixing more references from the CHANGELOG
StoicLoofah Nov 28, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fix up event names and hierarchy.
* PacketEvent is now ProgressEvent.
* SetToHotkeyEvent is now SetControlGroupEvent.
* AddToHotkeyEvent is now AddToControlGroupEvent.
* GetFromHotkeyEvent is now GetControlGroupEvent.
* PlayerAbilityEvent is no longer part of the event hierarchy.
* event.name is no longer a class property; it can only be accessed from an event instance.
  • Loading branch information
GraylinKim committed Sep 22, 2013
commit dda41fbb378d137a67898140fa494a31df9de016
14 changes: 13 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,11 +1,23 @@
CHANGELOG
============

0.7.0 -
---------------------------

* PacketEvent is now ProgressEvent.
* SetToHotkeyEvent is now SetControlGroupEvent.
* AddToHotkeyEvent is now AddToControlGroupEvent.
* GetFromHotkeyEvent is now GetControlGroupEvent.
* PlayerAbilityEvent is no longer part of the event hierarchy.
* event.name is no longer a class property; it can only be accessed from an event instance.



0.6.4 - September 22nd 2013
---------------------------

* Fix bug in code for logging errors.
* Fix siege tank supply count
* Fix siege tank supply count.
* Small improvements to message.events parsing.

0.6.3 - September 15th 2013
Expand Down
40 changes: 16 additions & 24 deletions sc2reader/engine/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from sc2reader.events import *
from sc2reader.engine.events import InitGameEvent, EndGameEvent, PluginExit


class GameEngine(object):
""" GameEngine Specification
--------------------------
Expand Down Expand Up @@ -56,9 +57,8 @@ def handleEventName(self, event, replay)
* handleMessageEvent - called for events in replay.message.events
* handleGameEvent - called for events in replay.game.events
* handleTrackerEvent - called for events in replay.tracker.events
* handlePlayerActionEvent - called for all game events indicating player actions
* handleAbilityEvent - called for all types of ability events
* handleHotkeyEvent - called for all player hotkey events
* handleControlGroupEvent - called for all player control group events

Plugins may also handle optional ``InitGame`` and ``EndGame`` events generated
by the GameEngine before and after processing all the events:
Expand Down Expand Up @@ -196,26 +196,18 @@ def _get_event_handlers(self, event, plugins):

def _get_plugin_event_handlers(self, plugin, event):
handlers = list()
if isinstance(event, Event) and self._has_event_handler(plugin, Event):
handlers.append(self._get_event_handler(plugin, Event))
if isinstance(event, MessageEvent) and self._has_event_handler(plugin, MessageEvent):
handlers.append(self._get_event_handler(plugin, MessageEvent))
if isinstance(event, GameEvent) and self._has_event_handler(plugin, GameEvent):
handlers.append(self._get_event_handler(plugin, GameEvent))
if isinstance(event, TrackerEvent) and self._has_event_handler(plugin, TrackerEvent):
handlers.append(self._get_event_handler(plugin, TrackerEvent))
if isinstance(event, PlayerActionEvent) and self._has_event_handler(plugin, PlayerActionEvent):
handlers.append(self._get_event_handler(plugin, PlayerActionEvent))
if isinstance(event, AbilityEvent) and self._has_event_handler(plugin, AbilityEvent):
handlers.append(self._get_event_handler(plugin, AbilityEvent))
if isinstance(event, HotkeyEvent) and self._has_event_handler(plugin, HotkeyEvent):
handlers.append(self._get_event_handler(plugin, HotkeyEvent))
if self._has_event_handler(plugin, event):
handlers.append(self._get_event_handler(plugin, event))
if isinstance(event, Event) and hasattr(plugin, 'handleEvent'):
handlers.append(getattr(plugin, 'handleEvent', None))
if isinstance(event, MessageEvent) and hasattr(plugin, 'handleMessageEvent'):
handlers.append(getattr(plugin, 'handleMessageEvent', None))
if isinstance(event, GameEvent) and hasattr(plugin, 'handleGameEvent'):
handlers.append(getattr(plugin, 'handleGameEvent', None))
if isinstance(event, TrackerEvent) and hasattr(plugin, 'handleTrackerEvent'):
handlers.append(getattr(plugin, 'handleTrackerEvent', None))
if isinstance(event, AbilityEvent) and hasattr(plugin, 'handleAbilityEvent'):
handlers.append(getattr(plugin, 'handleAbilityEvent', None))
if isinstance(event, ControlGroupEvent) and hasattr(plugin, 'handleControlGroupEvent'):
handlers.append(getattr(plugin, 'handleControlGroupEvent', None))
if hasattr(plugin, 'handle'+event.name):
handlers.append(getattr(plugin, 'handle'+event.name, None))
return handlers

def _has_event_handler(self, plugin, event):
return hasattr(plugin, 'handle'+event.name)

def _get_event_handler(self, plugin, event):
return getattr(plugin, 'handle'+event.name, None)
12 changes: 10 additions & 2 deletions sc2reader/engine/plugins/apm.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class APMTracker(object):
"""
Builds ``player.aps`` and ``player.apm`` dictionaries where an action is
any Selection, Hotkey, or Ability event.
any Selection, ControlGroup, or Ability event.

Also provides ``player.avg_apm`` which is defined as the sum of all the
above actions divided by the number of seconds played by the player (not
Expand All @@ -23,7 +23,15 @@ def handleInitGame(self, event, replay):
human.aps = defaultdict(int)
human.seconds_played = replay.length.seconds

def handlePlayerActionEvent(self, event, replay):
def handleControlGroupEvent(self, event, replay):
event.player.aps[event.second] += 1
event.player.apm[int(event.second/60)] += 1

def handleSelectionEvent(self, event, replay):
event.player.aps[event.second] += 1
event.player.apm[int(event.second/60)] += 1

def handleAbilityEvent(self, event, replay):
event.player.aps[event.second] += 1
event.player.apm[int(event.second/60)] += 1

Expand Down
112 changes: 36 additions & 76 deletions sc2reader/events/game.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ class GameEvent(Event):
"""
This is the base class for all game events. The attributes below are universally available.
"""
name = 'GameEvent'

def __init__(self, frame, pid):
#: The id of the player generating the event. This is 16 for global non-player events.
#: Prior to Heart of the Swarm this was the player id. Since HotS it is
Expand All @@ -34,6 +32,9 @@ def __init__(self, frame, pid):
#: A flag indicating if it is a local or global event.
self.is_local = (pid != 16)

#: Short cut string for event class name
self.name = self.__class__.__name__

def _str_prefix(self):
player_name = self.player.name if getattr(self, 'pid', 16) != 16 else "Global"
return "%s\t%-15s " % (Length(seconds=int(self.frame/16)), player_name)
Expand All @@ -47,9 +48,6 @@ class GameStartEvent(GameEvent):
Recorded when the game starts and the frames start to roll. This is a global non-player
event.
"""

name = 'GameStartEvent'

def __init__(self, frame, pid, data):
super(GameStartEvent, self).__init__(frame, pid)

Expand All @@ -58,9 +56,6 @@ class PlayerLeaveEvent(GameEvent):
"""
Recorded when a player leaves the game.
"""

name = 'PlayerLeaveEvent'

def __init__(self, frame, pid, data):
super(PlayerLeaveEvent, self).__init__(frame, pid)

Expand All @@ -70,9 +65,6 @@ class UserOptionsEvent(GameEvent):
This event is recorded for each player at the very beginning of the game before the
:class:`GameStartEvent`.
"""

name = 'UserOptionsEvent'

def __init__(self, frame, pid, data):
super(UserOptionsEvent, self).__init__(frame, pid)
#:
Expand Down Expand Up @@ -118,12 +110,8 @@ def create_command_event(frame, pid, data):
return SelfAbilityEvent(frame, pid, data)


class PlayerActionEvent(GameEvent):
name = 'PlayerActionEvent'


@loggable
class AbilityEvent(PlayerActionEvent):
class AbilityEvent(GameEvent):
"""
Ability events are generated when ever a player in the game issues a command
to a unit or group of units. They are split into three subclasses of ability,
Expand All @@ -133,11 +121,6 @@ class AbilityEvent(PlayerActionEvent):
See :class:`LocationAbilityEvent`, :class:`TargetAbilityEvent`, and :class:`SelfAbilityEvent`
for individual details.
"""

name = 'AbilityEvent'

is_player_action = True

def __init__(self, frame, pid, data):
super(AbilityEvent, self).__init__(frame, pid)

Expand Down Expand Up @@ -236,9 +219,6 @@ class LocationAbilityEvent(AbilityEvent):
Note that like all AbilityEvents, the event will be recorded regardless
of whether or not the command was successful.
"""

name = 'LocationAbilityEvent'

def __init__(self, frame, pid, data):
super(LocationAbilityEvent, self).__init__(frame, pid, data)

Expand All @@ -265,9 +245,6 @@ class TargetAbilityEvent(AbilityEvent):

Note that all AbilityEvents are recorded regardless of whether or not the command was successful.
"""

name = 'TargetAbilityEvent'

def __init__(self, frame, pid, data):
super(TargetAbilityEvent, self).__init__(frame, pid, data)

Expand Down Expand Up @@ -318,9 +295,6 @@ class SelfAbilityEvent(AbilityEvent):

Note that all AbilityEvents are recorded regardless of whether or not the command was successful.
"""

name = 'SelfAbilityEvent'

def __init__(self, frame, pid, data):
super(SelfAbilityEvent, self).__init__(frame, pid, data)

Expand All @@ -329,7 +303,7 @@ def __init__(self, frame, pid, data):


@loggable
class SelectionEvent(PlayerActionEvent):
class SelectionEvent(GameEvent):
"""
Selection events are generated when ever the active selection of the
player is updated. Unlike other game events, these events can also be
Expand All @@ -340,10 +314,6 @@ class SelectionEvent(PlayerActionEvent):
by non-player actions. When a player action updates a control group
a :class:`HotkeyEvent` is generated.
"""

name = 'SelectionEvent'
is_player_action = True

def __init__(self, frame, pid, data):
super(SelectionEvent, self).__init__(frame, pid)

Expand Down Expand Up @@ -392,39 +362,32 @@ def __str__(self):
def create_control_group_event(frame, pid, data):
update_type = data['control_group_update']
if update_type == 0:
return SetToHotkeyEvent(frame, pid, data)
return SetControlGroupEvent(frame, pid, data)
elif update_type == 1:
return AddToHotkeyEvent(frame, pid, data)
return AddToControlGroupEvent(frame, pid, data)
elif update_type == 2:
return GetFromHotkeyEvent(frame, pid, data)
return GetControlGroupEvent(frame, pid, data)
elif update_type == 3:
# TODO: What could this be?!?
return HotkeyEvent(frame, pid, data)
return ControlGroupEvent(frame, pid, data)


@loggable
class HotkeyEvent(PlayerActionEvent):
class ControlGroupEvent(GameEvent):
"""
Hotkey events are recorded when ever a player action modifies a control
group. I know that calling control group events hotkey events doesn't make
sense but for backwards compatibility I haven't changed it yet. Sorry.

There are three kinds of hotkey events, generated by each of the possible
ControlGroup events are recorded when ever a player action modifies or accesses a control
group. There are three kinds of events, generated by each of the possible
player actions:

* :class:`SetToHotkeyEvent` - Recorded when a user sets a control group (ctrl+#).
* :class:`GetFromHotkeyEvent` - Recorded when a user retrieves a control group (#).
* :class:`AddToHotkeyEvent` - Recorded when a user adds to a control group (shift+ctrl+#)
* :class:`SetControlGroup` - Recorded when a user sets a control group (ctrl+#).
* :class:`GetControlGroup` - Recorded when a user retrieves a control group (#).
* :class:`AddToControlGroup` - Recorded when a user adds to a control group (shift+ctrl+#)

All three events have the same set of data (shown below) but are interpretted differently.
See the class entry for details.
"""

name = 'HotkeyEvent'
is_player_action = True

def __init__(self, frame, pid, data):
super(HotkeyEvent, self).__init__(frame, pid)
super(ControlGroupEvent, self).__init__(frame, pid)

#: Index to the control group being modified
self.control_group = data['control_group_index']
Expand All @@ -445,38 +408,33 @@ def __init__(self, frame, pid, data):
self.mask_data = data['remove_mask'][1]


class SetToHotkeyEvent(HotkeyEvent):
class SetControlGroupEvent(ControlGroupEvent):
"""
Extends :class:`HotkeyEvent`
Extends :class:`ControlGroupEvent`

This event does a straight forward replace of the current control group contents
with the player's current selection. This event doesn't have masks set.
"""

name = 'SetToHotkeyEvent'


class AddToHotkeyEvent(HotkeyEvent):
class AddToControlGroupEvent(SetControlGroupEvent):
"""
Extends :class:`HotkeyEvent`
Extends :class:`ControlGroupEvent`

This event adds the current selection to the control group.
"""

name = 'AddToHotkeyEvent'


class GetFromHotkeyEvent(HotkeyEvent):
class GetControlGroupEvent(ControlGroupEvent):
"""
Extends :class:`HotkeyEvent`
Extends :class:`ControlGroupEvent`

This event replaces the current selection with the contents of the control group.
The mask data is used to limit that selection to units that are currently selectable.
You might have 1 medivac and 8 marines on the control group but if the 8 marines are
inside the medivac they cannot be part of your selection.
"""

name = 'GetFromHotkeyEvent'


@loggable
class CameraEvent(GameEvent):
Expand All @@ -485,9 +443,6 @@ class CameraEvent(GameEvent):
It does not matter why the camera changed, this event simply records the current
state of the camera after changing.
"""

name = 'CameraEvent'

def __init__(self, frame, pid, data):
super(CameraEvent, self).__init__(frame, pid)

Expand Down Expand Up @@ -515,8 +470,10 @@ def __str__(self):

@loggable
class ResourceTradeEvent(GameEvent):
name = 'ResourceTradeEvent'

"""
Generated when a player trades resources with another player. But not when fullfulling
resource requests.
"""
def __init__(self, frame, pid, data):
super(ResourceTradeEvent, self).__init__(frame, pid)

Expand Down Expand Up @@ -552,8 +509,9 @@ def __str__(self):


class ResourceRequestEvent(GameEvent):
name = 'ResourceRequestEvent'

"""
Generated when a player creates a resource request.
"""
def __init__(self, frame, pid, data):
super(ResourceRequestEvent, self).__init__(frame, pid)

Expand All @@ -577,8 +535,9 @@ def __str__(self):


class ResourceRequestFulfillEvent(GameEvent):
name = 'ResourceRequestFulfillEvent'

"""
Generated when a player accepts a resource request.
"""
def __init__(self, frame, pid, data):
super(ResourceRequestFulfillEvent, self).__init__(frame, pid)

Expand All @@ -587,8 +546,9 @@ def __init__(self, frame, pid, data):


class ResourceRequestCancelEvent(GameEvent):
name = 'ResourceRequestCancelEvent'

"""
Generated when a player cancels their resource request.
"""
def __init__(self, frame, pid, data):
super(ResourceRequestCancelEvent, self).__init__(frame, pid)

Expand Down
Loading