@ file : Jvm Name (" Launcher ") Ċ Ċ package Ġcc . em ux . launcher Ċ Ċ import Ġjava . awt . Image Ċ import Ġjava . awt . System Tray Ċ import Ġjava . awt . Tray Icon Ċ import Ġjava . net . URI Ċ import Ġjava . net . URL ClassLoader Ċ import Ġjava . nio . file . Files Ċ import Ġjava . nio . file . Paths Ċ import Ġjava . util . jar . Jar File Ċ import Ġjavax . image io . Image IO Ċ import Ġjavax . swing . JOptionPane Ċ import Ġjavax . swing . UI Manager Ċ import Ġkotlin . concurrent . thread Ċ Ċ /** ĠC CE mu X Ġdata Ġdir Ġ*/ Ċ val Ġdata Dir Ġby Ġlazy Ġ{ Ċ ĉ val Ġos Ġ= ĠSystem . getProperty (" os . name ") ĊĊ ĉ when Ġ{ Ċĉ ĉ os . startsWith (" Windows ") Ġ-> ĠPaths . get ( System . getenv (" app data ") Ġ?: ĠSystem . getProperty (" user . home ")) Ċĉ ĉ os . startsWith (" Mac ") Ġ-> ĠPaths . get ( System . getProperty (" user . home "), Ġ" Library ", Ġ" Application ĠSupport ") Ċĉ ĉ os . startsWith (" Linux ") Ġ-> ĠPaths . get ( System . getProperty (" user . home "), Ġ". local ", Ġ" share ") Ċĉ ĉ else Ġ-> ĠPaths . get ( System . getProperty (" user . home ")) Ċ ĉ }. resolve (" cce mux ") Ċ } Ċ Ċ /** ĠPrompt Ġthe Ġuser Ġto Ġselect Ġthe ĠC CE mu X Ġbuild Ġthey Ġwant Ġ( CC Ġvs ĠC CT ) Ġ*/ Ċ fun Ġprompt Build (): ĠString Ġ{ Ċ ĉ val Ġbuilds Ġ= Ġmap Of ( Ċĉĉ ĉ " cc " Ġto Ġ" Computer Craft ", Ċĉĉ ĉ " c ct " Ġto Ġ" CC - T weak ed " Ċ ĉ ). entries . toList () ĊĊ ĉ val Ġresult Ġ= ĠJOptionPane . show Option Dialog ( Ċĉĉ ĉ null , Ċĉĉ ĉ " Which ĠC CE mu X Ġbuild Ġwould Ġyou Ġlike ?", Ċĉĉ ĉ " CCE mu X Ġbuild ", Ċĉĉ ĉ JOptionPane . DEFAULT _ OPTION , Ċĉĉ ĉ JOptionPane . QUEST ION _ MESSAGE , Ċĉĉ ĉ null , Ċĉĉ ĉ builds . map Ġ{ Ġit . value Ġ}. to Typed Array (), Ċĉĉĉ 0 Ċ ĉ ) ĊĊ ĉ return Ġbuilds [ result ]. key Ċ } Ċ Ċ fun Ġget Version Jar ( version : ĠE mu Version ) Ġ= Ġdata Dir . resolve (" versions "). resolve ( version . path ) Ċ Ċ fun Ġmain ( args : ĠArray < String >) Ġ{ Ċ ĉ println (" Starting ĠC CE mu X Ġlauncher ") ĊĊ ĉ UI Manager . set Look And Feel ( UI Manager . getSystem Look And Feel ClassName ()) ĊĊ ĉ val Ġupdater Ġ= ĠLaunch er Config . update Site ?. let (:: URI )?. let (:: Updater ) ĊĊ ĉ if Ġ( updater Ġ== Ġnull ) Ġprintln (" No Ġupdate Ġsite Ġspecified , Ġautomatic Ġdownloads Ġdisabled ") ĊĊ ĉ val Ġbuild Ġ= ĠLaunch er Config . build Ġ?: Ġprompt Build (). also Ġ{ ĠLaunch er Config . build Ġ= Ġit Ġ} Ċ ĉ val Ġhash Ġ= ĠLaunch er Config . version Ġ?: Ġupdater ?. get Latest Version ()?. also Ġ{ ĠLaunch er Config . version Ġ= Ġit Ġ} ĊĊ ĉ if Ġ( hash Ġ== Ġnull ) Ġ{ Ċĉ ĉ JOptionPane . showMessageDialog ( Ċĉĉĉ ĉ null , Ċĉĉĉ ĉ " CCE mu X Ġversion Ġcould Ġnot Ġbe Ġdetermined . ĠEnsure Ġyou Ġhave Ġan Ġinternet Ġconnection Ġand Ġan Ġupdate Ġsite Ġset .", Ċĉĉĉ ĉ " Fatal Ġerror ", Ċĉĉĉ ĉ JOptionPane . ERROR _ MESSAGE ) ĊĊĉ ĉ System . exit ( 1 ) Ċĉ ĉ return Ċ ĉ } ĊĊ ĉ val Ġversion Ġ= ĠE mu Version ( hash , Ġbuild ) Ċ ĉ val Ġem u Jar Ġ= Ġget Version Jar ( version ) ĊĊ ĉ println (" Em ulator Ġversion : Ġ$ version ") ĊĊ ĉ if Ġ(! Files . is Regular File ( emu Jar )) Ġ{ Ċĉ ĉ if Ġ( updater Ġ== Ġnull Ġ|| Ġ! updater . download Version ( version , Ġem u Jar )) Ġ{ Ċĉĉ ĉ JOptionPane . showMessageDialog ( Ċĉĉĉĉ ĉ null , Ċĉĉĉĉ ĉ " CCE mu X Ġcould Ġnot Ġbe Ġdownloaded . ĠEnsure Ġyou Ġhave Ġan Ġinternet Ġconnection Ġand Ġan Ġupdate Ġsite Ġset .", Ċĉĉĉĉ ĉ " Fatal Ġerror ", Ċĉĉĉĉ ĉ JOptionPane . ERROR _ MESSAGE Ċĉĉ ĉ ) ĊĊĉĉ ĉ System . exit ( 1 ) Ċĉĉ ĉ return Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ // Ġsetup Ġemulator Ġthread Ċ ĉ val Ġem u Ġ= ĠJar File ( emu Jar . to File ()) Ċ ĉ val Ġmain ClassName Ġ= ĠcheckNotNull ( emu . manifest ?. main Attributes ?. getValue (" Main - Class ")) Ġ{ Ġ" No Ġmain Ġclass Ġfound " Ġ} Ċ ĉ println (" Em ulator Ġmain Ġclass : Ġ$ main ClassName ") ĊĊ ĉ val Ġclass Loader Ġ= ĠURL ClassLoader ( array Of ( emu Jar . to Uri (). to URL ())) Ċ ĉ val Ġmain Method Ġ= Ġclass Loader . load Class ( main ClassName ). getDeclared Method (" main ", ĠarrayOf < String >() :: class . java ) ĊĊ ĉ val Ġem u Thread Ġ= Ġthread ( false , Ġcontext ClassLoader Ġ= Ġclass Loader ) Ġ{ Ġmain Method . invoke ( null , Ġargs ) Ġ} Ċ ĉ emu Thread . set Un caught ExceptionHandler Ġ{ Ġt , Ġe Ġ-> Ċĉ ĉ e . printStackTrace () Ċĉ ĉ JOptionPane . showMessageDialog ( Ċĉĉĉ ĉ null , Ċĉĉĉ ĉ " CCE mu X Ġhas Ġcr ashed Ġwith Ġan Ġunexpected Ġerror : Ġ$ e ", Ċĉĉĉ ĉ " Fatal Ġerror ", Ċĉĉĉ ĉ JOptionPane . ERROR _ MESSAGE Ċĉ ĉ ) Ċ ĉ } ĊĊ ĉ // Ġsetup Ġupdate Ġchecker Ġthread Ċ ĉ val Ġupdate Thread Ġ= Ġthread ( false ) Ġ{ Ċĉ ĉ if Ġ( updater Ġ== Ġnull ) Ġreturn @ thread ĊĊĉ ĉ val Ġtr ay Icon Ġ= Ġif Ġ( System Tray . is Supported ()) Ġ{ Ċĉĉ ĉ Tray Icon ( Image IO . read ( Updater :: class . java . getResource ("/ tray . png ")), Ġ" CCE mu X ĠUp dater "). also Ġ{ Ċĉĉĉ ĉ System Tray . getSystem Tray (). add ( it ) Ċĉĉ ĉ } Ċĉ ĉ } Ġelse Ġnull ĊĊĉ ĉ tray Icon ?. is Image AutoSize Ġ= Ġtrue Ċĉ ĉ tray Icon ?. tool Tip Ġ= Ġ" Checking Ġfor ĠC CE mu X Ġupdates ..." ĊĊĉ ĉ val Ġlatest Hash Ġ= Ġupdater . get Latest Version () Ċĉ ĉ val Ġlatest Version Ġ= ĠE mu Version ( latest Hash , Ġbuild ) ĊĊĉ ĉ if Ġ( version Ġ!= Ġlatest Version ) Ġ{ Ċĉĉ ĉ println (" Update Ġavailable : Ġ$ version Ġ-> Ġ$ latest Version ") Ċĉĉ ĉ tray Icon ?. tool Tip Ġ= Ġ" Apply ing ĠC CE mu X Ġupdate ..." ĊĊĉĉ ĉ // Ġdownload Ġand Ġapply Ġupdate Ċĉĉ ĉ if Ġ( updater . download Version ( latest Version , Ġget Version Jar ( latest Version ))) Ġ{ Ċĉĉĉ ĉ Launcher Config . version Ġ= Ġlatest Hash Ċĉĉĉ ĉ println (" Update Ġapplied ") Ċĉĉĉ ĉ tray Icon ?. tool Tip Ġ= Ġ" CCE mu X Ġupdate Ġcomplete Ġ- Ġrestart Ġto Ġapply " ĊĊĉĉĉ ĉ tray Icon ?. display Message ( Ċĉĉĉĉĉ ĉ " CCE mu X Ġupdated ", Ċĉĉĉĉĉ ĉ " CCE mu X Ġhas Ġbeen Ġupdated Ġsuccessfully . ĠRestart Ġto Ġapply Ġchanges .", Ċĉĉĉĉĉ ĉ Tray Icon . MessageType . INFO Ċĉĉĉ ĉ ) Ċĉĉ ĉ } Ċĉ ĉ } Ġelse Ġ{ Ċĉĉ ĉ tray Icon ?. tool Tip Ġ= Ġ" No ĠC CE mu X Ġupdate Ġavailable " Ċĉ ĉ } Ċ ĉ } ĊĊ ĉ update Thread . is Daemon Ġ= Ġtrue Ċ ĉ update Thread . priority Ġ= ĠThread . MIN _ PRIORITY ĊĊ ĉ emu Thread . start () Ċ ĉ update Thread . start () Ċ ĉ emu Thread . join () Ċ } Ċ