galaxy.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. # 10 = 300 bytes
  23. self.warp_groups = 10
  24. # 3 = 560 bytes
  25. # 5 = 930 bytes
  26. self.port_groups = 3
  27. def storage_filename(self):
  28. """ return filename
  29. username.lower _ game.upper.json
  30. """
  31. user, game = self.usergame
  32. return "{0}_{1}.json".format(user.lower(), game.upper())
  33. def display(self):
  34. pprint(self.warps)
  35. pprint(self.ports)
  36. def save(self, *_):
  37. """ save gamedata as jsonlines.
  38. Enable sort_keys=True to provide stable json data output.
  39. We also sorted(.keys()) to keep records in order.
  40. Note: There's a "bug" when serializing to json, keys must be strings!
  41. """
  42. filename = self.storage_filename()
  43. with jsonlines.open(filename, mode="w", sort_keys=True) as writer:
  44. # for warp, sectors in self.warps.items():
  45. w = {"warp": {}}
  46. for warp in sorted(self.warps.keys()):
  47. sectors = self.warps[warp]
  48. # log.msg("save:", warp, sectors)
  49. sects = sorted(list(sectors)) # make a list
  50. w["warp"][warp] = sects
  51. if len(w["warp"]) >= self.warp_groups:
  52. writer.write(w)
  53. w = {"warp": {}}
  54. yield
  55. # log.msg(w)
  56. # writer.write(w)
  57. # yield
  58. if len(w["warp"]) > 1:
  59. writer.write(w)
  60. # for sector, port in self.ports.items():
  61. p = {"port": {}}
  62. for sector in sorted(self.ports.keys()):
  63. port = self.ports[sector]
  64. p["port"][sector] = port
  65. if len(p["port"]) >= self.port_groups:
  66. writer.write(p)
  67. p = {"port": {}}
  68. yield
  69. if len(p["port"]) > 1:
  70. writer.write(p)
  71. log.msg("Saved {0} {1}/{2}".format(filename, len(self.ports), len(self.warps)))
  72. def load(self):
  73. filename = self.storage_filename()
  74. self.warps = {}
  75. self.ports = {}
  76. if os.path.exists(filename):
  77. # Load it
  78. with jsonlines.open(filename) as reader:
  79. for obj in reader:
  80. if "warp" in obj:
  81. for s, w in obj["warp"].items():
  82. # log.msg(s, w)
  83. self.warps[int(s)] = set(w)
  84. # self.warps.update(obj["warp"])
  85. if "port" in obj:
  86. for s, p in obj["port"].items():
  87. self.ports[int(s)] = p
  88. # self.ports.update(obj["port"])
  89. yield
  90. log.msg("Loaded {0} {1}/{2}".format(filename, len(self.ports), len(self.warps)))
  91. def warp_to(self, source, *dest):
  92. """ connect sector source to destination.
  93. """
  94. log.msg("Warp {0} to {1}".format(source, dest))
  95. if source not in self.warps:
  96. self.warps[source] = set()
  97. for d in dest:
  98. if d not in self.warps[source]:
  99. self.warps[source].add(d)
  100. def set_port(self, sector, data):
  101. log.msg("Port {0} : {1}".format(sector, data))
  102. if sector not in self.ports:
  103. self.ports[sector] = dict()
  104. self.ports[sector].update(data)
  105. if "port" not in self.ports[sector]:
  106. # incomplete port type - can we "complete" it?
  107. if all(x in self.ports for x in ["fuel", "org", "equ"]):
  108. # We have all of the port types, so:
  109. port = "".join(
  110. [self.ports[sector][x]["sale"] for x in ["fuel", "org", "equ"]]
  111. )
  112. self.ports[sector]["ports"] = port
  113. self.ports[sector]["class"] = CLASSES_PORT[port]
  114. log.msg("completed {0} : {1}".format(sector, self.ports[sector]))