I'd like to know if it's possible to prevent cheating in the following case
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-?
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.