mirror of
https://github.com/Furglitch/modorganizer2-linux-installer.git
synced 2026-07-31 02:16:55 -04:00
Merge pull request #1008 from Furglitch/feat/remove-archive
fix: remove archiving step
This commit is contained in:
@@ -146,6 +146,33 @@ MO2-LINT currently only supports Proton 10.0. Ensure your game is configured to
|
||||
|
||||
Launch the game at least once through Steam/Heroic before installing MO2-LINT. This allows the launcher to set up the Proton prefix with default dependencies.
|
||||
|
||||
### Preserving Save Data Across a Prefix Reset
|
||||
|
||||
If you need to delete and recreate your game's prefix, your save files will be lost unless you back them up first. Save data is stored inside the prefix under the `users` folder:
|
||||
|
||||
- **Steam**: `<prefix>/pfx/drive_c/users/`
|
||||
- **GOG / Epic (Heroic)**: `<prefix>/drive_c/users/`
|
||||
|
||||
To find your prefix path, run:
|
||||
```bash
|
||||
mo2-lint list
|
||||
```
|
||||
and note the launcher for your instance, then refer to your launcher's library settings for the exact prefix location.
|
||||
|
||||
**To preserve your saves:**
|
||||
|
||||
1. Copy the `users` folder somewhere safe before deleting the prefix:
|
||||
```bash
|
||||
cp -r /path/to/prefix/drive_c/users ~/.tmp/mo2-lint/users-backup
|
||||
```
|
||||
2. Delete the old prefix and launch the game once to generate a fresh one, then exit.
|
||||
3. Restore your saves by copying the `users` folder back:
|
||||
```bash
|
||||
cp -r ~/.tmp/mo2-lint/users-backup/. /path/to/new/prefix/drive_c/users/
|
||||
```
|
||||
|
||||
> **Note:** Overwriting the entire `users` folder should be safe for save data, but be aware that some per-user configuration inside the prefix (e.g. registry hives under `users/<name>/`) may carry over stale settings from the old prefix.
|
||||
|
||||
## Instance Issues
|
||||
|
||||
### Instance Not Found
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from datetime import datetime
|
||||
from loguru import logger
|
||||
from pathlib import Path
|
||||
from shutil import copytree, move
|
||||
from step.load_game_info import get_launcher
|
||||
from util import lang, variables as var, state_file as state
|
||||
from util.heroic.find_library import get_data as get_heroic_data
|
||||
@@ -16,8 +14,6 @@ default_tricks = [
|
||||
|
||||
yes = ("", "y", "yes")
|
||||
|
||||
current_time = datetime.now().strftime("%Y%m%d-%H%M%S")
|
||||
|
||||
|
||||
def load_prefix() -> Path:
|
||||
"""
|
||||
@@ -75,56 +71,6 @@ def load_prefix() -> Path:
|
||||
return prefix
|
||||
|
||||
|
||||
def archive_prefix(prefix: Path):
|
||||
"""
|
||||
Archives the existing game prefix by renaming it with a timestamp suffix.\n
|
||||
Sets the global 'archive' variable to the new archive path.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
prefix : Path
|
||||
Path to the existing game prefix to be archived.
|
||||
"""
|
||||
if prefix.exists() and prefix.is_dir():
|
||||
archive_path = prefix.with_suffix(f".{current_time}").expanduser()
|
||||
move(prefix, archive_path)
|
||||
logger.trace(f"Backed up existing prefix from {prefix} to {archive_path}")
|
||||
var.archived_prefix = archive_path
|
||||
|
||||
|
||||
def restore_archived_prefix(prefix: Path):
|
||||
"""
|
||||
Restores the `users` directory from the archived prefix to the new prefix,\n
|
||||
preserving personal data such as saved games.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
prefix : Path
|
||||
Path to the new game prefix where personal data will be restored.
|
||||
"""
|
||||
match state.current_instance.launcher:
|
||||
case "steam":
|
||||
subpath = Path("pfx") / "drive_c" / "users"
|
||||
src = var.archived_prefix / subpath
|
||||
case "gog" | "epic" | _:
|
||||
subpath = Path("drive_c") / "users"
|
||||
src = var.archived_prefix / subpath
|
||||
dst = prefix / subpath
|
||||
logger.trace(
|
||||
f"Restoring personal data from archived prefix. Source: {src}, Destination: {dst}"
|
||||
)
|
||||
|
||||
copytree(src, dst.with_suffix(".bak"))
|
||||
logger.trace(
|
||||
f"Copied personal data to temporary backup location: {dst.with_suffix('.bak')}"
|
||||
)
|
||||
copytree(src, dst.with_suffix(".old"))
|
||||
move(dst.with_suffix(".old"), dst)
|
||||
logger.trace(
|
||||
f"Restored personal data to new prefix at {dst}. Original data backed up at {dst.with_suffix('.bak')}"
|
||||
)
|
||||
|
||||
|
||||
def configure():
|
||||
"""
|
||||
Run the necessary winetricks/protontricks for the selected game launcher.
|
||||
@@ -141,40 +87,18 @@ def configure():
|
||||
|
||||
def prompt():
|
||||
"""
|
||||
Prompts the user to archive their existing game prefix and create a clean one.
|
||||
|
||||
Raises
|
||||
------
|
||||
SystemExit
|
||||
If the user declines to create a clean prefix.
|
||||
Prompts the user to confirm their prefix is set up, then configures it.
|
||||
"""
|
||||
|
||||
# Prompt user to archive prefix
|
||||
prefix = load_prefix()
|
||||
for suffix in ["users", "drive_c", "pfx"]:
|
||||
if prefix.name == suffix:
|
||||
prefix = prefix.parent
|
||||
var.prefix = prefix
|
||||
logger.trace(f"Resolved prefix path for prompting: {prefix}")
|
||||
logger.debug(f"Prompting user to archive existing prefix at {prefix}")
|
||||
if lang.prompt_archive():
|
||||
logger.trace(
|
||||
"User agreed to archive existing prefix. Proceeding with archival."
|
||||
)
|
||||
archive_prefix(prefix)
|
||||
else:
|
||||
logger.warning(
|
||||
"User declined to archive existing prefix. Proceeding without archival."
|
||||
)
|
||||
var.archived_prefix = None
|
||||
|
||||
# Prompt user to create a clean prefix
|
||||
if not lang.prompt_archive_init():
|
||||
if not lang.prompt_prefix_init():
|
||||
logger.warning(
|
||||
"User declined that instructions were followed to create a clean prefix. No support will be provided if errors occur."
|
||||
"User did not confirm prefix setup. No support will be provided if errors occur."
|
||||
)
|
||||
|
||||
configure()
|
||||
if var.archived_prefix is not None:
|
||||
restore_archived_prefix(prefix)
|
||||
print(lang.prompt_archive_done.format(directory=var.archived_prefix))
|
||||
|
||||
@@ -17,11 +17,6 @@ help_pin = """Pin the Mod Organizer 2 installation in the specified directory, p
|
||||
help_unpin = """Unpin the Mod Organizer 2 installation in the specified directory, allowing updates."""
|
||||
help_update = """Update the Mod Organizer 2 installation in the specified directory, as well as the launch option for the game."""
|
||||
|
||||
prompt_archive_done = """Your prefix has been archived and can be found at: {directory}
|
||||
|
||||
Personal data from the archived prefix (e.g. saved games) has been preserved and restored to the new prefix.
|
||||
Feel free to delete the archive if you no longer need it after confirming your data is intact."""
|
||||
|
||||
|
||||
def list_instances(instance_list: list) -> list:
|
||||
"""
|
||||
@@ -44,41 +39,9 @@ def list_instances(instance_list: list) -> list:
|
||||
return instances
|
||||
|
||||
|
||||
def prompt_archive() -> bool:
|
||||
def prompt_prefix_init() -> bool:
|
||||
"""
|
||||
Prompts the user to archive the existing game prefix and create a clean one.
|
||||
|
||||
Returns
|
||||
-------
|
||||
bool
|
||||
True if the user agrees to archive prefix, False otherwise.
|
||||
"""
|
||||
logger.debug("Prompting user to archive existing prefix")
|
||||
if var.unattended:
|
||||
logger.debug("Unattended mode: skipping archive prompt, defaulting to False")
|
||||
return False
|
||||
|
||||
message = """It is recommended to archive your existing game prefix and create a clean one for Mod Organizer 2 to avoid potential conflicts.
|
||||
|
||||
This process will maintain your personal data (save games, settings) while providing a fresh environment for proton-/winetricks to set up the necessary dependencies.
|
||||
The archived prefix will be renamed with a timestamp suffix for easy identification.
|
||||
|
||||
Do you want to proceed with archiving the existing prefix and creating a clean one?"""
|
||||
|
||||
msg = {
|
||||
"type": "confirm",
|
||||
"message": message,
|
||||
"name": "archive_clean",
|
||||
"default": False,
|
||||
}
|
||||
result = prompt([msg])
|
||||
logger.debug(f"User chose to archive prefix: {result['archive_clean']}")
|
||||
return result["archive_clean"]
|
||||
|
||||
|
||||
def prompt_archive_init() -> bool:
|
||||
"""
|
||||
Prompts the user to initialize a clean prefix
|
||||
Prompts the user to confirm their game prefix has been set up.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -86,7 +49,7 @@ def prompt_archive_init() -> bool:
|
||||
True if the user indicates they have followed the instructions, False otherwise.
|
||||
"""
|
||||
logger.debug(
|
||||
f"Prompting user to initialize clean prefix for launcher: {state.current_instance.launcher}"
|
||||
f"Prompting user to confirm prefix setup for launcher: {state.current_instance.launcher}"
|
||||
)
|
||||
if var.unattended:
|
||||
logger.debug("Unattended mode: skipping prefix init prompt, defaulting to True")
|
||||
@@ -94,16 +57,16 @@ def prompt_archive_init() -> bool:
|
||||
|
||||
match state.current_instance.launcher:
|
||||
case "steam":
|
||||
instructions = """To create a clean Steam prefix, please follow these steps:
|
||||
instructions = """Before continuing, please ensure your Steam prefix is set up correctly:
|
||||
|
||||
1. Right-click on the game in your Steam library.
|
||||
2. Select 'Properties', and navigate to the 'Compatibility' tab.
|
||||
3. Check the box for 'Force the use of a specific Steam Play compatibility tool', if it's not already checked.
|
||||
4. From the dropdown menu, select your preferred Proton version. Proton 10.0 is the supported and recommended version.
|
||||
5. Close the properties window and launch the game once to allow Steam to set up the prefix.
|
||||
6. Exit the game completely. Do not launch it until the installation process is finished."""
|
||||
5. If you haven't already, launch the game once to allow Steam to set up the prefix, then exit completely.
|
||||
6. Do not launch the game again until the installation process is finished."""
|
||||
case "gog" | "epic":
|
||||
instructions = """To create a clean prefix for GOG/Epic via Heroic, please follow these steps:
|
||||
instructions = """Before continuing, please ensure your Heroic prefix is set up correctly:
|
||||
|
||||
1. Right-click on the game in your Heroic library.
|
||||
2. Select 'Settings', and navigate to the 'WINE' tab.
|
||||
@@ -112,20 +75,18 @@ def prompt_archive_init() -> bool:
|
||||
* If Proton versions are not available, you will need to enable "Allow using Valve Proton builds to run games"
|
||||
in Heroic's Settings, under the 'Advanced' tab. Then, ensure that Proton is downloaded and installed in Steam.
|
||||
4. Optional: Navigate to the 'OTHER' tab and check 'Use Steam Runtime'. This is recommended and may help with compatibility.
|
||||
5. Launch the game once to allow Heroic to set up the prefix.
|
||||
6. Exit the game completely. Do not launch it until the installation process is finished."""
|
||||
5. If you haven't already, launch the game once to allow Heroic to set up the prefix, then exit completely.
|
||||
6. Do not launch the game again until the installation process is finished."""
|
||||
|
||||
msg = {
|
||||
"type": "confirm",
|
||||
"message": f"{instructions}\n\n Have you completed these instructions?",
|
||||
"name": "clean_prefix_done",
|
||||
"message": f"{instructions}\n\n Have you completed these steps?",
|
||||
"name": "prefix_init_done",
|
||||
"default": False,
|
||||
}
|
||||
result = prompt([msg])
|
||||
logger.debug(
|
||||
f"User completed clean prefix initialization: {result['clean_prefix_done']}"
|
||||
)
|
||||
return result["clean_prefix_done"]
|
||||
logger.debug(f"User confirmed prefix setup: {result['prefix_init_done']}")
|
||||
return result["prefix_init_done"]
|
||||
|
||||
|
||||
def prompt_install_mo2_checksum_fail(mo2_path: str) -> bool:
|
||||
|
||||
@@ -863,16 +863,6 @@ prefix: Path = None
|
||||
Path to game's Wine/Proton prefix directory.
|
||||
"""
|
||||
|
||||
archived_prefix: Path = None
|
||||
"""
|
||||
Path to archived Wine/Proton prefix directory.
|
||||
"""
|
||||
|
||||
archived_prefixes: list[Path] = []
|
||||
"""
|
||||
List of previously archived Wine/Proton prefix directories.
|
||||
"""
|
||||
|
||||
heroic_config: tuple[str, str | int, Path, Path, Path] = ()
|
||||
|
||||
game_install_path: Path = None
|
||||
|
||||
Reference in New Issue
Block a user