2020-05-28 19:08:45 +08:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System ;
using System.Collections.Generic ;
2020-07-31 20:39:50 +08:00
using System.Linq ;
using System.Net ;
using Newtonsoft.Json.Linq ;
2020-05-28 19:08:45 +08:00
using NUnit.Framework ;
2024-11-27 13:55:02 +08:00
using osu.Framework.Graphics ;
2020-07-31 20:39:50 +08:00
using osu.Framework.Graphics.Containers ;
using osu.Framework.Testing ;
using osu.Game.Graphics.Containers ;
using osu.Game.Graphics.UserInterface ;
2020-05-28 19:08:45 +08:00
using osu.Game.Online.API ;
2020-07-31 20:39:50 +08:00
using osu.Game.Online.API.Requests ;
2021-11-04 17:02:44 +08:00
using osu.Game.Online.API.Requests.Responses ;
2024-01-16 01:47:46 +08:00
using osu.Game.Online.Placeholders ;
2020-12-25 12:38:11 +08:00
using osu.Game.Online.Rooms ;
2020-05-28 19:08:45 +08:00
using osu.Game.Rulesets.Osu ;
using osu.Game.Rulesets.Scoring ;
using osu.Game.Scoring ;
2020-12-25 23:50:00 +08:00
using osu.Game.Screens.OnlinePlay.Playlists ;
2020-07-31 20:39:50 +08:00
using osu.Game.Screens.Ranking ;
2020-05-28 19:08:45 +08:00
using osu.Game.Tests.Beatmaps ;
2021-12-13 15:34:48 +08:00
using osu.Game.Tests.Resources ;
2020-05-28 19:08:45 +08:00
2020-12-25 12:20:37 +08:00
namespace osu.Game.Tests.Visual.Playlists
2020-05-28 19:08:45 +08:00
{
2020-12-25 12:11:21 +08:00
public partial class TestScenePlaylistsResultsScreen : ScreenTestScene
2020-05-28 19:08:45 +08:00
{
2020-07-31 20:39:50 +08:00
private const int scores_per_result = 10 ;
2021-12-13 05:54:57 +08:00
private const int real_user_position = 200 ;
2020-07-31 20:39:50 +08:00
2024-11-27 13:55:02 +08:00
private ResultsScreen resultsScreen = null ! ;
2021-12-10 14:28:41 +08:00
2022-03-08 19:11:56 +08:00
private int lowestScoreId ; // Score ID of the lowest score in the list.
private int highestScoreId ; // Score ID of the highest score in the list.
2020-07-31 20:39:50 +08:00
private bool requestComplete ;
2021-10-08 14:18:01 +08:00
private int totalCount ;
2024-11-21 19:26:44 +08:00
private ScoreInfo userScore = null ! ;
2020-06-09 17:53:55 +08:00
2024-01-09 20:34:40 +08:00
[SetUpSteps]
public override void SetUpSteps ( )
2022-03-16 04:38:04 +08:00
{
base . SetUpSteps ( ) ;
2022-03-16 06:15:35 +08:00
// Previous test instances of the results screen may still exist at this point so wait for
// those screens to be cleaned up by the base SetUpSteps before re-initialising test state.
2023-12-31 21:10:49 +08:00
// The screen also holds a leased Beatmap bindable so reassigning it must happen after
// the screen has been exited.
2022-03-16 06:15:35 +08:00
AddStep ( "initialise user scores and beatmap" , ( ) = >
2022-03-16 04:38:04 +08:00
{
2022-03-16 06:15:35 +08:00
lowestScoreId = 1 ;
highestScoreId = 1 ;
requestComplete = false ;
totalCount = 0 ;
userScore = TestResources . CreateTestScoreInfo ( ) ;
userScore . TotalScore = 0 ;
userScore . Statistics = new Dictionary < HitResult , int > ( ) ;
2022-08-30 14:42:33 +08:00
userScore . MaximumStatistics = new Dictionary < HitResult , int > ( ) ;
2022-03-16 06:15:35 +08:00
// Beatmap is required to be an actual beatmap so the scores can get their scores correctly
// calculated for standardised scoring, else the tests that rely on ordering will fall over.
2022-03-16 04:38:04 +08:00
Beatmap . Value = CreateWorkingBeatmap ( Ruleset . Value ) ;
} ) ;
}
2020-05-28 19:08:45 +08:00
[Test]
2024-11-27 13:55:02 +08:00
public void TestShowUserScore ( )
2020-05-28 21:25:00 +08:00
{
2022-03-08 19:11:56 +08:00
AddStep ( "bind user score info handler" , ( ) = > bindHandler ( userScore : userScore ) ) ;
2020-07-31 20:39:50 +08:00
2024-11-27 13:55:02 +08:00
createResultsWithScore ( ( ) = > userScore ) ;
2024-01-09 20:28:46 +08:00
waitForDisplay ( ) ;
2020-07-31 20:39:50 +08:00
2021-12-10 14:37:12 +08:00
AddAssert ( "user score selected" , ( ) = > this . ChildrenOfType < ScorePanel > ( ) . Single ( p = > p . Score . OnlineID = = userScore . OnlineID ) . State = = PanelState . Expanded ) ;
2021-12-13 05:54:57 +08:00
AddAssert ( $"score panel position is {real_user_position}" ,
( ) = > this . ChildrenOfType < ScorePanel > ( ) . Single ( p = > p . Score . OnlineID = = userScore . OnlineID ) . ScorePosition . Value = = real_user_position ) ;
2020-05-28 21:25:00 +08:00
}
[Test]
2024-11-27 13:55:02 +08:00
public void TestShowUserBest ( )
{
AddStep ( "bind user score info handler" , ( ) = > bindHandler ( userScore : userScore ) ) ;
createUserBestResults ( ) ;
waitForDisplay ( ) ;
AddAssert ( "user score selected" , ( ) = > this . ChildrenOfType < ScorePanel > ( ) . Single ( p = > p . Score . UserID = = userScore . UserID ) . State = = PanelState . Expanded ) ;
AddAssert ( $"score panel position is {real_user_position}" ,
( ) = > this . ChildrenOfType < ScorePanel > ( ) . Single ( p = > p . Score . UserID = = userScore . UserID ) . ScorePosition . Value = = real_user_position ) ;
}
[Test]
public void TestShowNonUserScores ( )
2020-05-28 21:25:00 +08:00
{
2024-01-09 20:44:05 +08:00
AddStep ( "bind user score info handler" , ( ) = > bindHandler ( ) ) ;
2023-12-31 21:10:49 +08:00
2024-11-27 13:55:02 +08:00
createUserBestResults ( ) ;
2024-01-09 20:28:46 +08:00
waitForDisplay ( ) ;
2020-07-31 20:39:50 +08:00
AddAssert ( "top score selected" , ( ) = > this . ChildrenOfType < ScorePanel > ( ) . OrderByDescending ( p = > p . Score . TotalScore ) . First ( ) . State = = PanelState . Expanded ) ;
2020-06-09 17:53:55 +08:00
}
[Test]
2020-07-31 20:39:50 +08:00
public void TestShowUserScoreWithDelay ( )
{
2022-03-08 19:11:56 +08:00
AddStep ( "bind user score info handler" , ( ) = > bindHandler ( true , userScore ) ) ;
2020-07-31 20:39:50 +08:00
2024-11-27 13:55:02 +08:00
createResultsWithScore ( ( ) = > userScore ) ;
2024-01-09 20:28:46 +08:00
waitForDisplay ( ) ;
2020-07-31 20:39:50 +08:00
AddAssert ( "more than 1 panel displayed" , ( ) = > this . ChildrenOfType < ScorePanel > ( ) . Count ( ) > 1 ) ;
2021-12-10 14:37:12 +08:00
AddAssert ( "user score selected" , ( ) = > this . ChildrenOfType < ScorePanel > ( ) . Single ( p = > p . Score . OnlineID = = userScore . OnlineID ) . State = = PanelState . Expanded ) ;
2020-07-31 20:39:50 +08:00
}
[Test]
2024-11-27 13:55:02 +08:00
public void TestShowNonUserScoresWithDelay ( )
2020-06-09 17:53:55 +08:00
{
2021-02-22 14:43:58 +08:00
AddStep ( "bind delayed handler" , ( ) = > bindHandler ( true ) ) ;
2020-07-31 20:39:50 +08:00
2024-11-27 13:55:02 +08:00
createUserBestResults ( ) ;
2024-01-09 20:28:46 +08:00
waitForDisplay ( ) ;
2020-07-31 20:39:50 +08:00
AddAssert ( "top score selected" , ( ) = > this . ChildrenOfType < ScorePanel > ( ) . OrderByDescending ( p = > p . Score . TotalScore ) . First ( ) . State = = PanelState . Expanded ) ;
2020-05-28 21:25:00 +08:00
}
2020-07-31 20:39:50 +08:00
[Test]
public void TestFetchWhenScrolledToTheRight ( )
{
2024-01-09 20:44:05 +08:00
AddStep ( "bind delayed handler" , ( ) = > bindHandler ( true ) ) ;
2023-12-31 21:10:49 +08:00
2024-11-27 13:55:02 +08:00
createUserBestResults ( ) ;
2024-01-09 20:28:46 +08:00
waitForDisplay ( ) ;
2020-07-31 20:39:50 +08:00
for ( int i = 0 ; i < 2 ; i + + )
{
int beforePanelCount = 0 ;
AddStep ( "get panel count" , ( ) = > beforePanelCount = this . ChildrenOfType < ScorePanel > ( ) . Count ( ) ) ;
2024-11-27 13:55:02 +08:00
AddStep ( "scroll to right" , ( ) = > resultsScreen . ChildrenOfType < ScorePanelList > ( ) . Single ( ) . ChildrenOfType < OsuScrollContainer > ( ) . Single ( ) . ScrollToEnd ( false ) ) ;
AddAssert ( "right loading spinner shown" , ( ) = >
resultsScreen . ChildrenOfType < LoadingSpinner > ( ) . Single ( l = > l . Anchor = = Anchor . CentreRight ) . State . Value = = Visibility . Visible ) ;
2020-07-31 20:39:50 +08:00
waitForDisplay ( ) ;
2024-07-25 13:38:20 +08:00
AddAssert ( $"count increased by {scores_per_result}" , ( ) = > this . ChildrenOfType < ScorePanel > ( ) . Count ( ) = = beforePanelCount + scores_per_result ) ;
2024-11-27 13:55:02 +08:00
AddAssert ( "right loading spinner hidden" , ( ) = >
resultsScreen . ChildrenOfType < LoadingSpinner > ( ) . Single ( l = > l . Anchor = = Anchor . CentreRight ) . State . Value = = Visibility . Hidden ) ;
2020-07-31 20:39:50 +08:00
}
}
2024-01-16 01:47:46 +08:00
[Test]
public void TestNoMoreScoresToTheRight ( )
{
AddStep ( "bind delayed handler with scores" , ( ) = > bindHandler ( delayed : true ) ) ;
2024-11-27 13:55:02 +08:00
createUserBestResults ( ) ;
2024-01-16 01:47:46 +08:00
waitForDisplay ( ) ;
int beforePanelCount = 0 ;
AddStep ( "get panel count" , ( ) = > beforePanelCount = this . ChildrenOfType < ScorePanel > ( ) . Count ( ) ) ;
2024-11-27 13:55:02 +08:00
AddStep ( "scroll to right" , ( ) = > resultsScreen . ChildrenOfType < ScorePanelList > ( ) . Single ( ) . ChildrenOfType < OsuScrollContainer > ( ) . Single ( ) . ScrollToEnd ( false ) ) ;
AddAssert ( "right loading spinner shown" , ( ) = >
resultsScreen . ChildrenOfType < LoadingSpinner > ( ) . Single ( l = > l . Anchor = = Anchor . CentreRight ) . State . Value = = Visibility . Visible ) ;
2024-01-16 01:47:46 +08:00
waitForDisplay ( ) ;
2024-07-25 13:38:20 +08:00
AddAssert ( $"count increased by {scores_per_result}" , ( ) = > this . ChildrenOfType < ScorePanel > ( ) . Count ( ) = = beforePanelCount + scores_per_result ) ;
2024-11-27 13:55:02 +08:00
AddAssert ( "right loading spinner hidden" , ( ) = >
resultsScreen . ChildrenOfType < LoadingSpinner > ( ) . Single ( l = > l . Anchor = = Anchor . CentreRight ) . State . Value = = Visibility . Hidden ) ;
2024-01-16 01:47:46 +08:00
AddStep ( "get panel count" , ( ) = > beforePanelCount = this . ChildrenOfType < ScorePanel > ( ) . Count ( ) ) ;
AddStep ( "bind delayed handler with no scores" , ( ) = > bindHandler ( delayed : true , noScores : true ) ) ;
2024-11-27 13:55:02 +08:00
AddStep ( "scroll to right" , ( ) = > resultsScreen . ChildrenOfType < ScorePanelList > ( ) . Single ( ) . ChildrenOfType < OsuScrollContainer > ( ) . Single ( ) . ScrollToEnd ( false ) ) ;
AddAssert ( "right loading spinner shown" , ( ) = >
resultsScreen . ChildrenOfType < LoadingSpinner > ( ) . Single ( l = > l . Anchor = = Anchor . CentreRight ) . State . Value = = Visibility . Visible ) ;
2024-01-16 01:47:46 +08:00
waitForDisplay ( ) ;
AddAssert ( "count not increased" , ( ) = > this . ChildrenOfType < ScorePanel > ( ) . Count ( ) = = beforePanelCount ) ;
2024-11-27 13:55:02 +08:00
AddAssert ( "right loading spinner hidden" , ( ) = >
resultsScreen . ChildrenOfType < LoadingSpinner > ( ) . Single ( l = > l . Anchor = = Anchor . CentreRight ) . State . Value = = Visibility . Hidden ) ;
2024-01-16 01:47:46 +08:00
AddAssert ( "no placeholders shown" , ( ) = > this . ChildrenOfType < MessagePlaceholder > ( ) . Count ( ) , ( ) = > Is . Zero ) ;
}
2020-07-31 20:39:50 +08:00
[Test]
public void TestFetchWhenScrolledToTheLeft ( )
{
2022-03-08 19:11:56 +08:00
AddStep ( "bind user score info handler" , ( ) = > bindHandler ( userScore : userScore ) ) ;
2020-07-31 20:39:50 +08:00
2024-11-27 13:55:02 +08:00
createResultsWithScore ( ( ) = > userScore ) ;
2024-01-09 20:28:46 +08:00
waitForDisplay ( ) ;
2020-07-31 20:39:50 +08:00
2021-02-22 14:43:58 +08:00
AddStep ( "bind delayed handler" , ( ) = > bindHandler ( true ) ) ;
2020-07-31 20:39:50 +08:00
for ( int i = 0 ; i < 2 ; i + + )
{
int beforePanelCount = 0 ;
AddStep ( "get panel count" , ( ) = > beforePanelCount = this . ChildrenOfType < ScorePanel > ( ) . Count ( ) ) ;
2024-11-27 13:55:02 +08:00
AddStep ( "scroll to left" , ( ) = > resultsScreen . ChildrenOfType < ScorePanelList > ( ) . Single ( ) . ChildrenOfType < OsuScrollContainer > ( ) . Single ( ) . ScrollToStart ( false ) ) ;
AddAssert ( "left loading spinner shown" , ( ) = >
resultsScreen . ChildrenOfType < LoadingSpinner > ( ) . Single ( l = > l . Anchor = = Anchor . CentreLeft ) . State . Value = = Visibility . Visible ) ;
2020-07-31 20:39:50 +08:00
waitForDisplay ( ) ;
2024-07-25 13:38:20 +08:00
AddAssert ( $"count increased by {scores_per_result}" , ( ) = > this . ChildrenOfType < ScorePanel > ( ) . Count ( ) = = beforePanelCount + scores_per_result ) ;
2024-11-27 13:55:02 +08:00
AddAssert ( "left loading spinner hidden" , ( ) = >
resultsScreen . ChildrenOfType < LoadingSpinner > ( ) . Single ( l = > l . Anchor = = Anchor . CentreLeft ) . State . Value = = Visibility . Hidden ) ;
2020-07-31 20:39:50 +08:00
}
}
2024-11-27 13:55:02 +08:00
/// <summary>
/// Shows the <see cref="TestUserBestResultsScreen"/> with no scores provided by the API.
/// </summary>
2023-12-31 21:10:49 +08:00
[Test]
2024-11-27 13:55:02 +08:00
public void TestShowUserBestWithNoScoresPresent ( )
2023-12-31 21:10:49 +08:00
{
2024-01-09 20:44:05 +08:00
AddStep ( "bind user score info handler" , ( ) = > bindHandler ( noScores : true ) ) ;
2024-11-27 13:55:02 +08:00
createUserBestResults ( ) ;
AddAssert ( "no scores visible" , ( ) = > ! resultsScreen . ChildrenOfType < ScorePanelList > ( ) . Single ( ) . GetScorePanels ( ) . Any ( ) ) ;
2024-01-16 01:49:41 +08:00
AddAssert ( "placeholder shown" , ( ) = > this . ChildrenOfType < MessagePlaceholder > ( ) . Count ( ) , ( ) = > Is . EqualTo ( 1 ) ) ;
2023-12-31 21:10:49 +08:00
}
2024-11-27 13:55:02 +08:00
private void createResultsWithScore ( Func < ScoreInfo > getScore )
2020-06-09 17:53:55 +08:00
{
AddStep ( "load results" , ( ) = >
{
2024-11-27 13:55:02 +08:00
LoadScreen ( resultsScreen = new TestScoreResultsScreen ( getScore ( ) , 1 , new PlaylistItem ( new TestBeatmap ( new OsuRuleset ( ) . RulesetInfo ) . BeatmapInfo )
2020-06-09 17:53:55 +08:00
{
2022-02-15 15:01:14 +08:00
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
2020-06-09 17:53:55 +08:00
} ) ) ;
} ) ;
2021-09-06 19:20:52 +08:00
2021-12-20 15:58:16 +08:00
AddUntilStep ( "wait for screen to load" , ( ) = > resultsScreen . IsLoaded ) ;
2020-06-09 17:53:55 +08:00
}
2024-11-27 13:55:02 +08:00
private void createUserBestResults ( )
{
AddStep ( "load results" , ( ) = >
{
LoadScreen ( resultsScreen = new TestUserBestResultsScreen ( 1 , new PlaylistItem ( new TestBeatmap ( new OsuRuleset ( ) . RulesetInfo ) . BeatmapInfo )
{
RulesetID = new OsuRuleset ( ) . RulesetInfo . OnlineID
} , 2 ) ) ;
} ) ;
AddUntilStep ( "wait for screen to load" , ( ) = > resultsScreen . IsLoaded ) ;
}
2024-01-09 20:28:46 +08:00
private void waitForDisplay ( )
2020-05-28 19:08:45 +08:00
{
2021-12-20 15:58:16 +08:00
AddUntilStep ( "wait for scores loaded" , ( ) = >
2021-10-08 14:18:01 +08:00
requestComplete
2022-05-30 18:29:13 +08:00
// request handler may need to fire more than once to get scores.
& & totalCount > 0
2024-11-27 13:55:02 +08:00
& & resultsScreen . ChildrenOfType < ScorePanelList > ( ) . Single ( ) . GetScorePanels ( ) . Count ( ) = = totalCount
& & resultsScreen . ChildrenOfType < ScorePanelList > ( ) . Single ( ) . AllPanelsVisible ) ;
2020-07-31 20:39:50 +08:00
AddWaitStep ( "wait for display" , 5 ) ;
}
2024-11-21 19:26:44 +08:00
private void bindHandler ( bool delayed = false , ScoreInfo ? userScore = null , bool failRequests = false , bool noScores = false ) = > ( ( DummyAPIAccess ) API ) . HandleRequest = request = >
2020-07-31 20:39:50 +08:00
{
2021-03-23 17:08:32 +08:00
// pre-check for requests we should be handling (as they are scheduled below).
switch ( request )
{
2024-11-26 14:01:59 +08:00
case ShowPlaylistScoreRequest :
2024-11-27 13:55:02 +08:00
case ShowPlaylistUserScoreRequest :
2022-06-24 20:25:23 +08:00
case IndexPlaylistScoresRequest :
2021-03-23 17:08:32 +08:00
break ;
default :
return false ;
}
2020-07-31 20:39:50 +08:00
requestComplete = false ;
2021-02-22 14:43:58 +08:00
double delay = delayed ? 3000 : 0 ;
2020-07-31 20:39:50 +08:00
2021-02-22 14:43:58 +08:00
Scheduler . AddDelayed ( ( ) = >
2020-07-31 20:39:50 +08:00
{
2021-02-22 14:43:58 +08:00
if ( failRequests )
{
triggerFail ( request ) ;
return ;
}
switch ( request )
{
2024-11-26 14:01:59 +08:00
case ShowPlaylistScoreRequest s :
2021-02-22 14:43:58 +08:00
if ( userScore = = null )
triggerFail ( s ) ;
else
triggerSuccess ( s , createUserResponse ( userScore ) ) ;
2021-10-08 14:18:01 +08:00
2021-02-22 14:43:58 +08:00
break ;
2024-11-27 13:55:02 +08:00
case ShowPlaylistUserScoreRequest u :
if ( userScore = = null )
triggerFail ( u ) ;
else
triggerSuccess ( u , createUserResponse ( userScore ) ) ;
break ;
2021-02-22 14:43:58 +08:00
case IndexPlaylistScoresRequest i :
2023-12-31 21:10:49 +08:00
triggerSuccess ( i , createIndexResponse ( i , noScores ) ) ;
2021-02-22 14:43:58 +08:00
break ;
}
} , delay ) ;
2021-03-23 17:08:32 +08:00
return true ;
2020-07-31 20:39:50 +08:00
} ;
2020-05-28 19:08:45 +08:00
2021-02-22 14:43:58 +08:00
private void triggerSuccess < T > ( APIRequest < T > req , T result )
2020-07-31 20:39:50 +08:00
where T : class
{
2021-02-22 14:43:58 +08:00
requestComplete = true ;
req . TriggerSuccess ( result ) ;
2020-07-31 20:39:50 +08:00
}
2021-02-22 14:43:58 +08:00
private void triggerFail ( APIRequest req )
2020-07-31 20:39:50 +08:00
{
2021-02-22 14:43:58 +08:00
requestComplete = true ;
req . TriggerFailure ( new WebException ( "Failed." ) ) ;
2020-07-31 20:39:50 +08:00
}
2024-11-21 19:26:44 +08:00
private MultiplayerScore createUserResponse ( ScoreInfo userScore )
2020-07-31 20:39:50 +08:00
{
var multiplayerUserScore = new MultiplayerScore
{
2022-03-08 19:11:56 +08:00
ID = highestScoreId ,
2020-07-31 20:39:50 +08:00
Accuracy = userScore . Accuracy ,
Passed = userScore . Passed ,
Rank = userScore . Rank ,
2021-12-13 05:54:57 +08:00
Position = real_user_position ,
2020-07-31 20:39:50 +08:00
MaxCombo = userScore . MaxCombo ,
User = userScore . User ,
ScoresAround = new MultiplayerScoresAround
{
Higher = new MultiplayerScores ( ) ,
Lower = new MultiplayerScores ( )
}
} ;
2021-10-08 14:18:01 +08:00
totalCount + + ;
2020-07-31 20:39:50 +08:00
for ( int i = 1 ; i < = scores_per_result ; i + + )
{
multiplayerUserScore . ScoresAround . Lower . Scores . Add ( new MultiplayerScore
{
2022-04-11 14:38:11 +08:00
ID = getNextLowestScoreId ( ) ,
2020-07-31 20:39:50 +08:00
Accuracy = userScore . Accuracy ,
Passed = true ,
Rank = userScore . Rank ,
MaxCombo = userScore . MaxCombo ,
2021-11-04 17:02:44 +08:00
User = new APIUser
2020-07-31 20:39:50 +08:00
{
2024-11-27 13:55:02 +08:00
Id = 2 + i ,
2020-07-31 20:39:50 +08:00
Username = $"peppy{i}" ,
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg" ,
} ,
} ) ;
multiplayerUserScore . ScoresAround . Higher . Scores . Add ( new MultiplayerScore
{
2022-04-11 14:38:11 +08:00
ID = getNextHighestScoreId ( ) ,
2020-07-31 20:39:50 +08:00
Accuracy = userScore . Accuracy ,
Passed = true ,
Rank = userScore . Rank ,
MaxCombo = userScore . MaxCombo ,
2021-11-04 17:02:44 +08:00
User = new APIUser
2020-07-31 20:39:50 +08:00
{
2024-11-27 13:55:02 +08:00
Id = 2 + i ,
2020-07-31 20:39:50 +08:00
Username = $"peppy{i}" ,
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg" ,
} ,
} ) ;
2021-10-08 14:18:01 +08:00
totalCount + = 2 ;
2020-07-31 20:39:50 +08:00
}
addCursor ( multiplayerUserScore . ScoresAround . Lower ) ;
addCursor ( multiplayerUserScore . ScoresAround . Higher ) ;
return multiplayerUserScore ;
}
2023-12-31 21:10:49 +08:00
private IndexedMultiplayerScores createIndexResponse ( IndexPlaylistScoresRequest req , bool noScores = false )
2020-07-31 20:39:50 +08:00
{
var result = new IndexedMultiplayerScores ( ) ;
2023-12-31 21:10:49 +08:00
if ( noScores ) return result ;
2020-07-31 20:39:50 +08:00
string sort = req . IndexParams ? . Properties [ "sort" ] . ToObject < string > ( ) ? ? "score_desc" ;
for ( int i = 1 ; i < = scores_per_result ; i + + )
{
result . Scores . Add ( new MultiplayerScore
{
2022-04-11 14:38:11 +08:00
ID = sort = = "score_asc" ? getNextHighestScoreId ( ) : getNextLowestScoreId ( ) ,
2020-07-31 20:39:50 +08:00
Accuracy = 1 ,
2020-05-28 19:08:45 +08:00
Passed = true ,
2020-07-31 20:39:50 +08:00
Rank = ScoreRank . X ,
MaxCombo = 1000 ,
2021-11-04 17:02:44 +08:00
User = new APIUser
2020-05-28 19:08:45 +08:00
{
2024-11-27 13:55:02 +08:00
Id = 2 + i ,
2020-05-28 19:08:45 +08:00
Username = $"peppy{i}" ,
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg" ,
} ,
} ) ;
2021-10-08 14:18:01 +08:00
totalCount + + ;
2020-05-28 19:08:45 +08:00
}
2020-07-31 20:39:50 +08:00
addCursor ( result ) ;
return result ;
}
2022-04-11 14:38:11 +08:00
/// <summary>
/// The next highest score ID to appear at the left of the list. Monotonically decreasing.
/// </summary>
private int getNextHighestScoreId ( ) = > - - highestScoreId ;
/// <summary>
/// The next lowest score ID to appear at the right of the list. Monotonically increasing.
/// </summary>
/// <returns></returns>
private int getNextLowestScoreId ( ) = > + + lowestScoreId ;
2020-07-31 20:39:50 +08:00
private void addCursor ( MultiplayerScores scores )
{
scores . Cursor = new Cursor
{
Properties = new Dictionary < string , JToken >
{
{ "total_score" , JToken . FromObject ( scores . Scores [ ^ 1 ] . TotalScore ) } ,
{ "score_id" , JToken . FromObject ( scores . Scores [ ^ 1 ] . ID ) } ,
}
} ;
scores . Params = new IndexScoresParams
2020-05-28 19:08:45 +08:00
{
2020-07-31 20:39:50 +08:00
Properties = new Dictionary < string , JToken >
2020-05-28 19:08:45 +08:00
{
2022-04-11 14:38:11 +08:00
// [ 1, 2, 3, ... ] => score_desc (will be added to the right of the list)
// [ 3, 2, 1, ... ] => score_asc (will be added to the left of the list)
{ "sort" , JToken . FromObject ( scores . Scores [ ^ 1 ] . ID > scores . Scores [ ^ 2 ] . ID ? "score_desc" : "score_asc" ) }
2020-06-09 17:53:55 +08:00
}
} ;
2020-05-28 19:08:45 +08:00
}
2020-07-31 20:39:50 +08:00
2024-11-27 13:55:02 +08:00
private partial class TestScoreResultsScreen : PlaylistItemScoreResultsScreen
2020-07-31 20:39:50 +08:00
{
2024-11-27 13:55:02 +08:00
public TestScoreResultsScreen ( ScoreInfo score , int roomId , PlaylistItem playlistItem )
2024-02-23 02:15:02 +08:00
: base ( score , roomId , playlistItem )
2020-07-31 20:39:50 +08:00
{
2024-02-23 02:15:02 +08:00
AllowRetry = true ;
2020-07-31 20:39:50 +08:00
}
}
2024-11-27 13:55:02 +08:00
private partial class TestUserBestResultsScreen : PlaylistItemUserBestResultsScreen
{
public TestUserBestResultsScreen ( int roomId , PlaylistItem playlistItem , int userId )
: base ( roomId , playlistItem , userId )
{
AllowRetry = true ;
}
}
2020-05-28 19:08:45 +08:00
}
}