PHP Master Server

Hi,

Here’s a Master Server replacement I’ve been using that runs in PHP. I use dreamhost and can’t easily run other servers, but I can easily run php stuff :slight_smile:

This still uses Unity’s default NAT facilitator. You’ll need to create an sql database and table called “MasterServer” with the columns like you see in RegisterHost.php or QueryMS.php. I’ve also put in “PHPMasterServerConnect.js” which more or less mimics the original interface. And then there’s a “MainMenu.js” which uses it and shows a list of clients and lets you join them.

Hopefully it’s pretty straight forward how to use it, but if not and there’s enough interest I’ll make a tutorial. If you are using it, I’d be happy to hear about it.

Good Luck.

418583–14523–$PHPMasterServer.zip (5.6 KB)

Seems OK and well done. :wink: Would be a pleasure to check it out in-game.

Fantastic! I use dreamhost too so this should be very handy. Thanks!

If you’d like to see an example of it. I have a project on facebook where I make use. http://apps.facebook.com/WhoCutTheDeck (and don’t worry it’s just for fun no ads or micropayments or anything).

This looks like a pretty sweet piece of good tech. :slight_smile: I’m looking into this more, thanks for posting this!

I’ve tried everything to get this working … unity keeps creashing when I try to join a game. Any insite on this??

I’ve seen that too in the editor. Try running two instances (both the host and the join) not in the editor.

I should add, I think it’s actually a bug in the unity editor with the new GUID version of connecting. I haven’t yet confirmed it enough for myself to submit a bug though.

I have other problem, it seems to register the game in the database, but I can’t see the game in the “Join Game” List

btw, thanks this is Fantastic!

Ok As you said duhprey it does have something to do with the GUID and running in the editor … if I start a client and a server in the browser it works fine accept for one thing so far … the server never removes the game when the browser window is closed, in this case a game with no players will always be listed in the DB … is there a fix for this. Another issue I found may help you blueice …

In the file QueryMS.php have a look at line 19 …

if ($row[$cols - 1] > 30) { continue; }

I have no idea what this line is supposed to do … but it keeps the php file from returning data so your game list will always be empty. Comment out this line and you should see your games.

I think this is a great setup and will continue to use it myself, its especially useful for facebook games … thanks duhprey. One quick question … I had a look at you facebook example … how did you get the user pic to show up in unity … I know about the facebook API and have used it often but you can’t send data to the unity player … did you send this info to the DB first then query it form unity??

The final column in the database is supposed to be the timestamp when the host was registered. UpdateHost.php pings that time to keep it active while the host is up. The ping is RegistrationLoop() in PHPMasterServerConnect.js. I’m not too happy with it, but all of that is supposed to handle the case where the browser closes without properly removing the host entry in the database. Line 19 means hosts which haven’t called RegistrationLoop for more than 30 seconds will be ignored as dead hosts.

It doesn’t always happen that the host leaves a dangling DB entry (there is a OnDisconnectedFromServer in PHPMasterServerConnect) but I haven’t figured out what causes it.

So, if removing that line fixes it then it means you might not have the timer and update setup correctly. Reply back if that doesn’t help, blueice.

Btw, I have a github for this here GitHub - tosos/PHPMasterServer: A Master Server for Unity3d v3 that runs in PHP. (no difference to the version I posted here)

On how I did the facebook stuff, I wrote about it here: http://www.tosos.com/category/unity-game-development (I can’t link directly to it for some reason… it’s the second post down titled “Another Game and Facebook Woes (er… Tutorial)”)

blueice, one other thought… if you’re making a webplayer build and access the php through that they need to be hosted on the same domain. There’s extra security in the webplayer to not let you access domains other than the one that hosts the unity3d file. One way to test is make a desktop build and see if it works there.

Ok now the if ($row[$cols - 1] > 30) { continue; } makes some sense. But still after un-commenting that line and starting a server the game still never shows up in the list. Maybe it has something to do with the type I selected for that field in th DB. You didn’t specify types so I used what I thought was best for each field … most are pretty self explanatory. I used “DATE” for “updated” field … maybe I should use “DATETIME”, TIMESTAMP", or just “TIME” … I’ll check this out in a bit I’m in the middle of a good read.

One other thing … maybe adding an “isDead” field to the table would be a good idea … this way when some one connects the server could send a http://yourdomain/remove_dead.php in that php file could be something like …

$db = mysql_connect (“host”, “name”, “pass”);
if (!mysql_select_db (“DB”)) {
echo "Could not select database " . mysql_error ();
exit;
}
$query = “DELETE FROM MasterServer WHERE isDead=‘true’”;
$res = mysql_query ($query);
if (!$res) {
echo "Could not execute query: " . mysql_error ();
exit;
}
mysql_close ($db);
?>

so if the if ($row[$cols - 1] > 30) { continue; } is true we could set the “isDead” field to true. Then a clean list could be loaded … what do ya think?

Yeah, that’s right. I should be DATETIME (I think NOW() is only compatible with that). isDead might work. I think there also might be a way to do it without isDead with something like

DELETE FROM MasterServer WHERE (NOW()-updated) > 30

I suppose thinking about it, it could be done at the beginning of QueryMS.php to delete all the inactive rows before querying, then the if ($row[$col - 1] > 30) could go away entirely.

Ok great … I’m going to play around with this right now … will change the field to DATETIME and implement the DELETE query for dead games … be back with results later. Oh and thanks for the link to the facebook stuff … I’ll be needing that shortly … :slight_smile:

Since you have Dreamhost you can use your phpMyAdmin account to export the database structure to a .sql file that can be uploaded onto other servers. It’s a lot easier than setting up the whole thing and avoids a lot of potential errors. It just creates a text file with all the sql commands to recreate the database. You can export with or without the actual data.

Oh and, thanks for making this available!

well, I am testing it from the editor and a desktop build, it registers the host but I can’t see the game in the “join list”…

and here is the php code:

<?php
    $db = mysql_connect ("localhost", "********", "********");
    if (!mysql_select_db ("blueice_MServer")) {
	echo "Could not select database " . mysql_error ();
	exit;
    }
    $query = "SELECT externalIp,externalPort,internalIp,internalPort,useNat,guid,gameType,gameName,connectedPlayers,playerLimit,passwordProtected,comment,NOW()-updated FROM MServer WHERE gameType='".$_REQUEST["gameType"]."';";
    // echo ($query);
    $res = mysql_query ($query);
    if (!$res) {
	echo "Could not execute query: " . mysql_error ();
	exit;
    }
    $rows = mysql_num_rows ($res);
    $cols = mysql_num_fields ($res);
    $show = 0;
    for ($i = 0; $i < $rows; $i ++) {
       $row = mysql_fetch_row ($res);
       if ($row[$cols - 1] > 30) { continue; }
       if ($show == 1) {
         print ";";
       } else {
	 $show = 1;
       }
       if ($row[4] == "1"  $row[0] == $_SERVER['REMOTE_ADDR']) {
         print $row[2].",".$row[3].",0";
       } else {
       	 print $row[0].",".$row[1].",".$row[4];
       }
       for ($j = 5; $j < $cols; $j ++) {
         print ",".$row[$j];
       }
    }
    mysql_free_result ($res);
    mysql_close ($db);
?>

here you can see that the game is actually registered:

Like I had mentioned before … line 19 (if ($row[$cols - 1] > 30) { continue; }) in the file you posted blueice has something to do with it, not sure why but it wont show your list if this line of code is not commented out. As duhprey said this line just checks to see if a game has not been updated for the given amount of time … if it hasn’t it won’t be shown in the list. Not sure why its not working as he intended. And actually as I said above the DB is not cleaned up after the server closes. Anyway I came up with a fix for both … with duhprey’s help. Open up the QueryMS.php file … go to line 19 and either delete it or comment it out … then just before the $query = "SELECT ect. call add these two lines of code …

$query = “DELETE FROM MasterServer WHERE (NOW()-updated) > ‘30’;”;
$res = mysql_query ($query);

This will remove any old games that may still be hanging around and your games should now show up in your list … :slight_smile:
Hope this helps.

Actually now that I’m thinking about it, it might of had somthing to do with me having the wrong data type for the “update” field in the DB, it needs to be set for DATETIME. but in any event I like the fix we came up with as it keeps the DB clean and up to date. I’m going to keep it this way.

thanks! that did the trick, it’s working now