Custom colors!
This commit is contained in:
parent
ce573865f6
commit
68bda87253
9 changed files with 269 additions and 136 deletions
36
package-lock.json
generated
36
package-lock.json
generated
|
@ -14,9 +14,11 @@
|
||||||
"electron-squirrel-startup": "^1.0.0",
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
"elite-matrix": "^1.0.0",
|
"elite-matrix": "^1.0.0",
|
||||||
"glob": "^10.2.2",
|
"glob": "^10.2.2",
|
||||||
|
"ini": "^4.1.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"reverse-line-reader": "^0.2.6",
|
"reverse-line-reader": "^0.2.6",
|
||||||
"tail": "^2.2.6"
|
"tail": "^2.2.6",
|
||||||
|
"xml-js": "^1.6.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@electron-forge/cli": "^6.1.1",
|
"@electron-forge/cli": "^6.1.1",
|
||||||
|
@ -3796,6 +3798,12 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/global-prefix/node_modules/ini": {
|
||||||
|
"version": "1.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||||
|
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/global-prefix/node_modules/which": {
|
"node_modules/global-prefix/node_modules/which": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||||
|
@ -4075,10 +4083,12 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/ini": {
|
"node_modules/ini": {
|
||||||
"version": "1.3.8",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/ini/-/ini-4.1.0.tgz",
|
||||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
"integrity": "sha512-HLR38RSF2iulAzc3I/sma4CoYxQP844rPYCNfzGDOHqa/YqVlwuuZgBx6M50/X8dKgzk0cm1qRg3+47mK2N+cQ==",
|
||||||
"dev": true
|
"engines": {
|
||||||
|
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/interpret": {
|
"node_modules/interpret": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
|
@ -5982,6 +5992,11 @@
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sax": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||||
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.5.0",
|
"version": "7.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
|
||||||
|
@ -6951,6 +6966,17 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/xml-js": {
|
||||||
|
"version": "1.6.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz",
|
||||||
|
"integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==",
|
||||||
|
"dependencies": {
|
||||||
|
"sax": "^1.2.4"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"xml-js": "bin/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/xmlbuilder": {
|
"node_modules/xmlbuilder": {
|
||||||
"version": "15.1.1",
|
"version": "15.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
|
||||||
|
|
|
@ -45,8 +45,10 @@
|
||||||
"electron-squirrel-startup": "^1.0.0",
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
"elite-matrix": "^1.0.0",
|
"elite-matrix": "^1.0.0",
|
||||||
"glob": "^10.2.2",
|
"glob": "^10.2.2",
|
||||||
|
"ini": "^4.1.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"reverse-line-reader": "^0.2.6",
|
"reverse-line-reader": "^0.2.6",
|
||||||
"tail": "^2.2.6"
|
"tail": "^2.2.6",
|
||||||
|
"xml-js": "^1.6.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,9 +45,9 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row ms-1 me-1">
|
<div class="row ms-1 me-1">
|
||||||
<div class="col col-form-label system charted">
|
<label class="col col-form-label system charted">
|
||||||
Where to get RGB matrix:
|
Where to get RGB matrix:
|
||||||
</div>
|
</label>
|
||||||
<div class="col-2 system charted p-0 text-center">
|
<div class="col-2 system charted p-0 text-center">
|
||||||
<button type="button" class="btn" id="matrixBtn">Select File</button>
|
<button type="button" class="btn" id="matrixBtn">Select File</button>
|
||||||
<input type="hidden" id="matrixFile" name="matrixFile">
|
<input type="hidden" id="matrixFile" name="matrixFile">
|
||||||
|
|
|
@ -98,7 +98,7 @@ div.charted b.inactive {
|
||||||
}
|
}
|
||||||
|
|
||||||
.highlighted {
|
.highlighted {
|
||||||
color: var(--secondary-dark);
|
color: var(--background);
|
||||||
background: var(--main);
|
background: var(--main);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
import type { Tail as TailType } from 'tail'
|
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')
|
const EventEmitter = require('node:events');
|
||||||
import * as _ from 'lodash-es'
|
import * as _ from 'lodash-es';
|
||||||
const path = require('node:path')
|
const path = require('node:path');
|
||||||
const { readFile } = require('node:fs/promises')
|
const { readFile } = require('node:fs/promises');
|
||||||
const reverseLineReader = require('reverse-line-reader')
|
const reverseLineReader = require('reverse-line-reader');
|
||||||
const Tail = require('tail').Tail
|
const Tail = require('tail').Tail;
|
||||||
|
|
||||||
import { System } from "./System"
|
import { System } from "./System";
|
||||||
import { Log } from "./Log"
|
import { Log } from "./Log";
|
||||||
import { Body } from "./Body"
|
import { Body } from "./Body";
|
||||||
|
|
||||||
|
|
||||||
export class Journal extends EventEmitter {
|
export class Journal extends EventEmitter {
|
||||||
#path: string
|
#path: string;
|
||||||
testing: string
|
testing: string;
|
||||||
location: System
|
location: System;
|
||||||
navRoute: System[]
|
navRoute: System[];
|
||||||
|
|
||||||
constructor(journalPath: string) {
|
constructor(journalPath: string) {
|
||||||
super()
|
super();
|
||||||
|
|
||||||
this.#path = journalPath
|
this.#path = journalPath;
|
||||||
this.location = new System()
|
this.location = new System();
|
||||||
this.navRoute = []
|
this.navRoute = [];
|
||||||
|
|
||||||
// Start ReverseLineReader chain here.
|
// Start ReverseLineReader chain here.
|
||||||
Log.write(`Journal initialized. Attempting to find current location.`)
|
Log.write(`Journal initialized. Attempting to find current location.`);
|
||||||
this.#getLastFsdJump()
|
this.#getLastFsdJump();
|
||||||
// -> IF no FSD Jump: this.#getLastLocation()
|
// -> IF no FSD Jump: this.#getLastLocation()
|
||||||
// --> this.#getScannedBodies()
|
// --> this.#getScannedBodies()
|
||||||
|
|
||||||
this.testing = this.#path
|
this.testing = this.#path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- #getLastFsdJump ---- */
|
/* --------------------------------------------------------------------- #getLastFsdJump ---- */
|
||||||
|
@ -42,22 +42,23 @@ export class Journal extends EventEmitter {
|
||||||
#getLastFsdJump(): void {
|
#getLastFsdJump(): void {
|
||||||
reverseLineReader.eachLine(this.#path, (raw: string) => {
|
reverseLineReader.eachLine(this.#path, (raw: string) => {
|
||||||
if (raw) { //skip blank line at end of file
|
if (raw) { //skip blank line at end of file
|
||||||
const line: journalEntry = JSON.parse(raw)
|
const line: journalEntry = JSON.parse(raw);
|
||||||
|
|
||||||
if (line.event === 'FSDJump') {
|
if (line.event === 'FSDJump') {
|
||||||
this.location = new System((line as completeFsdJump))
|
this.location = new System((line as completeFsdJump));
|
||||||
Log.write(`Current location set to ${this.location.name}.`)
|
Log.write(`Current location set to ${this.location.name}.`);
|
||||||
this.emit('ENTERED_NEW_SYSTEM')
|
this.emit('ENTERED_NEW_SYSTEM');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if (this.location.name === 'Unknown') {
|
if (this.location.name === 'Unknown') {
|
||||||
Log.write('Unable to find last hyperspace jump. Searching for last known location.')
|
Log
|
||||||
this.#getLastLocation()
|
.write('Unable to find last hyperspace jump. Searching for last known location.');
|
||||||
|
this.#getLastLocation();
|
||||||
} else {
|
} else {
|
||||||
Log.write('Attempting to find scanned bodies in current system.')
|
Log.write('Attempting to find scanned bodies in current system.');
|
||||||
this.#getScannedBodies()
|
this.#getScannedBodies();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -69,27 +70,27 @@ export class Journal extends EventEmitter {
|
||||||
reverseLineReader.eachLine(this.#path, (raw: string, last: boolean) => {
|
reverseLineReader.eachLine(this.#path, (raw: string, last: boolean) => {
|
||||||
// Extra check just to be sure.
|
// Extra check just to be sure.
|
||||||
if (this.location.name !== 'Unknown') {
|
if (this.location.name !== 'Unknown') {
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw) {
|
if (raw) {
|
||||||
const line: journalEntry = JSON.parse(raw)
|
const line: journalEntry = JSON.parse(raw);
|
||||||
|
|
||||||
if (line.event === 'Location') {
|
if (line.event === 'Location') {
|
||||||
this.location = new System((line as completeFsdJump))
|
this.location = new System((line as completeFsdJump));
|
||||||
Log.write(`Current location set to ${this.location.name}.`)
|
Log.write(`Current location set to ${this.location.name}.`);
|
||||||
this.emit('ENTERED_NEW_SYSTEM')
|
this.emit('ENTERED_NEW_SYSTEM');
|
||||||
return false
|
return false;
|
||||||
|
|
||||||
} else if (last) {
|
} else if (last) {
|
||||||
Log.write('WARNING: Unable to find last known location.')
|
Log.write('WARNING: Unable to find last known location.');
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if (this.location.name !== 'Unknown') {
|
if (this.location.name !== 'Unknown') {
|
||||||
Log.write('Attempting to find scanned bodies in current system.')
|
Log.write('Attempting to find scanned bodies in current system.');
|
||||||
this.#getScannedBodies()
|
this.#getScannedBodies();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -102,38 +103,38 @@ export class Journal extends EventEmitter {
|
||||||
|
|
||||||
reverseLineReader.eachLine(this.#path, (raw: string) => {
|
reverseLineReader.eachLine(this.#path, (raw: string) => {
|
||||||
if (raw) {
|
if (raw) {
|
||||||
const line: journalEntry = JSON.parse(raw)
|
const line: journalEntry = JSON.parse(raw);
|
||||||
|
|
||||||
// Check if previous line was ScanType = Detailed, and handle that.
|
// Check if previous line was ScanType = Detailed, and handle that.
|
||||||
if (dssLine) {
|
if (dssLine) {
|
||||||
if (line.event === 'SAAScanComplete') {
|
if (line.event === 'SAAScanComplete') {
|
||||||
// This was a DSS, so add to list with DSS flag set to true.
|
// This was a DSS, so add to list with DSS flag set to true.
|
||||||
this.location.bodies.push(new Body(dssLine, true))
|
this.location.bodies.push(new Body(dssLine, true));
|
||||||
} else {
|
} else {
|
||||||
// Else, check that the body hasn't already been added (by a DSS scan line).
|
// Else, check that the body hasn't already been added (by a DSS scan line).
|
||||||
const dupChecker = {'BodyName': dssLine.BodyName, 'BodyID': dssLine.BodyID}
|
const dupChecker = {'BodyName': dssLine.BodyName, 'BodyID': dssLine.BodyID};
|
||||||
const r = _.find(this.location.bodies, dupChecker)
|
const r = _.find(this.location.bodies, dupChecker);
|
||||||
|
|
||||||
if (r === undefined) {
|
if (r === undefined) {
|
||||||
// Body was not already logged, so add to list.
|
// Body was not already logged, so add to list.
|
||||||
this.location.bodies.push(new Body(dssLine))
|
this.location.bodies.push(new Body(dssLine));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, clear the variable.
|
// Finally, clear the variable.
|
||||||
dssLine = null
|
dssLine = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now move on to evaluating the current line.
|
// Now move on to evaluating the current line.
|
||||||
if (line.event === 'Scan' && 'ScanType' in line) {
|
if (line.event === 'Scan' && 'ScanType' in line) {
|
||||||
// If ScanType = Detailed and body is not a star, save the line so we can check
|
// If ScanType = Detailed and body is not a star, save the line so we can check
|
||||||
// the one immediately above for event = SAAScanComplete, which indicates this
|
// the one immediately above for event = SAAScanComplete, which indicates this
|
||||||
// was a DSS.
|
// was a DSS.
|
||||||
if (line.ScanType === 'Detailed' && !('StarType' in line)) {
|
if (line.ScanType === 'Detailed' && !('StarType' in line)) {
|
||||||
dssLine = (line as detailedScan)
|
dssLine = (line as detailedScan);
|
||||||
|
|
||||||
} else if ('StarType' in line) { // Save stars to bodies list.
|
} else if ('StarType' in line) { // Save stars to bodies list.
|
||||||
this.location.bodies.push(new Body((line as autoScan|detailedScan)))
|
this.location.bodies.push(new Body((line as autoScan|detailedScan)));
|
||||||
|
|
||||||
} else if (line.ScanType === 'AutoScan') { // Save auto/discovery scan bodies.
|
} else if (line.ScanType === 'AutoScan') { // Save auto/discovery scan bodies.
|
||||||
// Check if planet, and then do the duplicate check (otherwise it's an
|
// Check if planet, and then do the duplicate check (otherwise it's an
|
||||||
|
@ -142,33 +143,33 @@ export class Journal extends EventEmitter {
|
||||||
const dupChecker = {
|
const dupChecker = {
|
||||||
'BodyName': (line as planetScan<'AutoScan'>).BodyName,
|
'BodyName': (line as planetScan<'AutoScan'>).BodyName,
|
||||||
'BodyID': (line as planetScan<'AutoScan'>).BodyID,
|
'BodyID': (line as planetScan<'AutoScan'>).BodyID,
|
||||||
}
|
};
|
||||||
const r = _.find(this.location.bodies, dupChecker)
|
const r = _.find(this.location.bodies, dupChecker);
|
||||||
|
|
||||||
if (r === undefined) {
|
if (r === undefined) {
|
||||||
this.location.bodies.push(new Body((line as autoScan)))
|
this.location.bodies.push(new Body((line as autoScan)));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // Asteroids.
|
} else { // Asteroids.
|
||||||
this.location.bodies.push(new Body((line as autoScan)))
|
this.location.bodies.push(new Body((line as autoScan)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (line.event === 'FSDJump') {
|
} else if (line.event === 'FSDJump') {
|
||||||
// Stop evaluating once we reach the beginning of current system entries.
|
// Stop evaluating once we reach the beginning of current system entries.
|
||||||
return false
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if (this.location.bodies.length > 0) {
|
if (this.location.bodies.length > 0) {
|
||||||
Log.write('No scanned bodies found in current system.')
|
Log.write('No scanned bodies found in current system.');
|
||||||
this.emit('BUILD_BODY_LIST')
|
this.emit('BUILD_BODY_LIST');
|
||||||
} else {
|
} else {
|
||||||
Log.write('Scanned bodies found.')
|
Log.write('Scanned bodies found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.write('Checking for nav route.')
|
Log.write('Checking for nav route.');
|
||||||
this.#getNavRoute()
|
this.#getNavRoute();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,40 +177,40 @@ export class Journal extends EventEmitter {
|
||||||
|
|
||||||
async #getNavRoute(): Promise<void> {
|
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
|
let routeFile: string|null = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const filePath: string = path.dirname(this.#path) + '/NavRoute.json'
|
const filePath: string = path.dirname(this.#path) + '/NavRoute.json';
|
||||||
routeFile = await readFile(filePath, {encoding: 'utf8'})
|
routeFile = await readFile(filePath, {encoding: 'utf8'});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Log.write(`Error reading nav route file: ${err.message}.`)
|
Log.write(`Error reading nav route file: ${err.message}.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (routeFile) {
|
if (routeFile) {
|
||||||
const route: navRoute = JSON.parse(routeFile)
|
const route: navRoute = JSON.parse(routeFile);
|
||||||
|
|
||||||
// system -> skip
|
// system -> skip
|
||||||
// CURRENT -> push = true; skip
|
// CURRENT -> push = true; skip
|
||||||
// system -> push
|
// system -> push
|
||||||
let push: boolean = false
|
let push: boolean = false;
|
||||||
route.Route.forEach((system) => {
|
route.Route.forEach((system) => {
|
||||||
if (!push && system.SystemAddress === this.location.SystemAddress) {
|
if (!push && system.SystemAddress === this.location.SystemAddress) {
|
||||||
push = true
|
push = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (push && system.SystemAddress !== this.location.SystemAddress) {
|
if (push && system.SystemAddress !== this.location.SystemAddress) {
|
||||||
this.navRoute.push(new System(system))
|
this.navRoute.push(new System(system));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (this.navRoute.length > 0) {
|
if (this.navRoute.length > 0) {
|
||||||
Log.write('Nav route set.')
|
Log.write('Nav route set.');
|
||||||
} else {
|
} else {
|
||||||
Log.write('No nav route found.')
|
Log.write('No nav route found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call this no matter what, so that cleared routes are properly dealt with.
|
// Call this no matter what, so that cleared routes are properly dealt with.
|
||||||
this.emit('SET_NAV_ROUTE')
|
this.emit('SET_NAV_ROUTE');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,63 +218,63 @@ export class Journal extends EventEmitter {
|
||||||
|
|
||||||
// Watch the journal for changes.
|
// Watch the journal for changes.
|
||||||
watch(): void {
|
watch(): void {
|
||||||
const tail: TailType = new Tail(this.#path, {useWatchFile: true})
|
const tail: TailType = new Tail(this.#path, {useWatchFile: true});
|
||||||
|
|
||||||
Log.write(`Watching ${path.basename(this.#path)}...`)
|
Log.write(`Watching ${path.basename(this.#path)}...`);
|
||||||
|
|
||||||
tail.on('line', (data) => data ? this.#parseLine(data) : undefined)
|
tail.on('line', (data) => data ? this.#parseLine(data) : undefined);
|
||||||
tail.on('error', (err) => Log.write(`Tail error in Journal.watch(): ${err}`))
|
tail.on('error', (err) => Log.write(`Tail error in Journal.watch(): ${err}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ #parseLine() ---- */
|
/* ------------------------------------------------------------------------ #parseLine() ---- */
|
||||||
|
|
||||||
// Parse and handle journal lines.
|
// Parse and handle journal lines.
|
||||||
#parseLine(raw: string) {
|
#parseLine(raw: string) {
|
||||||
const line: journalEntry = JSON.parse(raw)
|
const line: journalEntry = JSON.parse(raw);
|
||||||
let dssFlag: boolean = false
|
let dssFlag: boolean = false;
|
||||||
|
|
||||||
switch (line.event) {
|
switch (line.event) {
|
||||||
// Hyperspace jump started (3.. 2.. 1..)
|
// Hyperspace jump started (3.. 2.. 1..)
|
||||||
case 'StartJump': {
|
case 'StartJump': {
|
||||||
if ('JumpType' in line && line.JumpType === 'Hyperspace') {
|
if ('JumpType' in line && line.JumpType === 'Hyperspace') {
|
||||||
this.emit('ENTERING_WITCH_SPACE')
|
this.emit('ENTERING_WITCH_SPACE');
|
||||||
}
|
}
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CMDR jumped to new system, so update current location.
|
// CMDR jumped to new system, so update current location.
|
||||||
case 'FSDJump': {
|
case 'FSDJump': {
|
||||||
this.#handleFsdJump((line as completeFsdJump))
|
this.#handleFsdJump((line as completeFsdJump));
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CMDR completed DSS scan, so set flag for when next line processes and we want to
|
// CMDR completed DSS scan, so set flag for when next line processes and we want to
|
||||||
// figure out what kind of scan occurred.
|
// figure out what kind of scan occurred.
|
||||||
case 'SAAScanComplete': {
|
case 'SAAScanComplete': {
|
||||||
dssFlag = true
|
dssFlag = true;
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A scan occurred, so let's hand that info off to the appropriate function and then
|
// A scan occurred, so let's hand that info off to the appropriate function and then
|
||||||
// reset the DSS flag.
|
// reset the DSS flag.
|
||||||
case 'Scan': {
|
case 'Scan': {
|
||||||
this.#handleScanLine((line as autoScan|detailedScan), dssFlag)
|
this.#handleScanLine((line as autoScan|detailedScan), dssFlag);
|
||||||
dssFlag = false
|
dssFlag = false;
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CMDR set a new nav route.
|
// CMDR set a new nav route.
|
||||||
case 'NavRoute': {
|
case 'NavRoute': {
|
||||||
this.#getNavRoute()
|
this.#getNavRoute();
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CMDR cleared the nav route.
|
// CMDR cleared the nav route.
|
||||||
case 'NavRouteClear': {
|
case 'NavRouteClear': {
|
||||||
this.navRoute = []
|
this.navRoute = [];
|
||||||
Log.write('Nav route cleared.')
|
Log.write('Nav route cleared.');
|
||||||
this.emit('SET_NAV_ROUTE')
|
this.emit('SET_NAV_ROUTE');
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,49 +282,49 @@ export class Journal extends EventEmitter {
|
||||||
/* ---------------------------------------------------------------------- #handleFsdJump ---- */
|
/* ---------------------------------------------------------------------- #handleFsdJump ---- */
|
||||||
|
|
||||||
#handleFsdJump(line: completeFsdJump): void {
|
#handleFsdJump(line: completeFsdJump): void {
|
||||||
this.location = new System(line)
|
this.location = new System(line);
|
||||||
Log.write(`FSD Jump detected, current location updated to ${this.location.name}.`)
|
Log.write(`FSD Jump detected, current location updated to ${this.location.name}.`);
|
||||||
|
|
||||||
if (this.navRoute.length > 0) {
|
if (this.navRoute.length > 0) {
|
||||||
_.remove(this.navRoute, (system) => {
|
_.remove(this.navRoute, (system) => {
|
||||||
return system.SystemAddress === this.location.SystemAddress
|
return system.SystemAddress === this.location.SystemAddress;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('ENTERED_NEW_SYSTEM')
|
this.emit('ENTERED_NEW_SYSTEM');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- #handleScanLine ---- */
|
/* --------------------------------------------------------------------- #handleScanLine ---- */
|
||||||
|
|
||||||
#handleScanLine(line: autoScan|detailedScan, DSS: boolean = false) {
|
#handleScanLine(line: autoScan|detailedScan, DSS: boolean = false) {
|
||||||
const dupChecker = {'BodyName': line.BodyName, 'BodyID': line.BodyID}
|
const dupChecker = {'BodyName': line.BodyName, 'BodyID': line.BodyID};
|
||||||
let body: Body|null = null
|
let body: Body|null = null;
|
||||||
|
|
||||||
// If it's a DSS scan, then we should have already added the body to the list. But we'll
|
// If it's a DSS scan, then we should have already added the body to the list. But we'll
|
||||||
// check to make sure.
|
// check to make sure.
|
||||||
if (DSS) {
|
if (DSS) {
|
||||||
// Using findIndex() rather than find() so we can edit the body if found.
|
// Using findIndex() rather than find() so we can edit the body if found.
|
||||||
const bodyIndex: number = _.findIndex(this.location.bodies, dupChecker)
|
const bodyIndex: number = _.findIndex(this.location.bodies, dupChecker);
|
||||||
|
|
||||||
if (bodyIndex > -1) { // Body was found in list, so simply toggle the DSS flag.
|
if (bodyIndex > -1) { // Body was found in list, so simply toggle the DSS flag.
|
||||||
this.location.bodies[bodyIndex].DSSDone = true
|
this.location.bodies[bodyIndex].DSSDone = true;
|
||||||
|
|
||||||
} else { // Body was missed on initial journal scan, so add it to the list.
|
} else { // Body was missed on initial journal scan, so add it to the list.
|
||||||
body = new Body(line, true)
|
body = new Body(line, true);
|
||||||
this.location.bodies.push(body)
|
this.location.bodies.push(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // Otherwise it's an FSS or auto scan, and needs to be added to the list.
|
} else { // Otherwise it's an FSS or auto scan, and needs to be added to the list.
|
||||||
// Probably overkill, but do a duplicate check just in case.
|
// Probably overkill, but do a duplicate check just in case.
|
||||||
const r = _.find(this.location.bodies, dupChecker)
|
const r = _.find(this.location.bodies, dupChecker);
|
||||||
|
|
||||||
if (r === undefined) {
|
if (r === undefined) {
|
||||||
body = new Body(line)
|
body = new Body(line);
|
||||||
this.location.bodies.push(body)
|
this.location.bodies.push(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.write(`Scan detected. Body: ${line.BodyName}.`)
|
Log.write(`Scan detected. Body: ${line.BodyName}.`);
|
||||||
this.emit('BODY_SCANNED', body, DSS)
|
this.emit('BODY_SCANNED', body, DSS);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,17 +1,22 @@
|
||||||
|
import { EliteMatrix } from "elite-matrix";
|
||||||
|
const EventEmitter = require('node:events');
|
||||||
const fs = require('node:fs/promises');
|
const fs = require('node:fs/promises');
|
||||||
const { statSync, writeFileSync, readFileSync } = require('node:fs');
|
const { statSync, writeFileSync, readFileSync } = require('node:fs');
|
||||||
|
const ini = require('ini');
|
||||||
const os = require('node:os');
|
const os = require('node:os');
|
||||||
const path = require('node:path');
|
const path = require('node:path');
|
||||||
|
const { setTimeout } = require('node:timers/promises');
|
||||||
|
const xmlJS = require('xml-js');
|
||||||
|
|
||||||
import { EliteMatrix } from "elite-matrix";
|
|
||||||
import { Log } from "./Log";
|
import { Log } from "./Log";
|
||||||
|
|
||||||
interface settingsFile {
|
interface settingsFile {
|
||||||
minValue: number,
|
minValue: number,
|
||||||
maxDistance: number,
|
maxDistance: number,
|
||||||
|
matrixFile: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Settings {
|
export class Settings extends EventEmitter {
|
||||||
static #instance: Settings;
|
static #instance: Settings;
|
||||||
|
|
||||||
#file: string;
|
#file: string;
|
||||||
|
@ -20,10 +25,12 @@ export class Settings {
|
||||||
minValue: number;
|
minValue: number;
|
||||||
maxDistance: number;
|
maxDistance: number;
|
||||||
|
|
||||||
#matrixFile?: string;
|
#matrixFile: null|string;
|
||||||
matrix?: EliteMatrix;
|
matrix?: EliteMatrix;
|
||||||
|
|
||||||
private constructor(isPackaged: boolean) {
|
private constructor(isPackaged: boolean) {
|
||||||
|
super();
|
||||||
|
|
||||||
if (!isPackaged && os.platform() === 'linux') {
|
if (!isPackaged && os.platform() === 'linux') {
|
||||||
this.#file = '/mnt/c/Users/marle/ed-safari-settings.json';
|
this.#file = '/mnt/c/Users/marle/ed-safari-settings.json';
|
||||||
} else {
|
} else {
|
||||||
|
@ -39,6 +46,7 @@ export class Settings {
|
||||||
const contents: string = JSON.stringify({
|
const contents: string = JSON.stringify({
|
||||||
minValue: 500000,
|
minValue: 500000,
|
||||||
maxDistance: 10000,
|
maxDistance: 10000,
|
||||||
|
matrixFile: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
writeFileSync(this.#file, contents);
|
writeFileSync(this.#file, contents);
|
||||||
|
@ -49,8 +57,12 @@ export class Settings {
|
||||||
const contents: settingsFile = JSON.parse(readFileSync(this.#file, { encoding: 'utf8' }));
|
const contents: settingsFile = JSON.parse(readFileSync(this.#file, { encoding: 'utf8' }));
|
||||||
this.minValue = contents.minValue;
|
this.minValue = contents.minValue;
|
||||||
this.maxDistance = contents.maxDistance;
|
this.maxDistance = contents.maxDistance;
|
||||||
|
this.#matrixFile = contents.matrixFile;
|
||||||
this.#writing = false;
|
this.#writing = false;
|
||||||
|
|
||||||
|
if (this.#matrixFile) {
|
||||||
|
this.#setMatrix();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get(isPackaged: boolean = false): Settings {
|
static get(isPackaged: boolean = false): Settings {
|
||||||
|
@ -74,6 +86,10 @@ export class Settings {
|
||||||
this.#writing = false;
|
this.#writing = false;
|
||||||
|
|
||||||
Log.write('Settings saved!');
|
Log.write('Settings saved!');
|
||||||
|
|
||||||
|
// Update Settings props.
|
||||||
|
await this.#read();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Log.write(err);
|
Log.write(err);
|
||||||
|
@ -83,4 +99,73 @@ export class Settings {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------- #read ---- */
|
||||||
|
|
||||||
|
async #read(): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
const file: string = await fs.readFile(this.#file, { encoding: 'utf8' });
|
||||||
|
const contents: settingsFile = JSON.parse(file);
|
||||||
|
|
||||||
|
this.minValue = contents.minValue;
|
||||||
|
this.maxDistance = contents.maxDistance;
|
||||||
|
this.#matrixFile = contents.matrixFile;
|
||||||
|
|
||||||
|
if (this.#matrixFile) {
|
||||||
|
await this.#setMatrix();
|
||||||
|
Log.write('Custom colors set!');
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
Log.write(err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------- #setMatrix ---- */
|
||||||
|
|
||||||
|
async #setMatrix(): Promise<void> {
|
||||||
|
const file: string = await fs.readFile(this.#matrixFile, { encoding: 'utf8' });
|
||||||
|
|
||||||
|
let matrixRed: [number, number, number];
|
||||||
|
let matrixGreen: [number, number, number];
|
||||||
|
let matrixBlue: [number, number, number];
|
||||||
|
|
||||||
|
if (path.basename(this.#matrixFile) === 'GraphicsConfiguration.xml') {
|
||||||
|
const options = {
|
||||||
|
trim: true,
|
||||||
|
ignoreDeclaration: true,
|
||||||
|
ignoreAttributes: true,
|
||||||
|
compact: true,
|
||||||
|
textKey: '$'
|
||||||
|
};
|
||||||
|
const contents = xmlJS.xml2js(file, options);
|
||||||
|
|
||||||
|
let matrix = [
|
||||||
|
contents.GraphicsConfig.GUIColour.Default.MatrixRed.$,
|
||||||
|
contents.GraphicsConfig.GUIColour.Default.MatrixGreen.$,
|
||||||
|
contents.GraphicsConfig.GUIColour.Default.MatrixBlue.$,
|
||||||
|
];
|
||||||
|
|
||||||
|
matrix = matrix.map(v => v.replace(/\s/g, '').split(','));
|
||||||
|
|
||||||
|
matrixRed = matrix[0].length === 3 ? matrix[0] : [1,0,0];
|
||||||
|
matrixGreen = matrix[1].length === 3 ? matrix[1] : [0,1,0];
|
||||||
|
matrixBlue = matrix[2].length === 3 ? matrix[2] : [0,0,1];
|
||||||
|
|
||||||
|
this.matrix = new EliteMatrix(matrixRed, matrixGreen, matrixBlue);
|
||||||
|
|
||||||
|
} else if (path.basename(this.#matrixFile) === 'XML-Profile.ini') {
|
||||||
|
const contents = (ini.parse(file)).constants;
|
||||||
|
|
||||||
|
matrixRed = [contents.x150, contents.y150, contents.z150];
|
||||||
|
matrixGreen = [contents.x151, contents.y151, contents.z151];
|
||||||
|
matrixBlue = [contents.x152, contents.y152, contents.z152];
|
||||||
|
|
||||||
|
this.matrix = new EliteMatrix(matrixRed, matrixGreen, matrixBlue);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.emit('CUSTOM_COLORS_SET');
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -9,6 +9,17 @@ export class UI {
|
||||||
return Intl.NumberFormat().format(Math.round(number));
|
return Intl.NumberFormat().format(Math.round(number));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------- setColors ---- */
|
||||||
|
|
||||||
|
static setColors(matrix) {
|
||||||
|
const body = $('body');
|
||||||
|
body.css('--main', matrix.filterColor('#F5A804'));
|
||||||
|
body.css('--accent-dark', matrix.filterColor('#000e5f'));
|
||||||
|
body.css('--accent-light', matrix.filterColor('#17cbd4'));
|
||||||
|
body.css('--secondary-light', matrix.filterColor('#EAA529'));
|
||||||
|
body.css('--secondary-dark', matrix.filterColor('#370C03'));
|
||||||
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------- enterWitchSpace ---- */
|
/* --------------------------------------------------------------------- enterWitchSpace ---- */
|
||||||
|
|
||||||
static enterWitchSpace() {
|
static enterWitchSpace() {
|
||||||
|
|
|
@ -35,6 +35,12 @@ if (!journal) {
|
||||||
safari.watchJournalDir();
|
safari.watchJournalDir();
|
||||||
journal.watch();
|
journal.watch();
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------ set colors ---- */
|
||||||
|
|
||||||
|
settings.on('CUSTOM_COLORS_SET', () => {
|
||||||
|
UI.setColors(settings.matrix);
|
||||||
|
});
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- close window handler ---- */
|
/* -------------------------------------------------------------------- close window handler ---- */
|
||||||
|
|
||||||
$('#closeBtn').on('click', () => {
|
$('#closeBtn').on('click', () => {
|
||||||
|
@ -129,18 +135,4 @@ edsm.on('SYSTEM_APPRAISED', (system) => {
|
||||||
if (systemRow.length > 0) {
|
if (systemRow.length > 0) {
|
||||||
UI.setValue(systemRow, system.estimatedValueMapped);
|
UI.setValue(systemRow, system.estimatedValueMapped);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// const matrixRed = [1.2, 0.05, 0.07];
|
|
||||||
// const matrixGreen = [0.13, 1, 1.18];
|
|
||||||
// const matrixBlue = [0.4, 1.29, 2];
|
|
||||||
|
|
||||||
// const matrix = new EliteMatrix(matrixRed, matrixGreen, matrixBlue);
|
|
||||||
// const hex = matrix.filterColor('#f5a804');
|
|
||||||
// const rgb = matrix.filterColor([245, 168, 4]);
|
|
||||||
// console.log(`rgb(${rgb})`)
|
|
||||||
// $('body').css('--main', `rgb(${rgb})`);
|
|
||||||
// $('body').css('--accent-dark', matrix.filterColor('#000e5f'));
|
|
||||||
// $('body').css('--accent-light', matrix.filterColor('#17cbd4'));
|
|
||||||
// $('body').css('--secondary-light', matrix.filterColor('#EAA529'));
|
|
||||||
// $('body').css('--secondary-dark', matrix.filterColor('#370C03'));
|
|
|
@ -5,12 +5,23 @@ import './assets/ldom.min';
|
||||||
|
|
||||||
const { ipcRenderer } = require('electron');
|
const { ipcRenderer } = require('electron');
|
||||||
const { setTimeout } = require('node:timers/promises');
|
const { setTimeout } = require('node:timers/promises');
|
||||||
|
const { basename } = require('node:path');
|
||||||
|
|
||||||
import { Settings } from './models/Settings';
|
import { Settings } from './models/Settings';
|
||||||
import { UI } from './models/UI';
|
import { UI } from './models/UI';
|
||||||
|
|
||||||
const settings = Settings.get();
|
const settings = Settings.get();
|
||||||
|
|
||||||
|
if (settings.matrix) {
|
||||||
|
UI.setColors(settings.matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------ set colors ---- */
|
||||||
|
|
||||||
|
settings.on('CUSTOM_COLORS_SET', () => {
|
||||||
|
UI.setColors(settings.matrix);
|
||||||
|
});
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- close window handler ---- */
|
/* -------------------------------------------------------------------- close window handler ---- */
|
||||||
|
|
||||||
$('#closeBtn').on('click', () => {
|
$('#closeBtn').on('click', () => {
|
||||||
|
@ -61,6 +72,11 @@ $('form').on('submit', async function (event) {
|
||||||
errors = true;
|
errors = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileName = basename(data.matrixFile);
|
||||||
|
if (fileName !== 'XML-Profile.ini' || fileName !== 'GraphicsConfiguration.xml') {
|
||||||
|
UI.addFormError('#matrixFile', 'Invalid file.');
|
||||||
|
}
|
||||||
|
|
||||||
// TODO re-enable submit button if errors.
|
// TODO re-enable submit button if errors.
|
||||||
|
|
||||||
// If no errors, save.
|
// If no errors, save.
|
||||||
|
|
Loading…
Reference in a new issue