/// <summary> /// Query the API to populate mising OnlineBeatmapID / OnlineBeatmapSetID properties. /// </summary> /// <param name="beatmap">The beatmap to populate.</param> /// <param name="otherBeatmaps">The other beatmaps contained within this set.</param> /// <param name="force">Whether to re-query if the provided beatmap already has populated values.</param> /// <returns>True if population was successful.</returns> private bool fetchAndPopulateOnlineIDs(BeatmapInfo beatmap, IEnumerable <BeatmapInfo> otherBeatmaps, bool force = false) { if (!force && beatmap.OnlineBeatmapID != null && beatmap.BeatmapSet.OnlineBeatmapSetID != null) { return(true); } if (api.State != APIState.Online) { return(false); } Logger.Log("Attempting online lookup for IDs...", LoggingTarget.Database); try { var req = new GetBeatmapRequest(beatmap); req.Perform(api); var res = req.Result; Logger.Log($"Successfully mapped to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}.", LoggingTarget.Database); if (otherBeatmaps.Any(b => b.OnlineBeatmapID == res.OnlineBeatmapID)) { Logger.Log("Another beatmap in the same set already mapped to this ID. We'll skip adding it this time.", LoggingTarget.Database); return(false); } beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID; beatmap.OnlineBeatmapID = res.OnlineBeatmapID; return(true); } catch (Exception e) { Logger.Log($"Failed ({e})", LoggingTarget.Database); return(false); } }
private void load(RulesetStore rulesets) { beatmapId.Value = Model.ID; beatmapId.BindValueChanged(id => { Model.ID = id.NewValue ?? 0; if (id.NewValue != id.OldValue) { Model.BeatmapInfo = null; } if (Model.BeatmapInfo != null) { updatePanel(); return; } var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = Model.ID }); req.Success += res => { Model.BeatmapInfo = res.ToBeatmap(rulesets); updatePanel(); }; req.Failure += _ => { Model.BeatmapInfo = null; updatePanel(); }; API.Queue(req); }, true); mods.Value = Model.Mods; mods.BindValueChanged(modString => Model.Mods = modString.NewValue); }
private void load(RulesetStore rulesets) { beatmapId.Value = Model.ID; beatmapId.BindValueChanged(id => { Model.ID = id.NewValue ?? 0; if (id.NewValue != id.OldValue) { Model.BeatmapInfo = null; } if (Model.BeatmapInfo != null) { updatePanel(); return; } var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = Model.ID }); req.Success += res => { Model.BeatmapInfo = res.ToBeatmapInfo(rulesets); updatePanel(); }; req.Failure += _ => { Model.BeatmapInfo = null; updatePanel(); }; API.Queue(req); }, true); score.Value = Model.Score.ToString(); score.BindValueChanged(str => long.TryParse(str.NewValue, out Model.Score)); }
private void update(BeatmapSetInfo set, BeatmapInfo beatmap) { if (api?.State != APIState.Online) { return; } var req = new GetBeatmapRequest(beatmap); req.Failure += fail; try { // intentionally blocking to limit web request concurrency api.Perform(req); var res = req.Result; if (res != null) { beatmap.Status = res.Status; beatmap.BeatmapSet.Status = res.BeatmapSet.Status; beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID; beatmap.OnlineBeatmapID = res.OnlineBeatmapID; LogForModel(set, $"Online retrieval mapped {beatmap} to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}."); } } catch (Exception e) { fail(e); } void fail(Exception e) { beatmap.OnlineBeatmapID = null; LogForModel(set, $"Online retrieval failed for {beatmap} ({e.Message})"); } }
/// <summary> /// Query the API to populate missing values like OnlineBeatmapID / OnlineBeatmapSetID or (Rank-)Status. /// </summary> /// <param name="beatmap">The beatmap to populate.</param> /// <param name="force">Whether to re-query if the provided beatmap already has populated values.</param> /// <returns>True if population was successful.</returns> private bool fetchAndPopulateOnlineValues(BeatmapInfo beatmap, bool force = false) { if (api?.State != APIState.Online) { return(false); } if (!force && beatmap.OnlineBeatmapID != null && beatmap.BeatmapSet.OnlineBeatmapSetID != null && beatmap.Status != BeatmapSetOnlineStatus.None && beatmap.BeatmapSet.Status != BeatmapSetOnlineStatus.None) { return(true); } Logger.Log("Attempting online lookup for the missing values...", LoggingTarget.Database); try { var req = new GetBeatmapRequest(beatmap); req.Perform(api); var res = req.Result; Logger.Log($"Successfully mapped to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}.", LoggingTarget.Database); beatmap.Status = res.Status; beatmap.BeatmapSet.Status = res.BeatmapSet.Status; beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID; beatmap.OnlineBeatmapID = res.OnlineBeatmapID; return(true); } catch (Exception e) { Logger.Log($"Failed ({e})", LoggingTarget.Database); return(false); } }
/// <summary> /// Add missing beatmap info based on beatmap IDs /// </summary> private bool addBeatmaps() { bool addedInfo = false; foreach (var r in ladder.Rounds) { foreach (var b in r.Beatmaps) { if (b.BeatmapInfo == null && b.ID > 0) { var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = b.ID }); req.Perform(API); b.BeatmapInfo = req.Result?.ToBeatmap(RulesetStore); addedInfo = true; } } } return(addedInfo); }
private void update(BeatmapSetInfo set, BeatmapInfo beatmap) { if (api?.State != APIState.Online) { return; } var req = new GetBeatmapRequest(beatmap); req.Success += res => { LogForModel(set, $"Online retrieval mapped {beatmap} to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}."); beatmap.Status = res.Status; beatmap.BeatmapSet.Status = res.BeatmapSet.Status; beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID; beatmap.OnlineBeatmapID = res.OnlineBeatmapID; }; req.Failure += e => { LogForModel(set, $"Online retrieval failed for {beatmap}", e); }; // intentionally blocking to limit web request concurrency req.Perform(api); }
public Storage LocateStableStorage() { scheduled?.Cancel(); Storage = null; try { var path = findStablePath(); if (string.IsNullOrEmpty(path)) { return(null); } Storage = new DesktopStorage(path, host as DesktopGameHost); const string file_ipc_filename = "ipc.txt"; const string file_ipc_state_filename = "ipc-state.txt"; const string file_ipc_scores_filename = "ipc-scores.txt"; const string file_ipc_channel_filename = "ipc-channel.txt"; if (Storage.Exists(file_ipc_filename)) { scheduled = Scheduler.AddDelayed(delegate { try { using (var stream = Storage.GetStream(file_ipc_filename)) using (var sr = new StreamReader(stream)) { var beatmapId = int.Parse(sr.ReadLine()); var mods = int.Parse(sr.ReadLine()); if (lastBeatmapId != beatmapId) { beatmapLookupRequest?.Cancel(); lastBeatmapId = beatmapId; var existing = ladder.CurrentMatch.Value?.Round.Value?.Beatmaps.FirstOrDefault(b => b.ID == beatmapId && b.BeatmapInfo != null); if (existing != null) { Beatmap.Value = existing.BeatmapInfo; } else { beatmapLookupRequest = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = beatmapId }); beatmapLookupRequest.Success += b => Beatmap.Value = b.ToBeatmap(Rulesets); API.Queue(beatmapLookupRequest); } } Mods.Value = (LegacyMods)mods; } } catch { // file might be in use. } try { using (var stream = Storage.GetStream(file_ipc_channel_filename)) using (var sr = new StreamReader(stream)) { ChatChannel.Value = sr.ReadLine(); } } catch (Exception) { // file might be in use. } try { using (var stream = Storage.GetStream(file_ipc_state_filename)) using (var sr = new StreamReader(stream)) { State.Value = (TourneyState)Enum.Parse(typeof(TourneyState), sr.ReadLine()); } } catch (Exception) { // file might be in use. } try { using (var stream = Storage.GetStream(file_ipc_scores_filename)) using (var sr = new StreamReader(stream)) { Score1.Value = int.Parse(sr.ReadLine()); Score2.Value = int.Parse(sr.ReadLine()); } } catch (Exception) { // file might be in use. } }, 250, true); } } catch (Exception e) { Logger.Error(e, "Stable installation could not be found; disabling file based IPC"); } return(Storage); }
private void load(LadderInfo ladder, GameHost host) { StableStorage stable; try { stable = new StableStorage(host as DesktopGameHost); } catch (Exception e) { Logger.Error(e, "Stable installation could not be found; disabling file based IPC"); return; } const string file_ipc_filename = "ipc.txt"; const string file_ipc_state_filename = "ipc-state.txt"; const string file_ipc_scores_filename = "ipc-scores.txt"; const string file_ipc_channel_filename = "ipc-channel.txt"; if (stable.Exists(file_ipc_filename)) { Scheduler.AddDelayed(delegate { try { using (var stream = stable.GetStream(file_ipc_filename)) using (var sr = new StreamReader(stream)) { var beatmapId = int.Parse(sr.ReadLine()); var mods = int.Parse(sr.ReadLine()); if (lastBeatmapId != beatmapId) { lastBeatmapId = beatmapId; var existing = ladder.CurrentMatch.Value?.Round.Value?.Beatmaps.FirstOrDefault(b => b.ID == beatmapId && b.BeatmapInfo != null); if (existing != null) { Beatmap.Value = existing.BeatmapInfo; } else { var req = new GetBeatmapRequest(new BeatmapInfo { OnlineBeatmapID = beatmapId }); req.Success += b => Beatmap.Value = b.ToBeatmap(Rulesets); API.Queue(req); } } Mods.Value = (LegacyMods)mods; } } catch { // file might be in use. } try { using (var stream = stable.GetStream(file_ipc_channel_filename)) using (var sr = new StreamReader(stream)) { ChatChannel.Value = sr.ReadLine(); } } catch (Exception) { // file might be in use. } try { using (var stream = stable.GetStream(file_ipc_state_filename)) using (var sr = new StreamReader(stream)) { State.Value = (TourneyState)Enum.Parse(typeof(TourneyState), sr.ReadLine()); } } catch (Exception) { // file might be in use. } try { using (var stream = stable.GetStream(file_ipc_scores_filename)) using (var sr = new StreamReader(stream)) { Score1.Value = int.Parse(sr.ReadLine()); Score2.Value = int.Parse(sr.ReadLine()); } } catch (Exception) { // file might be in use. } }, 250, true); } }