初始化项目以及GUI简单实现

This commit is contained in:
moweishan
2026-03-18 15:48:40 +08:00
parent f7e429a9b3
commit b67c5be2f3
25 changed files with 1650 additions and 0 deletions

14
src/core/__init__.py Normal file
View File

@@ -0,0 +1,14 @@
"""
LuoLuoTool 核心模块
游戏自动化控制核心
"""
from .automation import AutomationController
from .game_window import GameWindowManager
from .actions import GameActions
__all__ = [
"AutomationController",
"GameWindowManager",
"GameActions",
]

41
src/core/actions.py Normal file
View File

@@ -0,0 +1,41 @@
"""
游戏动作定义
"""
import time
from typing import Optional
from src.utils.logger import logger
from .game_window import GameWindowManager
class GameActions:
"""游戏动作执行器"""
def __init__(self, window_manager: GameWindowManager):
self.window = window_manager
def click(self, x: int, y: int, delay: float = 0.1):
"""点击指定坐标"""
self.window.click(x, y)
time.sleep(delay)
def click_template(self, template_name: str, timeout: float = 5.0) -> bool:
"""点击匹配到的模板图像"""
# TODO: 实现模板匹配点击
logger.debug(f"尝试点击模板: {template_name}")
return False
def wait(self, seconds: float):
"""等待指定时间"""
time.sleep(seconds)
def swipe(self, x1: int, y1: int, x2: int, y2: int, duration: float = 0.5):
"""滑动操作"""
# TODO: 实现滑动
logger.debug(f"滑动: ({x1}, {y1}) -> ({x2}, {y2})")
def press_key(self, key: str):
"""按下键盘按键"""
# TODO: 实现按键
logger.debug(f"按键: {key}")

87
src/core/automation.py Normal file
View File

@@ -0,0 +1,87 @@
"""
自动化控制主类
"""
import threading
import time
from typing import Optional, Callable
from src.utils.logger import logger
from .game_window import GameWindowManager
from .actions import GameActions
class AutomationController:
"""自动化控制器"""
def __init__(self):
self.window_manager = GameWindowManager()
self.actions = GameActions(self.window_manager)
self._running = False
self._paused = False
self._thread: Optional[threading.Thread] = None
self._callback: Optional[Callable] = None
@property
def is_running(self) -> bool:
return self._running
@property
def is_paused(self) -> bool:
return self._paused
def set_callback(self, callback: Callable):
"""设置状态回调函数"""
self._callback = callback
def _notify(self, message: str):
"""通知UI更新"""
logger.info(message)
if self._callback:
self._callback(message)
def start(self):
"""开始自动化"""
if self._running:
return
if not self.window_manager.is_window_captured:
self._notify("请先捕获游戏窗口")
return
self._running = True
self._paused = False
self._thread = threading.Thread(target=self._run_loop, daemon=True)
self._thread.start()
self._notify("自动化已启动")
def stop(self):
"""停止自动化"""
self._running = False
self._paused = False
if self._thread:
self._thread.join(timeout=2)
self._notify("自动化已停止")
def pause(self):
"""暂停/继续"""
if not self._running:
return
self._paused = not self._paused
status = "已暂停" if self._paused else "已继续"
self._notify(f"自动化{status}")
def _run_loop(self):
"""主运行循环"""
while self._running:
if self._paused:
time.sleep(0.1)
continue
try:
# TODO: 实现具体的任务执行逻辑
time.sleep(0.1)
except Exception as e:
logger.error(f"运行错误: {e}")
self._notify(f"错误: {e}")

97
src/core/game_window.py Normal file
View File

@@ -0,0 +1,97 @@
"""
游戏窗口管理
"""
import win32gui
import win32con
from typing import Optional, Tuple
from src.utils.logger import logger
class GameWindowManager:
"""游戏窗口管理器"""
# 游戏窗口类名和标题
GAME_CLASS_NAME = "UnityWndClass" # Unity游戏常用类名
GAME_WINDOW_TITLE = "桃源深处有人家"
def __init__(self):
self._hwnd: Optional[int] = None
self._window_rect: Tuple[int, int, int, int] = (0, 0, 0, 0)
@property
def is_window_captured(self) -> bool:
"""是否已捕获窗口"""
if self._hwnd is None:
return False
return win32gui.IsWindow(self._hwnd)
@property
def hwnd(self) -> Optional[int]:
"""窗口句柄"""
return self._hwnd
@property
def window_rect(self) -> Tuple[int, int, int, int]:
"""窗口矩形 (left, top, right, bottom)"""
if self.is_window_captured:
self._window_rect = win32gui.GetWindowRect(self._hwnd)
return self._window_rect
@property
def client_size(self) -> Tuple[int, int]:
"""客户端区域大小 (width, height)"""
if not self.is_window_captured:
return (0, 0)
left, top, right, bottom = self.window_rect
return (right - left, bottom - top)
def find_window(self) -> bool:
"""查找游戏窗口"""
# 先尝试精确匹配
hwnd = win32gui.FindWindow(None, self.GAME_WINDOW_TITLE)
# 如果没找到,尝试模糊匹配
if hwnd == 0:
def callback(hwnd, extra):
if win32gui.IsWindowVisible(hwnd):
title = win32gui.GetWindowText(hwnd)
if self.GAME_WINDOW_TITLE in title:
extra.append(hwnd)
return True
windows = []
win32gui.EnumWindows(callback, windows)
if windows:
hwnd = windows[0]
if hwnd != 0:
self._hwnd = hwnd
self._window_rect = win32gui.GetWindowRect(hwnd)
logger.info(f"找到游戏窗口: {hwnd}, 大小: {self.client_size}")
return True
logger.warning("未找到游戏窗口")
return False
def capture_window(self) -> bool:
"""捕获游戏窗口"""
return self.find_window()
def bring_to_front(self):
"""将窗口置前"""
if self.is_window_captured:
win32gui.SetForegroundWindow(self._hwnd)
def click(self, x: int, y: int):
"""在窗口内点击"""
if not self.is_window_captured:
return
left, top, _, _ = self.window_rect
# 转换为屏幕坐标
screen_x = left + x
screen_y = top + y
# TODO: 使用pyautogui或win32api发送点击
logger.debug(f"点击坐标: ({screen_x}, {screen_y})")

View File

@@ -0,0 +1,14 @@
"""
挂机任务模块
所有任务逻辑代码写死实现
"""
from .daily_tasks import DailyTaskRunner
from .misc_tasks import MiscTaskRunner
from .pending_tasks import PendingTaskRunner
__all__ = [
"DailyTaskRunner",
"MiscTaskRunner",
"PendingTaskRunner",
]

View File

@@ -0,0 +1,69 @@
"""
日常挂机任务
"""
from typing import Dict, Any
from src.utils.logger import logger
class DailyTaskRunner:
"""日常任务执行器"""
# 任务配置 - 代码写死
TASKS = {
"daily_mission": {
"name": "每日委托",
"enabled": True,
"description": "完成每日任务",
},
"resin_farming": {
"name": "清体力",
"enabled": True,
"description": "消耗体力刷资源",
},
"monthly_card": {
"name": "领月卡",
"enabled": False,
"description": "领取月卡奖励",
},
"friend_gift": {
"name": "好友礼物",
"enabled": True,
"description": "领取好友赠送的礼物",
},
"shop_daily": {
"name": "每日商店",
"enabled": False,
"description": "购买每日商店物品",
},
}
def __init__(self):
self._config = self.TASKS.copy()
def get_tasks(self) -> Dict[str, Any]:
"""获取所有任务配置"""
return self._config
def update_task(self, task_id: str, enabled: bool):
"""更新任务启用状态"""
if task_id in self._config:
self._config[task_id]["enabled"] = enabled
logger.info(f"任务 {task_id} 状态更新为: {enabled}")
def run(self, actions):
"""执行启用的任务"""
for task_id, config in self._config.items():
if not config["enabled"]:
continue
logger.info(f"执行任务: {config['name']}")
try:
self._execute_task(task_id, actions)
except Exception as e:
logger.error(f"任务 {config['name']} 执行失败: {e}")
def _execute_task(self, task_id: str, actions):
"""执行具体任务"""
# TODO: 实现具体任务逻辑
logger.debug(f"执行任务逻辑: {task_id}")

View File

@@ -0,0 +1,64 @@
"""
杂项功能任务
"""
from typing import Dict, Any
from src.utils.logger import logger
class MiscTaskRunner:
"""杂项功能执行器"""
# 功能配置 - 代码写死
FEATURES = {
"auto_pickup": {
"name": "自动拾取",
"enabled": True,
"description": "自动拾取掉落物品",
},
"auto_skip": {
"name": "自动跳过对话",
"enabled": False,
"description": "自动跳过游戏对话",
},
"auto_heal": {
"name": "自动回血",
"enabled": True,
"description": "低血量自动回血",
},
"auto_repair": {
"name": "自动修理",
"enabled": False,
"description": "装备损坏自动修理",
},
}
def __init__(self):
self._config = self.FEATURES.copy()
def get_features(self) -> Dict[str, Any]:
"""获取所有功能配置"""
return self._config
def update_feature(self, feature_id: str, enabled: bool):
"""更新功能启用状态"""
if feature_id in self._config:
self._config[feature_id]["enabled"] = enabled
logger.info(f"功能 {feature_id} 状态更新为: {enabled}")
def run(self, actions):
"""执行启用的功能"""
for feature_id, config in self._config.items():
if not config["enabled"]:
continue
logger.info(f"执行功能: {config['name']}")
try:
self._execute_feature(feature_id, actions)
except Exception as e:
logger.error(f"功能 {config['name']} 执行失败: {e}")
def _execute_feature(self, feature_id: str, actions):
"""执行具体功能"""
# TODO: 实现具体功能逻辑
logger.debug(f"执行功能逻辑: {feature_id}")

View File

@@ -0,0 +1,48 @@
"""
待定功能任务
预留功能占位
"""
from typing import Dict, Any
from src.utils.logger import logger
class PendingTaskRunner:
"""待定功能执行器"""
# 待定功能配置 - 代码写死
PENDING_FEATURES = {
"feature_a": {
"name": "功能A待开发",
"enabled": False,
"description": "预留功能A",
},
"feature_b": {
"name": "功能B待开发",
"enabled": False,
"description": "预留功能B",
},
"feature_c": {
"name": "功能C待开发",
"enabled": False,
"description": "预留功能C",
},
}
def __init__(self):
self._config = self.PENDING_FEATURES.copy()
def get_features(self) -> Dict[str, Any]:
"""获取所有待定功能"""
return self._config
def update_feature(self, feature_id: str, enabled: bool):
"""更新功能状态"""
if feature_id in self._config:
self._config[feature_id]["enabled"] = enabled
logger.info(f"待定功能 {feature_id} 状态更新为: {enabled}")
def run(self, actions):
"""执行启用的功能"""
logger.info("待定功能模块 - 暂无实现")
# 待定功能暂不执行任何操作