177 lines
5.0 KiB
TypeScript
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(),
|
|
}
|
|
}
|
|
}
|