| """ |
| CanRun Game Compatibility Checker - Simple MCP Server Implementation |
| """ |
|
|
| import gradio as gr |
| import logging |
| import os |
| import signal |
| import sys |
| import time |
| import asyncio |
| import base64 |
| import platform |
|
|
| |
| IS_WINDOWS = platform.system() == "Windows" |
| from src.canrun_engine import CanRunEngine |
| from plugin import CanRunGAssistPlugin |
|
|
| |
| logging.basicConfig( |
| level=logging.INFO, |
| format="%(asctime)s - %(levelname)s - %(message)s", |
| handlers=[logging.StreamHandler(sys.stdout)] |
| ) |
| logger = logging.getLogger(__name__) |
|
|
| def signal_handler(signum, frame): |
| """Handle shutdown signals gracefully.""" |
| logger.info(f"Received signal {signum}, shutting down gracefully...") |
| sys.exit(0) |
|
|
| async def analyze_game(game_name): |
| """Analyze game compatibility using the CanRun engine""" |
| if not game_name: |
| return "Please enter a game name to begin the analysis." |
| |
| try: |
| plugin = CanRunGAssistPlugin() |
| params = {"game_name": game_name, "force_refresh": True} |
| |
| response = await plugin.check_game_compatibility(params) |
| |
| if response.get("success", False): |
| return response.get("message", "Analysis completed successfully.") |
| else: |
| return response.get("message", "Could not analyze the game. Please check the game name and try again.") |
| except Exception as e: |
| logger.error(f"Error analyzing game: {e}") |
| return f"An error occurred during analysis: {e}" |
|
|
| def detect_hardware(): |
| """Detect hardware specifications""" |
| try: |
| plugin = CanRunGAssistPlugin() |
| response = plugin.detect_hardware({}) |
| |
| if response.get("success", False): |
| return response.get("message", "Hardware detection successful.") |
| else: |
| return response.get("message", "Could not detect hardware specifications.") |
| except Exception as e: |
| logger.error(f"Error detecting hardware: {e}") |
| return f"An error occurred during hardware detection: {e}" |
|
|
| def get_logo_html(): |
| """Get HTML that displays the logo""" |
| logo_path = os.path.join(os.path.dirname(__file__), "logo.png") |
| |
| if os.path.exists(logo_path): |
| |
| with open(logo_path, "rb") as image_file: |
| encoded_image = base64.b64encode(image_file.read()).decode("utf-8") |
| |
| |
| return f""" |
| <div style="display: flex; align-items: center; margin-bottom: 0.5em"> |
| <img src="data:image/png;base64,{encoded_image}" alt="CanRun Logo" style="height: 4em; margin-right: 1em;"> |
| <div> |
| <h1 style="margin: 0; padding: 0">CanRun Game Compatibility Checker</h1> |
| <p style="margin: 0; padding: 0">Check if your PC can run any game with an advanced tier system and Steam API integration</p> |
| </div> |
| </div> |
| """ |
| else: |
| logger.warning(f"Logo file not found at {logo_path}") |
| return """ |
| <div> |
| <h1>CanRun Game Compatibility Checker</h1> |
| <p>Check if your PC can run any game with an advanced tier system and Steam API integration</p> |
| </div> |
| """ |
|
|
| def create_gradio_interface(): |
| """Create a simple Gradio interface with logo and favicon""" |
| |
| theme = gr.themes.Default( |
| primary_hue="green", |
| secondary_hue="gray", |
| ) |
| |
| |
| favicon_path = os.path.join(os.path.dirname(__file__), "logo.png") |
| |
| with gr.Blocks(theme=theme, title="CanRun - Game Compatibility Checker", css="") as demo: |
| |
| gr.HTML(get_logo_html()) |
| |
| |
| with gr.Row(): |
| with gr.Column(): |
| game_input = gr.Textbox(label="Game Name", placeholder="Enter game name (e.g., Diablo 4)") |
| check_btn = gr.Button("Check Compatibility", variant="primary") |
| hw_btn = gr.Button("Detect Hardware", variant="secondary") |
| |
| with gr.Column(): |
| result_output = gr.Textbox(label="Results", lines=20) |
| |
| |
| gr.HTML(""" |
| <div style="margin-top: 20px; text-align: center; padding: 10px; border-top: 1px solid #ddd;"> |
| <p>CanRun - Advanced Game Compatibility Checker with MCP Server Support</p> |
| <p>Powered by G-Assist Integration</p> |
| </div> |
| """) |
| |
| |
| check_btn.click(fn=analyze_game, inputs=game_input, outputs=result_output) |
| hw_btn.click(fn=detect_hardware, inputs=None, outputs=result_output) |
| |
| return demo |
|
|
| def is_mcp_available(): |
| """Check if the MCP package is available""" |
| try: |
| import mcp |
| return True |
| except ImportError: |
| return False |
|
|
| def main(): |
| """Main application entry point""" |
| |
| signal.signal(signal.SIGINT, signal_handler) |
| signal.signal(signal.SIGTERM, signal_handler) |
| |
| logger.info("Starting CanRun Game Compatibility Checker") |
| |
| |
| demo = create_gradio_interface() |
| |
| |
| mcp_enabled = is_mcp_available() |
| if mcp_enabled: |
| logger.info("MCP server functionality is enabled") |
| else: |
| logger.info("MCP server functionality is disabled. Install with 'pip install \"gradio[mcp]\"' to enable") |
| |
| |
| launch_kwargs = { |
| "server_name": "0.0.0.0", |
| "share": False, |
| "favicon_path": os.path.join(os.path.dirname(__file__), "logo.png"), |
| } |
| |
| |
| if mcp_enabled: |
| launch_kwargs["mcp_server"] = True |
| |
| |
| demo.queue().launch(**launch_kwargs) |
| |
| |
| logger.info("Press Ctrl+C to stop the server") |
| try: |
| |
| while True: |
| time.sleep(1) |
| except KeyboardInterrupt: |
| logger.info("Keyboard interrupt received, shutting down...") |
| sys.exit(0) |
|
|
| if __name__ == "__main__": |
| main() |