mirror of
https://github.com/djdevin/recflare.git
synced 2026-10-25 23:18:51 -07:00
[econ] owner currency 0 amount purchase
This commit is contained in:
@@ -6651,7 +6651,10 @@ const app = new Hono<App>({ strict: false })
|
||||
'NOBODY IS PAID — unlike the token sale, the price does not reach the room’s owner.',
|
||||
'',
|
||||
'`RequestedPurchaseCurrencyId` must be the key’s own `PurchaseCurrencyId` and',
|
||||
'`RequestedPrice` its `Price`. A key priced in TOKENS (a null `PurchaseCurrencyId`)',
|
||||
'`RequestedPrice` its `Price` — except that the room’s creator or a CO-OWNER gets',
|
||||
'their own room’s keys free: the client asks them `RequestedPrice=0` (the stored',
|
||||
'price is accepted too) and nothing is subtracted.',
|
||||
'A key priced in TOKENS (a null `PurchaseCurrencyId`)',
|
||||
'is not sold here — that is `GET /api/storefronts/v1/buyRoomKey`.',
|
||||
'',
|
||||
'Answers the client’s `RoomKeyPurchaseWithCurrencyResponseDTO`, a bare object with no',
|
||||
@@ -6710,13 +6713,21 @@ const app = new Hono<App>({ strict: false })
|
||||
if (requestedCurrencyId.toLowerCase() !== key.PurchaseCurrencyId.toLowerCase()) {
|
||||
return answer(false)
|
||||
}
|
||||
if (int(body.RequestedPrice) !== key.Price) return answer(false)
|
||||
// The room's creator and co-owners get their own room's keys free, as with the token
|
||||
// sale — the client asks them `RequestedPrice=0` — and are never charged.
|
||||
const canManage = await canManageRoomById(c.env.DB, key.RoomId, id)
|
||||
if (canManage === null) return answer(false)
|
||||
const requestedPrice = int(body.RequestedPrice)
|
||||
if (requestedPrice !== key.Price && !(canManage && requestedPrice === 0)) {
|
||||
return answer(false)
|
||||
}
|
||||
|
||||
// Claim the key BEFORE charging, as the token sale does: the insert is atomic, so of
|
||||
// two concurrent buys only one is charged. A buyer who cannot pay gives it back.
|
||||
if (!(await claimRoomKey(c.env.DB, id, key.RoomKeyId))) return answer(false)
|
||||
if (
|
||||
key.Price > 0 &&
|
||||
!canManage &&
|
||||
!(await spendRoomCurrency(c.env.DB, key.PurchaseCurrencyId, id, key.Price))
|
||||
) {
|
||||
await releaseRoomKey(c.env.DB, id, key.RoomKeyId)
|
||||
|
||||
@@ -3238,6 +3238,24 @@ describe('econ endpoints', () => {
|
||||
)
|
||||
expect(await held(coin, 7501)).toBe(500)
|
||||
|
||||
// A non-manager cannot buy it for 0; the room's managers can — the co-owner at the 0
|
||||
// the client asks them, the owner at the stored price — and nothing is subtracted.
|
||||
expect(await (await purchase('7502', key.RoomKeyId, 0, coin)).json()).toEqual(
|
||||
refused(7502, coin, 999)
|
||||
)
|
||||
await give(coin, 2, 10)
|
||||
const coOwner = (await (await purchase('2', key.RoomKeyId, 0, coin)).json()) as {
|
||||
Balance: { Balance: number }
|
||||
RoomKeyResponse: { Status: number }
|
||||
}
|
||||
expect(coOwner.RoomKeyResponse.Status).toBe(0)
|
||||
expect(coOwner.Balance.Balance).toBe(10)
|
||||
const own = (await (await purchase('1', key.RoomKeyId, 1000, coin)).json()) as typeof coOwner
|
||||
expect(own.RoomKeyResponse.Status).toBe(0)
|
||||
expect(own.Balance.Balance).toBe(0)
|
||||
expect(await holders(key.RoomKeyId)).toEqual([1, 2, 7501])
|
||||
expect([await held(coin, 1), await held(coin, 2)]).toEqual([0, 10])
|
||||
|
||||
await env.DB.prepare('DELETE FROM room_key_player').run()
|
||||
await env.DB.prepare('DELETE FROM room_key').run()
|
||||
await env.DB.prepare('DELETE FROM room_balance WHERE currency_id IN (?1, ?2)')
|
||||
|
||||
Reference in New Issue
Block a user