forked from OpenWF/SpaceNinjaServer
Compare commits
No commits in common. "main" and "fix-currency-sync" have entirely different histories.
main
...
fix-curren
0
UPDATE AND START SERVER.sh
Executable file → Normal file
0
UPDATE AND START SERVER.sh
Executable file → Normal file
0
docker-entrypoint.sh
Executable file → Normal file
0
docker-entrypoint.sh
Executable file → Normal file
3
package-lock.json
generated
3
package-lock.json
generated
@ -33,6 +33,9 @@
|
||||
"prettier": "^3.5.3",
|
||||
"tree-kill": "^1.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@types/express": "^5",
|
||||
"@types/morgan": "^1.9.9",
|
||||
|
||||
@ -4,14 +4,64 @@ import type { IPurchaseRequest } from "../../types/purchaseTypes.ts";
|
||||
import { handlePurchase } from "../../services/purchaseService.ts";
|
||||
import { getInventory } from "../../services/inventoryService.ts";
|
||||
import { sendWsBroadcastTo } from "../../services/wsService.ts";
|
||||
import { logger } from "../../utils/logger.ts";
|
||||
|
||||
export const purchaseController: RequestHandler = async (req, res) => {
|
||||
const purchaseRequest = JSON.parse(String(req.body)) as IPurchaseRequest;
|
||||
const accountId = await getAccountIdForRequest(req);
|
||||
const inventory = await getInventory(accountId);
|
||||
const response = await handlePurchase(purchaseRequest, inventory);
|
||||
await inventory.save();
|
||||
//console.log(JSON.stringify(response, null, 2));
|
||||
res.json(response);
|
||||
sendWsBroadcastTo(accountId, { update_inventory: true });
|
||||
|
||||
try {
|
||||
const inventory = await getInventory(accountId);
|
||||
|
||||
const beforePurchase = {
|
||||
RegularCredits: inventory.RegularCredits,
|
||||
PremiumCredits: inventory.PremiumCredits,
|
||||
PremiumCreditsFree: inventory.PremiumCreditsFree
|
||||
};
|
||||
|
||||
logger.debug(`Purchase attempt - Account: ${accountId}, Item: ${purchaseRequest.PurchaseParams.StoreItem}, Price: ${purchaseRequest.PurchaseParams.ExpectedPrice}, UsePremium: ${purchaseRequest.PurchaseParams.UsePremium}`);
|
||||
logger.debug(`Currency before purchase:`, beforePurchase);
|
||||
|
||||
const response = await handlePurchase(purchaseRequest, inventory);
|
||||
await inventory.save();
|
||||
|
||||
const afterPurchase = {
|
||||
RegularCredits: inventory.RegularCredits,
|
||||
PremiumCredits: inventory.PremiumCredits,
|
||||
PremiumCreditsFree: inventory.PremiumCreditsFree
|
||||
};
|
||||
|
||||
logger.debug(`Currency after purchase:`, afterPurchase);
|
||||
|
||||
res.json(response);
|
||||
|
||||
sendWsBroadcastTo(accountId, {
|
||||
update_inventory: true,
|
||||
currency_update: {
|
||||
RegularCredits: inventory.RegularCredits,
|
||||
PremiumCredits: inventory.PremiumCredits,
|
||||
PremiumCreditsFree: inventory.PremiumCreditsFree
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
logger.error(`Purchase failed for account ${accountId}:`, error);
|
||||
|
||||
if (error instanceof Error && error.message.includes('Insufficient')) {
|
||||
res.status(400).json({
|
||||
error: 'INSUFFICIENT_CURRENCY',
|
||||
message: error.message,
|
||||
details: {
|
||||
item: purchaseRequest.PurchaseParams.StoreItem,
|
||||
price: purchaseRequest.PurchaseParams.ExpectedPrice,
|
||||
usePremium: purchaseRequest.PurchaseParams.UsePremium
|
||||
}
|
||||
});
|
||||
} else {
|
||||
res.status(500).json({
|
||||
error: 'PURCHASE_FAILED',
|
||||
message: error instanceof Error ? error.message : 'Unknown error occurred'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -1254,10 +1254,18 @@ export const updateCurrency = (
|
||||
inventory: TInventoryDatabaseDocument,
|
||||
price: number,
|
||||
usePremium: boolean,
|
||||
inventoryChanges: IInventoryChanges = {}
|
||||
inventoryChanges: IInventoryChanges = {},
|
||||
validateBalance: boolean = true
|
||||
): IInventoryChanges => {
|
||||
if (price != 0 && isCurrencyTracked(inventory, usePremium)) {
|
||||
if (usePremium) {
|
||||
if (validateBalance) {
|
||||
const totalPlatinum = inventory.PremiumCredits + inventory.PremiumCreditsFree;
|
||||
if (totalPlatinum < price) {
|
||||
throw new Error(`Insufficient platinum balance. Required: ${price}, Available: ${totalPlatinum}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (inventory.PremiumCreditsFree > 0) {
|
||||
const premiumCreditsFreeDelta = Math.min(price, inventory.PremiumCreditsFree) * -1;
|
||||
inventoryChanges.PremiumCreditsFree ??= 0;
|
||||
@ -1269,6 +1277,10 @@ export const updateCurrency = (
|
||||
inventory.PremiumCredits -= price;
|
||||
logger.debug(`currency changes `, { PremiumCredits: -price });
|
||||
} else {
|
||||
if (validateBalance && inventory.RegularCredits < price) {
|
||||
throw new Error(`Insufficient credits balance. Required: ${price}, Available: ${inventory.RegularCredits}`);
|
||||
}
|
||||
|
||||
inventoryChanges.RegularCredits ??= 0;
|
||||
inventoryChanges.RegularCredits -= price;
|
||||
inventory.RegularCredits -= price;
|
||||
|
||||
@ -77,6 +77,11 @@ interface IWsMsgToClient {
|
||||
nonce_updated?: boolean;
|
||||
update_inventory?: boolean;
|
||||
logged_out?: boolean;
|
||||
currency_update?: {
|
||||
RegularCredits: number;
|
||||
PremiumCredits: number;
|
||||
PremiumCreditsFree: number;
|
||||
};
|
||||
}
|
||||
|
||||
const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user