马上注册,结交更多好友,享用更多功能,让你轻松玩转小K网。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
以管理员打开程序即可自动运行,初次修改为999999,低于500000将再次修改为999999。游戏金钱地址用CE修改器找到的,目前仅找到了修改金钱的方法,已经做到了自动修改。其他建造速度和超级武器未找到基址,欢迎各位大佬提供帮助。目前仅测试了红警2之心灵终结可用,其他版本未测试。
- import pymem
- import pymem.process
- import psutil
- import time
- import sys
- import threading
- import tkinter as tk
- from tkinter import ttk, messagebox, scrolledtext
- import ctypes
- class MoneyMonitorGUI:
- def __init__(self, root):
- self.root = root
- self.root.title("红警2金钱监控器")
- self.root.geometry("600x580")
- self.root.resizable(True, True)
-
- # 检查是否以管理员身份运行
- if not self.is_admin():
- self.show_admin_warning()
- return
-
- # 初始化监控器
- self.monitor = MoneyMonitor()
- self.monitor_thread = None
-
- # 创建界面
- self.create_widgets()
-
- # 重定向输出到文本框
- self.redirect_output()
-
- # 自动启动监控
- self.start_monitor()
-
- def is_admin(self):
- """检查是否以管理员身份运行"""
- try:
- return ctypes.windll.shell32.IsUserAnAdmin()
- except:
- return False
-
- def show_admin_warning(self):
- """显示管理员权限警告"""
- # 创建一个临时的顶层窗口用于显示警告
- temp_window = tk.Tk()
- temp_window.withdraw() # 隐藏主窗口
-
- messagebox.showerror("权限错误",
- "此程序需要以管理员身份运行才能正常工作!\n\n"
- "请右键点击程序图标,选择「以管理员身份运行」。")
-
- temp_window.destroy()
- self.root.destroy()
- sys.exit(1)
-
- def create_widgets(self):
- # 主框架
- main_frame = ttk.Frame(self.root, padding="10")
- main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
-
- # 配置网格权重
- self.root.columnconfigure(0, weight=1)
- self.root.rowconfigure(0, weight=1)
- main_frame.columnconfigure(1, weight=1)
- main_frame.rowconfigure(4, weight=1)
-
- # 标题
- title_label = ttk.Label(main_frame, text="红警2金钱监控器", font=("Arial", 16, "bold"))
- title_label.grid(row=0, column=0, columnspan=3, pady=(0, 20))
-
- # 操作按钮框架
- button_frame = ttk.LabelFrame(main_frame, text="操作选项", padding="10")
- button_frame.grid(row=1, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(0, 10))
-
- ttk.Button(button_frame, text="单次修改金钱", command=self.single_modify).pack(side=tk.LEFT, padx=(0, 10))
- self.start_button = ttk.Button(button_frame, text="停止监控", command=self.toggle_monitor)
- self.start_button.pack(side=tk.LEFT, padx=(0, 10))
-
- # 参数设置框架
- settings_frame = ttk.LabelFrame(main_frame, text="监控参数设置", padding="10")
- settings_frame.grid(row=2, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(0, 10))
-
- # 更新间隔
- ttk.Label(settings_frame, text="更新间隔(秒):").grid(row=0, column=0, sticky=tk.W, padx=(0, 5))
- self.interval_var = tk.StringVar(value=str(self.monitor.update_interval))
- ttk.Entry(settings_frame, textvariable=self.interval_var, width=10).grid(row=0, column=1, sticky=tk.W, padx=(0, 10))
-
- # 自动补充阈值和目标金钱值在同一行
- ttk.Label(settings_frame, text="自动补充阈值:").grid(row=0, column=2, sticky=tk.W, padx=(10, 5))
- self.threshold_var = tk.StringVar(value=str(self.monitor.min_money_threshold))
- ttk.Entry(settings_frame, textvariable=self.threshold_var, width=10).grid(row=0, column=3, sticky=tk.W, padx=(0, 5))
-
- ttk.Label(settings_frame, text="目标金钱值:").grid(row=0, column=4, sticky=tk.W, padx=(5, 5))
- self.target_var = tk.StringVar(value=str(self.monitor.target_money))
- ttk.Entry(settings_frame, textvariable=self.target_var, width=10).grid(row=0, column=5, sticky=tk.W, padx=(0, 10))
-
- # 应用设置按钮
- ttk.Button(settings_frame, text="应用设置", command=self.apply_settings).grid(row=1, column=0, columnspan=6, pady=(10, 0))
-
- # 状态显示框架
- status_frame = ttk.LabelFrame(main_frame, text="运行状态", padding="10")
- status_frame.grid(row=3, column=0, columnspan=3, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
- status_frame.columnconfigure(0, weight=1)
- status_frame.rowconfigure(0, weight=1)
-
- # 日志文本框
- self.log_text = scrolledtext.ScrolledText(status_frame, height=15, state='disabled')
- self.log_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
-
- # 清空日志按钮
- ttk.Button(status_frame, text="清空日志", command=self.clear_log).grid(row=1, column=0, pady=(5, 0))
-
- def redirect_output(self):
- # 重定向print输出到文本框
- import io
-
- class TextRedirector(io.StringIO):
- def __init__(self, widget):
- super().__init__()
- self.widget = widget
-
- def write(self, s):
- self.widget.config(state='normal')
- self.widget.insert(tk.END, s)
- self.widget.see(tk.END)
- self.widget.config(state='disabled')
-
- sys.stdout = TextRedirector(self.log_text)
-
- def single_modify(self):
- # 在新线程中执行单次修改,避免阻塞GUI
- threading.Thread(target=self._single_modify_thread, daemon=True).start()
-
- def _single_modify_thread(self):
- print("开始单次修改金钱...")
- self.monitor.single_modify()
-
- def toggle_monitor(self):
- if self.monitor.running:
- self.stop_monitor()
- else:
- self.start_monitor()
-
- def start_monitor(self):
- # 应用当前设置
- self.apply_settings()
-
- # 在新线程中启动监控
- self.monitor.running = True
- self.monitor_thread = threading.Thread(target=self.monitor.monitor_loop, daemon=True)
- self.monitor_thread.start()
-
- self.start_button.config(text="停止监控")
- print("监控已启动...")
-
- def stop_monitor(self):
- if self.monitor.running:
- self.monitor.running = False
- self.start_button.config(text="启动监控")
- print("监控已停止...")
-
- def apply_settings(self):
- try:
- interval = int(self.interval_var.get())
- threshold = int(self.threshold_var.get())
- target = int(self.target_var.get())
-
- self.monitor.set_monitor_settings(interval, threshold, target)
- print(f"参数已更新: 间隔={interval}s, 阈值={threshold}, 目标={target}")
- except ValueError:
- messagebox.showerror("错误", "请输入有效的数字参数")
-
- def clear_log(self):
- self.log_text.config(state='normal')
- self.log_text.delete(1.0, tk.END)
- self.log_text.config(state='disabled')
-
- class MoneyMonitor:
- def __init__(self):
- self.running = False
- self.pm = None
- self.base_address = None
- self.update_interval = 10 # 修改为10秒
- self.min_money_threshold = 500000 # 修改阈值为500000
- self.target_money = 999999 # 修改目标值为999999
-
- def get_dynamic_base_address(self):
- """动态获取当前游戏的基址"""
- try:
- # 查找游戏进程
- pid = None
- for proc in psutil.process_iter(['pid', 'name']):
- if proc.info['name'] and 'gamemd.exe' in proc.info['name'].lower():
- pid = proc.info['pid']
- break
-
- if not pid:
- return None, None
-
- # 连接到进程并获取基址
- pm = pymem.Pymem()
- pm.open_process_from_id(pid)
-
- game_module = pymem.process.module_from_name(pm.process_handle, "gamemd.exe")
- return pm, game_module.lpBaseOfDll if game_module else None
-
- except Exception as e:
- print(f"获取基址失败: {e}")
- return None, None
-
- def calculate_money_addresses(self):
- """计算两个金钱地址"""
- try:
- if not self.pm or not self.base_address:
- return None, None
-
- # 渲染地址
- render_address = self.base_address + 0x484D08
-
- # 实际地址(通过指针链)
- base_ptr = self.base_address + 0x00683D4C
- level1 = self.pm.read_int(base_ptr)
- actual_address = level1 + 0x30C
-
- return render_address, actual_address
-
- except Exception as e:
- print(f"计算地址失败: {e}")
- return None, None
-
- def read_money_values(self, render_addr, actual_addr):
- """读取两个金钱地址的值"""
- try:
- render_value = self.pm.read_int(render_addr)
- actual_value = self.pm.read_int(actual_addr)
- return render_value, actual_value
- except Exception as e:
- print(f"读取金钱值失败: {e}")
- return None, None
-
- def write_money_values(self, render_addr, actual_addr, value):
- """写入两个金钱地址的值"""
- try:
- self.pm.write_int(render_addr, value)
- self.pm.write_int(actual_addr, value)
- return True
- except Exception as e:
- print(f"写入金钱值失败: {e}")
- return False
-
- def auto_refill_money(self, render_addr, actual_addr):
- """自动补充金钱"""
- try:
- render_value, actual_value = self.read_money_values(render_addr, actual_addr)
- if render_value is None or actual_value is None:
- return False
-
- # 如果任意一个值低于阈值,就补充
- if render_value < self.min_money_threshold or actual_value < self.min_money_threshold:
- success = self.write_money_values(render_addr, actual_addr, self.target_money)
- if success:
- print(f"💰 自动补充: {max(render_value, actual_value)} -> {self.target_money}")
- return success
- return True
- except Exception as e:
- print(f"自动补充失败: {e}")
- return False
-
- def single_modify(self):
- """单次修改金钱"""
- self.pm, self.base_address = self.get_dynamic_base_address()
-
- if not self.pm or not self.base_address:
- print("无法连接到游戏进程")
- return False
-
- print(f"检测到游戏基址: 0x{self.base_address:X}")
-
- render_addr, actual_addr = self.calculate_money_addresses()
- if not render_addr or not actual_addr:
- print("计算地址失败")
- return False
-
- print(f"渲染地址: 0x{render_addr:X}")
- print(f"实际地址: 0x{actual_addr:X}")
-
- # 读取当前值
- render_value, actual_value = self.read_money_values(render_addr, actual_addr)
- if render_value is None or actual_value is None:
- print("读取当前值失败")
- return False
-
- # 计算差值
- diff = abs(render_value - actual_value)
- print(f"当前渲染: {render_value}, 实际: {actual_value}, 差值: {diff}")
-
- # 修改为目标值
- success = self.write_money_values(render_addr, actual_addr, self.target_money)
- if success:
- print(f"✅ 修改成功! {actual_value} -> {self.target_money}")
-
- return success
-
- def monitor_loop(self):
- """监控循环"""
- print(f"开始监控金钱... (更新间隔: {self.update_interval}秒)")
- print(f"自动补充阈值: {self.min_money_threshold}")
- print(f"目标金钱值: {self.target_money}")
- print("点击 GUI 中的停止按钮停止监控")
-
- last_base_address = None
-
- while self.running:
- try:
- # 重新获取进程和基址(处理游戏重启)
- self.pm, self.base_address = self.get_dynamic_base_address()
-
- if not self.pm or not self.base_address:
- print("❌ 游戏进程未找到,等待重新连接...")
- time.sleep(5)
- continue
-
- # 检查基址是否变化(游戏重启)
- if last_base_address != self.base_address:
- print(f"🔄 检测到游戏基址: 0x{self.base_address:X}")
- last_base_address = self.base_address
-
- # 计算地址
- render_addr, actual_addr = self.calculate_money_addresses()
- if not render_addr or not actual_addr:
- print("❌ 计算地址失败,跳过本次更新")
- time.sleep(self.update_interval)
- continue
-
- # 读取当前值
- render_value, actual_value = self.read_money_values(render_addr, actual_addr)
- if render_value is None or actual_value is None:
- print("❌ 读取值失败,跳过本次更新")
- time.sleep(self.update_interval)
- continue
-
- print(f"当前金钱为:{actual_value},低于补充阈值将自动改为{self.target_money},请放心游戏...")
-
- # 自动补充
- self.auto_refill_money(render_addr, actual_addr)
-
- time.sleep(self.update_interval)
-
- except Exception as e:
- print(f"监控循环错误: {e}")
- time.sleep(self.update_interval)
-
- def start_monitor(self):
- """开始监控"""
- self.running = True
- self.monitor_loop()
-
- def set_monitor_settings(self, interval=10, threshold=500000, target=999999):
- """设置监控参数"""
- self.update_interval = interval
- self.min_money_threshold = threshold
- self.target_money = target
-
- def main():
- root = tk.Tk()
- app = MoneyMonitorGUI(root)
- root.mainloop()
-
- if __name__ == "__main__":
- main()
复制代码
|