Initial commit

**Motivations:**
- Initialisation du versionning git pour le projet

**Root causes:**
- N/A (Nouveau projet)

**Correctifs:**
- N/A

**Evolutions:**
- Structure initiale du projet
- Ajout du .gitignore

**Pages affectées:**
- Tous les fichiers
This commit is contained in:
2026-03-03 22:24:17 +01:00
commit e031c9a1d2
155 changed files with 22334 additions and 0 deletions

58
server/bot-tick.js Normal file
View File

@@ -0,0 +1,58 @@
/**
* Server-side bot tick: load bot zoos, run same logic as client tickBotZoos, persist.
* Uses web/js/bot-zoo.js so bot rules stay in one place.
*/
import { getBotZoosForTick, updateBotZooState, expireSaleListings, getActiveSaleListings, placeBid } from "./db.js";
import { tickBotZoos } from "../web/js/bot-zoo.js";
const BOT_TICK_INTERVAL_MS = 15 * 1000;
let lastTickAt = 0;
/**
* Run one bot tick and persist all bot zoos.
* @returns {Promise<void>}
*/
export async function runBotTick() {
const nowUnix = Math.floor(Date.now() / 1000);
const nowMs = Date.now();
const dt = lastTickAt > 0 ? Math.min((nowMs - lastTickAt) / 1000, 60) : 10;
lastTickAt = nowMs;
await expireSaleListings();
const botZoos = await getBotZoosForTick();
if (botZoos.length === 0) return;
const activeListings = await getActiveSaleListings();
for (const listing of activeListings) {
const minBid = (listing.best_bid_amount ?? listing.initial_price) + 1;
const bidders = botZoos.filter(
(z) => z.id !== listing.seller_zoo_id && (z.botState?.coins ?? 0) >= minBid
);
if (bidders.length > 0) {
const bidder = bidders[Math.floor(Math.random() * bidders.length)];
const result = await placeBid(listing.id, bidder.id, minBid);
if (result.ok) break;
}
}
const state = { worldZoos: botZoos };
tickBotZoos(state, nowUnix, dt);
for (const zoo of botZoos) {
await updateBotZooState(zoo.id, zoo.animalWeights, zoo.botState);
}
}
/**
* Start the periodic bot tick (call after server listen).
* @returns {void}
*/
export function startBotTickInterval() {
setInterval(() => {
runBotTick().catch((err) => {
console.error("bot tick failed", err);
});
}, BOT_TICK_INTERVAL_MS);
}