Update analyzer.py, commander.py and six other files

This commit is contained in:
Richard Bronkhorst 2023-07-11 17:48:51 +02:00
parent 269b5cf537
commit 97296e1859
8 changed files with 42 additions and 29 deletions

View File

@ -44,16 +44,16 @@ class Analyzer:
location = self.store.get(Waypoint, location) location = self.store.get(Waypoint, location)
mkts = self.find_markets(resource, sellbuy) mkts = self.find_markets(resource, sellbuy)
candidates = [] candidates = []
origin = self.store.get(System, location.system()) origin = location.system
for typ, m in mkts: for typ, m in mkts:
system = self.store.get(System, m.system()) system = m.waypoint.system
d = origin.distance(system) d = origin.distance(system)
candidates.append((typ, m, d)) candidates.append((typ, m, d))
possibles = sorted(candidates, key=lambda m: m[2]) possibles = sorted(candidates, key=lambda m: m[2])
possibles = possibles[:10] possibles = possibles[:10]
results = [] results = []
for typ,m,d in possibles: for typ,m,d in possibles:
system = self.store.get(System, m.system()) system = m.waypoint.system
p = self.find_path(origin, system) p = self.find_path(origin, system)
if p is None: continue if p is None: continue
results.append((typ,m,d,len(p))) results.append((typ,m,d,len(p)))

View File

@ -121,7 +121,7 @@ class Commander(CommandLine):
def do_chaul(self): def do_chaul(self):
if not self.has_ship(): return if not self.has_ship(): return
if len(ship.cargo) > 0: if len(self.ship.cargo) > 0:
raise CommandError('please dump cargo first') raise CommandError('please dump cargo first')
contract = self.active_contract() contract = self.active_contract()
delivery = contract.unfinished_delivery() delivery = contract.unfinished_delivery()

View File

@ -28,7 +28,10 @@ class MissionParam:
elif self.cls == list: elif self.cls == list:
return [i.strip() for i in val.split(',')] return [i.strip() for i in val.split(',')]
elif issubclass(self.cls, Base): elif issubclass(self.cls, Base):
if type(val) == str:
data = store.get(self.cls, val) data = store.get(self.cls, val)
else:
data = val
if data is None: if data is None:
raise ValueError('object not found') raise ValueError('object not found')
return data.symbol return data.symbol
@ -179,9 +182,8 @@ class BaseMission(Mission):
traject = self.st('traject') traject = self.st('traject')
if traject is None or traject == []: if traject is None or traject == []:
return 'done' return 'done'
dest = self.store.get(Waypoint, traject[-1]) dest = traject[-1]
loc = self.ship.location() loc = self.ship.location
print(dest, loc)
if dest == loc: if dest == loc:
self.sts('traject', None) self.sts('traject', None)
return 'done' return 'done'
@ -200,10 +202,10 @@ class BaseMission(Mission):
def step_calculate_traject(self, dest): def step_calculate_traject(self, dest):
if type(dest) == str: if type(dest) == str:
dest = self.store.get(Waypoint, dest) dest = self.store.get(Waypoint, dest)
loc = self.ship.location() loc = self.ship.location
loc_sys = self.store.get(System, loc.system()) loc_sys = loc.system
loc_jg = self.analyzer.get_jumpgate(loc_sys) loc_jg = self.analyzer.get_jumpgate(loc_sys)
dest_sys = self.store.get(System, dest.system()) dest_sys = dest.system
dest_jg = self.analyzer.get_jumpgate(dest_sys) dest_jg = self.analyzer.get_jumpgate(dest_sys)
if dest_sys == loc_sys: if dest_sys == loc_sys:
result = [dest.symbol] result = [dest.symbol]
@ -212,10 +214,10 @@ class BaseMission(Mission):
path = self.analyzer.find_path(loc_sys, dest_sys) path = self.analyzer.find_path(loc_sys, dest_sys)
result = [] result = []
if loc.symbol != loc_jg.symbol: if loc.symbol != loc_jg.symbol:
result.append(loc_jg.symbol) result.append(loc_jg)
result += [s.symbol for s in path[1:]] result += [s.symbol for s in path[1:]]
if dest_jg.symbol != dest.symbol: if dest_jg.symbol != dest.symbol:
result.append(dest.symbol) result.append(dest)
self.sts('traject', result) self.sts('traject', result)
print(result) print(result)
return result return result

View File

@ -9,4 +9,4 @@ from nullptr.models.ship import Ship
from nullptr.models.contract import Contract from nullptr.models.contract import Contract
from nullptr.models.survey import Survey from nullptr.models.survey import Survey
__all__ = [ 'Waypoint', 'Sector', 'Ship', 'Survey', 'Agent', 'Marketplace', 'Jumpgate', 'Contract', 'Base' ] __all__ = [ 'Waypoint', 'Sector', 'Ship', 'Survey', 'System', 'Agent', 'Marketplace', 'Jumpgate', 'Contract', 'Base' ]

View File

@ -23,7 +23,7 @@ class Base:
def __init__(self, symbol, store): def __init__(self, symbol, store):
self.disable_dirty = True self.disable_dirty = True
self.file_offset = 0 self.file_offset = None
self.store = store self.store = store
self.symbol = symbol self.symbol = symbol
self.define() self.define()

View File

@ -3,6 +3,7 @@ from .base import Base
from time import time from time import time
from nullptr.util import * from nullptr.util import *
from dataclasses import field from dataclasses import field
from nullptr.models import Waypoint
class Marketplace(Base): class Marketplace(Base):
def define(self): def define(self):
@ -11,6 +12,11 @@ class Marketplace(Base):
self.exchange:list = [] self.exchange:list = []
self.prices:dict = {} self.prices:dict = {}
self.last_prices:int = 0 self.last_prices:int = 0
self.set_waypoint()
def set_waypoint(self):
waypoint = self.store.get(Waypoint, self.symbol, create=True)
self.waypoint = waypoint
def update(self, d): def update(self, d):
self.setlst('imports', d, 'imports', 'symbol') self.setlst('imports', d, 'imports', 'symbol')

View File

@ -1,7 +1,7 @@
from .base import Base from .base import Base
from time import time from time import time
from nullptr.util import * from nullptr.util import *
from dataclasses import dataclass, field from nullptr.models import Waypoint
class Ship(Base): class Ship(Base):
def define(self): def define(self):
@ -10,7 +10,7 @@ class Ship(Base):
self.status:str = '' self.status:str = ''
self.cargo_capacity:int = 0 self.cargo_capacity:int = 0
self.cargo_units:int = 0 self.cargo_units:int = 0
self.location_str = '' self.location = None
self.cooldown:int = 0 self.cooldown:int = 0
self.arrival:int = 0 self.arrival:int = 0
self.fuel_current:int = 0 self.fuel_current:int = 0
@ -22,16 +22,14 @@ class Ship(Base):
def ext(self): def ext(self):
return 'shp' return 'shp'
def location(self):
return self.store.get('Waypoint', self.location_str)
def path(self): def path(self):
agent = self.symbol.split('-')[0] agent = self.symbol.split('-')[0]
return f'{agent}/{self.symbol}.{self.ext()}' return f'{agent}/{self.symbol}.{self.ext()}'
def update(self, d): def update(self, d):
self.seta('status', d, 'nav.status') self.seta('status', d, 'nav.status')
self.seta('location_str', d, 'nav.waypointSymbol') getter = self.store.getter(Waypoint, create=True)
self.seta('location', d, 'nav.waypointSymbol', interp=getter)
self.seta('cargo_capacity', d, 'cargo.capacity') self.seta('cargo_capacity', d, 'cargo.capacity')
self.seta('cargo_units', d, 'cargo.units') self.seta('cargo_units', d, 'cargo.units')
self.seta('fuel_capacity', d, 'fuel.capacity') self.seta('fuel_capacity', d, 'fuel.capacity')
@ -95,7 +93,7 @@ class Ship(Base):
if detail > 1: if detail > 1:
r += ' ' + self.status r += ' ' + self.status
r += f' [{self.fuel_current}/{self.fuel_capacity}]' r += f' [{self.fuel_current}/{self.fuel_capacity}]'
r += ' ' + str(self.location()) r += ' ' + str(self.location)
if self.is_travelling(): if self.is_travelling():
r += f' [A: {arrival}]' r += f' [A: {arrival}]'
if self.is_cooldown(): if self.is_cooldown():

View File

@ -27,17 +27,19 @@ class StoreUnpickler(pickle.Unpickler):
class ChunkHeader: class ChunkHeader:
def __init__(self): def __init__(self):
self.offset = 0
self.in_use = True self.in_use = True
self.size = 0 self.size = 0
self.used = 0 self.used = 0
@classmethod @classmethod
def parse(cls, fil): def parse(cls, fil):
offset = fil.tell()
d = fil.read(16) d = fil.read(16)
if len(d) < 16: if len(d) < 16:
return None return None
# print(d)
o = cls() o = cls()
o.offset = offset
d, o.used = unpack('<QQ', d) d, o.used = unpack('<QQ', d)
o.size = d & 0x7fffffffffffffff o.size = d & 0x7fffffffffffffff
o.in_use = d & 0x8000000000000000 != 0 o.in_use = d & 0x8000000000000000 != 0
@ -97,7 +99,10 @@ class Store:
self.fil.seek(0) self.fil.seek(0)
offset = 0 offset = 0
while (hdr := ChunkHeader.parse(self.fil)): while (hdr := ChunkHeader.parse(self.fil)):
if not hdr.in_use: continue print(hdr)
if not hdr.in_use:
self.fil.seek(hdr.size, 1)
continue
data = self.fil.read(hdr.used) data = self.fil.read(hdr.used)
self.load_object(data, offset) self.load_object(data, offset)
self.fil.seek(hdr.size - hdr.used, 1) self.fil.seek(hdr.size - hdr.used, 1)
@ -118,6 +123,7 @@ class Store:
h = ChunkHeader() h = ChunkHeader()
h.size = sz h.size = sz
h.used = used h.used = used
h.offset = self.fil.tell()
h.write(self.fil) h.write(self.fil)
return offset, h return offset, h
@ -125,7 +131,7 @@ class Store:
data = self.dump_object(obj) data = self.dump_object(obj)
osize = len(data) osize = len(data)
# is there an existing chunk for this obj? # is there an existing chunk for this obj?
if obj.file_offset > 0: if obj.file_offset is not None:
# read chunk hdr # read chunk hdr
self.fil.seek(obj.file_offset) self.fil.seek(obj.file_offset)
hdr = ChunkHeader.parse(self.fil) hdr = ChunkHeader.parse(self.fil)
@ -135,15 +141,16 @@ class Store:
# free the chunk # free the chunk
hdr.in_use = False hdr.in_use = False
# force a new chunk # force a new chunk
obj.file_offset = 0 obj.file_offset = None
else: else:
# if it is big enough, update the used field # if it is big enough, update the used field
hdr.used = osize hdr.used = osize
self.fil.seek(obj.file_offset) self.fil.seek(hdr.offset)
hdr.write(self.fil) hdr.write(self.fil)
if obj.file_offset == 0: if obj.file_offset is None:
obj.file_offset, hdr = self.allocate_chunk(osize) obj.file_offset, hdr = self.allocate_chunk(osize)
print(type(obj).__name__, hdr)
self.fil.write(data) self.fil.write(data)
slack = b'\x00' * (hdr.size - hdr.used) slack = b'\x00' * (hdr.size - hdr.used)
self.fil.write(slack) self.fil.write(slack)
@ -181,7 +188,7 @@ class Store:
def getter(self, typ, create=False): def getter(self, typ, create=False):
if type(typ) == str and typ in self.model_names: if type(typ) == str and typ in self.model_names:
typ = self.model_names[typ] typ = self.model_names[typ]
return partial(self.get, typ=typ, create=create) return partial(self.get, typ, create=create)
def update(self, typ, data, symbol=None): def update(self, typ, data, symbol=None):
if type(typ) == str and typ in self.model_names: if type(typ) == str and typ in self.model_names: