diff options
author | Julien Dessaux | 2024-05-13 23:45:45 +0200 |
---|---|---|
committer | Julien Dessaux | 2024-05-13 23:45:45 +0200 |
commit | de0251bc22d554e2ace4d2d3d061dc1054656bcd (patch) | |
tree | 7e0f00f2ded551a9904a772c5cf6f37a2c06bb61 /nodejs/lib | |
parent | [node] improved sql migrations code (diff) | |
download | spacetraders-de0251bc22d554e2ace4d2d3d061dc1054656bcd.tar.gz spacetraders-de0251bc22d554e2ace4d2d3d061dc1054656bcd.tar.bz2 spacetraders-de0251bc22d554e2ace4d2d3d061dc1054656bcd.zip |
[node] Big Contracts lib refactoring
Diffstat (limited to '')
-rw-r--r-- | nodejs/lib/contracts.ts | 151 | ||||
-rw-r--r-- | nodejs/lib/ships.ts | 6 | ||||
-rw-r--r-- | nodejs/lib/types.ts | 23 |
3 files changed, 81 insertions, 99 deletions
diff --git a/nodejs/lib/contracts.ts b/nodejs/lib/contracts.ts index 0582cc7..1b54178 100644 --- a/nodejs/lib/contracts.ts +++ b/nodejs/lib/contracts.ts @@ -1,7 +1,6 @@ import { Agent, Cargo, - Contract, } from './types.ts'; import { APIError, @@ -11,84 +10,92 @@ import { } from './api.ts'; import { Ship } from './ships.ts'; import * as dbAgents from '../database/agents.ts'; -import * as dbContracts from '../database/contracts.ts'; - -export async function accept(contract: Contract): Promise<Contract> { - contract = dbContracts.getContract(contract.id); - if (contract.accepted) return contract; - const response = await send<{agent: Agent, contract: Contract, type: ''}>({endpoint: `/my/contracts/${contract.id}/accept`, method: 'POST'}); - if (response.error) { - debugLog(response); - throw response; - } - dbAgents.setAgent(response.data.agent); - dbContracts.setContract(response.data.contract); - return response.data.contract; -} export async function getContracts(): Promise<Array<Contract>> { const response = await sendPaginated<Contract>({endpoint: '/my/contracts'}); - response.forEach(contract => dbContracts.setContract(contract)); - return response; -} - -export async function getContract(contract: Contract): Promise<Contract> { - try { - return dbContracts.getContract(contract.id); - } catch {} - const response = await send<Contract>({endpoint: `/my/contracts/${contract.id}`}); - if (response.error) { - debugLog(response); - throw response; - } - dbContracts.setContract(response.data); - return response.data; + return response.map(contract => new Contract(contract)); } -export async function deliver(contract: Contract, ship: Ship): Promise<Contract> { - contract = dbContracts.getContract(contract.id); - if (contract.terms.deliver[0].unitsRequired <= contract.terms.deliver[0].unitsFulfilled) { - return await fulfill(contract); +export class Contract { + accepted: boolean; + deadlineToAccept: Date; + expiration: Date; + factionSymbol: string; + fulfilled: boolean; + id: string; + terms: { + deadline: Date; + payment: { + onAccepted: number; + onFulfilled: number; + }, + deliver: Array<{ + tradeSymbol: string; + destinationSymbol: string; + unitsRequired: number; + unitsFulfilled: number; + }>; + }; + type: string; + constructor(contract: Contract) { + this.accepted = contract.accepted; + this.deadlineToAccept = contract.deadlineToAccept; + this.expiration = contract.expiration; + this.factionSymbol = contract.factionSymbol; + this.fulfilled = contract.fulfilled; + this.id = contract.id; + this.terms = contract.terms; + this.type = contract.type; } - const tradeSymbol = contract.terms.deliver[0].tradeSymbol; - let units = 0; - ship.cargo.inventory.forEach(i => {if (i.symbol === tradeSymbol) units = i.units; }); - await ship.dock(); // we need to be docked to deliver - const response = await send<{contract: Contract, cargo: Cargo}>({ endpoint: `/my/contracts/${contract.id}/deliver`, method: 'POST', payload: { - shipSymbol: ship.symbol, - tradeSymbol: tradeSymbol, - units: units, - }}); - if (response.error) { - switch(response.error.code) { - case 4503: // contract has expired - // TODO sell cargo? the next trading loop should take care of it by itself - contract.fulfilled = true; - return contract; - case 4509: // contract delivery terms have been met - return await fulfill(contract); - default: // yet unhandled error - debugLog(response); - throw response; + async accept(): Promise<void> { + if (this.accepted) return; + const response = await send<{agent: Agent, contract: Contract, type: ''}>({endpoint: `/my/contracts/${this.id}/accept`, method: 'POST'}); + if (response.error) { + debugLog(response); + throw response; } + dbAgents.setAgent(response.data.agent); } - dbContracts.setContract(response.data.contract); - ship.cargo = response.data.cargo; - if(response.data.contract.terms.deliver[0].unitsRequired <= response.data.contract.terms.deliver[0].unitsFulfilled) { - return await fulfill(response.data.contract); + async deliver(ship: Ship): Promise<void> { + const unitsRemaining = this.terms.deliver[0].unitsRequired - this.terms.deliver[0].unitsFulfilled; + if (unitsRemaining <= 0) return await this.fulfill(); + const tradeSymbol = this.terms.deliver[0].tradeSymbol; + let units = 0; + ship.cargo.inventory.forEach(i => {if (i.symbol === tradeSymbol) units = i.units; }); + if (units === 0) return; + if (units > unitsRemaining) units = unitsRemaining; + await ship.dock(); // we need to be docked to deliver + const response = await send<{contract: Contract, cargo: Cargo}>({ endpoint: `/my/contracts/${this.id}/deliver`, method: 'POST', payload: { + shipSymbol: ship.symbol, + tradeSymbol: tradeSymbol, + units: units, + }}); + if (response.error) { + switch(response.error.code) { + case 4503: // contract has expired + // TODO sell cargo? the next trading loop should take care of it by itself + this.fulfilled = true; + return; + case 4509: // contract delivery terms have been met + return await this.fulfill(); + default: // yet unhandled error + debugLog(response); + throw response; + } + } + ship.cargo = response.data.cargo; + if(response.data.contract.terms.deliver[0].unitsRequired <= response.data.contract.terms.deliver[0].unitsFulfilled) { + return await this.fulfill(); + } } - return response.data.contract; -} - -export async function fulfill(contract: Contract): Promise<Contract> { - contract = dbContracts.getContract(contract.id); - if (contract.fulfilled) return contract; - const response = await send<{agent: Agent, contract: Contract}>({ endpoint: `/my/contracts/${contract.id}/fulfill`, method: 'POST'}); - if (response.error) { - debugLog(response); - throw response; + async fulfill(): Promise<void> { + if (this.terms.deliver[0].unitsRequired > this.terms.deliver[0].unitsFulfilled) return; + if (this.fulfilled) return; + const response = await send<{agent: Agent, contract: Contract}>({ endpoint: `/my/contracts/${this.id}/fulfill`, method: 'POST'}); + if (response.error) { + debugLog(response); + throw response; + } + dbAgents.setAgent(response.data.agent); } - dbAgents.setAgent(response.data.agent); - dbContracts.setContract(response.data.contract); - return response.data.contract; -} +}; diff --git a/nodejs/lib/ships.ts b/nodejs/lib/ships.ts index 74419fc..8df3aea 100644 --- a/nodejs/lib/ships.ts +++ b/nodejs/lib/ships.ts @@ -10,11 +10,11 @@ import { ShipIsStillOnCooldownError, ShipRequiresMoreFuelForNavigationError, } from './errors.ts'; +import { Contract } from './contracts.ts'; import * as libSystems from './systems.ts'; import { Agent, Cargo, - Contract, Cooldown, Fuel, Nav, @@ -25,7 +25,6 @@ import { shortestPath, } from './utils.ts'; import * as dbAgents from '../database/agents.ts'; -import * as dbContracts from '../database/contracts.ts'; export async function getShips(): Promise<Array<Ship>> { const response = await send<Array<Ship>>({endpoint: `/my/ships`, page: 1}); @@ -154,8 +153,7 @@ export class Ship { throw response; } } - dbContracts.setContract(response.data.contract); - return response.data.contract; + return new Contract(response.data.contract); } async orbit(): Promise<void> { if (this.nav.status === 'IN_ORBIT') return; diff --git a/nodejs/lib/types.ts b/nodejs/lib/types.ts index a8e748c..e4d750f 100644 --- a/nodejs/lib/types.ts +++ b/nodejs/lib/types.ts @@ -30,29 +30,6 @@ export type Chart = { submittedOn: Date; }; -export type Contract = { - id: string; - factionSymbol: string; - type: string; - terms: { - deadline: Date; - payment: { - onAccepted: number; - onFulfilled: number; - }, - deliver: Array<{ - tradeSymbol: string; - destinationSymbol: string; - unitsRequired: number; - unitsFulfilled: number; - }>; - }; - accepted: boolean; - fulfilled: boolean; - expiration: Date; - deadlineToAccept: Date; -}; - export type Cooldown = { shipSymbol: string; totalSeconds: number; |