mirror of
https://github.com/cassoule/flopobot_v2.git
synced 2026-03-18 21:40:27 +01:00
@@ -584,9 +584,11 @@ export const updateUser = flopoDB.prepare(
|
||||
export const updateUserAvatar = flopoDB.prepare("UPDATE users SET avatarUrl = @avatarUrl WHERE id = @id");
|
||||
export const queryDailyReward = flopoDB.prepare(`UPDATE users
|
||||
SET dailyQueried = 1
|
||||
WHERE id = ?`);
|
||||
WHERE id = ?`
|
||||
);
|
||||
export const resetDailyReward = flopoDB.prepare(`UPDATE users
|
||||
SET dailyQueried = 0`);
|
||||
SET dailyQueried = 0`
|
||||
);
|
||||
export const updateUserCoins = flopoDB.prepare("UPDATE users SET coins = @coins WHERE id = @id");
|
||||
export const getUser = flopoDB.prepare(
|
||||
"SELECT users.*,elos.elo FROM users LEFT JOIN elos ON elos.id = users.id WHERE users.id = ?",
|
||||
@@ -647,7 +649,6 @@ export const getMarketOffers = flopoDB.prepare(`
|
||||
FROM market_offers
|
||||
ORDER BY market_offers.posted_at DESC
|
||||
`);
|
||||
|
||||
export const getMarketOfferById = flopoDB.prepare(`
|
||||
SELECT market_offers.*,
|
||||
skins.displayName AS skinName,
|
||||
@@ -662,7 +663,6 @@ export const getMarketOfferById = flopoDB.prepare(`
|
||||
LEFT JOIN users AS buyer ON buyer.id = market_offers.buyer_id
|
||||
WHERE market_offers.id = ?
|
||||
`);
|
||||
|
||||
export const getMarketOffersBySkin = flopoDB.prepare(`
|
||||
SELECT market_offers.*,
|
||||
skins.displayName AS skinName,
|
||||
@@ -677,12 +677,10 @@ export const getMarketOffersBySkin = flopoDB.prepare(`
|
||||
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)
|
||||
`);
|
||||
|
||||
export const updateMarketOffer = flopoDB.prepare(`
|
||||
UPDATE market_offers
|
||||
SET final_price = @final_price,
|
||||
@@ -690,7 +688,6 @@ export const updateMarketOffer = flopoDB.prepare(`
|
||||
buyer_id = @buyer_id
|
||||
WHERE id = @id
|
||||
`);
|
||||
|
||||
export const deleteMarketOffer = flopoDB.prepare(`
|
||||
DELETE
|
||||
FROM market_offers
|
||||
@@ -708,25 +705,21 @@ export const getBids = flopoDB.prepare(`
|
||||
JOIN users AS bidder ON bidder.id = bids.bidder_id
|
||||
ORDER BY bids.offer_amount DESC, bids.offered_at ASC
|
||||
`);
|
||||
|
||||
export const getBidById = flopoDB.prepare(`
|
||||
SELECT bids.*
|
||||
FROM bids
|
||||
WHERE bids.id = ?
|
||||
`);
|
||||
|
||||
export const getOfferBids = flopoDB.prepare(`
|
||||
SELECT bids.*
|
||||
FROM bids
|
||||
WHERE bids.market_offer_id = ?
|
||||
ORDER BY bids.offer_amount DESC, bids.offered_at ASC
|
||||
`);
|
||||
|
||||
export const insertBid = flopoDB.prepare(`
|
||||
INSERT INTO bids (id, bidder_id, market_offer_id, offer_amount)
|
||||
VALUES (@id, @bidder_id, @market_offer_id, @offer_amount)
|
||||
`);
|
||||
|
||||
export const deleteBid = flopoDB.prepare(`
|
||||
DELETE
|
||||
FROM bids
|
||||
@@ -742,7 +735,6 @@ export const insertManyUsers = flopoDB.transaction((users) => {
|
||||
insertUser.run(user);
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
export const updateManyUsers = flopoDB.transaction((users) => {
|
||||
for (const user of users)
|
||||
try {
|
||||
@@ -751,7 +743,6 @@ export const updateManyUsers = flopoDB.transaction((users) => {
|
||||
console.log(`User update failed`);
|
||||
}
|
||||
});
|
||||
|
||||
export const insertManySkins = flopoDB.transaction((skins) => {
|
||||
for (const skin of skins)
|
||||
try {
|
||||
@@ -791,14 +782,16 @@ export const getUserGames = flopoDB.prepare(
|
||||
ELOS
|
||||
----------------------------*/
|
||||
export const insertElos = flopoDB.prepare(`INSERT INTO elos (id, elo)
|
||||
VALUES (@id, @elo)`);
|
||||
VALUES (@id, @elo)`
|
||||
);
|
||||
export const getElos = flopoDB.prepare(`SELECT *
|
||||
FROM elos`);
|
||||
FROM elos`
|
||||
);
|
||||
export const getUserElo = flopoDB.prepare(`SELECT *
|
||||
FROM elos
|
||||
WHERE id = @id`);
|
||||
WHERE id = @id`
|
||||
);
|
||||
export const updateElo = flopoDB.prepare("UPDATE elos SET elo = @elo WHERE id = @id");
|
||||
|
||||
export const getUsersByElo = flopoDB.prepare(
|
||||
"SELECT * FROM users JOIN elos ON elos.id = users.id ORDER BY elos.elo DESC",
|
||||
);
|
||||
@@ -808,14 +801,15 @@ export const getUsersByElo = flopoDB.prepare(
|
||||
----------------------------*/
|
||||
export const getSOTD = flopoDB.prepare(`SELECT *
|
||||
FROM sotd
|
||||
WHERE id = '0'`);
|
||||
WHERE id = '0'`
|
||||
);
|
||||
export const insertSOTD =
|
||||
flopoDB.prepare(`INSERT INTO sotd (id, tableauPiles, foundationPiles, stockPile, wastePile, seed)
|
||||
VALUES (0, @tableauPiles, @foundationPiles, @stockPile, @wastePile, @seed)`);
|
||||
export const deleteSOTD = flopoDB.prepare(`DELETE
|
||||
FROM sotd
|
||||
WHERE id = '0'`);
|
||||
|
||||
WHERE id = '0'`
|
||||
);
|
||||
export const getAllSOTDStats = flopoDB.prepare(`SELECT sotd_stats.*, users.globalName
|
||||
FROM sotd_stats
|
||||
JOIN users ON users.id = sotd_stats.user_id
|
||||
@@ -831,10 +825,6 @@ export const deleteUserSOTDStats = flopoDB.prepare(`DELETE
|
||||
FROM sotd_stats
|
||||
WHERE user_id = ?`);
|
||||
|
||||
/* -------------------------
|
||||
Market queries already declared above (kept for completeness)
|
||||
----------------------------*/
|
||||
|
||||
/* -------------------------
|
||||
pruneOldLogs
|
||||
----------------------------*/
|
||||
|
||||
@@ -20,6 +20,8 @@ export let pokerRooms = {};
|
||||
// Stores active erinyes rooms, keyed by a unique room ID (uuidv4).
|
||||
export let erinyesRooms = {};
|
||||
|
||||
export let monkePaths = {};
|
||||
|
||||
// --- User and Session State ---
|
||||
|
||||
// Stores active user inventories for paginated embeds, keyed by the interaction ID.
|
||||
|
||||
@@ -11,6 +11,7 @@ import { solitaireRoutes } from "./routes/solitaire.js";
|
||||
import { getSocketIo } from "./socket.js";
|
||||
import { blackjackRoutes } from "./routes/blackjack.js";
|
||||
import { marketRoutes } from "./routes/market.js";
|
||||
import { monkeRoutes } from "./routes/monke.js";
|
||||
|
||||
// --- EXPRESS APP INITIALIZATION ---
|
||||
const app = express();
|
||||
@@ -62,4 +63,7 @@ app.use("/api/market-place", marketRoutes(client, io));
|
||||
// erinyes-specific routes
|
||||
// app.use("/api/erinyes", erinyesRoutes(client, io));
|
||||
|
||||
// monke-specific routes
|
||||
app.use("/api/monke-game", monkeRoutes(client, io));
|
||||
|
||||
export { app };
|
||||
|
||||
134
src/server/routes/monke.js
Normal file
134
src/server/routes/monke.js
Normal file
@@ -0,0 +1,134 @@
|
||||
import express from "express";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { monkePaths } from "../../game/state.js";
|
||||
import { socketEmit } from "../socket.js";
|
||||
import { getUser, updateUserCoins, insertLog } from "../../database/index.js";
|
||||
import { init } from "openai/_shims/index.mjs";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
/**
|
||||
* Factory function to create and configure the monke API routes.
|
||||
* @param {object} client - The Discord.js client instance.
|
||||
* @param {object} io - The Socket.IO server instance.
|
||||
* @returns {object} The configured Express router.
|
||||
*/
|
||||
export function monkeRoutes(client, io) {
|
||||
// --- Router Management Endpoints
|
||||
|
||||
router.get("/:userId", (req, res) => {
|
||||
const { userId } = req.params;
|
||||
|
||||
if (!userId) return res.status(400).json({ error: "User ID is required" });
|
||||
const user = getUser.get(userId);
|
||||
if (!user) return res.status(404).json({ error: "User not found" });
|
||||
const userGamePath = monkePaths[userId] || null;
|
||||
if (!userGamePath) return res.status(404).json({ error: "No active game found for this user" });
|
||||
|
||||
return res.status(200).json({ userGamePath });
|
||||
});
|
||||
|
||||
router.post("/:userId/start", (req, res) => {
|
||||
const { userId } = req.params;
|
||||
const { initialBet } = req.body;
|
||||
|
||||
if (!userId) return res.status(400).json({ error: "User ID is required" });
|
||||
const user = getUser.get(userId);
|
||||
if (!user) return res.status(404).json({ error: "User not found" });
|
||||
if (!initialBet) return res.status(400).json({ error: "Initial bet is required" });
|
||||
|
||||
try {
|
||||
const newCoins = user.coins - initialBet;
|
||||
updateUserCoins.run({
|
||||
id: userId,
|
||||
coins: newCoins,
|
||||
});
|
||||
insertLog.run({
|
||||
id: `${userId}-monke-bet-${Date.now()}`,
|
||||
user_id: userId,
|
||||
target_user_id: null,
|
||||
action: "MONKE_BET",
|
||||
coins_amount: -initialBet,
|
||||
user_new_amount: newCoins,
|
||||
});
|
||||
} catch (error) {
|
||||
return res.status(500).json({ error: "Failed to update user coins" });
|
||||
}
|
||||
|
||||
monkePaths[userId] = [{ round: 0, choice: null, result: null, bet: initialBet, extractValue: null, timestamp: Date.now() }];
|
||||
|
||||
return res.status(200).json({ message: "Monke game started", userGamePath: monkePaths[userId] });
|
||||
});
|
||||
|
||||
router.post("/:userId/play", (req, res) => {
|
||||
const { userId } = req.params;
|
||||
const { choice, step } = req.body;
|
||||
|
||||
if (!userId) return res.status(400).json({ error: "User ID is required" });
|
||||
const user = getUser.get(userId);
|
||||
if (!user) return res.status(404).json({ error: "User not found" });
|
||||
if (!monkePaths[userId]) return res.status(400).json({ error: "No active game found for this user" });
|
||||
|
||||
const currentRound = monkePaths[userId].length - 1;
|
||||
if (step !== currentRound) return res.status(400).json({ error: "Invalid step for the current round" });
|
||||
if (monkePaths[userId][currentRound].choice !== null) return res.status(400).json({ error: "This round has already been played" });
|
||||
const randomLoseChoice = Math.floor(Math.random() * 3); // 0, 1, or 2
|
||||
|
||||
if (choice !== randomLoseChoice) {
|
||||
monkePaths[userId][currentRound].choice = choice;
|
||||
monkePaths[userId][currentRound].result = randomLoseChoice;
|
||||
monkePaths[userId][currentRound].extractValue = Math.round(monkePaths[userId][currentRound].bet * 1.33);
|
||||
monkePaths[userId][currentRound].timestamp = Date.now();
|
||||
|
||||
monkePaths[userId].push({ round: currentRound + 1, choice: null, result: null, bet: monkePaths[userId][currentRound].extractValue, extractValue: null, timestamp: Date.now() });
|
||||
|
||||
return res.status(200).json({ message: "Round won", userGamePath: monkePaths[userId], lost: false });
|
||||
} else {
|
||||
monkePaths[userId][currentRound].choice = choice;
|
||||
monkePaths[userId][currentRound].result = randomLoseChoice;
|
||||
monkePaths[userId][currentRound].extractValue = 0;
|
||||
monkePaths[userId][currentRound].timestamp = Date.now();
|
||||
|
||||
const userGamePath = monkePaths[userId];
|
||||
delete monkePaths[userId];
|
||||
|
||||
return res.status(200).json({ message: "Round lost", userGamePath, lost: true });
|
||||
}
|
||||
});
|
||||
|
||||
router.post("/:userId/stop", (req, res) => {
|
||||
const { userId } = req.params;
|
||||
if (!userId) return res.status(400).json({ error: "User ID is required" });
|
||||
const user = getUser.get(userId);
|
||||
if (!user) return res.status(404).json({ error: "User not found" });
|
||||
if (!monkePaths[userId]) return res.status(400).json({ error: "No active game found for this user" });
|
||||
const userGamePath = monkePaths[userId];
|
||||
delete monkePaths[userId];
|
||||
|
||||
const extractValue = userGamePath[userGamePath.length - 1].bet;
|
||||
const coins = user.coins || 0;
|
||||
|
||||
const newCoins = coins + extractValue;
|
||||
|
||||
try {
|
||||
updateUserCoins.run({
|
||||
id: userId,
|
||||
coins: newCoins,
|
||||
});
|
||||
insertLog.run({
|
||||
id: `${userId}-monke-withdraw-${Date.now()}`,
|
||||
user_id: userId,
|
||||
target_user_id: null,
|
||||
action: "MONKE_WITHDRAW",
|
||||
coins_amount: extractValue,
|
||||
user_new_amount: newCoins,
|
||||
});
|
||||
|
||||
return res.status(200).json({ message: "Game stopped", userGamePath });
|
||||
} catch (error) {
|
||||
return res.status(500).json({ error: "Failed to update user coins" });
|
||||
}
|
||||
});
|
||||
|
||||
return router;
|
||||
}
|
||||
@@ -475,7 +475,7 @@ const VCT_TEAMS = {
|
||||
],
|
||||
"vct-cn": [
|
||||
/x ag\)$/g, /x blg\)$/g, /x edg\)$/g, /x fpx\)$/g, /x jdg\)$/g, /x nova\)$/g, /x tec\)$/g,
|
||||
/x te\)$/g, /x tyl\)$/g, /x wol\)$/g, /x xlg\)$/g, /x xlg\)$/g, /x drg\)$/g, /x drg\)$/g
|
||||
/x te\)$/g, /x tyl\)$/g, /x wol\)$/g, /x xlg\)$/g, /x xlg\)$/g, /x drg\)$/g
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user