11using Grpc . Core ;
22using Limekuma . Prober . Common ;
3- using Limekuma . Prober . DivingFish ;
3+ using Limekuma . Prober . DivingFish . Enums ;
44using Limekuma . Prober . DivingFish . Models ;
55using Limekuma . Render ;
66using Limekuma . Utils ;
77using SixLabors . ImageSharp ;
88using System . Collections . Immutable ;
9- using System . Net ;
9+ using System . Text . Json . Serialization ;
1010
1111namespace Limekuma . Services ;
1212
1313public partial class BestsService
1414{
15+ private static async Task < ( CommonUser , ImmutableArray < CommonRecord > ) > PrepareDfRecordsForProcessAsync ( string token , uint ? qq , int ? frame , int ? plate , int ? icon )
16+ {
17+ ServiceExecutionHelper . EnsureArgument ( qq . HasValue && frame . HasValue && plate . HasValue && icon . HasValue ) ;
18+ PlayerData player = await DfGatewayService . GetPlayerDataAsync ( token , qq ! . Value ) ;
19+
20+ CommonUser user = player ;
21+ user . FrameId = frame ! . Value ;
22+ user . PlateId = plate ! . Value ;
23+ user . IconId = icon ! . Value ;
24+ return ( user , [ .. player . Records . ConvertAll < CommonRecord > ( _ => _ ) ] ) ;
25+ }
26+
1527 private static async Task < ( CommonUser , ImmutableArray < CommonRecord > , ImmutableArray < CommonRecord > , int , int ) > PrepareDfDataAsync (
16- uint qq , int frame , int plate , int icon )
28+ uint ? qq , int ? frame , int ? plate , int ? icon )
1729 {
18- DfResourceClient df = new ( ) ;
19- Player player ;
20- try
21- {
22- player = await df . GetPlayerAsync ( qq ) ;
23- }
24- catch ( HttpRequestException ex ) when ( ex . StatusCode is HttpStatusCode . BadRequest )
25- {
26- throw new RpcException ( new ( StatusCode . NotFound , ex . Message , ex ) ) ;
27- }
28- catch ( HttpRequestException ex ) when ( ex . StatusCode is HttpStatusCode . Forbidden )
29- {
30- throw new RpcException ( new ( StatusCode . PermissionDenied , ex . Message , ex ) ) ;
31- }
30+ ServiceExecutionHelper . EnsureArgument ( qq . HasValue && frame . HasValue && plate . HasValue && icon . HasValue ) ;
31+ Player player = await DfGatewayService . GetPlayerAsync ( qq ! . Value ) ;
3232
3333 CommonUser user = player ;
34- user . FrameId = frame ;
35- user . PlateId = plate ;
36- user . IconId = icon ;
34+ user . FrameId = frame ! . Value ;
35+ user . PlateId = plate ! . Value ;
36+ user . IconId = icon ! . Value ;
3737
3838 ImmutableArray < CommonRecord > bestEver = [ .. player . Bests . Ever . ConvertAll < CommonRecord > ( _ => _ ) . SortRecordForBests ( ) ] ;
3939 int everTotal = bestEver . Sum ( x => x . DXRating ) ;
@@ -46,14 +46,100 @@ public partial class BestsService
4646 return ( user , bestEver , bestCurrent , everTotal , currentTotal ) ;
4747 }
4848
49+ private static async Task < ( CommonUser , ImmutableArray < CommonRecord > , ImmutableArray < CommonRecord > , int , int ) > PrepareRiRenDfDataAsync ( )
50+ {
51+ List < CommonRecord > allRecords = [ ] ;
52+ foreach ( Song song in Songs . Shared )
53+ {
54+ if ( ! int . TryParse ( song . Id , out int id ) )
55+ {
56+ continue ;
57+ }
58+
59+ int chartCount = Math . Min ( song . Charts . Count , Math . Min ( song . LevelValues . Count , song . Levels . Count ) ) ;
60+ for ( int i = 0 ; i < chartCount ; i ++ )
61+ {
62+ allRecords . Add ( new Record ( )
63+ {
64+ Achievements = 101 ,
65+ ComboFlag = ComboFlags . AllPerfectPlus ,
66+ Difficulty = song . Type is SongTypes . Utage ? Difficulties . Utage : ( Difficulties ) ( i + 1 ) ,
67+ DifficultyIndex = i ,
68+ DXRating = ( int ) ( song . LevelValues [ i ] * 22.512 ) ,
69+ DXScore = song . Charts [ i ] . Notes . Total * 3 ,
70+ Id = id ,
71+ Level = song . Levels [ i ] ,
72+ LevelValue = song . LevelValues [ i ] ,
73+ Rank = Ranks . SSSPlus ,
74+ SyncFlag = SyncFlags . FullSyncDXPlus ,
75+ Title = song . Title ,
76+ Type = song . Type
77+ } ) ;
78+ }
79+ }
80+
81+ IEnumerable < CommonRecord > sortedRecords = allRecords . SortRecordForBests ( ) ;
82+ ImmutableArray < CommonRecord > bestEver = [ .. sortedRecords . Where ( record => ! record . Chart . Song . InCurrentGenre ) . Take ( 35 ) ] ;
83+ ImmutableArray < CommonRecord > bestCurrent = [ .. sortedRecords . Where ( record => record . Chart . Song . InCurrentGenre ) . Take ( 15 ) ] ;
84+ int everTotal = bestEver . Sum ( x => x . DXRating ) ;
85+ int currentTotal = bestCurrent . Sum ( x => x . DXRating ) ;
86+ CommonUser user = new ( )
87+ {
88+ Name = "DXKuma" ,
89+ Rating = everTotal + currentTotal ,
90+ TrophyColor = TrophyColor . Rainbow ,
91+ TrophyText = "でらっくま" ,
92+ CourseRank = CommonCourseRank . Urakaiden ,
93+ ClassRank = ClassRank . LEGEND ,
94+ IconId = 1 ,
95+ PlateId = 1 ,
96+ FrameId = 1
97+ } ;
98+
99+ await PrepareDataAsync ( user , bestEver , bestCurrent ) ;
100+ return ( user , bestEver , bestCurrent , everTotal , currentTotal ) ;
101+ }
102+
49103 public override async Task GetFromDivingFish ( DivingFishBestsRequest request ,
50104 IServerStreamWriter < ImageResponse > responseStream , ServerCallContext context )
51105 {
52- ( CommonUser user , ImmutableArray < CommonRecord > bestEver , ImmutableArray < CommonRecord > bestCurrent , int everTotal ,
53- int currentTotal ) = await PrepareDfDataAsync ( request . Qq , request . Frame , request . Plate , request . Icon ) ;
106+ CommonUser user ;
107+ CommonUser ? user2p = null ;
108+ ImmutableArray < CommonRecord > bestEver ;
109+ ImmutableArray < CommonRecord > bestCurrent ;
110+ int everTotal ;
111+ int currentTotal ;
112+ if ( ScoreProcesserHelper . GetProcesserByTags ( request . Tags ) is not null )
113+ {
114+ ( user , ImmutableArray < CommonRecord > records ) = await PrepareDfRecordsForProcessAsync ( request . Token , request . Qq , request . Frame , request . Plate , request . Icon ) ;
115+ ( bestEver , bestCurrent , everTotal , currentTotal , user2p ) = await ProcessBestsByTagsAsync (
116+ request . Tags ,
117+ request . Condition ,
118+ records ,
119+ async condition =>
120+ {
121+ CoopExtraInfo extraInfo = ServiceExecutionHelper . DeserializeOrThrow < CoopExtraInfo > ( condition , "Invalid arguments" ) ;
122+ return await PrepareDfRecordsForProcessAsync ( request . Token , extraInfo . Qq , extraInfo . Frame , extraInfo . Plate , extraInfo . Icon ) ;
123+ } ) ;
124+ }
125+ else if ( request . Tags . Contains ( "common" ) )
126+ {
127+ ( user , bestEver , bestCurrent , everTotal , currentTotal ) = await PrepareDfDataAsync ( request . Qq , request . Frame , request . Plate , request . Icon ) ;
128+ }
129+ else if ( request . Tags . Contains ( "riren" ) )
130+ {
131+ ( user , bestEver , bestCurrent , everTotal , currentTotal ) = await PrepareRiRenDfDataAsync ( ) ;
132+ }
133+ else
134+ {
135+ throw new RpcException ( new ( StatusCode . InvalidArgument , "Invalid arguments" ) ) ;
136+ }
137+
54138 using Image bestsImage = await new Drawer ( ) . DrawBestsAsync ( user , bestEver , bestCurrent , everTotal , currentTotal ,
55- request . Condition , "divingfish" , request . Tags ) ;
139+ request . Condition , "divingfish" , request . Tags , user2p ) ;
56140
57141 await responseStream . WriteToResponseAsync ( bestsImage ) ;
58142 }
59- }
143+
144+ public record CoopExtraInfo ( [ property: JsonPropertyName ( "qq" ) ] uint Qq , [ property: JsonPropertyName ( "frame" ) ] int Frame , [ property: JsonPropertyName ( "plate" ) ] int Plate , [ property: JsonPropertyName ( "icon" ) ] int Icon ) ;
145+ }
0 commit comments