package Ġme . ch ill . framework Ċ Ċ import Ġme . ch ill . arguments . types . Argument Mix Ċ import Ġme . ch ill . exception . Command Exception Ċ import Ġorg . reflection s . Reflection s Ċ import Ġorg . reflection s . sc anners . Method Annotations Scanner Ċ Ċ class ĠCommand Container Ġprivate Ġconstructor () Ġ{ ĊĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠ Ġval Ġcommand Sets Ġ= Ġmutable ListOf < Command Set >() ĊĊĠĠĠ Ġfun Ġload Container () Ġ{ ĊĠĠĠĠĠ Ġval Ġreflection s Ġ= ĠReflection s (" me . ch ill . commands ", ĠMethod Annotations Scanner ()) ĊĠĠĠĠĠ Ġreflection s . get Methods Annotated With ( Command Category :: class . java ). forEach Ġ{ Ġit . invoke ( null ) Ġ} ĊĠĠĠĠĠ Ġcheck Commands () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġhas Command ( command : ĠString ) Ġ= Ġcommand Sets . stream (). any Match Ġ{ Ġit . has Command ( command ) Ġ} ĊĊĠĠĠ Ġfun Ġhas Category ( category : ĠString ) Ġ= Ġcommand Sets . stream (). any Match Ġ{ Ġit . category Name Ġ== Ġcategory Ġ} ĊĊĠĠĠ Ġfun Ġget Command Set ( category : ĠString ) Ġ= ĊĠĠĠĠĠ Ġcommand Sets . stream (). filter Ġ{ Ġit . category Name Ġ== Ġcategory Ġ}. toArray ()[ 0 ] !! Ġas ĠCommand Set ĊĊĠĠĠ Ġfun Ġget Command ( command : ĠString ) Ġ= Ġget Command List (). filter Ġ{ Ġit . name Ġ== Ġcommand Ġ}. to Typed Array () ĊĊĠĠĠ Ġfun Ġget Command Names () Ġ= Ġget Command List (). map Ġ{ Ġit . name Ġ}. to Typed Array (). distinct () ĊĊĠĠĠ Ġfun Ġget Global Commands () Ġ= ĊĠĠĠĠĠ Ġget Command List (). as Sequence (). filter Ġ{ Ġit . getGlobal () Ġ== Ġtrue Ġ}. map Ġ{ Ġit . name Ġ}. distinct (). toList () ĊĊĠĠĠ Ġfun Ġget Command List () Ġ= Ġcommand Sets . map Ġ{ Ġit . commands Ġ}. flatten () ĊĠ Ġ} Ċ } Ċ Ċ inline Ġfun Ġcommands ( category Name : ĠString , Ġcreate : ĠCommand Set . () Ġ-> ĠUnit ) Ġ{ ĊĠ Ġval Ġset Ġ= ĠCommand Set ( category Name ) ĊĠ Ġset . create () ĊĠ Ġfor Ġ( command Ġin Ġset . commands ) Ġ{ ĊĠĠĠ Ġif Ġ( command . getGlobal () Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠ Ġcommand . set Global ( set . getGlobal ()) ĊĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠ Ġcommand . getGlobal ()?. let Ġ{ ĊĠĠĠĠĠĠĠ Ġcommand . set Global ( it ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĠ ĠCommand Container . command Sets . add ( set ) Ċ } Ċ Ċ private Ġfun Ġcheck Commands () Ġ{ ĊĠ ĠCommand Container . get Command List (). forEach Ġ{ ĊĠĠĠ Ġit . getAction () Ġ?: Ġthrow ĠCommand Exception ( it . name , Ġ" All Ġcommands Ġmust Ġimplement Ġan Ġexecute Ġbody ") ĊĊĠĠĠ Ġif Ġ(! it . name [ 0 ]. is Letter Or Digit ()) Ġ{ ĊĠĠĠĠĠ Ġthrow ĠCommand Exception ( it . name , Ġ" Command Ġname Ġmust Ġstart Ġwith Ġa Ġletter Ġor Ġdigit ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( it . name Ġ== Ġit . category . toLowerCase ()) Ġ{ ĊĠĠĠĠĠ Ġthrow ĠCommand Exception ( ĊĠĠĠĠĠĠĠ Ġit . name , ĊĠĠĠĠĠĠĠ Ġ" Command Ġnames Ġshould Ġnot Ġbe Ġthe Ġsame Ġas Ġa Ġcategory Ġname " ĊĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġif Ġ( it . argument Types . any Ġ{ Ġarg Ġ-> Ġarg . java Class Ġ== ĠArgument Mix :: class . java Ġ}) Ġ{ ĊĠĠĠĠĠ Ġval Ġarg Mix Ġ= Ġit . argument Types . filter Ġ{ Ġarg Ġ-> Ġarg . java Class Ġ== ĠArgument Mix :: class . java Ġ} [ 0 ] Ġas ĠArgument Mix ĊĠĠĠĠĠ Ġif Ġ( arg Mix . arguments . distinct By Ġ{ Ġmix Ġ-> Ġmix . java Class Ġ}. size Ġ!= Ġarg Mix . arguments . size ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠCommand Exception ( ĊĠĠĠĠĠĠĠĠĠ Ġit . name , ĊĠĠĠĠĠĠĠĠĠ Ġ" Unable Ġto Ġcreate Ġan ĠArgument Mix Ġof Ġthe Ġsame Ġargument Ġtype " ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġover loaded Commands Ġ= ĠCommand Container . get Command ( it . name ) ĊĠĠĠ Ġover loaded Commands . forEach Ġ{ Ġover loaded Command Ġ-> ĊĠĠĠĠĠ Ġif Ġ( over loaded Command Ġ!= Ġit ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( over loaded Command . argument Types . size Ġ== Ġit . argument Types . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġthrow ĠCommand Exception ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġit . name , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" Unable Ġto Ġoverload Ġcommand Ġwith Ġthe Ġsame Ġnumber Ġof Ġargument Ġtypes : Ġ${ over loaded Command . argument Types . size }" ĊĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} Ċ }