/* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 1 ĠD See LP Ġ& ĠFrame C ord Ġcontributors Ċ Ġ* Ċ Ġ* ĠMIT ĠLicense Ċ Ġ* Ċ Ġ* ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ċ Ġ* Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ċ Ġ* Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ġrights Ċ Ġ* Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ċ Ġ* Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ċ Ġ* Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ġall Ċ Ġ* Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ċ Ġ* ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ċ Ġ* ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ Ġ* ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ċ Ġ* ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , Ċ Ġ* ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN ĠTHE Ċ Ġ* ĠSOFTWARE . Ċ Ġ*/ Ċ Ċ package Ġio . github . d se el p . frame cord . api . event Ċ Ċ import Ġio . github . d se el p . frame cord . api . bot Ċ import Ġio . github . d se el p . frame cord . api . events . Plugin Disable Event Ċ import Ġio . github . d se el p . frame cord . api . events . Plugin EventType Ċ import Ġio . github . d se el p . frame cord . api . logging . logger Ċ import Ġio . github . d se el p . frame cord . api . plugins . Plugin Ċ import Ġio . github . d se el p . frame cord . api . plugins . Plugin Loader Ċ import Ġio . github . d se el p . frame cord . api . utils . Criterion Ċ import Ġio . github . d se el p . frame cord . api . utils . Reflection Utils Ċ import Ġio . github . d se el p . frame cord . api . utils . k oin . C ord K oin Component Ċ import Ġkotlinx . coroutines . launch Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġorg . k oin . core . component . inject Ċ import Ġjava . util .* Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġjava . util . concurrent . Executors Ċ import Ġkotlin . reflect . K Class Ċ import Ġkotlin . reflect . K Function Ċ import Ġkotlin . reflect . K Parameter Ċ import Ġkotlin . reflect . full .* Ċ Ċ @ Opt In ( io . github . d se el p . frame cord . api . InternalFrame C ord Api :: class ) Ċ @ Listener Ċ open Ġclass ĠEvent Bus Ġ: ĠC ord K oin Component Ġ{ ĊĠĠĠ Ġprivate Ġval Ġhandlers Ġ= ĠCollections . synchronized List ( mutable ListOf < Handler >()) ĊĊĠĠĠ Ġprivate Ġval Ġevent ExecutorService Ġ= ĠExec utors . new Fixed ThreadPool ( 4 ) ĊĊĊĠĠĠ Ġsuspend Ġfun Ġcall Async ( event : ĠAny , Ġasync : ĠBoolean Ġ= Ġfalse ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġevent Class Ġ= Ġevent :: class ĊĠĠĠĠĠĠĠ Ġwith Context ( bot . coroutine Context ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġexecute Function Ġ= Ġsuspend Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhandlers Ġ= Ġhandlers . map Ġ{ Ġit Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( index Ġin Ġ 0 .. handlers . last Index ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhandler Ġ= Ġhandlers . get OrNull ( index ) Ġ?: Ġcontinue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( handler Ġis ĠHandler . Class Handler <* >) Ġhandler . invoke ( event ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġif Ġ( handler . clazz Ġ== Ġevent Class Ġ|| Ġevent Class . is Subclass Of ( handler . clazz )) Ġhandler . invoke ( event ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( async ) Ġbot . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecute Function . invoke () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġexecute Function . invoke () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ io . github . d se el p . frame cord . api . InternalFrame C ord Api ĊĠĠĠ Ġfun Ġunregister ( clazz : ĠK Class < out ĠPlugin >) Ġ{ ĊĠĠĠĠĠĠĠ Ġhandlers . remove If Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . plugin :: class Ġ== Ġclazz ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġplugin Loader : ĠPlugin Loader Ġby Ġinject () ĊĠĠĠ Ġprivate Ġval Ġlog Ġby Ġlogger < EventBus >() ĊĊĠĠĠ Ġfun Ġsearch Packages ( plugin : ĠPlugin ? Ġ= Ġnull , Ġvar arg Ġpackages : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ ĠReflection Utils . find Classes ( packages . toList (). to Typed Array (), Ġplugin ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠC riterion . has Annotation < Listener >(). assert () ĊĠĠĠĠĠĠĠ Ġ}. on Each Ġ{ Ġclazz Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġp Ġ= Ġif Ġ( plugin Ġ!= Ġnull ) Ġplugin ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclass Loader Ġ= Ġclazz . java . class Loader ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġplugin Loader . loaded Plugins . first OrNull Ġ{ Ġit . class Loader Ġ== Ġclass Loader Ġ} ?. plugin ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( p Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" Failed Ġto Ġdetermine Ġplugin Ġfor Ġclass Ġ${ clazz . qualified Name }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġhandler Ġ= ĠHandler . Class Handler ( p , Ġclazz ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( handlers . find Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it Ġis ĠHandler . Class Handler <* >) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit . clazz Ġ== Ġclazz ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ== Ġnull ) Ġhandlers . add ( handler ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġremove Handler ( handler : ĠHandler ) Ġ{ ĊĠĠĠĠĠĠĠ Ġhandlers . remove ( handler ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġsearch Package ( packageName : ĠString , Ġplugin : ĠPlugin ? Ġ= Ġnull ) Ġ= Ġsearch Packages ( plugin , ĠpackageName ) ĊĊĠĠĠ Ġfun Ġadd Handler ( handler : ĠHandler ) Ġ{ ĊĠĠĠĠĠĠĠ Ġhandlers . add ( handler ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Handler ( plugin : ĠPlugin , Ġclazz : ĠK Class < out ĠAny >, Ġinstance : ĠAny ? Ġ= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġhandlers . add ( Handler . Class Handler ( plugin , Ġclazz , Ġinstance )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinline Ġfun Ġ< re ified ĠT Ġ: ĠAny > Ġadd Class Handler ( plugin : ĠPlugin , Ġlistener : ĠT ) Ġ{ ĊĠĠĠĠĠĠĠ Ġadd Handler ( plugin , Ġlistener :: class , Ġlistener ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinline Ġfun Ġ< re ified ĠT Ġ: ĠAny > Ġadd Class Handler ( plugin : ĠPlugin ) Ġ{ ĊĠĠĠĠĠĠĠ Ġadd Handler ( plugin , ĠT :: class ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinline Ġfun Ġ< re ified ĠT Ġ: ĠAny > Ġadd Handler ( plugin : ĠPlugin , Ġno inline Ġblock : Ġ( event : ĠT ) Ġ-> ĠUnit ) Ġ= Ġadd Handler ( ĊĠĠĠĠĠĠĠ ĠHandler . Lambda Handler ( plugin , ĠT :: class , Ġblock ) ĊĠĠĠ Ġ) ĊĊĠĠĠ Ġfun Ġremove Handlers ( plugin : ĠPlugin ) Ġ{ ĊĠĠĠĠĠĠĠ Ġhandlers . remove If Ġ{ Ġit . plugin Ġ== Ġplugin Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Event Handle ĊĠĠĠ Ġ@ io . github . d se el p . frame cord . api . InternalFrame C ord Api ĊĠĠĠ Ġfun Ġon Plugin Disable ( event : ĠPlugin Disable Event ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( event . type Ġ!= ĠPlugin EventType . POST ) Ġreturn ĊĠĠĠĠĠĠĠ Ġunregister ( event . plugin :: class ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġsealed Ġclass ĠHandler ( val Ġplugin : ĠPlugin ) Ġ{ ĊĠĠĠĠĠĠĠ Ġabstract Ġsuspend Ġfun Ġinvoke ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġevent : ĠAny ĊĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠ Ġabstract Ġval Ġclazz : ĠK Class < out ĠAny > ĊĊĠĠĠĠĠĠĠ Ġclass ĠLambda Handler < T >( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplugin : ĠPlugin , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġval Ġclazz : ĠK Class < out ĠAny >, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlambda : Ġ( event : ĠT ) Ġ-> ĠUnit ĊĠĠĠĠĠĠĠ Ġ) Ġ: ĠHandler ( plugin ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġinvoke ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent : ĠAny ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Suppress (" UN CHECK ED _ CAST ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlambda . invoke ( event Ġas ĠT ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Opt In ( io . github . d se el p . frame cord . api . InternalFrame C ord Api :: class ) ĊĠĠĠĠĠĠĠ Ġclass ĠClass Handler < T Ġ: ĠAny >( plugin : ĠPlugin , Ġoverride Ġval Ġclazz : ĠK Class < out ĠT >, Ġobj : ĠT ? Ġ= Ġnull ) Ġ: ĊĠĠĠĠĠĠĠĠĠĠĠ ĠHandler ( plugin ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠC ord K oin Component Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmethods Ġ= Ġ( clazz . member Functions Ġ+ Ġclazz . declared Member Functions ). distinct () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġit . has Annotation < Event Handle >() Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġit Ġto Ġit . parameters ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. filter Ġ{ Ġparam Ġ-> Ġ! param . is Optional Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map NotNull Ġ{ Ġif Ġ( it . second . size Ġ== Ġ 2 ) Ġit . first Ġto Ġit . second [ 1 ] Ġelse Ġnull Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclazz Obj Ġ= Ġ( obj Ġ?: Ġclazz . object Instance ) Ġ?: Ġget K oin (). get OrNull < Any >( clazz ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmethod Cache : ĠMutable Map < K Class <* >, ĠList < Pair < K Function <* >, ĠK Parameter >>> Ġ= ĠConcurrent HashMap () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġprivate Ġval Ġlog Ġby Ġlogger < EventBus >() ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġsuspend Ġfun Ġinvoke ( event : ĠAny ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġevent Class Ġ= Ġevent :: class ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethod Cache . get Or Put ( event Class ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmethods . filter Ġ{ Ġit . second . type . classifier Ġ== Ġevent Class Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. on Each Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmethod Ġ= Ġit . first ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( method . is Suspend ) Ġmethod . call Suspend ( clazz Obj , Ġevent ) Ġelse Ġmethod . call ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclazz Obj , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġevent ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠThrowable ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ" Failed Ġto Ġcall Ġmethod Ġ${ method . name } Ġin Ġ${ clazz . qualified Name }", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠtoString (): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ" Class Handler ( clazz =$ clazz )" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }