diff --git a/wowup-electron/app/ipc-events.ts b/wowup-electron/app/ipc-events.ts index 9b6bbca2..9b379af0 100644 --- a/wowup-electron/app/ipc-events.ts +++ b/wowup-electron/app/ipc-events.ts @@ -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(); diff --git a/wowup-electron/src/app/services/files/file.service.ts b/wowup-electron/src/app/services/files/file.service.ts index f48b0ed8..d8675a9b 100644 --- a/wowup-electron/src/app/services/files/file.service.ts +++ b/wowup-electron/src/app/services/files/file.service.ts @@ -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 { + return this._electronService.invoke(IPC_GET_HOME_DIR); + } + public getAssetFilePath(fileName: string): Promise { return this._electronService.invoke(IPC_GET_ASSET_FILE_PATH, fileName); } diff --git a/wowup-electron/src/app/services/warcraft/warcraft-installation.service.ts b/wowup-electron/src/app/services/warcraft/warcraft-installation.service.ts index 22dc8cc9..3047d8c7 100644 --- a/wowup-electron/src/app/services/warcraft/warcraft-installation.service.ts +++ b/wowup-electron/src/app/services/warcraft/warcraft-installation.service.ts @@ -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; diff --git a/wowup-electron/src/app/services/warcraft/warcraft.service.impl.ts b/wowup-electron/src/app/services/warcraft/warcraft.service.impl.ts index addb62c2..48fa79bf 100644 --- a/wowup-electron/src/app/services/warcraft/warcraft.service.impl.ts +++ b/wowup-electron/src/app/services/warcraft/warcraft.service.impl.ts @@ -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; getExecutableName(clientType: WowClientType): string; getClientType(binaryPath: string): WowClientType; + resolveProducts(decodedProducts: InstalledProduct[], agentPath: string): InstalledProduct[]; } diff --git a/wowup-electron/src/app/services/warcraft/warcraft.service.linux.ts b/wowup-electron/src/app/services/warcraft/warcraft.service.linux.ts index 7d0e1280..f6d6a6ad 100644 --- a/wowup-electron/src/app/services/warcraft/warcraft.service.linux.ts +++ b/wowup-electron/src/app/services/warcraft/warcraft.service.linux.ts @@ -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 { 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 { - 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 { + 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}`); diff --git a/wowup-electron/src/app/services/warcraft/warcraft.service.mac.ts b/wowup-electron/src/app/services/warcraft/warcraft.service.mac.ts index 3ef70b80..9357f795 100644 --- a/wowup-electron/src/app/services/warcraft/warcraft.service.mac.ts +++ b/wowup-electron/src/app/services/warcraft/warcraft.service.mac.ts @@ -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; + } } diff --git a/wowup-electron/src/app/services/warcraft/warcraft.service.ts b/wowup-electron/src/app/services/warcraft/warcraft.service.ts index 2de91243..b96f1aa9 100644 --- a/wowup-electron/src/app/services/warcraft/warcraft.service.ts +++ b/wowup-electron/src/app/services/warcraft/warcraft.service.ts @@ -99,6 +99,7 @@ export class WarcraftService { */ public async getInstalledProducts(blizzardAgentPath: string): Promise> { const decodedProducts = await this.decodeProducts(blizzardAgentPath); + const resolvedProducts = this._impl.resolveProducts(decodedProducts, blizzardAgentPath); const dictionary = new Map(); for (const product of decodedProducts) { diff --git a/wowup-electron/src/app/services/warcraft/warcraft.service.win.ts b/wowup-electron/src/app/services/warcraft/warcraft.service.win.ts index f6e86a62..0c48a812 100644 --- a/wowup-electron/src/app/services/warcraft/warcraft.service.win.ts +++ b/wowup-electron/src/app/services/warcraft/warcraft.service.win.ts @@ -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; + } } diff --git a/wowup-electron/src/app/services/wowup/patch-notes.service.ts b/wowup-electron/src/app/services/wowup/patch-notes.service.ts index ca26442b..edad6caf 100644 --- a/wowup-electron/src/app/services/wowup/patch-notes.service.ts +++ b/wowup-electron/src/app/services/wowup/patch-notes.service.ts @@ -34,7 +34,6 @@ const CHANGELOGS: ChangeLog[] = [ { Version: "2.5.1", html: ` -

Hotfix

  • Update the Windows signing cert
  • diff --git a/wowup-electron/src/common/constants.ts b/wowup-electron/src/common/constants.ts index ff5f104d..c082dd53 100644 --- a/wowup-electron/src/common/constants.ts +++ b/wowup-electron/src/common/constants.ts @@ -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"; diff --git a/wowup-electron/src/common/wowup.d.ts b/wowup-electron/src/common/wowup.d.ts index 95e8fc5a..08e86589 100644 --- a/wowup-electron/src/common/wowup.d.ts +++ b/wowup-electron/src/common/wowup.d.ts @@ -30,6 +30,7 @@ declare type RendererChannels = | "minimize-window" | "maximize-window" | "show-directory" + | "get-home-dir" | "get-asset-file-path" | "create-directory" | "list-directories" diff --git a/wowup-electron/src/environments/environment.prod.ts b/wowup-electron/src/environments/environment.prod.ts index 497dbef0..03325faf 100644 --- a/wowup-electron/src/environments/environment.prod.ts +++ b/wowup-electron/src/environments/environment.prod.ts @@ -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",