小K 发表于 9 小时前

红警2之心灵终结金钱修改器python源码

以管理员打开程序即可自动运行,初次修改为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()
复制代码
页: [1]
查看完整版本: 红警2之心灵终结金钱修改器python源码