lifeto-shop/src/lib/lifeto/order_manager.ts

177 lines
5.0 KiB
TypeScript
Raw Normal View History

2025-06-20 05:41:10 +00:00
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'
2022-07-07 07:54:36 +00:00
export interface OrderDetails {
2025-06-20 05:41:10 +00:00
item_uid: string | 'galders'
count: number
origin_path: string
target_path: string
2022-07-07 07:54:36 +00:00
}
2025-06-20 05:41:10 +00:00
const notSupported = new InvalidOrder('not supported yet')
const notFound = new InvalidOrder('character not found')
2022-07-07 07:54:36 +00:00
export class OrderTracker implements Serializable<OrderTracker> {
2025-06-20 05:41:10 +00:00
orders: { [key: string]: Order } = {}
2022-07-07 07:54:36 +00:00
2025-06-20 05:41:10 +00:00
async tick(r: RefStore, api: LTOApi): Promise<any> {
2022-07-07 07:54:36 +00:00
let hasDirty = false
2025-06-20 05:41:10 +00:00
for (const [id, order] of Object.entries(this.orders)) {
if (order.status() === 'SUCCESS' || order.status() === 'ERROR') {
2022-07-07 07:54:36 +00:00
hasDirty = true
delete this.orders[id]
}
2025-06-20 05:41:10 +00:00
order.tick(r, api)
2022-07-07 07:54:36 +00:00
}
2025-06-20 05:41:10 +00:00
if (hasDirty) {
2022-07-07 07:54:36 +00:00
r.dirty.value++
}
return
}
parse(s: any): OrderTracker {
2025-06-20 05:41:10 +00:00
if (s === undefined) {
2022-07-07 07:54:36 +00:00
return new OrderTracker()
}
2025-06-20 05:41:10 +00:00
if (s.orders === undefined) {
2022-07-07 07:54:36 +00:00
return new OrderTracker()
}
this.orders = {}
const raw: Order[] = Object.values(s.orders)
2025-06-20 05:41:10 +00:00
for (const o of raw) {
let newOrder: Order | undefined
if (o.details) {
if (o.status() === 'SUCCESS' || o.status() === 'ERROR') {
2022-07-07 07:54:36 +00:00
continue
}
2025-06-20 05:41:10 +00:00
switch (o.order_type) {
case 'InternalXfer':
2022-07-07 07:54:36 +00:00
newOrder = new InternalXfer(o.details).parse(o)
2025-06-20 05:41:10 +00:00
break
case 'BankItem':
2022-07-07 07:54:36 +00:00
newOrder = new BankItem(o.details).parse(o)
2025-06-20 05:41:10 +00:00
break
case 'MarketMove':
2022-08-10 01:39:44 +00:00
newOrder = new MarketMove(o.details).parse(o)
2025-06-20 06:18:37 +00:00
break
2025-06-20 05:41:10 +00:00
case 'MarketMoveToChar':
2022-08-10 01:39:44 +00:00
newOrder = new MarketMoveToChar(o.details).parse(o)
2025-06-20 05:41:10 +00:00
break
case 'InvalidOrder':
newOrder = new InvalidOrder('').parse(o)
break
2022-07-07 07:54:36 +00:00
}
2025-06-20 05:41:10 +00:00
if (newOrder) {
2022-07-07 07:54:36 +00:00
this.orders[newOrder.action_id] = newOrder
}
}
}
return this
}
}
export class OrderSender {
2024-08-12 01:13:42 +00:00
constructor(
private orders: OrderTracker,
2025-06-20 05:41:10 +00:00
private chars: Map<string, TricksterCharacter>,
) {}
2022-07-07 07:54:36 +00:00
2025-06-20 05:41:10 +00:00
send(o: OrderDetails): Order {
2022-07-07 07:54:36 +00:00
const formed = this.form(o)
2024-08-12 01:13:42 +00:00
this.orders.orders[formed.action_id] = formed
2022-07-07 07:54:36 +00:00
return formed
}
2025-06-20 05:41:10 +00:00
form(o: OrderDetails): Order {
2022-07-07 07:54:36 +00:00
// bank to bank
2025-06-20 05:41:10 +00:00
if (pathIsBank(o.origin_path) && pathIsBank(o.target_path)) {
2022-07-07 07:54:36 +00:00
return this.bank_to_bank(o)
}
// bank to user
2025-06-20 05:41:10 +00:00
if (pathIsBank(o.origin_path) && !pathIsBank(o.target_path)) {
2022-07-07 07:54:36 +00:00
return this.bank_to_user(o)
}
// user to bank
2025-06-20 05:41:10 +00:00
if (!pathIsBank(o.origin_path) && pathIsBank(o.target_path)) {
2022-07-07 07:54:36 +00:00
return this.user_to_bank(o)
}
// user to user
2025-06-20 05:41:10 +00:00
if (!pathIsBank(o.origin_path) && !pathIsBank(o.target_path)) {
2022-07-07 07:54:36 +00:00
return this.user_to_user(o)
}
return notSupported
}
2025-06-20 05:41:10 +00:00
bank_to_bank(o: OrderDetails): Order {
2024-08-12 01:13:42 +00:00
const origin = this.chars.get(o.origin_path)
const target = this.chars.get(o.target_path)
2025-06-20 05:41:10 +00:00
if (!(origin && target)) {
2022-08-10 01:39:44 +00:00
return notFound
}
return new MarketMove(this.transformInternalOrder(o))
2022-07-07 07:54:36 +00:00
}
2025-06-20 05:41:10 +00:00
bank_to_user(o: OrderDetails): Order {
2022-07-07 07:54:36 +00:00
// get the uid of the bank
2024-08-12 01:13:42 +00:00
const origin = this.chars.get(o.origin_path)
const target = this.chars.get(o.target_path)
2025-06-20 05:41:10 +00:00
if (!(origin && target)) {
2022-07-07 07:54:36 +00:00
return notFound
}
2025-06-20 05:41:10 +00:00
const [_account, _name] = splitPath(target.path)
2024-04-09 03:42:34 +00:00
/*if(account != origin.path) {
2022-08-10 01:39:44 +00:00
return new MarketMoveToChar(this.transformInternalOrder(o))
2024-04-09 03:42:34 +00:00
}*/
2022-08-10 01:39:44 +00:00
return new InternalXfer(this.transformInternalOrder(o))
2022-07-07 07:54:36 +00:00
}
2025-06-20 05:41:10 +00:00
user_to_bank(o: OrderDetails): Order {
2024-08-12 01:13:42 +00:00
const origin = this.chars.get(o.origin_path)
const target = this.chars.get(o.target_path)
2025-06-20 05:41:10 +00:00
if (!(origin && target)) {
2022-07-07 07:54:36 +00:00
return notFound
}
2025-06-20 05:41:10 +00:00
const [_account, _name] = splitPath(origin.path)
2024-04-09 03:42:34 +00:00
/*if(account != target.path) {
2022-08-10 01:39:44 +00:00
return new MarketMove(this.transformInternalOrder(o))
2024-04-09 03:42:34 +00:00
}*/
2022-08-10 01:39:44 +00:00
return new BankItem(this.transformInternalOrder(o))
2022-07-07 07:54:36 +00:00
}
2025-06-20 05:41:10 +00:00
user_to_user(o: OrderDetails): Order {
2024-08-12 01:13:42 +00:00
const origin = this.chars.get(o.origin_path)
const target = this.chars.get(o.target_path)
2025-06-20 05:41:10 +00:00
if (!(origin && target)) {
2022-08-10 01:39:44 +00:00
return notFound
}
2024-04-09 03:42:34 +00:00
// return new MarketMoveToChar(this.transformInternalOrder(o))
return new InternalXfer(this.transformInternalOrder(o))
2022-07-07 07:54:36 +00:00
}
2025-06-20 05:41:10 +00:00
private transformInternalOrder(o: OrderDetails): TxnDetails {
2025-06-20 06:18:37 +00:00
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}`)
}
2022-07-07 07:54:36 +00:00
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,
2022-08-10 01:39:44 +00:00
origin_account: origin.account_id.toString(),
target_account: target.account_id.toString(),
2022-07-07 07:54:36 +00:00
}
}
}