1
0
forked from 0ad/0ad

Rewrite the prelobby pages and add the Terms of Service, Terms of Use and the agreement checkbox to the login page.

Ensure lobby players cannot join without acceptance of the terms in case
they change, fixes #5218, as agreed in last staff meeting.

Separate lobby entrance, lobby login and lobby register GUI page.
Since bffe917914 they were squashed into a single GUI page;
 Adding lots of hardcode to set the visibility of GUI objects;
 Reinventing a GUI page manager in JS;
 Unintentionally persisting data between pages;
 Requiring lots of errorprone case distinctions which are unneeded once
relevant GUI objects and code is loaded exclusively.

Add the remember-password checkbox from b6b547d5f8 / D822 to the
registration page too.

Revert the revert of ccb534259d in 9f9db45a03 and continue to prefer
objects with separate functions per C++ GUI message type,
reducing the nesting of conditionals per function and reveal codeflow by
making input and output variables explicit.

Fix oversight in 0940db3fc0 by moving the registrationrate string from
0e2d2610c9 from the "disconnect" to the "error" case.

Differential Revision: https://code.wildfiregames.com/D1568
Few comments by: Vladislav, Imarok, gallaecio
This was SVN commit r21847.
This commit is contained in:
elexis 2018-06-11 15:59:22 +00:00
parent de1a73ba65
commit 80dbd1f2a3
24 changed files with 475 additions and 444 deletions

View File

@ -413,6 +413,7 @@ extended = true ; Whether to display the chat history
history = 0 ; Number of past messages to display on join
room = "arena23" ; Default MUC room to join
server = "lobby.wildfiregames.com" ; Address of lobby server
;server = "localhost" ; Address of lobby server
xpartamupp = "wfgbot23" ; Name of the server-side XMPP-account that manage games
echelon = "echelon23" ; Name of the server-side XMPP-account that manages ratings
buddies = "," ; Comma separated list of playernames that the current user has marked as buddies

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<page>
<include>common/modern/setup.xml</include>
<include>common/modern/styles.xml</include>
<include>common/modern/sprites.xml</include>
<include>common/global.xml</include>
<include>prelobby/entrance/entrance.xml</include>
</page>

View File

@ -6,5 +6,5 @@
<include>common/global.xml</include>
<include>prelobby/prelobby.xml</include>
<include>prelobby/login/login.xml</include>
</page>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<page>
<include>common/modern/setup.xml</include>
<include>common/modern/styles.xml</include>
<include>common/modern/sprites.xml</include>
<include>common/global.xml</include>
<include>prelobby/register/register.xml</include>
</page>

View File

@ -320,7 +320,7 @@
if (!Engine.StartXmppClient)
return;
closeMenu();
Engine.PushGuiPage("page_prelobby.xml");
Engine.PushGuiPage("page_prelobby_entrance.xml");
</action>
<action on="load">
if (!Engine.StartXmppClient)

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<object>
<object type="text" size="10 0 40% 30" style="ModernRightLabelText">
<translatableAttribute id="caption">Password again:</translatableAttribute>
</object>
<object name="passwordRepeat" type="input" size="40%+10 0 100%-20 24" style="ModernInput" mask="true" mask_char="*">
<action on="TextEdit">updateFeedback();</action>
</object>
</object>

View File

@ -0,0 +1,86 @@
function checkUsername(register)
{
let username = Engine.GetGUIObjectByName("username").caption;
if (!username)
return translate("Please enter your username");
if (register && (!username.match(/^[a-z0-9._-]*$/i) || username.length > 20))
return translate("Invalid username");
return "";
}
function checkPassword(register)
{
if (!Engine.GetGUIObjectByName("password").caption)
return register ?
translateWithContext("register", "Please enter your password") :
translateWithContext("login", "Please enter your password");
return "";
}
function checkPasswordConfirmation()
{
let password1 = Engine.GetGUIObjectByName("password").caption;
if (!password1)
return translate("Please enter your password again");
let password2 = Engine.GetGUIObjectByName("passwordRepeat").caption;
if (password1 != password2)
return translate("Passwords do not match");
return "";
}
function initRememberPassword()
{
Engine.GetGUIObjectByName("rememberPassword").checked =
Engine.ConfigDB_GetValue("user", "lobby.rememberpassword") == "true";
}
function toggleRememberPassword()
{
let checkbox = Engine.GetGUIObjectByName("rememberPassword");
let enabled = Engine.ConfigDB_GetValue("user", "lobby.rememberpassword") == "true";
if (!checkbox.checked && enabled && Engine.ConfigDB_GetValue("user", "lobby.password"))
messageBox(
360, 160,
translate("Are you sure you want to delete the password after connecting?"),
translate("Confirmation"),
[translate("No"), translate("Yes")],
[
() => { checkbox.checked = true; },
() => { saveSettingAndWriteToUserConfig("lobby.rememberpassword", String(!enabled)); }
]);
else
saveSettingAndWriteToUserConfig("lobby.rememberpassword", String(!enabled));
}
function getEncryptedPassword()
{
let typedUnencryptedPassword = Engine.GetGUIObjectByName("password").caption;
let storedEncryptedPassword = Engine.ConfigDB_GetValue("user", "lobby.password");
if (typedUnencryptedPassword == storedEncryptedPassword.substr(0, 10))
return storedEncryptedPassword;
return Engine.EncryptPassword(
typedUnencryptedPassword,
Engine.GetGUIObjectByName("username").caption);
}
function saveCredentials()
{
let username = Engine.GetGUIObjectByName("username").caption;
saveSettingAndWriteToUserConfig("playername.multiplayer", username);
saveSettingAndWriteToUserConfig("lobby.login", username);
if (Engine.ConfigDB_GetValue("user", "lobby.rememberpassword") == "true")
saveSettingAndWriteToUserConfig("lobby.password", getEncryptedPassword());
else
{
Engine.ConfigDB_RemoveValue("user", "lobby.password");
Engine.ConfigDB_WriteFile("user", "config/user.cfg");
}
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<object>
<object>
<object type="text" size="20 00 40% 30" style="ModernRightLabelText">
<translatableAttribute id="caption">Login:</translatableAttribute>
</object>
<object name="username" type="input" size="40%+10 0 100%-20 24" style="ModernInput">
<action on="TextEdit">updateFeedback();</action>
</object>
</object>>
<object>
<object type="text" size="20 40 40% 70" style="ModernRightLabelText">
<translatableAttribute id="caption">Password:</translatableAttribute>
</object>
<object name="password" type="input" size="40%+10 40 100%-20 64" style="ModernInput" mask="true" mask_char="*">
<action on="TextEdit">updateFeedback();</action>
</object>
</object>
</object>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<object>
<object name="rememberPassword" type="checkbox" size="40%-19 0 40% 20" style="ModernTickBox">
<action on="Press">toggleRememberPassword();</action>
</object>
<object type="text" size="40%+10 0 100%-20 20" style="ModernLeftLabelText">
<translatableAttribute id="caption">Remember Password</translatableAttribute>
</object>
</object>

View File

@ -0,0 +1,39 @@
var g_LobbyMessages = {
"error": message => {
setFeedback(message.text ||
translate("Unknown error. This usually occurs because the same IP address is not allowed to register more than one account within one hour."));
Engine.StopXmppClient();
},
"disconnected": message => {
setFeedback(message.reason);
Engine.StopXmppClient();
}
};
function onTick()
{
while (true)
{
let message = Engine.LobbyGuiPollNewMessage();
if (!message)
break;
if (message.type == "system" && message.level)
g_LobbyMessages[message.level](message);
else
warn("Unknown prelobby message: " + uneval(message));
}
}
function setFeedback(feedbackText)
{
Engine.GetGUIObjectByName("feedback").caption = feedbackText;
Engine.GetGUIObjectByName("continue").enabled = !feedbackText;
}
function cancelButton()
{
if (Engine.HasXmppClient())
Engine.StopXmppClient();
Engine.PopGuiPage();
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<object>
<action on="Tick">onTick();</action>
<object name="feedback" type="text" size="50 0 100%-50 60" style="ModernLabelText" textcolor="red"/>
<object name="cancel" type="button" size="18 65 50%-5 93" style="ModernButtonRed" hotkey="cancel">
<translatableAttribute id="caption">Cancel</translatableAttribute>
<action on="Press">cancelButton();</action>
</object>
<object name="continue" hotkey="confirm" type="button" size="50%+5 65 100%-18 93" style="ModernButtonRed" enabled="false">
<action on="Press">continueButton();</action>
</object>
</object>

View File

@ -0,0 +1,38 @@
var g_Terms = {
"Service": {
"title": translate("Terms of Service"),
"instruction": translate("Please read the Terms of Service"),
"file": "prelobby/common/terms/Terms_of_Service",
"read": false
},
"Use": {
"title": translate("Terms of Use"),
"instruction": translate("Please read the Terms of Use"),
"file": "prelobby/common/terms/Terms_of_Use",
"read": false
}
};
function openTerms(terms)
{
g_Terms[terms].read = true;
Engine.GetGUIObjectByName("agreeTerms").enabled = g_Terms.Service.read && g_Terms.Use.read;
Engine.PushGuiPage("page_manual.xml", {
"page": g_Terms[terms].file,
"title": g_Terms[terms].title,
"callback": "updateFeedback"
});
}
function checkTerms()
{
for (let page in g_Terms)
if (!g_Terms[page].read)
return g_Terms[page].instruction;
if (!Engine.GetGUIObjectByName("agreeTerms").checked)
return translate("Please agree to the Terms of Service and Terms of Use");
return "";
}

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<object>
<object type="button" size="20 0 100%-20 28" style="ModernButtonRed">
<translatableAttribute id="caption">Terms of Service</translatableAttribute>
<action on="Press">openTerms("Service");</action>
</object>
<object type="button" size="20 40 100%-20 68" style="ModernButtonRed">
<translatableAttribute id="caption">Terms of Use</translatableAttribute>
<action on="Press">openTerms("Use");</action>
</object>
<object type="text" size="20 80 100%-80 110" style="ModernLabelText">
<translatableAttribute id="caption">I have read and agree to the Terms of Service and Terms of Use:</translatableAttribute>
</object>
<object name="agreeTerms" type="checkbox" size="100%-60 85 100%-20 110" style="ModernTickBox" enabled="false">
<action on="Press">updateFeedback();</action>
</object>
</object>

View File

@ -0,0 +1,20 @@
function init()
{
if (Engine.ConfigDB_GetValue("user", "lobby.login"))
loginButton();
}
function loginButton()
{
Engine.PushGuiPage("page_prelobby_login.xml");
}
function registerButton()
{
Engine.PushGuiPage("page_prelobby_register.xml");
}
function cancelButton()
{
Engine.PopGuiPage();
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<objects>
<script directory="gui/common/"/>
<script directory="gui/prelobby/entrance/"/>
<!-- Add a translucent black background to fade out the menu page -->
<object type="image" z="0" sprite="ModernFade"/>
<object name="dialog" type="image" style="ModernDialog" size="50%-230 50%-130 50%+230 50%+130">
<object style="ModernLabelText" type="text" size="50%-128 -18 50%+128 14">
<translatableAttribute id="caption">Multiplayer Lobby</translatableAttribute>
</object>
<object size="0 32 100% 100%">
<object type="button" size="50 12 100%-50 68" style="ModernButtonRed">
<translatableAttribute id="caption">Create a new account</translatableAttribute>
<action on="Press">registerButton();</action>
</object>
<object type="button" size="50 80 100%-50 136" style="ModernButtonRed">
<translatableAttribute id="caption">Login to an existing account</translatableAttribute>
<action on="Press">loginButton();</action>
</object>
<object name="cancel" type="button" size="18 100%-45 50%-5 100%-17" style="ModernButtonRed" hotkey="cancel">
<translatableAttribute id="caption">Cancel</translatableAttribute>
<action on="Press">cancelButton();</action>
</object>
</object>
</object>
</objects>

View File

@ -0,0 +1,42 @@
function init()
{
g_LobbyMessages.connected = onLogin;
Engine.GetGUIObjectByName("continue").caption = translate("Connect");
// Shorten the displayed password for visual reasons only
Engine.GetGUIObjectByName("username").caption = Engine.ConfigDB_GetValue("user", "lobby.login");
Engine.GetGUIObjectByName("password").caption = Engine.ConfigDB_GetValue("user", "lobby.password").substr(0, 10);
initRememberPassword();
updateFeedback();
}
function updateFeedback()
{
setFeedback(checkUsername(false) || checkPassword(false) || checkTerms());
}
function continueButton()
{
setFeedback(translate("Connecting…"));
Engine.StartXmppClient(
Engine.GetGUIObjectByName("username").caption,
getEncryptedPassword(),
Engine.ConfigDB_GetValue("user", "lobby.room"),
Engine.GetGUIObjectByName("username").caption,
+Engine.ConfigDB_GetValue("user", "lobby.history"));
Engine.ConnectXmppClient();
}
function onLogin(message)
{
saveCredentials();
Engine.SwitchGuiPage("page_lobby.xml", {
"dialog": false
});
}

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<objects>
<script directory="gui/common/"/>
<script directory="gui/prelobby/common/credentials/"/>
<script directory="gui/prelobby/common/feedback/"/>
<script directory="gui/prelobby/common/terms/"/>
<script directory="gui/prelobby/login/"/>
<object type="image" style="ModernDialog" size="50%-230 50%-180 50%+230 50%+180">
<object style="ModernLabelText" type="text" size="50%-128 -18 50%+128 14">
<translatableAttribute id="caption">Connect to the game lobby</translatableAttribute>
</object>
<object size="0 30 100% 100">
<include file="gui/prelobby/common/credentials/credentials.xml"/>
</object>
<object size="0 105 100% 120">
<include file="gui/prelobby/common/credentials/rememberpassword.xml"/>
</object>
<object size="0 130 100% 240">
<include file="gui/prelobby/common/terms/terms.xml"/>
</object>
<object size="0 250 100% 350">
<include file="gui/prelobby/common/feedback/feedback.xml"/>
</object>
</object>
</objects>

View File

@ -1,330 +0,0 @@
var g_LobbyIsConnecting = false;
var g_EncryptedPassword = "";
var g_PasswordInputIsHidden = false;
var g_DisplayingSystemMessage = false;
var g_Terms = {
"Service": {
"title": translate("Terms of Service"),
"instruction": translate("Please read the Terms of Service"),
"file": "prelobby/Terms_of_Service",
"read": false
},
"Use": {
"title": translate("Terms of Use"),
"instruction": translate("Please read the Terms of Use"),
"file": "prelobby/Terms_of_Use",
"read": false
}
};
function init()
{
let username = Engine.ConfigDB_GetValue("user", "lobby.login");
g_EncryptedPassword = Engine.ConfigDB_GetValue("user", "lobby.password");
// We only show 10 characters to make it look decent.
Engine.GetGUIObjectByName("connectUsername").caption = username;
Engine.GetGUIObjectByName("connectPassword").caption = g_EncryptedPassword.substring(0, 10);
Engine.GetGUIObjectByName("rememberPassword").checked =
Engine.ConfigDB_GetValue("user", "lobby.rememberpassword") == "true";
if (username && g_EncryptedPassword)
switchPage("connect");
}
function lobbyStop()
{
Engine.GetGUIObjectByName("feedback").caption = "";
if (!g_LobbyIsConnecting)
return;
g_LobbyIsConnecting = false;
Engine.StopXmppClient();
}
function lobbyStartConnect()
{
if (g_LobbyIsConnecting)
return;
if (Engine.HasXmppClient())
Engine.StopXmppClient();
Engine.GetGUIObjectByName("continue").enabled = false;
let username = Engine.GetGUIObjectByName("connectUsername").caption;
let password = Engine.GetGUIObjectByName("connectPassword").caption;
let feedback = Engine.GetGUIObjectByName("feedback");
let room = Engine.ConfigDB_GetValue("user", "lobby.room");
let history = Number(Engine.ConfigDB_GetValue("user", "lobby.history"));
feedback.caption = translate("Connecting…");
// If they enter a different password, re-encrypt.
if (password != g_EncryptedPassword.substring(0, 10))
g_EncryptedPassword = Engine.EncryptPassword(password, username);
// We just use username as nick for simplicity.
Engine.StartXmppClient(username, g_EncryptedPassword, room, username, history);
g_LobbyIsConnecting = true;
Engine.ConnectXmppClient();
}
function lobbyStartRegister()
{
if (g_LobbyIsConnecting)
return;
if (Engine.HasXmppClient())
Engine.StopXmppClient();
Engine.GetGUIObjectByName("continue").enabled = false;
let account = Engine.GetGUIObjectByName("registerUsername").caption;
let password = Engine.GetGUIObjectByName("registerPassword").caption;
let feedback = Engine.GetGUIObjectByName("feedback");
feedback.caption = translate("Registering…");
g_EncryptedPassword = Engine.EncryptPassword(password, account);
Engine.StartRegisterXmppClient(account, g_EncryptedPassword);
g_LobbyIsConnecting = true;
Engine.ConnectXmppClient();
}
function onTick()
{
let pageRegisterHidden = Engine.GetGUIObjectByName("pageRegister").hidden;
let username = Engine.GetGUIObjectByName(pageRegisterHidden ? "connectUsername" : "registerUsername").caption;
let password = Engine.GetGUIObjectByName(pageRegisterHidden ? "connectPassword" : "registerPassword").caption;
let passwordAgain = Engine.GetGUIObjectByName("registerPasswordAgain").caption;
let agreeTerms = Engine.GetGUIObjectByName("registerAgreeTerms");
let feedback = Engine.GetGUIObjectByName("feedback");
let continueButton = Engine.GetGUIObjectByName("continue");
// Do not change feedback while connecting.
if (g_LobbyIsConnecting) {}
// Do not show feedback on the welcome screen.
else if (!Engine.GetGUIObjectByName("pageWelcome").hidden)
{
feedback.caption = "";
g_DisplayingSystemMessage = false;
}
// Check that they entered a username.
else if (!username)
{
continueButton.enabled = false;
feedback.caption = translate("Please enter your username");
}
// Prevent registation (but not login) with non-alphanumerical characters
else if (!pageRegisterHidden && (!username.match(/^[a-z0-9._-]*$/i) || username.length > 20))
{
continueButton.enabled = false;
feedback.caption = translate("Invalid username");
}
// Check that they entered a password.
else if (!password)
{
continueButton.enabled = false;
feedback.caption = pageRegisterHidden ?
translateWithContext("login", "Please enter your password") :
translateWithContext("register", "Please enter your password");
}
// Allow them to connect if tests pass up to this point.
else if (pageRegisterHidden)
{
if (!g_DisplayingSystemMessage)
feedback.caption = "";
continueButton.enabled = true;
}
// Check that they entered their password again.
else if (!passwordAgain)
{
continueButton.enabled = false;
feedback.caption = translate("Please enter your password again");
}
// Check that the passwords match.
else if (passwordAgain != password)
{
continueButton.enabled = false;
feedback.caption = translate("Passwords do not match");
}
// Check that they read the Terms of Service.
else if (!g_Terms.Service.read)
{
continueButton.enabled = false;
feedback.caption = g_Terms.Service.instruction;
}
// Check that they read the Terms of Use.
else if (!g_Terms.Use.read)
{
continueButton.enabled = false;
feedback.caption = g_Terms.Use.instruction;
}
// Check that they agree to the terms of service and use.
else if (!agreeTerms.checked)
{
continueButton.enabled = false;
feedback.caption = translate("Please agree to the Terms of Service and Terms of Use");
}
// Allow them to register.
else
{
if (!g_DisplayingSystemMessage)
feedback.caption = "";
continueButton.enabled = true;
}
// Handle queued messages from the XMPP client (if running and if any)
let message;
while ((message = Engine.LobbyGuiPollNewMessage()) != undefined)
{
// TODO: Properly deal with unrecognized messages
if (message.type != "system" || !message.level)
continue;
g_LobbyIsConnecting = false;
switch (message.level)
{
case "error":
{
Engine.GetGUIObjectByName("feedback").caption = message.text;
g_DisplayingSystemMessage = true;
Engine.StopXmppClient();
break;
}
case "disconnected":
{
Engine.GetGUIObjectByName("feedback").caption = message.reason ||
translate("Unknown error. This usually occurs because the same IP address is not allowed to register more than one account within one hour.");
g_DisplayingSystemMessage = true;
Engine.StopXmppClient();
break;
}
case "registered":
Engine.GetGUIObjectByName("feedback").caption = translate("Registered");
g_DisplayingSystemMessage = true;
Engine.GetGUIObjectByName("connectUsername").caption = username;
Engine.GetGUIObjectByName("connectPassword").caption = password;
Engine.StopXmppClient();
switchPage("connect");
break;
case "connected":
{
Engine.PopGuiPage();
Engine.SwitchGuiPage("page_lobby.xml", { "dialog": false });
saveSettingAndWriteToUserConfig("playername.multiplayer", username);
saveSettingAndWriteToUserConfig("lobby.login", username);
// We only store the encrypted password, so make sure to re-encrypt it if changed before saving.
if (password != g_EncryptedPassword.substring(0, 10))
g_EncryptedPassword = Engine.EncryptPassword(password, username);
Engine.ConfigDB_CreateValue("user", "lobby.password", g_EncryptedPassword);
if (Engine.ConfigDB_GetValue("user", "lobby.rememberpassword") == "true")
Engine.ConfigDB_WriteValueToFile("user", "lobby.password", g_EncryptedPassword, "config/user.cfg");
else
{
Engine.ConfigDB_RemoveValue("user", "lobby.password");
Engine.ConfigDB_WriteFile("user", "config/user.cfg");
}
break;
}
}
}
}
function switchPage(page)
{
// First hide everything.
if (!Engine.GetGUIObjectByName("pageWelcome").hidden)
Engine.GetGUIObjectByName("pageWelcome").hidden = true;
else if (!Engine.GetGUIObjectByName("pageRegister").hidden)
{
Engine.GetGUIObjectByName("pageRegister").hidden = true;
Engine.GetGUIObjectByName("continue").hidden = true;
let dialog = Engine.GetGUIObjectByName("dialog");
let newSize = dialog.size;
newSize.bottom -= 150;
dialog.size = newSize;
}
else if (!Engine.GetGUIObjectByName("pageConnect").hidden)
{
Engine.GetGUIObjectByName("pageConnect").hidden = true;
Engine.GetGUIObjectByName("continue").hidden = true;
}
// Then show appropriate page.
switch(page)
{
case "welcome":
Engine.GetGUIObjectByName("pageWelcome").hidden = false;
break;
case "register":
{
let dialog = Engine.GetGUIObjectByName("dialog");
let newSize = dialog.size;
newSize.bottom += 150;
dialog.size = newSize;
Engine.GetGUIObjectByName("pageRegister").hidden = false;
Engine.GetGUIObjectByName("continue").caption = translate("Register");
Engine.GetGUIObjectByName("continue").hidden = false;
break;
}
case "connect":
Engine.GetGUIObjectByName("pageConnect").hidden = false;
Engine.GetGUIObjectByName("continue").caption = translate("Connect");
Engine.GetGUIObjectByName("continue").hidden = false;
break;
}
}
function openTerms(terms)
{
g_Terms[terms].read = true;
Engine.GetGUIObjectByName("registerAgreeTerms").enabled = g_Terms.Service.read && g_Terms.Use.read;
Engine.PushGuiPage("page_manual.xml", {
"page": g_Terms[terms].file,
"title": g_Terms[terms].title
});
}
function prelobbyConnect()
{
if (!Engine.GetGUIObjectByName("pageConnect").hidden)
lobbyStartConnect();
else if (!Engine.GetGUIObjectByName("pageRegister").hidden)
lobbyStartRegister();
}
function prelobbyCancel()
{
lobbyStop();
Engine.GetGUIObjectByName("feedback").caption = "";
if (Engine.GetGUIObjectByName("pageWelcome").hidden)
switchPage("welcome");
else
Engine.PopGuiPage();
}
function toggleRememberPassword()
{
let checkbox = Engine.GetGUIObjectByName("rememberPassword");
let enabled = Engine.ConfigDB_GetValue("user", "lobby.rememberpassword") == "true";
if (!checkbox.checked && enabled && Engine.ConfigDB_GetValue("user", "lobby.password"))
{
messageBox(
360, 160,
translate("Are you sure you want to delete the password after connecting?"),
translate("Confirmation"),
[translate("No"), translate("Yes")],
[function() { checkbox.checked = true; },
function() { saveSettingAndWriteToUserConfig("lobby.rememberpassword", String(!enabled)); }]
);
}
else
saveSettingAndWriteToUserConfig("lobby.rememberpassword", String(!enabled));
}

View File

@ -1,110 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<objects>
<script directory="gui/common/"/>
<script directory="gui/prelobby/"/>
<object hotkey="lobby">
<action on="Press">
lobbyStop();
Engine.PopGuiPage();
</action>
</object>
<!-- Add a translucent black background to fade out the menu page -->
<object type="image" z="0" sprite="ModernFade"/>
<object name="dialog" type="image" style="ModernDialog" size="50%-230 50%-130 50%+230 50%+130">
<action on="Tick">onTick();</action>
<object style="ModernLabelText" type="text" size="50%-128 -18 50%+128 14">
<translatableAttribute id="caption">Multiplayer Lobby</translatableAttribute>
</object>
<object name="pageWelcome" size="0 32 100% 100%">
<object type="button" size="50 12 100%-50 68" style="ModernButtonRed">
<translatableAttribute id="caption">Create a new account</translatableAttribute>
<action on="Press">switchPage("register");</action>
</object>
<object type="button" size="50 80 100%-50 136" style="ModernButtonRed">
<translatableAttribute id="caption">Login to an existing account</translatableAttribute>
<action on="Press">switchPage("connect");</action>
</object>
</object>
<object name="pageConnect" size="0 32 100% 100%" hidden="true">
<object type="text" size="0 0 100% 30" style="ModernLabelText">
<translatableAttribute id="caption">Connect to the game lobby</translatableAttribute>
</object>
<object name="connectUsernameLabel" type="text" size="20 40 50% 70" style="ModernRightLabelText">
<translatableAttribute id="caption">Login:</translatableAttribute>
</object>
<object name="connectUsername" type="input" size="50%+10 40 100%-20 64" style="ModernInput"/>
<object name="connectPasswordLabel" type="text" size="20 80 50% 110" style="ModernRightLabelText">
<translatableAttribute id="caption">Password:</translatableAttribute>
</object>
<object name="connectPassword" type="input" size="50%+10 80 100%-20 104" style="ModernInput" mask="true" mask_char="*">
<action on="Press">lobbyStartConnect();</action>
</object>
<object name="rememberPassword" type="checkbox" size="50%-19 115 50% 135" style="ModernTickBox">
<action on="Press">toggleRememberPassword();</action>
</object>
<object type="text" size="50%+10 115 100%-20 135" style="ModernLeftLabelText">
<translatableAttribute id="caption">Remember Password</translatableAttribute>
</object>
</object>
<object name="pageRegister" size="0 32 100% 100%" hidden="true">
<object type="text" size="0 0 100% 30" style="ModernLabelText">
<translatableAttribute id="caption">Registration</translatableAttribute>
</object>
<object name="registerUsernameLabel" type="text" size="10 40 50% 70" style="ModernRightLabelText">
<translatableAttribute id="caption">Login:</translatableAttribute>
</object>
<object name="registerUsername" type="input" size="50%+10 40 100%-20 64" style="ModernInput"/>
<object name="registerPasswordLabel" type="text" size="10 80 50% 110" style="ModernRightLabelText">
<translatableAttribute id="caption">Password:</translatableAttribute>
</object>
<object name="registerPassword" type="input" size="50%+10 80 100%-20 104" style="ModernInput" mask="true" mask_char="*"/>
<object name="registerPasswordAgainLabel" type="text" size="10 120 50% 150" style="ModernRightLabelText">
<translatableAttribute id="caption">Password again:</translatableAttribute>
</object>
<object name="registerPasswordAgain" type="input" size="50%+10 120 100%-20 144" style="ModernInput" mask="true" mask_char="*"/>
<object type="button" size="20 160 100%-20 188" style="ModernButtonRed">
<translatableAttribute id="caption">Terms of Service</translatableAttribute>
<action on="Press">openTerms("Service");</action>
</object>
<object type="button" size="20 200 100%-20 228" style="ModernButtonRed">
<translatableAttribute id="caption">Terms of Use</translatableAttribute>
<action on="Press">openTerms("Use");</action>
</object>
<object name="registerAgreeTermsLabel" type="text" size="20 240 100%-80 270" style="ModernLabelText">
<translatableAttribute id="caption">I have read and agree to the Terms of Service and Terms of Use:</translatableAttribute>
</object>
<object name="registerAgreeTerms" type="checkbox" size="100%-60 245 100%-20 270" style="ModernTickBox" enabled="false"/>
</object>
<object name="feedback" type="text" size="50 100%-110 100%-50 100%-50" style="ModernLabelText" textcolor="red"/>
<object name="cancel" type="button" size="18 100%-45 50%-5 100%-17" style="ModernButtonRed" hotkey="cancel">
<translatableAttribute id="caption">Cancel</translatableAttribute>
<action on="Press">prelobbyCancel();</action>
</object>
<object name="continue" hotkey="confirm" type="button" size="50%+5 100%-45 100%-18 100%-17" style="ModernButtonRed" enabled="false" hidden="true">
<translatableAttribute id="caption">Connect</translatableAttribute>
<action on="Press">prelobbyConnect();</action>
</object>
</object>
</objects>

View File

@ -0,0 +1,38 @@
function init()
{
g_LobbyMessages.registered = onRegistered;
Engine.GetGUIObjectByName("continue").caption = translate("Register");
initRememberPassword();
updateFeedback();
}
function updateFeedback()
{
setFeedback(checkUsername(true) || checkPassword(true) || checkPasswordConfirmation() || checkTerms());
}
function continueButton()
{
setFeedback(translate("Registering…"));
Engine.StartRegisterXmppClient(
Engine.GetGUIObjectByName("username").caption,
getEncryptedPassword());
Engine.ConnectXmppClient();
}
function onRegistered()
{
saveCredentials();
setFeedback(translate("Registered"));
Engine.StopXmppClient();
Engine.PopGuiPage();
Engine.PushGuiPage("page_prelobby_login.xml");
}

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<objects>
<script directory="gui/common/"/>
<script directory="gui/prelobby/common/credentials/"/>
<script directory="gui/prelobby/common/feedback/"/>
<script directory="gui/prelobby/common/terms/"/>
<script directory="gui/prelobby/register/"/>
<object type="image" style="ModernDialog" size="50%-230 50%-205 50%+230 50%+205">
<object style="ModernLabelText" type="text" size="50%-128 -18 50%+128 14">
<translatableAttribute id="caption">Registration</translatableAttribute>
</object>
<object size="0 30 100% 100">
<include file="gui/prelobby/common/credentials/credentials.xml"/>
</object>
<object size="0 110 100% 140">
<include file="gui/prelobby/common/credentials/confirmpassword.xml"/>
</object>
<object size="0 145 100% 165">
<include file="gui/prelobby/common/credentials/rememberpassword.xml"/>
</object>
<object size="0 180 100% 290">
<include file="gui/prelobby/common/terms/terms.xml"/>
</object>
<object size="0 300 100% 400">
<include file="gui/prelobby/common/feedback/feedback.xml"/>
</object>
</object>
</objects>

View File

@ -166,8 +166,8 @@
{
"extractor": "txt",
"filemasks": [
"gui/prelobby/Terms_of_Service.txt",
"gui/prelobby/Terms_of_Use.txt"
"gui/prelobby/common/terms/Terms_of_Service.txt",
"gui/prelobby/common/terms/Terms_of_Use.txt"
],
"options": {
}