A corporation manager and dashboard for EVE Online
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

331 lignes
8.9 KiB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. import gzip
  4. from pathlib import Path
  5. import shutil
  6. import sys
  7. import yaml
  8. _SHIP_CAT = 6
  9. _FIGHTER_CAT = 87
  10. _STRUCT_CATS = [22, 23, 40, 46, 65]
  11. _REGION = 3
  12. _CONSTELLATION = 4
  13. _SOLAR_SYSTEM = 5
  14. def _load_yaml(filename):
  15. with filename.open("rb") as fp:
  16. return yaml.load(fp, Loader=yaml.CLoader)
  17. def _save_yaml(filename, data):
  18. with filename.open("w") as fp:
  19. fp.write(yaml.dump(data, Dumper=yaml.CDumper))
  20. def _verify_categoryids(sde_dir):
  21. print("Verifying categoryIDs... ", end="", flush=True)
  22. data = _load_yaml(sde_dir / "fsd" / "categoryIDs.yaml")
  23. assert data[_SHIP_CAT]["name"]["en"] == "Ship"
  24. print("done.")
  25. def _load_groupids(sde_dir):
  26. print("Loading groupIDs... ", end="", flush=True)
  27. data = _load_yaml(sde_dir / "fsd" / "groupIDs.yaml")
  28. groups = {cid: {} for cid in [_SHIP_CAT, _FIGHTER_CAT] + _STRUCT_CATS}
  29. for gid, group in data.items():
  30. cat = group["categoryID"]
  31. if cat in groups:
  32. name = group["name"]["en"]
  33. assert isinstance(gid, int)
  34. assert isinstance(name, str)
  35. groups[cat][gid] = name
  36. print("done.")
  37. return groups
  38. def _load_typeids(sde_dir, groups):
  39. print("Loading typeIDs... ", end="", flush=True)
  40. data = _load_yaml(sde_dir / "fsd" / "typeIDs.yaml")
  41. assert data[_REGION]["groupID"] == _REGION
  42. assert data[_REGION]["name"]["en"] == "Region"
  43. assert data[_CONSTELLATION]["groupID"] == _CONSTELLATION
  44. assert data[_CONSTELLATION]["name"]["en"] == "Constellation"
  45. assert data[_SOLAR_SYSTEM]["groupID"] == _SOLAR_SYSTEM
  46. assert data[_SOLAR_SYSTEM]["name"]["en"] == "Solar System"
  47. types = {"ships": {}, "structures": {}, "fighters": {}}
  48. cat_conv = {_SHIP_CAT: "ships", _FIGHTER_CAT: "fighters"}
  49. cat_conv.update({cid: "structures" for cid in _STRUCT_CATS})
  50. group_conv = {gid: cid for cid, gids in groups.items() for gid in gids}
  51. for tid, type_ in data.items():
  52. gid = type_["groupID"]
  53. if gid in group_conv:
  54. cid = group_conv[gid]
  55. cname = cat_conv[cid]
  56. name = type_["name"]["en"]
  57. group = groups[cid][gid]
  58. assert isinstance(tid, int)
  59. types[cname][tid] = {"name": name, "group": group}
  60. print("done.")
  61. return types
  62. def _load_ids(sde_dir):
  63. print("Loading itemIDs... ", end="", flush=True)
  64. data = _load_yaml(sde_dir / "bsd" / "invItems.yaml")
  65. ids = {_REGION: [], _CONSTELLATION: [], _SOLAR_SYSTEM: []}
  66. for entry in data:
  67. if entry["typeID"] in ids:
  68. ids[entry["typeID"]].append(entry["itemID"])
  69. print("done.")
  70. return ids
  71. def _load_names(sde_dir):
  72. print("Loading itemNames... ", end="", flush=True)
  73. data = _load_yaml(sde_dir / "bsd" / "invNames.yaml")
  74. names = {}
  75. for entry in data:
  76. name = entry["itemName"]
  77. assert isinstance(name, str)
  78. names[entry["itemID"]] = name
  79. print("done.")
  80. return names
  81. def _build_galaxy_skeleton(ids, names):
  82. print("Building galaxy skeleton... ", end="", flush=True)
  83. galaxy = {"regions": {}, "constellations": {}, "systems": {}}
  84. d = galaxy["regions"]
  85. for rid in ids[_REGION]:
  86. assert isinstance(rid, int)
  87. d[rid] = {
  88. "name": names[rid]
  89. }
  90. d = galaxy["constellations"]
  91. for cid in ids[_CONSTELLATION]:
  92. assert isinstance(cid, int)
  93. d[cid] = {
  94. "name": names[cid],
  95. "region": -1
  96. }
  97. d = galaxy["systems"]
  98. for sid in ids[_SOLAR_SYSTEM]:
  99. assert isinstance(sid, int)
  100. d[sid] = {
  101. "name": names[sid],
  102. "constellation": -1, "region": -1, "security": 0.0
  103. }
  104. print("done.")
  105. return galaxy
  106. def _load_assoc_for_system(galaxy, system, rid, cid):
  107. data = _load_yaml(system / "solarsystem.staticdata")
  108. sid = data["solarSystemID"]
  109. sec = data["security"]
  110. assert isinstance(sid, int)
  111. assert isinstance(sec, float)
  112. assert sid >= 0
  113. assert sec >= -1.0 and sec <= 1.0
  114. galaxy["systems"][sid]["constellation"] = cid
  115. galaxy["systems"][sid]["region"] = rid
  116. galaxy["systems"][sid]["security"] = sec
  117. if "factionID" in data:
  118. facid = data["factionID"]
  119. assert isinstance(facid, int)
  120. assert facid >= 0
  121. galaxy["systems"][sid]["faction"] = facid
  122. def _load_assoc_for_constellation(galaxy, constellation, rid):
  123. data = _load_yaml(constellation / "constellation.staticdata")
  124. cid = data["constellationID"]
  125. assert isinstance(cid, int)
  126. assert cid >= 0
  127. galaxy["constellations"][cid]["region"] = rid
  128. if "factionID" in data:
  129. facid = data["factionID"]
  130. assert isinstance(facid, int)
  131. assert facid >= 0
  132. galaxy["constellations"][cid]["faction"] = facid
  133. for system in constellation.iterdir():
  134. if not system.is_dir():
  135. continue
  136. _load_assoc_for_system(galaxy, system, rid, cid)
  137. def _load_assoc_for_region(galaxy, region):
  138. data = _load_yaml(region / "region.staticdata")
  139. rid = data["regionID"]
  140. assert isinstance(rid, int)
  141. assert rid >= 0
  142. if "factionID" in data:
  143. facid = data["factionID"]
  144. assert isinstance(facid, int)
  145. assert facid >= 0
  146. galaxy["regions"][rid]["faction"] = facid
  147. for constellation in region.iterdir():
  148. if not constellation.is_dir():
  149. continue
  150. _load_assoc_for_constellation(galaxy, constellation, rid)
  151. def _load_galaxy_associations(sde_dir, galaxy):
  152. print("Loading galaxy staticdata... ", end="", flush=True)
  153. univdir = sde_dir / "fsd" / "universe"
  154. for base in univdir.iterdir():
  155. if not base.is_dir():
  156. continue
  157. for region in base.iterdir():
  158. if not region.is_dir():
  159. continue
  160. _load_assoc_for_region(galaxy, region)
  161. print("done.")
  162. for cid, constellation in galaxy["constellations"].items():
  163. if constellation["region"] < 0:
  164. print("[WARNING] Orphaned constellation: %d=%s" % (
  165. cid, constellation["name"]))
  166. for sid, system in galaxy["systems"].items():
  167. if system["region"] < 0 or system["constellation"] < 0:
  168. print("[WARNING] Orphaned system: %d=%s" % (sid, system["name"]))
  169. def _load_factions(sde_dir):
  170. print("Loading factions... ", end="", flush=True)
  171. data = _load_yaml(sde_dir / "bsd" / "chrFactions.yaml")
  172. factions = {}
  173. for entry in data:
  174. fid = entry["factionID"]
  175. name = entry["factionName"]
  176. assert isinstance(fid, int)
  177. assert isinstance(name, str)
  178. assert fid >= 0
  179. factions[fid] = {"name": name}
  180. print("done.")
  181. return factions
  182. def _dump_types(out_dir, types):
  183. print("Dumping types... ", end="", flush=True)
  184. _save_yaml(out_dir / "types.yml", types)
  185. print("done.")
  186. def _dump_galaxy(out_dir, galaxy):
  187. print("Dumping galaxy... ", end="", flush=True)
  188. _save_yaml(out_dir / "galaxy.yml", galaxy)
  189. print("done.")
  190. def _dump_entities(out_dir, factions):
  191. print("Dumping entities... ", end="", flush=True)
  192. entities = {"factions": factions}
  193. _save_yaml(out_dir / "entities.yml", entities)
  194. print("done.")
  195. def _compress(out_dir):
  196. targets = ["types", "galaxy", "entities"]
  197. for basename in targets:
  198. print("Compressing %s... " % basename, end="", flush=True)
  199. fn_src = out_dir / (basename + ".yml")
  200. fn_dst = out_dir / (basename + ".yml.gz")
  201. with fn_src.open("rb") as f_in:
  202. with gzip.open(str(fn_dst), "wb") as f_out:
  203. shutil.copyfileobj(f_in, f_out)
  204. print("done.")
  205. def _cleanup(out_dir):
  206. print("Cleaning up... ", end="", flush=True)
  207. targets = ["types", "galaxy", "entities"]
  208. for basename in targets:
  209. (out_dir / (basename + ".yml")).unlink()
  210. print("done.")
  211. def import_sde(sde_dir, out_dir):
  212. """Import the SDE unzipped at sde_dir to out_dir."""
  213. print("EVE Online static data import")
  214. print("- from: %s" % sde_dir)
  215. print("- to: %s" % out_dir)
  216. _verify_categoryids(sde_dir)
  217. groups = _load_groupids(sde_dir)
  218. types = _load_typeids(sde_dir, groups)
  219. _dump_types(out_dir, types)
  220. del groups, types
  221. ids = _load_ids(sde_dir)
  222. print("Counts: regions=%d, constellations=%d, systems=%d" % (
  223. len(ids[_REGION]), len(ids[_CONSTELLATION]), len(ids[_SOLAR_SYSTEM])))
  224. names = _load_names(sde_dir)
  225. galaxy = _build_galaxy_skeleton(ids, names)
  226. del ids, names
  227. _load_galaxy_associations(sde_dir, galaxy)
  228. _dump_galaxy(out_dir, galaxy)
  229. del galaxy
  230. factions = _load_factions(sde_dir)
  231. _dump_entities(out_dir, factions)
  232. del factions
  233. _compress(out_dir)
  234. _cleanup(out_dir)
  235. def main():
  236. if len(sys.argv) < 2:
  237. print("usage: %s <sde_directory>" % sys.argv[0])
  238. exit(1)
  239. sde_dir = Path(sys.argv[1]).resolve()
  240. out_dir = Path(__file__).resolve().parent.parent / "data" / "universe"
  241. import_sde(sde_dir, out_dir)
  242. if __name__ == "__main__":
  243. main()