internal SteamUserStatsResponse(JobID jobId, CMsgClientGetUserStatsResponse body) { JobID = jobId; GameId = body.game_id; GameIdSpecified = body.game_idSpecified; Result = (EResult)body.eresult; ResultSpecified = body.eresultSpecified; CrcStats = body.crc_stats; CrcStatsSpecified = body.crc_statsSpecified; Schema = body.schema; SchemaSpecified = body.schemaSpecified; Stats = body.stats; AchievementBlocks = body.achievement_blocks; ParsedSchema = new KeyValue(); if (body.schemaSpecified && body.schema != null) { using (MemoryStream ms = new MemoryStream(body.schema)) using (var br = new BinaryReader(ms)) { ParsedSchema.TryReadAsBinary(ms); } } }
//Utilities private List <StatData>?ParseResponse(CMsgClientGetUserStatsResponse Response) { List <StatData> result = new List <StatData>(); KeyValue KeyValues = new KeyValue(); if (Response.schema != null) { using (MemoryStream ms = new MemoryStream(Response.schema)) { if (!KeyValues.TryReadAsBinary(ms)) { ASF.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsInvalid, nameof(Response.schema))); return(null); } ; } //first we enumerate all real achievements foreach (KeyValue stat in KeyValues.Children.Find(Child => Child.Name == "stats")?.Children ?? new List <KeyValue>()) { if (stat.Children.Find(Child => Child.Name == "type")?.Value == "4") { foreach (KeyValue Achievement in stat.Children.Find(Child => Child.Name == "bits")?.Children ?? new List <KeyValue>()) { if (int.TryParse(Achievement.Name, out int bitNum)) { if (uint.TryParse(stat.Name, out uint statNum)) { bool isSet = false; if ((Response.stats != null) && (Response.stats.Find(statElement => statElement.stat_id == statNum) != null)) { isSet = (Response.stats.Find(statElement => statElement.stat_id == statNum) !.stat_value & ((uint)1 << bitNum)) != 0; } ; bool restricted = Achievement.Children.Find(Child => Child.Name == "permission") != null; string?dependancyName = (Achievement.Children.Find(Child => Child.Name == "progress") == null) ? "" : Achievement.Children.Find(Child => Child.Name == "progress")?.Children?.Find(Child => Child.Name == "value")?.Children?.Find(Child => Child.Name == "operand1")?.Value; uint.TryParse((Achievement.Children.Find(Child => Child.Name == "progress") == null) ? "0" : Achievement.Children.Find(Child => Child.Name == "progress") !.Children.Find(Child => Child.Name == "max_val")?.Value, out uint dependancyValue); string lang = CultureInfo.CurrentUICulture.EnglishName.ToLower(); if (lang.IndexOf('(') > 0) { lang = lang.Substring(0, lang.IndexOf('(') - 1); } if (Achievement.Children.Find(Child => Child.Name == "display")?.Children?.Find(Child => Child.Name == "name")?.Children?.Find(Child => Child.Name == lang) == null) { lang = "english"; //fallback to english } string?name = Achievement.Children.Find(Child => Child.Name == "display")?.Children?.Find(Child => Child.Name == "name")?.Children?.Find(Child => Child.Name == lang)?.Value; result.Add(new StatData() { StatNum = statNum, BitNum = bitNum, IsSet = isSet, Restricted = restricted, DependancyValue = dependancyValue, DependancyName = dependancyName, Dependancy = 0, Name = name }); } } } } } //Now we update all dependancies foreach (KeyValue stat in KeyValues.Children.Find(Child => Child.Name == "stats")?.Children ?? new List <KeyValue>()) { if (stat.Children.Find(Child => Child.Name == "type")?.Value == "1") { if (uint.TryParse(stat.Name, out uint statNum)) { bool restricted = stat.Children.Find(Child => Child.Name == "permission") != null; string?name = stat.Children.Find(Child => Child.Name == "name")?.Value; if (name != null) { StatData?ParentStat = result.Find(item => item.DependancyName == name); if (ParentStat != null) { ParentStat.Dependancy = statNum; if (restricted && !ParentStat.Restricted) { ParentStat.Restricted = true; } } } } } } } return(result); }