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 = "
" locks_html += f"

Removable lock IDs (IndexOffset: {indexOffset}):

" locks_html += "
" else: locks_html = "
" \ f"

Removable lock IDs (IndexOffset: {indexOffset}):

" \ "

Нет доступных элементов для удаления

" 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()