I'm developing a very, very basic turn-based game using php and jquery and I'm looking at two different ways of keeping track of the current user's score:
1) global javascript variables - for example var currentScore at the beginning of the js. The game action and turns are all controlled via ajax so I don't have to worry about a page refreshing losing the variable data.
2) mysql - create a row with currentScore, user, etc and access it / update it every turn.
I'm trying to balance a) load speed and b) making the score tamper-proof. I'm thinking that local javascript would be fast and less load time but mysql records would be more tamper-proof. Does anyone have any advice as to which is faster and which is more tamper-proof, or perhaps have another way of accomplishing this that I didn't list above?
Run your game in PHP, not in JS.
What I mean to say is instead of allowing the player's computer to control the action, and send the results back to the server...
that allows for people to hijack and send messages to your PHP like auto-firing pistols...
...or headshot scripts ...or speed-hacking.
...or even worse -- sending in messages like: "I just scored 500 points on my turn", and having your PHP script go: "Okay!".
So instead, the core of the game engine should run in PHP, the client should just say: "My character wants to move X squares.", and then the server can say: "No, you're a cheating tool, you can only move 3 squares.", and then the client will have to adhere to those rules.
In this regard, PHP will be 100% in control of the score-keeping.
any data that is not stored on the server will be tamperable. any data sent to the server can be doctored. not only should the server store all of the game data, but it should be validating all incoming data from the client. for instance, do the rules actually allow this player to use the move they are telling me they are using? Otherwise, it will be fairly easy to cheat. Then again, your project may not require that amount of scrutiny.
both,
never trust javascript in games. There will always be a clever player which will mess with it.
Use javascript for the gui part and controlling the game, but always check ALL results in PHP, especially player specific values. Check for the right player!! Else some losers will mess with your game.
Don't worry about speed, just script your game (of course with speed and data in mind) and investigate when you hit performance problems. One issue is important from beginning: think about your database tables and queries. That will become most likely your performnce bottleneck,more then bad php scripting.
Related
So as you know in some browser-games such as Travian, Tribalwars and etcetera, you can build up a building, it takes X amount of time and it finishes.
So I'm curious how that is done?
Is it a cron-job running every second or what? How are they then doing with troops, they can't have a cron-job running ever millisecond, that wouldn't be resource usage friendly, right?
So I'm really curious about this and I have no idea so I can't really say I have tried. I have however searched around but never found anything helpful.
Thanks.
The easiest way to implement something like this is simple timestamps. The request on the front end generates a timestamp based on the constraints given by the details of the request (what type of building you are building, what level you are, if you have bought the upgrade). Then a timestamp is inserted into the database for when the completion occurs. Then, if you want the browser to refresh when the job is up, you make a script on the js that makes a request for all timestamps in queue and reloads when they come up.
One way: You let the client handle the timer. So the timer will sit on the browser side counting down using javascript. When the time is up it will contact server to see if it's valid (never trust client side code). Server looks up the building and see if it would have been finished by then. Server side doesn't need to keep any timers it just answers requests. Timers are UI side.
Well, PHP is one of the worst things you could use to build a game... In games, everything is controlled by the main loop that controls the game. So basically, in a game, everything is running inside an infinite loop, albeit one that allows for user input without freezeing the computer, obviously. So that loop takes care of the timing as well, and the way to compute timing will depends on the language on which the game is developed. For web-based games, Java, JavaScript and Flash are usual choices.
I need some advice on website design.
Lets take example of twitter for my question. Lets say I am making twitter. Now on the home_page.php ,I need both, Data about tweets (Tweet id , who tweeted , tweet time etc. etc) and Data about the user( userId , username , user profile pic).
Now to display all this, I have two option in mind..
1) Making separate php files like tweets.php and userDetails.php. By using AJAX queries, I can get the data on the home_page.php.
2) Adding all the php code (connecting to db, fetching data ) in the home_page.php itself.
In option one, I need to make many HTTP requests, which (i think) will be load to the network. So it might slow down the website.
But option two, I will have a defined REST API. Which will be good of adding more features in the future.
Please give me some advice on picking the best. Also I am still a learner, so if there are more options of implementing this, please share.
In number 1 you're reliant on java-script which doesn't follow progressive enhancement or graceful degradation; if a user doesn't have JS they will see zero content which is obviously bad.
Split your code into manageable php files to make it easier to read and require them all in one main php file; this wont take any extra http requests because all the includes are done server side and 1 page is sent back.
You can add additional javascript to grab more "tweets" like twitter does, but dont make the main functionality rely on javascript.
Don't think of PHP applications as a collection of PHP files that map to different URLs. A single PHP file should handle all your requests and include functionality as needed.
In network programming, it's usually good to minimize the number of network requests, because each request introduces an overhead beyond the time it takes for the raw data to be transmitted (due to protocol-specific information being transmitted and the time it takes to establish a connection for example).
Don't rely on JavaScript. JavaScript can be used for usability enhancements, but must not be used to provide essential functionality of your application.
Adding to Kiee's answer:
It can also depend on the size of your content. If your tweets and user info is very large, the response the single PHP file will take considerable time to prepare and deliver. Then you should go for a "minimal viable response" (i.e. last 10 tweets + 10 most popular users, or similar).
But what you definitely will have to do: create an API to bring your page to life. No matter which approach you will use...
Here is my problem, for those of you who looked at the title and thought "PHP does not wait on user input because it is a server side language and therefore your problem is a client-side one," just hear me out.
I'm making a game. It is mulitplayer game, therefore multiple users. At the start of every game round the users involved in the game are prompted with a chose of things they want to do that round. Course, the round isn't to commence until everyone has made a selection on what they want to do that round.
See, that is my problem. How do I make a script wait for 'all' users to send a request (send input) before continuing execution? The server-side language is PHP. The answer wouldn't be with the client as the client is only responsible for one user and wouldn't know what the other users are doing.
Thanks.
Fundamentally, you have two choices:
Choice one, you have each script check if it has all the data it needs, and then do all the work to calculate the next move (or whatever). That is actually much harder to get right than it sounds, because you run into problems of concurrency.
Basically, that approach leads to more than one "process" - page load - trying to do the same work on the same data, and that opens the door to races where you either don't do the work at all, or where you do it twice.
Choice two, which sounds harder, is where you write another PHP script that checks to see if it has all the moves, calculates the outcome, and updates the database (or whatever) in the background.
Then, run that off a cron job, or something like that, so you only have one instance running at a time. That makes life easier: your "is everything done" script is only running once, and so you don't have to worry about races - but there might be a lag between the last move being submitted and calculating the outcome.
That approach is actually easier in the long run, because while it involves more code and more moving parts, it actually avoids the hard problems (concurrency) in return for a few more easy problems (a bit more code, using cron).
You can improve on both of those, of course, but those are the fundamental models. Locking and other coordination techniques can make "calculate in the last page" work better, but they involve you addressing the races.
Using various "background job" tools can improve the latency of the second approach, by letting you trigger the check instantly rather than just on a timer. You still have some latency, but the user doesn't see as much of it.
Really, though, you get to pick one of those two strategies and go with it.
(Also, I strongly advise that if you can, grab a framework or something where someone else already solved these problems, then use that.)
Since you can't push data out, I'd tackle this as follows:
collect the submitted information on the server in eg DB
run a client-side script to check periodically if all required information is available
on the client evaluate the response: if true, start game - if not "wait" = keep checking
so you need:
script on the server that collects the info
server script that checks if all info is available
client script that checks periodically and evaluates
Is there any way you can push data to a page rather than checking for it periodically?
Obviously you can check for it periodically with ajax, but is there any way you can force the page to reload when a php script is executed?
Theoretically you can improve an ajax request's speed by having a table just for when the ajax function is supposed to execute (update a value in the table when the ajax function should retrieve new data from the database) but this still requires a sizable amount of memory and a mysql connection as well as still some waiting time while the query executes even when there isn't an update/you don't want to execute the ajax function that retrieves database data.
Is there any way to either make this even more efficient than querying a database and checking the table that stores the 'if updated' data OR tell the ajax function to execute from another page?
I guess node.js or HTML5 webSocket could be a viable solution as well?
Or you could store 'if updated' data in a text file? Any suggestions are welcome.
You're basically talking about notifying the client (i.e. browser) of server-side events. It really comes down to two things:
What web server are you using? (are you limited to a particular language?)
What browsers do you need to support?
Your best option is using WebSockets to do the job, anything beyond using web-sockets is a hack. Still, many "hacks" work just fine, I suggest you try Comet or AJAX long-polling.
There's a project called Atmosphere (and many more) that provide you with a solution suited towards the web server you are using and then will automatically pick the best option depending on the user's browser.
If you aren't limited by browsers and can pick your web stack then I suggest using SocketIO + nodejs. It's just my preference right now, WebSockets is still in it's infancy and things are going to get interesting once it starts to develop more. Sometimes my entire application isn't suited for nodejs, so I'll just offload the data operation to it alone.
Good luck.
Another possibility, if you can store the data in a simple format in a file, you update a file with the data and use the web server to check its timestamp.
Then the browser can poll, making HEAD requests, which will check the update times on the file to see if it needs an updated copy.
This avoids making a DB call for anything that doesn't change the data, but at the expense of keeping file system copies of important resources. It might be a good trade-off, though, if you can do this for active data, and roll them off after some time. You will need to ensure that you manage to change this on any call that updates the data.
It shares the synchronization risks of any systems with multiple copies of the same data, but it might be worth investigating if the enhanced responsiveness is worth the risks.
There was once a technology called "server push" that kept a Web server process sitting there waiting for more output from your script and forwarding it on to the client when it appeared. This was the hot new technology of 1995 and, while you can probably still do it, nobody does because it's a freakishly terrible idea.
So yeah, you can, but when you get there you'll most likely wish you hadn't.
Well you can (or will) with HTML5 Sockets.
This page has some great info about this technology:
http://www.html5rocks.com/en/tutorials/websockets/basics/
I'm working on a game, which has score based on a JavaScript countdown: the faster you finish the level before the countdown reaches zero, the bigger your score is.
How can I make sure it is not somehow altered when I finally receive it from client-side on server-side?
My initial idea is to make two checkpoints: one at the beginning of a level and another at the end. Checkpoint is basically a session sent via AJAX to server-side PHP script which is then timestamped. So after the game is finished on client-side, the score is verified with the one on server-side. Is this kind of protection any good?
Thank you in advance!
EDIT:
I'm also open to any other ways to achieve the desired functionality.
Simply, you store the value in a datetime field in your database. Then, you seed your javascript with that value. Thus, any change on the client side, will not have an effect on the stored time.
However, if you depend on the client side to get a value, you cannot do anything to make sure it's correct. The user can still spoof the ajax request with no real problem. It makes it a bit harded, but certainly doable.
Once your countdown is somehow related to the client side, there is no escape :)
As others have pointed out, there's no way you can be certain that the times have not been tampered with, however there are ways to mitigate the consequences:
If you have a (server-side) system that suspects that scores have been tampered, you can blacklist that IP address or cookie, and not show those scores to other users. Do show the scores to the hacker, though. This has several effects: Firstly, if they think they've beaten you they may move on and leave your code alone. Secondly, if your cheat detection wrongly thinks that a ninja player is hacking, the player will still see their score in the tables as normal (even if other players don't). Consequently, false positives don't matter so much, and you can use fuzzier algorithms, e.g. How does this player's rate of improvement compare to the average? Has he got a bunch of poor scores then suddenly an incredible one? Has my server seen an unusual pattern of hits from this user? Etc.
You could probably set this up so that you could refine your detection algorithms incrementally, and blacklist players after you've got suspicious about them (and un-blacklist false positives).
There are 2 possible scenarios which you might be facing. Let me start with the easy one:
a) If the web application is designed such that the game starts as soon as the page is loaded, your life is going to be simple. The script which sends out the game should timestamp the database with the time at which the game was sent out. This would be the start time. The end time would be recorded when the client sends in a "level completed" message. As time is being recorded at the server side in both the cases, you do not need the client to keep time. However, there is a catch. See The Catch section below.
b) If the client loads the application but the game begins much later when the user hits 'play' etc., your life is going to be a little more difficult. In this scenario, you would need a "level began" as well as a "level completed" message coming from the client. Again, it would be a better idea to keep time at the server and not the client. However, you would need to ensure that the client receives an ACK to the "level began" message before starting the game to ensure that the user does not play a game which is not being recorded by the server. (The "level began" message might never have reached the server).
The Catch: You need to realise that there is no protection possible for the user cheating on his scores! JS is completely open and no matter how you implement your start / end calls to the server, any user can write a script to send similar calls to the server at whatever time interval she wishes to use. Even if you use a session / cookie, these can be easily replicated. (Using a sniffer for instance). Thus, you must realise and accept the design limitations imposed by the HTML/JS architecture and code within these limits. Hence, the best idea is to write code for the users and not to prevent the hackers from sending rogue calls. Make your game fun for the people who would be playing your game and do not worry about the hackers cheating on their scores - they would not be your target audience anyway.
First of all, forget getting the elapsed time from the client side. Any malicious user can alter the sent data.
Server side must be the only authority for storing the time. At the beginning of the level, store the current time in the $_SESSION. At the end of the level, subtract it from the current time and it is the elapsed time for the level.
$_SESSION['start_time'] = time();
$elapsed_time = time() - $_SESSION['start_time'];
You can still show the elapsed time by Javascript for the user's convenience. For the timing differences between the client and the server (which is perfectly possible), you can do synchronization by getting the elapsed_time whenever your client hit the server.
If the level completion span between multiple sessions (like you start the level, leave the site, and come back later to finish it) you have to store it in a persistent data store (database).
You can use a timestamp in a session to store the start date and then send make JavaScript do a request when the player's done (but the second timestamp should come from PHP, or other server-side language, too).
The ony really bullet-proof way is to show nothing to the user and to ask him to tell you every single move, check it with the server and send back what it allows him to know. But this means delay.
You could issue a unique token, that is stored within the user's session and is available to your Javascript code. When starting an AJAX request, pass this token as an additional parameter, so the server can distinguish between legimitate and spurious requests.
This token should be valid for a single request only of course.
In combination with the mentioned solutions (server-based time checks etc.) you should be able to build a solid scoring system.
well, thinking of this problem gives me two ideas:
Attack your own server.
by that i mean, send a request every 1 second, that will save the score.
this way, the "hacker" can not send Start/End time and cheat.
make the requests at a specific time diffrences.
ok, so lets say we started playing, you can send a request at specific time intervals (3.4 sec? )
if a request is not in that time frame then the user is cheating ?
or at least marked as possible cheater.
use a simple string. XD
for start/end time sent to server, offcourse encrypted.
you can try jCryption for encryption.
since as the others said, it is not totaly fail proof ( since we are talking about client side script ) , but at least it will make it a lot harder to cheat.
dunno, its just my two cents.
It is not possible to make it 100% bulletproof, you can only make it harder to hack if it is based on client-side
You can generate a GUID when the page is rendered. You can concatenate this GUID, the start datetime ticks, the session ID, and calculate a hash of them to validate the data when user return.