All pastes #34945 Raw Edit

itrebal

public text v1 · immutable
#34945 ·published 2005-12-26 23:56 UTC
rendered paste body
#!/usr/local/bin/php -f
<?
error_reporting(2047);
ini_set('display_errors', 1);
include('srv.cls.php');

// Settings
$srv = new server('192.168.1.3',9000,50);
$srv->hello_msg[] = 'Functions:';
$srv->hello_msg[] = '#nick <nickname>';
$srv->hello_msg[] = '#list';

function evaluate($uid){
  global $srv;
  $nick = get_nick($uid);
  $input = $srv->get_input($uid);
  if($input{0} != '#'){
    if(!empty($nick)){
      global_send(date('Y-d-m H:i:s').' ['.get_nick($uid).']: '.$input);
      return true;
    }
    $srv->send($uid, 'Error: You do not have a nick.');
    return true;
  }

  $input = explode(' ', $input, 3);
  $command = substr($input[0], 1);
  $input[1] = empty($input[1])?'':$input[1];
  $input[2] = empty($input[2])?'':$input[2];
  $params = array($input[1], $input[2]);
  switch($command){
  case 'nick':
    if(count($params) == 0){
      $srv->send($uid, 'Error: Nick missing.');
      return false;
    }
    $nick_new = $params[0];
    $nick_old = get_nick($uid);
    for($i = 0;$i <= $srv->active_clients;$i++){
      if($nick_new == get_nick($i)){
	$srv->send($uid, 'Error: Nick already in use.');
	return false;
      }
    }
    set_nick($uid, $nick_new);
    if(empty($nick_old)){
      global_send('['.$nick_new.'] joined the chat.', true, true, $nick_new);
      $srv->send($uid, 'You have joined the chat as ['.$nick_new.'].');
      echo '['.$srv->get_addr($uid).'] is ['.$nick_new."]\n";
      return true;
    }
    global_send('['.$nick_old.'] is now ['.$nick_new.']');
    $srv->send($uid, 'Your nick was changed to ['.$nick_new.']');
    echo '['.$srv->get_addr($uid).'] is now ['.$nick_new."]\n";
    break;
  case 'list':
    if(empty($nick)){
      $srv->send($uid, 'Error: You are not logged in.');
      return false;
    }
    $list = '';
    $users = 0;
    for($i=0;$i <= $srv->active_clients;$i++){
      $nick = get_nick($i);
      if(!empty($nick)){
	$list .= '['.$nick.'] ';
	$users++;
      }
    }
    $list .= $users;
    $srv->send($uid, $list);
    break;
  case 'quit':
    global_send('['.get_nick($uid).'] left the chat.', true, true, get_nick($uid));
    $srv->send($uid, 'You left the chat.');
    $srv->kick($uid);
    break;
  default:
    $srv->send($uid, 'Error: Unknown command.');
  break;
  }
}


function set_nick($i, $name){
  global $srv;
  $srv->clients[$i]['nick'] = $name;
}

function get_nick($i){
  global $srv;
  return isset($srv->clients[$i]['nick']) ? $srv->clients[$i]['nick'] : '';
}
function global_send($what,$loggedin=true,$avoid_user=true,$nick_in=false){
  global $srv;
  for($i=0;$i<=$srv->active_clients;$i++){
    $nick = get_nick($i);
    $send = true;
    if($loggedin){
      if(empty($nick)){
	$send = false;
      }
    }
    if($avoid_user){
      if($nick == $nick_in){
	$send = false;
      }
    }
    if($send){
      $srv->send($i, $what);
    }
  }  
  return true;
}

$srv->run();
?>






<?php
/*                       
*********************************************************************************
*Itrebal Creations PHP Server Class                                             *
*Copyright (C) 2005  Graham Christensen                                         *
*Email itrebal@gmail.com IRC: itrebal@freenode.net AIM: itrebal                 *
*Website: www.itrebal.com                                                       *
*                                                                               *
*This program is free software; you can redistribute it and/or                  *
*modify it under the terms of the GNU General Public License                    *
*as published by the Free Software Foundation; either version 2                 *
*of the License, or any later version.                                          *
*                                                                               *
*This program is distributed in the hope that it will be useful,                *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                 *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                  *
*GNU General Public License for more details.                                   *
*                                                                               *
*You should have received a copy of the GNU General Public License              *
*along with this program; if not, write to the Free Software                    *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.*
*********************************************************************************
*/

class server{
  public $clients;
  public $active_clients;
  public $socket;
  public $ip;
  public $port;
  public $max_clients;
  public $crlf;
  public $version;
  public $run_msg;
  public $hello_msg;
  function server($ip,$port,$max_clients){
    $this->ip             = $ip;
    $this->port           = $port;
    $this->max_clients    = $max_clients;
    $this->clients        = array();
    $this->active_clients = 0;
    $this->socket         = '';
    $this->version        = '1.0.0';
    $this->crlf           = "\r\n";
    set_time_limit(0);
  }     
  function create_socket(){
    $socket = socket_create(AF_INET,SOCK_STREAM,0);
    $port = $this->port;
    while(!@socket_bind($socket,$this->ip,$port)){
      $port++;
    }
    $this->port = $port;
    socket_listen($socket);
    $this->socket = $socket;
  }
  
  function display($echo){
    echo $echo."\n";
  }
  
  function new_client($socket){
    if($this->active_clients < $this->max_clients){
      $this->clients[$this->active_clients] = array();
      $this->set_socket($this->active_clients, socket_accept($socket));
      $this->reset_input($this->active_clients);
      socket_getpeername($this->get_socket($this->active_clients), &$ip,&$port);
      $set = $ip.':'.$port;
      $this->set_addr($this->active_clients, $set);
      //
      //Say hello
      //
      //Loop through and send it
      foreach($this->hello_msg as $line){
	$this->send($this->active_clients, $line);
      }


      $this->socket_setnonblock($this->active_clients);

      //Make the server log happy
      $this->logit('['.$this->get_addr($this->active_clients).'] Connected');
      $this->active_clients++;
    }
  }

  function get_socket($i){
    return $this->clients[$i]['sock'];
  }
  function set_socket($i,$socket){
    $this->clients[$i]['sock'] = $socket;
  }
  function get_addr($i){
    return $this->clients[$i]['address'];
  }
  function set_input($i, $input){
    $this->clients[$i]['input'] = $input;
  }
  function get_input($i){
    return $this->clients[$i]['input'];
  }
  function reset_input($i){
    $this->clients[$i]['input'] = '';
  }
  function read_socket($i){
    if(is_bool(@socket_recv($this->clients[$i]['sock'],$buf,1024,0))){
      return FALSE;
    }else{
      return $buf;
    }
  }
  function kick($i){
    $this->logit('['.$this->get_addr($i).'] disconnected');
    @socket_close($this->clients[$index]['sock']);
    $this->clients[$i] = $this->clients[--$this->active_clients];
    array_pop($this->clients);
  }
  function socket_end(){
    socket_close($this->socket);
  }
  function set_addr($i,$addr){
    $this->clients[$i]['address'] = $addr;
  }
  function socket_setnonblock($i){
    socket_set_nonblock($this->clients[$i]['sock']);
  }
  function send($i,$msg){
    $msg = $msg.$this->crlf;
    @socket_send($this->clients[$i]['sock'],$msg,strlen($msg),0);
  }
  function logit($msg){
    echo '['.date('m/d/Y H:i:s').'] '.$msg."\n";
  }
  function run(){
    $this->create_socket();
    $this->display('Itrebal Creations PHP Server Running on Port '.$this->port);
    while(true){
      $read = array();
      $i = 0;
      $read[0] = $this->socket;
      $clients = $this->clients;
      foreach($clients as $val){
	$read[++$i] = $val['sock'];
      }
      
      $ready = socket_select($read, $write, $except,0);
      
      // Handle new clients
      if(in_array($this->socket,$read)){
	$this->new_client($this->socket);
      }
      // Serve clients
      for($i=0;$i < $this->active_clients;$i++){
	if(in_array($this->get_socket($i),$read)){
	  // Append input
	  $temp = $this->read_socket($i);
	  if(is_bool($temp)){
	    $this->kick($i);
	    continue;
	  }
	  $input = $this->get_input($i).$temp;
	  // Apply backspaces
	  $input = preg_replace("/(^|.)\\x08/","",$input);
	  // IF END OF STRING = <crlf>
	  if(preg_match("/[\\015\\012]{2}$/",$input)){
	    // Kick <crlf> and trailing spaces
	    $input = preg_replace("/[ \\015\\012]+$/","",$input);
	    if($input == ''){
	      $this->reset_input($i);
	    }else{
	      // Evaluate input
	      $this->set_input($i,$input);
	      evaluate($i); //processes the input and decides on the output..The meat
	      $this->reset_input($i);
	    }
	  }else{
	    $this->set_input($i,$input);
	  }
	}
      }
    }
    
    // Close master sockets
    $this->socket_end();
  }
}
?>