codice:
// Crea un'array che conterrà la socket del server
$socket_array = array($socket);
// Entra in loop infinito
while(1) {
// Crea l'array delle socket da controllare
$tmparray = array_merge($socket_array, $_CLIENTS_SOCK);
// Controlla se nelle socket ci sono dati disponibili
$num = socket_select($tmparray, $w = NULL, $e = NULL, 0, 10);
// Se si
if ($num > 0) {
// Cicla la lista delle socket con dati disponibili
foreach($tmparray as $sock) {
// Controlla se la socket selezionata corrisponde alla socket del server
if ($sock === $socket) {
// Controlla se il numero di utenti
if (count($_CLIENTS_SOCK) >= $_CONFIG['max_users']) {
// Se si, accetta la socket
$new_sock = socket_accept($socket);
// Invia un messaggio
sock_write($new_sock, "Numero massimo di utenti raggiunto");
// Chiude la socket
socket_close($new_sock);
// Scarica la socket
unset($new_sock);
// Continua il ciclo
continue;
}
// Controlla se riesce ad accettare la socket
if ($new_sock = socket_accept($socket)) {
$tmpnum = (int) $new_sock;
// Estrae HOST e PORTA di provenienza
socket_getpeername($new_sock, $host, $port);
// Inserisce le informazioni negli array
$_CLIENTS_SOCK[$tmpnum] = &$new_sock;
$_CLIENTS_INFO[$tmpnum] = array(
'host' => $host,
'port' => $port,
'key' => $tmpnum,
'buffer' => '',
'state' => STATE_CONNECTED,
'is_reg' => FALSE
);
$_CLIENTS_NICK[$tmpnum] = '';
// Invia il messaggio di entrata alla socket
sock_write($new_sock, "Nickname: ", FALSE);
// Elimina i riferimenti inutili
unset($tmpnum);
unset($new_sock);
} else {
// Errore, quindi muore
die("Errore durante l'accettazione di una socket!\n" . socket_strerror(socket_last_error()) . "[" . socket_last_error() . "]\n");
}
} else {
// Legge i dati dalla socket
$buf = socket_read($sock, 512);
// Controlla se la connessione è chiusa o ha dato errore
if ($buf == FALSE) {
// Essendo chiusa fa disconnettere l'utente
quit_user($sock);
break;
} elseif($buf == '') {
// Ha dato errore, quindi esce
die("Errore durante la ricezione dei dati\n" . socket_strerror(socket_last_error()) . "[" . socket_last_error() . "]\n");
}
$tmpnum = (int) $sock;
// Aggiunge i dati appena letti al buffer della socket
$_CLIENTS_INFO[$tmpnum]['buffer'] .= $buf;
// Controlla se l'ultimo carattere è \n
if ($buf{strlen($buf)-1} == "\n") {
// Se si controlla lo stato in cui si trova l'utente
switch($_CLIENTS_INFO[$tmpnum]['state']) {
case STATE_CONNECTED:
// Elimina gli ultimi caratteri inutili
$_CLIENTS_INFO[$tmpnum]['buffer'] = rtrim($_CLIENTS_INFO[$tmpnum]['buffer'], " \r\n");
// Riceve il nick, controlla il suo contenuto! Non può contenere spazi.
if (strpos(' ', $_CLIENTS_INFO[$tmpnum]['buffer'])>0) {
sock_write($sock, "Il nickname non può contenere spazi!\nReinserisci il nickname: ", FALSE);
break;
}
// Controlla se il nick non è già in uso
if (in_array($_CLIENTS_INFO[$tmpnum]['buffer'], $_CLIENTS_NICK)) {
sock_write($sock, "Nickname già in uso, scegline un'altro!\nReinserisci il nickname: ", FALSE);
break;
}
// Se tutto va bene imposta il nick
$_CLIENTS_NICK[$tmpnum] = $_CLIENTS_INFO[$tmpnum]['buffer'];
// Controlla se l'utente è registrato
if (user_is_regged($_CLIENTS_NICK[$tmpnum])) {
$_CLIENTS_INFO[$tmpnum]['state'] = STATE_WAITPASS;
sock_write($sock, "Questo nickname è registrato, invia la password!\nPassword: ", FALSE);
break;
}
// Non e' registrato quindi annunzia del nuovo utente
new_user($_CLIENTS_NICK[$tmpnum]);
// Imposta lo stato
$_CLIENTS_INFO[$tmpnum]['state'] = STATE_CANCHAT;
break;
case STATE_WAITPASS:
// Elimina i caratteri inutili
$_CLIENTS_INFO[$tmpnum]['buffer'] = rtrim($_CLIENTS_INFO[$tmpnum]['buffer'], " \r\n");
// Controlla che la password sia corretta
if (!check_user($_CLIENTS_NICK[$tmpnum], $_CLIENTS_INFO[$tmpnum]['buffer'])) {
sock_write($sock, "Password errata!\nBye Bye\n");
quit_user($sock, FALSE);
break;
}
// Tutto ok, quindi annunzia il nuovo utente
new_user($_CLIENTS_NICK[$tmpnum]);
// Imposta alcune informazioni
$_CLIENTS_INFO[$tmpnum]['state'] = STATE_CANCHAT;
$_CLIENTS_INFO[$tmpnum]['is_reg'] = TRUE;
break;
case STATE_CANCHAT:
// Controlla se l'utente sta chiedendo un messaggio privato
if (preg_match("/^\/PVT ?([^ ]+) (.+)/i", $_CLIENTS_INFO[$tmpnum]['buffer'], $tmparr)) {
privatechat_user($sock, $tmparr[1], $tmparr[2]);
break;
}
// Controlla se sta chiedendo la disconnessione
if (preg_match("/^\/EXIT/i", $_CLIENTS_INFO[$tmpnum]['buffer'], $tmparr)) {
quit_user($sock);
break;
}
// Controlla se sta chiedendo di uccidere il server (solo per i registrati)
if (preg_match("/^\/QUIT/i", $_CLIENTS_INFO[$tmpnum]['buffer'], $tmparr) && $_CLIENTS_INFO[$tmpnum]['is_reg']) {
chat_user($sock, "Chisura del server in corso");
echo "Chiusura del server in corso";
die();
break;
}
// Dato che non è nessuno di questi, vuol dire che è chat ed invia il messaggio
chat_user($sock, $_CLIENTS_INFO[$tmpnum]['buffer']);
break;
}
// Svuota il buffer
$_CLIENTS_INFO[$tmpnum]['buffer'] = '';
}
}
}
}
}
?>
Credo che qui i commenti parlino da soli