a removeChild block opera on iframe stream, removed
[brisk.git] / web / Obj / brisk.phh
index 1ff1f9f..f38b504 100644 (file)
@@ -2,7 +2,7 @@
 /*
  *  brisk - brisk.phh
  *
- *  Copyright (C) 2006-2011 Matteo Nastasi
+ *  Copyright (C) 2006-2012 Matteo Nastasi
  *                          mailto: nastasi@alternativeoutput.it 
  *                                  matteo.nastasi@milug.org
  *                          web: http://www.alternativeoutput.it
@@ -45,9 +45,13 @@ define('COMM_GEN_N', 50);
 
 define('CHAT_N', 3);
 define('CHAT_ILL_TIME', 6);
+define('CHAT_ENABLED', TRUE);
 
 define('SESS_LEN', 13);
 define('STREAM_TIMEOUT', 60);
+/* FIXME: move to sac-a-push .phh */
+/* TIME_RD define the server-side timeout, after half of it a ping request
+   is sent to client, after this time the client is log out */
 define('EXPIRE_TIME_RD', 180);
 define('EXPIRE_TIME_SMAMMA', 360);
 define('EXPIRE_TIME_WAG', 10);
@@ -136,10 +140,10 @@ $mlang_brisk = array( 'btn_backstand'=> array( 'it' => 'torna in piedi',
 $G_lng = langtolng($G_lang);
 
 $G_all_points = array( 11,10,4,3,2, 0,0,0,0,0 );
-$G_brisk_version = "3.6.3";
+$G_brisk_version = "4.3.0";
 
 /* MLANG: ALL THE INFO STRINGS IN brisk.phh */
-$root_wellarr = array( 'it' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: nuovo sistema di evidenziazione degli utenti registrati.',
+$root_wellarr = array( 'it' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: adottato sac-a-push come motore per l\'invio dei dati in tempo reale, nuovo trasporto httpfile per explorer, tanti bug fixati, freeze su disco, fix del calcolo dei punti, nuovo stream dati xhr.',
                                        'Se vuoi iscriverti alla <a target="_blank" href="mailto:ml-briscola+subscribe@milug.org">Mailing List</a>, cliccala!' ),
                        'en' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NEWS</b>: usage of reader/writer locking instead of generic exclusive locking.',
                                        'If you want to subscribe our <a target="_blank" href="ml-briscola+subscribe@milug.org">Mailing List</a>, click it!' ) );
@@ -282,7 +286,7 @@ Copyright 2006-2012 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nasta
   declaration briscola in ajax sauce <b>(Beta)</b>
 </div>
 <br><b>version '.$G_brisk_version.'</b><br><br>
-Copyright 2006-2009 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>');
+Copyright 2006-2012 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>');
 
 function mop_flush()
 {
@@ -292,6 +296,13 @@ function mop_flush()
     flush();
 }
 
+function force_no_cache(&$header_out)
+{
+    $header_out['Pragma'] = 'no-cache, must-revalidate';
+    $header_out['Cache-Control'] = 'no-cache';
+    $header_out['Expires'] = '-1';
+}
+
 function file_lock($fname, $is_exclusive)
 {
     if (($res = @fopen($fname, "r+")) == FALSE) {
@@ -659,579 +670,51 @@ class Table {
 } // end class Table
 
 
-// User flags
-define('USER_FLAG_AUTH',     0x02);
-
-define('USER_FLAG_MAP_AUTH', 0x0c);
-define('USER_FLAG_LISTAUTH', 0x04);
-define('USER_FLAG_ISOLAUTH', 0x08);
-
-define('USER_FLAG_DBFAILED', 0x10);
-
-//   user status
-define('USER_FLAG_S_NORM',  0x000); // done
-define('USER_FLAG_S_PAU',   0x100); // done
-define('USER_FLAG_S_OUT',   0x200); // done
-define('USER_FLAG_S_DOG',   0x300); // done
-define('USER_FLAG_S_EAT',   0x400); // done
-define('USER_FLAG_S_WRK',   0x500); // done
-define('USER_FLAG_S_SMK',   0x600); // done
-define('USER_FLAG_S_EYE',   0x700); // done
-define('USER_FLAG_S_RABB',  0x800); // done
-define('USER_FLAG_S_SOCC',  0x900); // done
-define('USER_FLAG_S_BABY',  0xa00); // done
-define('USER_FLAG_S_MOP',   0xb00); // done
-
-define('USER_FLAG_S_ALL',   0xf00); // done
-
-/* type of user normal, supporter etc ... */
-define('USER_FLAG_TY_ALL',     0xff0000); // done
-define('USER_FLAG_TY_NORM',    0x010000); // done
-define('USER_FLAG_TY_SUPER',   0x020000); // done
-//  ... other usefull status ...
-define('USER_FLAG_TY_SUSPEND', 0x400000); // done
-define('USER_FLAG_TY_DISABLE', 0x800000); // done
-
-// 240 is the right value, 600 is for fwrite error test
-define('RD_ENDTIME_DELTA',  240);
-define('RD_KEEPALIVE_TOUT',   4);
-
-class User {
-  var $idx;        // index in the users array when you are in game
-  var $idx_orig;   // index in the users array when you aren't in game
-  var $code;       // authentication code
-  var $name;       // name of the user
-  var $sess;       // session of the user
-  var $ip;         // ip of the user
-  var $lacc;       // last access (for the cleanup)
-  var $laccwr;     // last access (for the cleanup)
-  var $bantime;    // timeout to temporary ban
-  var $stat;       // status (outdoor, room, table, game, ...)
-  var $subst;      // substatus for each status   
-  var $step;       // step of the current status
-  var $trans_step; // step to enable transition between pages (disable == -1)
-
-  var $rd_socket;  // socket handle of push stream
-  var $rd_endtime; // end time for push stream
-  var $rd_stat;    // actual status of push stream
-  var $rd_subst;   // actual substatus of push stream
-  var $rd_step;    // actual step of push stream
-  var $rd_from;    // referer
-  var $rd_scristp; // current script step (for each session) 
-  var $rd_kalive;  // if no message are sent after RD_KEEPALIVE_TOUT secs we send a keepalive from server
-  var $rd_cache;   // place where store failed fwrite data
-
-  var $comm;       // commands array
-  // var $asta_card;  // 
-  // var $asta_pnt;   //
-  // var $handpt;     // Total card points at the beginning of the current hand.
-  // var $exitislock; // Player can exit from the table ?
-
-  // FIXME: the table_orig field must be removed after table field verify of index management (in spawned table
-  //        it is allways ZERO
-  var $table;      // id of the current table when you are in game
-  var $table_orig; // id of the current table when you aren't in game
-  var $table_pos;  // idx on the table
-  var $table_token;// token that identify a game on a table
-  var $flags;      // Bitfield with: AUTHENTICATE: 0x02 
-  var $the_end;    // Flag to change the end of the session
-
-  var $chat_lst;      // Last chat line
-  var $chattime;      // Array of chat times
-  var $chat_cur;      // Current chat line number
-  var $chat_ban;      // Time for ban chat
-  var $chat_dlt;      // Delta t for ban
-  var $shm_sz;
-
-  function User() {
-  }
-
-  function create($idx, $name, $sess, $stat = "", $subst = "", $table = -1, $ip="0.0.0.0") {
-    if (($thiz = new User()) == FALSE)
-      return (FALSE);
-
-    $thiz->idx        = $idx;
-    $thiz->idx_orig   = $idx;
-    $thiz->code       = -1;
-    $thiz->name       = $name;
-    $thiz->sess       = $sess;
-    $thiz->ip         = $ip;
-    $thiz->lacc       = time();
-    $thiz->laccwr     = time();
-    $thiz->bantime    = 0;
-    $thiz->stat       = $stat;
-    $thiz->subst      = $subst;
-    $thiz->step       = 1;
-    $thiz->trans_step = -1;
-    $thiz->comm       = array();
-
-    $thiz->rd_socket  = NULL;
-    $thiz->rd_endtime = -1;
-    $thiz->rd_stat    = -1;
-    $thiz->rd_subst   = "";
-    $thiz->rd_step    = -1;
-    $thiz->rd_from    = "";
-    $thiz->rd_scristp = -1;
-    $thiz->rd_kalive  = -1;
-    $thiz->rd_cache   = "";
-
-    $thiz->asta_card  = -2;
-    $thiz->asta_pnt   = -1;
-    $thiz->handpt     = -1;
-    $thiz->exitislock = TRUE;
-
-    $thiz->flags      = 0x00;
-    
-    $thiz->chattime   = array_fill(0, CHAT_N, 0);
-    $thiz->chat_cur   = 0;
-    $thiz->chat_lst   = "";
-    $thiz->chat_ban   = 0;
-    $thiz->chat_dlt   = 0;
-
-    $thiz->table_orig = $table;
-    $thiz->table      = $table;
-    $thiz->table_pos  = -1;
-    $thiz->table_token= "";
-    $thiz->shm_sz = SHM_DIMS_U_MIN;
-    return ($thiz);
-  }
-
-  function copy($from)
-  {
-    $this->idx        = $from->idx;
-    $this->idx_orig   = $from->idx;
-    $this->code       = $from->code;
-    $this->name       = $from->name;
-    $this->sess       = $from->sess;
-    $this->ip         = $from->ip;
-    $this->lacc       = $from->lacc;
-    $this->laccwr     = $from->laccwr;
-    $this->bantime    = $from->bantime;
-    $this->stat       = $from->stat;
-    $this->subst      = $from->subst;
-    $this->step       = $from->step;
-    $this->trans_step = $from->trans_step;
-    $this->comm       = array();
-
-    $i_start = (1 > ($from->step - COMM_N) ? 1 : ($from->step - COMM_N)); 
-    for ($i = $i_start ; $i < $from->step ; $i++) {
-        $ii = $i % COMM_N;
-        if (isset($from->comm[$ii])) {
-            $this->comm[$ii] = $from->comm[$ii];
-        }
-    }
-    $this->asta_card  = $from->asta_card;
-    $this->asta_pnt   = $from->asta_pnt;
-    $this->handpt     = $from->handpt;
-    $this->exitislock = $from->exitislock;
-
-    $this->flags      = $from->flags;
-
-    $this->chattime   = array();
-    for ($i = 0 ; $i < CHAT_N ; $i++)
-      $this->chattime[$i] = $from->chattime[$i];
-    $this->chat_cur   = $from->chat_cur;
-    $this->chat_lst   = $from->chat_lst;
-    $this->chat_ban   = $from->chat_ban;
-    $this->chat_dlt   = $from->chat_dlt;
-
-    $this->table_orig = $from->table_orig;
-    $this->table      = $from->table;
-    $this->table_pos  = $from->table_pos;
-    $this->table_token = $from->table_token;
-    $this->the_end    = $from->the_end;
-    $this->shm_sz     = $from->shm_sz;
-    return (TRUE);
-  }
-
-
-  function myclone($from)
-  {
-    if (($thiz = new User()) == FALSE)
-      return (FALSE);
-    
-    $thiz->copy($from);
-
-    return ($thiz);
-  }
-  
-  function spawn($from, $table, $table_pos)
-  {
-    if (($thiz = new User()) == FALSE)
-      return (FALSE);
-    
-    $thiz->idx        = $from->idx;
-    $thiz->idx_orig   = $from->idx;
-    $thiz->code       = $from->code;
-    $thiz->name       = $from->name;
-    $thiz->sess       = $from->sess;
-    $thiz->ip         = $from->ip;
-    $thiz->lacc       = $from->lacc;
-    $thiz->laccwr     = $from->laccwr;
-    $thiz->bantime    = $from->bantime;
-    $thiz->stat       = $from->stat;
-    $thiz->subst      = $from->subst;
-    $thiz->step       = $from->step;
-    $thiz->trans_step = $from->trans_step;
-    $thiz->comm       = array();
-
-    /*
-    $i_start = (1 > ($from->step - COMM_N) ? 1 : ($from->step - COMM_N)); 
-    for ($i = $i_start ; $i < $from->step ; $i++) {
-      log_wr("TRY PUSH:".$i);
-      $ii = $i % COMM_N;
-      $thiz->comm[$ii]   = $from->comm[$ii];
-    }
-    */
-    $thiz->asta_card  = $from->asta_card;
-    $thiz->asta_pnt   = $from->asta_pnt;
-    $thiz->handpt     = $from->handpt;
-    $thiz->exitislock = $from->exitislock;
-    $thiz->the_end    = $from->the_end;
-
-    $thiz->flags      = $from->flags;
-
-    $thiz->chattime   = array_fill(0, CHAT_N, 0);
-    $thiz->chat_cur   = 0;
-    $thiz->chat_lst   = "";
-    $thiz->chat_ban   = 0;
-    $thiz->chat_dlt   = 0;
-
-
-    $thiz->table_orig = $table;
-    $thiz->table      = 0;
-    $thiz->table_pos  = $table_pos;
-    $thiz->table_token = $from->table_token;
-    $thiz->shm_sz      = $from->shm_sz;
-
-    return ($thiz);
-  }
-
-  function rd_data_set($curtime, $stat, $subst, $step, $from)
-  {
-      $this->rd_endtime = $curtime + RD_ENDTIME_DELTA;
-      $this->rd_stat    = $stat;
-      $this->rd_subst   = $subst;
-      $this->rd_step    = $step;
-      $this->rd_from    = $from;
-      $this->rd_scristp = 0;
-      $this->rd_kalive  = $curtime + RD_KEEPALIVE_TOUT;
-  }
-
-  function rd_socket_get() {
-      return ($this->rd_socket);
-  }
-
-  function rd_socket_set($sock) {
-      $this->rd_socket = $sock;
-  }
-
-  function rd_kalive_get()
-  {
-      return ($this->rd_kalive);
-  }
-
-  function rd_kalive_set($tm)
-  {
-      $this->rd_kalive = $tm;
-  }
-
-  function rd_kalive_is_expired($tm)
-  {
-      // printf("rd_kalive %d tm %d\n", $this->rd_kalive, $tm);
-      return ($this->rd_kalive < $tm);
-  }
-
-  function rd_endtime_is_expired($tm)
-  {
-      // printf("rd_endtime %d tm %d\n", $this->rd_kalive, $tm);
-      return ($this->rd_endtime < $tm);
-  }
-
-  function rd_kalive_reset($tm)
-  {
-      $this->rd_kalive = $tm + RD_KEEPALIVE_TOUT;
-  }
-
-  function rd_cache_get()
-  {
-      return ($this->rd_cache);
-  }
-
-  function rd_cache_set($cache)
-  {
-      $this->rd_cache = $cache;
-  }
-
-  function idx_get() {
-      return ($this->idx);
-  }
-
-  function code_get() {
-      return ($this->code);
-  }
-  
-  function stat_set($stat) {
-    log_main("sess: [".$this->sess. "] NEW STAT: [".$stat."]"); 
-    $this->stat = "$stat";
-    
-    /*
-    if (validate_sess($this->sess)) {
-      if (file_exists(PROXY_PATH) == FALSE)
-        mkdir(PROXY_PATH, 0775, TRUE);
-      $fp = @fopen(PROXY_PATH."/".$this->sess.".stat", 'w');
-      fwrite($fp, sprintf("%s\n",$this->stat));
-      fclose($fp);
-    }
-    */
-  }
-
-  function step_set($step) 
-  {
-      $this->step = $step & 0x7fffffff;
-      
-      return (TRUE);
-  }
-
-  function step_inc($delta = 1) {
-      $this->step += $delta;
-      /* modularization because unpack() not manage unsigned 32bit int correctly */
-      $this->step &= 0x7fffffff;
-      
-      return TRUE;
-  }
-
-
-  function save_step() 
-  {
-      do {
-          if (validate_sess($this->sess) == FALSE)
-              break;
-          if (file_exists(PROXY_PATH) == FALSE)
-              mkdir(PROXY_PATH, 0775, TRUE);
-          if (($fp = @fopen(PROXY_PATH."/".$this->sess.".step", 'w')) == FALSE)
-              break;
-          fwrite($fp, pack("LL",$this->step, $this->idx));
-          fclose($fp);
-          
-          log_main("step_set [".$this->sess. "] [".$this->step."]"); 
-          
-          return (TRUE);
-      } while (0);
-      
-      return (FALSE);
-  }
-  
-  static function load_step($sess) 
-  {
-      $fp = FALSE;
-      do {
-          if (validate_sess($sess) == FALSE)
-              break;
-          
-          if (file_exists(PROXY_PATH) == FALSE)
-              mkdir(PROXY_PATH, 0775, TRUE);
-          if (($fp = @fopen(PROXY_PATH."/".$sess.".step", 'rb')) == FALSE)
-              break;
-          if (($s = fread($fp, 8)) == FALSE)
-              break;
-          if (mb_strlen($s, "ASCII") != 8)
-              break;
-          $arr = unpack('Ls/Li', $s);
-          fclose($fp);
-          
-          // log_rd2("A0: ".$arr[0]."  A1: ".$arr[1]);
-          return ($arr);
-      } while (0);
-      
-      if ($fp != FALSE)
-          fclose($fp);
-      
-      log_rd2("STEP_GET [".$sess."]: return false ");
-      
-      return (FALSE);
-  }
-
-  static function unproxy_step($sess) {
-      log_rd2("UNPROXY: ".PROXY_PATH."/".$sess.".step");
-      if (file_exists(PROXY_PATH) == FALSE)
-          return;
-      @unlink(PROXY_PATH."/".$sess.".step");
-  }
-
-  function reset() {
-    $curtime = time();
-    log_legal($curtime, 'xxx', $this, "STAT:LOGOUT", '');
-
-    $tmp_sess = $this->sess;
-    $this->sess = "";
-    self::unproxy_step($tmp_sess);
-    $this->name = "";  // OK here
-    while (array_pop($this->comm) != NULL);
-    $this->step = 0;
-    $this->chattime = array_fill(0, CHAT_N, 0);
-    $this->chat_cur = 0;
-    $this->chat_lst = "";
-    $this->chat_ban = 0;
-    $this->chat_dlt = 0;
-    $this->the_end = FALSE;
-  }
-
-  static function load_data($id, $sess) 
-  {
-      log_main("load_data: id [".$id."] sess [".($sess == FALSE ? "FALSE" : $sess)."] ");
-      
-      do {
-          if (($tok = @ftok(FTOK_PATH."/user".$id, "B")) == -1) {
-              log_main("ftok failed");
-              break;
-          }
-          
-          if (($shm_sz = sharedmem_sz($tok)) == -1) {
-              log_main("shmop_open failed");
-          }
-          
-          if ($shm_sz == -1)
-              $shm_sz = SHM_DIMS_U_MIN;
-          
-          if ($shm = shm_attach($tok, $shm_sz)) {
-              if (($user = @shm_get_var($shm, $tok)) == FALSE) {
-                  break;
-              }
-              if ($sess != FALSE && $user->sess != $sess) {
-                  break;
-              }
-              log_only("user ==  ".($user == FALSE ?   "FALSE" : "TRUE")."  user ===  ".($user === FALSE ? "FALSE" : "TRUE")."  user isset ".(isset($user) ?   "TRUE" : "FALSE"));
-              
-              if ($user == FALSE) {
-                  log_only("INIT MAIN DATA");
-                  
-                  // SHSPLIT FIXME: init_data for User class ??
-                  $user = User::create($id, "", "");
-                  if (@shm_put_var($shm, $tok, $user) == FALSE) {
-                      log_only("PUT_VAR FALLITA ".strlen(serialize($user)));
-                      log_only(serialize($user));
-                  }
-                  log_shme("User::save_data2");
-              }
-              else {
-                  if ($sess != FALSE) {
-                      /*
-                       *  NOTE:  this part is for check only, theoretically 
-                       *         user->step anch proxy_step are set allways at the same value
-                       */
-                      $old_step = $user->step;
-                      $arr = User::load_step($sess);
-                      $user->step = $arr['s'];
-                      if ($old_step != $user->step) {
-                          log_crit("steps are diffetents User->step ".$user->step." Old_step: ".$old_step);
-                      }
-                  }
-              }
-              $user->shm_sz = $shm_sz;
-              
-              shm_detach($shm);
-          }
-          
-          //  
-          // SHSPLIT: load users from the shared memory
-          //
-          return ($user);
-      } while (0);
-      
-      return (FALSE);
-  }
-  
-
-  static function save_data($user, $id) 
-  {
-      GLOBAL $sess;
-      
-      $shm =   FALSE;
-      
-      if (($tok = @ftok(FTOK_PATH."/user".$id, "B")) == -1) {
-          return (FALSE);
-      }
-      while ($user->shm_sz < SHM_DIMS_U_MAX) {
-          if (($shm = shm_attach($tok, $user->shm_sz)) == FALSE)
-              break;
-          
-          // log_only("PUT_VAR DI ".strlen(serialize($user)));
-          if (@shm_put_var($shm, $tok, $user) != FALSE) {
-              shm_detach($shm);
-              if ($user->sess != "")
-                  $user->save_step();
 
-              log_shme("User::save_data");
 
-              log_main("User[".$id."] saved.");
-              return (TRUE);
-          }
-          if (shm_remove($shm) === FALSE) {
-              log_only("REMOVE FALLITA");
-              break;
-          }
-          shm_detach($shm);
-          $user->shm_sz += SHM_DIMS_U_DLT;
-      } 
-      
-      if ($shm)
-          shm_detach($shm);
-      
-      return (FALSE);
-  }
-
-  function myname_innerHTML()
-  {
-      $class_id = ($this->flags & USER_FLAG_AUTH) + 1;
-      
-      return (sprintf('$("myname").innerHTML = "<span class=\"au%d\">%s</span>";', $class_id, 
-                      xcape($this->name,ENT_COMPAT,"UTF-8")));
-  }
-
-} // end class User
-
-
-
-class Room {
+class Room
+{
     static $delta_t;
-
-  var $user;
-  var $table;
-  var $comm; // commands for many people
-  var $step; // current step of the comm array
-  // externalized var $garbage_timeout;
-  var $shm_sz;
-
-  function Room () {
-    $this->user = array();
-    $this->table = array();
-
-    for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
-        $this->user[$i] = User::create($i, "", "");
-    }
-
-    for ($i = 0 ; $i < TABLES_N ; $i++) {
-      $this->table[$i] = Table::create($i);
-      /* OLD METHOD
-      if ($i < 12) {
-        $row = ( (((int)($i / 4)) % 2) == 0 );
-        $col = ($i % 2 == 0);
-        $this->table[$i]->auth_only = (($row && $col) || (!$row && !$col));
-      }
-      else {
-        $this->table[$i]->auth_only = FALSE;
-      }
-      */
-      if ($i < TABLES_AUTH_N) 
-        $this->table[$i]->auth_only = TRUE;
-      else
-        $this->table[$i]->auth_only = FALSE;
+    
+    var $crystal_filename;
+    var $user;
+    var $table;
+    var $match;
+    var $comm; // commands for many people
+    var $step; // current step of the comm array
+    var $garbage_timeout;
+    var $shm_sz;
+    
+    function Room ($crystal_filename) {
+        $this->crystal_filename = $crystal_filename;
+        $this->user  = array();
+        $this->table = array();
+        $this->match = array();
+        
+        for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
+            $this->user[$i] = User::create($this, $i, "", "");
+        }
+        
+        for ($i = 0 ; $i < TABLES_N ; $i++) {
+            $this->table[$i] = Table::create($i);
+            /* OLD METHOD
+               if ($i < 12) {
+               $row = ( (((int)($i / 4)) % 2) == 0 );
+               $col = ($i % 2 == 0);
+               $this->table[$i]->auth_only = (($row && $col) || (!$row && !$col));
+               }
+               else {
+               $this->table[$i]->auth_only = FALSE;
+               }
+            */
+            if ($i < TABLES_AUTH_N) 
+                $this->table[$i]->auth_only = TRUE;
+            else
+                $this->table[$i]->auth_only = FALSE;
+        }
+        $this->garbage_timeout = 0;
+        $this->shm_sz = SHM_DIMS_MIN;
     }
-    // externalized $this->garbage_timeout = 0;
-    Room::garbage_time_expire_set(0);
-    $this->shm_sz = SHM_DIMS_MIN;
-  }
 
   function garbage_manager($force)
   {
@@ -1244,163 +727,156 @@ class Room {
     /* Garbage collector degli utenti in timeout */
     $curtime = time();
 
-    // externalized if ($force || $this->garbage_timeout < $curtime) {
-    if (!$force && !Room::garbage_time_is_expired($curtime)) {
+    if (!$force && !($this->garbage_timeout < $curtime)) {
         return ($ismod);
     }
       
     webservers_check();
-      // FIXME BRISK4: include for each kind of table
-      require_once("${G_base}briskin5/Obj/briskin5.phh");
-
-      // Before all align times with table timeout
-      for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
+    
+    // Before all align times with table timeout
+    for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
        $table_cur = $this->table[$table_idx];
        // if the table is complete and exists its shared mem we get the info about users lacc
-
+        
        if ($table_cur->player_n == PLAYERS_N) {
-         log_main("PLAYERS == N TABLE ".$table_idx);
-         
-         if (($sem = Bin5::lock_data(TRUE, $table_idx)) != FALSE) { 
-           log_main("bin5 lock data success");
-           
-           $no_recovery = FALSE;
-           if (($bri = Bin5::load_data($table_idx)) != FALSE) {
-             if ($table_cur->table_token != $bri->table_token) {
-               log_main("ERROR: not matching table_token. Room: ".$table_cur->table_token."  Table: ".$bri->table_token);
-               log_main("ERROR: not matching table_start. Room: ".$table_cur->table_start."  Table: ".$bri->table_start);
-               $no_recovery = TRUE;
-               $bri = FALSE;
-             }
-           }
-           
-           if ($bri != FALSE) {
-             //
-             //  SPAWN: JOIN
-             //
-             log_main("garbage_manager: bri loaded successfully.");
-             $bri->garbage_manager(TRUE);
-             
-             $bri_table = $bri->table[0];
-
-             // is the end of the table
-             if ($bri->the_end == TRUE) {
-                  /*
-                *  DESTROY OF FINISHED TABLE && MOVE PLAYER TO ROOM AGAIN
-                */
-               log_main("garbage_manager: INSIDE THE END.");
-
-                $plist = "$table_cur->table_token|$table_cur->idx|$table_cur->player_n";
-                for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
-                  $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
+            log_main("PLAYERS == N TABLE ".$table_idx);
+            
+            
+            $no_recovery = FALSE;
+            if (isset($this->match[$table_idx])) {
+                $bri = $this->match[$table_idx];
+
+                if ($table_cur->table_token != $bri->table_token) {
+                    log_main("ERROR: not matching table_token. Room: ".$table_cur->table_token."  Table: ".$bri->table_token);
+                    log_main("ERROR: not matching table_start. Room: ".$table_cur->table_start."  Table: ".$bri->table_start);
+                    $no_recovery = TRUE;
+                    $bri = FALSE;
                 }
 
-               for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
-                 // stat must be "table" by definition
-                 $user_cur = $this->user[$table_cur->player[$i]];
-                 $bri_user = $bri->user[$i];
-                 
-                 $user_cur->subst      = $bri_user->subst;
-                 $user_cur->step       = $bri_user->step;
-                 $user_cur->lacc       = $bri_user->lacc;
-                 $user_cur->laccwr     = $bri_user->lacc;
-                 $user_cur->bantime    = $bri_user->bantime;
-               }
-
-                log_legal($curtime, 'xxx', $user_cur, "STAT:DESTROY_GAME", $plist);
-
-               $this->room_join_wakeup($user_cur, FALSE, 0); 
-               $table_cur->table_token = "";
-                $table_cur->wakeup_time = $curtime + WAKEUP_TIME;
-                        
-                        $bri->destroy_data($table_idx);
-             }
-             else {
-               log_main("gm:: save_data");
-
-               for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
-                 $this->user[$table_cur->player[$i]]->lacc = $bri->user[$i]->lacc;
-               }
-             
-               Bin5::save_data($bri);
-             }
-           } // else if (($bri = Bin5::load_data($table_idx)) != FALSE) {
-           else if ($no_recovery == FALSE) {
-             log_crit("ERROR: table ".$table_idx." unrecoverable join");
-
-             for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
-               $user_cur = $this->user[$table_cur->player[$i]];
-               $user_cur->subst = "shutdowner";
-               $user_cur->step_inc();
-               
-               $ret = sprintf('stat = "%s"; subst = "%s";',  $user_cur->stat, $user_cur->subst);
-               $ret .= "gst.st = ".($user_cur->step+1)."; ";
-                // MLANG <br>I dati del tavolo n&deg; ".$user_cur->table." sono inconsistenti, verranno resettati.<br><br>Torni in piedi.<br><br>
-                $prestr = sprintf($mlang_brisk['tabincon'][$G_lang], $user_cur->table);
-               $ret .= show_notify($prestr, 2000, $mlang_brisk['btn_close'][$G_lang], 400, 110);
-               $user_cur->comm[$user_cur->step % COMM_N] = $ret;
-               $user_cur->step_inc();
-             }
-
-              $plist = "$table_cur->table_token|$user_cur->table|$table_cur->player_n";
-              for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
-                $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
-              }
-              log_legal($curtime, 'xxx', $user_cur, "STAT:DESTROY_GAME(RECOVERY)", $plist);
-              
-             $this->room_join_wakeup($user_cur, TRUE, -2); 
-             $table_cur->table_token = "";
-           }
 
-           Bin5::unlock_data($sem);
-         } // bri::lock_data
-       } //  if ($table_cur->player_n == PLAYERS_N) {
-      } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
+                if ($bri != FALSE) {
+                    //
+                    //  SPAWN: JOIN
+                    //
+                    log_main("garbage_manager: bri loaded successfully.");
+                    $bri->garbage_manager(TRUE);
+                    
+                    $bri_table = $bri->table[0];
+                    
+                    // is the end of the table
+                    
+                    if ($bri->the_end == TRUE) {
+                        /*
+                         *  DESTROY OF FINISHED TABLE && MOVE PLAYER TO ROOM AGAIN
+                         */
+                        log_main("garbage_manager: INSIDE THE END.");
+                        
+                        $plist = "$table_cur->table_token|$table_cur->idx|$table_cur->player_n";
+                        for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
+                            $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
+                        }
+                        
+                        for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
+                            // stat must be "table" by definition
+                            $user_cur = $this->user[$table_cur->player[$i]];
+                            $bri_user = $bri->user[$i];
+                            
+                            $user_cur->subst      = $bri_user->subst;
+                            $user_cur->step       = $bri_user->step;
+                            $user_cur->lacc       = $bri_user->lacc;
+                            $user_cur->laccwr     = $bri_user->lacc;
+                            $user_cur->bantime    = $bri_user->bantime;
+                        }
+                        
+                        log_legal($curtime, 'xxx', $user_cur, "STAT:DESTROY_GAME", $plist);
+                        
+                        $this->room_join_wakeup($user_cur, FALSE, 0); 
+                        $table_cur->table_token = "";
+                        $table_cur->wakeup_time = $curtime + WAKEUP_TIME;
+                        
+                        $this->match_del($table_idx);
+                    }
+                    else {
+                        log_main("gm:: save_data");
+                        
+                        for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
+                            $this->user[$table_cur->player[$i]]->lacc = $bri->user[$i]->lacc;
+                        }
+                    }
+                } // if ($bri == FALSE
+                else if ($no_recovery == FALSE) {
+                    log_crit("ERROR: table ".$table_idx." unrecoverable join");
+                    
+                    for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
+                        $user_cur = $this->user[$table_cur->player[$i]];
+                        $user_cur->subst = "shutdowner";
+                        $user_cur->step_inc();
+                        
+                        $ret = sprintf('stat = "%s"; subst = "%s";',  $user_cur->stat, $user_cur->subst);
+                        $ret .= "gst.st = ".($user_cur->step+1)."; ";
+                        // MLANG <br>I dati del tavolo n&deg; ".$user_cur->table." sono inconsistenti, verranno resettati.<br><br>Torni in piedi.<br><br>
+                        $prestr = sprintf($mlang_brisk['tabincon'][$G_lang], $user_cur->table);
+                        $ret .= show_notify($prestr, 2000, $mlang_brisk['btn_close'][$G_lang], 400, 110);
+                        $user_cur->comm[$user_cur->step % COMM_N] = $ret;
+                        $user_cur->step_inc();
+                    }
+                    
+                    $plist = "$table_cur->table_token|$user_cur->table|$table_cur->player_n";
+                    for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
+                        $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
+                    }
+                    log_legal($curtime, 'xxx', $user_cur, "STAT:DESTROY_GAME(RECOVERY)", $plist);
+                    
+                    $this->room_join_wakeup($user_cur, TRUE, -2); 
+                    $table_cur->table_token = "";
+                }
+            }
+        } //  if ($table_cur->player_n == PLAYERS_N) {
+    } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
     
-      log_rd2("out new loop.");
-               
-      for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
+    log_rd2("out new loop.");
+    
+    for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
        $user_cur = $this->user[$i];
        
        log_rd2("User: ".$user_cur->name."  stat: ".$user_cur->stat."  subst: ".$user_cur->subst);
-         
+       
        if ($user_cur->sess == "") 
-         continue;
+            continue;
        
        if ($user_cur->lacc + EXPIRE_TIME_RD < $curtime) {
-         // Auto logout dell'utente
-         log_rd2("AUTO LOGOUT.".($user_cur->lacc + EXPIRE_TIME_RD)." curtime ".$curtime);
-         
-         if ($user_cur->stat == 'table' || $user_cur->stat == 'room') {
-           log_auth($user_cur->sess, "Autologout session.");
-           
-           $user_cur->reset();
+            // Auto logout dell'utente
+            log_rd2("AUTO LOGOUT.".($user_cur->lacc + EXPIRE_TIME_RD)." curtime ".$curtime);
+            
+            if ($user_cur->stat == 'table' || $user_cur->stat == 'room') {
+                log_auth($user_cur->sess, "Autologout session.");
+                
+                $user_cur->reset();
            
-           log_rd2("AUTO LOGOUT.");
-           if ($user_cur->subst == 'sitdown' || $user_cur->stat == 'table')
-             $this->room_wakeup($user_cur);
-           else if ($user_cur->subst == 'standup')
-             $this->room_outstandup($user_cur);
-           else
-             log_rd2("LOGOUT FROM WHAT ???");
-         }
+                log_rd2("AUTO LOGOUT.");
+                if ($user_cur->subst == 'sitdown' || $user_cur->stat == 'table')
+                    $this->room_wakeup($user_cur);
+                else if ($user_cur->subst == 'standup')
+                    $this->room_outstandup($user_cur);
+                else
+                    log_rd2("LOGOUT FROM WHAT ???");
+            }
        }
 
        if ($user_cur->laccwr + EXPIRE_TIME_SMAMMA < $curtime) { // lo rimettiamo in piedi
-         if ($user_cur->stat == 'room' && $user_cur->subst == 'sitdown') {
-           $this->room_wakeup($user_cur);
-           $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
-            /* MLANG: <br>Sei stato inattivo per ".(EXPIRE_TIME_SMAMMA/60.0)." minuti. <br><br>Quindi ritorni tra i <b>Giocatori in piedi</b>.", "torna ai tavoli" */
-           $user_cur->comm[$user_cur->step % COMM_N] .=  show_notify($mlang_brisk['tabtout_a'][$G_lang].(EXPIRE_TIME_SMAMMA/60.0).$mlang_brisk['tabtout_b'][$G_lang], 0, $mlang_brisk['btn_backstand'][$G_lang], 400, 100);
-           $user_cur->step_inc();
-         }
+            if ($user_cur->stat == 'room' && $user_cur->subst == 'sitdown') {
+                $this->room_wakeup($user_cur);
+                $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
+                /* MLANG: <br>Sei stato inattivo per ".(EXPIRE_TIME_SMAMMA/60.0)." minuti. <br><br>Quindi ritorni tra i <b>Giocatori in piedi</b>.", "torna ai tavoli" */
+                $user_cur->comm[$user_cur->step % COMM_N] .=  show_notify($mlang_brisk['tabtout_a'][$G_lang].(EXPIRE_TIME_SMAMMA/60.0).$mlang_brisk['tabtout_b'][$G_lang], 0, $mlang_brisk['btn_backstand'][$G_lang], 400, 100);
+                $user_cur->step_inc();
+            }
        }
-      }
-      log_rd2("GARBAGE UPDATED!");
-      
-      // externalized $this->garbage_timeout = time() + GARBAGE_TIMEOUT;
-      Room::garbage_time_expire_set($curtime + GARBAGE_TIMEOUT);
-      $ismod = TRUE;
+    }
+    log_rd2("GARBAGE UPDATED!");
+    
+    $this->garbage_timeout = $curtime + GARBAGE_TIMEOUT;
+    $ismod = TRUE;
 
     return ($ismod);
   }
@@ -1450,7 +926,8 @@ class Room {
         $ret .= sprintf('tra.rem(%d); ', $i);
     }
     $ret .= $this->standup_content($user);
-    
+    $ret .= "setTimeout(preload_images, 0, g_preload_img_arr, g_imgct); ";
+
     return ($ret);
   }
   
@@ -1510,7 +987,7 @@ class Room {
 
       $ret = "gst.st = ".($user_cur->step+1)."; ".($remove_wagon ? sprintf("tra.rem(%d);",$table_idx) : "");
       if ($from_table && ($user_cur->table == $table_idx || $user->idx_get() == $i)) {
-       $ret .= 'gst.st_loc++; hstm.stop(); window.onunload = null; window.onbeforeunload = null; document.location.assign("index.php");|';
+       $ret .= 'gst.st_loc++; xstm.stop(); window.onunload = null; window.onbeforeunload = null; document.location.assign("index.php");|';
        // $ret .= 'gst.st_loc++; document.location.assign("index.php");|';
        log_main("DOCUMENT.index.php: from table");
       }
@@ -1745,7 +1222,7 @@ class Room {
     $only_you = FALSE;
     
     // common settings
-    $msg = substr($mesg, 6, 128);
+    $msg = mb_substr($mesg, 6, 128, "UTF-8");
     $curtime = time();
     $dt = date("H:i ", $curtime);
     $target = "";
@@ -2005,7 +1482,7 @@ class Room {
 
     else { // normal chat line
       $is_normchat = TRUE;
-      if ($curtime < ($user->chat_ban + $user->chat_dlt)) {
+      if (CHAT_ENABLED && $curtime < ($user->chat_ban + $user->chat_dlt)) {
         $only_you = TRUE;
         $user->chat_dlt = $user->chat_dlt * 2; 
         if ($user->chat_dlt > 120)
@@ -2013,7 +1490,7 @@ class Room {
       }
       else if ($user->chat_lst == $msg)
         $only_you = TRUE;
-      else if ($curtime - $user->chattime[($user->chat_cur + 1) % CHAT_N] < CHAT_ILL_TIME) {
+      else if (CHAT_ENABLED && $curtime - $user->chattime[($user->chat_cur + 1) % CHAT_N] < CHAT_ILL_TIME) {
         $user->chat_ban = $curtime;
         $user->chat_dlt = 5;
         $only_you = TRUE;
@@ -2087,46 +1564,27 @@ class Room {
     }
     
     if ($to_tabl) {
-      // FIXME BRISK4: include for each kind of table
-      require_once("${G_base}briskin5/Obj/briskin5.phh");
-      // Before all align times with table timeout
-      for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
-        $table_cur = $this->table[$table_idx];
-        // if the table is complete and exists its shared mem we get the info about users lacc
-        
-        if ($table_cur->player_n == PLAYERS_N) {
-          log_main("PLAYERS == N TABLE ".$table_idx);
-        
-          if (($sem = Bin5::lock_data(TRUE, $table_idx)) != FALSE) { 
-            log_main("bin5 lock data success");
-            
-            $no_recovery = FALSE;
-            if (($bri = Bin5::load_data($table_idx)) != FALSE) {
-              if ($table_cur->table_token != $bri->table_token) {
-                log_main("ERROR: not matching table_token. Room: ".$table_cur->table_token."  Table: ".$bri->table_token);
-                $bri = FALSE;
-              }
-            }
-            
-            if ($bri != FALSE) {
-              $bri_table = $bri->table[0];
-              for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
-                // stat must be "table" by definition
-                $bri_user = $bri->user[$i];
+        // FIXME BRISK4: include for each kind of table
+        require_once("${G_base}briskin5/Obj/briskin5.phh");
+        // Before all align times with table timeout
+        for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
+            if (isset($this->match[$table_idx])) {
+                $bri = $this->match[$table_idx];
+
+                $bri_table = $bri->table[0];
+                for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
+                    // stat must be "table" by definition
+                    $bri_user = $bri->user[$i];
               
-                if ($target != "" && $bri_user->name != $target)
-                  continue;
-                log_main("writa: ".$user_mesg);
-                $bri_user->comm[$bri_user->step % COMM_N] = "gst.st = ".($bri_user->step+1)."; ";
-                $bri_user->comm[$bri_user->step % COMM_N] .= $to_tabl;
-                $bri_user->step_inc();
-              }
-              Bin5::save_data($bri);
-            }
-            Bin5::unlock_data($sem);
-          } // bri::lock_data
-        } //  if ($table_cur->player_n == PLAYERS_N) {
-      } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
+                    if ($target != "" && $bri_user->name != $target)
+                        continue;
+                    log_main("writa: ".$user_mesg);
+                    $bri_user->comm[$bri_user->step % COMM_N] = "gst.st = ".($bri_user->step+1)."; ";
+                    $bri_user->comm[$bri_user->step % COMM_N] .= $to_tabl;
+                    $bri_user->step_inc();
+                }
+            } // if (isset($this->match
+        } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
     } // if ($to_tabl == true ...
 
     if ($update_room) {
@@ -2179,9 +1637,9 @@ class Room {
    *   if ($idx == -$idx && ret == user)   =>  SUCCESS (but the login exists in the auth db)
    */
 
-  function add_user(&$sess, &$idx, $name, $pass, $ip)
+  function add_user(&$sess, &$idx, $name, $pass, $ip, $cookie)
   {
-    GLOBAL $G_base, $CO_list;
+    GLOBAL $G_base;
 
     $idx = 0;
 
@@ -2262,6 +1720,7 @@ class Room {
 
       $ghost_user = $this->user[$ghost];
       $curtime = time();
+      $ghost_user->comm[$ghost_user->step % COMM_N] = "";
       $ghost_user->step_inc();
       if ($sess == "") {
         $sess = uniqid(""); 
@@ -2274,18 +1733,16 @@ class Room {
       // If user at the table we need to update the table data too
       $table_idx = $ghost_user->table;
       if ($ghost_user->stat == "table" && $this->table[$table_idx]->player_n == PLAYERS_N) {
-        // FIXME BRISK4: include for each kind of table
-        require_once("${G_base}briskin5/Obj/briskin5.phh");
-        if (($brisem = Bin5::lock_data(TRUE, $table_idx)) != FALSE) { 
-          if (($bri = Bin5::load_data($table_idx)) != FALSE) {
-            if ($bri->the_end != TRUE) {
-              $bri->user[$ghost_user->table_pos]->step_inc();
-              $bri->user[$ghost_user->table_pos]->sess = $sess;
-              Bin5::save_data($bri);
-            }
+          require_once("${G_base}briskin5/Obj/briskin5.phh");
+          if (isset($this->match[$table_idx])) {
+              $bri = $this->match[$table_idx];
+
+              if ($bri->the_end != TRUE) {
+                  $bri->user[$ghost_user->table_pos]->comm[$bri->user[$ghost_user->table_pos]->step % COMM_N] = "";
+                  $bri->user[$ghost_user->table_pos]->step_inc();
+                  $bri->user[$ghost_user->table_pos]->sess = $sess;
+              }
           }
-          Bin5::unlock_data($brisem);
-        }
       }
 
       $idx = $ghost;
@@ -2321,12 +1778,12 @@ class Room {
         $this->user[$idx]->code = $authenticate->code_get();
         $this->user[$idx]->flags |= USER_FLAG_LISTAUTH;
 
-        if (isset($CO_list)) {
-          if (strcmp($CO_list, "auth") == 0) {
+        if (isset($cookie['CO_list'])) {
+          if (strcmp($cookie['CO_list'], "auth") == 0) {
             $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
             $this->user[$idx]->flags |= USER_FLAG_LISTAUTH;
           }
-          if (strcmp($CO_list, "isolation") == 0) {
+          if (strcmp($cookie['CO_list'], "isolation") == 0) {
             $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
             $this->user[$idx]->flags |= USER_FLAG_ISOLAUTH;
           }
@@ -2409,10 +1866,17 @@ class Room {
   }
 
   // Static functions
-  static function create()
+  static function create($crystal_filename)
   {
-    $room = new Room();
-    
+      if (($room_ser = @file_get_contents($crystal_filename)) == FALSE ||
+          ($room = unserialize($room_ser)) == FALSE) {
+          fprintf(STDERR, "NEW ROOM\n");
+          $room = new Room($crystal_filename);
+      }
+      else {
+          fprintf(STDERR, "ROOM FROM FILE\n");
+      }
+
     return $room;
   }
   
@@ -2422,7 +1886,7 @@ class Room {
     GLOBAL $sess;
 
     do {
-      if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) {
+      if (($tok = @ftok(FTOK_PATH."/main", "C")) == -1) {
        log_main("ftok failed");
        break;
       }
@@ -2487,7 +1951,7 @@ class Room {
     
     // var_dump($room);
     
-    if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) 
+    if (($tok = @ftok(FTOK_PATH."/main", "C")) == -1) 
       return (FALSE);
     
     while ($room->shm_sz < SHM_DIMS_MAX) {
@@ -2512,7 +1976,16 @@ class Room {
     
     return (FALSE);
   }
-
+  function dump_data()
+  {
+      $room_ser = serialize($this);
+      $room_ser_len = mb_strlen($room_ser, "ASCII");
+      if (file_put_contents($this->crystal_filename, $room_ser) == $room_ser_len) {
+          return (TRUE);
+      }
+      
+      return (FALSE);
+  }
 
   function save_data($room) 
   {
@@ -2521,7 +1994,7 @@ class Room {
       $ret =   FALSE;
       $shm =   FALSE;
     
-      if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) 
+      if (($tok = @ftok(FTOK_PATH."/main", "C")) == -1) 
           return (FALSE);
     
       // SHSPLIT: before save the $room you must save users, 
@@ -2659,48 +2132,120 @@ class Room {
     return ($ret);
   }
 
-  static function garbage_time_is_expired($tm) 
+  function request_mgr(&$s_a_p, $header, &$header_out, &$new_socket, $path, $addr, $get, $post, $cookie)
   {
-      $ret = TRUE;
-      $fp = FALSE;
-      do {
-          if (file_exists(PROXY_PATH) == FALSE)
-              mkdir(PROXY_PATH, 0775, TRUE);
-          if (($fp = @fopen(PROXY_PATH."/garbage_time.expired", 'rb')) == FALSE)
-              break;
-          if (($s = fread($fp, 4)) == FALSE)
-              break;
-          if (mb_strlen($s, "ASCII") != 4)
-              break;
-          $arr = unpack('Le', $s);
-          if ($arr['e'] > $tm)
-              $ret = FALSE;
-      } while (0);
-      
-      if ($fp != FALSE)
-          fclose($fp);
-      
-      log_rd2("END: return ".($ret ? "TRUE" : "FALSE"));
-      
-      return ($ret);
-  }
+      printf("NEW_SOCKET (root): %d\n", intval($new_socket));
 
-  static function garbage_time_expire_set($tm) 
-  {
-      do {
-          if (file_exists(PROXY_PATH) == FALSE)
-              mkdir(PROXY_PATH, 0775, TRUE);
-          if (($fp = @fopen(PROXY_PATH."/garbage_time.expired", 'wb')) == FALSE)
-              break;
-          fwrite($fp, pack("L",$tm));
-          fclose($fp);
+      $enc = get_encoding($header);
+      if (isset($header['User-Agent']) && strstr($header['User-Agent'], "MSIE")) {
+          $transp_type = "htmlfile";
+      }
+      else {
+          $transp_type = "iframe";
+      }
+      force_no_cache($header_out);
+
+      switch ($path) {
+      case "":
+      case "index.php":
+          ob_start();
+          index_main($this, $transp_type, $header_out, $addr, $get, $post, $cookie);
+          $content = ob_get_contents();
+          ob_end_clean();
+
+          $s_a_p->pgflush_try_add($enc, $new_socket, 20, $header_out, $content);
+          return TRUE;
+
+          break;
+      case "index_wr.php":
+          ob_start();
+          index_wr_main($this, $addr, $get, $post, $cookie);
+          $content = ob_get_contents();
+          ob_end_clean();
           
-          return (TRUE);
-      } while (0);
-      
+          $s_a_p->pgflush_try_add($enc, $new_socket, 20, $header_out, $content);
+          return TRUE;
+
+          break;
+      case "index_rd_ifra.php":
+          do {
+              if (!isset($cookie['sess'])
+                  || (($user = $this->get_user($cookie['sess'], $idx)) == FALSE)) {
+                  $content = User::stream_fini($s_a_p->rndstr, TRUE);
+                  
+                  $s_a_p->pgflush_try_add($enc, $new_socket, 20, $header_out, $content);
+                  return TRUE;
+
+                  break;
+              }
+              // close a previous opened index_read_ifra socket, if exists
+              if (($prev = $user->rd_socket_get()) != NULL) {
+                  $s_a_p->socks_unset($user->rd_socket_get());
+                  fclose($user->rd_socket_get());
+                  printf("CLOSE AND OPEN AGAIN ON IFRA2\n");
+                  $user->rd_socket_set(NULL);
+              }
+
+              $content = "";
+              $user->stream_init($s_a_p->rndstr, $enc, $header_out, $content, $get, $post, $cookie);
+              
+              $response = headers_render($header_out, -1).chunked_content($user->rd_zls_get(), $content);
+              $response_l = mb_strlen($response, "ASCII");
+              
+              $wret = @fwrite($new_socket, $response, $response_l);
+              if ($wret < $response_l) {
+                  printf("TROUBLES WITH FWRITE: %d\n", $wret);
+                  $user->rd_cache_set(mb_substr($content, $wret, $response_l - $wret, "ASCII"));
+              }
+              else {
+                  $user->rd_cache_set("");
+              }
+              fflush($new_socket);
+              
+              
+              $s_a_p->socks_set($new_socket, $user);
+              $user->rd_socket_set($new_socket);
+              printf(" - qui ci siamo - ");
+              return TRUE;
+          } while (FALSE);
+          
+          return FALSE;
+          break;
+
+      default:
+          /* FAR TODO: move all into an array of registered sub-apps */
+          $subs = "briskin5/";
+          $subs_l = strlen($subs);
+          if (!strncmp($path, $subs, $subs_l)) {
+              $ret = Bin5::request_mgr(&$s_a_p, $header, &$header_out, &$new_socket, substr($path, $subs_l) , $addr, $get, $post, $cookie);
+              return ($ret);
+          }
+          break;
+      }
+
       return (FALSE);
   }
 
+  function match_add($idx, $match)
+  {
+      $this->match[$idx] = $match;
+  }
+
+  function match_del($idx)
+  {
+      unset($this->match[$idx]);
+  }
+
+  function match_get($idx, $token)
+  {
+      if (isset($this->match[$idx])) {
+          if (   $token == NULL 
+              || $token == $this->match[$idx]->table_token) {
+              return ($this->match[$idx]);
+          }
+      }
+      return NULL;
+  }
 
 } // end class Room
 
@@ -3138,7 +2683,7 @@ function validate_sess($sess)
 
 function validate_name($name) 
 {
-  $name_new = str_replace(' ', '_', substr(trim($name),0,12));
+    $name_new = str_replace(' ', '_', mb_substr(trim($name),0,12, "UTF-8"));
 
   for ($i = 0 ; $i < strlen($name_new) ; $i++) {
     $c = $name_new[$i];