diff --git a/.gitignore b/.gitignore
index dad14a5..43be494 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@ node_modules
dist
public/css/*
+!public/css/hint.min.css
public/js
diff --git a/public/css/hint.min.css b/public/css/hint.min.css
new file mode 100644
index 0000000..d4411d0
--- /dev/null
+++ b/public/css/hint.min.css
@@ -0,0 +1,5 @@
+/*! Hint.css - v2.7.0 - 2021-10-01
+* https://kushagra.dev/lab/hint/
+* Copyright (c) 2021 Kushagra Gour */
+
+[class*=hint--]{position:relative;display:inline-block}[class*=hint--]:after,[class*=hint--]:before{position:absolute;-webkit-transform:translate3d(0,0,0);-moz-transform:translate3d(0,0,0);transform:translate3d(0,0,0);visibility:hidden;opacity:0;z-index:1000000;pointer-events:none;-webkit-transition:.3s ease;-moz-transition:.3s ease;transition:.3s ease;-webkit-transition-delay:0s;-moz-transition-delay:0s;transition-delay:0s}[class*=hint--]:hover:after,[class*=hint--]:hover:before{visibility:visible;opacity:1;-webkit-transition-delay:.1s;-moz-transition-delay:.1s;transition-delay:.1s}[class*=hint--]:before{content:'';position:absolute;background:0 0;border:6px solid transparent;z-index:1000001}[class*=hint--]:after{background:#383838;color:#fff;padding:8px 10px;font-size:12px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;line-height:12px;white-space:nowrap;text-shadow:0 -1px 0 #000;box-shadow:4px 4px 8px rgba(0,0,0,.3)}[class*=hint--][aria-label]:after{content:attr(aria-label)}[class*=hint--][data-hint]:after{content:attr(data-hint)}[aria-label='']:after,[aria-label='']:before,[data-hint='']:after,[data-hint='']:before{display:none!important}.hint--top-left:before,.hint--top-right:before,.hint--top:before{border-top-color:#383838}.hint--bottom-left:before,.hint--bottom-right:before,.hint--bottom:before{border-bottom-color:#383838}.hint--top:after,.hint--top:before{bottom:100%;left:50%}.hint--top:before{margin-bottom:-11px;left:calc(50% - 6px)}.hint--top:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translateX(-50%)}.hint--top:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--top:hover:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}.hint--bottom:after,.hint--bottom:before{top:100%;left:50%}.hint--bottom:before{margin-top:-11px;left:calc(50% - 6px)}.hint--bottom:after{-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);transform:translateX(-50%)}.hint--bottom:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--bottom:hover:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}.hint--right:before{border-right-color:#383838;margin-left:-11px;margin-bottom:-6px}.hint--right:after{margin-bottom:-14px}.hint--right:after,.hint--right:before{left:100%;bottom:50%}.hint--right:hover:after,.hint--right:hover:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)}.hint--left:before{border-left-color:#383838;margin-right:-11px;margin-bottom:-6px}.hint--left:after{margin-bottom:-14px}.hint--left:after,.hint--left:before{right:100%;bottom:50%}.hint--left:hover:after,.hint--left:hover:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--top-left:after,.hint--top-left:before{bottom:100%;left:50%}.hint--top-left:before{margin-bottom:-11px;left:calc(50% - 6px)}.hint--top-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translateX(-100%);margin-left:12px}.hint--top-left:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--top-left:hover:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translateX(-100%) translateY(-8px)}.hint--top-right:after,.hint--top-right:before{bottom:100%;left:50%}.hint--top-right:before{margin-bottom:-11px;left:calc(50% - 6px)}.hint--top-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translateX(0);margin-left:-12px}.hint--top-right:hover:after,.hint--top-right:hover:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--bottom-left:after,.hint--bottom-left:before{top:100%;left:50%}.hint--bottom-left:before{margin-top:-11px;left:calc(50% - 6px)}.hint--bottom-left:after{-webkit-transform:translateX(-100%);-moz-transform:translateX(-100%);transform:translateX(-100%);margin-left:12px}.hint--bottom-left:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--bottom-left:hover:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translateX(-100%) translateY(8px)}.hint--bottom-right:after,.hint--bottom-right:before{top:100%;left:50%}.hint--bottom-right:before{margin-top:-11px;left:calc(50% - 6px)}.hint--bottom-right:after{-webkit-transform:translateX(0);-moz-transform:translateX(0);transform:translateX(0);margin-left:-12px}.hint--bottom-right:hover:after,.hint--bottom-right:hover:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--large:after,.hint--medium:after,.hint--small:after{white-space:normal;line-height:1.4em;word-wrap:break-word}.hint--small:after{width:80px}.hint--medium:after{width:150px}.hint--large:after{width:300px}.hint--error:after{background-color:#b34e4d;text-shadow:0 -1px 0 #592726}.hint--error.hint--top-left:before,.hint--error.hint--top-right:before,.hint--error.hint--top:before{border-top-color:#b34e4d}.hint--error.hint--bottom-left:before,.hint--error.hint--bottom-right:before,.hint--error.hint--bottom:before{border-bottom-color:#b34e4d}.hint--error.hint--left:before{border-left-color:#b34e4d}.hint--error.hint--right:before{border-right-color:#b34e4d}.hint--warning:after{background-color:#c09854;text-shadow:0 -1px 0 #6c5328}.hint--warning.hint--top-left:before,.hint--warning.hint--top-right:before,.hint--warning.hint--top:before{border-top-color:#c09854}.hint--warning.hint--bottom-left:before,.hint--warning.hint--bottom-right:before,.hint--warning.hint--bottom:before{border-bottom-color:#c09854}.hint--warning.hint--left:before{border-left-color:#c09854}.hint--warning.hint--right:before{border-right-color:#c09854}.hint--info:after{background-color:#3986ac;text-shadow:0 -1px 0 #1a3c4d}.hint--info.hint--top-left:before,.hint--info.hint--top-right:before,.hint--info.hint--top:before{border-top-color:#3986ac}.hint--info.hint--bottom-left:before,.hint--info.hint--bottom-right:before,.hint--info.hint--bottom:before{border-bottom-color:#3986ac}.hint--info.hint--left:before{border-left-color:#3986ac}.hint--info.hint--right:before{border-right-color:#3986ac}.hint--success:after{background-color:#458746;text-shadow:0 -1px 0 #1a321a}.hint--success.hint--top-left:before,.hint--success.hint--top-right:before,.hint--success.hint--top:before{border-top-color:#458746}.hint--success.hint--bottom-left:before,.hint--success.hint--bottom-right:before,.hint--success.hint--bottom:before{border-bottom-color:#458746}.hint--success.hint--left:before{border-left-color:#458746}.hint--success.hint--right:before{border-right-color:#458746}.hint--always:after,.hint--always:before{opacity:1;visibility:visible}.hint--always.hint--top:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--top:after{-webkit-transform:translateX(-50%) translateY(-8px);-moz-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}.hint--always.hint--top-left:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--top-left:after{-webkit-transform:translateX(-100%) translateY(-8px);-moz-transform:translateX(-100%) translateY(-8px);transform:translateX(-100%) translateY(-8px)}.hint--always.hint--top-right:after,.hint--always.hint--top-right:before{-webkit-transform:translateY(-8px);-moz-transform:translateY(-8px);transform:translateY(-8px)}.hint--always.hint--bottom:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--bottom:after{-webkit-transform:translateX(-50%) translateY(8px);-moz-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}.hint--always.hint--bottom-left:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--bottom-left:after{-webkit-transform:translateX(-100%) translateY(8px);-moz-transform:translateX(-100%) translateY(8px);transform:translateX(-100%) translateY(8px)}.hint--always.hint--bottom-right:after,.hint--always.hint--bottom-right:before{-webkit-transform:translateY(8px);-moz-transform:translateY(8px);transform:translateY(8px)}.hint--always.hint--left:after,.hint--always.hint--left:before{-webkit-transform:translateX(-8px);-moz-transform:translateX(-8px);transform:translateX(-8px)}.hint--always.hint--right:after,.hint--always.hint--right:before{-webkit-transform:translateX(8px);-moz-transform:translateX(8px);transform:translateX(8px)}.hint--rounded:after{border-radius:4px}.hint--no-animate:after,.hint--no-animate:before{-webkit-transition-duration:0s;-moz-transition-duration:0s;transition-duration:0s}.hint--bounce:after,.hint--bounce:before{-webkit-transition:opacity .3s ease,visibility .3s ease,-webkit-transform .3s cubic-bezier(.71,1.7,.77,1.24);-moz-transition:opacity .3s ease,visibility .3s ease,-moz-transform .3s cubic-bezier(.71,1.7,.77,1.24);transition:opacity .3s ease,visibility .3s ease,transform .3s cubic-bezier(.71,1.7,.77,1.24)}.hint--no-shadow:after,.hint--no-shadow:before{text-shadow:initial;box-shadow:initial}.hint--no-arrow:before{display:none}
diff --git a/public/html/index.html b/public/html/index.html
index d86f3cf..0853bbd 100644
--- a/public/html/index.html
+++ b/public/html/index.html
@@ -7,6 +7,7 @@
+
diff --git a/src/ts/lib/LauncherLib.ts b/src/ts/lib/LauncherLib.ts
index dfef4ba..f2689f6 100644
--- a/src/ts/lib/LauncherLib.ts
+++ b/src/ts/lib/LauncherLib.ts
@@ -346,6 +346,22 @@ export default class LauncherLib
else return null;
}
+ public static async getWinetricks (): Promise
+ {
+ return new Promise((resolve) => {
+ if (!fs.existsSync(path.join(constants.launcherDir, 'winetricks.sh')))
+ {
+ Tools.downloadFile(constants.uri.winetricks, path.join(constants.launcherDir, 'winetricks.sh')).then(() => {
+ resolve(path.join(constants.launcherDir, 'winetricks.sh'));
+ });
+ }
+ else
+ {
+ resolve(path.join(constants.launcherDir, 'winetricks.sh'));
+ }
+ });
+ }
+
// WINEPREFIX='...../wineprefix' winetricks corefonts usetakefocus=n
public static async installPrefix (prefixPath: string, progress: (output: string, current: number, total: number) => void): Promise
{
@@ -369,9 +385,7 @@ export default class LauncherLib
];
return new Promise((resolve) => {
- const winetricksSh = path.join(constants.launcherDir, 'winetricks.sh');
-
- Tools.downloadFile(constants.uri.winetricks, winetricksSh).then(() => {
+ LauncherLib.getWinetricks().then((winetricksSh) => {
let installationProgress = 0;
let env: any = {
@@ -412,8 +426,6 @@ export default class LauncherLib
});
installerProcess.on('close', () => {
- fs.unlinkSync(winetricksSh);
-
resolve();
});
});
diff --git a/src/ts/settings.ts b/src/ts/settings.ts
index 6d28de3..ac59fda 100644
--- a/src/ts/settings.ts
+++ b/src/ts/settings.ts
@@ -139,48 +139,78 @@ $(() => {
/**
* winetricks button
*/
- if (commandExists('winetricks'))
- {
- $('#general-action-buttons #winetricks').on('click', () => {
- exec('winetricks', {
- env: {
- ...process.env,
- WINEPREFIX: constants.prefixDir.get()
- }
- });
- });
- }
- else
- {
- $('#general-action-buttons #winetricks')
- .addClass('hint--top hint--small')
- .attr('data-hint', LauncherUI.i18n.translate('IsNotInstalled', ['winetricks']))
- .attr('disabled', 'disabled');
- }
+ $('#general-action-buttons #winetricks').on('click', async () => {
+ let winetricks = await LauncherLib.getWinetricks();
+ $('#general-action-buttons #winetricks').attr('disabled', 'disabled');
+
+ let env: any = {
+ ...process.env,
+ WINEPREFIX: constants.prefixDir.get()
+ };
+
+ if (!commandExists('wine') && LauncherLib.getConfig('runner') !== null)
+ {
+ env['WINE'] = path.join(
+ constants.runnersDir,
+ LauncherLib.getConfig('runner.folder'),
+ LauncherLib.getConfig('runner.executable')
+ );
+
+ env['WINESERVER'] = path.join(path.dirname(env['WINE']), 'wineserver');
+
+ if (!fs.existsSync(env['WINE']))
+ console.error(`Patcher supposed to use ${LauncherLib.getConfig('runner.name')} runner, but it doesn't installed`);
+ }
+
+ const winetrickshell = spawn('bash', [winetricks], {
+ env: env
+ })
+
+ winetrickshell.on('close', () => {
+ $('#general-action-buttons #winetricks').removeAttr('disabled');
+ });
+ });
/**
* winecfg button
*/
- if (commandExists('winecfg'))
- {
- $('#general-action-buttons #winecfg').on('click', () => {
- exec('winecfg', {
- env: {
- ...process.env,
- WINEPREFIX: constants.prefixDir.get()
- }
- });
- });
- }
- else
- {
- $('#general-action-buttons #winecfg')
- .addClass('hint--top hint--small')
- .attr('data-hint', LauncherUI.i18n.translate('IsNotInstalled', ['winecfg']))
- .attr('disabled', 'disabled');
- }
+ $('#general-action-buttons #winecfg').on('click', () => {
+ $('#general-action-buttons #winecfg').attr('disabled', 'disabled');
+
+ let env: any = {
+ ...process.env,
+ WINEPREFIX: constants.prefixDir.get()
+ };
+
+ if (!commandExists('wine') && LauncherLib.getConfig('runner') !== null)
+ {
+ env['WINE'] = path.join(
+ constants.runnersDir,
+ LauncherLib.getConfig('runner.folder'),
+ LauncherLib.getConfig('runner.executable')
+ );
+
+ env['WINESERVER'] = path.join(path.dirname(env['WINE']), 'wineserver');
+
+ if (!fs.existsSync(env['WINE']))
+ console.error(`Patcher supposed to use ${LauncherLib.getConfig('runner.name')} runner, but it doesn't installed`);
+ }
+
+ const winecfg = LauncherLib.getConfig('runner.name').startsWith == 'Proton' ?
+ path.join(LauncherLib.getConfig('runner.folder'), 'files', 'lib64', 'wine', 'x86_64-windows', 'winecfg.exe') :
+ LauncherLib.getConfig('runner.name').startsWith == 'Lutris' ?
+ path.join(LauncherLib.getConfig('runner.folder'), 'lib64', 'wine', 'x86_64-windows', 'winecfg.exe') : 'winecfg'
+
+ const winecfgshell = exec(winecfg, {
+ env: env
+ });
+
+ winecfgshell.on('close', () => {
+ $('#general-action-buttons #winecfg').removeAttr('disabled');
+ });
+ });
/**
* HUD