sc2reader icon indicating copy to clipboard operation
sc2reader copied to clipboard

Event.player is None

Open rcortini opened this issue 6 years ago • 6 comments

When using the APMTracker plugin, it became clear to me that the events that the plugin parses the attribute player is None.

Code to reproduce:

class TestPlugin(object):

    name = 'TestPlugin'
            
    def handleCommandEvent(self, event, replay):
        print(event.player)
                
replay_file = '/home/rcortini/soft/sc2reader/test_replays/4.7.0.70154/1.SC2Replay'
replay = sc2reader.load_replay(
    replay_file,
    engine=sc2reader.engine.GameEngine(plugins=[TestPlugin()]))

which outputs a bunch of Nones.

By the way, this also means that the APMTracker plugin does not work, and that it is very difficult to write functional plugins.

rcortini avatar Jul 28 '19 10:07 rcortini

Yes. This issue was closed without a proper fix in #62.

cclauss avatar Jul 28 '19 11:07 cclauss

Is it all events in this replay that have the player set to none, or is it only specific events that are missing the player? If it's the latter, can we figure out what the reason is?

I think this is worth solving, but I don't have much context or any intuition for why it could be happening

StoicLoofah avatar Jul 29 '19 21:07 StoicLoofah

Hi and thanks for the comment.

It is, as far as I can see, for all events and for all the players. Digging in the code I figured out that the constructor of the Event class assigns None to the attribute .player, but never actually assigns it to anything else. I reckon the constructor of Event would be the place to assign it, after checking whether the is_local flag is set to true.

rcortini avatar Jul 30 '19 07:07 rcortini

Okay, I figured out that this only happens when using

replay = sc2reader.load_replay(
    replay_file,
    engine=sc2reader.engine.GameEngine(plugins=[TestPlugin()]))

but it does not happen if you use

sc2reader.engine.register_plugin(TestPlugin())
replay = sc2reader.load_replay(replay_file)

rcortini avatar Jul 30 '19 09:07 rcortini

Oh, that is fascinating. I have to admit that despite being the current maintainer for this library, I am completely unfamiliar with this code =P

Since you have a reasonable workaround, I feel better on the urgency of this. Maybe I'll take a stab at this sometime, but others are welcome to investigate and share what you find. The relevant logic is presumably in https://github.com/ggtracker/sc2reader/blob/71d0903a60616798373565fcf658b722eba3475f/sc2reader/factories/sc2factory.py

StoicLoofah avatar Jul 30 '19 16:07 StoicLoofah

Okay, I figured out that this only happens when using

replay = sc2reader.load_replay(
    replay_file,
    engine=sc2reader.engine.GameEngine(plugins=[TestPlugin()]))

but it does not happen if you use

sc2reader.engine.register_plugin(TestPlugin())
replay = sc2reader.load_replay(replay_file)

The problem here is ContextLoader() plugin. When using default engine, the sc2reader.engine has 2 plugins registered: GameHeartNormalizer() and ContextLoader(), and the 'ContextLoader()' does many things including assign some Events' event.player according to event.pid. If you want to use your own engine, you should do something like this:

my_engine=sc2reader.engine.GameEngine(plugins=[ContextLoader(), TestPlugin()])
replay = sc2reader.load_replay(replay_file, engine=my_engine)

NumberPigeon avatar Sep 09 '23 06:09 NumberPigeon