Merge branch 'sac-a-push' of git.birds.lan:brisk into sac-a-push
[brisk.git] / web / Obj / brisk.phh
1 <?php
2 /*
3  *  brisk - brisk.phh
4  *
5  *  Copyright (C) 2006-2011 Matteo Nastasi
6  *                          mailto: nastasi@alternativeoutput.it 
7  *                                  matteo.nastasi@milug.org
8  *                          web: http://www.alternativeoutput.it
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details. You should have received a
19  * copy of the GNU General Public License along with this program; if
20  * not, write to the Free Software Foundation, Inc, 59 Temple Place -
21  * Suite 330, Boston, MA 02111-1307, USA.
22  *
23  */
24
25
26 define('BRISK_CONF', "brisk.conf.pho");
27 define('FTOK_PATH', "/var/lib/brisk");
28 define('LEGAL_PATH', "/tmp/legal_brisk");
29 define('PROXY_PATH', "/var/lib/brisk_proxy");
30 define('TABLES_N', 36);
31 define('TABLES_AUTH_N', 4);
32 define('PLAYERS_N', 3);
33 define('MAX_POINTS', 5);
34 define('MAX_PLAYERS', (20 + (PLAYERS_N * TABLES_N)));
35 define('SHM_DIMS_MIN', (50000 + 10000 * TABLES_N + 15000 * MAX_PLAYERS));
36 define('SHM_DIMS_MAX', SHM_DIMS_MIN + 1048576);
37 define('SHM_DIMS_DLT', 65536);
38
39 define('SHM_DIMS_U_MIN', 4096);
40 define('SHM_DIMS_U_MAX', 65536);
41 define('SHM_DIMS_U_DLT', 4096);
42
43 define('COMM_N', 18);
44 define('COMM_GEN_N', 50);
45
46 define('CHAT_N', 3);
47 define('CHAT_ILL_TIME', 6);
48
49 define('SESS_LEN', 13);
50 define('STREAM_TIMEOUT', 60);
51 /* FIXME: move to sac-a-push .phh */
52 define('EXPIRE_TIME_RD', 180);
53 define('EXPIRE_TIME_SMAMMA', 360);
54 define('EXPIRE_TIME_WAG', 10);
55 define('WAKEUP_TIME', 12);
56 // BAN_TIME da allineare anche in commons.js
57 define('BAN_TIME', 3600);
58 define('GARBAGE_TIMEOUT', 10);
59 define('NICKSERV', "<i>BriskServ</i>");
60
61 define('LOCK_SHARE_MAX', 10000);
62
63 define('DBG_ONL2', 0x0001);
64 define('DBG_ONLY', 0x0002);
65 define('DBG_MAIN', 0x0004);
66 define('DBG_READ', 0x0008);
67 define('DBG_REA2', 0x0010);
68 define('DBG_SEND', 0x0020);
69 define('DBG_LOCK', 0x0040);
70 define('DBG_WRIT', 0x0080);
71 define('DBG_LOAD', 0x0100);
72 define('DBG_AUTH', 0x0200);
73 define('DBG_CRIT', 0x0400);
74 define('DBG_LMOP', 0x0800);
75 define('DBG_TRAC', 0x1000);
76 define('DBG_SHME', 0x2000);
77 // NOTE: BRISK DEBUG must be a numerical constant, not the result of operations on symbols 
78 define('BRISK_DEBUG', 0x0800);
79
80 define('BRISK_SINGLE_DEBUG',0);
81 define('BRISK_SINGLE_SESS', "");
82 define('DEBUGGING', "no-debugging");
83
84 require_once("$DOCUMENT_ROOT/Etc/".BRISK_CONF);
85
86 $mlang_brisk = array( 'btn_backstand'=> array( 'it' => 'torna in piedi',
87                                                'en' => 'back standing' ),
88                       'btn_close' => array( 'it' => 'chiudi',
89                                             'en' => 'close'),
90
91                       'tit_all' => array( 'it' => 'tutti',
92                                           'en' => 'all' ),
93
94                       'tabtout_a'=> array( 'it' => '<br>Sei stato inattivo per ', 
95                                            'en' => '<br>You are being idle for ' ),
96                       'tabtout_b'=> array( 'it' => ' minuti. <br><br>Quindi ritorni tra i <b>Giocatori in piedi</b>.',
97                                            'en' => ' minutes. <br><br>Then you return with the <b>standing players</b>.'),
98                       'tickmust' => array( 'it' => '<br>Per attivare il messaggio di segnalazione del tavolo occorre essere seduti.<br><br>',
99                                            'en' => '<br>To activate the signalling message of the table it\'s necessary to be sitting<br><br>'),
100                       'tickjust' => array( 'it' => '<br>Il messaggio di segnalazione del tavolo &egrave; gi&agrave; attivato.<br><br> ',
101                                            'en' => 'EN<br>Il messaggio di segnalazione del tavolo &egrave; gi&agrave; attivato.<br><br> '),
102                       'tickwait' => array( 'it' => '<br>Il messaggio di segnalazione del tavolo<br>&egrave; disattivato ancora per %d second%s.<br><br>',
103                                            'en' => 'EN<br>The signalling message of the table<br>will be deactivated for %d second%s.<br><br>'),
104                       'alarpass' => array( 'it' => '<br>La password digitata non &egrave; corretta.<br><br>',
105                                            'en' => '<br>The entered password is not correct.<br><br>'),
106                       'alarret'  => array( 'it' => '"Alarm \\"<b>%s</b>\\" inviato a <b>%s</b>."',
107                                            'en' => '"Alarm \\"<b>%s</b>\\" sent to <b>%s</b>."'),
108                       'authmust' => array( 'it' => '<b>Per autenticare qualcuno devi a tua volta essere autenticato.</b>',
109                                            'en' => '<b>To authenticate someone you have to be authenticated.</b>'), // on your turn
110                       'mesgmust' => array( 'it' => '<b>Per inviare un messaggio devi essere autenticato.</b>',
111                                            'en' => '<b>To send a message you have to be authenticated.</b>'),
112                       'nickmust' => array( 'it' => 'Il nickname deve contenere almeno una lettera dell\'alfabeto o una cifra.',
113                                            'en' => 'The nickname have to contain at least one letter or one number.'),
114                       'nickdupl' => array( 'it' => 'Nickname <b>%s</b> gi&agrave; in uso.',
115                                            'en' => 'The nickname <b>%s</b> is already in use.'),
116                       'authchan' => array( 'it' => '<b>Non puoi cambiare nick a un tavolo per soli autenticati o se sei in modalità isolata.</b>',
117                                            'en' => '<b>You can\'t change your nickname into a table for only authenticated or if you are in isolation mode.</b>'),
118                       'nickjust' => array( 'it' => 'Il nickname <b>\'%s\'</b> &egrave; gi&agrave; registrato, <b>se il suo proprietario si autentificher&agrave; verrai rinominato d\'ufficio come ghost<i>N</i>.</b>',
119                                            'en' => 'The nickname <b>\'%s\'</b> is already registered, <b>if its proprietary will authenticate you will named again officially ghost<i>N</i>.</b>'), // FIXME: him ???
120                       'statunkn' => array( 'it' => 'Questo stato non esiste.',
121                                            'en' => 'This state don\'t exists.'),
122                       'tabincon' => array( 'it' => '<br>I dati del tavolo n&deg; %d sono inconsistenti, verranno resettati.<br><br>Torni in piedi.<br><br>',
123                                            'en' => 'EN <br>I dati del tavolo n&deg; %d sono inconsistenti, verranno resettati.<br><br>Torni in piedi.<br><br>'),
124                       'listmust' => array( 'it' => '<b>Per andare in isolamento non bisogna essere seduti a tavoli non riservati.</b>',
125                                            'en' => '<b>To go to isolation you must don\'t stay on not reserved tables</b>'),
126
127                       'tit_onauth'=>array( 'it' => '(solo aut.)',
128                                            'en' => '(only aut.)'),
129                       'tit_onisol'=>array( 'it' => '(isolam.to)',
130                                            'en' => '(isolation)'),
131                       'db_failed' =>array('it'  => '<br>Il collegamento al database è fallito.<br>Temporaneamente tutte le autenticazioni verranno sospese, accederai a Brisk come un utente normale.<br><br>Ci scusiamo per il disagio.',
132                                           'en'  => 'Connection to the database failed<br>All authentications are suspended temporarly, you login as normal user.<br>We are about the limitation')
133                       
134
135 );
136
137 $G_lng = langtolng($G_lang);
138
139 $G_all_points = array( 11,10,4,3,2, 0,0,0,0,0 );
140 $G_brisk_version = "3.6.3";
141
142 /* MLANG: ALL THE INFO STRINGS IN brisk.phh */
143 $root_wellarr = array( 'it' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: nuovo sistema di evidenziazione degli utenti registrati.',
144                                        'Se vuoi iscriverti alla <a target="_blank" href="mailto:ml-briscola+subscribe@milug.org">Mailing List</a>, cliccala!' ),
145                        'en' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NEWS</b>: usage of reader/writer locking instead of generic exclusive locking.',
146                                        'If you want to subscribe our <a target="_blank" href="ml-briscola+subscribe@milug.org">Mailing List</a>, click it!' ) );
147
148 $G_room_help = array( 'it' => '
149 <div style=\\"text-align: left; padding: 8px;\\">
150 <b>Descrizione</b><br>
151 Questa è un\'implementazione della briscola in cinque, cos&igrave; come &egrave; spiegata su
152 <a target=\\"_blank\\" href=\\"http://it.wikipedia.org/wiki/Briscola#Gioco_a_5\\">Wikipedia</a>; in breve &egrave; la variante con l\'asta prima sulla carta e poi sui punti.<br><br>
153 <b>Configurazione del browser.</b><br>
154 Occorre abilitare i cookies.<br>
155 <br>
156 <b>Uso del sito</b><br>
157 Potete sedervi a un tavolo o rimanere in piedi.<br>
158 Se al vostro tavolo si raggiungono i 5 giocatori inizia automaticamente la partita.<br>
159 <br>
160 <b>Partita</b><br>
161 All\'inizio vengono distribuite le carte e parte l\'asta; per partecipare all\'asta, quando sar&agrave; il vostro turno, potrete scegliere se andare avanti o passare cliccando sulle icone corrispondenti. Se si arriva ai punti, scrivete nella textbox il vostro rilancio e cliccate PUNTI.<br><br>
162 Chi vince l\'asta dovr&agrave; decidere il seme della carta scelta e inizier&agrave; la mano.<br>
163 Per giocare le carte dovrete trascinarle nel quadrato al centro del vostro schermo.<br><br>
164 Il vostro turno &egrave; sempre segnalato da una cornice verde lampeggiante intorno al quadrato al centro del vostro schermo.<br><br>
165 Durante la partita, se vorrete ricaricare la pagina, usate l\'apposito bottone \\"reload\\" in basso a destra.<br>
166 Dopo che &egrave; iniziata una partita per uscirne dovete chiedere agli altri giocatori di sbloccarla cliccando sul lucchetto. Se non si segue questa prassi, una volta usciti, non vi potrete sedere a nessun tavolo per '.floor(BAN_TIME/60).' minuti.
167 <dl>
168 <dt><b>Comandi della chat</b>
169 <dd><b>/nick <i>&lt;nuovo_nickname&gt;</i></b> - cambio di nickname
170 <dd><b>/tav <i>&lt;frase di invito&gt;</i></b> - invito per gli altri giocatori al tavolo dove si &egrave; seduti 
171 <dd><b>/st <i>&lt;stato&gt;</i></b> - cambia l\'icona associata al tuo user; <i>stato</i> pu&ograve; valere: \\"normale\\", \\"fuori\\", \\"pausa\\", \\"cibo\\", \\"cane\\", \\"lavoro\\", \\"presente\\" oppure \\"sigaretta\\"
172 <dd><b>/authreq</b> - se si &egrave; autenticati permette di garantire per un utente fidato
173 <dd><b>/mesgtoadm</b> - se si &egrave; autenticati permette di lasciare un messaggio all\'amministratore del sito
174 <dd><b>/listen &lt;all or auth&gt;</b> - se si &egrave; autenticati permette leggere solo i messaggi degli altri autenticati (auth) o di tutti (all)
175 </dl>
176 </div>
177 ',
178
179 'en' => '
180 <div style=\\"text-align: left; padding: 8px;\\">
181 <b>EN Descrizione</b><br>
182 EN Questa è un\'implementazione della briscola in cinque, cos&igrave; come &egrave; spiegata su
183 <a target=\\"_blank\\" href=\\"http://it.wikipedia.org/wiki/Briscola#Gioco_a_5\\">Wikipedia</a>; in breve &egrave; la variante con l\'asta prima sulla carta e poi sui punti.<br><br>
184 <b>EN Configurazione del browser.</b><br>
185 Occorre abilitare i cookies.<br>
186 <br>
187 <b>Uso del sito</b><br>
188 Potete sedervi a un tavolo o rimanere in piedi.<br>
189 Se al vostro tavolo si raggiungono i 5 giocatori inizia automaticamente la partita.<br>
190 <br>
191 <b>Partita</b><br>
192 All\'inizio vengono distribuite le carte e parte l\'asta; per partecipare all\'asta, quando sar&agrave; il vostro turno, potrete scegliere se andare avanti o passare cliccando sulle icone corrispondenti. Se si arriva ai punti, scrivete nella textbox il vostro rilancio e cliccate PUNTI.<br><br>
193 Chi vince l\'asta dovr&agrave; decidere il seme della carta scelta e inizier&agrave; la mano.<br>
194 Per giocare le carte dovrete trascinarle nel quadrato al centro del vostro schermo.<br><br>
195 Il vostro turno &egrave; sempre segnalato da una cornice verde lampeggiante intorno al quadrato al centro del vostro schermo.<br><br>
196 Durante la partita, se vorrete ricaricare la pagina, usate l\'apposito bottone \\"reload\\" in basso a destra.<br>
197 Dopo che &egrave; iniziata una partita per uscirne dovete chiedere agli altri giocatori di sbloccarla cliccando sul lucchetto. Se non si segue questa prassi, una volta usciti, non vi potrete sedere a nessun tavolo per '.floor(BAN_TIME/60).' minuti.
198 <dl>
199 <dt><b>Comandi della chat</b>
200 <dd><b>/nick <i>&lt;nuovo_nickname&gt;</i></b> - cambio di nickname
201 <dd><b>/tav <i>&lt;frase di invito&gt;</i></b> - invito per gli altri giocatori al tavolo dove si &egrave; seduti 
202 <dd><b>/st <i>&lt;stato&gt;</i></b> - cambia l\'icona associata al tuo user; <i>stato</i> pu&ograve; valere: \\"normale\\", \\"fuori\\", \\"pausa\\", \\"cibo\\", \\"cane\\", \\"lavoro\\", \\"presente\\" oppure \\"sigaretta\\"
203 <dd><b>/authreq</b> - se si &egrave; autenticati permette di garantire per un utente fidato
204 <dd><b>/mesgtoadm</b> - se si &egrave; autenticati permette di lasciare un messaggio all\'amministratore del sito
205 <dd><b>/listen &lt;all or auth&gt;</b> - se si &egrave; autenticati permette leggere solo i messaggi degli altri autenticati (auth) o di tutti (all)
206 </dl>
207 </div>
208 ');
209
210 //  
211 $G_room_passwdhowto = array( 'it' => '<br><h2>Come registrarsi su Brisk</h2>
212 <div style=\\"text-align: left; padding: 8px;\\">
213 Attualmente ci sono due metodi per ottenere una password sul sito:<br><br>
214 <dir>
215 <li><b>Facendosi garantire da un utente di Brisk che gi&agrave; possidede una password</b><br><br>
216 <li><b>Auto-garantendosi utilizzando uno dei seguenti sistemi di identificazione digitale:</b><br><br>
217 <dir>
218 <li>Carta Regionale dei Servizi della Lombardia (la tessera sanitaria)
219 <li>Carta Regionale dei Servizi del Friuli Venezia Giulia (la tessera sanitaria)
220 <li>Smart card di InfoCamere
221 </dir>
222 <br>
223 <b>Per auto-garantisi occorre possedere:</b><br><br>
224 <dir>
225 <li>il codice PIN della propria carta
226 <li>il lettore di smart-card per collegare la carta al PC (acquistabile di solito presso le edicole)
227 </dir>
228 <br>
229 <b>Per effettuare la registrazione collegarsi al sito:</b><br><br>
230 <dl>
231 <dd><a class=\\"flat\\"  target=\\"_blank\\" href=\\"https://brisk.mine.nu\\">https://brisk.mine.nu</a>
232 </dl>
233 <br><br>
234 Se sei in possesso di una carta che permette l\'identificazione via internet che non è nell\'elenco qui sopra
235 <a class=\\"flat\\" href=\\"mailto:authadmbrisk@alternativeoutput.it\\">fai una segnalazione</a>.
236
237 </dir>
238 </div>
239 ',
240                              'en' => '<br><h2>EN Come registrarsi su Brisk</h2>
241 <div style=\\"text-align: left; padding: 8px;\\">
242 EN Attualmente ci sono due metodi per ottenere una password sul sito:<br><br>
243 <dir>
244 <li><b>Facendosi garantire da un utente di Brisk che gi&agrave; possidede una password</b><br><br>
245 <li><b>Auto-garantendosi utilizzando uno dei seguenti sistemi di identificazione digitale:</b><br><br>
246 <dir>
247 <li>Carta Regionale dei Servizi della Lombardia (la tessera sanitaria)
248 <li>Carta Regionale dei Servizi del Friuli Venezia Giulia (la tessera sanitaria)
249 </dir>
250 <br>
251 <b>Per auto-garantisi occorre possedere:</b><br><br>
252 <dir>
253 <li>il codice PIN della propria carta
254 <li>il lettore di smart-card per collegare la carta al PC (acquistabile di solito presso le edicole)
255 </dir>
256 <br>
257 <b>Per effettuare la registrazione collegarsi al sito:</b><br><br>
258 <dl>
259 <dd><a class=\\"flat\\"  target=\\"_blank\\" href=\\"https://brisk.mine.nu\\">https://brisk.mine.nu</a>
260 </dl>
261 <br><br>
262 Se sei in possesso di una carta che permette l\'identificazione via internet che non è nell\'elenco qui sopra
263 <a class=\\"flat\\" href=\\"mailto:authadmbrisk@alternativeoutput.it\\">fai una segnalazione</a>.
264
265 </dir>
266 </div>
267 ' );
268 /*
269 <dd>Seguendo la procedura di auto-garanzia all\'url: <a href="https://brisk.mine.nu">https://brisk.mine.nu</a>
270 ';
271 */
272
273 $G_room_about = array( 'it' => '<br>
274 <div id=\\"header\\" class=\\"header\\">
275   <img class=\\"nobo\\" src=\\"img/brisk_logo64.png\\">
276   briscola chiamata in salsa ajax
277 </div>
278 <br><b>version '.$G_brisk_version.'</b><br><br>
279 Copyright 2006-2012 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>',
280                       'en' => '<br>
281 <div id=\\"header\\" class=\\"header\\">
282   <img class=\\"nobo\\" src=\\"img/brisk_logo64.png\\">
283   declaration briscola in ajax sauce <b>(Beta)</b>
284 </div>
285 <br><b>version '.$G_brisk_version.'</b><br><br>
286 Copyright 2006-2009 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>');
287
288 function mop_flush()
289 {
290     for ($i = 0; $i < ob_get_level(); $i++)
291         ob_end_flush();
292     ob_implicit_flush(1);
293     flush();
294 }
295
296 function force_no_cache(&$header_out)
297 {
298     $header_out['Pragma'] = 'no-cache, must-revalidate';
299     $header_out['Cache-Control'] = 'no-cache';
300     $header_out['Expires'] = '-1';
301 }
302
303 function file_lock($fname, $is_exclusive)
304 {
305     if (($res = @fopen($fname, "r+")) == FALSE) {
306         return (FALSE);
307     }
308         
309     if (flock($res, ($is_exclusive ? LOCK_EX : LOCK_SH)) == FALSE) {
310         fclose($res);
311         return (FALSE);
312     }
313
314     return ($res);
315 }
316
317 function file_unlock($res)
318 {
319     if ($res != FALSE) {
320         flock($res, LOCK_UN);
321         fclose($res);
322     }
323 }
324
325 function webservers_exceeded()
326 {
327     return(file_exists(PROXY_PATH."/webservers_exceded.flag"));
328 }
329
330 function webservers_check()
331 {
332     GLOBAL $G_webserver_max;
333
334     /* FIXME: check all procs expirations */
335     return (10);
336
337     $ct = 0;
338
339     $dh = opendir('/proc');
340     while (($file = readdir($dh)) !== false) {
341         if (preg_match('/[0-9]+/', $file)) {
342             $cmdline = explode("\0", file_get_contents('/proc/'.$file.'/cmdline'));
343             // echo "xxx".$cmdline[0].$n;
344             if (strstr('/usr/sbin/apache2', $cmdline[0]) != FALSE) {
345                 // echo "yyy".$cmdline[0].$n;
346                 $ct++;
347             }
348         }
349     }
350     closedir($dh);
351
352     if ($ct >= $G_webserver_max) {
353         touch(PROXY_PATH."/webservers_exceded.flag");
354     }
355     else {
356         unlink(PROXY_PATH."/webservers_exceded.flag");
357     }
358     return ($ct);
359 }
360
361 $escpush_from = array("\\", "\"");
362 $escpush_to   = array("\\\\", "\\\"");
363 function escpush($s)
364 {
365     GLOBAL $escpush_from, $escpush_to;
366
367     return str_replace($escpush_from, $escpush_to, $s);
368 }
369
370 $escinp_from = array( "\""     );
371 $escinp_to = array(   "&quot;" );
372
373 function escinput($s)
374 {
375     GLOBAL $escinp_from, $escinp_to;
376     
377     return str_replace($escinp_from, $escinp_to, $s);
378 }
379
380 function eschtml($s)
381 {
382     return htmlentities($s);
383 }
384
385 function esclfhtml($s)
386 {
387     return str_replace("\n", "<br>\n", htmlentities($s));
388 }
389
390
391 function langtolng($lang)
392 {
393   GLOBAL $G_lang;
394
395   return ($G_lang == 'en' ? '-en' : '');
396 }
397
398 function csplitter($in, $sep)
399 {
400   $st = 0;
401   $id = 0;
402   $out = array();
403   $out[$id] = "";
404   for ($i = 0 ; $i < strlen($in) ; $i++) {
405     $ini = substr($in, $i, 1);
406     if ($st == 0) {
407       if ($ini == '\\')
408         $st = 1;
409       else if ($ini == $sep) {
410         $id++;
411         $out[$id] = "";
412       }
413       else {
414         $out[$id] .= $ini;
415       }
416     }
417     else if ($st == 1) {
418       $out[$id] .= $ini;
419       $st = 0;
420     }
421   }
422
423   return ($out);
424 }
425
426 function xcape($s)
427 {
428   $from = array (   '\\',     '@',        '|' );
429   $to   = array ( '\\\\', '&#64;', '&brvbar;' );
430
431   return (str_replace($from, $to, htmlentities($s,ENT_COMPAT,"UTF-8")));
432 }
433
434 function xcapelt($s)
435 {
436   $from = array (   '\\',     '|',  "\t",  "\n");
437   $to   = array ( '\\\\',   '\\|', "\\t", "\\n");
438
439   return (str_replace($from, $to, $s));
440 }
441
442 function xcapemesg($s)
443 {
444   $from = array (  "\n");
445   $to   = array ( "\\n");
446
447   return (str_replace($from, $to, $s));
448 }
449
450
451 class Vect {
452     function Vect($a)
453     {
454         $this->el = $a;
455     }
456     
457     function getbyid($idx)
458     {
459         return ($this->el[$idx]);
460     }
461     
462     function setbyid($idx, $v)
463     {
464         $this->el[$idx] = $v;
465     }
466 }
467
468 class Table {
469   var $idx;
470   var $player;
471   var $player_n;
472
473   var $auth_only;     // se tavolo riservato o libero
474
475   var $wag_own;
476   var $wag_com;
477   var $wag_tout;
478
479   var $table_token;
480   var $table_start;   // information field
481
482   var $wakeup_time;
483
484   function Table() 
485   {
486   }
487   
488   function create($idx) 
489   {
490     if (($thiz = new Table()) == FALSE)
491       return (FALSE);
492
493     $thiz->idx       =   $idx;
494     $thiz->player    =   array();
495     $thiz->player_n  =   0;
496     $thiz->auth_only =   FALSE;
497
498     $thiz->wag_own   =  -1;
499     $thiz->wag_com   =  "";
500     $thiz->wag_tout   =  0;
501
502     $thiz->table_token  = "";
503     $thiz->table_start  = 0;
504     
505     $thiz->wakeup_time = 0;
506
507     return ($thiz);
508   }
509
510   function copy($from)
511   {
512     $this->idx = $from->idx;
513     $this->player = array();
514     for ($i = 0 ; $i < $from->player_n ; $i++)
515       $this->player[$i] = $from->player[$i];
516     $this->player_n = $from->player_n;
517
518     log_main("PLAYER_N - parent::copy.".$this->player_n);
519     
520     $this->auth_only =  $from->auth_only;
521
522     $this->wag_own   =  $from->wag_own;
523     $this->wag_com   =  $from->wag_com;
524     $this->wag_tout  =  $from->wag_tout;
525
526     $this->table_token  = $from->table_token;
527     $this->table_start  = $from->table_start;
528
529     $this->wakeup_time = $from->wakeup_time;
530   }
531
532   function myclone($from)
533   {
534     if (($thiz = new Table()) == FALSE)
535       return (FALSE);
536
537     $this->copy($from);
538
539     return ($thiz);
540   }
541   
542   function spawn($from)
543   {
544     if (($thiz = new Table()) == FALSE)
545       return (FALSE);
546     
547     $thiz->idx = $from->idx;
548     $thiz->player = array();
549     for ($i = 0 ; $i < $from->player_n ; $i++)
550       $thiz->player[$i] = $i;
551     $thiz->player_n = $from->player_n;
552
553     $thiz->auth_only =  $from->auth_only;
554
555     $thiz->wag_own = $from->wag_own;
556     $thiz->wag_com = $from->wag_com;
557     $thiz->wag_tout  =  $from->wag_tout;
558
559     $thiz->table_token  = $from->table_token;
560     $thiz->table_start  = $from->table_start;
561
562     $thiz->wakeup_time = $from->wakeup_time;
563
564     return ($thiz);
565   }
566
567   function wag_set($user_idx, $mesg)
568   {
569     log_main("WAG_SET");
570
571     $this->wag_own  =  $user_idx;
572     $this->wag_com  =  $mesg;
573     $this->wag_tout =  0;
574   }
575
576   function wag_reset($timeout)
577   {
578     log_main("WAG_RESET");
579
580     unset($this->wag_own);
581     $this->wag_own  = -1;
582     $this->wag_com  = "";
583     $this->wag_tout = $timeout;
584   }
585
586   function player_get($idx)
587   {
588     return ($this->player[$idx]);
589   }
590
591   function player_set($idx, $player)
592   {
593     $this->player[$idx] = $player;
594   }
595
596   function user_add($idx)
597   {
598     $this->player[$this->player_n] = $idx;
599     $this->player_n++;
600     
601     return ($this->player_n - 1);
602   }
603   
604   function user_rem($room, $user)
605   {
606     $tabpos = $user->table_pos;
607     
608     /* verifico la consistenza dei dati */
609     if ($room->user[$this->player[$tabpos]] == $user) {
610       
611       /* aggiorna l'array dei giocatori al tavolo. */
612       for ($i = $tabpos ; $i < $this->player_n-1 ; $i++) {
613         $this->player[$i] = $this->player[$i+1];
614         $user_cur = $room->user[$this->player[$i]];
615         $user_cur->table_pos = $i;
616       }
617       $this->player_n--;
618     }
619     else {
620       log_main("INCONSISTENCY ON TABLE.");
621     }
622   }
623
624
625
626   //      $ret .= table_act_content(($user->subst == 'standup'), $this->table[$i]->player_n, $i, $user->table, 
627   //                              ($this->table[$i]->auth_only == FALSE ? TRUE : $user->flags & USER_FLAG_AUTH));
628
629   // function act_content($isstanding, $sitted, $table, $cur_table, $allowed)
630   function act_content($user)
631   {
632     $ret = "";
633     $isstanding = ($user->subst == 'standup');
634     $sitted = $this->player_n;
635     $table = $this->idx;
636     $cur_table = $user->table;
637     $allowed = TRUE;
638
639     if ($isstanding) {
640       if ($sitted < PLAYERS_N) {
641         if ($this->auth_only) {
642           if ($user->flags & USER_FLAG_AUTH) 
643             $act = "sitreser";
644           else
645             $act = 'reserved';
646         }
647         else {
648           $act = 'sit';
649         }
650       }
651       else {
652         $act = 'none';
653       }
654     }
655     else {
656       if ($table == $cur_table)
657         $act = 'wake';
658       else
659         $act = 'none';
660     }
661     
662     if ($act != '')
663       $ret = sprintf('j_tab_act_cont(%d, \'%s\');', $table, $act);
664     
665     return ($ret);
666   }
667 } // end class Table
668
669
670
671
672 class Room {
673     static $delta_t;
674
675   var $user;
676   var $table;
677   var $match;
678   var $comm; // commands for many people
679   var $step; // current step of the comm array
680   // externalized var $garbage_timeout;
681   var $shm_sz;
682
683   function Room () {
684     $this->user  = array();
685     $this->table = array();
686     $this->match = array();
687
688     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
689         $this->user[$i] = User::create($this, $i, "", "");
690     }
691
692     for ($i = 0 ; $i < TABLES_N ; $i++) {
693       $this->table[$i] = Table::create($i);
694       /* OLD METHOD
695       if ($i < 12) {
696         $row = ( (((int)($i / 4)) % 2) == 0 );
697         $col = ($i % 2 == 0);
698         $this->table[$i]->auth_only = (($row && $col) || (!$row && !$col));
699       }
700       else {
701         $this->table[$i]->auth_only = FALSE;
702       }
703       */
704       if ($i < TABLES_AUTH_N) 
705         $this->table[$i]->auth_only = TRUE;
706       else
707         $this->table[$i]->auth_only = FALSE;
708     }
709     // externalized $this->garbage_timeout = 0;
710     Room::garbage_time_expire_set(0);
711     $this->shm_sz = SHM_DIMS_MIN;
712   }
713
714   function garbage_manager($force)
715   {
716     GLOBAL $G_lang, $mlang_brisk, $G_base;
717
718     $ismod = FALSE;
719
720     log_rd2("garbage_manager START");
721
722     /* Garbage collector degli utenti in timeout */
723     $curtime = time();
724
725     // externalized if ($force || $this->garbage_timeout < $curtime) {
726     if (!$force && !Room::garbage_time_is_expired($curtime)) {
727         return ($ismod);
728     }
729       
730     webservers_check();
731     
732     // Before all align times with table timeout
733     for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
734         $table_cur = $this->table[$table_idx];
735         // if the table is complete and exists its shared mem we get the info about users lacc
736         
737         if ($table_cur->player_n == PLAYERS_N) {
738             log_main("PLAYERS == N TABLE ".$table_idx);
739             
740             
741             $no_recovery = FALSE;
742             if (isset($this->match[$table_idx])) {
743                 $bri = $this->match[$table_idx];
744
745                 if ($table_cur->table_token != $bri->table_token) {
746                     log_main("ERROR: not matching table_token. Room: ".$table_cur->table_token."  Table: ".$bri->table_token);
747                     log_main("ERROR: not matching table_start. Room: ".$table_cur->table_start."  Table: ".$bri->table_start);
748                     $no_recovery = TRUE;
749                     $bri = FALSE;
750                 }
751
752
753                 if ($bri != FALSE) {
754                     //
755                     //  SPAWN: JOIN
756                     //
757                     log_main("garbage_manager: bri loaded successfully.");
758                     $bri->garbage_manager(TRUE);
759                     
760                     $bri_table = $bri->table[0];
761                     
762                     // is the end of the table
763                     
764                     if ($bri->the_end == TRUE) {
765                         /*
766                          *  DESTROY OF FINISHED TABLE && MOVE PLAYER TO ROOM AGAIN
767                          */
768                         log_main("garbage_manager: INSIDE THE END.");
769                         
770                         $plist = "$table_cur->table_token|$table_cur->idx|$table_cur->player_n";
771                         for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
772                             $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
773                         }
774                         
775                         for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
776                             // stat must be "table" by definition
777                             $user_cur = $this->user[$table_cur->player[$i]];
778                             $bri_user = $bri->user[$i];
779                             
780                             $user_cur->subst      = $bri_user->subst;
781                             $user_cur->step       = $bri_user->step;
782                             $user_cur->lacc       = $bri_user->lacc;
783                             $user_cur->laccwr     = $bri_user->lacc;
784                             $user_cur->bantime    = $bri_user->bantime;
785                         }
786                         
787                         log_legal($curtime, 'xxx', $user_cur, "STAT:DESTROY_GAME", $plist);
788                         
789                         $this->room_join_wakeup($user_cur, FALSE, 0); 
790                         $table_cur->table_token = "";
791                         $table_cur->wakeup_time = $curtime + WAKEUP_TIME;
792                         
793                         $this->match_del($table_idx);
794                     }
795                     else {
796                         log_main("gm:: save_data");
797                         
798                         for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
799                             $this->user[$table_cur->player[$i]]->lacc = $bri->user[$i]->lacc;
800                         }
801                     }
802                 } // if ($bri == FALSE
803                 else if ($no_recovery == FALSE) {
804                     log_crit("ERROR: table ".$table_idx." unrecoverable join");
805                     
806                     for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
807                         $user_cur = $this->user[$table_cur->player[$i]];
808                         $user_cur->subst = "shutdowner";
809                         $user_cur->step_inc();
810                         
811                         $ret = sprintf('stat = "%s"; subst = "%s";',  $user_cur->stat, $user_cur->subst);
812                         $ret .= "gst.st = ".($user_cur->step+1)."; ";
813                         // MLANG <br>I dati del tavolo n&deg; ".$user_cur->table." sono inconsistenti, verranno resettati.<br><br>Torni in piedi.<br><br>
814                         $prestr = sprintf($mlang_brisk['tabincon'][$G_lang], $user_cur->table);
815                         $ret .= show_notify($prestr, 2000, $mlang_brisk['btn_close'][$G_lang], 400, 110);
816                         $user_cur->comm[$user_cur->step % COMM_N] = $ret;
817                         $user_cur->step_inc();
818                     }
819                     
820                     $plist = "$table_cur->table_token|$user_cur->table|$table_cur->player_n";
821                     for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
822                         $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
823                     }
824                     log_legal($curtime, 'xxx', $user_cur, "STAT:DESTROY_GAME(RECOVERY)", $plist);
825                     
826                     $this->room_join_wakeup($user_cur, TRUE, -2); 
827                     $table_cur->table_token = "";
828                 }
829             }
830         } //  if ($table_cur->player_n == PLAYERS_N) {
831     } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
832     
833     log_rd2("out new loop.");
834     
835     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
836         $user_cur = $this->user[$i];
837         
838         log_rd2("User: ".$user_cur->name."  stat: ".$user_cur->stat."  subst: ".$user_cur->subst);
839         
840         if ($user_cur->sess == "") 
841             continue;
842         
843         if ($user_cur->lacc + EXPIRE_TIME_RD < $curtime) {
844             // Auto logout dell'utente
845             log_rd2("AUTO LOGOUT.".($user_cur->lacc + EXPIRE_TIME_RD)." curtime ".$curtime);
846             
847             if ($user_cur->stat == 'table' || $user_cur->stat == 'room') {
848                 log_auth($user_cur->sess, "Autologout session.");
849                 
850                 $user_cur->reset();
851             
852                 log_rd2("AUTO LOGOUT.");
853                 if ($user_cur->subst == 'sitdown' || $user_cur->stat == 'table')
854                     $this->room_wakeup($user_cur);
855                 else if ($user_cur->subst == 'standup')
856                     $this->room_outstandup($user_cur);
857                 else
858                     log_rd2("LOGOUT FROM WHAT ???");
859             }
860         }
861
862         if ($user_cur->laccwr + EXPIRE_TIME_SMAMMA < $curtime) { // lo rimettiamo in piedi
863             if ($user_cur->stat == 'room' && $user_cur->subst == 'sitdown') {
864                 $this->room_wakeup($user_cur);
865                 $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
866                 /* 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" */
867                 $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);
868                 $user_cur->step_inc();
869             }
870         }
871     }
872     log_rd2("GARBAGE UPDATED!");
873     
874     // externalized $this->garbage_timeout = time() + GARBAGE_TIMEOUT;
875     Room::garbage_time_expire_set($curtime + GARBAGE_TIMEOUT);
876     $ismod = TRUE;
877
878     return ($ismod);
879   }
880
881   function show_room($user_step, $user)
882   {
883     GLOBAL $G_lang, $mlang_brisk;
884     log_main("show_room: username: ".$user->name);
885     
886     $ret = sprintf('gst.st = %d; ',  $user_step);
887
888     if ($user->flags & USER_FLAG_ISOLAUTH) {
889       $ret .= 'list_set(\'isolation\', false, \''.$mlang_brisk['tit_onisol'][$G_lang].'\' ); ';
890     }
891     else if ($user->flags & USER_FLAG_LISTAUTH) {
892       $ret .= 'list_set(\'auth\', false, \''.$mlang_brisk['tit_onauth'][$G_lang].'\' ); ';
893     }
894     else {
895       $ret .= 'list_set(\'all\', false, \'\' ); ';
896     }
897
898     if ($user->subst == 'standup')
899       $ret .= "tra.show(); ";
900     else
901       $ret .= "tra.hide(); ";
902
903     $ret .= sprintf('stat = "%s";',  $user->stat);
904     
905     $ret .= root_wellcome($user);
906     if ($user->flags & USER_FLAG_DBFAILED) {
907         $ret .= "gst.st = ".($user->step+1)."; ";
908         $ret .= show_notify($mlang_brisk['db_failed'][$G_lang], 0, $mlang_brisk['btn_close'][$G_lang], 400, 140);
909     }
910
911     $ret .= sprintf('subst = "%s";', $user->subst);
912     $ret .= $user->myname_innerHTML();
913
914     for ($i = 0 ; $i < TABLES_N ; $i++) {
915
916       $ret .= $this->table_content($user, $i);
917       // $ret .= table_act_content(($user->subst == 'standup'), $this->table[$i]->player_n, $i, $user->table, 
918       //                          ($this->table[$i]->auth_only == FALSE ? TRUE : $user->flags & USER_FLAG_AUTH));
919       $ret .=  $this->table[$i]->act_content($user);
920       if ($this->table[$i]->wag_own != -1) 
921         $ret .= sprintf('tra.add(%d, "%s: %s"); ', $i,  $this->user[$this->table[$i]->wag_own]->name, $this->table[$i]->wag_com);
922       else 
923         $ret .= sprintf('tra.rem(%d); ', $i);
924     }
925     $ret .= $this->standup_content($user);
926     
927     return ($ret);
928   }
929   
930
931   function room_wakeup($user)
932   {
933     $table_idx = $user->table;
934     $table = $this->table[$table_idx];
935
936     log_main("WAKEUP: begin function table:".$table_idx."  stat: ".$user->stat."  subst: ".$user->subst);
937
938     $curtime = time();
939
940     $from_table = ($user->stat == "table");
941     if ($from_table) {
942       log_main("WAKEUP: from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
943
944       for ($i = 0 ; $i < $table->player_n ; $i++) {
945         $user_cur = $this->user[$table->player[$i]];
946         log_main("PREIMPOST: INLOOP name: ".$user_cur->name);
947
948         if ($user->idx_get() != $table->player[$i]) {
949           $user_cur->stat_set("room");
950           $user_cur->subst = "sitdown";
951           $user_cur->laccwr = $curtime;
952         }
953         else if ($user->sess != "") {
954           $user_cur->stat_set("room");
955           $user_cur->subst = "standup";
956           $user_cur->laccwr = $curtime;
957           $user_cur->table = -1;
958         }
959       }
960     }
961     else {
962       $user->stat_set("room");
963       $user->subst = "standup";
964       $user->laccwr = $curtime;
965     }
966     
967     $remove_wagon = FALSE;
968     if($table->wag_own == $user->idx_get()) {
969       $table->wag_reset($curtime);
970       $remove_wagon = TRUE;
971     }
972     
973
974     /* aggiorna l'array dei giocatori al tavolo. */
975     $table->user_rem($this, $user);
976
977     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
978       $user_cur = $this->user[$i];
979       if ($user_cur->sess == '' || $user_cur->stat != 'room')
980         continue;
981       
982       // log_main("VALORI: name: ".$user_cur->name."from_table: ".$from_table."  tab: ".$user_cur->table." taix: ".$table_idx."  ucur: ".$user_cur."  us: ".$user);
983
984       $ret = "gst.st = ".($user_cur->step+1)."; ".($remove_wagon ? sprintf("tra.rem(%d);",$table_idx) : "");
985       if ($from_table && ($user_cur->table == $table_idx || $user->idx_get() == $i)) {
986         $ret .= 'gst.st_loc++; hstm.stop(); window.onunload = null; window.onbeforeunload = null; document.location.assign("index.php");|';
987         // $ret .= 'gst.st_loc++; document.location.assign("index.php");|';
988         log_main("DOCUMENT.index.php: from table");
989       }
990       else if ($user_cur->stat == "room") {
991         log_main("DOCUMENT.index.php: from table");
992
993         $ret .= $this->table_content($user_cur, $table_idx);
994         $ret .= $this->standup_content($user_cur);
995         
996         // $ret .= table_act_content(FALSE, 0, $table_idx, $user->table, FALSE);
997         $ret .= $table->act_content($user);
998
999         if ($user->idx_get() == $i) {
1000           // set the new status 
1001           $ret .=  'subst = "standup"; tra.show(); ';
1002           // clean the action buttons in other tables
1003           for ($e = 0 ; $e < TABLES_N ; $e++) {
1004             if ($this->table[$e]->player_n < PLAYERS_N) {
1005               // $ret .= table_act_content(TRUE, 0, $e, $user->table, 
1006               //                           ($this->table[$e]->auth_only == FALSE ? TRUE : $user->flags & USER_FLAG_AUTH));
1007               $ret .= $this->table[$e]->act_content($user);
1008             }
1009           }
1010         }
1011         else {
1012           // $ret .= table_act_content(($user_cur->subst == 'standup'), $table->player_n, $table_idx, $user_cur->table,
1013           //                           ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
1014           $ret .= $table->act_content($user_cur);
1015         }
1016       }
1017       log_wr("ROOM_WAKEUP: ".$ret);
1018       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1019       $user_cur->step_inc();
1020     }
1021   }
1022
1023   function room_join_wakeup($user, $update_lacc = FALSE, $trans_delta)
1024   {
1025     $table_idx = $user->table;
1026     $table = $this->table[$table_idx];
1027     
1028     log_main("JOIN_WAKEUP: begin function table:".$table_idx."  stat: ".$user->stat."  subst: ".$user->subst);
1029
1030     $curtime = time();
1031     $user_wup = array();
1032     $user_wup_n = 0;
1033     $user_tab = array();
1034     $user_tab_n = 0;
1035     log_main("JOIN WAKEUP: from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
1036     
1037     for ($i = 0 ; $i < $table->player_n ; $i++) {
1038       $user_cur = $this->user[$table->player[$i]];
1039       log_main("PREIMPOST INLOOP name: ".$user_cur->name);
1040       if ($user_cur->sess != "") {
1041         if ($update_lacc == TRUE) {
1042           $user_cur->laccwr = $curtime;
1043         }
1044         log_main("cur: ".$user_cur->name."  subst: ".$user_cur->subst);
1045         if ($user_cur->subst == "shutdowned") {
1046           $user_cur->stat_set("room");
1047           $user_cur->subst = "sitdown";
1048         }
1049         else if ($user_cur->subst == "shutdowner") {
1050           $user_cur->stat_set("room");
1051           $user_cur->subst = "standup";
1052           $user_cur->table = -1;
1053           $user_wup[$user_wup_n++] = $user_cur;
1054           
1055           $remove_wagon = FALSE;
1056           if($table->wag_own == $table->player[$i]) {
1057             $remove_wagon = TRUE;
1058             $table->wag_reset($curtime);
1059           }
1060         }
1061         $user_tab[$user_tab_n++] = $table->player[$i];
1062       }
1063     }
1064
1065     for ($wup_idx = 0 ; $wup_idx < $user_wup_n  ; $wup_idx++)
1066       $table->user_rem($this, $user_wup[$wup_idx]);
1067
1068     /* aggiorna l'array dei giocatori al tavolo. */
1069
1070     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1071       log_main("START LOOP");
1072       $user_cur = $this->user[$i];
1073       if ($user_cur->sess == '' || $user_cur->stat != 'room') {
1074         log_main("name: ".$user_cur->name."skip   subst: ".$user_cur->subst);
1075         continue;
1076       }
1077
1078       log_main("___");
1079       log_main("VALORI name: ".$user_cur->name."  tab: ".$user_cur->table." taix: ".$table_idx);
1080
1081       $ret = "gst.st = ".($user_cur->step+1)."; ".($remove_wagon ? sprintf("tra.rem(%d);",$table_idx) : "");
1082       if ($user_cur->stat == "room") {
1083         log_main("DOCUMENT.index.php from table");
1084
1085         $ret .= $this->table_content($user_cur, $table_idx);
1086         $ret .= $this->standup_content($user_cur);
1087         
1088         // $ret .= table_act_content(FALSE, 0, $table_idx, $user_cur->table,
1089         //                           ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
1090         $ret .= $table->act_content($user_cur);
1091
1092
1093         for ($tab_idx = 0 ; $tab_idx < $user_tab_n  ; $tab_idx++)
1094             if ($user_tab[$tab_idx] == $i) 
1095                 break;
1096
1097         // for users that wakeup the room will be reconstructed by index_rd.php
1098         if ($tab_idx < $user_tab_n) {
1099           log_main("PRE show_room username: ".$user_cur->name."  STEP: ".$user_cur->step);
1100
1101 //        ARRAY_POP DISABLED
1102 //        if ($trans_delta == 0)
1103 //          while (array_pop($user_cur->comm) != NULL);
1104
1105           $user_cur->trans_step = $user_cur->step + 1 + $trans_delta;
1106           $user_cur->comm[$user_cur->step % COMM_N] = "";
1107           $user_cur->step_inc();
1108           $user_cur->comm[$user_cur->step % COMM_N] = $this->show_room(($user_cur->step + 1), $user_cur);
1109           $user_cur->step_inc();
1110           log_main("POST show_room username: ".$user_cur->name."  STEP: ".$user_cur->step);
1111
1112           continue;
1113         }
1114         log_main("JOIN_WAKEUP wup_idx ".$wup_idx."  wup_n ".$user_wup_n);
1115
1116         log_main("JOIN_WAKEUP more");
1117         // $ret .= table_act_content(($user_cur->subst == 'standup'), $table->player_n, $table_idx, $user_cur->table,
1118         //                           ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
1119         $ret .= $table->act_content($user_cur);
1120
1121         log_main("JOIN_WAKEUP end more");
1122       }
1123       log_wr("ROOM_JOIN_WAKEUP: ".$ret);
1124       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1125       $user_cur->step_inc();
1126     }
1127   }
1128
1129   function room_outstandup($user)
1130   {
1131     $this->room_sitdown($user, -1);
1132   }
1133   
1134   function table_update($user)
1135   {
1136     log_main("table_update: pre - USER: ".$user->name);
1137
1138     $table_idx = $user->table;
1139
1140     if ($table_idx > -1) 
1141       $table = $this->table[$table_idx];
1142     
1143     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1144       $ret = "";
1145       $user_cur = $this->user[$i];
1146       if ($user_cur->sess == '' || $user_cur->stat != 'room')
1147       continue;
1148       
1149       $ret = "gst.st = ".($user_cur->step+1)."; ";
1150       if ($table_idx > -1)
1151         $ret .= $this->table_content($user_cur, $table_idx);
1152       
1153       if ($user->idx_get() == $i) {
1154           $ret .= $user->myname_innerHTML();
1155       }
1156       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1157       $user_cur->step_inc();
1158     }
1159
1160     log_main("table_update: post");
1161   }
1162
1163   function room_sitdown($user, $table_idx)
1164   {
1165     log_main("room_sitdown ".($user == FALSE ? "USER: FALSE" : "USER: ".$user->name));
1166
1167     $train_app = "";
1168
1169     if ($table_idx > -1 && $table_idx < TABLES_N) { 
1170       $table = $this->table[$table_idx];
1171
1172       // wagon shutdown 
1173       if ($table->wag_own != -1 && $table->player_n == PLAYERS_N) {        
1174         for ($i = 0 ; $i < TABLES_N ; $i++) {
1175             if ($table->wag_own == $table->player[$i]) {
1176                 $train_app = sprintf("tra.rem(%d); ", $table_idx); 
1177                 $table->wag_reset(time());
1178                 break;
1179             }
1180         }
1181       }
1182     }
1183
1184     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1185       $ret = "";
1186       $user_cur = $this->user[$i];
1187       if ($user_cur->sess == '' || $user_cur->stat != 'room')
1188       continue;
1189       
1190       $ret = "gst.st = ".($user_cur->step+1)."; ".$train_app;
1191       if ($table_idx > -1)
1192       $ret .= $this->table_content($user_cur, $table_idx);
1193       $ret .= $this->standup_content($user_cur);
1194       
1195       if ($user->idx_get() == $i) {
1196         $ret .=  'subst = "sitdown"; tra.hide(); ';
1197         // clean the action buttons in other tables
1198         for ($e = 0 ; $e < TABLES_N ; $e++) {
1199           // $ret .= table_act_content(FALSE, 0, $e, $user_cur->table, FALSE);
1200           $ret .= $this->table[$e]->act_content($user_cur);
1201         }
1202       }
1203       else if ($table_idx > -1) {
1204         if ($table->player_n == PLAYERS_N) {
1205           // $ret .= table_act_content(($user_cur->subst == 'standup'), PLAYERS_N, $table_idx, $user_cur->table,
1206           ///                      ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
1207           $ret .= $table->act_content($user_cur);
1208         }
1209       }
1210       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1211       $user_cur->step_inc();
1212     }
1213   }
1214
1215   function chatt_send($user, $mesg)
1216   {
1217     GLOBAL $G_base, $G_alarm_passwd, $mlang_brisk, $G_lang;
1218     $only_you = FALSE;
1219     
1220     // common settings
1221     $msg = substr($mesg, 6, 128);
1222     $curtime = time();
1223     $dt = date("H:i ", $curtime);
1224     $target = "";
1225
1226     //
1227     //  Compute actions
1228     //
1229
1230     $to_user     = FALSE;
1231     $to_all      = FALSE;
1232     $to_room     = FALSE;
1233     $to_tabl     = FALSE;
1234     $is_normchat = FALSE;
1235     /* for old isolation management $is_ticker   = FALSE; */
1236     $update_room = FALSE;
1237
1238     if (strcmp($msg,  "/tav") == 0 || 
1239         strncmp($msg, "/tav ", 5) == 0) {
1240       do {
1241         if ($user->stat != 'room' || $user->subst != 'sitdown') {
1242           /* MLANG: "<br>Per attivare il messaggio di segnalazione del tavolo occorre essere seduti.<br><br>", "<br>Il messaggio di segnalazione del tavolo &egrave; gi&agrave; attivato.<br><br>", "<br>Il messaggio di segnalazione del tavolo<br>&egrave; disattivato ancora per %d second%s.<br><br>" */
1243           $msg = $mlang_brisk['tickmust'][$G_lang];
1244           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1245
1246           break;
1247         }
1248
1249         $table = $this->table[$user->table];
1250         
1251         if ($table->wag_own != -1) {
1252           // MLANG <br>Il messaggio di segnalazione del tavolo &egrave; gi&agrave; attivato.<br><br> 
1253           $msg = $mlang_brisk['tickjust'][$G_lang];
1254           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1255
1256           break;
1257         }
1258
1259         $dtime = $curtime - $table->wag_tout;
1260         if ($dtime  < EXPIRE_TIME_WAG) {
1261           // MLANG - <br>Il messaggio di segnalazione del tavolo<br>&egrave; disattivato ancora per %d second%s.<br><br>
1262           $msg = sprintf($mlang_brisk['tickwait'][$G_lang],
1263                          EXPIRE_TIME_WAG - $dtime, (EXPIRE_TIME_WAG - $dtime == 1 ? ($G_lang == 'en' ? "" : "o") : ($G_lang == 'en' ? "s" : "i")));
1264           $to_user = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang] , 400, 100);
1265
1266           break;
1267         }
1268         
1269         $msg = substr($msg, 5);
1270         
1271         $table->wag_set($user->idx_get(), $msg);
1272         $to_user = sprintf('tra.add(%d, "%s");', $user->table, xcape(sprintf("%s: %s", $user->name, $msg)));
1273         $to_room = $to_user;
1274         /* for old isolation management $is_ticker = TRUE; */
1275       } while (0);
1276     } // /tav chat command
1277
1278     else if (strncmp($msg, "/alarm ", 7) == 0) {
1279       if (strncmp($msg, "/alarm to ", 10) == 0) {
1280         $sp_pos = strpos($msg, " ", 10);
1281         $target = substr($msg, 10, $sp_pos - 10);
1282         $alarm_check = "/alarm to ".$target." ".$G_alarm_passwd." ";
1283       }
1284       else {
1285         $target = "";
1286         $alarm_check = "/alarm ".$G_alarm_passwd." ";
1287       }
1288       do {
1289         if (strncmp($msg, $alarm_check, strlen($alarm_check)) != 0) {
1290           /* MLANG: "<br>La password digitata non &egrave; corretta.<br><br>" */
1291           $msg = $mlang_brisk['alarpass'][$G_lang];
1292           $to_user = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang], 400, 100);
1293
1294           break;
1295         }
1296
1297         /* MLANG: "Alarm <b>%s</b> inviato a <b>%s</b>." */
1298         $prestr = sprintf($mlang_brisk['alarret'][$G_lang], xcape(substr($msg, strlen($alarm_check))), 
1299                            ($target == "" ? $mlang_brisk['tit_all'][$G_lang] : xcape($target)) );
1300         $to_user = sprintf('chatt_sub("%s", [2, "%s"],%s);', 
1301                            $dt, NICKSERV, $prestr);
1302
1303         $msg = sprintf("<br><b>%s<br><br>%s</b><br><br>",
1304                        $dt.NICKSERV, xcape(substr($msg, strlen($alarm_check))));
1305         /* MLANG: "chiudi" */
1306         $to_all = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang], 400, 120);
1307       } while (0);
1308     } // /alarm chat command
1309     else if (strncmp($msg, "/listen ", 8) == 0) {
1310       $arg = substr($msg, 8);
1311
1312       if (strcasecmp($arg, "isolation") == 0) {
1313         $flags_old = 0;
1314         if ($user->stat == 'room' && $user->subst == 'sitdown' &&
1315             $user->table >= TABLES_AUTH_N) {
1316           $to_user = sprintf('chatt_sub("%s", [2, "%s"],"%s");', $dt, NICKSERV, $mlang_brisk['listmust'][$G_lang]);
1317           
1318         }
1319         else {
1320           $user->flags &= ~USER_FLAG_MAP_AUTH;
1321           $user->flags |= USER_FLAG_ISOLAUTH;
1322           $to_user = 'list_set(\'isolation\', true, \''.$mlang_brisk['tit_onisol'][$G_lang].'\'); ';
1323         }
1324       }
1325       else if (strcasecmp($arg, "auth") == 0) {
1326         $flags_old = $user->flags;
1327         $user->flags &= ~USER_FLAG_MAP_AUTH;
1328         $user->flags |= USER_FLAG_LISTAUTH;
1329         $to_user = 'list_set(\'auth\', true, \''.$mlang_brisk['tit_onauth'][$G_lang].'\'); ';
1330       }
1331       else {
1332         $flags_old = $user->flags;
1333         $user->flags &= ~USER_FLAG_MAP_AUTH;
1334         $to_user = 'list_set(\'all\', true, \'\'); ';
1335         
1336       }
1337       // if from isolation redraw standup area
1338       if (($flags_old ^ $user->flags) & USER_FLAG_ISOLAUTH) {
1339         $to_user .= 'standup_data_old = null; '.$this->standup_content($user);
1340         
1341       }
1342     }
1343     else if (strcmp($msg, "/authreq") == 0) {
1344       if ($user->flags & USER_FLAG_AUTH) {
1345         $to_user = sprintf('authbox(300,200);');
1346       }
1347       else {
1348         /* MLANG: "<b>Per autenticare qualcuno devi a tua volta essere autenticato.</b>", "Il nickname deve contenere almeno una lettera dell\'alfabeto o una cifra.", "Nickname <b>%s</b> gi&agrave; in uso." */
1349         $to_user = sprintf('chatt_sub("%s", [2, "%s"],"%s");', $dt, NICKSERV, $mlang_brisk['authmust'][$G_lang]);
1350       }
1351     }
1352     else if (strncmp($msg, "/mesgtoadm", 8) == 0) {
1353       if ($user->flags & USER_FLAG_AUTH) {
1354         $to_user = sprintf('mesgtoadmbox(500,300);');
1355       }
1356       else {
1357         /* MLANG: "<b>Per inviare un messaggio devi essere autenticato.</b>" */
1358         $to_user = sprintf('chatt_sub("%s", [2, "%s"],"%s");', $dt, NICKSERV, $mlang_brisk['mesgmust'][$G_lang]);
1359       }
1360     }
1361     else if (strncmp($msg, "/nick ", 6) == 0) {
1362       log_main("chatt_send BEGIN");
1363
1364       do {
1365         if (($name_new = validate_name(substr($msg, 6))) == FALSE) {
1366           $to_user = sprintf('chatt_sub("%s", [2,"%s"],"%s");', $dt, NICKSERV, $mlang_brisk['nickmust'][$G_lang]);
1367           break;
1368         }
1369
1370         $msg = "COMMAND ".$msg;
1371         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1372           $user_cur = $this->user[$i];
1373
1374           if ($user_cur->sess == '')
1375             continue;
1376           if (strcasecmp($user_cur->name,$name_new) == 0)
1377             break;
1378           }
1379         if ($i <  MAX_PLAYERS) {
1380           $prestr = sprintf($mlang_brisk['nickdupl'][$G_lang], xcape($name_new));
1381           $to_user = sprintf('chatt_sub("%s", [2, "%s"],"%s");', $dt, NICKSERV, $prestr);
1382           break;
1383         }
1384         
1385         /* MLANG: "<b>Non puoi cambiare nick a un tavolo per soli autenticati.</b>", "Il nickname <b>\'%s\'</b> &egrave; gi&agrave; registrato, <b>se il suo proprietario si autentificher&agrave; verrai rinominato d\'ufficio come ghost<i>N</i>.</b>" */
1386         if ($user->flags & USER_FLAG_AUTH) {
1387           if (strcasecmp($user->name,$name_new) != 0) {
1388              if (( ($user->flags & USER_FLAG_MAP_AUTH) != USER_FLAG_ISOLAUTH) &&
1389                 ($user->subst == 'standup' || 
1390                  ($user->subst != 'standup' && $this->table[$user->table]->auth_only == FALSE)
1391                  )
1392                 ) {
1393               $user->flags &= ~(USER_FLAG_AUTH | USER_FLAG_TY_ALL); // Remove auth if name changed
1394               for ($i = 0 ; $i < TABLES_N ; $i++) {
1395                 $to_user .= $this->table[$i]->act_content($user);
1396               }
1397             }
1398             else {
1399               $to_user = sprintf('chatt_sub("%s", [2, "%s"],"%s");', $dt, NICKSERV, $mlang_brisk['authchan'][$G_lang]);
1400               break;
1401             }
1402           }
1403         }
1404         $user->name = $name_new; // OK - nick changed
1405         /* se nome gia' in uso, segnala cosa potrebbe capitare */
1406         if (($user->flags & USER_FLAG_AUTH) == 0) {
1407             if (($bdb = BriskDB::create()) != FALSE) {
1408                 $bdb->users_load();
1409                 /* MLANG: "Il nickname <b>\'%s\'</b> &egrave; gi&agrave; registrato, <b>se il suo proprietario si autentificher&agrave; verrai rinominato d\'ufficio come ghost<i>N</i>.</b>" */
1410                 if ($bdb->login_exists($name_new)) {
1411                     $prestr = sprintf($mlang_brisk['nickjust'][$G_lang], xcape($name_new));
1412                     $to_user .= sprintf('chatt_sub("%s", [2, "%s"],"%s");', $dt, NICKSERV, $prestr);
1413                 }
1414             }
1415         }
1416
1417         log_main("chatt_send start set");
1418
1419         $update_room = TRUE;
1420       } while (0);
1421     } // nick chat command
1422
1423     else if (strncmp($msg, "/st ", 4) == 0) {
1424       log_main("chatt_send BEGIN");
1425
1426       do {
1427         $st_str = substr($msg, 4);
1428         
1429         if (strcasecmp($st_str, "normale") == 0) {
1430           $st = USER_FLAG_S_NORM;
1431         }
1432         else if (strcasecmp($st_str, "pausa") == 0) {
1433           $st = USER_FLAG_S_PAU;
1434         }
1435         else if (strcasecmp($st_str, "fuori") == 0) {
1436           $st = USER_FLAG_S_OUT;
1437         }
1438         else if (strcasecmp($st_str, "cane") == 0) {
1439           $st = USER_FLAG_S_DOG;
1440         }
1441         else if (strcasecmp($st_str, "cibo") == 0) {
1442           $st = USER_FLAG_S_EAT;
1443         }
1444         else if (strcasecmp($st_str, "lavoro") == 0) {
1445           $st = USER_FLAG_S_WRK;
1446         }
1447         else if (strcasecmp($st_str, "sigaretta") == 0) {
1448           $st = USER_FLAG_S_SMK;
1449         }
1450         else if (strcasecmp($st_str, "presente") == 0) {
1451           $st = USER_FLAG_S_EYE;
1452         }
1453         else if (strcasecmp($st_str, "coniglio") == 0) {
1454           $st = USER_FLAG_S_RABB;
1455         }
1456         else if (strcasecmp($st_str, "calcio") == 0) {
1457           $st = USER_FLAG_S_SOCC;
1458         }
1459         else if (strcasecmp($st_str, "pupo") == 0) {
1460           $st = USER_FLAG_S_BABY;
1461         }
1462         else if (strcasecmp($st_str, "pulizie") == 0) {
1463           $st = USER_FLAG_S_MOP;
1464         }
1465         else {
1466           /* MLANG: "Questo stato non esiste." */
1467           $to_user = sprintf('chatt_sub("%s", [2,"%s"],"%s");', $dt, NICKSERV, $mlang_brisk['statunkn'][$G_lang]);
1468           break;
1469         }
1470
1471         log_main("chatt_send start set");
1472         if (($user->flags & USER_FLAG_S_ALL) != $st) {
1473           $update_room = TRUE;
1474           $user->flags = ($user->flags & ~USER_FLAG_S_ALL) | $st;
1475         }
1476       } while (0);
1477     } // nick chat command
1478
1479     else { // normal chat line
1480       $is_normchat = TRUE;
1481       if ($curtime < ($user->chat_ban + $user->chat_dlt)) {
1482         $only_you = TRUE;
1483         $user->chat_dlt = $user->chat_dlt * 2; 
1484         if ($user->chat_dlt > 120)
1485           $user->chat_dlt = 120; 
1486       }
1487       else if ($user->chat_lst == $msg)
1488         $only_you = TRUE;
1489       else if ($curtime - $user->chattime[($user->chat_cur + 1) % CHAT_N] < CHAT_ILL_TIME) {
1490         $user->chat_ban = $curtime;
1491         $user->chat_dlt = 5;
1492         $only_you = TRUE;
1493       }
1494       else {
1495         $user->chat_ban = 0;
1496         $user->chat_dlt = 0;
1497       }
1498
1499       if ($only_you) {
1500         $to_user = sprintf('chatt_sub("%s", [%d, "%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape("== chat ban =="));
1501       }
1502       else {
1503         $to_user = sprintf('chatt_sub("%s", [%d, "%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape($msg));
1504         // temporary silentiation for troll (will became array check)
1505         // if (strcasecmp($user->name,'JackRokka') != 0 && $user->sess != '47ea653f602e8')
1506         $to_room = $to_user;
1507       }
1508
1509       log_legal($curtime, 'xxx', $user, 
1510                 ($user->stat == 'room' ? 'room' : 'table '.$user->table),$msg);
1511       
1512       $user->chat_lst = "$msg";
1513       $user->chattime[$user->chat_cur % CHAT_N] = $curtime;
1514       $user->chat_cur++;
1515     }
1516
1517     if ($to_all) {
1518       $to_room = $to_all;
1519       $to_tabl = $to_all;
1520     }
1521
1522     //
1523     //  Output to clients
1524     //
1525
1526     if ($to_user != FALSE) {
1527       $user->comm[$user->step % COMM_N] =  "gst.st = ".($user->step+1)."; ";
1528       $user->comm[$user->step % COMM_N] .= $to_user;
1529       $user->step_inc();
1530     }
1531
1532     if ($to_room != FALSE) {
1533       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1534         $user_cur = $this->user[$i];
1535         if ($target != "" && $user_cur->name != $target)
1536           continue;
1537         if ($user_cur->sess == '' || $user_cur->stat == 'table' || $user->idx_get() == $i)
1538           continue;
1539         
1540         if ($is_normchat == TRUE) {
1541           // use MAP_AUTH to check if auth or isolation
1542           if ($user_cur->flags & USER_FLAG_MAP_AUTH) {
1543             if (($user->flags & USER_FLAG_AUTH) == 0) {
1544               continue;
1545             }
1546           }
1547         }
1548         /*
1549         else if ($is_ticker) {
1550           if (($user_cur->flags & USER_FLAG_MAP_AUTH) == USER_FLAG_ISOLAUTH) {
1551             if ($user->table >= TABLES_AUTH_N)
1552               continue;
1553           }
1554         }
1555         */
1556         $user_cur->comm[$user_cur->step % COMM_N] =  "gst.st = ".($user_cur->step+1)."; ";
1557         $user_cur->comm[$user_cur->step % COMM_N] .= $to_room; 
1558         $user_cur->step_inc();
1559       }
1560     }
1561     
1562     if ($to_tabl) {
1563       // FIXME BRISK4: include for each kind of table
1564       require_once("${G_base}briskin5/Obj/briskin5.phh");
1565       // Before all align times with table timeout
1566       for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1567         $table_cur = $this->table[$table_idx];
1568         // if the table is complete and exists its shared mem we get the info about users lacc
1569         
1570         if ($table_cur->player_n == PLAYERS_N) {
1571           log_main("PLAYERS == N TABLE ".$table_idx);
1572         
1573           if (($sem = Bin5::lock_data(TRUE, $table_idx)) != FALSE) { 
1574             log_main("bin5 lock data success");
1575             
1576             $no_recovery = FALSE;
1577             if (($bri = Bin5::load_data($table_idx)) != FALSE) {
1578               if ($table_cur->table_token != $bri->table_token) {
1579                 log_main("ERROR: not matching table_token. Room: ".$table_cur->table_token."  Table: ".$bri->table_token);
1580                 $bri = FALSE;
1581               }
1582             }
1583             
1584             if ($bri != FALSE) {
1585               $bri_table = $bri->table[0];
1586               for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
1587                 // stat must be "table" by definition
1588                 $bri_user = $bri->user[$i];
1589               
1590                 if ($target != "" && $bri_user->name != $target)
1591                   continue;
1592                 log_main("writa: ".$user_mesg);
1593                 $bri_user->comm[$bri_user->step % COMM_N] = "gst.st = ".($bri_user->step+1)."; ";
1594                 $bri_user->comm[$bri_user->step % COMM_N] .= $to_tabl;
1595                 $bri_user->step_inc();
1596               }
1597               Bin5::save_data($bri);
1598             }
1599             Bin5::unlock_data($sem);
1600           } // bri::lock_data
1601         } //  if ($table_cur->player_n == PLAYERS_N) {
1602       } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1603     } // if ($to_tabl == true ...
1604
1605     if ($update_room) {
1606       if ($user->stat == 'room' && $user->subst == 'standup') {
1607         $this->standup_update($user);
1608       }
1609       else if ($user->stat == 'room' && $user->subst == 'sitdown') {
1610         log_main("chatt_send pre table update");
1611         $this->table_update($user);
1612         log_main("chatt_send post table update");
1613       }
1614     } // if ($update_room ...
1615
1616     return;
1617   } // function chatt_send( ...
1618
1619   function get_user($sess, &$idx)
1620   {
1621     GLOBAL $PHP_SELF;
1622
1623     if (validate_sess($sess)) {
1624       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1625         if (strcmp($sess, $this->user[$i]->sess) == 0) {
1626           // find it
1627           $idx = $i;
1628           $ret = $this->user[$i];
1629           return ($ret);
1630         }
1631       }
1632       log_main(sprintf("get_user: Wrong sess from page [%s]",$PHP_SELF));
1633       // for ($i = 0 ; $i < MAX_PLAYERS ; $i++) 
1634       // log_main(sprintf("get_user: Wrong sess compared with [%s]",$this->user[$i]->sess));
1635     }
1636     else {
1637       log_main(sprintf("get_user: Wrong strlen [%s]",$sess));
1638     }
1639
1640     return (FALSE);
1641   }
1642
1643   /*
1644    * function add_user(&$room, &$sess, &$idx, $name, $pass, $ip)
1645    *
1646    * RETURN VALUE:
1647    *   if ($idx >  -1    && ret == FALSE)  =>  duplicated nick
1648    *   if ($idx == -2    && ret == FALSE)  =>  invalid name
1649    *   if ($idx == -3    && ret == FALSE)  =>  wrong password
1650    *   if ($idx == -1    && ret == FALSE)  =>  no space left
1651    *   if ($idx ==  0    && ret == user)   =>  SUCCESS
1652    *   if ($idx == -$idx && ret == user)   =>  SUCCESS (but the login exists in the auth db)
1653    */
1654
1655   function add_user(&$sess, &$idx, $name, $pass, $ip)
1656   {
1657     GLOBAL $G_base, $CO_list;
1658
1659     $idx = 0;
1660
1661     $authenticate = FALSE;
1662     $user_type    = 0;
1663     $login_exists = FALSE;
1664     $ghost = -1;
1665     $ghost_auth = FALSE;
1666     $idx = -1;
1667     $idfree = -1;
1668     $code = FALSE;
1669
1670     if (($name_new = validate_name($name)) == FALSE) {
1671       $idx = -2;
1672       return (FALSE);
1673     }
1674
1675     log_auth("XXX", sprintf("ARRIVA: [%s] pass:[%s]", $sess, ($pass == FALSE ? "FALSE" : $pass)));
1676     if (validate_sess($sess) == FALSE) 
1677       $sess = "";
1678
1679     /* if pass != FALSE verify the login with pass */
1680     log_auth("XXX", "auth1");
1681
1682     if (($bdb = BriskDB::create()) != FALSE) {
1683         $bdb->users_load();
1684         if ($pass != FALSE) { // TODO: here add a method to $bdb to check if the db is available.
1685             log_auth("XXX", "auth2");
1686             $authenticate = $bdb->login_verify($name_new, $pass, $code);
1687             log_auth("XXX", "authenticate: ".($authenticate != FALSE ? "TRUE" : "FALSE"));
1688             
1689             if ($authenticate != FALSE) {
1690                 $user_type = $authenticate->type_get();
1691             }
1692             else {
1693                 $idx = -3;
1694                 return (FALSE);
1695             }
1696         }
1697         else {
1698             $login_exists =  $bdb->login_exists($name_new);
1699         }
1700     }
1701     else {
1702         // if db is down, send a warning and verify only current users
1703         // no actions at this moment
1704     }
1705     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1706       /* free user ? */
1707       if (strcmp($sess, $this->user[$i]->sess) == 0) {
1708         if ($idx == -1)
1709           $idx = $i;
1710       }
1711       if ($idfree == -1 && strcmp($this->user[$i]->sess, "") == 0) {
1712         $idfree = $i;
1713         continue; // NOTE: CHECK IT !!
1714       }
1715       if (strcasecmp($this->user[$i]->name, $name_new) == 0) {
1716           if ($authenticate != FALSE) {
1717               $ghost = $i;
1718               $ghost_auth = ($this->user[$i]->flags & USER_FLAG_AUTH);
1719           }
1720           else {
1721               $idx = $i;
1722               break;
1723           }
1724       }
1725     }
1726     if ($idx == -1)
1727       $idx = $idfree;
1728
1729     log_auth("XXX", sprintf("TROVATO A QUESTO PUNTO [%d] sess [%s] name [%s]", $idx, $sess, $name_new));
1730
1731     /* there is another user logged with your account and you and him have authenticated => new user
1732        get the session of the old user */
1733     if ($ghost > -1 && $ghost_auth && ($authenticate != FALSE)) {
1734       /* swap session */
1735
1736       $ghost_user = $this->user[$ghost];
1737       $curtime = time();
1738       $ghost_user->step_inc();
1739       if ($sess == "") {
1740         $sess = uniqid(""); 
1741         $ghost_user->sess = $sess;
1742       }
1743       else {
1744         $ghost_user->sess = $sess;
1745       }
1746       
1747       // If user at the table we need to update the table data too
1748       $table_idx = $ghost_user->table;
1749       if ($ghost_user->stat == "table" && $this->table[$table_idx]->player_n == PLAYERS_N) {
1750         // FIXME BRISK4: include for each kind of table
1751         require_once("${G_base}briskin5/Obj/briskin5.phh");
1752         if (($brisem = Bin5::lock_data(TRUE, $table_idx)) != FALSE) { 
1753           if (($bri = Bin5::load_data($table_idx)) != FALSE) {
1754             if ($bri->the_end != TRUE) {
1755               $bri->user[$ghost_user->table_pos]->step_inc();
1756               $bri->user[$ghost_user->table_pos]->sess = $sess;
1757               Bin5::save_data($bri);
1758             }
1759           }
1760           Bin5::unlock_data($brisem);
1761         }
1762       }
1763
1764       $idx = $ghost;
1765       return ($this->user[$ghost]);
1766     }
1767     else if ($idx != -1 && $i == MAX_PLAYERS) {
1768       /* SUCCESS */
1769       $curtime = time();
1770       if ($sess == "") {
1771         $sess = uniqid("");
1772         $this->user[$idx]->sess = $sess;
1773       }
1774       else {
1775         $this->user[$idx]->sess = $sess;
1776       }
1777       $this->user[$idx]->name = $name_new; // OK - add new user
1778       $this->user[$idx]->stat_set("room");
1779       $this->user[$idx]->step_set(0);
1780       while (array_pop($this->user[$idx]->comm) != NULL);
1781       $this->user[$idx]->subst = "standup";
1782       $this->user[$idx]->lacc =   $curtime;
1783       $this->user[$idx]->laccwr = $curtime;
1784       $this->user[$idx]->bantime = 0;
1785       $this->user[$idx]->ip = $ip;
1786
1787       $this->user[$idx]->flags = $user_type;
1788       $this->user[$idx]->flags |= ($authenticate != FALSE ? USER_FLAG_AUTH : 0x00);
1789       $this->user[$idx]->flags |= ( ($pass != FALSE && $bdb == FALSE) ? USER_FLAG_DBFAILED : 0x00);
1790       log_auth("XXX", sprintf("FLAGS: [%x]", $this->user[$idx]->flags));
1791
1792       
1793       if ($authenticate != FALSE) {
1794         $this->user[$idx]->code = $authenticate->code_get();
1795         $this->user[$idx]->flags |= USER_FLAG_LISTAUTH;
1796
1797         if (isset($CO_list)) {
1798           if (strcmp($CO_list, "auth") == 0) {
1799             $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
1800             $this->user[$idx]->flags |= USER_FLAG_LISTAUTH;
1801           }
1802           if (strcmp($CO_list, "isolation") == 0) {
1803             $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
1804             $this->user[$idx]->flags |= USER_FLAG_ISOLAUTH;
1805           }
1806           else {
1807             $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
1808           }
1809         }
1810       }
1811       
1812       if ($ghost > -1) {
1813         log_main("ghost: rename!");
1814         $ghost_user = $this->user[$ghost];
1815
1816         if ($ghost_auth == FALSE) {
1817           for ($sfx = 1 ; $sfx <= MAX_PLAYERS ; $sfx++) {
1818             $ghostname = 'ghost'.$sfx;
1819             for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1820               if (strcmp("", $this->user[$i]->sess) == 0) 
1821                 continue;
1822               
1823               if (strcasecmp($this->user[$i]->name, $ghostname) == 0) {
1824                 $ghostname = '';
1825                 break;
1826               }
1827             }
1828             if ($ghostname != '')
1829               break;
1830           }
1831           
1832           $ghost_user->name = $ghostname;
1833           
1834           if ($ghost_user->stat == 'room' && $ghost_user->subst == 'standup') {
1835             $this->standup_update($ghost_user);
1836           }
1837           else {
1838             log_main("chatt_send pre table update");
1839             $this->table_update($ghost_user);
1840           log_main("chatt_send post table update");
1841           }
1842         } // if ($ghost_auth == FALSE
1843         else {
1844           // FIXME: cacciare il vecchio utente room && table (if needed)
1845           $ghost_user->the_end = TRUE;
1846           $ghost_user->lacc = 0;
1847           $this->garbage_manager(TRUE);
1848         }
1849       } //  if ($ghost > -1) {
1850
1851       $real_idx = $idx;
1852       if ($login_exists)
1853         $idx = -($idx + 1);
1854       log_main(sprintf("TROVATO LIBERO A [%d] sess [%s] name [%s] count [%d] name [%s] code [%s]", $idx, $sess, $name_new, count($this->user),$this->user[$real_idx]->name, $this->user[$real_idx]->code));
1855
1856       $ret = $this->user[$real_idx];
1857       return ($ret);
1858     }
1859
1860     return (FALSE);
1861   }
1862   
1863   function standup_update($user)
1864   {
1865     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1866       $user_cur = $this->user[$i];
1867       if ($user_cur->sess == '')
1868         continue;
1869
1870       log_main("STANDUP START: ".$user_cur->stat);
1871       
1872       if ($user_cur->stat == 'room') {
1873         $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ".$this->standup_content($user_cur);
1874         if ($user->idx_get() == $i) {
1875           $user_cur->comm[$user_cur->step % COMM_N] .= $user->myname_innerHTML();
1876         }
1877         log_main("FROM STANDUP: NAME: ".$user_cur->name." SENDED: ".$user_cur->comm[$user_cur->step % COMM_N]);
1878         
1879         $user_cur->step_inc();
1880       }
1881     }
1882   }
1883
1884   // Static functions
1885   static function create()
1886   {
1887     $room = new Room();
1888     
1889     return $room;
1890   }
1891   
1892   
1893   function load_data() 
1894   {
1895     GLOBAL $sess;
1896
1897     do {
1898       if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) {
1899         log_main("ftok failed");
1900         break;
1901       }
1902     
1903       if (($shm_sz = sharedmem_sz($tok)) == -1) {
1904         log_main("shmop_open failed");
1905       }
1906         
1907       if ($shm_sz == -1)
1908         $shm_sz = SHM_DIMS_MIN;
1909
1910       if ($shm = shm_attach($tok, $shm_sz)) {
1911           $room = @shm_get_var($shm, $tok); // CHECKED BELOW
1912           
1913           log_only("bri ==  ".($room == FALSE ?   "FALSE" : "TRUE")."  bri ===  ".($room === FALSE ? "FALSE" : "TRUE")."  bri isset ".(isset($room) ?   "TRUE" : "FALSE"));
1914           if (isset($room)) 
1915               log_only("bri count ".count($room));
1916           
1917           if ($room == FALSE) {
1918               log_only("INIT MAIN DATA");
1919               shm_detach($shm);
1920               
1921               $room = Room::create();
1922               
1923               log_shme("Room::create");
1924
1925               if (Room::save_data($room) == FALSE)
1926                   return FALSE;
1927
1928               return $room;
1929           }
1930           $room->shm_sz = $shm_sz;
1931           
1932           shm_detach($shm);
1933
1934           for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1935               if (($room->user[$i] = User::load_data($i, FALSE)) == FALSE) {
1936                   log_crit("User::load_data failed");
1937                   break;
1938               }
1939           }
1940           if ($i < MAX_PLAYERS) {
1941               break;
1942           }
1943       }
1944       
1945       //  
1946       // SHSPLIT: load users from the shared memory
1947       //
1948       return ($room);
1949     } while (0);
1950     
1951     return (FALSE);
1952   }
1953   
1954
1955   function save_data_orig($room) 
1956   {
1957     GLOBAL $sess;
1958     
1959     $shm =   FALSE;
1960     
1961     // var_dump($room);
1962     
1963     if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) 
1964       return (FALSE);
1965     
1966     while ($room->shm_sz < SHM_DIMS_MAX) {
1967       if (($shm = shm_attach($tok, $room->shm_sz)) == FALSE)
1968         break;
1969       
1970       // log_only("PUT_VAR DI ".strlen(serialize($room)));
1971       if (@shm_put_var($shm, $tok, $room) != FALSE) {
1972         shm_detach($shm);
1973         return (TRUE);
1974       }
1975       if (shm_remove($shm) === FALSE) {
1976         log_only("REMOVE FALLITA");
1977         break;
1978       }
1979       shm_detach($shm);
1980       $room->shm_sz += SHM_DIMS_DLT;
1981     } 
1982
1983     if ($shm)
1984       shm_detach($shm);
1985     
1986     return (FALSE);
1987   }
1988
1989
1990   function save_data($room) 
1991   {
1992       GLOBAL $sess;
1993     
1994       $ret =   FALSE;
1995       $shm =   FALSE;
1996     
1997       if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) 
1998           return (FALSE);
1999     
2000       // SHSPLIT: before save the $room you must save users, 
2001       //          detach from main struct and (then) reattach
2002       $user_park = array();
2003       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2004           $user_park[$i]  = $room->user[$i];
2005           $room->user[$i] = FALSE;
2006       }
2007
2008       while ($room->shm_sz < SHM_DIMS_MAX) {
2009           if (($shm = shm_attach($tok, $room->shm_sz)) == FALSE)
2010               break;
2011       
2012           // log_only("PUT_VAR DI ".strlen(serialize($room)));
2013           if (@shm_put_var($shm, $tok, $room) != FALSE) {
2014               log_shme("Room::save_data");
2015               $ret = TRUE;
2016               break;
2017           }
2018           if (shm_remove($shm) === FALSE) {
2019               log_only("REMOVE FALLITA");
2020               break;
2021           }
2022           shm_detach($shm);
2023           $room->shm_sz += SHM_DIMS_DLT;
2024       } 
2025
2026       if ($shm)
2027           shm_detach($shm);
2028     
2029       // SHSPLIT: reattach users to the room class
2030       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2031           User::save_data($user_park[$i], $i);
2032           $room->user[$i] = $user_park[$i];
2033       }
2034       log_load("FINISH: ".($ret == TRUE ? "TRUE" : "FALSE"));
2035
2036       return ($ret);
2037   }
2038
2039   static function lock_data($is_exclusive)
2040   {
2041       if (($res = file_lock(FTOK_PATH."/main", $is_exclusive)) != FALSE) {
2042           self::$delta_t = microtime(TRUE);
2043           log_lock("LOCK   room         [".self::$delta_t."]");
2044           
2045           return ($res);
2046       }
2047
2048       return (FALSE);
2049   }
2050   
2051   static function unlock_data($res)
2052   {
2053     GLOBAL $sess; 
2054     
2055     log_lock("UNLOCK room         [".(microtime(TRUE) - (self::$delta_t))."]");
2056
2057     file_unlock($res);
2058   }
2059
2060
2061   function standup_content($user)
2062   {
2063     $ret = "";
2064     $content = "";
2065     
2066     if ($user->stat != 'room')
2067       return;
2068     
2069     for ($i = 0 , $ct = 0 ; $ct < 4 && $i < MAX_PLAYERS ; $i++) {
2070       if ($this->user[$i]->sess == "" || $this->user[$i]->stat != "room" || $this->user[$i]->name == "")
2071         continue;
2072       $ct++;
2073     }
2074     
2075     // $content .= sprintf('<table cols=\\"%d\\" class=\\"table_standup\\">', $ct);
2076     
2077     $content = ' j_stand_cont( [ ';
2078
2079     for ($i = 0 , $ct = 0 ; $i < MAX_PLAYERS ; $i++) {
2080       if ($this->user[$i]->sess == "" || $this->user[$i]->stat != "room" || $this->user[$i]->name == "")
2081         continue;
2082       
2083       $flags = $this->user[$i]->flags;
2084       
2085       if ($this->user[$i]->subst == "standup") {
2086           if ($user->idx_get() == $i) { 
2087               $flags |= 1;
2088           }
2089           
2090           $content .= sprintf('%s[ %d, "%s" ]',($ct > 0 ? ', ' : ''), $flags, xcape($this->user[$i]->name));
2091           $ct++;
2092       }
2093     }
2094     $content .= ' ]);';
2095     
2096     return ($content);
2097   }
2098   
2099   function table_content($user, $table_idx)
2100   {
2101     $content = "";
2102     $ret = "";
2103     // TODO
2104     //
2105     //   Si possono usare i dati nella classe table
2106     //
2107     
2108     $sess = $user->sess;
2109     $table = $this->table[$table_idx];
2110     
2111     if ($user->stat != 'room')
2112       return;
2113     
2114     $content = "[ ";
2115     for ($i = 0 ; $i < $table->player_n ; $i++) {
2116         $user_cur = $this->user[$table->player[$i]];
2117         
2118         $flags = $user_cur->flags;
2119         
2120         if ($user->idx_get() == $table->player[$i]) 
2121             $flags |= 1;
2122         
2123         log_main($user_cur->name. sprintf(" IN TABLE [%d]", $table_idx));
2124         
2125         $content .= sprintf('%s[ %d, "%s" ]',($i == 0 ? '' : ', '), $flags, xcape($user_cur->name));
2126     }
2127
2128     $content .= ' ]';
2129
2130     $ret .= sprintf('j_tab_cont(%d, %s);', $table_idx, $content);
2131     
2132     return ($ret);
2133   }
2134
2135   static function garbage_time_is_expired($tm) 
2136   {
2137       $ret = TRUE;
2138       $fp = FALSE;
2139       do {
2140           if (file_exists(PROXY_PATH) == FALSE)
2141               mkdir(PROXY_PATH, 0775, TRUE);
2142           if (($fp = @fopen(PROXY_PATH."/garbage_time.expired", 'rb')) == FALSE)
2143               break;
2144           if (($s = fread($fp, 4)) == FALSE)
2145               break;
2146           if (mb_strlen($s, "ASCII") != 4)
2147               break;
2148           $arr = unpack('Le', $s);
2149           if ($arr['e'] > $tm)
2150               $ret = FALSE;
2151       } while (0);
2152       
2153       if ($fp != FALSE)
2154           fclose($fp);
2155       
2156       log_rd2("END: return ".($ret ? "TRUE" : "FALSE"));
2157       
2158       return ($ret);
2159   }
2160
2161   static function garbage_time_expire_set($tm) 
2162   {
2163       do {
2164           if (file_exists(PROXY_PATH) == FALSE)
2165               mkdir(PROXY_PATH, 0775, TRUE);
2166           if (($fp = @fopen(PROXY_PATH."/garbage_time.expired", 'wb')) == FALSE)
2167               break;
2168           fwrite($fp, pack("L",$tm));
2169           fclose($fp);
2170           
2171           return (TRUE);
2172       } while (0);
2173       
2174       return (FALSE);
2175   }
2176
2177   function request_mgr(&$s_a_p, &$header_out, &$new_socket, $path, $addr, $get, $post, $cookie)
2178   {
2179       printf("NEW_SOCKET (root): %d\n", intval($new_socket));
2180
2181       switch ($path) {
2182       case "":
2183       case "index.php":
2184           ob_start();
2185       index_main($this, $header_out, $addr, $get, $post, $cookie);
2186       $content = ob_get_contents();
2187       ob_end_clean();
2188
2189       force_no_cache($header_out);
2190
2191       $s_a_p->pgflush_try_add($new_socket, 20, $header_out, $content);
2192       return TRUE;
2193
2194       break;
2195       case "index_wr.php":
2196           ob_start();
2197           index_wr_main($this, $addr, $get, $post, $cookie);
2198           $content = ob_get_contents();
2199           ob_end_clean();
2200
2201           force_no_cache($header_out);
2202
2203           $s_a_p->pgflush_try_add($new_socket, 20, $header_out, $content);
2204           return TRUE;
2205
2206           break;
2207       case "index_rd_ifra.php":
2208           do {
2209               if (!isset($cookie['sess'])
2210                   || (($user = $this->get_user($cookie['sess'], $idx)) == FALSE)) {
2211                   $content = User::stream_fini(TRUE);
2212                   
2213                   $s_a_p->pgflush_try_add($new_socket, 20, $header_out, $content);
2214                   return TRUE;
2215
2216                   break;
2217               }
2218               // close a previous opened index_read_ifra socket, if exists
2219               if (($prev = $user->rd_socket_get()) != NULL) {
2220                   $s_a_p->socks_unset($user->rd_socket_get());
2221                   fclose($user->rd_socket_get());
2222                   printf("CLOSE AND OPEN AGAIN ON IFRA2\n");
2223                   $user->rd_socket_set(NULL);
2224               }
2225               
2226               $content = "";
2227               $user->stream_init($header_out, $content, $get, $post, $cookie);
2228               
2229               $response = headers_render($header_out, -1).chunked_content($content);
2230               $response_l = mb_strlen($response, "ASCII");
2231               
2232               $wret = @fwrite($new_socket, $response, $response_l);
2233               if ($wret < $response_l) {
2234                   printf("TROUBLES WITH FWRITE: %d\n", $wret);
2235                   $user->rd_cache_set(mb_substr($content, $wret, $response_l - $wret, "ASCII"));
2236               }
2237               else {
2238                   $user->rd_cache_set("");
2239               }
2240               fflush($new_socket);
2241               
2242               
2243               $s_a_p->socks_set($new_socket, $user);
2244               $user->rd_socket_set($new_socket);
2245               printf(" - qui ci siamo - ");
2246               return TRUE;
2247           } while (FALSE);
2248           
2249           return FALSE;
2250           break;
2251
2252       default:
2253           /* FAR TODO: move all into an array of registered sub-apps */
2254           $subs = "briskin5/";
2255           $subs_l = strlen($subs);
2256           if (!strncmp($path, $subs, $subs_l)) {
2257               $ret = Bin5::request_mgr(&$s_a_p, &$header_out, &$new_socket, substr($path, $subs_l) , $addr, $get, $post, $cookie);
2258               return ($ret);
2259           }
2260           break;
2261       }
2262
2263       return (FALSE);
2264   }
2265
2266   function match_add($idx, $match)
2267   {
2268       $this->match[$idx] = $match;
2269   }
2270
2271   function match_del($idx)
2272   {
2273       unset($this->match[$idx]);
2274   }
2275
2276   function match_get($idx, $token)
2277   {
2278       if (isset($this->match[$idx])) {
2279           if (   $token == NULL 
2280               || $token == $this->match[$idx]->table_token) {
2281               return ($this->match[$idx]);
2282           }
2283       }
2284       return NULL;
2285   }
2286
2287 } // end class Room
2288
2289 function make_seed()
2290 {
2291   list($usec, $sec) = explode(' ', microtime());
2292   return (float) $sec + ((float) $usec * 100000);
2293 }
2294
2295 function btrace_line($ar)
2296 {
2297     GLOBAL $G_btrace_pref_sub;
2298
2299     $ret = "";
2300     for ($i = 0 ; $i < count($ar) ; $i++) {
2301         $with_class = isset($ar[$i]['class']);
2302         $with_file  = isset($ar[$i]['file']);
2303         $ret .= sprintf("%s%s%s (%s:%d)", ($i == 0 ? "" : ", "), 
2304                         ($with_class ?  $ar[$i]['class'].$ar[$i]['type'] : ""), 
2305                         $ar[$i]['function'], ($with_file ? str_replace($G_btrace_pref_sub, "", $ar[$i]['file']) : ""), 
2306                         ($with_file ? $ar[$i]['line'] : ""));
2307     }
2308     
2309     return ($ret);
2310 }
2311
2312 function trace_ftok($id, $add)
2313 {
2314     // NOTE: without space to use sed to substitute "= @ftok("  with "= @ftok("
2315     $tok=@ftok($id, $add);
2316
2317     log_shme($tok.": ".$id." + ".$add);
2318
2319     return ($tok);
2320 }
2321
2322 function log_mop($step, $log)
2323 {
2324     GLOBAL $sess, $PHP_SELF;
2325     
2326     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LMOP) == 0)
2327         return;
2328     
2329     if (isset($sess) == FALSE)
2330         $ssess = "XXXX";
2331     else
2332         $ssess = $sess;
2333     
2334     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LMOP) == 0)
2335         return;
2336     
2337     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2338         $btrace = btrace_line(debug_backtrace());
2339     else
2340         $btrace = "";
2341     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2342         fwrite($fp, sprintf("LMOP: [%f] [%05d] [%s] [%s]\n", gettimeofday(TRUE), $step, $log, $btrace));
2343         fclose($fp);
2344     }
2345 }
2346
2347
2348 function log_only2($log)
2349 {
2350     GLOBAL $sess, $PHP_SELF;
2351     
2352     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_ONL2) == 0)
2353         return;
2354     
2355     if (isset($sess) == FALSE)
2356         $ssess = "XXXX";
2357     else
2358         $ssess = $sess;
2359     
2360     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_ONL2) == 0)
2361         return;
2362     
2363     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2364         $btrace = btrace_line(debug_backtrace());
2365     else
2366         $btrace = "";
2367     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2368         fwrite($fp, sprintf("ONL2: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2369         fclose($fp);
2370     }
2371 }
2372
2373 function log_crit($log)
2374 {
2375     GLOBAL $sess, $PHP_SELF;
2376     
2377     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_CRIT) == 0)
2378         return;
2379     
2380     if (isset($sess) == FALSE)
2381         $ssess = "XXXX";
2382     else
2383         $ssess = $sess;
2384     
2385     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_CRIT) == 0)
2386         return;
2387     
2388     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2389         $btrace = btrace_line(debug_backtrace());
2390     else
2391         $btrace = "";
2392     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2393         fwrite($fp, sprintf("CRIT: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2394         fclose($fp);
2395     }
2396 }
2397
2398 function log_only($log)
2399 {
2400     GLOBAL $sess, $PHP_SELF;
2401     
2402     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_ONLY) == 0)
2403         return;
2404     
2405     if (isset($sess) == FALSE)
2406         $ssess = "XXXX";
2407     else
2408         $ssess = $sess;
2409     
2410     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_ONLY) == 0)
2411         return;
2412     
2413     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2414         $btrace = btrace_line(debug_backtrace());
2415     else
2416         $btrace = "";
2417     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2418         fwrite($fp, sprintf("ONLY: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2419         fclose($fp);
2420     }
2421 }
2422
2423 function log_main($log)
2424 {
2425     GLOBAL $sess, $PHP_SELF;
2426     
2427     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_MAIN) == 0)
2428         return;
2429     
2430     if (isset($sess) == FALSE)
2431         $ssess = "XXXX";
2432     else
2433         $ssess = $sess;
2434     
2435     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_MAIN) == 0)
2436         return;
2437     
2438     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2439         $btrace = btrace_line(debug_backtrace());
2440     else
2441         $btrace = "";
2442     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2443         fwrite($fp, sprintf("MAIN: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2444         fclose($fp);
2445     }
2446 }
2447
2448 function log_rd($log)
2449 {
2450     GLOBAL $sess, $PHP_SELF;
2451     
2452     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_READ) == 0)
2453         return;
2454     
2455     if (isset($sess) == FALSE)
2456         $ssess = "XXXX";
2457     else
2458         $ssess = $sess;
2459     
2460     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_READ) == 0)
2461         return;
2462
2463     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2464         $btrace = btrace_line(debug_backtrace());
2465     else
2466         $btrace = "";    
2467     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2468         fwrite($fp, sprintf("READ: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2469         fclose($fp);
2470     }
2471 }
2472
2473 function log_rd2($log)
2474 {
2475     GLOBAL $sess, $PHP_SELF;
2476     
2477     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_REA2) == 0)
2478         return;
2479     
2480     if (isset($sess) == FALSE)
2481         $ssess = "XXXX";
2482     else
2483         $ssess = $sess;
2484     
2485     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_REA2) == 0)
2486         return;
2487     
2488     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2489         $btrace = btrace_line(debug_backtrace());
2490     else
2491         $btrace = "";
2492     
2493     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2494         fwrite($fp, sprintf("REA2: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2495         fclose($fp);
2496     }
2497 }
2498
2499 function log_send($log)
2500 {
2501     GLOBAL $sess, $PHP_SELF;
2502     
2503     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_SEND) == 0)
2504         return;
2505     
2506     if (isset($sess) == FALSE)
2507         $ssess = "XXXX";
2508     else
2509         $ssess = $sess;
2510     
2511     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_SEND) == 0)
2512         return;
2513
2514     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)    
2515         $btrace = btrace_line(debug_backtrace());
2516     else
2517         $btrace = "";
2518     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2519         fwrite($fp, sprintf("SEND: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2520         fclose($fp);
2521     }
2522 }
2523
2524 function log_lock($log)
2525 {
2526     GLOBAL $sess, $PHP_SELF;
2527     
2528     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LOCK) == 0)
2529         return;
2530     
2531     if (isset($sess) == FALSE)
2532         $ssess = "XXXX";
2533     else
2534         $ssess = $sess;
2535     
2536     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LOCK) == 0)
2537         return;
2538     
2539     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2540         $btrace = btrace_line(debug_backtrace());
2541     else
2542         $btrace = "";
2543     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2544         fwrite($fp, sprintf("LOCK: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2545         fclose($fp);
2546     }
2547 }
2548
2549 function log_wr($log)
2550 {
2551     GLOBAL $sess, $PHP_SELF;
2552     
2553     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_WRIT) == 0)
2554         return;
2555     
2556     if (isset($sess) == FALSE)
2557         $ssess = "XXXX";
2558     else
2559         $ssess = $sess;
2560     
2561     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_WRIT) == 0)
2562         return;
2563     
2564     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2565         $btrace = btrace_line(debug_backtrace());
2566     else
2567         $btrace = "";
2568     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2569         fwrite($fp, sprintf("WRIT: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2570         fclose($fp);
2571     }
2572 }
2573
2574 function log_load($log)
2575 {
2576     GLOBAL $sess, $PHP_SELF;
2577     
2578     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LOAD) == 0)
2579         return;
2580     
2581     if (isset($sess) == FALSE)
2582         $ssess = "XXXX";
2583     else
2584         $ssess = $sess;
2585     
2586     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LOAD) == 0)
2587         return;
2588     
2589     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2590         $btrace = btrace_line(debug_backtrace());
2591     else
2592         $btrace = "";
2593     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2594         fwrite($fp, sprintf("LOAD: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2595         fclose($fp);
2596     }
2597 }
2598
2599 function log_auth($sess, $log)
2600 {
2601     GLOBAL $PHP_SELF;
2602
2603     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_AUTH) == 0)
2604         return;
2605     
2606     if (( (BRISK_DEBUG | ($sess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_AUTH) == 0)
2607         return;
2608     
2609     if ((BRISK_DEBUG | ($sess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2610         $btrace = btrace_line(debug_backtrace());
2611     else
2612         $btrace = "";
2613     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2614         fwrite($fp, sprintf("LOAD: [%s] [%d] [%s] [%s]\n", $sess, time(), $log, $btrace));
2615         fclose($fp);
2616     }
2617 }
2618
2619 function log_shme($log)
2620 {
2621     GLOBAL $sess, $PHP_SELF;
2622     
2623     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_SHME) == 0)
2624         return;
2625     
2626     if (isset($sess) == FALSE)
2627         $ssess = "XXXX";
2628     else
2629         $ssess = $sess;
2630     
2631     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_SHME) == 0)
2632         return;
2633     
2634     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2635         $btrace = btrace_line(debug_backtrace());
2636     else
2637         $btrace = "";
2638     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2639         fwrite($fp, sprintf("SHME: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2640         fclose($fp);
2641     }
2642 }
2643
2644
2645
2646 // function log_legal($curtime, $sess, $name, $where, $mesg) 
2647 function log_legal($curtime, $addr, $user, $where, $mesg) 
2648 {
2649
2650   if (($fp = @fopen(LEGAL_PATH."/legal.log", 'a')) != FALSE) {
2651     /* Unix time | session | nickname | IP | where was | mesg */
2652     fwrite($fp, sprintf("%ld|%s|%s|%s|%s|%s|%s|\n", $curtime, $user->sess,
2653                         ($user->flags & USER_FLAG_AUTH ? 'A' : 'N'),
2654                         $user->name, $addr, $where , $mesg));
2655     fclose($fp);
2656   }
2657 }
2658
2659 function table_act_content($isstanding, $sitted, $table, $cur_table, $allowed)
2660 {
2661   $ret = "";
2662
2663   if ($isstanding) {
2664     if ($sitted < PLAYERS_N) {
2665       if ($allowed)
2666         $act = 'sit';
2667       else
2668         $act = 'reserved';
2669     }
2670   }
2671   else {
2672     if ($table == $cur_table)
2673       $act = 'wake';
2674     else
2675       $act = 'none';
2676   }
2677
2678   if ($act != '')
2679     $ret = sprintf('j_tab_act_cont(%d, \'%s\');', $table, $act);
2680
2681   return ($ret);
2682 }
2683
2684 function show_notify($text, $tout, $butt, $w, $h)
2685 {
2686   log_main("SHOW_NOTIFY: ".$text);
2687   return sprintf('var noti = new notify(gst,"%s",%d,"%s",%d,%d);', $text, $tout, $butt, $w, $h);
2688 }
2689
2690 function show_notify_ex($text, $tout, $butt, $w, $h, $is_opaque, $block_time)
2691 {
2692   log_main("SHOW_NOTIFY OPAQUE: ".$text);
2693   return sprintf('var noti = new notify_ex(gst,"%s",%d,"%s",%d,%d, %s, %d);', $text, $tout, $butt, $w, $h, ($is_opaque ? "true" : "false"), $block_time);
2694 }
2695
2696
2697 function root_wellcome($user)
2698 {
2699   GLOBAL $root_wellarr, $G_lang;
2700   $ret = "";
2701
2702   $curtime = time();
2703   $dt = date("H:i ", $curtime);
2704     
2705   for ($i = 0 ; $i < count($root_wellarr[$G_lang]) ; $i++)
2706     $ret .= sprintf('chatt_sub("%s", [2, "%s"],"%s");', $dt, NICKSERV, str_replace('"', '\"', $root_wellarr[$G_lang][$i]));
2707
2708   return ($ret);
2709 }
2710
2711
2712
2713 function validate_sess($sess) 
2714 {
2715   if (strlen($sess) == SESS_LEN) 
2716     return (TRUE);
2717   else
2718     return (FALSE);
2719 }
2720
2721 function validate_name($name) 
2722 {
2723   $name_new = str_replace(' ', '_', substr(trim($name),0,12));
2724
2725   for ($i = 0 ; $i < strlen($name_new) ; $i++) {
2726     $c = $name_new[$i];
2727     if (($c >= "a" && $c <= "z") || ($c >= "A" && $c <= "Z") || ($c >= "0" && $c <= "9"))
2728       return ($name_new);
2729   }
2730
2731   return (FALSE);
2732 }
2733
2734 function playsound($filename)
2735 {
2736   return (sprintf('playsound("flasou", "%s");', $filename));
2737 }
2738
2739 function secstoword($secs)
2740 {
2741   GLOBAL $G_lang;
2742
2743   $ret = "";
2744
2745   $mins = floor($secs / 60);
2746   $secs = $secs % 60;
2747   if ($G_lang == 'en') {
2748     if ($mins > 0) 
2749       $ret = sprintf("%d minute%s%s", $mins, ($mins > 1 ? "s" : ""), ($secs > 0 ? " and " : ""));
2750     
2751     if ($secs > 0)
2752       $ret .= sprintf("%d second%s", $secs, ($secs > 1 ? "s" : ""));
2753   }
2754   else {
2755     if ($mins > 0) 
2756       $ret = sprintf("%d minut%s%s", $mins, ($mins > 1 ? "i" : "o"), ($secs > 0 ? " e " : ""));
2757     
2758     if ($secs > 0)
2759       $ret .= sprintf("%d second%s", $secs, ($secs > 1 ? "i" : "o"));
2760   }
2761   return ($ret);
2762 }
2763
2764 function sharedmem_sz($tok)
2765 {
2766   if (($shm_id = @shmop_open($tok, 'a', 0, 0)) == FALSE) {
2767     log_main("shmop_open failed");
2768     return (-1);
2769   }
2770   $shm_sz = shmop_size($shm_id);
2771   shmop_close($shm_id);
2772   
2773   // log_main("shm_sz: ".$shm_sz."   SHM_DIMS: ".SHM_DIMS);
2774   return ($shm_sz);
2775 }    
2776
2777 class Warrant {
2778     static $delta_t;
2779
2780   static function lock_data($is_exclusive)
2781   {
2782       if (($res = file_lock(FTOK_PATH."/warrant", $is_exclusive)) != FALSE) {
2783           self::$delta_t = microtime(TRUE);
2784           log_lock("LOCK   warrant      [".self::$delta_t."]");
2785           
2786           return ($res);
2787       }
2788
2789       return (FALSE);
2790   }
2791   
2792   static function unlock_data($res)
2793   {
2794     GLOBAL $sess; 
2795     
2796     log_lock("UNLOCK warrant      [".(microtime(TRUE) - (self::$delta_t))."]");
2797
2798     file_unlock($res);
2799   }
2800 }
2801
2802 class Poll {
2803     static $delta_t;
2804
2805   static function lock_data($is_exclusive)
2806   {
2807       if (($res = file_lock(FTOK_PATH."/poll", $is_exclusive)) != FALSE) {
2808           self::$delta_t = microtime(TRUE);
2809           log_lock("LOCK   poll         [".self::$delta_t."]");
2810           
2811           return ($res);
2812       }
2813
2814       return (FALSE);
2815   }
2816   
2817   static function unlock_data($res)
2818   {
2819     GLOBAL $sess; 
2820     
2821     log_lock("UNLOCK poll         [".(microtime(TRUE) - (self::$delta_t))."]");
2822     
2823     file_unlock($res);
2824   }
2825 }
2826
2827 ?>