/* Ċ Ġ* ĠĠĠ ĠCopyright Ġ 2 0 1 9 - 2 0 2 0 ĠFl orian ĠSp ie ÃŁ Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ @ file : Jvm Name (" Main ") Ċ package Ġclub . min n ced . bot Ċ Ċ import Ġclub . min n ced . bot . command .* Ċ import Ġclub . min n ced . bot . mod eration . on Member Ban Ċ import Ġclub . min n ced . bot . mod eration . on Member Kick Ċ import Ġclub . min n ced . bot . mod eration . on Member Un ban Ċ import Ġclub . min n ced . j da . reactor . as Mono Ċ import Ġclub . min n ced . j da . reactor . create Manager Ċ import Ġclub . min n ced . j da . reactor . on Ċ import Ġkotlinx . coroutines . reactive . await First OrNull Ċ import Ġkotlinx . coroutines . reactor . mono Ċ import Ġnet . dv 8 tion . j da . api . J DA Builder Ċ import Ġnet . dv 8 tion . j da . api . Online Status Ċ import Ġnet . dv 8 tion . j da . api . Permission Ċ import Ġnet . dv 8 tion . j da . api . entities . Activity Ċ import Ġnet . dv 8 tion . j da . api . events . Ready Event Ċ import Ġnet . dv 8 tion . j da . api . events . Shutdown Event Ċ import Ġnet . dv 8 tion . j da . api . events . guild . Generic Guild Event Ċ import Ġnet . dv 8 tion . j da . api . events . guild . Guild Ban Event Ċ import Ġnet . dv 8 tion . j da . api . events . guild . Guild Un ban Event Ċ import Ġnet . dv 8 tion . j da . api . events . guild . member . Guild Member Remove Event Ċ import Ġnet . dv 8 tion . j da . api . events . message . Message Received Event Ċ import Ġnet . dv 8 tion . j da . api . requests . Gateway Intent .* Ċ import Ġreactor . core . publisher . Mono Ċ import Ġreactor . core . scheduler . Schedulers Ċ import Ġjava . io . File Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Executors Ċ import Ġjava . util . concurrent . Fork Join Pool Ċ import Ġkotlin . concurrent . thread Ċ import Ġkotlin . system . exit Process Ċ Ċ fun Ġmain ( args : ĠArray < String >) Ġ{ ĊĠĠĠ Ġval Ġtoken Ġ= ĠgetToken ( args ) ĊĊĠĠĠ Ġ// ĠCreate Ġa Ġshared Ġexecutor Ġfor Ġthe Ġflux Ġprocessor Ġand ĠJ DA ĊĠĠĠ Ġvar Ġcount Ġ= Ġ 0 ĊĠĠĠ Ġval Ġexecutor Ġ= ĠExec utors . new Scheduled ThreadPool ( Fork Join Pool . get Common Pool Parallel ism ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġthread ( start = false , Ġblock = it :: run , Ġname =" j da - thread -${ count ++ }", Ġis Daemon = true ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠWrap Ġexecutor Ġin Ġscheduler Ġfor Ġflux Ġprocessor ĊĠĠĠ Ġval Ġscheduler Wrap Ġ= ĠS chedulers . from Executor ( executor ) ĊĊĠĠĠ Ġ// ĠCreate Ġa Ġreactive Ġevent Ġmanager Ġwith Ġthe Ġscheduler ĊĠĠĠ Ġval Ġmanager Ġ= Ġcreate Manager Ġ{ ĊĠĠĠĠĠĠĠ Ġscheduler Ġ= Ġscheduler Wrap ĊĠĠĠĠĠĠĠ Ġis Dispose Ġ= Ġfalse Ġ// ĠThe Ġscheduler Ġuses Ġa Ġdaemon Ġpool Ġso Ġit Ġdoesn 't Ġneed Ġto Ġbe Ġshutdown Ġhere Ġsince Ġthe ĠJVM Ġwill Ġterminate Ġanyway ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠApply Ġready Ġhandler Ġbefore Ġcalling Ġbuild () Ġto Ġavoid Ġrace Ġcondition ĊĠĠĠ Ġmanager . on < Ready Event >() ĊĠĠĠĠĠĠĠ Ġ// ĠConvert Ġto ĠMono < Ready Event > Ġto Ġsimplify ĊĠĠĠĠĠĠĠ Ġ. next () ĊĠĠĠĠĠĠĠ Ġ// ĠTake Ġthe ĠJ DA Ġinstance ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . j da Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠREAD Y Ġ-> Ġset Ġstatus Ġfrom ĠD ND Ġto ĠON LINE ĊĠĠĠĠĠĠĠ Ġ. do On Success Ġ{ Ġit . presence . setStatus ( Online Status . ON LINE ) Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠRetrieve Ġbot Ġowner ĊĠĠĠĠĠĠĠ Ġ. flatMap Ġ{ Ġit . retrieve Application Info (). as Mono () Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġonly Ġneed Ġthe Ġid ĊĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . owner . id Long Ġ} Ġ// ĠAlternatively Ġuse Ġthe Ġteam Ġwith Ġit . team Ġand Ġcheck Ġthe Ġmembers ! ĊĠĠĠĠĠĠĠ Ġ// ĠMap Ġto Ġowner - only Ġcommands ĊĠĠĠĠĠĠĠ Ġ. flatMap Many Ġ{ Ġowner Id Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmanager . on < Message Received Event >() ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . author . id Long Ġ== Ġowner Id Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠWe Ġonly Ġhave Ġone Ġowner - only Ġcommand Ġcalled Ġshutdown ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . message . content Raw Ġ== Ġ"-- shutdown " Ġ} ĊĠĠĠĠĠĠĠ Ġ// ĠConvert Ġto ĠJ DA Ġinstance Ġof Ġthe Ġevent ĊĠĠĠĠĠĠĠ Ġ. map ( Message Received Event :: get J DA ) ĊĠĠĠĠĠĠĠ Ġ// ĠShutdown ĊĠĠĠĠĠĠĠ Ġ. subscribe Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTo Ġmake Ġthe ĠJVM Ġshutdown Ġwe Ġhave Ġto Ġget Ġrid Ġof Ġall Ġthe Ġuser Ġthreads Ġ( non - daemon Ġthreads ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ ĠJ DA Ġcreates Ġat Ġleast Ġ 2 Ġuser Ġthreads Ġfor Ġthe Ġgateway Ġconnection Ġ( re ceiving Ġevents Ġfrom Ġdiscord ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġ Ġand Ġthe ĠHTTP Ġclient Ġcreates Ġat Ġleast Ġ 1 Ġuser Ġthread Ġfor Ġthe Ġdiscord Ġconnection Ġ( http / 2 Ġre - used Ġsocket ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠShutdown ĠJ DA Ġconnection ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . shutdown () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠP rune Ġhttp Ġclient Ġthreads ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . httpClient . connection Pool (). ev ict All () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĊĠĠĠ Ġ// ĠStart Ġthe ĠJ DA Ġconnection ĊĠĠĠ Ġval Ġj da Ġ= ĠJ DA Builder . create Light ( token , ĠGU ILD _ MESSAGES , ĠGU ILD _ MEMBER S , ĠGU ILD _ BAN S ) ĊĠĠĠĠĠĠĠ Ġ. set Event Manager ( manager ) Ġ// Ġaltern atively Ġjust Ġreactive () Ġif Ġthe Ġmanager Ġdoesn 't Ġneed Ġto Ġbe Ġused Ġdirectly ĊĠĠĠĠĠĠĠ Ġ. set Activity ( Activity . list ening (" for Ġcommands ")) ĊĠĠĠĠĠĠĠ Ġ. setStatus ( Online Status . DO _ NOT _ DIST UR B ) Ġ// Ġstatus ĠD ND Ġduring Ġsetup ĊĠĠĠĠĠĠĠ Ġ. set RateLimit Pool ( executor ) ĊĠĠĠĠĠĠĠ Ġ. set Gateway Pool ( executor ) ĊĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġ// ĠHandle Ġcommands ĊĠĠĠ Ġj da . on < Message Received Event >() ĊĠĠĠĠĠĠĠ Ġ// Ġdon 't Ġrespond Ġto Ġbots ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġ! it . author . is Bot Ġ} ĊĠĠĠĠĠĠĠ Ġ// Ġfilter Ġby Ġprefix ĊĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . message . content Raw . startsWith ("-- ") Ġ} ĊĠĠĠĠĠĠĠ Ġ. flatMap (:: handle Command ) ĊĠĠĠĠĠĠĠ Ġ. subscribe () ĊĊĠĠĠ Ġ// Handle Ġevents Ġfor Ġmod - log , Ġnote Ġthat Ġall Ġof Ġthese Ġonly Ġwork Ġwhen Ġthe Ġaudit Ġentry Ġis Ġgenerated ĊĠĠĠ Ġ// ĠThis Ġmeans Ġthe Ġleave Ġevent Ġwill Ġonly Ġtrigger Ġthe Ġmod - log Ġupdate Ġif Ġit Ġcan Ġbe Ġseen Ġas Ġa Ġkick Ġthrough Ġaudit Ġlogs . ĊĊĠĠĠ Ġ// ĠOnly Ġhandle Ġif Ġaudit Ġlogs Ġare Ġreadable ĊĠĠĠ Ġval Ġhas Permission : Ġ( Generic Guild Event ) Ġ-> ĠBoolean Ġ= Ġ{ Ġit . guild . self Member . has Permission ( Permission . VIEW _ AUDIT _ LOG S ) Ġ} ĊĊĠĠĠ Ġ// ĠB an ĊĠĠĠ Ġj da . on < Guild Ban Event >() ĊĠĠĠĠĠĠ Ġ. filter ( has Permission ) ĊĠĠĠĠĠĠ Ġ. subscribe Ġ{ Ġon Member Ban ( it . guild , Ġit . user ) Ġ} ĊĠĠĠ Ġ// ĠU nb an ĊĠĠĠ Ġj da . on < Guild Un ban Event >() ĊĠĠĠĠĠĠ Ġ. filter ( has Permission ) ĊĠĠĠĠĠĠ Ġ. subscribe Ġ{ Ġon Member Un ban ( it . guild , Ġit . user ) Ġ} ĊĠĠĠ Ġ// ĠPo ss ibly Ġkick Ġ( usually Ġjust Ġleave , Ġthis Ġis Ġalso Ġtriggered Ġby Ġb ans ) ĊĠĠĠ Ġj da . on < Guild Member Remove Event >() ĊĠĠĠĠĠĠ Ġ. filter ( has Permission ) ĊĠĠĠĠĠĠ Ġ. subscribe Ġ{ Ġon Member Kick ( it . guild , Ġit . user ) Ġ} ĊĊĠĠĠ Ġ// ĠHandle Ġshutdown Ġcleanup ĊĠĠĠ Ġj da . on < Shutdown Event >() ĊĠĠĠĠĠĠ Ġ. subscribe Ġ{ ĊĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCleanup ĠHTTP Ġconnections Ġthat Ġkeep Ġthe ĠJVM Ġfrom Ġshut ting Ġdown ĊĠĠĠĠĠĠĠĠĠĠ Ġit . j da . httpClient . connection Pool (). ev ict All () ĊĠĠĠĠĠĠ Ġ} Ċ } Ċ Ċ private Ġfun Ġhandle Command ( it : ĠMessage Received Event ) Ġ= Ġmono Ġ{ ĊĠĠĠ Ġ// ĠCommands Ġthat Ġwork Ġanywhere ĊĠĠĠ Ġon Basic Command ( it ). await First OrNull () ĊĠĠĠ Ġ// ĠCommands Ġthat Ġonly Ġwork Ġin Ġguild s ĊĠĠĠ Ġif Ġ( it . is From Guild Ġ&& Ġit . text Channel . check Write ()) ĊĠĠĠĠĠĠĠ Ġon Guild Command ( it ). await First OrNull () Ċ } Ċ Ċ private Ġfun ĠgetToken ( args : ĠArray < String >): ĠString Ġ{ ĊĠĠĠ Ġif Ġ( args . isEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġprintln (" Cannot Ġstart Ġbot Ġwithout Ġa Ġtoken !") ĊĠĠĠĠĠĠĠ Ġexit Process ( 1 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġtoken File Ġ= ĠFile ( args [ 0 ]) ĊĠĠĠ Ġif Ġ(! token File . can Read ()) Ġ{ ĊĠĠĠĠĠĠĠ Ġprintln (" Cannot Ġread Ġfrom Ġfile Ġ${ args [ 0 ]} ") ĊĠĠĠĠĠĠĠ Ġexit Process ( 2 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġreturn Ġtoken File . read Text (). trim () Ċ } Ċ Ċ fun Ġon Basic Command ( event : ĠMessage Received Event ): ĠMono < *> Ġ{ ĊĠĠĠ Ġval Ġcontent Ġ= Ġevent . message . content Raw ĊĠĠĠ Ġval Ġparts Ġ= Ġcontent . split (" Ġ", Ġlimit Ġ= Ġ 2 ) ĊĠĠĠ Ġval Ġcommand Ġ= Ġparts [ 0 ]. substring ( 2 ). lowercase ( Locale . getDefault ()) ĊĠĠĠ Ġreturn Ġwhen Ġ( command ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" ping " Ġ-> Ġon Ping ( event . channel ) ĊĠĠĠĠĠĠĠ Ġ" rtt " Ġ-> Ġon RT T ( event . channel ) ĊĠĠĠĠĠĠĠ Ġ" avatar " Ġ-> Ġon Avatar ( parts . get OrNull ( 1 ), Ġevent ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> ĠMono . empty < Unit >() ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġon Guild Command ( event : ĠMessage Received Event ): ĠMono < *> Ġ{ ĊĠĠĠ Ġval Ġcontent Ġ= Ġevent . message . content Raw ĊĠĠĠ Ġval Ġparts Ġ= Ġcontent . split (" Ġ", Ġlimit Ġ= Ġ 2 ) ĊĠĠĠ Ġval Ġcommand Ġ= Ġparts [ 0 ]. substring ( 2 ). lowercase ( Locale . getDefault ()) ĊĠĠĠ Ġreturn Ġwhen Ġ( command ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ" soft ban " Ġ-> Ġon Soft ban ( parts . get OrNull ( 1 ), Ġevent ) ĊĠĠĠĠĠĠĠ Ġ" purge " Ġ-> Ġon Purge ( parts . get OrNull ( 1 ), Ġevent ) ĊĠĠĠĠĠĠĠ Ġelse Ġ-> ĠMono . empty < Unit >() ĊĠĠĠ Ġ} Ċ } ĊĊ