@@ -12,6 +12,7 @@ use urlencoding::{decode, encode};
1212use crate :: {
1313 app_handle,
1414 log:: { alert, log} ,
15+ set_ratelimit, set_thread_status,
1516} ;
1617
1718#[ derive( PartialEq , Clone , Debug ) ]
@@ -20,7 +21,7 @@ enum AccType {
2021 UNCLAIMED ,
2122}
2223
23- #[ derive( Debug ) ]
24+ #[ derive( Clone , Debug ) ]
2425pub struct Account {
2526 token : String ,
2627 refresh_token : String ,
@@ -90,7 +91,7 @@ impl Account {
9091 } else {
9192 ClientBuilder :: new ( ) . default_headers ( map) . build ( ) . ok ( ) ?
9293 } ;
93- if self . get_type ( ) == AccType :: UNCLAIMED {
94+ if self . acc_type == AccType :: UNCLAIMED {
9495 let data = format ! (
9596 r#"{{
9697 "profileName" : "{}"
@@ -222,12 +223,60 @@ impl Account {
222223 None
223224 }
224225
225- pub fn get_token ( & self ) -> String {
226- self . token . clone ( )
227- }
226+ pub fn check ( & self , name : String , proxy : Option < Proxy > ) -> Result < bool , String > {
227+ let client = match if let Some ( proxy) = proxy {
228+ ClientBuilder :: new ( ) . proxy ( proxy) . build ( )
229+ } else {
230+ ClientBuilder :: new ( ) . build ( )
231+ } {
232+ Ok ( c) => c,
233+ Err ( _) => return Err ( "Failed to build client for checking!" . to_string ( ) ) ,
234+ } ;
235+
236+ let Ok ( res) = client
237+ . get ( format ! (
238+ "https://api.minecraftservices.com/minecraft/profile/name/{}/available" ,
239+ name
240+ ) )
241+ . header ( "Authorization" , format ! ( "Bearer {}" , self . token) )
242+ . send ( )
243+ else {
244+ return Err ( "Failed to send request for checking" . to_string ( ) ) ;
245+ } ;
246+
247+ let status = res. status ( ) . as_u16 ( ) ;
248+ if status == 401 {
249+ return Err ( "A check request returned unathorized!" . to_string ( ) ) ;
250+ } else if status == 429 {
251+ set_ratelimit ( true ) ;
252+ return Err ( "Hit a ratelimit, sleeping for 300 seconds to clear it." . to_string ( ) ) ;
253+ } else if status != 200 {
254+ return Err ( format ! (
255+ "Checking request returned status code {} with body: {}" ,
256+ status,
257+ res. text( )
258+ . unwrap_or_else( |_| "Failed to get body." . to_string( ) )
259+ ) ) ;
260+ }
261+
262+ let Ok ( body) = res. text ( ) else {
263+ return Err ( "Failed to get body from check request." . to_string ( ) ) ;
264+ } ;
228265
229- fn get_type ( & self ) -> AccType {
230- self . acc_type . clone ( )
266+ if body. contains ( "AVAILABLE" ) {
267+ return Ok ( true ) ;
268+ } else if body. contains ( "DUPLICATE" ) {
269+ return Ok ( false ) ;
270+ } else if body. contains ( "NOT_ALLOWED" ) {
271+ alert ( "The name is blocked by mojang!" ) ;
272+ set_thread_status ( false ) ;
273+ return Err ( "The name is blocked by mojang!" . to_string ( ) ) ;
274+ } else {
275+ return Err ( format ! (
276+ "Check request response body is malformed: {}" ,
277+ body
278+ ) ) ;
279+ }
231280 }
232281
233282 fn check_type ( token : String , proxy : Option < Proxy > ) -> Option < AccType > {
@@ -277,7 +326,7 @@ impl Account {
277326 }
278327
279328 fn reauth ( & mut self , proxy : Option < Proxy > ) -> Result < ( ) , String > {
280- let Ok ( client) = ( if let Some ( proxy) = proxy {
329+ let Ok ( client) = ( if let Some ( proxy) = proxy. clone ( ) {
281330 ClientBuilder :: new ( ) . cookie_store ( true ) . proxy ( proxy) . build ( )
282331 } else {
283332 ClientBuilder :: new ( ) . cookie_store ( true ) . build ( )
@@ -301,11 +350,35 @@ impl Account {
301350 } ;
302351
303352 let Some ( access_token) = body. get ( "access_token" ) . and_then ( |v| v. as_str ( ) ) else {
304- return Err ( "No access_token in response!" . to_string ( ) ) ;
353+ log (
354+ "ERROR" ,
355+ Color :: from ( ( 255 , 0 , 0 ) ) ,
356+ "Failed to reauth with refresh_token, trying full auth!" ,
357+ ) ;
358+ match Self :: auth ( & self . user , & self . passwd , proxy) {
359+ Ok ( ( bearer, refresh_token) ) => {
360+ self . token = bearer;
361+ self . refresh_token = refresh_token;
362+ return Ok ( ( ) ) ;
363+ }
364+ Err ( e) => return Err ( e) ,
365+ }
305366 } ;
306367
307368 let Some ( refresh_token) = body. get ( "refresh_token" ) . and_then ( |v| v. as_str ( ) ) else {
308- return Err ( "No refresh_token in response!" . to_string ( ) ) ;
369+ log (
370+ "ERROR" ,
371+ Color :: from ( ( 255 , 0 , 0 ) ) ,
372+ "Failed to reauth with refresh_token, trying full auth!" ,
373+ ) ;
374+ match Self :: auth ( & self . user , & self . passwd , proxy) {
375+ Ok ( ( bearer, refresh_token) ) => {
376+ self . token = bearer;
377+ self . refresh_token = refresh_token;
378+ return Ok ( ( ) ) ;
379+ }
380+ Err ( e) => return Err ( e) ,
381+ }
309382 } ;
310383
311384 let body = json ! ( {
@@ -455,8 +528,8 @@ impl Account {
455528 let Ok ( res) = client. get ( "https://login.live.com/oauth20_authorize.srf?client_id=000000004C12AE6F&redirect_uri=https://login.live.com/oauth20_desktop.srf&scope=service::user.auth.xboxlive.com::MBI_SSL&display=touch&response_type=token&locale=en" ) . send ( ) else {
456529 return Err ( "Failed to send initial request for auth!" . to_string ( ) ) } ;
457530
458- let val_regex = Regex :: new ( "value=\" (.+ ?)\" " ) . unwrap ( ) ;
459- let url_post_regex = Regex :: new ( "urlPost:' (.+?)'" ) . unwrap ( ) ;
531+ let val_regex = Regex :: new ( r# "value=\\\ "(.* ?)\\\""# ) . unwrap ( ) ;
532+ let url_post_regex = Regex :: new ( r# "urlPost":" (.+?)""# ) . unwrap ( ) ;
460533
461534 let Ok ( res) = res. text ( ) else {
462535 return Err ( "Failed to extract text from initial request for auth!" . to_string ( ) ) ;
@@ -554,12 +627,12 @@ impl Account {
554627
555628 let body = json ! ( {
556629 "Properties" : {
557- "Authmethod " : "RPS" ,
558- "Sitename " : "user.auth.xboxlive.com" ,
559- "Rpsticket " : access_token,
630+ "AuthMethod " : "RPS" ,
631+ "SiteName " : "user.auth.xboxlive.com" ,
632+ "RpsTicket " : access_token,
560633 } ,
561- "Relyingparty " : "http://auth.xboxlive.com" ,
562- "Tokentype " : "JWT" ,
634+ "RelyingParty " : "http://auth.xboxlive.com" ,
635+ "TokenType " : "JWT" ,
563636 } ) ;
564637
565638 let mut headers = HeaderMap :: new ( ) ;
@@ -662,8 +735,8 @@ impl Account {
662735 } ;
663736
664737 let body = json ! ( {
665- "identityToken" : format!( "XBL3.0 x={};{}" , uhs, token) ,
666- "ensureLegacyEnabled" : true
738+ "identityToken" : dbg! ( format!( "XBL3.0 x={};{}" , uhs, token) ) ,
739+ "ensureLegacyEnabled" : true
667740 } ) ;
668741
669742 let Ok ( res) = client
@@ -674,9 +747,12 @@ impl Account {
674747 return Err ( "Failed to send request for bearer!" . to_string ( ) ) ;
675748 } ;
676749
677- let Ok ( data) = res. json :: < Value > ( ) else {
750+ println ! ( "{}" , res. text( ) . unwrap( ) ) ;
751+
752+ /* let Ok(data) = res.json::<Value>() else {
678753 return Err("Failed to parse response for bearer!".to_string());
679- } ;
754+ }; */
755+ let data = Value :: Null ;
680756
681757 let Some ( bearer) = data. get ( "access_token" ) . and_then ( |v| v. as_str ( ) ) else {
682758 return Err ( "Failed to extract bearer!" . to_string ( ) ) ;
0 commit comments