Загрузка данных


import pymem
import psutil
import json
import os
import time
from tkinter import Tk, Label, Entry, Button, StringVar, messagebox

CONFIG_FILE = "config.json"

class Standoff2SkinChanger:
    def __init__(self):
        self.pm = None
        self.config = self.load_config()
        self.old_id = self.config["old_skin_id"]
        self.new_id = self.config["new_skin_id"]
        self.process_name = self.config["process_name"]
        
    def load_config(self):
        if os.path.exists(CONFIG_FILE):
            with open(CONFIG_FILE, 'r') as f:
                return json.load(f)
        else:
            return {"old_skin_id": 33602, "new_skin_id": 97100, "process_name": "HD-Player.exe", "scan_delay": 0}
    
    def find_bluestacks_pid(self):
        for proc in psutil.process_iter(['pid', 'name']):
            if self.process_name in proc.info['name']:
                return proc.info['pid']
        return None
    
    def attach_to_process(self):
        pid = self.find_bluestacks_pid()
        if not pid:
            return False, "Bluestacks не запущен"
        try:
            self.pm = pymem.Pymem(pid)
            return True, "Подключено"
        except Exception as e:
            return False, f"Ошибка: {e}"
    
    def find_skin_address(self):
        """Ищет адрес по старому ID"""
        if not self.pm:
            return None
        old_bytes = self.old_id.to_bytes(4, 'little')
        start = 0x01000000
        end = 0x7FFFFFFF
        
        print("Поиск адреса...")
        for addr in range(start, end, 0x100000):
            try:
                chunk = self.pm.read_bytes(addr, 0x100000)
                pos = chunk.find(old_bytes)
                while pos != -1:
                    full_addr = addr + pos
                    try:
                        val = self.pm.read_int(full_addr)
                        if val == self.old_id:
                            print(f"Найден адрес: 0x{full_addr:X} = {val}")
                            return full_addr
                    except:
                        pass
                    pos = chunk.find(old_bytes, pos + 1)
            except:
                continue
        return None
    
    def replace_skins(self):
        if not self.pm:
            return False, "Не подключено"
        
        addr = self.find_skin_address()
        if not addr:
            return False, f"Скин {self.old_id} не найден в памяти"
        
        try:
            current = self.pm.read_int(addr)
            print(f"Текущее значение: {current}")
            
            self.pm.write_int(addr, self.new_id)
            time.sleep(0.1)
            check = self.pm.read_int(addr)
            
            if check == self.new_id:
                return True, f"Заменено! {self.old_id} → {self.new_id}"
            else:
                return False, "Не удалось записать"
        except Exception as e:
            return False, f"Ошибка: {e}"
    
    def run(self, status_callback=None):
        success, msg = self.attach_to_process()
        if not success:
            return False, msg
        return self.replace_skins()

class SkinChangerGUI:
    def __init__(self):
        self.root = Tk()
        self.root.title("Standoff 2 Skin Changer v1.2")
        self.root.geometry("400x250")
        self.root.resizable(False, False)
        self.changer = Standoff2SkinChanger()
        self.status_var = StringVar()
        self.status_var.set("Готов")
        self.create_widgets()
        
    def create_widgets(self):
        Label(self.root, text="Standoff 2 Skin Changer", font=("Arial", 14, "bold")).pack(pady=10)
        Label(self.root, text=f"Замена: {self.changer.old_id} → {self.changer.new_id}", font=("Arial", 10)).pack()
        
        Label(self.root, text="Старый ID:").pack(pady=(10,0))
        self.old_entry = Entry(self.root, width=15)
        self.old_entry.insert(0, str(self.changer.old_id))
        self.old_entry.pack()
        
        Label(self.root, text="Новый ID:").pack(pady=(5,0))
        self.new_entry = Entry(self.root, width=15)
        self.new_entry.insert(0, str(self.changer.new_id))
        self.new_entry.pack()
        
        Button(self.root, text="Обновить настройки", command=self.update_config).pack(pady=5)
        Button(self.root, text="ЗАМЕНИТЬ СКИНЫ", command=self.execute, bg="green", fg="white", font=("Arial", 12, "bold")).pack(pady=10)
        Label(self.root, textvariable=self.status_var, fg="blue").pack(pady=5)
        
    def update_config(self):
        try:
            old = int(self.old_entry.get())
            new = int(self.new_entry.get())
            self.changer.old_id = old
            self.changer.new_id = new
            self.changer.config["old_skin_id"] = old
            self.changer.config["new_skin_id"] = new
            with open(CONFIG_FILE, 'w') as f:
                json.dump(self.changer.config, f, indent=4)
            self.status_var.set(f"Обновлено: {old} → {new}")
        except:
            self.status_var.set("Ошибка ввода")
    
    def execute(self):
        self.status_var.set("Поиск и замена...")
        self.root.update()
        success, msg = self.changer.run(lambda s: self.status_var.set(s))
        if success:
            messagebox.showinfo("Успех", msg)
            self.status_var.set("Готово!")
        else:
            messagebox.showerror("Ошибка", msg)
            self.status_var.set("Ошибка")
    
    def run(self):
        self.root.mainloop()

if __name__ == "__main__":
    app = SkinChangerGUI()
    app.run()