| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570 | 
							- <?php
 
- require_once(realpath(dirname(__FILE__)).'/common.php');
 
- class ClientSocket extends SocketServer {
 
- 	public $connected = array();
 
- 	private $received = array();
 
- 	function onDataReceived($socket,$data) {
 
- 		
 
- 			$socketId = (int)$socket;
 
- 			if(!isset($received[$socketId] )) $received[$socketId] = '';
 
- 			$received[$socketId].= $data;
 
- 			
 
- 			if(substr($received[$socketId],-5)=='<EOF>'){
 
- 				
 
- 				$received[$socketId] = substr($received[$socketId],0,-5);
 
- 				$this->handleData($this->connected[(int)$socket],$received[$socketId]);
 
- 				$received[$socketId] = '';
 
- 			}
 
- 	
 
- 				
 
- 	}
 
- 	function onClientConnected($socket) {
 
- 		$this->log('New client connected: ' . $socket);
 
- 		$client = new ClientDevice();
 
- 		$client->socket= $socket;
 
- 		$client->id= (int)$socket;
 
- 		$client->name = 'Client '.count($this->clients);
 
- 		$this->connected[(int)$socket] = $client;
 
- 	}
 
- 	function onClientDisconnected($socket) {
 
- 		$client = $this->connected[(int)$socket];
 
- 		$this->log($client->type.' - '.$client->location . ' disconnected');
 
- 		unset($this->connected[(int)$socket]);
 
- 		
 
- 		$this->clientdisconnected($client);
 
- 		//$this->sendBroadcast($socket . ' left the room');
 
- 	}
 
- 	
 
- 	function handleData($client,$data){
 
- 		$this->log("Try to parse received data : ".$data);
 
- 		try{
 
- 		$datas = explode('<EOF>',$data);
 
- 		foreach($datas  as $data){
 
- 			
 
- 		$_ = json_decode($data,true);
 
- 		if(!$_) throw new Exception("Unable to parse data : ".$data);
 
- 		
 
- 		if(!isset($_['action'])) $_['action'] = '';
 
- 		$this->log("Parsed action : ".$_['action']);
 
- 		switch($_['action']){
 
- 			case 'TALK':
 
- 				$this->talkAnimate();
 
- 				$this->talk($_['parameter']);
 
- 			break;
 
- 			case 'TALK_FINISHED':
 
- 				$this->muteAnimate();
 
- 			break;
 
- 			case 'EMOTION':
 
- 				$this->emotion($_['parameter']);
 
- 			break;
 
- 			case 'IMAGE':
 
- 				$this->image($_['parameter']);
 
- 			break;
 
- 			case 'SOUND':
 
- 				$this->sound($_['parameter']);
 
- 			break;
 
- 			case 'EXECUTE':
 
- 				$this->execute($_['parameter']);
 
- 			break;
 
- 			case 'CLIENT_INFOS':
 
- 				$client->type = $_['type'];
 
- 				$client->location = $_['location'];
 
- 				$userManager = new User();
 
- 				$myUser = $userManager->load(array('token'=>$_['token']));
 
- 				if(isset($myUser) && $myUser!=false)
 
- 					$myUser->loadRight();
 
- 				$client->user =  (!$myUser?new User():$myUser);
 
- 				$this->log('setting infos '.$client->type.' - '.$client->location.' for '.$client->name.' with user:'.$client->user->getLogin());
 
- 			
 
- 				$this->clientConnected($client);
 
- 				
 
- 			break;
 
- 			case 'GET_SPEECH_COMMANDS':
 
- 				$response = array();
 
- 				Plugin::callHook("vocal_command", array(&$response,YANA_URL));
 
- 				$commands = array();
 
- 				foreach($response['commands'] as $command){
 
- 					unset($command['url']);
 
- 					$this->send($this->connected[$client->id]->socket,'{"action":"ADD_COMMAND","command":'.json_encode($command).'}');
 
- 				}
 
- 				$this->send($this->connected[$client->id]->socket,'{"action":"UPDATE_COMMANDS"}');
 
- 			break;
 
- 			case 'GET_CONNECTED_CLIENTS':
 
- 				$response = array();
 
- 			
 
- 				foreach($this->connected as $id=>$cli){
 
- 					$this->send($this->connected[$client->id]->socket,'{"action":"clientConnected","client":{"type":"'.$cli->type.'","location":"'.$cli->location.'","user":"'.($cli->user!=null && is_object($cli->user)?$cli->user->getLogin():'Anonyme').'"}}');
 
- 				}
 
- 				
 
- 				
 
- 			break;
 
- 			case 'CATCH_COMMAND':
 
- 				$response = "";
 
- 				$this->log("Call listen hook (v2.0 plugins) with params ".$_['command']." > ".$_['text']." > ".$_['confidence']);
 
- 				Plugin::callHook('listen',array($_['command'],trim(str_replace($_['command'],'',$_['text'])),$_['confidence'],$client->user));
 
- 			break;
 
- 			case '':
 
- 			default:
 
- 				//$this->talk("Coucou");
 
- 				//$this->sound("C:/poule.wav");
 
- 				//$this->execute("C:\Program Files (x86)\PuTTY\putty.exe");
 
- 				$this->log($client->name.'('.$client->type.') send '.$data);
 
- 			break;
 
- 		}
 
- 		$this->updateClient($client);
 
- 		}
 
- 		}catch(Exception $e){
 
- 			$this->log("ERROR : ".$e->getMessage());
 
- 		}
 
- 		//system('php '.realpath(dirname(__FILE__)).'\action.php '.$json['action'],$out);
 
- 		//$this->send($socket,$out);
 
- 		
 
- 	}
 
- 	function updateClient($client){
 
- 	
 
- 		$this->connected[$client->id] = $client;
 
- 	}
 
- 	
 
- 	public function sound($message,$clients=array()){
 
- 		if(count($clients)==0)
 
- 			 $clients = $this->getByType('speak');
 
- 		
 
- 		foreach($clients as $client){
 
- 			$socket = $this->connected[$client->id]->socket;
 
- 			$this->send($socket,'{"action":"sound","file":"'.str_replace('\\','/',$message).'"}');
 
- 		}
 
- 	}
 
- 	
 
- 	public function talk($message,$clients=array()){
 
- 		
 
- 		if(count($clients)==0)
 
- 			 $clients = $this->getByType('speak');
 
- 		
 
- 		$this->log("TALK : Try to send ".$message." to ".count($clients)." clients");
 
- 		foreach($clients as $client){
 
- 			$socket = $this->connected[$client->id]->socket;
 
- 			$this->log("send ".'{"action":"talk","message":"'.$message.'"} to '.$client->name);
 
- 			$this->send($socket,'{"action":"talk","message":"'.$message.'"}');
 
- 		}
 
- 	}
 
- 	public function clientConnected($new_client,$clients=array()){
 
- 		
 
- 		if(count($clients)==0)
 
- 			 $clients = $this->getByType('face');
 
- 		
 
- 		//$this->log("CONNECTED : Try to send ".$emotion." to ".count($clients)." clients");
 
- 		foreach($clients as $client){
 
- 			if($client->id == $new_client->id) continue;
 
- 			$socket = $this->connected[$client->id]->socket;
 
- 			$packet = '{"action":"clientConnected","client":{"type":"'.$new_client->type.'","location":"'.$new_client->location.'","user":"'.($new_client->user!=null && is_object($new_client->user)?$new_client->user->getLogin():'Anonyme').'"}}';
 
- 			$this->log("send ".$packet." to ".$client->name);
 
- 			$this->send($socket,$packet);
 
- 		}
 
- 	}
 
- 	public function clientDisconnected($new_client,$clients=array()){
 
- 		
 
- 		if(count($clients)==0)
 
- 			 $clients = $this->getByType('face');
 
- 		
 
- 		//$this->log("CONNECTED : Try to send ".$emotion." to ".count($clients)." clients");
 
- 		foreach($clients as $client){
 
- 			$socket = $this->connected[$client->id]->socket;
 
- 			$packet = '{"action":"clientDisconnected","client":{"type":"'.$new_client->type.'","location":"'.$new_client->location.'"}}';
 
- 			$this->log("send ".$packet." to ".$client->name);
 
- 			$this->send($socket,$packet);
 
- 		}
 
- 	}
 
- 	public function emotion($emotion,$clients=array()){
 
- 		
 
- 		if(count($clients)==0)
 
- 			 $clients = $this->getByType('face');
 
- 		
 
- 		$this->log("EMOTION : Try to send ".$emotion." to ".count($clients)." clients");
 
- 		foreach($clients as $client){
 
- 			$socket = $this->connected[$client->id]->socket;
 
- 			$packet = '{"action":"emotion","type":"'.$emotion.'"}';
 
- 			$this->log("send ".$packet." to ".$client->name);
 
- 			$this->send($socket,$packet);
 
- 		}
 
- 	}
 
- 	public function image($image,$clients=array()){
 
- 		
 
- 		if(count($clients)==0)
 
- 			 $clients = $this->getByType('face');
 
- 		
 
- 		$this->log("IMAGE : Try to send ".$image." to ".count($clients)." clients");
 
- 		foreach($clients as $client){
 
- 			$socket = $this->connected[$client->id]->socket;
 
- 			$packet = '{"action":"image","url":"'.$image.'"}';
 
- 			$this->log("send ".$packet." to ".$client->name);
 
- 			$this->send($socket,$packet);
 
- 		}
 
- 	}
 
- 	public function talkAnimate($clients=array()){
 
- 		
 
- 		if(count($clients)==0)
 
- 			 $clients = $this->getByType('face');
 
- 		
 
- 		$this->log("TALK ANIMATION : Try to send ".$emotion." to ".count($clients)." clients");
 
- 		foreach($clients as $client){
 
- 			$socket = $this->connected[$client->id]->socket;
 
- 			$packet = '{"action":"talk"}';
 
- 			$this->log("send ".$packet." to ".$client->name);
 
- 			$this->send($socket,$packet);
 
- 		}
 
- 	}
 
- 	public function muteAnimate($clients=array()){
 
- 		
 
- 		if(count($clients)==0)
 
- 			 $clients = $this->getByType('face');
 
- 		
 
- 		$this->log("MUTE ANIMATION : Try to send ".$emotion." to ".count($clients)." clients");
 
- 		foreach($clients as $client){
 
- 			$socket = $this->connected[$client->id]->socket;
 
- 			$packet = '{"action":"mute"}';
 
- 			$this->log("send ".$packet." to ".$client->name);
 
- 			$this->send($socket,$packet);
 
- 		}
 
- 	}
 
- 	public function url($message,$clients=array()){
 
- 			echo "Envois de l\'url".$message;
 
- 		if(count($clients)==0)
 
- 			$clients = $this->getByType('speak');
 
- 			if(count($clients)==0) return;
 
- 			foreach($clients as $client){
 
- 			//$client = $clients[0];
 
- 			$socket = $this->connected[$client->id]->socket;
 
- 			$this->log("url ".'{"action":"url","url":"'.$message.'"} to '.$client->name);
 
- 			$this->send($socket,'{"action":"url","url":"'.$message.'"}');
 
- 		}
 
- 		
 
- 	}
 
- 	public function execute($message,$clients=array()){
 
- 		if(count($clients)==0)
 
- 			 $clients = $this->getByType('speak');
 
- 	
 
- 		foreach($clients as $client){
 
- 			$socket = $this->connected[$client->id]->socket;
 
- 			$this->log("send ".'{"action":"execute","command":"'.$message.'"} to '.$client->name);
 
- 			$this->send($socket,'{"action":"execute","command":"'.str_replace('\\','/',$message).'"}');
 
- 		}
 
- 	}
 
- 	
 
- 	public function getByType($type){
 
- 		$clients =array();
 
- 		foreach ($this->connected as $client) 
 
- 			if($client->type == $type) $clients[] = $client;
 
- 		return $clients;
 
- 	}
 
- 	private $lastMessage;
 
- }
 
- 	require_once('constant.php');
 
- 	logs("Launch Program");
 
- 	$client = new ClientSocket('0.0.0.0',SOCKET_PORT,SOCKET_MAX_CLIENTS);
 
- 	$client->start();
 
- 	
 
- class ClientDevice {
 
- 	public $id,$type,$socket,$location,$user;
 
- }
 
- /**
 
-  * Class to handle a sockets server
 
-  * It's abstract class so you need to create another class that will extends SocketServer to run your server
 
-  * 
 
-  * @author Cyril Mazur	www.cyrilmazur.com	twitter.com/CyrilMazur	facebook.com/CyrilMazur
 
-  * @abstract
 
-  */
 
- abstract class SocketServer {
 
- 	/**
 
- 	 * The address the socket will be bound to
 
- 	 * @var string
 
- 	 */
 
- 	protected $address;
 
- 	
 
- 	/**
 
- 	 * The port the socket will be bound to
 
- 	 * @var int
 
- 	 */
 
- 	protected $port;
 
- 	
 
- 	/**
 
- 	 * The max number of clients authorized
 
- 	 * @var int
 
- 	 */
 
- 	protected $maxClients;
 
- 	
 
- 	/**
 
- 	 * Array containing all the connected clients
 
- 	 * @var array
 
- 	 */
 
- 	protected $clients;
 
- 	
 
- 	/**
 
- 	 * The master socket
 
- 	 * @var resource
 
- 	 */
 
- 	protected $master;
 
- 	
 
- 	/**
 
- 	 * Constructor
 
- 	 * @param string $address
 
- 	 * @param int $port
 
- 	 * @param int $maxClients
 
- 	 * @return SocketServer
 
- 	 */
 
- 	public function __construct($address,$port,$maxClients) {
 
- 		$this->address		= $address;
 
- 		$this->port			= $port;
 
- 		$this->maxClients	= $maxClients;
 
- 		$this->clients		= array();
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Start the server
 
- 	 */
 
- 	public function start() {
 
- 		// flush all the output directly
 
- 		ob_implicit_flush();
 
- 		
 
- 		// create master socket
 
- 		$this->master = @socket_create(AF_INET, SOCK_STREAM, 0) or die($this->log('Could not create socket'));
 
- 		// to prevent: address already in use
 
- 		//socket_set_option($this->master, SOL_SOCKET, SO_REUSEADDR, 1) or die($this->log('Could not set up SO_REUSEADDR',true));
 
- 		// bind socket to port
 
- 		@socket_bind($this->master, $this->address, $this->port) or die($this->log('Could not bind to socket',true));
 
- 		
 
- 		// start listening for connections
 
- 		socket_listen($this->master) or die($this->log('Could not set up socket listener'));
 
- 		
 
- 		$this->log('Server started on ' . $this->address . ':' . $this->port);
 
- 		
 
- 		// infinite loop
 
- 		while(true) {
 
- 			// build the array of sockets to select
 
- 			$read	= array_merge(array($this->master),$this->clients);
 
- 			
 
- 			$write = NULL;
 
- 			$except = NULL;
 
- 			$tv_sec = NULL;
 
- 			// if no socket has changed its status, continue the loop
 
- 			socket_select($read,$write,$except,$tv_sec);
 
- 			
 
- 			// if the master's status changed, it means a new client would like to connect
 
- 			if (in_array($this->master,$read)) {
 
- 				
 
- 				// if we didn't reach the maximum amount of connected clients
 
- 				if (sizeof($this->clients) < $this->maxClients) {
 
- 					
 
- 					// attempt to create a new socket
 
- 					$socket = socket_accept($this->master);
 
- 					
 
- 					// if socket created successfuly, add it to the clients array and write message log
 
- 					if ($socket !== false) {
 
- 						$this->clients[] = $socket;
 
- 						
 
- 						if (socket_getpeername($socket,$ip)) {
 
- 							$this->log('New client connected: ' . $socket . ' (' . $ip . ')');
 
- 						} else {
 
- 							$this->log('New client connected: ' . $socket);
 
- 						}
 
- 						
 
- 						$this->onClientConnected($socket);
 
- 						
 
- 					// else display error message to the log console
 
- 					} else {
 
- 						$this->log('Impossible to connect new client',true);
 
- 					}
 
- 				
 
- 				// else tell the client that there is not place available and display error message to the log console
 
- 				} else {
 
- 					$socket = socket_accept($this->master);
 
- 					socket_write($socket,'Max clients reached. Retry later.' . chr(0));
 
- 					socket_close($socket);
 
- 					
 
- 					$this->log('Impossible to connect new client: maxClients reached');
 
- 				}
 
- 				
 
- 				if (sizeof($read) == 1)
 
- 					continue;
 
- 			}
 
- 			
 
- 			// foreach client that is ready to be read
 
- 			foreach($read as $client) {
 
- 				
 
- 				// we don't read data from the master socket
 
- 				if ($client != $this->master) {
 
- 					
 
- 					// read input
 
- 					$input = @socket_read($client, 1024, PHP_BINARY_READ);
 
- 					
 
- 					// if socket_read() returned false, the client has been disconnected
 
- 					if (strlen($input) == 0) {
 
- 						// disconnect client
 
- 						$this->disconnect($client);
 
- 						
 
- 						// custom method called
 
- 						$this->onClientDisconnected($client);
 
- 					
 
- 					// else, we received a normal message
 
- 					} else {
 
- 						$input = trim($input);
 
- 						
 
- 						// special case of a domain policy file request
 
- 						if ($input == '<policy-file-request/>') {
 
- 							$cmd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><cross-domain-policy xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd\"><allow-access-from domain=\"*\" to-ports=\"*\" secure=\"false\" /><site-control permitted-cross-domain-policies=\"master-only\" /></cross-domain-policy>";
 
- 							
 
- 							$this->log('Policy file requested by ' . $client);
 
- 							socket_write($client,$cmd . chr(0));
 
- 							
 
- 						// normal case, standard message
 
- 						} else {
 
- 							// custom method called
 
- 							$this->onDataReceived($client,$input);
 
- 						}
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Stop the server: disconnect all the coonected clients, close the master socket
 
- 	 */
 
- 	public function stop() {
 
- 		foreach($this->clients as $client) {
 
- 			socket_close($client);
 
- 		}
 
- 		
 
- 		$this->clients = array();
 
- 		
 
- 		socket_close($this->master);
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Disconnect a client
 
- 	 * @param resource $client
 
- 	 * @return bool
 
- 	 */
 
- 	protected function disconnect($client) {
 
- 		// close socket
 
- 		socket_close($client);
 
- 		
 
- 		// unset variable in the clients array
 
- 		$key = array_keys($this->clients,$client);
 
- 		unset($this->clients[$key[0]]);
 
- 		
 
- 		$this->log('Client disconnected: ' . $client);
 
- 		
 
- 		return true;
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Send data to a client
 
- 	 * @param resource $client
 
- 	 * @param string $data
 
- 	 * @return bool
 
- 	 */
 
- 	protected function send($client,$data) {
 
- 		@socket_write($client, $data);
 
- 		usleep(100);
 
- 		@socket_write($client, "<EOF>");
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Send data to everybody
 
- 	 * @param string $data
 
- 	 * @return bool
 
- 	 */
 
- 	protected function sendBroadcast($data) {
 
- 		$return = true;
 
- 		foreach($this->clients as $client) {
 
- 			$return = $return && socket_write($client, $data . chr(0));
 
- 		}
 
- 		
 
- 		return $return;
 
- 	}
 
- 	
 
- 	/**
 
- 	 * Method called after a value had been read
 
- 	 * @abstract
 
- 	 * @param resource $socket
 
- 	 * @param string $data
 
- 	 */
 
- 	abstract protected function onDataReceived($socket,$data);
 
- 	
 
- 	/**
 
- 	 * Method called after a new client is connected
 
- 	 * @param resource $socket
 
- 	 */
 
- 	abstract protected function onClientConnected($socket);
 
- 	
 
- 	/**
 
- 	 * Method called after a new client is disconnected
 
- 	 * @param resource $socket
 
- 	 */
 
- 	abstract protected function onClientDisconnected($socket);
 
- 	
 
- 	/**
 
- 	 * Write log messages to the console
 
- 	 * @param string $message
 
- 	 * @param bool $socketError
 
- 	 */
 
- 	public function log($message,$socketError = false) {
 
- 		echo '[' . date('d/m/Y H:i:s') . '] ' . $message;
 
- 		
 
- 		if ($socketError) {
 
- 			$errNo	= socket_last_error();
 
- 			$errMsg	= socket_strerror($errNo);
 
- 			
 
- 			echo ' : #' . $errNo . ' ' . $errMsg;
 
- 		}
 
- 		
 
- 		echo "\n";
 
- 	}
 
- }
 
- function logs($message) {
 
- 		echo '[' . date('d/m/Y H:i:s') . '] ' . $message.PHP_EOL;
 
- 	}
 
- ?>
 
 
  |