mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-08 22:33:24 +00:00
Various fixes; allow direct import from URL
This commit is contained in:
@@ -16,4 +16,5 @@
|
||||
* Enable boost display even if power distributor is disabled
|
||||
* Calculate breakdown of ship offensive and defensive stats
|
||||
* Add 'Offence summary' and 'Defence summary' components
|
||||
* Add ability to import directly from companion API output
|
||||
* Add ability to import from companion API output through import feature
|
||||
* Add ability to import from companion API output through URL
|
||||
|
||||
@@ -7,6 +7,8 @@ import Persist from './stores/Persist';
|
||||
import Header from './components/Header';
|
||||
import Tooltip from './components/Tooltip';
|
||||
import ModalImport from './components/ModalImport';
|
||||
import * as CompanionApiUtils from './utils/CompanionApiUtils';
|
||||
import * as Utils from './utils/UtilityFunctions';
|
||||
|
||||
import AboutPage from './pages/AboutPage';
|
||||
import NotFoundPage from './pages/NotFoundPage';
|
||||
@@ -15,6 +17,8 @@ import ComparisonPage from './pages/ComparisonPage';
|
||||
import ShipyardPage from './pages/ShipyardPage';
|
||||
import ErrorDetails from './pages/ErrorDetails';
|
||||
|
||||
const zlib = require('zlib');
|
||||
|
||||
/**
|
||||
* Coriolis App
|
||||
*/
|
||||
@@ -52,6 +56,7 @@ export default class Coriolis extends React.Component {
|
||||
this._onLanguageChange = this._onLanguageChange.bind(this);
|
||||
this._onSizeRatioChange = this._onSizeRatioChange.bind(this);
|
||||
this._keyDown = this._keyDown.bind(this);
|
||||
this._importBuild = this._importBuild.bind(this);
|
||||
|
||||
this.emitter = new EventEmitter();
|
||||
this.state = {
|
||||
@@ -63,6 +68,7 @@ export default class Coriolis extends React.Component {
|
||||
};
|
||||
|
||||
Router('', (r) => this._setPage(ShipyardPage, r));
|
||||
Router('/import/:data', (r) => this._importBuild(r));
|
||||
Router('/outfit/:ship/:code?', (r) => this._setPage(OutfittingPage, r));
|
||||
Router('/compare/:name?', (r) => this._setPage(ComparisonPage, r));
|
||||
Router('/comparison/:code', (r) => this._setPage(ComparisonPage, r));
|
||||
@@ -70,6 +76,23 @@ export default class Coriolis extends React.Component {
|
||||
Router('*', (r) => this._setPage(null, r));
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a build directly
|
||||
*/
|
||||
_importBuild(r) {
|
||||
try {
|
||||
// Need to decode and gunzip the data
|
||||
const data = zlib.gunzipSync(new Buffer(Utils.fromUrlSafe(r.params.data), 'base64'))
|
||||
const json = JSON.parse(data);
|
||||
const ship = CompanionApiUtils.shipFromJson(json);
|
||||
r.params.ship = ship.id;
|
||||
r.params.code = ship.toString();
|
||||
this._setPage(OutfittingPage, r);
|
||||
} catch (err) {
|
||||
this.setState({ error: err });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates / Sets the page and route context
|
||||
* @param {[type]} page The page to be shown
|
||||
|
||||
@@ -64,7 +64,7 @@ export default class HardpointSlot extends Slot {
|
||||
{ m.getHps() ? <div className={'l'} onMouseOver={termtip.bind(null, m.getClip() ? 'hpsshps' : 'hps')} onMouseOut={tooltip.bind(null, null)}>{translate('HPS')}: {formats.round1(m.getHps())} { m.getClip() ? <span>({formats.round1((m.getClip() * m.getHps() / m.getRoF()) / ((m.getClip() / m.getRoF()) + m.getReload())) })</span> : null }</div> : null }
|
||||
{ m.getDps() && m.getEps() ? <div className={'l'} onMouseOver={termtip.bind(null, 'dpe')} onMouseOut={tooltip.bind(null, null)}>{translate('DPE')}: {formats.f1(m.getDps() / m.getEps())}</div> : null }
|
||||
{ m.getRoF() ? <div className={'l'} onMouseOver={termtip.bind(null, 'rof')} onMouseOut={tooltip.bind(null, null)}>{translate('ROF')}: {formats.f1(m.getRoF())}{u.ps}</div> : null }
|
||||
{ m.getRange() && !m.getDps() ? <div className={'l'}>{translate('Range')} : {formats.round(m.getRange() / 1000)}{u.km}</div> : null }
|
||||
{ m.getRange() ? <div className={'l'}>{translate('range')} {formats.f1(m.getRange() / 1000)}{u.km}</div> : null }
|
||||
{ m.getShieldBoost() ? <div className={'l'}>+{formats.pct1(m.getShieldBoost())}</div> : null }
|
||||
{ m.getAmmo() ? <div className={'l'}>{translate('ammunition')}: {formats.int(m.getClip())}/{formats.int(m.getAmmo())}</div> : null }
|
||||
{ showModuleResistances && m.getExplosiveResistance() ? <div className='l'>{translate('explres')}: {formats.pct(m.getExplosiveResistance())}</div> : null }
|
||||
|
||||
@@ -40,7 +40,7 @@ export default class InternalSlot extends Slot {
|
||||
{ m.rate ? <div className={'l'}>{translate('rate')}: {m.rate}{u.kgs} {translate('refuel time')}: {formats.time(this.props.fuel * 1000 / m.rate)}</div> : null }
|
||||
{ m.getAmmo() ? <div className={'l'}>{translate('ammunition')}: {formats.gen(m.getAmmo())}</div> : null }
|
||||
{ m.cells ? <div className={'l'}>{translate('cells')}: {m.cells}</div> : null }
|
||||
{ m.recharge ? <div className={'l'}>{translate('recharge')}: {m.recharge} <u>MJ</u> {translate('total')}: {m.cells * m.recharge}{u.MJ}</div> : null }
|
||||
{ m.shieldreinforcement ? <div className={'l'}>{translate('shieldreinforcement')}: {formats.int(m.getShieldReinforcement())} <u>MJ</u> {translate('total')}: {formats.int(m.cells * m.getShieldReinforcement())}{u.MJ}</div> : null }
|
||||
{ m.repair ? <div className={'l'}>{translate('repair')}: {m.repair}</div> : null }
|
||||
{ m.getFacingLimit() ? <div className={'l'}>{translate('facinglimit')} {formats.f1(m.getFacingLimit())}°</div> : null }
|
||||
{ m.getRange() ? <div className={'l'}>{translate('range')} {formats.f2(m.getRange())}{u.km}</div> : null }
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ModuleGroupToName, MountMap, BulkheadNames } from './Constants';
|
||||
import { Ships } from 'coriolis-data/dist';
|
||||
import Ship from './Ship';
|
||||
import * as ModuleUtils from './ModuleUtils';
|
||||
import * as Utils from '../utils/UtilityFunctions';
|
||||
import LZString from 'lz-string';
|
||||
|
||||
const STANDARD = ['powerPlant', 'thrusters', 'frameShiftDrive', 'lifeSupport', 'powerDistributor', 'sensors', 'fuelTank'];
|
||||
@@ -209,13 +210,13 @@ export function toDetailedExport(builds) {
|
||||
* @return {string} Zipped Base 64 encoded JSON
|
||||
*/
|
||||
export function fromComparison(name, builds, facets, predicate, desc) {
|
||||
return LZString.compressToBase64(JSON.stringify({
|
||||
return Utils.toUrlSafe(LZString.compressToBase64(JSON.stringify({
|
||||
n: name,
|
||||
b: builds.map((b) => { return { s: b.id, n: b.buildName, c: b.toString() }; }),
|
||||
f: facets,
|
||||
p: predicate,
|
||||
d: desc ? 1 : 0
|
||||
})).replace(/\//g, '-');
|
||||
})));
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -224,5 +225,5 @@ export function fromComparison(name, builds, facets, predicate, desc) {
|
||||
* @return {Object} Comparison data object
|
||||
*/
|
||||
export function toComparison(code) {
|
||||
return JSON.parse(LZString.decompressFromBase64(code.replace(/-/g, '/')));
|
||||
return JSON.parse(LZString.decompressFromBase64(Utils.fromUrlSafe(code)));
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as Calc from './Calculations';
|
||||
import * as ModuleUtils from './ModuleUtils';
|
||||
import * as Utils from '../utils/UtilityFunctions';
|
||||
import Module from './Module';
|
||||
import LZString from 'lz-string';
|
||||
import isEqual from 'lodash/lang';
|
||||
@@ -601,15 +602,15 @@ export default class Ship {
|
||||
code = parts[0];
|
||||
|
||||
if (parts[1]) {
|
||||
enabled = LZString.decompressFromBase64(parts[1].replace(/-/g, '/')).split('');
|
||||
enabled = Utils.fromUrlSafe(LZString.decompressFromBase64(parts[1])).split('');
|
||||
}
|
||||
|
||||
if (parts[2]) {
|
||||
priorities = LZString.decompressFromBase64(parts[2].replace(/-/g, '/')).split('');
|
||||
priorities = Utils.fromUrlSafe(LZString.decompressFromBase64(parts[2])).split('');
|
||||
}
|
||||
|
||||
if (parts[3]) {
|
||||
const modstr = parts[3].replace(/-/g, '/');
|
||||
const modstr = Utils.fromUrlSafe(parts[3]);
|
||||
if (modstr.match(':')) {
|
||||
this.decodeModificationsString(modstr, modifications);
|
||||
} else {
|
||||
@@ -1198,7 +1199,7 @@ export default class Ship {
|
||||
priorities.push(slot.priority);
|
||||
}
|
||||
|
||||
this.serialized.priorities = LZString.compressToBase64(priorities.join('')).replace(/\//g, '-');
|
||||
this.serialized.priorities = Utils.toUrlSafe(LZString.compressToBase64(priorities.join('')));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1219,7 +1220,7 @@ export default class Ship {
|
||||
enabled.push(slot.enabled ? 1 : 0);
|
||||
}
|
||||
|
||||
this.serialized.enabled = LZString.compressToBase64(enabled.join('')).replace(/\//g, '-');
|
||||
this.serialized.enabled = Utils.toUrlSafe(LZString.compressToBase64(enabled.join('')));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1265,7 +1266,7 @@ export default class Ship {
|
||||
}
|
||||
allMods.push(slotMods.join(';'));
|
||||
}
|
||||
this.serialized.modifications = LZString.compressToBase64(allMods.join(',').replace(/,+$/, '')).replace(/\//g, '-');
|
||||
this.serialized.modifications = Utils.toUrlSafe(LZString.compressToBase64(allMods.join(',').replace(/,+$/, '')));
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1386,7 +1387,7 @@ export default class Ship {
|
||||
buffer.writeInt8(-1, curpos++);
|
||||
}
|
||||
|
||||
this.serialized.modifications = zlib.gzipSync(buffer).toString('base64').replace(/\//g, '-');
|
||||
this.serialized.modifications = Utils.toUrlSafe(zlib.gzipSync(buffer).toString('base64'));
|
||||
} else {
|
||||
this.serialized.modifications = null;
|
||||
}
|
||||
|
||||
@@ -151,6 +151,7 @@ export function shipFromJson(json) {
|
||||
throw 'Unknown bulkheads "' + armourJson.name + '"';
|
||||
}
|
||||
ship.bulkheads.enabled = true;
|
||||
if (armourJson.modifiers) _addModifications(ship.bulkheads.m, armourJson.modifiers);
|
||||
|
||||
// Add the standard modules
|
||||
// Power plant
|
||||
@@ -159,7 +160,7 @@ export function shipFromJson(json) {
|
||||
if (powerplantJson.modifiers) _addModifications(powerplant, powerplantJson.modifiers);
|
||||
ship.use(ship.standard[0], powerplant, true);
|
||||
ship.standard[0].enabled = powerplantJson.on === true;
|
||||
ship.standard[0].priority = powerplantJson.priority + 1;
|
||||
ship.standard[0].priority = powerplantJson.priority;
|
||||
|
||||
// Thrusters
|
||||
const thrustersJson = json.modules.MainEngines.module;
|
||||
@@ -167,7 +168,7 @@ export function shipFromJson(json) {
|
||||
if (thrustersJson.modifiers) _addModifications(thrusters, thrustersJson.modifiers);
|
||||
ship.use(ship.standard[1], thrusters, true);
|
||||
ship.standard[1].enabled = thrustersJson.on === true;
|
||||
ship.standard[1].priority = thrustersJson.priority + 1;
|
||||
ship.standard[1].priority = thrustersJson.priority;
|
||||
|
||||
// FSD
|
||||
const frameshiftdriveJson = json.modules.FrameShiftDrive.module;
|
||||
@@ -175,7 +176,7 @@ export function shipFromJson(json) {
|
||||
if (frameshiftdriveJson.modifiers) _addModifications(frameshiftdrive, frameshiftdriveJson.modifiers);
|
||||
ship.use(ship.standard[2], frameshiftdrive, true);
|
||||
ship.standard[2].enabled = frameshiftdriveJson.on === true;
|
||||
ship.standard[2].priority = frameshiftdriveJson.priority + 1;
|
||||
ship.standard[2].priority = frameshiftdriveJson.priority;
|
||||
|
||||
// Life support
|
||||
const lifesupportJson = json.modules.LifeSupport.module;
|
||||
@@ -183,7 +184,7 @@ export function shipFromJson(json) {
|
||||
if (lifesupportJson.modifiers)_addModifications(lifesupport, lifesupportJson.modifiers);
|
||||
ship.use(ship.standard[3], lifesupport, true);
|
||||
ship.standard[3].enabled = lifesupportJson.on === true;
|
||||
ship.standard[3].priority = lifesupportJson.priority + 1;
|
||||
ship.standard[3].priority = lifesupportJson.priority;
|
||||
|
||||
// Power distributor
|
||||
const powerdistributorJson = json.modules.PowerDistributor.module;
|
||||
@@ -191,7 +192,7 @@ export function shipFromJson(json) {
|
||||
if (powerdistributorJson.modifiers) _addModifications(powerdistributor, powerdistributorJson.modifiers);
|
||||
ship.use(ship.standard[4], powerdistributor, true);
|
||||
ship.standard[4].enabled = powerdistributorJson.on === true;
|
||||
ship.standard[4].priority = powerdistributorJson.priority + 1;
|
||||
ship.standard[4].priority = powerdistributorJson.priority;
|
||||
|
||||
// Sensors
|
||||
const sensorsJson = json.modules.Radar.module;
|
||||
@@ -199,14 +200,14 @@ export function shipFromJson(json) {
|
||||
if (sensorsJson.modifiers) _addModifications(sensors, sensorsJson.modifiers);
|
||||
ship.use(ship.standard[5], sensors, true);
|
||||
ship.standard[5].enabled = sensorsJson.on === true;
|
||||
ship.standard[5].priority = sensorsJson.priority + 1;
|
||||
ship.standard[5].priority = sensorsJson.priority;
|
||||
|
||||
// Fuel tank
|
||||
const fueltankJson = json.modules.FuelTank.module;
|
||||
const fueltank = _moduleFromEdId(fueltankJson.id);
|
||||
ship.use(ship.standard[6], fueltank, true);
|
||||
ship.standard[6].enabled = true;
|
||||
ship.standard[6].priority = 1;
|
||||
ship.standard[6].priority = 0;
|
||||
|
||||
// Add hardpoints
|
||||
let hardpointClassNum = -1;
|
||||
@@ -285,11 +286,11 @@ function _addModifications(module, modifiers) {
|
||||
// Carry out the required changes
|
||||
for (const action in modifierActions) {
|
||||
const actionValue = modifierActions[action] * value;
|
||||
let mod = module.getModValue(action);
|
||||
let mod = module.getModValue(action) / 10000;
|
||||
if (!mod) {
|
||||
mod = 0;
|
||||
}
|
||||
module.setModValue(action, ((1 + mod / 10000) * (1 + actionValue) - 1) * 10000);
|
||||
module.setModValue(action, ((1 + mod) * (1 + actionValue) - 1) * 10000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,20 +300,20 @@ function _addModifications(module, modifiers) {
|
||||
// being a 4% boost they are a 104% multiplier. Unfortunately this means that our % modification
|
||||
// is incorrect so we fix it
|
||||
if (module.grp === 'sb' && module.getModValue('shieldboost')) {
|
||||
const alteredBoost = (1 + module.shieldboost) * (module.getModValue('shieldboost'));
|
||||
module.setModValue('shieldboost', alteredBoost / module.shieldboost);
|
||||
const alteredBoost = (1 + module.shieldboost) * (module.getModValue('shieldboost') / 10000);
|
||||
module.setModValue('shieldboost', alteredBoost * 10000 / module.shieldboost);
|
||||
}
|
||||
|
||||
// Shield booster resistance is actually a damage modifier, so needs to be inverted.
|
||||
if (module.grp === 'sb') {
|
||||
if (module.getModValue('explres')) {
|
||||
module.setModValue('explres', module.getModValue('explres') * -1);
|
||||
module.setModValue('explres', ((module.getModValue('explres') / 10000) * -1) * 10000);
|
||||
}
|
||||
if (module.getModValue('kinres')) {
|
||||
module.setModValue('kinres', module.getModValue('kinres') * -1);
|
||||
module.setModValue('kinres', ((module.getModValue('kinres') / 10000) * -1) * 10000);
|
||||
}
|
||||
if (module.getModValue('thermres')) {
|
||||
module.setModValue('thermres', module.getModValue('thermres') * -1);
|
||||
module.setModValue('thermres', ((module.getModValue('thermres') / 10000) * -1) * 10000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,17 +321,43 @@ function _addModifications(module, modifiers) {
|
||||
// In addition, the modification is based off the inherent resistance of the module
|
||||
if (module.isShieldGenerator()) {
|
||||
if (module.getModValue('explres')) {
|
||||
module.setModValue('explres', (1 - (1 - module.explres) * (1 + module.getModValue('explres'))) - module.explres);
|
||||
module.setModValue('explres', ((1 - (1 - module.explres) * (1 + module.getModValue('explres') / 10000)) - module.explres) * 10000);
|
||||
}
|
||||
if (module.getModValue('kinres')) {
|
||||
module.setModValue('kinres', (1 - (1 - module.kinres) * (1 + module.getModValue('kinres')))- module.kinres);
|
||||
module.setModValue('kinres', ((1 - (1 - module.kinres) * (1 + module.getModValue('kinres') / 10000)) - module.kinres) * 10000);
|
||||
}
|
||||
if (module.getModValue('thermres')) {
|
||||
module.setModValue('thermres', (1 - (1 - module.thermres) * (1 + module.getModValue('thermres'))) - module.thermres);
|
||||
module.setModValue('thermres', ((1 - (1 - module.thermres) * (1 + module.getModValue('thermres') / 10000)) - module.thermres) * 10000);
|
||||
}
|
||||
}
|
||||
|
||||
// Hull reinforcement package resistance is actually a damage modifier, so needs to be inverted.
|
||||
if (module.grp === 'hr') {
|
||||
if (module.getModValue('explres')) {
|
||||
module.setModValue('explres', ((module.getModValue('explres') / 10000) * -1) * 10000);
|
||||
}
|
||||
if (module.getModValue('kinres')) {
|
||||
module.setModValue('kinres', ((module.getModValue('kinres') / 10000) * -1) * 10000);
|
||||
}
|
||||
if (module.getModValue('thermres')) {
|
||||
module.setModValue('thermres', ((module.getModValue('thermres') / 10000) * -1) * 10000);
|
||||
}
|
||||
}
|
||||
|
||||
// Bulkhead resistance is actually a damage modifier, so needs to be inverted.
|
||||
// In addition, the modification is based off the inherent resistance of the module
|
||||
if (module.grp == 'bh') {
|
||||
if (module.getModValue('explres')) {
|
||||
module.setModValue('explres', ((1 - (1 - module.explres) * (1 + module.getModValue('explres') / 10000)) - module.explres) * 10000);
|
||||
}
|
||||
if (module.getModValue('kinres')) {
|
||||
module.setModValue('kinres', ((1 - (1 - module.kinres) * (1 + module.getModValue('kinres') / 10000)) - module.kinres) * 10000);
|
||||
}
|
||||
if (module.getModValue('thermres')) {
|
||||
module.setModValue('thermres', ((1 - (1 - module.thermres) * (1 + module.getModValue('thermres') / 10000)) - module.thermres) * 10000);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO do this for armour resistances as well ?
|
||||
|
||||
// Jitter is in degrees not % so need to divide it by 100 to obtain the correct number
|
||||
if (module.getModValue('jitter')) {
|
||||
@@ -339,7 +366,6 @@ function _addModifications(module, modifiers) {
|
||||
|
||||
// FD uses interval between bursts internally, so we need to translate this to a real rate of fire
|
||||
if (module.getModValue('rof')) {
|
||||
module.setModValue('rof', (1 / (1 + module.getModValue('jitter'))) - 1);
|
||||
module.setModValue('rof', ((1 / (1 + module.getModValue('rof') / 10000)) - 1) * 10000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,3 +58,21 @@ export function shallowEqual(objA, objB) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn a base-64 encoded string in to a URL-safe version
|
||||
* @param {string} data the string
|
||||
* @return {string} the converted string
|
||||
*/
|
||||
export function toUrlSafe(data) {
|
||||
return data.replace(/\\/g, '-').replace(/\+/g, '_');
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn a URL-safe base-64 encoded string in to a normal version
|
||||
* @param {string} data the string
|
||||
* @return {string} the converted string
|
||||
*/
|
||||
export function fromUrlSafe(data) {
|
||||
return data.replace(/-/g, '/').replace(/_/g, '+');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user