fan_utils / app.py
SnowFlash383935's picture
Update app.py
4be4e7c verified
import gradio as gr
import fanl_yp
import zlib
def load_and_display_info(gameFilePath: str):
"""Загружает файл и возвращает game.title + game объект для дальнейшей обработки"""
if gameFilePath is None:
return "", "", gr.update(interactive=False), gr.update(visible=False)
try:
with open(gameFilePath, "rb") as f:
compressed_data = f.read()
data = zlib.decompress(compressed_data)
game = fanl_yp.decode.decode(data)
title = getattr(game, 'title', 'Название не найдено')
# Генерация списка removable lock IDs
indexOffset = getattr(game, 'indexOffset', 0)
removable_locks = []
offset = indexOffset
for objectContainer in game.objectContainers:
if objectContainer.headerReader.hasVoxels():
removable_locks.append(f"{offset} {objectContainer.name}")
offset += 1
if removable_locks:
locks_html = "<div style='background-color: #f0f0f0; padding: 10px; border-radius: 5px;'>"
locks_html += f"<h4>Removable lock IDs (IndexOffset: {indexOffset}):</h4>"
locks_html += "<ul>"
for lock in removable_locks:
locks_html += f"<li>{lock}</li>"
locks_html += "</ul></div>"
else:
locks_html = "<div style='background-color: #f0f0f0; padding: 10px; border-radius: 5px;'>" \
f"<h4>Removable lock IDs (IndexOffset: {indexOffset}):</h4>" \
"<p>Нет доступных элементов для удаления</p></div>"
return title, locks_html, gr.update(interactive=True), gr.update(visible=True)
except Exception as e:
return f"Ошибка загрузки файла: {str(e)}", "", gr.update(interactive=False), gr.update(visible=False)
def process_save_file(game_obj, original_path: str):
"""Обрабатывает сохранение и возвращает путь к новому файлу"""
if game_obj is None or original_path is None:
return None
try:
output_path = original_path + "_fixed"
output = fanl_yp.encode.encode(game_obj, output_path)
output.flush()
return output_path
except Exception as e:
raise gr.Error(f"Ошибка обработки файла: {str(e)}")
def clear_handler():
"""Обработчик очистки файла"""
return "", "", gr.update(interactive=False), gr.update(visible=False)
with gr.Blocks() as demo:
gr.Markdown("## Обработка сохранений игры")
with gr.Row():
file_input = gr.File(label="Загрузите файл сохранения", file_types=None)
title_output = gr.Textbox(label="Информация о сохранении", interactive=False)
# HTML компонент для отображения списка removable lock IDs
locks_output = gr.HTML(visible=False)
process_button = gr.Button("Обработать сохранение", interactive=False)
file_output = gr.File(label="Сохранить исправленный файл")
# Скрытое состояние для хранения объекта game между вызовами
game_state = gr.State()
# Когда файл загружен — обновляем текстовое поле и разблокируем кнопку
file_input.upload(
fn=load_and_display_info,
inputs=file_input,
outputs=[title_output, locks_output, process_button, locks_output],
queue=False
)
# Когда файл удален — очищаем все поля и блокируем кнопку
file_input.clear(
fn=clear_handler,
inputs=None,
outputs=[title_output, locks_output, process_button, locks_output],
queue=False
)
# При нажатии кнопки запускаем обработку
process_button.click(
fn=process_save_file,
inputs=[game_state, file_input],
outputs=file_output
)
if __name__ == "__main__":
demo.launch()