package Ġdev . ro bo code . tank roy ale . server . dev . ro bo code . tank roy ale . server . connection Ċ Ċ import Ġcom . google . gson . Gson Ċ import Ġcom . google . gson . JsonObject Ċ import Ġcom . google . gson . Json Syntax Exception Ċ import Ġdev . ro bo code . tank roy ale . schema .* Ċ import Ġdev . ro bo code . tank roy ale . server . Server Ċ import Ġdev . ro bo code . tank roy ale . server . core . Server Setup Ċ import Ġdev . ro bo code . tank roy ale . server . dev . ro bo code . tank roy ale . server . core . StatusCode Ċ import Ġorg . java _ websocket . WebSocket Ċ import Ġorg . java _ websocket . handshake . Client Handshake Ċ import Ġorg . java _ websocket . server . WebSocket Server Ċ import Ġorg . slf 4 j . LoggerFactory Ċ import Ġjava . net . Inet SocketAddress Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġjava . util . concurrent . ExecutorService Ċ import Ġjava . util . concurrent . Executors Ċ import Ġjava . util . concurrent . TimeUnit Ċ Ċ class ĠConnection Handler ( ĊĠĠĠ Ġprivate Ġval Ġsetup : ĠServer Setup , ĊĠĠĠ Ġprivate Ġval Ġlistener : ĠI Connection Listener , ĊĠĠĠ Ġprivate Ġval Ġcontroller Secrets : ĠSet < String >, ĊĠĠĠ Ġprivate Ġval Ġbot Secrets : ĠSet < String > Ċ ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġweb Socket Observer : ĠWebSocket Observer ĊĠĠĠ Ġprivate Ġval Ġall Connections Ġ= ĠConcurrent HashMap . new Key Set < WebSocket >() ĊĠĠĠ Ġprivate Ġval Ġbot Connections Ġ= ĠConcurrent HashMap . new Key Set < WebSocket >() ĊĠĠĠ Ġprivate Ġval Ġobserver Connections Ġ= ĠConcurrent HashMap . new Key Set < WebSocket >() ĊĠĠĠ Ġprivate Ġval Ġcontroller Connections Ġ= ĠConcurrent HashMap . new Key Set < WebSocket >() ĊĠĠĠ Ġprivate Ġval Ġbot Hand sh akes Ġ= ĠConcurrent HashMap < WebSocket , ĠBot Handshake >() ĊĠĠĠ Ġprivate Ġval Ġobserver Hand sh akes Ġ= ĠConcurrent HashMap < WebSocket , ĠObserver Handshake >() ĊĠĠĠ Ġprivate Ġval Ġcontroller Hand sh akes Ġ= ĠConcurrent HashMap < WebSocket , ĠController Handshake >() ĊĠĠĠ Ġprivate Ġval ĠexecutorService : ĠExecutor Service ĊĊĠĠĠ Ġprivate Ġval Ġlog Ġ= ĠLoggerFactory . getLogger ( Connection Handler :: class . java ) ĊĊĠĠĠ Ġprivate Ġval Ġgson Ġ= ĠGson () ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġaddress Ġ= ĠInet SocketAddress (" localhost ", ĠServer . port . toInt ()) ĊĠĠĠĠĠĠĠ Ġweb Socket Observer Ġ= ĠWebSocket Observer ( address ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis Tcp No Delay Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ ĠexecutorService Ġ= ĠExec utors . new Cached ThreadPool () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstart () Ġ{ ĊĠĠĠĠĠĠĠ Ġweb Socket Observer . run () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġstop () Ġ{ ĊĠĠĠĠĠĠĠ Ġshutdown And Await Termination ( executor Service ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġbroadcast To Observer And Controllers ( message : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbroadcast ( observer And Controller Connections , Ġmessage ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Bot Connections (): ĠSet < WebSocket > Ġ= Ġbot Connections . toSet () ĊĊĠĠĠ Ġval Ġobserver And Controller Connections : ĠSet < WebSocket > ĊĠĠĠĠĠĠĠ Ġget () Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmutable Set Of < WebSocket >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis Ġ+= Ġobserver Connections ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis Ġ+= Ġcontroller Connections ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Bot Hand sh akes (): ĠMap < WebSocket , ĠBot Handshake > Ġ= Ġbot Hand sh akes . toMap () ĊĊĠĠĠ Ġfun Ġget Bot Connections ( bot Addresses : ĠCollection < Bot Address >): ĠSet < WebSocket > Ġ= ĊĠĠĠĠĠĠĠ Ġmutable Set Of < WebSocket >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbot Hand sh akes . keys . forEach Ġ{ Ġconn Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠaddTo Found Connection ( conn , Ġbot Addresses , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠaddTo Found Connection ( ĊĠĠĠĠĠĠĠ Ġconn : ĠWebSocket , ĊĠĠĠĠĠĠĠ Ġbot Addresses : ĠCollection < Bot Address >, ĊĠĠĠĠĠĠĠ Ġfound Connections : ĠMutable Set < WebSocket > ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġconn . remote SocketAddress ?. let Ġ{ Ġaddress Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbot Addresses . forEach Ġ{ Ġbot Address Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( to IpAddress ( address ) Ġ== Ġto IpAddress ( address ) Ġ&& Ġbot Address . port Ġ== Ġaddress . port ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfound Connections Ġ+= Ġconn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ forEach ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġto IpAddress ( address : ĠInet SocketAddress ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġip Ġ= Ġaddress . toString (). split ("/ ")[ 1 ] ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( ip . equals (" localhost ", Ġtrue )) Ġ" 1 2 7 . 0 . 0 . 1 " Ġelse Ġip ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġshutdown And Await Termination ( pool : ĠExecutor Service ) Ġ{ ĊĠĠĠĠĠĠĠ Ġpool . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġshutdown () Ġ// ĠDisable Ġnew Ġtasks Ġfrom Ġbeing Ġsubmitted ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! await Termination ( 5 , ĠTimeUnit . SECONDS )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshutdown Now () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! await Termination ( 5 , ĠTimeUnit . SECONDS )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . warn (" Pool Ġdid Ġnot Ġterminate ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠInterruptedException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshutdown Now () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠThread . currentThread (). interrupt () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġsend ( conn : ĠWebSocket , Ġmessage : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . debug (" Sending Ġto : Ġ${ conn . remote SocketAddress }, Ġmessage : Ġ$ message ") ĊĠĠĠĠĠĠĠ Ġconn . send ( message ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġbroadcast ( clients : ĠCollection < WebSocket >, Ġmessage : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . debug (" Broadcast Ġmessage : Ġ$ message ") ĊĠĠĠĠĠĠĠ Ġweb Socket Observer . broadcast ( message , Ġclients ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġnotify Exception ( exception : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlog . error (" Exception Ġoccurred : Ġ$ exception ") ĊĠĠĠĠĠĠĠ Ġlistener . on Exception ( exception ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinner Ġclass ĠWebSocket Observer ( address : ĠInet SocketAddress ) Ġ: ĠWebSocket Server ( address ) Ġ{ ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonStart () Ġ{} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Open ( conn : ĠWebSocket , Ġhandshake : ĠClient Handshake ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" on Open (): Ġ${ conn . remote SocketAddress }") ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠexecutorService . submit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall Connections Ġ+= Ġconn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠServer Handshake (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ`$ type ` Ġ= ĠMessage .` $ type `. SERVER _ HAND SHA KE ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġvariant Ġ= Ġ" Tank ĠRo y ale " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġversion Ġ= Ġversion Ġ?: Ġ" ?" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgame Types Ġ= Ġsetup . game Types ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. also Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsend ( conn , ĠGson (). toJson ( it )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonClose ( conn : ĠWebSocket , Ġcode : ĠInt , Ġreason : ĠString , Ġremote : ĠBoolean ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" onClose : Ġ${ conn . remote SocketAddress }, Ġcode : Ġ$ code , Ġreason : Ġ$ reason , Ġremote : Ġ$ remote ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠexecutorService . submit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall Connections Ġ-= Ġconn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbot Connections . remove ( conn ) Ġ-> Ġhandle Bot Left ( conn ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobserver Connections . remove ( conn ) Ġ-> Ġhandle Observer Left ( conn ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller Connections . remove ( conn ) Ġ-> Ġhandle Controller Left ( conn ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġhandle Bot Left ( conn : ĠWebSocket ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbot Hand sh akes [ conn ]?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . on Bot Left ( conn , Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbot Hand sh akes Ġ-= Ġconn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġhandle Observer Left ( conn : ĠWebSocket ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobserver Hand sh akes [ conn ]?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . on Observer Left ( conn , Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġobserver Hand sh akes Ġ-= Ġconn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġhandle Controller Left ( conn : ĠWebSocket ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller Hand sh akes [ conn ]?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . on Controller Left ( conn , Ġit ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller Hand sh akes Ġ-= Ġconn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Message ( conn : ĠWebSocket , Ġmessage : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" on Message : Ġ${ conn . remote SocketAddress }, Ġmessage : Ġ$ message ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ ĠexecutorService . submit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgson . fromJson ( message , ĠJsonObject :: class . java )[" \$ type "] ?. let Ġ{ Ġjson Type Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtype Ġ= ĠMessage .` $ type `. from Value ( json Type . asString ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . debug (" Handling Ġmessage : Ġ$ type ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( type ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. BOT _ INT ENT Ġ-> Ġhandle Intent ( conn , Ġmessage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. BOT _ HAND SHA KE Ġ-> Ġhandle Bot Handshake ( conn , Ġmessage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. OB SERVER _ HAND SHA KE Ġ-> Ġhandle Observer Handshake ( conn , Ġmessage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. CONTROLLER _ HAND SHA KE Ġ-> Ġhandle Controller Handshake ( conn , Ġmessage ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. BOT _ READY Ġ-> Ġhandle Bot Ready ( conn ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. START _ GAME Ġ-> Ġhandle Start Game ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. STOP _ GAME Ġ-> Ġhandle Stop Game () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. PAUSE _ GAME Ġ-> Ġhandle Pause Game () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. RE SU ME _ GAME Ġ-> Ġhandle Resume Game () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. NEXT _ T URN Ġ-> Ġhandle Next Turn () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠMessage .` $ type `. CHANGE _ TP S Ġ-> ĠhandleChange T ps ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnotify Exception ( IllegalStateException (" Unhandled Ġmessage Ġtype : Ġ$ type ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠIllegalArgumentException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnotify Exception ( IllegalStateException (" Unhandled Ġmessage Ġtype : Ġ${ json Type . asString } ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠJson Syntax Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" Invalid Ġmessage : Ġ$ message ", Ġex ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" Error Ġwhen Ġpassing Ġmessage : Ġ$ message ", Ġex ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun ĠonError ( conn : ĠWebSocket , Ġex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlog . error (" onError : Ġ${ conn . remote SocketAddress }, Ġexception : Ġ$ ex ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Intent ( conn : ĠWebSocket , Ġmessage : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġintent Ġ= Ġgson . fromJson ( message , ĠBot Intent :: class . java ) ĊĠĠĠĠĠĠĠ Ġlistener . on Bot Intent ( conn , Ġbot Hand sh akes [ conn ] !! , Ġintent ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Bot Handshake ( conn : ĠWebSocket , Ġmessage : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġgson . fromJson ( message , ĠBot Handshake :: class . java ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠValidate Ġclient Ġsecret Ġbefore Ġcontinuing ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( bot Secrets . isNotEmpty () Ġ&& Ġ! bot Secrets . contains ( secret )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Ign oring Ġbot Ġusing Ġinvalid Ġsecret : Ġname : Ġ$ name , Ġversion : Ġ$ version ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconn . close ( StatusCode . POLICY _ VI OL ATION . value , Ġ" Wrong Ġsecret ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbot Connections Ġ+= Ġconn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġbot Hand sh akes [ conn ] Ġ= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . on Bot Joined ( conn , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Observer Handshake ( conn : ĠWebSocket , Ġmessage : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġgson . fromJson ( message , ĠObserver Handshake :: class . java ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠValidate Ġclient Ġsecret Ġbefore Ġcontinuing ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( controller Secrets . isNotEmpty () Ġ&& Ġ! controller Secrets . contains ( secret )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Ign oring Ġobserver Ġusing Ġinvalid Ġsecret : Ġname : Ġ$ name , Ġversion : Ġ$ version ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconn . close ( StatusCode . POLICY _ VI OL ATION . value , Ġ" Wrong Ġsecret ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobserver Connections Ġ+= Ġconn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġobserver Hand sh akes [ conn ] Ġ= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . on Observer Joined ( conn , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Controller Handshake ( conn : ĠWebSocket , Ġmessage : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġgson . fromJson ( message , ĠController Handshake :: class . java ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠValidate Ġclient Ġsecret Ġbefore Ġcontinuing ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( controller Secrets . isNotEmpty () Ġ&& Ġ! controller Secrets . contains ( secret )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlog . info (" Ign oring Ġcontroller Ġusing Ġinvalid Ġsecret : Ġname : Ġ$ name , Ġversion : Ġ$ version ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġconn . close ( StatusCode . POLICY _ VI OL ATION . value , Ġ" Wrong Ġsecret ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller Connections Ġ+= Ġconn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcontroller Hand sh akes [ conn ] Ġ= Ġthis ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . on Controller Joined ( conn , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Bot Ready ( conn : ĠWebSocket ) Ġ{ ĊĠĠĠĠĠĠĠ Ġlistener . on Bot Ready ( conn , Ġbot Hand sh akes [ conn ] !! ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Start Game ( message : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġgson . fromJson ( message , ĠStart Game :: class . java ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . onStart Game ( game Setup , Ġbot Addresses ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Stop Game () Ġ{ ĊĠĠĠĠĠĠĠ ĠexecutorService . submit ( listener :: on Abort Game ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Pause Game () Ġ{ ĊĠĠĠĠĠĠĠ ĠexecutorService . submit ( listener :: on Pause Game ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Resume Game () Ġ{ ĊĠĠĠĠĠĠĠ ĠexecutorService . submit ( listener :: on Resume Game ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Next Turn () Ġ{ ĊĠĠĠĠĠĠĠ ĠexecutorService . submit ( listener :: onNext Turn ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠhandleChange T ps ( message : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ ĠexecutorService . submit Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgson . fromJson ( message , ĠChange T ps :: class . java ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlistener . onChange T ps ( tps ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }