forked from mirrors/0ad
Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 18b470a5ea | |||
| d0dd3ccbc8 | |||
| 3e2c7f88e0 | |||
| 7115e4f9c7 | |||
| fa1c281e79 | |||
| 01cdd24fea | |||
| a896f670f0 | |||
| badd8cc137 | |||
| e76b7d1e02 | |||
| 1bd9f4393b | |||
| 2b847a520a | |||
| dd57ba436d | |||
| 039637cf13 | |||
| 5dce2f1fb1 | |||
| 214d6caf43 | |||
| ccef625280 | |||
| 31929d916f | |||
| 237c706dff | |||
| 404f2c48b3 | |||
| 9459825159 | |||
| 04ba9d1db4 | |||
| 9df2fcf43e | |||
| ba8b23f28d | |||
| c5cb9f6d11 | |||
| c3d2ef2dbb | |||
| 9f68d092a7 | |||
| 54e5ad2ae9 | |||
| bbf6fc47de | |||
| 5a95ee0406 | |||
| c69cf5076f | |||
| b3631d7bd5 | |||
| 0e2adda813 | |||
| d7ff9722c6 | |||
| 209bab0255 | |||
| c898c19735 | |||
| 82740d9278 | |||
| a098f59a6b | |||
| 74fbb4b823 | |||
| b496168d0a | |||
| d19e32b2ea | |||
| 27c107a448 | |||
| 82a89c4eb1 | |||
| 6a1d8e7515 | |||
| da49aa1541 | |||
| 41395ffe5d | |||
| ef8582a7fd | |||
| 8311d9f899 | |||
| 8569f188b0 | |||
| 4b4d3f71f5 | |||
| d910f4f164 | |||
| 936d32414a | |||
| b574f7f45f | |||
| 78d7702262 | |||
| 1beb96cb20 | |||
| 86db66cac1 | |||
| 81dfd63610 | |||
| e07ef3fafb | |||
| 7f4950cb17 | |||
| dd008af2f8 | |||
| b3438cabd2 | |||
| 9e712fa0c5 | |||
| 22791af91f | |||
| ecce63628c | |||
| 1e59db453a | |||
| f11b59f117 | |||
| f7783fb4bb | |||
| 2af94c5898 | |||
| bdc68f85c9 | |||
| d6caaaa54c | |||
| 9fa1a230cb | |||
| aec7509004 | |||
| 81d1e7a111 | |||
| 468d963e78 | |||
| fe41404ba8 | |||
| 88eb3527b7 | |||
| 80dbd1f2a3 | |||
| de1a73ba65 | |||
| f51f78c999 | |||
| ce64c57b8c | |||
| eda236522c | |||
| 2588682c09 | |||
| 8ae179aaae | |||
| 8e168f85e6 | |||
| 43730f15f3 | |||
| ee9cf54149 | |||
| 48e794e97d | |||
| 1608202d4f | |||
| 06e2e77349 | |||
| 4fbe399e07 | |||
| 333766ef1b | |||
| 572b72fa7f | |||
| 4cefb286f4 | |||
| 788ca1f69d | |||
| 51afc72886 | |||
| 44ec2e324e | |||
| 83d228fe7e |
@@ -83,3 +83,10 @@ in particular, let us know and we can try to clarify it.
|
||||
|
||||
/source/tools/atlas
|
||||
GPL version 2 (or later) - see license_gpl-2.0.txt
|
||||
|
||||
/binaries/data/mods/public/gui/prelobby/common/terms
|
||||
/binaries/data/mods/public/gui/userreport/Terms_and_Conditions.txt
|
||||
/binaries/data/mods/mod/gui/modio/Disclaimer.txt
|
||||
Redistributing modified Terms and Conditions of online services may be within the licensing,
|
||||
but may not change the legality or enforceability of the terms of the service provider.
|
||||
It may be against the terms of the service provider to use online services with modified terms.
|
||||
|
||||
@@ -411,13 +411,18 @@ extended = true ; Whether to display the chat history
|
||||
|
||||
[lobby]
|
||||
history = 0 ; Number of past messages to display on join
|
||||
room = "arena23" ; Default MUC room to join
|
||||
room = "arena23b" ; Default MUC room to join
|
||||
server = "lobby.wildfiregames.com" ; 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
|
||||
tls = true ; Whether to use TLS encryption when connecting to the server.
|
||||
verify_certificate = false ; Whether to reject connecting to the lobby if the TLS certificate is invalid (TODO: wait for Gloox GnuTLS trust implementation to be fixed)
|
||||
terms_url = "https://trac.wildfiregames.com/browser/ps/trunk/binaries/data/mods/public/gui/prelobby/common/terms/"; Allows the user to save the text and print the terms
|
||||
terms_of_service = "0" ; Version (hash) of the Terms of Service that the user has accepted
|
||||
terms_of_use = "0" ; Version (hash) of the Terms of Use that the user has accepted
|
||||
privacy_policy = "0" ; Version (hash) of the Privacy Policy that the user has accepted
|
||||
xpartamupp = "wfgbot23b" ; Name of the server-side XMPP-account that manage games
|
||||
echelon = "echelon23b" ; Name of the server-side XMPP-account that manages ratings
|
||||
buddies = "," ; Comma separated list of playernames that the current user has marked as buddies
|
||||
rememberpassword = true ; Whether to store the encrypted password in the user config
|
||||
secureauth = true ; Secure Lobby Authentication: This prevents the impersonation of other players. The lobby server confirms the identity of the player before they join.
|
||||
|
||||
[lobby.columns]
|
||||
gamerating = false ; Show the average rating of the participating players in a column of the gamelist
|
||||
@@ -434,7 +439,8 @@ delay = 200 ; Duration in milliseconds that is waited b
|
||||
enabledmods = "mod public"
|
||||
|
||||
[modio]
|
||||
public_key = "RWQBhIRg+dOifTWlwgYHe8RfD8bqoDh1cCvygboAl3GOUKiCo0NlF4fw" ; Public key corresponding to the private key valid mods are signed with
|
||||
public_key = "RWTsHxQMrRq4xwHisyBa2rNQfAedcINzbTT83jeX4/ZcfVxqLfWB4y8w" ; Public key corresponding to the private key valid mods are signed with
|
||||
disclaimer = "0" ; Version (hash) of the Disclaimer that the user has accepted
|
||||
|
||||
[modio.v1]
|
||||
baseurl = "https://api.mod.io/v1"
|
||||
@@ -445,6 +451,7 @@ name_id = "0ad"
|
||||
duplicateplayernames = false ; Rename joining player to "User (2)" if "User" is already connected, otherwise prohibit join.
|
||||
lateobservers = everyone ; Allow observers to join the game after it started. Possible values: everyone, buddies, disabled.
|
||||
observerlimit = 8 ; Prevent further observer joins in running games if this limit is reached
|
||||
gamestarttimeout = 60000 ; Don't disconnect clients timing out in the loading screen and rejoin process before exceeding this timeout.
|
||||
|
||||
[overlay]
|
||||
fps = "false" ; Show frames per second in top right corner
|
||||
@@ -471,7 +478,10 @@ nick = true ; Play a sound when someone mentions your name
|
||||
debug = false ; Print error messages each time a translation for an English string is not found.
|
||||
|
||||
[userreport] ; Opt-in online user reporting system
|
||||
url = "http://feedback.wildfiregames.com/report/upload/v1/"
|
||||
url_upload = "https://feedback.wildfiregames.com/report/upload/v1/" ; URL where UserReports are uploaded to
|
||||
url_publication = "https://feedback.wildfiregames.com/" ; URL where UserReports were analyzed and published
|
||||
url_terms = "https://trac.wildfiregames.com/browser/ps/trunk/binaries/data/mods/public/gui/userreport/Terms_and_Conditions.txt"; Allows the user to save the text and print the terms
|
||||
terms = "0" ; Version (hash) of the UserReporter Terms that the user has accepted
|
||||
|
||||
[view] ; Camera control settings
|
||||
scroll.speed = 120.0
|
||||
|
||||
@@ -46,3 +46,16 @@ function messageBox(mbWidth, mbHeight, mbMessage, mbTitle, mbButtonCaptions, mbB
|
||||
"callback": mbBtnCode && "messageBoxCallbackFunction"
|
||||
});
|
||||
}
|
||||
|
||||
function openURL(url)
|
||||
{
|
||||
Engine.OpenURL(url);
|
||||
|
||||
messageBox(
|
||||
600, 200,
|
||||
sprintf(
|
||||
translate("Opening %(url)s\n in default web browser. Please wait…"),
|
||||
{ "url": url }
|
||||
),
|
||||
translate("Opening page"));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
var g_Terms = {};
|
||||
|
||||
function initTerms(terms)
|
||||
{
|
||||
g_Terms = terms;
|
||||
}
|
||||
|
||||
function openTerms(page)
|
||||
{
|
||||
Engine.PushGuiPage("page_termsdialog.xml", {
|
||||
"file": g_Terms[page].file,
|
||||
"title": g_Terms[page].title,
|
||||
"sprintf": g_Terms[page].sprintf,
|
||||
"urlButtons": g_Terms[page].urlButtons || [],
|
||||
"termsURL": g_Terms[page].termsURL || undefined,
|
||||
"page": page,
|
||||
"callback": "acceptTerms"
|
||||
});
|
||||
}
|
||||
|
||||
function acceptTerms(data)
|
||||
{
|
||||
g_Terms[data.page].accepted = data.accepted;
|
||||
|
||||
let value = data.accepted ? getTermsHash(data.page) : "0";
|
||||
Engine.ConfigDB_CreateValue("user", g_Terms[data.page].config, value);
|
||||
Engine.ConfigDB_WriteValueToFile("user", g_Terms[data.page].config, value, "config/user.cfg");
|
||||
|
||||
if (g_Terms[data.page].callback)
|
||||
g_Terms[data.page].callback(data);
|
||||
}
|
||||
|
||||
function checkTerms()
|
||||
{
|
||||
for (let page in g_Terms)
|
||||
if (!g_Terms[page].accepted)
|
||||
return g_Terms[page].instruction || page;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function getTermsHash(page)
|
||||
{
|
||||
return Engine.CalculateMD5(
|
||||
(g_Terms[page].salt ? g_Terms[page].salt() : "") +
|
||||
Engine.ReadFile(g_Terms[page].file));
|
||||
}
|
||||
|
||||
function loadTermsAcceptance()
|
||||
{
|
||||
for (let page in g_Terms)
|
||||
g_Terms[page].accepted = Engine.ConfigDB_GetValue("user", g_Terms[page].config) == getTermsHash(page);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
0 A.D. Empires Ascendant mod.io Disclaimer
|
||||
|
||||
Document Date: 2018-10-12
|
||||
|
||||
You are about to connect to the mod.io online service.
|
||||
This service provides an easy way to download and install community-made mods and is provided by DBolical Pty Ltd, the company behind IndieDB and ModDB.
|
||||
The service is for users age 13 and over.
|
||||
|
||||
Wildfire Games has taken care to make this connection secure and reviewed the mods for security flaws, but cannot guarantee that this does not pose any risks.
|
||||
|
||||
By using the service, you understand that mod.io's Terms of Use and Privacy Policy apply and that Wildfire Games is not liable for any damages resulting from this service.
|
||||
@@ -6,9 +6,9 @@
|
||||
* A mod is defined by a mod.json file, for example
|
||||
* {
|
||||
* "name": "0ad",
|
||||
* "version": "0.0.16",
|
||||
* "version": "0.0.23",
|
||||
* "label": "0 A.D. - Empires Ascendant",
|
||||
* "url": "http://wildfiregames.com/",
|
||||
* "url": "https://wildfiregames.com/",
|
||||
* "description": "A free, open-source, historical RTS game.",
|
||||
* "dependencies": []
|
||||
* }
|
||||
@@ -19,7 +19,7 @@
|
||||
* "label": "Mod 2",
|
||||
* "version": "1.1",
|
||||
* "description": "",
|
||||
* "dependencies": ["0ad<=0.0.16", "rote"]
|
||||
* "dependencies": ["0ad<=0.0.23", "rote"]
|
||||
* }
|
||||
*
|
||||
* A mod is identified by the directory name.
|
||||
@@ -60,6 +60,7 @@ var g_ColorDependenciesNotMet = "255 100 100";
|
||||
function init(data, hotloadData)
|
||||
{
|
||||
g_InstalledMods = data && data.installedMods || hotloadData && hotloadData.installedMods || [];
|
||||
|
||||
initMods();
|
||||
initGUIButtons(data);
|
||||
}
|
||||
@@ -305,23 +306,6 @@ function isDependencyMet(dependency)
|
||||
(!operator || versionSatisfied(g_Mods[folder].version, operator[0], version)));
|
||||
}
|
||||
|
||||
function modIo()
|
||||
{
|
||||
messageBox(500, 250,
|
||||
translate("You are about to connect to the mod.io online service. This provides easy access to community-made mods, but is not under the control of Wildfire Games.\n\nWhile we have taken care to make this secure, we cannot guarantee with absolute certainty that this is not a security risk.\n\nDo you really want to connect?"),
|
||||
translate("Connect to mod.io?"),
|
||||
[translate("Cancel"), translateWithContext("mod.io connection message box", "Connect")],
|
||||
[
|
||||
null,
|
||||
() => {
|
||||
Engine.PushGuiPage("page_modio.xml", {
|
||||
"callback": "initMods"
|
||||
});
|
||||
}
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the given versions using the given operator.
|
||||
* '-' or '_' is ignored. Only numbers are supported.
|
||||
@@ -411,5 +395,5 @@ function visitModWebsite()
|
||||
if (!url.startsWith("http://") && !url.startsWith("https://"))
|
||||
url = "http://" + url;
|
||||
|
||||
Engine.OpenURL(url);
|
||||
openURL(url);
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
|
||||
<object type="button" style="ModernButtonRed" size="100%-606 100%-44 100%-412 100%-16">
|
||||
<translatableAttribute id="caption">Download Mods</translatableAttribute>
|
||||
<action on="Press">modIo();</action>
|
||||
<action on="Press">downloadModsButton();</action>
|
||||
</object>
|
||||
|
||||
<object name="saveConfigurationButton" type="button" style="ModernButtonRed" size="100%-408 100%-44 100%-214 100%-16">
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
function downloadModsButton()
|
||||
{
|
||||
initTerms({
|
||||
"Disclaimer": {
|
||||
"title": translate("Disclaimer"),
|
||||
"file": "gui/modio/Disclaimer.txt",
|
||||
"config": "modio.disclaimer",
|
||||
"accepted": false,
|
||||
"callback": openModIo,
|
||||
"urlButtons": [
|
||||
{
|
||||
"caption": translate("mod.io Terms"),
|
||||
"url": "https://mod.io/terms"
|
||||
},
|
||||
{
|
||||
"caption": translate("mod.io Privacy Policy"),
|
||||
"url": "https://mod.io/privacy"
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
openTerms("Disclaimer");
|
||||
}
|
||||
|
||||
function openModIo(data)
|
||||
{
|
||||
if (data.accepted)
|
||||
Engine.PushGuiPage("page_modio.xml", {
|
||||
"callback": "initMods"
|
||||
});
|
||||
}
|
||||
@@ -28,7 +28,7 @@ const g_ModProperties = {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
// example: "http://wildfiregames.com/"
|
||||
// example: "https://wildfiregames.com/"
|
||||
"url": {
|
||||
"required": false,
|
||||
"type": "string"
|
||||
|
||||
@@ -3,7 +3,7 @@ const g_ValidTestMods = {
|
||||
"name": "0ad",
|
||||
"version": "0.0.23",
|
||||
"label": "0 A.D. Empires Ascendant",
|
||||
"url": "play0ad.com",
|
||||
"url": "https://play0ad.com",
|
||||
"description": "A free, open-source, historical RTS game.",
|
||||
"dependencies": []
|
||||
},
|
||||
@@ -11,7 +11,7 @@ const g_ValidTestMods = {
|
||||
"name": "Terra_Magna",
|
||||
"version": "0.0.22",
|
||||
"label": "0 A.D. Terra Magna",
|
||||
"url": "forum.wildfiregames.com",
|
||||
"url": "https://forum.wildfiregames.com",
|
||||
"description": "Adds various civilizations to 0 A.D.",
|
||||
"dependencies": ["0ad"]
|
||||
},
|
||||
@@ -19,7 +19,7 @@ const g_ValidTestMods = {
|
||||
"name": "millenniumad",
|
||||
"version": "0.0.22",
|
||||
"label": "0 A.D. Medieval Extension",
|
||||
"url": "forum.wildfiregames.com",
|
||||
"url": "https://forum.wildfiregames.com",
|
||||
"description": "Adds medieval content like civilizations + maps.",
|
||||
"dependencies": ["0ad=0.0.23"]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?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>termsdialog/termsdialog.xml</include>
|
||||
</page>
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* This implements a basic "Clickwrap agreement", which is an industry standard:
|
||||
*
|
||||
* The European Court of Justice decided in the case El Majdoub (case nr C-322/14) that click-wrap agreements are acceptable under certain circumstances
|
||||
* as proof of the acceptance of terms and conditions (in the meaning of Regulation 44/2001, now replaced by Regulation 1215/2012).
|
||||
* See https://eur-lex.europa.eu/legal-content/en/TXT/HTML/?uri=uriserv%3AOJ.C_.2015.236.01.0019.01.ENG
|
||||
* The user should be able to save and print the text of the terms.
|
||||
*/
|
||||
|
||||
var g_TermsPage;
|
||||
var g_TermsFile;
|
||||
var g_TermsSprintf;
|
||||
|
||||
function init(data)
|
||||
{
|
||||
g_TermsPage = data.page;
|
||||
g_TermsFile = data.file;
|
||||
g_TermsSprintf = data.sprintf;
|
||||
|
||||
Engine.GetGUIObjectByName("title").caption = data.title;
|
||||
initURLButtons(data.termsURL, data.urlButtons);
|
||||
initLanguageSelection();
|
||||
}
|
||||
|
||||
function initURLButtons(termsURL, urlButtons)
|
||||
{
|
||||
if (termsURL)
|
||||
urlButtons.unshift({
|
||||
// Translation: Label of a button that when pressed opens the Terms and Conditions in the default webbrowser.
|
||||
"caption": translate("View online"),
|
||||
"url": termsURL
|
||||
});
|
||||
|
||||
urlButtons.forEach((urlButton, i) => {
|
||||
let button = Engine.GetGUIObjectByName("button[" + i + "]");
|
||||
button.caption = urlButton.caption;
|
||||
button.hidden = false;
|
||||
button.tooltip = sprintf(translate("Open %(url)s in the browser."), {
|
||||
"url": urlButton.url
|
||||
});
|
||||
button.onPress = () => {
|
||||
openURL(urlButton.url);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function initLanguageSelection()
|
||||
{
|
||||
let languageLabel = Engine.GetGUIObjectByName("languageLabel");
|
||||
let languageLabelWidth = Engine.GetTextWidth(languageLabel.font, languageLabel.caption)
|
||||
languageLabel.size = "0 0 " + languageLabelWidth + " 100%";
|
||||
|
||||
let languageDropdown = Engine.GetGUIObjectByName("languageDropdown");
|
||||
languageDropdown.size = (languageLabelWidth + 10) + " 4 100% 100%";
|
||||
|
||||
languageDropdown.list = (() => {
|
||||
let displayNames = Engine.GetSupportedLocaleDisplayNames();
|
||||
let baseNames = Engine.GetSupportedLocaleBaseNames();
|
||||
|
||||
// en-US
|
||||
let list = [displayNames[0]];
|
||||
|
||||
// current locale
|
||||
let currentLocaleDict = Engine.GetFallbackToAvailableDictLocale(Engine.GetCurrentLocale());
|
||||
if (currentLocaleDict != baseNames[0])
|
||||
list.push(displayNames[baseNames.indexOf(currentLocaleDict)]);
|
||||
|
||||
return list;
|
||||
})();
|
||||
|
||||
languageDropdown.onSelectionChange = () => {
|
||||
Engine.GetGUIObjectByName("mainText").caption =
|
||||
sprintf(
|
||||
languageDropdown.selected == 1 ?
|
||||
Engine.TranslateLines(Engine.ReadFile(g_TermsFile)) :
|
||||
Engine.ReadFile(g_TermsFile),
|
||||
g_TermsSprintf);
|
||||
};
|
||||
|
||||
languageDropdown.selected = languageDropdown.list.length - 1;
|
||||
}
|
||||
|
||||
function closeTerms(accepted)
|
||||
{
|
||||
Engine.PopGuiPageCB({
|
||||
"page": g_TermsPage,
|
||||
"accepted": accepted
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<objects>
|
||||
|
||||
<script directory="gui/common/"/>
|
||||
<script directory="gui/termsdialog/"/>
|
||||
|
||||
<object type="image" z="0" sprite="ModernFade"/>
|
||||
|
||||
<object type="image" style="ModernDialog" size="50%-360 50%-290 50%+360 50%+290">
|
||||
|
||||
<object name="title" style="ModernLabelText" type="text" size="50%-128 -18 50%+128 14"/>
|
||||
|
||||
<object size="25 18 100%-25 50">
|
||||
<object type="text" name="languageLabel" style="ModernLabelText">
|
||||
<translatableAttribute id="caption">Language</translatableAttribute>
|
||||
</object>
|
||||
<object type="dropdown" name="languageDropdown" style="ModernDropDown"/>
|
||||
</object>
|
||||
|
||||
<object size="20 60 100%-20 100%-50">
|
||||
<object name="mainTextPanel" type="image" sprite="ModernFade">
|
||||
<object name="mainText" type="text" style="ModernTextPanel"/>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object size="25 100%-45 100% 100%-16">
|
||||
|
||||
<object size="0 0 160 100%" type="button" name="button[0]" style="ModernButtonRed" hidden="true"/>
|
||||
<object size="170 0 330 100%" type="button" name="button[1]" style="ModernButtonRed" hidden="true"/>
|
||||
|
||||
<object size="100%-355 0 100% 100%">
|
||||
<object type="button" style="ModernButtonRed" size="0 0 160 100%" hotkey="cancel">
|
||||
<translatableAttribute id="caption">Decline</translatableAttribute>
|
||||
<action on="Press">closeTerms(false);</action>
|
||||
</object>
|
||||
|
||||
<object name="connectButton" type="button" style="ModernButtonRed" size="170 0 330 100%">
|
||||
<translatableAttribute id="caption">Accept</translatableAttribute>
|
||||
<action on="Press">closeTerms(true);</action>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
</object>
|
||||
|
||||
</objects>
|
||||
@@ -101,7 +101,7 @@ var g_IntelWindowsChipsets = [
|
||||
"*",
|
||||
];
|
||||
// Determined manually from data reports.
|
||||
// See http://en.wikipedia.org/wiki/Intel_GMA for useful listing.
|
||||
// See https://en.wikipedia.org/wiki/Intel_GMA for useful listing.
|
||||
|
||||
var g_IntelMacChipsets = [
|
||||
"Intel GMA 950",
|
||||
@@ -112,7 +112,7 @@ var g_IntelMacChipsets = [
|
||||
"*",
|
||||
];
|
||||
// Determined manually from data reports.
|
||||
// See http://support.apple.com/kb/HT3246 for useful listing.
|
||||
// See https://support.apple.com/kb/HT3246 for useful listing.
|
||||
|
||||
function IsWorseThanIntelMesa(renderer, chipset)
|
||||
{
|
||||
@@ -245,7 +245,7 @@ function RunDetection(settings)
|
||||
}
|
||||
|
||||
// NVIDIA 260.19.* UNIX drivers cause random crashes soon after startup.
|
||||
// http://www.wildfiregames.com/forum/index.php?showtopic=13668
|
||||
// https://www.wildfiregames.com/forum/index.php?showtopic=13668
|
||||
// Fixed in 260.19.21:
|
||||
// "Fixed a race condition in OpenGL that could cause crashes with multithreaded applications."
|
||||
if (os_unix && GL_VERSION.match(/NVIDIA 260\.19\.(0[0-9]|1[0-9]|20)$/))
|
||||
@@ -253,7 +253,7 @@ function RunDetection(settings)
|
||||
dialog_warnings.push("You are using 260.19.* series NVIDIA drivers, which may crash the game. Please upgrade to 260.19.21 or later.");
|
||||
}
|
||||
|
||||
// http://trac.wildfiregames.com/ticket/684
|
||||
// https://trac.wildfiregames.com/ticket/684
|
||||
// https://bugs.freedesktop.org/show_bug.cgi?id=24047
|
||||
// R600 drivers will advertise support for S3TC but not actually support it,
|
||||
// and will draw everything in grey instead, so forcibly disable S3TC.
|
||||
@@ -261,7 +261,7 @@ function RunDetection(settings)
|
||||
if (os_unix && GL_RENDERER.match(/^Mesa DRI R600 /))
|
||||
disable_s3tc = true;
|
||||
|
||||
// http://trac.wildfiregames.com/ticket/623
|
||||
// https://trac.wildfiregames.com/ticket/623
|
||||
// Shadows are reportedly very slow on various drivers:
|
||||
// r300 classic
|
||||
// Intel 945
|
||||
@@ -292,7 +292,7 @@ function RunDetection(settings)
|
||||
disable_shadowpcf = true;
|
||||
}
|
||||
|
||||
// http://trac.wildfiregames.com/ticket/780
|
||||
// https://trac.wildfiregames.com/ticket/780
|
||||
// r300 classic has problems with shader mode, so fall back to non-shader
|
||||
if (os_unix && GL_RENDERER.match(/^Mesa DRI R[123]00 /))
|
||||
{
|
||||
@@ -300,7 +300,7 @@ function RunDetection(settings)
|
||||
warnings.push("Some graphics features are disabled, due to bugs in old graphics drivers. Upgrading to a Gallium-based driver might help.");
|
||||
}
|
||||
|
||||
// http://www.wildfiregames.com/forum/index.php?showtopic=15058
|
||||
// https://www.wildfiregames.com/forum/index.php?showtopic=15058
|
||||
// GF FX has poor shader performance, so fall back to non-shader
|
||||
if (GL_RENDERER.match(/^GeForce FX /))
|
||||
{
|
||||
@@ -308,7 +308,7 @@ function RunDetection(settings)
|
||||
disable_allwater = true;
|
||||
}
|
||||
|
||||
// http://trac.wildfiregames.com/ticket/964
|
||||
// https://trac.wildfiregames.com/ticket/964
|
||||
// SiS Mirage 3 drivers apparently crash with shaders, so fall back to non-shader
|
||||
// (The other known SiS cards don't advertise GL_ARB_fragment_program so we
|
||||
// don't need to do anything special for them)
|
||||
|
||||
@@ -26,5 +26,5 @@
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>aura.xml</material>
|
||||
<material>basic_trans.xml</material>
|
||||
</actor>
|
||||
|
||||
+6
-1
@@ -4,7 +4,12 @@
|
||||
<group>
|
||||
<variant frequency="1" name="pers treasure 4 (food big)">
|
||||
<mesh>props/treasure_pers_4.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
+6
-1
@@ -4,7 +4,12 @@
|
||||
<group>
|
||||
<variant frequency="1" name="pers treasure 1 (food smalll)">
|
||||
<mesh>props/treasure_pers_1.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
+6
-1
@@ -4,7 +4,12 @@
|
||||
<group>
|
||||
<variant frequency="1" name="pers treasure 2 (metal bigl)">
|
||||
<mesh>props/treasure_pers_2.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
+6
-1
@@ -4,7 +4,12 @@
|
||||
<group>
|
||||
<variant frequency="1" name="pers treasure 3 (metal small)">
|
||||
<mesh>props/treasure_pers_3.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
+7
-5
@@ -2,15 +2,17 @@
|
||||
<actor version="1">
|
||||
|
||||
<castshadow/>
|
||||
|
||||
|
||||
<group>
|
||||
<variant frequency="100" name="palisade rocks outpost banners">
|
||||
<animations/>
|
||||
<mesh>props/palisade_rocks_outpost_banners.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<material>player_trans.xml</material>
|
||||
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
<props>
|
||||
<prop actor="props/structures/persians/alt_building_01_prop.xml" attachpoint="root"/>
|
||||
</props>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -21,5 +25,6 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
|
||||
+6
-2
@@ -4,8 +4,12 @@
|
||||
<group>
|
||||
<variant frequency="1" name="props">
|
||||
<mesh>props/pers_alt_build_01_prop.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
<props>
|
||||
<prop actor="props/structures/persians/alt_building_02_prop.xml" attachpoint="root"/>
|
||||
</props>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -21,5 +25,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
+6
-6
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<actor version="1">
|
||||
|
||||
<castshadow/>
|
||||
|
||||
<group>
|
||||
<variant frequency="1" name="base">
|
||||
<mesh>props/pers_alt_build_02_prop.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<material>player_trans.xml</material>
|
||||
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
<props>
|
||||
<prop actor="props/structures/persians/alt_building_03_prop.xml" attachpoint="root"/>
|
||||
</props>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -21,5 +25,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
+6
-6
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<actor version="1">
|
||||
|
||||
<castshadow/>
|
||||
|
||||
<group>
|
||||
<variant frequency="1" name="persian-alt-building-03-prop">
|
||||
<mesh>props/pers_alt_build_03_prop.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<material>basic_trans.xml</material>
|
||||
|
||||
<material>basic_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
<group>
|
||||
<variant frequency="1" name="persian-alt-building-04">
|
||||
<mesh>props/pers_alt_build_04.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -18,5 +22,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
<prop actor="props/structures/persians/alt_building_05_baskets.xml" attachpoint="root"/>
|
||||
<prop actor="props/structures/persians/alt_building_05_prop.xml" attachpoint="root"/>
|
||||
</props>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -23,5 +27,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
+6
-7
@@ -1,8 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<actor version="1">
|
||||
|
||||
<castshadow/>
|
||||
|
||||
<group>
|
||||
<variant frequency="1" name="baskets_a">
|
||||
<mesh>props/pers_alt_build_05_baskets_a.dae</mesh>
|
||||
@@ -11,13 +9,14 @@
|
||||
<mesh>props/pers_alt_build_05_baskets_b.dae</mesh>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<variant frequency="1" name="texture">
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<material>basic_trans.xml</material>
|
||||
|
||||
<material>basic_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
+6
-6
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<actor version="1">
|
||||
|
||||
<castshadow/>
|
||||
|
||||
<group>
|
||||
<variant frequency="1" name="persian-alt-building-05-prop">
|
||||
<mesh>props/pers_alt_build_05_prop.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<material>basic_trans.xml</material>
|
||||
|
||||
<material>basic_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<actor version="1">
|
||||
|
||||
<castshadow/>
|
||||
|
||||
<group>
|
||||
<variant frequency="1" name="props_b">
|
||||
<mesh>props/pers_civic_props_b.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<material>basic_trans.xml</material>
|
||||
|
||||
<material>basic_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
+15
-13
@@ -1,13 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<actor version="1">
|
||||
<castshadow/>
|
||||
<group>
|
||||
<variant>
|
||||
<mesh>structural/pers_gardens_struct_transp.dae</mesh>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.dds" name="baseTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>basic_trans.xml</material>
|
||||
</actor>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<actor version="1">
|
||||
<castshadow/>
|
||||
<group>
|
||||
<variant>
|
||||
<mesh>structural/pers_gardens_struct_transp.dae</mesh>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>basic_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<actor version="1">
|
||||
|
||||
<castshadow/>
|
||||
|
||||
<group>
|
||||
<variant frequency="1" name="props-a">
|
||||
<mesh>props/pers_market_props_a.dae</mesh>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<variant>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<material>basic_trans.xml</material>
|
||||
|
||||
<material>basic_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<actor version="1">
|
||||
|
||||
<castshadow/>
|
||||
|
||||
<group>
|
||||
<variant frequency="1" name="props_1">
|
||||
<mesh>props/pers_storehouse_1.dae</mesh>
|
||||
@@ -11,11 +9,14 @@
|
||||
<mesh>props/pers_storehouse_2.dae</mesh>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
<variant>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<material>basic_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<actor version="1">
|
||||
|
||||
<castshadow/>
|
||||
|
||||
<group>
|
||||
<variant frequency="1">
|
||||
<mesh>props/pers_wall_tower_prop.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<material>basic_trans.xml</material>
|
||||
|
||||
<material>basic_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
<group>
|
||||
<variant frequency="1" name="camel prop1">
|
||||
<mesh>props/pers_camel_prop1.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>basic_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
||||
<actor version="1">
|
||||
|
||||
<castshadow/>
|
||||
|
||||
<group>
|
||||
<variant frequency="1" name="base">
|
||||
<mesh>structural/pers_sb_1.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
|
||||
<material>player_trans.xml</material>
|
||||
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
<variant frequency="100" name="Ishtar Gate">
|
||||
<color>58 98 203</color>
|
||||
<mesh>structural/pers_ishtar.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>objectcolor.xml</material>
|
||||
|
||||
@@ -3,32 +3,50 @@
|
||||
<castshadow/>
|
||||
<float/>
|
||||
<group>
|
||||
<variant frequency="1" name="Greek Fishing Boata">
|
||||
<variant frequency="1" name="Greek Fishing Boat">
|
||||
<animations>
|
||||
<animation file="mechanical/rowing_boat_idle.dae" name="idle" speed="100"/>
|
||||
<animation file="mechanical/rowing_boat_move.dae" name="Walk" speed="10"/>
|
||||
<animation file="mechanical/rowing_boat_move.dae" name="Run" speed="10"/>
|
||||
<animation file="mechanical/rowing_boat_move.dae" name="carry_food" speed="10"/>
|
||||
</animations>
|
||||
<mesh>structural/hele_fishing_boat.dae</mesh>
|
||||
<props>
|
||||
<prop actor="props/structures/hellenes/fisherman_body.xml" attachpoint="root"/>
|
||||
<prop actor="props/units/heads/head_hele_b.xml" attachpoint="head"/>
|
||||
<prop actor="units/hellenes/fisherman.xml" attachpoint="fisherman"/>
|
||||
<prop actor="props/units/tools/fish_bucket.xml" attachpoint="fish_bucket"/>
|
||||
<prop actor="" attachpoint="fish_a"/>
|
||||
<prop actor="" attachpoint="fish_b"/>
|
||||
<prop actor="" attachpoint="fish_c"/>
|
||||
</props>
|
||||
<textures><texture file="structural/hele_fishing_boat.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/hele_fishing_boat.dds" name="baseTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
<variant frequency="1" name="Greek Fishing Boatb">
|
||||
<animations>
|
||||
<animation file="mechanical/rowing_boat_move.dae" name="Walk" speed="10"/>
|
||||
<animation file="mechanical/rowing_boat_move.dae" name="Run" speed="10"/>
|
||||
<animation file="mechanical/rowing_boat_move.dae" name="carry_food" speed="10"/>
|
||||
</animations>
|
||||
<mesh>structural/hele_fishing_boat.dae</mesh>
|
||||
</group>
|
||||
<group>
|
||||
<variant frequency="1" name="Idle"/>
|
||||
<variant frequency="1" name="walk"/>
|
||||
<variant frequency="1" name="run"/>
|
||||
<variant frequency="1" name="gather_fish">
|
||||
<props>
|
||||
<prop actor="props/structures/hellenes/fisherman_body.xml" attachpoint="root"/>
|
||||
<prop actor="props/units/heads/head_hele_e.xml" attachpoint="head"/>
|
||||
<prop actor="props/units/heads/hele_straw.xml" attachpoint="head"/>
|
||||
<prop actor="props/fauna/fish_captured.xml" attachpoint="fish_a"/>
|
||||
<prop actor="props/fauna/fish_captured.xml" attachpoint="fish_b"/>
|
||||
<prop actor="props/fauna/fish_captured.xml" attachpoint="fish_c"/>
|
||||
</props>
|
||||
</variant>
|
||||
<variant frequency="1" name="carry_fish">
|
||||
<props>
|
||||
<prop actor="props/fauna/fish_captured.xml" attachpoint="fish_a"/>
|
||||
<prop actor="props/fauna/fish_captured.xml" attachpoint="fish_b"/>
|
||||
<prop actor="props/fauna/fish_captured.xml" attachpoint="fish_c"/>
|
||||
</props>
|
||||
</variant>
|
||||
<variant frequency="1" name="carry_idle">
|
||||
<props>
|
||||
<prop actor="props/fauna/fish_captured.xml" attachpoint="fish_a"/>
|
||||
<prop actor="props/fauna/fish_captured.xml" attachpoint="fish_b"/>
|
||||
<prop actor="props/fauna/fish_captured.xml" attachpoint="fish_c"/>
|
||||
</props>
|
||||
<textures><texture file="structural/hele_fishing_boat.dds" name="baseTex"/></textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<actor version="1">
|
||||
<castshadow/>
|
||||
<group>
|
||||
<variant name="pers dock rubble struct">
|
||||
<mesh>props/pers_dock_rubble_struct.dae</mesh>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.dds" name="baseTex"/>
|
||||
<texture file="props/ao/pers_dock_rubble_ao.png" name="aoTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans_ao.xml</material>
|
||||
</actor>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<actor version="1">
|
||||
<castshadow/>
|
||||
<group>
|
||||
<variant name="pers dock rubble struct">
|
||||
<mesh>props/pers_dock_rubble_struct.dae</mesh>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
<texture file="props/ao/pers_dock_rubble_ao.png" name="aoTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans_ao_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<actor version="1">
|
||||
<castshadow/>
|
||||
<group>
|
||||
<variant name="pers cc pieces 6x6">
|
||||
<mesh>props/pers_cc_pieces.dae</mesh>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.dds" name="baseTex"/>
|
||||
<texture file="props/ao/pers_cc_rubble.png" name="aoTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans_ao.xml</material>
|
||||
</actor>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<actor version="1">
|
||||
<castshadow/>
|
||||
<group>
|
||||
<variant name="pers cc pieces 6x6">
|
||||
<mesh>props/pers_cc_pieces.dae</mesh>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
<texture file="props/ao/pers_cc_rubble.png" name="aoTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans_ao_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
<props>
|
||||
<prop actor="props/structures/persians/sb1.xml" attachpoint="root"/>
|
||||
</props>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -30,5 +34,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<props>
|
||||
<prop actor="props/structures/decals/dirt_4x4.xml" attachpoint="root"/>
|
||||
<prop actor="props/structures/persians/barracks.xml" attachpoint="root"/>
|
||||
<prop actor="props/structures/persians/barracks_shields.xml" attachpoint="root"/>
|
||||
<prop actor="props/structures/persians/barracks_shields.xml" attachpoint="root"/>
|
||||
<prop actor="props/units/shields/pers_taka_a.xml" attachpoint="shieldright"/>
|
||||
<prop actor="props/units/shields/pers_pelta_a.xml" attachpoint="shieldleft"/>
|
||||
<prop actor="props/units/shields/pers_tower.xml" attachpoint="entranceshield"/>
|
||||
@@ -16,9 +16,9 @@
|
||||
<prop actor="props/units/shields/pers_round_kardakes.xml" attachpoint="shieldoutside"/>
|
||||
</props>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
<texture file="structural/ao/pers_barracks.png" name="aoTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
|
||||
@@ -8,8 +8,10 @@
|
||||
<prop actor="props/structures/decals/iber_corral_mud.xml" attachpoint="root"/>
|
||||
</props>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.dds" name="baseTex"/>
|
||||
<texture file="structural/ao/pers_corral.png" name="aoTex"/>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
<texture file="structural/ao/pers_corral.png" name="aoTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
@@ -24,5 +26,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans_ao.xml</material>
|
||||
<material>player_trans_ao_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
<props>
|
||||
<prop actor="fauna/elephant_asian.xml" attachpoint="root"/>
|
||||
</props>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -20,5 +24,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
<prop actor="props/structures/decals/dirt_small.xml" attachpoint="root"/>
|
||||
</props>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.dds" name="baseTex"/>
|
||||
<texture file="structural/ao/pers_storehouse.png" name="aoTex"/>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
<texture file="structural/ao/pers_storehouse.png" name="aoTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
@@ -26,5 +28,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans_ao.xml</material>
|
||||
<material>player_trans_ao_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
<animation file="mechanical/pers_wall_gate_closing.dae" name="gate_closing" speed="65"/>
|
||||
</animations>
|
||||
<mesh>structural/pers_wall_gate.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -22,5 +26,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
<group>
|
||||
<variant frequency="100" name="wall long">
|
||||
<mesh>structural/pers_wall_long.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -16,5 +20,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
<group>
|
||||
<variant frequency="100" name="wall medium">
|
||||
<mesh>structural/pers_wall_medium.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -16,5 +20,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
<group>
|
||||
<variant frequency="100" name="wall_short">
|
||||
<mesh>structural/pers_wall_short.dae</mesh>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -16,5 +20,5 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
<prop actor="props/units/weapons/arrow_front.xml" attachpoint="loaded-projectile"/>
|
||||
<prop actor="props/units/weapons/arrow_front.xml" attachpoint="projectile"/>
|
||||
</props>
|
||||
<textures><texture file="structural/pers_struct.dds" name="baseTex"/></textures>
|
||||
<textures>
|
||||
<texture file="structural/pers_struct.png" name="baseTex"/>
|
||||
<texture file="structural/pers_struct_norm.png" name="normTex"/>
|
||||
<texture file="structural/pers_struct_spec.png" name="specTex"/>
|
||||
</textures>
|
||||
</variant>
|
||||
</group>
|
||||
<group>
|
||||
@@ -32,5 +36,7 @@
|
||||
</props>
|
||||
</variant>
|
||||
</group>
|
||||
<material>player_trans.xml</material>
|
||||
<material>player_trans_parallax_spec.xml</material>
|
||||
</actor>
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -8,7 +8,7 @@
|
||||
<animation file="quadraped/horse_idle_a.dae" name="attack_ranged" speed="80"/>
|
||||
<animation file="quadraped/horse_attack_short_a.dae" name="attack_slaughter" id="attack1" speed="80"/>
|
||||
<animation file="quadraped/horse_attack_short_b.dae" name="attack_slaughter" id="attack2" speed="80"/>
|
||||
<animation file="quadraped/horse_trot.dae" name="Walk" event="0.94" speed="7"/>
|
||||
<animation file="quadraped/horse_trot.dae" name="Walk" speed="7"/>
|
||||
<animation file="quadraped/horse_gallop.dae" name="Run" speed="7"/>
|
||||
<animation file="quadraped/horse_death.dae" name="death" id="death1" speed="120"/>
|
||||
<animation file="quadraped/horse_death.dae" name="death" id="death2" speed="120"/>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=531915
|
||||
*
|
||||
* They mostly meet the ECMAScript Edition 5 spec, see
|
||||
* http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
|
||||
* https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
|
||||
*
|
||||
* See simulation/components/tests/test_Math.js for tests.
|
||||
*/
|
||||
@@ -228,7 +228,7 @@ Math.log = function(x)
|
||||
return x;
|
||||
|
||||
// start with calculating the binary logarithm
|
||||
// based on http://en.wikipedia.org/wiki/Binary_logarithm#Real_number
|
||||
// based on https://en.wikipedia.org/wiki/Binary_logarithm#Real_number
|
||||
|
||||
// calculate to 50 fractional bits -> error ~=~ 10^-16
|
||||
var precisionBits = 50;
|
||||
|
||||
@@ -77,7 +77,7 @@ function clampColorValue(value)
|
||||
/**
|
||||
* Convert color value from RGB to HSL space.
|
||||
*
|
||||
* @see {@link http://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion}
|
||||
* @see {@link https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion}
|
||||
* @param {number} r - red
|
||||
* @param {number} g - green
|
||||
* @param {number} b - blue
|
||||
@@ -118,7 +118,7 @@ function rgbToHsl(r, g, b)
|
||||
/**
|
||||
* Convert color value from HSL to RGB space.
|
||||
*
|
||||
* @see {@link http://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion}
|
||||
* @see {@link https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion}
|
||||
* @param {number} h - hueness
|
||||
* @param {number} s - saturation
|
||||
* @param {number} l - lightness
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
function openURL(url)
|
||||
{
|
||||
Engine.OpenURL(url);
|
||||
|
||||
messageBox(
|
||||
600, 200,
|
||||
sprintf(
|
||||
translate("Opening %(url)s\n in default web browser. Please wait…"),
|
||||
{ "url": url }
|
||||
),
|
||||
translate("Opening page")
|
||||
);
|
||||
}
|
||||
|
||||
function updateCounters()
|
||||
{
|
||||
let counters = [];
|
||||
@@ -80,6 +66,9 @@ function cancelOnLoadGameError(msg)
|
||||
{
|
||||
Engine.EndGame();
|
||||
|
||||
if (Engine.HasXmppClient())
|
||||
Engine.StopXmppClient();
|
||||
|
||||
Engine.SwitchGuiPage("page_pregame.xml");
|
||||
|
||||
if (msg)
|
||||
|
||||
@@ -46,23 +46,14 @@ function sortNameIgnoreCase(x, y)
|
||||
|
||||
/**
|
||||
* Escape tag start and escape characters, so users cannot use special formatting.
|
||||
* Also limit string length to 256 characters (not counting escape characters).
|
||||
*/
|
||||
function escapeText(text, limitLength = true)
|
||||
function escapeText(text)
|
||||
{
|
||||
if (!text)
|
||||
return text;
|
||||
|
||||
if (limitLength)
|
||||
text = text.substr(0, 255);
|
||||
|
||||
return text.replace(/\\/g, "\\\\").replace(/\[/g, "\\[");
|
||||
}
|
||||
|
||||
function unescapeText(text)
|
||||
{
|
||||
if (!text)
|
||||
return text;
|
||||
return text.replace(/\\\\/g, "\\").replace(/\\\[/g, "\[");
|
||||
}
|
||||
|
||||
@@ -82,12 +73,18 @@ function playerDataToStringifiedTeamList(playerData)
|
||||
delete teamList[team].Team;
|
||||
}
|
||||
|
||||
return escapeText(JSON.stringify(teamList), false);
|
||||
return escapeText(JSON.stringify(teamList));
|
||||
}
|
||||
|
||||
function stringifiedTeamListToPlayerData(stringifiedTeamList)
|
||||
{
|
||||
let teamList = JSON.parse(unescapeText(stringifiedTeamList));
|
||||
let teamList = {};
|
||||
try
|
||||
{
|
||||
teamList = JSON.parse(unescapeText(stringifiedTeamList));
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
let playerData = [];
|
||||
|
||||
for (let team in teamList)
|
||||
@@ -171,12 +168,13 @@ function clearChatMessages()
|
||||
g_ChatMessages.length = 0;
|
||||
Engine.GetGUIObjectByName("chatText").caption = "";
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
for (let timer of g_ChatTimers)
|
||||
clearTimeout(timer);
|
||||
g_ChatTimers.length = 0;
|
||||
} catch (e) {
|
||||
}
|
||||
catch (e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,21 @@ var g_Buddies = Engine.ConfigDB_GetValue("user", "lobby.buddies").split(g_BuddyL
|
||||
*/
|
||||
var g_BuddySymbol = '•';
|
||||
|
||||
var g_MapPreviewPath = "session/icons/mappreview/";
|
||||
|
||||
/**
|
||||
* Returns the biome specific mappreview image if it exists, or empty string otherwise.
|
||||
*/
|
||||
function getBiomePreview(mapName, biomeName)
|
||||
{
|
||||
let biomePreview = basename(mapName) + "_" + basename(biomeName) + ".png";
|
||||
|
||||
if (Engine.TextureExists("art/textures/ui/" + g_MapPreviewPath + biomePreview))
|
||||
return biomePreview;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns map description and preview image or placeholder.
|
||||
*/
|
||||
@@ -47,11 +62,11 @@ function getMapDescriptionAndPreview(mapType, mapName, gameAttributes = undefine
|
||||
else if (Engine.FileExists(mapName + ".xml"))
|
||||
mapData = Engine.LoadMapSettings(mapName + ".xml");
|
||||
|
||||
let mapBiome = gameAttributes && g_Settings.Biomes.find(biome => biome.Id == gameAttributes.settings.Biome);
|
||||
let biomePreview = getBiomePreview(mapName, gameAttributes && gameAttributes.settings.Biome || "");
|
||||
|
||||
return deepfreeze({
|
||||
"description": mapData && mapData.settings && mapData.settings.Description ? translate(mapData.settings.Description) : translate("Sorry, no description available."),
|
||||
"preview": mapBiome && mapBiome.Preview ? mapBiome.Preview :
|
||||
"preview": biomePreview ? biomePreview :
|
||||
mapData && mapData.settings && mapData.settings.Preview ? mapData.settings.Preview : "nopreview.png"
|
||||
});
|
||||
}
|
||||
@@ -67,7 +82,7 @@ function setMapPreviewImage(guiObject, filename)
|
||||
{
|
||||
Engine.GetGUIObjectByName(guiObject).sprite =
|
||||
"cropped:" + 400 / 512 + "," + 300 / 512 + ":" +
|
||||
"session/icons/mappreview/" + filename;
|
||||
g_MapPreviewPath + filename;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -277,7 +277,7 @@ var g_ReadyInit = true;
|
||||
var g_ReadyChanged = 2;
|
||||
|
||||
/**
|
||||
* Used to prevent calling resetReadyData when starting a game.
|
||||
* Used to prevent calling resetReadyData when starting a game or doubleclicking on the "Start Game" button.
|
||||
*/
|
||||
var g_GameStarted = false;
|
||||
|
||||
@@ -780,7 +780,7 @@ var g_PlayerDropdowns = {
|
||||
g_GameAttributes.settings.PlayerData[playerIdx].Civ = g_PlayerCivList.code[selectedIdx];
|
||||
},
|
||||
"enabled": () => g_GameAttributes.mapType != "scenario",
|
||||
"autocomplete": 0,
|
||||
"autocomplete": 90,
|
||||
},
|
||||
"playerColorPicker": {
|
||||
"labels": (playerIdx) => g_PlayerColorPickerList.map(color => "■"),
|
||||
@@ -1011,6 +1011,16 @@ var g_MiscControls = {
|
||||
"startGame": {
|
||||
"caption": () =>
|
||||
g_IsController ? translate("Start Game!") : g_ReadyData[g_IsReady].caption,
|
||||
"onPress": () => function() {
|
||||
if (g_IsController)
|
||||
launchGame();
|
||||
else
|
||||
toggleReady();
|
||||
},
|
||||
"onPressRight": () => function() {
|
||||
if (!g_IsController && g_IsReady)
|
||||
setReady(0, true);
|
||||
},
|
||||
"tooltip": (hoverIdx) =>
|
||||
!g_IsController ?
|
||||
g_ReadyData[g_IsReady].tooltip :
|
||||
@@ -1018,14 +1028,28 @@ var g_MiscControls = {
|
||||
g_PlayerAssignments[guid].status || g_PlayerAssignments[guid].player == -1) ?
|
||||
translate("Start a new game with the current settings.") :
|
||||
translate("Start a new game with the current settings (disabled until all players are ready)"),
|
||||
"enabled": () => !g_IsController ||
|
||||
Object.keys(g_PlayerAssignments).every(guid => g_PlayerAssignments[guid].status ||
|
||||
g_PlayerAssignments[guid].player == -1 ||
|
||||
guid == Engine.GetPlayerGUID() && g_IsController),
|
||||
"enabled": () => !g_GameStarted && (
|
||||
!g_IsController ||
|
||||
Object.keys(g_PlayerAssignments).every(guid => g_PlayerAssignments[guid].status ||
|
||||
g_PlayerAssignments[guid].player == -1 ||
|
||||
guid == Engine.GetPlayerGUID() && g_IsController)),
|
||||
"hidden": () =>
|
||||
!g_PlayerAssignments[Engine.GetPlayerGUID()] ||
|
||||
g_PlayerAssignments[Engine.GetPlayerGUID()].player == -1 && !g_IsController,
|
||||
},
|
||||
"civInfoButton": {
|
||||
"tooltip": () => sprintf(
|
||||
translate("%(hotkey_civinfo)s / %(hotkey_structree)s: View History / Structure Tree\nLast opened will be reopened on click."), {
|
||||
"hotkey_civinfo": colorizeHotkey("%(hotkey)s", "civinfo"),
|
||||
"hotkey_structree": colorizeHotkey("%(hotkey)s", "structree")
|
||||
}),
|
||||
"onPress": () => function() {
|
||||
Engine.PushGuiPage(g_CivInfo.page, {
|
||||
"civ": g_CivInfo.code,
|
||||
"callback": "storeCivInfoPage"
|
||||
});
|
||||
}
|
||||
},
|
||||
"civResetButton": {
|
||||
"hidden": () => g_GameAttributes.mapType == "scenario" || !g_IsController,
|
||||
},
|
||||
@@ -1099,13 +1123,6 @@ function init(attribs)
|
||||
return;
|
||||
}
|
||||
|
||||
if (["offline", "server", "client"].indexOf(attribs.type) == -1)
|
||||
{
|
||||
error("Unexpected 'type' in gamesetup init: " + attribs.type);
|
||||
cancelSetup();
|
||||
return;
|
||||
}
|
||||
|
||||
g_IsTutorial = !!attribs.tutorial;
|
||||
g_ServerName = attribs.serverName;
|
||||
g_ServerPort = attribs.serverPort;
|
||||
@@ -1127,12 +1144,6 @@ function init(attribs)
|
||||
supplementDefaults();
|
||||
|
||||
setTimeout(displayGamestateNotifications, 1000);
|
||||
|
||||
Engine.GetGUIObjectByName("civInfoButton").tooltip = sprintf(
|
||||
translate("%(hotkey_civinfo)s / %(hotkey_structree)s: View History / Structure Tree\nLast opened will be reopened on click."), {
|
||||
"hotkey_civinfo": colorizeHotkey("%(hotkey)s", "civinfo"),
|
||||
"hotkey_structree": colorizeHotkey("%(hotkey)s", "structree")
|
||||
});
|
||||
}
|
||||
|
||||
function initDefaults()
|
||||
@@ -1658,12 +1669,9 @@ function getMapDisplayName(map)
|
||||
|
||||
function getMapPreview(map)
|
||||
{
|
||||
if (g_GameAttributes.settings.Biome)
|
||||
{
|
||||
let biomePreview = basename(map) + "_" + basename(g_GameAttributes.settings.Biome) + ".png";
|
||||
if (Engine.FileExists("art/textures/ui/session/icons/mappreview/" + biomePreview))
|
||||
return biomePreview;
|
||||
}
|
||||
let biomePreview = g_GameAttributes.settings.Biome && getBiomePreview(map, g_GameAttributes.settings.Biome);
|
||||
if (biomePreview)
|
||||
return biomePreview;
|
||||
|
||||
let mapData = loadMapData(map);
|
||||
if (!mapData || !mapData.settings || !mapData.settings.Preview)
|
||||
@@ -2179,9 +2187,13 @@ function launchGame()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_GameAttributes.map)
|
||||
if (!g_GameAttributes.map || g_GameStarted)
|
||||
return;
|
||||
|
||||
// Prevent reseting the readystate or calling this function twice
|
||||
g_GameStarted = true;
|
||||
updateGUIMiscControl("startGame");
|
||||
|
||||
savePersistMatchSettings();
|
||||
|
||||
// Select random map
|
||||
@@ -2201,9 +2213,6 @@ function launchGame()
|
||||
|
||||
g_GameAttributes.settings.TriggerScripts = g_GameAttributes.settings.VictoryScripts.concat(g_GameAttributes.settings.TriggerScripts || []);
|
||||
|
||||
// Prevent reseting the readystate
|
||||
g_GameStarted = true;
|
||||
|
||||
g_GameAttributes.settings.mapType = g_GameAttributes.mapType;
|
||||
|
||||
// Get a unique array of selectable cultures
|
||||
|
||||
@@ -70,17 +70,7 @@
|
||||
<translatableAttribute id="caption">Civilization</translatableAttribute>
|
||||
</object>
|
||||
|
||||
<object name="civInfoButton"
|
||||
type="button"
|
||||
style="IconButton"
|
||||
sprite="iconInfoGold"
|
||||
sprite_over="iconInfoWhite"
|
||||
size="85%-37 0 85%-21 16"
|
||||
>
|
||||
<action on="Press">
|
||||
Engine.PushGuiPage(g_CivInfo.page, { "civ": g_CivInfo.code, "callback": "storeCivInfoPage" });
|
||||
</action>
|
||||
</object>
|
||||
<object name="civInfoButton" type="button" style="IconButton" sprite="iconInfoGold" sprite_over="iconInfoWhite" size="85%-37 0 85%-21 16"/>
|
||||
|
||||
<object name="civResetButton"
|
||||
type="button"
|
||||
@@ -121,18 +111,8 @@
|
||||
<translatableAttribute id="tooltip">Select player.</translatableAttribute>
|
||||
</object>
|
||||
<object name="playerAssignmentText[n]" type="text" style="ModernLabelText" size="22%+5 0 50%+35 30"/>
|
||||
<object name="playerConfig[n]" type="button" style="StoneButton" size="50%+40 4 50%+64 28"
|
||||
tooltip_style="onscreenToolTip"
|
||||
font="sans-bold-stroke-12"
|
||||
sprite="ModernGear"
|
||||
sprite_over="ModernGearHover"
|
||||
sprite_pressed="ModernGearPressed"
|
||||
>
|
||||
<translatableAttribute id="tooltip">Configure AI settings.</translatableAttribute>
|
||||
</object>
|
||||
<object name="playerCiv[n]" type="dropdown" style="ModernDropDown" size="50%+69 2 85% 30" tooltip_style="onscreenToolTip" dropdown_size="424">
|
||||
<translatableAttribute id="tooltip">Select player's civilization.</translatableAttribute>
|
||||
</object>
|
||||
<object name="playerConfig[n]" type="button" style="StoneButton" size="50%+40 4 50%+64 28" tooltip_style="onscreenToolTip" font="sans-bold-stroke-12" sprite="ModernGear" sprite_over="ModernGearHover" sprite_pressed="ModernGearPressed"/>
|
||||
<object name="playerCiv[n]" type="dropdown" style="ModernDropDown" size="50%+69 2 85% 30" tooltip_style="onscreenToolTip" dropdown_size="424"/>
|
||||
<object name="playerCivText[n]" type="text" style="ModernLabelText" size="50%+65 0 85% 30"/>
|
||||
<object name="playerTeam[n]" type="dropdown" style="ModernDropDown" size="85%+5 2 100%-5 30" tooltip_style="onscreenToolTip">
|
||||
<translatableAttribute id="tooltip">Select player's team.</translatableAttribute>
|
||||
@@ -157,7 +137,7 @@
|
||||
|
||||
<!-- Map Preview -->
|
||||
<object type="image" sprite="ModernDarkBoxGold" name="gamePreviewBox" size="100%-426 40 100%-24 336">
|
||||
<object type="image" sprite="snMapPreview" size="1 1 401 294" name="mapPreview"/>
|
||||
<object type="image" size="1 1 401 294" name="mapPreview"/>
|
||||
<object name="mapInfoName" type="text" style="ModernLeftLabelText" size="5 100%-20 100% 100%-1"/>
|
||||
</object>
|
||||
|
||||
@@ -266,14 +246,7 @@
|
||||
size="100%-164 100%-52 100%-24 100%-24"
|
||||
tooltip_style="onscreenToolTip"
|
||||
z="21"
|
||||
>
|
||||
<action on="Press">
|
||||
if (g_IsController)
|
||||
launchGame();
|
||||
else
|
||||
toggleReady();
|
||||
</action>
|
||||
</object>
|
||||
/>
|
||||
|
||||
<!-- Cancel Button -->
|
||||
<object
|
||||
|
||||
@@ -48,7 +48,6 @@ function init(attribs)
|
||||
case "host":
|
||||
{
|
||||
Engine.GetGUIObjectByName("hostSTUNWrapper").hidden = !Engine.HasXmppClient();
|
||||
Engine.GetGUIObjectByName("hostLobbyAuthWrapper").hidden = !Engine.HasXmppClient();
|
||||
if (Engine.HasXmppClient())
|
||||
{
|
||||
Engine.GetGUIObjectByName("hostPlayerName").caption = attribs.name;
|
||||
@@ -56,7 +55,6 @@ function init(attribs)
|
||||
sprintf(translate("%(name)s's game"), { "name": attribs.name });
|
||||
|
||||
Engine.GetGUIObjectByName("useSTUN").checked = Engine.ConfigDB_GetValue("user", "lobby.stun.enabled") == "true";
|
||||
Engine.GetGUIObjectByName("useLobbyAuth").checked = Engine.ConfigDB_GetValue("user", "lobby.secureauth") == "true";
|
||||
}
|
||||
|
||||
switchSetupPage("pageHost");
|
||||
@@ -231,7 +229,6 @@ function pollAndHandleNetworkClient()
|
||||
return; // we'll process the game setup messages in the next tick
|
||||
}
|
||||
Engine.SwitchGuiPage("page_gamesetup.xml", {
|
||||
"type": g_GameType,
|
||||
"serverName": g_ServerName,
|
||||
"serverPort": g_ServerPort,
|
||||
"stunEndpoint": g_StunEndpoint
|
||||
@@ -269,7 +266,7 @@ function switchSetupPage(newPage)
|
||||
if (newPage == "pageJoin" || newPage == "pageHost")
|
||||
{
|
||||
let pageSize = multiplayerPages.size;
|
||||
let halfHeight = newPage == "pageJoin" ? 130 : Engine.HasXmppClient() ? 145 : 110;
|
||||
let halfHeight = newPage == "pageJoin" ? 130 : Engine.HasXmppClient() ? 125 : 110;
|
||||
pageSize.top = -halfHeight;
|
||||
pageSize.bottom = halfHeight;
|
||||
multiplayerPages.size = pageSize;
|
||||
@@ -313,10 +310,9 @@ function startHost(playername, servername, port)
|
||||
}
|
||||
}
|
||||
|
||||
let useLobbyAuth = Engine.HasXmppClient() && Engine.GetGUIObjectByName("useLobbyAuth").checked;
|
||||
try
|
||||
{
|
||||
Engine.StartNetworkHost(playername + (g_UserRating ? " (" + g_UserRating + ")" : ""), port, playername, useLobbyAuth);
|
||||
Engine.StartNetworkHost(playername + (g_UserRating ? " (" + g_UserRating + ")" : ""), port, playername);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
|
||||
@@ -114,16 +114,6 @@
|
||||
<translatableAttribute id="caption">Use STUN to work around firewalls</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="hostLobbyAuthWrapper" size="120 141 100% 181">
|
||||
<object name="useLobbyAuth" size="0 10 32 100%" type="checkbox" style="ModernTickBox">
|
||||
<action on="Press">saveSettingAndWriteToUserConfig("lobby.secureauth", String(this.checked));</action>
|
||||
</object>
|
||||
<object type="text" size="26 0 100% 100%" style="ModernLeftLabelText">
|
||||
<translatableAttribute id="caption">Require Lobby Authentication</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">This prevents the impersonation of other players. The lobby server confirms the identity of the player before they join.</translatableAttribute>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object name="hostFeedback" type="text" style="ModernLabelText" size="50 100%-80 100%-50 100%-45" textcolor="red"/>
|
||||
|
||||
@@ -1017,7 +1017,16 @@ function updateGameList()
|
||||
Math.round(playerRatings.reduce((sum, current) => sum + current) / playerRatings.length) :
|
||||
g_DefaultLobbyRating;
|
||||
|
||||
if (!hasSameMods(JSON.parse(game.mods), Engine.GetEngineInfo().mods))
|
||||
try
|
||||
{
|
||||
game.mods = JSON.parse(game.mods);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
game.mods = [];
|
||||
}
|
||||
|
||||
if (!hasSameMods(game.mods, Engine.GetEngineInfo().mods))
|
||||
game.state = "incompatible";
|
||||
|
||||
return game;
|
||||
@@ -1178,13 +1187,14 @@ function joinButton()
|
||||
messageBox(
|
||||
400, 200,
|
||||
translate("Your active mods do not match the mods of this game.") + "\n\n" +
|
||||
comparedModsString(JSON.parse(game.mods), Engine.GetEngineInfo().mods) + "\n\n" +
|
||||
comparedModsString(game.mods, Engine.GetEngineInfo().mods) + "\n\n" +
|
||||
translate("Do you want to switch to the mod selection page?"),
|
||||
translate("Incompatible mods"),
|
||||
[translate("No"), translate("Yes")],
|
||||
[
|
||||
null,
|
||||
() => {
|
||||
Engine.StopXmppClient();
|
||||
Engine.SwitchGuiPage("page_modmod.xml", {
|
||||
"cancelbutton": true
|
||||
});
|
||||
@@ -1423,7 +1433,7 @@ function ircFormat(msg)
|
||||
let coloredFrom = msg.from && colorPlayerName(msg.from);
|
||||
|
||||
// Handle commands allowed past handleChatCommand.
|
||||
if (msg.text[0] == '/')
|
||||
if (msg.text && msg.text[0] == '/')
|
||||
{
|
||||
let [command, message] = ircSplit(msg.text);
|
||||
switch (command)
|
||||
@@ -1527,7 +1537,7 @@ function ircFormat(msg)
|
||||
|
||||
/**
|
||||
* Generate a (mostly) unique color for this player based on their name.
|
||||
* @see http://stackoverflow.com/questions/3426404/create-a-hexadecimal-colour-based-on-a-string-with-jquery-javascript
|
||||
* @see https://stackoverflow.com/questions/3426404/create-a-hexadecimal-colour-based-on-a-string-with-jquery-javascript
|
||||
* @param {string} playername
|
||||
*/
|
||||
function getPlayerColor(playername)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<object type="button" style="ModernButtonRed" tooltip_style="snToolTip" size="100%-408 100%-52 100%-218 100%-24" hotkey="cancel">
|
||||
<translatableAttribute id="caption">Close</translatableAttribute>
|
||||
<action on="Press"><![CDATA[closeManual();]]></action>
|
||||
<action on="Press">closeManual();</action>
|
||||
</object>
|
||||
<object name="url" type="button" style="ModernButtonRed" size="100%-214 100%-52 100%-24 100%-24" hidden="true">
|
||||
<translatableAttribute id="caption">View Online</translatableAttribute>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
As a free, open source game, we don't have the resources to test on a wide range of systems, but we want to provide the best quality experience to as many players as possible. When you enable automatic feedback, we'll receive data to help us understand the hardware we should focus on supporting, and to identify performance problems we should fix.
|
||||
|
||||
The following data will be sent to our server:
|
||||
|
||||
• A random user ID (stored in %APPDATA%\\0ad\\config\\user.cfg on Windows, ~/.config/0ad/config/user.cfg on Unix), to let us detect repeated reports from the same user.
|
||||
• Game version number and basic build settings (optimisation mode, CPU architecture, timestamp, compiler version).
|
||||
• Hardware details: OS version, graphics driver version, OpenGL capabilities, screen size, CPU details, RAM size.
|
||||
• Performance details: a snapshot of timing data a few seconds after you start a match or change graphics settings.
|
||||
|
||||
The data will only be a few kilobytes each time you run the game, so bandwidth usage is minimal.
|
||||
|
||||
We will store the submitted data on our server, and may publish statistics or non-user-identifiable details to help other game developers with similar questions. We will store the IP address that submitted the data, to help detect abuse of the service, but will not publish it. The published data can be seen at http://feedback.wildfiregames.com/
|
||||
@@ -377,6 +377,12 @@
|
||||
"tooltip": "These settings only affect the multiplayer.",
|
||||
"options":
|
||||
[
|
||||
{
|
||||
"type": "boolean",
|
||||
"label": "TLS Encryption",
|
||||
"tooltip": "Protect login and data exchanged with the lobby server using TLS encryption.",
|
||||
"config": "lobby.tls"
|
||||
},
|
||||
{
|
||||
"type": "number",
|
||||
"label": "Chat Backlog",
|
||||
|
||||
@@ -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>
|
||||
+1
-1
@@ -6,5 +6,5 @@
|
||||
|
||||
<include>common/global.xml</include>
|
||||
|
||||
<include>prelobby/prelobby.xml</include>
|
||||
<include>prelobby/login/login.xml</include>
|
||||
</page>
|
||||
@@ -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>
|
||||
@@ -24,8 +24,6 @@ function init(initData, hotloadData)
|
||||
// Initialize currentSubmenuType with placeholder to avoid null when switching
|
||||
currentSubmenuType = "submenuSinglePlayer";
|
||||
|
||||
EnableUserReport(Engine.IsUserReportEnabled());
|
||||
|
||||
// Only show splash screen(s) once at startup, but not again after hotloading
|
||||
g_ShowSplashScreens = hotloadData ? hotloadData.showSplashScreens : initData && initData.isStartup;
|
||||
|
||||
@@ -38,12 +36,15 @@ function init(initData, hotloadData)
|
||||
guiObj.sprite = g_BackgroundLayerset[i].sprite;
|
||||
guiObj.z = i;
|
||||
}
|
||||
|
||||
Engine.GetGUIObjectByName("structreeButton").tooltip = colorizeHotkey(
|
||||
translate("%(hotkey)s: View the structure tree of civilizations featured in 0 A.D."),
|
||||
"structree");
|
||||
|
||||
Engine.GetGUIObjectByName("civInfoButton").tooltip = colorizeHotkey(
|
||||
translate("%(hotkey)s: Learn about the many civilizations featured in 0 A.D."),
|
||||
"civinfo");
|
||||
|
||||
Engine.GetGUIObjectByName("lobbyButton").tooltip = colorizeHotkey(
|
||||
translate("%(hotkey)s: Launch the multiplayer lobby to join and host publicly visible games and chat with other players."),
|
||||
"lobby");
|
||||
@@ -79,41 +80,6 @@ function scrollBackgrounds()
|
||||
}
|
||||
}
|
||||
|
||||
function submitUserReportMessage()
|
||||
{
|
||||
let input = Engine.GetGUIObjectByName("userReportMessageInput");
|
||||
if (input.caption.length)
|
||||
Engine.SubmitUserReport("message", 1, input.caption);
|
||||
input.caption = "";
|
||||
}
|
||||
|
||||
function formatUserReportStatus(status)
|
||||
{
|
||||
let d = status.split(/:/, 3);
|
||||
|
||||
if (d[0] == "disabled")
|
||||
return translate("disabled");
|
||||
|
||||
if (d[0] == "connecting")
|
||||
return translate("connecting to server");
|
||||
|
||||
if (d[0] == "sending")
|
||||
return sprintf(translate("uploading (%f%%)"), Math.floor(100 * d[1]));
|
||||
|
||||
if (d[0] == "completed")
|
||||
{
|
||||
let httpCode = d[1];
|
||||
if (httpCode == 200)
|
||||
return translate("upload succeeded");
|
||||
return sprintf(translate("upload failed (%(errorCode)s)"), { "errorCode": httpCode });
|
||||
}
|
||||
|
||||
if (d[0] == "failed")
|
||||
return sprintf(translate("upload failed (%(errorMessage)s)"), { "errorMessage": d[2] });
|
||||
|
||||
return translate("unknown");
|
||||
}
|
||||
|
||||
function onTick()
|
||||
{
|
||||
let now = Date.now();
|
||||
@@ -124,14 +90,6 @@ function onTick()
|
||||
|
||||
updateMenuPosition(tickLength);
|
||||
|
||||
if (Engine.IsUserReportEnabled())
|
||||
Engine.GetGUIObjectByName("userReportEnabledText").caption =
|
||||
'[font="sans-bold-16"]' + translate("Thank you for helping improve 0 A.D.!") + "[/font]\n\n" +
|
||||
translate("Anonymous feedback is currently enabled.") + "\n" +
|
||||
sprintf(translate("Status: %(status)s."), {
|
||||
"status": formatUserReportStatus(Engine.GetUserReportStatus())
|
||||
});
|
||||
|
||||
// Show splash screens here, so we don't interfere with main menu hotloading
|
||||
if (g_ShowSplashScreens)
|
||||
{
|
||||
@@ -163,7 +121,7 @@ function ShowRenderPathMessage()
|
||||
translate("Please press \"Read More\" for more information or \"OK\" to continue."),
|
||||
translate("WARNING!"),
|
||||
[translate("OK"), translate("Read More")],
|
||||
[ null, function() { Engine.OpenURL("http://www.wildfiregames.com/forum/index.php?showtopic=16734"); } ]
|
||||
[ null, function() { Engine.OpenURL("https://www.wildfiregames.com/forum/index.php?showtopic=16734"); } ]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -172,13 +130,6 @@ function SplashScreenClosedCallback()
|
||||
ShowRenderPathMessage();
|
||||
}
|
||||
|
||||
function EnableUserReport(Enabled)
|
||||
{
|
||||
Engine.GetGUIObjectByName("userReportDisabled").hidden = Enabled;
|
||||
Engine.GetGUIObjectByName("userReportEnabled").hidden = !Enabled;
|
||||
Engine.SetUserReportEnabled(Enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Slide menu.
|
||||
*/
|
||||
@@ -288,11 +239,6 @@ function getLobbyDisabledByBuild()
|
||||
return translate("Launch the multiplayer lobby to join and host publicly visible games and chat with other players. \\[DISABLED BY BUILD]");
|
||||
}
|
||||
|
||||
function getTechnicalDetails()
|
||||
{
|
||||
return translate("Technical Details");
|
||||
}
|
||||
|
||||
function getManual()
|
||||
{
|
||||
return translate("Manual");
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<script directory="gui/common/"/>
|
||||
<script directory="gui/pregame/"/>
|
||||
<script directory="gui/pregame/backgrounds/"/>
|
||||
<script directory="gui/pregame/userreport/"/>
|
||||
|
||||
<!--
|
||||
==========================================
|
||||
@@ -43,65 +44,7 @@
|
||||
- MAIN MENU - USER REPORT
|
||||
==========================================
|
||||
-->
|
||||
<object
|
||||
name="userReportDisabled"
|
||||
size="100%-304 100%-154 100%-4 100%-4"
|
||||
type="image"
|
||||
style="userReportPanel"
|
||||
>
|
||||
<object
|
||||
type="text"
|
||||
style="userReportText"
|
||||
>
|
||||
<attribute id="caption">
|
||||
<keep>[font="sans-bold-16"]</keep>
|
||||
<translate>Help improve 0 A.D.!</translate>
|
||||
<keep>[/font]\n</keep>
|
||||
<translate>You can automatically send us anonymous feedback that will help us fix bugs, and improve performance and compatibility.</translate>
|
||||
</attribute>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="8 100%-36 146 100%-8">
|
||||
<translatableAttribute id="caption">Enable Feedback</translatableAttribute>
|
||||
<action on="Press">EnableUserReport(true);</action>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="100%-146 100%-36 100%-8 100%-8">
|
||||
<translatableAttribute id="caption">Technical Details</translatableAttribute>
|
||||
<action on="Press">
|
||||
Engine.PushGuiPage("page_manual.xml", {
|
||||
"page": "manual/userreport",
|
||||
"title": getTechnicalDetails()
|
||||
});
|
||||
</action>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<object
|
||||
name="userReportEnabled"
|
||||
size="100%-304 100%-154 100%-4 100%-4"
|
||||
type="image"
|
||||
style="userReportPanel"
|
||||
>
|
||||
<object
|
||||
name="userReportEnabledText"
|
||||
type="text"
|
||||
style="userReportText"
|
||||
/>
|
||||
|
||||
<object type="button" style="StoneButton" size="8 100%-36 146 100%-8">
|
||||
<translatableAttribute id="caption">Disable Feedback</translatableAttribute>
|
||||
<action on="Press">EnableUserReport(false);</action>
|
||||
</object>
|
||||
<object type="button" style="StoneButton" size="100%-146 100%-36 100%-8 100%-8">
|
||||
<translatableAttribute id="caption">Technical Details</translatableAttribute>
|
||||
<action on="Press">
|
||||
Engine.PushGuiPage("page_manual.xml", {
|
||||
"page": "manual/userreport",
|
||||
"title": getTechnicalDetails()
|
||||
});
|
||||
</action>
|
||||
</object>
|
||||
</object>
|
||||
|
||||
<include file="gui/pregame/userreport/userreport.xml"/>
|
||||
|
||||
<!--
|
||||
==========================================
|
||||
@@ -150,7 +93,7 @@
|
||||
Engine.PushGuiPage("page_manual.xml", {
|
||||
"page": "manual/intro",
|
||||
"title": getManual(),
|
||||
"url": "http://trac.wildfiregames.com/wiki/0adManual"
|
||||
"url": "https://trac.wildfiregames.com/wiki/0adManual"
|
||||
});
|
||||
</action>
|
||||
</object>
|
||||
@@ -165,7 +108,7 @@
|
||||
<translatableAttribute id="caption">Tutorial</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Start the economic tutorial.</translatableAttribute>
|
||||
<action on="Press">
|
||||
Engine.SwitchGuiPage("page_gamesetup.xml", { "type": "offline", "tutorial": true });
|
||||
Engine.SwitchGuiPage("page_gamesetup.xml", { "tutorial": true });
|
||||
</action>
|
||||
</object>
|
||||
|
||||
@@ -219,7 +162,7 @@
|
||||
<translatableAttribute id="caption">Matches</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Click here to start a new single player game.</translatableAttribute>
|
||||
<action on="Press">
|
||||
Engine.SwitchGuiPage("page_gamesetup.xml", { "type": "offline" });
|
||||
Engine.SwitchGuiPage("page_gamesetup.xml", {});
|
||||
</action>
|
||||
</object>
|
||||
|
||||
@@ -320,7 +263,7 @@
|
||||
if (!Engine.StartXmppClient)
|
||||
return;
|
||||
closeMenu();
|
||||
Engine.PushGuiPage("page_prelobby.xml");
|
||||
Engine.PushGuiPage("page_prelobby_entrance.xml");
|
||||
</action>
|
||||
<action on="load">
|
||||
if (!Engine.StartXmppClient)
|
||||
@@ -574,7 +517,7 @@
|
||||
<translatableAttribute id="caption">Website</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Click to open play0ad.com in your web browser.</translatableAttribute>
|
||||
<action on="Press">
|
||||
openURL("http://play0ad.com/");
|
||||
openURL("https://play0ad.com/");
|
||||
</action>
|
||||
</object>
|
||||
|
||||
@@ -586,7 +529,7 @@
|
||||
<translatableAttribute id="caption">Chat</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Click to open the 0 A.D. IRC chat in your browser. (#0ad on webchat.quakenet.org)</translatableAttribute>
|
||||
<action on="Press">
|
||||
openURL("http://webchat.quakenet.org/?channels=0ad");
|
||||
openURL("https://webchat.quakenet.org/?channels=0ad");
|
||||
</action>
|
||||
</object>
|
||||
|
||||
@@ -598,7 +541,7 @@
|
||||
<translatableAttribute id="caption">Report a Bug</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Click to visit 0 A.D. Trac to report a bug, crash, or error.</translatableAttribute>
|
||||
<action on="Press">
|
||||
openURL("http://trac.wildfiregames.com/wiki/ReportingErrors/");
|
||||
openURL("https://trac.wildfiregames.com/wiki/ReportingErrors/");
|
||||
</action>
|
||||
</object>
|
||||
|
||||
@@ -610,7 +553,7 @@
|
||||
<translatableAttribute id="caption">Translate the Game</translatableAttribute>
|
||||
<translatableAttribute id="tooltip">Click to open the 0 A.D. translate page in your browser.</translatableAttribute>
|
||||
<action on="Press">
|
||||
openURL("http://trac.wildfiregames.com/wiki/Localization");
|
||||
openURL("https://trac.wildfiregames.com/wiki/Localization");
|
||||
</action>
|
||||
</object>
|
||||
|
||||
|
||||
@@ -21,9 +21,10 @@
|
||||
/>
|
||||
|
||||
<style name="userReportText"
|
||||
ghost="true"
|
||||
font="sans-14"
|
||||
textcolor="white"
|
||||
scrollbar="true"
|
||||
scrollbar_style="ModernScrollBar"
|
||||
/>
|
||||
|
||||
</styles>
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
var g_TermsUserReport = {
|
||||
"TermsAndConditions": {
|
||||
"title": translateWithContext("UserReporter Terms and Conditions", "Terms"),
|
||||
"instruction": translate("Please read and accept the UserReporter Terms and Conditions."),
|
||||
"file": "gui/userreport/Terms_and_Conditions.txt",
|
||||
"termsURL": Engine.ConfigDB_GetValue("user", "userreport.url_terms"),
|
||||
"sprintf": {
|
||||
"logPath": setStringTags(Engine.GetUserReportLogPath(), { "font": "sans-bold-12" }),
|
||||
"configPath": setStringTags(Engine.GetUserReportConfigPath(), { "font": "sans-bold-12" })
|
||||
},
|
||||
"config": "userreport.terms",
|
||||
"callback": data => {
|
||||
setUserReportEnabled(data.accepted);
|
||||
},
|
||||
"accepted": false,
|
||||
"urlButtons": [
|
||||
{
|
||||
"caption": translate("Publications"),
|
||||
"url": Engine.ConfigDB_GetValue("user", "userreport.url_publication")
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
var g_UserReportStatusFormat = {
|
||||
"disabled": data => translate("disabled"),
|
||||
"proxy": data => translate("connecting to server"),
|
||||
"waiting": data => translate("connecting to server"),
|
||||
"connecting": data => translate("connecting to server"),
|
||||
"sending": data => sprintf(translate("uploading (%f%%)"), Math.floor(100 * data[1])),
|
||||
"completed": data =>
|
||||
data[1] == 200 ?
|
||||
translate("upload succeeded") :
|
||||
sprintf(translate("upload failed (%(errorCode)s)"), {
|
||||
"errorCode": data[1]
|
||||
}),
|
||||
"failed": data => sprintf(translate("upload failed (%(errorMessage)s)"), {
|
||||
"errorMessage": data.slice(2).join(":")
|
||||
})
|
||||
};
|
||||
|
||||
function initUserReport()
|
||||
{
|
||||
initTerms(g_TermsUserReport);
|
||||
loadTermsAcceptance();
|
||||
|
||||
setUserReportEnabled(!checkTerms() && Engine.IsUserReportEnabled());
|
||||
}
|
||||
|
||||
function setUserReportEnabled(enabled)
|
||||
{
|
||||
Engine.SetUserReportEnabled(enabled);
|
||||
updateUserReportButtons();
|
||||
}
|
||||
|
||||
function updateUserReportButtons()
|
||||
{
|
||||
let termsFeedback = checkTerms();
|
||||
|
||||
let userReportEnableButton = Engine.GetGUIObjectByName("userReportEnableButton");
|
||||
userReportEnableButton.caption = Engine.IsUserReportEnabled() ? translate("Disable Feedback") : translate("Enable Feedback");
|
||||
userReportEnableButton.enabled = !termsFeedback;
|
||||
userReportEnableButton.tooltip = termsFeedback;
|
||||
userReportEnableButton.onPress = () => {
|
||||
setUserReportEnabled(!Engine.IsUserReportEnabled());
|
||||
};
|
||||
|
||||
let userReportTermsButton = Engine.GetGUIObjectByName("userReportTermsButton");
|
||||
userReportTermsButton.caption = g_TermsUserReport.TermsAndConditions.title;
|
||||
userReportTermsButton.onPress = () => {
|
||||
openTerms("TermsAndConditions");
|
||||
};
|
||||
}
|
||||
|
||||
function updateUserReportStatus()
|
||||
{
|
||||
let statusData = Engine.GetUserReportStatus().split(":");
|
||||
|
||||
Engine.GetGUIObjectByName("userReportText").caption =
|
||||
Engine.IsUserReportEnabled() ?
|
||||
setStringTags(translate("Thank you for helping improve 0 A.D.!"), { "font": "sans-bold-16" }) + "\n\n" +
|
||||
translate("Feedback is currently enabled.") + "\n" +
|
||||
sprintf(translate("Status: %(status)s."), {
|
||||
"status": g_UserReportStatusFormat[statusData[0]] ? g_UserReportStatusFormat[statusData[0]](statusData) : translate("unknown")
|
||||
}) :
|
||||
setStringTags(translate("Help improve 0 A.D.!"), { "font": "sans-bold-16" }) + "\n\n" +
|
||||
translate("You can automatically send us feedback that can help us fix bugs, and improve performance and compatibility.");
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<object name="userReport" type="image" style="userReportPanel" size="100%-314 100%-154 100%-4 100%-4">
|
||||
|
||||
<action on="Load">initUserReport();</action>
|
||||
<action on="Tick">updateUserReportStatus();</action>
|
||||
|
||||
<object type="text" name="userReportText" style="userReportText" size="2 2 100%-2 100%-40"/>
|
||||
|
||||
<object type="button" name="userReportEnableButton" style="StoneButton" size="8 100%-36 151 100%-8"/>
|
||||
<object type="button" name="userReportTermsButton" style="StoneButton" size="100%-151 100%-36 100%-8 100%-8"/>
|
||||
|
||||
</object>
|
||||
@@ -1,20 +0,0 @@
|
||||
0 A.D. Empires Ascendant Multiplayer Lobby Terms of Service
|
||||
Definitions:
|
||||
* The "service" is the 0 A.D. Empires Ascendant Multiplayer Lobby provided by Wildfire Games (WFG).
|
||||
* "You" are the user of the service.
|
||||
* "We" are the collective of all Wildfire Games (WFG) team members.
|
||||
* "Rating" refers to the process of analyzing various user statistics for the purpose of generating a single comprehensive score.
|
||||
* "Moderate" refers to the process of enforcing usage policies.
|
||||
By using the service you agree to:
|
||||
1. Follow all usage policies.
|
||||
2. Allow user identifiable statistics to be gathered for the purposes of rating, user profiles, and community statistics.
|
||||
We also reserve the right to:
|
||||
1. Moderate the service.
|
||||
2. Appoint others to moderate the service.
|
||||
3. Discontinue or interrupt service at any time with or without prior announcement.
|
||||
4. Change the service at any time with or without announcement.
|
||||
5. Delete any and all service data at any time with or without announcement.
|
||||
6. Collect any or all user identifiable statistics at any time without consent for:
|
||||
a. Private analysis by Wildfire Games (WFG) team members and their affiliates.
|
||||
b. Anonymized public release by Wildfire Games (WFG) team members.
|
||||
7. Change this document in any way; at any time; on the condition that the user of the service is given adequate notice of the change (the definition of adequate notice will be determined at the time by a panel of Wildfire Games (WFG) team members).
|
||||
@@ -1,19 +0,0 @@
|
||||
0 A.D. Empires Ascendant Multiplayer Lobby Terms of Use
|
||||
Definitions:
|
||||
* The "service" is the 0 A.D. Empires Ascendant Multiplayer Lobby provided by Wildfire Games (WFG).
|
||||
* "You" are the user of the service.
|
||||
* "Impersonate" refers to the action in which you attempt to exploit another's identity for your own purposes.
|
||||
* "Spam" refers to irrelevant or inappropriate messages sent to a large number of recipients.
|
||||
* "Rating" refers to the per-user comprehensive score.
|
||||
* "Ranked games" refers to games in which rating changing statistics are tracked.
|
||||
You agree to:
|
||||
1. Only create one account per unique user on the service unless authorized by a Wildfire Games (WFG) team member.
|
||||
2. Not post profane statements, rude humor, pornographic content, or discriminatory comments on the service.
|
||||
3. Not purposefully demean the worth of others using the service.
|
||||
4. Not use the service to promote specific goods, services, or products.
|
||||
5. Not impersonate other users of the service.
|
||||
6. Not spam the service.
|
||||
7. Not attempt to artificially adjust any user of the service's rating or any of the statistics which impact it. (Examples of this are, but are not limited to: cheating in ranked games, reverse engineering the service, and taking advantage of other users of the service.)
|
||||
8. Allow yourself to be removed from the service if at any time a moderator determines your behavior is not consistent with these rules.
|
||||
We also reserve the right to:
|
||||
1. Change this document in any way; at any time; on the condition that the user of the service is given adequate notice of the change (the definition of adequate notice will be determined at the time by a panel of Wildfire Games (WFG) team members).
|
||||
@@ -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,91 @@
|
||||
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)
|
||||
{
|
||||
let password = Engine.GetGUIObjectByName("password").caption;
|
||||
|
||||
if (!password)
|
||||
return register ?
|
||||
translateWithContext("register", "Please enter your password") :
|
||||
translateWithContext("login", "Please enter your password");
|
||||
|
||||
if (register && password.length < 8)
|
||||
return translate("Please choose a longer 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">onUsernameEdit();</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,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<object>
|
||||
<action on="Tick">onTick();</action>
|
||||
|
||||
<object name="feedback" type="text" size="50 0 100%-50 75" style="ModernLabelText" textcolor="red"/>
|
||||
|
||||
<object size="18 80 100%-18 108">
|
||||
|
||||
<object name="cancel" type="button" size="0 0 50%-5 100%" 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 0 100% 100%" style="ModernButtonRed" enabled="false">
|
||||
<action on="Press">continueButton();</action>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
@@ -0,0 +1,80 @@
|
||||
[font="sans-bold-18"]0 A.D. Empires Ascendant Multiplayer Lobby Privacy Policy[/font]
|
||||
|
||||
[font="sans-bold-14"]Document Date:[/font] 2018-10-16
|
||||
|
||||
[font="sans-bold-16"]Personal data processed by Wildfire Games and purposes of processing:[/font]
|
||||
[font="sans-bold-14"]1. Playername[/font]
|
||||
The player is identified by a name that the player chooses at the time of registration.
|
||||
Having a unique playername is a requirement to gain a rating, to allow players, moderators and developers to identify players they met before, communicate about the game, coordinate matches and enables moderators to enforce the Terms of Use.
|
||||
The playername serves as a pseudoynm. The identity (natural person) of players is not known to Wildfire Games, except where personally identifiable information (such as the realname) was disclosed on the Lobby Chat, other services of Wildfire Games or elsewhere in the public, or when the IP address is used to bring criminal proceedings.
|
||||
|
||||
[font="sans-bold-14"]2. Password[/font]
|
||||
A player is authenticated using a password that the player chooses at the time of registration.
|
||||
Wildfire Games only receives an encrypted version of the password, so that the password chosen by the user is not revealed to Wildfire Games or others in case of a breach.
|
||||
|
||||
[font="sans-bold-14"]3. IP address[/font]
|
||||
When a player hosts a match in the Multiplayer Lobby, the IP address of that player is sent to every player who is online, so that other players can join that game.
|
||||
Wildfire Games stores players IP addresses and may infer publicly available geolocation and internet service provider data (for example "geolite2") from the IP address in order to:
|
||||
1. Enforce the Terms of Use where persons create multiple accounts without Wildfire Games permission, in particular after having been banned from the service for violating the Terms of Use.
|
||||
IP addresses will not be saved for longer than three years for this purpose.
|
||||
2. Make it possible to bring criminal proceedings in case of a cyberattack (EU Court of Justice Press Release No 112/16).
|
||||
Wildfire Games will not use the IP address logs for any other purpose, in particular not for marketing, not otherwise disclose IP addresses to the public or third parties and erase IP addresses if they are not relevant for the stated purposes anymore.
|
||||
|
||||
[font="sans-bold-14"]4. Online presence[/font]
|
||||
Which players are currently connected to the Multiplayer Lobby and which match they joined is shown to all online players.
|
||||
|
||||
[font="sans-bold-14"]5. Chat messages[/font]
|
||||
The Multiplayer Lobby features a public chat room that enables players to discuss the game and organize multiplayer matches.
|
||||
Wildfire Games stores a log of the public chat messages and online presence to meet the following purposes:
|
||||
1. Moderators may screen chat messages to enforce the Terms of Use.
|
||||
2. Wildfire Games may address or resolve bug reports, balancing issues or feature proposals indicated by players in the chat room.
|
||||
3. Wildfire Games may assess trends amongst discussed topics, the growth of the active community and use these indicators as feedback to assess, improve and direct development of the game and the service.
|
||||
|
||||
[font="sans-bold-14"]6. Match statistics[/font]
|
||||
Players can gain a rating on the Multiplayer Lobby that reflects their skill at the game.
|
||||
The rating of all players is published by Wildfire Games and allows players to focus on competitive or balanced matchmaking if they wish to.
|
||||
During a rated match, players send data relating to the game (such as the number of units trained, resources gathered and the winner of the match) to Wildfire Games, so that Wildfire Games can adapt the players ratings based on these statistics.
|
||||
Wildfire Games stores match statistics to:
|
||||
1. Verify the accuracy of the rating score and identify and enforce Terms of Use violations relating to that.
|
||||
2. Compute and publish community statistics to improve the game and the service, for example to improve the balancing of the game or to make certain aspects of the game more appealing.
|
||||
|
||||
[font="sans-bold-14"]Security of processing:[/font]
|
||||
The transmission of personal data is secured using TLS encryption (GDPR 32).
|
||||
Personal data is protected against unintentional loss in encrypted backups for additional time (GDPR 30.1.g, GDPR 32).
|
||||
|
||||
All personal data that Wildfire Games processes is obtained from the user (GDPR 14).
|
||||
Wildfire Games reserves the right to delete any service data (including personal data) at any time, except where a user has objected to the erasure of his or her personal data for performance of a legal claim.
|
||||
|
||||
[font="sans-bold-16"]Legal basis for the processing:[/font]
|
||||
1. The processing is necessary for the performance of the service defined in the terms (GDPR 6.1.b).
|
||||
2. Wildfire Games has legitimate interests in providing the Multiplayer Lobby, in the development and improvement of 0 A.D. and the Multiplayer Lobby, in enforcing the Terms of Use and in the protection against cyberattacks (GDPR 6.1.f).
|
||||
3. Wildfire Games does not process any further data for the Multiplayer Lobby and does not ask for consent to process data (GDPR 6.1.a, GDPR 7, GDPR 8, GDPR 13.2.c).
|
||||
|
||||
[font="sans-bold-16"]User rights:[/font]
|
||||
1. Contact Wildfire Games, by sending an email to webmaster at wildfiregames dot com (GDPR 13.1.a, GDPR 13.1.b).
|
||||
To exercise any user right, please refer to this contact.
|
||||
2. Right of access to personal data concerning him or her (GDPR 15).
|
||||
3. Right to obtain personal data in a machine-readable format (GDPR 20).
|
||||
4. Right to rectification of inaccurate personal data (GDPR 16).
|
||||
5. Right to erasure of personal data where it is not relevant to the stated purposes, if the data was processed unlawfully or if the user objects to the processing and has overriding legitimate grounds (GDPR 17).
|
||||
6. Right to restriction of personal data processing where the accuracy of the data is contested by the user, if the data was processed unlawfully or if the user requires the data for a legal claim (GDPR 18).
|
||||
7. Right to object to the processing of personal data concerning him or her on grounds relating to their particular situation (GDPR 21).
|
||||
8. Right to lodge a complaint with a supervisory authority (GDPR 13.2.d, GDPR 77).
|
||||
Requests that are manifestly unfounded or excessive are not responded to or may be charged (GDPR 12.4, GDPR 12.5).
|
||||
|
||||
[font="sans-bold-16"]Wildfire Games obligations:[/font]
|
||||
1. Wildfire Games demonstrates compliance with GDPR (GDPR 5.2 'accountability').
|
||||
2. Wildfire Games documents their processing activities appropriately, in particular the categories of processed personal data and security measures to protect it (GDPR 30).
|
||||
3. Wildfire Games processes personal data lawfully, fairly and transparently (GDPR 5.1.a, GDPR 12.1).
|
||||
4. Wildfire Games informs users of the purposes, legal grounds, legitimate interests and retention periods of personal data processing at the time it is processed, recipients of personal data and where applicable, transfer of personal data to third countries and automated decision-making (GDPR 13.1.c-f, GDPR 13.2.a, GDPR 13.2.e-f, GDPR 15.1, GDPR 15.4).
|
||||
5. Wildfire Games does not processes personal data for purposes other than the specified ones (GDPR 5.1.b, 'purpose limitation', GDPR 13.3).
|
||||
6. Wildfire Games does not process personal data that is not needed for the specified purposes (GDPR 5.1.c, 'data minimization').
|
||||
7. Wildfire Games uses a storage form that does not allow identification of natural persons for longer than necessary (GDPR 5.1.e 'storage limitation').
|
||||
8. Wildfire Games secures personal data processing to prevent unauthorised or unlawful processing and accidental loss (GDPR 5.1.f. 'integrity and confidentiality').
|
||||
9. Wildfire Games informs users of their right to access, to rectify, to erase personal data and the right to restrict, to withdraw consent to, to object to personal data processing and to complain at a supervisory authority (GDPR 13.2.b, GDPR 13.2.c, GDPR 13.2.d).
|
||||
10. Wildfire Games facilitates the exercise of user rights where possible (GDPR 12.2), without undue delay (GDPR 12.3).
|
||||
11. Wildfire Games informs the users that to exercise their rights, users might need to provide additional information to identify the natural person or the data (GDPR 12.6, GDPR 13.2.e).
|
||||
12. Wildfire Games will not knowingly collect personal data from children under the age of 13 (Children's Online Privacy Protection Act). If you believe Wildfire Games received any personal data from or about a child under 13, please contact Wildfire Games.
|
||||
13. Where Wildfire Games processes sensitive personal data based on legitimate interests, Wildfire Games considers performing, recording and periodically reviewing Legitimate Interests Assessments and Data Protection Impact Assessments (GDPR 35) to become confident that the individual's interests do not override Wildfire Games legitimate interests, and that Wildfire Games is not using personal data in intrusive ways unless there is a very good reason to.
|
||||
|
||||
For further information on Wildfire Games Privacy Policies, visit https://trac.wildfiregames.com/wiki/UserDataProtection
|
||||
@@ -0,0 +1,22 @@
|
||||
[font="sans-bold-18"]0 A.D. Empires Ascendant Multiplayer Lobby Terms of Service[/font]
|
||||
|
||||
[font="sans-bold-14"]Document Date:[/font] 2018-10-16
|
||||
|
||||
The 0 A.D. Empires Ascendant Multiplayer Lobby is an online service provided by Wildfire Games that allows players to setup online multiplayer matches, discuss the game in a public chat room and gain a rating that reflects their skill.
|
||||
|
||||
Due to the subject matter of historic warfare, description and depiction of violence and the language on the Multiplayer Lobby, 0 A.D. and the Multiplayer Lobby are not directed to young children (COPPA §312.2).
|
||||
The minimum age to use the Multiplayer Lobby is 13.
|
||||
|
||||
[font="sans-bold-14"]By using the 0 A.D. Multiplayer Lobby, you agree to:[/font]
|
||||
1. Follow all usage policies.
|
||||
2. Not use the service with third-party software or mods that prevents the user from being informed of updated Terms and Conditions, unless authorized by a Wildfire Games team member.
|
||||
3. Use the service at your own risk. Wildfire Games does not take responsibility for the content posted by users or damages resulting from this service.
|
||||
|
||||
[font="sans-bold-14"]Wildfire Games reserves the right to:[/font]
|
||||
1. Moderate the service, i.e. to enforce the Terms of Use by restricting, suspending or terminating user accounts.
|
||||
2. Appoint others to moderate the service.
|
||||
3. Discontinue or interrupt any part of the service at any time.
|
||||
4. Change the service or the terms. The document date of the terms indicate its version, and the user is informed of the new terms before being able to use the service again.
|
||||
5. Process personal data in accordance with the Lobby Privacy Policy, the General Data Protection Regulation (GDPR) and the Children's Online Privacy Protection Act (COPPA) where applicable.
|
||||
|
||||
If parts of the terms are held to be illegal or otherwise unenforceable, the remainder of the terms shall still apply ('severability').
|
||||
@@ -0,0 +1,17 @@
|
||||
[font="sans-bold-18"]0 A.D. Empires Ascendant Multiplayer Lobby Terms of Use[/font]
|
||||
|
||||
[font="sans-bold-14"]Document Date:[/font] 2018-10-13
|
||||
|
||||
[font="sans-bold-14"]By using the 0 A.D. Multiplayer Lobby, you agree to:[/font]
|
||||
1. Only create one account per person on the service unless authorized by Wildfire Games.
|
||||
2. Not impersonate other users of the service and only use your registered username in multiplayer matches.
|
||||
3. Not post profanity, pejorative terms or pornographic content.
|
||||
4. Not harass, harm, intimidate, discriminate, threaten, defame, cause damage to others or purposefully demean the worth of others using this service.
|
||||
5. Not violate the privacy of others by disclosing personally identifiable information (for example real name, location, ID) or private details (for example social media or messenger account names) of others without their consent.
|
||||
6. Not incite violence or promote illegal acts.
|
||||
7. Not attempt to artificially adjust any user of the service's rating or any of the statistics which impact it. (Examples of this are, but are not limited to: cheating in ranked games, reverse engineering the service, and taking advantage of other users of the service.)
|
||||
8. Not undermine the intended gameplay or purposefully gain unfair advantages in multiplayer matches (for example cheating, using exploits or bugs).
|
||||
9. Not spam the service and not post large amounts of repetitive or unwanted messages.
|
||||
10. Not use the service to promote specific goods, services, or products unless authorized by Wildfire Games.
|
||||
|
||||
If a moderator deems your behavior to be inconsistent with these terms, your account may be restricted, suspended or terminated.
|
||||
@@ -0,0 +1,58 @@
|
||||
var g_TermsButtonHeight = 40;
|
||||
|
||||
function initLobbyTerms()
|
||||
{
|
||||
let termsURL = Engine.ConfigDB_GetValue("user", "lobby.terms_url");
|
||||
|
||||
let terms = {
|
||||
"Service": {
|
||||
"title": translate("Terms of Service"),
|
||||
"instruction": translate("Please read and accept the Terms of Service."),
|
||||
"file": "gui/prelobby/common/terms/Terms_of_Service.txt",
|
||||
"termsURL": termsURL + "Terms_of_Service.txt",
|
||||
"config": "lobby.terms_of_service",
|
||||
"salt": () => Engine.GetGUIObjectByName("username").caption,
|
||||
"accepted": false,
|
||||
"callback": updateFeedback
|
||||
},
|
||||
"Use": {
|
||||
"title": translate("Terms of Use"),
|
||||
"instruction": translate("Please read and accept the Terms of Use."),
|
||||
"file": "gui/prelobby/common/terms/Terms_of_Use.txt",
|
||||
"termsURL": termsURL + "Terms_of_Use.txt",
|
||||
"config": "lobby.terms_of_use",
|
||||
"salt": () => Engine.GetGUIObjectByName("username").caption,
|
||||
"accepted": false,
|
||||
"callback": updateFeedback
|
||||
},
|
||||
"Privacy": {
|
||||
"title": translate("Privacy Policy"),
|
||||
"instruction": translate("Please read and accept the Privacy Policy."),
|
||||
"file": "gui/prelobby/common/terms/Privacy_Policy.txt",
|
||||
"termsURL": termsURL + "Privacy_Policy.txt",
|
||||
"config": "lobby.privacy_policy",
|
||||
"salt": () => Engine.GetGUIObjectByName("username").caption,
|
||||
"accepted": false,
|
||||
"callback": updateFeedback
|
||||
}
|
||||
};
|
||||
|
||||
Object.keys(terms).forEach((page, i) => {
|
||||
|
||||
let button = Engine.GetGUIObjectByName("termsButton[" + i + "]");
|
||||
|
||||
button.caption = terms[page].title;
|
||||
|
||||
button.onPress = () => {
|
||||
openTerms(page);
|
||||
};
|
||||
|
||||
let size = button.size;
|
||||
size.top = i * g_TermsButtonHeight;
|
||||
size.bottom = i * g_TermsButtonHeight + 28;
|
||||
button.size = size;
|
||||
});
|
||||
|
||||
initTerms(terms);
|
||||
loadTermsAcceptance();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<object>
|
||||
|
||||
<repeat count="3" var="n">
|
||||
<object name="termsButton[n]" type="button" size="20 0 100%-20 28" style="ModernButtonRed"/>
|
||||
</repeat>
|
||||
|
||||
</object>
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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>
|
||||
@@ -0,0 +1,51 @@
|
||||
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);
|
||||
|
||||
initLobbyTerms();
|
||||
|
||||
initRememberPassword();
|
||||
|
||||
updateFeedback();
|
||||
}
|
||||
|
||||
function updateFeedback()
|
||||
{
|
||||
setFeedback(checkUsername(false) || checkPassword(false) || checkTerms());
|
||||
}
|
||||
|
||||
// Remember which user agreed to the terms
|
||||
function onUsernameEdit()
|
||||
{
|
||||
loadTermsAcceptance();
|
||||
updateFeedback();
|
||||
}
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
@@ -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%-190 50%+230 50%+190">
|
||||
|
||||
<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 140 100% 250">
|
||||
<include file="gui/prelobby/common/terms/termslobby.xml"/>
|
||||
</object>
|
||||
|
||||
<object size="0 255 100% 370">
|
||||
<include file="gui/prelobby/common/feedback/feedback.xml"/>
|
||||
</object>
|
||||
|
||||
</object>
|
||||
|
||||
</objects>
|
||||
@@ -1,307 +0,0 @@
|
||||
var g_LobbyIsConnecting = false;
|
||||
var g_EncryptedPassword = "";
|
||||
var g_PasswordInputIsHidden = false;
|
||||
var g_TermsOfServiceRead = false;
|
||||
var g_TermsOfUseRead = false;
|
||||
var g_DisplayingSystemMessage = false;
|
||||
|
||||
function init()
|
||||
{
|
||||
Engine.GetGUIObjectByName("rememberPassword").checked =
|
||||
Engine.ConfigDB_GetValue("user", "lobby.rememberpassword") == "true";
|
||||
g_EncryptedPassword = Engine.ConfigDB_GetValue("user", "lobby.password");
|
||||
if (Engine.ConfigDB_GetValue("user", "lobby.login") && 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_TermsOfServiceRead)
|
||||
{
|
||||
continueButton.enabled = false;
|
||||
feedback.caption = translate("Please read the Terms of Service");
|
||||
}
|
||||
// Check that they read the Terms of Use.
|
||||
else if (!g_TermsOfUseRead)
|
||||
{
|
||||
continueButton.enabled = false;
|
||||
feedback.caption = translate("Please read the Terms of Use");
|
||||
}
|
||||
// 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 openTermsOfService()
|
||||
{
|
||||
g_TermsOfServiceRead = true;
|
||||
Engine.PushGuiPage("page_manual.xml", {
|
||||
"page": "prelobby/Terms_of_Service",
|
||||
"title": translate("Terms of Service"),
|
||||
});
|
||||
}
|
||||
|
||||
function openTermsOfUse()
|
||||
{
|
||||
g_TermsOfUseRead = true;
|
||||
Engine.PushGuiPage("page_manual.xml", {
|
||||
"page": "prelobby/Terms_of_Use",
|
||||
"title": translate("Terms of Use"),
|
||||
});
|
||||
}
|
||||
|
||||
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,127 +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">
|
||||
<action on="Load">
|
||||
this.caption = Engine.ConfigDB_GetValue("user", "lobby.login");
|
||||
</action>
|
||||
</object>
|
||||
<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="Load">
|
||||
// We only show 10 characters to make it look decent.
|
||||
this.caption = Engine.ConfigDB_GetValue("user", "lobby.password").substring(0, 10);
|
||||
</action>
|
||||
<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">openTermsOfService();</action>
|
||||
</object>
|
||||
|
||||
<object type="button" size="20 200 100%-20 228" style="ModernButtonRed">
|
||||
<translatableAttribute id="caption">Terms of Use</translatableAttribute>
|
||||
<action on="Press">openTermsOfUse();</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">
|
||||
<action on="Tick"><![CDATA[this.enabled = g_TermsOfServiceRead && g_TermsOfUseRead;]]></action>
|
||||
</object>
|
||||
|
||||
</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">
|
||||
if (!Engine.GetGUIObjectByName("pageConnect").hidden)
|
||||
lobbyStartConnect();
|
||||
else if (!Engine.GetGUIObjectByName("pageRegister").hidden)
|
||||
lobbyStartRegister();
|
||||
</action>
|
||||
</object>
|
||||
|
||||
</object>
|
||||
|
||||
</objects>
|
||||
@@ -0,0 +1,45 @@
|
||||
function init()
|
||||
{
|
||||
g_LobbyMessages.registered = onRegistered;
|
||||
|
||||
Engine.GetGUIObjectByName("continue").caption = translate("Register");
|
||||
|
||||
initLobbyTerms();
|
||||
|
||||
initRememberPassword();
|
||||
|
||||
updateFeedback();
|
||||
}
|
||||
|
||||
function updateFeedback()
|
||||
{
|
||||
setFeedback(checkUsername(true) || checkPassword(true) || checkPasswordConfirmation() || checkTerms());
|
||||
}
|
||||
|
||||
function onUsernameEdit()
|
||||
{
|
||||
updateFeedback();
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
@@ -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%-210 50%+230 50%+210">
|
||||
|
||||
<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/termslobby.xml"/>
|
||||
</object>
|
||||
|
||||
<object size="0 295 100% 510">
|
||||
<include file="gui/prelobby/common/feedback/feedback.xml"/>
|
||||
</object>
|
||||
|
||||
</object>
|
||||
|
||||
</objects>
|
||||
@@ -65,7 +65,6 @@
|
||||
name="chatInput"
|
||||
size="75 100%-76 100%-16 100%-52"
|
||||
style="ModernInput"
|
||||
max_length="80"
|
||||
>
|
||||
<action on="Press">submitChatInput();</action>
|
||||
<action on="Tab">
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user