diff --git a/EveCalc.Shared/AssemblyInfo.cs b/EveCalc.Shared/AssemblyInfo.cs new file mode 100644 index 0000000..8b5504e --- /dev/null +++ b/EveCalc.Shared/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/EveCalc.Shared/Enums.cs b/EveCalc.Shared/Enums.cs new file mode 100644 index 0000000..c5fa106 --- /dev/null +++ b/EveCalc.Shared/Enums.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EveCalc.Shared +{ + public enum Materials + { + Tritanium = 34, + Pyerite = 35, + Mexallon = 36, + Isogen = 37, + Nocxium = 38, + Zydrine = 39, + Megacyte = 40 + } +} diff --git a/EveCalc.Shared/EveCalc.Shared.csproj b/EveCalc.Shared/EveCalc.Shared.csproj new file mode 100644 index 0000000..92c0f14 --- /dev/null +++ b/EveCalc.Shared/EveCalc.Shared.csproj @@ -0,0 +1,25 @@ + + + + Library + net5.0-windows + true + + + + + + + + + + + + + + + + + + + diff --git a/EveCalc.Shared/Logic/EsiClientWrapper.cs b/EveCalc.Shared/Logic/EsiClientWrapper.cs new file mode 100644 index 0000000..8122472 --- /dev/null +++ b/EveCalc.Shared/Logic/EsiClientWrapper.cs @@ -0,0 +1,201 @@ +using ESI.NET; +using ESI.NET.Enumerations; +using ESI.NET.Models.SSO; +using EveCalc.Shared.ObjectModel; +using Microsoft.Extensions.Options; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace EveCalc.Shared.Logic +{ + public partial class EsiClientWrapper + { + private readonly EsiClient client; + private AuthorizedCharacterData charData; + private string loginState = "guguseli123"; + + public EsiClientWrapper() + { + IOptions config = Options.Create(new EsiConfig() + { + EsiUrl = "https://esi.evetech.net/", + DataSource = DataSource.Tranquility, + ClientId = "f6892ca208364df1b0b8984773e16a2f", + SecretKey = "u5SqGF6ZkEdvjLBRn5rzU1Lz3oaFcpsGDX8Ki6Jn", + CallbackUrl = "https://localhost/evecalc", + UserAgent = "EveCalc.Test", + AuthVersion = AuthVersion.v2 + }); + + this.client = new EsiClient(config); + + // Init existsing token + if (File.Exists("token.json")) + { + var json = File.ReadAllText("token.json"); + this.charData = JsonConvert.DeserializeObject(json); + this.client.SetCharacterData(this.charData); + if (this.charData.ExpiresOn.AddHours(1) < DateTime.Now) + { + this.RefreshToken(); + } + } + + // Init cache + this.LoadNameCache(); + } + + public string GetLoginUrl() + { + var scopes = new List + { + "publicData", + //"esi-calendar.respond_calendar_events.v1", + //"esi-calendar.read_calendar_events.v1", + //"esi-location.read_location.v1", + //"esi-location.read_ship_type.v1", + //"esi-mail.organize_mail.v1", + //"esi-mail.read_mail.v1", + //"esi-mail.send_mail.v1", + //"esi-skills.read_skills.v1", + //"esi-skills.read_skillqueue.v1", + "esi-wallet.read_character_wallet.v1", + "esi-wallet.read_corporation_wallet.v1", + //"esi-search.search_structures.v1", + //"esi-clones.read_clones.v1", + //"esi-characters.read_contacts.v1", + "esi-universe.read_structures.v1", + //"esi-bookmarks.read_character_bookmarks.v1", + //"esi-killmails.read_killmails.v1", + "esi-corporations.read_corporation_membership.v1", + "esi-assets.read_assets.v1", + //"esi-planets.manage_planets.v1", + //"esi-fleets.read_fleet.v1", + //"esi-fleets.write_fleet.v1", + //"esi-ui.open_window.v1", + //"esi-ui.write_waypoint.v1", + //"esi-characters.write_contacts.v1", + //"esi-fittings.read_fittings.v1", + //"esi-fittings.write_fittings.v1", + "esi-markets.structure_markets.v1", + "esi-corporations.read_structures.v1", + //"esi-characters.read_loyalty.v1", + //"esi-characters.read_opportunities.v1", + //"esi-characters.read_chat_channels.v1", + //"esi-characters.read_medals.v1", + //"esi-characters.read_standings.v1", + //"esi-characters.read_agents_research.v1", + //"esi-industry.read_character_jobs.v1", + "esi-markets.read_character_orders.v1", + "esi-characters.read_blueprints.v1", + //"esi-characters.read_corporation_roles.v1", + //"esi-location.read_online.v1", + //"esi-contracts.read_character_contracts.v1", + //"esi-clones.read_implants.v1", + //"esi-characters.read_fatigue.v1", + //"esi-killmails.read_corporation_killmails.v1", + //"esi-corporations.track_members.v1", + "esi-wallet.read_corporation_wallets.v1", + //"esi-characters.read_notifications.v1", + //"esi-corporations.read_divisions.v1", + //"esi-corporations.read_contacts.v1", + "esi-assets.read_corporation_assets.v1", + //"esi-corporations.read_titles.v1", + "esi-corporations.read_blueprints.v1", + //"esi-bookmarks.read_corporation_bookmarks.v1", + //"esi-contracts.read_corporation_contracts.v1", + //"esi-corporations.read_standings.v1", + //"esi-corporations.read_starbases.v1", + //"esi-industry.read_corporation_jobs.v1", + "esi-markets.read_corporation_orders.v1", + //"esi-corporations.read_container_logs.v1", + //"esi-industry.read_character_mining.v1", + //"esi-industry.read_corporation_mining.v1", + //"esi-planets.read_customs_offices.v1", + //"esi-corporations.read_facilities.v1", + //"esi-corporations.read_medals.v1", + //"esi-characters.read_titles.v1", + //"esi-alliances.read_contacts.v1", + //"esi-characters.read_fw_stats.v1", + //"esi-corporations.read_fw_stats.v1", + //"esi-characterstats.read.v1" + }; + return client.SSO.CreateAuthenticationUrl(scopes, this.loginState); + } + + public async void SetAuthCode(string code) + { + SsoToken token = await this.client.SSO.GetToken(GrantType.AuthorizationCode, code); + this.charData = await client.SSO.Verify(token); + this.client.SetCharacterData(this.charData); + + var json = JsonConvert.SerializeObject(this.charData); + File.WriteAllText("token.json", json); + } + + public async void RefreshToken() + { + var token = await this.client.SSO.GetToken(GrantType.RefreshToken, this.charData.RefreshToken); + this.charData = await client.SSO.Verify(token); + this.client.SetCharacterData(this.charData); + } + + public async void Test() + { + var response = await client.Universe.Names(new List() + { + 1590304510, + 99006319, + 20000006 + }); + } + + public async Task> GetCorpBlueprints() + { + var response = await this.client.Corporation.Blueprints(); + + var result = new List(); + foreach (var blueprint in response.Data) + { + var blueprint2 = new Blueprint(blueprint); + blueprint2.TypeName = await this.GetFromNameCache(blueprint2.TypeId); + result.Add(blueprint2); + } + + return result; + } + + public async Task GetCorpMats() + { + var response = await this.client.Assets.ForCorporation(); + + //var result = new List(); + //foreach (var blueprint in response.Data) + //{ + // var blueprint2 = new Blueprint(blueprint); + // blueprint2.TypeName = await this.GetFromNameCache(blueprint2.TypeId); + // result.Add(blueprint2); + //} + + return response.Data; + } + + public async Task> Search(string query) + { + var response = await this.client.Search.Query(SearchType.Public, query, SearchCategory.InventoryType); + var result = new Dictionary(); + + foreach (var data in response.Data.InventoryTypes) + { + var name = await this.GetFromNameCache(data); + result.Add(data, name); + } + + return result; + } + } +} diff --git a/EveCalc.Shared/Logic/NameCache.cs b/EveCalc.Shared/Logic/NameCache.cs new file mode 100644 index 0000000..6a87385 --- /dev/null +++ b/EveCalc.Shared/Logic/NameCache.cs @@ -0,0 +1,67 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EveCalc.Shared.Logic +{ + public partial class EsiClientWrapper + { + private static string nameCacheFileName = "namecache.json"; + private Dictionary nameCache = new Dictionary(); + + public void LoadNameCache() + { + if (File.Exists(nameCacheFileName)) + { + var json = File.ReadAllText(nameCacheFileName); + this.nameCache = JsonConvert.DeserializeObject>(json); + } + } + + public void AddToNameCache(long id, string name) + { + if (this.nameCache.ContainsKey(id)) + { + if (this.nameCache[id] != name) + { + this.nameCache[id] = name; + this.SaveCache(); + } + } + else + { + this.nameCache.Add(id, name); + this.SaveCache(); + } + } + + public async Task GetFromNameCache(long id) + { + if (this.nameCache.ContainsKey(id)) + { + return this.nameCache[id]; + } + + // Get from api + var response2 = await client.Universe.Names(new List { id }); + if (response2.Data != null && response2.Data.Count > 0) + { + var name = response2.Data[0].Name; + this.AddToNameCache(id, name); + return name; + } + + return null; + } + + private void SaveCache() + { + var json = JsonConvert.SerializeObject(this.nameCache); + File.WriteAllText(nameCacheFileName, json); + } + } +} diff --git a/EveCalc.Shared/ObjectModel/Blueprint.cs b/EveCalc.Shared/ObjectModel/Blueprint.cs new file mode 100644 index 0000000..5d6dbae --- /dev/null +++ b/EveCalc.Shared/ObjectModel/Blueprint.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EveCalc.Shared.ObjectModel +{ + public class Blueprint : ESI.NET.Models.Corporation.Blueprint + { + public string TypeName { get; set; } + + public Blueprint(ESI.NET.Models.Corporation.Blueprint blueprint) : base() + { + this.ItemId = blueprint.ItemId; + this.LocationFlag = blueprint.LocationFlag; + this.LocationId = blueprint.LocationId; + this.MaterialEfficiency = blueprint.MaterialEfficiency; + this.Quantity = blueprint.Quantity; + this.Runs = blueprint.Runs; + this.TimeEfficiency = blueprint.TimeEfficiency; + this.TypeId = blueprint.TypeId; + } + } +} diff --git a/EveCalc.Shared/ObjectModel/BlueprintMaterial.cs b/EveCalc.Shared/ObjectModel/BlueprintMaterial.cs new file mode 100644 index 0000000..5382b10 --- /dev/null +++ b/EveCalc.Shared/ObjectModel/BlueprintMaterial.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EveCalc.Shared.ObjectModel +{ + public class BlueprintMaterial + { + public long MaterialTypeId { get; set; } + + public string MaterialTypeName { get; set; } + + public long Quantity { get; set; } + } +} diff --git a/EveCalc.Shared/StaticData/StaticDataProvider.cs b/EveCalc.Shared/StaticData/StaticDataProvider.cs new file mode 100644 index 0000000..b4e9050 --- /dev/null +++ b/EveCalc.Shared/StaticData/StaticDataProvider.cs @@ -0,0 +1,51 @@ +using EveCalc.Shared.ObjectModel; +using Microsoft.Data.Sqlite; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EveCalc.Shared.StaticData +{ + public class StaticDataProvider + { + public StaticDataProvider() + { + } + public List GetMaterialsForBlueprint(long id) + { + var result = new List(); + + using (var connection = new SqliteConnection("Data Source=StaticData\\staticdata.sqlite")) + { + connection.Open(); + + var command = connection.CreateCommand(); + command.CommandText = @"select materialTypeID, invTypes.typename, quantity " + + "from industryActivityMaterials " + + "inner join invTypes on invTypes.typeID=industryActivityMaterials.materialTypeID " + + "where blueprintTypeID=$id"; + command.Parameters.AddWithValue("id", id); + + using (var reader = command.ExecuteReader()) + { + while (reader.Read()) + { + var material = new BlueprintMaterial(); + material.MaterialTypeId = reader.GetInt64(0); + material.MaterialTypeName = reader.GetString(1); + material.Quantity = reader.GetInt64(2); + result.Add(material); + } + } + + connection.Close(); + } + + return result; + } + + } +} diff --git a/EveCalc.Shared/StaticData/staticdata.sqlite b/EveCalc.Shared/StaticData/staticdata.sqlite new file mode 100644 index 0000000..cc72ef3 Binary files /dev/null and b/EveCalc.Shared/StaticData/staticdata.sqlite differ diff --git a/EveCalc.Shared/Views/BrowserView.xaml b/EveCalc.Shared/Views/BrowserView.xaml new file mode 100644 index 0000000..7535637 --- /dev/null +++ b/EveCalc.Shared/Views/BrowserView.xaml @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/EveCalc.Shared/Views/BrowserView.xaml.cs b/EveCalc.Shared/Views/BrowserView.xaml.cs new file mode 100644 index 0000000..392d9cc --- /dev/null +++ b/EveCalc.Shared/Views/BrowserView.xaml.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace EveCalc.Shared.Views +{ + /// + /// Interaction logic for BrowserView.xaml + /// + public partial class BrowserView : Window + { + public string AuthCode { get; private set; } + public BrowserView() + { + this.InitializeComponent(); + //this.WbrBrowser.EnsureCoreWebView2Async().Wait(); + } + + public BrowserView(string url) : this() + { + this.WbrBrowser.Source = new Uri(url); + } + + private void WbrBrowser_NavigationStarting(object sender, Microsoft.Web.WebView2.Core.CoreWebView2NavigationStartingEventArgs e) + { + this.TxtUrl.Text = e.Uri.ToString(); + + if (this.TxtUrl.Text.StartsWith("https://localhost/evecalc?code=")) + { + // Habemus login + var split = this.TxtUrl.Text.Split(new[] { "code=", "&state=" }, StringSplitOptions.None); + this.AuthCode = split[1]; + this.DialogResult = true; + this.Close(); + } + } + } +} diff --git a/EveCalc.Tests/App.xaml b/EveCalc.Tests/App.xaml new file mode 100644 index 0000000..cd459b4 --- /dev/null +++ b/EveCalc.Tests/App.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/EveCalc.Tests/App.xaml.cs b/EveCalc.Tests/App.xaml.cs new file mode 100644 index 0000000..2db87c1 --- /dev/null +++ b/EveCalc.Tests/App.xaml.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; + +namespace EveCalc.Tests +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/EveCalc.Tests/AssemblyInfo.cs b/EveCalc.Tests/AssemblyInfo.cs new file mode 100644 index 0000000..8b5504e --- /dev/null +++ b/EveCalc.Tests/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/EveCalc.Tests/EveCalc.Tests.csproj b/EveCalc.Tests/EveCalc.Tests.csproj new file mode 100644 index 0000000..403b4ee --- /dev/null +++ b/EveCalc.Tests/EveCalc.Tests.csproj @@ -0,0 +1,13 @@ + + + + WinExe + net5.0-windows + true + + + + + + + diff --git a/EveCalc.Tests/MainWindow.xaml b/EveCalc.Tests/MainWindow.xaml new file mode 100644 index 0000000..b18b54e --- /dev/null +++ b/EveCalc.Tests/MainWindow.xaml @@ -0,0 +1,21 @@ + + + + + + + + +