Any player can easily cheat on this game by changing the amount of cupcakes through the browser console. I wanted to know if there was a way to prevent the user from doing so. This is also posted on github.
var numberOfCupcakesDisplay = document.getElementById("numberOfCupcakes");
var cupcake = document.getElementById("cupcake");
function updateValues() {
numberOfCupcakesDisplay.innerHTML = amountOfCupcakes.toString();
//displays number of cupcakes to screen
document.getElementById("amountOfToasters").innerHTML = amountOfToasters.toString();
//displays number of toasters to screen
document.getElementById("toasterButton").innerHTML = "        " + Math.round(costOfToasters).toString() + " cc";
//changes cost of toaster every time it is bought by 110%
}
cupcake.addEventListener('webkitAnimationEnd', function(e){
e.preventDefault();
this.style.webkitAnimationName = '';
}, false);
function clickCupcake() {
++amountOfCupcakes;
cupcake.style.animation = "shiftCupcake";
cupcake.style.webkitAnimationName = "shiftCupcake";
}
updateValues();
Yeah!! As other answers mention it is IMPOSSIBLE to prevent users from changing the values from browser console. In other words, You are simply asking How to write JS code so that user can not debug it. You can always use some methods which make life hard for people who want to cheat on the game.
1.Obfuscate the code.
Look at these links for more information on obfuscation.
- SO: How to obfuscate Javascript
- Jsobfuscate.com
2.Do not store the game's control values in global variable.
Do not store control values in global variables. Instead define a class and have these variables as private to it So that user has to dig in deep in order to find out where to put the breakpoints.
3.Minify/Compress your javascripts.
Obfuscation more or less covers minification as well.
You cannot prevent this. The best you can do is minify the JS so it's harder for players to find the right values to change. In fact, you can't prevent this with any game or indeed application; the user's computer controls all of the information so they can do anything they want to it.
The only way to be secure against this is to do all of the processing on a server you control. Even though, players can lie about their input data (hence aimbotting or other hacks).
by changing the amount of cupcakes through the browser console
Well, technically you can prevent this by creating a new scope:
(function(){
var cupcakes = 10;
})();
console.log(cupcakes); // ReferenceError: cupcakes is not defined
But note that there are still ways to "cheat," even with this protection (i.e. edit the JS source code). And if you are sending the result to a server... well, that will be even harder if not impossible to secure, since you can easily send a simple HTTP request via XMLHttpRequest
.
There may actually be a way to reach your goal. But it depends on the game's logic.
If you can simulate the game on your server, you can generate random IDs for the cakes and when the game creates a new cake (on client), it would request an ID for it. Later when the cake is "destroyed", it would contact the server and provide it with the cake's ID. The final score is then computed on the server from the IDs it received.
This way you can track what was actually done by the user.
But an adversary can listen the network requests and determine the request for creating a new ID. The same way he can determine the request to tell the server this ID has been "destroyed".
If your game logic allows, you can e.g. tell the server to only generate one ID every 5 seconds or so. You can also mark as spoofed all results where all cakes were "destroyed" and none was missed (if the game is difficult enough).
So, it's still not 100% secure, but you might be able to reach a relatively high level of spoofing protection. On the other hand, it adds a lot of code complications and you must weigh the pros and cons.