Inutt 42bc097e92 Pass events prior to initial LoadGame event to plugins
Done by temporarily buffering events before monitor.mode is set, then notifying plugins about them before sending the
first event where monitor.mode has a value. LoadGame is currently the only event that sets monitor.mode.

Fixes #2286
diff --git a/EDMarketConnector.py b/EDMarketConnector.py
index e7bdf490..d53b625d 100644
--- a/EDMarketConnector.py
+++ b/EDMarketConnector.py
@@ -22,7 +22,7 @@ import threading
 import webbrowser
 from os import chdir, environ
 from time import localtime, strftime, time
-from typing import TYPE_CHECKING, Any, Literal
+from typing import TYPE_CHECKING, Any, Literal, MutableMapping
 from constants import applongname, appname, protocolhandler_redirect

 # Have this as early as possible for people running EDMarketConnector.exe
@@ -458,6 +458,8 @@ class AppWindow:

     def __init__(self, master: tk.Tk):  # noqa: C901, CCR001 # TODO - can possibly factor something out

+        self.early_journal_events: list[MutableMapping[str, Any]] = []
+
         self.capi_query_holdoff_time = config.get_int('querytime', default=0) + companion.capi_query_cooldown
         self.capi_fleetcarrier_query_holdoff_time = config.get_int('fleetcarrierquerytime', default=0) \
             + companion.capi_fleetcarrier_query_cooldown
@@ -1400,6 +1402,19 @@ class AppWindow:
         self.cooldown()
         logger.trace_if('capi.worker', '...done')

+    def handle_plugin_event_error(self, err: str | None) -> None:
+        """
+        Display a plugin's error message at the bottom of the main window.
+
+        If there was no error message passed in, nothing will be done.
+
+        :param err: Message to display, or None for no error.
+        """
+        if err:
+            self.status['text'] = err
+            if not config.get_int('hotkey_mute'):
+                hotkeymgr.play_bad()
+
     def journal_event(self, event: str):  # noqa: C901, CCR001 # Currently not easily broken up.
         """
         Handle a Journal event passed through event queue from monitor.py.
@@ -1513,15 +1528,21 @@ class AppWindow:

             if monitor.cmdr and monitor.mode == 'CQC' and entry['event']:
                 err = plug.notify_journal_entry_cqc(monitor.cmdr, monitor.is_beta, entry, monitor.state)
-                if err:
-                    self.status['text'] = err
-                    if not config.get_int('hotkey_mute'):
-                        hotkeymgr.play_bad()
+                self.handle_plugin_event_error(err)

                 return  # in CQC

             if not entry['event'] or not monitor.mode:
+                # Game session has not fully loaded yet. We may be receiving events from the
+                # journal, but don't know which game mode (Open/CQC/solo etc) we're running in.
                 logger.trace_if('journal.queue', 'Startup, returning')
+
+                if entry['event']:
+                    # Since we don't know which mode the game is in (and therefore whether to send
+                    # the event to a plugin's `journal_event` or `journal_event_cqc` function),
+                    # temporarily queue it so we can pass it on once the mode is known.
+                    self.early_journal_events.append(entry)
+
                 return  # Startup

             if entry['event'] in ('StartUp', 'LoadGame') and monitor.started:
@@ -1538,6 +1559,25 @@ class AppWindow:
                 if not dashboard.start(self.w, monitor.started):
                     logger.info("Can't start Status monitoring")

+            # monitor.cmdr should always be set if monitor.mode is set (and monitor.mode must be set
+            # if we reach this point in the function), but we check monitor.cmdr here so the mypy
+            # doesn't complain about passing str|None where str is required.
+            if self.early_journal_events and monitor.cmdr:
+                for early_entry in self.early_journal_events:
+                    if monitor.mode == 'CQC':
+                        err = plug.notify_journal_entry_cqc(monitor.cmdr, monitor.is_beta, early_entry, monitor.state)
+                    else:
+                        err = plug.notify_journal_entry(
+                            monitor.cmdr,
+                            monitor.is_beta,
+                            monitor.state['SystemName'],
+                            monitor.state['StationName'],
+                            early_entry,
+                            monitor.state
+                        )
+                    self.handle_plugin_event_error(err)
+                self.early_journal_events.clear()
+
             # Export loadout
             if entry['event'] == 'Loadout' and not monitor.state['Captain'] \
                     and config.get_int('output') & config.OUT_SHIP:
@@ -1553,10 +1593,7 @@ class AppWindow:
                     monitor.state
                 )

-                if err:
-                    self.status['text'] = err
-                    if not config.get_int('hotkey_mute'):
-                        hotkeymgr.play_bad()
+                self.handle_plugin_event_error(err)

             auto_update = False
             # Only if auth callback is not pending
@@ -1638,11 +1675,7 @@ class AppWindow:
         # Currently we don't do anything with these events
         if monitor.cmdr:
             err = plug.notify_dashboard_entry(monitor.cmdr, monitor.is_beta, entry)
-
-            if err:
-                self.status['text'] = err
-                if not config.get_int('hotkey_mute'):
-                    hotkeymgr.play_bad()
+            self.handle_plugin_event_error(err)

     def plugin_error(self, event=None) -> None:
         """Display asynchronous error from plugin."""
2025-11-28 03:37:14 +00:00
2025-11-18 22:17:26 -05:00
2025-11-20 18:03:58 -05:00
2025-06-30 12:41:24 +00:00
2025-11-11 20:31:50 -05:00
2024-05-06 13:53:48 -04:00
2025-11-20 18:00:06 -05:00
2025-04-11 20:49:13 -04:00
2025-11-18 22:17:26 -05:00
2025-11-16 21:55:02 -05:00
2023-11-16 16:14:59 -05:00
2024-04-05 17:20:05 -04:00
2018-08-01 00:23:47 +01:00
2024-04-27 20:10:09 -04:00
2024-04-05 17:20:05 -04:00
2025-11-20 18:19:04 -05:00
2025-04-11 19:57:18 -04:00
2024-06-10 17:21:06 -04:00
2015-06-02 20:14:04 +01:00
2024-06-10 17:21:06 -04:00
2025-04-27 21:58:01 -04:00
2025-11-13 21:45:06 -05:00
2022-12-21 18:26:42 +00:00
2024-06-10 18:16:11 -04:00
2025-11-11 20:24:58 -05:00
2025-05-03 19:52:14 -04:00
2020-07-06 16:31:04 +01:00
2025-04-27 21:58:01 -04:00
2015-09-12 04:03:12 +01:00
2015-09-12 04:03:12 +01:00
2025-11-11 20:24:58 -05:00
2024-03-27 22:01:49 -04:00
2025-11-11 21:47:02 -05:00

Any questions or offers of help can be directed to the EDCD Discord #edmc channel:

Discord chat

Elite: Dangerous Market Connector (EDMC)

This application is only of use to PC players of the game Elite Dangerous (and its expansions). It won't work with PS4 or Xbox accounts.

It utilises the Journal files written by the game on the user's computer, together with data from the API Frontier Developments supplies in order to feed this data to various third party sites that the user may find useful.

See the Wiki documentation for more details.

Installation & Uninstall

Please see the Installation & Setup wiki page.

Running from source

Please see the Running from source wiki page.

Plugins

Plugins extend the behaviour of this app. See the Plugins wiki page for more information.

If you would like to write a plugin please see PLUGINS.md.

Troubleshooting

Please see the Troubleshooting wiki page.

Reporting a problem

Please report a problem as a new GitHub issue. See Reporting a problem for further guidance, including how to find the necessary log files to attach to the report.

Packaging for distribution

Please see docs/Releasing.md.

Disclaimer

This app uses the “Companion” web API that Frontier originally supplied for their Elite Dangerous iOS app and now support for third-party apps. If that API ceases to function in the future then much of this application's functionality will be curtailed (although it could still utilise Journal files).

Acknowledgements

Please see the Acknowledgements wiki page.

License

Copyright © 2015-2019 Jonathan Harris, 2020-2024 EDCD

Licensed under the GNU Public License (GPL) version 2 or later.

S
Description
Downloads commodity market and other station data from the game Elite: Dangerous for use with all popular online and offline trading tools.
Readme GPL-2.0
45 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 99.7%
Shell 0.3%