#!/usr/bin/env python3 import socket import time import sys import os import asyncio import importlib sys.path.append(os.path.dirname(os.path.abspath(__file__))) from src.database import Database from src.game_engine import GameEngine from modules import CoreCommands, Exploration, BattleSystem, PetManagement, Achievements, Admin, Inventory, GymBattles from webserver import PetBotWebServer class PetBotDebug: def __init__(self): print("šŸ¤– PetBot Debug Mode - Initializing...") self.database = Database() self.game_engine = GameEngine(self.database) self.config = { "server": "irc.libera.chat", "port": 6667, "nickname": "PetBot", "channel": "#petz", "command_prefix": "!" } self.socket = None self.connected = False self.running = True self.active_encounters = {} self.modules = {} self.command_map = {} self.web_server = None print("āœ… Basic initialization complete") def initialize_async_components(self): """Initialize async components""" print("šŸ”„ Creating event loop...") loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) print("āœ… Event loop created") print("šŸ”„ Initializing database...") loop.run_until_complete(self.database.init_database()) print("āœ… Database initialized") print("šŸ”„ Loading game data...") loop.run_until_complete(self.game_engine.load_game_data()) print("āœ… Game data loaded") print("šŸ”„ Loading modules...") self.load_modules() print("āœ… Modules loaded") print("šŸ”„ Starting web server...") self.web_server = PetBotWebServer(self.database, port=8080) self.web_server.start_in_thread() print("āœ… Web server started") self.loop = loop print("āœ… Async components ready") def load_modules(self): """Load all command modules""" module_classes = [ CoreCommands, Exploration, BattleSystem, PetManagement, Achievements, Admin, Inventory, GymBattles ] self.modules = {} self.command_map = {} for module_class in module_classes: module_name = module_class.__name__ print(f" Loading {module_name}...") module_instance = module_class(self, self.database, self.game_engine) self.modules[module_name] = module_instance # Map commands to modules commands = module_instance.get_commands() for command in commands: self.command_map[command] = module_instance print(f" āœ… {module_name}: {len(commands)} commands") print(f"āœ… Loaded {len(self.modules)} modules with {len(self.command_map)} commands") async def reload_modules(self): """Reload all modules (for admin use)""" try: # Reload module files import modules importlib.reload(modules.core_commands) importlib.reload(modules.exploration) importlib.reload(modules.battle_system) importlib.reload(modules.pet_management) importlib.reload(modules.achievements) importlib.reload(modules.admin) importlib.reload(modules) # Reinitialize modules print("šŸ”„ Reloading modules...") self.load_modules() print("āœ… Modules reloaded successfully") return True except Exception as e: print(f"āŒ Module reload failed: {e}") return False def test_connection(self): """Test if we can connect to IRC""" print("šŸ”„ Testing IRC connection...") try: test_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) test_sock.settimeout(5) test_sock.connect((self.config["server"], self.config["port"])) test_sock.close() print("āœ… IRC connection test successful") return True except Exception as e: print(f"āŒ IRC connection failed: {e}") return False def connect(self): print("šŸš€ Starting bot connection process...") print("šŸ”„ Step 1: Initialize async components...") self.initialize_async_components() print("āœ… Step 1 complete") print("šŸ”„ Step 2: Test IRC connectivity...") if not self.test_connection(): print("āŒ IRC connection test failed - would run offline mode") print("āœ… Bot core systems are working - IRC connection unavailable") return print("āœ… Step 2 complete") print("šŸ”„ Step 3: Create IRC socket...") self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.settimeout(10) print("āœ… Socket created") print("šŸ”„ Step 4: Connect to IRC server...") try: self.socket.connect((self.config["server"], self.config["port"])) print("āœ… Connected to IRC server!") except Exception as e: print(f"āŒ Failed to connect: {e}") return print("šŸ”„ Step 5: Send IRC handshake...") self.send(f"NICK {self.config['nickname']}") self.send(f"USER {self.config['nickname']} 0 * :{self.config['nickname']}") print("āœ… Handshake sent") print("šŸ”„ Step 6: Start main loop...") self.socket.settimeout(1) print("āœ… Bot is now running!") print(f"āœ… Will join {self.config['channel']} when connected") print(f"āœ… Loaded commands: {', '.join(sorted(self.command_map.keys()))}") print("šŸŽ® Ready for testing! Press Ctrl+C to stop.") self.main_loop() def main_loop(self): message_count = 0 while self.running: try: data = self.socket.recv(4096).decode('utf-8', errors='ignore') if not data: print("šŸ’€ Connection closed by server") break lines = data.strip().split('\n') for line in lines: if line.strip(): message_count += 1 if message_count <= 10: # Show first 10 messages for debugging print(f"šŸ“Ø {message_count}: {line.strip()}") self.handle_line(line.strip()) except socket.timeout: continue except KeyboardInterrupt: print("\nšŸ›‘ Shutting down bot...") self.running = False break except Exception as e: print(f"āŒ Error in main loop: {e}") time.sleep(1) if self.socket: self.socket.close() self.loop.close() print("āœ… Bot shutdown complete") def send(self, message): if self.socket: full_message = f"{message}\r\n" print(f"šŸ“¤ >> {message}") self.socket.send(full_message.encode('utf-8')) def handle_line(self, line): if line.startswith("PING"): pong_response = line.replace("PING", "PONG") self.send(pong_response) return # Handle connection messages if "376" in line or "422" in line: # End of MOTD if not self.connected: self.send(f"JOIN {self.config['channel']}") self.connected = True print(f"šŸŽ‰ Joined {self.config['channel']} - Bot is ready for commands!") return parts = line.split() if len(parts) < 4: return if parts[1] == "PRIVMSG": channel = parts[2] message = " ".join(parts[3:])[1:] hostmask = parts[0][1:] nickname = hostmask.split('!')[0] if message.startswith(self.config["command_prefix"]): print(f"šŸŽ® Command from {nickname}: {message}") self.handle_command(channel, nickname, message) def handle_command(self, channel, nickname, message): command_parts = message[1:].split() if not command_parts: return command = command_parts[0].lower() args = command_parts[1:] try: if command in self.command_map: module = self.command_map[command] print(f"šŸ”§ Executing {command} via {module.__class__.__name__}") # Run async command handler self.loop.run_until_complete( module.handle_command(channel, nickname, command, args) ) else: self.send_message(channel, f"{nickname}: Unknown command. Use !help for available commands.") except Exception as e: self.send_message(channel, f"{nickname}: Error processing command: {str(e)}") print(f"āŒ Command error: {e}") import traceback traceback.print_exc() def send_message(self, target, message): self.send(f"PRIVMSG {target} :{message}") time.sleep(0.5) def run_async_command(self, coro): return self.loop.run_until_complete(coro) if __name__ == "__main__": print("🐾 Starting Pet Bot for IRC (Debug Mode)...") bot = PetBotDebug() try: bot.connect() except KeyboardInterrupt: print("\nšŸ”„ Bot stopping...") # Gracefully shutdown the game engine try: bot.loop.run_until_complete(bot.game_engine.shutdown()) except Exception as e: print(f"Error during shutdown: {e}") print("āœ… Bot stopped by user") except Exception as e: print(f"āŒ Bot crashed: {e}") import traceback traceback.print_exc()