Added game manifest model. Reworked settings to be a bit more universal across the extension. Made server URL configurable.
parent
cf326dd5ca
commit
787a983c03
|
@ -82,6 +82,9 @@
|
||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
|
<Reference Include="YamlDotNet, Version=12.0.0.0, Culture=neutral, PublicKeyToken=ec19458f3c15af5e, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\YamlDotNet.12.3.1\lib\net45\YamlDotNet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="InstallController.cs" />
|
<Compile Include="InstallController.cs" />
|
||||||
|
|
|
@ -14,12 +14,12 @@ namespace LANCommander.Playnite.Extension
|
||||||
{
|
{
|
||||||
internal class LANCommanderClient
|
internal class LANCommanderClient
|
||||||
{
|
{
|
||||||
private readonly RestClient Client;
|
public readonly RestClient Client;
|
||||||
public AuthToken Token;
|
public AuthToken Token;
|
||||||
|
|
||||||
public LANCommanderClient()
|
public LANCommanderClient(string baseUrl)
|
||||||
{
|
{
|
||||||
Client = new RestClient("https://localhost:7087");
|
Client = new RestClient(baseUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private T PostRequest<T>(string route, object body)
|
private T PostRequest<T>(string route, object body)
|
||||||
|
@ -89,6 +89,9 @@ namespace LANCommander.Playnite.Extension
|
||||||
|
|
||||||
var response = Client.Post<AuthResponse>(request);
|
var response = Client.Post<AuthResponse>(request);
|
||||||
|
|
||||||
|
if (response.StatusCode != HttpStatusCode.OK)
|
||||||
|
throw new WebException(response.ErrorMessage);
|
||||||
|
|
||||||
return response.Data;
|
return response.Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,24 @@
|
||||||
using Playnite.SDK;
|
using LANCommander.Models;
|
||||||
|
using Playnite.SDK;
|
||||||
using Playnite.SDK.Models;
|
using Playnite.SDK.Models;
|
||||||
using Playnite.SDK.Plugins;
|
using Playnite.SDK.Plugins;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using YamlDotNet.Serialization;
|
||||||
|
using YamlDotNet.Serialization.NamingConventions;
|
||||||
|
using PN = Playnite;
|
||||||
|
|
||||||
namespace LANCommander.Playnite.Extension
|
namespace LANCommander.Playnite.Extension
|
||||||
{
|
{
|
||||||
public class PlayniteLibraryPlugin : LibraryPlugin
|
public class PlayniteLibraryPlugin : LibraryPlugin
|
||||||
{
|
{
|
||||||
public static readonly ILogger Logger = LogManager.GetLogger();
|
public static readonly ILogger Logger = LogManager.GetLogger();
|
||||||
private PlayniteSettingsViewModel Settings { get; set; }
|
internal PlayniteSettingsViewModel Settings { get; set; }
|
||||||
internal LANCommanderClient LANCommander { get; set; }
|
internal LANCommanderClient LANCommander { get; set; }
|
||||||
|
|
||||||
public override Guid Id { get; } = Guid.Parse("48e1bac7-e0a0-45d7-ba83-36f5e9e959fc");
|
public override Guid Id { get; } = Guid.Parse("48e1bac7-e0a0-45d7-ba83-36f5e9e959fc");
|
||||||
|
@ -22,41 +27,19 @@ namespace LANCommander.Playnite.Extension
|
||||||
|
|
||||||
public PlayniteLibraryPlugin(IPlayniteAPI api) : base(api)
|
public PlayniteLibraryPlugin(IPlayniteAPI api) : base(api)
|
||||||
{
|
{
|
||||||
LANCommander = new LANCommanderClient();
|
|
||||||
Settings = new PlayniteSettingsViewModel(this);
|
|
||||||
Properties = new LibraryPluginProperties
|
Properties = new LibraryPluginProperties
|
||||||
{
|
{
|
||||||
HasSettings = true,
|
HasSettings = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LoadSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<GameMetadata> GetGames(LibraryGetGamesArgs args)
|
public override IEnumerable<GameMetadata> GetGames(LibraryGetGamesArgs args)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var token = new SDK.Models.AuthToken()
|
var syncedGames = PlayniteApi.Database.Games;
|
||||||
{
|
|
||||||
AccessToken = Settings.AccessToken,
|
|
||||||
RefreshToken = Settings.RefreshToken,
|
|
||||||
};
|
|
||||||
|
|
||||||
LANCommander.Token = token;
|
|
||||||
|
|
||||||
var tokenIsValid = LANCommander.ValidateToken(token);
|
|
||||||
|
|
||||||
if (!tokenIsValid)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
LANCommander.RefreshToken(token);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
ShowAuthenticationWindow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LANCommander.Token = token;
|
|
||||||
|
|
||||||
var games = LANCommander
|
var games = LANCommander
|
||||||
.GetGames()
|
.GetGames()
|
||||||
|
@ -101,6 +84,52 @@ namespace LANCommander.Playnite.Extension
|
||||||
return new PlayniteSettingsView(this);
|
return new PlayniteSettingsView(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void LoadSettings()
|
||||||
|
{
|
||||||
|
Settings = LoadPluginSettings<PlayniteSettingsViewModel>();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (LANCommander == null)
|
||||||
|
LANCommander = new LANCommanderClient(Settings.ServerAddress);
|
||||||
|
|
||||||
|
LANCommander.Client.BaseUrl = new Uri(Settings.ServerAddress);
|
||||||
|
|
||||||
|
var token = new SDK.Models.AuthToken()
|
||||||
|
{
|
||||||
|
AccessToken = Settings.AccessToken,
|
||||||
|
RefreshToken = Settings.RefreshToken,
|
||||||
|
};
|
||||||
|
|
||||||
|
LANCommander.Token = token;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveSettings()
|
||||||
|
{
|
||||||
|
SavePluginSettings(Settings);
|
||||||
|
|
||||||
|
if (LANCommander == null)
|
||||||
|
LANCommander = new LANCommanderClient(Settings.ServerAddress);
|
||||||
|
|
||||||
|
if (Settings.ServerAddress != LANCommander.Client.BaseUrl.ToString())
|
||||||
|
{
|
||||||
|
LANCommander.Client.BaseUrl = new Uri(Settings.ServerAddress);
|
||||||
|
|
||||||
|
var token = new SDK.Models.AuthToken()
|
||||||
|
{
|
||||||
|
AccessToken = Settings.AccessToken,
|
||||||
|
RefreshToken = Settings.RefreshToken,
|
||||||
|
};
|
||||||
|
|
||||||
|
LANCommander.Token = token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public System.Windows.Window ShowAuthenticationWindow()
|
public System.Windows.Window ShowAuthenticationWindow()
|
||||||
{
|
{
|
||||||
var window = PlayniteApi.Dialogs.CreateWindow(new WindowCreationOptions()
|
var window = PlayniteApi.Dialogs.CreateWindow(new WindowCreationOptions()
|
||||||
|
@ -119,5 +148,44 @@ namespace LANCommander.Playnite.Extension
|
||||||
|
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private GameMetadata ParseManifest(string installDirectory)
|
||||||
|
{
|
||||||
|
var manifestContents = File.ReadAllText(Path.Combine(installDirectory, "_manifest.yml"));
|
||||||
|
var deserializer = new DeserializerBuilder()
|
||||||
|
.WithNamingConvention(PascalCaseNamingConvention.Instance)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var manifest = deserializer.Deserialize<GameManifest>(manifestContents);
|
||||||
|
|
||||||
|
var metadata = new GameMetadata()
|
||||||
|
{
|
||||||
|
Name = manifest.Title,
|
||||||
|
SortingName = manifest.SortTitle,
|
||||||
|
Description = manifest.Description,
|
||||||
|
ReleaseDate = new ReleaseDate(manifest.ReleasedOn),
|
||||||
|
Version = manifest.Version,
|
||||||
|
GameActions = manifest.Actions.Select(a =>
|
||||||
|
{
|
||||||
|
return new PN.SDK.Models.GameAction()
|
||||||
|
{
|
||||||
|
Name = a.Name,
|
||||||
|
Arguments = a.Arguments,
|
||||||
|
Path = a.Path,
|
||||||
|
WorkingDir = a.WorkingDirectory,
|
||||||
|
IsPlayAction = a.IsPrimaryAction
|
||||||
|
};
|
||||||
|
}).ToList()
|
||||||
|
};
|
||||||
|
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
throw new FileNotFoundException("The manifest file is invalid or corrupt.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace LANCommander.Playnite.Extension
|
||||||
{
|
{
|
||||||
private readonly PlayniteLibraryPlugin Plugin;
|
private readonly PlayniteLibraryPlugin Plugin;
|
||||||
|
|
||||||
public string ServerUrl { get; set; } = String.Empty;
|
public string ServerAddress { get; set; } = String.Empty;
|
||||||
public string AccessToken { get; set; } = String.Empty;
|
public string AccessToken { get; set; } = String.Empty;
|
||||||
public string RefreshToken { get; set; } = String.Empty;
|
public string RefreshToken { get; set; } = String.Empty;
|
||||||
|
|
||||||
|
@ -25,14 +25,9 @@ namespace LANCommander.Playnite.Extension
|
||||||
{
|
{
|
||||||
Plugin = plugin;
|
Plugin = plugin;
|
||||||
|
|
||||||
var savedSettings = Plugin.LoadPluginSettings<PlayniteSettingsViewModel>();
|
ServerAddress = Plugin.Settings.ServerAddress;
|
||||||
|
AccessToken = Plugin.Settings.AccessToken;
|
||||||
if (savedSettings != null)
|
RefreshToken = Plugin.Settings.RefreshToken;
|
||||||
{
|
|
||||||
ServerUrl = savedSettings.ServerUrl;
|
|
||||||
AccessToken = savedSettings.AccessToken;
|
|
||||||
RefreshToken = savedSettings.RefreshToken;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginEdit()
|
public void BeginEdit()
|
||||||
|
@ -47,7 +42,9 @@ namespace LANCommander.Playnite.Extension
|
||||||
|
|
||||||
public void EndEdit()
|
public void EndEdit()
|
||||||
{
|
{
|
||||||
// Plugin.SavePluginSettings(this);
|
Plugin.Settings.ServerAddress = ServerAddress;
|
||||||
|
|
||||||
|
Plugin.SaveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool VerifySettings(out List<string> errors)
|
public bool VerifySettings(out List<string> errors)
|
||||||
|
|
|
@ -27,23 +27,40 @@ namespace LANCommander.Playnite.Extension
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
var settings = new PlayniteSettingsViewModel(plugin);
|
UpdateAuthenticationButtonVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
if (Plugin.LANCommander.ValidateToken(new AuthToken()
|
private void UpdateAuthenticationButtonVisibility()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Plugin.LANCommander.ValidateToken(new AuthToken()
|
||||||
|
{
|
||||||
|
AccessToken = Plugin.Settings.AccessToken,
|
||||||
|
RefreshToken = Plugin.Settings.RefreshToken,
|
||||||
|
}))
|
||||||
|
{
|
||||||
|
var authenticateButton = FindName("AuthenticateButton") as Button;
|
||||||
|
|
||||||
|
authenticateButton.Visibility = Visibility.Hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
{
|
{
|
||||||
AccessToken = settings.AccessToken,
|
|
||||||
RefreshToken = settings.RefreshToken,
|
|
||||||
}))
|
|
||||||
{
|
|
||||||
var authenticateButton = FindName("AuthenticateButton") as Button;
|
|
||||||
|
|
||||||
authenticateButton.Visibility = Visibility.Hidden;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AuthenticateButton_Click(object sender, RoutedEventArgs e)
|
private void AuthenticateButton_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Plugin.ShowAuthenticationWindow();
|
var authWindow = Plugin.ShowAuthenticationWindow();
|
||||||
|
|
||||||
|
authWindow.Closed += AuthWindow_Closed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AuthWindow_Closed(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
UpdateAuthenticationButtonVisibility();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace LANCommander.Playnite.Extension.ViewModels
|
||||||
{
|
{
|
||||||
internal class Authentication
|
internal class Authentication
|
||||||
{
|
{
|
||||||
|
public string ServerAddress { get; set; }
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
</Style>
|
</Style>
|
||||||
</d:DesignerProperties.DesignStyle>
|
</d:DesignerProperties.DesignStyle>
|
||||||
<StackPanel Margin="20">
|
<StackPanel Margin="20">
|
||||||
|
<TextBlock Text="Server Address" />
|
||||||
|
<TextBox Name="ServerAddress" Text="{Binding ServerAddress}" KeyDown="TextBox_KeyDown" />
|
||||||
<TextBlock Text="Username"/>
|
<TextBlock Text="Username"/>
|
||||||
<TextBox Name="Username" Text="{Binding UserName}" KeyDown="TextBox_KeyDown" />
|
<TextBox Name="Username" Text="{Binding UserName}" KeyDown="TextBox_KeyDown" />
|
||||||
<TextBlock Text="Password" />
|
<TextBlock Text="Password" />
|
||||||
|
|
|
@ -21,12 +21,10 @@ namespace LANCommander.Playnite.Extension.Views
|
||||||
{
|
{
|
||||||
private PlayniteLibraryPlugin Plugin;
|
private PlayniteLibraryPlugin Plugin;
|
||||||
private ViewModels.Authentication Context { get { return (ViewModels.Authentication)DataContext; } }
|
private ViewModels.Authentication Context { get { return (ViewModels.Authentication)DataContext; } }
|
||||||
private PlayniteSettingsViewModel Settings { get; set; }
|
|
||||||
|
|
||||||
public Authentication(PlayniteLibraryPlugin plugin)
|
public Authentication(PlayniteLibraryPlugin plugin)
|
||||||
{
|
{
|
||||||
Plugin = plugin;
|
Plugin = plugin;
|
||||||
Settings = Plugin.GetSettings(false) as PlayniteSettingsViewModel;
|
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
@ -56,16 +54,21 @@ namespace LANCommander.Playnite.Extension.Views
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (Plugin.LANCommander == null)
|
||||||
|
Plugin.LANCommander = new LANCommanderClient(Context.ServerAddress);
|
||||||
|
else
|
||||||
|
Plugin.LANCommander.Client.BaseUrl = new Uri(Context.ServerAddress);
|
||||||
|
|
||||||
var response = Plugin.LANCommander.Authenticate(Context.UserName, Context.Password);
|
var response = Plugin.LANCommander.Authenticate(Context.UserName, Context.Password);
|
||||||
|
|
||||||
Settings.AccessToken = response.AccessToken;
|
Plugin.Settings.ServerAddress = Context.ServerAddress;
|
||||||
Settings.RefreshToken = response.RefreshToken;
|
Plugin.Settings.AccessToken = response.AccessToken;
|
||||||
|
Plugin.Settings.RefreshToken = response.RefreshToken;
|
||||||
|
|
||||||
// Probably unneeded, but why not be more secure?
|
// Probably unneeded, but why not be more secure?
|
||||||
Context.Password = String.Empty;
|
Context.Password = String.Empty;
|
||||||
|
|
||||||
Plugin.SavePluginSettings(Settings);
|
Plugin.SaveSettings();
|
||||||
//Plugin.Settings = Plugin.LoadPluginSettings<PlayniteSettingsViewModel>();
|
|
||||||
|
|
||||||
Window.GetWindow(this).Close();
|
Window.GetWindow(this).Close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,4 +12,5 @@
|
||||||
<package id="System.Text.Json" version="5.0.1" targetFramework="net462" />
|
<package id="System.Text.Json" version="5.0.1" targetFramework="net462" />
|
||||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net462" />
|
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net462" />
|
||||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net462" />
|
<package id="System.ValueTuple" version="4.5.0" targetFramework="net462" />
|
||||||
|
<package id="YamlDotNet" version="12.3.1" targetFramework="net462" />
|
||||||
</packages>
|
</packages>
|
|
@ -0,0 +1,38 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace LANCommander.Models
|
||||||
|
{
|
||||||
|
public class GameManifest
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string SortTitle { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public DateTime ReleasedOn { get; set; }
|
||||||
|
public string[] Genre { get; set; }
|
||||||
|
public string[] Tags { get; set; }
|
||||||
|
public string[] Publishers { get; set; }
|
||||||
|
public string[] Developers { get; set; }
|
||||||
|
public string Version { get; set; }
|
||||||
|
public string Icon { get; set; }
|
||||||
|
public GameAction[] Actions { get; set; }
|
||||||
|
public bool Singleplayer { get; set; }
|
||||||
|
public MultiplayerInfo LocalMultiplayer { get; set; }
|
||||||
|
public MultiplayerInfo LanMultiplayer { get; set; }
|
||||||
|
public MultiplayerInfo OnlineMultiplayer { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GameAction
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Arguments { get; set; }
|
||||||
|
public string Path { get; set; }
|
||||||
|
public string WorkingDirectory { get; set; }
|
||||||
|
public bool IsPrimaryAction { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MultiplayerInfo
|
||||||
|
{
|
||||||
|
public int MinPlayers { get; set; }
|
||||||
|
public int MaxPlayers { get; set; }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue