1
0
forked from mirrors/0ad

Compare commits

..

96 Commits

Author SHA1 Message Date
Itms 18b470a5ea Correctly choose DarwinSSL TLS backend on macOS for libcurl.
According to https://curl.haxx.se/docs/install.html, explicitly
disabling OpenSSL/BoringSSL/libressl with the confusing `--without-ssl`
flag is necessary.

Also disable a few more unneeded dependencies explicitly.

Patch By: Stan
Accepted By: trompetin17
Differential Revision: https://code.wildfiregames.com/D1687
This was SVN commit r21945.
2018-12-08 21:09:27 +00:00
Itms d0dd3ccbc8 New mod signing key for A23b.
Fix indentation in previous commit (3e2c7f88e0).

Differential Revision: https://code.wildfiregames.com/D1686
This was SVN commit r21944.
2018-12-08 20:49:59 +00:00
user1 3e2c7f88e0 Update client\'s default.cfg for the new muc room arena23b
This was SVN commit r21943.
2018-12-06 13:36:28 +00:00
Itms 7115e4f9c7 Target 10.9 as minimal OSX version in all scripts, in order to match the libraries build script.
Differential Revision: https://code.wildfiregames.com/D1685
Tested By: trompetin17
This was SVN commit r21942.
2018-12-03 11:07:00 +00:00
Itms fa1c281e79 Import part of commit https://github.com/premake/premake-core/commit/5f57b5d62a4518f391cf66e1cfb70e4a92353178 to our copy of premake5 alpha10.
After the re-release of A23, premake5 will be updated to the latest
alpha version, which includes this change.

This allows to build premake on macOS Mojave. See
https://github.com/premake/premake-core/issues/1154.

Differential Revision: https://code.wildfiregames.com/D1669
Based on patch by: trompetin17
This was SVN commit r21941.
2018-12-02 20:58:19 +00:00
Itms 01cdd24fea Build gloox with GnuTLS on macOS, refs #4705.
This includes GMP and nettle, that are dependencies of GnuTLS.
On versions of OSX/macOS up to 10.11, TLS handshakes can still fail and
crash, so users of those older versions should disable TLS on the lobby
in the options screen, and will still be able to use it.

Differential Revision: https://code.wildfiregames.com/D1654
Tested By: Tobbi, trompetin17, and testers of their bundles.
This was SVN commit r21940.
2018-12-02 20:52:40 +00:00
Itms a896f670f0 Minor change to the libcurl macOS compilation.
nghttp2 can sometimes be detected on the system by configure, whereas we
do not provide nor use it.

Differential Revision: https://code.wildfiregames.com/D1487
Tested By: trompetin17
This was SVN commit r21939.
2018-12-02 20:41:55 +00:00
Itms badd8cc137 Credit translators for A23b.
This was SVN commit r21938.
2018-12-02 17:56:19 +00:00
elexis e76b7d1e02 Remove obsolete DisplayMessageBox function from 00e18e4ea8, unused since 835609df20.
C++ should not hardcode JS implementation details or strings.
SendEventToAll or CallFunctionVoid are more common and versatile
alternatives.

This was SVN commit r21935.
2018-11-29 12:33:45 +00:00
elexis 1bd9f4393b Allow users to disable TLS encryption entirely in the GUI to ease use of the lobby if gloox/GnuTLS crashes upon TLS handshake, refs #5349, #4705.
Differential Revision: https://code.wildfiregames.com/D1679
Based on patch by: Itms
Tested on Fedora: Itms, bb and myself

This was SVN commit r21932.
2018-11-27 14:41:44 +00:00
Itms 2b847a520a Small changes to the macOS build scripts.
Patch By: smiley, Tobbi and trompetin17.
Differential Revision: https://code.wildfiregames.com/D1609
This was SVN commit r21931.
2018-11-13 16:09:35 +00:00
elexis dd57ba436d Prevent segfault when receiving a STUN connection request while not hosting, refs 61261d14fc / D364.
This was SVN commit r21928.
2018-11-07 22:56:05 +00:00
elexis 039637cf13 The files in this path were not marked as moved in 5dce2f1fb1...
This was SVN commit r21927.
2018-11-07 17:32:21 +00:00
elexis 5dce2f1fb1 Split XpartaMuPP and EcheLOn into separate directories and rename parent folder to "lobbybots" following 5e643ba6be.
Yields a more transparent directory structure, in particular when adding
the third bot or systemd service files.

Refs: #3022, D1659, D1661.
Comments by: user1, Dunedan
This was SVN commit r21926.
2018-11-07 17:23:56 +00:00
elexis 214d6caf43 Complete the lobby server readme and provide a sample ejabberd configuration file.
Describe Wildfire Games undocumented, but relevant or even required
configuration settings.
Add chapter on ejabberd connectivity: TLS encryption (1beb96cb20, refs
#4705), STUN (61261d14fc / D364), IPv6.
Elaborate use policy configuration, add nickname restrictions from
23d8bc11a5.
Brief Terms and Conditions notification (81883806ec, 54e5ad2ae9).
Recommend to run bots without administrative access (but explain the
alternative too for fans of the setting).
Explain how to configure and test 0 A.D. with new lobbies and how to
distribute the settings.

Differential Revision: https://code.wildfiregames.com/D1659
Fixes #4671
Reviewed By: user1
Comments By: Dunedan
This was SVN commit r21925.
2018-11-07 15:59:28 +00:00
elexis ccef625280 Support connecting the lobby bots without TLS errors if the server does not devlier a valid, non-selfsigned certificate.
From https://code.wildfiregames.com/D1659
Reviewed By: user1
Refs #4705

This was SVN commit r21924.
2018-11-07 11:31:01 +00:00
user1 31929d916f Some terms rephrasing and IP policy update
Summary:
* ValihrAnt pointed out a typo and that the "obtains" sentence is
ambiguous.
* It is proposed to save IPs for 3 years.
* stierkampf mentioned that one should refer to the contact url to
exercise the rights.

Test Plan:
Compare legitimate interest assessments by user1 and me to try to value
the retention period.
Judge how much time is left to translate, how efficient the translators
are and weigh against the benefit of the fix.

Reviewers: user1

Reviewed By: user1
Subscribers: user1, smiley, Stan, Vulcan

Differential Revision: https://code.wildfiregames.com/D1658
This was SVN commit r21922.
2018-11-05 20:56:17 +00:00
elexis 237c706dff Allow the user to print and save the text of the terms and conditions before the conclusion of the contract and use the word "Clickwrap agreement".
See EU Court of Justice decision C-322/14, refs #5257.
Adds one string.

Differential Revision: https://code.wildfiregames.com/D1657
This was SVN commit r21919.
2018-10-25 12:32:28 +00:00
elexis 404f2c48b3 Use a banmask for multiplayer matches that have lobby-authentication enabled.
This prevents a lobby player banned by the host from rejoining after
getting a new IP address and changing the rating part of the nickname,
refs #5320, #3241 / 32da740f14, #3549 / 0fd8aa2a77 / D897.

Differential Revision: https://code.wildfiregames.com/D1655
Reproduced By: Hannibal_Barca
This was SVN commit r21918.
2018-10-25 11:58:26 +00:00
elexis 9459825159 Remove two unused dangling gui xml references.
Revert the unintentional revert of 31e412b94e during the rebase of
ac7b5ce861.
Remove unintentionally copy-pasted onscreenToolTip reference from the
termsdialog following 74fbb4b823.

This was SVN commit r21917.
2018-10-24 12:04:11 +00:00
elexis 04ba9d1db4 Gracefully handle empty lobby chat messages.
One case was reproducible with PMs sent via psi-plus that contained only
whitespace, which is trimmed to the empty string clientside.

This was SVN commit r21916.
2018-10-21 14:19:36 +00:00
elexis 9df2fcf43e Delete Siwa Oasis (2) Skirmish map from 4dd90a1ef3 as the source topography map cannot be identified anymore and since it is not unlikely to come from a source that isn't public domain.
Differential Revision: https://code.wildfiregames.com/D1646
Comments By: wowgetoffyourcellphone, smiley, Stan, asterix
This was SVN commit r21915.
2018-10-19 21:06:07 +00:00
elexis ba8b23f28d Use static linking for macOS libsodium build, forgotton in dfa2048dc5.
Patch By: Itms
Refs https://github.com/na-Itms/0ad/tree/osx-fix

This was SVN commit r21914.
2018-10-19 16:29:48 +00:00
elexis c5cb9f6d11 Update macOS libcurl --without-libidn flag to --without-libidn2 following https://github.com/curl/curl/commit/9c91ec778104ae3b744b39444d544e82d5ee9ece
Fixes #5231.
Refs: 8ceb7142fa, 8817050e3a.
Differential Revision: https://code.wildfiregames.com/D1610
Patch By: Tobbi and viky / Victor Adascalitei
Comments By: Itms, andy5995
This was SVN commit r21913.
2018-10-19 16:14:12 +00:00
Itms c3d2ef2dbb Allow the translation scripts to pull the new resource (5a95ee0406).
This was SVN commit r21911.
2018-10-17 21:15:57 +00:00
elexis 9f68d092a7 Increase minimum password length on the lobby from 1 to 8, refs #5257.
This was SVN commit r21909.
2018-10-16 15:57:32 +00:00
elexis 54e5ad2ae9 Lobby Privacy Policy.
Restricts the previous Terms of Service clauses that asked for a
universal grant for personal data processing without explicitly
mentioning chatlogs or IP address logs (possibly in violation of the
Data Protection Directive).
Hopefully establishes GDPR compliance for the lobby by mentioning all
data procsessed, purposes and new user rights, fixes #5257.
Explain why the service is not directed to children < 13 and a COPPA
compliance note.
Add severability clause.
Add licensing note for terms.

Differential Revision: https://code.wildfiregames.com/D1590
Accepted By: Itms
refs https://wildfiregames.com/forum/index.php?/topic/24325-gdpr/

This was SVN commit r21908.
2018-10-16 13:46:18 +00:00
elexis bbf6fc47de Add liability and third party software exclusion to the Lobby and UserReporter terms.
Shorten Lobby Terms of Service by inlining definitions.
No personal data changes in this commit, refs #5257, D1590.

This was SVN commit r21906.
2018-10-13 13:34:28 +00:00
elexis 5a95ee0406 Create UserReporter translation resource for 209bab0255 / D1598.
Differential Revision: https://code.wildfiregames.com/D1647
Reviewed By: Itms
This was SVN commit r21905.
2018-10-13 00:06:52 +00:00
elexis c69cf5076f Add COPPA compliance note to UserReporter and mod.io terms.
Outlaw cheating on the lobby as proposed by user1.
Phrasing improvement of b3631d7bd5 by Hannibal Barca.

This was SVN commit r21904.
2018-10-13 00:01:35 +00:00
elexis b3631d7bd5 Update Lobby Terms Of Use.
Refs #5257, D1590, https://github.com/elexis1/0ad/pull/1
Comments By: Itms, user1, Hannibal_Barca, KeyCollector
This was SVN commit r21903.
2018-10-11 22:56:13 +00:00
elexis 0e2adda813 Display lobby TLS certificate verification errors from gloox, refs #4705.
Update to the most reason why TLS certificate verification fails.
Don't use translation yet..

Differential Revision: https://code.wildfiregames.com/D1620
Upstream bugreport: https://bugs.camaya.net/ticket/?id=280

This was SVN commit r21901.
2018-10-09 17:50:08 +00:00
elexis d7ff9722c6 Don't delay the pyrogenesis shutdown for 5 minutes but at most 10 seconds if the server is not responding, refs #968;
in particular Philips server not responding to SSL which became a
requirement by the client following 209bab0255 or following GDPR 32.1.a,
refs #5257 while the new backend is not ready yet.

Mark file emptied in 209bab0255 as deleted.
Add scrolling to the UserReporter window, so that the timeout error
strings that became visible following the bugfixes in b496168d0a and
c898c19735 and don't overlap with the buttons.

This was SVN commit r21900.
2018-10-09 16:27:42 +00:00
elexis 209bab0255 New UserReporter Terms and Conditions, hopefully GDPR compliant, refs #5257.
Require SSL for the UserReporter clientside.

Differential Revision: https://code.wildfiregames.com/D1598
Includes contributions by bb and Itms

This was SVN commit r21898.
2018-10-05 22:19:28 +00:00
elexis c898c19735 Fix UserReporter curl error message being cut off after the first colon following 0da7e822ff, refs 41395ffe5d, b496168d0a.
Informs maintainers of the UserReporter backend why it's currently
broken.

This was SVN commit r21897.
2018-10-04 22:24:13 +00:00
elexis 82740d9278 Mod.io Disclaimer.
Have the user accept explicitly that he is subject to the Terms and
Conditions and Privacy Policy by the DBolical Pty Ltd company when using
their service with our client.

Rely on luck that this is sufficient to count as educating the users
about the personal data processed, the purposes and legal grounds of
personal data processing and the GDPR user right to access, rectify,
erase, restrict and complain, refs #5257, GDPR 13.
The Mod.IO DMCA report possibility should be added eventually.
Remove FileExists hack from da49aa1541 / D1602.
Refs D1601, https://github.com/elexis1/0ad/tree/terms

This was SVN commit r21896.
2018-10-02 15:52:48 +00:00
elexis a098f59a6b New strings for the Terms and Conditions dialog, refs #5257.
Button captions and instruction strings by bb from D1602.
For the UserReporter replace "anonymous feedback" with "feedback"
because it was never anonymized on Philips backend and won't be
anonymous on the new backend either, certainly until the logfile is
rotated and possibly arguably afterwards too.

This was SVN commit r21895.
2018-09-30 14:49:02 +00:00
elexis 74fbb4b823 Language selection dropdown in the terms dialog.
Allows the user to either read the english Terms and Conditions written
by Wildfire Games or the version translated into the current locale by
transifex users.
The underlying problem that Wildfire Games cannot verify the accuracy or
completeness of the translations while providing the services to a
global audience remains.

Refs #5257
Differential Revision: https://code.wildfiregames.com/D1643
Comments By: bb on irc, smiley, asterix
This was SVN commit r21894.
2018-09-29 21:25:04 +00:00
elexis b496168d0a Fix UserReporter passing uninitialized data through the JS Interface and displaying it in the UI following 0da7e822ff if the curl connection failed.
Display a generic error message using curl_easy_strerror if the detailed
error description is unavailable.

Differential Revision: https://code.wildfiregames.com/D1625
This was SVN commit r21892.
2018-09-23 00:20:17 +00:00
elexis d19e32b2ea Fix mod.io curl error handling, following 833c9f108c / D1029 / https://gitlab.com/na-Itms/0ad/commit/cdc324f7f57bf3098c196c59a92718b1ab4d1e87.
Displays if the server is down instead of a misleading unrelated later
error message.

Differential Revision: https://code.wildfiregames.com/D1608
This was SVN commit r21891.
2018-09-23 00:06:25 +00:00
elexis 27c107a448 Inform users that they are subject to the mod.io Terms and Conditions and Privacy Policy and provide links following 833c9f108c / D1029. Refs GDPR #5257.
Add link to feedback.wildfiregames.com, which demonstrates users how
their data is going to be used.

Add link buttons to the Terms dialog (refs #4583), so that users are
informed of the terms prior to becoming subject to them.
Don't link the DMCA / copyright terms of mod.io now since I found no UI
with support for 3 buttons that doesn't appear unsatisfyingly ugly.
Adds 3 button captions and 1 tooltip string.

Differential Revision: https://code.wildfiregames.com/D1627
A Comment and a relatable patch in D1601 by smiley / (-_-).

This was SVN commit r21890.
2018-09-22 16:27:49 +00:00
elexis 82a89c4eb1 Move openURL function and two strings from public/ to mod/.
Use it for the mod author website now.
Use it for the terms links next, refs #5257, D1627.

This was SVN commit r21889.
2018-09-22 16:23:43 +00:00
elexis 6a1d8e7515 This file should have been moved, not copied in the previous commit da49aa1541, noticed by Emperior.
This was SVN commit r21888.
2018-09-14 20:17:24 +00:00
elexis da49aa1541 Refactor lobby terms and conditions UI from 80dbd1f2a3 / D1568 to a new terms dialog UI and reuse that for mod.io and the UserReporter, refs #5257, #5218.
Reuse all existing strings, use a FileExists hack for mod.io until the
new strings are committed.
Rename prelobby/common/terms/terms.js to termslobby.js for easier
distinction from common/terms.js.

Based on patch by: bb
Differential Revision: https://code.wildfiregames.com/D1602
refs https://code.wildfiregames.com/D1601
refs https://github.com/bb-bb/0ad/tree/terms
refs https://github.com/elexis1/0ad/tree/terms

This was SVN commit r21887.
2018-09-14 15:14:48 +00:00
elexis 41395ffe5d Split UserReporter JS and XML from mainmenu code and refactor it.
XML button duplication removal by bb in
https://github.com/bb-bb/0ad/commit/62acfd74cb3efdb517db537bd4e62fa0ba6c304d
Write formatUserReportStatus in object-oriented style, refs irc
discussion with Vladislav on 2018-08-10.
Add the two missing cases "proxy" and "waiting" from UserReport.cpp and
reuse the "connecting to server" string.
No messages.json changes needed for the new directory, no string
changes.

This was SVN commit r21886.
2018-09-13 12:46:08 +00:00
Stan ef8582a7fd Update docs.
Patch by: The person asked not to be credited.
Refs: #5160
Differential Revision: ​https://code.wildfiregames.com/D1505
This was SVN commit r21885.
2018-09-11 16:33:22 +00:00
Stan 8311d9f899 Fix two bugs noticed by fatherbushido.
Fixes #5174

This was SVN commit r21884.
2018-09-11 09:12:36 +00:00
Stan 8569f188b0 Fix a texture bug reported by Hidan
Here :
https://wildfiregames.com/forum/index.php?/topic/24633-persian-temple-textures-missing/
Based on a tweak by wowgetoffyourcellphone mixed with a personal one.
- Move Old Pers struct to the old public as it shouldn't be used
anymore.
- Use Normal and specular textures where available.
- Make sure the pers png is used from now on.

This was SVN commit r21883.
2018-09-11 08:47:25 +00:00
elexis 4b4d3f71f5 Gamesetup cleanup.
Move civInfo press event handling from XML to the JS GUI object data
from b4e5858f6d / D322.
Equally move civInfo tooltip from init (which should remain agnostic of
content) following 760a47335d / D846, refs #4970.

This was SVN commit r21882.
2018-09-10 15:34:48 +00:00
elexis d910f4f164 Remove two dead strings from gamesetup.xml following 8cfd494b88 / D505 and 6a10797355 / D1066.
This was SVN commit r21881.
2018-09-09 17:07:39 +00:00
elexis 936d32414a Remove unused type argument and sanity check following 100be98215, f4749a8e2c.
This was SVN commit r21880.
2018-09-05 10:49:57 +00:00
Stan b574f7f45f Fix Persian chariots making walking sound, as it becomes annoying when too many of them are moving.
Reported by and discussed with Imarok.

This was SVN commit r21878.
2018-09-01 17:24:02 +00:00
elexis 78d7702262 Always require lobby authentication for lobby matches, refs #3549 / 0fd8aa2a77 / D897.
This is due to too many oversteppings of the lobby Terms of Use
following JS mods that implemented an UI for players to join lobby games
with arbitrary nicknames or 'replace' / impersonate other players in
lobby games.

Agreed with: user1, Dunedan
Code proofread by: Vladislav
Minor discussions with: Imarok, Hannibal_Barca, smiley, fpre, bb, nani
refs
https://wildfiregames.com/forum/index.php?/topic/24722-improving-mod-security/

This was SVN commit r21877.
2018-08-25 14:34:30 +00:00
elexis 1beb96cb20 Lobby to optionally require TLS certificate and certificate verification, refs #4737, #5257.
These are config options because developers should be able to test a
local lobby server quickly without going through the hassle to create a
valid or invalid certificate or modify and compile the client.
To protect from malicious JS mods reducing these security config
options, these options as well as the hostname would have to be
protected from JS access.
The user might still connect to other lobbies through a hypothetical UI
if there were a non-modifiable GUI confirmation dialog prior to the
connection.

Proofreading and feature design discussion by Vladislav and Dunedan on
irc on 2018-08-19 and 2018-08-23.

This was SVN commit r21875.
2018-08-24 11:29:38 +00:00
elexis 86db66cac1 Allow players to instantly reset the readystate by rightclicking on the ready button, refs #4369, D49 / 5f8f7bae20.
This was SVN commit r21873.
2018-08-23 17:57:43 +00:00
elexis 81dfd63610 Fix missing alias in 468d963e78 / D1575, refs #5218, taken from D1590.
This was SVN commit r21872.
2018-08-23 17:26:31 +00:00
elexis e07ef3fafb Fix uppercase following Hexify function for lobby password encryption in ecce63628c / D1591, fixes #5289.
This was SVN commit r21871.
2018-08-23 17:13:22 +00:00
elexis 7f4950cb17 Use https in hyperlinks for sites that support it, refs #5257.
This was SVN commit r21870.
2018-08-23 09:23:06 +00:00
elexis dd008af2f8 Write UserReport data to local logfiles, so that users can review the personal data impact without exposing the data to JS/mods, refs #5257, b3438cabd2.
Write the logfiles even if the UserReporter is disabled, so that the
assessment can be done prior to use.

This was SVN commit r21868.
2018-08-22 22:17:42 +00:00
elexis b3438cabd2 Hide userreporter ID from mods and logfiles, since it shall be used as an authentication token for GDPR personal data requests, refs #5257, f51f78c999 / D1563.
Comments by: Vladislav in irc on 2018-08-13
This was SVN commit r21867.
2018-08-22 16:02:05 +00:00
elexis 9e712fa0c5 Move UserReporter C++/JS functions from JSInterface_Debug.cpp to JSInterface_UserReport.cpp, refs #4772.
This way it stands out more as a separate feature that can be more
easily exchanged, extended, maintained or conditionally removed from the
build and leaves more transparent includes, refs #5257.

Add missing string includes following 7c2e9027c2 and d6cb9c845b.
Remove unused Profile include following 38d6f81d71 and d6cb9c845b.
Remove unused CLogger include, add missing debug include following
d6cb9c845b.
Remove unused CConsole include following 9f0484e5ce / D1073.
Remove unused ProfilerViewer include following 2af94c5898.

This was SVN commit r21866.
2018-08-22 12:48:27 +00:00
s0600204 22791af91f Use pkg-config instead of sdl2-config
Resolves build issue on Arch Linux (and Arch-derivatives)

(Also forms part of a fix for Slackware-current builds)


Accepted By: echotangoecho (Arch)
Confirmed as functional by: Imarok (Ubuntu 16.04, gcc5.4), wes-fole-dog
(Parabola)
Refs: #5157
Fixes: #5152
Differential Revision: https://code.wildfiregames.com/D1582
This was SVN commit r21865.
2018-08-17 19:47:19 +00:00
elexis ecce63628c Unify duplicate u8* to hex string functions in a new Hexify function variant, similar to bb1f86f515, used by Tests, CacheLoader, Terms and Conditions, Lobby and mod.io.
Removes the call to the sprintf_s function from test_MD5.h in 17718981cf
and JSInterface_Main.cpp in 468d963e78.
As reported by Vladislav that function might not null-terminate strings
on untested/newer platforms, but the caller requires it here.
The sprintf_s calls in other places have the same problem.

Differential Revision: https://code.wildfiregames.com/D1591
Accepted By: Vladislav
This was SVN commit r21863.
2018-08-08 12:59:05 +00:00
elexis 1e59db453a Prioritize civ names over mapnames for gamesetup chat autocompletion (Persians > Persian Highlands).
This was SVN commit r21862.
2018-08-06 10:46:33 +00:00
elexis f11b59f117 Add back incorrectly removed clause from f7783fb4bb that was needed for the lobby, refs #4962 / D1583.
This was SVN commit r21861.
2018-08-06 09:45:33 +00:00
elexis f7783fb4bb Fix biome-specific mappreviews in 7f602037ba for zipped mods, refs #4962.
Add TextureExists to avoid needless redundant hardcoding of the
filenames.
Remove mapBiome.Preview from gamedescription.js, obsolete following
8cde469501.

Differential Revision: https://code.wildfiregames.com/D1583
Accepted By: Vladislav
This was SVN commit r21859.
2018-08-05 21:50:00 +00:00
elexis 2af94c5898 Remove disabled remains of the performance data (= profiler data + text input) upload feature from the UserReporter from 0da7e822ff.
User-submitted text upload was removed in 2779512c6e in preference of
the bugtracker.
Remove leftover mainmenu.js function that this commit should have
removed.

Profiler data upload was disabled in b9e46f386b because the data amount
was too large and because the two timing snapshots are inconclusive
without further data.
The hereby removed exposed JS functions could have been exploited by JS
mods to upload 0ad userdata to arbitrary places.

The performance data upload feature can be redesigned, implemented
without JS exposure, with a more transparent privacy policy (refs
#5257).

Differential Revision: https://code.wildfiregames.com/D1597
Performance upload feature removal accepted by: Vladislav
This was SVN commit r21858.
2018-08-05 15:18:00 +00:00
elexis bdc68f85c9 Add missing XmppClient destruction if maploading failed in bffe917914.
Differential Revision: https://code.wildfiregames.com/D1596
Patch By: smiley aka (-_-)
This was SVN commit r21856.
2018-07-21 12:17:13 +00:00
elexis d6caaaa54c Add missing XmppClient destruction in 4b09d6f167 needed for the case of leaving the lobby to change the mods but then not changing the mods and entering the lobby again.
This was SVN commit r21855.
2018-07-21 12:05:06 +00:00
elexis 9fa1a230cb Prevent hosts that didn't modify C++ code from starting the game without all assigned online players being ready (launchGame(); cheat), refs #4463.
This works in autostartmode because that sets every client to an
observer and still relies on enabled cheats to have players assign
themselves.

This was SVN commit r21854.
2018-07-21 11:58:35 +00:00
elexis aec7509004 Remove 256 character limit from escapeText.
escapeText was added for the gamesetup and session chat in 9ee44bd9b8,
but the character limit is counterproductive for chatting with more than
2 sentences per line, when displaying a file path or other arbitrary
escaped text,
not really an effective measure against lobby spam, nor was that option
considered in any of the later calls except d7d0a7f869 and
thus more likely to cause unintended than intended code behavior and
should instead be implemented with max_length for input fields and
linebreaks and smaller GUI object sizes for displaying, refs #5266.

Remove early returns that are redundant code and require more
performance in the average case (non-empty string).

From Differential-Revision: https://code.wildfiregames.com/D720

This was SVN commit r21853.
2018-07-21 09:25:04 +00:00
elexis 81d1e7a111 Fix conversion in previous 468d963e78 / D1575.
This was SVN commit r21851.
2018-06-21 16:52:52 +00:00
elexis 468d963e78 Persist the lobby Terms Of Use and Terms Of Service checkbox if the logged in user and the accepted versions of the pages didn't change since last login, refs #5218.
This way the user is only forced to read the Terms again that changed or
if the user logged in from a different machine.
Use md5sum since it is sufficiently resistant against collisions and
doesn't freeze the window for 2 seconds like EncryptPassword / SHA256
does, refs #4399.
Use 0 instead of empty string in default.cfg, refs #3990.

Differential Revision: https://code.wildfiregames.com/D1575
Partial review by: Vladislav
This was SVN commit r21850.
2018-06-21 16:38:08 +00:00
elexis fe41404ba8 Fix XML syntax error in 80dbd1f2a3 reported by gameboy.
The error was hidden by Xeromyces loading the syntactically correct XMB
file that is still written for syntactically wrong XML files, refs
#5222, D1574.

This was SVN commit r21849.
2018-06-12 09:18:50 +00:00
elexis 88eb3527b7 Remove leftover debug line from previous.
This was SVN commit r21848.
2018-06-11 16:08:49 +00:00
elexis 80dbd1f2a3 Rewrite the prelobby pages and add the Terms of Service, Terms of Use and the agreement checkbox to the login page.
Ensure lobby players cannot join without acceptance of the terms in case
they change, fixes #5218, as agreed in last staff meeting.

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

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

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

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

Differential Revision: https://code.wildfiregames.com/D1568
Few comments by: Vladislav, Imarok, gallaecio
This was SVN commit r21847.
2018-06-11 15:59:22 +00:00
elexis de1a73ba65 Lobby register/login dialog cleanup.
Move JS code from XML files to JS files.
Move all terms data to one JS object.
Unify duplicate Terms dialog opening code.
Update the checkbox enabled property only upon dialog close, not onTick.

This was SVN commit r21846.
2018-06-08 13:39:52 +00:00
elexis f51f78c999 Don't print lobby buddies to mainlog.html, refs D209 / dcf12abe8c.
Differential Revision: https://code.wildfiregames.com/D1563
Comments By: Vladislav
This was SVN commit r21844.
2018-06-06 22:37:20 +00:00
elexis ce64c57b8c Prevent calling the JS gamestart function twice when doubleclicking on the "Start Game" button.
It triggered an OOS on rejoin prior to ee9cf54149, refs #5199 and
resulted in the playernames of the current match persisting into new
gamesetups, fixes #5206.

Differential Revision: https://code.wildfiregames.com/D1558
Comments By: wraitii
This was SVN commit r21843.
2018-06-06 22:25:15 +00:00
elexis eda236522c Prevent players from disconnecting during the loading screen by increasing the timeout tolerance to 60 seconds for that period, fixes #5163.
The NetClient runs in the main thread, so any part of the loading screen
consuming several seconds makes that client timeout.
This is a workaround because threading the NetClient would have prevent
these timeouts, refs #3700.
Coutnerintuitively, since enet timeout tolerance is proportional to the
latency, the better the connection of the player, the more likely it was
to drop on gamestart.

This problem became very frequent in Alpha 23, at least due to the Aura
bugfix 583b6ec625, AIInterface being particularly slow and that not
having been disabled yet in the loading screen resulting in additional
10 second freezes during the loading screen, even on empty maps, refs
#5200, 8e168f85e6.

Differential Revision: https://code.wildfiregames.com/D1513
Based on patch by: causative
This was SVN commit r21842.
2018-06-06 22:09:38 +00:00
elexis 2588682c09 In preparation of D1513, allow the NetClientSession to find out if it's the "Local Client", refs #5163.
For good practice, mention all members in the affected member
initializer list:
Add booelan m_IsLocalClient and u32 m_HostID to the member initializer
list (to not have them undefined, even though they are not read from
until they are set).
Add the strings m_GUID and m_UserName for completeness (even though the
default constructor is already called for strings).
Use nullptr instead of NULL for pointers.

Comments By: Vladislav
This was SVN commit r21841.
2018-06-06 21:17:01 +00:00
elexis 8ae179aaae Support parsing config values as u32 in preparation of D1513, refs #5163.
Differential Revision: https://code.wildfiregames.com/D1566
Reviewed By: Vladislav
This was SVN commit r21840.
2018-06-06 17:55:08 +00:00
temple 8e168f85e6 Disable AIInterface earlier to remove unnecessary lag on gamestart
Differential Revision: https://code.wildfiregames.com/D1559
Reviewed by: wraitii
Comments by: elexis, Itms, Stan
Refs: #5200

This was SVN commit r21838.
2018-06-05 23:23:37 +00:00
elexis 43730f15f3 Fix network FSM errors when a client closes the game during the loading screen or rejoin synchronization stage, fixes #4594, refs 3199.
Fix comments claiming to ensure reliability when in reality there is
only a small likelihood of the message being received.

Broken by fa85527baf / refs #2420 which was a preparation for a3e1c68b9a
/ refs #2373, which hence didn't actually work and was circumvented by
9b136a45fc without clarification.
Might have caused #3643.
Differential Revision: https://code.wildfiregames.com/D1557
Reviewed By: Imarok
This was SVN commit r21837.
2018-06-05 14:52:41 +00:00
elexis ee9cf54149 Fix an OOS on rejoin after doubleclicking on the StartGame button, fixes #5199, refs #5162.
Prevents changes to the gamesettings after the game was started, so as
to use the correct map seed when generating the random map terrain for
rejoiners.
D1558 will prevent the UI bug #5206 and FSM error from doubleclicking on
StartGame.

Differential Revision: https://code.wildfiregames.com/D1562
Tested and accepted by: temple
This was SVN commit r21836.
2018-06-05 12:24:30 +00:00
temple 48e794e97d Always call SetPassabilityCircular -- Fix OOS after rejoin on square maps
Differential Revision: https://code.wildfiregames.com/D1555
Reviewed by: elexis
Fixes: #5186

This was SVN commit r21835.
2018-06-03 16:40:44 +00:00
elexis 1608202d4f Fix an OOS on rejoin on Danubius following 3d65bfe555, refs #4855, fixes #5198.
Vectors are still deserialized as objects without their prototype
functions, so doing math on these obejcts fails upon rejoin, refs #4698.
This patch doesn't add any version incompatibilities and players with
the patched version can successfully rejoin unpatched games.

Differential Revision: https://code.wildfiregames.com/D1548
Reviewed By: temple
This was SVN commit r21834.
2018-06-03 11:49:55 +00:00
elexis 06e2e77349 Report network timeouts and lag warnings to clients that finished the loading screen but are waiting for other clients to finish it.
This allows the host to distinguish clients that are just slower than
everyone else with the loading screen from clients who have most likely
disconnected or crashed already and may be considered to be kicked.
This is especially important for D1513, because that increases the
timeout tolerance to a minute or longer.

Fixes #5193
Differential Revision: https://code.wildfiregames.com/D1546
Reviewed By: causative
This was SVN commit r21832.
2018-06-01 17:35:00 +00:00
elexis 4fbe399e07 Save oos_dump.dat too when saving oos_dump.txt.
Saves time to reproduce the binary simstate or provides data that may be
otherwise irreproducible, refs #5162.

Differential Revision: https://code.wildfiregames.com/D1544
Reviewed By: temple
This was SVN commit r21830.
2018-05-29 02:50:33 +00:00
elexis 333766ef1b Test all full hashes in non-visual replaymode by default and keep skipping quick-hash by default.
The previous code only tested quick hashes every 100 turns and could not
be used to confirm replay hashes matching.
The option can become used for visual replays too.

Differential Revision: https://code.wildfiregames.com/D1538
Refs #5162
Reviewed By: temple
This was SVN commit r21829.
2018-05-29 02:14:38 +00:00
Stan 572b72fa7f Fix non-visual replay hash mismatch caused by CCmpSound condition in CCmpVisualActor
Differential Revision: ​https://code.wildfiregames.com/D1519
Reviewed by: temple, elexis, wraitii
refs: af2abb8cbf

This was SVN commit r21828.
2018-05-28 19:06:09 +00:00
elexis 4cefb286f4 Prevent the lobby gamelist from breaking entirely if a gamestanza contains an empty or invalid mod version JSON string (refs eca956a513).
Catch all JSON SyntaxError exceptions in JS (refs d7d0a7f869).
The C++ ParseJSON function already catches exceptions and the resulting
errors can't trigger a denial of service.

Differential Revision: https://code.wildfiregames.com/D1479
Based on patch by: Imarok
Reviewed by: Imarok
Comments By: Itms
This was SVN commit r21827.
2018-05-27 13:47:18 +00:00
Gallaecio 788ca1f69d Revert 51afc72886, it violates current freezes
This was SVN commit r21826.
2018-05-26 18:26:31 +00:00
Gallaecio 51afc72886 reaffect → reassign
Reported by GunChleoc on Transifex.

This was SVN commit r21825.
2018-05-26 18:22:12 +00:00
elexis 44ec2e324e Alpha 23 "lobby lag" release fix.
Caches the loaded mod versions, so that GetEngineInfo doesn't read the
zip and json files everytime and returns about 1000 times faster.
Adds two missing includes.

The lobby froze multiple times every few seconds on updateGameList().
The gamesetup page was slowed down with every stanza sent and the
load savegame selection page was slowed down per savegame selection,
proportional to the number of installed zipped mods.

Introduced by: d5807cd59f and eca956a513
Differential Revision: https://code.wildfiregames.com/D1518
Reviewed By: wraitii
Comments By: Imarok (in D1512, P121), leper (in the lobby)
This was SVN commit r21823.
2018-05-24 18:08:56 +00:00
wraitii 83d228fe7e Fix hosting games in the lobby.
Fixes #5164.

Reported by: HMS-Surprise
Reviewed By: Stan
Trac Tickets: #5164

Differential Revision: https://code.wildfiregames.com/D1498
This was SVN commit r21822.
2018-05-21 16:52:50 +00:00
194 changed files with 3819 additions and 1522 deletions
+7
View File
@@ -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.
+16 -6
View File
@@ -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.
+5 -21
View File
@@ -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);
}
+1 -1
View File
@@ -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>
+8 -8
View File
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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"/>
+14 -4
View File
@@ -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>
@@ -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