Refactoring: migrating to @kayahr/ed-journal.

This commit is contained in:
marley 2023-05-17 20:38:26 -07:00
parent de2819eab3
commit 36e73b89bc
7 changed files with 218 additions and 66 deletions

16
package-lock.json generated
View file

@ -9,6 +9,7 @@
"version": "1.0.0",
"license": "GPL-3.0-only",
"dependencies": {
"@kayahr/ed-journal": "^2.5.0",
"app-root-path": "^3.1.0",
"bootstrap": "^5.3.0-alpha3",
"chokidar": "^3.5.3",
@ -3307,6 +3308,18 @@
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
"dev": true
},
"node_modules/@kayahr/ed-journal": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@kayahr/ed-journal/-/ed-journal-2.5.0.tgz",
"integrity": "sha512-vMNkAU5Sjn0U9BxdCnu63yR8/+Bpxe+BLsRxSCxpiiRL5ngOLawxIZbclLQySxGdjZ2avuHvQ3c6YRE6tPFOYQ==",
"dependencies": {
"chokidar": "^3.5.3",
"tslib": "^2.4.1"
},
"funding": {
"url": "https://github.com/kayahr/ed-journal?sponsor=1"
}
},
"node_modules/@malept/cross-spawn-promise": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz",
@ -10639,8 +10652,7 @@
"node_modules/tslib": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==",
"dev": true
"integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
},
"node_modules/type-detect": {
"version": "4.0.8",

View file

@ -47,6 +47,7 @@
"typescript": "^5.0.4"
},
"dependencies": {
"@kayahr/ed-journal": "^2.5.0",
"app-root-path": "^3.1.0",
"bootstrap": "^5.3.0-alpha3",
"chokidar": "^3.5.3",

View file

@ -1,24 +1,16 @@
import type { SAAScanComplete, Scan } from '@kayahr/ed-journal';
import type { valuableBody } from '../@types/edsmResponses';
import type {
asteroidScan,
autoScan,
detailedScan,
planetScan,
starScan,
} from '../@types/journalLines';
import { BodyCodes } from '../data/BodyCodes';
export interface Body extends starScan<'AutoScan'|'DetailedScan'>,
asteroidScan<'AutoScan'|'DetailedScan'>,
planetScan<'AutoScan'|'DetailedScan'> {}
export interface Body extends Scan {}
export class Body {
DSSDone: boolean;
mappedValue: number;
constructor(
journalLine: autoScan|detailedScan|valuableBody|null = null,
journalLine: Scan|SAAScanComplete|valuableBody|null = null,
DSS: boolean = false,
) {
this.DSSDone = DSS;
@ -67,7 +59,15 @@ export class Body {
/* ---------------------------------------------------------------------------- simpleName ---- */
simpleName(): string {
return this.BodyName.replace(this.StarSystem, '');
let name: string;
if (typeof this.StarSystem === 'string') {
name = this.BodyName.replace(this.StarSystem, '');
} else {
name = this.BodyName;
}
return name;
}
/* ------------------------------------------------------------------------------ typeIcon ---- */
@ -78,19 +78,19 @@ export class Body {
if (this.isStar() || this.isAsteroid()) {
typeIcon = this.nameIcon();
} else {
const planetClass: string = this.PlanetClass.toLowerCase();
const planetClass: string|undefined = this.PlanetClass?.toLowerCase();
if (planetClass.includes('metal')) {
if (planetClass?.includes('metal')) {
typeIcon = 'ingot';
} else if (planetClass.includes('icy')) {
} else if (planetClass?.includes('icy')) {
typeIcon = 'snowflake';
} else if (planetClass.includes('earth')) {
} else if (planetClass?.includes('earth')) {
typeIcon = 'earth';
} else if (planetClass.includes('gas giant')) {
} else if (planetClass?.includes('gas giant')) {
typeIcon = 'jupiter-1';
} else if (planetClass.includes('rock')) {
} else if (planetClass?.includes('rock')) {
typeIcon = 'asteroid-3';
} else if (planetClass.includes('water') || planetClass.includes('ammonia')) {
} else if (planetClass?.includes('water') || planetClass?.includes('ammonia')) {
typeIcon = 'water-drops';
}
}
@ -105,7 +105,7 @@ export class Body {
#getValue(): number {
const bodyType = this.#getNumericalBodyType();
const mass = 'MassEM' in this ? this.MassEM : 1;
const mass = this.MassEM !== undefined ? this.MassEM : 1;
let terraformState = this.#getNumericalTerraformState();

View file

@ -1,16 +1,24 @@
import type { Tail as TailType } from 'tail';
import type { autoScan, completeFsdJump, detailedScan, journalEntry, navRoute, planetScan } from "../@types/journalLines";
import type {
autoScan,
completeFsdJump,
detailedScan,
journalEntry,
navRoute,
planetScan,
} from '../@types/journalLines';
const EventEmitter = require('node:events');
import * as _ from 'lodash-es';
const path = require('node:path');
const { readFile } = require('node:fs/promises');
const reverseLineReader = require('reverse-line-reader');
const Tail = require('tail').Tail;
import { System } from "./System";
import { Log } from "./Log";
import { Body } from "./Body";
import { System } from './System';
import { Log } from './Log';
import { Body } from './Body';
export class Journal extends EventEmitter {
@ -97,7 +105,7 @@ export class Journal extends EventEmitter {
// Look for all scanned bodies before last FSDJump, for same reasons as getting location.
#getScannedBodies(): void {
let dssLine: detailedScan|null = null
let dssLine: detailedScan|null = null;
reverseLineReader.eachLine(this.#path, (raw: string) => {
if (raw) {
@ -168,13 +176,13 @@ export class Journal extends EventEmitter {
Log.write('Checking for nav route.');
this.#getNavRoute();
})
});
}
/* ------------------------------------------------------------------------ #getNavRoute ---- */
async #getNavRoute(): Promise<void> {
this.navRoute = [] // Clear previous route, to catch overwritten routes.
this.navRoute = []; // Clear previous route, to catch overwritten routes.
let routeFile: string|null = null;
try {
@ -199,7 +207,7 @@ export class Journal extends EventEmitter {
if (push && system.SystemAddress !== this.location.SystemAddress) {
this.navRoute.push(new System(system));
}
})
});
if (this.navRoute.length > 0) {
Log.write('Nav route set.');
@ -286,7 +294,7 @@ export class Journal extends EventEmitter {
if (this.navRoute.length > 0) {
_.remove(this.navRoute, (system) => {
return system.SystemAddress === this.location.SystemAddress;
})
});
}
this.emit('ENTERED_NEW_SYSTEM');

132
src/models/NewJournal.ts Normal file
View file

@ -0,0 +1,132 @@
import type { JournalEvent, Scan } from '@kayahr/ed-journal';
import { Journal as EDJournal } from '@kayahr/ed-journal';
import { Body } from './Body';
import { Log } from './Log';
import { System } from './System';
import * as _ from 'lodash-es';
const EventEmitter = require('events');
const reverseLineReader = require('reverse-line-reader');
export class Journal extends EventEmitter {
readonly #path: string;
location: System;
navRoute: System[];
#journal?: EDJournal;
constructor(journalPath: string) {
super();
this.#path = journalPath;
this.location = new System();
this.navRoute = [];
this.#init();
}
/* --------------------------------------------------------------------------------- #init ---- */
#init(): void {
Log.write(`Journal initialized. Attempting to find current location.`);
this.#getLastLocation().then(() => {
if (this.location.name !== 'Unknown') {
Log.write('Attempting to find scanned bodies in current system.');
this.#getScannedBodies().then(async () => {
if (this.location.bodies.length > 0) {
Log.write('Scanned bodies found.');
this.emit('BUILD_BODY_LIST');
} else {
Log.write('No scanned bodies found in current system.');
}
this.#journal = await EDJournal.open({ watch: true, position: 'end' });
Log.write('Checking for nav route.');
await this.#getNavRoute();
});
}
});
}
/* ---------------------------------------------------------------------- #getLastLocation ---- */
#getLastLocation(): any {
return reverseLineReader.eachLine(this.#path, (raw: string, last: boolean) => {
if (raw) {
const line = JSON.parse(raw);
if (line.event === 'FSDJump' || line.event === 'Location') {
this.location = new System(line);
Log.write(`Current location set to ${this.location.name}.`);
this.emit('ENTERED_NEW_SYSTEM');
return false;
} else if (last) {
Log.write('WARNING: Unable to find last known location.');
return false;
}
}
});
}
/* --------------------------------------------------------------------- #getScannedBodies ---- */
#getScannedBodies(): any {
let dssLine: Scan|null = null;
return reverseLineReader.eachLine(this.#path, (raw: string) => {
if (raw) {
const line: JournalEvent = JSON.parse(raw);
if (dssLine) {
if (line.event === 'SAAScanComplete') {
this.location.bodies.push(new Body(dssLine, true));
} else {
const dupChecker = { 'BodyName': dssLine.BodyName, 'BodyID': dssLine.BodyID };
const duplicate = _.find(this.location.bodies, dupChecker);
if (duplicate === undefined) {
this.location.bodies.push(new Body(dssLine));
}
}
dssLine = null;
}
if (line.event === 'Scan' && 'ScanType' in line) {
if (line.ScanType === 'Detailed' && !('StarType' in line)) {
dssLine = line as Scan;
} else if ('StarType' in line) {
this.location.bodies.push(new Body(line as Scan));
} else if (line.ScanType == 'AutoScan') {
if ('PlanetClass' in line) {
const dupChecker = {
'BodyName': (line as Scan).BodyName,
'BodyID': (line as Scan).BodyID,
};
const duplicate = _.find(this.location.bodies, dupChecker);
if (duplicate === undefined) {
this.location.bodies.push(new Body(line as Scan));
}
} else { // Asteroid.
this.location.bodies.push(new Body(line as Scan));
}
}
} else if (line.event === 'FSDJump' || line.event === 'Location') {
return false;
}
}
});
}
/* -------------------------------------------------------------------------- #getNavRoute ---- */
async #getNavRoute(): Promise<void> {
this.navRoute = [];
}
}

0
src/models/NewSafari.ts Normal file
View file

View file

@ -1,13 +1,12 @@
const chokidar = require('chokidar');
const fs = require('node:fs');
const { globSync } = require('glob');
import * as _ from 'lodash-es';
const os = require('node:os');
const path = require('node:path');
import { Journal } from './Journal';
import { Log } from './Log';
import * as _ from 'lodash-es';
export class Safari {
static #instance: Safari;
@ -18,13 +17,10 @@ export class Safari {
#watcher?: any;
private constructor(isPackaged: boolean, isTesting: boolean = false) {
if (isTesting) {
private constructor(isPackaged: boolean = false) {
if (!isPackaged && os.platform() === 'linux') {
this.#journalDir = require('app-root-path').resolve('/test_journals');
} else if (!isPackaged && os.platform() === 'linux') { // Account for WSL during development
this.#journalDir = '/mnt/c/Users/marle/Saved\ Games/Frontier\ Developments/Elite\ Dangerous/';
} else if (os.platform() === 'win32') { // Windows
this.#journalDir = path.join(
os.homedir(),
@ -59,9 +55,9 @@ export class Safari {
}
}
static start(isPackaged: boolean, isTesting: boolean = false): Safari {
static start(isPackaged: boolean = false): Safari {
if (!Safari.#instance) {
Safari.#instance = new Safari(isPackaged, isTesting);
Safari.#instance = new Safari(isPackaged);
}
return Safari.#instance;
@ -72,7 +68,10 @@ export class Safari {
// https://stackoverflow.com/questions/15696218/get-the-most-recent-file-in-a-directory-node-js
#getLatestJournal(): Journal|undefined {
// @ts-ignore
const journals = globSync(this.#journalPattern, {windowsPathsNoEscape: true});
const journals = globSync(
this.#journalPattern,
{ windowsPathsNoEscape: true },
);
const journalPath: string|undefined = _.maxBy(journals, file => fs.statSync(file).mtime);
if (journalPath) {