mirror of
https://github.com/WowUp/WowUp.git
synced 2026-04-22 15:00:38 -04:00
Merge branch 'lutris' of https://github.com/fultonm/WowUp into pr/1054
This commit is contained in:
@@ -21,6 +21,7 @@ import * as path from "path";
|
||||
import { Transform } from "stream";
|
||||
import * as yauzl from "yauzl";
|
||||
import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
|
||||
import {
|
||||
IPC_ADDONS_SAVE_ALL,
|
||||
@@ -34,6 +35,7 @@ import {
|
||||
IPC_DOWNLOAD_FILE_CHANNEL,
|
||||
IPC_FOCUS_WINDOW,
|
||||
IPC_GET_APP_VERSION,
|
||||
IPC_GET_HOME_DIR,
|
||||
IPC_GET_ASSET_FILE_PATH,
|
||||
IPC_GET_DIRECTORY_TREE,
|
||||
IPC_GET_LATEST_DIR_UPDATE_TIME,
|
||||
@@ -107,6 +109,7 @@ import { createTray, restoreWindow } from "./system-tray";
|
||||
import { WowUpFolderScanner } from "./wowup-folder-scanner";
|
||||
import * as push from "./push";
|
||||
import { GetDirectoryTreeRequest } from "../src/common/models/ipc-request";
|
||||
import { electron } from 'process';
|
||||
|
||||
let PENDING_OPEN_URLS: string[] = [];
|
||||
|
||||
@@ -476,6 +479,10 @@ export function initializeIpcHandlers(window: BrowserWindow): void {
|
||||
return getDirTree(args.dirPath, args.opts);
|
||||
});
|
||||
|
||||
handle(IPC_GET_HOME_DIR, (): String => {
|
||||
return os.homedir();
|
||||
});
|
||||
|
||||
handle(IPC_MINIMIZE_WINDOW, () => {
|
||||
if (window?.minimizable) {
|
||||
window.minimize();
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
IPC_COPY_FILE_CHANNEL,
|
||||
IPC_CREATE_DIRECTORY_CHANNEL,
|
||||
IPC_DELETE_DIRECTORY_CHANNEL,
|
||||
IPC_GET_HOME_DIR,
|
||||
IPC_GET_ASSET_FILE_PATH,
|
||||
IPC_LIST_DIRECTORIES_CHANNEL,
|
||||
IPC_PATH_EXISTS_CHANNEL,
|
||||
@@ -34,6 +35,10 @@ import { ZipEntry } from "../../../common/models/ipc-response";
|
||||
export class FileService {
|
||||
public constructor(private _electronService: ElectronService) {}
|
||||
|
||||
public getHomeDir(): Promise<string> {
|
||||
return this._electronService.invoke(IPC_GET_HOME_DIR);
|
||||
}
|
||||
|
||||
public getAssetFilePath(fileName: string): Promise<string> {
|
||||
return this._electronService.invoke<string>(IPC_GET_ASSET_FILE_PATH, fileName);
|
||||
}
|
||||
|
||||
@@ -234,13 +234,7 @@ export class WarcraftInstallationService {
|
||||
|
||||
const label = await this.getNewInstallLabel(typeName, currentInstallations.length);
|
||||
|
||||
let fullProductPath: string;
|
||||
if (this._electronService.isLinux) {
|
||||
fullProductPath = this.getFullLutrisProductPath(product.location, blizzardAgentPath, product.clientType);
|
||||
} else {
|
||||
fullProductPath = this.getFullProductPath(product.location, product.clientType);
|
||||
}
|
||||
console.log(fullProductPath)
|
||||
let fullProductPath = this.getFullProductPath(product.location, product.clientType);
|
||||
const wowInstallation: WowInstallation = {
|
||||
id: uuidv4(),
|
||||
clientType: product.clientType,
|
||||
@@ -324,12 +318,7 @@ export class WarcraftInstallationService {
|
||||
|
||||
const label = await this._translateService.get(`COMMON.CLIENT_TYPES.${typeName.toUpperCase()}`).toPromise();
|
||||
|
||||
let newLocation: string;
|
||||
if (this._electronService.isLinux) {
|
||||
newLocation = this.getFullLutrisProductPath(legacyLocation, this._blizzardAgentPath, clientType);
|
||||
} else {
|
||||
newLocation = this.getFullProductPath(legacyLocation, clientType);
|
||||
}
|
||||
const newLocation = this.getFullProductPath(legacyLocation, clientType);
|
||||
|
||||
const newLocationExists = await this._fileService.pathExists(newLocation);
|
||||
if (!newLocationExists) {
|
||||
@@ -357,17 +346,6 @@ export class WarcraftInstallationService {
|
||||
return path.join(location, clientFolderName, executableName);
|
||||
}
|
||||
|
||||
private getFullLutrisProductPath(location: string, agentPath: string, clientType: WowClientType): string {
|
||||
const clientFolderName = this._warcraftService.getClientFolderName(clientType);
|
||||
const executableName = this._warcraftService.getExecutableName(clientType);
|
||||
const agentPathPrefixRegex = new RegExp(`(.*drive_c)`);
|
||||
console.log(`location: ${location} agentPath: ${agentPath} clienttype: ${clientType}`)
|
||||
const regexResults = agentPathPrefixRegex.exec(agentPath)
|
||||
console.log(regexResults)
|
||||
const agentPathPrefix = regexResults[1].trim();
|
||||
return path.join(agentPathPrefix, location.substr(3), clientFolderName, executableName);
|
||||
}
|
||||
|
||||
private getLegacyDefaultAddonChannel(typeName: string): AddonChannelType {
|
||||
const legacyDefaultChannelKey = `${typeName}${DEFAULT_CHANNEL_PREFERENCE_KEY_SUFFIX}`.toLowerCase();
|
||||
return parseInt(this._preferenceStorageService.findByKey(legacyDefaultChannelKey), 10) as AddonChannelType;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { WowClientType } from "../../../common/warcraft/wow-client-type";
|
||||
import { InstalledProduct } from '../../models/warcraft/installed-product';
|
||||
|
||||
export interface WarcraftServiceImpl {
|
||||
getExecutableExtension(): string;
|
||||
@@ -6,4 +7,5 @@ export interface WarcraftServiceImpl {
|
||||
getBlizzardAgentPath(): Promise<string>;
|
||||
getExecutableName(clientType: WowClientType): string;
|
||||
getClientType(binaryPath: string): WowClientType;
|
||||
resolveProducts(decodedProducts: InstalledProduct[], agentPath: string): InstalledProduct[];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as path from "path";
|
||||
import os from 'os';
|
||||
import { WOW_CLASSIC_ERA_FOLDER, WOW_CLASSIC_ERA_PTR_FOLDER } from "../../../common/constants";
|
||||
import { WowClientType } from "../../../common/warcraft/wow-client-type";
|
||||
import { InstalledProduct } from '../../models/warcraft/installed-product';
|
||||
import { ElectronService } from "../electron/electron.service";
|
||||
import { FileService } from "../files/file.service";
|
||||
import { WarcraftServiceImpl } from "./warcraft.service.impl";
|
||||
@@ -22,9 +22,7 @@ const WOW_APP_NAMES = [
|
||||
WOW_CLASSIC_BETA_NAME,
|
||||
];
|
||||
|
||||
const LUTRIS_DEFAULT_LIBRARY_PATH = "/Games"
|
||||
const LUTRIS_CONFIG_PATH = "/.config/lutris";
|
||||
const LUTRIS_CONFIG_FILE = "system.yml";
|
||||
const LUTRIS_CONFIG_PATH = "/.config/lutris/system.yml"
|
||||
// Search in this order until products are found on one.
|
||||
// All WoW products can be found under any or all of them,
|
||||
// since each of them are essentially just Battle.net
|
||||
@@ -32,7 +30,7 @@ const LUTRIS_CONFIG_FILE = "system.yml";
|
||||
const LUTRIS_WOW_DIRS = [
|
||||
"battlenet/drive_c",
|
||||
"world-of-warcraft/drive_c",
|
||||
"world-of-warcraft-classic/drive_c"];
|
||||
"world-of-warcraft-classic/drive_c"]
|
||||
|
||||
// BLIZZARD STRINGS
|
||||
const WINDOWS_BLIZZARD_AGENT_PATH = "ProgramData/Battle.net/Agent";
|
||||
@@ -50,21 +48,20 @@ export class WarcraftServiceLinux implements WarcraftServiceImpl {
|
||||
}
|
||||
|
||||
/**
|
||||
* On Linux players are normally using Lutris to install Battle.net launcher or WoW
|
||||
* On Linux players could be using Lutris to install the Battle.net launcher or WoW
|
||||
*/
|
||||
public async getBlizzardAgentPath(): Promise<string> {
|
||||
try {
|
||||
const lutrisLibraryPath = await this.getLutrisWowProductPath();
|
||||
const lutrisLibraryPath = await this.getLutrisWowPath();
|
||||
if (lutrisLibraryPath.length === 0) {
|
||||
throw new Error("Lutris library not found");
|
||||
}
|
||||
|
||||
const agentPath = path.join(lutrisLibraryPath, WINDOWS_BLIZZARD_AGENT_PATH, BLIZZARD_PRODUCT_DB_NAME);
|
||||
console.log(`Agent path: ${agentPath}`)
|
||||
const agentPathExists = await this._fileService.pathExists(agentPath);
|
||||
|
||||
if (agentPathExists) {
|
||||
console.log(`Found products at ${agentPath}`);
|
||||
console.log(`Found WoW products at ${agentPath}`);
|
||||
return agentPath;
|
||||
}
|
||||
|
||||
@@ -75,32 +72,35 @@ export class WarcraftServiceLinux implements WarcraftServiceImpl {
|
||||
return "";
|
||||
}
|
||||
|
||||
public async getLutrisWowProductPath(): Promise<string> {
|
||||
const lutrisConfigPath = path.join(os.homedir(), LUTRIS_CONFIG_PATH);
|
||||
public resolveProducts(decodedProducts: InstalledProduct[], agentPath: string): InstalledProduct[] {
|
||||
const resolvedProducts: InstalledProduct[] = [];
|
||||
const agentPathPrefixRegex = new RegExp(`(.*drive_c)`);
|
||||
for (const product of decodedProducts) {
|
||||
console.log(`location: ${location} agentPath: ${agentPath}`);
|
||||
const agentPathPrefix = agentPathPrefixRegex.exec(agentPath)[1].trim();
|
||||
resolvedProducts.push(
|
||||
{
|
||||
...product,
|
||||
location: path.join(agentPathPrefix, product.location.substr(3))
|
||||
} as InstalledProduct);
|
||||
|
||||
}
|
||||
return resolvedProducts;
|
||||
}
|
||||
|
||||
public async getLutrisWowPath(): Promise<string> {
|
||||
const homeDir = await this._fileService.getHomeDir();
|
||||
const resolvedPath = path.join(homeDir, LUTRIS_CONFIG_PATH);
|
||||
try {
|
||||
const lutrisConfigPathExists = await this._fileService.pathExists(lutrisConfigPath);
|
||||
if (lutrisConfigPathExists) {
|
||||
const lutrisConfigFilePath = path.join(lutrisConfigPath, LUTRIS_CONFIG_FILE);
|
||||
const lutrisConfigFileExists = await this._fileService.pathExists(lutrisConfigFilePath)
|
||||
let libraryPath: string;
|
||||
if (lutrisConfigFileExists) {
|
||||
const lutrisConfig = await this._fileService.readFile(lutrisConfigFilePath);
|
||||
const libraryPathRegex = new RegExp(`game_path: (.*)`);
|
||||
const potentialLibraryPath = libraryPathRegex.exec(lutrisConfig)[1].trim();
|
||||
const libraryPathExists = await this._fileService.pathExists(potentialLibraryPath);
|
||||
if (libraryPathExists) {
|
||||
libraryPath = potentialLibraryPath;
|
||||
}
|
||||
}
|
||||
// If the system.yml file doesn't exist, or game_path entry does not exist within it,
|
||||
// then use the default game installation path.
|
||||
if (libraryPath.length == 0) {
|
||||
libraryPath = path.join(os.homedir(), LUTRIS_DEFAULT_LIBRARY_PATH);
|
||||
}
|
||||
const lutrisConfigExists = await this._fileService.pathExists(resolvedPath);
|
||||
if (lutrisConfigExists) {
|
||||
const lutrisConfig = await this._fileService.readFile(resolvedPath);
|
||||
const libraryPathRegex = new RegExp(`game_path: (.*)`);
|
||||
const libraryPath = libraryPathRegex.exec(lutrisConfig)[1].trim();
|
||||
const libraryPathExists = await this._fileService.pathExists(libraryPath);
|
||||
if (libraryPathExists) {
|
||||
for (const wowDir of LUTRIS_WOW_DIRS) {
|
||||
const productPath = path.join(libraryPath, wowDir);
|
||||
const productPath = path.join(libraryPath, wowDir)
|
||||
const productPathExists = await this._fileService.pathExists(productPath);
|
||||
if (productPathExists) {
|
||||
console.log(`Found WoW product in Lutris library at ${productPath}`);
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as path from "path";
|
||||
|
||||
import { WOW_CLASSIC_ERA_FOLDER, WOW_CLASSIC_ERA_PTR_FOLDER } from "../../../common/constants";
|
||||
import { WowClientType } from "../../../common/warcraft/wow-client-type";
|
||||
import { InstalledProduct } from '../../models/warcraft/installed-product';
|
||||
import { FileService } from "../files/file.service";
|
||||
import { WarcraftServiceImpl } from "./warcraft.service.impl";
|
||||
|
||||
@@ -25,7 +26,7 @@ const BLIZZARD_AGENT_PATH = "/Users/Shared/Battle.net/Agent";
|
||||
const BLIZZARD_PRODUCT_DB_NAME = "product.db";
|
||||
|
||||
export class WarcraftServiceMac implements WarcraftServiceImpl {
|
||||
public constructor(private _fileService: FileService) {}
|
||||
public constructor(private _fileService: FileService) { }
|
||||
|
||||
public getExecutableExtension(): string {
|
||||
return "app";
|
||||
@@ -92,4 +93,8 @@ export class WarcraftServiceMac implements WarcraftServiceImpl {
|
||||
return WowClientType.None;
|
||||
}
|
||||
}
|
||||
|
||||
public resolveProducts(decodedProducts: InstalledProduct[], agentPath: string): InstalledProduct[] {
|
||||
return decodedProducts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,6 +99,7 @@ export class WarcraftService {
|
||||
*/
|
||||
public async getInstalledProducts(blizzardAgentPath: string): Promise<Map<WowClientType, InstalledProduct>> {
|
||||
const decodedProducts = await this.decodeProducts(blizzardAgentPath);
|
||||
const resolvedProducts = this._impl.resolveProducts(decodedProducts, blizzardAgentPath);
|
||||
const dictionary = new Map<WowClientType, InstalledProduct>();
|
||||
|
||||
for (const product of decodedProducts) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { ElectronService } from "../electron/electron.service";
|
||||
import { FileService } from "../files/file.service";
|
||||
import { WarcraftServiceImpl } from "./warcraft.service.impl";
|
||||
import { IPC_LIST_DISKS_WIN32, WOW_CLASSIC_ERA_FOLDER, WOW_CLASSIC_ERA_PTR_FOLDER } from "../../../common/constants";
|
||||
import { InstalledProduct } from '../../models/warcraft/installed-product';
|
||||
|
||||
const WOW_RETAIL_NAME = "Wow.exe";
|
||||
const WOW_RETAIL_PTR_NAME = "WowT.exe";
|
||||
@@ -109,4 +110,8 @@ export class WarcraftServiceWin implements WarcraftServiceImpl {
|
||||
return WowClientType.None;
|
||||
}
|
||||
}
|
||||
|
||||
public resolveProducts(decodedProducts: InstalledProduct[], agentPath: string): InstalledProduct[] {
|
||||
return decodedProducts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ const CHANGELOGS: ChangeLog[] = [
|
||||
{
|
||||
Version: "2.5.1",
|
||||
html: `
|
||||
<div>
|
||||
<h4 style="margin-top: 1em;">Hotfix</h4>
|
||||
<ul>
|
||||
<li>Update the Windows signing cert</li>
|
||||
|
||||
@@ -41,6 +41,7 @@ export const IPC_CURSE_HASH_FILE_CHANNEL = "curse-hash-file";
|
||||
export const IPC_SHOW_DIRECTORY = "show-directory";
|
||||
export const IPC_CURSE_GET_SCAN_RESULTS = "curse-get-scan-results";
|
||||
export const IPC_WOWUP_GET_SCAN_RESULTS = "wowup-get-scan-results";
|
||||
export const IPC_GET_HOME_DIR = "get-home-dir";
|
||||
export const IPC_GET_ASSET_FILE_PATH = "get-asset-file-path";
|
||||
export const IPC_CREATE_TRAY_MENU_CHANNEL = "create-tray-menu";
|
||||
export const IPC_LIST_DISKS_WIN32 = "list-disks-win32";
|
||||
|
||||
1
wowup-electron/src/common/wowup.d.ts
vendored
1
wowup-electron/src/common/wowup.d.ts
vendored
@@ -30,6 +30,7 @@ declare type RendererChannels =
|
||||
| "minimize-window"
|
||||
| "maximize-window"
|
||||
| "show-directory"
|
||||
| "get-home-dir"
|
||||
| "get-asset-file-path"
|
||||
| "create-directory"
|
||||
| "list-directories"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export const AppConfig = {
|
||||
production: true,
|
||||
environment: "PROD",
|
||||
wowUpWebsiteUrl: "https://dev.wowup.io",
|
||||
wowUpWebsiteUrl: "https://wowup.io",
|
||||
wowUpApiUrl: "https://api.wowup.io",
|
||||
wowUpHubUrl: "https://hub.wowup.io",
|
||||
googleAnalyticsId: "UA-92563227-4",
|
||||
|
||||
Reference in New Issue
Block a user