├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── question.md │ ├── feature_request.md │ └── bug_report.md └── release.yml ├── .coderabbit.yaml ├── forum ├── main_01.jpg ├── main_02.jpg ├── control_01.jpg ├── settings_01.jpg ├── settings_02.jpg ├── settings_03.jpg └── settings_04.jpg ├── source ├── icon.png ├── Models │ ├── ItadShops.cs │ ├── CountData.cs │ ├── WishlistIgnore.cs │ ├── ItadGiveaway.cs │ ├── Api │ │ ├── ServiceShop.cs │ │ ├── GameLookup.cs │ │ ├── Giveaways.cs │ │ └── GamePrices.cs │ ├── ApiWebsite │ │ └── Country.cs │ ├── ItadGameInfo.cs │ ├── ItadNotificationCriteria.cs │ └── Wishlist.cs ├── extension.yaml ├── packages.config ├── Services │ ├── HumbleAccountClientExtend.cs │ ├── ItadViewSidebarcs.cs │ └── ItadTopPanelItem.cs ├── Properties │ └── AssemblyInfo.cs ├── Clients │ ├── GogWishlist.cs │ ├── EpicWishlist.cs │ ├── OriginWishlist.cs │ ├── UplayWishlist.cs │ ├── XboxWishlist.cs │ ├── HumbleBundleWishlist.cs │ ├── SteamWishlist.cs │ └── GenericWishlist.cs ├── IsThereAnyDeal.sln └── Localization │ ├── zh_CN.xaml │ ├── ja_JP.xaml │ ├── ar_SA.xaml │ ├── bg_BG.xaml │ ├── cs_CZ.xaml │ ├── da_DK.xaml │ ├── el_GR.xaml │ ├── en_US.xaml │ ├── et_EE.xaml │ ├── fa_IR.xaml │ ├── fi_FI.xaml │ ├── gl_ES.xaml │ ├── he_IL.xaml │ ├── hr_HR.xaml │ ├── id_ID.xaml │ ├── ko_KR.xaml │ ├── lt_LT.xaml │ └── nl_NL.xaml ├── crowdin.yml ├── screenshots ├── plugin_mainview.jpg ├── plugin_settings.jpg └── thumbs │ ├── plugin_mainview.jpg │ └── plugin_settings.jpg ├── .gitmodules ├── LICENSE ├── manifest └── Lacro59_IsThereAnyDeal.yaml ├── README.md └── .gitignore /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: lacro59 2 | -------------------------------------------------------------------------------- /.coderabbit.yaml: -------------------------------------------------------------------------------- 1 | ignored_branch: "l10n_master, l10n_devel" -------------------------------------------------------------------------------- /forum/main_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/forum/main_01.jpg -------------------------------------------------------------------------------- /forum/main_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/forum/main_02.jpg -------------------------------------------------------------------------------- /source/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/source/icon.png -------------------------------------------------------------------------------- /forum/control_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/forum/control_01.jpg -------------------------------------------------------------------------------- /forum/settings_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/forum/settings_01.jpg -------------------------------------------------------------------------------- /forum/settings_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/forum/settings_02.jpg -------------------------------------------------------------------------------- /forum/settings_03.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/forum/settings_03.jpg -------------------------------------------------------------------------------- /forum/settings_04.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/forum/settings_04.jpg -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | files: 2 | - source: LocSource.xaml 3 | translation: /%original_path%/%locale_with_underscore%.xaml 4 | -------------------------------------------------------------------------------- /screenshots/plugin_mainview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/screenshots/plugin_mainview.jpg -------------------------------------------------------------------------------- /screenshots/plugin_settings.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/screenshots/plugin_settings.jpg -------------------------------------------------------------------------------- /screenshots/thumbs/plugin_mainview.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/screenshots/thumbs/plugin_mainview.jpg -------------------------------------------------------------------------------- /screenshots/thumbs/plugin_settings.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lacro59/playnite-isthereanydeal-plugin/HEAD/screenshots/thumbs/plugin_settings.jpg -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question on project 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | --- 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "source/playnite-plugincommon"] 2 | path = source/playnite-plugincommon 3 | url = https://github.com/Lacro59/playnite-plugincommon.git 4 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | # .github/release.yml 2 | 3 | changelog: 4 | categories: 5 | - title: 'Fixed:' 6 | labels: 7 | - bug 8 | - title: 'Added:' 9 | labels: 10 | - enhancement 11 | - title: 'Other Changes:' 12 | labels: 13 | - "*" 14 | -------------------------------------------------------------------------------- /source/Models/ItadShops.cs: -------------------------------------------------------------------------------- 1 | namespace IsThereAnyDeal.Models 2 | { 3 | public class ItadShops 4 | { 5 | public string Id { get; set; } 6 | public string Title { get; set; } 7 | public string Color { get; set; } 8 | public bool IsCheck { get; set; } = false; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /source/Models/CountData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace IsThereAnyDeal.Models 8 | { 9 | public class CountData 10 | { 11 | public string StoreName { get; set; } 12 | public int Count { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen or implemented. 12 | 13 | **Screenshots** 14 | If applicable, add screenshots to help explain your problem. 15 | -------------------------------------------------------------------------------- /source/Models/WishlistIgnore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace IsThereAnyDeal.Models 8 | { 9 | public class WishlistIgnore 10 | { 11 | public string StoreId { get; set; } 12 | public string StoreName { get; set; } 13 | public string Id { get; set; } 14 | public string Name { get; set; } 15 | public string Slug { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /source/extension.yaml: -------------------------------------------------------------------------------- 1 | Id: playnite-isthereanydeal-plugin 2 | Name: IsThereAnyDeal 3 | Author: Lacro59 4 | Version: 3.3 5 | Module: IsThereAnyDeal.dll 6 | Type: GenericPlugin 7 | Icon: icon.png 8 | Links: 9 | - Name: Github 10 | Url: https://github.com/Lacro59/playnite-isthereanydeal-plugin 11 | - Name: Help and Troubleshooting 12 | Url: https://github.com/Lacro59/playnite-isthereanydeal-plugin/wiki 13 | - Name: Issues Tracker 14 | Url: https://github.com/Lacro59/playnite-isthereanydeal-plugin/issues 15 | - Name: Translate 16 | Url: https://crowdin.com/project/playnite-extensions 17 | - Name: Ko-fi (Tips and Donations) 18 | Url: https://ko-fi.com/lacro59 -------------------------------------------------------------------------------- /source/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **Extensions log** 23 | Attach Playnite's `Extensions.log` file. It is located in Playnite's installation directory in the portable version or in `%AppData%\Playnite` (Can be pasted in Explorer) in the installed version 24 | -------------------------------------------------------------------------------- /source/Models/ItadGiveaway.cs: -------------------------------------------------------------------------------- 1 | using IsThereAnyDeal.Services; 2 | using Playnite.SDK.Data; 3 | using System; 4 | 5 | namespace IsThereAnyDeal.Models 6 | { 7 | public class ItadGiveaway 8 | { 9 | public string TitleAll { get; set; } 10 | public string Title { get; set; } 11 | public DateTime? Time { get; set; } 12 | public string Link { get; set; } 13 | public int Count { get; set; } 14 | public string ShopName { get; set; } 15 | [DontSerialize] 16 | public string ShopColor => IsThereAnyDealApi.GetShopColor(ShopName); 17 | public bool HasSeen { get; set; } 18 | public bool InWaitlist { get; set; } 19 | public bool InCollection { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /source/Services/HumbleAccountClientExtend.cs: -------------------------------------------------------------------------------- 1 | using CommonPlayniteShared.PluginLibrary.HumbleLibrary.Services; 2 | using CommonPluginsShared; 3 | using Playnite.SDK; 4 | 5 | namespace IsThereAnyDeal.Services 6 | { 7 | public class HumbleAccountClientExtend : HumbleAccountClient 8 | { 9 | public HumbleAccountClientExtend(IWebView webView) : base(webView) 10 | { 11 | } 12 | 13 | public bool RemoveWishList(string storeId) 14 | { 15 | Common.LogDebug(true, $"Humble.RemoveWishList({storeId}) - {webView.GetPageSource()}"); 16 | string url = string.Format(@"https://www.humblebundle.com/wishlist/remove/{0}", storeId); 17 | webView.NavigateAndWait(url); 18 | return true; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /source/Models/Api/ServiceShop.cs: -------------------------------------------------------------------------------- 1 | using Playnite.SDK.Data; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace IsThereAnyDeal.Models.Api 9 | { 10 | public class ServiceShop 11 | { 12 | [SerializationPropertyName("id")] 13 | public int Id { get; set; } 14 | 15 | [SerializationPropertyName("title")] 16 | public string Title { get; set; } 17 | 18 | [SerializationPropertyName("deals")] 19 | public int Deals { get; set; } 20 | 21 | [SerializationPropertyName("games")] 22 | public int Games { get; set; } 23 | 24 | [SerializationPropertyName("update")] 25 | public DateTime? Update { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /source/Models/ApiWebsite/Country.cs: -------------------------------------------------------------------------------- 1 | using Playnite.SDK.Data; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace IsThereAnyDeal.Models.ApiWebsite 9 | { 10 | public class Country 11 | { 12 | [SerializationPropertyName("alpha2")] 13 | public string Alpha2 { get; set; } 14 | 15 | [SerializationPropertyName("alpha3")] 16 | public string Alpha3 { get; set; } 17 | 18 | [SerializationPropertyName("m49")] 19 | public string M49 { get; set; } 20 | 21 | [SerializationPropertyName("name")] 22 | public string Name { get; set; } 23 | 24 | [SerializationPropertyName("currency")] 25 | public string Currency { get; set; } 26 | 27 | [SerializationPropertyName("rCurrency")] 28 | public string RCurrency { get; set; } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /source/Models/ItadGameInfo.cs: -------------------------------------------------------------------------------- 1 | using IsThereAnyDeal.Services; 2 | using Playnite.SDK.Data; 3 | using System; 4 | 5 | namespace IsThereAnyDeal.Models 6 | { 7 | public class ItadGameInfo 8 | { 9 | public string Name { get; set; } 10 | public string Id { get; set; } 11 | public string Slug { get; set; } 12 | public string StoreId { get; set; } 13 | public Guid SourceId { get; set; } 14 | public double PriceNew { get; set; } 15 | public double PriceOld { get; set; } 16 | public double PriceCut { get; set; } 17 | public string CurrencySign { get; set; } 18 | public string ShopName { get; set; } 19 | [DontSerialize] 20 | public string ShopColor => IsThereAnyDealApi.GetShopColor(ShopName); 21 | public string UrlBuy { get; set; } 22 | 23 | [DontSerialize] 24 | public string UrlGame => string.Format("https://isthereanydeal.com/game/{0}/info/", Slug); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /source/Models/Api/GameLookup.cs: -------------------------------------------------------------------------------- 1 | using Playnite.SDK.Data; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace IsThereAnyDeal.Models.Api 9 | { 10 | public class GameLookup 11 | { 12 | [SerializationPropertyName("found")] 13 | public bool Found { get; set; } 14 | 15 | [SerializationPropertyName("game")] 16 | public Game Game { get; set; } 17 | } 18 | 19 | public class Game 20 | { 21 | [SerializationPropertyName("id")] 22 | public string Id { get; set; } 23 | 24 | [SerializationPropertyName("slug")] 25 | public string Slug { get; set; } 26 | 27 | [SerializationPropertyName("title")] 28 | public string Title { get; set; } 29 | 30 | [SerializationPropertyName("type")] 31 | public string Type { get; set; } 32 | 33 | [SerializationPropertyName("mature")] 34 | public bool Mature { get; set; } 35 | 36 | [SerializationPropertyName("assets")] 37 | public object Assets { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Lacro59 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /source/Models/ItadNotificationCriteria.cs: -------------------------------------------------------------------------------- 1 | using Playnite.SDK; 2 | using Playnite.SDK.Data; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | 8 | namespace IsThereAnyDeal.Models 9 | { 10 | public class ItadNotificationCriteria 11 | { 12 | public int PriceCut { get; set; } = -1; 13 | public int PriceInferior { get; set; } = -1; 14 | 15 | [DontSerialize] 16 | public string Criteria 17 | { 18 | get 19 | { 20 | string CriteriaString = string.Empty; 21 | 22 | if (PriceCut > -1) 23 | { 24 | CriteriaString = ResourceProvider.GetString("LOCItadLimitNotificationAt") + " " + PriceCut + " %"; 25 | } 26 | 27 | if (PriceInferior > -1) 28 | { 29 | if (CriteriaString.IsNullOrEmpty()) 30 | { 31 | CriteriaString = ResourceProvider.GetString("LOCItadLimitNotificationPriceAt") + " " + PriceInferior; 32 | } 33 | else 34 | { 35 | CriteriaString += " & " + ResourceProvider.GetString("LOCItadLimitNotificationPriceAt") + " " + PriceInferior; 36 | } 37 | } 38 | 39 | return CriteriaString; 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /source/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("IsThereAnyDeal")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("IsThereAnyDeal")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("7d5cbee9-3c86-4389-ac7b-9abe3da4c9cd")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /source/Services/ItadViewSidebarcs.cs: -------------------------------------------------------------------------------- 1 | using CommonPluginsShared.Controls; 2 | using IsThereAnyDeal.Views; 3 | using Playnite.SDK; 4 | using Playnite.SDK.Plugins; 5 | using System; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Windows.Controls; 9 | using System.Windows.Media; 10 | 11 | namespace IsThereAnyDeal.Services 12 | { 13 | public class ItadViewSidebar : SidebarItem 14 | { 15 | private static IResourceProvider ResourceProvider => new ResourceProvider(); 16 | private SidebarItemControl SidebarItemControl { get; set; } 17 | 18 | public ItadViewSidebar(IsThereAnyDeal plugin) 19 | { 20 | Type = SiderbarItemType.View; 21 | Title = ResourceProvider.GetString("LOCItad"); 22 | Icon = new TextBlock 23 | { 24 | Text = "\uea63", 25 | FontFamily = ResourceProvider.GetResource("CommonFont") as FontFamily 26 | }; 27 | Opened = () => 28 | { 29 | if (SidebarItemControl == null) 30 | { 31 | SidebarItemControl = new SidebarItemControl(); 32 | SidebarItemControl.SetTitle(ResourceProvider.GetString("LOCItad")); 33 | SidebarItemControl.AddContent(new IsThereAnyDealView(plugin)); 34 | } 35 | return SidebarItemControl; 36 | }; 37 | Visible = plugin.PluginSettings.Settings.EnableIntegrationButtonSide; 38 | } 39 | 40 | public void ResetView() 41 | { 42 | SidebarItemControl = null; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /source/Services/ItadTopPanelItem.cs: -------------------------------------------------------------------------------- 1 | using CommonPluginsShared; 2 | using IsThereAnyDeal.Views; 3 | using Playnite.SDK; 4 | using Playnite.SDK.Plugins; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows; 11 | using System.Windows.Controls; 12 | using System.Windows.Media; 13 | 14 | namespace IsThereAnyDeal.Services 15 | { 16 | public class ItadTopPanelItem : TopPanelItem 17 | { 18 | public ItadTopPanelItem(IsThereAnyDeal plugin) 19 | { 20 | Icon = new TextBlock 21 | { 22 | Text = "\uea63", 23 | FontSize = 22, 24 | FontFamily = ResourceProvider.GetResource("CommonFont") as FontFamily 25 | }; 26 | Title = ResourceProvider.GetString("LOCItad"); 27 | Activated = () => 28 | { 29 | WindowOptions windowOptions = new WindowOptions 30 | { 31 | ShowMinimizeButton = false, 32 | ShowMaximizeButton = false, 33 | ShowCloseButton = true, 34 | CanBeResizable = false, 35 | Width = 1180, 36 | Height = 720 37 | }; 38 | 39 | IsThereAnyDealView viewExtension = new IsThereAnyDealView(plugin); 40 | Window windowExtension = PlayniteUiHelper.CreateExtensionWindow(ResourceProvider.GetString("LOCItad"), viewExtension, windowOptions); 41 | _ = windowExtension.ShowDialog(); 42 | }; 43 | Visible = plugin.PluginSettings.Settings.EnableIntegrationButtonHeader; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /source/Models/Api/Giveaways.cs: -------------------------------------------------------------------------------- 1 | using Playnite.SDK.Data; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace IsThereAnyDeal.Models.Api 9 | { 10 | public class Counts 11 | { 12 | [SerializationPropertyName("games")] 13 | public int Games { get; set; } 14 | 15 | [SerializationPropertyName("waitlist")] 16 | public int Waitlist { get; set; } 17 | 18 | [SerializationPropertyName("collection")] 19 | public int Collection { get; set; } 20 | } 21 | 22 | public class Datum 23 | { 24 | [SerializationPropertyName("id")] 25 | public int Id { get; set; } 26 | 27 | [SerializationPropertyName("url")] 28 | public string Url { get; set; } 29 | 30 | [SerializationPropertyName("expiry")] 31 | public int? Expiry { get; set; } 32 | 33 | [SerializationPropertyName("publishAt")] 34 | public int PublishAt { get; set; } 35 | 36 | [SerializationPropertyName("isPending")] 37 | public bool IsPending { get; set; } 38 | 39 | [SerializationPropertyName("title")] 40 | public string Title { get; set; } 41 | 42 | [SerializationPropertyName("isMature")] 43 | public bool IsMature { get; set; } 44 | 45 | [SerializationPropertyName("shop")] 46 | public int Shop { get; set; } 47 | 48 | [SerializationPropertyName("counts")] 49 | public Counts Counts { get; set; } 50 | 51 | [SerializationPropertyName("games")] 52 | public List Games { get; set; } 53 | } 54 | 55 | public class Giveaways 56 | { 57 | [SerializationPropertyName("_id")] 58 | public int Id { get; set; } 59 | 60 | [SerializationPropertyName("offset")] 61 | public int Offset { get; set; } 62 | 63 | [SerializationPropertyName("done")] 64 | public bool Done { get; set; } 65 | 66 | [SerializationPropertyName("data")] 67 | public List Data { get; set; } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /source/Models/Api/GamePrices.cs: -------------------------------------------------------------------------------- 1 | using Playnite.SDK.Data; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace IsThereAnyDeal.Models.Api 9 | { 10 | public class GamePrices 11 | { 12 | [SerializationPropertyName("id")] 13 | public string Id { get; set; } 14 | 15 | [SerializationPropertyName("deals")] 16 | public List Deals { get; set; } 17 | } 18 | 19 | public class Deal 20 | { 21 | [SerializationPropertyName("shop")] 22 | public Element Shop { get; set; } 23 | 24 | [SerializationPropertyName("price")] 25 | public Price Price { get; set; } 26 | 27 | [SerializationPropertyName("regular")] 28 | public Price Regular { get; set; } 29 | 30 | [SerializationPropertyName("cut")] 31 | public int Cut { get; set; } 32 | 33 | [SerializationPropertyName("voucher")] 34 | public object Voucher { get; set; } 35 | 36 | [SerializationPropertyName("storeLow")] 37 | public Price StoreLow { get; set; } 38 | 39 | [SerializationPropertyName("historyLow")] 40 | public Price HistoryLow { get; set; } 41 | 42 | [SerializationPropertyName("flag")] 43 | public object Flag { get; set; } 44 | 45 | [SerializationPropertyName("drm")] 46 | public List Drm { get; set; } 47 | 48 | [SerializationPropertyName("platforms")] 49 | public List Platforms { get; set; } 50 | 51 | [SerializationPropertyName("timestamp")] 52 | public DateTime Timestamp { get; set; } 53 | 54 | [SerializationPropertyName("expiry")] 55 | public object Expiry { get; set; } 56 | 57 | [SerializationPropertyName("url")] 58 | public string Url { get; set; } 59 | } 60 | 61 | public class Element 62 | { 63 | [SerializationPropertyName("id")] 64 | public int Id { get; set; } 65 | 66 | [SerializationPropertyName("name")] 67 | public string Name { get; set; } 68 | } 69 | 70 | public class Price 71 | { 72 | [SerializationPropertyName("amount")] 73 | public double Amount { get; set; } 74 | 75 | [SerializationPropertyName("amountInt")] 76 | public int AmountInt { get; set; } 77 | 78 | [SerializationPropertyName("currency")] 79 | public string Currency { get; set; } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /source/Clients/GogWishlist.cs: -------------------------------------------------------------------------------- 1 | using IsThereAnyDeal.Models; 2 | using Playnite.SDK; 3 | using CommonPluginsShared; 4 | using System; 5 | using System.Collections.Generic; 6 | using IsThereAnyDeal.Models.Api; 7 | using CommonPluginsStores.Gog; 8 | using CommonPluginsStores.Models; 9 | using System.Collections.ObjectModel; 10 | 11 | namespace IsThereAnyDeal.Services 12 | { 13 | public class GogWishlist : GenericWishlist 14 | { 15 | private static GogApi GogApi => IsThereAnyDeal.GogApi; 16 | 17 | 18 | public GogWishlist(IsThereAnyDeal plugin) : base(plugin, "GOG") 19 | { 20 | ExternalPlugin = PlayniteTools.ExternalPlugin.GogLibrary; 21 | } 22 | 23 | internal override List GetStoreWishlist(List cachedData) 24 | { 25 | Logger.Info($"Load data from web for {ClientName}"); 26 | 27 | if (!GogApi.IsUserLoggedIn) 28 | { 29 | Logger.Warn($"{ClientName}: Not authenticated"); 30 | API.Instance.Notifications.Add(new NotificationMessage( 31 | $"IsThereAnyDeal-{ClientName}-NotAuthenticate", 32 | "IsThereAnyDeal" + Environment.NewLine 33 | + string.Format(ResourceProvider.GetString("LOCCommonStoresNoAuthenticate"), ClientName), 34 | NotificationType.Error, 35 | () => PlayniteTools.ShowPluginSettings(ExternalPlugin) 36 | )); 37 | 38 | return cachedData; 39 | } 40 | 41 | IsThereAnyDealApi isThereAnyDealApi = new IsThereAnyDealApi(); 42 | List wishlists = new List(); 43 | ObservableCollection accountWishlist = GogApi.GetWishlist(GogApi.CurrentAccountInfos); 44 | 45 | accountWishlist.ForEach(x => 46 | { 47 | try 48 | { 49 | GameLookup gamesLookup = isThereAnyDealApi.GetGamesLookup(x.Name).GetAwaiter().GetResult(); 50 | wishlists.Add(new Wishlist 51 | { 52 | StoreId = x.Id, 53 | StoreName = "GOG", 54 | ShopColor = GetShopColor(), 55 | StoreUrl = x.Link, 56 | Name = x.Name, 57 | SourceId = PlayniteTools.GetPluginId(ExternalPlugin), 58 | ReleaseDate = x.Released, 59 | Added = x.Added, 60 | Capsule = x.Image, 61 | Game = (gamesLookup?.Found ?? false) ? gamesLookup.Game : null, 62 | IsActive = true 63 | }); 64 | } 65 | catch (Exception ex) 66 | { 67 | Common.LogError(ex, false, true, "IsThereAnyDeal"); 68 | } 69 | }); 70 | 71 | wishlists = SetCurrentPrice(wishlists, false); 72 | SaveWishlist(wishlists); 73 | return wishlists; 74 | } 75 | 76 | public override bool RemoveWishlist(string storeId) 77 | { 78 | return GogApi.RemoveWishlist(storeId); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /source/Clients/EpicWishlist.cs: -------------------------------------------------------------------------------- 1 | using Playnite.SDK; 2 | using IsThereAnyDeal.Models; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using CommonPluginsShared; 7 | using IsThereAnyDeal.Models.Api; 8 | using CommonPluginsStores.Epic; 9 | using System.Collections.ObjectModel; 10 | using CommonPluginsStores.Models; 11 | 12 | namespace IsThereAnyDeal.Services 13 | { 14 | public class EpicWishlist : GenericWishlist 15 | { 16 | private static EpicApi EpicApi => IsThereAnyDeal.EpicApi; 17 | 18 | 19 | public EpicWishlist(IsThereAnyDeal plugin) : base(plugin, "Epic") 20 | { 21 | ExternalPlugin = PlayniteTools.ExternalPlugin.EpicLibrary; 22 | } 23 | 24 | internal override List GetStoreWishlist(List cachedData) 25 | { 26 | Logger.Info($"Load data from web for {ClientName}"); 27 | 28 | if (!EpicApi.IsUserLoggedIn) 29 | { 30 | Logger.Warn($"{ClientName}: Not authenticated"); 31 | API.Instance.Notifications.Add(new NotificationMessage( 32 | $"IsThereAnyDeal-{ClientName}-NotAuthenticate", 33 | "IsThereAnyDeal" + Environment.NewLine 34 | + string.Format(ResourceProvider.GetString("LOCCommonStoresNoAuthenticate"), ClientName), 35 | NotificationType.Error, 36 | () => PlayniteTools.ShowPluginSettings(ExternalPlugin) 37 | )); 38 | 39 | return cachedData; 40 | } 41 | 42 | IsThereAnyDealApi isThereAnyDealApi = new IsThereAnyDealApi(); 43 | List wishlists = new List(); 44 | ObservableCollection accountWishlist = EpicApi.GetWishlist(EpicApi.CurrentAccountInfos); 45 | 46 | accountWishlist.ForEach(x => 47 | { 48 | try 49 | { 50 | GameLookup gamesLookup = isThereAnyDealApi.GetGamesLookup(x.Name).GetAwaiter().GetResult(); 51 | wishlists.Add(new Wishlist 52 | { 53 | StoreId = x.Id, 54 | StoreName = "Epic", 55 | ShopColor = GetShopColor(), 56 | StoreUrl = x.Link, 57 | Name = x.Name, 58 | SourceId = PlayniteTools.GetPluginId(ExternalPlugin), 59 | ReleaseDate = x.Released, 60 | Added = x.Added, 61 | Capsule = x.Image, 62 | Game = (gamesLookup?.Found ?? false) ? gamesLookup.Game : null, 63 | IsActive = true 64 | }); 65 | } 66 | catch (Exception ex) 67 | { 68 | Common.LogError(ex, false, true, "IsThereAnyDeal"); 69 | } 70 | }); 71 | 72 | wishlists = SetCurrentPrice(wishlists, false); 73 | SaveWishlist(wishlists); 74 | return wishlists; 75 | } 76 | 77 | public override bool RemoveWishlist(string storeId) 78 | { 79 | return EpicApi.RemoveWishlist(storeId); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /manifest/Lacro59_IsThereAnyDeal.yaml: -------------------------------------------------------------------------------- 1 | AddonId: playnite-isthereanydeal-plugin 2 | Packages: 3 | - Version: 2.0 4 | RequiredApiVersion: 6.1.0 5 | ReleaseDate: 2021-10-22 6 | PackageUrl: https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/download/v2.0/playnite-isthereanydeal-plugin_2_0.pext 7 | Changelog: 8 | - Playnite 9 version 9 | - Version: 2.1 10 | RequiredApiVersion: 6.1.0 11 | ReleaseDate: 2021-11-23 12 | PackageUrl: https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/download/v2.1/playnite-isthereanydeal-plugin_2_1.pext 13 | Changelog: 14 | - Updated localizations 15 | - Fixed wish lists download 16 | - Fixed notification system 17 | - Added options to add header and sidebar button 18 | - Fixed issue on large wish list 19 | - Version: 2.1.1 20 | RequiredApiVersion: 6.2.0 21 | ReleaseDate: 2021-11-30 22 | PackageUrl: https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/download/v2.1.1/playnite-isthereanydeal-plugin_2_1_1.pext 23 | Changelog: 24 | - Fixed a crash 25 | - Fixed FullScreen issue 26 | - Fixed minors bugs 27 | - Version: 2.2 28 | RequiredApiVersion: 6.2.2 29 | ReleaseDate: 2022-02-02 30 | PackageUrl: https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/download/v2.2/playnite-isthereanydeal-plugin_2_2.pext 31 | Changelog: 32 | - Updated localizations 33 | - Ignore empty data from ITAD 34 | - Fixed minors bugs 35 | - Fixed missing ITAG regions 36 | - Added new filters options in ITAD view 37 | - Optimized data loading 38 | - Version: 3.0 39 | RequiredApiVersion: 6.5.0 40 | ReleaseDate: 2022-10-04 41 | PackageUrl: https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/download/v3.0/playnite-isthereanydeal-plugin_3_0.pext 42 | Changelog: 43 | - Playnite 10 only 44 | - Updated localizations 45 | - Version: 3.1 46 | RequiredApiVersion: 6.8.0 47 | ReleaseDate: 2022-10-04 48 | PackageUrl: https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/download/v3.1/playnite-isthereanydeal-plugin_3_1.pext 49 | Changelog: 50 | - Added Ubisoft wishlist 51 | - Updated localizations 52 | - Updated store name 53 | - Minors optimizations 54 | - Version: 3.2 55 | RequiredApiVersion: 6.11.0 56 | ReleaseDate: 2024-02-26 57 | PackageUrl: https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/download/v3.2/playnite-isthereanydeal-plugin_3_2.pext 58 | Changelog: 59 | - Updated localizations 60 | - Used new ITAD api 61 | - Fixed issue with filters 62 | - Fixed issue on price 63 | - UI optimizations (thanks to SparrowBrain) 64 | - Fixed issues on stores wishlist 65 | - Fixed crashes 66 | - Fixed minors bugs 67 | - Version: 3.2.1 68 | RequiredApiVersion: 6.11.0 69 | ReleaseDate: 2024-02-27 70 | PackageUrl: https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/download/v3.2.1/playnite-isthereanydeal-plugin_3_2_1.pext 71 | Changelog: 72 | - Updated localizations 73 | - Fixed issues to authenticate with Steam 74 | - Version: 3.3 75 | RequiredApiVersion: 6.11.0 76 | ReleaseDate: 2025-02-24 77 | PackageUrl: https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/download/v3.3/playnite-isthereanydeal-plugin_3_3.pext 78 | Changelog: 79 | - 'Updated: Localizations' 80 | - 'Fixed: Missing give away tab' 81 | - 'Fixed: Issue with Uplay wishlist' 82 | - 'Fixed: Issue with Steam wishlist' 83 | - 'Updated: ITAD api' 84 | - 'Added: Options for background updates' -------------------------------------------------------------------------------- /source/Clients/OriginWishlist.cs: -------------------------------------------------------------------------------- 1 | using IsThereAnyDeal.Models; 2 | using IsThereAnyDeal.Services; 3 | using Playnite.SDK; 4 | using CommonPluginsShared; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using IsThereAnyDeal.Models.Api; 10 | using System.Collections.ObjectModel; 11 | using CommonPluginsStores.Models; 12 | using CommonPluginsStores.Origin; 13 | 14 | namespace IsThereAnyDeal.Clients 15 | { 16 | public class OriginWishlist : GenericWishlist 17 | { 18 | protected static OriginApi _originApi; 19 | internal static OriginApi OriginApi 20 | { 21 | get 22 | { 23 | if (_originApi == null) 24 | { 25 | _originApi = new OriginApi("IsTeherAnyDeals"); 26 | } 27 | return _originApi; 28 | } 29 | 30 | set => _originApi = value; 31 | } 32 | 33 | 34 | public OriginWishlist(IsThereAnyDeal plugin) : base(plugin, "Origin") 35 | { 36 | ExternalPlugin = PlayniteTools.ExternalPlugin.OriginLibrary; 37 | } 38 | 39 | internal override List GetStoreWishlist(List cachedData) 40 | { 41 | Logger.Info($"Load data from web for {ClientName}"); 42 | 43 | if (!OriginApi.IsUserLoggedIn) 44 | { 45 | Logger.Warn($"{ClientName}: Not authenticated"); 46 | API.Instance.Notifications.Add(new NotificationMessage( 47 | $"IsThereAnyDeal-{ClientName}-NotAuthenticate", 48 | "IsThereAnyDeal" + Environment.NewLine 49 | + string.Format(ResourceProvider.GetString("LOCCommonStoresNoAuthenticate"), ClientName), 50 | NotificationType.Error, 51 | () => PlayniteTools.ShowPluginSettings(ExternalPlugin) 52 | )); 53 | 54 | return cachedData; 55 | } 56 | 57 | IsThereAnyDealApi isThereAnyDealApi = new IsThereAnyDealApi(); 58 | List wishlists = new List(); 59 | ObservableCollection accountWishlist = OriginApi.GetWishlist(OriginApi.CurrentAccountInfos); 60 | 61 | accountWishlist.ForEach(x => 62 | { 63 | try 64 | { 65 | GameLookup gamesLookup = isThereAnyDealApi.GetGamesLookup(x.Name).GetAwaiter().GetResult(); 66 | wishlists.Add(new Wishlist 67 | { 68 | StoreId = x.Id, 69 | StoreName = "EA app", 70 | ShopColor = GetShopColor(), 71 | StoreUrl = x.Link, 72 | Name = x.Name, 73 | SourceId = PlayniteTools.GetPluginId(ExternalPlugin), 74 | ReleaseDate = x.Released, 75 | Added = x.Added, 76 | Capsule = x.Image, 77 | Game = (gamesLookup?.Found ?? false) ? gamesLookup.Game : null, 78 | IsActive = true 79 | }); 80 | } 81 | catch (Exception ex) 82 | { 83 | Common.LogError(ex, false, true, "IsThereAnyDeal"); 84 | } 85 | }); 86 | 87 | wishlists = SetCurrentPrice(wishlists, false); 88 | SaveWishlist(wishlists); 89 | return wishlists; 90 | } 91 | 92 | public override bool RemoveWishlist(string storeId) 93 | { 94 | return OriginApi.RemoveWishlist(storeId); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /source/Clients/UplayWishlist.cs: -------------------------------------------------------------------------------- 1 | using AngleSharp.Dom; 2 | using AngleSharp.Dom.Html; 3 | using AngleSharp.Parser.Html; 4 | using CommonPluginsShared; 5 | using IsThereAnyDeal.Models; 6 | using IsThereAnyDeal.Models.Api; 7 | using IsThereAnyDeal.Services; 8 | using Playnite.SDK; 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using System.Text; 13 | 14 | namespace IsThereAnyDeal.Clients 15 | { 16 | public class UplayWishlist : GenericWishlist 17 | { 18 | public UplayWishlist(IsThereAnyDeal plugin) : base(plugin, "Ubisoft") 19 | { 20 | ExternalPlugin = PlayniteTools.ExternalPlugin.UplayLibrary; 21 | } 22 | 23 | internal override List GetStoreWishlist(List cachedData) 24 | { 25 | Logger.Info($"Load data from web for {ClientName}"); 26 | 27 | if (Settings.UbisoftLink.IsNullOrEmpty()) 28 | { 29 | Logger.Error($"{ClientName}: No url"); 30 | API.Instance.Notifications.Add(new NotificationMessage( 31 | $"IsThereAnyDeal-{ClientName}-Url", 32 | "IsThereAnyDeal" + Environment.NewLine 33 | + string.Format(ResourceProvider.GetString("LOCCommonStoreBadConfiguration"), ClientName), 34 | NotificationType.Error, 35 | () => Plugin.OpenSettingsView() 36 | )); 37 | 38 | return cachedData; 39 | } 40 | 41 | List wishlists = new List(); 42 | 43 | // Get wishlist 44 | string response = Web.DownloadStringData(Settings.UbisoftLink).GetAwaiter().GetResult(); 45 | 46 | if (!response.IsNullOrEmpty()) 47 | { 48 | HtmlParser parser = new HtmlParser(); 49 | IHtmlDocument HtmlRequirement = parser.Parse(response); 50 | 51 | IsThereAnyDealApi isThereAnyDealApi = new IsThereAnyDealApi(); 52 | foreach (IElement searchElement in HtmlRequirement.QuerySelectorAll(".wishlist-items-list li")) 53 | { 54 | string storeId = string.Empty; 55 | string name = string.Empty; 56 | DateTime releaseDate = default; 57 | string capsule = string.Empty; 58 | 59 | storeId = searchElement.QuerySelector("div.product-tile").GetAttribute("data-itemid"); 60 | capsule = searchElement.QuerySelector("img").GetAttribute("data-src"); 61 | name = searchElement.QuerySelector("div.card-title div.prod-title").InnerHtml.Trim(); 62 | 63 | GameLookup gamesLookup = isThereAnyDealApi.GetGamesLookup(name).GetAwaiter().GetResult(); 64 | 65 | wishlists.Add(new Wishlist 66 | { 67 | StoreId = storeId.Trim(), 68 | StoreName = "Ubisoft Connect", 69 | ShopColor = GetShopColor(), 70 | StoreUrl = @"https://store.ubi.com/fr/game?pid=" + storeId.Trim(), 71 | Name = name.Trim(), 72 | SourceId = PlayniteTools.GetPluginId(ExternalPlugin), 73 | ReleaseDate = releaseDate.ToUniversalTime(), 74 | Capsule = capsule.Trim(), 75 | Game = (gamesLookup?.Found ?? false) ? gamesLookup.Game : null, 76 | IsActive = true 77 | }); 78 | } 79 | } 80 | else 81 | { 82 | return cachedData; 83 | } 84 | 85 | wishlists = SetCurrentPrice(wishlists, false); 86 | SaveWishlist(wishlists); 87 | return wishlists; 88 | } 89 | 90 | public override bool RemoveWishlist(string storeId) 91 | { 92 | return false; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /source/Clients/XboxWishlist.cs: -------------------------------------------------------------------------------- 1 | using IsThereAnyDeal.Models; 2 | using IsThereAnyDeal.Services; 3 | using Playnite.SDK; 4 | using CommonPluginsShared; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using IsThereAnyDeal.Models.Api; 10 | using System.Collections.ObjectModel; 11 | using CommonPluginsStores.Models; 12 | using CommonPluginsStores.Xbox; 13 | 14 | namespace IsThereAnyDeal.Clients 15 | { 16 | public class XboxWishlist : GenericWishlist 17 | { 18 | protected static XboxApi _xboxApi; 19 | internal static XboxApi XboxApi 20 | { 21 | get 22 | { 23 | if (_xboxApi == null) 24 | { 25 | _xboxApi = new XboxApi("IsThereAnyDeals"); 26 | } 27 | return _xboxApi; 28 | } 29 | 30 | set => _xboxApi = value; 31 | } 32 | 33 | 34 | public XboxWishlist(IsThereAnyDeal plugin) : base(plugin, "Xbox") 35 | { 36 | ExternalPlugin = PlayniteTools.ExternalPlugin.XboxLibrary; 37 | } 38 | 39 | internal override List GetStoreWishlist(List cachedData) 40 | { 41 | Logger.Info($"Load data from web for {ClientName}"); 42 | 43 | if (Settings.XboxLink.IsNullOrEmpty() 44 | && !Settings.XboxLink.StartsWith("https://www.microsoft.com/", StringComparison.InvariantCultureIgnoreCase) 45 | && !Settings.XboxLink.Contains("wishlist?id=", StringComparison.InvariantCultureIgnoreCase)) 46 | { 47 | Logger.Error($"{ClientName}: No url"); 48 | API.Instance.Notifications.Add(new NotificationMessage( 49 | $"IsThereAnyDeal-{ClientName}-Url", 50 | "IsThereAnyDeal" + Environment.NewLine 51 | + string.Format(ResourceProvider.GetString("LOCCommonStoreBadConfiguration"), ClientName), 52 | NotificationType.Error, 53 | () => Plugin.OpenSettingsView() 54 | )); 55 | 56 | return cachedData; 57 | } 58 | 59 | IsThereAnyDealApi isThereAnyDealApi = new IsThereAnyDealApi(); 60 | List wishlists = new List(); 61 | ObservableCollection accountWishlist = XboxApi.GetWishlist(new AccountInfos { Link = Settings.XboxLink }); 62 | 63 | accountWishlist.ForEach(x => 64 | { 65 | try 66 | { 67 | GameLookup gamesLookup = isThereAnyDealApi.GetGamesLookup(x.Name).GetAwaiter().GetResult(); 68 | wishlists.Add(new Wishlist 69 | { 70 | StoreId = x.Id, 71 | StoreName = "Microsoft Store", 72 | ShopColor = GetShopColor(), 73 | StoreUrl = x.Link, 74 | Name = x.Name, 75 | SourceId = PlayniteTools.GetPluginId(ExternalPlugin), 76 | ReleaseDate = x.Released, 77 | Added = x.Added, 78 | Capsule = x.Image, 79 | Game = (gamesLookup?.Found ?? false) ? gamesLookup.Game : null, 80 | IsActive = true 81 | }); 82 | } 83 | catch (Exception ex) 84 | { 85 | Common.LogError(ex, false, true, "IsThereAnyDeal"); 86 | } 87 | }); 88 | 89 | wishlists = SetCurrentPrice(wishlists, false); 90 | SaveWishlist(wishlists); 91 | return wishlists; 92 | } 93 | 94 | public override bool RemoveWishlist(string storeId) 95 | { 96 | return false; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /source/IsThereAnyDeal.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.35706.149 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IsThereAnyDeal", "IsThereAnyDeal.csproj", "{4FDF1E89-5BC3-4C72-8FDA-0D580E7A5D5F}" 7 | EndProject 8 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CommonPlayniteShared", "playnite-plugincommon\CommonPlayniteShared\CommonPlayniteShared.shproj", "{0D7DBC82-26AF-49AD-8ED5-0E11AA56BCE0}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonPluginsResources", "playnite-plugincommon\CommonPluginsResources\CommonPluginsResources.csproj", "{4EFFE926-9C64-4750-A399-F344710EDC09}" 11 | EndProject 12 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CommonPluginsShared", "playnite-plugincommon\CommonPluginsShared\CommonPluginsShared.shproj", "{27E5D35B-F3CE-4A3F-9705-4564674615A5}" 13 | EndProject 14 | Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CommonPluginsStores", "playnite-plugincommon\CommonPluginsStores\CommonPluginsStores.shproj", "{C066F255-3BFA-4862-A490-09D7933647D4}" 15 | EndProject 16 | Global 17 | GlobalSection(SharedMSBuildProjectFiles) = preSolution 18 | playnite-plugincommon\CommonPlayniteShared\CommonPlayniteShared.projitems*{0d7dbc82-26af-49ad-8ed5-0e11aa56bce0}*SharedItemsImports = 13 19 | playnite-plugincommon\CommonPluginsShared\CommonPluginsShared.projitems*{27e5d35b-f3ce-4a3f-9705-4564674615a5}*SharedItemsImports = 13 20 | playnite-plugincommon\CommonPlayniteShared\CommonPlayniteShared.projitems*{4fdf1e89-5bc3-4c72-8fda-0d580e7a5d5f}*SharedItemsImports = 4 21 | playnite-plugincommon\CommonPluginsShared\CommonPluginsShared.projitems*{4fdf1e89-5bc3-4c72-8fda-0d580e7a5d5f}*SharedItemsImports = 4 22 | playnite-plugincommon\CommonPluginsStores\CommonPluginsStores.projitems*{4fdf1e89-5bc3-4c72-8fda-0d580e7a5d5f}*SharedItemsImports = 4 23 | playnite-plugincommon\CommonPluginsStores\CommonPluginsStores.projitems*{c066f255-3bfa-4862-a490-09d7933647d4}*SharedItemsImports = 13 24 | EndGlobalSection 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | DebugFS|Any CPU = DebugFS|Any CPU 28 | Debug-Release|Any CPU = Debug-Release|Any CPU 29 | Release|Any CPU = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 32 | {4FDF1E89-5BC3-4C72-8FDA-0D580E7A5D5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {4FDF1E89-5BC3-4C72-8FDA-0D580E7A5D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {4FDF1E89-5BC3-4C72-8FDA-0D580E7A5D5F}.DebugFS|Any CPU.ActiveCfg = DebugFS|Any CPU 35 | {4FDF1E89-5BC3-4C72-8FDA-0D580E7A5D5F}.DebugFS|Any CPU.Build.0 = DebugFS|Any CPU 36 | {4FDF1E89-5BC3-4C72-8FDA-0D580E7A5D5F}.Debug-Release|Any CPU.ActiveCfg = Debug-Release|Any CPU 37 | {4FDF1E89-5BC3-4C72-8FDA-0D580E7A5D5F}.Debug-Release|Any CPU.Build.0 = Debug-Release|Any CPU 38 | {4FDF1E89-5BC3-4C72-8FDA-0D580E7A5D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {4FDF1E89-5BC3-4C72-8FDA-0D580E7A5D5F}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {4EFFE926-9C64-4750-A399-F344710EDC09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {4EFFE926-9C64-4750-A399-F344710EDC09}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {4EFFE926-9C64-4750-A399-F344710EDC09}.DebugFS|Any CPU.ActiveCfg = DebugFS|Any CPU 43 | {4EFFE926-9C64-4750-A399-F344710EDC09}.DebugFS|Any CPU.Build.0 = DebugFS|Any CPU 44 | {4EFFE926-9C64-4750-A399-F344710EDC09}.Debug-Release|Any CPU.ActiveCfg = Debug-Release|Any CPU 45 | {4EFFE926-9C64-4750-A399-F344710EDC09}.Debug-Release|Any CPU.Build.0 = Debug-Release|Any CPU 46 | {4EFFE926-9C64-4750-A399-F344710EDC09}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {4EFFE926-9C64-4750-A399-F344710EDC09}.Release|Any CPU.Build.0 = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | GlobalSection(ExtensibilityGlobals) = postSolution 53 | SolutionGuid = {28C74630-4FA2-4DBB-8982-0DC70C9AB164} 54 | EndGlobalSection 55 | EndGlobal 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Crowdin](https://badges.crowdin.net/playnite-extensions/localized.svg)](https://crowdin.com/project/playnite-extensions) 2 | [![GitHub release (latest by date)](https://img.shields.io/github/v/release/Lacro59/playnite-isthereanydeal-plugin?cacheSeconds=5000&logo=github)](https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/latest) 3 | [![GitHub Release Date](https://img.shields.io/github/release-date/Lacro59/playnite-isthereanydeal-plugin?cacheSeconds=5000)](https://github.com/Lacro59/playnite-isthereanydeal-plugin/releases/latest) 4 | [![Github Lastest Releases](https://img.shields.io/github/downloads/Lacro59/playnite-isthereanydeal-plugin/latest/total.svg)]() 5 | [![GitHub commit activity](https://img.shields.io/github/commit-activity/m/Lacro59/playnite-isthereanydeal-plugin)](https://github.com/Lacro59/playnite-isthereanydeal-plugin/graphs/commit-activity) 6 | [![GitHub contributors](https://img.shields.io/github/contributors/Lacro59/playnite-isthereanydeal-plugin?cacheSeconds=5000)](https://github.com/Lacro59/playnite-isthereanydeal-plugin/graphs/contributors) 7 | [![GitHub](https://img.shields.io/github/license/Lacro59/playnite-isthereanydeal-plugin?cacheSeconds=50000)](https://github.com/Lacro59/playnite-isthereanydeal-plugin/blob/master/LICENSE) 8 | 9 | # playnite-isthereanydeal-plugin 10 | Extension for [Playnite](https://playnite.link). 11 | 12 | ## Informations 13 | This plugin gets [IsThereAnyDeal](https://isthereanydeal.com) data in application database from stores wishlist. 14 | The plugin is a alternative version to [bburky](https://github.com/bburky/isthereanydeal-playnite). 15 | 16 | 17 | 18 | main_01 19 | 20 | 21 | 22 | 23 | main_01 24 | 25 | 26 | 27 | 28 | steamgriddb_01 29 | 30 | 31 | 32 | 33 | settings_01 34 | 35 | 36 | 37 | 38 | settings_01 39 | 40 | 41 | 42 | 43 | settings_01 44 | 45 | 46 | 47 | 48 | settings_01 49 | 50 | 51 | 52 | With this plugin you can 53 | * get whislit from Steam, GOG, Epic Game Store, Humble Bundle, Oringin and Xbox 54 | * manual Steam whislit import 55 | * remove a game in your wish list for GOG, Epci Game Store and Origin 56 | * show best price for different game in wishlit 57 | * notification when percent reduc is above limit defined 58 | * show giveaways 59 | * notification for new giveaways 60 | 61 | ## Translations 62 | You can help to translate the extensions do different languages via the project [Crowdin](https://crowdin.com/project/playnite-extensions) page. 63 | 64 | ## More 65 | Remember to support [Playnite](https://www.patreon.com/playnite) and [IsThereAnyDeal](https://isthereanydeal.com). 66 | Buy Me a Coffee at ko-fi.com 67 | -------------------------------------------------------------------------------- /source/Clients/HumbleBundleWishlist.cs: -------------------------------------------------------------------------------- 1 | using Playnite.SDK; 2 | using Playnite.SDK.Data; 3 | using IsThereAnyDeal.Models; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Net; 8 | using CommonPluginsShared; 9 | using IsThereAnyDeal.Models.Api; 10 | 11 | namespace IsThereAnyDeal.Services 12 | { 13 | public class HumbleBundleWishlist : GenericWishlist 14 | { 15 | public HumbleBundleWishlist(IsThereAnyDeal plugin) : base(plugin, "HumbleBundle") 16 | { 17 | ExternalPlugin = PlayniteTools.ExternalPlugin.HumbleLibrary; 18 | } 19 | 20 | internal override List GetStoreWishlist(List cachedData) 21 | { 22 | Logger.Info($"Load data from web for {ClientName}"); 23 | 24 | if (Settings.HumbleKey.IsNullOrEmpty()) 25 | { 26 | Logger.Error($"{ClientName}: No key"); 27 | API.Instance.Notifications.Add(new NotificationMessage( 28 | $"IsThereAnyDeal-{ClientName}-Key", 29 | "IsThereAnyDeal" + Environment.NewLine 30 | + string.Format(ResourceProvider.GetString("LOCCommonStoreBadConfiguration"), ClientName), 31 | NotificationType.Error, 32 | () => Plugin.OpenSettingsView() 33 | )); 34 | 35 | return cachedData; 36 | } 37 | 38 | List wishlists = new List(); 39 | string resultWeb = string.Empty; 40 | string url = string.Format(@"https://www.humblebundle.com/store/wishlist/{0}", Settings.HumbleKey); 41 | 42 | resultWeb = Web.DownloadStringData(url).GetAwaiter().GetResult(); 43 | if (!resultWeb.IsNullOrEmpty()) 44 | { 45 | int startSub = resultWeb.IndexOf(""); 54 | resultWeb = resultWeb.Substring(0, endSub); 55 | 56 | resultWeb = resultWeb.Replace("