/// <summary> Show detailed information about a specific player. </summary> /// <param name="owner">Window that will own the details window.</param> /// <param name="p">Player to display.</param> public void OpenPlayerDetails(Window owner, Player p) { if (p != null) { // Generate player details view var vm = new PlayerDetailViewmodel(p); var win = new PlayerDetailView(vm) { Owner = owner }; win.ShowDialog(); } }
/// <summary> Log into the swgoh.help service and pull complete guild data. </summary> /// <remarks>TODO: refactor and break up.</remarks> private async void PullData() { if (!api.IsLoggedIn) { if (await DoLogin() == false) { return; } } // If we successfully logged in, store these settings to re-use next time settings.username = Username; settings.userid = UserId; settings.allycode = AllyCode; ProgramSettings.Store(settings, SettingsFile); UpdateProgramState(ProgramState.GETTING_GUILD_DATA); GuildInfo resp = null; bool success = false; // Reuse existing information if it's relatively recent. // The server doesn't refresh too often, so don't set time window too small. if (guild == null || guild.Updated < DateTimeOffset.Now.AddHours(-8)) { // Fetch guild information DebugMessage($"Guild Info: Start"); try { resp = await api.GetGuildInfo(api.AllyCode); success = true; } catch (Exception e) { ShowError($"Error fetching guild info:\n{e.Message}"); } DebugMessage($"Guild Info: End"); // Update UI and VM with results if (!success || resp == null) { guild = null; Members.Clear(); rawPlayerInfo = null; PlayerName = ""; GuildName = ""; UpdateProgramState(ProgramState.NO_DATA_AVAILABLE); return; } guild = resp; } // NOTE: It would be better to pull the player's info first and check if they were in a guild. // The API is so slow, though, that it saves a noticible amount of time to blindly pull // guild info first and try to catch the error. If this becomes unmanageably awkward, // change it to work the other way. if (guild != null) { // Player is in a guild, pull roster info and unlock full UI PlayerName = guild.roster.Where(p => p.allyCode == api.AllyCode.Value).FirstOrDefault().name; GuildName = guild.name; if (rawPlayerInfo == null || rawPlayerInfo.First().Updated < DateTimeOffset.Now.AddHours(-8) || rawPlayerInfo.Count != guild.members) { // Fetch player info Members.Clear(); var codes = guild.roster.Select(r => new AllyCode((uint)r.allyCode)); var pdata = await UpdatePlayerData(codes); if (pdata == null) { rawPlayerInfo = null; return; } rawPlayerInfo = pdata; } if (!gameData.HasData() || gameData.IsOutdated()) { DebugMessage("Game metadata update needed"); UpdateProgramState(ProgramState.GETTING_MISC_DATA); gameData = await UpdateGameData(); if (!gameData.HasData() || gameData.IsOutdated()) { UpdateProgramState(ProgramState.NO_DATA_AVAILABLE); return; } // Cache game metadata GameData.Store(gameData, GameDataFile); } // Build roster ComputeTruePower(rawPlayerInfo, gameData.RelicMultipliers); BuildRoster(rawPlayerInfo, gameData.Titles); UpdateProgramState(ProgramState.READY); DebugMessage("Ready"); } else { // Player doesn't seem to be in a guild, try pulling individual player information UpdateProgramState(ProgramState.GETTING_PLAYER_DATA); var codes = new List <AllyCode>() { api.AllyCode }; List <PlayerInfo> pinfo = null; success = false; try { pinfo = await api.GetPlayerInfo(codes); success = true; } catch (Newtonsoft.Json.JsonReaderException e) { ShowError($"Error deserializing JSON:\n{e.Message}"); } catch (Exception e) { ShowError($"Error fetching player:\n{e.Message}"); } if (success) { // Display player info Player p = new Player(pinfo.First()); var vm = new PlayerDetailViewmodel(p); var win = new PlayerDetailView(vm) { Owner = parent }; win.ShowDialog(); // Nothing else to do if no guild, so just close the program. parent.Close(); } } }