<pre><?php
set_time_limit(0);
define('MAXLINE', 1024);	   // how much to read from a socket at a time
define('LISTENQ', 200);		// listening queue
define('PORT', 90);		// the default port to run on
define('FD_SETSIZE', 20);	   // file descriptor set size (max number of 
$serverIP="localhost";
$serverPort=90;
$mysql = mysql_connect("localhost","root","cM27kl");
mysql_select_db("habbo");
function killDaemon()
{
	global $listenfd, $client;
 	socket_close($listenfd);
	$msg = "Daemon going down!\n";
	for ($i = 0; $i < FD_SETSIZE; $i++)
	{
	    if ($client[$i] != null)
	    {
		   socket_write($client[$i], $msg, strlen($msg));
		   socket_close($client[$i]);
	    }
	}
	print "Shutting down the daemon\n";
	exit;
}
function closeClient($i)
{
	global $client, $remote_host, $remote_port;
	print "closing client[$i] ({$remote_host[$i]}:{$remote_port[$i]})\n";
	socket_close($client[$i]);
	$client[$i] = null;
	unset($remote_host[$i]);
	unset($remote_port[$i]);
}
function getUserCount($room) {
	return 0;
}
function sendData($socket, $line) {
	global $client, $remote_host, $remote_port, $listenfd;
	$line = str_replace("\n", chr(13), $line);
	var_dump("# " . $line . "\n##");
	return @socket_write($client[$socket], "# " . $line . chr(13) . "##");
}
function newKey() {
	return "nz3vlinucwjwy4o66zznyolynl6b2pw1uhz8vj3ptwqdolmypmt0oinjqdkpl1xd69tyi9d0ahzviuww46znoylbp1h8jpwdlym0ijdp1d9y90h";
}
$listenfd = socket_create(AF_INET, SOCK_STREAM, 0);
if ($listenfd)
	print "Listening on port " . PORT . "\n";
else
	die("AIEE -- socket died!\n");
socket_setopt($listenfd, SOL_SOCKET, SO_REUSEADDR, 1);
function checkPassword($username, $password) {
	$mysqlquery = "SELECT * FROM `users` WHERE `name` = '" . mysql_real_escape_string($username) . "' AND `password` = '" . strtolower(trim(mysql_real_escape_string($password))) . "' LIMIT 1;";
	$mysqlresult = mysql_query($mysqlquery);
	if($mysqlresult && mysql_num_rows($mysqlresult)) return true;
}
function userExists($username) {
	$mysqlquery = "SELECT * FROM `users` WHERE `name` = '" . mysql_real_escape_string($username) . "' LIMIT 1;";
	$mysqlresult = mysql_query($mysqlquery);
	if($mysqlresult && mysql_num_rows($mysqlresult)) return true;
}
function userObject($username) {
	$mysqlquery = "SELECT * FROM `users` WHERE `name` = '" . mysql_real_escape_string($username) . "' LIMIT 1;";
	$mysqlresult = mysql_query($mysqlquery);
	if(!mysql_num_rows($mysqlresult)) return false;
	$row = mysql_fetch_assoc($mysqlresult);
	$uo = sprintf("name=%s\nemail=%s\nfigure=%s\nbirthday=%s\nphonenumber=+44\ncustomData=%s\nhad_read_agreement=%s\nsex=%s\ncountry=United Kingdom\nhas_special_rights=%s\nbadge_type=%s\n", $row["name"], $row["email"], $row["figure"], $row["birthday"], $row["customdata"], $row["had_read_agreement"], $row["sex"], $row["has_special_rights"], $row["badge_type"]);
	return $uo;
}
function getCredits($username) {
	$mysqlquery = "SELECT `credits` FROM `users` WHERE `name` = '" . mysql_real_escape_string($username) . "' LIMIT 1;";
	$mysqlresult = mysql_query($mysqlquery);
	if(!mysql_num_rows($mysqlresult)) return false;
	$row = mysql_fetch_assoc($mysqlresult);
	return $row["credits"];
}
function getMSG($username) {
	return $username;
}
if (!socket_bind($listenfd, "0.0.0.0", PORT))
{
	socket_close($listenfd);
	die("AIEE -- Couldn't bind!\n");
}
function left($string, $length) {
   return substr($string, 0, $length);
}
function right($string, $length) {
   return substr($string, -$length, $length);
}

socket_listen($listenfd, LISTENQ);
$maxi = -1;
for ($i = 0; $i < FD_SETSIZE; $i++) $client[$i] = null;
$todo = 0;
$todoarray = array();
while(1)
{
	$rfds[0] = $listenfd;
 	for ($i = 0; $i < FD_SETSIZE; $i++) if ($client[$i] != null) $rfds[$i + 1] = $client[$i];
	$nready = socket_select($rfds, $null, $null, null);
	if (in_array($listenfd, $rfds)) {
		print "listenfd heard something, setting up new client\n";
		for ($i = 0; $i < FD_SETSIZE; $i++) {
			if ($client[$i] == null) {
				$client[$i] = socket_accept($listenfd);
				socket_setopt($client[$i], SOL_SOCKET, SO_REUSEADDR, 1);
				socket_getpeername($client[$i], $remote_host[$i], $remote_port[$i]);
				print "Accepted {$remote_host[$i]}:{$remote_port[$i]} as \$client[$i]\n";
				sendData($i, "SECRET_KEY \n7777");
				break;
			}
			if ($i == FD_SETSIZE - 1) {
				trigger_error("too many clients", E_USER_ERROR);
				exit;
			}
		}
		if ($i > $maxi) $maxi = $i;
		if (--$nready <= 0) continue;
	}
	for ($i = 0; $i <= $maxi; $i++) {
		if ($client[$i] == null) continue;
 		if (in_array($client[$i], $rfds)) {
			$nin = socket_read($client[$i], MAXLINE);
			if (!$nin) {
				closeClient($i);
			} else {
				$nin = trim($nin);
				while(strlen($nin) >= 1 && !empty($nin) && $todo <= 30) {
					$theNumber = (int) substr($nin, 0, 4);
					$todoarray[$todo] = substr($nin, 4, $theNumber);
					$nin = right($nin, strlen($nin) - $theNumber - 4);
					$nin = trim($nin);
					$todo++;
				}
				foreach($todoarray as $n) {
				$explodedN = explode(" ", $n);
				switch($explodedN[0]) {
					case "VERSIONCHECK":
						if($explodedN[1] == "client002" || $explodedN[1] = "client003") {
							sendData($i, "ENCRYPTION_OFF");
							sendData($i, "SECRET_KEY \n" . newKey());
						}
						break;
					case "LOGIN":
						if(checkPassword($explodedN[1], $explodedN[2]) == false) {
							sendData($i, "BADNAME");
							closeClient($i);
						} else {
							$username[$i] = $explodedN[1];
						}
						break;
					case "INFORETRIEVE":
						if(checkPassword($explodedN[1], $explodedN[2]) == true) {
							sendData($i, "USEROBJECT\n" . userObject($explodedN[1]));
						}
						break;
					case "APPROVENAME":
						if(userExists(strtolower((string) $explodedN[1])) == true) {
							sendData($i, "BADNAME");
						}
						break;
					case "GETCREDITS":
						sendData($i, "WALLETBALANCE \n" . getCredits($username[$i]));
						sendData($i, "MESSENGERSMSACCOUNT \nnoaccount");
						sendData($i, "MESSENGERREADY \n");
						sendData($i, "MYPERSISTENTMSG \n" . getMSG($username[$i]));
						break;
					case "REGISTER":
						register($explodedN, $i);
						break;
					case "UINFO_MATCH":
						$buffer = trim(substr($n, strpos($n, "/") + 1));
						if(userExists($buffer) == false)
							sendData($i, "NOSUCHUSER MESSENGER\n" . $buffer);
						else
							sendData($i, "MEMBERINFO MESSENGER\n" . $buffer . "\n" . getMSG($buffer) . "\n" . getLastTime($buffer) . "\n" . isOnline($buffer) . "\n" . getFigure($buffer) . getSex($buffer));

						break;
					case "MESSENGER_ASSIGNPERSMSG":
						$buffer = substr($n, strpos($n, " ") + 1);
						assignPersMSG($buffer, $i);
						sendData($i, "MYPERSISTENTMSG\n" . getMSG($i));
						break;
					case "UPDATE":
						update($buffer, $i);
						break;
					case "INITUNITLISTENER":
						sendData($i, "BUSY_FLAT_RESULTS 1\n1/Room Name/Room Owner/open/ekakerros/floor1/" . $serverIP . "/" . $serverPort . "/" . getUserCount(1) . "/null/Room Description");
						sendData($i, "ALLUNITS \nThe Dirty Duck Pub,0,25,localhost/localhost,22009,The Dirty Duck Pub\tpub,1,25,pub_a");
						break;
					case "GETUNITUSERS":
						sendData($i, "UNITMEMBERS ");
						break;
				}
				$todoarray = array();
				$todo = 0;
				}
			}
			if  (--$nready <= 0) break;
		}
	}
	flush();
}
?>