mirror of
https://github.com/cassoule/flopobot_v2.git
synced 2026-01-18 16:37:40 +01:00
wip: case opening
This commit is contained in:
@@ -603,9 +603,9 @@ export const getAllAkhys = flopoDB.prepare(
|
||||
----------------------------*/
|
||||
export const insertSkin = flopoDB.prepare(
|
||||
`INSERT INTO skins (uuid, displayName, contentTierUuid, displayIcon, user_id, tierRank, tierColor, tierText,
|
||||
basePrice, currentLvl, currentChroma, currentPrice, maxPrice)
|
||||
basePrice, maxPrice)
|
||||
VALUES (@uuid, @displayName, @contentTierUuid, @displayIcon, @user_id, @tierRank, @tierColor, @tierText,
|
||||
@basePrice, @currentLvl, @currentChroma, @currentPrice, @maxPrice)`,
|
||||
@basePrice, @maxPrice)`,
|
||||
);
|
||||
export const updateSkin = flopoDB.prepare(
|
||||
`UPDATE skins
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
getMarketOffersBySkin,
|
||||
getOfferBids,
|
||||
getSkin,
|
||||
getAllAvailableSkins,
|
||||
getUser,
|
||||
getUserElo,
|
||||
getUserGames,
|
||||
@@ -116,14 +117,60 @@ export function apiRoutes(client, io) {
|
||||
|
||||
router.get("/carousel-skins", (req, res) => {
|
||||
try {
|
||||
const dbSkins = getAllAvailableSkins.all();
|
||||
const filteredSkins = skins.filter(
|
||||
(s) => s.displayIcon !== null && s.displayName.toLowerCase().includes("champions"),
|
||||
(s) => dbSkins.find((dbSkin) => dbSkin.uuid === s.uuid),
|
||||
);
|
||||
filteredSkins.forEach((s) => {
|
||||
let dbSKin = getSkin.get(s.uuid);
|
||||
s.tierColor = dbSKin?.tierColor;
|
||||
let dbSkin = getSkin.get(s.uuid);
|
||||
s.tierColor = dbSkin?.tierColor;
|
||||
});
|
||||
res.json(filteredSkins);
|
||||
const tierWeights = {
|
||||
"12683d76-48d7-84a3-4e09-6985794f0445": 50, // Select
|
||||
"0cebb8be-46d7-c12a-d306-e9907bfc5a25": 30, // Deluxe
|
||||
"60bca009-4182-7998-dee7-b8a2558dc369": 15, // Premium
|
||||
"e046854e-406c-37f4-6607-19a9ba8426fc": 4, // Exclusive
|
||||
"411e4a55-4e59-7757-41f0-86a53f101bb5": 1, // Ultra
|
||||
}
|
||||
filteredSkins.forEach((s) => {
|
||||
s.weight = tierWeights[s.tierUuid] ?? 1; // fallback if missing
|
||||
});
|
||||
|
||||
function weightedSample(arr, count) {
|
||||
let totalWeight = arr.reduce((sum, x) => sum + x.weight, 0);
|
||||
const list = [...arr];
|
||||
const result = [];
|
||||
|
||||
for (let i = 0; i < count && list.length > 0; i++) {
|
||||
let r = Math.random() * totalWeight;
|
||||
let running = 0;
|
||||
let pickIndex = -1;
|
||||
|
||||
for (let j = 0; j < list.length; j++) {
|
||||
running += list[j].weight;
|
||||
if (r <= running) {
|
||||
pickIndex = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pickIndex < 0) break;
|
||||
|
||||
const picked = list.splice(pickIndex, 1)[0];
|
||||
result.push(picked);
|
||||
|
||||
// Subtract removed weight
|
||||
totalWeight -= picked.weight;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const selectedSkins = weightedSample(filteredSkins, 100);
|
||||
|
||||
const randomSelectedSkinIndex = Math.floor(Math.random() * selectedSkins.length);
|
||||
const randomSelectedSkinUuid = selectedSkins[randomSelectedSkinIndex].uuid;
|
||||
res.json({ selectedSkins, randomSelectedSkinUuid, randomSelectedSkinIndex });
|
||||
} catch (error) {
|
||||
console.error("Error fetching skins:", error);
|
||||
res.status(500).json({ error: "Failed to fetch skins." });
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
getUser,
|
||||
insertBid,
|
||||
insertLog,
|
||||
insertMarketOffer,
|
||||
updateUserCoins,
|
||||
} from "../../database/index.js";
|
||||
import { emitMarketUpdate } from "../socket.js";
|
||||
@@ -68,12 +69,35 @@ export function marketRoutes(client, io) {
|
||||
});
|
||||
|
||||
router.post("/place-offer", async (req, res) => {
|
||||
const { seller_id, skin_uuid, starting_price, delay, duration, timestamp } = req.body;
|
||||
const now = Date.now();
|
||||
try {
|
||||
const skin = getSkin.get(skin_uuid);
|
||||
if (!skin) return res.status(404).send({ error: "Skin not found" });
|
||||
const seller = getUser.get(seller_id);
|
||||
if (!seller) return res.status(404).send({ error: "Seller not found" });
|
||||
if (skin.user_id !== seller.id) return res.status(403).send({ error: "You do not own this skin" });
|
||||
|
||||
const opening_at = now + delay;
|
||||
const closing_at = opening_at + duration;
|
||||
|
||||
insertMarketOffer.run({
|
||||
id: Date.now() + '-' + seller.id + '-' + skin.uuid,
|
||||
skin_uuid: skin.uuid,
|
||||
seller_id: seller.id,
|
||||
starting_price: starting_price,
|
||||
buyout_price: null,
|
||||
status: delay > 0 ? "pending" : "open",
|
||||
opening_at: opening_at,
|
||||
closing_at: closing_at,
|
||||
});
|
||||
// Placeholder for placing an offer logic
|
||||
// Extract data from req.body and process accordingly
|
||||
res.status(200).send({ message: "Offer placed successfully" });
|
||||
await emitMarketUpdate();
|
||||
res.status(200).send({ message: "Offre créée avec succès" });
|
||||
} catch (e) {
|
||||
res.status(500).send({ error: e });
|
||||
console.log(e)
|
||||
return res.status(500).send({ error: e });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
updateUserCoins,
|
||||
} from "../database/index.js";
|
||||
import { activeInventories, activePredis, activeSearchs, pokerRooms, skins } from "../game/state.js";
|
||||
import { emitMarketUpdate } from "../server/socket.js";
|
||||
|
||||
export async function InstallGlobalCommands(appId, commands) {
|
||||
// API endpoint to overwrite global commands
|
||||
@@ -119,7 +120,7 @@ export async function getAkhys(client) {
|
||||
*/
|
||||
export function setupCronJobs(client, io) {
|
||||
// Every 5 minutes: Update market offers
|
||||
cron.schedule("*/1 * * * *", () => {
|
||||
cron.schedule("* * * * *", () => {
|
||||
console.log("[Cron] Checking market offers for updates...");
|
||||
handleMarketOffersUpdate();
|
||||
});
|
||||
@@ -258,38 +259,55 @@ export async function postAPOBuy(userId, amount) {
|
||||
function handleMarketOffersUpdate() {
|
||||
const now = Date.now();
|
||||
const offers = getMarketOffers.all();
|
||||
offers.forEach((offer) => {
|
||||
console.log(`[Market Cron] Checking offer ID: ${offer.id}, Status: ${offer.status}`);
|
||||
|
||||
offers.forEach(async (offer) => {
|
||||
if (now >= offer.opening_at && offer.status === "pending") {
|
||||
updateMarketOffer.run({ id: offer.id, final_price: null, buyer_id: null, status: "open" });
|
||||
//TODO: Maybe notify seller that their offer is now open
|
||||
await emitMarketUpdate();
|
||||
}
|
||||
if (now >= offer.closing_at && offer.status !== "closed") {
|
||||
const bids = getOfferBids.all(offer.id);
|
||||
const lastBid = bids[0];
|
||||
const seller = getUser.get(offer.seller_id);
|
||||
const buyer = getUser.get(lastBid.bidder_id);
|
||||
|
||||
try {
|
||||
// Change skin ownership
|
||||
const skin = getSkin.get(offer.skin_uuid);
|
||||
if (!skin) throw new Error(`Skin not found for offer ID: ${offer.id}`);
|
||||
updateSkin.run({
|
||||
user_id: buyer.id,
|
||||
currentLvl: skin.currentLvl,
|
||||
currentChroma: skin.currentChroma,
|
||||
currentPrice: skin.currentPrice,
|
||||
uuid: skin.uuid,
|
||||
});
|
||||
if (bids.length === 0) {
|
||||
// No bids placed, mark as closed without a sale
|
||||
updateMarketOffer.run({
|
||||
id: offer.id,
|
||||
buyer_id: buyer.id,
|
||||
final_price: lastBid.offer_amount,
|
||||
buyer_id: null,
|
||||
final_price: null,
|
||||
status: "closed",
|
||||
});
|
||||
const newUserCoins = seller.coins + lastBid.offer_amount;
|
||||
updateUserCoins.run({ id: seller.id, coins: newUserCoins });
|
||||
//TODO: Notify users in DMs
|
||||
} catch (e) {
|
||||
console.error(`[Market Cron] Error processing offer ID: ${offer.id}`, e);
|
||||
await emitMarketUpdate();
|
||||
} else {
|
||||
const lastBid = bids[0];
|
||||
const seller = getUser.get(offer.seller_id);
|
||||
const buyer = getUser.get(lastBid.bidder_id);
|
||||
|
||||
try {
|
||||
// Change skin ownership
|
||||
const skin = getSkin.get(offer.skin_uuid);
|
||||
if (!skin) throw new Error(`Skin not found for offer ID: ${offer.id}`);
|
||||
updateSkin.run({
|
||||
user_id: buyer.id,
|
||||
currentLvl: skin.currentLvl,
|
||||
currentChroma: skin.currentChroma,
|
||||
currentPrice: skin.currentPrice,
|
||||
uuid: skin.uuid,
|
||||
});
|
||||
updateMarketOffer.run({
|
||||
id: offer.id,
|
||||
buyer_id: buyer.id,
|
||||
final_price: lastBid.offer_amount,
|
||||
status: "closed",
|
||||
});
|
||||
const newUserCoins = seller.coins + lastBid.offer_amount;
|
||||
updateUserCoins.run({ id: seller.id, coins: newUserCoins });
|
||||
//TODO: Notify users in DMs
|
||||
await emitMarketUpdate();
|
||||
} catch (e) {
|
||||
console.error(`[Market Cron] Error processing offer ID: ${offer.id}`, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user