diff --git a/Kruzya.TelegramBot.sln b/Kruzya.TelegramBot.sln
index 48d8613..9681417 100644
--- a/Kruzya.TelegramBot.sln
+++ b/Kruzya.TelegramBot.sln
@@ -12,6 +12,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "tests\Tests.csproj
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UrlLimitations", "modules\UrlLimitations\UrlLimitations.csproj", "{B82E3339-3B34-4600-8C59-C5A3640B1982}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Destiny2.WhereIsXur", "modules\Destiny2.WhereIsXur\Destiny2.WhereIsXur.csproj", "{AE782132-BED8-4D1E-98FA-CB768171D332}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -38,10 +40,15 @@ Global
{B82E3339-3B34-4600-8C59-C5A3640B1982}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B82E3339-3B34-4600-8C59-C5A3640B1982}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B82E3339-3B34-4600-8C59-C5A3640B1982}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AE782132-BED8-4D1E-98FA-CB768171D332}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AE782132-BED8-4D1E-98FA-CB768171D332}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AE782132-BED8-4D1E-98FA-CB768171D332}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AE782132-BED8-4D1E-98FA-CB768171D332}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{F1E1FBB7-ABA4-4304-9A42-D4975822B002} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
{C50D64C3-204B-4B58-927B-C8D759787252} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
{B82E3339-3B34-4600-8C59-C5A3640B1982} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
+ {AE782132-BED8-4D1E-98FA-CB768171D332} = {C7821F15-DEDD-474F-A575-A296D4B58F10}
EndGlobalSection
EndGlobal
diff --git a/modules/Destiny2.WhereIsXur/Destiny2.WhereIsXur.csproj b/modules/Destiny2.WhereIsXur/Destiny2.WhereIsXur.csproj
new file mode 100644
index 0000000..260611a
--- /dev/null
+++ b/modules/Destiny2.WhereIsXur/Destiny2.WhereIsXur.csproj
@@ -0,0 +1,18 @@
+
+
+
+ netcoreapp3.1
+ Kruzya.TelegramBot.D2_WhereIsXur
+ Kruzya.TelegramBot.Destiny2.WhereIsXur
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/Destiny2.WhereIsXur/Provider/IXurPlaceProvider.cs b/modules/Destiny2.WhereIsXur/Provider/IXurPlaceProvider.cs
new file mode 100644
index 0000000..681af6f
--- /dev/null
+++ b/modules/Destiny2.WhereIsXur/Provider/IXurPlaceProvider.cs
@@ -0,0 +1,10 @@
+using System.Threading.Tasks;
+
+namespace Kruzya.TelegramBot.Destiny2.WhereIsXur.Provider
+{
+ public interface IXurPlaceProvider
+ {
+ public Task GetPlaceAsync();
+ public string GetPlace();
+ }
+}
\ No newline at end of file
diff --git a/modules/Destiny2.WhereIsXur/Provider/XurWiki.cs b/modules/Destiny2.WhereIsXur/Provider/XurWiki.cs
new file mode 100644
index 0000000..f9a207c
--- /dev/null
+++ b/modules/Destiny2.WhereIsXur/Provider/XurWiki.cs
@@ -0,0 +1,28 @@
+using System.Threading.Tasks;
+using Fizzler.Systems.HtmlAgilityPack;
+using HtmlAgilityPack;
+
+namespace Kruzya.TelegramBot.Destiny2.WhereIsXur.Provider
+{
+ public class XurWiki : IXurPlaceProvider
+ {
+ public async Task GetPlaceAsync()
+ {
+ var web = new HtmlWeb();
+ var document = await web.LoadFromWebAsync("https://xur.wiki");
+
+ var place = document.DocumentNode.QuerySelector(".location_name");
+ if (place != null)
+ {
+ return place.InnerText.Trim();
+ }
+
+ return "";
+ }
+
+ public string GetPlace()
+ {
+ return GetPlaceAsync().GetAwaiter().GetResult();
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/Destiny2.WhereIsXur/RequestHandler.cs b/modules/Destiny2.WhereIsXur/RequestHandler.cs
new file mode 100644
index 0000000..b051062
--- /dev/null
+++ b/modules/Destiny2.WhereIsXur/RequestHandler.cs
@@ -0,0 +1,36 @@
+using System.Threading.Tasks;
+using BotFramework;
+using BotFramework.Attributes;
+using Kruzya.TelegramBot.Destiny2.WhereIsXur.Provider;
+using Telegram.Bot.Types.Enums;
+
+namespace Kruzya.TelegramBot.Destiny2.WhereIsXur
+{
+ public class RequestHandler : BotEventHandler
+ {
+ protected readonly IXurPlaceProvider _placeProvider;
+
+ public RequestHandler(IXurPlaceProvider xurPlaceProvider)
+ {
+ _placeProvider = xurPlaceProvider;
+ }
+
+ [Command("d2_xur")]
+ public async Task WhereIsXur()
+ {
+ var place = await _placeProvider.GetPlaceAsync();
+ if (string.IsNullOrWhiteSpace(place))
+ {
+ await Response("unknown");
+ return;
+ }
+
+ await Response(place);
+ }
+
+ protected async Task Response(string place)
+ {
+ await Bot.SendTextMessageAsync(Chat, $"Xûr place is {place}", ParseMode.Html);
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/Destiny2.WhereIsXur/WhereIsXur.cs b/modules/Destiny2.WhereIsXur/WhereIsXur.cs
new file mode 100644
index 0000000..bd176c0
--- /dev/null
+++ b/modules/Destiny2.WhereIsXur/WhereIsXur.cs
@@ -0,0 +1,18 @@
+using Kruzya.TelegramBot.Core;
+using Kruzya.TelegramBot.Destiny2.WhereIsXur.Provider;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Kruzya.TelegramBot.Destiny2.WhereIsXur
+{
+ public class WhereIsXur : Module
+ {
+ public WhereIsXur(Core.Core core) : base(core)
+ {
+ }
+
+ public override void ConfigureServices(IServiceCollection services)
+ {
+ services.AddSingleton();
+ }
+ }
+}
\ No newline at end of file