添加 server.py
This commit is contained in:
212
server.py
Normal file
212
server.py
Normal file
@@ -0,0 +1,212 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Maya MCP Server
|
||||
Core implementation of the Model Context Protocol server for Maya.
|
||||
|
||||
Version: 1.0.0
|
||||
Author: Jeffrey Tsai
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import time
|
||||
import traceback
|
||||
import maya.cmds as cmds
|
||||
import maya.api.OpenMaya as om
|
||||
from port_config import SERVER_PORT
|
||||
from log_config import get_logger, initialize_logging
|
||||
|
||||
# Initialize logging
|
||||
initialize_logging()
|
||||
logger = get_logger("Server")
|
||||
|
||||
# Import HTTP handler
|
||||
try:
|
||||
from http_handler import start_http_server, stop_http_server, is_http_server_running, broadcast_event
|
||||
logger.info("HTTP handler imported successfully")
|
||||
except Exception as e:
|
||||
logger.error(f"Error importing HTTP handler: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
|
||||
# Global variables
|
||||
_server_running = False
|
||||
|
||||
# Public functions
|
||||
def start_server(port=SERVER_PORT):
|
||||
"""
|
||||
Start the MCP server
|
||||
|
||||
Args:
|
||||
port (int): Server port number
|
||||
|
||||
Returns:
|
||||
int: Port number if server started successfully, None otherwise
|
||||
"""
|
||||
global SERVER_PORT, _server_running
|
||||
|
||||
try:
|
||||
# Check if server is already running
|
||||
if _server_running:
|
||||
logger.info(f"Server already running on port {SERVER_PORT}")
|
||||
return SERVER_PORT
|
||||
|
||||
logger.info(f"Starting MCP server on port {port}...")
|
||||
|
||||
# Start HTTP server
|
||||
http_port = start_http_server(port)
|
||||
|
||||
if http_port:
|
||||
_server_running = True
|
||||
SERVER_PORT = http_port
|
||||
|
||||
logger.info(f"MCP server successfully started on port {SERVER_PORT}")
|
||||
|
||||
# Get Maya info
|
||||
try:
|
||||
maya_info = {
|
||||
"maya_version": cmds.about(version=True),
|
||||
"maya_api_version": om.MGlobal.apiVersion(),
|
||||
"os_name": cmds.about(operatingSystem=True),
|
||||
"product_name": cmds.about(product=True)
|
||||
}
|
||||
|
||||
logger.info(f"Maya info: {maya_info}")
|
||||
|
||||
# Broadcast Maya info event
|
||||
try:
|
||||
broadcast_event("maya_info", maya_info)
|
||||
logger.debug("Maya info event broadcasted")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error broadcasting Maya info: {e}")
|
||||
logger.debug(traceback.format_exc())
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting Maya info: {e}")
|
||||
logger.debug(traceback.format_exc())
|
||||
|
||||
return SERVER_PORT
|
||||
else:
|
||||
logger.error(f"Failed to start HTTP server on port {port}")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Error starting server: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
return None
|
||||
|
||||
def stop_server():
|
||||
"""
|
||||
Stop the MCP server
|
||||
|
||||
Returns:
|
||||
bool: Whether server was successfully stopped
|
||||
"""
|
||||
global _server_running
|
||||
|
||||
try:
|
||||
if _server_running:
|
||||
logger.info("Stopping MCP server...")
|
||||
|
||||
# Stop HTTP server
|
||||
success = stop_http_server()
|
||||
|
||||
if success:
|
||||
_server_running = False
|
||||
logger.info("MCP server stopped successfully")
|
||||
else:
|
||||
logger.error("Failed to stop HTTP server")
|
||||
|
||||
return success
|
||||
else:
|
||||
logger.info("Server is not running")
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.error(f"Error stopping server: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
return False
|
||||
|
||||
def is_server_running():
|
||||
"""
|
||||
Check if server is running
|
||||
|
||||
Returns:
|
||||
bool: Whether server is running
|
||||
"""
|
||||
global _server_running
|
||||
|
||||
if _server_running:
|
||||
return is_http_server_running()
|
||||
return False
|
||||
|
||||
def get_scene_info():
|
||||
"""
|
||||
Get Maya scene information
|
||||
|
||||
Returns:
|
||||
dict: Scene information
|
||||
"""
|
||||
try:
|
||||
logger.debug("Getting scene information...")
|
||||
|
||||
# Get current file
|
||||
try:
|
||||
current_file = cmds.file(query=True, sceneName=True) or "untitled"
|
||||
logger.debug(f"Current file: {current_file}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting current file: {e}")
|
||||
logger.debug(traceback.format_exc())
|
||||
current_file = "unknown"
|
||||
|
||||
# Get selection
|
||||
try:
|
||||
# Ensure to pass boolean True, not the string "True"
|
||||
selection = cmds.ls(sl=True) or []
|
||||
logger.debug(f"Selection: {selection}")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting selection: {e}")
|
||||
logger.debug(traceback.format_exc())
|
||||
selection = []
|
||||
|
||||
# Get scene objects
|
||||
try:
|
||||
objects = cmds.ls(type="transform") or []
|
||||
logger.debug(f"Found {len(objects)} transform objects")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting objects: {e}")
|
||||
logger.debug(traceback.format_exc())
|
||||
objects = []
|
||||
|
||||
# Get cameras
|
||||
try:
|
||||
cameras = cmds.ls(type="camera") or []
|
||||
logger.debug(f"Found {len(cameras)} cameras")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting cameras: {e}")
|
||||
logger.debug(traceback.format_exc())
|
||||
cameras = []
|
||||
|
||||
# Get lights
|
||||
try:
|
||||
lights = cmds.ls(type="light") or []
|
||||
logger.debug(f"Found {len(lights)} lights")
|
||||
except Exception as e:
|
||||
logger.warning(f"Error getting lights: {e}")
|
||||
logger.debug(traceback.format_exc())
|
||||
lights = []
|
||||
|
||||
# Create scene info
|
||||
scene_info = {
|
||||
"file": current_file,
|
||||
"selection": selection,
|
||||
"objects": objects[:10], # Limit to first 10
|
||||
"cameras": cameras,
|
||||
"lights": lights
|
||||
}
|
||||
|
||||
logger.debug(f"Scene info retrieved: {len(str(scene_info))} bytes")
|
||||
return scene_info
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting scene info: {e}")
|
||||
logger.error(traceback.format_exc())
|
||||
return {"error": str(e)}
|
Reference in New Issue
Block a user