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