Advertisement
Guest User

Редактор Hollywood Animal

a guest
Apr 11th, 2025
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.03 KB | Gaming | 0 0
  1. import os
  2. import json
  3. import shutil
  4. import tkinter as tk
  5. import math
  6. import sys
  7. import time
  8.  
  9. # Функция для пересчёта путей к файлам конфигураций
  10. def update_config_paths():
  11.     global BUILDINGS_FILE, PERKS_FILE, CONFIG_PATH
  12.     global SCRIPT_PATH  # Используем глобальную переменную
  13.  
  14.     # Пересчитываем пути с учётом нового пути SCRIPT_PATH
  15.     CONFIG_PATH = os.path.join(SCRIPT_PATH, "Holly_Data", "StreamingAssets", "Data", "Configs")
  16.     BUILDINGS_FILE = os.path.join(CONFIG_PATH, "Buildings.json")
  17.     PERKS_FILE = os.path.join(CONFIG_PATH, "Perks.json")
  18.  
  19. # Определяем путь к папке с игрой. Мы будем считать, что скрипт всегда находится в корне игры.
  20. if getattr(sys, 'frozen', False):  # Проверяем, запущен ли файл как exe
  21.     SCRIPT_PATH = os.path.dirname(sys.executable)  # Получаем путь к директории, где находится .exe
  22. else:
  23.     SCRIPT_PATH = os.path.dirname(os.path.abspath(__file__))  # Для обычного Python скрипта
  24.  
  25. # Изначально обновим пути к конфигам
  26. update_config_paths()
  27.  
  28. # Функция для загрузки файла JSON
  29. def load_json_file(file_path, log_widget):
  30.     if not os.path.exists(file_path):
  31.         log_widget.insert(tk.END, f"Ошибка: Файл {file_path} не найден!\n")
  32.         log_widget.yview(tk.END)
  33.         return None
  34.     with open(file_path, 'r', encoding='utf-8') as file:
  35.         return json.load(file)
  36.  
  37. # Функция для сохранения изменений в файл JSON
  38. def save_json_file(file_path, data, log_widget):
  39.     with open(file_path, 'w', encoding='utf-8') as file:
  40.         json.dump(data, file, indent=2, ensure_ascii=False)
  41.     log_widget.insert(tk.END, f"Изменения успешно сохранены в {file_path}.\n")
  42.     log_widget.yview(tk.END)
  43.  
  44. # Функция для обработки введённого значения и конвертации его в абсолютное изменение или процент
  45. def parse_input(value, log_widget):
  46.     if not value:
  47.         return None, None
  48.  
  49.     # Проверка на процент
  50.     if "%" in value:
  51.         try:
  52.             percent = int(value.replace("%", ""))
  53.             if percent < -100 or percent > 100:
  54.                 log_widget.insert(tk.END, "Ошибка: процент должен быть от -100 до 100.\n")
  55.                 log_widget.yview(tk.END)
  56.                 return None, None
  57.             return percent, None
  58.         except ValueError:
  59.             log_widget.insert(tk.END, "Ошибка: неверный формат процента.\n")
  60.             log_widget.yview(tk.END)
  61.             return None, None
  62.     else:
  63.         try:
  64.             absolute_change = int(value)
  65.             if absolute_change < -2147483648 or absolute_change > 2147483647:  # Ограничение int32
  66.                 log_widget.insert(tk.END, "Ошибка: значение должно быть в пределах int32.\n")
  67.                 log_widget.yview(tk.END)
  68.                 return None, None
  69.             return None, absolute_change
  70.         except ValueError:
  71.             log_widget.insert(tk.END, "Ошибка: неверный формат числа.\n")
  72.             log_widget.yview(tk.END)
  73.             return None, None
  74.  
  75. # Функция для применения изменений в Perks.json
  76. def apply_study_changes(log_widget, value):
  77.     global SCRIPT_PATH  # Используем глобальную переменную
  78.  
  79.     percent, absolute_change = parse_input(value, log_widget)
  80.     if percent is None and absolute_change is None:
  81.         return
  82.  
  83.     data = load_json_file(PERKS_FILE, log_widget)
  84.     if data:
  85.         modified = False
  86.         for key in data:
  87.             if "duration" in data[key]:
  88.                 original_value = data[key]["duration"]
  89.                 if original_value < 0:
  90.                     log_widget.insert(tk.END, f"Перки: Ключ {key} имеет значение {original_value}. Оставляем без изменений.\n")
  91.                     continue
  92.                 if original_value == 0 and absolute_change is not None:
  93.                     new_value = absolute_change
  94.                 else:
  95.                     if percent is not None:
  96.                         new_value = int(math.floor(original_value * (1 + percent / 100)))
  97.                     elif absolute_change is not None:
  98.                         new_value = absolute_change  # Применяем абсолютное изменение, а не прибавляем
  99.                     else:
  100.                         continue
  101.                 log_widget.insert(tk.END, f"Перки: Ключ {key}: {original_value} → {new_value}.\n")
  102.                 data[key]["duration"] = new_value
  103.                 modified = True
  104.         if modified:
  105.             save_json_file(PERKS_FILE, data, log_widget)
  106.  
  107. # Функция для применения изменений в Buildings.json
  108. def apply_build_changes(log_widget, value):
  109.     global SCRIPT_PATH  # Используем глобальную переменную
  110.  
  111.     percent, absolute_change = parse_input(value, log_widget)
  112.     if percent is None and absolute_change is None:
  113.         return
  114.  
  115.     data = load_json_file(BUILDINGS_FILE, log_widget)
  116.     if data:
  117.         modified = False
  118.         for key in data:
  119.             if "baseDuration" in data[key]:
  120.                 original_value = data[key]["baseDuration"]
  121.                 if original_value < 0:
  122.                     log_widget.insert(tk.END, f"Здания: Ключ {key} имеет значение {original_value}. Оставляем без изменений.\n")
  123.                     continue
  124.                 if original_value == 0 and absolute_change is not None:
  125.                     new_value = absolute_change
  126.                 else:
  127.                     if percent is not None:
  128.                         new_value = int(math.floor(original_value * (1 + percent / 100)))
  129.                     elif absolute_change is not None:
  130.                         new_value = absolute_change  # Применяем абсолютное изменение, а не прибавляем
  131.                     else:
  132.                         continue
  133.                 log_widget.insert(tk.END, f"Здания: Ключ {key}: {original_value} → {new_value}.\n")
  134.                 data[key]["baseDuration"] = new_value
  135.                 modified = True
  136.         if modified:
  137.             save_json_file(BUILDINGS_FILE, data, log_widget)
  138.  
  139.  
  140. # Функция для создания резервной копии файлов
  141. def handle_backup(log_widget):
  142.     global SCRIPT_PATH  # Используем глобальную переменную
  143.  
  144.     # Папка для резервных копий
  145.     backup_dir = os.path.join(SCRIPT_PATH, "BackupFiles")
  146.     if not os.path.exists(backup_dir):
  147.         os.makedirs(backup_dir)  # Создаём папку для бэкапов, если она не существует
  148.  
  149.     # Генерируем уникальное имя для копий (с использованием времени)
  150.     timestamp = str(int(time.time()))
  151.     backup_buildings = os.path.join(backup_dir, f"Buildings_{timestamp}.json")
  152.     backup_perks = os.path.join(backup_dir, f"Perks_{timestamp}.json")
  153.  
  154.     # Копируем файлы, если они существуют
  155.     try:
  156.         if os.path.exists(BUILDINGS_FILE):
  157.             shutil.copy(BUILDINGS_FILE, backup_buildings)
  158.             log_widget.insert(tk.END, f"Резервная копия Buildings.json сохранена: {backup_buildings}\n")
  159.         else:
  160.             log_widget.insert(tk.END, "Ошибка: файл Buildings.json не найден для бэкапа.\n")
  161.  
  162.         if os.path.exists(PERKS_FILE):
  163.             shutil.copy(PERKS_FILE, backup_perks)
  164.             log_widget.insert(tk.END, f"Резервная копия Perks.json сохранена: {backup_perks}\n")
  165.         else:
  166.             log_widget.insert(tk.END, "Ошибка: файл Perks.json не найден для бэкапа.\n")
  167.  
  168.         log_widget.yview(tk.END)  # Прокручиваем окно логов до конца
  169.     except Exception as e:
  170.         log_widget.insert(tk.END, f"Ошибка при создании резервной копии: {e}\n")
  171.         log_widget.yview(tk.END)
  172.  
  173. # Основная функция для создания интерфейса
  174. def create_interface():
  175.     global SCRIPT_PATH  # Используем глобальную переменную
  176.  
  177.     root = tk.Tk()
  178.     root.title("Редактор конфигураций игры")
  179.  
  180.     # Логовое окно для вывода сообщений
  181.     log_widget = tk.Text(root, height=10, width=50, wrap=tk.WORD, font=("Arial", 12))
  182.     log_widget.pack(padx=10, pady=10)
  183.  
  184.     # Поля ввода и кнопки для применения изменений
  185.     percent_label = tk.Label(root, text="Изменить время изучения улучшений на:", font=("Arial", 12))
  186.     percent_label.pack(pady=5)
  187.     percent_entry = tk.Entry(root, font=("Arial", 12))
  188.     percent_entry.pack(pady=5)
  189.  
  190.     study_button = tk.Button(root, text="Применить изменения в Perks.json", font=("Arial", 12),
  191.                              command=lambda: apply_study_changes(log_widget, percent_entry.get()))
  192.     study_button.pack(pady=5)
  193.  
  194.     build_label = tk.Label(root, text="Изменить время строительства зданий на:", font=("Arial", 12))
  195.     build_label.pack(pady=5)
  196.     build_entry = tk.Entry(root, font=("Arial", 12))
  197.     build_entry.pack(pady=5)
  198.  
  199.     build_button = tk.Button(root, text="Применить изменения в Buildings.json", font=("Arial", 12),
  200.                              command=lambda: apply_build_changes(log_widget, build_entry.get()))
  201.     build_button.pack(pady=5)
  202.  
  203.     # Кнопка для создания резервных копий
  204.     backup_button = tk.Button(root, text="Создать резервные копии", font=("Arial", 12),
  205.                               command=lambda: handle_backup(log_widget))
  206.     backup_button.pack(pady=5)
  207.  
  208.     # Кнопка очистки лога
  209.     clear_button = tk.Button(root, text="Очистить лог", font=("Arial", 12), command=lambda: log_widget.delete(1.0, tk.END))
  210.     clear_button.pack(pady=5)
  211.  
  212.     # Поле для ввода пути до папки с игрой
  213.     game_path_label = tk.Label(root, text="Путь до папки с игрой:", font=("Arial", 12))
  214.     game_path_label.pack(pady=5)
  215.  
  216.     game_path_var = tk.StringVar()
  217.     game_path_var.set(SCRIPT_PATH)  # по умолчанию текущая папка
  218.     game_path_entry = tk.Entry(root, textvariable=game_path_var, font=("Arial", 12))
  219.     game_path_entry.pack(pady=5)
  220.  
  221.     # Кнопка для применения пути
  222.     def apply_path():
  223.         global SCRIPT_PATH  # Используем глобальную переменную
  224.         SCRIPT_PATH = game_path_var.get()
  225.         update_config_paths()  # Обновляем пути
  226.  
  227.         log_widget.insert(tk.END, f"Новый путь до папки с игрой: {SCRIPT_PATH}\n")
  228.         log_widget.yview(tk.END)
  229.  
  230.         # Обновляем текст с текущим путем
  231.         current_path_label.config(text=f"Текущий путь: {SCRIPT_PATH}")
  232.  
  233.     apply_path_button = tk.Button(root, text="Применить новый путь", font=("Arial", 12), command=apply_path)
  234.     apply_path_button.pack(pady=5)
  235.  
  236.     # Отображение текущего пути
  237.     current_path_label = tk.Label(root, text=f"Текущий путь: {SCRIPT_PATH}", font=("Arial", 12))
  238.     current_path_label.pack(pady=5)
  239.  
  240.     root.mainloop()
  241.  
  242. # Запуск интерфейса
  243. create_interface()
  244.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement