Page MenuHomeWildfire Games

Fix Lobby lag when updating the game list
AbandonedPublic

Authored by elexis on May 21 2018, 8:45 AM.

Details

Summary

I could only partly reproduce the lobbylag this morning: Each time I open the lobby from gamesetup it needs some seconds to open. This delay does not occur when using the non-packaged version.

As hinted by @ffffffff calling Engine.GetEngineInfo() seems to be quite costly and caused the delay in my case of "lobby from gamesetup startup delay". This is fixed by caching Engine.GetEngineInfo().mods at init. Should be save to do so as you can only change the enabled mods by restarting the game.

Test Plan

If you can reproduce lobbylag with the packaged version of the game. put the patched lobby.js into the right path under mods/user/

Diff Detail

Repository
rP 0 A.D. Public Repository
Branch
/ps/trunk
Lint
Lint OK
Unit
No Unit Test Coverage
Build Status
Buildable 6127
Build 10200: Vulcan BuildJenkins
Build 10199: arc lint + arc unit

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
Vulcan added a subscriber: Vulcan.May 21 2018, 8:55 AM

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  47|  47|  * The playerlist will be assembled using these values.
|  48|  48|  */
|  49|  49| var g_PlayerStatuses = {
|  50|    |-	"available": { "color": "0 219 0",     "status": translate("Online") },
|    |  50|+	"available": { "color": "0 219 0", "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'away'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  48|  48|  */
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|    |-	"away":      { "color": "229 76 13",   "status": translate("Away") },
|    |  51|+	"away": { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  48|  48|  */
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|    |-	"away":      { "color": "229 76 13",   "status": translate("Away") },
|    |  51|+	"away":      { "color": "229 76 13", "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'playing'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|    |-	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|    |  52|+	"playing": { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|    |-	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|    |  52|+	"playing":   { "color": "200 0 0", "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'offline'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|    |-	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    |  53|+	"offline": { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|  56|  56| 
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|    |-	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    |  53|+	"offline":   { "color": "0 0 0", "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|  56|  56| 
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'unknown'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|    |-	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|    |  54|+	"unknown": { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|  56|  56| 
|  57|  57| var g_RoleNames = {
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 224| 224| 					me ?
| 225| 225| 						translate("You have been muted.") :
| 226| 226| 						translate("%(nick)s has been muted.") :
| 227|    |-				newrole == "moderator" ?
|    | 227|+					newrole == "moderator" ?
| 228| 228| 					me ?
| 229| 229| 						translate("You are now a moderator.") :
| 230| 230| 						translate("%(nick)s is now a moderator.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 225| 225| 						translate("You have been muted.") :
| 226| 226| 						translate("%(nick)s has been muted.") :
| 227| 227| 				newrole == "moderator" ?
| 228|    |-					me ?
|    | 228|+						me ?
| 229| 229| 						translate("You are now a moderator.") :
| 230| 230| 						translate("%(nick)s is now a moderator.") :
| 231| 231| 				msg.oldrole == "visitor" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 226| 226| 						translate("%(nick)s has been muted.") :
| 227| 227| 				newrole == "moderator" ?
| 228| 228| 					me ?
| 229|    |-						translate("You are now a moderator.") :
|    | 229|+							translate("You are now a moderator.") :
| 230| 230| 						translate("%(nick)s is now a moderator.") :
| 231| 231| 				msg.oldrole == "visitor" ?
| 232| 232| 					me ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 227| 227| 				newrole == "moderator" ?
| 228| 228| 					me ?
| 229| 229| 						translate("You are now a moderator.") :
| 230|    |-						translate("%(nick)s is now a moderator.") :
|    | 230|+							translate("%(nick)s is now a moderator.") :
| 231| 231| 				msg.oldrole == "visitor" ?
| 232| 232| 					me ?
| 233| 233| 						translate("You have been unmuted.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 228| 228| 					me ?
| 229| 229| 						translate("You are now a moderator.") :
| 230| 230| 						translate("%(nick)s is now a moderator.") :
| 231|    |-				msg.oldrole == "visitor" ?
|    | 231|+						msg.oldrole == "visitor" ?
| 232| 232| 					me ?
| 233| 233| 						translate("You have been unmuted.") :
| 234| 234| 						translate("%(nick)s has been unmuted.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 229| 229| 						translate("You are now a moderator.") :
| 230| 230| 						translate("%(nick)s is now a moderator.") :
| 231| 231| 				msg.oldrole == "visitor" ?
| 232|    |-					me ?
|    | 232|+							me ?
| 233| 233| 						translate("You have been unmuted.") :
| 234| 234| 						translate("%(nick)s has been unmuted.") :
| 235| 235| 					me ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 230| 230| 						translate("%(nick)s is now a moderator.") :
| 231| 231| 				msg.oldrole == "visitor" ?
| 232| 232| 					me ?
| 233|    |-						translate("You have been unmuted.") :
|    | 233|+								translate("You have been unmuted.") :
| 234| 234| 						translate("%(nick)s has been unmuted.") :
| 235| 235| 					me ?
| 236| 236| 						translate("You are not a moderator anymore.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 231| 231| 				msg.oldrole == "visitor" ?
| 232| 232| 					me ?
| 233| 233| 						translate("You have been unmuted.") :
| 234|    |-						translate("%(nick)s has been unmuted.") :
|    | 234|+								translate("%(nick)s has been unmuted.") :
| 235| 235| 					me ?
| 236| 236| 						translate("You are not a moderator anymore.") :
| 237| 237| 						translate("%(nick)s is not a moderator anymore.");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 232| 232| 					me ?
| 233| 233| 						translate("You have been unmuted.") :
| 234| 234| 						translate("%(nick)s has been unmuted.") :
| 235|    |-					me ?
|    | 235|+							me ?
| 236| 236| 						translate("You are not a moderator anymore.") :
| 237| 237| 						translate("%(nick)s is not a moderator anymore.");
| 238| 238| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 233| 233| 						translate("You have been unmuted.") :
| 234| 234| 						translate("%(nick)s has been unmuted.") :
| 235| 235| 					me ?
| 236|    |-						translate("You are not a moderator anymore.") :
|    | 236|+								translate("You are not a moderator anymore.") :
| 237| 237| 						translate("%(nick)s is not a moderator anymore.");
| 238| 238| 
| 239| 239| 			addChatMessage({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 234| 234| 						translate("%(nick)s has been unmuted.") :
| 235| 235| 					me ?
| 236| 236| 						translate("You are not a moderator anymore.") :
| 237|    |-						translate("%(nick)s is not a moderator anymore.");
|    | 237|+								translate("%(nick)s is not a moderator anymore.");
| 238| 238| 
| 239| 239| 			addChatMessage({
| 240| 240| 				"text": "/special " + sprintf(txt, { "nick": msg.nick }),

binaries/data/mods/public/gui/lobby/lobby.js
|1031| »   »   switch·(sortBy)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/lobby/lobby.js
|1291| »   while·(true)
|    | [NORMAL] ESLintBear (no-constant-condition):
|    | Unexpected constant condition.

binaries/data/mods/public/gui/lobby/lobby.js
| 734| »   »   case·'name':
|    | [NORMAL] JSHintBear:
|    | Expected a 'break' statement before 'default'.

Link to build: https://jenkins.wildfiregames.com/job/differential/535/display/redirect

I cannot reproduce any lobbylag on windows. All above was doen using Ubuntu.

elexis added a subscriber: elexis.May 21 2018, 1:12 PM

Why is it a reproduction partial (i.e. which part was not reproduced?),
why is the function slow (is reading the zip files the slow part?) and
why is it the caching not in done at the root (C++)?

FYI My plan is to commit if it doesn't appear to brea kantyhing and immediately raise a concern.

ffffffff requested changes to this revision.May 21 2018, 4:07 PM

pls cache in gamesetup.js too
especially when sending stanza changes

This revision now requires changes to proceed.May 21 2018, 4:07 PM
wraitii commandeered this revision.May 21 2018, 7:15 PM
wraitii added a reviewer: Imarok.
wraitii updated this revision to Diff 6606.May 21 2018, 7:29 PM
wraitii retitled this revision from Probably fix the lobbylag to Fix Lobby lag when updating the game list.

So the real cause of this freeze is definitely that we're fetching the data for every game instead. Then this is also perhaps slow on Windows for some odd pathological reason in the bundle that we should investigate (possibly windows is dumber about reading big zips than we thought).

The below will definitely fix the intense lag.

Successful build - Chance fights ever on the side of the prudent.

Linter detected issues:
Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  47|  47|  * The playerlist will be assembled using these values.
|  48|  48|  */
|  49|  49| var g_PlayerStatuses = {
|  50|    |-	"available": { "color": "0 219 0",     "status": translate("Online") },
|    |  50|+	"available": { "color": "0 219 0", "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'away'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  48|  48|  */
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|    |-	"away":      { "color": "229 76 13",   "status": translate("Away") },
|    |  51|+	"away": { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  48|  48|  */
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|    |-	"away":      { "color": "229 76 13",   "status": translate("Away") },
|    |  51|+	"away":      { "color": "229 76 13", "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'playing'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|    |-	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|    |  52|+	"playing": { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|    |-	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|    |  52|+	"playing":   { "color": "200 0 0", "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'offline'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|    |-	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    |  53|+	"offline": { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|  56|  56| 
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|    |-	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    |  53|+	"offline":   { "color": "0 0 0", "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|  56|  56| 
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'unknown'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|    |-	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|    |  54|+	"unknown": { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|  56|  56| 
|  57|  57| var g_RoleNames = {
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 219| 219| 					me ?
| 220| 220| 						translate("You have been muted.") :
| 221| 221| 						translate("%(nick)s has been muted.") :
| 222|    |-				newrole == "moderator" ?
|    | 222|+					newrole == "moderator" ?
| 223| 223| 					me ?
| 224| 224| 						translate("You are now a moderator.") :
| 225| 225| 						translate("%(nick)s is now a moderator.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 220| 220| 						translate("You have been muted.") :
| 221| 221| 						translate("%(nick)s has been muted.") :
| 222| 222| 				newrole == "moderator" ?
| 223|    |-					me ?
|    | 223|+						me ?
| 224| 224| 						translate("You are now a moderator.") :
| 225| 225| 						translate("%(nick)s is now a moderator.") :
| 226| 226| 				msg.oldrole == "visitor" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 221| 221| 						translate("%(nick)s has been muted.") :
| 222| 222| 				newrole == "moderator" ?
| 223| 223| 					me ?
| 224|    |-						translate("You are now a moderator.") :
|    | 224|+							translate("You are now a moderator.") :
| 225| 225| 						translate("%(nick)s is now a moderator.") :
| 226| 226| 				msg.oldrole == "visitor" ?
| 227| 227| 					me ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 222| 222| 				newrole == "moderator" ?
| 223| 223| 					me ?
| 224| 224| 						translate("You are now a moderator.") :
| 225|    |-						translate("%(nick)s is now a moderator.") :
|    | 225|+							translate("%(nick)s is now a moderator.") :
| 226| 226| 				msg.oldrole == "visitor" ?
| 227| 227| 					me ?
| 228| 228| 						translate("You have been unmuted.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 223| 223| 					me ?
| 224| 224| 						translate("You are now a moderator.") :
| 225| 225| 						translate("%(nick)s is now a moderator.") :
| 226|    |-				msg.oldrole == "visitor" ?
|    | 226|+						msg.oldrole == "visitor" ?
| 227| 227| 					me ?
| 228| 228| 						translate("You have been unmuted.") :
| 229| 229| 						translate("%(nick)s has been unmuted.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 224| 224| 						translate("You are now a moderator.") :
| 225| 225| 						translate("%(nick)s is now a moderator.") :
| 226| 226| 				msg.oldrole == "visitor" ?
| 227|    |-					me ?
|    | 227|+							me ?
| 228| 228| 						translate("You have been unmuted.") :
| 229| 229| 						translate("%(nick)s has been unmuted.") :
| 230| 230| 					me ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 225| 225| 						translate("%(nick)s is now a moderator.") :
| 226| 226| 				msg.oldrole == "visitor" ?
| 227| 227| 					me ?
| 228|    |-						translate("You have been unmuted.") :
|    | 228|+								translate("You have been unmuted.") :
| 229| 229| 						translate("%(nick)s has been unmuted.") :
| 230| 230| 					me ?
| 231| 231| 						translate("You are not a moderator anymore.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 226| 226| 				msg.oldrole == "visitor" ?
| 227| 227| 					me ?
| 228| 228| 						translate("You have been unmuted.") :
| 229|    |-						translate("%(nick)s has been unmuted.") :
|    | 229|+								translate("%(nick)s has been unmuted.") :
| 230| 230| 					me ?
| 231| 231| 						translate("You are not a moderator anymore.") :
| 232| 232| 						translate("%(nick)s is not a moderator anymore.");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 227| 227| 					me ?
| 228| 228| 						translate("You have been unmuted.") :
| 229| 229| 						translate("%(nick)s has been unmuted.") :
| 230|    |-					me ?
|    | 230|+							me ?
| 231| 231| 						translate("You are not a moderator anymore.") :
| 232| 232| 						translate("%(nick)s is not a moderator anymore.");
| 233| 233| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 228| 228| 						translate("You have been unmuted.") :
| 229| 229| 						translate("%(nick)s has been unmuted.") :
| 230| 230| 					me ?
| 231|    |-						translate("You are not a moderator anymore.") :
|    | 231|+								translate("You are not a moderator anymore.") :
| 232| 232| 						translate("%(nick)s is not a moderator anymore.");
| 233| 233| 
| 234| 234| 			addChatMessage({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 229| 229| 						translate("%(nick)s has been unmuted.") :
| 230| 230| 					me ?
| 231| 231| 						translate("You are not a moderator anymore.") :
| 232|    |-						translate("%(nick)s is not a moderator anymore.");
|    | 232|+								translate("%(nick)s is not a moderator anymore.");
| 233| 233| 
| 234| 234| 			addChatMessage({
| 235| 235| 				"text": "/special " + sprintf(txt, { "nick": msg.nick }),

binaries/data/mods/public/gui/lobby/lobby.js
|1028| »   »   switch·(sortBy)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/lobby/lobby.js
|1288| »   while·(true)
|    | [NORMAL] ESLintBear (no-constant-condition):
|    | Unexpected constant condition.

binaries/data/mods/public/gui/lobby/lobby.js
| 729| »   »   case·'name':
|    | [NORMAL] JSHintBear:
|    | Expected a 'break' statement before 'default'.

Link to build: https://jenkins.wildfiregames.com/job/differential/536/display/redirect

first patch was better

Why not caching it on init?

wraitii updated this revision to Diff 6610.May 21 2018, 10:26 PM

So I misunderstood that I couldn't reproduce this, because I could.

Here's the correct C++ fix, with also the JS fix because I think it's still a good move. The issue was… that vfs_lookup was completely broken.

I'm not sure what the old code was trying to do to be honest, it looked like lazy-loading but did the exact opposite?
The result was that we loaded the whole mod any time we loaded a file, it seems.

This should correctly lazy-load.

Should be tested on other systems.

Build failure - The Moirai have given mortals hearts that can endure.

Linter detected issues:
Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  47|  47|  * The playerlist will be assembled using these values.
|  48|  48|  */
|  49|  49| var g_PlayerStatuses = {
|  50|    |-	"available": { "color": "0 219 0",     "status": translate("Online") },
|    |  50|+	"available": { "color": "0 219 0", "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'away'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  48|  48|  */
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|    |-	"away":      { "color": "229 76 13",   "status": translate("Away") },
|    |  51|+	"away": { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  48|  48|  */
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|    |-	"away":      { "color": "229 76 13",   "status": translate("Away") },
|    |  51|+	"away":      { "color": "229 76 13", "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'playing'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|    |-	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|    |  52|+	"playing": { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  49|  49| var g_PlayerStatuses = {
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|    |-	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|    |  52|+	"playing":   { "color": "200 0 0", "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'offline'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|    |-	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    |  53|+	"offline": { "color": "0 0 0",       "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|  56|  56| 
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  50|  50| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|    |-	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    |  53|+	"offline":   { "color": "0 0 0", "status": translate("Offline") },
|  54|  54| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|  56|  56| 
|    | [NORMAL] ESLintBear (key-spacing):
|    | Extra space before value for key 'unknown'.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|  51|  51| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  52|  52| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  53|  53| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  54|    |-	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|    |  54|+	"unknown": { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  55|  55| };
|  56|  56| 
|  57|  57| var g_RoleNames = {
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 5 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 219| 219| 					me ?
| 220| 220| 						translate("You have been muted.") :
| 221| 221| 						translate("%(nick)s has been muted.") :
| 222|    |-				newrole == "moderator" ?
|    | 222|+					newrole == "moderator" ?
| 223| 223| 					me ?
| 224| 224| 						translate("You are now a moderator.") :
| 225| 225| 						translate("%(nick)s is now a moderator.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 220| 220| 						translate("You have been muted.") :
| 221| 221| 						translate("%(nick)s has been muted.") :
| 222| 222| 				newrole == "moderator" ?
| 223|    |-					me ?
|    | 223|+						me ?
| 224| 224| 						translate("You are now a moderator.") :
| 225| 225| 						translate("%(nick)s is now a moderator.") :
| 226| 226| 				msg.oldrole == "visitor" ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 221| 221| 						translate("%(nick)s has been muted.") :
| 222| 222| 				newrole == "moderator" ?
| 223| 223| 					me ?
| 224|    |-						translate("You are now a moderator.") :
|    | 224|+							translate("You are now a moderator.") :
| 225| 225| 						translate("%(nick)s is now a moderator.") :
| 226| 226| 				msg.oldrole == "visitor" ?
| 227| 227| 					me ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 222| 222| 				newrole == "moderator" ?
| 223| 223| 					me ?
| 224| 224| 						translate("You are now a moderator.") :
| 225|    |-						translate("%(nick)s is now a moderator.") :
|    | 225|+							translate("%(nick)s is now a moderator.") :
| 226| 226| 				msg.oldrole == "visitor" ?
| 227| 227| 					me ?
| 228| 228| 						translate("You have been unmuted.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 6 tabs but found 4.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 223| 223| 					me ?
| 224| 224| 						translate("You are now a moderator.") :
| 225| 225| 						translate("%(nick)s is now a moderator.") :
| 226|    |-				msg.oldrole == "visitor" ?
|    | 226|+						msg.oldrole == "visitor" ?
| 227| 227| 					me ?
| 228| 228| 						translate("You have been unmuted.") :
| 229| 229| 						translate("%(nick)s has been unmuted.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 224| 224| 						translate("You are now a moderator.") :
| 225| 225| 						translate("%(nick)s is now a moderator.") :
| 226| 226| 				msg.oldrole == "visitor" ?
| 227|    |-					me ?
|    | 227|+							me ?
| 228| 228| 						translate("You have been unmuted.") :
| 229| 229| 						translate("%(nick)s has been unmuted.") :
| 230| 230| 					me ?
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 225| 225| 						translate("%(nick)s is now a moderator.") :
| 226| 226| 				msg.oldrole == "visitor" ?
| 227| 227| 					me ?
| 228|    |-						translate("You have been unmuted.") :
|    | 228|+								translate("You have been unmuted.") :
| 229| 229| 						translate("%(nick)s has been unmuted.") :
| 230| 230| 					me ?
| 231| 231| 						translate("You are not a moderator anymore.") :
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 226| 226| 				msg.oldrole == "visitor" ?
| 227| 227| 					me ?
| 228| 228| 						translate("You have been unmuted.") :
| 229|    |-						translate("%(nick)s has been unmuted.") :
|    | 229|+								translate("%(nick)s has been unmuted.") :
| 230| 230| 					me ?
| 231| 231| 						translate("You are not a moderator anymore.") :
| 232| 232| 						translate("%(nick)s is not a moderator anymore.");
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 7 tabs but found 5.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 227| 227| 					me ?
| 228| 228| 						translate("You have been unmuted.") :
| 229| 229| 						translate("%(nick)s has been unmuted.") :
| 230|    |-					me ?
|    | 230|+							me ?
| 231| 231| 						translate("You are not a moderator anymore.") :
| 232| 232| 						translate("%(nick)s is not a moderator anymore.");
| 233| 233| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 228| 228| 						translate("You have been unmuted.") :
| 229| 229| 						translate("%(nick)s has been unmuted.") :
| 230| 230| 					me ?
| 231|    |-						translate("You are not a moderator anymore.") :
|    | 231|+								translate("You are not a moderator anymore.") :
| 232| 232| 						translate("%(nick)s is not a moderator anymore.");
| 233| 233| 
| 234| 234| 			addChatMessage({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 8 tabs but found 6.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/lobby/lobby.js
| 229| 229| 						translate("%(nick)s has been unmuted.") :
| 230| 230| 					me ?
| 231| 231| 						translate("You are not a moderator anymore.") :
| 232|    |-						translate("%(nick)s is not a moderator anymore.");
|    | 232|+								translate("%(nick)s is not a moderator anymore.");
| 233| 233| 
| 234| 234| 			addChatMessage({
| 235| 235| 				"text": "/special " + sprintf(txt, { "nick": msg.nick }),

binaries/data/mods/public/gui/lobby/lobby.js
|1028| »   »   switch·(sortBy)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/lobby/lobby.js
|1288| »   while·(true)
|    | [NORMAL] ESLintBear (no-constant-condition):
|    | Unexpected constant condition.

binaries/data/mods/public/gui/lobby/lobby.js
| 729| »   »   case·'name':
|    | [NORMAL] JSHintBear:
|    | Expected a 'break' statement before 'default'.

Link to build: https://jenkins.wildfiregames.com/job/differential/540/display/redirect

Imarok requested changes to this revision.May 21 2018, 11:04 PM

This breaks the version check.

Engine.GetEngineInfo returns an empty version field.

This revision now requires changes to proceed.May 21 2018, 11:04 PM
elexis added a comment.EditedMay 22 2018, 3:29 AM

something like that although it doesn't work yet at all, needs a different scriptinterface when started in nonvisual mode, missing comments and motivation, unneeded include and moved something unrelated which gave me pain while reading.

Edit: Just the ParseJSON call itself warrant this being cached in C++ even if the VFS is lightning fast.

Edit 2: Calling the function currently consumes 170ms. Multiply with 25 games in the lobby and you get +4 seconds frezee. That is called every few seconds in the lobby.

wraitii updated this revision to Diff 6615.May 22 2018, 7:40 AM

Alternative patch with C++ caching.

Since we only ever mount mods in MountMods(), we should cache it there. I keep the vector because there's a useful distinction between mods we want to load (set by JS for example) and mods we actually loaded.

Note that this doesn't work for two reasons, which I need comments on:

  • Distinguishing the mod.json thing may be tricky with mods that have no mods.json . I might work around this by checking for the very explicit path or even not using the vfs, but that's annoying
  • We don't have a script interface at that point in time so we can't parse JSON. Do we re-use a library to do this? Do we defer this? Do we special-case mod.json here?

Build failure - The Moirai have given mortals hearts that can endure.

Link to build: https://jenkins.wildfiregames.com/job/differential/545/display/redirect

wraitii updated this revision to Diff 6616.May 22 2018, 7:56 AM

VFS changes are un-necessary with the C++ caching. I still think they are correct, but probably for another diff.

Still doesn't work because of the above issue but I think this is the best fix we'll have at the moment.

Successful build - Chance fights ever on the side of the prudent.

Link to build: https://jenkins.wildfiregames.com/job/differential/546/display/redirect

Imarok added inline comments.May 22 2018, 9:11 AM
source/ps/scripting/JSInterface_Mod.cpp
60 ↗(On Diff #6616)

modmod is crying.
(You should test the mod selector when changing things with mod loading)

wraitii added inline comments.May 22 2018, 9:19 AM
source/ps/scripting/JSInterface_Mod.cpp
60 ↗(On Diff #6616)

Ack, I did forget that. The existence of this function now makes sense, but it really shouldn't be used in GetEngineInfo.

wraitii planned changes to this revision.May 22 2018, 9:19 AM
elexis added inline comments.May 22 2018, 9:47 AM
source/ps/GameSetup/GameSetup.cpp
417

You cant parse JSON without a spidermonkey context because the result needs to be allocated somewhere and is a JS value

source/ps/Mod.cpp
33

g_M if already changed

wraitii added inline comments.May 22 2018, 10:15 AM
source/ps/GameSetup/GameSetup.cpp
417

We could if we had a library to do it.

elexis added inline comments.May 22 2018, 10:15 AM
source/ps/GameSetup/GameSetup.cpp
417

How are you going to save a JS value without JS?

wraitii added inline comments.May 22 2018, 12:10 PM
source/ps/GameSetup/GameSetup.cpp
417

I don't need a Js value, I want the version string here.

elexis added inline comments.May 22 2018, 12:18 PM
source/ps/GameSetup/GameSetup.cpp
417

In C++ you need a type before you can read from it. A JS C++ library that doesn't parse all possible JSON strings is not a JS library.
Also we do have a library for reading JS values, we probably don't need to add a second one if we can just add one more line at the right place.

I'm currently trying to just create a new scriptinterface, but the g_ScriptRuntime isn't initialized when InitVFS is called yet too, so it's kind of a dead end.
Only caching the the JS Interface which is only called from the JS GUI might be an alternative, but I didn't give in yet.

wraitii added inline comments.May 22 2018, 12:27 PM
source/ps/GameSetup/GameSetup.cpp
417

Sorry I feel like there's a misunderstanding here. I don't need a "JS Library", I just need something that parses JSON into something usable by C++, so that I can use the mod version and put it in my C++ thingy.

library for reading JS values

Are you referring to Spidermonkey? I feel like initialising a spider monkey runtime just for parsing "mod.json" to C++ is extremely overkill.

We could initialise Spidermonkey at the very startup, and use it instead, but that feels like a bit of an anti-pattern.


My approach is to parse mod.json in C++ without relying on the JS runtime.

elexis added inline comments.May 22 2018, 12:42 PM
source/ps/GameSetup/GameSetup.cpp
417

JSON = JavaScript Object Notation and it can hold any natively serializable JS object.

I feel like initialising a spider monkey runtime just for parsing "mod.json" to C++ is extremely overkill.

Importing a new library seems more lightweight?
I didn't suggest to create a new Runtime, only a new ScriptInterface

We could initialise Spidermonkey at the very startup, and use it instead, but that feels like a bit of an anti-pattern.

Not sure what you mean with anti-pattern here. Initializing one thing before the other before using it seems right.
Making the mod mounting code that currently doesn't depend on SM depend on SM seems like an anti-pattern maybe ("dependency hell") maybe.
But the greater problem that prevents us from doing so is that there is a code comment stating that VFS should be initialized before anything else, which we probably don't want to play with. But that isn't the more attractive of the proposed alternatives to explore anyway. I'll post some new brokenwipdiff or better later hopefully.

My approach is to parse mod.json in C++ without relying on the JS runtime.

I don't feel understood. As I said, think about the data structures that are required to hold any JS object that can be expressed in JSON.
It will require you to use a JS data type.
So you either have to propose adding a new library that can hold JS objects, use an existing library that can hold JS objects or you write your own mod.json parser that parses each character individually.

Could we just do a small and quick fix (common js only cache) for A23 and think about the approptiate fix for A24 after the rerelease?

(Also does this diff still preserve the load order of the mods?)

source/ps/Mod.cpp
125

modsMounted.second == "user" -> first?

In D1512#61928, @Imarok wrote:

Could we just do a small and quick fix (common js only cache) for A23 and think about the approptiate fix for A24 after the rerelease?

Committing something without knowing what investigating the situation prior to the commit is not happening with my agreement and the matter is not hard to understand.

wraitii added a comment.EditedMay 22 2018, 12:56 PM

@elexis : I don't really understand why you treat JSON as only the "way to natively store JS value", I see it more as a random document storing method, like XML. But whatever. Maybe this isn't the best approach but it seemed clean enough.
I believe initialising spider monkey could be done independently from VFS which is a very 0 A.D. thing so that sounds safe, but we'll have to see.

In D1512#61928, @Imarok wrote:

(Also does this diff still preserve the load order of the mods?)

Should be checked, but this makes me realise that this code is messier than I thought.

Imarok added a comment.EditedMay 22 2018, 12:58 PM
In D1512#61930, @elexis wrote:
In D1512#61928, @Imarok wrote:

Could we just do a small and quick fix (common js only cache) for A23 and think about the approptiate fix for A24 after the rerelease?

Committing something without knowing what investigating the situation prior to the commit is not happening with my agreement and the matter is not hard to understand.

Sorry I cannot parse this sentence...
(Maybe there is something missing, e.g. a verb?)

In D1512#61930, @elexis wrote:
In D1512#61928, @Imarok wrote:

Could we just do a small and quick fix (common js only cache) for A23 and think about the approptiate fix for A24 after the rerelease?

Committing something without knowing what investigating the situation prior to the commit is not happening with my agreement and the matter is not hard to understand.

We've identified the problems:

  • GetAvailableMods is very slow when using an archive. It takes about 3ms on my machine when not using an archive. This problem I had a patch for (see above).
  • Calling GetEngineInfo in the game loop is still slow, even on non-archive builds, as it could take 150-200ms it seems. For this you suggest C++ caching.

The issues are that:

  • This is a VFS change right on a re-release.
  • Caching this in C++ is not straightforward so far.

I think we have a pretty good handle on the problem, and we realise that properly fixing it is hard. I suggest doing the hotfix (JS caching), and then raising a concern about it until we fix things properly. Otherwise it'll take ages imo.

@elexis : I don't really understand why you treat JSON as only the "way to natively store JS value"

Not my treatment but it was a citation of the definition of what JSON is.

I see it more as a random document storing method, like XML. But whatever.

If you can store random documents then you need a data structure that can store random documents.
One can't store cars/giraffes/JSON values without a car/giraffe/JSON datatype in C++, so the datatype needs to come from somewhere.

Maybe this isn't the best approach but it seemed clean enough.

Which approach? The diff didn't implement the place in question. Specify how to implement parsing JSON without using spidermonkey or JS datatypes and it can be judged.
I don't understand the smiley button in phabricator, is there an overview of smiley choices somewhere?

I think we have a pretty good handle on the problem, and we realise that properly fixing it is hard. I suggest doing the hotfix (JS caching), and then raising a concern about it until we fix things properly. Otherwise it'll take ages imo.

I agree. I proposed a patch in P121.

In D1512#61875, @elexis wrote:

something like that although it doesn't work yet at all, needs a different scriptinterface when started in nonvisual mode, missing comments and motivation, unneeded include and moved something unrelated which gave me pain while reading.

That could work 👍

we realise that properly fixing it is hard

I have the impression that you two didn't even try.

I suggest doing the hotfix (JS caching), and then raising a concern about it until we fix things properly

I suggest to not commit something and raise a concern right after.
If you (plural) don't want to try to cut the problem at the root, do it with my disapproval.

wraitii added a comment.EditedMay 22 2018, 3:15 PM

Let's do it your way then, I'm not dying on this hill. Feel free to commandeer with your patch, otherwise I'll take it as a basis and carry on myself.

Let's do it your way then, I'm not dying on this hill. Feel free to commandeer with your patch, otherwise I'll take it as a basis and carry on myself.

In German we say: "der klügere gibt nach" ;)
(No offense in direction of elexis intended)

elexis commandeered this revision.May 22 2018, 4:37 PM
elexis added a reviewer: wraitii.

meh

elexis updated this revision to Diff 6620.May 22 2018, 4:39 PM

unfinished proof of concept

elexis planned changes to this revision.May 22 2018, 4:41 PM

Notice it's meh to first MountMods, do unrelated and SM inits, then cache the versions.
Hence might still miss a call somewhere.
Going to remove unneeded code, clean and proofread.

Successful build - Chance fights ever on the side of the prudent.

Link to build: https://jenkins.wildfiregames.com/job/differential/549/display/redirect

As a c++ caching method, this is probably the best, but obviously the question is "when to cache the data". I'm okay with once in Init like you've done, otherwise it should probably go in GetEngineInfo with an if of some kind.

As a c++ caching method, this is probably the best, but obviously the question is "when to cache the data". I'm okay with once in Init like you've done, otherwise it should probably go in GetEngineInfo with an if of some kind.

I thought about just in time caching too. But usually its better to have a deterministic load order, especially when there is a dependency on the load order.
Plus we would need a second variable that is true or false (or a pointer that might be null) to state if we cached already.
Plus, the cache needs to be reloaded when things changed, so it seems it won't become less code.
So the question is if the proposed approach would be the most maintainable shortest most benefitial approach in the long term under all circumstances.
The only malus I see here is the requirement that CacheEnabledModVersions needs to be called after MountMods.
Surface area for oversights (which the other approaches have too, just in other places).

Stan added a subscriber: Stan.May 22 2018, 5:13 PM
Stan added inline comments.
source/ps/Mod.cpp
122

Could probably be a range loop but I guess that's out of scope.

wraitii added a comment.EditedMay 22 2018, 5:20 PM

The mountMods prerequisite is a little awkward indeed.

I can see two fixes:

  • Moving the JS init earlier, so we can call this in MountMods directly - sounds doable but the wfs warning is a little daunting
  • Mounting Mods after the existing JS init. This sounds doable and might be cleaner.
Imarok added inline comments.May 22 2018, 6:56 PM
binaries/data/mods/public/art/textures/ui/global/icon/bubble.png
1

Ahm...

source/main.cpp
621

Why is this moved?

source/ps/GameSetup/GameSetup.cpp
444

Also needs a CacheEnabledModVersions call?

source/ps/Mod.cpp
122

Good idea

wraitii requested changes to this revision.May 22 2018, 7:07 PM

IMO OK once requested changes are done.

source/main.cpp
551

This needs to go in CReplayPlayer::Replay, the g_scriptRuntime isn't initialised at this point.

source/ps/GameSetup/GameSetup.cpp
444

It's actually done in Init below. The decoupling is annoying but necessary atm, I think this should be fixed later.

source/ps/GameSetup/GameSetup.h
36

Seems un-necessary.

source/ps/Mod.cpp
115

cleanup

139

delete

149

delete

elexis added inline comments.May 22 2018, 7:10 PM
binaries/data/mods/public/art/textures/ui/global/icon/bubble.png
1

(As I said "unfinished proof of concept" and marked planned changes.)

source/main.cpp
621

Defragmentation.


I hadn't tested it, see comment about now removing unrelated code.
I posted the proof of concept to provide counterevidence to the claims of this diff being harder or more time consuming than the JS proposals.

source/ps/GameSetup/GameSetup.h
36

(This is a leftover too in case someone was wondering)

source/ps/Mod.cpp
122

(Noticed too and implemented)

elexis abandoned this revision.EditedMay 23 2018, 11:21 AM

I'll post a clean one from scratch.

Edit: Primarily because the description is messed up and changing it would invalidate the comments below it!

source/main.cpp
551

(Refs unfinished proof of concept and planned changes)
To distance myself from others who only complain about your presence: Thank you for pointing this out. Here you were faster than me.

source/ps/GameSetup/GameSetup.cpp
444

The problem that there is no ScriptRuntime at this point was mentioned already Imarok, no?
If fixing means changing the init order to first initialize the ScriptRuntime and then the VFS, then maybe yes later if we are extremely careful.

source/ps/GameSetup/GameSetup.h
36

(I posted too slowly by some seconds..)

wraitii added inline comments.May 23 2018, 11:56 AM
source/ps/GameSetup/GameSetup.cpp
444

Agreed.