summaryrefslogtreecommitdiff
path: root/nodejs/automation
diff options
context:
space:
mode:
authorJulien Dessaux2024-03-21 17:08:37 +0100
committerJulien Dessaux2024-03-27 15:21:00 +0100
commitd668eac4a63a9aa98c3efff395faa23cfcea1c1b (patch)
tree691e3bb471bcacadb975f581f73e09b84287b4a5 /nodejs/automation
parent[javascript] fixed mining loop (diff)
downloadspacetraders-d668eac4a63a9aa98c3efff395faa23cfcea1c1b.tar.gz
spacetraders-d668eac4a63a9aa98c3efff395faa23cfcea1c1b.tar.bz2
spacetraders-d668eac4a63a9aa98c3efff395faa23cfcea1c1b.zip
[node] begin the great typescript rewrite
Diffstat (limited to 'nodejs/automation')
-rw-r--r--nodejs/automation/contracting.js71
-rw-r--r--nodejs/automation/contracting.ts72
-rw-r--r--nodejs/automation/init.js4
-rw-r--r--nodejs/automation/selling.js118
4 files changed, 134 insertions, 131 deletions
diff --git a/nodejs/automation/contracting.js b/nodejs/automation/contracting.js
deleted file mode 100644
index 19183fb..0000000
--- a/nodejs/automation/contracting.js
+++ /dev/null
@@ -1,71 +0,0 @@
-import * as mining from './mining.js';
-import * as selling from './selling.js';
-import * as dbContracts from '../database/contracts.js';
-import * as dbShips from '../database/ships.js';
-import * as api from '../lib/api.js';
-import * as contracts from '../lib/contracts.js';
-import * as libShips from '../lib/ships.js';
-import * as systems from '../lib/systems.js';
-import * as utils from '../lib/utils.js';
-
-export async function init() {
- const cs = dbContracts.getContracts();
- cs.forEach(contract => run(contract));
-}
-
-async function run(contract) {
- await contracts.accept({id: contract.id});
- const contractSystem = utils.systemFromWaypoint(contract.terms.deliver[0].destinationSymbol);
- let ships = dbShips.getShipsAt(contractSystem);
- ships = ships.filter(ship => ship.registration.role !== 'SATELLITE'); // filter out probes
-
- switch(contract.type) {
- case 'PROCUREMENT':
- await runProcurement(contract, ships);
- break;
- default:
- throw `Handling of contract type ${contract.type} is not implemented yet`;
- }
-}
-
-async function runProcurement(contract, ships) {
- // TODO check if contract is fulfilled!
- const wantedCargo = contract.terms.deliver[0].tradeSymbol;
- const deliveryPoint = contract.terms.deliver[0].destinationSymbol;
- const asteroids = await systems.type({symbol: ships[0].nav.systemSymbol, type: 'ENGINEERED_ASTEROID'});
- const asteroidSymbol = asteroids[0].symbol;
- ships.forEach(async function(ship) {
- while (!dbContracts.getContract(contract.id).fulfilled) {
- ship = dbShips.getShip(ship.symbol);
- let goodCargo = ship.cargo.inventory.filter(i => i.symbol === wantedCargo)[0];
- // If we are in transit, we wait until we arrive
- const delay = new Date(ship.nav.route.arrival) - new Date();
- if (delay > 0) await api.sleep(delay);
- // Then it depends on where we are
- switch (ship.nav.waypointSymbol) {
- case asteroidSymbol:
- await mining.mineUntilFullOf({
- asteroidSymbol: asteroidSymbol,
- good: wantedCargo,
- symbol: ship.symbol
- });
- await libShips.navigate({symbol: ship.symbol, waypoint: deliveryPoint});
- break;
- case deliveryPoint:
- if (goodCargo !== undefined) { // we could be here if a client restart happens right after selling before we navigate away
- console.log(`delivering ${goodCargo.units} of ${wantedCargo}`);
- if (await contracts.deliver({id: contract.id, symbol: ship.symbol, good: wantedCargo, units: goodCargo.units })) {
- break;
- }
- }
- await libShips.navigate({symbol: ship.symbol, waypoint: asteroidSymbol});
- break;
- default:
- // we were either selling or started contracting
- await selling.sell(ship, wantedCargo);
- await libShips.navigate({symbol: ship.symbol, waypoint: asteroidSymbol});
- }
- }
- // TODO repurpose the ship
- });
-}
diff --git a/nodejs/automation/contracting.ts b/nodejs/automation/contracting.ts
new file mode 100644
index 0000000..2857778
--- /dev/null
+++ b/nodejs/automation/contracting.ts
@@ -0,0 +1,72 @@
+import { Contract } from '../model/contract.ts';
+import { Ship } from '../model/ship.ts';
+import * as mining from './mining.js';
+import * as selling from './selling.js';
+import * as dbContracts from '../database/contracts.ts';
+import * as dbShips from '../database/ships.ts';
+import * as api from '../lib/api.ts';
+import * as contracts from '../lib/contracts.ts';
+import * as libShips from '../lib/ships.ts';
+import * as systems from '../lib/systems.ts';
+import * as utils from '../lib/utils.ts';
+
+export async function init() {
+ const cs = dbContracts.getContracts();
+ cs.forEach(contract => run(contract));
+}
+
+async function run(contract: Contract) {
+ await contracts.accept(contract);
+ const contractSystem = utils.systemFromWaypoint(contract.terms.deliver[0].destinationSymbol);
+ let ships = dbShips.getShipsAt(contractSystem);
+ ships = ships.filter(ship => ship.registration.role !== 'SATELLITE'); // filter out probes
+
+ switch(contract.type) {
+ case 'PROCUREMENT':
+ await runProcurement(contract, ships);
+ break;
+ default:
+ throw `Handling of contract type ${contract.type} is not implemented yet`;
+ }
+}
+
+async function runProcurement(contract: Contract, ships: Array<Ship>) {
+ // TODO check if contract is fulfilled!
+ const wantedCargo = contract.terms.deliver[0].tradeSymbol;
+ const deliveryPoint = contract.terms.deliver[0].destinationSymbol;
+ const asteroids = await systems.type({symbol: ships[0].nav.systemSymbol, type: 'ENGINEERED_ASTEROID'});
+ const asteroidSymbol = asteroids[0].symbol;
+ ships.forEach(async function(ship) {
+ while (!contract.fulfilled) {
+ ship = dbShips.getShip(ship.symbol) as Ship;
+ let goodCargo = ship.cargo.inventory.filter(i => i.symbol === wantedCargo)[0]
+ // If we are in transit, we wait until we arrive
+ const delay = new Date(ship.nav.route.arrival).getTime() - new Date().getTime();
+ if (delay > 0) await api.sleep(delay);
+ // Then it depends on where we are
+ switch (ship.nav.waypointSymbol) {
+ case asteroidSymbol:
+ await mining.mineUntilFullOf({
+ asteroidSymbol: asteroidSymbol,
+ good: wantedCargo,
+ symbol: ship.symbol
+ });
+ await libShips.navigate(ship, deliveryPoint);
+ break;
+ case deliveryPoint:
+ if (goodCargo !== undefined) { // we could be here if a client restart happens right after selling before we navigate away
+ console.log(`delivering ${goodCargo.units} of ${wantedCargo}`);
+ contract = await contracts.deliver(contract, ship);
+ if (contract.fulfilled) break;
+ }
+ await libShips.navigate(ship, asteroidSymbol);
+ break;
+ default:
+ // we were either selling or started contracting
+ await selling.sell(ship, wantedCargo);
+ await libShips.navigate(ship, asteroidSymbol);
+ }
+ }
+ // TODO repurpose the ship
+ });
+}
diff --git a/nodejs/automation/init.js b/nodejs/automation/init.js
index b921942..93e5a70 100644
--- a/nodejs/automation/init.js
+++ b/nodejs/automation/init.js
@@ -6,6 +6,8 @@ import * as dbTokens from '../database/tokens.js';
import * as api from '../lib/api.js';
import * as ships from '../lib/ships.js';
+const symbol = process.env.NODE_ENV === 'test' ? 'ADYXAX-0' : 'ADYXAX-TS';
+
// This function registers then inits the database
export async function init() {
const response = await fetch('https://api.spacetraders.io/v2/register', {
@@ -14,7 +16,7 @@ export async function init() {
'Content-Type': 'application/json',
},
body: JSON.stringify({
- symbol: "ADYXAX-JS",
+ symbol: symbol,
faction: "COSMIC",
}),
});
diff --git a/nodejs/automation/selling.js b/nodejs/automation/selling.js
index b52d52c..3d444af 100644
--- a/nodejs/automation/selling.js
+++ b/nodejs/automation/selling.js
@@ -8,65 +8,65 @@ import * as utils from '../lib/utils.js';
// example ctx { ship: {XXX}, keep: 'SILVER_ORE' }
export async function sell(ship, keep) {
outer: while(true) {
- // first lets see what we want to sell
- let cargo = utils.categorizeCargo(ship.cargo, keep);
- // get the marketdata from our location
- const market = await libSystems.market(ship.nav.waypointSymbol);
- // can we sell anything here?
- const goods = whatCanBeTradedAt(cargo.goods, market.imports.concat(market.exchange));
- for (let i = 0; i < goods.length; i++) {
- const symbol = goods[i].symbol;
- await libShips.sell({
- good: symbol,
- symbol: ship.symbol,
- units: cargo.goods[symbol],
- });
- delete cargo.goods[symbol];
- };
- // are we done selling everything we can?
- ship = dbShips.getShip(ship.symbol);
- cargo = utils.categorizeCargo(ship.cargo, keep);
- if (Object.keys(cargo.goods).length === 0) {
- return;
- }
- // we need to move somewhere else to sell our remaining goods
- // first we look into markets in our system
- const rawMarkets = await libSystems.trait({symbol: ship.nav.systemSymbol, trait: 'MARKETPLACE'});
- // sorted by distance from where we are
- const markets = rawMarkets.map(function (m) { return {
- data: m,
- distance: (m.x - ship.nav.route.destination.x) ** 2 + (m.y - ship.nav.route.destination.y) ** 2,
- }});
- markets.sort(function(a, b) {
- if (a.distance < b.distance) {
- return -1;
- } else if (a.distance > b.distance) {
- return 1;
- }
- return 0;
- });
- // check from the closest one if they import what we need to sell
- for (let i = 0; i < markets.length; i++) {
- const waypointSymbol = markets[i].data.symbol;
- const market = await libSystems.market(waypointSymbol);
- // if we have no data on the market we need to go there and see
- // and if we have data and can sell there we need to go too
- if (market === null || whatCanBeTradedAt(cargo.goods, market.imports).length > 0) {
- await libShips.navigate({symbol: ship.symbol, waypoint: waypointSymbol});
- continue outer;
- }
- }
- // check from the closest one if they exchange what we need to sell
- for (let i = 0; i < markets.length; i++) {
- const waypointSymbol = markets[i].data.symbol;
- const market = await libSystems.market(waypointSymbol);
- // if we can sell there we need to go
- if (whatCanBeTradedAt(cargo.goods, market.exchange).length > 0) {
- await libShips.navigate({symbol: ship.symbol, waypoint: waypointSymbol});
- continue outer;
- }
- }
- throw new Error(`Ship {ship.symbol} has found no importing or exchanging market for its cargo in the system`);
+ // first lets see what we want to sell
+ let cargo = utils.categorizeCargo(ship.cargo, keep);
+ // get the marketdata from our location
+ const market = await libSystems.market(ship.nav.waypointSymbol);
+ // can we sell anything here?
+ const goods = whatCanBeTradedAt(cargo.goods, market.imports.concat(market.exchange));
+ for (let i = 0; i < goods.length; i++) {
+ const symbol = goods[i].symbol;
+ await libShips.sell({
+ good: symbol,
+ symbol: ship.symbol,
+ units: cargo.goods[symbol],
+ });
+ delete cargo.goods[symbol];
+ };
+ // are we done selling everything we can?
+ ship = dbShips.getShip(ship.symbol);
+ cargo = utils.categorizeCargo(ship.cargo, keep);
+ if (Object.keys(cargo.goods).length === 0) {
+ return;
+ }
+ // we need to move somewhere else to sell our remaining goods
+ // first we look into markets in our system
+ const rawMarkets = await libSystems.trait({symbol: ship.nav.systemSymbol, trait: 'MARKETPLACE'});
+ // sorted by distance from where we are
+ const markets = rawMarkets.map(function (m) { return {
+ data: m,
+ distance: (m.x - ship.nav.route.destination.x) ** 2 + (m.y - ship.nav.route.destination.y) ** 2,
+ }});
+ markets.sort(function(a, b) {
+ if (a.distance < b.distance) {
+ return -1;
+ } else if (a.distance > b.distance) {
+ return 1;
+ }
+ return 0;
+ });
+ // check from the closest one if they import what we need to sell
+ for (let i = 0; i < markets.length; i++) {
+ const waypointSymbol = markets[i].data.symbol;
+ const market = await libSystems.market(waypointSymbol);
+ // if we have no data on the market we need to go there and see
+ // and if we have data and can sell there we need to go too
+ if (market === null || whatCanBeTradedAt(cargo.goods, market.imports).length > 0) {
+ await libShips.navigate({symbol: ship.symbol, waypoint: waypointSymbol});
+ continue outer;
+ }
+ }
+ // check from the closest one if they exchange what we need to sell
+ for (let i = 0; i < markets.length; i++) {
+ const waypointSymbol = markets[i].data.symbol;
+ const market = await libSystems.market(waypointSymbol);
+ // if we can sell there we need to go
+ if (whatCanBeTradedAt(cargo.goods, market.exchange).length > 0) {
+ await libShips.navigate({symbol: ship.symbol, waypoint: waypointSymbol});
+ continue outer;
+ }
+ }
+ throw new Error(`Ship {ship.symbol} has found no importing or exchanging market for its cargo in the system`);
}
}