Exemple #1
0
        private void showBeatmapPanel(SpectatorState state)
        {
            if (state?.BeatmapID == null)
            {
                beatmapPanelContainer.Clear();
                onlineBeatmap = null;
                return;
            }

            var req = new GetBeatmapSetRequest(state.BeatmapID.Value, BeatmapSetLookupType.BeatmapId);

            req.Success += res => Schedule(() =>
            {
                if (state != this.state)
                {
                    return;
                }

                onlineBeatmap = res.ToBeatmapSet(rulesets);
                beatmapPanelContainer.Child = new GridBeatmapPanel(onlineBeatmap);
                checkForAutomaticDownload();
            });

            api.Queue(req);
        }
Exemple #2
0
        private void updateLocalRoomSettings(MultiplayerRoomSettings settings)
        {
            if (Room == null)
            {
                return;
            }

            Schedule(() =>
            {
                if (Room == null)
                {
                    return;
                }

                Debug.Assert(apiRoom != null);

                // Update a few properties of the room instantaneously.
                Room.Settings      = settings;
                apiRoom.Name.Value = Room.Settings.Name;

                // The playlist update is delayed until an online beatmap lookup (below) succeeds.
                // In-order for the client to not display an outdated beatmap, the playlist is forcefully cleared here.
                apiRoom.Playlist.Clear();

                RoomChanged?.Invoke();

                var req      = new GetBeatmapSetRequest(settings.BeatmapID, BeatmapSetLookupType.BeatmapId);
                req.Success += res => updatePlaylist(settings, res);

                api.Queue(req);
            });
        }
Exemple #3
0
        private void loadNewPanel(BeatmapInfo beatmap)
        {
            loadCancellation?.Cancel();
            request?.Cancel();

            panel?.FadeOut(200);
            panel?.Expire();
            panel = null;

            if (beatmap?.OnlineBeatmapID == null)
            {
                return;
            }

            loadCancellation = new CancellationTokenSource();

            request          = new GetBeatmapSetRequest(beatmap.OnlineBeatmapID.Value, BeatmapSetLookupType.BeatmapId);
            request.Success += res => Schedule(() =>
            {
                panel = new DirectGridPanel(res.ToBeatmapSet(rulesets));
                LoadComponentAsync(panel, AddInternal, loadCancellation.Token);
            });

            api.Queue(request);
        }
Exemple #4
0
        private Task updateLocalRoomSettings(MultiplayerRoomSettings settings, CancellationToken cancellationToken = default) => scheduleAsync(() =>
        {
            if (Room == null)
            {
                return;
            }

            Debug.Assert(apiRoom != null);

            // Update a few properties of the room instantaneously.
            Room.Settings      = settings;
            apiRoom.Name.Value = Room.Settings.Name;

            // The current item update is delayed until an online beatmap lookup (below) succeeds.
            // In-order for the client to not display an outdated beatmap, the current item is forcefully cleared here.
            CurrentMatchPlayingItem.Value = null;

            RoomUpdated?.Invoke();

            var req      = new GetBeatmapSetRequest(settings.BeatmapID, BeatmapSetLookupType.BeatmapId);
            req.Success += res =>
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                updatePlaylist(settings, res);
            };

            api.Queue(req);
        }, cancellationToken);
        private void load(OsuGameBase osu, APIAccess api, RulesetStore rulesets)
        {
            Bindable <BeatmapInfo> beatmapBindable = new Bindable <BeatmapInfo>();

            var imported = ImportBeatmapTest.LoadOszIntoOsu(osu);

            Child = backgroundSprite = new UpdateableBeatmapBackgroundSprite {
                RelativeSizeAxes = Axes.Both
            };

            backgroundSprite.Beatmap.BindTo(beatmapBindable);

            var req = new GetBeatmapSetRequest(1);

            api.Queue(req);

            AddStep("null", () => beatmapBindable.Value = null);

            AddStep("imported", () => beatmapBindable.Value = imported.Beatmaps.First());

            if (api.IsLoggedIn)
            {
                AddUntilStep(() => req.Result != null, "wait for api response");

                AddStep("online", () => beatmapBindable.Value = new BeatmapInfo
                {
                    BeatmapSet = req.Result?.ToBeatmapSet(rulesets)
                });
            }
            else
            {
                AddStep("online (login first)", () => { });
            }
        }
        public void TestOnlineBeatmap()
        {
            if (api.IsLoggedIn)
            {
                var req = new GetBeatmapSetRequest(1);
                api.Queue(req);

                AddUntilStep("wait for api response", () => req.Result != null);

                TestUpdateableBeatmapBackgroundSprite background = null;

                AddStep("load online beatmap", () =>
                {
                    Child = background = new TestUpdateableBeatmapBackgroundSprite
                    {
                        RelativeSizeAxes = Axes.Both,
                        Beatmap          = { Value = new BeatmapInfo {
                                                 BeatmapSet = req.Result?.ToBeatmapSet(rulesets)
                                             } }
                    };
                });

                AddUntilStep("wait for load", () => background.ContentLoaded);
            }
            else
            {
                AddStep("online (login first)", () => { });
            }
        }
        public void ShowBeatmapSet(int beatmapSetId)
        {
            // todo: display the overlay while we are loading here. we need to support setting BeatmapSet to null for this to work.
            var req = new GetBeatmapSetRequest(beatmapSetId);

            req.Success += res => ShowBeatmapSet(res.ToBeatmapSet(rulesets));
            api.Queue(req);
        }
Exemple #8
0
        public void FetchAndShowBeatmapSet(int beatmapSetId)
        {
            beatmapSet.Value = null;
            var req = new GetBeatmapSetRequest(beatmapSetId);

            req.Success += res => beatmapSet.Value = res.ToBeatmapSet(rulesets);
            API.Queue(req);
            Show();
        }
Exemple #9
0
        private void showBeatmapPanel(int beatmapId)
        {
            var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId);

            req.Success += res => Schedule(() =>
            {
                beatmapPanelContainer.Child = new GridBeatmapPanel(res.ToBeatmapSet(rulesets));
            });

            api.Queue(req);
        }
Exemple #10
0
        public void FetchAndShowBeatmap(int beatmapId)
        {
            beatmapSet.Value = null;
            var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId);

            req.Success += res =>
            {
                beatmapSet.Value            = res.ToBeatmapSet(rulesets);
                Header.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId);
            };
            API.Queue(req);
            Show();
        }
Exemple #11
0
        private void showBeatmapPanel(SpectatorState state)
        {
            Debug.Assert(state.BeatmapID != null);

            onlineBeatmapRequest          = new GetBeatmapSetRequest(state.BeatmapID.Value, BeatmapSetLookupType.BeatmapId);
            onlineBeatmapRequest.Success += beatmapSet => Schedule(() =>
            {
                this.beatmapSet             = beatmapSet;
                beatmapPanelContainer.Child = new BeatmapCardNormal(this.beatmapSet, allowExpansion: false);
                checkForAutomaticDownload();
            });

            api.Queue(onlineBeatmapRequest);
        }
Exemple #12
0
        private void showBeatmapPanel(SpectatorState state)
        {
            Debug.Assert(state.BeatmapID != null);

            onlineBeatmapRequest          = new GetBeatmapSetRequest(state.BeatmapID.Value, BeatmapSetLookupType.BeatmapId);
            onlineBeatmapRequest.Success += res => Schedule(() =>
            {
                onlineBeatmap = res.ToBeatmapSet(rulesets);
                beatmapPanelContainer.Child = new GridBeatmapPanel(onlineBeatmap);
                checkForAutomaticDownload();
            });

            api.Queue(onlineBeatmapRequest);
        }
Exemple #13
0
        protected override Task <APIBeatmapSet> GetOnlineBeatmapSet(int beatmapId, CancellationToken cancellationToken = default)
        {
            var tcs = new TaskCompletionSource <APIBeatmapSet>();
            var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId);

            req.Success += res =>
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    tcs.SetCanceled();
                    return;
                }

                tcs.SetResult(res);
            };

            req.Failure += e => tcs.SetException(e);

            API.Queue(req);

            return(tcs.Task);
        }
Exemple #14
0
        public bool Crawl(int id, PisstaubeDbContext _context)
        {
            try
            {
                while (!_apiAccess.IsLoggedIn)
                {
                    Thread.Sleep(1000);
                }

                var setRequest = new GetBeatmapSetRequest(id);

                lock (_lock)
                    _request_count++;

                _rl.Limit();
                setRequest.Perform(_apiAccess);

                lock (_lock)
                    if (_request_count > int.Parse(Environment.GetEnvironmentVariable("CRAWLER_REQUESTS_PER_MINUTE")))
                    {
                        Thread.Sleep(TimeSpan.FromMinutes(1));
                    }

                var apiSet = setRequest.Result;

                var localSet = apiSet?.ToBeatmapSet(_store);
                if (localSet == null)
                {
                    return(false);
                }

                var dbSet = BeatmapSet.FromBeatmapSetInfo(localSet);
                if (dbSet == null)
                {
                    return(false);
                }

                foreach (var map in dbSet.ChildrenBeatmaps)
                {
                    var fileInfo = _downloader.Download(map);

                    map.FileMd5 = _cache.Get()
                                  .CacheBeatmaps
                                  .Where(cmap => cmap.Hash == fileInfo.Hash)
                                  .Select(cmap => cmap.FileMd5)
                                  .FirstOrDefault();
                }

                lock (_lock)
                {
                    _context.BeatmapSet.Add(dbSet);
                }

                _search.IndexBeatmap(dbSet);
            }
            catch (Exception ex)
            {
                Logger.Error(ex, $"Unknown Error occured while crawling Id {id}!");

                lock (_lock)
                    Thread.Sleep(TimeSpan.FromMinutes(1));
                return(false);
            }

            return(true);
        }
        private void load()
        {
            int currentScoreId = 0;

            // Handling here is pretending to be a server, while also updating the local state to match
            // how the server would eventually respond and update the RoomManager.
            ((DummyAPIAccess)api).HandleRequest = req =>
            {
                switch (req)
                {
                case CreateRoomRequest createRoomRequest:
                    var apiRoom = new Room();

                    apiRoom.CopyFrom(createRoomRequest.Room);

                    // Passwords are explicitly not copied between rooms.
                    apiRoom.HasPassword.Value = !string.IsNullOrEmpty(createRoomRequest.Room.Password.Value);
                    apiRoom.Password.Value    = createRoomRequest.Room.Password.Value;

                    AddRoom(apiRoom);

                    var responseRoom = new APICreatedRoom();
                    responseRoom.CopyFrom(createResponseRoom(apiRoom, false));

                    createRoomRequest.TriggerSuccess(responseRoom);
                    return(true);

                case JoinRoomRequest joinRoomRequest:
                {
                    var room = Rooms.Single(r => r.RoomID.Value == joinRoomRequest.Room.RoomID.Value);

                    if (joinRoomRequest.Password != room.Password.Value)
                    {
                        joinRoomRequest.TriggerFailure(new InvalidOperationException("Invalid password."));
                        return(true);
                    }

                    joinRoomRequest.TriggerSuccess();
                    return(true);
                }

                case PartRoomRequest partRoomRequest:
                    partRoomRequest.TriggerSuccess();
                    return(true);

                case GetRoomsRequest getRoomsRequest:
                    var roomsWithoutParticipants = new List <Room>();

                    foreach (var r in Rooms)
                    {
                        roomsWithoutParticipants.Add(createResponseRoom(r, false));
                    }

                    getRoomsRequest.TriggerSuccess(roomsWithoutParticipants);
                    return(true);

                case GetRoomRequest getRoomRequest:
                    getRoomRequest.TriggerSuccess(createResponseRoom(Rooms.Single(r => r.RoomID.Value == getRoomRequest.RoomId), true));
                    return(true);

                case GetBeatmapSetRequest getBeatmapSetRequest:
                    var onlineReq = new GetBeatmapSetRequest(getBeatmapSetRequest.ID, getBeatmapSetRequest.Type);
                    onlineReq.Success += res => getBeatmapSetRequest.TriggerSuccess(res);
                    onlineReq.Failure += e => getBeatmapSetRequest.TriggerFailure(e);

                    // Get the online API from the game's dependencies.
                    game.Dependencies.Get <IAPIProvider>().Queue(onlineReq);
                    return(true);

                case CreateRoomScoreRequest createRoomScoreRequest:
                    createRoomScoreRequest.TriggerSuccess(new APIScoreToken {
                        ID = 1
                    });
                    return(true);

                case SubmitRoomScoreRequest submitRoomScoreRequest:
                    submitRoomScoreRequest.TriggerSuccess(new MultiplayerScore
                    {
                        ID         = currentScoreId++,
                        Accuracy   = 1,
                        EndedAt    = DateTimeOffset.Now,
                        Passed     = true,
                        Rank       = ScoreRank.S,
                        MaxCombo   = 1000,
                        TotalScore = 1000000,
                        User       = api.LocalUser.Value,
                        Statistics = new Dictionary <HitResult, int>()
                    });
                    return(true);
                }

                return(false);
            };
        }
        private void load()
        {
            int currentScoreId        = 0;
            int currentRoomId         = 0;
            int currentPlaylistItemId = 0;

            ((DummyAPIAccess)api).HandleRequest = req =>
            {
                switch (req)
                {
                case CreateRoomRequest createRoomRequest:
                    var createdRoom = new APICreatedRoom();

                    createdRoom.CopyFrom(createRoomRequest.Room);
                    createdRoom.RoomID.Value ??= currentRoomId++;

                    for (int i = 0; i < createdRoom.Playlist.Count; i++)
                    {
                        createdRoom.Playlist[i].ID = currentPlaylistItemId++;
                    }

                    Rooms.Add(createdRoom);
                    createRoomRequest.TriggerSuccess(createdRoom);
                    return(true);

                case JoinRoomRequest joinRoomRequest:
                    joinRoomRequest.TriggerSuccess();
                    return(true);

                case PartRoomRequest partRoomRequest:
                    partRoomRequest.TriggerSuccess();
                    return(true);

                case GetRoomsRequest getRoomsRequest:
                    var roomsWithoutParticipants = new List <Room>();

                    foreach (var r in Rooms)
                    {
                        var newRoom = new Room();

                        newRoom.CopyFrom(r);
                        newRoom.RecentParticipants.Clear();

                        roomsWithoutParticipants.Add(newRoom);
                    }

                    getRoomsRequest.TriggerSuccess(roomsWithoutParticipants);
                    return(true);

                case GetRoomRequest getRoomRequest:
                    getRoomRequest.TriggerSuccess(Rooms.Single(r => r.RoomID.Value == getRoomRequest.RoomId));
                    return(true);

                case GetBeatmapSetRequest getBeatmapSetRequest:
                    var onlineReq = new GetBeatmapSetRequest(getBeatmapSetRequest.ID, getBeatmapSetRequest.Type);
                    onlineReq.Success += res => getBeatmapSetRequest.TriggerSuccess(res);
                    onlineReq.Failure += e => getBeatmapSetRequest.TriggerFailure(e);

                    // Get the online API from the game's dependencies.
                    game.Dependencies.Get <IAPIProvider>().Queue(onlineReq);
                    return(true);

                case CreateRoomScoreRequest createRoomScoreRequest:
                    createRoomScoreRequest.TriggerSuccess(new APIScoreToken {
                        ID = 1
                    });
                    return(true);

                case SubmitRoomScoreRequest submitRoomScoreRequest:
                    submitRoomScoreRequest.TriggerSuccess(new MultiplayerScore
                    {
                        ID         = currentScoreId++,
                        Accuracy   = 1,
                        EndedAt    = DateTimeOffset.Now,
                        Passed     = true,
                        Rank       = ScoreRank.S,
                        MaxCombo   = 1000,
                        TotalScore = 1000000,
                        User       = api.LocalUser.Value,
                        Statistics = new Dictionary <HitResult, int>()
                    });
                    return(true);
                }

                return(false);
            };
        }
Exemple #17
0
        public void BeginUpdaterSync()
        {
            while (true)
            {
                var beatmapSets = _factory.Get().BeatmapSet.Where(x => !x.Disabled)
                                  .Where(
                    x => x.LastChecked != null && ((
                                                       (
                                                           x.RankedStatus == BeatmapSetOnlineStatus.None ||
                                                           x.RankedStatus == BeatmapSetOnlineStatus.Graveyard ||
                                                           x.RankedStatus == BeatmapSetOnlineStatus.Pending ||
                                                           x.RankedStatus == BeatmapSetOnlineStatus.Ranked ||
                                                           x.RankedStatus == BeatmapSetOnlineStatus.Loved
                                                       ) &&
                                                       (x.LastChecked.Value + TimeSpan.FromDays(30))
                                                       .Subtract(DateTime.Now).TotalMilliseconds < 0
                                                       ) ||
                                                   (
                                                       (
                                                           x.RankedStatus == BeatmapSetOnlineStatus.Qualified ||
                                                           x.RankedStatus == BeatmapSetOnlineStatus.WIP
                                                       ) &&
                                                       (x.LastChecked.Value + TimeSpan.FromDays(1))
                                                       .Subtract(DateTime.Now).TotalMilliseconds < 0
                                                   ) ||
                                                   (
                                                       (
                                                           x.RankedStatus == BeatmapSetOnlineStatus.Approved
                                                       ) &&
                                                       (x.LastChecked.Value + TimeSpan.FromDays(90))
                                                       .Subtract(DateTime.Now).TotalMilliseconds < 0
                                                   ))
                    );

                foreach (var bmSet in beatmapSets.ToList())
                {
                    bmSet.ChildrenBeatmaps = _factory.Get().Beatmaps.Where(x => x.ParentSetId == bmSet.SetId).ToList();
                    var setRequest = new GetBeatmapSetRequest(bmSet.SetId);
                    _rl.Limit();
                    setRequest.Perform(_apiAccess);

                    Logger.LogPrint("Updating BeatmapSetId " + bmSet.SetId);

                    var setInfo = setRequest.Result.ToBeatmapSet(_store);
                    var newBm   = BeatmapSet.FromBeatmapSetInfo(setInfo);

                    using var db = _factory.GetForWrite();

                    var hasChanged = false;
                    foreach (var cb in newBm.ChildrenBeatmaps)
                    {
                        var fInfo = _bmDl.Download(cb);
                        var ha    = _cFactory.Get().CacheBeatmaps.Where(b => b.Hash == fInfo.Hash).Select(f => f.FileMd5).FirstOrDefault();
                        cb.FileMd5 = ha;

                        db.Context.Entry(cb).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
                        db.Context.Beatmaps.Update(cb);

                        if (bmSet.ChildrenBeatmaps.Any(x => x.FileMd5 == ha))
                        {
                            continue;
                        }



                        hasChanged = true;
                    }

                    if (newBm.ChildrenBeatmaps.Count > bmSet.ChildrenBeatmaps.Count)
                    {
                        hasChanged = true;
                    }

                    var bmFileId      = newBm.SetId.ToString("x8");
                    var bmFileIdNoVid = newBm.SetId.ToString("x8") + "_novid";

                    if (hasChanged)
                    {
                        _storage.GetStorageForDirectory("cache").Delete(bmFileId);
                        _storage.GetStorageForDirectory("cache").Delete(bmFileIdNoVid);

                        _search.DeleteBeatmap(newBm.SetId);
                        _search.IndexBeatmap(newBm);
                    }

                    db.Context.Entry(newBm).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
                    db.Context.BeatmapSet.Update(newBm);

                    FileSafety.DeleteCleanupDirectory();
                }
            }
        }
Exemple #18
0
        public virtual async Task <bool> Crawl(int id)
        {
            var dbContext = _dbContextPool.Rent();

            Logger.LogPrint($"Crawling BeatmapId {id}...", LoggingTarget.Network, LogLevel.Debug);

            try
            {
                var beatmapSetRequest = new GetBeatmapSetRequest(id);
                beatmapSetRequest.Perform(ApiProvider);

                var beatmapSetInfo = beatmapSetRequest.Result;

                if (beatmapSetInfo == null)
                {
                    _errorCount++;
                    return(false);
                }

                var beatmapSet = BeatmapSet.FromBeatmapSetInfo(beatmapSetInfo.ToBeatmapSet());

                if (beatmapSet == null)
                {
                    _errorCount++;
                    return(false);
                }

                var cacheStorage = _storage.GetStorageForDirectory("cache");

                if (cacheStorage.Exists(beatmapSet.SetId.ToString("x8") + "_novid"))
                {
                    cacheStorage.Delete(beatmapSet.SetId.ToString("x8") + "_novid");
                }
                if (cacheStorage.Exists(beatmapSet.SetId.ToString("x8")))
                {
                    cacheStorage.Delete(beatmapSet.SetId.ToString("x8"));
                }

                foreach (var childrenBeatmap in beatmapSet.ChildrenBeatmaps)
                {
                    var fileInfo = _beatmapDownloader.Download(childrenBeatmap);

                    childrenBeatmap.FileMd5 = fileInfo.Item2;
                }

                dbContext.BeatmapSet.AddOrUpdate(beatmapSet);

                await dbContext.SaveChangesAsync();

                SearchEngine.Index(new [] { beatmapSet });

                _errorCount = 0;
                return(true);
            }
            catch (WebException) // Don't worry about WebException exceptions, we can safely ignore those.
            {
                _errorCount++;
                return(false);
            }
            catch (Exception e) // Everything else, redo the Crawl.
            {
                Logger.Error(e, "Unknown error during crawling occured!");

                SentrySdk.CaptureException(e);

                if (_errorCount > 1024)
                {
                    Logger.LogPrint("Error count too high! canceling crawl...", LoggingTarget.Network, LogLevel.Important);
                    return(false);
                }

                _errorCount++;
                return(await Crawl(id));
            } finally {
                _dbContextPool.Return(dbContext);
            }
        }
Exemple #19
0
        /// <summary>
        /// Handles an API request, while also updating the local state to match
        /// how the server would eventually respond and update an <see cref="RoomManager"/>.
        /// </summary>
        /// <param name="request">The API request to handle.</param>
        /// <param name="localUser">The local user to store in responses where required.</param>
        /// <param name="game">The game base for cases where actual online requests need to be sent.</param>
        /// <returns>Whether the request was successfully handled.</returns>
        public bool HandleRequest(APIRequest request, User localUser, OsuGameBase game)
        {
            switch (request)
            {
            case CreateRoomRequest createRoomRequest:
                var apiRoom = new Room();

                apiRoom.CopyFrom(createRoomRequest.Room);

                // Passwords are explicitly not copied between rooms.
                apiRoom.HasPassword.Value = !string.IsNullOrEmpty(createRoomRequest.Room.Password.Value);
                apiRoom.Password.Value    = createRoomRequest.Room.Password.Value;

                AddServerSideRoom(apiRoom);

                var responseRoom = new APICreatedRoom();
                responseRoom.CopyFrom(createResponseRoom(apiRoom, false));

                createRoomRequest.TriggerSuccess(responseRoom);
                return(true);

            case JoinRoomRequest joinRoomRequest:
            {
                var room = ServerSideRooms.Single(r => r.RoomID.Value == joinRoomRequest.Room.RoomID.Value);

                if (joinRoomRequest.Password != room.Password.Value)
                {
                    joinRoomRequest.TriggerFailure(new InvalidOperationException("Invalid password."));
                    return(true);
                }

                joinRoomRequest.TriggerSuccess();
                return(true);
            }

            case PartRoomRequest partRoomRequest:
                partRoomRequest.TriggerSuccess();
                return(true);

            case GetRoomsRequest getRoomsRequest:
                var roomsWithoutParticipants = new List <Room>();

                foreach (var r in ServerSideRooms)
                {
                    roomsWithoutParticipants.Add(createResponseRoom(r, false));
                }

                getRoomsRequest.TriggerSuccess(roomsWithoutParticipants);
                return(true);

            case GetRoomRequest getRoomRequest:
                getRoomRequest.TriggerSuccess(createResponseRoom(ServerSideRooms.Single(r => r.RoomID.Value == getRoomRequest.RoomId), true));
                return(true);

            case GetBeatmapSetRequest getBeatmapSetRequest:
                var onlineReq = new GetBeatmapSetRequest(getBeatmapSetRequest.ID, getBeatmapSetRequest.Type);
                onlineReq.Success += res => getBeatmapSetRequest.TriggerSuccess(res);
                onlineReq.Failure += e => getBeatmapSetRequest.TriggerFailure(e);

                // Get the online API from the game's dependencies.
                game.Dependencies.Get <IAPIProvider>().Queue(onlineReq);
                return(true);

            case CreateRoomScoreRequest createRoomScoreRequest:
                createRoomScoreRequest.TriggerSuccess(new APIScoreToken {
                    ID = 1
                });
                return(true);

            case SubmitRoomScoreRequest submitRoomScoreRequest:
                submitRoomScoreRequest.TriggerSuccess(new MultiplayerScore
                {
                    ID         = currentScoreId++,
                    Accuracy   = 1,
                    EndedAt    = DateTimeOffset.Now,
                    Passed     = true,
                    Rank       = ScoreRank.S,
                    MaxCombo   = 1000,
                    TotalScore = 1000000,
                    User       = localUser,
                    Statistics = new Dictionary <HitResult, int>()
                });
                return(true);
            }

            return(false);
        }