1+ using System . Collections . Immutable ;
2+ using System . Drawing ;
3+ using System . Text ;
4+ using GitcgNetCord . MainApp . Entities . Repositories ;
5+ using HoyolabHttpClient ;
6+ using NetCord . Rest ;
7+ using NetCord . Services . ApplicationCommands ;
8+
9+ namespace GitcgNetCord . MainApp . Commands . Slash ;
10+
11+ public static class CardSlashCommand
12+ {
13+ public static async Task ExecuteAsync (
14+ HoyolabHttpClientService hoyolab ,
15+ IServiceProvider serviceProvider ,
16+ ApplicationCommandContext context ,
17+ [
18+ SlashCommandParameter (
19+ Description = "Minimum use count for a card to be considered. Default: 10."
20+ )
21+ ]
22+ int minUseCount = 10 ,
23+ [
24+ SlashCommandParameter (
25+ Description = "Number of top win rates to display. Default: 5."
26+ )
27+ ]
28+ int topWinRateCount = 5 ,
29+ [
30+ SlashCommandParameter (
31+ Description = "Number of top use counts to display. Default: 10."
32+ )
33+ ]
34+ int topUseCount = 10
35+ )
36+ {
37+ var activeHoyolabAccountService = serviceProvider
38+ . GetRequiredService < ActiveHoyolabAccountService > ( ) ;
39+
40+ await context . Interaction . SendResponseAsync (
41+ InteractionCallback . DeferredMessage ( )
42+ ) ;
43+
44+ var hoyolabAccount = await activeHoyolabAccountService
45+ . GetActiveHoyolabAccountAsync ( context . User . Id ) ;
46+
47+ if ( hoyolabAccount == null )
48+ {
49+ var commands = await context . Client . Rest
50+ . GetGlobalApplicationCommandsAsync ( context . Client . Id ) ;
51+
52+ var accountCommand = commands
53+ . First ( x => x . Name == "hoyolab-accounts" ) ;
54+
55+ await context . Interaction . ModifyResponseAsync ( message =>
56+ {
57+ message . AddEmbeds ( new EmbedProperties ( )
58+ . WithTitle ( "Error" )
59+ . WithDescription (
60+ $ """
61+ You don't have an active Hoyolab account.
62+ Please use the command { accountCommand } to set one up.
63+ """
64+ )
65+ . WithColor ( new NetCord . Color ( Color . Red . ToArgb ( ) ) )
66+ ) ;
67+ } ) ;
68+
69+ return ;
70+ }
71+
72+ var authorize = new HoyolabAuthorize (
73+ HoyolabUserId : hoyolabAccount . HoyolabUserId ,
74+ Token : hoyolabAccount . Token
75+ ) ;
76+
77+ var uid = hoyolabAccount . GameRoleId ;
78+ var server = hoyolabAccount . Region ;
79+
80+ HoyolabHttpClient . Responses . GcgCardList . Data data ;
81+ try
82+ {
83+ data = await hoyolab . GetGcgCardListAsync (
84+ server : server ,
85+ roleId : uid ,
86+ authorize : authorize
87+ ) ;
88+ }
89+ catch ( Exception e )
90+ {
91+ await context . Interaction . ModifyResponseAsync ( message =>
92+ {
93+ message . AddEmbeds ( new EmbedProperties ( )
94+ . WithTitle ( "Error" )
95+ . WithDescription ( e . Message )
96+ . WithColor ( new NetCord . Color ( Color . Red . ToArgb ( ) ) )
97+ ) ;
98+ } ) ;
99+ return ;
100+ }
101+
102+ var appEmojis = await context . Client . Rest
103+ . GetApplicationEmojisAsync ( context . Client . Id ) ;
104+ var emojis = appEmojis . ToImmutableDictionary ( x => x . Name ) ;
105+
106+ var winRate = data . CardList
107+ . Where ( x => x is
108+ {
109+ CardType : "CardTypeCharacter" ,
110+ UseCount : > 0
111+ }
112+ && x . UseCount > minUseCount
113+ )
114+ . Select ( x => new
115+ {
116+ x . Id , x . Name , x . Proficiency , x . UseCount ,
117+ WinRate = ( float ) x . Proficiency / x . UseCount
118+ } )
119+ . OrderByDescending ( x => x . WinRate )
120+ . ToImmutableArray ( ) ;
121+
122+ var bestWinRate = winRate
123+ . Take ( topWinRateCount )
124+ . ToImmutableArray ( ) ;
125+
126+ var lowestWinRate = winRate
127+ . TakeLast ( topWinRateCount )
128+ . Reverse ( )
129+ . ToImmutableArray ( ) ;
130+
131+ var topCharacterUseCounts = data . CardList
132+ . Where ( x => x . CardType == "CardTypeCharacter" )
133+ . Select ( x => new
134+ {
135+ x . Id , x . Name , x . UseCount
136+ } )
137+ . OrderByDescending ( x => x . UseCount )
138+ . Take ( topUseCount )
139+ . ToImmutableArray ( ) ;
140+
141+ var topActionUseCounts = data . CardList
142+ . Where ( x => x . CardType != "CardTypeCharacter" )
143+ . Select ( x => new
144+ {
145+ x . Id , x . Name , x . UseCount
146+ } )
147+ . OrderByDescending ( x => x . UseCount )
148+ . Take ( topUseCount )
149+ . ToImmutableArray ( ) ;
150+
151+ var bestWinRateStringBuilder = new StringBuilder ( ) ;
152+
153+ for ( var i = 0 ; i < bestWinRate . Length ; i ++ )
154+ {
155+ var x = bestWinRate [ i ] ;
156+
157+ bestWinRateStringBuilder . AppendLine (
158+ $ "{ i + 1 } . { emojis [ x . Id . ToString ( ) ] } { x . Name } - " +
159+ $ "{ x . WinRate : P2} " +
160+ $ "({ x . Proficiency } /{ x . UseCount } )"
161+ ) ;
162+ }
163+
164+ var lowestWinRateStringBuilder = new StringBuilder ( ) ;
165+ for ( var i = 0 ; i < lowestWinRate . Length ; i ++ )
166+ {
167+ var x = lowestWinRate [ i ] ;
168+
169+ lowestWinRateStringBuilder . AppendLine (
170+ $ "{ i + 1 } . { emojis [ x . Id . ToString ( ) ] } { x . Name } - " +
171+ $ "{ x . WinRate : P2} " +
172+ $ "({ x . Proficiency } /{ x . UseCount } )"
173+ ) ;
174+ }
175+
176+ var topUseCountsStringBuilder = new StringBuilder ( ) ;
177+ for ( var i = 0 ; i < topCharacterUseCounts . Length ; i ++ )
178+ {
179+ var card = topCharacterUseCounts [ i ] ;
180+
181+ topUseCountsStringBuilder . AppendLine (
182+ $ "{ i + 1 } . { card . Name } - { card . UseCount } "
183+ ) ;
184+ }
185+
186+ var topActionUseCountsStringBuilder = new StringBuilder ( ) ;
187+ for ( var i = 0 ; i < topActionUseCounts . Length ; i ++ )
188+ {
189+ var card = topActionUseCounts [ i ] ;
190+
191+ topActionUseCountsStringBuilder . AppendLine (
192+ $ "{ i + 1 } . { card . Name } - { card . UseCount } "
193+ ) ;
194+ }
195+
196+ await context . Interaction . ModifyResponseAsync ( message =>
197+ {
198+ message . AddEmbeds (
199+ new EmbedProperties ( )
200+ . WithColor ( new NetCord . Color ( Color . Purple . ToArgb ( ) ) )
201+ . WithTitle ( $ "{ data . Stats . Nickname } ")
202+ . AddFields (
203+ new EmbedFieldProperties ( )
204+ . WithName ( "Best win rate" )
205+ . WithValue ( bestWinRateStringBuilder . ToString ( ) )
206+ . WithInline ( ) ,
207+ new EmbedFieldProperties ( )
208+ . WithName ( "Lowest win rate" )
209+ . WithValue ( lowestWinRateStringBuilder . ToString ( ) )
210+ . WithInline ( )
211+ )
212+ )
213+ . AddEmbeds (
214+ new EmbedProperties ( )
215+ . WithColor ( new NetCord . Color ( Color . Purple . ToArgb ( ) ) )
216+ . AddFields (
217+ new EmbedFieldProperties ( )
218+ . WithName ( "Top character use counts" )
219+ . WithValue ( topUseCountsStringBuilder . ToString ( ) )
220+ . WithInline ( ) ,
221+ new EmbedFieldProperties ( )
222+ . WithName ( "Top action use counts" )
223+ . WithValue ( topActionUseCountsStringBuilder . ToString ( ) )
224+ . WithInline ( )
225+ )
226+ ) ;
227+ } ) ;
228+ }
229+ }
0 commit comments