Chris4K's picture
Upload 195 files
4c75d73 verified
"""
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)