diff --git a/LANCommander.PCGamingWiki/LANCommander.PCGamingWiki.csproj b/LANCommander.PCGamingWiki/LANCommander.PCGamingWiki.csproj new file mode 100644 index 0000000..dcf4157 --- /dev/null +++ b/LANCommander.PCGamingWiki/LANCommander.PCGamingWiki.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.0 + + + + + + + + + + + + diff --git a/LANCommander.PCGamingWiki/PCGamingWikiClient.cs b/LANCommander.PCGamingWiki/PCGamingWikiClient.cs new file mode 100644 index 0000000..43cd630 --- /dev/null +++ b/LANCommander.PCGamingWiki/PCGamingWikiClient.cs @@ -0,0 +1,91 @@ +using HtmlAgilityPack; +using LANCommander.SDK; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text.Json; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Web; + +namespace LANCommander.PCGamingWiki +{ + public class PCGamingWikiClient + { + private HttpClient Client; + + public PCGamingWikiClient() + { + Client = new HttpClient(); + Client.BaseAddress = new Uri("https://www.pcgamingwiki.com/"); + } + + public async Task Search(string keyword) + { + var results = await Client.GetStringAsync($"w/api.php?action=opensearch&format=json&formatversion=2&search={HttpUtility.UrlEncode(keyword)}&limit=1"); + + string pattern = @"(https:\/\/www.pcgamingwiki.com.+)"""; + RegexOptions options = RegexOptions.Multiline; + + var match = Regex.Match(results, pattern, options); + + if (match.Success && match.Groups.Count == 2) + { + return new Uri(match.Groups[1].Value); + } + + return null; + } + + public async Task> GetMultiplayerPlayerCounts(string keyword) + { + var url = await Search(keyword); + + return await GetMultiplayerPlayerCounts(url); + } + + public async Task> GetMultiplayerPlayerCounts(Uri url) + { + var results = new Dictionary(); + + HtmlWeb web = new HtmlWeb(); + HtmlDocument dom = web.Load(url); + + HtmlNode multiplayerTable = dom.GetElementbyId("table-network-multiplayer"); + + if (multiplayerTable == null) + return null; + + var multiplayerAbbrs = multiplayerTable.SelectNodes(".//abbr"); + var multiplayerCounts = multiplayerTable.SelectNodes(".//td[contains(@class, 'table-network-multiplayer-body-players')]"); + + for (int i = 0; i < multiplayerAbbrs.Count; i++) + { + var type = multiplayerAbbrs[i].InnerText; + var players = multiplayerCounts[i].InnerText; + + int playerCount = 0; + + if (Int32.TryParse(players, out playerCount)) + { + switch (type.ToLower()) + { + case "local play": + results["Local Play"] = playerCount; + break; + + case "lan play": + results["LAN Play"] = playerCount; + break; + + case "online play": + results["Online Play"] = playerCount; + break; + } + } + } + + return results; + } + } +} diff --git a/LANCommander.sln b/LANCommander.sln index b9ea7d4..a9129f6 100644 --- a/LANCommander.sln +++ b/LANCommander.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LANCommander.PlaynitePlugin EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LANCommander.SDK", "LANCommander.SDK\LANCommander.SDK.csproj", "{4C2A71FD-A30B-4D62-888A-4EF843D8E506}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LANCommander.PCGamingWiki", "LANCommander.PCGamingWiki\LANCommander.PCGamingWiki.csproj", "{2436B817-4475-4E70-9BB2-E1E7866DB79F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +29,10 @@ Global {4C2A71FD-A30B-4D62-888A-4EF843D8E506}.Debug|Any CPU.Build.0 = Debug|Any CPU {4C2A71FD-A30B-4D62-888A-4EF843D8E506}.Release|Any CPU.ActiveCfg = Release|Any CPU {4C2A71FD-A30B-4D62-888A-4EF843D8E506}.Release|Any CPU.Build.0 = Release|Any CPU + {2436B817-4475-4E70-9BB2-E1E7866DB79F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2436B817-4475-4E70-9BB2-E1E7866DB79F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2436B817-4475-4E70-9BB2-E1E7866DB79F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2436B817-4475-4E70-9BB2-E1E7866DB79F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/LANCommander/Controllers/GamesController.cs b/LANCommander/Controllers/GamesController.cs index 08c99f8..f0982fc 100644 --- a/LANCommander/Controllers/GamesController.cs +++ b/LANCommander/Controllers/GamesController.cs @@ -13,6 +13,7 @@ using LANCommander.Services; using System.Drawing; using LANCommander.Models; using LANCommander.Data.Enums; +using LANCommander.PCGamingWiki; namespace LANCommander.Controllers { @@ -26,6 +27,7 @@ namespace LANCommander.Controllers private readonly GenreService GenreService; private readonly CompanyService CompanyService; private readonly IGDBService IGDBService; + private readonly PCGamingWikiClient PCGamingWikiClient; public GamesController(GameService gameService, ArchiveService archiveService, CategoryService categoryService, TagService tagService, GenreService genreService, CompanyService companyService, IGDBService igdbService) { @@ -36,6 +38,7 @@ namespace LANCommander.Controllers GenreService = genreService; CompanyService = companyService; IGDBService = igdbService; + PCGamingWikiClient = new PCGamingWikiClient(); } // GET: Games @@ -57,7 +60,12 @@ namespace LANCommander.Controllers if (igdbid == null) { - viewModel.Game = new Game(); + viewModel.Game = new Game() + { + Actions = new List(), + MultiplayerModes = new List() + }; + viewModel.Developers = CompanyService.Get().OrderBy(c => c.Name).Select(c => new SelectListItem() { Text = c.Name, Value = c.Name }).ToList(); viewModel.Publishers = CompanyService.Get().OrderBy(c => c.Name).Select(c => new SelectListItem() { Text = c.Name, Value = c.Name }).ToList(); viewModel.Genres = GenreService.Get().OrderBy(g => g.Name).Select(g => new SelectListItem() { Text = g.Name, Value = g.Name }).ToList(); @@ -74,9 +82,42 @@ namespace LANCommander.Controllers Title = result.Name, Description = result.Summary, ReleasedOn = result.FirstReleaseDate.GetValueOrDefault().UtcDateTime, - MultiplayerModes = new List(), + Actions = new List(), + MultiplayerModes = new List() }; + var playerCounts = await PCGamingWikiClient.GetMultiplayerPlayerCounts(result.Name); + + foreach (var playerCount in playerCounts) + { + MultiplayerType type; + + switch (playerCount.Key) + { + case "Local Play": + type = MultiplayerType.Local; + break; + + case "LAN Play": + type = MultiplayerType.Lan; + break; + + case "Online Play": + type = MultiplayerType.Online; + break; + + default: + continue; + } + + viewModel.Game.MultiplayerModes.Add(new MultiplayerMode() + { + Type = type, + MaxPlayers = playerCount.Value, + MinPlayers = 2 + }); + } + if (result.GameModes != null && result.GameModes.Values != null) viewModel.Game.Singleplayer = result.GameModes.Values.Any(gm => gm.Name == "Singleplayer"); diff --git a/LANCommander/LANCommander.csproj b/LANCommander/LANCommander.csproj index a83bc36..4b3d345 100644 --- a/LANCommander/LANCommander.csproj +++ b/LANCommander/LANCommander.csproj @@ -49,6 +49,7 @@ + diff --git a/LANCommander/Views/Games/Add.cshtml b/LANCommander/Views/Games/Add.cshtml index 32095f4..769094b 100644 --- a/LANCommander/Views/Games/Add.cshtml +++ b/LANCommander/Views/Games/Add.cshtml @@ -1,4 +1,5 @@ -@model LANCommander.Models.GameViewModel +@using LANCommander.Components +@model LANCommander.Models.GameViewModel @{ ViewData["Title"] = "Add Game"; @@ -83,6 +84,18 @@ +
+

Actions

+
+ + + +
+

Multiplayer Modes

+
+ + +