File size: 14,463 Bytes
4c75d73 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
"""
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)
|