Spaces:
Sleeping
Sleeping
| 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() | |