4545import com .jme3 .network .ConnectionListener ;
4646import com .jme3 .network .HostedConnection ;
4747import com .jme3 .network .Server ;
48+ import com .jme3 .scene .Node ;
4849
50+ import com .simsilica .lemur .*;
4951import com .simsilica .lemur .core .VersionedHolder ;
52+ import com .simsilica .lemur .style .ElementId ;
5053import com .simsilica .state .DebugHudState ;
5154import com .simsilica .state .DebugHudState .Location ;
5255
@@ -62,21 +65,49 @@ public class HostState extends BaseAppState {
6265 static Logger log = LoggerFactory .getLogger (HostState .class );
6366
6467 private GameServer gameServer ;
68+ private int port ;
6569
6670 private VersionedHolder <String > hostingState ;
6771 private VersionedHolder <String > connectionCount ;
6872
6973 private ConnectionListener connectionListener = new ConnectionObserver ();
7074
75+ private Container hostWindow ;
76+
7177 public HostState ( int port , String description ) {
7278 try {
79+ this .port = port ;
7380 this .gameServer = new GameServer (port , description );
7481 gameServer .getServer ().addConnectionListener (connectionListener );
7582 } catch ( IOException e ) {
7683 throw new RuntimeException ("Error creating server" , e );
7784 }
7885 }
7986
87+ protected void joinGame () {
88+ log .info ("joinGame()" );
89+ getStateManager ().attach (new ConnectState ("127.0.0.1" , port ));
90+ setEnabled (false ); // hide our window
91+ }
92+
93+ protected void stopHosting () {
94+ log .info ("stopHosting()" );
95+ if ( gameServer .getServer ().isRunning () && !gameServer .getServer ().getConnections ().isEmpty () ) {
96+ String msg = "Really kick all " + gameServer .getServer ().getConnections ().size () + " connections?" ;
97+ getState (OptionPanelState .class ).show ("Disconnect" , msg ,
98+ new CallMethodAction ("Yes" , this , "detach" ),
99+ new EmptyAction ("No" ),
100+ new EmptyAction ("Cancel" ));
101+ } else {
102+ // Just detach
103+ detach ();
104+ }
105+ }
106+
107+ protected void detach () {
108+ getStateManager ().detach (this );
109+ }
110+
80111 @ Override
81112 protected void initialize ( Application app ) {
82113 // We'll manage the server itself as part of the app state
@@ -91,24 +122,40 @@ protected void initialize( Application app ) {
91122
92123 connectionCount = getState (DebugHudState .class ).createDebugValue ("Connections" , Location .Right );
93124 resetConnectionCount ();
125+
126+ hostWindow = new Container ();
127+
128+ // For now just something simple
129+ hostWindow .addChild (new Label ("Hosting Control" , new ElementId ("title" )));
130+ hostWindow .addChild (new ActionButton (new CallMethodAction ("Join Game" , this , "joinGame" )));
131+ hostWindow .addChild (new ActionButton (new CallMethodAction ("Stop Hosting" , this , "stopHosting" )));
94132 }
95133
96134 @ Override
97135 protected void cleanup ( Application app ) {
98- gameServer .close ();
136+ gameServer .close ("Shutting down." );
99137 hostingState .setObject ("Offline" );
100138
101139 // And remove the debug messages anyway
102140 getState (DebugHudState .class ).removeDebugValue ("Hosting" );
103141 getState (DebugHudState .class ).removeDebugValue ("Connections" );
142+
143+ // And re-enable the main menu
144+ getState (MainMenuState .class ).setEnabled (true );
104145 }
105146
106147 @ Override
107148 protected void onEnable () {
149+ Node gui = ((Main )getApplication ()).getGuiNode ();
150+
151+ int height = getApplication ().getCamera ().getHeight ();
152+ hostWindow .setLocalTranslation (10 , height - 10 , 0 );
153+ gui .attachChild (hostWindow );
108154 }
109155
110156 @ Override
111157 protected void onDisable () {
158+ hostWindow .removeFromParent ();
112159 }
113160
114161 protected void resetConnectionCount () {
0 commit comments