lifeto-shop/src/lib/lifeto/order_manager.ts
2025-06-20 01:18:37 -05:00

177 lines
5.0 KiB
TypeScript

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<OrderTracker> {
orders: { [key: string]: Order } = {}
async tick(r: RefStore, api: LTOApi): Promise<any> {
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<string, TricksterCharacter>,
) {}
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(),
}
}
}