|
|
|
import asyncio
|
|
from src.interfaces.plugin_interfaces import IChatPlugin, PluginMetadata, PluginType
|
|
from typing import Dict, List, Any
|
|
|
|
class EnhancedChatPlugin(IChatPlugin):
|
|
def __init__(self):
|
|
self._metadata = PluginMetadata(
|
|
id="enhanced_chat",
|
|
name="Enhanced Chat System",
|
|
version="1.2.0",
|
|
author="MMORPG Dev Team",
|
|
description="Adds emotes, chat channels, and advanced chat commands",
|
|
plugin_type=PluginType.SERVICE,
|
|
dependencies=[],
|
|
config={
|
|
"enable_emotes": True,
|
|
"enable_channels": True,
|
|
"max_message_length": 500,
|
|
"chat_cooldown": 1
|
|
}
|
|
)
|
|
self._enabled = False
|
|
self._context = None
|
|
|
|
|
|
self.chat_history = []
|
|
self.max_history = 100
|
|
|
|
|
|
self.ignore_lists = {}
|
|
|
|
|
|
self.channels = {
|
|
'global': {'description': 'Global chat channel', 'members': set()},
|
|
'trade': {'description': 'Trading channel', 'members': set()},
|
|
'help': {'description': 'Help and questions channel', 'members': set()}
|
|
}
|
|
|
|
|
|
self.player_channels = {}
|
|
|
|
@property
|
|
def metadata(self) -> PluginMetadata:
|
|
return self._metadata
|
|
|
|
def initialize(self, context: Dict[str, Any]) -> bool:
|
|
"""Initialize the enhanced chat plugin."""
|
|
try:
|
|
self._context = context
|
|
self._config = self._metadata.config
|
|
self._enabled = True
|
|
print(f"💬 Enhanced Chat Plugin initialized")
|
|
return True
|
|
except Exception as e:
|
|
print(f"💬 Failed to initialize Enhanced Chat Plugin: {e}")
|
|
return False
|
|
|
|
def shutdown(self) -> bool:
|
|
"""Shutdown the plugin and cleanup resources."""
|
|
self._enabled = False
|
|
print("💬 Enhanced Chat Plugin shut down")
|
|
return True
|
|
|
|
def get_status(self) -> Dict[str, Any]:
|
|
"""Get current plugin status."""
|
|
return {
|
|
"status": "active" if self._enabled else "inactive",
|
|
"message": "Enhanced chat system with marketplace commands"
|
|
}
|
|
|
|
def process_message(self, player_id: str, message: str, channel: str = "global") -> Dict[str, Any]:
|
|
"""Process and enhance chat messages."""
|
|
if message.startswith('/'):
|
|
return self._process_command(player_id, message)
|
|
else:
|
|
return self._broadcast_message(player_id, message)
|
|
|
|
def get_available_commands(self) -> List[Dict[str, str]]:
|
|
"""Get list of available chat commands."""
|
|
return [
|
|
{"command": "/marketplace", "description": "View marketplace listings"},
|
|
{"command": "/trade create <item> <price>", "description": "Create trade listing"},
|
|
{"command": "/trade accept <id>", "description": "Accept trade offer"},
|
|
{"command": "/auction create <item> <start_price>", "description": "Create auction"},
|
|
{"command": "/tell <player> <message>", "description": "Send private message"},
|
|
{"command": "/who", "description": "List online players"},
|
|
{"command": "/help", "description": "Show available commands"},
|
|
{"command": "/shout <message>", "description": "Shout to all players"},
|
|
{"command": "/emote <action>", "description": "Perform an emote"},
|
|
{"command": "/me <action>", "description": "Perform an emote (alias)"},
|
|
{"command": "/time", "description": "Show current time"},
|
|
{"command": "/channels", "description": "List available channels"}
|
|
]
|
|
|
|
def get_chat_channels(self) -> Dict[str, Dict[str, str]]:
|
|
"""Get available chat channels."""
|
|
return {
|
|
"global": {"name": "Global", "description": "Main chat channel"},
|
|
"trade": {"name": "Trade", "description": "Trading discussions"},
|
|
"help": {"name": "Help", "description": "Help and questions"}
|
|
}
|
|
|
|
def _process_command(self, player_id: str, message: str) -> Dict[str, Any]:
|
|
"""Process chat commands"""
|
|
parts = message.split(' ', 1)
|
|
command = parts[0].lower()
|
|
args = parts[1] if len(parts) > 1 else ""
|
|
|
|
|
|
command_handlers = {
|
|
'/marketplace': self._marketplace_command,
|
|
'/trade': self._trade_command,
|
|
'/auction': self._auction_command,
|
|
'/tell': self._tell_command,
|
|
'/whisper': self._tell_command,
|
|
'/who': self._who_command,
|
|
'/help': self._help_command,
|
|
'/commands': self._help_command,
|
|
'/shout': self._shout_command,
|
|
'/emote': self._emote_command,
|
|
'/me': self._emote_command,
|
|
'/time': self._time_command,
|
|
'/channels': self._channels_command
|
|
}
|
|
|
|
if command in command_handlers:
|
|
try:
|
|
return command_handlers[command](player_id, args)
|
|
except Exception as e:
|
|
return {
|
|
"success": False,
|
|
"message": f"Error executing command: {str(e)}",
|
|
"target": player_id
|
|
}
|
|
else:
|
|
return {
|
|
"success": False,
|
|
"message": f"Unknown command: {command}. Type /help for available commands.",
|
|
"target": player_id
|
|
}
|
|
|
|
def _broadcast_message(self, player_id: str, message: str) -> Dict[str, Any]:
|
|
"""Broadcast a message to all players"""
|
|
player_name = self._get_player_name(player_id)
|
|
formatted_message = f"{player_name}: {message}"
|
|
|
|
|
|
self._add_to_history(formatted_message)
|
|
|
|
return {
|
|
"success": True,
|
|
"message": formatted_message,
|
|
"type": "broadcast",
|
|
"sender": player_id
|
|
}
|
|
|
|
def _add_to_history(self, message: str):
|
|
"""Add message to chat history"""
|
|
import time
|
|
self.chat_history.append({
|
|
'timestamp': time.time(),
|
|
'message': message
|
|
})
|
|
|
|
|
|
if len(self.chat_history) > self.max_history:
|
|
self.chat_history.pop(0)
|
|
|
|
def _marketplace_command(self, player_id: str, args: str) -> Dict[str, Any]:
|
|
"""Handle marketplace command"""
|
|
marketplace_text = """
|
|
🏪 **MARKETPLACE** 🏪
|
|
═══════════════════════
|
|
|
|
📦 **AVAILABLE ITEMS:**
|
|
• Iron Sword - 150 gold (Seller: Trader_Bob)
|
|
• Health Potion - 25 gold (Seller: Alchemist_Ann)
|
|
• Magic Ring - 300 gold (Seller: Wizard_Will)
|
|
• Steel Shield - 200 gold (Seller: Smith_Sam)
|
|
|
|
💰 **RECENT TRADES:**
|
|
• Leather Boots sold for 75 gold
|
|
• Fire Staff sold for 450 gold
|
|
• Healing Herbs sold for 15 gold
|
|
|
|
📝 Use `/trade create <item> <price>` to list an item
|
|
🤝 Use `/trade accept <seller>` to buy an item
|
|
🔨 Use `/auction create <item> <starting_price>` for auctions
|
|
|
|
Type `/help` for more trading commands!
|
|
"""
|
|
|
|
return {
|
|
"success": True,
|
|
"message": marketplace_text.strip(),
|
|
"target": player_id,
|
|
"type": "info"
|
|
}
|
|
|
|
def _trade_command(self, player_id: str, args: str) -> Dict[str, Any]:
|
|
"""Handle trade command"""
|
|
if not args:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /trade <action> [parameters]\nActions: create, accept, list, cancel",
|
|
"target": player_id
|
|
}
|
|
|
|
parts = args.split(' ', 1)
|
|
action = parts[0].lower()
|
|
|
|
if action == 'create':
|
|
if len(parts) < 2:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /trade create <item> <price>",
|
|
"target": player_id
|
|
}
|
|
|
|
|
|
create_args = parts[1].split(' ')
|
|
if len(create_args) < 2:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /trade create <item> <price>",
|
|
"target": player_id
|
|
}
|
|
|
|
price = create_args[-1]
|
|
item = ' '.join(create_args[:-1])
|
|
|
|
return {
|
|
"success": True,
|
|
"message": f"✅ Trade listing created: {item} for {price} gold",
|
|
"target": player_id,
|
|
"type": "trade_create",
|
|
"data": {"item": item, "price": price, "seller": player_id}
|
|
}
|
|
|
|
elif action == 'accept':
|
|
if len(parts) < 2:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /trade accept <seller_name>",
|
|
"target": player_id
|
|
}
|
|
|
|
seller_name = parts[1]
|
|
return {
|
|
"success": True,
|
|
"message": f"🤝 Attempting to trade with {seller_name}...",
|
|
"target": player_id,
|
|
"type": "trade_accept"
|
|
}
|
|
|
|
elif action == 'list':
|
|
return {
|
|
"success": True,
|
|
"message": "📋 Your active trade listings:\n• No active listings",
|
|
"target": player_id
|
|
}
|
|
|
|
else:
|
|
return {
|
|
"success": False,
|
|
"message": "Unknown trade action. Use 'create', 'accept', 'list', or 'cancel'.",
|
|
"target": player_id
|
|
}
|
|
|
|
def _auction_command(self, player_id: str, args: str) -> Dict[str, Any]:
|
|
"""Handle auction command"""
|
|
if not args:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /auction <action> [parameters]\nActions: create, bid, list",
|
|
"target": player_id
|
|
}
|
|
|
|
parts = args.split(' ', 1)
|
|
action = parts[0].lower()
|
|
|
|
if action == 'create':
|
|
if len(parts) < 2:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /auction create <item> <starting_price>",
|
|
"target": player_id
|
|
}
|
|
|
|
|
|
create_args = parts[1].split(' ')
|
|
if len(create_args) < 2:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /auction create <item> <starting_price>",
|
|
"target": player_id
|
|
}
|
|
|
|
starting_price = create_args[-1]
|
|
item = ' '.join(create_args[:-1])
|
|
|
|
return {
|
|
"success": True,
|
|
"message": f"🔨 Auction created: {item} starting at {starting_price} gold",
|
|
"target": player_id,
|
|
"type": "auction_create"
|
|
}
|
|
|
|
else:
|
|
return {
|
|
"success": False,
|
|
"message": "Unknown auction action. Use 'create' to start an auction.",
|
|
"target": player_id
|
|
}
|
|
|
|
def _tell_command(self, player_id: str, args: str) -> Dict[str, Any]:
|
|
"""Send a private message to another player"""
|
|
if not args:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /tell <player> <message>",
|
|
"target": player_id
|
|
}
|
|
|
|
parts = args.split(' ', 1)
|
|
if len(parts) < 2:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /tell <player> <message>",
|
|
"target": player_id
|
|
}
|
|
|
|
target_name, message = parts
|
|
sender_name = self._get_player_name(player_id)
|
|
|
|
return {
|
|
"success": True,
|
|
"message": f"[TELL to {target_name}]: {message}",
|
|
"target": player_id,
|
|
"type": "tell",
|
|
"data": {
|
|
"target_name": target_name,
|
|
"sender_name": sender_name,
|
|
"message": message
|
|
}
|
|
}
|
|
|
|
def _who_command(self, player_id: str, args: str) -> Dict[str, Any]:
|
|
"""Show list of online players"""
|
|
|
|
return {
|
|
"success": True,
|
|
"message": "👥 Online players (3): Player1, Player2, Player3",
|
|
"target": player_id,
|
|
"type": "info"
|
|
}
|
|
|
|
def _help_command(self, player_id: str, args: str) -> Dict[str, Any]:
|
|
"""Show available commands"""
|
|
commands = self.get_available_commands()
|
|
help_text = "📋 **AVAILABLE COMMANDS:**\n"
|
|
help_text += "═══════════════════════\n\n"
|
|
|
|
for cmd in commands:
|
|
help_text += f"• {cmd['command']} - {cmd['description']}\n"
|
|
|
|
return {
|
|
"success": True,
|
|
"message": help_text,
|
|
"target": player_id,
|
|
"type": "info"
|
|
}
|
|
|
|
def _shout_command(self, player_id: str, args: str) -> Dict[str, Any]:
|
|
"""Send a message to all players with emphasis"""
|
|
if not args:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /shout <message>",
|
|
"target": player_id
|
|
}
|
|
|
|
player_name = self._get_player_name(player_id)
|
|
formatted_message = f"📢 {player_name} shouts: {args}"
|
|
|
|
self._add_to_history(formatted_message)
|
|
|
|
return {
|
|
"success": True,
|
|
"message": formatted_message,
|
|
"type": "shout",
|
|
"sender": player_id
|
|
}
|
|
|
|
def _emote_command(self, player_id: str, args: str) -> Dict[str, Any]:
|
|
"""Send an emote message"""
|
|
if not args:
|
|
return {
|
|
"success": False,
|
|
"message": "Usage: /emote <action> or /me <action>",
|
|
"target": player_id
|
|
}
|
|
|
|
player_name = self._get_player_name(player_id)
|
|
formatted_message = f"✨ {player_name} {args}"
|
|
|
|
self._add_to_history(formatted_message)
|
|
|
|
return {
|
|
"success": True,
|
|
"message": formatted_message,
|
|
"type": "emote",
|
|
"sender": player_id
|
|
}
|
|
|
|
def _time_command(self, player_id: str, args: str) -> Dict[str, Any]:
|
|
"""Show current game time"""
|
|
import datetime
|
|
current_time = datetime.datetime.now().strftime("%H:%M:%S")
|
|
|
|
return {
|
|
"success": True,
|
|
"message": f"🕐 Current time: {current_time}",
|
|
"target": player_id,
|
|
"type": "info"
|
|
}
|
|
|
|
def _channels_command(self, player_id: str, args: str) -> Dict[str, Any]:
|
|
"""Show available chat channels"""
|
|
channels = self.get_chat_channels()
|
|
channels_text = "📺 **CHAT CHANNELS:**\n"
|
|
channels_text += "═══════════════════\n\n"
|
|
|
|
for channel_id, channel_info in channels.items():
|
|
channels_text += f"• #{channel_id} - {channel_info['description']}\n"
|
|
|
|
return {
|
|
"success": True,
|
|
"message": channels_text,
|
|
"target": player_id,
|
|
"type": "info"
|
|
}
|
|
|
|
|
|
def _get_player_name(self, player_id: str) -> str:
|
|
"""Get player name from player ID"""
|
|
|
|
return f"Player{player_id[-3:]}" if len(player_id) > 3 else f"Player{player_id}"
|
|
|