Skip to content
This repository has been archived by the owner on Jun 6, 2022. It is now read-only.

Commit

Permalink
Fix launching and detecting Battle.net games
Browse files Browse the repository at this point in the history
  • Loading branch information
doZennn committed Sep 11, 2019
1 parent 8313b38 commit 1ab05a4
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 37 deletions.
41 changes: 41 additions & 0 deletions BnetHelper.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
param (
[Parameter(Mandatory=$True)][string]$bnet, # Path to the Battle.net executable
[Parameter(Mandatory=$True)][string]$launchid # Battle.net launch id to launch
)

Write-Host 'Starting Battle.net'
Start-Process $bnet

# Wait to be sure log file gets created (just to be safe, usually gets created instantly)
Start-Sleep -Seconds 3

# Get latest log file
$log = Get-ChildItem -Path "$env:LOCALAPPDATA\Battle.net\Logs" -Filter "battle.net-*.log" | Sort-Object LastAccessTime -Descending | Select-Object -First 1

$bnetStarted = $False

Write-Host 'Waiting for Battle.net to start completely'

# Get current system date
$currentDate = Get-Date
Do {
# Check log file until we find this string
$launchedCompletely = Select-String -path $log -pattern 'GameController initialization complete'

If (!($launchedCompletely)) {
# Timeout after 1 minute
If ($currentDate.AddMinutes(1) -lt (Get-Date))
{
Write-Host 'Could not find successful launch'
exit
}
Start-Sleep -Seconds 1
} Else {
Write-Host 'Bnet started!'
$bnetStarted = $True
}
} Until ($bnetStarted)

# Launch
Write-Host "Starting game ($launchid)"
Start-Process $bnet "--exec=`"launch $launchid`""
29 changes: 17 additions & 12 deletions LauncherAutoClose.ps1
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
# This script is used to auto-close launchers that don't have an auto-close setting.


# $launchcmd = Command to launch game
# $launcher = Launcher to kill
# $game = Game(s) to watch

param (
[Parameter(Mandatory=$true)][string]$launchcmd,
[Parameter(Mandatory=$true)][string]$launcher,
[Parameter(Mandatory=$true)][string[]]$game
[Parameter(Mandatory=$True)][string]$launchcmd, # Command to launch game
[Parameter(Mandatory=$True)][string]$launcher, # Launcher to kill
[Parameter(Mandatory=$True)][string[]]$game, # Game(s) to watch

[Parameter(Mandatory=$False)][bool]$bnet = $False, # Use Battle.net-specific launch method
[Parameter(Mandatory=$False)][string]$bnetpath, # Battle.net executable
[Parameter(Mandatory=$False)][string]$bnetlaunchid # Battle.net launch ID
)

$scriptPath = Split-Path -parent $MyInvocation.MyCommand.Definition

function Wait-ProcessChildren($id) {
$child = Get-WmiObject win32_process | where {$_.ParentProcessId -In $id}
if ($child) {
Expand All @@ -22,12 +24,16 @@ function Wait-ProcessChildren($id) {

# Kill launcher
Write-Host 'Killing launcher'
Get-Process $launcher | Stop-Process
Get-Process $launcher -ErrorAction SilentlyContinue | Stop-Process

# Start Game
Start-Process $launchcmd
If ($bnet) {
& "$scriptPath\BnetHelper.ps1" -bnet $bnetpath -launchid $bnetlaunchid
} Else {
Start-Process $launchcmd
}

$gameStarted = $false
$gameStarted = $False

Write-Host 'Waiting for game to start'

Expand All @@ -38,8 +44,7 @@ Do {

If (!($gameProcess)) {
# Timeout after 30 minutes
If ($currentDate.AddMinutes(30) -lt (Get-Date))
{
If ($currentDate.AddMinutes(30) -lt (Get-Date)) {
Write-Host 'Game process could not be found'
exit
}
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
"from": "LauncherAutoClose.ps1",
"to": "."
},
{
"from": "BnetHelper.ps1",
"to": "."
},
"SteamGridDB Manager.VisualElementsManifest.xml"
],
"win": {
Expand Down
110 changes: 85 additions & 25 deletions src/js/importers/BattleNet.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,77 @@
const electron = window.require('electron');
const Registry = window.require('winreg');
const fs = window.require('fs');
const path = window.require('path');
import decoder from 'blizzard-product-parser/src/js/database'; // Workaround for badly configured lib

const BNET_GAMES = {
'd3': {
name: 'Diablo III',
launchId: 'D3',
exes: ['Diablo III', 'Diablo III64'],
icon: 'Diablo III Launcher.exe'
},
'dst2': {
name: 'Destiny 2',
launchId: 'DST2',
exes: ['destiny2'],
icon: 'Destiny 2 Launcher.exe'
},
'hero': {
name: 'Heroes of the Storm',
launchId: 'Hero',
exes: ['HeroesSwitcher', 'HeroesSwitcher_x64'],
icon: 'Heroes of the Storm.exe'
},
/*
'odin': {
name: 'Call of Duty: Modern Warfare',
launchId: 'ODIN',
},
*/
'pro': {
name: 'Overwatch',
launchId: 'Pro',
exes: ['Overwatch'],
icon: 'Overwatch Launcher.exe'
},
's1': {
name: 'Starcraft Remastered',
launchId: 'S1',
exes: ['StarCraft'],
icon: 'StarCraft Launcher.exe'
},
's2': {
name: 'Starcraft 2',
launchId: 'S2',
exes: ['SC2Switcher_x64', 'SC2Switcher'],
icon: 'StarCraft II.exe'
},
'viper': {
name: 'Call of Duty: Black Ops 4',
launchId: 'VIPR',
exes: ['BlackOps4', 'BlackOps4_boot'],
icon: 'Black Ops 4 Launcher.exe'
},
'w3': {
name: 'Warcraft 3: Reforged',
launchId: 'W3',
exes: ['Warcraft III'],
icon: 'Warcraft III.exe'
},
'wtcg': {
name: 'Hearthstone',
launchId: 'WTCG',
exes: ['Hearthstone'],
icon: 'Hearthstone.exe'
},
'wow': {
name: 'World of Warcraft',
launchId: 'WoW',
exes: ['Wow'],
icon: 'World of Warcraft Launcher.exe'
}
};

class BattleNet {
static isInstalled() {
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -52,43 +120,35 @@ class BattleNet {
return new Promise((resolve, reject) => {
this.getBattlenetPath().then((bnetPath) => {
const games = [];
const executable = path.join(bnetPath, 'Battle.net.exe');
let appData = (electron.app || electron.remote.app).getPath('userData');
appData = path.join(appData.replace(path.basename(appData), ''), 'Battle.net');

// Get latest .config file
const files = fs.readdirSync(appData).filter((files) => !(files === 'Battle.net.config' || !files.includes('.config')));
const latest = files.reduce((prev, current) => {
const prevFile = fs.statSync(path.join(appData, prev)).mtimeMs;
const currentFile = fs.statSync(path.join(appData, current)).mtimeMs;
return (prevFile.mtimeMs > currentFile.mtimeMs) ? prev : current;
});
const bnetExe = path.join(bnetPath, 'Battle.net.exe');

// Parse config file as JSON
const config = JSON.parse(fs.readFileSync(path.join(appData, latest)).toString());
const gameIds = {};
// Get path to LauncherAutoClose.ps1
let launcherWatcher = path.resolve(path.dirname(process.resourcesPath), '../../../', 'LauncherAutoClose.ps1');
if (!fs.existsSync(launcherWatcher)) {
launcherWatcher = path.join(path.dirname(process.resourcesPath), 'LauncherAutoClose.ps1');
}

// Map correct case id to lower case key
Object.keys(config.User.Client.PlayScreen.GameFamily).forEach((id) => {
gameIds[id.toLowerCase()] = id;
});
const powershellExe = path.join(process.env.windir, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe');

try {
const decoded = decoder.decode(fs.readFileSync('C:\\ProgramData\\Battle.net\\Agent\\product.db'));
const installed = decoded.productInstall.filter((product) => !(product.uid === 'battle.net' || product.uid === 'agent')); // Filter out non-games

installed.forEach((product) => {
const gameId = product.uid;
let launchId = product.productCode; // Lowercase, find correct case by matching with .config file
launchId = gameIds[launchId.toLowerCase()];
if (launchId) {
const name = path.basename(product.settings.installPath);
const launchIdLower = product.productCode.toLowerCase();
if (BNET_GAMES[launchIdLower]) {
const launchId = BNET_GAMES[launchIdLower].launchId;
const name = BNET_GAMES[launchIdLower].name;
const exes = BNET_GAMES[launchIdLower].exes;
const icon = path.join(product.settings.installPath, BNET_GAMES[launchIdLower].icon);
games.push({
id: gameId,
name: name,
exe: `"${executable}"`,
exe: `"${powershellExe}"`,
icon: `"${icon}"`,
startIn: `"${bnetPath}"`,
params: `--exec="launch ${launchId}"`,
params: `-windowstyle hidden -NoProfile -ExecutionPolicy Bypass -Command "& \\"${launcherWatcher}\\" -launcher \\"battle.net\\" -game \\"${exes.join('\\",\\"')}\\" -launchcmd \\"dummy\\" -bnet $True -bnetpath \\"${bnetExe}\\" -bnetlaunchid \\"${launchId}\\""`,
platform: 'bnet'
});
}
Expand Down

0 comments on commit 1ab05a4

Please sign in to comment.