1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-23 12:20:30 +03:00

Fix multiple missions with the same cargo type

A user can collect multiple missions with the same mission cargo, which
is added to the cargo.json as distinct entries. Previously we would take
the last number as the total, leading to invalid counts (and possibly
negative counts).

This adds a method to sum cargo entries based on the cargo name. It also
adds a field on status to access the original cargo JSON data.

Fixes #817
This commit is contained in:
A_D 2020-12-30 17:13:54 +02:00 committed by Athanasius
parent 91e6583326
commit b04b39fa8a

View File

@ -7,7 +7,7 @@ from os.path import basename, expanduser, isdir, join
from sys import platform
from time import gmtime, localtime, sleep, strftime, strptime, time
from calendar import timegm
from typing import Any, Optional, OrderedDict as OrderedDictT, Tuple, TYPE_CHECKING, Union
from typing import Any, List, MutableMapping, Optional, OrderedDict as OrderedDictT, Tuple, TYPE_CHECKING, Union
if TYPE_CHECKING:
import tkinter
@ -118,6 +118,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
'ModulesValue': None,
'Rebuy': None,
'Modules': None,
'CargoJSON': None, # The raw data from the last time cargo.json was read
}
def start(self, root: 'tkinter.Tk'):
@ -363,7 +364,7 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
try:
# Preserve property order because why not?
entry: OrderedDictT[str, Any] = json.loads(line, object_pairs_hook=OrderedDict)
entry: MutableMapping[str, Any] = json.loads(line, object_pairs_hook=OrderedDict)
entry['timestamp'] # we expect this to exist # TODO: replace with assert? or an if key in check
event_type = entry['event']
@ -608,8 +609,11 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
if 'Inventory' not in entry:
with open(join(self.currentdir, 'Cargo.json'), 'rb') as h: # type: ignore
entry = json.load(h, object_pairs_hook=OrderedDict) # Preserve property order because why not?
self.state['CargoJSON'] = entry
self.state['Cargo'].update({self.canonicalise(x['Name']): x['Count'] for x in entry['Inventory']})
clean = self.coalesce_cargo(entry['Inventory'])
self.state['Cargo'].update({self.canonicalise(x['Name']): x['Count'] for x in clean})
elif event_type in ('CollectCargo', 'MarketBuy', 'BuyDrones', 'MiningRefined'):
commodity = self.canonicalise(entry['Type'])
@ -966,6 +970,35 @@ class EDLogs(FileSystemEventHandler): # type: ignore # See below
with open(filename, 'wt') as h:
h.write(string)
def coalesce_cargo(self, raw_cargo: List[MutableMapping[str, Any]]) -> List[MutableMapping[str, Any]]:
"""
Coalesce multiple entries of the same cargo into one.
This exists due to the fact that a user can accept multiple missions that all require the same cargo. On the ED
side, this is represented as multiple entries in the `Inventory` List with the same names etc. Just a differing
MissionID. We (as in EDMC Core) dont want to support the multiple mission IDs, but DO want to have correct cargo
counts. Thus, we reduce all existing cargo down to one total.
:param raw_cargo: Raw cargo data (usually from Cargo.json)
:return: Coalesced data
"""
# self.state['Cargo'].update({self.canonicalise(x['Name']): x['Count'] for x in entry['Inventory']})
out: List[MutableMapping[str, Any]] = []
for inventory_item in raw_cargo:
if not any(self.canonicalise(x['Name']) == self.canonicalise(inventory_item['Name']) for x in out):
out.append(dict(inventory_item))
continue
# We've seen this before, update that count
x = list(filter(lambda x: self.canonicalise(x['Name']) == self.canonicalise(inventory_item['Name']), out))
if len(x) != 1:
logger.debug(f'Unexpected number of items: {len(x)} where 1 was expected. {x}')
x[0]['Count'] += inventory_item['Count']
return out
# singleton
monitor = EDLogs()