phudbase/
phudbase/client/
phudbase/client/css/
phudbase/client/images/colorbox/CVS/
phudbase/client/js/
phudbase/server/
phudbase/server/includes/actions/
phudbase/server/includes/classes/
phudbase/server/includes/classes/GameObjects/
<?php
class GameServer extends SocketServer
{	
	function on_connect($clientID)
	{			
		$cObj = $this->getClientObject($clientID);
		
		// Attempt to read from the socket to catch the handshake from a WebSocket connection (without waiting if nothing's there) //
		@socket_recv($cObj->getSocket(), $input, 2048, MSG_DONTWAIT);
				
		if (substr_count($input, "Upgrade: WebSocket") > 0)
		{
			list($resource,$host,$origin) = $this->getHeaders($input);

			if ($resource == "")
			{
				$resource = WS_RESOURCE;
				$host = WS_HOST;
				$origin = WS_ORIGIN;
			}
			
			$upgrade = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
	           "Upgrade: WebSocket\r\n" .
	           "Connection: Upgrade\r\n" .
	           "WebSocket-Origin: $origin\r\n" .
	           "WebSocket-Location: ws://" . $host . $resource . "\r\n" .
			   "\r\n";				
	
			$cObj->setClientType(GC_WEBSOCKET);
			$cObj->handshake = true;		
			
			socket_write($cObj->getSocket(), $upgrade.chr(0),strlen($upgrade.chr(0)));

			echo "Good handshake for client [$clientID]\n";
		} else {
			$cObj->setClientType(GC_TELNET);
			$cObj->handshake = true;		
					
			$cObj->send("Welcome to Phud!\nType a name for your character and press enter to continue.\r\n");
			
			echo "Client [$clientID] set to GC_TELNET\n";	
		}		
	}
	
	function post_connect($clientID)
	{
		
	}
	
	function on_disconnect($clientID)
	{
		$cObj = $this->getClientObject($clientID);
		
		global $game;
		if (is_object($game) && is_object($cObj) && $cObj->getCharEID() > 0)
		{		
			// Remove the connection from the game object //	
			$char = getCharMem($cObj->getCharEID());		
			echo "Disconnecting: {$char->getName()}\n";
			$game->removeConnection($cObj->getCharEID());
		}
	}
	
	function on_read($client = -1, $data = "")
	{				
		$cObj = $this->getClientObject($client);

		// If this client has NOT sent a handshake request and the server type is GC_WEBSOCKET, //
		// it's a telnet or other attempt, so set the client's type to GC_TELNET as a fallback  //
		// to prevent sending the handshake unnecessarily. //
		if ($this->getClientType() == GC_WEBSOCKET && !$cObj->hasHandshake() && substr_count($data, "Upgrade: WebSocket") == 0)
		{
			$cObj->setClientType(GC_TELNET);
			$cObj->handshake = true;				
		}
		
		// Only parse the input if the client has completed the handshake (for WebSocket clients) or is a Telnet client //		
		if ($cObj->getClientType() == GC_TELNET || ($cObj->getClientType() == GC_WEBSOCKET && $cObj->hasHandshake()))
		{
			// Trim the nasty from WebSocket data (a 0xFF byte appended to every message) //
			if ($cObj->getClientType() == GC_WEBSOCKET)
				$data = substr($data, 0, strlen($data) - 1);
			
			$break = split("\n", $data);
			
			foreach ($break as $i => $temp)
			{				
				$this->parseClientInput($cObj, $temp);			
			}		
		}
	}

	
	// Overall Game Parser //
	function parseClientInput(GameClient $cObject, $cdata)
	{		
		global $game;
		
		$cdata = stripEnds($cdata);
		
		$fSplit = splitOnce($cdata, " ");		

		//echo "Client [{$cObject->getID()}] sends: $cdata\n";
			
		if (!$fSplit) // One word input... //
		{
			$command = $cdata;
			$data = "";
		} else {
			$command = $fSplit[0];
			$data = $fSplit[1];
		}		
	
		// Process user sent commands //
		if (!$cObject->getCharEID() > 0)
		{
			$eid = count($game->getCharacters())+1; // Account for number of rooms, just in case //
			
			$name = htmlentities($command);
			
			$c = new Character($eid, $name,"A loyal citizen of Phud.");				
					
			if (is_object($c))
			{					
				// Set the character's connection info //
				global $game;
				if (is_object($game))
				{
					$cObject->setCharEID($c->getEID());
					$cObject->setLastTime();
					
					$game->addConnection($c->getEID(), $cObject);														
				}
				
				// Send an extra message for WebSocket's sake... No clue why, except that it works //
				if ($this->getClientType() == GC_WEBSOCKET)
					$c->send("");
				
				$c->send("Welcome back to Phud, {$c->getName()}!", "notify");
				
				// Cause the action "look" so the player will see his starting room // 	
				look($c->getEID());
								
				map_Refresh($c);
				
				// Let everyone in the room know to update the room contents area //
				$c->getRoom()->send("{$c->getName()} pops into existence....", "sysmessage", $c->getEID());
				foreach ($c->getRoom()->getCharacters() as $key => $char)
				{
					rc_Update($char);
				}
								
				echo "Logging {$c->getName()} in!\n";				
			}
				
			return true;
			
		} else {
			// Don't let the user spam us //
			if (microtime(true) - $cObject->getLastTime() <= .35) {return true;}
				
			$cObject->setLastTime();
						
			$c = getCharMem($cObject->getCharEID());
			
			if (!is_object($c)) return true;
												
			// Signing out //
			if ($command == "quit")
			{
				$c->send("We hope to see you again soon!", "sysmessage");
				
				if ($c->getConnection()->getClientType() == GC_WEBSOCKET)				
					$c->sendDirect("window.top.client.close();");
					
				$c->setOffline();		
										
				return true;		
			}
		
			if (trim($command) == "")
			{			
				$c->send("Do nothing on your own time...", "notify");
				return true;
			} else {			
				$command = strtolower($command);
								
				if ($command == "say")
				{
					say($c->getEID(), $data);
					return true;
				}		
				
				if ($command == "look" || $command == "ql" || $command == "l")
				{
					look($c->getEID());
					return true;
				}
				
				if ($command == "nw" || $command == "n" || $command == "ne"	|| 
					$command == "w" || $command == "e" || 
					$command == "sw" || $command == "s" || $command == "se")
				{
					// Wanna send the command, as there is no data //
					move($c->getEID(), $command);
					return true;
				}
			}
		}		
	}
	
}
?>