1
0
Fork 0
mirror of https://github.com/Nioux/AideDeJeu.git synced 2025-10-31 07:26:09 +00:00

Cablage des critères + reorg

This commit is contained in:
Yan Maniez 2018-04-25 19:47:13 +02:00
parent e1eae80d13
commit b38c9f65ea
15 changed files with 230 additions and 149 deletions

View file

@ -11,5 +11,6 @@ namespace AideDeJeu.Services
Task<bool> DeleteItemAsync(T item); Task<bool> DeleteItemAsync(T item);
Task<T> GetItemAsync(string id); Task<T> GetItemAsync(string id);
Task<IEnumerable<T>> GetItemsAsync(bool forceRefresh = false); Task<IEnumerable<T>> GetItemsAsync(bool forceRefresh = false);
Task<IEnumerable<T>> GetItemsAsync(string classe, int niveauMin, int niveauMax);
} }
} }

View file

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using AideDeJeu.Models; using AideDeJeu.Models;
using AideDeJeuLib; using AideDeJeuLib;
using AideDeJeuLib.Spells;
[assembly: Xamarin.Forms.Dependency(typeof(AideDeJeu.Services.MockDataStore))] [assembly: Xamarin.Forms.Dependency(typeof(AideDeJeu.Services.MockDataStore))]
namespace AideDeJeu.Services namespace AideDeJeu.Services
@ -68,5 +69,10 @@ namespace AideDeJeu.Services
items = spells.Select(spell => new Item() { Text = spell.Title, Description = spell.DescriptionText }).ToList(); items = spells.Select(spell => new Item() { Text = spell.Title, Description = spell.DescriptionText }).ToList();
return await Task.FromResult(items); return await Task.FromResult(items);
} }
public async Task<IEnumerable<Item>> GetItemsAsync(string classe, int minLevel, int maxLevel)
{
return await GetItemsAsync();
}
} }
} }

View file

@ -5,6 +5,7 @@ using System.Threading.Tasks;
using AideDeJeu.Models; using AideDeJeu.Models;
using AideDeJeuLib; using AideDeJeuLib;
using AideDeJeuLib.Spells;
[assembly: Xamarin.Forms.Dependency(typeof(AideDeJeu.Services.SpellDataStore))] [assembly: Xamarin.Forms.Dependency(typeof(AideDeJeu.Services.SpellDataStore))]
namespace AideDeJeu.Services namespace AideDeJeu.Services
@ -64,5 +65,14 @@ namespace AideDeJeu.Services
//items = spells.Select(spell => new Item() { Text = spell.Title, Description = spell.DescriptionText }).ToList(); //items = spells.Select(spell => new Item() { Text = spell.Title, Description = spell.DescriptionText }).ToList();
return await Task.FromResult(items); return await Task.FromResult(items);
} }
public async Task<IEnumerable<Spell>> GetItemsAsync(string classe, int niveauMin, int niveauMax)
{
var scrapper = new Scrappers();
items = (await scrapper.GetSpells(classe, niveauMin, niveauMax)).ToList();
return await Task.FromResult(items);
}
} }
} }

View file

@ -8,6 +8,7 @@ using Xamarin.Forms;
using AideDeJeu.Models; using AideDeJeu.Models;
using AideDeJeu.Services; using AideDeJeu.Services;
using AideDeJeuLib; using AideDeJeuLib;
using AideDeJeuLib.Spells;
namespace AideDeJeu.ViewModels namespace AideDeJeu.ViewModels
{ {

View file

@ -1,13 +1,10 @@
using System; using AideDeJeu.Tools;
using AideDeJeuLib.Spells;
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using AideDeJeu.Models;
using AideDeJeuLib;
using HtmlAgilityPack;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.Internals;
using AideDeJeu.Tools;
namespace AideDeJeu.ViewModels namespace AideDeJeu.ViewModels
{ {
@ -48,7 +45,8 @@ namespace AideDeJeu.ViewModels
{ {
var fd = FormatedTextHelpers.FontData.FromResource("contentital"); var fd = FormatedTextHelpers.FontData.FromResource("contentital");
var fs = new FormattedString(); var fs = new FormattedString();
fs.Spans.Add(new Span() { Text = string.Format("{0} de niveau {1}", Item.Type, Item.Level), FontFamily = fd.FontFamily, FontAttributes = fd.FontAttributes, FontSize = fd.FontSize, ForegroundColor = fd.TextColor}); var capType = Item.Type.First().ToString().ToUpper() + Item.Type.Substring(1);
fs.Spans.Add(new Span() { Text = string.Format("{0} de niveau {1}", capType, Item.Level), FontFamily = fd.FontFamily, FontAttributes = fd.FontAttributes, FontSize = fd.FontSize, ForegroundColor = fd.TextColor});
return fs; return fs;
} }
} }

View file

@ -8,12 +8,90 @@ using Xamarin.Forms;
using AideDeJeu.Models; using AideDeJeu.Models;
using AideDeJeu.Views; using AideDeJeu.Views;
using AideDeJeuLib; using AideDeJeuLib;
using AideDeJeuLib.Spells;
using System.Collections.Generic;
namespace AideDeJeu.ViewModels namespace AideDeJeu.ViewModels
{ {
public class SpellsViewModel : BaseViewModel public class SpellsViewModel : BaseViewModel
{ {
public ObservableCollection<Spell> Items { get; set; } public ObservableCollection<Spell> Items { get; set; }
public List<KeyValuePair<string, string>> Classes { get; set; } = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("", "Toutes"),
new KeyValuePair<string, string>("b", "Barde"),
new KeyValuePair<string, string>("c", "Clerc"),
new KeyValuePair<string, string>("d", "Druide"),
new KeyValuePair<string, string>("s", "Ensorceleur"),
new KeyValuePair<string, string>("w", "Magicien"),
new KeyValuePair<string, string>("p", "Paladin"),
new KeyValuePair<string, string>("r", "Rôdeur"),
new KeyValuePair<string, string>("k", "Sorcier"),
};
public List<KeyValuePair<int, string>> Niveaux { get; set; } = new List<KeyValuePair<int, string>>()
{
new KeyValuePair<int, string>(0, "Sorts mineurs"),
new KeyValuePair<int, string>(1, "Niveau 1"),
new KeyValuePair<int, string>(2, "Niveau 2"),
new KeyValuePair<int, string>(3, "Niveau 3"),
new KeyValuePair<int, string>(4, "Niveau 4"),
new KeyValuePair<int, string>(5, "Niveau 5"),
new KeyValuePair<int, string>(6, "Niveau 6"),
new KeyValuePair<int, string>(7, "Niveau 7"),
new KeyValuePair<int, string>(8, "Niveau 8"),
new KeyValuePair<int, string>(9, "Niveau 9"),
};
private int _Classe = 0;
public int Classe
{
get
{
return _Classe;
}
set
{
SetProperty(ref _Classe, value);
LoadItemsCommand.Execute(null);
}
}
private int _NiveauMin = 0;
public int NiveauMin
{
get
{
return _NiveauMin;
}
set
{
SetProperty(ref _NiveauMin, value);
if (_NiveauMax < _NiveauMin)
{
SetProperty(ref _NiveauMax, value, nameof(NiveauMax));
}
LoadItemsCommand.Execute(null);
}
}
private int _NiveauMax = 9;
public int NiveauMax
{
get
{
return _NiveauMax;
}
set
{
SetProperty(ref _NiveauMax, value);
if (_NiveauMax < _NiveauMin)
{
SetProperty(ref _NiveauMin, value, nameof(NiveauMin));
}
LoadItemsCommand.Execute(null);
}
}
public Command LoadItemsCommand { get; set; } public Command LoadItemsCommand { get; set; }
public SpellsViewModel() public SpellsViewModel()
@ -39,8 +117,18 @@ namespace AideDeJeu.ViewModels
try try
{ {
//<option value="b">Barde</option>
//<option value="c">Clerc</option>
//<option value="d">Druide</option>
//<option value="s">Ensorceleur</option>
//<option value="w">Magicien</option>
//<option value="p">Paladin</option>
//<option value="r">Rôdeur</option>
//<option value="k">Sorcier</option>
string[] classes = new string[] { "", "b", "c", "d", "s", "w", "p", "r", "k" };
Items.Clear(); Items.Clear();
var items = await SpellDataStore.GetItemsAsync(true); var items = await SpellDataStore.GetItemsAsync(classe: classes[Classe], niveauMin: NiveauMin, niveauMax: NiveauMax);
foreach (var item in items) foreach (var item in items)
{ {
Items.Add(item); Items.Add(item);

View file

@ -27,8 +27,9 @@
</Picker.Items> </Picker.Items>
</Picker>--> </Picker>-->
<Label Text="Classe" /> <Label Text="Classe" />
<Picker HorizontalOptions="FillAndExpand"> <Picker HorizontalOptions="FillAndExpand" ItemsSource="{Binding Classes}" ItemDisplayBinding="{Binding Value}" SelectedItem="{Binding Key}" SelectedIndex="{Binding Classe}">
<Picker.Items> <!--<Picker.Items>
<x:String> </x:String>
<x:String>Barde</x:String> <x:String>Barde</x:String>
<x:String>Clerc</x:String> <x:String>Clerc</x:String>
<x:String>Druide</x:String> <x:String>Druide</x:String>
@ -37,11 +38,11 @@
<x:String>Paladin</x:String> <x:String>Paladin</x:String>
<x:String>Rôdeur</x:String> <x:String>Rôdeur</x:String>
<x:String>Sorcier</x:String> <x:String>Sorcier</x:String>
</Picker.Items> </Picker.Items>-->
</Picker> </Picker>
<Label Text="Niveau min" /> <Label Text="Niveau min" />
<Picker HorizontalOptions="FillAndExpand"> <Picker HorizontalOptions="FillAndExpand" ItemsSource="{Binding Niveaux}" ItemDisplayBinding="{Binding Value}" SelectedItem="{Binding Key}" SelectedIndex="{Binding NiveauMin}">
<Picker.Items> <!--<Picker.Items>
<x:String>Sorts mineurs</x:String> <x:String>Sorts mineurs</x:String>
<x:String>1</x:String> <x:String>1</x:String>
<x:String>2</x:String> <x:String>2</x:String>
@ -52,11 +53,11 @@
<x:String>7</x:String> <x:String>7</x:String>
<x:String>8</x:String> <x:String>8</x:String>
<x:String>9</x:String> <x:String>9</x:String>
</Picker.Items> </Picker.Items>-->
</Picker> </Picker>
<Label Text="Niveau max" /> <Label Text="Niveau max" />
<Picker HorizontalOptions="FillAndExpand"> <Picker HorizontalOptions="FillAndExpand" ItemsSource="{Binding Niveaux}" ItemDisplayBinding="{Binding Value}" SelectedItem="{Binding Key}" SelectedIndex="{Binding NiveauMax}">
<Picker.Items> <!--<Picker.Items>
<x:String>Sorts mineurs</x:String> <x:String>Sorts mineurs</x:String>
<x:String>1</x:String> <x:String>1</x:String>
<x:String>2</x:String> <x:String>2</x:String>
@ -67,7 +68,7 @@
<x:String>7</x:String> <x:String>7</x:String>
<x:String>8</x:String> <x:String>8</x:String>
<x:String>9</x:String> <x:String>9</x:String>
</Picker.Items> </Picker.Items>-->
</Picker> </Picker>
</StackLayout> </StackLayout>
</ContentPage> </ContentPage>

View file

@ -1,6 +1,7 @@
using AideDeJeu.Models; using AideDeJeu.Models;
using AideDeJeu.ViewModels; using AideDeJeu.ViewModels;
using AideDeJeuLib; using AideDeJeuLib;
using AideDeJeuLib.Spells;
using System; using System;
using Xamarin.Forms; using Xamarin.Forms;

View file

@ -6,6 +6,7 @@ using Xamarin.Forms.Xaml;
using AideDeJeu.Models; using AideDeJeu.Models;
using AideDeJeu.ViewModels; using AideDeJeu.ViewModels;
using AideDeJeuLib; using AideDeJeuLib;
using AideDeJeuLib.Spells;
namespace AideDeJeu.Views namespace AideDeJeu.Views
{ {

View file

@ -10,4 +10,8 @@
<PackageReference Include="HtmlAgilityPack" Version="1.8.1" /> <PackageReference Include="HtmlAgilityPack" Version="1.8.1" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Monsters\" />
</ItemGroup>
</Project> </Project>

View file

@ -1,15 +1,8 @@
using System; using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization; using System.Runtime.Serialization;
using System.Text;
namespace AideDeJeuLib namespace AideDeJeuLib.Cards
{ {
/*public class CardDataOwner
{
public CardData[] CardDatas { get; set; }
}*/
[DataContract] [DataContract]
public class CardData public class CardData
{ {

View file

@ -1,11 +1,9 @@
using HtmlAgilityPack; using AideDeJeuLib.Spells;
using System; using HtmlAgilityPack;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Text;
namespace AideDeJeuLib namespace AideDeJeuLib.Cards
{ {
public static class Converters public static class Converters
{ {

View file

@ -1,63 +0,0 @@
using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
using System.Text.RegularExpressions;
namespace AideDeJeuLib
{
public class Spell
{
public string Id { get; set; }
public string Title { get; set; }
public string TitleUS { get; set; }
public string LevelType { get; set; }
public string Level { get; set; }
public string Type { get; set; }
public string Concentration { get; set; }
public string Rituel { get; set; }
public string CastingTime { get; set; }
public string Range { get; set; }
public string Components { get; set; }
public string Duration { get; set; }
public string DescriptionHtml
{
get
{
return DescriptionDiv?.InnerHtml;
}
set
{
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(value);
DescriptionDiv = doc.DocumentNode;
}
}
public string DescriptionText
{
get
{
string html = DescriptionDiv?.InnerText?.Replace("\n", "\r\n\r\n");
//string html = DescriptionDiv?.InnerHtml;
//html = html?.Replace("<br>", "\r\n");
//html = html?.Replace("<strong>", "");
//html = html?.Replace("</strong>", "");
//html = html?.Replace("<em>", "");
//html = html?.Replace("</em>", "");
//if (html != null)
//{
// var regex = new Regex("<a href=.*?>");
// html = regex.Replace(html, "");
//}
//html = html?.Replace("</a>", "");
return html;
}
}
[IgnoreDataMember]
public HtmlNode DescriptionDiv { get; set; }
public string Overflow { get; set; }
public string NoOverflow { get; set; }
public string Source { get; set; }
}
}

View file

@ -2,17 +2,13 @@
using HtmlAgilityPack; using HtmlAgilityPack;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Runtime.Serialization; using System.Reactive.Linq;
using System.Runtime.Serialization.Json;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Reactive.Linq;
namespace AideDeJeuLib namespace AideDeJeuLib.Spells
{ {
public class Scrappers public class Scrappers
{ {
@ -27,22 +23,6 @@ namespace AideDeJeuLib
return client; return client;
} }
public async Task<IEnumerable<string>> GetSpellIds(string classe, int niveauMin = 0, int niveauMax = 9)
{
string html = null;
using (var client = GetHttpClient())
{
// https://www.aidedd.org/dnd/sorts.php?vo=ray-of-frost
// https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
// https://www.aidedd.org/regles/sorts/
html = await client.GetStringAsync(string.Format("https://www.aidedd.org/adj/livre-sorts/?c={0}&min=1{1}&max=1{2}", classe, niveauMin, niveauMax));
}
var pack = new HtmlDocument();
pack.LoadHtml(html);
return pack.DocumentNode.SelectNodes("//input[@name='select_sorts[]']").Select(node => node.GetAttributeValue("value", ""));
}
public async Task<IEnumerable<Spell>> GetSpells(string classe = "", int niveauMin = 0, int niveauMax = 9, string ecole = "", string rituel = "", string source = "srd") public async Task<IEnumerable<Spell>> GetSpells(string classe = "", int niveauMin = 0, int niveauMax = 9, string ecole = "", string rituel = "", string source = "srd")
{ {
string html = null; string html = null;
@ -92,41 +72,33 @@ namespace AideDeJeuLib
} }
var pack = new HtmlDocument(); var pack = new HtmlDocument();
pack.LoadHtml(html); pack.LoadHtml(html);
var newSpells = new List<Spell>();
var divSpell = pack.DocumentNode.SelectNodes("//div[contains(@class,'bloc')]").FirstOrDefault(); var divSpell = pack.DocumentNode.SelectNodes("//div[contains(@class,'bloc')]").FirstOrDefault();
var newSpell = HtmlDivToSpell(divSpell); return Spell.FromHtml(divSpell);
return newSpell;
} }
public async Task<Spell> GetSpell(string id) public async Task<Spell> GetSpell(string id)
{ {
BlobCache.ApplicationName = "AkavacheExperiment"; BlobCache.ApplicationName = "AkavacheExperiment";
//await BlobCache.UserAccount.InsertObject(id, newSpell); //await BlobCache.UserAccount.InsertObject(id, newSpell);
var truc = await BlobCache.UserAccount.GetOrFetchObject<Spell>(id, () => GetSpellFromSource(id)); return await BlobCache.UserAccount.GetOrFetchObject<Spell>(id, () => GetSpellFromSource(id));
return truc;
} }
public Spell HtmlDivToSpell(HtmlNode divSpell) public async Task<IEnumerable<string>> GetSpellIds(string classe, int niveauMin = 0, int niveauMax = 9)
{ {
var newSpell = new Spell(); string html = null;
newSpell.Title = divSpell.SelectSingleNode("h1").InnerText; using (var client = GetHttpClient())
newSpell.TitleUS = divSpell.SelectSingleNode("div[@class='trad']").InnerText; {
newSpell.LevelType = divSpell.SelectSingleNode("h2/em").InnerText; // https://www.aidedd.org/dnd/sorts.php?vo=ray-of-frost
newSpell.Level = newSpell.LevelType.Split(new string[] { " - " }, StringSplitOptions.None)[0].Split(' ')[1]; // https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
newSpell.Type = newSpell.LevelType.Split(new string[] { " - " }, StringSplitOptions.None)[1]; // https://www.aidedd.org/regles/sorts/
newSpell.CastingTime = divSpell.SelectSingleNode("div[@class='paragraphe']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
newSpell.Range = divSpell.SelectSingleNode("div[strong/text()='Portée']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
newSpell.Components = divSpell.SelectSingleNode("div[strong/text()='Composantes']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
newSpell.Duration = divSpell.SelectSingleNode("div[strong/text()='Durée']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
newSpell.DescriptionDiv = divSpell.SelectSingleNode("div[contains(@class,'description')]");
newSpell.Overflow = divSpell.SelectSingleNode("div[@class='overflow']")?.InnerText;
newSpell.NoOverflow = divSpell.SelectSingleNode("div[@class='nooverflow']")?.InnerText;
newSpell.Source = divSpell.SelectSingleNode("div[@class='source']").InnerText;
return newSpell; html = await client.GetStringAsync(string.Format("https://www.aidedd.org/adj/livre-sorts/?c={0}&min=1{1}&max=1{2}", classe, niveauMin, niveauMax));
}
var pack = new HtmlDocument();
pack.LoadHtml(html);
return pack.DocumentNode.SelectNodes("//input[@name='select_sorts[]']").Select(node => node.GetAttributeValue("value", ""));
} }
public async Task<IEnumerable<Spell>> GetSpells(IEnumerable<string> spellIds) public async Task<IEnumerable<Spell>> GetSpells(IEnumerable<string> spellIds)
{ {
string html = null; string html = null;
@ -167,6 +139,7 @@ namespace AideDeJeuLib
} }
return newSpells; return newSpells;
} }
/*
public async Task<string> OnGetAsync(IReadOnlyDictionary<string, string> context) public async Task<string> OnGetAsync(IReadOnlyDictionary<string, string> context)
{ {
var client = new HttpClient(); var client = new HttpClient();
@ -191,16 +164,16 @@ namespace AideDeJeuLib
// https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre // https://www.aidedd.org/dnd/sorts.php?vf=rayon-de-givre
// https://www.aidedd.org/regles/sorts/ // https://www.aidedd.org/regles/sorts/
/*
<option value="b">Barde</option> //<option value="b">Barde</option>
<option value="c">Clerc</option> //<option value="c">Clerc</option>
<option value="d">Druide</option> //<option value="d">Druide</option>
<option value="s">Ensorceleur</option> //<option value="s">Ensorceleur</option>
<option value="w">Magicien</option> //<option value="w">Magicien</option>
<option value="p">Paladin</option> //<option value="p">Paladin</option>
<option value="r">Rôdeur</option> //<option value="r">Rôdeur</option>
<option value="k">Sorcier</option> //<option value="k">Sorcier</option>
*/
string c = context["c"]; string c = context["c"];
var htmlSpellBook = await client.GetStringAsync("https://www.aidedd.org/adj/livre-sorts/?c=" + c + "&min=10&max=19"); var htmlSpellBook = await client.GetStringAsync("https://www.aidedd.org/adj/livre-sorts/?c=" + c + "&min=10&max=19");
var pack = new HtmlDocument(); var pack = new HtmlDocument();
@ -273,7 +246,7 @@ namespace AideDeJeuLib
//} //}
} }
*/
} }
} }

View file

@ -0,0 +1,69 @@
using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Text;
using System.Text.RegularExpressions;
namespace AideDeJeuLib.Spells
{
public class Spell
{
public string Id { get; set; }
public string Title { get; set; }
public string TitleUS { get; set; }
public string LevelType { get; set; }
public string Level { get; set; }
public string Type { get; set; }
public string Concentration { get; set; }
public string Rituel { get; set; }
public string CastingTime { get; set; }
public string Range { get; set; }
public string Components { get; set; }
public string Duration { get; set; }
public string DescriptionHtml
{
get
{
return DescriptionDiv?.InnerHtml;
}
set
{
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(value);
DescriptionDiv = doc.DocumentNode;
}
}
public string DescriptionText
{
get
{
return DescriptionDiv?.InnerText?.Replace("\n", "\r\n\r\n");
}
}
[IgnoreDataMember]
public HtmlNode DescriptionDiv { get; set; }
public string Overflow { get; set; }
public string NoOverflow { get; set; }
public string Source { get; set; }
public static Spell FromHtml(HtmlNode nodeSpell)
{
var spell = new Spell();
spell.Title = nodeSpell.SelectSingleNode("h1").InnerText;
spell.TitleUS = nodeSpell.SelectSingleNode("div[@class='trad']").InnerText;
spell.LevelType = nodeSpell.SelectSingleNode("h2/em").InnerText;
spell.Level = spell.LevelType.Split(new string[] { " - " }, StringSplitOptions.None)[0].Split(' ')[1];
spell.Type = spell.LevelType.Split(new string[] { " - " }, StringSplitOptions.None)[1];
spell.CastingTime = nodeSpell.SelectSingleNode("div[@class='paragraphe']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
spell.Range = nodeSpell.SelectSingleNode("div[strong/text()='Portée']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
spell.Components = nodeSpell.SelectSingleNode("div[strong/text()='Composantes']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
spell.Duration = nodeSpell.SelectSingleNode("div[strong/text()='Durée']").InnerText.Split(new string[] { " : " }, StringSplitOptions.None)[1];
spell.DescriptionDiv = nodeSpell.SelectSingleNode("div[contains(@class,'description')]");
spell.Overflow = nodeSpell.SelectSingleNode("div[@class='overflow']")?.InnerText;
spell.NoOverflow = nodeSpell.SelectSingleNode("div[@class='nooverflow']")?.InnerText;
spell.Source = nodeSpell.SelectSingleNode("div[@class='source']").InnerText;
return spell;
}
}
}