galaxy.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import jsonlines
  2. import os
  3. from twisted.python import log
  4. from pprint import pprint
  5. PORT_CLASSES = {
  6. 1: "BBS",
  7. 2: "BSB",
  8. 3: "SBB",
  9. 4: "SSB",
  10. 5: "SBS",
  11. 6: "BSS",
  12. 7: "SSS",
  13. 8: "BBB",
  14. }
  15. CLASSES_PORT = {v: k for k, v in PORT_CLASSES.items()}
  16. class GameData(object):
  17. def __init__(self, usergame):
  18. # Construct the GameData storage object
  19. self.usergame = usergame
  20. self.warps = {}
  21. self.ports = {}
  22. def storage_filename(self):
  23. """ return filename
  24. username.lower _ game.upper.json
  25. """
  26. user, game = self.usergame
  27. return "{0}_{1}.json".format(user.lower(), game.upper())
  28. def display(self):
  29. pprint(self.warps)
  30. pprint(self.ports)
  31. def save(self, *_):
  32. """ save gamedata as jsonlines.
  33. Enable sort_keys=True to provide stable json data output.
  34. We also sorted(.keys()) to keep records in order.
  35. Note: There's a "bug" when serializing to json, keys must be strings!
  36. """
  37. filename = self.storage_filename()
  38. with jsonlines.open(filename, mode="w", sort_keys=True) as writer:
  39. # for warp, sectors in self.warps.items():
  40. for warp in sorted(self.warps.keys()):
  41. sectors = self.warps[warp]
  42. # log.msg("save:", warp, sectors)
  43. sects = sorted(list(sectors)) # make a list
  44. w = {"warp": {warp: sects}}
  45. # log.msg(w)
  46. writer.write(w)
  47. yield
  48. # for sector, port in self.ports.items():
  49. for sector in sorted(self.ports.keys()):
  50. port = self.ports[sector]
  51. p = {"port": {sector: port}}
  52. writer.write(p)
  53. yield
  54. log.msg("Saved {0} {1}/{2}".format(filename, len(self.ports), len(self.warps)))
  55. def load(self):
  56. filename = self.storage_filename()
  57. self.warps = {}
  58. self.ports = {}
  59. if os.path.exists(filename):
  60. # Load it
  61. with jsonlines.open(filename) as reader:
  62. for obj in reader:
  63. if "warp" in obj:
  64. for s, w in obj["warp"].items():
  65. # log.msg(s, w)
  66. self.warps[int(s)] = set(w)
  67. # self.warps.update(obj["warp"])
  68. if "port" in obj:
  69. for s, p in obj["port"].items():
  70. self.ports[int(s)] = p
  71. # self.ports.update(obj["port"])
  72. yield
  73. log.msg("Loaded {0} {1}/{2}".format(filename, len(self.ports), len(self.warps)))
  74. def warp_to(self, source, *dest):
  75. """ connect sector source to destination.
  76. """
  77. log.msg("Warp {0} to {1}".format(source, dest))
  78. if source not in self.warps:
  79. self.warps[source] = set()
  80. for d in dest:
  81. if d not in self.warps[source]:
  82. self.warps[source].add(d)
  83. def set_port(self, sector, data):
  84. log.msg("Port {0} : {1}".format(sector, data))
  85. if sector not in self.ports:
  86. self.ports[sector] = dict()
  87. self.ports[sector].update(data)
  88. if "port" not in self.ports[sector]:
  89. # incomplete port type - can we "complete" it?
  90. if all(x in self.ports for x in ["fuel", "org", "equ"]):
  91. # We have all of the port types, so:
  92. port = "".join(
  93. [self.ports[sector][x]["sale"] for x in ["fuel", "org", "equ"]]
  94. )
  95. self.ports[sector]["ports"] = port
  96. self.ports[sector]["class"] = CLASSES_PORT[port]
  97. log.msg("completed {0} : {1}".format(sector, self.ports[sector]))