package Ġxyz . gn ar bot . gn ar . apis . pat re on Ċ Ċ import Ġokhttp 3 . Http Url Ċ import Ġokhttp 3 . Request Ċ import Ġokhttp 3 . RequestBody Ċ import Ġorg . json . JSONObject Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġxyz . gn ar bot . gn ar . Bot Ċ import Ġxyz . gn ar bot . gn ar . utils . Request Util Ċ import Ġxyz . gn ar bot . gn ar . utils . extensions . build Url Ċ import Ġxyz . gn ar bot . gn ar . utils . extensions . open Private Channel ById Ċ import Ġxyz . gn ar bot . gn ar . utils . extensions . url Ċ import Ġjava . net . URI Ċ import Ġjava . net . URL Decoder Ċ import Ġjava . util . concurrent . Comp letableFuture Ċ import Ġjava . util . concurrent . Executors Ċ import Ġjava . util . concurrent . TimeUnit ĊĊ Ċ class ĠPat re on API ( var ĠaccessToken : ĠString ?) Ġ{ Ċ // Ġ( val ĠclientId : ĠString , Ġval Ġclient Secret : ĠString , Ġval Ġrefresh Token : ĠString ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġscheduler Ġ= ĠExec utors . new Single Thread Scheduled Executor () ĊĠĠĠ Ġ// var ĠaccessToken : ĠString Ġ= Ġ"" ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( accessToken ?. isEmpty () Ġ== Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Initial ising Ġsweep y Ġbo i Ġ// ĠSW EE PER ! ĠAW ĠMAN !") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġscheduler . schedule (:: sweep , Ġ 1 , ĠTimeUnit . DAYS ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsweep (): ĠCompletableFuture < Sweep Stats > Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġstored P led ges Ġ= ĠBot . getInstance (). db (). premium Users ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfetch P led ges (). then Apply Ġ{ Ġp led ges Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtotal Ġ= Ġstored P led ges . size ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġchanged Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġremoved Ġ= Ġ 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( entry Ġin Ġstored P led ges ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠuserId Ġ= Ġentry . id Long ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġp ledge Ġ= Ġp led ges . first OrNull Ġ{ Ġit . discord Id Ġ!= Ġnull Ġ&& Ġit . discord Id Ġ== ĠuserId Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( p ledge Ġ== Ġnull Ġ|| Ġp ledge . is Decl ined ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠBot . getInstance (). shard Manager . open Private Channel ById ( userId ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . sendMessage (" Your Ġp ledge Ġwas Ġeither Ġdecl ined Ġor Ġremoved Ġfrom ĠPat re on . Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" As Ġa Ġresult , Ġyour Ġper ks Ġhave Ġbeen Ġrev oked . ĠIf Ġyou Ġbelieve Ġthis Ġwas Ġin Ġerror , Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" check Ġyour Ġpayment Ġmethod . ĠIf Ġnot , Ġwe Ġhope ĠOct ave Ġexceeded Ġyour Ġexpectations , Ġand Ġ" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" we Ġhope Ġto Ġsee Ġyou Ġagain Ġsoon !") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. queue () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( guild Ġin Ġentry . premium Guild s List ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġguild . delete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . delete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġremoved ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġp led ging Ġ= Ġp ledge . p ledge C ents . toDouble () Ġ/ Ġ 1 0 0 ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( p led ging Ġ< Ġentry . p ledge Amount ) Ġ{ Ġ// ĠUser Ġis Ġp led ging Ġless Ġthan Ġwhat Ġwe Ġhave Ġstored . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġentry . set P ledge Amount ( p led ging ). save () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġent itled Servers Ġ= Ġentry . total Prem ium Guild Quota ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġactivated Servers Ġ= Ġentry . premium Guild s List ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexceed ing Limit By Ġ= Ġactivated Servers . size Ġ- Ġent itled Servers ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ex ceeding Limit By Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġremove Ġ= Ġ( 0 Ġuntil Ġexceed ing Limit By ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( unused Ġin Ġremove ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġactivated Servers . first OrNull ()?. delete () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠMessage Ġabout Ġremoved Ġguild s ? Ġeh ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġchanged ++ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠS weep Stats ( total , Ġchanged , Ġremoved ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠFetch Ġp led ges Ġfrom Ġdatabase . ĠIterate Ġthrough Ġresults Ġfrom Ġapi . ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġno Ġp ledge , Ġor Ġp ledge Ġis Ġdecl ined ; Ġremove Ġfrom ĠDB . ĠPur ge Ġprem ium Ġservers . ĊĠĠĠĠĠĠĠ Ġ// ĠIf Ġp ledge Amount Ġ< Ġstored , Ġremove Ġservers Ġuntil Ġquota Ġis Ġno Ġlonger Ġexceeded . ĊĠĠĠĠĠĠĠ Ġ// ĠThose Ġp led ging Ġmore Ġthan Ġstored , Ġupdate Ġamount ? ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġfetch P led ges ( campaign Id : ĠString Ġ= Ġ" 7 5 4 1 0 3 ") Ġ= Ġfetch P led ges Of Campaign 0 ( campaign Id ) Ċ Ċ // ĠĠĠ Ġfun Ġrefresh AccessToken () Ġ{ Ċ // ĠĠĠĠĠĠĠ Ġval Ġurl Ġ= ĠbaseUrl . newBuilder (). apply Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġadd Path Segment (" token ") Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter (" grant _ type ", Ġ" refresh _ token ") Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter (" refresh _ token ", Ġrefresh Token ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter (" client _ id ", ĠclientId ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġadd QueryParameter (" client _ secret ", Ġclient Secret ) Ċ // ĠĠĠĠĠĠĠ Ġ}. build () Ċ // ĠĠĠĠĠĠĠ Ġprintln ( url ) Ċ // Ċ // ĠĠĠĠĠĠĠ Ġrequest Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġurl ( url ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġpost ( RequestBody . create ( null , ĠByteArray ( 0 ))) Ċ // ĠĠĠĠĠĠĠ Ġ}. then Accept Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġit . getString (" access _ token ") Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexpires Epoch Seconds Ġ= Ġit . getLong (" expires _ in ") Ċ // Ċ // ĠĠĠĠĠĠĠĠĠĠĠ ĠaccessToken Ġ= Ġtoken Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġscheduler . schedule (:: refresh AccessToken , Ġexpires Epoch Seconds , ĠTimeUnit . SECONDS ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Successfully Ġref reshed ĠPat re on Ġaccess Ġtoken .") Ċ // ĠĠĠĠĠĠĠ Ġ}. exception ally Ġ{ Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" Unable Ġto Ġrefresh ĠPat re on Ġaccess Ġtoken !", Ġit ) Ċ // ĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ exception ally Ġnull Ċ // ĠĠĠĠĠĠĠ Ġ} Ċ // ĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfetch P led ges Of Campaign 0 ( campaign Id : ĠString , Ġoffset : ĠString ? Ġ= Ġnull ): ĠCompletableFuture < List < Pat re on User >> Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġusers Ġ= Ġmutable ListOf < Pat re on User >() ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfetch Page Of P ledge ( campaign Id , Ġoffset ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. then Compose Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġusers . addAll ( it . p led ges ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . hasMore ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfetch P led ges Of Campaign 0 ( campaign Id , Ġit . offset ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠCompletableFuture . completed Future ( emptyList ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. then Accept Ġ{ Ġusers . addAll ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. then Apply Ġ{ Ġusers Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfetch Page Of P ledge ( campaign Id : ĠString , Ġoffset : ĠString ?): ĠCompletableFuture < Result Page > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġget Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd Path Segments (" api / campaign s /$ campaign Id / p led ges ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġset QueryParameter (" include ", Ġ" p ledge , pat ron ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoffset ?. let Ġ{ Ġset QueryParameter (" page [ cursor ]", Ġit ) Ġ} ĊĠĠĠĠĠĠĠ Ġ}. then Apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġp led ges Ġ= Ġit . get JSONArray (" data ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Page Ġ= ĠgetNext Page ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġusers Ġ= Ġmutable ListOf < Pat re on User >() ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( index , Ġobj ) Ġin Ġit . get JSONArray (" included "). with Index ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobj Ġas ĠJSONObject ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( obj . getString (" type ") Ġ== Ġ" user ") Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġp ledge Ġ= Ġp led ges . getJSONObject ( index ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġusers . add ( Pat re on User . from JsonObject ( obj , Ġp ledge )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠResult Page ( users , Ġnext Page Ġ!= Ġnull , Ġnext Page ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠgetNext Page ( json : ĠJSONObject ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġjson . getJSONObject (" links ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. take If Ġ{ Ġit . has (" next ") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ Ġparse QueryString ( it . getString (" next ")) [" page [ cursor ] "] Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse QueryString ( url : ĠString ): ĠMap < String , ĠString > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠURI ( url ). query ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. split ('& ') ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . split (" =") Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. associate By ({ Ġdecode ( it [ 0 ]) Ġ}, Ġ{ Ġdecode ( it [ 1 ]) Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdecode ( s : ĠString ) Ġ= ĠURL Decoder . decode ( s , ĠChar sets . UTF _ 8 ) ĊĊĠĠĠ Ġprivate Ġfun Ġget ( url Opts : ĠHttp Url . Builder . () Ġ-> ĠUnit ): ĠCompletableFuture < JSONObject > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( accessToken ?. isNotEmpty () Ġ!= Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠCompletableFuture . failed Future ( IllegalStateException (" Access Ġtoken Ġis Ġempty ! ")) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġurl Ġ= ĠbaseUrl . newBuilder (). apply ( url Opts ). build () ĊĠĠĠĠĠĠĠ Ġreturn Ġrequest Ġ{ Ġurl ( url ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġrequest ( request Opts : ĠRequest . Builder . () Ġ-> ĠUnit ): ĠCompletableFuture < JSONObject > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠRequest Util . jsonObject ({ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapply ( request Opts ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġheader (" Authorization ", Ġ" Bearer Ġ$ accessToken ") ĊĠĠĠĠĠĠĠ Ġ}, Ġtrue ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval Ġlog Ġ= ĠLoggerFactory . getLogger ( Pat re on API :: class . java ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠbaseUrl Ġ= ĠHttp Url . get (" https :// www . pat re on . com / api / oauth 2 ") ĊĠĠĠ Ġ} Ċ } Ċ