Spaces:
Runtime error
Runtime error
| """ | |
| Chat management service implementation. | |
| """ | |
| from typing import Dict, List, Tuple, Optional | |
| from ..interfaces.service_interfaces import IChatService | |
| from ..interfaces.game_interfaces import IGameWorld | |
| class ChatService(IChatService): | |
| """Service for managing chat messages and communication.""" | |
| def __init__(self, game_world: IGameWorld, plugin_service=None): | |
| self.game_world = game_world | |
| self.plugin_service = plugin_service | |
| def send_public_message(self, sender_id: str, message: str) -> bool: | |
| """Send a public chat message visible to all players.""" | |
| try: | |
| # Process message through plugins first (for commands and enhancements) | |
| if self.plugin_service: | |
| # Check if any plugin handles this message (e.g., chat commands) | |
| enhanced_chat_plugin = None | |
| for plugin_id, plugin in self.plugin_service.loaded_plugins.items(): | |
| if hasattr(plugin, 'process_message') and plugin_id == 'enhanced_chat': | |
| enhanced_chat_plugin = plugin | |
| break | |
| if enhanced_chat_plugin and enhanced_chat_plugin.is_enabled(): | |
| # Process the message through the enhanced chat plugin | |
| result = enhanced_chat_plugin.process_message(sender_id, message) | |
| # If it's a command that was processed, handle the response | |
| if result.get('is_command', False): | |
| command_response = result.get('command_response', '') | |
| if command_response: | |
| # Add command response as system message | |
| self.game_world.add_chat_message( | |
| sender="System", | |
| message=command_response, | |
| message_type="system", | |
| sender_id="system" | |
| ) | |
| return True | |
| # If message was modified/enhanced (emotes, etc.), use processed version | |
| if result.get('processed') and result.get('valid', True): | |
| message = result['processed'] | |
| # Get sender player to get their name | |
| sender_player = self.game_world.get_player(sender_id) | |
| sender_name = sender_player.name if sender_player else "Unknown" | |
| # Add the message to game world | |
| self.game_world.add_chat_message( | |
| sender=sender_name, | |
| message=message, | |
| message_type="public", | |
| sender_id=sender_id | |
| ) | |
| return True | |
| except Exception as e: | |
| print(f"[ChatService] Error sending public message: {e}") | |
| return False | |
| def send_private_message(self, sender_id: str, target_id: str, message: str) -> Tuple[bool, str]: | |
| """Send a private message between players or to NPCs.""" | |
| try: | |
| sender_player = self.game_world.get_player(sender_id) | |
| if not sender_player: | |
| return False, "Sender not found" | |
| print(f"[ChatService] Sending private message from {sender_player.name} ({sender_id}) to {target_id}: {message}") | |
| # Check if target is a player | |
| target_player = self.game_world.get_player(target_id) | |
| if target_player: | |
| # Send to player | |
| self.game_world.add_chat_message( | |
| sender=f"🔒 {sender_player.name}", | |
| message=f"[Private to {target_player.name}]: {message}", | |
| message_type="private_to_player", | |
| target=target_id, | |
| sender_id=sender_id | |
| ) | |
| return True, f"Message sent to {target_player.name}" | |
| else: | |
| # Check if target is an NPC | |
| all_npcs = self.game_world.get_all_npcs() if hasattr(self.game_world, 'get_all_npcs') else {} | |
| if not all_npcs: | |
| # Fallback: check direct access to npcs attribute | |
| all_npcs = getattr(self.game_world, 'npcs', {}) | |
| if target_id in all_npcs: | |
| npc = all_npcs[target_id] | |
| npc_name = npc.get('name', target_id) | |
| # Send player's message | |
| self.game_world.add_chat_message( | |
| sender=f"🔒 {sender_player.name}", | |
| message=f"[Private to {npc_name}]: {message}", | |
| message_type="private_to_npc", | |
| target=target_id, | |
| sender_id=sender_id | |
| ) | |
| # Generate and send NPC response | |
| npc_response = self._get_npc_response(target_id, message, sender_id) | |
| self.game_world.add_chat_message( | |
| sender=f"🤖 {npc_name}", | |
| message=npc_response, | |
| message_type="private_from_npc", | |
| target=sender_id, | |
| sender_id=target_id | |
| ) | |
| print(f"[ChatService] NPC {npc_name} responded: {npc_response}") | |
| return True, f"Message sent to {npc_name}" | |
| else: | |
| return False, "Target not found" | |
| except Exception as e: | |
| print(f"[ChatService] Error sending private message: {e}") | |
| return False, f"Error: {str(e)}" | |
| def get_chat_history(self, limit: int = None) -> List[Dict]: | |
| """Get chat message history.""" | |
| try: | |
| if hasattr(self.game_world, 'get_chat_history'): | |
| return self.game_world.get_chat_history(limit) | |
| else: | |
| # Fallback - access chat_messages directly | |
| messages = getattr(self.game_world, 'chat_messages', []) | |
| if limit: | |
| return messages[-limit:] | |
| return messages | |
| except Exception as e: | |
| print(f"[ChatService] Error getting chat history: {e}") | |
| return [] | |
| def add_system_message(self, message: str) -> bool: | |
| """Add a system message to the chat.""" | |
| try: | |
| self.game_world.add_chat_message( | |
| sender="System", | |
| message=message, | |
| message_type="system" | |
| ) | |
| return True | |
| except Exception as e: | |
| print(f"[ChatService] Error adding system message: {e}") | |
| return False | |
| def broadcast_message(self, message: str, message_type: str = "announcement") -> bool: | |
| """Broadcast a message to all players.""" | |
| try: | |
| self.game_world.add_chat_message( | |
| sender="System", | |
| message=f"📢 {message}", | |
| message_type=message_type | |
| ) | |
| return True | |
| except Exception as e: | |
| print(f"[ChatService] Error broadcasting message: {e}") | |
| return False | |
| def send_npc_message(self, npc_id: str, message: str, target_player_id: str = None) -> bool: | |
| """Send a message from an NPC.""" | |
| try: | |
| # Get NPC data | |
| all_npcs = getattr(self.game_world, 'npcs', {}) | |
| npc = all_npcs.get(npc_id) | |
| if not npc: | |
| return False | |
| npc_name = npc.get('name', npc_id) | |
| if target_player_id: | |
| # Private message to specific player | |
| self.game_world.add_chat_message( | |
| sender=npc_name, | |
| message=message, | |
| message_type="npc_private", | |
| target=target_player_id, | |
| sender_id=npc_id | |
| ) | |
| else: | |
| # Public message from NPC | |
| self.game_world.add_chat_message( | |
| sender=npc_name, | |
| message=message, | |
| message_type="npc_public", | |
| sender_id=npc_id | |
| ) | |
| return True | |
| except Exception as e: | |
| print(f"[ChatService] Error sending NPC message: {e}") | |
| return False | |
| def filter_messages_by_type(self, message_type: str) -> List[Dict]: | |
| """Filter chat messages by type.""" | |
| try: | |
| all_messages = self.get_chat_history() | |
| return [msg for msg in all_messages if msg.get('type') == message_type] | |
| except Exception as e: | |
| print(f"[ChatService] Error filtering messages: {e}") | |
| return [] | |
| def get_recent_messages(self, count: int = 10) -> List[Dict]: | |
| """Get the most recent chat messages.""" | |
| return self.get_chat_history(limit=count) | |
| def _get_npc_response(self, npc_id: str, message: str, player_id: str = None) -> str: | |
| """Generate NPC response - checks for addons first, then falls back to generic responses""" | |
| all_npcs = getattr(self.game_world, 'npcs', {}) | |
| npc = all_npcs.get(npc_id) | |
| if not npc: | |
| return "I don't understand." | |
| # Check if this NPC has an addon that can handle commands | |
| addon_npcs = getattr(self.game_world, 'addon_npcs', {}) | |
| if npc_id in addon_npcs and player_id: | |
| addon = addon_npcs[npc_id] | |
| try: | |
| response = addon.handle_command(player_id, message) | |
| if response: | |
| return response | |
| except Exception as e: | |
| print(f"[ChatService] NPC addon error: {e}") | |
| # Fall through to default responses | |
| # Fall back to personality-based or ID-based responses | |
| personality = npc.get('personality', npc_id) | |
| # Personality-based responses | |
| responses = { | |
| 'wise_teacher': [ | |
| "📚 Knowledge is power! What would you like to learn today?", | |
| "🎓 In my experience, every question leads to wisdom. Ask away!", | |
| "📖 I sense curiosity in your words. How can I enlighten you?", | |
| "🔍 Learning never ends. What mysteries shall we explore?" | |
| ], | |
| 'comedian': [ | |
| "🎭 Ha! That's funnier than my last joke... and that's saying something!", | |
| "😂 You know what they say - laughter is the best medicine! *wink*", | |
| "🃏 I've got a million jokes, but they're all terrible! Want to hear one?", | |
| "🎪 Life's a comedy show, and we're all just trying not to trip on stage!" | |
| ], | |
| 'tough_trainer': [ | |
| "⚔️ Steel yourself, warrior! Every challenge makes you stronger!", | |
| "💪 No pain, no gain! Are you ready for real training?", | |
| "🛡️ A true fighter learns from every battle. What will you learn today?", | |
| "⚡ Victory belongs to those who never give up! Show me your spirit!" | |
| ], | |
| 'gentle_healer': [ | |
| "💚 Peace be with you, traveler. How may I ease your burdens?", | |
| "✨ Healing comes from within as much as without. Stay strong.", | |
| "🌿 Nature provides all we need for wellness. Trust in its power.", | |
| "🕊️ A kind heart heals faster than any potion. Remember that." | |
| ], | |
| 'traveler': [ | |
| "🚶 The road teaches many lessons. Where has your journey taken you?", | |
| "🗺️ I've seen many lands and met many souls. Each has a story to tell.", | |
| "⛰️ Adventures await around every corner! What calls to your spirit?", | |
| "🌅 Every sunrise brings new possibilities. What will you discover today?" | |
| ], | |
| 'mystical_sage': [ | |
| "🧙 The threads of fate weave in mysterious ways...", | |
| "🔮 Ancient wisdom whispers secrets to those who listen carefully.", | |
| "⭐ The stars hold answers for those patient enough to seek them.", | |
| "🌙 Magic flows through all things. Can you feel its presence?" | |
| ] | |
| } | |
| # Default responses by NPC ID | |
| default_responses = { | |
| 'merchant': [ | |
| "🏪 Welcome to my shop! Looking for anything special today?", | |
| "💰 I've got the finest wares in all the land! What catches your eye?", | |
| "📦 Trade is the lifeblood of adventure! What do you need?", | |
| "💎 Quality goods at fair prices! That's my motto!" | |
| ], | |
| 'read2burn_mailbox': [ | |
| "📮 Secure messaging at your service! Your secrets are safe with me.", | |
| "🔒 Need to send a confidential message? I'm your mailbox!", | |
| "📧 Self-destructing messages for ultimate privacy!", | |
| "🗂️ Your private communications, protected and secure." | |
| ], | |
| 'weather_oracle': [ | |
| "🌤️ The winds whisper of weather patterns... what location interests you?", | |
| "⛅ I can read the skies! Tell me where you wish to know the weather.", | |
| "🌦️ Weather knowledge is my domain! Ask about any location!", | |
| "🌈 From sunshine to storms, I know it all! Where shall I forecast?" | |
| ] | |
| } | |
| # Choose appropriate response list | |
| response_list = responses.get(personality) or default_responses.get(npc_id) or [ | |
| "Hello there! How can I help you?", | |
| "Greetings, traveler! What brings you to me?", | |
| "Good day! Is there something you need?", | |
| "Welcome! How may I assist you today?" | |
| ] | |
| import random | |
| return random.choice(response_list) | |