Merge pull request #52 from cassoule/market-place

Market place
This commit is contained in:
Milo Gourvest
2025-11-24 10:18:30 +01:00
committed by GitHub
5 changed files with 71 additions and 37 deletions

View File

@@ -10,24 +10,23 @@ import {
stripMentionsOfBot,
} from "../../utils/ai.js";
import {
formatTime,
postAPOBuy,
getAPOUsers,
getAkhys,
calculateBasePrice,
calculateMaxPrice,
formatTime,
getAkhys,
getAPOUsers,
postAPOBuy,
} from "../../utils/index.js";
import { channelPointsHandler, slowmodesHandler, randomSkinPrice, initTodaysSOTD } from "../../game/points.js";
import { requestTimestamps, activeSlowmodes, activePolls, skins, activeSolitaireGames } from "../../game/state.js";
import { channelPointsHandler, initTodaysSOTD, randomSkinPrice, slowmodesHandler } from "../../game/points.js";
import { activePolls, activeSlowmodes, requestTimestamps, skins } from "../../game/state.js";
import {
flopoDB,
getUser,
getAllUsers,
updateManyUsers,
insertUser,
updateUserAvatar,
getAllSkins,
getAllUsers,
getUser,
hardUpdateSkin,
updateManyUsers,
updateUserAvatar,
} from "../../database/index.js";
import { client } from "../client.js";
import { autoSolveMoves } from "../../game/solitaire.js";
@@ -57,7 +56,7 @@ export async function handleMessageCreate(message, client, io) {
// --- Main Guild Features (Points & Slowmode) ---
if (message.guildId === process.env.GUILD_ID) {
// Award points for activity
const pointsAwarded = await channelPointsHandler(message);
const pointsAwarded = channelPointsHandler(message);
if (pointsAwarded) {
io.emit("data-updated", { table: "users", action: "update" });
}

View File

@@ -137,17 +137,8 @@ export const stmtBids = flopoDB.prepare(`
stmtBids.run();
export const getMarketOffers = flopoDB.prepare(`
SELECT market_offers.*,
skins.displayName AS skinName,
skins.displayIcon AS skinIcon,
seller.username AS sellerName,
seller.globalName AS sellerGlobalName,
buyer.username AS buyerName,
buyer.globalName AS buyerGlobalName
SELECT *
FROM market_offers
JOIN skins ON skins.uuid = market_offers.skin_uuid
JOIN users AS seller ON seller.id = market_offers.seller_id
LEFT JOIN users AS buyer ON buyer.id = market_offers.buyer_id
ORDER BY market_offers.posted_at DESC
`);
@@ -166,6 +157,21 @@ export const getMarketOfferById = flopoDB.prepare(`
WHERE market_offers.id = ?
`);
export const getMarketOffersBySkin = flopoDB.prepare(`
SELECT market_offers.*,
skins.displayName AS skinName,
skins.displayIcon AS skinIcon,
seller.username AS sellerName,
seller.globalName AS sellerGlobalName,
buyer.username AS buyerName,
buyer.globalName AS buyerGlobalName
FROM market_offers
JOIN skins ON skins.uuid = market_offers.skin_uuid
JOIN users AS seller ON seller.id = market_offers.seller_id
LEFT JOIN users AS buyer ON buyer.id = market_offers.buyer_id
WHERE market_offers.skin_uuid = ?
`);
export const insertMarketOffer = flopoDB.prepare(`
INSERT INTO market_offers (id, skin_uuid, seller_id, starting_price, buyout_price, status, opening_at, closing_at)
VALUES (@id, @skin_uuid, @seller_id, @starting_price, @buyout_price, @status, @opening_at, @closing_at)
@@ -234,7 +240,8 @@ export const stmtLogs = flopoDB.prepare(`
action TEXT,
target_user_id TEXT REFERENCES users,
coins_amount INTEGER,
user_new_amount INTEGER
user_new_amount INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
`);
stmtLogs.run();
@@ -332,14 +339,14 @@ export const stmtSOTDStats = flopoDB.prepare(`
stmtSOTDStats.run();
export const getAllSOTDStats = flopoDB.prepare(`SELECT sotd_stats.*, users.globalName
FROM sotd_stats
JOIN users ON users.id = sotd_stats.user_id
ORDER BY score DESC, moves ASC, time ASC`);
FROM sotd_stats
JOIN users ON users.id = sotd_stats.user_id
ORDER BY score DESC, moves ASC, time ASC`);
export const getUserSOTDStats = flopoDB.prepare(`SELECT *
FROM sotd_stats
WHERE user_id = ?`);
export const insertSOTDStats = flopoDB.prepare(`INSERT INTO sotd_stats (id, user_id, time, moves, score)
VALUES (@id, @user_id, @time, @moves, @score)`);
VALUES (@id, @user_id, @time, @moves, @score)`);
export const clearSOTDStats = flopoDB.prepare(`DELETE
FROM sotd_stats`);
export const deleteUserSOTDStats = flopoDB.prepare(`DELETE
@@ -367,7 +374,7 @@ export async function pruneOldLogs() {
FROM logs
WHERE id IN (SELECT id
FROM (SELECT id,
ROW_NUMBER() OVER (ORDER BY id DESC) AS rn
ROW_NUMBER() OVER (ORDER BY created_at DESC) AS rn
FROM logs
WHERE user_id = ?)
WHERE rn > ${process.env.LOGS_BY_USER})

View File

@@ -1,16 +1,17 @@
import {
getUser,
updateUserCoins,
insertLog,
getAllSkins,
insertSOTD,
clearSOTDStats,
getAllSOTDStats,
deleteSOTD,
getAllSkins,
getAllSOTDStats,
getUser,
insertGame,
insertLog,
insertSOTD,
pruneOldLogs,
updateUserCoins
} from "../database/index.js";
import { messagesTimestamps, activeSlowmodes, skins } from "./state.js";
import { deal, createSeededRNG, seededShuffle, createDeck } from "./solitaire.js";
import { activeSlowmodes, messagesTimestamps, skins } from "./state.js";
import { createDeck, createSeededRNG, deal, seededShuffle } from "./solitaire.js";
/**
* Handles awarding points (coins) to users for their message activity.
@@ -65,6 +66,8 @@ export async function channelPointsHandler(message) {
user_new_amount: newCoinTotal,
});
await pruneOldLogs();
return true; // Indicate that points were awarded
}

View File

@@ -6,6 +6,9 @@ import {
getAllAkhys,
getAllUsers,
getLogs,
getMarketOffersBySkin,
getOfferBids,
getSkin,
getUser,
getUserElo,
getUserGames,
@@ -219,6 +222,19 @@ export function apiRoutes(client, io) {
router.get("/user/:id/inventory", (req, res) => {
try {
const inventory = getUserInventory.all({ user_id: req.params.id });
inventory.forEach((skin) => {
const marketOffers = getMarketOffersBySkin.all(skin.uuid);
marketOffers.forEach((offer) => {
offer.skin = getSkin.get(offer.skin_uuid);
offer.seller = getUser.get(offer.seller_id);
offer.buyer = getUser.get(offer.buyer_id) || null;
offer.bids = getOfferBids.all(offer.id) || {};
offer.bids.forEach((bid) => {
bid.bidder = getUser.get(bid.bidder_id);
});
});
skin.offers = marketOffers || {};
});
res.json({ inventory });
} catch (error) {
res.status(500).json({ error: "Failed to fetch inventory." });

View File

@@ -5,7 +5,7 @@ import express from "express";
// --- Utility and API Imports ---
// --- Discord.js Builder Imports ---
import { ButtonStyle } from "discord.js";
import { getMarketOfferById, getMarketOffers, getOfferBids } from "../../database/index.js";
import { getMarketOfferById, getMarketOffers, getOfferBids, getSkin, getUser } from "../../database/index.js";
// Create a new router instance
const router = express.Router();
@@ -20,6 +20,15 @@ export function marketRoutes(client, io) {
router.get("/offers", async (req, res) => {
try {
const offers = getMarketOffers.all();
offers.forEach((offer) => {
offer.skin = getSkin.get(offer.skin_uuid);
offer.seller = getUser.get(offer.seller_id);
offer.buyer = getUser.get(offer.buyer_id) || null;
offer.bids = getOfferBids.all(offer.id) || {};
offer.bids.forEach((bid) => {
bid.bidder = getUser.get(bid.bidder_id);
});
});
res.status(200).send({ offers });
} catch (e) {
res.status(500).send({ error: e });