mirror of
https://github.com/EDCD/EDMarketConnector.git
synced 2025-04-14 16:27:13 +03:00
Drop support for exporting in Coriolis-specific format
This commit is contained in:
parent
7598d5b7b7
commit
66b9699b45
4
EDMC.py
4
EDMC.py
@ -22,7 +22,6 @@ from commodity import COMMODITY_DEFAULT
|
|||||||
import outfitting
|
import outfitting
|
||||||
import loadout
|
import loadout
|
||||||
import edshipyard
|
import edshipyard
|
||||||
import coriolis
|
|
||||||
import shipyard
|
import shipyard
|
||||||
import eddn
|
import eddn
|
||||||
import stats
|
import stats
|
||||||
@ -43,7 +42,6 @@ try:
|
|||||||
parser = argparse.ArgumentParser(prog=appcmdname, description='Prints the current system and station (if docked) to stdout and optionally writes player status, ship locations, ship loadout and/or station data to file. Requires prior setup through the accompanying GUI app.')
|
parser = argparse.ArgumentParser(prog=appcmdname, description='Prints the current system and station (if docked) to stdout and optionally writes player status, ship locations, ship loadout and/or station data to file. Requires prior setup through the accompanying GUI app.')
|
||||||
parser.add_argument('-v', '--version', help='print program version and exit', action='store_const', const=True)
|
parser.add_argument('-v', '--version', help='print program version and exit', action='store_const', const=True)
|
||||||
parser.add_argument('-a', metavar='FILE', help='write ship loadout to FILE in Companion API json format')
|
parser.add_argument('-a', metavar='FILE', help='write ship loadout to FILE in Companion API json format')
|
||||||
parser.add_argument('-c', metavar='FILE', help='write ship loadout to FILE in Coriolis json format')
|
|
||||||
parser.add_argument('-e', metavar='FILE', help='write ship loadout to FILE in E:D Shipyard plain text format')
|
parser.add_argument('-e', metavar='FILE', help='write ship loadout to FILE in E:D Shipyard plain text format')
|
||||||
parser.add_argument('-l', metavar='FILE', help='write ship locations to FILE in CSV format')
|
parser.add_argument('-l', metavar='FILE', help='write ship locations to FILE in CSV format')
|
||||||
parser.add_argument('-m', metavar='FILE', help='write station commodity market data to FILE in CSV format')
|
parser.add_argument('-m', metavar='FILE', help='write station commodity market data to FILE in CSV format')
|
||||||
@ -118,8 +116,6 @@ try:
|
|||||||
h.write(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')).encode('utf-8'))
|
h.write(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True, separators=(',', ': ')).encode('utf-8'))
|
||||||
if args.a:
|
if args.a:
|
||||||
loadout.export(data, args.a)
|
loadout.export(data, args.a)
|
||||||
if args.c:
|
|
||||||
coriolis.export(data, args.c)
|
|
||||||
if args.e:
|
if args.e:
|
||||||
edshipyard.export(data, args.e)
|
edshipyard.export(data, args.e)
|
||||||
if args.l:
|
if args.l:
|
||||||
|
@ -206,7 +206,6 @@ Arguments:
|
|||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
-v, --version print program version and exit
|
-v, --version print program version and exit
|
||||||
-a FILE write ship loadout to FILE in Companion API json format
|
-a FILE write ship loadout to FILE in Companion API json format
|
||||||
-c FILE write ship loadout to FILE in Coriolis json format
|
|
||||||
-e FILE write ship loadout to FILE in E:D Shipyard plain text format
|
-e FILE write ship loadout to FILE in E:D Shipyard plain text format
|
||||||
-l FILE write ship locations to FILE in CSV format
|
-l FILE write ship locations to FILE in CSV format
|
||||||
-m FILE write station commodity market data to FILE in CSV format
|
-m FILE write station commodity market data to FILE in CSV format
|
||||||
|
261
coriolis.py
261
coriolis.py
@ -7,11 +7,7 @@ import base64
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import cPickle
|
import cPickle
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
from os.path import join
|
|
||||||
import re
|
|
||||||
import StringIO
|
import StringIO
|
||||||
import time
|
|
||||||
import gzip
|
import gzip
|
||||||
|
|
||||||
from config import config
|
from config import config
|
||||||
@ -19,225 +15,6 @@ import outfitting
|
|||||||
import companion
|
import companion
|
||||||
|
|
||||||
|
|
||||||
# Map API slot names to Coriolis categories
|
|
||||||
# http://cdn.coriolis.io/schemas/ship-loadout/2.json
|
|
||||||
|
|
||||||
slot_map = {
|
|
||||||
'hugehardpoint' : 'hardpoints',
|
|
||||||
'largehardpoint' : 'hardpoints',
|
|
||||||
'mediumhardpoint' : 'hardpoints',
|
|
||||||
'smallhardpoint' : 'hardpoints',
|
|
||||||
'tinyhardpoint' : 'utility',
|
|
||||||
'armour' : 'standard',
|
|
||||||
'powerplant' : 'standard',
|
|
||||||
'mainengines' : 'standard',
|
|
||||||
'frameshiftdrive' : 'standard',
|
|
||||||
'lifesupport' : 'standard',
|
|
||||||
'powerdistributor' : 'standard',
|
|
||||||
'radar' : 'standard',
|
|
||||||
'fueltank' : 'standard',
|
|
||||||
'military' : 'internal',
|
|
||||||
'slot' : 'internal',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Map API ship names to Coriolis names
|
|
||||||
ship_map = dict(companion.ship_map)
|
|
||||||
ship_map['cobramkiii'] = 'Cobra Mk III'
|
|
||||||
ship_map['cobramkiv'] = 'Cobra Mk IV',
|
|
||||||
ship_map['viper'] = 'Viper'
|
|
||||||
ship_map['viper_mkiv'] = 'Viper Mk IV'
|
|
||||||
|
|
||||||
|
|
||||||
# Map EDDN outfitting schema / in-game names to Coriolis names
|
|
||||||
# https://raw.githubusercontent.com/jamesremuscat/EDDN/master/schemas/outfitting-v1.0.json
|
|
||||||
|
|
||||||
standard_map = OrderedDict([ # in output order
|
|
||||||
('Armour', 'bulkheads'),
|
|
||||||
(None, 'cargoHatch'), # not available in the Companion API data
|
|
||||||
('Power Plant', 'powerPlant'),
|
|
||||||
('Thrusters', 'thrusters'),
|
|
||||||
('Frame Shift Drive', 'frameShiftDrive'),
|
|
||||||
('Life Support', 'lifeSupport'),
|
|
||||||
('Power Distributor', 'powerDistributor'),
|
|
||||||
('Sensors', 'sensors'),
|
|
||||||
('Fuel Tank', 'fuelTank'),
|
|
||||||
])
|
|
||||||
|
|
||||||
weaponmount_map = {
|
|
||||||
'Fixed' : 'Fixed',
|
|
||||||
'Gimballed' : 'Gimballed',
|
|
||||||
'Turreted' : 'Turret',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Modules that have a name as well as a group
|
|
||||||
bulkheads = outfitting.armour_map.values()
|
|
||||||
fixup_map = {}
|
|
||||||
fixup_map.update({ x[0] : ('Scanner', x[0]) for x in outfitting.misc_internal_map.values() })
|
|
||||||
fixup_map.update({ x[0] : ('Countermeasure', x[0]) for x in outfitting.countermeasure_map.values() })
|
|
||||||
fixup_map.update({
|
|
||||||
'Advanced Plasma Accelerator' : ('Plasma Accelerator', 'Advanced Plasma Accelerator'),
|
|
||||||
'Corrosion Resistant Cargo Rack': ('Cargo Rack', 'Corrosion Resistant'),
|
|
||||||
'Cytoscrambler Burst Laser' : ('Burst Laser', 'Cytoscrambler'),
|
|
||||||
'Enforcer Cannon' : ('Multi-cannon', 'Enforcer'),
|
|
||||||
'Enhanced Performance Thrusters': ('Thrusters', 'Enhanced Performance'),
|
|
||||||
'Imperial Hammer Rail Gun' : ('Rail Gun', 'Imperial Hammer'),
|
|
||||||
'Luxury Class Passenger Cabin' : ('Luxury Passenger Cabin', None),
|
|
||||||
'Mining Lance Beam Laser' : ('Mining Laser', 'Mining Lance'),
|
|
||||||
'Multi-Cannon' : ('Multi-cannon', None),
|
|
||||||
'Pacifier Frag-Cannon' : ('Fragment Cannon', 'Pacifier'),
|
|
||||||
'Pack-Hound Missile Rack' : ('Missile Rack', 'Pack-Hound'),
|
|
||||||
'Pulse Disruptor Laser' : ('Pulse Laser', 'Disruptor'),
|
|
||||||
'Retributor Beam Laser' : ('Beam Laser', 'Retributor'),
|
|
||||||
'Rocket Propelled FSD Disruptor': ('Missile Rack', 'Rocket Propelled FSD Disruptor'),
|
|
||||||
'Shock Mine Launcher' : ('Mine Launcher', 'Shock Mine Launcher'),
|
|
||||||
'Standard Docking Computer' : ('Docking Computer', 'Standard Docking Computer'),
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
# Ship masses
|
|
||||||
ships = cPickle.load(open(join(config.respath, 'ships.p'), 'rb'))
|
|
||||||
|
|
||||||
|
|
||||||
def export(data, filename=None):
|
|
||||||
|
|
||||||
querytime = config.getint('querytime') or int(time.time())
|
|
||||||
|
|
||||||
loadout = OrderedDict([ # Mimic Coriolis export ordering
|
|
||||||
('$schema', 'http://cdn.coriolis.io/schemas/ship-loadout/2.json#'),
|
|
||||||
('name', ship_map.get(data['ship']['name'].lower(), data['ship']['name'])),
|
|
||||||
('ship', ship_map.get(data['ship']['name'].lower(), data['ship']['name'])),
|
|
||||||
('components', OrderedDict([
|
|
||||||
('standard', OrderedDict([(x,None) for x in standard_map.values()])),
|
|
||||||
('hardpoints', []),
|
|
||||||
('utility', []),
|
|
||||||
('internal', []),
|
|
||||||
])),
|
|
||||||
])
|
|
||||||
maxpri = 0
|
|
||||||
mass = 0.0
|
|
||||||
fsd = None
|
|
||||||
|
|
||||||
# Correct module ordering relies on the fact that "Slots" in the data are correctly ordered alphabetically.
|
|
||||||
# Correct hardpoint ordering additionally relies on the fact that "Huge" < "Large" < "Medium" < "Small"
|
|
||||||
for slot in sorted(data['ship']['modules']):
|
|
||||||
|
|
||||||
v = data['ship']['modules'][slot]
|
|
||||||
try:
|
|
||||||
for s in slot_map:
|
|
||||||
if slot.lower().startswith(s):
|
|
||||||
category = slot_map[s]
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
if __debug__:
|
|
||||||
for skip in ['bobble', 'decal', 'paintjob', 'planetaryapproachsuite', 'enginecolour', 'shipkit', 'weaponcolour']:
|
|
||||||
if slot.lower().startswith(skip):
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
print 'Coriolis: Unknown slot %s' % slot
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not v:
|
|
||||||
# Need to add nulls for empty slots. Assumes that standard slots can't be empty.
|
|
||||||
loadout['components'][category].append(None)
|
|
||||||
continue
|
|
||||||
|
|
||||||
module = outfitting.lookup(v['module'], ship_map)
|
|
||||||
if not module:
|
|
||||||
raise AssertionError('Unknown module %s' % v) # Shouldn't happen
|
|
||||||
mass += module.get('mass', 0)
|
|
||||||
|
|
||||||
thing = OrderedDict([
|
|
||||||
('class',int(module['class'])),
|
|
||||||
('rating', module['rating']),
|
|
||||||
('enabled', module['enabled']),
|
|
||||||
('priority', module['priority']+1), # make 1-based
|
|
||||||
])
|
|
||||||
maxpri = max(maxpri, thing['priority'])
|
|
||||||
|
|
||||||
if category == 'standard':
|
|
||||||
# Standard items are indexed by "group" rather than containing a "group" member
|
|
||||||
if module['name'] in bulkheads:
|
|
||||||
loadout['components'][category]['bulkheads'] = module['name'] # Bulkheads are just strings
|
|
||||||
else:
|
|
||||||
loadout['components'][category][standard_map[module['name']]] = thing
|
|
||||||
if module['name'] == 'Frame Shift Drive':
|
|
||||||
fsd = module # save for range calculation
|
|
||||||
else:
|
|
||||||
# All other items have a "group" member, some also have a "name"
|
|
||||||
if module['name'] in fixup_map:
|
|
||||||
thing['group'], name = fixup_map[module['name']]
|
|
||||||
if name: thing['name'] = name
|
|
||||||
else:
|
|
||||||
thing['group'] = module['name']
|
|
||||||
|
|
||||||
if 'mount' in module:
|
|
||||||
thing['mount'] = weaponmount_map[module['mount']]
|
|
||||||
if 'guidance' in module:
|
|
||||||
thing['missile'] = module['guidance'][0] # not mentioned in schema
|
|
||||||
|
|
||||||
loadout['components'][category].append(thing)
|
|
||||||
|
|
||||||
except AssertionError as e:
|
|
||||||
# Silently skip unrecognized modules
|
|
||||||
if __debug__: print 'Coriolis: %s' % e
|
|
||||||
if category != 'standard':
|
|
||||||
loadout['components'][category].append(None)
|
|
||||||
except:
|
|
||||||
if __debug__: raise
|
|
||||||
|
|
||||||
# Cargo Hatch status is not available in the data - fake something up
|
|
||||||
loadout['components']['standard']['cargoHatch'] = OrderedDict([
|
|
||||||
('enabled', True),
|
|
||||||
('priority', maxpri),
|
|
||||||
])
|
|
||||||
|
|
||||||
# Add mass and range
|
|
||||||
assert data['ship']['name'].lower() in companion.ship_map, data['ship']['name']
|
|
||||||
assert companion.ship_map[data['ship']['name'].lower()] in ships, companion.ship_map[data['ship']['name'].lower()]
|
|
||||||
try:
|
|
||||||
# https://github.com/cmmcleod/coriolis/blob/master/app/js/shipyard/module-shipyard.js#L184
|
|
||||||
hullMass = ships[companion.ship_map[data['ship']['name'].lower()]]['hullMass']
|
|
||||||
mass += hullMass
|
|
||||||
multiplier = pow(min(data['ship']['fuel']['main']['capacity'], fsd['maxfuel']) / fsd['fuelmul'], 1.0 / fsd['fuelpower']) * fsd['optmass']
|
|
||||||
|
|
||||||
loadout['stats'] = OrderedDict([
|
|
||||||
('hullMass', hullMass),
|
|
||||||
('fuelCapacity', data['ship']['fuel']['main']['capacity']),
|
|
||||||
('cargoCapacity', data['ship']['cargo']['capacity']),
|
|
||||||
('ladenMass', mass + data['ship']['fuel']['main']['capacity'] + data['ship']['cargo']['capacity']),
|
|
||||||
('unladenMass', mass),
|
|
||||||
('unladenRange', round(multiplier / (mass + min(data['ship']['fuel']['main']['capacity'], fsd['maxfuel'])), 2)), # fuel for one jump
|
|
||||||
('fullTankRange', round(multiplier / (mass + data['ship']['fuel']['main']['capacity']), 2)),
|
|
||||||
('ladenRange', round(multiplier / (mass + data['ship']['fuel']['main']['capacity'] + data['ship']['cargo']['capacity']), 2)),
|
|
||||||
])
|
|
||||||
except:
|
|
||||||
if __debug__: raise
|
|
||||||
|
|
||||||
# Construct description
|
|
||||||
string = json.dumps(loadout, indent=2, separators=(',', ': '))
|
|
||||||
|
|
||||||
if filename:
|
|
||||||
with open(filename, 'wt') as h:
|
|
||||||
h.write(string)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Look for last ship of this type
|
|
||||||
ship = companion.ship_map.get(data['ship']['name'].lower(), data['ship']['name']) # Use in-game name
|
|
||||||
regexp = re.compile(re.escape(ship) + '\.\d\d\d\d\-\d\d\-\d\dT\d\d\.\d\d\.\d\d\.json')
|
|
||||||
oldfiles = sorted([x for x in os.listdir(config.get('outdir')) if regexp.match(x)])
|
|
||||||
if oldfiles:
|
|
||||||
with open(join(config.get('outdir'), oldfiles[-1]), 'rU') as h:
|
|
||||||
if h.read() == string:
|
|
||||||
return # same as last time - don't write
|
|
||||||
|
|
||||||
# Write
|
|
||||||
filename = join(config.get('outdir'), '%s.%s.json' % (ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime))))
|
|
||||||
with open(filename, 'wt') as h:
|
|
||||||
h.write(string)
|
|
||||||
|
|
||||||
|
|
||||||
# Return a URL for the current ship
|
# Return a URL for the current ship
|
||||||
def url(data, is_beta):
|
def url(data, is_beta):
|
||||||
|
|
||||||
@ -246,16 +23,41 @@ def url(data, is_beta):
|
|||||||
out = StringIO.StringIO()
|
out = StringIO.StringIO()
|
||||||
with gzip.GzipFile(fileobj=out, mode='w') as f:
|
with gzip.GzipFile(fileobj=out, mode='w') as f:
|
||||||
f.write(string)
|
f.write(string)
|
||||||
return (is_beta and 'http://beta.coriolis.edcd.io/import?data=' or 'https://coriolis.edcd.io/import?data=') + base64.urlsafe_b64encode(out.getvalue()).replace('=', '%3D')
|
return (is_beta and 'https://beta.coriolis.edcd.io/import?data=' or 'https://coriolis.edcd.io/import?data=') + base64.urlsafe_b64encode(out.getvalue()).replace('=', '%3D')
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# build ship and module databases from https://github.com/cmmcleod/coriolis-data
|
# build ship and module databases from https://github.com/EDCD/coriolis-data/
|
||||||
#
|
#
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import json
|
|
||||||
data = json.load(open('coriolis-data/dist/index.json'))
|
data = json.load(open('coriolis-data/dist/index.json'))
|
||||||
|
|
||||||
|
bulkheads = outfitting.armour_map.values()
|
||||||
|
|
||||||
|
# Modules that have a name as well as a group
|
||||||
|
fixup_map = {}
|
||||||
|
fixup_map.update({ x[0] : ('Scanner', x[0]) for x in outfitting.misc_internal_map.values() })
|
||||||
|
fixup_map.update({ x[0] : ('Countermeasure', x[0]) for x in outfitting.countermeasure_map.values() })
|
||||||
|
fixup_map.update({
|
||||||
|
'Advanced Plasma Accelerator' : ('Plasma Accelerator', 'Advanced Plasma Accelerator'),
|
||||||
|
'Corrosion Resistant Cargo Rack': ('Cargo Rack', 'Corrosion Resistant'),
|
||||||
|
'Cytoscrambler Burst Laser' : ('Burst Laser', 'Cytoscrambler'),
|
||||||
|
'Enforcer Cannon' : ('Multi-cannon', 'Enforcer'),
|
||||||
|
'Enhanced Performance Thrusters': ('Thrusters', 'Enhanced Performance'),
|
||||||
|
'Imperial Hammer Rail Gun' : ('Rail Gun', 'Imperial Hammer'),
|
||||||
|
'Luxury Class Passenger Cabin' : ('Luxury Passenger Cabin', None),
|
||||||
|
'Mining Lance Beam Laser' : ('Mining Laser', 'Mining Lance'),
|
||||||
|
'Multi-Cannon' : ('Multi-cannon', None),
|
||||||
|
'Pacifier Frag-Cannon' : ('Fragment Cannon', 'Pacifier'),
|
||||||
|
'Pack-Hound Missile Rack' : ('Missile Rack', 'Pack-Hound'),
|
||||||
|
'Pulse Disruptor Laser' : ('Pulse Laser', 'Disruptor'),
|
||||||
|
'Retributor Beam Laser' : ('Beam Laser', 'Retributor'),
|
||||||
|
'Rocket Propelled FSD Disruptor': ('Missile Rack', 'Rocket Propelled FSD Disruptor'),
|
||||||
|
'Shock Mine Launcher' : ('Mine Launcher', 'Shock Mine Launcher'),
|
||||||
|
'Standard Docking Computer' : ('Docking Computer', 'Standard Docking Computer'),
|
||||||
|
})
|
||||||
|
specials = { v:k for k,v in fixup_map.items() }
|
||||||
|
|
||||||
# Map Coriolis's names to names displayed in the in-game shipyard
|
# Map Coriolis's names to names displayed in the in-game shipyard
|
||||||
coriolis_ship_map = {
|
coriolis_ship_map = {
|
||||||
'Cobra Mk III' : 'Cobra MkIII',
|
'Cobra Mk III' : 'Cobra MkIII',
|
||||||
@ -326,8 +128,6 @@ if __name__ == "__main__":
|
|||||||
'tp' : 'Torpedo Pylon'
|
'tp' : 'Torpedo Pylon'
|
||||||
};
|
};
|
||||||
|
|
||||||
specials = { v:k for k,v in fixup_map.items() }
|
|
||||||
|
|
||||||
ships = {}
|
ships = {}
|
||||||
modules = {}
|
modules = {}
|
||||||
|
|
||||||
@ -363,5 +163,10 @@ if __name__ == "__main__":
|
|||||||
else:
|
else:
|
||||||
modules[key] = { 'mass': m.get('mass', 0) } # Some modules don't have mass
|
modules[key] = { 'mass': m.get('mass', 0) } # Some modules don't have mass
|
||||||
|
|
||||||
|
# Repair Limpet Controller not yet present in coriolis-data. Same masses as Prospector
|
||||||
|
for k in modules.keys():
|
||||||
|
if k[0] == 'Prospector Limpet Controller':
|
||||||
|
modules[('Repair Limpet Controller',) + k[1:]] = modules[k]
|
||||||
|
|
||||||
modules = OrderedDict([(k,modules[k]) for k in sorted(modules)]) # sort for easier diffing
|
modules = OrderedDict([(k,modules[k]) for k in sorted(modules)]) # sort for easier diffing
|
||||||
cPickle.dump(modules, open('modules.p', 'wb'))
|
cPickle.dump(modules, open('modules.p', 'wb'))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user