123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- import jsonlines
- import os
- from twisted.python import log
- from pprint import pprint
- PORT_CLASSES = {
- 1: "BBS",
- 2: "BSB",
- 3: "SBB",
- 4: "SSB",
- 5: "SBS",
- 6: "BSS",
- 7: "SSS",
- 8: "BBB",
- }
- CLASSES_PORT = {v: k for k, v in PORT_CLASSES.items()}
- class GameData(object):
- def __init__(self, usergame):
- # Construct the GameData storage object
- self.usergame = usergame
- self.warps = {}
- self.ports = {}
- # 10 = 300 bytes
- self.warp_groups = 10
- # 3 = 560 bytes
- # 5 = 930 bytes
- self.port_groups = 3
- def storage_filename(self):
- """ return filename
- username.lower _ game.upper.json
- """
- user, game = self.usergame
- return "{0}_{1}.json".format(user.lower(), game.upper())
- def display(self):
- pprint(self.warps)
- pprint(self.ports)
- def save(self, *_):
- """ save gamedata as jsonlines.
- Enable sort_keys=True to provide stable json data output.
- We also sorted(.keys()) to keep records in order.
- Note: There's a "bug" when serializing to json, keys must be strings!
- """
- filename = self.storage_filename()
- with jsonlines.open(filename, mode="w", sort_keys=True) as writer:
- # for warp, sectors in self.warps.items():
- w = {"warp": {}}
- for warp in sorted(self.warps.keys()):
- sectors = self.warps[warp]
- # log.msg("save:", warp, sectors)
- sects = sorted(list(sectors)) # make a list
- w["warp"][warp] = sects
- if len(w["warp"]) >= self.warp_groups:
- writer.write(w)
- w = {"warp": {}}
- yield
- # log.msg(w)
- # writer.write(w)
- # yield
- if len(w["warp"]) > 1:
- writer.write(w)
- # for sector, port in self.ports.items():
- p = {"port": {}}
- for sector in sorted(self.ports.keys()):
- port = self.ports[sector]
- p["port"][sector] = port
- if len(p["port"]) >= self.port_groups:
- writer.write(p)
- p = {"port": {}}
- yield
- if len(p["port"]) > 1:
- writer.write(p)
- log.msg("Saved {0} {1}/{2}".format(filename, len(self.ports), len(self.warps)))
- def load(self):
- filename = self.storage_filename()
- self.warps = {}
- self.ports = {}
- if os.path.exists(filename):
- # Load it
- with jsonlines.open(filename) as reader:
- for obj in reader:
- if "warp" in obj:
- for s, w in obj["warp"].items():
- # log.msg(s, w)
- self.warps[int(s)] = set(w)
- # self.warps.update(obj["warp"])
- if "port" in obj:
- for s, p in obj["port"].items():
- self.ports[int(s)] = p
- # self.ports.update(obj["port"])
- yield
- log.msg("Loaded {0} {1}/{2}".format(filename, len(self.ports), len(self.warps)))
- def warp_to(self, source, *dest):
- """ connect sector source to destination.
- """
- log.msg("Warp {0} to {1}".format(source, dest))
- if source not in self.warps:
- self.warps[source] = set()
- for d in dest:
- if d not in self.warps[source]:
- self.warps[source].add(d)
- def set_port(self, sector, data):
- log.msg("Port {0} : {1}".format(sector, data))
- if sector not in self.ports:
- self.ports[sector] = dict()
- self.ports[sector].update(data)
- if "port" not in self.ports[sector]:
- # incomplete port type - can we "complete" it?
- if all(x in self.ports for x in ["fuel", "org", "equ"]):
- # We have all of the port types, so:
- port = "".join(
- [self.ports[sector][x]["sale"] for x in ["fuel", "org", "equ"]]
- )
- self.ports[sector]["ports"] = port
- self.ports[sector]["class"] = CLASSES_PORT[port]
- log.msg("completed {0} : {1}".format(sector, self.ports[sector]))
|