Skip to content

Commit

Permalink
New: Battle.net support #34
Browse files Browse the repository at this point in the history
  • Loading branch information
JosefNemec committed Oct 13, 2017
1 parent 370b497 commit 823020c
Show file tree
Hide file tree
Showing 33 changed files with 1,192 additions and 108 deletions.
15 changes: 14 additions & 1 deletion source/Playnite/Database/GameDatabase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System.Threading;
using System.Windows.Threading;
using Playnite.Providers.Uplay;
using Playnite.Providers.BattleNet;

namespace Playnite.Database
{
Expand Down Expand Up @@ -235,6 +236,7 @@ public LiteCollection<IGame> GamesCollection
private ISteamLibrary steamLibrary;
private IOriginLibrary originLibrary;
private IUplayLibrary uplayLibrary;
private IBattleNetLibrary battleNetLibrary;

public readonly ushort DBVersion = 1;

Expand All @@ -255,14 +257,16 @@ public GameDatabase()
steamLibrary = new SteamLibrary();
originLibrary = new OriginLibrary();
uplayLibrary = new UplayLibrary();
battleNetLibrary = new BattleNetLibrary();
}

public GameDatabase(IGogLibrary gogLibrary, ISteamLibrary steamLibrary, IOriginLibrary originLibrary, IUplayLibrary uplayLibrary)
public GameDatabase(IGogLibrary gogLibrary, ISteamLibrary steamLibrary, IOriginLibrary originLibrary, IUplayLibrary uplayLibrary, IBattleNetLibrary battleNetLibrary)
{
this.gogLibrary = gogLibrary;
this.steamLibrary = steamLibrary;
this.originLibrary = originLibrary;
this.uplayLibrary = uplayLibrary;
this.battleNetLibrary = battleNetLibrary;
}

private void CheckDbState()
Expand Down Expand Up @@ -741,6 +745,9 @@ public void UpdateGameWithMetadata(IGame game)
case Provider.Uplay:
metadata = uplayLibrary.UpdateGameWithMetadata(game);
break;
case Provider.BattleNet:
metadata = battleNetLibrary.UpdateGameWithMetadata(game);
break;
case Provider.Custom:
return;
default:
Expand Down Expand Up @@ -782,6 +789,9 @@ public void UpdateInstalledGames(Provider provider)
case Provider.Uplay:
installedGames = uplayLibrary.GetInstalledGames();
break;
case Provider.BattleNet:
installedGames = battleNetLibrary.GetInstalledGames();
break;
default:
return;
}
Expand Down Expand Up @@ -860,6 +870,9 @@ public void UpdateOwnedGames(Provider provider)
break;
case Provider.Uplay:
return;
case Provider.BattleNet:
importedGames = battleNetLibrary.GetLibraryGames();
break;
default:
return;
}
Expand Down
17 changes: 17 additions & 0 deletions source/Playnite/FilterSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public bool Active
Origin ||
GOG ||
Uplay ||
BattleNet ||
Custom ||
!string.IsNullOrEmpty(Name) ||
!string.IsNullOrEmpty(ReleaseDate) ||
Expand Down Expand Up @@ -278,6 +279,22 @@ public bool Uplay
}
}

private bool battleNet;
public bool BattleNet
{
get
{
return battleNet;
}

set
{
battleNet = value;
OnPropertyChanged("BattleNet");
OnPropertyChanged("Active");
}
}

private bool custom;
public bool Custom
{
Expand Down
9 changes: 9 additions & 0 deletions source/Playnite/GamesStats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class GamesStats : INotifyPropertyChanged
public int Steam { get; private set; } = 0;
public int GOG { get; private set; } = 0;
public int Uplay { get; private set; } = 0;
public int BattleNet { get; private set; } = 0;
public int Custom { get; private set; } = 0;

public int Total
Expand Down Expand Up @@ -70,6 +71,7 @@ private void Recalculate()
Steam = 0;
GOG = 0;
Uplay = 0;
BattleNet = 0;
Custom = 0;

foreach (var game in database.GamesCollection.FindAll())
Expand Down Expand Up @@ -110,6 +112,9 @@ private void Recalculate()
case Provider.Uplay:
Uplay++;
break;
case Provider.BattleNet:
BattleNet++;
break;
default:
break;
}
Expand All @@ -133,6 +138,7 @@ private void NotifiyAllChanged()
OnPropertyChanged("Steam");
OnPropertyChanged("GOG");
OnPropertyChanged("Uplay");
OnPropertyChanged("BattleNet");
OnPropertyChanged("Custom");
OnPropertyChanged("Total");
}
Expand Down Expand Up @@ -222,6 +228,9 @@ private void IncrementalUpdate(IGame game, int modifier)
case Provider.Uplay:
Uplay = Uplay + (1 * modifier);
break;
case Provider.BattleNet:
BattleNet = BattleNet + (1 * modifier);
break;
}
}
}
Expand Down
56 changes: 46 additions & 10 deletions source/Playnite/Models/Game.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using Playnite.Providers;
using System.Collections.Concurrent;
using Playnite.Providers.Uplay;
using Playnite.Providers.BattleNet;

namespace Playnite.Models
{
Expand Down Expand Up @@ -65,6 +66,7 @@ public string DescriptionView
case Provider.Custom:
case Provider.Origin:
case Provider.Uplay:
case Provider.BattleNet:
case Provider.Steam:
default:
return string.IsNullOrEmpty(SteamSettings.DescriptionTemplate) ? Description : SteamSettings.DescriptionTemplate.Replace("{0}", Description);
Expand Down Expand Up @@ -448,19 +450,31 @@ public void InstallGame()
{
case Provider.Steam:
Process.Start(@"steam://install/" + ProviderId);
RegisterStateMonitor(new SteamGameStateMonitor(ProviderId, new SteamLibrary()));
RegisterStateMonitor(new SteamGameStateMonitor(ProviderId, new SteamLibrary()), GameStateMonitorType.Install);
break;
case Provider.GOG:
Process.Start(@"goggalaxy://openGameView/" + ProviderId);
RegisterStateMonitor(new GogGameStateMonitor(ProviderId, InstallDirectory, new GogLibrary()));
RegisterStateMonitor(new GogGameStateMonitor(ProviderId, InstallDirectory, new GogLibrary()), GameStateMonitorType.Install);
break;
case Provider.Origin:
Process.Start(string.Format(@"origin2://game/launch?offerIds={0}&autoDownload=true", ProviderId));
RegisterStateMonitor(new OriginGameStateMonitor(ProviderId, new OriginLibrary()));
RegisterStateMonitor(new OriginGameStateMonitor(ProviderId, new OriginLibrary()), GameStateMonitorType.Install);
break;
case Provider.Uplay:
Process.Start("uplay://install/" + ProviderId);
RegisterStateMonitor(new UplayGameStateMonitor(ProviderId, new UplayLibrary()));
RegisterStateMonitor(new UplayGameStateMonitor(ProviderId, new UplayLibrary()), GameStateMonitorType.Install);
break;
case Provider.BattleNet:
var product = BattleNetLibrary.GetAppDefinition(ProviderId);
if (product.Type == BattleNetLibrary.BNetAppType.Classic)
{
Process.Start(@"https://battle.net/account/management/download/");
}
else
{
Process.Start(BattleNetSettings.ClientExecPath, $"--game={product.InternalId}");
}
RegisterStateMonitor(new BattleNetGameStateMonitor(product, new BattleNetLibrary()), GameStateMonitorType.Install);
break;
case Provider.Custom:
break;
Expand Down Expand Up @@ -498,7 +512,7 @@ public void UninstallGame()
{
case Provider.Steam:
Process.Start("steam://uninstall/" + ProviderId);
RegisterStateMonitor(new SteamGameStateMonitor(ProviderId, new SteamLibrary()));
RegisterStateMonitor(new SteamGameStateMonitor(ProviderId, new SteamLibrary()), GameStateMonitorType.Uninstall);
break;
case Provider.GOG:
var uninstaller = Path.Combine(InstallDirectory, "unins000.exe");
Expand All @@ -508,15 +522,29 @@ public void UninstallGame()
}

Process.Start(uninstaller);
RegisterStateMonitor(new GogGameStateMonitor(ProviderId, InstallDirectory, new GogLibrary()));
RegisterStateMonitor(new GogGameStateMonitor(ProviderId, InstallDirectory, new GogLibrary()), GameStateMonitorType.Uninstall);
break;
case Provider.Origin:
Process.Start("appwiz.cpl");
RegisterStateMonitor(new OriginGameStateMonitor(ProviderId, new OriginLibrary()));
RegisterStateMonitor(new OriginGameStateMonitor(ProviderId, new OriginLibrary()), GameStateMonitorType.Uninstall);
break;
case Provider.Uplay:
Process.Start("uplay://uninstall/" + ProviderId);
RegisterStateMonitor(new UplayGameStateMonitor(ProviderId, new UplayLibrary()));
RegisterStateMonitor(new UplayGameStateMonitor(ProviderId, new UplayLibrary()), GameStateMonitorType.Uninstall);
break;
case Provider.BattleNet:
var product = BattleNetLibrary.GetAppDefinition(ProviderId);
var entry = BattleNetLibrary.GetUninstallEntry(product);
if (entry != null)
{
var args = string.Format("/C \"{0}\"", entry.UninstallString);
Process.Start("cmd", args);
RegisterStateMonitor(new BattleNetGameStateMonitor(product, new BattleNetLibrary()), GameStateMonitorType.Uninstall);
}
else
{
RegisterStateMonitor(new BattleNetGameStateMonitor(product, new BattleNetLibrary()), GameStateMonitorType.Uninstall);
}
break;
case Provider.Custom:
break;
Expand All @@ -525,7 +553,7 @@ public void UninstallGame()
}
}

public void RegisterStateMonitor(IGameStateMonitor monitor)
public void RegisterStateMonitor(IGameStateMonitor monitor, GameStateMonitorType type)
{
if (stateMonitor != null)
{
Expand All @@ -535,7 +563,15 @@ public void RegisterStateMonitor(IGameStateMonitor monitor)
stateMonitor = monitor;
stateMonitor.GameInstalled += StateMonitor_GameInstalled;
stateMonitor.GameUninstalled += StateMonitor_GameUninstalled;
stateMonitor.StartMonitoring();
if (type == GameStateMonitorType.Install)
{
stateMonitor.StartInstallMonitoring();
}
else
{
stateMonitor.StartUninstallMonitoring();
}

IsSetupInProgress = true;
}

Expand Down
3 changes: 2 additions & 1 deletion source/Playnite/Models/Provider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public enum Provider
GOG,
Origin,
Steam,
Uplay
Uplay,
BattleNet
}
}
4 changes: 4 additions & 0 deletions source/Playnite/Playnite.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,12 @@
<Compile Include="MetaProviders\Wikipedia.cs" />
<Compile Include="ObservableConcurrentDictionary.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Providers\BattleNet\BattleNetLibrary.cs" />
<Compile Include="Providers\BattleNet\BattleNetSettings.cs" />
<Compile Include="Models\GameMetadata.cs" />
<Compile Include="Providers\BattleNet\IBattleNetLibrary.cs" />
<Compile Include="Providers\BattleNet\BattleNetGameStateMonitor.cs" />
<Compile Include="Providers\BattleNet\WebApiClient.cs" />
<Compile Include="Providers\EpicLauncher\EpicLauncherSettings.cs" />
<Compile Include="Providers\GameInstalledEventArgs.cs" />
<Compile Include="Providers\GOG\GogGameStateMonitor.cs" />
Expand Down
109 changes: 109 additions & 0 deletions source/Playnite/Providers/BattleNet/BattleNetGameStateMonitor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using Microsoft.Win32;
using NLog;
using Playnite.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Playnite.Providers.BattleNet
{
public class BattleNetGameStateMonitor : IGameStateMonitor
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private IBattleNetLibrary library;
private BattleNetLibrary.BNetApp app;
private CancellationTokenSource cancelToken;

public event EventHandler GameUninstalled;
public event GameInstalledEventHandler GameInstalled;

public BattleNetGameStateMonitor(BattleNetLibrary.BNetApp app, IBattleNetLibrary library)
{
this.app = app;
this.library = library;
}

public void Dispose()
{
cancelToken?.Cancel(false);
}

public void StartInstallMonitoring()
{
logger.Info("Starting install monitoring of BattleNet app " + app.ProductId);
Dispose();

cancelToken = new CancellationTokenSource();

Task.Factory.StartNew(() =>
{
while (!cancelToken.Token.IsCancellationRequested)
{
var entry = BattleNetLibrary.GetUninstallEntry(app);
if (entry != null)
{
logger.Info($"BattleNet app {app.ProductId} has been installed.");
GameTask playTask;
if (app.Type == BattleNetLibrary.BNetAppType.Classic)
{
playTask = new GameTask()
{
Type = GameTaskType.File,
WorkingDir = @"{InstallDir}",
Path = @"{InstallDir}\" + app.ClassicExecutable
};
}
else
{
playTask = library.GetGamePlayTask(app.ProductId);
}
GameInstalled?.Invoke(this, new GameInstalledEventArgs(new Game()
{
PlayTask = playTask,
InstallDirectory = entry.InstallLocation
}));
return;
}
Thread.Sleep(5000);
}
}, cancelToken.Token);
}

public void StartUninstallMonitoring()
{
logger.Info("Starting uninstall monitoring of BattleNet app " + app.ProductId);
Dispose();

cancelToken = new CancellationTokenSource();

Task.Factory.StartNew(() =>
{
while (!cancelToken.Token.IsCancellationRequested)
{
var entry = BattleNetLibrary.GetUninstallEntry(app);
if (entry == null)
{
logger.Info($"BattleNet app {app.ProductId} has been uninstalled.");
GameUninstalled?.Invoke(this, null);
return;
}
Thread.Sleep(5000);
}
}, cancelToken.Token);
}

public void StopMonitoring()
{
logger.Info("Stopping monitoring of BattleNet app " + app.ProductId);
Dispose();
}
}
}
Loading

0 comments on commit 823020c

Please sign in to comment.