I have coded a simple snake like game in Java. I want to store the high scores of users in a database and so I have created a mySQL database. The problem I'm facing is having the program connect to the mySQL database without leaking the login information which will allow users to mess with the database. I have looked into it and everyone has suggested a web service in the middle between the game and the SQL database. However the problem is still there and anyone can feed data which can again mess up the database.
One option I've thought of is having the jar file uploaded along with the data to the web service. The web service then gets the hash value (was looking into SAH 512) and compares it to the hash value that it's suppose to get and if matches then it proceeds. But then someone can just reverse engineer my game and change the code a bit and send the original game file but send a different NAME+SCORE to the database. Also having people keep uploading files to the web service would be a huge pain on my network because it could handle only so much considering I'm using a home network.
I could encrypt some file with the password on but since the program is able to decrypt it then surely the user will be able to decrypt it and get the information as well.
Basically anyway I provide the program with a key to my database someone will be able to reverse engineer it and edit it so that they are able to access my database. That's my thought behind it. Anyway I provide the program a way to access the database someone will also be able to use that way to mess with the database if they wanted to.
There must be a way for me to be able to store information from my game onto a mySQL database and making sure that nobody is able to change stuff around it but only the program that I've made is able to. Somehow to hide the details behind a service or something. How the hell do other people do it? Can I have some guidance? Any ideas are welcome.
Typically, applications shouldn't make direct connections to a database, rather they make calls to a server that has db access.
In fact, you can not get a guarantee for that. The application can always be decompiled and its behavior changed.
If you accept this limit, you can guarantee a certain level of security by using a middle layer (web service). Here, you can guarantee a secure transport layer (SSL) and trustworthy login through a user certificate placed in the app. You can also add a digital signature to the sent data.
This will give you a fairly reliable system whose drilling will need to decompile the application.
This is an age old problem, and there is no easy solution to it. For some scenarios, it can be solved, but for others it cannot.
The basic rule is, anything you do in the client is pretty much useless in terms of security. As you said, anybody can decompile and analyse your client-side code, obtain any secrets and so on. The user has full control of the client, and therefore, you cannot trust data (scores) sent by the client.
So you need a server-side solution, and that's where it starts to get interesting. What you can actually do is you can send the whole flow of the game (all the events) to the server to be able to fully (or at least in part) reconstruct what happened - server side. The score doesn't even need to be sent then, you can calculate it from how the game went in the client.
For single player skill games, this doesn't help, the user can still construct the whole flow like he was playing really well. But on the one hand, that's much harder than just to fake a score, and on the other hand, there may be games, where coming up with a solution is the point. Especially for games that are NP-hard, finding the solution is indeed the trick, verifying it is easy.
Also for multiplayer games, this would help, because if all players submit the flow, those flows received must match, otherwise there is a cheater (or all the players are cheaters, or the same cheater is playing as all the players, but you should be able to prevent that then by other means).
If you have the whole flow of the game, you can also implement other anti-cheating techniques, like for example if it's a skill game, you can try to find actions that appear super-human. It will never be perfect, and the difficulty then is not to mark legitimate players as cheaters.
it depends a little...
one example that will at least make it a little harder for someone who wants to mess with your game could be like this:
if your game is procedurally generating content, store and transmit the initial seed ... then do not just transmit the score and a name...
store and transmit all player decisions that lead to a specific score
let your server replay the game based on the provided seed and decisions, and take the score that was calculated on the server
so... to forge a score you need to solve the game (or an automated approach for this)
this approach does make it harder to fake a score, but it does not bind a name and a score together (you could submit the same score with a different name later ...)
to add that you can change things a little further:
online scores require online games ...
when a game is started, ask for the players name ...
post that name to the server, to aquire a HMAC (Hashed Message Authentication Code) secured token, containing an ID (think of an GUID) and the server generated starting seed
the server stores name and ID, and gives out a limited number of tokens per timespan and IP
the token is valid for a timespan x, after that you can delete it if it was not "used" within that timespan
when the player finished the game, you can provide this token, together with the players decisions to the server
the server knows who the player is, and can recreated the final gamestate and find the score
systems like this do not prevent all forms of cheating, but they are usually not that hard to implement and demand at least a little more effort from an attacker, thus filtering out the script kiddies
Related
I am trying to make multiplayer turn based game in Unity. I want to store first client's move in database and in second client's application look for the database and update game board with first client's move.I want to know that is there other way except regularly check for value change in database?
Databases are used to store data only, like a big file you can access when you want with queries (SQL). You can make a timer who track changes every X ms but i don't think this is the right way when you'r building real time application or games over networking.
I don't know how your unity networking is. But i'll try to explain how you need to implement :
Unity networking and games in general are based on direct tcp connection between client and server part. What you need to do is to keep your game state (like "moves") in the server side, that way you will be able to notify every client that "PLAYER X MOVE THERE".
You can use a database to save your server side state every X second if you want as an "anti crash device".
A database will be more usefull if its used for no real time data like scores history or user informations.
I hope I was clear enough in my awnser :)
All s/w is Windows based, coded in Delphi.
Some guys submit some data, which I send by TCP to a database server running MySql.
Some other guys add a pass/fail to their data and update the database.
And a third group are just looking at reports.
Now, the first group can see a history of what they submitted. When the second group adds pass/fail, I would like to update their history. My options seem to be
blindly refresh the history regularly (in Delphi, I display on a DB grid so I would close then open the query), but this seems inefficient.
ask the database server regularly if anything changed in the last X minutes.
never poll the database server, instead letting it inform the user's app when something changes.
1 seems inefficient. 2 seems better. 3 reduces TCP traffic, but that isn't much. Anyway, just a few bytes for each 2. However, it has the disadvantage that both sides are now both TCP client and server.
Similarly, if a member of the third group is viewing a report and a member of either of the first two groups updates data, I wish to reflect this in the report. What it the best way to do this?
I guess there are two things to consider. Most importantly, reduce network traffic and, less important, make my code simpler.
I am sure this is a very common pattern, but I am new to this kind of thing, so would welcome advice. Thanks in advance.
[Update] Close voters, I have googled & can't find an answer. I am hoping for the beneft of your experience. Can you help me reword this to be acceptable? or maybe give a UTL which will help me? Thanks
Short answer: use notifications (option 3).
Long answer: this is a use case for some middle layer which propagates changes using a message-oriented middleware. This decouples the messaging logic from database metadata (triggers / stored procedures), can use peer-to-peer and publish/subscribe communication patterns, and more.
I have blogged a two-part article about this at
Firebird Database Events and Message-oriented Middleware (part 1)
Firebird Database Events and Message-oriented Middleware (part 2)
The article is about Firebird but the suggested solutions can be applied to any application / database.
In your scenarios, clients can also use the middleware message broker send messages to the system even if the database or the Delphi part is down. The messages will be queued in the broker until the other parts of the system are back online. This is an advantage if there are many clients and update installations or maintenance windows are required.
Similarly, if a member of the third group is viewing a report and a
member of either of the first two groups updates data, I wish to
reflect this in the report. What it the best way to do this?
If this is a real requirement (reports are usually a immutable 'snapshot' of data, but maybe you mean a view which needs to be updated while beeing watched, similar to a stock ticker) but it is easy to implement - a client just needs to 'subscribe' to an information channel which announces relevant data changes. This can be solved very flexible and resource-saving with existing message broker features like message selectors and destination wildcards. (Note that I am the author of some Delphi and Free Pascal client libraries for open source message brokers.)
Related questions:
Client-Server database application: how to notify clients that data was changed?
How to communicate within this system?
Each of your proposed solutions are all viable in certain situations.
I've been writing software for a long time and comments below relate to personal experience which dates way back to 1981. I have no doubt others will have alternative opinions which will also answer your questions.
Please allow me to justify the positives and negatives of each approach, and the parameters around each comment.
"blindly refresh the history regularly (in Delphi, I display on a DB grid so I would close then open the query), but this seems inefficient."
Yes, this is inefficient
Is often the quickest and simplest thing to do.
Seems like the best short-term temporary solution which gives maximum value for minimal effort.
Good for "exploratory coding" helping derive a better software design.
Should be a good basis to refine / explore alternatives.
It's very important for programmers to strive to document and/or share with team members who could be affected by your changes their team when a tech debt-inducing fix has been checked-in.
If not intended as production quality code, this is acceptable.
If usability is poor, then consider more efficient solutions, like what you've described below.
"ask the database server regularly if anything changed in the last X minutes."
You are talking about a "pull" or "polling" model. Consider the following API options for this model:
What's changed since the last time I called you? (client to provide time to avoid service having to store and retrieve seesion state)
If nothing has changed, server can provide a time when the client should poll again. A system under excessive load is then able to back-off clients, i.e if a server application has an awareness of such conditions, then it is therefore better able to control the polling rate of compliant clients, by instructing them to wait for a longer period before retrying.
After considering that, ask "Is the API as simple as it can possibly be?"
"never poll the database server, instead letting it inform the user's app when something changes."
This is the "push" model you're talking about- publishing changes, ready for subscribers to act upon.
Consider what impact this has on clients waiting for a push - timeout scenarios, number of clients, etc, System resource consumption, etc.
Consider that the "pusher" has to become aware of all consuming applications. If using industry standard messaging queueing systems (RabbitMQ, MS MQ, MQ Series, etc, all naturally supporting Publish/Subscribe JMS topics or equivalent then this problem is abstracted away, but also added some complexity to your application)
consider the scenarios where clients suddenly become unavailable, hypothesize failure modes and test the robustness of you system so you have confidence that it is able to recover properly from failure and consistently remain stable.
So, what do you think the right approach is now?
Well I don't know if the title for this question is appropriate or not, but I didn't know how to put this in few words.
I'm currently developing a multiplayer 2D game using NodeJS and Socket.io on the server side and HTML5 on the client side. This game doesn't need to save the players progress unless when they finish it. And I must make sure that all information about the players, such as, scores and helps are always valid. So I decided to centralize this information on the server, this way the clients never send a score to the server, instead based on the information sent the server calculates the scores and send them to all clients. Besides that, I can have different sessions of this game running with 2 players minimum and 4 players maximum.
At first I decided to implement this with the server always maintaing the games sessions data in memory, but now I'm questioning myself if I shouldn't have used a database to store this data instead. I'm using a database to store the sessions data only when they are finished because I have no use for unfinished sessions data. But should I instead maintain the sessions and players data on the database while they are playing? My problem here is that the clients communicate very frequently with the server, with this approach I would have to first request their data from the database, make the necessary changes, store it back into the database, and repeat this process on each client request. Maybe the answer to this is obvious, but should I use this approach instead?
It is the first time I'm developing a game, so I have no idea how things usually work. I just know that I want the server to be fast. I chose to maintain everything on memory mainly because all examples and tutorials I found about multiplayer games development never mentioned a database...
Thank you!
I am also developing a multiplayer game using node.js and socket.io. You should not access the database on each client request because,
1) I/O operations are expensive.
Reading/writing to database is "expensive" (slow). It is much faster to read and write from memory.
2) I/O operations should be asynchronous in Node.js.
function read_or_alter_database(input, function(callback){ update_the_client(); });
This makes the database operation non-blocking: the rest of your application will still run, until the operation is done. Then, the callback function is executed. If the player's client rely on the database access to update the game state, then this becomes a blocking operation (since the game cannot proceed until the database operation is done), which negates the main purpose of Node.js.
3) There will be a high volume of client requests in multiplayer games.
This plus point 1 results in a big efficiency loss.
Sounds like you already have your answer: Since the state is only important once a session is complete, only store the data upon completion of that session. Storing the intermediate values serves no purpose, and only slows things down.
Node.js is a relatively new development platform - it is uncertain if it would be able to support such a system. As far as what is NORMALLY done - as much information as possible is stored client side, first off, and then servers typically hold data in memory, or, at least, I know this is the case for the popular games League of Legends, World of Warcraft, and Starcraft II. Then again, those applications are not HTML/Node.js, are very very demanding on the system, and are by huge development companies - it may be that the DB approach is fine for a smaller game, I've just never heard of it.
I'm creating a game for a viral marketing campaign where roughly one in 100 players will get access to a QR code for some exclusive thingamajig. The game will require information to be pulled and pushed from the database since the game environment will 'grow' over time.
I haven't decided yet on how to do this, but I had 2 ideas, each with their concerns:
solution 1: connect the SWF to a database
concern: I have decompiled SWF's before and it is remarkably easy. How do I protect my database credentials against this?
solution 2: have the SWF connect to .php scripts that query a database. This way my database connection credentials are safe inside the php file.
concern: However, how do I then make sure the PHP script isn't being accessed by a custom script? Somebody could get the php URL from the SWF source and just access it directly, bypassing the flash app.
You need to understand one thing.
Anything client side can be and if money is involved probably will be hacked.
With that being said, security is about layers, the more layers involved, the harder it is to be hacked.
There are many methods you can use and combine together that will take out of the picture the average swf hacker.
The first place I would start with is never ever store sensitive info in the client.(IE: server compiled SWFs)
If you have data there, it can be grabbed/modified.
Next, I would encrypt all data sent to and from the swf with a public key. This key would expire frequently. To obtain the key the swf would have to pass user credentials(login).
On the server side you can track the user via a session.
You can add socket connection support with a persistent connection
httsp, SSL, TSL
And many many more options to pick from.
The choice is yours.
The real question however, is how far do you want to go.
I would rule Solution 1 out right away for just the reason you identified.
So let's just talk about how to circumvent the solution 2 issues.
What I see is a common way to handle this is having the server side script handle the generation of these special items. If you look at a lot of online flash games, I'm sure you'll agree that Flash is responsible for the UI almost entirely, the rest is handled by the backend. This of course limits the type of games you can do this way.
There is also another way. If you could have your swf generated by your backend, you could store session data that would only be good for a limited time. This of course wouldn't have to be the same swf that stores all of your game assets but just the classes that are required to communicate with the backend. Generating the server interaction swf dynamically would then allow to store session important data and encrypting it with a different key every time, so that if someone does hack it, it would limit what they can do with it, as a new session would require new credentials.
I'm making an Online game where I will host a game server. Players will login to my game server. They will then be taken to a lobby where they can choose a game to join. I will be keeping track of wins and loses and a few other statistics.
My requirements are as follows:
At any time in game, a player should be able to click on another
player and get their latest up-to-date statistics.
A player should also be able to go to my Web Site and get the same
statistics. (Ideally, up to date immediately, but less important than
in game)
I will also have a leader-board that will be generated from data on
the Web Site.
My question is: What type of solution would typically be used for this type of situation?
It is vital that I never lose data. One thing that worries me about using a Web Site database is data loss.
I'm also unsure how the interactions between the Web Site database and the game server would work. Is there a capability with mySQL to do this sort of thing? My other concern with using a Web Site database is how much bandwidth I would consume monthly. I generously estimate that I will have 1000 people online at any given time. A game lasts around 20 minutes.
How are these types of situations typically solved? I've looked all over but I've yet to find a clear answer to my concerns.
Thanks
I would recommend a few things based on your requirements. Your question is very open ended so the answers given are quite general:
Databases are fine to store data as they write to a harddrive and are transactional (meaning they fine to survive web server crashes).
Databases can be backed up using any one of numerous back up tools, such as: https://www.google.com/search?q=sql+backup&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a
For up to date statistics you should probably be pulling active game players information from a cache (otherwise you might find you are pounding the database when most of your data isnt going to change (ie possibly most gamers could be offline and their data will remain static but might want to be viewed.
Investigate what kind of database you want. NOSQL, or SQL. There is no obvious choice here without evaluating the benefits of each.
Investigate N-Tier or MultiTier design. http://en.wikipedia.org/wiki/Multitier_architecture
Consider some sort of cloud like infrastructure such as appfabric, azure, (there are other linux ones too) etc. There are many cloud services which can provide high scalability. It could be a short cut for the previous points.