Explorar o código

- Ensures if there is a $pref::server::password set and you're creating a localConnection game, you can connect even if you don't have a client password set
- Changed ChooseLevelMenu layout to have a vertical list for levels with a static preview set, as well as a separate tab for server configs if trying to create a server
- Added field to set password for connecting to passworded servers on the JoinServerMenu
- Added sanity check so you can't try and activate a menuList that has no children(caused error spam)

Areloch hai 1 ano
pai
achega
c809dbb4be

+ 1 - 1
Engine/source/T3D/gameBase/gameConnection.cpp

@@ -478,7 +478,7 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
    setProtocolVersion(currentProtocol < CurrentProtocolVersion ? currentProtocol : CurrentProtocolVersion);
 
    const char *serverPassword = Con::getVariable("pref::Server::Password");
-   if(serverPassword[0])
+   if(serverPassword[0] && !isLocalConnection())
    {
       if(String::compare(joinPassword, serverPassword))
       {

+ 274 - 25
Templates/BaseGame/game/data/UI/guis/ChooseLevelMenu.gui

@@ -10,7 +10,8 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
    isContainer = "1";
    canSaveDynamicFields = "1";
       launchInEditor = "0";
-      
+      previewButtonSize = "445 120";
+
    new GuiInputCtrl(ChooseLevelInputHandler) {
       ignoreMouseEvents = "1";
       ActionMap = "ChooseLevelActionMap";
@@ -21,7 +22,6 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
       profile = "GuiInputCtrlProfile";
       tooltipProfile = "GuiToolTipProfile";
    };
-
    new GuiPanel(ChooseLevelTitlePanel) {
       extent = "1281 60";
       horizSizing = "width";
@@ -36,6 +36,275 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
          tooltipProfile = "GuiToolTipProfile";
       };
    };
+   new GuiStackControl(ChooseLevelMenuTabList) {
+      stackingType = "Horizontal";
+      padding = "10";
+      position = "485 61";
+      extent = "310 41";
+      horizSizing = "center";
+      profile = "GuiDefaultProfile";
+      visible = "0";
+      tooltipProfile = "GuiToolTipProfile";
+      hidden = "1";
+
+      new GuiButtonCtrl() {
+         text = "Level";
+         groupNum = "1";
+         extent = "150 41";
+         profile = "GuiMenuButtonProfile";
+         command = "ChooseLevelMenu.openMenu(0);";
+         tooltipProfile = "GuiToolTipProfile";
+         class = "ChooseLevelMenuButton";
+      };
+      new GuiButtonCtrl() {
+         text = "Server Config";
+         groupNum = "1";
+         position = "160 0";
+         extent = "150 41";
+         profile = "GuiMenuButtonProfile";
+         command = "ChooseLevelMenu.openMenu(1);";
+         tooltipProfile = "GuiToolTipProfile";
+         class = "ChooseLevelMenuButton";
+      };
+   };
+   new GuiControl(ChooseLevelMenuNavButtonOverlay) {
+      position = "0 61";
+      extent = "1281 60";
+      horizSizing = "width";
+      profile = "GuiNonModalDefaultProfile";
+      visible = "0";
+      tooltipProfile = "GuiToolTipProfile";
+      isContainer = "1";
+      hidden = "1";
+
+      new GuiBitmapCtrl(ChooseLevelMenuPrevNavIcon) {
+         BitmapAsset = "UI:Keyboard_Black_Q_image";
+         position = "485 24";
+         extent = "40 40";
+         vertSizing = "top";
+         profile = "GuiNonModalDefaultProfile";
+         tooltipProfile = "GuiToolTipProfile";
+      };
+      new GuiBitmapCtrl(ChooseLevelMenuNextNavIcon) {
+         BitmapAsset = "UI:Keyboard_Black_E_image";
+         position = "595 24";
+         extent = "40 40";
+         vertSizing = "top";
+         profile = "GuiNonModalDefaultProfile";
+         tooltipProfile = "GuiToolTipProfile";
+      };
+   };
+   new GuiContainer(LevelSelectContainer) {
+      position = "196 119";
+      extent = "888 566";
+      horizSizing = "center";
+      profile = "GuiNonModalDefaultProfile";
+      tooltipProfile = "GuiToolTipProfile";
+
+      new GuiScrollCtrl(LevelPreviewScroll) {
+         hScrollBar = "alwaysOff";
+         vScrollBar = "dynamic";
+         extent = "445 562";
+         vertSizing = "height";
+         profile = "GuiMenuScrollProfile";
+         tooltipProfile = "GuiToolTipProfile";
+
+         new GuiStackControl(LevelPreviewArray) {
+            padding = "5";
+            position = "0 1";
+            extent = "445 120";
+            horizSizing = "width";
+            vertSizing = "height";
+            profile = "GuiMenuDefaultProfile";
+            tooltipProfile = "GuiToolTipProfile";
+         };
+      };
+      new GuiBitmapCtrl(LevelPreviewBitmap) {
+         BitmapAsset = "testMaps:EmptyLevel_preview_image";
+         position = "448 0";
+         extent = "440 440";
+         horizSizing = "left";
+         profile = "GuiNonModalDefaultProfile";
+         tooltipProfile = "GuiToolTipProfile";
+      };
+      new GuiTextCtrl(LevelNameText) {
+         text = "EmptyLevel";
+         position = "448 445";
+         extent = "440 20";
+         horizSizing = "left";
+         profile = "MenuSubHeaderText";
+         tooltipProfile = "GuiToolTipProfile";
+         internalName = "levelNameTxt";
+      };
+      new GuiMLTextCtrl(LevelDescriptionText) {
+         position = "448 473";
+         extent = "440 19";
+         horizSizing = "left";
+         profile = "GuiMLTextProfile";
+         tooltipProfile = "GuiToolTipProfile";
+         internalName = "levelDescTxt";
+      };
+   };
+   new GuiContainer(ServerConfigContainer) {
+      position = "196 119";
+      extent = "888 566";
+      horizSizing = "center";
+      profile = "GuiNonModalDefaultProfile";
+      visible = "0";
+      tooltipProfile = "GuiToolTipProfile";
+      hidden = "1";
+
+      new GuiScrollCtrl(ServerConfigScroll) {
+         hScrollBar = "alwaysOff";
+         vScrollBar = "dynamic";
+         extent = "888 566";
+         horizSizing = "width";
+         vertSizing = "height";
+         profile = "GuiMenuScrollProfile";
+         tooltipProfile = "GuiToolTipProfile";
+
+         new GuiStackControl(ServerConfigList) {
+            padding = "5";
+            changeChildSizeToFit = "0";
+            position = "1 1";
+            extent = "900 170";
+            horizSizing = "width";
+            vertSizing = "height";
+            profile = "GuiMenuDefaultProfile";
+            tooltipProfile = "GuiToolTipProfile";
+
+            new GuiContainer() {
+               extent = "900 30";
+               horizSizing = "width";
+               profile = "GuiDefaultProfile";
+               tooltipProfile = "GuiToolTipProfile";
+
+               new GuiTextCtrl() {
+                  text = "Host Player Name";
+                  position = "0 3";
+                  extent = "140 23";
+                  vertSizing = "center";
+                  profile = "MenuMLSubHeaderText";
+                  tooltipProfile = "GuiToolTipProfile";
+               };
+               new GuiTextEditCtrl() {
+                  text = "Visitor";
+                  position = "606 4";
+                  extent = "295 22";
+                  horizSizing = "left";
+                  vertSizing = "center";
+                  profile = "MenuTextEditprofile";
+                  variable = "$pref::Player::Name";
+                  tooltipProfile = "GuiToolTipProfile";
+               };
+            };
+            new GuiContainer() {
+               position = "0 35";
+               extent = "900 30";
+               horizSizing = "width";
+               profile = "GuiDefaultProfile";
+               tooltipProfile = "GuiToolTipProfile";
+
+               new GuiTextCtrl() {
+                  text = "Server Name";
+                  position = "0 3";
+                  extent = "101 23";
+                  vertSizing = "center";
+                  profile = "MenuMLSubHeaderText";
+                  tooltipProfile = "GuiToolTipProfile";
+               };
+               new GuiTextEditCtrl() {
+                  text = "Torque 3D Server";
+                  position = "606 4";
+                  extent = "295 22";
+                  horizSizing = "left";
+                  vertSizing = "center";
+                  profile = "MenuTextEditprofile";
+                  variable = "$Pref::Server::Name";
+                  tooltipProfile = "GuiToolTipProfile";
+               };
+            };
+            new GuiContainer() {
+               position = "0 70";
+               extent = "900 30";
+               horizSizing = "width";
+               profile = "GuiDefaultProfile";
+               tooltipProfile = "GuiToolTipProfile";
+
+               new GuiTextCtrl() {
+                  text = "Server Password";
+                  position = "0 3";
+                  extent = "135 23";
+                  vertSizing = "center";
+                  profile = "MenuMLSubHeaderText";
+                  tooltipProfile = "GuiToolTipProfile";
+               };
+               new GuiTextEditCtrl() {
+                  text = "Torque 3D Server";
+                  position = "606 4";
+                  extent = "295 22";
+                  horizSizing = "left";
+                  vertSizing = "center";
+                  profile = "MenuTextEditprofile";
+                  variable = "$Pref::Server::Password";
+                  tooltipProfile = "GuiToolTipProfile";
+               };
+            };
+            new GuiContainer() {
+               position = "0 105";
+               extent = "900 30";
+               horizSizing = "width";
+               profile = "GuiDefaultProfile";
+               tooltipProfile = "GuiToolTipProfile";
+
+               new GuiTextCtrl() {
+                  text = "Server Description";
+                  position = "0 3";
+                  extent = "147 23";
+                  vertSizing = "center";
+                  profile = "MenuMLSubHeaderText";
+                  tooltipProfile = "GuiToolTipProfile";
+               };
+               new GuiTextEditCtrl() {
+                  text = "This is a Torque 3D server.";
+                  position = "606 4";
+                  extent = "295 22";
+                  horizSizing = "left";
+                  vertSizing = "center";
+                  profile = "MenuTextEditprofile";
+                  variable = "$Pref::Server::Info";
+                  tooltipProfile = "GuiToolTipProfile";
+               };
+            };
+            new GuiContainer() {
+               position = "0 140";
+               extent = "900 30";
+               horizSizing = "width";
+               profile = "GuiDefaultProfile";
+               tooltipProfile = "GuiToolTipProfile";
+
+               new GuiTextCtrl() {
+                  text = "Max Players";
+                  position = "0 3";
+                  extent = "94 23";
+                  vertSizing = "center";
+                  profile = "MenuMLSubHeaderText";
+                  tooltipProfile = "GuiToolTipProfile";
+               };
+               new GuiTextEditCtrl(JoinServerPlayerNameTxt) {
+                  text = "64";
+                  position = "606 4";
+                  extent = "295 22";
+                  horizSizing = "left";
+                  vertSizing = "center";
+                  profile = "MenuTextEditprofile";
+                  variable = "$Pref::Server::MaxPlayers";
+                  tooltipProfile = "GuiToolTipProfile";
+               };
+            };
+         };
+      };
+   };
    new GuiPanel(ChooseLevelButtonPanel) {
       position = "0 683";
       extent = "1281 40";
@@ -49,9 +318,9 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
          sizeIconToButton = "1";
          makeIconSquare = "1";
          textLocation = "Center";
-         text = "Start";
-         position = "1115 0";
-         extent = "140 40";
+         text = "Start Game";
+         position = "1092 0";
+         extent = "163 40";
          horizSizing = "left";
          vertSizing = "center";
          profile = "GuiMenuButtonProfile";
@@ -72,25 +341,5 @@ $guiContent = new GuiControl(ChooseLevelMenu) {
          tooltipProfile = "GuiToolTipProfile";
       };
    };
-   new GuiScrollCtrl(LevelPreviewScroll) {
-      hScrollBar = "dynamic";
-      vScrollBar = "alwaysOff";
-      position = "0 118";
-      extent = "1283 500";
-      horizSizing = "width";
-      vertSizing = "center";
-      profile = "GuiMenuScrollProfile";
-      tooltipProfile = "GuiToolTipProfile";
-
-      new GuiStackControl(LevelPreviewArray) {
-         position = "1 1";
-         extent = "1280 480";
-         vertSizing = "center";
-         profile = "GuiMenuDefaultProfile";
-         tooltipProfile = "GuiToolTipProfile";
-         padding = "5";
-         stackingType = "Horizontal";
-      };
-   };
 };
 //--- OBJECT WRITE END ---

+ 129 - 68
Templates/BaseGame/game/data/UI/guis/ChooseLevelMenu.tscript

@@ -19,12 +19,13 @@
 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
-
 //----------------------------------------
 function ChooseLevelMenu::onAdd( %this )
 {
    if(!isObject(ChooseLevelAssetQuery))
       new AssetQuery(ChooseLevelAssetQuery);
+      
+   %this.previewButtonSize = "445 120";
 }
 
 function ChooseLevelMenu::onWake(%this)
@@ -42,7 +43,7 @@ function ChooseLevelMenu::onWake(%this)
       MessageBoxOK("Error", "No levels were found in any modules. Please ensure you have modules loaded that contain gameplay code and level files.", 
          "Canvas.popDialog(ChooseLevelMenu); if(isObject(ChooseLevelMenu.returnGui) && ChooseLevelMenu.returnGui.isMethod(\"onReturnTo\")) ChooseLevelMenu.returnGui.onReturnTo();");
          
-      ChooseLevelAssetQuery.delete();
+      ChooseLevelAssetQuery.clear();
       return;
    }
    
@@ -65,47 +66,27 @@ function ChooseLevelMenu::onWake(%this)
       if (!isFile(%levelPreviewImg))
          %levelPreviewImg = "UI:no_preview_image";
          
-      %preview = new GuiContainer() { 
-         extent = "480 480";
+      %preview = new GuiIconButtonCtrl() {
+         position = "0 0";
+         extent = %this.previewButtonSize;
+         buttonType = "PushButton";
+         profile = GuiMenuButtonLeftJustProfile;
+         horizSizing = "right";
+         vertSizing = "bottom";
+         internalName = "button";
+         class = "LevelPreviewButton";
+         //command = "$selectedLevelAsset = " @ %assetId @ ";";
+         altCommand = "ChooseLevelBegin(1);"; //allow doubleclick to quick action it
+         text = %levelAsset.levelName;
+         bitmapAsset = %levelPreviewImg;
+         levelAsset = %levelAsset;
          levelAssetId = %assetId;
-         
-         new GuiButtonCtrl() {
-            position = "0 0";
-            extent = "480 480";
-            buttonType = "ToggleButton";
-            profile = GuiMenuButtonLeftJustProfile;
-            horizSizing = "width";
-            vertSizing = "height";
-            internalName = "button";
-            class = "LevelPreviewButton";
-            command = "$selectedLevelAsset = " @ %assetId @ ";";
-            altCommand = "ChooseLevelBegin(1);"; //allow doubleclick to quick action it
-         };
-         
-         new GuiBitmapCtrl() {
-            position = "20 0";
-            extent =  "440 440";
-            BitmapAsset = %levelPreviewImg; 
-            horizSizing = "width";
-            vertSizing = "bottom";
-            profile = GuiNonModalDefaultProfile;
-         };
-         
-         new GuiTextCtrl() { 
-            position = "20 445";
-            extent = "440 15";
-            text = %levelAsset.levelName;
-            profile = MenuSubHeaderText;
-            internalName = "levelNameTxt";
-         };
-            
-         new GuiMLTextCtrl() { 
-            position = "20 465";
-            extent = "440 15";
-            text = %levelAsset.levelDescription;
-            profile = GuiMLTextProfile;
-            internalName = "levelDescTxt";
-         };
+         iconLocation = "left";
+         sizeIconToButton = true;
+         makeIconSquare = true;
+         textLocation = "left";
+         textMargin = 120;
+         groupNum = 2;
       };
       
       LevelPreviewArray.add(%preview);
@@ -117,50 +98,115 @@ function ChooseLevelMenu::onWake(%this)
    {
       %this.addMissionFile( "tools/levels/DefaultEditorLevel.mis" );
    }
-   
-   //LevelList.setSelected(0);
-   
+
    if(!$pref::HostMultiPlayer)
       ChooseLevelTitleText.setText("SINGLE PLAYER");
    else
       ChooseLevelTitleText.setText("CREATE SERVER");
       
-   $MenuList = LevelPreviewArray;
-   $MenuList.listPosition = 0;
-   $MenuList.syncGui();
+   %this.openMenu(0);
 }
 
 if(!isObject( ChooseLevelActionMap ) )
 {
    new ActionMap(ChooseLevelActionMap){}; 
    
-   //Null the up/down nav so we can swap in left/right nav
-   ChooseLevelActionMap.bindCmd( keyboard, w, "" );
-   ChooseLevelActionMap.bindCmd( keyboard, s, "" );
-   ChooseLevelActionMap.bindCmd( gamepad, yaxis, "" );
-   ChooseLevelActionMap.bindCmd( gamepad, upov, "" );
-   ChooseLevelActionMap.bindCmd( gamepad, dpov, "" );
+   ChooseLevelActionMap.bind( keyboard, q, ChooseLevelMenuPrevMenu);
+   ChooseLevelActionMap.bind( gamepad, btn_l, ChooseLevelMenuPrevMenu);
    
-   ChooseLevelActionMap.bind( keyboard, a, BaseUINavigatePrev );
-   ChooseLevelActionMap.bind( keyboard, d, BaseUINavigateNext );
-   ChooseLevelActionMap.bind( gamepad, xaxis, "D", "-0.23 0.23", BaseUIStickNavigate );
-   ChooseLevelActionMap.bind( gamepad, lpov, BaseUINavigatePrev );
-   ChooseLevelActionMap.bind( gamepad, rpov, BaseUINavigateNext );
+   ChooseLevelActionMap.bind( keyboard, e, ChooseLevelMenuNextMenu);
+   ChooseLevelActionMap.bind( gamepad, btn_r, ChooseLevelMenuNextMenu);
    
    ChooseLevelActionMap.bind( keyboard, Space, ChooseLevelBegin );
    ChooseLevelActionMap.bind( gamepad, btn_a, ChooseLevelBegin );
 }
 
-function LevelPreviewArray::syncGUI(%this)
+function ChooseLevelMenu::syncGUI(%this)
 {
-   %this.callOnChildren("setHighlighted", false);
+   //Update the button imagery to comply to the last input device we'd used
+   %device = Canvas.getLastInputDevice();
+   if(%device $= "mouse")
+      %device = "keyboard";
+      
+   //Category handling
+   %btn = ChooseLevelMenuTabList.getObject(%this.currentMenuIdx);
+   %btn.setHighlighted(true);
+   
+   %buttonPosX = %btn.position.x + ChooseLevelMenuTabList.position.x;
+
+   ChooseLevelMenuPrevNavIcon.position.x = %buttonPosX;
+   ChooseLevelMenuNextNavIcon.position.x = %buttonPosX + %btn.extent.x - 40;
+     
+   ChooseLevelBackBtn.setBitmap(BaseUIActionMap.getCommandButtonBitmap(%device, "BaseUIBackOut"));
+   
+   ChooseLevelStartBtn.setBitmap(ChooseLevelActionMap.getCommandButtonBitmap(%device, "ChooseLevelBegin"));
    
+   ChooseLevelMenuPrevNavIcon.setBitmap(ChooseLevelActionMap.getCommandButtonBitmap(%device, "ChooseLevelMenuPrevMenu"));
+   ChooseLevelMenuNextNavIcon.setBitmap(ChooseLevelActionMap.getCommandButtonBitmap(%device, "ChooseLevelMenuNextMenu"));
+   
+   ChooseLevelMenuTabList.visible = $pref::HostMultiPlayer;
+   ChooseLevelMenuNavButtonOverlay.visible = $pref::HostMultiPlayer;
+}
+
+function LevelPreviewArray::syncGUI(%this)
+{
    %btn = %this.getObject(%this.listPosition);
-   %btn-->button.setHighlighted(true);
+   %btn.setHighlighted(true);
    
    $selectedLevelAsset = %btn.levelAssetId;
 }
 
+function ChooseLevelMenuPrevMenu(%val)
+{
+   if(%val)
+   {
+      %currentIdx = ChooseLevelMenu.currentMenuIdx;
+      ChooseLevelMenu.currentMenuIdx -= 1;
+      
+      ChooseLevelMenu.currentMenuIdx = mClamp(ChooseLevelMenu.currentMenuIdx, 0, 1);
+    
+      if(%currentIdx == ChooseLevelMenu.currentMenuIdx)
+         return;
+ 
+      ChooseLevelMenu.openMenu(ChooseLevelMenu.currentMenuIdx);
+   }
+}
+
+function ChooseLevelMenuNextMenu(%val)
+{
+   if(%val)
+   {
+      %currentIdx = ChooseLevelMenu.currentMenuIdx;
+      ChooseLevelMenu.currentMenuIdx += 1;
+      
+      ChooseLevelMenu.currentMenuIdx = mClamp(ChooseLevelMenu.currentMenuIdx, 0, 1);
+    
+      if(%currentIdx == ChooseLevelMenu.currentMenuIdx)
+         return;
+ 
+      ChooseLevelMenu.openMenu(ChooseLevelMenu.currentMenuIdx);
+   }
+}
+
+
+function ChooseLevelMenu::openMenu(%this, %menuIdx)
+{
+   LevelSelectContainer.setVisible(%menuIdx == 0);
+   ServerConfigContainer.setVisible(%menuIdx == 1);
+   
+   if(%menuIdx == 0)
+      $MenuList = LevelPreviewArray;
+   else if(%menuIdx == 1)
+      $MenuList = ServerConfigList;
+   
+    %this.currentMenuIdx = %menuIdx;
+
+   if($MenuList.isMethod("syncGui"))
+      $MenuList.syncGui();
+      
+   %this.syncGui();
+}
+
 function ChooseLevelBegin(%val)
 {
    if(%val)
@@ -178,6 +224,8 @@ function ChooseLevelBegin(%val)
          MessageBoxOK("Error", "Selected level preview does not have a valid level asset!");
          return;  
       }
+      
+      $selectedLevelAsset = %entry.levelAssetId;
 
       // Launch the chosen level with the editor open?
       if ( ChooseLevelMenu.launchInEditor )
@@ -198,14 +246,27 @@ function ChooseLevelMenu::onSleep( %this )
    // This is set from the outside, only stays true for a single wake/sleep
    // cycle.
    %this.launchInEditor = false;
+   
+   //Ensure any changes we made to our server configs is saved out
+   if($pref::HostMultiPlayer)
+   {
+      echo("Exporting server prefs");
+      %prefPath = getPrefpath();
+      export("$Pref::Server::*", %prefPath @ "/serverPrefs." @ $TorqueScriptFileExtension, false);
+      BanList::Export(%prefPath @ "/banlist." @ $TorqueScriptFileExtension);  
+   }
 }
 
 function LevelPreviewButton::onHighlighted(%this, %highlighted)
 {
-   %container = %this.getParent();
-   
-   %container-->levelNameTxt.profile = %highlighted ? MenuSubHeaderTextHighlighted : MenuSubHeaderText;
-   %container-->levelDescTxt.profile = %highlighted ? GuiMLTextProfileHighlighted : GuiMLTextProfile;
-   
-   LevelPreviewScroll.scrollToObject(%this);
+   if(%highlighted)
+   {
+      $MenuList.listPosition = $MenuList.getObjectIndex(%this);
+      
+      LevelPreviewBitmap.bitmapAsset = %this.bitmapAsset;
+      LevelNameText.text = %this.levelAsset.levelName;
+      LevelDescriptionText.setText(%this.levelAsset.levelDescription);
+      
+      LevelPreviewScroll.scrollToObject(%this);
+   }
 }

+ 30 - 4
Templates/BaseGame/game/data/UI/guis/joinServerMenu.gui

@@ -50,7 +50,7 @@ $guiContent = new GuiControl(JoinServerMenu) {
       new GuiTextEditCtrl(JoinServerPlayerNameTxt) {
          text = "Visitor";
          position = "606 7";
-         extent = "295 18";
+         extent = "295 22";
          horizSizing = "left";
          vertSizing = "center";
          profile = "MenuTextEditprofile";
@@ -59,7 +59,33 @@ $guiContent = new GuiControl(JoinServerMenu) {
       };
    };
    new GuiContainer() {
-      position = "190 97";
+      position = "190 87";
+      extent = "900 30";
+      horizSizing = "center";
+      profile = "GuiDefaultProfile";
+      tooltipProfile = "GuiToolTipProfile";
+
+      new GuiTextCtrl() {
+         text = "Password";
+         position = "0 5";
+         extent = "78 23";
+         vertSizing = "center";
+         profile = "MenuMLSubHeaderText";
+         tooltipProfile = "GuiToolTipProfile";
+      };
+      new GuiTextEditCtrl(JoinServerPasswordTxt) {
+         text = "Visitor";
+         position = "606 7";
+         extent = "295 22";
+         horizSizing = "left";
+         vertSizing = "center";
+         profile = "MenuTextEditprofile";
+         variable = "$Client::Password";
+         tooltipProfile = "GuiToolTipProfile";
+      };
+   };
+   new GuiContainer() {
+      position = "190 121";
       extent = "900 30";
       horizSizing = "center";
       profile = "GuiMenuPanelProfile";
@@ -94,8 +120,8 @@ $guiContent = new GuiControl(JoinServerMenu) {
    new GuiScrollCtrl() {
       hScrollBar = "alwaysOff";
       vScrollBar = "dynamic";
-      position = "190 127";
-      extent = "900 551";
+      position = "190 151";
+      extent = "900 532";
       minExtent = "8 8";
       horizSizing = "center";
       vertSizing = "height";

+ 9 - 0
Templates/BaseGame/game/data/UI/guis/joinServerMenu.tscript

@@ -2,11 +2,20 @@
 function JoinServerMenu::onWake(%this)
 {
    $MenuList = JoinServerList;
+   $MenuList.clear();
+   $Client::Password = "";
    JoinServerList.listPosition = 0;
    
    JoinServerList.syncGui();
 }   
 
+function JoinServerMenu::onSleep(%this)
+{
+   echo("Exporting client prefs");
+   %prefPath = getPrefpath();
+   export("$pref::*", %prefPath @ "/clientPrefs." @ $TorqueScriptFileExtension, false);  
+}
+
 if(!isObject( JoinServerActionMap ) )
 {
    new ActionMap(JoinServerActionMap){};

+ 3 - 0
Templates/BaseGame/game/data/UI/guis/mainMenu.tscript

@@ -120,6 +120,9 @@ function MainMenuButton::onHighlighted(%this, %highlighted)
 
 function BaseUIActivateSelected()
 {
+   if($MenuList.getCount() == 0 || $MenuList.listPosition >= $MenuList.getCount() || $MenuList.listPosition < 0)
+      return;
+      
    %btn = $MenuList.getObject($MenuList.listPosition);
    
    if(%btn.isMethod("performClick"))