What a mess

This commit is contained in:
Joan
2025-11-07 15:27:13 +01:00
parent 0b79b3ae59
commit 33cc9586c2
130 changed files with 29819 additions and 1175 deletions

112
main.py
View File

@@ -2,13 +2,13 @@ import asyncio
import logging
import signal
import os
import time
from dotenv import load_dotenv
from telegram import Update
from telegram.ext import Application, CommandHandler, CallbackQueryHandler
from bot import database, handlers
from bot import background_tasks
# Enable logging
logging.basicConfig(
@@ -26,103 +26,6 @@ def signal_handler(sig, frame):
logger.info("Shutdown signal received. Shutting down gracefully...")
shutdown_event.set()
async def decay_dropped_items():
"""A background task that periodically cleans up old dropped items."""
while not shutdown_event.is_set():
try:
# Wait for 5 minutes before the next cleanup
await asyncio.wait_for(shutdown_event.wait(), timeout=300)
except asyncio.TimeoutError:
start_time = time.time()
logger.info("Running item decay task...")
# Set decay time to 1 hour (3600 seconds)
decay_seconds = 3600
timestamp_limit = int(time.time()) - decay_seconds
items_removed = await database.remove_expired_dropped_items(timestamp_limit)
elapsed = time.time() - start_time
if items_removed > 0:
logger.info(f"Decayed and removed {items_removed} old items in {elapsed:.2f}s")
async def regenerate_stamina():
"""A background task that periodically regenerates stamina for all players."""
while not shutdown_event.is_set():
try:
# Wait for 5 minutes before the next regeneration cycle
await asyncio.wait_for(shutdown_event.wait(), timeout=300)
except asyncio.TimeoutError:
start_time = time.time()
logger.info("Running stamina regeneration...")
players_updated = await database.regenerate_all_players_stamina()
elapsed = time.time() - start_time
if players_updated > 0:
logger.info(f"Regenerated stamina for {players_updated} players in {elapsed:.2f}s")
# Alert if regeneration is taking too long (potential scaling issue)
if elapsed > 5.0:
logger.warning(f"⚠️ Stamina regeneration took {elapsed:.2f}s (threshold: 5s) - check database load!")
async def check_combat_timers():
"""A background task that checks for idle combat turns and auto-attacks."""
while not shutdown_event.is_set():
try:
# Wait for 30 seconds before next check
await asyncio.wait_for(shutdown_event.wait(), timeout=30)
except asyncio.TimeoutError:
start_time = time.time()
# Check for combats idle for more than 5 minutes (300 seconds)
idle_threshold = time.time() - 300
idle_combats = await database.get_all_idle_combats(idle_threshold)
if idle_combats:
logger.info(f"Processing {len(idle_combats)} idle combats...")
for combat in idle_combats:
try:
from bot import combat as combat_logic
# Force end player's turn and let NPC attack
if combat['turn'] == 'player':
logger.info(f"Player {combat['player_id']} idle in combat - auto-ending turn")
await database.update_combat(combat['player_id'], {
'turn': 'npc',
'turn_started_at': time.time()
})
# NPC attacks
await combat_logic.npc_attack(combat['player_id'])
except Exception as e:
logger.error(f"Error processing idle combat: {e}")
# Log performance for monitoring
if idle_combats:
elapsed = time.time() - start_time
logger.info(f"Processed {len(idle_combats)} idle combats in {elapsed:.2f}s")
# Warn if taking too long (potential scaling issue)
if elapsed > 10.0:
logger.warning(f"⚠️ Combat timer check took {elapsed:.2f}s (threshold: 10s) - consider batching!")
async def decay_corpses():
"""A background task that removes old corpses."""
while not shutdown_event.is_set():
try:
# Wait for 10 minutes before next cleanup
await asyncio.wait_for(shutdown_event.wait(), timeout=600)
except asyncio.TimeoutError:
logger.info("Running corpse decay...")
# Player corpses decay after 24 hours
player_corpse_limit = time.time() - (24 * 3600)
player_corpses_removed = await database.remove_expired_player_corpses(player_corpse_limit)
# NPC corpses decay after 2 hours
npc_corpse_limit = time.time() - (2 * 3600)
npc_corpses_removed = await database.remove_expired_npc_corpses(npc_corpse_limit)
if player_corpses_removed > 0 or npc_corpses_removed > 0:
logger.info(f"Decayed {player_corpses_removed} player corpses and {npc_corpses_removed} NPC corpses.")
async def main() -> None:
"""Start the bot and wait for a shutdown signal."""
load_dotenv()
@@ -151,10 +54,13 @@ async def main() -> None:
await spawn_manager.start_spawn_manager()
# Start the background tasks
decay_task = asyncio.create_task(decay_dropped_items())
stamina_task = asyncio.create_task(regenerate_stamina())
combat_timer_task = asyncio.create_task(check_combat_timers())
corpse_decay_task = asyncio.create_task(decay_corpses())
logger.info("Starting background tasks...")
decay_task = asyncio.create_task(background_tasks.decay_dropped_items(shutdown_event))
stamina_task = asyncio.create_task(background_tasks.regenerate_stamina(shutdown_event))
combat_timer_task = asyncio.create_task(background_tasks.check_combat_timers(shutdown_event))
corpse_decay_task = asyncio.create_task(background_tasks.decay_corpses(shutdown_event))
status_effects_task = asyncio.create_task(background_tasks.process_status_effects(shutdown_event))
logger.info("✅ All background tasks started")
await shutdown_event.wait()
@@ -162,10 +68,12 @@ async def main() -> None:
await application.stop()
# Ensure the background tasks are also cancelled on shutdown
logger.info("Stopping background tasks...")
decay_task.cancel()
stamina_task.cancel()
combat_timer_task.cancel()
corpse_decay_task.cancel()
status_effects_task.cancel()
logger.info("Bot has been shut down.")