Pergunta

I'd like to know if it's possible to prevent cheating in the following case

  • I have a Ruby on Rails app and a Active Record database
  • I have Users (model User), that play Games(model Game) and there are Prizes (model Prize).

What I want is to :

1- prevent a player from cheating/hacking on the winnings (prizes he has won)

2- prevent a player from cheating on the nb of shots he has

As a user can win multiple prizes and prizes can belong to multiple users, I have a many_to_many relations: i use for this a table/model Winnings that lists all stuff won in the games by each User (a user has many winnings and a prize has many winnings)

Players have a certain number of shots, let's say 3 per user.

For 1-, basically, i guess everytime a user wins a prize in a Game, i'll send the server a url like: mygame/com/?winning_id=1234;game_id=3;user_id=6;prize_id=4, telling the server the user with id 6 has won a prize with id4 in the game with id 6

I don't want players to be able to cheat that. how can I do this. Can any player just use that url above and send this way a message/action to my server (post) telling him he won? that would make it freaking easy to cheat?

Should I encrypt stuff/the url and make the url/message only understandable by my server?

For 2- (shots), I think I should send actions to server side every time and calculate scores at server side but still can't he cheat the same way as 1-?

Foi útil?

Solução

In addition to using post as mentioned in the answer from palainum above, if needed, you could add a string (instead of an ID) in any place in your game where the URL could be edited and is visible.

Background - I had a similar problem in one of my apps (where if a URL was changed people could deduce / edit the number and cheat). The way I overcame it was to generate a unique code for the item in the URL.

To do this, I would add a string attribute to Winning model called url_code, make it required and indexable:

  add_column :winning, string :url_code, :null => false, :index => true

in your model add an after_initialize callback:

Class Winning
  validates :url_code, :uniqueness => true
  after_initialize :create_url_code

  def create_url_code
    self.url_code=SecureRandom.hex(4) if self.url_code.nil?
  end

And use that as a parameter in the cases using an ID is a problem (similar to this in your controller)...

@winning = Winning.find_by_url_code(params[:id])

Also, you could do the same thing for your users URL (or if you need to display it every in URL) by using the user.name as a friendly_id.

edit - just fixed a typo where I had offer_code instead of url_code.

Outras dicas

There are at least two things you can do now:

  1. Send POST request - it will be still possible to cheat, but it will require more work
  2. Create a model Win - and create object of this class after winning a game. Then after making request (point 1) you can check if this object exists.

EDIT:

Sorry, you already mentioned Winning class. Just create object of this class after winning a game, then check if a user won a game (if the table contains a record with the user and the game).

You should also store shots of a user in a game and use unique validation to disallow for example shooting twice in one game.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top