新闻详情

新闻详情

首页 / 资讯中心 / 详情

python语言GTA SA 固定地址修改器 v1.0 - 完整版代码QZQ

发布时间:2026/10/2 12:14:31来源:尧图网络
python语言GTA SA 固定地址修改器 v1.0 - 完整版代码QZQ
import pymem import pymem.process import tkinter as tk from tkinter import ttk, messagebox import threading import psutil import time # GTA SA v1.0 固定地址表 # 数据来源GTAMods Wiki / SDA Knowledge Base / 社区公认文档 # 适用范围GTA SA v1.0 US (模块基址 0x400000) # FIXED_ADDRESSES { # ---- 核心属性 ---- 当前金钱: {addr: 0xB7CE50, type: int, desc: 玩家现金}, 生命上限: {addr: 0xB793E0, type: float, desc: Max Health}, 肌肉: {addr: 0xB793DC, type: float, desc: Muscle}, 体力: {addr: 0xB793D8, type: float, desc: Stamina}, 肥胖度: {addr: 0xB793D4, type: float, desc: Fat}, 性吸引力: {addr: 0xB793E4, type: float, desc: Sex Appeal}, 肺活量: {addr: 0xB791A4, type: float, desc: Lung Capacity}, # ---- 技能/熟练度 ---- 自行车技能: {addr: 0xB791B8, type: float, desc: Bike Skill}, 摩托车技能: {addr: 0xB791B4, type: float, desc: Cycle Skill}, 飞行技能: {addr: 0xB7919C, type: float, desc: Flying Skill}, 驾驶技能: {addr: 0xB790A0, type: float, desc: Driving Skill}, # ---- 游戏统计 ---- 游戏时长(ms): {addr: 0xB7CB84, type: int, desc: Playing Time}, 步行距离: {addr: 0xB7938C, type: float, desc: Distance on foot}, 驾驶距离: {addr: 0xB79390, type: float, desc: Distance in car}, 骑行距离: {addr: 0xB793EC, type: float, desc: Distance on bicycle}, # ---- 通缉等级 ---- 通缉等级: {addr: 0xBAA420, type: int, desc: Wanted Level 0-6}, # ---- 游戏时间/天气 ---- 游戏小时: {addr: 0xB7014C, type: int, desc: 0-23}, 游戏分钟: {addr: 0xB70150, type: int, desc: 0-59}, 天气: {addr: 0xC81320, type: int, desc: 0-20}, } # 动态属性通过玩家指针偏移计算 # 玩家指针固定地址0xB6F5F0 # 读取方式CPed [0xB6F5F0]然后 CPed 偏移 # PLAYER_POINTER 0xB6F5F0 # 玩家 CPed 指针 PLAYER_OFFSETS { 当前生命: 0x540, # Float 当前护甲: 0x548, # Float } # 玩家坐标指针链 # CPed - 0x14 坐标结构 - 0x30/0x34/0x38 X/Y/Z # COORD_PTR_OFFSET 0x14 COORD_X_OFFSET 0x30 COORD_Y_OFFSET 0x34 COORD_Z_OFFSET 0x38 class GTASAFixedEditor: def __init__(self, root): self.root root self.root.title(GTA SA 固定地址修改器 v1.0 - 完整版) self.root.geometry(680x700) self.root.resizable(True, True) self.pm None self.process_id None self.player_ptr None # CPed 指针值 self.entries {} # 名称 - 输入框 self.locks {} # 名称 - 是否锁定 self.lock_threads {} # 名称 - 线程 self.create_widgets() self.detect_game() # UI def create_widgets(self): # 顶部进程状态 top ttk.LabelFrame(self.root, text进程) top.pack(fillx, padx10, pady5) self.proc_var tk.StringVar(value未连接) ttk.Label(top, textvariableself.proc_var, width55).pack(sideleft, padx5) ttk.Button(top, text刷新检测, commandself.detect_game).pack(sideright, padx5) # 玩家指针状态 ptr_frame ttk.LabelFrame(self.root, text玩家指针 (CPed)) ptr_frame.pack(fillx, padx10, pady5) self.ptr_var tk.StringVar(value未获取) ttk.Label(ptr_frame, textvariableself.ptr_var, font(Consolas, 10)).pack(sideleft, padx5) ttk.Button(ptr_frame, text刷新指针, commandself.update_player_ptr).pack(sideright, padx5) # 中部固定地址属性列表 mid ttk.LabelFrame(self.root, text属性列表v1.0 固定地址) mid.pack(fillboth, expandTrue, padx10, pady5) canvas tk.Canvas(mid, height350) scrollbar ttk.Scrollbar(mid, orientvertical, commandcanvas.yview) self.scrollable_frame ttk.Frame(canvas) self.scrollable_frame.bind( Configure, lambda e: canvas.configure(scrollregioncanvas.bbox(all)) ) canvas.create_window((0, 0), windowself.scrollable_frame, anchornw) canvas.configure(yscrollcommandscrollbar.set) canvas.pack(sideleft, fillboth, expandTrue) scrollbar.pack(sideright, filly) # 表头 header ttk.Frame(self.scrollable_frame) header.grid(row0, column0, columnspan7, stickyew, pady2) ttk.Label(header, text属性, width12, font(, 9, bold)).pack(sideleft, padx3) ttk.Label(header, text地址, width12, font(, 9, bold)).pack(sideleft, padx3) ttk.Label(header, text类型, width6, font(, 9, bold)).pack(sideleft, padx3) ttk.Label(header, text值, width15, font(, 9, bold)).pack(sideleft, padx3) ttk.Label(header, text操作, width20, font(, 9, bold)).pack(sideleft, padx3) # 生成所有属性行固定 动态 all_attrs list(FIXED_ADDRESSES.items()) [ (当前生命, {addr: 动态, type: float, desc: CPed0x540}), (当前护甲, {addr: 动态, type: float, desc: CPed0x548}), ] for i, (name, info) in enumerate(all_attrs, start1): self.create_attr_row(i, name, info) # 底部操作按钮 bot ttk.Frame(self.root) bot.pack(fillx, padx10, pady5) ttk.Button(bot, text读取全部, commandself.read_all).pack(sideleft, padx3) ttk.Button(bot, text一键满血满甲, commandself.max_hp_armor).pack(sideleft, padx3) ttk.Button(bot, text金钱9999999, commandlambda: self.quick_set(当前金钱, 9999999)).pack(sideleft, padx3) ttk.Button(bot, text通缉0, commandlambda: self.quick_set(通缉等级, 0)).pack(sideleft, padx3) # 坐标显示 coord_frame ttk.LabelFrame(self.root, text玩家坐标) coord_frame.pack(fillx, padx10, pady5) self.coord_var tk.StringVar(valueX?, Y?, Z?) ttk.Label(coord_frame, textvariableself.coord_var, font(Consolas, 10)).pack(sideleft, padx5) ttk.Button(coord_frame, text读取坐标, commandself.read_coords).pack(sideright, padx5) # 状态栏 self.status_var tk.StringVar(value就绪) ttk.Label(self.root, textvariableself.status_var, reliefsunken, anchorw).pack(fillx, sidebottom) def create_attr_row(self, row, name, info): 创建一行属性 ttk.Label(self.scrollable_frame, textname, width12).grid( rowrow, column0, padx3, pady2, stickyw) addr info[addr] addr_text f0x{addr:08X} if isinstance(addr, int) else str(addr) ttk.Label(self.scrollable_frame, textaddr_text, font(Consolas, 9), width12).grid( rowrow, column1, padx3, pady2) ttk.Label(self.scrollable_frame, textinfo[type], width6).grid( rowrow, column2, padx3, pady2) entry ttk.Entry(self.scrollable_frame, width15) entry.grid(rowrow, column3, padx3, pady2) self.entries[name] entry # 按钮组 btn_frame ttk.Frame(self.scrollable_frame) btn_frame.grid(rowrow, column4, padx3, pady2) ttk.Button(btn_frame, text读, width3, commandlambda nname: self.read_value(n)).pack(sideleft, padx1) ttk.Button(btn_frame, text写, width3, commandlambda nname: self.write_value(n)).pack(sideleft, padx1) ttk.Button(btn_frame, text锁, width3, commandlambda nname: self.toggle_lock(n)).pack(sideleft, padx1) # 进程操作 def detect_game(self): try: found None for p in psutil.process_iter([pid, name]): if gta_sa in (p.info[name] or ).lower(): found p.info break if not found: self.proc_var.set(未检测到 gta_sa.exe) self.pm None return self.process_id found[pid] self.pm pymem.Pymem(self.process_id) self.proc_var.set(f已连接 {found[name]} (PID {self.process_id})) self.status_var.set(连接成功点“读取全部”刷新数值) self.update_player_ptr() except Exception as e: self.pm None self.proc_var.set(f连接失败: {e}) def update_player_ptr(self): 读取玩家指针 if self.pm is None: messagebox.showinfo(提示, 未连接游戏进程) return try: self.player_ptr self.pm.read_int(PLAYER_POINTER) self.ptr_var.set(fCPed 0x{self.player_ptr:08X}) self.status_var.set(f玩家指针更新: 0x{self.player_ptr:08X}) except Exception as e: self.player_ptr None self.ptr_var.set(读取失败) self.status_var.set(f玩家指针读取失败: {e}) # 读取/写入 def resolve_address(self, name): 解析地址固定地址直接返回动态属性需要 player_ptr # 动态属性 if name in PLAYER_OFFSETS: if self.player_ptr is None: self.update_player_ptr() if self.player_ptr is None: return None return self.player_ptr PLAYER_OFFSETS[name] # 固定属性 if name in FIXED_ADDRESSES: return FIXED_ADDRESSES[name][addr] return None def get_type(self, name): 获取属性类型 if name in PLAYER_OFFSETS: return float if name in FIXED_ADDRESSES: return FIXED_ADDRESSES[name][type] return int def read_value(self, name): if self.pm is None: messagebox.showinfo(提示, 未连接游戏进程) return addr self.resolve_address(name) if addr is None: self.status_var.set(f{name} 地址无效需要玩家指针) return try: t self.get_type(name) if t float: val self.pm.read_float(addr) disp f{val:.2f} else: val self.pm.read_int(addr) disp str(val) self.entries[name].delete(0, tk.END) self.entries[name].insert(0, disp) self.status_var.set(f{name} {disp}) except Exception as e: self.status_var.set(f读取 {name} 失败: {e}) def write_value(self, name): if self.pm is None: messagebox.showinfo(提示, 未连接游戏进程) return addr self.resolve_address(name) if addr is None: self.status_var.set(f{name} 地址无效需要玩家指针) return try: txt self.entries[name].get().strip() t self.get_type(name) if t float: self.pm.write_float(addr, float(txt)) else: self.pm.write_int(addr, int(txt)) self.status_var.set(f{name} 已写入: {txt}) except ValueError: messagebox.showerror(错误, 请输入有效数字) except Exception as e: self.status_var.set(f写入 {name} 失败: {e}) def quick_set(self, name, value): 快捷设置 if name not in self.entries: return self.entries[name].delete(0, tk.END) self.entries[name].insert(0, str(value)) self.write_value(name) def max_hp_armor(self): 一键满血满甲 if self.pm is None: messagebox.showinfo(提示, 未连接游戏进程) return self.quick_set(当前生命, 100) self.quick_set(当前护甲, 100) self.status_var.set(生命和护甲已设为 100) def read_all(self): for name in list(FIXED_ADDRESSES.keys()) list(PLAYER_OFFSETS.keys()): self.read_value(name) def read_coords(self): 读取玩家坐标 if self.pm is None: messagebox.showinfo(提示, 未连接游戏进程) return if self.player_ptr is None: self.update_player_ptr() if self.player_ptr is None: return try: coord_ptr self.pm.read_int(self.player_ptr COORD_PTR_OFFSET) x self.pm.read_float(coord_ptr COORD_X_OFFSET) y self.pm.read_float(coord_ptr COORD_Y_OFFSET) z self.pm.read_float(coord_ptr COORD_Z_OFFSET) self.coord_var.set(fX{x:.2f}, Y{y:.2f}, Z{z:.2f}) self.status_var.set(f坐标: X{x:.2f}, Y{y:.2f}, Z{z:.2f}) except Exception as e: self.coord_var.set(读取失败) self.status_var.set(f读取坐标失败: {e}) # 锁定 def toggle_lock(self, name): if self.locks.get(name): self.locks[name] False self.status_var.set(f{name} 锁定已关闭) else: self.locks[name] True t threading.Thread(targetself.lock_worker, args(name,), daemonTrue) self.lock_threads[name] t t.start() self.status_var.set(f{name} 锁定中...) def lock_worker(self, name): while self.locks.get(name): try: if self.pm is not None: addr self.resolve_address(name) if addr is not None: txt self.entries[name].get().strip() if txt: t self.get_type(name) if t float: self.pm.write_float(addr, float(txt)) else: self.pm.write_int(addr, int(txt)) except Exception: pass time.sleep(0.3) if __name__ __main__: root tk.Tk() app GTASAFixedEditor(root) root.mainloop()
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Spring Boot面试刷题平台开发实战:从需求到答辩全流程 2026/10/2 14:16:03

Spring Boot面试刷题平台开发实战:从需求到答辩全流程

这个标题我做下来已经有一段时间了,从选题、建表、写接口到部署上线,中间踩了不少坑,也总结了一些经验。这篇博文就围绕“基于Spring Boot的面试刷题平台/面试试题管理系统”这个课设/毕设项目,把需求梳理、技术选型、数据库设计、…

阅读更多 →
零基础学ESP32:手机蓝牙控制舵机实战 2026/10/2 14:16:02

零基础学ESP32:手机蓝牙控制舵机实战

说实话,很多玩单片机的人,第一次真正觉得“有点东西”的时刻,不是点亮LED,而是让手机离开发板半米远,按一下按钮,舵机就听话地转到指定角度。项目标题“零基础学ESP32:蓝牙控制舵机——手机一点…

阅读更多 →
RK3576 LCD驱动实战:从设备树到DRM/KMS的全链路解析 2026/10/2 14:16:02

RK3576 LCD驱动实战:从设备树到DRM/KMS的全链路解析

1. 项目概述:从RK3576平台切入LCD驱动开发的真实路径“驱动之路#04:LCD 驱动序析(基于 RK3576)”这个标题,不是教科书里的概念堆砌,而是一条踩过坑、调过波形、烧过屏、改过设备树的实战路径。我带团队在RK…

阅读更多 →
反转链表:机试高频题的迭代与递归解法全拆解 2026/10/2 14:15:56

反转链表:机试高频题的迭代与递归解法全拆解

1. 这道题为什么是机试的“钉子户” 做了几年面试官,也刷过几百道题,我越来越能理解为什么“反转链表”能成为机试环节的钉子户。它不像动态规划那样需要敏锐的模型抽象能力,也不像红黑树那样考验庞大的知识储备,但它恰好卡在“基…

阅读更多 →
前后端分离科研管理系统实战:SpringBoot+Vue+MyBatis全栈设计与部署 2026/10/2 14:15:56

前后端分离科研管理系统实战:SpringBoot+Vue+MyBatis全栈设计与部署

前后端分离这套东西,这几年基本成了JavaWeb项目的标配。手头上刚好有一套完整的科研管理系统,SpringBoot Vue MyBatis MySQL,前后端完全拆开,源码和部署文档都齐整。写这篇东西不是给你贴代码,而是把这套系统的设计…

阅读更多 →
jQuery画半圆是伪命题?CSS与SVG实现半圆进度条完整指南 2026/10/2 14:15:56

jQuery画半圆是伪命题?CSS与SVG实现半圆进度条完整指南

上个月给一个老后台系统加模块,需求很简单:首页要放一个半圆形的完成率仪表盘,数据从接口拉,刷新要顺滑。我习惯性地先搜了一圈jQuery插件,结果不是体积太大,就是样式死活套不进现有设计,最后只…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉