import { RefStore } from '../../state/state' import { Serializable } from '../storage' import { TricksterCharacter } from '../trickster' import { LTOApi } from './api' import { pathIsBank, splitPath } from './lifeto' import { BankItem, InternalXfer, InvalidOrder, MarketMove, MarketMoveToChar, Order, TxnDetails, } from './order' export interface OrderDetails { item_uid: string | 'galders' count: number origin_path: string target_path: string } const notSupported = new InvalidOrder('not supported yet') const notFound = new InvalidOrder('character not found') export class OrderTracker implements Serializable { orders: { [key: string]: Order } = {} async tick(r: RefStore, api: LTOApi): Promise { let hasDirty = false for (const [id, order] of Object.entries(this.orders)) { if (order.status() === 'SUCCESS' || order.status() === 'ERROR') { hasDirty = true delete this.orders[id] } order.tick(r, api) } if (hasDirty) { r.dirty.value++ } return } parse(s: any): OrderTracker { if (s === undefined) { return new OrderTracker() } if (s.orders === undefined) { return new OrderTracker() } this.orders = {} const raw: Order[] = Object.values(s.orders) for (const o of raw) { let newOrder: Order | undefined if (o.details) { if (o.status() === 'SUCCESS' || o.status() === 'ERROR') { continue } switch (o.order_type) { case 'InternalXfer': newOrder = new InternalXfer(o.details).parse(o) break case 'BankItem': newOrder = new BankItem(o.details).parse(o) break case 'MarketMove': newOrder = new MarketMove(o.details).parse(o) break case 'MarketMoveToChar': newOrder = new MarketMoveToChar(o.details).parse(o) break case 'InvalidOrder': newOrder = new InvalidOrder('').parse(o) break } if (newOrder) { this.orders[newOrder.action_id] = newOrder } } } return this } } export class OrderSender { constructor( private orders: OrderTracker, private chars: Map, ) {} send(o: OrderDetails): Order { const formed = this.form(o) this.orders.orders[formed.action_id] = formed return formed } form(o: OrderDetails): Order { // bank to bank if (pathIsBank(o.origin_path) && pathIsBank(o.target_path)) { return this.bank_to_bank(o) } // bank to user if (pathIsBank(o.origin_path) && !pathIsBank(o.target_path)) { return this.bank_to_user(o) } // user to bank if (!pathIsBank(o.origin_path) && pathIsBank(o.target_path)) { return this.user_to_bank(o) } // user to user if (!pathIsBank(o.origin_path) && !pathIsBank(o.target_path)) { return this.user_to_user(o) } return notSupported } bank_to_bank(o: OrderDetails): Order { const origin = this.chars.get(o.origin_path) const target = this.chars.get(o.target_path) if (!(origin && target)) { return notFound } return new MarketMove(this.transformInternalOrder(o)) } bank_to_user(o: OrderDetails): Order { // get the uid of the bank const origin = this.chars.get(o.origin_path) const target = this.chars.get(o.target_path) if (!(origin && target)) { return notFound } const [_account, _name] = splitPath(target.path) /*if(account != origin.path) { return new MarketMoveToChar(this.transformInternalOrder(o)) }*/ return new InternalXfer(this.transformInternalOrder(o)) } user_to_bank(o: OrderDetails): Order { const origin = this.chars.get(o.origin_path) const target = this.chars.get(o.target_path) if (!(origin && target)) { return notFound } const [_account, _name] = splitPath(origin.path) /*if(account != target.path) { return new MarketMove(this.transformInternalOrder(o)) }*/ return new BankItem(this.transformInternalOrder(o)) } user_to_user(o: OrderDetails): Order { const origin = this.chars.get(o.origin_path) const target = this.chars.get(o.target_path) if (!(origin && target)) { return notFound } // return new MarketMoveToChar(this.transformInternalOrder(o)) return new InternalXfer(this.transformInternalOrder(o)) } private transformInternalOrder(o: OrderDetails): TxnDetails { const origin = this.chars.get(o.origin_path) const target = this.chars.get(o.target_path) if (!origin || !target) { throw new Error(`Character not found: origin=${o.origin_path}, target=${o.target_path}`) } return { origin: origin.id.toString(), target: target.id.toString(), item_uid: o.item_uid, count: o.count, origin_path: o.origin_path, target_path: o.target_path, origin_account: origin.account_id.toString(), target_account: target.account_id.toString(), } } }