import { useState, useEffect } from "react"; import { useTranslation } from "react-i18next"; import { motion } from "framer-motion"; import { TauriService } from "../../services/TauriService"; export default function ImportWorldModal({ isOpen, onClose, playPressSound, playBackSound, targetInstanceId, targetInstanceName, }: { isOpen: boolean; onClose: () => void; playPressSound: (s?: string) => void; playBackSound: (s?: string) => void; targetInstanceId: string; targetInstanceName: string; }) { const { t } = useTranslation(); const [status, setStatus] = useState(""); const [error, setError] = useState(""); const [isImporting, setIsImporting] = useState(false); useEffect(() => { if (!isOpen) { setStatus(""); setError(""); setIsImporting(false); } }, [isOpen]); const handleImportMs = async () => { if (!targetInstanceId) return; playPressSound(); setIsImporting(true); setError(""); setStatus(t("modals.importWorld.selectingSource")); try { setStatus(t("modals.importWorld.selectingMsFile")); const picked = await TauriService.pickFile("Select saveData.ms", [ "*.ms", "*", ]); if (!picked) { setIsImporting(false); return; } const worldName = deriveWorldName(picked); setStatus(t("modals.importWorld.copyingLceSave")); const instancePath = await TauriService.getInstancePath(targetInstanceId); const saveDir = `${instancePath}/Windows64/GameHDD/${worldName}`; await TauriService.importWorld(picked, `${saveDir}/saveData.ms`); setStatus( t("modals.importWorld.worldImported", { name: targetInstanceName }), ); setTimeout(() => { onClose(); }, 2000); } catch (e: unknown) { setError(e instanceof Error ? e.message : String(e)); setStatus(""); setIsImporting(false); } }; const handleImportXbox = async () => { if (!targetInstanceId) return; playPressSound(); setIsImporting(true); setError(""); setStatus(t("modals.importWorld.selectingSource")); try { setStatus(t("modals.importWorld.selectingXboxSave")); const picked = await TauriService.pickFile( "Select Xbox 360 Minecraft save", ["*.bin", "*"], ); if (!picked) { setIsImporting(false); return; } setStatus(t("modals.importWorld.convertingXbox")); const instancePath = await TauriService.getInstancePath(targetInstanceId); const gameHdd = `${instancePath}/Windows64/GameHDD`; await TauriService.importLceSave(picked, gameHdd); setStatus( t("modals.importWorld.xboxConverted", { name: targetInstanceName }), ); setTimeout(() => { onClose(); }, 2000); } catch (e: unknown) { setError(e instanceof Error ? e.message : String(e)); setStatus(""); setIsImporting(false); } }; const handleImportPs3 = async () => { if (!targetInstanceId) return; playPressSound(); setIsImporting(true); setError(""); setStatus(t("modals.importWorld.selectingSource")); try { setStatus(t("modals.importWorld.selectingPs3Folder")); const picked = await TauriService.pickFolder(); if (!picked) { setIsImporting(false); return; } setStatus(t("modals.importWorld.convertingPs3")); const instancePath = await TauriService.getInstancePath(targetInstanceId); const gameHdd = `${instancePath}/Windows64/GameHDD`; await TauriService.importLceSave(picked, gameHdd); setStatus( t("modals.importWorld.ps3Converted", { name: targetInstanceName }), ); setTimeout(() => { onClose(); }, 2000); } catch (e: unknown) { setError(e instanceof Error ? e.message : String(e)); setStatus(""); setIsImporting(false); } }; const handleImportJava = async () => { if (!targetInstanceId) return; playPressSound(); setIsImporting(true); setError(""); setStatus(t("modals.importWorld.selectingSource")); try { setStatus(t("modals.importWorld.selectingJavaFolder")); const picked = await TauriService.pickFolder(); if (!picked) { setIsImporting(false); return; } const worldName = deriveWorldName(picked); setStatus(t("modals.importWorld.convertingJava")); const instancePath = await TauriService.getInstancePath(targetInstanceId); const saveDir = `${instancePath}/Windows64/GameHDD/${worldName}`; await TauriService.javaToLce(picked, `${saveDir}/saveData.ms`); setStatus( t("modals.importWorld.javaConverted", { name: targetInstanceName }), ); setTimeout(() => { onClose(); }, 2000); } catch (e: unknown) { setError(e instanceof Error ? e.message : String(e)); setStatus(""); setIsImporting(false); } }; const handleExportJava = async () => { if (!targetInstanceId) return; playPressSound(); setIsImporting(true); setError(""); setStatus(t("modals.importWorld.selectingSource")); try { setStatus(t("modals.importWorld.selectingMsFile")); const picked = await TauriService.pickFile("Select saveData.ms", [ "*.ms", "*", ]); if (!picked) { setIsImporting(false); return; } setStatus(t("modals.importWorld.selectingOutputFolder")); const outputFolder = await TauriService.pickFolder(); if (!outputFolder) { setIsImporting(false); return; } setStatus(t("modals.importWorld.convertingLceToJava")); await TauriService.lceToJava(picked, outputFolder); setStatus( t("modals.importWorld.javaExported", { path: outputFolder }), ); setTimeout(() => { onClose(); }, 2000); } catch (e: unknown) { setError(e instanceof Error ? e.message : String(e)); setStatus(""); setIsImporting(false); } }; const handleKey = (e: KeyboardEvent) => { if (e.key === "Escape") { playBackSound(); if (isImporting) return; onClose(); } }; useEffect(() => { if (!isOpen) return; window.addEventListener("keydown", handleKey); return () => window.removeEventListener("keydown", handleKey); }, [isOpen, isImporting]); if (!isOpen) return null; return (
{!isImporting ? ( <>

Import World

Import into:{" "} {targetInstanceName}

Import an existing .ms save file:

Convert an Xbox 360 or PS3 save:

Java Edition world conversion:

{error && (
{error}
)} ) : ( <>

Importing World

{status}

{error && (
{error}
)} )}
); } function deriveWorldName(inputPath: string): string { const name = inputPath.replace(/\\/g, "/").split("/").filter(Boolean).pop() || "ImportedWorld"; return name.replace(/[^a-zA-Z0-9_\- ]/g, "_").slice(0, 64); }