Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
515 changes: 370 additions & 145 deletions HumbleKeysLibrary.cs

Large diffs are not rendered by default.

91 changes: 81 additions & 10 deletions HumbleKeysLibrarySettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,68 @@

namespace HumbleKeys
{
public enum RedemptionStoreType
{
None, // 0
Source, // 1
Tag, // 2
Category, // 3
Platform, // 4
}

public enum TagMethodology
{
None, // 0
Monthly, // 1
All, // 2
}

public enum UnredeemableMethodology
{
Tag, // 0
Delete, // 1
}

public class KeyInfo
{
public string Name { get; set; } // Description used anywhere else needed, other than for Playnite's "Source" field
public string SourceName { get; set; } // Exact match for Playnite's "Source" field, only used when Redemption Store is saved to Source
public Guid SourceId { get; set; } // "Source" field GUID found in Playnite
}

public class HumbleKeysLibrarySettings : ObservableObject, ISettings
{
private readonly HumbleKeysLibrary plugin;
private static ILogger logger = LogManager.GetLogger();
private static readonly ILogger logger = LogManager.GetLogger();
private HumbleKeysLibrarySettings editingClone;

public bool ConnectAccount { get; set; } = false;
public bool IgnoreRedeemedKeys { get; set; } = false;
public bool AddKeyStatus { get; set; } = true;
public int RedemptionStore { get; set; } = (int)RedemptionStoreType.Source;
public bool AddLinks { get; set; } = true;
public bool ImportChoiceKeys { get; set; } = false;
public int TagWithBundleName { get; set; } = (int)TagMethodology.None;
public int UnredeemableKeyHandling { get; set; } = (int)UnredeemableMethodology.Tag;
public bool CacheEnabled { get; set; } = false;
public string CurrentTagMethodology { get; set; } = "none";

public string CurrentUnredeemableMethodology { get; set; } = "tag";

[Obsolete("Deprecated, scheduled for deletion: Use TagWithBundleName instead")]
public string CurrentTagMethodology { get; set; }
[Obsolete("Deprecated, scheduled for deletion: Use UnredeemableKeyHandling instead")]
public string CurrentUnredeemableMethodology { get; set; }
public bool AddPlatformNintendo { get; set; } = true;
public bool AddPlatformWindows { get; set; } = true;

[DontSerialize]
public List<string> keyTypeWhitelist = new List<string>() {
"gog",
"nintendo_direct",
"origin",
"origin_keyless",
"steam",
public Dictionary<string, KeyInfo> keyTypeWhitelist = new Dictionary<string, KeyInfo>
{
//["epic"] = new KeyInfo { Name = "Epic", SourceName = "Epic" }, // This key type is valid so do we want to add it? I only have game dev asset keys at Epic myself right now but I assume this could be real games too
//["epic_keyless"] = new KeyInfo { Name = "Epic keyless", SourceName = "Epic" }, // Is this even a valid key type? I just guessed it might be because Humble mentions it has keyless Epic keys
["gog"] = new KeyInfo { Name = "GOG", SourceName = "GOG" },
["nintendo_direct"] = new KeyInfo { Name = "Nintendo", SourceName = "Nintendo" },
["origin"] = new KeyInfo { Name = "EA", SourceName = "EA app" },
["origin_keyless"] = new KeyInfo { Name = "EA keyless", SourceName = "EA app" },
["steam"] = new KeyInfo { Name = "Steam", SourceName = "Steam" },
};

[DontSerialize]
Expand Down Expand Up @@ -68,6 +109,36 @@ public HumbleKeysLibrarySettings(HumbleKeysLibrary plugin)

if (savedSettings != null)
{
// Migrate old setting strings to enum ints; This code section is scheduled for deletion in the future
if (savedSettings.CurrentTagMethodology != null || savedSettings.CurrentUnredeemableMethodology != null)
{
switch (savedSettings.CurrentTagMethodology)
{
//case "none": // None is default, so already correct
case "monthly":
savedSettings.TagWithBundleName = (int)TagMethodology.Monthly;
break;
case "all":
savedSettings.TagWithBundleName = (int)TagMethodology.All;
break;
}

// Tag is default, so no need to fix
if (savedSettings.CurrentUnredeemableMethodology == "delete")
{
savedSettings.UnredeemableKeyHandling = (int)UnredeemableMethodology.Delete;
}

// Clear deprecated values so migration only happens once
savedSettings.CurrentTagMethodology = null;
savedSettings.CurrentUnredeemableMethodology = null;

// Save, otherwise values won't stick
plugin.SavePluginSettings(savedSettings);
}
// End settings migration section


LoadValues(savedSettings);
}
}
Expand Down
145 changes: 84 additions & 61 deletions HumbleKeysLibrarySettingsView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,69 +29,92 @@
IsChecked="{Binding ConnectAccount}"
Content="{DynamicResource LOCHumbleSettingsConnectAccount}"/>

<StackPanel DockPanel.Dock="Top" Margin="40,5,5,0"
<StackPanel DockPanel.Dock="Top" Margin="40,5,5,0"
IsEnabled="{Binding IsChecked, ElementName=CheckHumbleConnectAccount}">

<CheckBox Margin="0,10,0,0"
IsChecked="{Binding IgnoreRedeemedKeys}"
Content="Ignore Redeemed Keys"
ToolTip="When checked, Humble Keys Library does not import keys that have already been redeemed. (NOTE: Unchecking this and running a library sync will REMOVE prior imported games that have been redeemed)"/>
<CheckBox Margin="0,10,0,0"
IsChecked="{Binding ImportChoiceKeys}"
Content="Import Choice Games"
Name="ImportChoiceKeys"
ToolTip="When checked, Humble Keys Library will import Humble Choice games for months that the User is subscribed for." Unchecked="ImportChoiceKeys_OnUnchecked"/>
<StackPanel Margin="0 10 0 10" Width="Auto" Orientation="Horizontal">
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock
Name="TagWithBundleName"
Text="Create Tags for Bundle Names"
ToolTip="When None is not selected, Humble Keys Library will add a new Tag per Bundle Name"
Grid.Column="0"/>
<ListBox Margin="10 0 0 0 " Name="TagMethodology" SelectedValuePath="Tag" SelectedValue="{Binding CurrentTagMethodology, Mode=TwoWay}" Grid.Column="1" SelectionMode="Single">

<ListBoxItem Tag="none" ToolTip="Do not create Tags based on Bundle Name">None</ListBoxItem>
<ListBoxItem Tag="monthly" ToolTip="Create only Tags for Humble Choice Monthly bundles" IsEnabled="{Binding IsChecked,ElementName=ImportChoiceKeys}">
<ListBoxItem.Style>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Foreground" Value="White" />
<Style.Triggers>
</Style.Triggers>
</Style>
</ListBoxItem.Style>
Monthly Only
</ListBoxItem>
<ListBoxItem Tag="all" ToolTip="Create Tags for all Bundles">All</ListBoxItem>
</ListBox>
</Grid>
</StackPanel>
<StackPanel Margin="0 10 0 10" Width="Auto" Orientation="Horizontal">
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock
Name="UnredeemableKeyHandling"
Text="Unredeemable key handling"
ToolTip="If Tag is selected a new tag will replace the existing 'Key: Unredeemed' tag with 'Key: Unredeemable', if Delete is selected the game will be deleted from the library if it cannot be redeemed"
IsChecked="{Binding IgnoreRedeemedKeys}"
Content="Ignore Redeemed Keys"
ToolTip="When checked, Humble Keys Library does not import keys that have already been redeemed. (NOTE: Checking this and running a library sync will REMOVE prior imported games that have been redeemed)"/>
<CheckBox Margin="0,10,0,0" x:Name="CheckAddKeyStatus" IsChecked="{Binding AddKeyStatus}" Content="Add Key Redemption status Tag"/>
<Grid Margin="0 10 0 0" Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock
Name="RedemptionStoreLabel" VerticalAlignment="Center"
Text="Add Redemption Store to field:"
ToolTip="{DynamicResource LOCHumbleRedemptionStoreTip}"
Grid.Column="0"/>
<ComboBox Margin="10 0 0 0" Name="RedemptionStoreValues" SelectedValuePath="Tag" SelectedValue="{Binding RedemptionStore, Mode=TwoWay}"
Grid.Column="1" ToolTip="{DynamicResource LOCHumbleRedemptionStoreTip}">
<ComboBoxItem Tag="0" ToolTip="Don't add to any field">None</ComboBoxItem>
<ComboBoxItem Tag="1" ToolTip="Recommended">Source</ComboBoxItem>
<ComboBoxItem Tag="2">Tag</ComboBoxItem>
<ComboBoxItem Tag="3">Category</ComboBoxItem>
<ComboBoxItem Tag="4" ToolTip="Not recommended (may not work properly with some metadata add-ons; for backward compatibility)">Platform</ComboBoxItem>
</ComboBox>
</Grid>
<CheckBox Margin="0,10,0,0" x:Name="CheckAddLinks" IsChecked="{Binding AddLinks}" Content="{DynamicResource LOCHumbleAddLinks}"/>
<CheckBox Margin="0,10,0,0"
IsChecked="{Binding ImportChoiceKeys}"
Content="Import Choice Games"
Name="ImportChoiceKeys"
ToolTip="When checked, Humble Keys Library will import Humble Choice games for months that the User is subscribed for." Unchecked="ImportChoiceKeys_OnUnchecked"/>
<Grid Margin="0 10 0 0" Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock
Name="TagWithBundleNameLabel" VerticalAlignment="Center"
Text="Create Tags for Bundle Names:"
ToolTip="{DynamicResource LOCHumbleTagWithBundleTip}"
Grid.Column="0"/>
<ListBox Margin="10 0 0 0 " Name="UnredeemableKeyValues" SelectedValuePath="Tag" SelectedValue="{Binding CurrentUnredeemableMethodology, Mode=TwoWay}" Grid.Column="1" SelectionMode="Single">
<ListBoxItem Tag="tag" ToolTip="Create only Tags for games that cannot be redeemed">Tag</ListBoxItem>
<ListBoxItem Tag="delete" ToolTip="Delete games that cannot be redeemed">Delete</ListBoxItem>
</ListBox>
</Grid>
</StackPanel>
<ComboBox Margin="10 0 0 0" Name="TagMethodCombo" SelectedValuePath="Tag" SelectedValue="{Binding TagWithBundleName, Mode=TwoWay}"
Grid.Column="1" ToolTip="{DynamicResource LOCHumbleTagWithBundleTip}">
<ComboBoxItem Tag="0" ToolTip="Do not create Tags based on Bundle Name">None</ComboBoxItem>
<ComboBoxItem Tag="1" ToolTip="Create only Tags for Humble Choice Monthly bundles" IsEnabled="{Binding IsChecked,ElementName=ImportChoiceKeys}">
<ComboBoxItem.Style>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="Foreground" Value="White" />
<Style.Triggers>
</Style.Triggers>
</Style>
</ComboBoxItem.Style>
Monthly Only
</ComboBoxItem>
<ComboBoxItem Tag="2" ToolTip="Create Tags for all Bundles">All</ComboBoxItem>
</ComboBox>
</Grid>
<Grid Margin="0 10 0 0" Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock
Name="UnredeemableKeyHandlingLabel" VerticalAlignment="Center"
Text="Unredeemable key handling:"
ToolTip="{DynamicResource LOCHumbleUnredeemableKeyHandlingTip}"
Grid.Column="0"/>
<ComboBox Margin="10 0 0 0" Name="UnredeemableKeyValues" SelectedValuePath="Tag" SelectedValue="{Binding UnredeemableKeyHandling, Mode=TwoWay}"
Grid.Column="1" ToolTip="{DynamicResource LOCHumbleUnredeemableKeyHandlingTip}">
<ComboBoxItem Tag="0" ToolTip="Create only Tags for games that cannot be redeemed">Tag</ComboBoxItem>
<ComboBoxItem Tag="1" ToolTip="Delete games that cannot be redeemed">Delete</ComboBoxItem>
</ComboBox>
</Grid>
<CheckBox Margin="0,10,0,0"
IsChecked="{Binding CacheEnabled}"
Content="Enable Cache"
Name="EnableCache"
ToolTip="When checked, Humble Keys Library will create a persistent Cache in ExtensionsData directory, if a Cache entry exists, it will no longer be retrieved from Humble"/>
<StackPanel Orientation="Horizontal" Margin="0,10,0,0">
IsChecked="{Binding CacheEnabled}"
Content="Enable Cache"
Name="EnableCache"
ToolTip="When checked, Humble Keys Library will create a persistent Cache in ExtensionsData directory, if a Cache entry exists, it will no longer be retrieved from Humble"/>

<Label Content="Platform" Margin="0,20,0,5"/>
<Separator Margin="0,0,0,5" />
<CheckBox x:Name="CheckPlatformNintendo" IsChecked="{Binding AddPlatformNintendo}" Content="Add Nintendo Switch to all Nintendo keys"/>
<CheckBox Margin="0,10,0,0" x:Name="CheckPlatformWindows" IsChecked="{Binding AddPlatformWindows}" Content="Add PC (Windows) to all other keys (Recommended)"/>

<StackPanel Orientation="Horizontal" Margin="0,20,0,0">
<Button Content="{DynamicResource LOCHumbleAuthenticateLabel}" HorizontalAlignment="Left"
Command="{Binding LoginCommand}" Margin="0,5,5,5"/>
<TextBlock VerticalAlignment="Center" Margin="10,5,5,5">
Expand All @@ -102,8 +125,8 @@
</PriorityBinding>
</TextBlock.Tag>
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseTextBlockStyle}">
<Style.Triggers>
<Style TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseTextBlockStyle}">
<Style.Triggers>
<Trigger Property="Tag" Value="{StaticResource True}">
<Setter Property="Text" Value="{DynamicResource LOCHumbleLoggedIn}" />
</Trigger>
Expand Down
10 changes: 3 additions & 7 deletions HumbleKeysLibrarySettingsView.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,9 @@ private void LoadLocalizedResources()
void ImportChoiceKeys_OnUnchecked(object sender, RoutedEventArgs e)
{
if (!(DataContext is HumbleKeysLibrarySettings model)) return;
if (model.CurrentTagMethodology != "monthly") return;
model.CurrentTagMethodology = "none";
if (!(FindName("TagMethodology") is ListBox listBox)) return;
foreach (ListBoxItem listBoxItem in listBox.Items)
{
listBoxItem.IsSelected = (string)listBoxItem.Tag == model.CurrentTagMethodology;
}
if (model.TagWithBundleName != (int)TagMethodology.Monthly) return;
model.TagWithBundleName = (int)TagMethodology.None;
TagMethodCombo.SelectedValue = model.TagWithBundleName;
}
}
}
4 changes: 4 additions & 0 deletions Localization/en-US.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@
<sys:String x:Key="LOCHumbleNotLoggedIn">Requires authentication</sys:String>
<sys:String x:Key="LOCHumbleNotLoggedInError">Failed to authenticate user.</sys:String>
<sys:String x:Key="LOCHumbleAuthenticateLabel">Authenticate</sys:String>
<sys:String x:Key="LOCHumbleAddLinks">Add Humble &amp; Steam links</sys:String>
<sys:String x:Key="LOCHumbleRedemptionStoreTip">Add the store the key is for (e.g. Steam) to this field</sys:String>
<sys:String x:Key="LOCHumbleTagWithBundleTip">When None is not selected, Humble Keys Library will add a new Tag per Bundle Name</sys:String>
<sys:String x:Key="LOCHumbleUnredeemableKeyHandlingTip">If Tag is selected a new tag will replace the existing 'Key: Unredeemed' tag with 'Key: Unredeemable', if Delete is selected the game will be deleted from the library if it cannot be redeemed</sys:String>
</ResourceDictionary>
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Humble Keys Library
![DownloadCountTotal](https://img.shields.io/github/downloads/Dasmius007/HumbleKeysLibrary/total?label=Total%20Downloads&style=plastic)
![DownloadCountLatest](https://img.shields.io/github/downloads/Dasmius007/HumbleKeysLibrary/latest/total?label=Downloads@Latest&style=plastic)
![LatestVersion](https://img.shields.io/github/v/release/Dasmius007/HumbleKeysLibrary?label=Latest%20Version&style=plastic)
![BuildStatus](https://img.shields.io/github/actions/workflow/status/Dasmius007/HumbleKeysLibrary/generate_release_artifacts.yml?label=Build)
[![Build PEXT](https://github.com/Dasmius007/HumbleKeysLibrary/actions/workflows/msbuild.yml/badge.svg?event=push)](https://github.com/Dasmius007/HumbleKeysLibrary/actions/workflows/msbuild.yml)

# HumbleKeysLibrary
Humble Keys Library is a library plug-in extension for [Playnite](https://playnite.link/) which queries [Humble Bundle](https://www.humblebundle.com/) for third-party keys, and also supports Humble Choice subscription games.

The default Humble Library plug-in only reports DRM-free games, not the keys for third-party services like Steam. Humble Keys Library allows you to search your entire collection for a game, to make sure you don't buy a new copy in the latest sale if you already have one from a previous Humble Bundle.
Expand Down
10 changes: 10 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
## What's Changed
# 0.3.9
* IMPORTANT: Platform field is no longer used by default to store the Redemption Store, but now Source is (helps some metadata plugins properly match games)
* Added setting: Checkbox to add Key Redemption status Tag (default enabled)
* Added setting: Checkbox to "Add Humble & Steam links" (default enabled)
* Added setting: Checkbox to add "Nintendo Switch" to Platform for all Nintendo keys
* Added setting: Checkbox to add default of "PC (Windows)" to Platform for all other keys
* Added setting: Dropdown to add Redemption Store (e.g. "Humble Key: Steam") to choice of field: Source (now default), Tag, Category, Platform (no longer default), or None (disabled)
* Updated settings UI to be more compact and add the above features
* Fixed a couple misc. bugs related to key redemption tags and tag methodology

# 0.3.8
* Restored plugin name
* Restored plugin GUID to fix broken auto-update process from old versions, prevent duplicate old & new plugins installed at the same time, and ensure "Already installed" button works properly in Add-on Browser
Expand Down
Loading