Browse Source

Add faction sovereignty information to universe data.

master
Ben Kurtovic 4 years ago
parent
commit
c9a7325f01
2 changed files with 207 additions and 69 deletions
  1. +97
    -29
      calefaction/eve/universe.py
  2. +110
    -40
      scripts/import_sde.py

+ 97
- 29
calefaction/eve/universe.py View File

@@ -7,19 +7,23 @@ import yaml

__all__ = ["Universe"]

class _SolarSystem:
"""Represents a solar system."""
class _UniqueObject:
"""Base class for uniquely ID'd objects in the universe."""

def __init__(self, universe, sid, data):
def __init__(self, universe, id_, data):
self._universe = universe
self._id = sid
self._id = id_
self._data = data

@property
def id(self):
"""The solar system's ID, as an integer."""
"""The object's unique ID, as an integer."""
return self._id


class _SolarSystem(_UniqueObject):
"""Represents a solar system."""

@property
def name(self):
"""The solar system's name, as a string."""
@@ -40,19 +44,31 @@ class _SolarSystem:
"""The solar system's security status, as a float."""
return self._data["security"]

@property
def faction(self):
"""The solar system's faction, as a _Faction object, or None."""
if "faction" in self._data:
return self._universe.faction(self._data["faction"])
return self.constellation.faction

class _Constellation:
"""Represents a constellation."""
@property
def is_nullsec(self):
"""Whether the solar system is in nullsec."""
return self.security < 0.05

def __init__(self, universe, cid, data):
self._universe = universe
self._id = cid
self._data = data
@property
def is_lowsec(self):
"""Whether the solar system is in nullsec."""
return self.security >= 0.05 and self.security < 0.45

@property
def id(self):
"""The constellation's ID, as an integer."""
return self._id
def is_highsec(self):
"""Whether the solar system is in nullsec."""
return self.security >= 0.45


class _Constellation(_UniqueObject):
"""Represents a constellation."""

@property
def name(self):
@@ -64,23 +80,36 @@ class _Constellation:
"""The constellation's region, as a _Region object."""
return self._universe.region(self._data["region"])

@property
def faction(self):
"""The constellation's faction, as a _Faction object, or None."""
if "faction" in self._data:
return self._universe.faction(self._data["faction"])
return self.region.faction


class _Region:
class _Region(_UniqueObject):
"""Represents a region."""

def __init__(self, universe, rid, data):
self._universe = universe
self._id = rid
self._data = data
@property
def name(self):
"""The region's name, as a string."""
return self._data["name"]

@property
def id(self):
"""The region's ID, as an integer."""
return self._id
def faction(self):
"""The region's faction, as a _Faction object, or None."""
if "faction" in self._data:
return self._universe.faction(self._data["faction"])
return None


class _Faction(_UniqueObject):
"""Represents a faction."""

@property
def name(self):
"""The region's name, as a string."""
"""The faction's name, as a string."""
return self._data["name"]


@@ -115,16 +144,34 @@ class _DummyRegion(_Region):
})


class _DummyFaction(_Faction):
"""Represents an unknown or invalid faction."""

def __init__(self, universe):
super().__init__(universe, -1, {
"name": "Unknown"
})


class Universe:
"""EVE API module for static universe data."""

def __init__(self, datadir):
self._dir = datadir

self._lock = Lock()
self._loaded = False

self._systems = {}
self._constellations = {}
self._regions = {}
self._factions = {}

@staticmethod
def _load_yaml(path):
"""Load in and return a YAML file with the given path."""
with gzip.open(str(path), "rb") as fp:
return yaml.load(fp, Loader=yaml.CLoader)

def _load(self):
"""Load in universe data. This can be called multiple times safely."""
@@ -135,13 +182,16 @@ class Universe:
if self._loaded:
return

filename = str(self._dir / "galaxy.yml.gz")
with gzip.open(filename, "rb") as fp:
data = yaml.load(fp, Loader=yaml.CLoader)
galaxy = self._load_yaml(self._dir / "galaxy.yml.gz")
self._systems = galaxy["systems"]
self._constellations = galaxy["constellations"]
self._regions = galaxy["regions"]
del galaxy

entities = self._load_yaml(self._dir / "entities.yml.gz")
self._factions = entities["factions"]
del entities

self._systems = data["systems"]
self._constellations = data["constellations"]
self._regions = data["regions"]
self._loaded = True

def system(self, sid):
@@ -173,3 +223,21 @@ class Universe:
if rid not in self._regions:
return _DummyRegion(self)
return _Region(self, rid, self._regions[rid])

def faction(self, fid):
"""Return a _Faction with the given ID.

If the ID is invalid, return a dummy unknown object with ID -1.
"""
self._load()
if fid not in self._factions:
return _DummyFaction(self)
return _Faction(self, fid, self._factions[fid])

def ship(self, sid):
"""Return a _Ship with the given ID.

If the ID is invalid, return a dummy unknown object with ID -1.
"""
...
raise NotImplementedError()

+ 110
- 40
scripts/import_sde.py View File

@@ -90,6 +90,66 @@ def _build_galaxy_skeleton(ids, names):
print("done.")
return galaxy

def _load_assoc_for_system(galaxy, system, rid, cid):
data = _load_yaml(system / "solarsystem.staticdata")
sid = data["solarSystemID"]
sec = data["security"]

assert isinstance(sid, int)
assert isinstance(sec, float)
assert sid >= 0
assert sec >= -1.0 and sec <= 1.0

galaxy["systems"][sid]["constellation"] = cid
galaxy["systems"][sid]["region"] = rid
galaxy["systems"][sid]["security"] = sec

if "factionID" in data:
facid = data["factionID"]
assert isinstance(facid, int)
assert facid >= 0
galaxy["systems"][sid]["faction"] = facid

def _load_assoc_for_constellation(galaxy, constellation, rid):
data = _load_yaml(constellation / "constellation.staticdata")
cid = data["constellationID"]

assert isinstance(cid, int)
assert cid >= 0

galaxy["constellations"][cid]["region"] = rid

if "factionID" in data:
facid = data["factionID"]
assert isinstance(facid, int)
assert facid >= 0
galaxy["constellations"][cid]["faction"] = facid

for system in constellation.iterdir():
if not system.is_dir():
continue

_load_assoc_for_system(galaxy, system, rid, cid)

def _load_assoc_for_region(galaxy, region):
data = _load_yaml(region / "region.staticdata")
rid = data["regionID"]

assert isinstance(rid, int)
assert rid >= 0

if "factionID" in data:
facid = data["factionID"]
assert isinstance(facid, int)
assert facid >= 0
galaxy["regions"][rid]["faction"] = facid

for constellation in region.iterdir():
if not constellation.is_dir():
continue

_load_assoc_for_constellation(galaxy, constellation, rid)

def _load_galaxy_associations(sde_dir, galaxy):
print("Loading galaxy staticdata... ", end="", flush=True)

@@ -101,38 +161,8 @@ def _load_galaxy_associations(sde_dir, galaxy):
for region in base.iterdir():
if not region.is_dir():
continue
rdata = _load_yaml(region / "region.staticdata")
rid = rdata["regionID"]

assert isinstance(rid, int)
assert rid >= 0

for constellation in region.iterdir():
if not constellation.is_dir():
continue
cdata = _load_yaml(constellation / "constellation.staticdata")
cid = cdata["constellationID"]

assert isinstance(cid, int)
assert cid >= 0

galaxy["constellations"][cid]["region"] = rid

for system in constellation.iterdir():
if not system.is_dir():
continue
sdata = _load_yaml(system / "solarsystem.staticdata")
sid = sdata["solarSystemID"]
sec = sdata["security"]

assert isinstance(sid, int)
assert isinstance(sec, float)
assert sid >= 0
assert sec >= -1.0 and sec <= 1.0

galaxy["systems"][sid]["constellation"] = cid
galaxy["systems"][sid]["region"] = rid
galaxy["systems"][sid]["security"] = sec
_load_assoc_for_region(galaxy, region)

print("done.")

@@ -145,6 +175,25 @@ def _load_galaxy_associations(sde_dir, galaxy):
if system["region"] < 0 or system["constellation"] < 0:
print("[WARNING] Orphaned system: %d=%s" % (sid, system["name"]))

def _load_factions(sde_dir):
print("Loading factions... ", end="", flush=True)

data = _load_yaml(sde_dir / "bsd" / "chrFactions.yaml")

factions = {}
for entry in data:
fid = entry["factionID"]
name = entry["factionName"]

assert isinstance(fid, int)
assert isinstance(name, str)
assert fid >= 0

factions[fid] = {"name": name}

print("done.")
return factions

def _dump_galaxy(out_dir, galaxy):
print("Dumping galaxy... ", end="", flush=True)

@@ -154,22 +203,37 @@ def _dump_galaxy(out_dir, galaxy):

print("done.")

def _compress_galaxy(out_dir):
print("Compressing galaxy... ", end="", flush=True)
def _dump_entities(out_dir, factions):
print("Dumping entities... ", end="", flush=True)

fn_src = out_dir / "galaxy.yml"
fn_dst = out_dir / "galaxy.yml.gz"
entities = {"factions": factions}

with fn_src.open("rb") as f_in:
with gzip.open(str(fn_dst), "wb") as f_out:
shutil.copyfileobj(f_in, f_out)
filename = out_dir / "entities.yml"
with filename.open("w") as fp:
fp.write(yaml.dump(entities, Dumper=yaml.CDumper))

print("done.")

def _compress(out_dir):
targets = ["galaxy", "entities"]
for basename in targets:
print("Compressing %s... " % basename, end="", flush=True)

fn_src = out_dir / (basename + ".yml")
fn_dst = out_dir / (basename + ".yml.gz")

with fn_src.open("rb") as f_in:
with gzip.open(str(fn_dst), "wb") as f_out:
shutil.copyfileobj(f_in, f_out)

print("done.")

def _cleanup(out_dir):
print("Cleaning up... ", end="", flush=True)

(out_dir / "galaxy.yml").unlink()
targets = ["galaxy", "entities"]
for basename in targets:
(out_dir / (basename + ".yml")).unlink()

print("done.")

@@ -184,13 +248,19 @@ def import_sde(sde_dir, out_dir):
print("Counts: regions=%d, constellations=%d, systems=%d" % (
len(ids[_REGION]), len(ids[_CONSTELLATION]), len(ids[_SOLAR_SYSTEM])))
names = _load_names(sde_dir)

galaxy = _build_galaxy_skeleton(ids, names)
del ids
del names
_load_galaxy_associations(sde_dir, galaxy)
_dump_galaxy(out_dir, galaxy)
del galaxy
_compress_galaxy(out_dir)

factions = _load_factions(sde_dir)
_dump_entities(out_dir, factions)
del factions

_compress(out_dir)
_cleanup(out_dir)

def main():


Loading…
Cancel
Save