HomeWildfire Games

Add spying to the game
Concern RaisedrP19247

Description

Add spying to the game
Summary:
With https://code.wildfiregames.com/rP19175 we can now add spying into the game: you have first to research a tech (available in phase 3, espionage), and then you can bribe a random unit (defined as Bribable in its template) from a chosen player and share its vision during 15s.
There is also an option in the gamesetup to disable this feature, analoguous to the treasure disabling option.
In the current version, only traders (land and naval ones) are bribables.
Reviewed By: Itms, elexis
Differential Revision: https://code.wildfiregames.com/D117

Details

Auditors
elexis
Committed
mimoFeb 27 2017, 7:17 PM
Reviewer
Itms
Differential Revision
D117: Add spying to the game
Parents
rP19246: [i18n] Updated POT and PO files.
Branches
Unknown
Tags
Unknown
Build Status
Buildable 609
Build 963: Post-Commit BuildJenkins

Event Timeline

elexis raised a concern with this commit.Oct 9 2019, 8:31 PM
elexis added a subscriber: elexis.
elexis added inline comments.
/ps/trunk/binaries/data/mods/public/gui/session/menu.js
465

refs "source": g_ViewedPlayer

517

Concern: This is an 'exploitable' simulation bug.

I didn't notice during the review that source": g_ViewedPlayer should not be part of the sent information, because it allows the player to send a command with a different playerID.

But both networking and simulation code is otherwise written in such a way that it is impossible to send commands for other players if cheats are disabled. (See also https://trac.wildfiregames.com/wiki/SimulationRequirements#Cheatprevention)

When Commands.js processes this simulation command, the playerID of the command sender is already known without it having to be voluntarily sent by the client (and the spy code uses the sender playerID too, just in one line it uses the "source" player).

It looks like it was copied from the attack-request command, which has the same issue, refs rP16533.

Reproduce "exploit":

  1. Find a player that has trade carts
  2. Pick a victim (for example an enemy) that researched the spy technology
  3. Open the JS console with F9
  4. Type Engine.PostNetworkCommand({"source":3,"type":"spy-request","player":4}); where 3 is the victim and 4 is the player with trade carts.

Result: The victim has paid for a spy but never ordered one and lost that amount of metal. Can be repeated arbitrarily.

Here a sample alpha23 replay where the "exploit" was reproduced:

/ps/trunk/binaries/data/mods/public/simulation/helpers/Commands.js
760

cmd.source is intended to be identical to player, if a player would modify it to be different, it would be either a bug or undocumented feature (buying a spy rewarding a different player which might not even be an ally).

764

(This probably correctly used player instead of cmd.source due to copying it from / consistency with the other calls)

This commit now has outstanding concerns.Oct 9 2019, 8:31 PM
elexis added a comment.EditedOct 10 2019, 3:32 PM

Another concern:
It is possible to use the spies feature without having researched LOS by enabling the button or sending the command via JS terminal (F9), since the GUI but not the simulation checks for it. (Edit: its possible to bribe spies of allies after having researched shared vision)

If it was a required-tech in the simulation, then the GUI doesnt have to hardcode a hasSharedLos check that can be circumvented by the player arbitrarily (https://trac.wildfiregames.com/wiki/SimulationRequirements#Cheatprevention).
(The required tech tooltip would then also show the has shared los tech in the tooltip, if that requirements parsing / tooltip code wouldnt lack supporting that as well)

The "Espionage" technology could be considered to have the the "Cartography" technology removed as a requirement:

"tooltip": "See what your allies see, browse their summary and check their resources and population count in the top panel.",
"description": "By means of trading and travelling people explored beyond the boundaries of their lands and drew maps of it in order to share and memorize their discoveries.",

Otherwise the "Espionage" tooltip should be updated:

"description": "Merchants' first goal was trading, but they also gathered information about the countries they crossed.",
"tooltip": "Allows bribing the units of other players in order to share their vision.",

(But since thats a gameplay design question, I can only think of the fact that 900 metal is a very high prize for very little information in return, in particular in comparison to what cavalry costs and returns in investment.
I remember it was said that it's about historic accuracy that not every unit can be bribed, but is it also historically accurate that the information that was obtained was what a random trader sees on his tours between two cities, not rather strategic valuable information?

As it stood and stands the feature is only useful in case the enemy is fully walled and one has several thousands of metal in the bank and no more techs to research, no more metal units to train (i.e. hour long turtle games, which may be a legitimate use case).
Whatever, I'll fix the GUI code when I can.)

/ps/trunk/binaries/data/mods/public/gui/session/menu.js
341

This function is not called on every onTick call, but updated on selection change and on simulation state change.

The buttons need to be updated on simulationstate change if they should respond to it,
for example if the player had been defeated, then the buttons should become disabled to reflect the simulation state not allowing to send further tributes, displaying the same state as when the page was opened.

elexis added a comment.EditedOct 10 2019, 3:42 PM

False alert for the last comment, can't read, its only hiding the button for allies after seeing their units anyway.
In that case the simulation coulr or should in theory still refuse it for allies after having researched the tech, at least the simulation code usually does check strictly.

Edit 2: I forgot the cost was reduced to 500 metal in rP19357, but doesnt necessarily change the point that the return value. (The feature should be powerful, so it shouldn't be cheap.)