Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic optifine support #240

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions portablemc/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
from portablemc.fabric import FabricVersion, FabricResolveEvent
from portablemc.forge import ForgeVersion, ForgeResolveEvent, ForgePostProcessingEvent, \
ForgePostProcessedEvent, ForgeInstallError, _NeoForgeVersion
import portablemc.optifine as optifine
# import portablemc.optifine_withprefix as optifine # if you want to use optifine with prefix


from typing import cast, Optional, List, Union, Dict, Callable, Any, Tuple

Expand Down Expand Up @@ -300,13 +303,32 @@ def cmd_search_handler(ns: SearchNs, kind: str, table: OutputTable):
for loader in api._request_loaders():
if search is None or search in loader.version:
table.add(loader.version, _("search.flags.stable") if loader.stable else "")

elif kind == "optifine":
table.add(_("search.loader_version"), _("search.release_date"), _("search.flags"), _("search.OptiFine.ForgeCompatibility"))
if not ns.work_dir:
c= Context()
ns.work_dir=c.work_dir
try:
v_list=optifine.get_compatible_versions(ns.work_dir)
except VersionNotFoundError as e:
try:
v_list=optifine.get_offline_versions(ns.work_dir/"versions")
except Exception as b:
print(b)
did_lines=True
for k in v_list.keys():
if did_lines and any((search is None or search in loader.mc_version or search in loader.edition) for loader in v_list[k]):
table.separator()
did_lines=False
for loader in v_list[k]:
if search is None or search in loader.mc_version or search in loader.edition:
did_lines=True
table.add(f"{loader.mc_version}-OptiFine_{loader.edition}", loader.date, _("search.flags.stable") if not loader.preview else "preview", loader.forge if loader.forge else "")
else:
raise ValueError()


def cmd_start(ns: StartNs):

version_parts = ns.version.split(":")

# If no split, the kind of version is "standard": parts have at least 2 elements.
Expand Down Expand Up @@ -497,7 +519,9 @@ def cmd_start_handler(ns: StartNs, kind: str, parts: List[str]) -> Optional[Vers
constructor = ForgeVersion if kind == "forge" else _NeoForgeVersion
prefix = ns.forge_prefix if kind == "forge" else ns.neoforge_prefix
return constructor(version, context=ns.context, prefix=prefix)

elif kind == "optifine":
constructor= optifine.OptifineVersion
return constructor(":".join(parts) if len(parts) > 0 else "recommended", context=ns.context)
else:
return None

Expand Down Expand Up @@ -801,7 +825,6 @@ def __init__(self, ns: RootNs) -> None:

def progress_task(key: str, **kwargs) -> None:
ns.out.task("..", key, **kwargs)

def finish_task(key: str, **kwargs) -> None:
ns.out.task("OK", key, **kwargs)
ns.out.finish()
Expand Down Expand Up @@ -855,6 +878,11 @@ def forge_resolve(e: ForgeResolveEvent) -> None:
DownloadStartEvent: self.download_start,
DownloadProgressEvent: self.download_progress,
DownloadCompleteEvent: self.download_complete,
# Optifine install logic is particular: it needs to be done after the download of the client and installer jar
# There is no particular event for the fetching of the version, because the entire json is generated after patch
optifine.OptifineStartInstallEvent: lambda e: progress_task("start.optifine.install"),
optifine.OptifineEndInstallEvent: lambda e: finish_task("start.optifine.installed", version=e.version),
optifine.OptifinePatchEvent: lambda e: progress_task("start.optifine.patching", progress=f"{e.done}/{e.total}"),
})

self.ns = ns
Expand Down
12 changes: 10 additions & 2 deletions portablemc/cli/lang.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ def get(key: str, **kwargs) -> str:
"args._":
" A fast, reliable and cross-platform command-line Minecraft launcher and API\n"
" for developers. Including fast and easy installation of common mod loaders such\n"
" as Fabric, LegacyFabric, Forge, NeoForge, Quilt and Babric. This launcher is\n"
" compatible with the standard Minecraft directories.\n\n",
" as Fabric, LegacyFabric, Forge, NeoForge, Quilt, Babric and Optifine. \n"
" This launcher is compatible with the standard Minecraft directories.\n\n",
"args.main_dir": "Set the main directory where libraries, assets and versions.",
"args.work_dir": "Set the working directory where the game run and place for examples "
"saves, screenshots (and resources for legacy versions), it also store "
Expand Down Expand Up @@ -75,6 +75,7 @@ def get(key: str, **kwargs) -> str:
"args.search.kind.comp.legacyfabric": "Search for LegacyFabric versions.",
"args.search.kind.comp.quilt": "Search for Quilt versions.",
"args.search.kind.comp.babric": "Search for Babric versions.",
"args.search.kind.comp.optifine": "Search for Optifine versions.",
"args.search.input": "Search input.",
"args.search.input.comp.release": "Resolve version of the latest release.",
"args.search.input.comp.snapshot": "Resolve version of the latest snapshot.",
Expand All @@ -88,6 +89,7 @@ def get(key: str, **kwargs) -> str:
"args.start.version.babric": "babric::[<loader-version>]",
"args.start.version.forge": "forge:[<forge-version>] (forge-version >= 1.5.2)",
"args.start.version.neoforge": "neoforge:[<neoforge-version>] (neoforge-version >= 1.20.1)",
"args.start.version.optifine": "optifine:[<vanilla-version>[:<optifine-version>]]",
"args.start.version.comp.release": "Start the latest release (default).",
"args.start.version.comp.snapshot": "Start the latest snapshot.",
"args.start.version.comp.fabric": "Start Fabric mod loader with latest release.",
Expand All @@ -96,6 +98,7 @@ def get(key: str, **kwargs) -> str:
"args.start.version.comp.babric": "Start Babric mod loader with beta 1.7.3.",
"args.start.version.comp.forge": "Start Forge mod loader with latest release.",
"args.start.version.comp.neoforge": "Start NeoForge mod loader with latest release.",
"args.start.version.comp.optifine": "Start Optifine mod loader with latest recommended release.",
"args.start.dry": "Simulate game starting.",
"args.start.disable_multiplayer": "Disable the multiplayer buttons (>= 1.16).",
"args.start.disable_chat": "Disable the online chat (>= 1.16).",
Expand Down Expand Up @@ -189,6 +192,7 @@ def get(key: str, **kwargs) -> str:
"search.flags.local": "local",
"search.flags.stable": "stable",
"search.loader_version": "Loader version",
"search.OptiFine.ForgeCompatibility": "Forge compatibility",
# Command login
"login.tip.remember_start_login": "Remember to start the game with '-l {email}' if you want to be authenticated in-game.",
# Command logout
Expand Down Expand Up @@ -249,6 +253,10 @@ def get(key: str, **kwargs) -> str:
"start.forge.post_processed": "Forge post processing done",
f"start.forge.install_error.{ForgeInstallError.INSTALL_PROFILE_NOT_FOUND}": "Install profile not found in the forge installer.",
f"start.forge.install_error.{ForgeInstallError.VERSION_METADATA_NOT_FOUND}": "Version metadata not found in the forge installer.",
# Command start (optifine)
"start.optifine.install": "Installing OptiFine...",
"start.optifine.patching": "Patching OptiFine library {progress}",
"start.optifine.installed": "OptiFine Library {version} installed",
# Pretty download
"download.threads_count": "Download threads count: {count}",
"download.start": "Download starting...",
Expand Down
2 changes: 1 addition & 1 deletion portablemc/cli/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ def get_outputs() -> List[str]:
return ["human-color", "human", "machine"]

def get_search_kinds() -> List[str]:
return ["mojang", "local", "forge", "fabric", "quilt", "legacyfabric", "babric"]
return ["mojang", "local", "forge", "fabric", "quilt", "legacyfabric", "babric", "optifine"]

def get_auth_services() -> List[str]:
return ["microsoft", "yggdrasil"]
Expand Down
2 changes: 1 addition & 1 deletion portablemc/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def from_entry(cls, entry: DownloadEntry, *, redirect: int = 0) -> "_DownloadEnt
url_parsed.scheme == "https",
url_parsed.netloc,
url_parsed.port,
url_parsed.path,
url_parsed.path+("" if url_parsed.query == "" else "?"+url_parsed.query),
entry,
redirect=redirect)

Expand Down
Loading