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. Sincebffe917914
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 fromb6b547d5f8
/ D822 to the registration page too. Revert the revert ofccb534259d
in9f9db45a03
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 in0940db3fc0
by moving the registrationrate string from0e2d2610c9
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:
parent
de1a73ba65
commit
80dbd1f2a3
@ -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
|
||||
|
10
binaries/data/mods/public/gui/page_prelobby_entrance.xml
Normal file
10
binaries/data/mods/public/gui/page_prelobby_entrance.xml
Normal 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>
|
@ -6,5 +6,5 @@
|
||||
|
||||
<include>common/global.xml</include>
|
||||
|
||||
<include>prelobby/prelobby.xml</include>
|
||||
<include>prelobby/login/login.xml</include>
|
||||
</page>
|
10
binaries/data/mods/public/gui/page_prelobby_register.xml
Normal file
10
binaries/data/mods/public/gui/page_prelobby_register.xml
Normal 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>
|
@ -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)
|
||||
|
@ -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>
|
@ -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");
|
||||
}
|
||||
}
|
@ -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>
|
@ -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>
|
@ -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();
|
||||
}
|
@ -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>
|
38
binaries/data/mods/public/gui/prelobby/common/terms/terms.js
Normal file
38
binaries/data/mods/public/gui/prelobby/common/terms/terms.js
Normal 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 "";
|
||||
}
|
@ -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>
|
20
binaries/data/mods/public/gui/prelobby/entrance/entrance.js
Normal file
20
binaries/data/mods/public/gui/prelobby/entrance/entrance.js
Normal 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();
|
||||
}
|
38
binaries/data/mods/public/gui/prelobby/entrance/entrance.xml
Normal file
38
binaries/data/mods/public/gui/prelobby/entrance/entrance.xml
Normal 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>
|
42
binaries/data/mods/public/gui/prelobby/login/login.js
Normal file
42
binaries/data/mods/public/gui/prelobby/login/login.js
Normal 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
|
||||
});
|
||||
}
|
34
binaries/data/mods/public/gui/prelobby/login/login.xml
Normal file
34
binaries/data/mods/public/gui/prelobby/login/login.xml
Normal 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>
|
@ -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));
|
||||
}
|
@ -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>
|
38
binaries/data/mods/public/gui/prelobby/register/register.js
Normal file
38
binaries/data/mods/public/gui/prelobby/register/register.js
Normal 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");
|
||||
}
|
38
binaries/data/mods/public/gui/prelobby/register/register.xml
Normal file
38
binaries/data/mods/public/gui/prelobby/register/register.xml
Normal 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>
|
@ -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": {
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user