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.Xml" />
|
||||
<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>
|
||||
<Compile Include="InstallController.cs" />
|
||||
|
|
|
@ -14,12 +14,12 @@ namespace LANCommander.Playnite.Extension
|
|||
{
|
||||
internal class LANCommanderClient
|
||||
{
|
||||
private readonly RestClient Client;
|
||||
public readonly RestClient Client;
|
||||
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)
|
||||
|
@ -89,6 +89,9 @@ namespace LANCommander.Playnite.Extension
|
|||
|
||||
var response = Client.Post<AuthResponse>(request);
|
||||
|
||||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
throw new WebException(response.ErrorMessage);
|
||||
|
||||
return response.Data;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
using Playnite.SDK;
|
||||
using LANCommander.Models;
|
||||
using Playnite.SDK;
|
||||
using Playnite.SDK.Models;
|
||||
using Playnite.SDK.Plugins;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Controls;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
using PN = Playnite;
|
||||
|
||||
namespace LANCommander.Playnite.Extension
|
||||
{
|
||||
public class PlayniteLibraryPlugin : LibraryPlugin
|
||||
{
|
||||
public static readonly ILogger Logger = LogManager.GetLogger();
|
||||
private PlayniteSettingsViewModel Settings { get; set; }
|
||||
internal PlayniteSettingsViewModel Settings { get; set; }
|
||||
internal LANCommanderClient LANCommander { get; set; }
|
||||
|
||||
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)
|
||||
{
|
||||
LANCommander = new LANCommanderClient();
|
||||
Settings = new PlayniteSettingsViewModel(this);
|
||||
Properties = new LibraryPluginProperties
|
||||
{
|
||||
HasSettings = true,
|
||||
};
|
||||
|
||||
LoadSettings();
|
||||
}
|
||||
|
||||
public override IEnumerable<GameMetadata> GetGames(LibraryGetGamesArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var token = new SDK.Models.AuthToken()
|
||||
{
|
||||
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 syncedGames = PlayniteApi.Database.Games;
|
||||
|
||||
var games = LANCommander
|
||||
.GetGames()
|
||||
|
@ -101,6 +84,52 @@ namespace LANCommander.Playnite.Extension
|
|||
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()
|
||||
{
|
||||
var window = PlayniteApi.Dialogs.CreateWindow(new WindowCreationOptions()
|
||||
|
@ -119,5 +148,44 @@ namespace LANCommander.Playnite.Extension
|
|||
|
||||
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;
|
||||
|
||||
public string ServerUrl { get; set; } = String.Empty;
|
||||
public string ServerAddress { get; set; } = String.Empty;
|
||||
public string AccessToken { get; set; } = String.Empty;
|
||||
public string RefreshToken { get; set; } = String.Empty;
|
||||
|
||||
|
@ -25,14 +25,9 @@ namespace LANCommander.Playnite.Extension
|
|||
{
|
||||
Plugin = plugin;
|
||||
|
||||
var savedSettings = Plugin.LoadPluginSettings<PlayniteSettingsViewModel>();
|
||||
|
||||
if (savedSettings != null)
|
||||
{
|
||||
ServerUrl = savedSettings.ServerUrl;
|
||||
AccessToken = savedSettings.AccessToken;
|
||||
RefreshToken = savedSettings.RefreshToken;
|
||||
}
|
||||
ServerAddress = Plugin.Settings.ServerAddress;
|
||||
AccessToken = Plugin.Settings.AccessToken;
|
||||
RefreshToken = Plugin.Settings.RefreshToken;
|
||||
}
|
||||
|
||||
public void BeginEdit()
|
||||
|
@ -47,7 +42,9 @@ namespace LANCommander.Playnite.Extension
|
|||
|
||||
public void EndEdit()
|
||||
{
|
||||
// Plugin.SavePluginSettings(this);
|
||||
Plugin.Settings.ServerAddress = ServerAddress;
|
||||
|
||||
Plugin.SaveSettings();
|
||||
}
|
||||
|
||||
public bool VerifySettings(out List<string> errors)
|
||||
|
|
|
@ -27,12 +27,17 @@ namespace LANCommander.Playnite.Extension
|
|||
|
||||
InitializeComponent();
|
||||
|
||||
var settings = new PlayniteSettingsViewModel(plugin);
|
||||
UpdateAuthenticationButtonVisibility();
|
||||
}
|
||||
|
||||
private void UpdateAuthenticationButtonVisibility()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Plugin.LANCommander.ValidateToken(new AuthToken()
|
||||
{
|
||||
AccessToken = settings.AccessToken,
|
||||
RefreshToken = settings.RefreshToken,
|
||||
AccessToken = Plugin.Settings.AccessToken,
|
||||
RefreshToken = Plugin.Settings.RefreshToken,
|
||||
}))
|
||||
{
|
||||
var authenticateButton = FindName("AuthenticateButton") as Button;
|
||||
|
@ -40,10 +45,22 @@ namespace LANCommander.Playnite.Extension
|
|||
authenticateButton.Visibility = Visibility.Hidden;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
public string ServerAddress { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string Password { get; set; }
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
</Style>
|
||||
</d:DesignerProperties.DesignStyle>
|
||||
<StackPanel Margin="20">
|
||||
<TextBlock Text="Server Address" />
|
||||
<TextBox Name="ServerAddress" Text="{Binding ServerAddress}" KeyDown="TextBox_KeyDown" />
|
||||
<TextBlock Text="Username"/>
|
||||
<TextBox Name="Username" Text="{Binding UserName}" KeyDown="TextBox_KeyDown" />
|
||||
<TextBlock Text="Password" />
|
||||
|
|
|
@ -21,12 +21,10 @@ namespace LANCommander.Playnite.Extension.Views
|
|||
{
|
||||
private PlayniteLibraryPlugin Plugin;
|
||||
private ViewModels.Authentication Context { get { return (ViewModels.Authentication)DataContext; } }
|
||||
private PlayniteSettingsViewModel Settings { get; set; }
|
||||
|
||||
public Authentication(PlayniteLibraryPlugin plugin)
|
||||
{
|
||||
Plugin = plugin;
|
||||
Settings = Plugin.GetSettings(false) as PlayniteSettingsViewModel;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
@ -56,16 +54,21 @@ namespace LANCommander.Playnite.Extension.Views
|
|||
{
|
||||
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);
|
||||
|
||||
Settings.AccessToken = response.AccessToken;
|
||||
Settings.RefreshToken = response.RefreshToken;
|
||||
Plugin.Settings.ServerAddress = Context.ServerAddress;
|
||||
Plugin.Settings.AccessToken = response.AccessToken;
|
||||
Plugin.Settings.RefreshToken = response.RefreshToken;
|
||||
|
||||
// Probably unneeded, but why not be more secure?
|
||||
Context.Password = String.Empty;
|
||||
|
||||
Plugin.SavePluginSettings(Settings);
|
||||
//Plugin.Settings = Plugin.LoadPluginSettings<PlayniteSettingsViewModel>();
|
||||
Plugin.SaveSettings();
|
||||
|
||||
Window.GetWindow(this).Close();
|
||||
}
|
||||
|
|
|
@ -12,4 +12,5 @@
|
|||
<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.ValueTuple" version="4.5.0" targetFramework="net462" />
|
||||
<package id="YamlDotNet" version="12.3.1" targetFramework="net462" />
|
||||
</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