Skip to content

Commit

Permalink
Added Epic as a link source
Browse files Browse the repository at this point in the history
  • Loading branch information
HerrKnarz committed Nov 1, 2022
1 parent af25d08 commit 13292e2
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 6 deletions.
3 changes: 3 additions & 0 deletions Source/LinkUtilities.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
Expand All @@ -59,6 +60,7 @@
<Compile Include="Linker\ILink.cs" />
<Compile Include="Linker\Link.cs" />
<Compile Include="Linker\LinkAndLibrary.cs" />
<Compile Include="Linker\LinkSources\LinkEpic.cs" />
<Compile Include="Linker\LinkSources\LinkMetacritic.cs" />
<Compile Include="Linker\LinkSources\LinkHG101.cs" />
<Compile Include="Linker\LinkSources\LinkMobyGames.cs" />
Expand All @@ -71,6 +73,7 @@
<Compile Include="Linker\Links.cs" />
<Compile Include="Linker\LinkSources\LinkWikipedia.cs" />
<Compile Include="Logging.cs" />
<Compile Include="Models\EpicSearchResult.cs" />
<Compile Include="Models\GogSearchResult.cs" />
<Compile Include="Models\ItchMetaData.cs" />
<Compile Include="Models\GogMetaData.cs" />
Expand Down
2 changes: 1 addition & 1 deletion Source/Linker/Libraries/LibraryLinkGog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace LinkUtilities.Linker
{
/// <summary>
/// Adds a link to the gog page of the game, if it is part of the steam library.
/// Adds a link to GOG.
/// </summary>
class LibraryLinkGog : LinkAndLibrary
{
Expand Down
2 changes: 1 addition & 1 deletion Source/Linker/Libraries/LibraryLinkItch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace LinkUtilities.Linker
{
/// <summary>
/// Adds a link to the itch.io page of the game, if it is part of the steam library.
/// Adds a link to itch.io.
/// </summary>
class LibraryLinkItch : LinkAndLibrary
{
Expand Down
2 changes: 1 addition & 1 deletion Source/Linker/Libraries/LibraryLinkSteam.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace LinkUtilities.Linker
{
/// <summary>
/// Adds a link to the steam page of the game, if it is part of the steam library.
/// Adds a link to Steam.
/// </summary>
class LibraryLinkSteam : LinkAndLibrary
{
Expand Down
104 changes: 104 additions & 0 deletions Source/Linker/LinkSources/LinkEpic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using LinkUtilities.Helper;
using LinkUtilities.Models;
using LinkUtilities.Models.Epic;
using Playnite.SDK;
using Playnite.SDK.Models;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace LinkUtilities.Linker
{
class LinkEpic : Link
{
public override string LinkName { get; } = "Epic";
public override string BaseUrl { get; } = "https://store.epicgames.com/en-US/p/";
public override string SearchUrl { get; } = "https://www.epicgames.com/graphql?query={Catalog{searchStore(keywords:%22{SearchString}%22,category:%22games/edition%22,effectiveDate:%22[1900-01-01,{DateUntil}]%22,count:100){elements{title%20urlSlug%20seller{name}}}}}";

private readonly string CheckUrl = "https://store-content-ipv4.ak.epicgames.com/api/en-US/content/products/";

public override string GetGamePath(Game game)
{
// Epic Links need the game name in lowercase without special characters and underscores instead of white spaces.
return game.Name.RemoveDiacritics()
.RemoveSpecialChars()
.CollapseWhitespaces()
.Replace(" ", "-")
.ToLower();
}

public override bool AddLink(Game game)
{
// Unfortunately Epic returns the status code forbidden, when trying to check the url, because they want cookies and
// javascipt active. Fortunately we can use the game slug in the store api. If it doesn't return an error, there should also
// be a link with that slug.
string gameSlug = GetGamePath(game);
string url = $"{CheckUrl}{gameSlug}";

WebClient client = new WebClient() { Encoding = Encoding.UTF8 };
client.Headers.Add("Accept", "application/json");

try
{
string _ = client.DownloadString(url);
LinkUrl = $"{BaseUrl}{gameSlug}";
return LinkHelper.AddLink(game, LinkName, LinkUrl, Settings);
}
catch
{
LinkUrl = string.Empty;
return false;
}
}

public override List<GenericItemOption> SearchLink(string searchTerm)
{
SearchResults.Clear();

try
{
WebClient client = new WebClient() { Encoding = Encoding.UTF8 };

client.Headers.Add("Accept", "application/json");

// We use replace instead of format, because the url already contains several braces.
string url = SearchUrl
.Replace("{SearchString}", searchTerm.UrlEncode())
.Replace("{DateUntil}", DateTime.Now.AddDays(5).ToString("yyyy-MM-dd"));

string jsonResult = client.DownloadString(url);

EpicSearchResult epicSearchResult = Newtonsoft.Json.JsonConvert.DeserializeObject<EpicSearchResult>(jsonResult);

int counter = 0;

foreach (Element element in epicSearchResult.Data.Catalog.SearchStore.Elements)
{
counter++;

if (!string.IsNullOrEmpty(element.UrlSlug))
{
SearchResults.Add(new SearchResult
{
Name = $"{counter}. {element.Title}",
Url = $"{BaseUrl}{element.UrlSlug}",
Description = element.Seller.Name
}
);
}
}
}
catch (Exception ex)
{
Log.Error(ex, $"Error loading data from {LinkName}");
}

return base.SearchLink(searchTerm);
}

public LinkEpic(LinkUtilitiesSettings settings) : base(settings)
{
}
}
}
2 changes: 1 addition & 1 deletion Source/Linker/LinkSources/LinkHG101.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
namespace LinkUtilities.Linker
{
/// <summary>
/// Adds a link to MobyGames.
/// Adds a link to Hardcore Gaming 101.
/// </summary>
class LinkHG101 : Link
{
Expand Down
2 changes: 1 addition & 1 deletion Source/Linker/LinkSources/LinkMetacritic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace LinkUtilities.Linker
{
/// <summary>
/// Adds a link to MobyGames.
/// Adds a link to Metacritic.
/// </summary>
class LinkMetacritic : Link
{
Expand Down
1 change: 1 addition & 0 deletions Source/Linker/Links.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class Links : List<Link>
{
public Links(LinkUtilitiesSettings settings)
{
Add(new LinkEpic(settings));
Add(new LibraryLinkGog(settings));
Add(new LinkHG101(settings));
if (!string.IsNullOrWhiteSpace(settings.ItchApiKey))
Expand Down
2 changes: 1 addition & 1 deletion Source/Logging.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public static void Error(Exception ex, string Message = "", bool showDialog = fa
Message = $"Error on {traceInfos.InitialCaller}()";
}

Message += $"{Message}|{traceInfos.FileName}|{traceInfos.LineNumber}";
Message += $"|{traceInfos.FileName}|{traceInfos.LineNumber}";

logger.Error(ex, $"{Message}");

Expand Down
57 changes: 57 additions & 0 deletions Source/Models/EpicSearchResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Newtonsoft.Json;
using System.Collections.Generic;

// Contains all the classes needed to deserialize the JSON fetched from the Epic graphql api.
namespace LinkUtilities.Models.Epic
{
public class Catalog
{
[JsonProperty("searchStore")]
public SearchStore SearchStore;
}

public class Data
{
[JsonProperty("Catalog")]
public Catalog Catalog;
}

public class Element
{
[JsonProperty("title")]
public string Title;

[JsonProperty("urlSlug")]
public string UrlSlug;

[JsonProperty("seller")]
public Seller Seller;
}

public class Extensions
{
}

public class EpicSearchResult
{
[JsonProperty("data")]
public Data Data;

[JsonProperty("extensions")]
public Extensions Extensions;
}

public class SearchStore
{
[JsonProperty("elements")]
public List<Element> Elements;
}

public class Seller
{
[JsonProperty("name")]
public string Name;
}


}

0 comments on commit 13292e2

Please sign in to comment.