Highscores... again.

addscores.php

<?php 
        $db = mysql_connect('localhost', 'wanillan_wanilla', '*********') or die('Could not connect: ' . mysql_error()); 
        mysql_select_db('wanillan_scores') or die('Could not select database');
 
        // Strings must be escaped to prevent SQL injection attack. 
        $name = mysql_real_escape_string($_GET['name'], $db); 
        $score = mysql_real_escape_string($_GET['score'], $db); 
        $hash = $_GET['hash']; 
 
        $secretKey="*******"; # Change this value to match the value stored in the client javascript below 
 
        $real_hash = md5($name . $score . $secretKey); 
        if($real_hash == $hash) { 
            // Send variables for the MySQL database class. 
            $query = "insert into ssp3d values (NULL, '$name', '$score');"; 
            $result = mysql_query($query) or die('Query failed: ' . mysql_error()); 
        }
?>

HSController.js

private var secretKey="*******";
var addScoreUrl="http://www.wanilla.net/ssp3d/addscores.php?";
var myscore = 0;
var nameEntered : GameObject;
var myName = "";

function OnMouseDown () {
	myName = nameEntered.GetComponent (TextMesh).text;
	myscore = scoreCounter.display;
	if (myName != "") {
		postScore();
	} else {
		showError();
	}
}

function postScore() {
    //This connects to a server side php script that will add the name and score to a MySQL DB.
    // Supply it with a string representing the players name and the players score.
    var myhash=Md5.Md5Sum(myName + myscore + secretKey);
 
    var highscore_url = addScoreUrl + "name=" + WWW.EscapeURL(myName) + "&score=" + myscore + "&hash=" + myhash;
        
    // Post the URL to the site and create a download object to get the result.
    hs_post = WWW(highscore_url);
    GetComponent (TextMesh).text = "Submitting".ToString ();
    yield hs_post; // Wait until the download is done
    if(hs_post.error) {
        print("There was an error posting the high score: " + hs_post.error);
    }
    yield WaitForSeconds(0.5);
    Application.LoadLevel("Title");
}

function showError() {
	GetComponent (TextMesh).text = "Enter a Name".ToString ();
	yield WaitForSeconds (3);
	GetComponent (TextMesh).text = "Submit".ToString ();
}

Yeah, I somehow had this working, and suddenly it stopped. >.< I can’t figure it out, so could some of you smart people take a look?

The first thing I notice is that your database name has changed (it was called ssp3d_sleepy before) - is that deliberate?

Secondly, try commenting out the “if ($realHash… )” line (put // at the start of that line and the start of the line with the closing brace) and send score values directly to the PHP script with a browser. You can type “http://www.wanilla.net/ssp3d/addscores.php?name=Moldorma&score=14” directly in the URL line and see the results. If this adds the score into the database correctly, then uncomment the lines and add an “else” part to the “if” which prints out “Fail”. You can then check for this result in your JavaScript via the WWW class’s data property - if you get “Fail” in the result then the hash clearly isn’t operating properly. You might also be able to make use of your TextMesh to display what the PHP script is returning without using a browser.

Thirdly, I notice a dangerous mix of identifier styles in the JS file: myscore, myName, hs_post. As you’ve already seen with PHP, it’s quite easy to get empty values accidentally by using a similar but not identical variable name. It helps to choose your favourite style and then stick to it consistently. Easier said than done with third-party code, of course…

I’ve already tried the commenting out, which let me send the scores fine by manually changing the URL line. So there’s a problem with the hash, but I don’t see what it could be. I’ve checked and double-checked it.

The problem could be with the hash, but you must make sure that the message is being passed from the player to the server. You could check in the web server’s access log for an access with the right URL at the right time, or send some data back to the player and check that it is correctly received.

If the communication is OK, then try using PHP’s error_log function in your script, just before the “if” statement. Use this to dump the received values of name, score and hash (ie, the values from the $_GET array) to a file along with the checking hash value that is calculated on the server. (Alternatively, you could send these values back to the Unity web player as I mentioned above if you have some convenient way to display them.) You should be able to tell by looking at this data whether there is an incorrectly sent/handled variable or an incorrectly calculated hash. If it turns out to be the hash that is wrong, then the most obvious culprit is the secretKey value, but I’m sure this was the first thing you looked for. A false value in a variable could be caused by various things, but it will narrow down the search if you can detect which variable is wrong.

(Note that it’s not absolutely impossible that the MD5 implementation is wrong but it isn’t the sort of algorithm that you would expect to work only some of the time.)

Okay, this is wierd. By looking at the access logs I’ve definitely found the culprit. The Unityweb file is trying to send it to addscore.php instead of addscores.php. O_o I guess the obvious solution is just to drop the s on addscores.php.

Are you definitely sure that the latest version of the unityweb file is in the web folder? Another thing to check is that your JS script doesn’t have any compiler errors - I think Unity runs/builds with the last working version of your code when the newer version fails to compile. Also, is it possible that your browser is just mistakenly caching the previous version of the player? Try explicitly emptying the cache to make sure. You might be able to configure the web server to send a no-cache header for unityweb files if you have access to those kinds of settings.

It’s very unlikely that the unityweb file has the latest version of the JS code, yet is somehow retaining the previous contents of that particular string. Unless you’re absolutely sure that it’s appropriate, then I don’t think you should solve this by changing the name of the PHP file back to addscore again. You should work with the assumption that you at least might need to fix further JS bugs in the future!