Jump to content

Easy Cheating? Changing Game States Inside the Console


jamespierce
 Share

Recommended Posts

I would like to prevent players from switching to any game state by typing "game.state.start('name');" into the console. Has anyone found a way to prevent this from happening? Imagine you have a login-screen and any user can just type "game.state.start('play');" into the console and skip straight into the game.

I have already tried using anonymous functions and closures but the problem is that the other states such as BootState, MenuState, GameState etc cannot access the game object created from new Phaser.game. I cannot be the only one who's worried that users can simply skip any game state by typing one line into the console. How have others dealt with this security breach? I tried googling but couldn't find any posts about this whatsoever.

Thanks in advance for all answers!

Link to comment
Share on other sites

I guess I should have done more coding myself and less googling, I got an idea to solve it:

I suppose we cannot prevent users from changing game states from inside the console but through prototyping we can have functions in all the game states that are NOT accessible from within the console. So setting a variable in the game states to check that a user has properly arrived in this game state and re-directing the user back to the previous state if the check-variable is not set might be a possible way to prevent skipping game states.

I will test it out update this post.

Link to comment
Share on other sites

Okay it was very easy to test actually, here is a simple check:

login.js:

var loginState = function() {};
loginState.prototype = {
    login: function() {
        var safeState = true;
        game.state.start('menu', true, false, safeState);
    }
};

menu.js:

var menuState = function() {};

menuState.prototype = {
    init: function(safeState) {
        if(typeof(safeState) == 'undefined' || safeState != true) {
            game.state.start('login');
        }
    }
};

With the game.state.start() method we can send parameters to the next game state (see Phaser doc: link here). We can then access these parameters in the init method of the new game state.

In the example above, we simply create a variable "safeState" which we set to true when calling the "login" method. In the following menuState we check if the "safeState" variable is set or not, and also if it is set to true. Else we redirect back to the loginState.

By the way, this only works if you prototype the game state function, else you can just execute the method "loginState.login()" from the console again and the check becomes useless.

You can test it out now, it is not possible to skip game states in the console anymore. You can execute the method game.state.start()  in the console but you will be redirected back to where you are supposed to be.

Okay sorry for opening this thread I guess I jumped a bit too fast on the forum. However, maybe somebody has a better way of handling this issue? Else admins feel free to close this thread.

Link to comment
Share on other sites

This is a interesting topic, but I am going to say since the game is on the client, most of these situations can always be bypassed by adding/changing code.

If you ran the game on the server and only used the client for the visuals, you could reduce hacking a lot.

Link to comment
Share on other sites

Yes you can stop them, just stop declaring globals variables (its not a terrible idea, but its almost always best avoided, outside of dev anyway). This doesn't stop all cheating of course, but it solves your immediate issue/s.

Use a proper module system or hack a simple one yourself (google for JS namespacing).

There is a caveat here that I haven't found a nice way to encapsulate either Pixi or Phaser (both dump a global) but their globals are only used to instantiate and control properties, so they won't be of any use for people aiming to fiddle with your game.

Link to comment
Share on other sites

@mattstyles While googling about a completely different topic ("Phaser.JS file structure") I found an answer on sitepoint which I think addresses the issue you have mentioned: not declaring global variables. Here is the code snippet from the sitepoint tutorial:

Game = function() {};

Game.prototype = {
	start: function() {
		var game = new Phaser.Game(640, 480, Phaser.AUTO, 'game-area');
		
		game.state.add('boot', BootState);
		game.state.add('preload', PreloadState);
		game.state.add('main-intro', MainIntroState);
		game.state.add('main-menu', MainMenuState);
		game.state.add('level-master', LevelMasterState);
		game.state.add('level-intro', LevelIntroState);
		game.state.add('level-round', LevelRoundState);
		
		game.state.start('boot');
	}
};

Then in menuState.js to move to the new state the method can be called from this.game:

var menuState = function() {};

menuState.prototype = {
    login: function() {
        this.game.state.start('level-master');
    }
};

Now the method to change game states is not accessible anymore from the console, as it is not declared in a global variable as you have suggested.

I think this is what you meant and is probably the cleanest way to do it?

I find handling name space one of the best methods to reduce immediate cheating-threats and also keeps code a lot cleaner. If there is a better way to handle name space for this example, I would love to know.

@rgk yes I know that client side code is always at risk. But I still want to remove as many leaks as possible. I have a lot of friends who know enough JavaScript to simply write such a command in the console but could never go beyond that. I think users will respect your game a lot more if you limit cheating as much as possible. Yes, even if a hardcore hacker could find a way around it, I still wanna remove all possible hacks for maybe a "hobby hacker". I think you get the idea :) I think proper name spacing solves a lot of these issues already, as mattstyles explained above. I just couldn't figure out a way to do it in this case until I found the tutorial on sitepoint. Now the question that remains is: Is this the proper name spacing technique for this particular case? I think yes but if somebody has a different code snippet to show, it's always very appreciated :) 

Link to comment
Share on other sites

On 06/09/2016 at 9:16 AM, mattstyles said:

Yes you can stop them, just stop declaring globals variables (its not a terrible idea, but its almost always best avoided, outside of dev anyway). This doesn't stop all cheating of course, but it solves your immediate issue/s.

Use a proper module system or hack a simple one yourself (google for JS namespacing).

There is a caveat here that I haven't found a nice way to encapsulate either Pixi or Phaser (both dump a global) but their globals are only used to instantiate and control properties, so they won't be of any use for people aiming to fiddle with your game.

I used to do a custom build of phaser/pixi without the intro/outro and then encapsulate that and the game code in a closure to run through google closure compiler.  It was a lot of work to get working but did nicely hide the globals as well as generating smaller, faster & more obfuscated code.  BUT I still had to export the Phaser global, there were still internal requirements for this, it wouldn't work just in the closure scope.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...