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