public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { serializer.Converters.Add(new SkillTreeGroupConverter()); var jObject = JObject.Load(reader); var skillTree = new PoESkillTree(); if (jObject.GetValue("nodes") is JToken nodes && nodes.Type == JTokenType.Array) { skillTree.Nodes = nodes.ToObject <List <SkillNode> >().ToDictionary(i => i.Id, i => i); jObject.Remove("nodes"); } if (jObject.GetValue("skillSprites") is JToken spritesToken) { var sprites = spritesToken.ToObject <Dictionary <string, List <OldSkillSprite> > >(); if (sprites.Count == 2) { skillTree.SkillSprites = new Dictionary <string, List <SkillSprite> >(); foreach (var i in sprites) { //i.Key == "active", "inactive" var key = $"{i.Key.First().ToString().ToUpper()}{i.Key.Substring(1)}"; foreach (var j in i.Value) { if (!skillTree.SkillSprites.ContainsKey($"normal{key}")) { skillTree.SkillSprites.Add($"normal{key}", new List <SkillSprite>()); } skillTree.SkillSprites[$"normal{key}"].Add(new SkillSprite() { FileName = j.FileName, Coords = j.Coords ?? new Dictionary <string, Art2D>() }); if (!skillTree.SkillSprites.ContainsKey($"notable{key}")) { skillTree.SkillSprites.Add($"notable{key}", new List <SkillSprite>()); } skillTree.SkillSprites[$"notable{key}"].Add(new SkillSprite() { FileName = j.FileName, Coords = j.NotableCoords ?? new Dictionary <string, Art2D>() }); if (!skillTree.SkillSprites.ContainsKey($"keystone{key}")) { skillTree.SkillSprites.Add($"keystone{key}", new List <SkillSprite>()); } skillTree.SkillSprites[$"keystone{key}"].Add(new SkillSprite() { FileName = j.FileName, Coords = j.KeystoneCoords ?? new Dictionary <string, Art2D>() }); } } jObject.Remove("skillSprites"); } } serializer.Populate(jObject.CreateReader(), skillTree); return(skillTree); }
public void Decode(string jsonTree) { Nodes = new List <SkillNode>(); var jss = new JsonSerializerSettings { Error = (sender, args) => { // This one is known: "509":{"x":_,"y":_,"oo":[],"n":[]}} has an Array in "oo". // if (args.ErrorContext.Path != "groups.509.oo") // PoeHUD.Plugins.BasePlugin.LogError("Exception while deserializing Json tree" + args.ErrorContext.Error, 5); if (args.ErrorContext.Path == null || !args.ErrorContext.Path.EndsWith(".oo")) { Logger.Log.Error("Exception while deserializing Json tree" + args.ErrorContext.Error); } args.ErrorContext.Handled = true; } }; SkillTree = JsonConvert.DeserializeObject <PoESkillTree>(jsonTree, jss); Skillnodes = new Dictionary <ushort, SkillNode>(); NodeGroups = new List <SkillNodeGroup>(); foreach (var nd in SkillTree.nodes) { var skillNode = new SkillNode { Id = nd.Value.id, Name = nd.Value.dn, Orbit = nd.Value.o, OrbitIndex = nd.Value.oidx, bJevel = nd.Value.isJewelSocket, bKeyStone = nd.Value.ks, bMastery = nd.Value.m, bMult = nd.Value.isMultipleChoice, bNotable = nd.Value.not, linkedNodes = nd.Value._out }; Nodes.Add(skillNode); Skillnodes.Add(nd.Value.id, skillNode); } NodeGroups = new List <SkillNodeGroup>(); foreach (var gp in SkillTree.groups) { var ng = new SkillNodeGroup(); ng.OcpOrb = gp.Value.oo; ng.Position = new Vector2((float)gp.Value.x, (float)gp.Value.y); foreach (var node in gp.Value.n) { var nodeToAdd = Skillnodes[node]; ng.Nodes.Add(nodeToAdd); nodeToAdd.SkillNodeGroup = ng; } NodeGroups.Add(ng); } }
/// <summary> /// Downloads the asset images mentioned in the provided tree asynchronously. /// Existing files are not overriden. /// </summary> /// <param name="inTree"></param> /// <param name="reportProgress">If specified, it is called to set this method's progress as a value /// from 0 to 1.</param> /// <returns></returns> internal async Task DownloadAssetsAsync(PoESkillTree inTree, Action <double>?reportProgress = null) { Directory.CreateDirectory(_tempAssetsPath); var zoomLevel = inTree.ImageZoomLevels[Constants.AssetZoomLevel].ToString(CultureInfo.InvariantCulture); var perAssetProgress = 1.0 / inTree.Assets.Count; var progress = 0.0; foreach (var asset in inTree.Assets) { var path = _tempAssetsPath + asset.Key + ".png"; var url = asset.Value.GetValueOrDefault(zoomLevel, () => asset.Value.Values.First()); await DownloadAsync(url, path); progress += perAssetProgress; reportProgress?.Invoke(progress); } }
/// <summary> /// Downloads the node sprite images mentioned in the provided tree asynchronously. /// Existing files are not overriden. /// </summary> /// <param name="inTree"></param> /// <param name="reportProgress">If specified, it is called to set this method's progress as a value /// from 0 to 1.</param> /// <returns></returns> internal async Task DownloadSkillNodeSpritesAsync(PoESkillTree inTree, Action <double>?reportProgress = null) { Directory.CreateDirectory(_tempAssetsPath); var perSpriteProgress = 1.0 / inTree.SkillSprites.Count; var progress = 0.0; foreach (var obj in inTree.SkillSprites) { var sprite = obj.Value[Constants.AssetZoomLevel]; var path = _tempAssetsPath + sprite.FileName; var url = SpriteUrl + sprite.FileName; if (path.Contains('?')) { path = path.Remove(path.IndexOf('?')); } await DownloadAsync(url, path); progress += perSpriteProgress; reportProgress?.Invoke(progress); } }