Skip to content

Commit

Permalink
feat: support using crossover
Browse files Browse the repository at this point in the history
  • Loading branch information
3Shain committed Mar 12, 2023
1 parent 514bc12 commit 868d87b
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 51 deletions.
10 changes: 8 additions & 2 deletions src/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { createUpdater, downloadProgram } from "./updater";
import { createCommonUpdateUI } from "./common-update-ui";
import { createLocale } from "./locale";
import zh_CN from "./locale/zh_CN";
import { CROSSOVER_LOADER } from "./crossover";

export async function createApp() {
await setKey("singleton", null);
Expand Down Expand Up @@ -94,11 +95,16 @@ export async function createApp() {
}
}

const { wineReady, wineUpdate, wineUpdateTag } = await checkWine(github);
const { wineReady, wineUpdate, wineUpdateTag, wineTag } = await checkWine(
github
);
const prefixPath = await resolve("./wineprefix"); // CHECK: hardcoded path?
if (wineReady) {
const wine = await createWine({
installDir: await resolve("./wine"), // CHECK: hardcoded path?
loaderBin:
wineTag == "crossover"
? CROSSOVER_LOADER
: await resolve("./wine/bin/wine64"), // CHECK: hardcoded path?
prefix: prefixPath,
});
return await createLauncher({ aria2, wine, locale, github });
Expand Down
54 changes: 42 additions & 12 deletions src/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import {
VStack,
} from "@hope-ui/solid";
import { createSignal, For, onMount } from "solid-js";
import { alert, getKey, setKey, _safeRelaunch } from "./utils";
import { checkCrossover } from "./crossover";
import { alert, getKey, prompt, setKey, _safeRelaunch } from "./utils";
import { WineVersionChecker } from "./wine";

export interface LauncherConfiguration {
Expand Down Expand Up @@ -56,6 +57,14 @@ export async function createConfiguration({
} catch {}

const currentWineVersion = await getKey("wine_tag");
const crossoverVersion = (await checkCrossover())
? [
{
tag: "crossover",
url: "not_applicable",
},
]
: [];
const [currentConfig, setCurrentConfig] = createSignal({
...config,
wine_tag: currentWineVersion,
Expand Down Expand Up @@ -90,16 +99,37 @@ export async function createConfiguration({
await setKey("config_retina", config.retina ? "true" : "false");
}
if (currentWineVersion != currentConfig().wine_tag) {
await alert("启动器需要重启", "需要重启以更新wine版本");
// await setKey("")
await setKey("wine_state", "update");
const tag = currentConfig().wine_tag;
await setKey("wine_update_tag", tag);
await setKey(
"wine_update_url",
wineVersions().find((x) => x.tag == tag)!.url
);
await _safeRelaunch();
if (currentConfig().wine_tag == "crossover") {
if (
(await prompt(
"CrossOver",
`CrossOver自带的MoltenVK版本过低,无法正常运行。如果你没有手动更新过文件,请参考一下教程 https://github.com/3Shain/yet-another-anime-game-launcher/wiki/CrossOver%E6%A8%A1%E5%BC%8F%E4%BD%BF%E7%94%A8%E6%9C%80%E6%96%B0%E7%89%88MoltenVK
如果不确定要如何操作,你现在可以取消。
确认操作后启动器将重启`
)) == true
) {
await setKey("wine_state", "update");
await setKey("wine_update_tag", "crossover");
await setKey("wine_update_url", "");
await _safeRelaunch();
} else {
setCurrentConfig((x) => {
return { ...x, wine_tag: currentWineVersion };
})
}
} else {
await alert("启动器需要重启", "需要重启以更新wine版本");
// await setKey("")
await setKey("wine_state", "update");
const tag = currentConfig().wine_tag;
await setKey("wine_update_tag", tag);
await setKey(
"wine_update_url",
wineVersions().find((x) => x.tag == tag)!.url
);
await _safeRelaunch();
}

return;
}
props.onClose();
Expand All @@ -126,7 +156,7 @@ export async function createConfiguration({
</SelectTrigger>
<SelectContent>
<SelectListbox>
<For each={wineVersions()}>
<For each={[...wineVersions(), ...crossoverVersion]}>
{(item) => (
<SelectOption value={item.tag}>
<SelectOptionText>{item.tag}</SelectOptionText>
Expand Down
12 changes: 12 additions & 0 deletions src/crossover.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { stats } from "./utils";

export const CROSSOVER_LOADER = "/Applications/CrossOver.app/Contents/SharedSupport/CrossOver/CrossOver-Hosted Application/wineloader64";

export async function checkCrossover() {
try {
await stats(CROSSOVER_LOADER);
return true;
} catch {
return false;
}
}
85 changes: 48 additions & 37 deletions src/wine.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
import { join } from "path-browserify";
import { Aria2 } from "./aria2";
import { CommonUpdateProgram, createCommonUpdateUI } from "./common-update-ui";
import { CROSSOVER_LOADER } from "./crossover";
import { Github, GithubReleases } from "./github";
import { Locale } from "./locale";
import {
exec as unixExec,
fatal,
getKey,
humanFileSize,
log,
removeFile,
resolve,
restart,
rmrf_dangerously,
setKey,
tar_extract,
wait,
} from "./utils";
import { xattrRemove } from "./utils/unix";

export async function createWine(options: {
installDir: string;
loaderBin: string;
prefix: string;
}) {
async function cmd(command: string, args: string[]) {
Expand All @@ -34,7 +32,7 @@ export async function createWine(options: {
log_file: string | undefined = undefined
) {
return await unixExec(
join(options.installDir, "bin/wine64"),
options.loaderBin,
program == "copy" ? ["cmd", "/c", program, ...args] : [program, ...args],
{
WINEPREFIX: `"${options.prefix}"`,
Expand Down Expand Up @@ -62,7 +60,6 @@ export type Wine = ReturnType<typeof createWine> extends Promise<infer T>
: never;

export async function checkWine(github: Github) {
// TODO
try {
const wineState = await getKey("wine_state");
if (wineState == "update") {
Expand All @@ -72,7 +69,7 @@ export async function checkWine(github: Github) {
wineUpdateTag: await getKey("wine_update_tag"),
} as const;
}
return { wineReady: true } as const;
return { wineReady: true, wineTag: await getKey("wine_tag") } as const;
} catch (e) {
// FIXME:
return {
Expand All @@ -93,8 +90,10 @@ export async function createWineVersionChecker(github: Github) {
return x.map((x) => {
return {
tag: x.tag_name,
url: github.acceleratedPath(x.assets.find((x) => x.name === "wine.tar.gz")!
.browser_download_url),
url: github.acceleratedPath(
x.assets.find((x) => x.name === "wine.tar.gz")!
.browser_download_url
),
};
});
});
Expand Down Expand Up @@ -127,13 +126,16 @@ export async function createWineInstallProgram({
}) {
async function* program(): CommonUpdateProgram {
const wineBinaryDir = await resolve("./wine");
let existBackup = true;
let existBackup = false;
try {
yield ["setStateText", "BACKUP_USER_DATA"];
await getKey("wine_tag");
const currentTag = await getKey("wine_tag");
// there is an existing wine
const wine = await createWine({
installDir: wineBinaryDir,
loaderBin:
currentTag === "crossover"
? CROSSOVER_LOADER
: join(wineBinaryDir, "bin", "wine64"),
prefix: await resolve("./wineprefix"),
});
// backup
Expand All @@ -153,34 +155,43 @@ export async function createWineInstallProgram({
await rmrf_dangerously(wineAbsPrefix);
existBackup = true;
} catch {}
yield ["setStateText", "DOWNLOADING_ENVIRONMENT"];
const wineTarPath = await resolve("./wine.tar.gz");
for await (const progress of aria2.doStreamingDownload({
uri: wineUpdateTarGzFile,
absDst: wineTarPath,
})) {
yield [
"setProgress",
Number((progress.completedLength * BigInt(100)) / progress.totalLength),
];
yield [
"setStateText",
"DOWNLOADING_ENVIRONMENT_SPEED",
`${humanFileSize(Number(progress.downloadSpeed))}`,
];
}
yield ["setStateText", "EXTRACT_ENVIRONMENT"];
yield ["setUndeterminedProgress"];
await rmrf_dangerously(wineBinaryDir);
await unixExec("mkdir", ["-p", wineBinaryDir]);
await tar_extract(await resolve("./wine.tar.gz"), wineBinaryDir);
await removeFile(wineTarPath);
if (wineTag === "crossover") {
yield ["setStateText", "CONFIGURING_ENVIRONMENT"];
} else {
yield ["setStateText", "DOWNLOADING_ENVIRONMENT"];
const wineTarPath = await resolve("./wine.tar.gz");
for await (const progress of aria2.doStreamingDownload({
uri: wineUpdateTarGzFile,
absDst: wineTarPath,
})) {
yield [
"setProgress",
Number(
(progress.completedLength * BigInt(100)) / progress.totalLength
),
];
yield [
"setStateText",
"DOWNLOADING_ENVIRONMENT_SPEED",
`${humanFileSize(Number(progress.downloadSpeed))}`,
];
}
yield ["setStateText", "EXTRACT_ENVIRONMENT"];
yield ["setUndeterminedProgress"];
await rmrf_dangerously(wineBinaryDir);
await unixExec("mkdir", ["-p", wineBinaryDir]);
await tar_extract(await resolve("./wine.tar.gz"), wineBinaryDir);
await removeFile(wineTarPath);

yield ["setStateText", "CONFIGURING_ENVIRONMENT"];
yield ["setStateText", "CONFIGURING_ENVIRONMENT"];

await xattrRemove("com.apple.quarantine", wineBinaryDir);
await xattrRemove("com.apple.quarantine", wineBinaryDir);
}

const wine64Bin = await resolve("./wine/bin/wine64");
const wine64Bin =
wineTag === "crossover"
? CROSSOVER_LOADER
: await resolve("./wine/bin/wine64");
const d = await unixExec(wine64Bin, ["wineboot", "-u"], {
WINEPREFIX: `"${wineAbsPrefix}"`,
});
Expand Down

0 comments on commit 868d87b

Please sign in to comment.