Page MenuHomeWildfire Games

Filter lobby games by mod
ClosedPublic

Authored by Imarok on Sep 27 2017, 12:49 AM.

Details

Summary

Filters the lobby games by enabled mods.

Test Plan

Think about possible pitfalls. Test hosting with an enabled mod and looking into the lobby without that mod.

Diff Detail

Repository
rP 0 A.D. Public Repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

Imarok created this revision.Sep 27 2017, 12:49 AM
Owners added a subscriber: Restricted Owners Package.Sep 27 2017, 12:49 AM
elexis added a subscriber: elexis.Sep 27 2017, 1:06 AM

The games should be visible, so that we don't have 'ghost players' around. It should just show a message box informing the user that he can't join because of the mods.

We also need gamesetup/netserver/netclient support of mods, but thats not the scope of this ticket (there is another ticket for that).

Version number should be checked as well, since the mods can be updated very frequently. Guess that's wrong for replays and savegames too then.

We also have an URL field in the mod json file, would be great to advertize the URL that way to encourage people downloading the mod (and/or malware).

binaries/data/mods/public/gui/gamesetup/gamesetup.js
2382 ↗(On Diff #3779)

Extend the modding wiki page that a comma will break lobby support because we didn't use JSON encoding, or use JSON encoding.

Vulcan added a subscriber: Vulcan.Sep 27 2017, 1:36 AM

Build is green

Updating workspaces...
Updating bundled third-party dependencies...

FCollada/FCollada.cpp
FCollada/FColladaPlugin.cpp
FCollada/FCDocument/FCDAnimated.cpp
FCollada/FCDocument/FCDAnimationChannel.cpp
FCollada/FCDocument/FCDAnimationClip.cpp
FCollada/FCDocument/FCDAnimationClipTools.cpp
FCollada/FCDocument/FCDAnimation.cpp
FCollada/FCDocument/FCDAnimationCurve.cpp
FCollada/FCDocument/FCDAnimationCurveTools.cpp
FCollada/FCDocument/FCDAnimationKey.cpp
FCollada/FCDocument/FCDAnimationMultiCurve.cpp
FCollada/FCDocument/FCDAsset.cpp
FCollada/FCDocument/FCDCamera.cpp
FCollada/FCDocument/FCDController.cpp
FCollada/FCDocument/FCDControllerInstance.cpp
FCollada/FCDocument/FCDControllerTools.cpp
FCollada/FCDocument/FCDEffectCode.cpp
FCollada/FCDocument/FCDEffect.cpp
FCollada/FCDocument/FCDEffectParameter.cpp
FCollada/FCDocument/FCDEffectParameterFactory.cpp
FCollada/FCDocument/FCDEffectParameterSampler.cpp
FCollada/FCDocument/FCDEffectParameterSurface.cpp
FCollada/FCDocument/FCDEffectPass.cpp
FCollada/FCDocument/FCDEffectPassShader.cpp
FCollada/FCDocument/FCDEffectPassState.cpp
FCollada/FCDocument/FCDEffectProfile.cpp
FCollada/FCDocument/FCDEffectProfileFX.cpp
FCollada/FCDocument/FCDEffectStandard.cpp
FCollada/FCDocument/FCDEffectTechnique.cpp
FCollada/FCDocument/FCDEffectTools.cpp
FCollada/FCDocument/FCDEmitter.cpp
FCollada/FCDocument/FCDEmitterInstance.cpp
FCollada/FCDocument/FCDEmitterObject.cpp
FCollada/FCDocument/FCDEmitterParticle.cpp
FCollada/FCDocument/FCDEntity.cpp
FCollada/FCDocument/FCDEntityInstance.cpp
FCollada/FCDocument/FCDEntityReference.cpp
FCollada/FCDocument/FCDExternalReferenceManager.cpp
FCollada/FCDocument/FCDExtra.cpp
FCollada/FCDocument/FCDForceDeflector.cpp
FCollada/FCDocument/FCDForceDrag.cpp
FCollada/FCDocument/FCDForceField.cpp
FCollada/FCDocument/FCDForceGravity.cpp
FCollada/FCDocument/FCDForcePBomb.cpp
FCollada/FCDocument/FCDForceWind.cpp
FCollada/FCDocument/FCDGeometry.cpp
FCollada/FCDocument/FCDGeometryInstance.cpp
FCollada/FCDocument/FCDGeometryMesh.cpp
FCollada/FCDocument/FCDGeometryNURBSSurface.cpp
FCollada/FCDocument/FCDGeometryPolygons.cpp
FCollada/FCDocument/FCDGeometryPolygonsInput.cpp
FCollada/FCDocument/FCDGeometryPolygonsTools.cpp
FCollada/FCDocument/FCDGeometrySource.cpp
FCollada/FCDocument/FCDGeometrySpline.cpp
FCollada/FCDocument/FCDImage.cpp
FCollada/FCDocument/FCDLibrary.cpp
FCollada/FCDocument/FCDLight.cpp
FCollada/FCDocument/FCDLightTools.cpp
FCollada/FCDocument/FCDMaterial.cpp
FCollada/FCDocument/FCDMaterialInstance.cpp
FCollada/FCDocument/FCDMorphController.cpp
FCollada/FCDocument/FCDObject.cpp
FCollada/FCDocument/FCDObjectWithId.cpp
FCollada/FCDocument/FCDocument.cpp
FCollada/FCDocument/FCDocumentTools.cpp
FCollada/FCDocument/FCDParameterAnimatable.cpp
FCollada/FCDocument/FCDParticleModifier.cpp
FCollada/FCDocument/FCDPhysicsAnalyticalGeometry.cpp
FCollada/FCDocument/FCDPhysicsForceFieldInstance.cpp
FCollada/FCDocument/FCDPhysicsMaterial.cpp
FCollada/FCDocument/FCDPhysicsModel.cpp
FCollada/FCDocument/FCDPhysicsModelInstance.cpp
FCollada/FCDocument/FCDPhysicsRigidBody.cpp
FCollada/FCDocument/FCDPhysicsRigidBodyInstance.cpp
FCollada/FCDocument/FCDPhysicsRigidBodyParameters.cpp
FCollada/FCDocument/FCDPhysicsRigidConstraint.cpp
FCollada/FCDocument/FCDPhysicsRigidConstraintInstance.cpp
FCollada/FCDocument/FCDPhysicsScene.cpp
FCollada/FCDocument/FCDPhysicsShape.cpp
FCollada/FCDocument/FCDPlaceHolder.cpp
FCollada/FCDocument/FCDSceneNode.cpp
FCollada/FCDocument/FCDSceneNodeIterator.cpp
FCollada/FCDocument/FCDSceneNodeTools.cpp
FCollada/FCDocument/FCDSkinController.cpp
FCollada/FCDocument/FCDTargetedEntity.cpp
FCollada/FCDocument/FCDTexture.cpp
FCollada/FCDocument/FCDTransform.cpp
FCollada/FCDocument/FCDVersion.cpp
FCollada/FMath/FMAllocator.cpp
FCollada/FMath/FMAngleAxis.cpp
FCollada/FMath/FMColor.cpp
FCollada/FMath/FMInterpolation.cpp
FCollada/FMath/FMLookAt.cpp
FCollada/FMath/FMMatrix33.cpp
FCollada/FMath/FMMatrix44.cpp
FCollada/FMath/FMQuaternion.cpp
FCollada/FMath/FMRandom.cpp
FCollada/FMath/FMSkew.cpp
FCollada/FMath/FMVector3.cpp
FCollada/FMath/FMVolume.cpp
FCollada/FUtils/FUAssert.cpp
FCollada/FUtils/FUBase64.cpp
FCollada/FUtils/FUBoundingBox.cpp
FCollada/FUtils/FUBoundingSphere.cpp
FCollada/FUtils/FUCrc32.cpp
FCollada/FUtils/FUCriticalSection.cpp
FCollada/FUtils/FUDaeEnum.cpp
FCollada/FUtils/FUDateTime.cpp
FCollada/FUtils/FUDebug.cpp
FCollada/FUtils/FUError.cpp
FCollada/FUtils/FUErrorLog.cpp
FCollada/FUtils/FUFile.cpp
FCollada/FUtils/FUFileManager.cpp
FCollada/FUtils/FULogFile.cpp
FCollada/FUtils/FUObject.cpp
FCollada/FUtils/FUObjectType.cpp
FCollada/FUtils/FUParameter.cpp
FCollada/FUtils/FUParameterizable.cpp
FCollada/FUtils/FUPluginManager.cpp
FCollada/FUtils/FUSemaphore.cpp
FCollada/FUtils/FUStringBuilder.cpp
FCollada/FUtils/FUStringConversion.cpp
FCollada/FUtils/FUSynchronizableObject.cpp
FCollada/FUtils/FUThread.cpp
FCollada/FUtils/FUTracker.cpp
FCollada/FUtils/FUUniqueStringMap.cpp
FCollada/FUtils/FUUri.cpp
FCollada/FUtils/FUXmlDocument.cpp
FCollada/FUtils/FUXmlParser.cpp
FCollada/FUtils/FUXmlWriter.cpp
FColladaPlugins/FArchiveXML/FArchiveXML.cpp
FColladaPlugins/FArchiveXML/FAXAnimationExport.cpp
FColladaPlugins/FArchiveXML/FAXAnimationImport.cpp
FColladaPlugins/FArchiveXML/FAXCameraExport.cpp
FColladaPlugins/FArchiveXML/FAXCameraImport.cpp
FColladaPlugins/FArchiveXML/FAXColladaParser.cpp
FColladaPlugins/FArchiveXML/FAXColladaWriter.cpp
FColladaPlugins/FArchiveXML/FAXControllerExport.cpp
FColladaPlugins/FArchiveXML/FAXControllerImport.cpp
FColladaPlugins/FArchiveXML/FAXEmitterExport.cpp
FColladaPlugins/FArchiveXML/FAXEmitterImport.cpp
FColladaPlugins/FArchiveXML/FAXEntityExport.cpp
FColladaPlugins/FArchiveXML/FAXEntityImport.cpp
FColladaPlugins/FArchiveXML/FAXForceFieldExport.cpp
FColladaPlugins/FArchiveXML/FAXForceFieldImport.cpp
FColladaPlugins/FArchiveXML/FAXGeometryExport.cpp
FColladaPlugins/FArchiveXML/FAXGeometryImport.cpp
FColladaPlugins/FArchiveXML/FAXImportLinking.cpp
FColladaPlugins/FArchiveXML/FAXInstanceExport.cpp
FColladaPlugins/FArchiveXML/FAXInstanceImport.cpp
FColladaPlugins/FArchiveXML/FAXLightExport.cpp
FColladaPlugins/FArchiveXML/FAXLightImport.cpp
FColladaPlugins/FArchiveXML/FAXMaterialExport.cpp
FColladaPlugins/FArchiveXML/FAXMaterialImport.cpp
FColladaPlugins/FArchiveXML/FAXPhysicsExport.cpp
FColladaPlugins/FArchiveXML/FAXPhysicsImport.cpp
FColladaPlugins/FArchiveXML/FAXSceneExport.cpp
FColladaPlugins/FArchiveXML/FAXSceneImport.cpp
FCollada/FCollada.cpp
FCollada/FColladaPlugin.cpp
FCollada/FCDocument/FCDAnimated.cpp
FCollada/FCDocument/FCDAnimationChannel.cpp
FCollada/FCDocument/FCDAnimationClip.cpp
FCollada/FCDocument/FCDAnimationClipTools.cpp
FCollada/FCDocument/FCDAnimation.cpp
FCollada/FCDocument/FCDAnimationCurve.cpp
FCollada/FCDocument/FCDAnimationCurveTools.cpp
FCollada/FCDocument/FCDAnimationKey.cpp
FCollada/FCDocument/FCDAnimationMultiCurve.cpp
FCollada/FCDocument/FCDAsset.cpp
FCollada/FCDocument/FCDCamera.cpp
FCollada/FCDocument/FCDController.cpp
FCollada/FCDocument/FCDControllerInstance.cpp
FCollada/FCDocument/FCDControllerTools.cpp
FCollada/FCDocument/FCDEffectCode.cpp
FCollada/FCDocument/FCDEffect.cpp
FCollada/FCDocument/FCDEffectParameter.cpp
FCollada/FCDocument/FCDEffectParameterFactory.cpp
FCollada/FCDocument/FCDEffectParameterSampler.cpp
FCollada/FCDocument/FCDEffectParameterSurface.cpp
FCollada/FCDocument/FCDEffectPass.cpp
FCollada/FCDocument/FCDEffectPassShader.cpp
FCollada/FCDocument/FCDEffectPassState.cpp
FCollada/FCDocument/FCDEffectProfile.cpp
FCollada/FCDocument/FCDEffectProfileFX.cpp
FCollada/FCDocument/FCDEffectStandard.cpp
FCollada/FCDocument/FCDEffectTechnique.cpp
FCollada/FCDocument/FCDEffectTools.cpp
FCollada/FCDocument/FCDEmitter.cpp
FCollada/FCDocument/FCDEmitterInstance.cpp
FCollada/FCDocument/FCDEmitterObject.cpp
FCollada/FCDocument/FCDEmitterParticle.cpp
FCollada/FCDocument/FCDEntity.cpp
FCollada/FCDocument/FCDEntityInstance.cpp
FCollada/FCDocument/FCDEntityReference.cpp
FCollada/FCDocument/FCDExternalReferenceManager.cpp
FCollada/FCDocument/FCDExtra.cpp
FCollada/FCDocument/FCDForceDeflector.cpp
FCollada/FCDocument/FCDForceDrag.cpp
FCollada/FCDocument/FCDForceField.cpp
FCollada/FCDocument/FCDForceGravity.cpp
FCollada/FCDocument/FCDForcePBomb.cpp
FCollada/FCDocument/FCDForceWind.cpp
FCollada/FCDocument/FCDGeometry.cpp
FCollada/FCDocument/FCDGeometryInstance.cpp
FCollada/FCDocument/FCDGeometryMesh.cpp
FCollada/FCDocument/FCDGeometryNURBSSurface.cpp
FCollada/FCDocument/FCDGeometryPolygons.cpp
FCollada/FCDocument/FCDGeometryPolygonsInput.cpp
FCollada/FCDocument/FCDGeometryPolygonsTools.cpp
FCollada/FCDocument/FCDGeometrySource.cpp
FCollada/FCDocument/FCDGeometrySpline.cpp
FCollada/FCDocument/FCDImage.cpp
FCollada/FCDocument/FCDLibrary.cpp
FCollada/FCDocument/FCDLight.cpp
FCollada/FCDocument/FCDLightTools.cpp
FCollada/FCDocument/FCDMaterial.cpp
FCollada/FCDocument/FCDMaterialInstance.cpp
FCollada/FCDocument/FCDMorphController.cpp
FCollada/FCDocument/FCDObject.cpp
FCollada/FCDocument/FCDObjectWithId.cpp
FCollada/FCDocument/FCDocument.cpp
FCollada/FCDocument/FCDocumentTools.cpp
FCollada/FCDocument/FCDParameterAnimatable.cpp
FCollada/FCDocument/FCDParticleModifier.cpp
FCollada/FCDocument/FCDPhysicsAnalyticalGeometry.cpp
FCollada/FCDocument/FCDPhysicsForceFieldInstance.cpp
FCollada/FCDocument/FCDPhysicsMaterial.cpp
FCollada/FCDocument/FCDPhysicsModel.cpp
FCollada/FCDocument/FCDPhysicsModelInstance.cpp
FCollada/FCDocument/FCDPhysicsRigidBody.cpp
FCollada/FCDocument/FCDPhysicsRigidBodyInstance.cpp
FCollada/FCDocument/FCDPhysicsRigidBodyParameters.cpp
FCollada/FCDocument/FCDPhysicsRigidConstraint.cpp
FCollada/FCDocument/FCDPhysicsRigidConstraintInstance.cpp
FCollada/FCDocument/FCDPhysicsScene.cpp
FCollada/FCDocument/FCDPhysicsShape.cpp
FCollada/FCDocument/FCDPlaceHolder.cpp
FCollada/FCDocument/FCDSceneNode.cpp
FCollada/FCDocument/FCDSceneNodeIterator.cpp
FCollada/FCDocument/FCDSceneNodeTools.cpp
FCollada/FCDocument/FCDSkinController.cpp
FCollada/FCDocument/FCDTargetedEntity.cpp
FCollada/FCDocument/FCDTexture.cpp
FCollada

http://jenkins-master:8080/job/phabricator/2073/ for more details.

Executing section Default...
Executing section Source...
Executing section JS...
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/gui/lobby/lobby.js
|  41|  41|  * The playerlist will be assembled using these values.
|  42|  42|  */
|  43|  43| var g_PlayerStatuses = {
|  44|    |-	"available": { "color": "0 219 0",     "status": translate("Online") },
|    |  44|+	"available": { "color": "0 219 0", "status": translate("Online") },
|  45|  45| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  46|  46| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  47|  47| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/gui/lobby/lobby.js
|  42|  42|  */
|  43|  43| var g_PlayerStatuses = {
|  44|  44| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  45|    |-	"away":      { "color": "229 76 13",   "status": translate("Away") },
|    |  45|+	"away":      { "color": "229 76 13", "status": translate("Away") },
|  46|  46| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  47|  47| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  48|  48| 	"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/phabricator_lint/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/gui/lobby/lobby.js
|  43|  43| var g_PlayerStatuses = {
|  44|  44| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  45|  45| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  46|    |-	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|    |  46|+	"playing":   { "color": "200 0 0", "status": translate("Busy") },
|  47|  47| 	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|  48|  48| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  49|  49| };
|    | [NORMAL] ESLintBear (no-multi-spaces):
|    | Multiple spaces found before '"status"'.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/gui/lobby/lobby.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/gui/lobby/lobby.js
|  44|  44| 	"available": { "color": "0 219 0",     "status": translate("Online") },
|  45|  45| 	"away":      { "color": "229 76 13",   "status": translate("Away") },
|  46|  46| 	"playing":   { "color": "200 0 0",     "status": translate("Busy") },
|  47|    |-	"offline":   { "color": "0 0 0",       "status": translate("Offline") },
|    |  47|+	"offline":   { "color": "0 0 0", "status": translate("Offline") },
|  48|  48| 	"unknown":   { "color": "178 178 178", "status": translateWithContext("lobby presence", "Unknown") }
|  49|  49| };
|  50|  50| 

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

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

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

http://jenkins-master:8080/job/phabricator_lint/551/ for more details.

Imarok added a comment.Oct 9 2017, 4:00 PM
In D931#36454, @elexis wrote:

The games should be visible, so that we don't have 'ghost players' around. It should just show a message box informing the user that he can't join because of the mods.

Ack. (Will grey out the incompatible games)

Version number should be checked as well, since the mods can be updated very frequently. Guess that's wrong for replays and savegames too then.

yep, replays and savegames only check the engine version.
(Seems like there were plans: https://github.com/0ad/0ad/blob/34b42203179d9fa33c2fcbd6db387bff75611fef/source/ps/SavedGame.cpp#L36)

We also have an URL field in the mod json file, would be great to advertize the URL that way to encourage people downloading the mod (and/or malware).

not sure if that's a good idea...

elexis added a comment.Oct 9 2017, 4:53 PM
In D931#37178, @Imarok wrote:

I assume that this constant is for the savegame format itself, similar to the server protocol constants that we bump each time we bump the network protocol.
The version of a mod can change without the version of the savegame.

We also have an URL field in the mod json file, would be great to advertize the URL that way to encourage people downloading the mod (and/or malware).

not sure if that's a good idea...

Carrying the URL will be a must-have, making it non-trivial to distribute malware is a must-have too.
I guess an "Are you sure you want to visit the website, we cannot guarantee external content to be safe" message box might be sufficient.

The version check should work for replays and savegames too, thus probably requiring a separate patch to do it clean.
But if we don't have the resources to accomplish that, just passing the mod name would already be a tremendous benefit, so that the host doesn't have to ban unknown accounts preemptively to avoid OOS errors.

Imarok added a comment.Oct 9 2017, 4:56 PM
In D931#37190, @elexis wrote:
In D931#37178, @Imarok wrote:

I assume that this constant is for the savegame format itself, similar to the server protocol constants that we bump each time we bump the network protocol.
The version of a mod can change without the version of the savegame.

Oh, that could be true.

We also have an URL field in the mod json file, would be great to advertize the URL that way to encourage people downloading the mod (and/or malware).

not sure if that's a good idea...

Carrying the URL will be a must-have, making it non-trivial to distribute malware is a must-have too.
I guess an "Are you sure you want to visit the website, we cannot guarantee external content to be safe" message box might be sufficient.

The version check should work for replays and savegames too, thus probably requiring a separate patch to do it clean.

Already on that.

But if we don't have the resources to accomplish that, just passing the mod name would already be a tremendous benefit, so that the host doesn't have to ban unknown accounts preemptively to avoid OOS errors.

Imarok updated this revision to Diff 3976.Oct 25 2017, 10:25 PM

Show incompatible games in gray. Move them to the bottom of the list. Add a Dialog informing users that try to join. Transmit the mod list separated by , instead of , to allow commas in mod names.

Imarok retitled this revision from [RFC]Filter lobby games by mod to Filter lobby games by mod.Oct 25 2017, 10:26 PM
Imarok marked an inline comment as done.

Build is green

Updating workspaces...
Build (release)...
Build (debug)...
Running release tests...
Running cxxtest tests (307 tests)...................................................................................................................................................................................................................................................................................................................OK!
Running debug tests...
Running cxxtest tests (307 tests)...................................................................................................................................................................................................................................................................................................................OK!
Checking XML files...

http://jenkins-master:8080/job/phabricator/2165/ for more details.

Executing section Default...
Executing section Source...
Executing section JS...

binaries/data/mods/public/gui/lobby/lobby.js
| 500| »   if·(mapSizeFilter.selected·!=·0·&&
|    | [NORMAL] JSHintBear:
|    | Use '!==' to compare with '0'.

binaries/data/mods/public/gui/lobby/lobby.js
| 504| »   if·(playersNumberFilter.selected·!=·0·&&
|    | [NORMAL] JSHintBear:
|    | Use '!==' to compare with '0'.

binaries/data/mods/public/gui/lobby/lobby.js
| 508| »   if·(mapTypeFilter.selected·!=·0·&&
|    | [NORMAL] JSHintBear:
|    | Use '!==' to compare with '0'.

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

binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1666| »   if·(g_LoadingState·==·0)
|    | [NORMAL] JSHintBear:
|    | Use '===' to compare with '0'.
Executing section XML GUI...
|    | [INFO] XMLBear:
|    | XML can be formatted better.
|----|    | /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/gui/lobby/lobby.xml
|    |++++| /mnt/data/jenkins-phabricator/workspace/phabricator_lint/binaries/data/mods/public/gui/lobby/lobby.xml
|   1|   1| <?xml version="1.0" encoding="utf-8"?>
|   2|    |-
|   3|   2| <objects>
|   4|   3| 
|   5|   4| 	<script file="gui/common/color.js"/>

http://jenkins-master:8080/job/phabricator_lint/630/ for more details.

In D931#38362, @Imarok wrote:

Show incompatible games in gray. Move them to the bottom of the list. Add a Dialog informing users that try to join. Transmit the mod list separated by , instead of , to allow commas in mod names.

The internal mod name (which is used to identify mods) is meant to be simple to parse, so just update the docs, and possibly add a check to the mod manager that this only consists of A-Za-z_0-9 and call it done.

elexis requested changes to this revision.Dec 4 2017, 8:10 PM

Set of mods is just 50%, the other 50% are the versions of the mods. That should be transported equally in the replays, savegames and lobby IMO (D955). Also here I think it should be sufficient to post only one instead of two objects { modname: modversion, ... }

In D1093 there is a validation function proposed (which might or might not be of use here too), and that modID names are restricted to alphanumeric characters.

binaries/data/mods/public/gui/gamesetup/gamesetup.js
2382 ↗(On Diff #3779)

agree with leper, only ,

binaries/data/mods/public/gui/lobby/lobby.js
1105 ↗(On Diff #3976)

I'd love to see this unified with the savegame checks. Could be abstracted to gui/common/, maybe even in mod instead of public.

This revision now requires changes to proceed.Dec 4 2017, 8:10 PM

To add the version check, most lines of the code will have to be changed again, so this should only be committed as a defect fix before translation freeze in case we don't get ourselves to commit the version with the version check.

binaries/data/mods/public/gui/lobby/lobby.js
1105 ↗(On Diff #3976)

Not every dream comes true immediately

binaries/data/mods/public/gui/lobby/lobby.xml
12 ↗(On Diff #3976)

How old is that patch?

Imarok marked an inline comment as done.Feb 17 2018, 7:02 PM
Imarok added inline comments.
binaries/data/mods/public/gui/lobby/lobby.xml
12 ↗(On Diff #3976)

How old is that patch?

Old enough :D

Imarok updated this revision to Diff 5820.Feb 17 2018, 9:23 PM
Imarok marked an inline comment as done.

Rebase upon D955's commit

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-trailing-spaces):
|    | Trailing spaces not allowed.
|----|    | /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
|   9|   9| const g_MapTypes = prepareForDropdown(g_Settings && g_Settings.MapTypes);
|  10|  10| 
|  11|  11| /**
|  12|    |- *  Used for civ settings display of the selected game. 
|    |  12|+ *  Used for civ settings display of the selected game.
|  13|  13|  */
|  14|  14| const g_CivData = loadCivData(false, false);
|  15|  15| 
|    | [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
|1026| »   »   switch·(sortBy)
|    | [NORMAL] ESLintBear (default-case):
|    | Expected a default case.

binaries/data/mods/public/gui/lobby/lobby.js
|1279| »   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'.
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  53|  53| var g_RomanNumbers = [undefined, "I", "II", "III", "IV", "V", "VI", "VII", "VIII"];
|  54|  54| 
|  55|  55| var g_PlayerTeamList = prepareForDropdown([{
|  56|    |-		"label": translateWithContext("team", "None"),
|    |  56|+	"label": translateWithContext("team", "None"),
|  57|  57| 		"id": -1
|  58|  58| 	}].concat(
|  59|  59| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  54|  54| 
|  55|  55| var g_PlayerTeamList = prepareForDropdown([{
|  56|  56| 		"label": translateWithContext("team", "None"),
|  57|    |-		"id": -1
|    |  57|+	"id": -1
|  58|  58| 	}].concat(
|  59|  59| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  60|  60| 			"label": i + 1,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  55|  55| var g_PlayerTeamList = prepareForDropdown([{
|  56|  56| 		"label": translateWithContext("team", "None"),
|  57|  57| 		"id": -1
|  58|    |-	}].concat(
|    |  58|+}].concat(
|  59|  59| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  60|  60| 			"label": i + 1,
|  61|  61| 			"id": i
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  56|  56| 		"label": translateWithContext("team", "None"),
|  57|  57| 		"id": -1
|  58|  58| 	}].concat(
|  59|    |-		Array(g_MaxTeams).fill(0).map((v, i) => ({
|    |  59|+	Array(g_MaxTeams).fill(0).map((v, i) => ({
|  60|  60| 			"label": i + 1,
|  61|  61| 			"id": i
|  62|  62| 		}))
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  57|  57| 		"id": -1
|  58|  58| 	}].concat(
|  59|  59| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  60|    |-			"label": i + 1,
|    |  60|+		"label": i + 1,
|  61|  61| 			"id": i
|  62|  62| 		}))
|  63|  63| 	)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  58|  58| 	}].concat(
|  59|  59| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  60|  60| 			"label": i + 1,
|  61|    |-			"id": i
|    |  61|+		"id": i
|  62|  62| 		}))
|  63|  63| 	)
|  64|  64| );
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  59|  59| 		Array(g_MaxTeams).fill(0).map((v, i) => ({
|  60|  60| 			"label": i + 1,
|  61|  61| 			"id": i
|  62|    |-		}))
|    |  62|+	}))
|  63|  63| 	)
|  64|  64| );
|  65|  65| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  60|  60| 			"label": i + 1,
|  61|  61| 			"id": i
|  62|  62| 		}))
|  63|    |-	)
|    |  63|+)
|  64|  64| );
|  65|  65| 
|  66|  66| /**
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  69|  69| var g_RelicCountList = Object.keys(g_CivData).map((civ, i) => i + 1);
|  70|  70| 
|  71|  71| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  72|    |-		"name": translateWithContext("civilization", "Random"),
|    |  72|+	"name": translateWithContext("civilization", "Random"),
|  73|  73| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  74|  74| 		"color": g_ColorRandom,
|  75|  75| 		"code": "random"
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  70|  70| 
|  71|  71| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  72|  72| 		"name": translateWithContext("civilization", "Random"),
|  73|    |-		"tooltip": translate("Picks one civilization at random when the game starts."),
|    |  73|+	"tooltip": translate("Picks one civilization at random when the game starts."),
|  74|  74| 		"color": g_ColorRandom,
|  75|  75| 		"code": "random"
|  76|  76| 	}].concat(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  71|  71| var g_PlayerCivList = g_CivData && prepareForDropdown([{
|  72|  72| 		"name": translateWithContext("civilization", "Random"),
|  73|  73| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  74|    |-		"color": g_ColorRandom,
|    |  74|+	"color": g_ColorRandom,
|  75|  75| 		"code": "random"
|  76|  76| 	}].concat(
|  77|  77| 		Object.keys(g_CivData).filter(
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  72|  72| 		"name": translateWithContext("civilization", "Random"),
|  73|  73| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  74|  74| 		"color": g_ColorRandom,
|  75|    |-		"code": "random"
|    |  75|+	"code": "random"
|  76|  76| 	}].concat(
|  77|  77| 		Object.keys(g_CivData).filter(
|  78|  78| 			civ => g_CivData[civ].SelectableInGameSetup
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  73|  73| 		"tooltip": translate("Picks one civilization at random when the game starts."),
|  74|  74| 		"color": g_ColorRandom,
|  75|  75| 		"code": "random"
|  76|    |-	}].concat(
|    |  76|+}].concat(
|  77|  77| 		Object.keys(g_CivData).filter(
|  78|  78| 			civ => g_CivData[civ].SelectableInGameSetup
|  79|  79| 		).map(civ => ({
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  74|  74| 		"color": g_ColorRandom,
|  75|  75| 		"code": "random"
|  76|  76| 	}].concat(
|  77|    |-		Object.keys(g_CivData).filter(
|    |  77|+	Object.keys(g_CivData).filter(
|  78|  78| 			civ => g_CivData[civ].SelectableInGameSetup
|  79|  79| 		).map(civ => ({
|  80|  80| 			"name": g_CivData[civ].Name,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  75|  75| 		"code": "random"
|  76|  76| 	}].concat(
|  77|  77| 		Object.keys(g_CivData).filter(
|  78|    |-			civ => g_CivData[civ].SelectableInGameSetup
|    |  78|+		civ => g_CivData[civ].SelectableInGameSetup
|  79|  79| 		).map(civ => ({
|  80|  80| 			"name": g_CivData[civ].Name,
|  81|  81| 			"tooltip": g_CivData[civ].History,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  76|  76| 	}].concat(
|  77|  77| 		Object.keys(g_CivData).filter(
|  78|  78| 			civ => g_CivData[civ].SelectableInGameSetup
|  79|    |-		).map(civ => ({
|    |  79|+	).map(civ => ({
|  80|  80| 			"name": g_CivData[civ].Name,
|  81|  81| 			"tooltip": g_CivData[civ].History,
|  82|  82| 			"color": g_ColorRegular,
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  77|  77| 		Object.keys(g_CivData).filter(
|  78|  78| 			civ => g_CivData[civ].SelectableInGameSetup
|  79|  79| 		).map(civ => ({
|  80|    |-			"name": g_CivData[civ].Name,
|    |  80|+		"name": g_CivData[civ].Name,
|  81|  81| 			"tooltip": g_CivData[civ].History,
|  82|  82| 			"color": g_ColorRegular,
|  83|  83| 			"code": civ
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  78|  78| 			civ => g_CivData[civ].SelectableInGameSetup
|  79|  79| 		).map(civ => ({
|  80|  80| 			"name": g_CivData[civ].Name,
|  81|    |-			"tooltip": g_CivData[civ].History,
|    |  81|+		"tooltip": g_CivData[civ].History,
|  82|  82| 			"color": g_ColorRegular,
|  83|  83| 			"code": civ
|  84|  84| 		})).sort(sortNameIgnoreCase)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  79|  79| 		).map(civ => ({
|  80|  80| 			"name": g_CivData[civ].Name,
|  81|  81| 			"tooltip": g_CivData[civ].History,
|  82|    |-			"color": g_ColorRegular,
|    |  82|+		"color": g_ColorRegular,
|  83|  83| 			"code": civ
|  84|  84| 		})).sort(sortNameIgnoreCase)
|  85|  85| 	)
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 2 tabs but found 3.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  80|  80| 			"name": g_CivData[civ].Name,
|  81|  81| 			"tooltip": g_CivData[civ].History,
|  82|  82| 			"color": g_ColorRegular,
|  83|    |-			"code": civ
|    |  83|+		"code": civ
|  84|  84| 		})).sort(sortNameIgnoreCase)
|  85|  85| 	)
|  86|  86| );
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 1 tab but found 2.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  81|  81| 			"tooltip": g_CivData[civ].History,
|  82|  82| 			"color": g_ColorRegular,
|  83|  83| 			"code": civ
|  84|    |-		})).sort(sortNameIgnoreCase)
|    |  84|+	})).sort(sortNameIgnoreCase)
|  85|  85| 	)
|  86|  86| );
|  87|  87| 
|    | [NORMAL] ESLintBear (indent):
|    | Expected indentation of 0 tabs but found 1.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|  82|  82| 			"color": g_ColorRegular,
|  83|  83| 			"code": civ
|  84|  84| 		})).sort(sortNameIgnoreCase)
|  85|    |-	)
|    |  85|+)
|  86|  86| );
|  87|  87| 
|  88|  88| /**
|    | [NORMAL] ESLintBear (semi):
|    | Missing semicolon.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1024|1024| 			let spTips = Engine.GetGUIObjectByName("spTips");
|1025|1025| 			return g_IsNetworked ||
|1026|1026| 				Engine.ConfigDB_GetValue("user", "gui.gamesetup.enabletips") !== "true" ||
|1027|    |-				spTips.size.right > settingsPanel.getComputedSize().left
|    |1027|+				spTips.size.right > settingsPanel.getComputedSize().left;
|1028|1028| 		}
|1029|1029| 	}
|1030|1030| };
|    | [NORMAL] ESLintBear (curly):
|    | Unnecessary { after 'if' condition.
|----|    | /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|    |++++| /mnt/data/jenkins-phabricator/workspace/differential/binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1698|1698| 	let biomeList;
|1699|1699| 
|1700|1700| 	if (g_GameAttributes.mapType == "random" && g_GameAttributes.settings.SupportedBiomes)
|1701|    |-	{
|    |1701|+	
|1702|1702| 		if (typeof g_GameAttributes.settings.SupportedBiomes == "string")
|1703|1703| 			biomeList = g_Settings.Biomes.filter(biome => biome.Id.startsWith(g_GameAttributes.settings.SupportedBiomes));
|1704|1704| 		else
|1705|1705| 			biomeList = g_Settings.Biomes.filter(
|1706|1706| 				biome => g_GameAttributes.settings.SupportedBiomes.indexOf(biome.Id) != -1);
|1707|    |-	}
|    |1707|+	
|1708|1708| 
|1709|1709| 	g_BiomeList = biomeList && prepareForDropdown(
|1710|1710| 		[{

binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1929| »   while·(g_IsNetworked)
|    | [NORMAL] ESLintBear (no-unmodified-loop-condition):
|    | 'g_IsNetworked' is not modified in this loop.

binaries/data/mods/public/gui/gamesetup/gamesetup.js
|1027| »   »   »   »   spTips.size.right·>·settingsPanel.getComputedSize().left
|    | [NORMAL] JSHintBear:
|    | Missing semicolon.

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

elexis accepted this revision.Feb 19 2018, 5:22 PM

Very happy to see this in alpha 23 if the message box is changed (and if you test it before committing again).

Again, would be nice to

  • display the mods in the gameselection if the game is incompatible
  • display the url of the mod (moderation should ensure that there isn't crap advertized)
  • add a compatibility checkbox if we can afford the screenspace
binaries/data/mods/public/gui/lobby/lobby.js
1180 ↗(On Diff #5820)

s/that/this

1182 ↗(On Diff #5820)

I'm not confident that we want to ask this question, considering that people are willing to not care about warnings, then trigger an OOS and people will be annoyed.
Maybe the long-term goal is to allow people to join with mods that don't change the simulation state, but I'd feel better to either make that a host choice whether to deny invalid modders or add a flag to the mod.json stating if it changes the simstate.
So I'd prefer to delete the question string and make that an "Ok I give up" dialog.

This revision is now accepted and ready to land.Feb 19 2018, 5:22 PM
Imarok marked 2 inline comments as done.Feb 21 2018, 6:22 PM
Imarok added inline comments.
binaries/data/mods/public/gui/lobby/lobby.js
1182 ↗(On Diff #5820)

Ack

This revision was automatically updated to reflect the committed changes.
Imarok marked an inline comment as done.