commit
5cba0b970c
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,6 +1,8 @@
|
||||
.env
|
||||
*.log
|
||||
llm_debug.log
|
||||
config.py
|
||||
__pycache__/
|
||||
debug_screenshots/
|
||||
chat_logs/
|
||||
chat_logs/
|
||||
backup/
|
||||
134
config.py
134
config.py
@ -1,134 +0,0 @@
|
||||
# config.py
|
||||
import os
|
||||
import json # Import json for building args string
|
||||
from dotenv import load_dotenv # Import load_dotenv
|
||||
|
||||
# --- Load environment variables from .env file ---
|
||||
load_dotenv()
|
||||
print("Attempted to load environment variables from .env file.")
|
||||
# --- End Load ---
|
||||
|
||||
# OpenAI API Configuration / OpenAI-Compatible Provider Settings
|
||||
# --- Modify these lines ---
|
||||
# Leave OPENAI_API_BASE_URL as None or "" to use official OpenAI
|
||||
OPENAI_API_BASE_URL = "https://openrouter.ai/api/v1" # <--- For example "http://localhost:1234/v1" or your provider URL
|
||||
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
||||
#LLM_MODEL = "anthropic/claude-3.7-sonnet"
|
||||
#LLM_MODEL = "meta-llama/llama-4-maverick"
|
||||
#LLM_MODEL = "deepseek/deepseek-chat-v3-0324:free"
|
||||
#LLM_MODEL = "google/gemini-2.5-flash-preview"
|
||||
LLM_MODEL = "deepseek/deepseek-chat-v3-0324" # <--- Ensure this matches the model name provided by your provider
|
||||
|
||||
#LLM_MODEL = "openai/gpt-4.1-nano"
|
||||
|
||||
EXA_API_KEY = os.getenv("EXA_API_KEY")
|
||||
MCP_REDIS_API_KEY = os.getenv("MCP_REDIS_APU_KEY")
|
||||
MCP_REDIS_PATH = os.getenv("MCP_REDIS_PATH")
|
||||
|
||||
# --- Dynamically build Exa server args ---
|
||||
exa_config_dict = {"exaApiKey": EXA_API_KEY if EXA_API_KEY else "YOUR_EXA_KEY_MISSING"}
|
||||
# Need to dump dict to JSON string, then properly escape it for cmd arg
|
||||
# Using json.dumps handles internal quotes correctly.
|
||||
# The outer quotes for cmd might need careful handling depending on OS / shell.
|
||||
# For cmd /c on Windows, embedding escaped JSON often works like this:
|
||||
exa_config_arg_string = json.dumps(json.dumps(exa_config_dict)) # Double dump for cmd escaping? Or just one? Test needed.
|
||||
# Let's try single dump first, often sufficient if passed correctly by subprocess
|
||||
exa_config_arg_string_single_dump = json.dumps(exa_config_dict) # Use this one
|
||||
|
||||
# --- MCP Server Configuration ---
|
||||
MCP_SERVERS = {
|
||||
#"exa": { # Temporarily commented out to prevent blocking startup
|
||||
## "command": "cmd",
|
||||
# "args": [
|
||||
# "/c",
|
||||
# "npx",
|
||||
# "-y",
|
||||
# "@smithery/cli@latest",
|
||||
# "run",
|
||||
# "exa",
|
||||
# "--config",
|
||||
# # Pass the dynamically created config string with the environment variable key
|
||||
# exa_config_arg_string_single_dump # Use the single dump variable
|
||||
# ],
|
||||
#},
|
||||
"exa": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"C:/Users/Bigspring/AppData/Roaming/npm/exa-mcp-server",
|
||||
"--tools=web_search,research_paper_search,twitter_search,company_research,crawling,competitor_finder"
|
||||
],
|
||||
"env": {
|
||||
"EXA_API_KEY": EXA_API_KEY
|
||||
}
|
||||
},
|
||||
#"github.com/modelcontextprotocol/servers/tree/main/src/memory": {
|
||||
# "command": "npx",
|
||||
# "args": [
|
||||
# "-y",
|
||||
# "@modelcontextprotocol/server-memory"
|
||||
# ],
|
||||
# "disabled": False
|
||||
#},
|
||||
#"redis": {
|
||||
# "command": "uv",
|
||||
# "args": [
|
||||
# "--directory",
|
||||
# MCP_REDIS_PATH,
|
||||
# "run",
|
||||
# "src/main.py"
|
||||
# ],
|
||||
# "env": {
|
||||
# "REDIS_HOST": "127.0.0.1",
|
||||
# "REDIS_PORT": "6379",
|
||||
# "REDIS_SSL": "False",
|
||||
# "REDIS_CLUSTER_MODE": "False"
|
||||
# }
|
||||
# }
|
||||
#"basic-memory": {
|
||||
# "command": "uvx",
|
||||
# "args": [
|
||||
# "basic-memory",
|
||||
# "mcp"
|
||||
# ],
|
||||
#}
|
||||
"chroma": {
|
||||
"command": "uvx",
|
||||
"args": [
|
||||
"chroma-mcp",
|
||||
"--client-type",
|
||||
"persistent",
|
||||
"--data-dir",
|
||||
"Z:/mcp/Server/Chroma-MCP"
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# MCP Client Configuration
|
||||
MCP_CONFIRM_TOOL_EXECUTION = False # True: Confirm before execution, False: Execute automatically
|
||||
|
||||
# --- Chat Logging Configuration ---
|
||||
ENABLE_CHAT_LOGGING = True # True: Enable logging, False: Disable logging
|
||||
LOG_DIR = "chat_logs" # Directory to store chat logs
|
||||
|
||||
# Persona Configuration
|
||||
PERSONA_NAME = "Wolfhart"
|
||||
# PERSONA_RESOURCE_URI = "persona://wolfhart/details" # Now using local file instead
|
||||
|
||||
# Game window title (used in ui_interaction.py and game_monitor.py)
|
||||
WINDOW_TITLE = "Last War-Survival Game"
|
||||
|
||||
# --- Game Monitor Configuration ---
|
||||
ENABLE_SCHEDULED_RESTART = True # 是否啟用定時重啟遊戲功能
|
||||
RESTART_INTERVAL_MINUTES = 60 # 定時重啟的間隔時間(分鐘),預設 4 小時
|
||||
GAME_EXECUTABLE_PATH = r"C:\Users\Bigspring\AppData\Local\TheLastWar\Launch.exe" # Path to the game launcher
|
||||
GAME_WINDOW_X = 50 # Target X position for the game window
|
||||
GAME_WINDOW_Y = 30 # Target Y position for the game window
|
||||
GAME_WINDOW_WIDTH = 600 # Target width for the game window
|
||||
GAME_WINDOW_HEIGHT = 1070 # Target height for the game window
|
||||
MONITOR_INTERVAL_SECONDS = 5 # How often to check the window (in seconds)
|
||||
|
||||
# --- Print loaded keys for verification (Optional - BE CAREFUL!) ---
|
||||
# print(f"DEBUG: Loaded OPENAI_API_KEY: {'*' * (len(OPENAI_API_KEY) - 4) + OPENAI_API_KEY[-4:] if OPENAI_API_KEY else 'Not Found'}")
|
||||
print(f"DEBUG: Loaded EXA_API_KEY: {'*' * (len(EXA_API_KEY) - 4) + EXA_API_KEY[-4:] if EXA_API_KEY else 'Not Found'}") # Uncommented Exa key check
|
||||
# print(f"DEBUG: Exa args: {MCP_SERVERS['exa']['args']}")
|
||||
62
config_template.py
Normal file
62
config_template.py
Normal file
@ -0,0 +1,62 @@
|
||||
# ====================================================================
|
||||
# Wolf Chat Configuration Template
|
||||
# This file is used by setup.py to generate the final config.py
|
||||
# ====================================================================
|
||||
import os
|
||||
import json
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# --- Load environment variables from .env file ---
|
||||
load_dotenv()
|
||||
print("Loaded environment variables from .env file.")
|
||||
|
||||
# =============================================================================
|
||||
# OpenAI API Configuration / OpenAI-Compatible Provider Settings
|
||||
# =============================================================================
|
||||
# Leave OPENAI_API_BASE_URL as None or "" to use official OpenAI
|
||||
OPENAI_API_BASE_URL = "${OPENAI_API_BASE_URL}"
|
||||
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
|
||||
LLM_MODEL = "${LLM_MODEL}"
|
||||
|
||||
# =============================================================================
|
||||
# External API Keys
|
||||
# =============================================================================
|
||||
EXA_API_KEY = os.getenv("EXA_API_KEY")
|
||||
|
||||
# --- Exa Configuration ---
|
||||
exa_config_dict = {"exaApiKey": EXA_API_KEY if EXA_API_KEY else "YOUR_EXA_KEY_MISSING"}
|
||||
exa_config_arg_string = json.dumps(exa_config_dict)
|
||||
|
||||
# =============================================================================
|
||||
# MCP Server Configuration
|
||||
# =============================================================================
|
||||
MCP_SERVERS = ${MCP_SERVERS}
|
||||
|
||||
# =============================================================================
|
||||
# MCP Client Configuration
|
||||
# =============================================================================
|
||||
MCP_CONFIRM_TOOL_EXECUTION = False # True: Confirm before execution, False: Execute automatically
|
||||
|
||||
# =============================================================================
|
||||
# Chat Logging Configuration
|
||||
# =============================================================================
|
||||
ENABLE_CHAT_LOGGING = ${ENABLE_CHAT_LOGGING}
|
||||
LOG_DIR = "${LOG_DIR}"
|
||||
|
||||
# =============================================================================
|
||||
# Persona Configuration
|
||||
# =============================================================================
|
||||
PERSONA_NAME = "Wolfhart"
|
||||
|
||||
# =============================================================================
|
||||
# Game Window Configuration
|
||||
# =============================================================================
|
||||
WINDOW_TITLE = "${WINDOW_TITLE}"
|
||||
ENABLE_SCHEDULED_RESTART = ${ENABLE_SCHEDULED_RESTART}
|
||||
RESTART_INTERVAL_MINUTES = ${RESTART_INTERVAL_MINUTES}
|
||||
GAME_EXECUTABLE_PATH = r"${GAME_EXECUTABLE_PATH}"
|
||||
GAME_WINDOW_X = ${GAME_WINDOW_X}
|
||||
GAME_WINDOW_Y = ${GAME_WINDOW_Y}
|
||||
GAME_WINDOW_WIDTH = ${GAME_WINDOW_WIDTH}
|
||||
GAME_WINDOW_HEIGHT = ${GAME_WINDOW_HEIGHT}
|
||||
MONITOR_INTERVAL_SECONDS = ${MONITOR_INTERVAL_SECONDS}
|
||||
137
install.py
Normal file
137
install.py
Normal file
@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Wolf Chat Installation Script
|
||||
Installs required dependencies for Wolf Chat
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox
|
||||
|
||||
REQUIREMENTS = [
|
||||
"openai",
|
||||
"mcp",
|
||||
"pyautogui",
|
||||
"opencv-python",
|
||||
"numpy",
|
||||
"pyperclip",
|
||||
"pygetwindow",
|
||||
"psutil",
|
||||
"pywin32",
|
||||
"python-dotenv",
|
||||
"keyboard"
|
||||
]
|
||||
|
||||
def install_requirements(progress_var=None, status_label=None, root=None):
|
||||
"""Install all required packages using pip"""
|
||||
|
||||
total = len(REQUIREMENTS)
|
||||
success_count = 0
|
||||
failed_packages = []
|
||||
|
||||
for i, package in enumerate(REQUIREMENTS):
|
||||
if status_label:
|
||||
status_label.config(text=f"Installing {package}...")
|
||||
if progress_var:
|
||||
progress_var.set((i / total) * 100)
|
||||
if root:
|
||||
root.update()
|
||||
|
||||
try:
|
||||
print(f"Installing {package}...")
|
||||
# Use subprocess to run pip install
|
||||
process = subprocess.run(
|
||||
[sys.executable, "-m", "pip", "install", package],
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True
|
||||
)
|
||||
print(f"Successfully installed {package}")
|
||||
success_count += 1
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Failed to install {package}: {e}")
|
||||
print(f"Error output: {e.stderr}")
|
||||
failed_packages.append(package)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Unexpected error installing {package}: {str(e)}")
|
||||
failed_packages.append(package)
|
||||
|
||||
# Final progress update
|
||||
if progress_var:
|
||||
progress_var.set(100)
|
||||
|
||||
# Report results
|
||||
if not failed_packages:
|
||||
result_message = f"All {success_count} packages installed successfully!"
|
||||
print(result_message)
|
||||
if status_label:
|
||||
status_label.config(text=result_message)
|
||||
return True, result_message
|
||||
else:
|
||||
result_message = f"Installed {success_count}/{total} packages. Failed: {', '.join(failed_packages)}"
|
||||
print(result_message)
|
||||
if status_label:
|
||||
status_label.config(text=result_message)
|
||||
return False, result_message
|
||||
|
||||
def run_installer_gui():
|
||||
"""Run a simple GUI for the installer"""
|
||||
root = tk.Tk()
|
||||
root.title("Wolf Chat Installer")
|
||||
root.geometry("400x200")
|
||||
root.resizable(False, False)
|
||||
|
||||
# Main frame
|
||||
main_frame = ttk.Frame(root, padding=20)
|
||||
main_frame.pack(fill=tk.BOTH, expand=True)
|
||||
|
||||
# Title
|
||||
title_label = ttk.Label(main_frame, text="Wolf Chat Dependency Installer", font=("", 12, "bold"))
|
||||
title_label.pack(pady=(0, 10))
|
||||
|
||||
# Info text
|
||||
info_text = f"This will install {len(REQUIREMENTS)} required packages for Wolf Chat."
|
||||
info_label = ttk.Label(main_frame, text=info_text)
|
||||
info_label.pack(pady=(0, 15))
|
||||
|
||||
# Progress bar
|
||||
progress_var = tk.DoubleVar()
|
||||
progress_bar = ttk.Progressbar(main_frame, variable=progress_var, maximum=100)
|
||||
progress_bar.pack(fill=tk.X, pady=(0, 10))
|
||||
|
||||
# Status label
|
||||
status_label = ttk.Label(main_frame, text="Ready to install...")
|
||||
status_label.pack(pady=(0, 15))
|
||||
|
||||
# Install button
|
||||
def start_installation():
|
||||
# Disable button during installation
|
||||
install_button.config(state=tk.DISABLED)
|
||||
|
||||
# Run installation in a separate thread to keep UI responsive
|
||||
success, message = install_requirements(progress_var, status_label, root)
|
||||
|
||||
# Show completion message
|
||||
if success:
|
||||
messagebox.showinfo("Installation Complete", message)
|
||||
else:
|
||||
messagebox.showwarning("Installation Issues", message)
|
||||
|
||||
# Close the window
|
||||
root.destroy()
|
||||
|
||||
install_button = ttk.Button(main_frame, text="Install Dependencies", command=start_installation)
|
||||
install_button.pack()
|
||||
|
||||
# Start the GUI loop
|
||||
root.mainloop()
|
||||
|
||||
if __name__ == "__main__":
|
||||
# If run directly, show GUI
|
||||
run_installer_gui()
|
||||
@ -1,121 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Game Window Monitor Script - Keep game window on top and in position
|
||||
|
||||
This script monitors a specified game window, ensuring it stays
|
||||
always on top and at the desired screen coordinates.
|
||||
"""
|
||||
|
||||
import time
|
||||
import argparse
|
||||
import pygetwindow as gw
|
||||
import win32gui
|
||||
import win32con
|
||||
|
||||
def find_window_by_title(window_title):
|
||||
"""Find the first window matching the title."""
|
||||
try:
|
||||
windows = gw.getWindowsWithTitle(window_title)
|
||||
if windows:
|
||||
return windows[0]
|
||||
except Exception as e:
|
||||
# pygetwindow can sometimes raise exceptions if a window disappears
|
||||
# during enumeration. Ignore these for monitoring purposes.
|
||||
# print(f"Error finding window: {e}")
|
||||
pass
|
||||
return None
|
||||
|
||||
def set_window_always_on_top(hwnd):
|
||||
"""Set the window to be always on top."""
|
||||
try:
|
||||
win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, 0, 0, 0, 0,
|
||||
win32con.SWP_NOMOVE | win32con.SWP_NOSIZE | win32con.SWP_SHOWWINDOW)
|
||||
# print(f"Window {hwnd} set to always on top.")
|
||||
except Exception as e:
|
||||
print(f"Error setting window always on top: {e}")
|
||||
|
||||
def move_window_if_needed(window, target_x, target_y):
|
||||
"""Move the window to the target coordinates if it's not already there."""
|
||||
try:
|
||||
current_x, current_y = window.topleft
|
||||
if current_x != target_x or current_y != target_y:
|
||||
print(f"Window moved from ({current_x}, {current_y}). Moving back to ({target_x}, {target_y}).")
|
||||
window.moveTo(target_x, target_y)
|
||||
# print(f"Window moved to ({target_x}, {target_y}).")
|
||||
except gw.PyGetWindowException as e:
|
||||
# Handle cases where the window might close unexpectedly
|
||||
print(f"Error accessing window properties (might be closed): {e}")
|
||||
except Exception as e:
|
||||
print(f"Error moving window: {e}")
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Game Window Monitor Tool')
|
||||
parser.add_argument('--window_title', default="Last War-Survival Game", help='Game window title to monitor')
|
||||
parser.add_argument('--x', type=int, default=50, help='Target window X coordinate')
|
||||
parser.add_argument('--y', type=int, default=30, help='Target window Y coordinate')
|
||||
parser.add_argument('--interval', type=float, default=1.0, help='Check interval in seconds')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
print(f"Monitoring window: '{args.window_title}'")
|
||||
print(f"Target position: ({args.x}, {args.y})")
|
||||
print(f"Check interval: {args.interval} seconds")
|
||||
print("Press Ctrl+C to stop.")
|
||||
|
||||
hwnd = None
|
||||
last_hwnd_check_time = 0
|
||||
|
||||
try:
|
||||
while True:
|
||||
current_time = time.time()
|
||||
window = None
|
||||
|
||||
# Find window handle (HWND) - less frequent check if already found
|
||||
# pygetwindow can be slow, so avoid calling it too often if we have a valid handle
|
||||
if not hwnd or current_time - last_hwnd_check_time > 5: # Re-check HWND every 5 seconds
|
||||
window_obj = find_window_by_title(args.window_title)
|
||||
if window_obj:
|
||||
# Get the HWND (window handle) needed for win32gui
|
||||
# Accessing _hWnd is using an internal attribute, but it's common practice with pygetwindow
|
||||
try:
|
||||
hwnd = window_obj._hWnd
|
||||
window = window_obj # Keep the pygetwindow object for position checks
|
||||
last_hwnd_check_time = current_time
|
||||
# print(f"Found window HWND: {hwnd}")
|
||||
except AttributeError:
|
||||
print("Could not get HWND from window object. Retrying...")
|
||||
hwnd = None
|
||||
else:
|
||||
if hwnd:
|
||||
print(f"Window '{args.window_title}' lost.")
|
||||
hwnd = None # Reset hwnd if window not found
|
||||
|
||||
if hwnd:
|
||||
# Ensure it's always on top
|
||||
set_window_always_on_top(hwnd)
|
||||
|
||||
# Check and correct position using the pygetwindow object if available
|
||||
# Re-find the pygetwindow object if needed for position check
|
||||
if not window:
|
||||
window = find_window_by_title(args.window_title)
|
||||
|
||||
if window:
|
||||
move_window_if_needed(window, args.x, args.y)
|
||||
else:
|
||||
# If we have hwnd but can't get pygetwindow object, maybe it's closing
|
||||
print(f"Have HWND {hwnd} but cannot get window object for position check.")
|
||||
hwnd = None # Force re-find next cycle
|
||||
|
||||
else:
|
||||
# print(f"Window '{args.window_title}' not found. Waiting...")
|
||||
pass # Wait for the window to appear
|
||||
|
||||
time.sleep(args.interval)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nMonitoring stopped by user.")
|
||||
except Exception as e:
|
||||
print(f"\nAn unexpected error occurred: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@ -1,103 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Game Window Setup Script - Adjust game window position and size
|
||||
|
||||
This script will launch the game and adjust its window to a specified position and size (100,100 1280x768),
|
||||
making it easier to take screenshots of UI elements for later use.
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
import pygetwindow as gw
|
||||
import psutil
|
||||
import argparse
|
||||
|
||||
def is_process_running(process_name):
|
||||
"""Check if a specified process is currently running"""
|
||||
for proc in psutil.process_iter(['name']):
|
||||
if proc.info['name'].lower() == process_name.lower():
|
||||
return True
|
||||
return False
|
||||
|
||||
def launch_game(game_path):
|
||||
"""Launch the game"""
|
||||
if not os.path.exists(game_path):
|
||||
print(f"Error: Game executable not found at {game_path}")
|
||||
return False
|
||||
|
||||
print(f"Launching game: {game_path}")
|
||||
subprocess.Popen(game_path)
|
||||
return True
|
||||
|
||||
def find_game_window(window_title, max_wait=30):
|
||||
"""Find the game window"""
|
||||
print(f"Searching for game window: {window_title}")
|
||||
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < max_wait:
|
||||
try:
|
||||
windows = gw.getWindowsWithTitle(window_title)
|
||||
if windows:
|
||||
return windows[0]
|
||||
except Exception as e:
|
||||
print(f"Error finding window: {e}")
|
||||
|
||||
print("Window not found, waiting 1 second before retrying...")
|
||||
time.sleep(1)
|
||||
|
||||
print(f"Error: Game window not found within {max_wait} seconds")
|
||||
return None
|
||||
|
||||
def set_window_position_size(window, x, y, width, height):
|
||||
"""Set window position and size"""
|
||||
try:
|
||||
print(f"Adjusting window position to ({x}, {y}) and size to {width}x{height}")
|
||||
window.moveTo(x, y)
|
||||
window.resizeTo(width, height)
|
||||
print("Window adjustment completed")
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"Error adjusting window: {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Game Window Setup Tool')
|
||||
parser.add_argument('--launch', action='store_true', help='Whether to launch the game')
|
||||
parser.add_argument('--game_path', default=r"C:\Users\Bigspring\AppData\Local\TheLastWar\Launch.exe", help='Game launcher path')
|
||||
parser.add_argument('--window_title', default="Last War-Survival Game", help='Game window title')
|
||||
parser.add_argument('--process_name', default="LastWar.exe", help='Game process name')
|
||||
parser.add_argument('--x', type=int, default=50, help='Window X coordinate')
|
||||
parser.add_argument('--y', type=int, default=30, help='Window Y coordinate')
|
||||
parser.add_argument('--width', type=int, default=600, help='Window width')
|
||||
parser.add_argument('--height', type=int, default=1070, help='Window height')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Check if game is already running
|
||||
if not is_process_running(args.process_name):
|
||||
if args.launch:
|
||||
# Launch the game
|
||||
if not launch_game(args.game_path):
|
||||
return
|
||||
else:
|
||||
print(f"Game process {args.process_name} is not running, please launch the game first or use the --launch parameter")
|
||||
return
|
||||
else:
|
||||
print(f"Game process {args.process_name} is already running")
|
||||
|
||||
# Find game window
|
||||
window = find_game_window(args.window_title)
|
||||
if not window:
|
||||
return
|
||||
|
||||
# Set window position and size
|
||||
set_window_position_size(window, args.x, args.y, args.width, args.height)
|
||||
|
||||
# Display final window state
|
||||
print("\nFinal window state:")
|
||||
print(f"Position: ({window.left}, {window.top})")
|
||||
print(f"Size: {window.width}x{window.height}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
x
Reference in New Issue
Block a user