cc24d3ddd4371309e11c5817c7cab5a6b8a9d4f7
[brisk.git] / web / Obj / brisk.phh
1 <?php
2 /*
3  *  brisk - brisk.phh
4  *
5  *  Copyright (C) 2006-2015 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', 8);
32 define('TABLES_CERT_N', 4);
33 define('PLAYERS_N', 3);
34 define('MAX_POINTS', 5);
35 define('MAX_PLAYERS', (20 + (PLAYERS_N * TABLES_N)));
36 define('SHM_DIMS_MIN', (50000 + 10000 * TABLES_N + 15000 * MAX_PLAYERS));
37 define('SHM_DIMS_MAX', SHM_DIMS_MIN + 1048576);
38 define('SHM_DIMS_DLT', 65536);
39
40 define('SHM_DIMS_U_MIN', 4096);
41 define('SHM_DIMS_U_MAX', 65536);
42 define('SHM_DIMS_U_DLT', 4096);
43
44 define('COMM_N', 18);
45 define('COMM_GEN_N', 50);
46
47 define('CHAT_N', 3);
48 define('CHAT_ILL_TIME', 6);
49 define('CHAT_ENABLED', TRUE);
50
51 define('SESS_LEN', 13);
52 define('STREAM_TIMEOUT', 60);
53 /* FIXME: move to sac-a-push .phh */
54 /* TIME_RD define the server-side timeout, after half of it a ping request
55    is sent to client, after this time the client is log out */
56 define('EXPIRE_TIME_RD', 180);
57 define('EXPIRE_TIME_SMAMMA', 360);
58 define('EXPIRE_TIME_WAG', 10);
59 define('WAKEUP_TIME', 12);
60 // BAN_TIME da allineare anche in commons.js
61 define('BAN_TIME', 3600);
62 define('GARBAGE_TIMEOUT', 5);
63 define('NICKSERV', "BriskServ");
64
65 define('LOCK_SHARE_MAX', 10000);
66
67 define('DBG_ONL2', 0x000001);
68 define('DBG_ONLY', 0x000002);
69 define('DBG_MAIN', 0x000004);
70 define('DBG_READ', 0x000008);
71 define('DBG_REA2', 0x000010);
72 define('DBG_SEND', 0x000020);
73 define('DBG_LOCK', 0x000040);
74 define('DBG_WRIT', 0x000080);
75 define('DBG_LOAD', 0x000100);
76 define('DBG_AUTH', 0x000200);
77 define('DBG_CRIT', 0x000400);
78 define('DBG_LMOP', 0x000800);
79 define('DBG_TRAC', 0x001000);
80 define('DBG_SHME', 0x002000);
81 define('DBG_ENGI', 0x004000);
82 define('DBG_CDS',  0x008000);
83 define('DBG_STEP', 0x010000);
84 // NOTE: BRISK DEBUG must be a numerical constant, not the result of operations on symbols
85 define('BRISK_DEBUG', 0x0800);
86
87 define('BRISK_SINGLE_DEBUG',0);
88 define('BRISK_SINGLE_SESS', "");
89 define('DEBUGGING', "no-debugging");
90
91 require_once("$DOCUMENT_ROOT/Etc/".BRISK_CONF);
92 require_once("${G_base}Obj/ipclass.phh");
93
94 $mlang_brisk = array( 'btn_backstand'=> array( 'it' => 'torna in piedi',
95                                                'en' => 'back standing' ),
96                       'btn_close' => array( 'it' => 'chiudi',
97                                             'en' => 'close'),
98
99                       'tit_all' => array( 'it' => 'tutti',
100                                           'en' => 'all' ),
101
102                       'tabtout_a'=> array( 'it' => '<br>Sei stato inattivo per ',
103                                            'en' => '<br>You are being idle for ' ),
104                       'tabtout_b'=> array( 'it' => ' minuti. <br><br>Quindi ritorni tra i <b>Giocatori in piedi</b>.',
105                                            'en' => ' minutes. <br><br>Then you return with the <b>standing players</b>.'),
106                       'tickmust' => array( 'it' => '<br>Per attivare il messaggio di segnalazione del tavolo occorre essere seduti.<br><br>',
107                                            'en' => '<br>To activate the signalling message of the table it\'s necessary to be sitting<br><br>'),
108                       'tickjust' => array( 'it' => '<br>Il messaggio di segnalazione del tavolo &egrave; gi&agrave; attivato.<br><br> ',
109                                            'en' => 'EN<br>Il messaggio di segnalazione del tavolo &egrave; gi&agrave; attivato.<br><br> '),
110                       'tickwait' => array( 'it' => '<br>Il messaggio di segnalazione del tavolo<br>&egrave; disattivato ancora per %d second%s.<br><br>',
111                                            'en' => 'EN<br>The signalling message of the table<br>will be deactivated for %d second%s.<br><br>'),
112                       'alarpass' => array( 'it' => '<br>La password digitata non &egrave; corretta.<br><br>',
113                                            'en' => '<br>The entered password is not correct.<br><br>'),
114                       'alarret'  => array( 'it' => 'Alarm \\"<b>%s</b>\\" inviato a <b>%s</b>.',
115                                            'en' => 'Alarm \\"<b>%s</b>\\" sent to <b>%s</b>.'),
116                       'authmust' => array( 'it' => '<b>Per autenticare qualcuno devi a tua volta essere autenticato e certificato.</b>',
117                                            'en' => '<b>To authenticate someone you have to be authenticated and certified.</b>'), // on your turn
118                       'mesgmust' => array( 'it' => '<b>Per inviare un messaggio devi essere autenticato.</b>',
119                                            'en' => '<b>To send a message you have to be authenticated.</b>'),
120                       'nickmust' => array( 'it' => 'Il nickname deve contenere almeno una lettera dell\'alfabeto o una cifra.',
121                                            'en' => 'The nickname have to contain at least one letter or one number.'),
122                       'nickdupl' => array( 'it' => 'Nickname <b>%s</b> gi&agrave; in uso.',
123                                            'en' => 'The nickname <b>%s</b> is already in use.'),
124                       'authchan' => array( 'it' => '<b>Non puoi cambiare nick a un tavolo per soli autenticati o se sei in modalità isolata.</b>',
125                                            'en' => '<b>You can\'t change your nickname into a table for only authenticated or if you are in isolation mode.</b>'),
126                       '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>',
127                                            '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 ???
128                       'statunkn' => array( 'it' => 'Questo stato non esiste.',
129                                            'en' => 'This state don\'t exists.'),
130                       'tabincon' => array( 'it' => '<br>I dati del tavolo n&deg; %d sono inconsistenti, verranno resettati.<br><br>Torni in piedi.<br><br>',
131                                            'en' => 'EN <br>I dati del tavolo n&deg; %d sono inconsistenti, verranno resettati.<br><br>Torni in piedi.<br><br>'),
132                       'listmust' => array( 'it' => '<b>Per andare in isolamento non bisogna essere seduti a tavoli non riservati.</b>',
133                                            'en' => '<b>To go to isolation you must don\'t stay on not reserved tables</b>'),
134
135                       'tit_onauth'=>array( 'it' => '(solo aut.)',
136                                            'en' => '(only aut.)'),
137                       'tit_onisol'=>array( 'it' => '(isolam.to)',
138                                            'en' => '(isolation)'),
139                       '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.',
140                                           'en'  => 'Connection to the database failed<br>All authentications are suspended temporarly, you login as normal user.<br>We are about the limitation'),
141
142                       'tos_old'  => array( 'it' => '<b>%s</b> ha sottoscritto dei Termini del Servizio antecedenti a quelli necessari per poter richiedere questa funzionalità.',
143                                            'en' => 'EN <b>%s</b> ha sottoscritto dei Termini del Servizio antecedenti a quelli necessarig per poter richiedere questa funzionalità.'),
144                       'inf_self' => array( 'it' => 'Non puoi informarti su te stesso.',
145                                            'en' => 'EN Non puoi informarti su te stesso.'),
146                       'inf_nfd'  => array( 'it' => 'Non è stato trovato un garante per <b>%s</b>.',
147                                            'en' => 'EN Non è stato trovato un garante per <b>%s</b>.'),
148                       'inf_err'  => array( 'it' => 'Error %d. Utilizzo: <b>/info <i>&lt;login&gt;</i></b>.',
149                                            'en' => 'Error %d. Usage: <b>/info <i>&lt;login&gt;</i></b>.')
150 );
151
152 $G_lng = langtolng($G_lang);
153
154 $G_all_points = array( 11,10,4,3,2, 0,0,0,0,0 );
155 $G_brisk_version = "5.1.2";
156
157 /* MLANG: ALL THE INFO STRINGS IN brisk.phh */
158 $root_wellarr = array( 'it' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: comando /info e doppio click sugli utenti registrati, nuovi utenti apprendisti, info su numero di mani e di partite.',
159                                        'Se vuoi iscriverti alla <a target="_blank" href="mailto:ml-briscola+subscribe@milug.org">Mailing List</a>, cliccala!' ),
160                        'en' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NEWS</b>: ENcomando /info e doppio click sugli utenti registrati, nuovi utenti apprendisti.',
161                                        'If you want to subscribe our <a target="_blank" href="ml-briscola+subscribe@milug.org">Mailing List</a>, click it!' ) );
162
163 $G_room_help = array( 'it' => '
164 <div style=\\"text-align: left; padding: 8px;\\">
165 <b>Descrizione</b><br>
166 Questa è un\'implementazione della briscola in cinque, cos&igrave; come &egrave; spiegata su
167 <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>
168 <b>Configurazione del browser.</b><br>
169 Occorre abilitare i cookies.<br>
170 <br>
171 <b>Uso del sito</b><br>
172 Potete sedervi a un tavolo o rimanere in piedi.<br>
173 Se al vostro tavolo si raggiungono i 5 giocatori inizia automaticamente la partita.<br>
174 <br>
175 <b>Partita</b><br>
176 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>
177 Chi vince l\'asta dovr&agrave; decidere il seme della carta scelta e inizier&agrave; la mano.<br>
178 Per giocare le carte dovrete trascinarle nel quadrato al centro del vostro schermo.<br><br>
179 Il vostro turno &egrave; sempre segnalato da una cornice verde lampeggiante intorno al quadrato al centro del vostro schermo.<br><br>
180 Durante la partita, se vorrete ricaricare la pagina, usate l\'apposito bottone \\"reload\\" in basso a destra.<br>
181 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.
182 <dl>
183 <dt><b>Comandi della chat</b>
184 <dd><b>/nick <i>&lt;nuovo_nickname&gt;</i></b> - cambio di nickname
185 <dd><b>/tav <i>&lt;frase di invito&gt;</i></b> - invito per gli altri giocatori al tavolo dove si &egrave; seduti
186 <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\\"
187 <dd><b>/cont <i>&lt;id partita&gt;</i></b> - quando si è a un tavolo per garantiti, permette di proseguire una partita giocata in precedenza con gli stessi giocatori
188 <dd><b>/info <i>&lt;login&gt;</i></b> - mostra lo stato corrente dell\'utente passato come argomento e in che relazione siete
189 <dd><b>/authreq</b> - se si &egrave; autenticati permette di garantire per un utente fidato
190 <dd><b>/mesgtoadm</b> - se si &egrave; autenticati permette di lasciare un messaggio all\'amministratore del sito
191 <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)
192 </dl>
193 </div>
194 ',
195
196 'en' => '
197 <div style=\\"text-align: left; padding: 8px;\\">
198 <b>EN Descrizione</b><br>
199 EN Questa è un\'implementazione della briscola in cinque, cos&igrave; come &egrave; spiegata su
200 <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>
201 <b>Configurazione del browser.</b><br>
202 Occorre abilitare i cookies.<br>
203 <br>
204 <b>Uso del sito</b><br>
205 Potete sedervi a un tavolo o rimanere in piedi.<br>
206 Se al vostro tavolo si raggiungono i 5 giocatori inizia automaticamente la partita.<br>
207 <br>
208 <b>Partita</b><br>
209 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>
210 Chi vince l\'asta dovr&agrave; decidere il seme della carta scelta e inizier&agrave; la mano.<br>
211 Per giocare le carte dovrete trascinarle nel quadrato al centro del vostro schermo.<br><br>
212 Il vostro turno &egrave; sempre segnalato da una cornice verde lampeggiante intorno al quadrato al centro del vostro schermo.<br><br>
213 Durante la partita, se vorrete ricaricare la pagina, usate l\'apposito bottone \\"reload\\" in basso a destra.<br>
214 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.
215 <dl>
216 <dt><b>Comandi della chat</b>
217 <dd><b>/nick <i>&lt;nuovo_nickname&gt;</i></b> - cambio di nickname
218 <dd><b>/tav <i>&lt;frase di invito&gt;</i></b> - invito per gli altri giocatori al tavolo dove si &egrave; seduti
219 <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\\"
220 <dd><b>/cont <i>&lt;id partita&gt;</i></b> - quando si è a un tavolo per garantiti, permette di proseguire una partita giocata in precedenza con gli stessi giocatori
221 <dd><b>/info <i>&lt;login&gt;</i></b> - mostra lo stato corrente dell\'utente passato come argomento e in che relazione siete
222 <dd><b>/authreq</b> - se si &egrave; autenticati permette di garantire per un utente fidato
223 <dd><b>/mesgtoadm</b> - se si &egrave; autenticati permette di lasciare un messaggio all\'amministratore del sito
224 <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)
225 </dl>
226 </div>
227 ');
228
229 //
230 $G_room_passwdhowto = array( 'it' => '<br><h2>Come registrarsi su Brisk</h2>
231 <div style=\\"text-align: left; padding: 8px;\\">
232 Attualmente ci sono due metodi per ottenere una password sul sito:<br><br>
233 <dir>
234 <li><b>Facendosi garantire da un utente di Brisk che sia certificato.</b><br><br>
235 <li><b>Auto-garantendosi utilizzando uno dei seguenti sistemi di identificazione digitale:</b><br><br>
236 <dir>
237 <li>Carta Regionale dei Servizi della Lombardia (la tessera sanitaria)
238 <li>Carta Regionale dei Servizi del Friuli Venezia Giulia (la tessera sanitaria)
239 <li>Smart card di InfoCamere
240 </dir>
241 <br>
242 <b>Per auto-garantisi occorre possedere:</b><br><br>
243 <dir>
244 <li>il codice PIN della propria carta
245 <li>il lettore di smart-card per collegare la carta al PC (acquistabile di solito presso le edicole)
246 </dir>
247 <br>
248 <b>Per effettuare la registrazione collegarsi al sito:</b> <a class=\\"flat\\"  target=\\"_blank\\" href=\\"https://brisk.mine.nu\\">https://brisk.mine.nu</a>
249 <br>
250 Se sei in possesso di una carta che permette l\'identificazione via internet che non è nell\'elenco qui sopra
251 <a class=\\"flat\\" href=\\"mailto:authadmbrisk@alternativeoutput.it\\">fai una segnalazione</a>.<br><br>
252 Le regole per ottenere la certificazione sono in via di definizione, l\' unica accettata è la conoscenza
253 diretta dell\' utente da parte dell\' amministratore.
254
255 </dir>
256 </div>
257 ',
258                              'en' => '<br><h2>EN Come registrarsi su Brisk</h2>
259 <div style=\\"text-align: left; padding: 8px;\\">
260 EN Attualmente ci sono due metodi per ottenere una password sul sito:<br><br>
261 <dir>
262 <li><b>Facendosi garantire da un utente di Brisk che gi&agrave; possidede una password</b><br><br>
263 <li><b>Auto-garantendosi utilizzando uno dei seguenti sistemi di identificazione digitale:</b><br><br>
264 <dir>
265 <li>Carta Regionale dei Servizi della Lombardia (la tessera sanitaria)
266 <li>Carta Regionale dei Servizi del Friuli Venezia Giulia (la tessera sanitaria)
267 </dir>
268 <br>
269 <b>Per auto-garantisi occorre possedere:</b><br><br>
270 <dir>
271 <li>il codice PIN della propria carta
272 <li>il lettore di smart-card per collegare la carta al PC (acquistabile di solito presso le edicole)
273 </dir>
274 <br>
275 <b>Per effettuare la registrazione collegarsi al sito:</b> <a class=\\"flat\\"  target=\\"_blank\\" href=\\"https://brisk.mine.nu\\">https://brisk.mine.nu</a>
276 <br>
277 Se sei in possesso di una carta che permette l\'identificazione via internet che non è nell\'elenco qui sopra
278 <a class=\\"flat\\" href=\\"mailto:authadmbrisk@alternativeoutput.it\\">fai una segnalazione</a>.<br><br>
279 Le regole per ottenere la certificazione sono in via di definizione, l\' unica accettata è la conoscenza
280 diretta dell\' utente da parte dell\' amministratore.
281
282
283 </dir>
284 </div>
285 ' );
286 /*
287 <dd>Seguendo la procedura di auto-garanzia all\'url: <a href="https://brisk.mine.nu">https://brisk.mine.nu</a>
288 ';
289 */
290
291 $G_room_about = array( 'it' => '<br>
292 <div id=\\"header\\" class=\\"header\\">
293   <img class=\\"nobo\\" src=\\"img/brisk_logo64.png\\">
294   briscola chiamata in salsa ajax
295 </div>
296 <br><b>version '.$G_brisk_version.'</b><br><br>
297 Copyright 2006-2012 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>',
298                       'en' => '<br>
299 <div id=\\"header\\" class=\\"header\\">
300   <img class=\\"nobo\\" src=\\"img/brisk_logo64.png\\">
301   declaration briscola in ajax sauce <b>(Beta)</b>
302 </div>
303 <br><b>version '.$G_brisk_version.'</b><br><br>
304 Copyright 2006-2012 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>');
305
306
307 $G_PG_vow = array("a", "e", "i", "o", "u", "y");
308 $G_PG_vow_n = 6;
309 $G_PG_cons = array(
310       "b", "bb", "bc", "bd", "bf", "bg", "bk", "bl", "bm", "bn", "bp",       "br", "bs", "bt", "bv", "bw",       "bz",
311       "c", "cb", "cc", "cd", "cf", "cg", "ck", "cl", "cm", "cn", "cp", "cq", "cr", "cs", "ct", "cv", "cw", "cx", "cz",
312       "d", "db", "dc", "dd", "df", "dg", "dk", "dl", "dm", "dn", "dp",       "dr", "ds", "dt", "dv", "dw", "dx", "dz",
313       "f", "fb", "fc", "fd", "ff", "fg", "fk", "fl", "fm", "fn", "fp",       "fr", "fs", "ft", "fv", "fw", "fx", "fz",
314       "g", "gb", "gc", "gd", "gf", "gg", "gk", "gl", "gm", "gn", "gp",       "gr", "gs", "gt", "gv", "gw", "gx", "gz",
315       "j", "jb", "jc", "jd", "jf", "jg", "jk", "jl", "jm", "jn", "jp", "jq", "jr", "js", "jt", "jv", "jw", "jx", "jz",
316       "k", "kb", "kc", "kd", "kf", "kg", "kk", "kl", "km", "kn", "kp",       "kr", "ks", "kt", "kv", "kw", "kx", "kz",
317       "l", "lb", "lc", "ld", "lf", "lg", "lk", "ll", "lm", "ln", "lp",       "lr", "ls", "lt", "lv", "lw", "lx", "lz",
318       "m", "mb", "mc", "md", "mf", "mg", "mk", "ml", "mm", "mn", "mp",       "mr", "ms", "mt", "mv", "mw", "mx", "mz",
319       "n", "nb", "nc", "nd", "nf", "ng", "nk", "nl", "nm", "nn", "np",       "nr", "ns", "nt", "nv", "nw", "nx", "nz",
320       "p", "pb", "pc", "pd", "pf", "pg", "pk", "pl", "pm", "pn", "pp",       "pr", "ps", "pt", "pv", "pw", "px", "pz",
321       "q", "qb", "qc", "qd", "qf", "qg", "qk", "ql", "qm", "qn", "qp", "qq", "qr", "qs", "qt", "qv", "qw", "qx", "qz",
322       "r", "rb", "rc", "rd", "rf", "rg", "rk", "rl", "rm", "rn", "rp",       "rr", "rs", "rt", "rv", "rw", "rx", "rz",
323       "s", "sb", "sc", "sd", "sf", "sg", "sk", "sl", "sm", "sn", "sp", "sq", "sr", "ss", "st", "sv", "sw", "sx", "sz",
324       "t", "tb", "tc", "td", "tf", "tg", "tk", "tl", "tm", "tn", "tp",       "tr", "ts", "tt", "tv", "tw", "tx", "tz",
325       "v", "vb", "vc", "vd", "vf", "vg", "vk", "vl", "vm", "vn", "vp",       "vr", "vs", "vt", "vv", "vw", "vx", "vz",
326       "w", "wb", "wc", "wd", "wf", "wg", "wk", "wl", "wm", "wn", "wp",       "wr", "ws", "wt", "wv", "ww", "wx", "wz",
327       "x", "xb", "xc", "xd", "xf", "xg", "xk", "xl", "xm", "xn", "xp",       "xr", "xs", "xt", "xv", "xw", "xx", "xz",
328       "z", "zb", "zc", "zd", "zf", "zg", "zk", "zl", "zm", "zn", "zp",       "zr", "zs", "zt", "zv", "zw", "zx", "zz",
329                   );
330 // $G_PG_cons_n = count($G_PG_cons);
331 // printf("N CONS: %d\n", $G_PG_cons_n);
332 $G_PG_cons_n = 345;
333     /*     printf("%d %d\n", count($voc), count($cons)); */
334     /* for ($i = 0 ; $i < 26 ; $i++) { */
335     /*     if (array_search(chr(ord('a') + $i), $voc) !== FALSE || $i == 7) */
336     /*         continue; */
337     /*     printf('      "%s", ', chr(ord('a') + $i)); */
338     /*     for ($e = 0 ; $e < 26 ; $e++) { */
339     /*         if (array_search(chr(ord('a') + $e), $voc) !== FALSE || $e == 7) */
340     /*             continue; */
341     /*         printf('"%s%s", ', chr(ord('a') + $i), chr(ord('a') + $e)); */
342     /*     } */
343     /*     printf("\n"); */
344     /* } */
345
346 function ip2int($s)
347 {
348     return (ip2long($s));
349 }
350
351 function int2ip($i)
352 {
353     return (long2ip($i));
354 }
355
356 function int2four($l)
357 {
358     if (PHP_INT_SIZE == 4)
359         return ($l);
360
361     return ( ($l & 0x80000000 ? 0xffffffff00000000 : 0x00) | $l );
362 }
363
364 function four2int($s)
365 {
366     return ($s & 0xffffffff);
367 }
368
369 function ip2four($s)
370 {
371     return int2four( ip2int($s) );
372 }
373
374 function four2ip($i)
375 {
376     return int2ip( four2int($i) );
377 }
378
379 function nickserv_msg($dt, $msg) {
380     return sprintf('chatt_sub("%s",[0x040003,"%s"],"%s");', $dt, NICKSERV, $msg);
381 }
382
383 function passwd_gen($seed = NULL)
384 {
385     GLOBAL $G_PG_vow, $G_PG_vow_n, $G_PG_cons, $G_PG_cons_n;
386
387     $pw = "";
388
389     if ($seed != NULL)
390         mt_srand($seed);
391     else
392         mt_srand();
393
394     for ($sil = 0 ; $sil < 7 ; $sil++) {
395         if (($sil % 2) == 0) {
396             // vowels
397             for ($n = 0 ; $n < mt_rand(1,2) ; $n++) {
398                 if ($n == 0) {
399                     $old = mt_rand(0, $G_PG_vow_n-1);
400                     $pw .= $G_PG_vow[$old];
401                 }
402                 else {
403                     $new = mt_rand(0, $G_PG_vow_n-1);
404                     if ($new == $old)
405                         $new = ($new + mt_rand(0, $G_PG_vow_n-2)) % $G_PG_vow_n;
406                     $pw .= $G_PG_vow[$new];
407                 }
408             }
409         }
410         else {
411             // consonants
412             $pw .= $G_PG_cons[mt_rand(0, $G_PG_cons_n-1)];
413         }
414     }
415
416     return $pw;
417 }
418
419 function cmd_return($val, $desc)
420 {
421     return array('val' => $val, 'desc' => $desc);
422 }
423
424 function cmd_serialize($attrs)
425 {
426     $ret = "";
427
428     $sep = "";
429     foreach ($attrs as $key => $value) {
430         $ret .= $sep . $key . '=' . urlencode($value);
431         $sep = "&";
432     }
433     return $ret;
434 }
435
436 function cmd_deserialize($cmd)
437 {
438     $ret = array();
439     $a = explode('&', $cmd);
440     $i = 0;
441     while ($i < count($a)) {
442         $b = split('=', $a[$i]);
443         $ret[urldecode($b[0])] = urldecode($b[1]);
444         $i++;
445     }
446
447     return $ret;
448 }
449
450 //  return values
451 // -1 v1 < v2
452 //  0 equal
453 //  1 v1 > v2
454 function versions_cmp($v1, $v2)
455 {
456     // printf("V1: [%s]\nV2: [%s]\n", $v1, $v2);
457     if ($v1 == $v2)
458         return 0;
459
460     $v1_ar = split('\.', $v1);
461     $v2_ar = split('\.', $v2);
462
463     $v2_ct = count($v2_ar);
464
465     for ($i = 0 ; $i < count($v1_ar) ; $i++) {
466         if (($v2_ct - 1) < $i) {
467             break;
468         }
469         // printf("here [%s] [%s]\n", $v1_ar[$i], $v2_ar[$i]);
470         if ($v1_ar[$i] != $v2_ar[$i]) {
471             if (strval($v1_ar[$i]) < strval($v2_ar[$i]))
472                 return -1;
473             else
474                 return  1;
475         }
476     }
477     return 0;
478 }
479
480 // return string with IPV4 address
481 function addrtoipv4($addr)
482 {
483     $ipv4addr_arr = explode(':' , $addr);
484     if (isset($ipv4addr_arr[3])) {
485         $ipv4addr = $ipv4addr_arr[3];
486     }
487     else {
488         $ipv4addr = $addr;
489     }
490     return $ipv4addr;
491 }
492
493 function mop_flush()
494 {
495     for ($i = 0; $i < ob_get_level(); $i++)
496         ob_end_flush();
497     ob_implicit_flush(1);
498     flush();
499 }
500
501 function force_no_cache(&$header_out)
502 {
503     $header_out['Pragma'] = 'no-cache, must-revalidate';
504     $header_out['Cache-Control'] = 'no-cache';
505     $header_out['Expires'] = '-1';
506 }
507
508 function file_lock($fname, $is_exclusive)
509 {
510     if (($res = @fopen($fname, "r+")) == FALSE) {
511         return (FALSE);
512     }
513
514     if (flock($res, ($is_exclusive ? LOCK_EX : LOCK_SH)) == FALSE) {
515         fclose($res);
516         return (FALSE);
517     }
518
519     return ($res);
520 }
521
522 function file_unlock($res)
523 {
524     if ($res != FALSE) {
525         flock($res, LOCK_UN);
526         fclose($res);
527     }
528 }
529
530 $escpush_from = array("\\", "\"");
531 $escpush_to   = array("\\\\", "\\\"");
532 function escpush($s)
533 {
534     GLOBAL $escpush_from, $escpush_to;
535
536     return str_replace($escpush_from, $escpush_to, $s);
537 }
538
539 $escinp_from = array( "\""     );
540 $escinp_to = array(   "&quot;" );
541
542 function escinput($s)
543 {
544     GLOBAL $escinp_from, $escinp_to;
545
546     return str_replace($escinp_from, $escinp_to, $s);
547 }
548
549 function eschtml($s)
550 {
551     return htmlentities($s, ENT_COMPAT, "UTF-8");
552 }
553
554 function esclfhtml($s)
555 {
556     return str_replace(" ", "&nbsp;", str_replace("\n", "<br>", htmlspecialchars($s)));
557 }
558
559 function langtolng($lang)
560 {
561   GLOBAL $G_lang;
562
563   return ($G_lang == 'en' ? '-en' : '');
564 }
565
566 function csplitter($in, $sep)
567 {
568   $st = 0;
569   $id = 0;
570   $out = array();
571   $out[$id] = "";
572   for ($i = 0 ; $i < strlen($in) ; $i++) {
573     $ini = substr($in, $i, 1);
574     if ($st == 0) {
575       if ($ini == '\\')
576         $st = 1;
577       else if ($ini == $sep) {
578         $id++;
579         $out[$id] = "";
580       }
581       else {
582         $out[$id] .= $ini;
583       }
584     }
585     else if ($st == 1) {
586       $out[$id] .= $ini;
587       $st = 0;
588     }
589   }
590
591   return ($out);
592 }
593
594 function xcape($s)
595 {
596   $from = array (   '\\',     '@',        '|' );
597   $to   = array ( '\\\\', '&#64;', '&brvbar;' );
598
599   return (str_replace($from, $to, htmlentities($s,ENT_COMPAT,"UTF-8")));
600 }
601
602 function xcapelt($s)
603 {
604   $from = array (   '\\',     '|',  "\t",  "\n");
605   $to   = array ( '\\\\',   '\\|', "\\t", "\\n");
606
607   return (str_replace($from, $to, $s));
608 }
609
610 function xcapemesg($s)
611 {
612   $from = array (  "\n");
613   $to   = array ( "\\n");
614
615   return (str_replace($from, $to, $s));
616 }
617
618
619 class Vect {
620     function Vect($a)
621     {
622         $this->el = $a;
623     }
624
625     function getbyid($idx)
626     {
627         return ($this->el[$idx]);
628     }
629
630     function setbyid($idx, $v)
631     {
632         $this->el[$idx] = $v;
633     }
634 }
635
636 define('TABLE_AUTH_TY_PUBL', 0);
637 define('TABLE_AUTH_TY_AUTH', 1);
638 define('TABLE_AUTH_TY_CERT', 2);
639
640
641 class Table {
642   var $idx;
643   var $player;
644   var $player_n;
645
646   var $auth_type;     // required authorization to sit down
647
648   var $wag_own;
649   var $wag_com;
650   var $wag_tout;
651
652   var $table_token;
653   var $table_start;   // information field
654
655   var $wakeup_time;
656
657   function Table()
658   {
659   }
660
661   function create($idx)
662   {
663     if (($thiz = new Table()) == FALSE)
664       return (FALSE);
665
666     $thiz->idx       =   $idx;
667     $thiz->player    =   array();
668     $thiz->player_n  =   0;
669
670     if ($idx < TABLES_CERT_N)
671         $thiz->auth_type =   TABLE_AUTH_TY_CERT;
672     else if ($idx < TABLES_AUTH_N)
673         $thiz->auth_type =   TABLE_AUTH_TY_AUTH;
674     else
675         $thiz->auth_type =   TABLE_AUTH_TY_PUBL;
676
677     $thiz->wag_own   =  -1;
678     $thiz->wag_com   =  "";
679     $thiz->wag_tout   =  0;
680
681     $thiz->table_token  = "";
682     $thiz->table_start  = 0;
683
684     $thiz->wakeup_time = 0;
685
686     return ($thiz);
687   }
688
689   function copy($from)
690   {
691     $this->idx = $from->idx;
692     $this->player = array();
693     for ($i = 0 ; $i < $from->player_n ; $i++)
694       $this->player[$i] = $from->player[$i];
695     $this->player_n = $from->player_n;
696
697     log_main("PLAYER_N - parent::copy.".$this->player_n);
698
699     $this->auth_type =  $from->auth_type;
700
701     $this->wag_own   =  $from->wag_own;
702     $this->wag_com   =  $from->wag_com;
703     $this->wag_tout  =  $from->wag_tout;
704
705     $this->table_token  = $from->table_token;
706     $this->table_start  = $from->table_start;
707
708     $this->wakeup_time = $from->wakeup_time;
709   }
710
711   function myclone($from)
712   {
713     if (($thiz = new Table()) == FALSE)
714       return (FALSE);
715
716     $this->copy($from);
717
718     return ($thiz);
719   }
720
721   function spawn($from)
722   {
723     if (($thiz = new Table()) == FALSE)
724       return (FALSE);
725
726     $thiz->idx = $from->idx;
727     $thiz->player = array();
728     for ($i = 0 ; $i < $from->player_n ; $i++)
729       $thiz->player[$i] = $i;
730     $thiz->player_n = $from->player_n;
731
732     $thiz->auth_type =  $from->auth_type;
733
734     $thiz->wag_own = $from->wag_own;
735     $thiz->wag_com = $from->wag_com;
736     $thiz->wag_tout  =  $from->wag_tout;
737
738     $thiz->table_token  = $from->table_token;
739     $thiz->table_start  = $from->table_start;
740
741     $thiz->wakeup_time = $from->wakeup_time;
742
743     return ($thiz);
744   }
745
746   function wag_set($user_idx, $mesg)
747   {
748     log_main("WAG_SET");
749
750     $this->wag_own  =  $user_idx;
751     $this->wag_com  =  $mesg;
752     $this->wag_tout =  0;
753   }
754
755   function wag_reset($timeout)
756   {
757     log_main("WAG_RESET");
758
759     unset($this->wag_own);
760     $this->wag_own  = -1;
761     $this->wag_com  = "";
762     $this->wag_tout = $timeout;
763   }
764
765   function player_get($idx)
766   {
767     return ($this->player[$idx]);
768   }
769
770   function player_set($idx, $player)
771   {
772     $this->player[$idx] = $player;
773   }
774
775   function user_add($idx)
776   {
777     $this->player[$this->player_n] = $idx;
778     $this->player_n++;
779
780     return ($this->player_n - 1);
781   }
782
783   function user_rem($brisk, $user)
784   {
785     $tabpos = $user->table_pos;
786
787     /* verifico la consistenza dei dati */
788     if ($brisk->user[$this->player[$tabpos]] == $user) {
789
790       /* aggiorna l'array dei giocatori al tavolo. */
791       for ($i = $tabpos ; $i < $this->player_n-1 ; $i++) {
792         $this->player[$i] = $this->player[$i+1];
793         $user_cur = $brisk->user[$this->player[$i]];
794         $user_cur->table_pos = $i;
795       }
796       $this->player_n--;
797     }
798     else {
799       log_main("INCONSISTENCY ON TABLE.");
800     }
801   }
802
803   // Table->act_content - return 'id' of type of output required for table button
804   function act_content($user)
805   {
806     $ret = "";
807     $isstanding = ($user->subst == 'standup');
808     $sitted = $this->player_n;
809     $table = $this->idx;
810     $cur_table = $user->table;
811     $allowed = TRUE;
812
813     if ($isstanding) {
814       if ($sitted < PLAYERS_N) {
815           switch ($this->auth_type) {
816           case TABLE_AUTH_TY_CERT:
817               if ($user->is_cert() && !$user->is_appr())
818                   $act = "sitcert";
819               else
820                   $act = 'resercert';
821               break;
822           case TABLE_AUTH_TY_AUTH:
823               if ($user->is_auth() && !$user->is_appr())
824                   $act = "sitreser";
825               else
826                   $act = 'reserved';
827               break;
828           default:
829               $act = 'sit';
830               break;
831           }
832       }
833       else {
834         $act = 'none';
835       }
836     }
837     else {
838       if ($table == $cur_table)
839         $act = 'wake';
840       else
841         $act = 'none';
842     }
843
844     if ($act != '')
845       $ret = sprintf('j_tab_act_cont(%d, \'%s\');', $table, $act);
846
847     return ($ret);
848   }
849 } // end class Table
850
851
852 class Delay_Manager
853 {
854     var $delta;
855     var $lastckeck;
856     var $triglevel;
857
858     function Delay_Manager($triglevel)
859     {
860         $this->triglevel = $triglevel;
861         $this->delta = array();
862         $this->lastcheck = 0;
863     }
864
865     function delta_get($curtime)
866     {
867         // clean too old delta items
868         for ($i = 0 ; $i < count($this->delta) ; $i++) {
869             if ($this->delta[$i][0] < $curtime) {
870                 array_splice($this->delta, $i, 1);
871                 $i--;
872             }
873         }
874
875         // add new delta items if delay exceeded $this->triglevel sec
876         if ($curtime > $this->lastcheck + $this->triglevel && $curtime < $this->lastcheck + 1200.0) {
877             $delta = $curtime - $this->lastcheck - $this->triglevel;
878             array_push($this->delta, array($curtime + $delta , $delta));
879             // fprintf(STDERR, "DELTA: add new delta [%f] [%f] [%f]\n", $this->triglevel, $curtime + $delta, $delta);
880         }
881
882         // extract the maximum valid delta
883         $delta_max = 0.0;
884         for ($i = 0 ; $i < count($this->delta) ; $i++) {
885             $delta_cur = $this->delta[$i][1];
886             if ($delta_max < $delta_cur)
887                 $delta_max = $delta_cur;
888         }
889
890         // fprintf(STDERR, "DELTA: status %d, delta_max: %f\n", count($this->delta), $delta_max);
891
892         return ($delta_max);
893     }
894
895     function lastcheck_set($curtime)
896     {
897         $this->lastcheck = $curtime;
898     }
899 }
900
901 class Client_prefs {
902     var $listen;
903     var $supp_comp;
904
905     function Client_prefs()
906     {
907     }
908
909     static function from_user($user)
910     {
911         $thiz = new Client_prefs();
912         $thiz->user_load($user);
913
914         return ($thiz);
915     }
916
917     static function from_json($json)
918     {
919         $thiz = new Client_prefs();
920         if ($thiz->json_load($json) == FALSE) {
921             unset($thiz);
922             return (FALSE);
923         }
924
925         return ($thiz);
926     }
927
928     function user_load($user)
929     {
930         fprintf(STDERR, "QQ %s: %x\n", __FUNCTION__, $user->flags);
931         $this->listen = ($user->flags & USER_FLAG_MAP_AUTH) >> 2;
932         if ($user->rec != FALSE) {
933             $this->supp_comp = $user->rec->supp_comp_get();
934         }
935         else {
936             $this->supp_comp = "000000000000";
937         }
938
939         fprintf(STDERR, "QQ %s: LISTEN: %d\n", __FUNCTION__, $this->listen);
940     }
941
942     function json_load($json_s)
943     {
944         $ret = FALSE;
945
946         do {
947             if (gettype($json_s) == "string") {
948                 if (($json = json_decode($json_s)) == FALSE)
949                     break;
950             }
951             else {
952                 $json = $json_s;
953             }
954             if ($this->listen < 0 || $this->listen > 2)
955                 break;
956             $this->listen = $json->listen;
957
958             if (mb_strlen($json->supp_comp, "ASCII") != 12)
959                 break;
960
961             for ($i = 0, $idx = 0 ; $i < 12 ; $i++) {
962                 if (($json->supp_comp[$i] >= '0' && $json->supp_comp[$i] <= '9') ||
963                     ($json->supp_comp[$i] >= 'a' && $json->supp_comp[$i] <= 'f'))
964                     continue;
965                 break;
966             }
967             if ($i < 12)
968                 break;
969             $this->supp_comp = $json->supp_comp;
970             $ret = TRUE;
971         } while (FALSE);
972
973         return ($ret);
974     }
975
976     function store($user, $is_save)
977     {
978         // save into DB
979         fprintf(STDERR, "QQ %s::%s PRE: %x\n", __CLASS__, __FUNCTION__,
980                 $user->flags & (~USER_FLAG_S_ALL & ~USER_FLAG_AUTH));
981         $user->flags_set(($this->listen << 2), USER_FLAG_MAP_AUTH);
982         fprintf(STDERR, "QQ %s::%s %x\n", __CLASS__, __FUNCTION__,
983                 $user->flags);
984         if ($user->is_supp_custom()) {
985             $user->rec->supp_comp_set($this->supp_comp);
986         }
987         if ($is_save)
988             $user->prefs_store();
989     }
990 }
991
992 define('GHOST_SESS_TOUT', 1800);
993 define('GHOST_SESS_REAS_LOUT', 1); // logout
994 define('GHOST_SESS_REAS_ANOT', 2); // another user get session
995 define('GHOST_SESS_REAS_TOUT', 3); // room timeout
996 define('GHOST_SESS_REAS_TTOT', 4); // table timeout
997 define('GHOST_SESS_REAS_ANON', 5); // anonymizer access
998 define('GHOST_SESS_REAS_PROX', 6); // proxy access
999
1000 class GhostSessEl
1001 {
1002     var $time;
1003     var $sess;
1004     var $reas;
1005
1006     function GhostSessEl($time, $sess, $reas)
1007     {
1008         $this->time = $time + GHOST_SESS_TOUT;
1009         $this->sess = $sess;
1010         $this->reas = $reas;
1011     }
1012 }
1013
1014 class GhostSess
1015 {
1016     var $gs;
1017
1018     function GhostSess()
1019     {
1020         $this->gs = array();
1021     }
1022
1023     // push or update for this session
1024     function push($time, $sess, $reas)
1025     {
1026         foreach($this->gs as $el) {
1027             if ($el->sess == "$sess") {
1028                 $el->reas = $reas;
1029                 $el->time = $time + GHOST_SESS_TOUT;
1030                 return TRUE;
1031             }
1032         }
1033
1034         $this->gs[] = new GhostSessEl($time, $sess, $reas);
1035         return TRUE;
1036     }
1037
1038     function pop($sess)
1039     {
1040         foreach($this->gs as $key => $el) {
1041             if ($el->sess == "$sess") {
1042                 $ret = $this->gs[$key];
1043                 unset($this->gs[$key]);
1044                 return ($ret);
1045             }
1046         }
1047         return FALSE;
1048     }
1049
1050     function garbage_manager($curtime)
1051     {
1052         foreach($this->gs as $key => $el) {
1053             if ($el->time < $curtime) {
1054                 unset($this->gs[$key]);
1055             }
1056         }
1057     }
1058 }
1059
1060 class Brisk
1061 {
1062     static $delta_t;
1063
1064     var $crystal_filename;
1065     var $user;
1066     var $table;
1067     var $match;
1068     var $comm; // commands for many people
1069     var $step; // current step of the comm array
1070     var $garbage_timeout;
1071     var $shm_sz;
1072
1073     var $ban_list;       // ban list (authized allowed)
1074     var $black_list;     // black list (anti-dos, noone allowed)
1075     var $cloud_smasher;  // list of cloud ip ranges to be rejected
1076     var $ghost_sess;
1077     var $delay_mgr;
1078
1079     var $cds;
1080
1081     public static $sess_cur;
1082
1083     function Brisk()
1084     {
1085         $this->cds = NULL;
1086     }
1087
1088     // constructor
1089     static function create($crystal_filename, $ban_list, $black_list, $cloud_smasher) {
1090         if (($brisk_ser = @file_get_contents($crystal_filename)) != FALSE) {
1091             if (($brisk = unserialize($brisk_ser)) != FALSE) {
1092                 fprintf(STDERR, "ROOM FROM FILE\n");
1093                 rename($crystal_filename, $crystal_filename.".old");
1094
1095                 $brisk->reload(TRUE, $ban_list, $black_list, $cloud_smasher);
1096
1097                 return($brisk);
1098             }
1099         }
1100
1101         fprintf(STDERR, "NEW ROOM\n");
1102         $thiz = new Brisk();
1103
1104         $thiz->crystal_filename = $crystal_filename;
1105         $thiz->user  = array();
1106         $thiz->table = array();
1107         $thiz->match = array();
1108
1109         $thiz->ban_list = IpClass::create();
1110         $thiz->black_list = IpClass::create();
1111         $thiz->cloud_smasher = IpClass::create();
1112         $thiz->ghost_sess = new GhostSess();
1113
1114         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1115             $thiz->user[$i] = User::create($thiz, $i, "", "");
1116         }
1117
1118         for ($i = 0 ; $i < TABLES_N ; $i++) {
1119             $thiz->table[$i] = Table::create($i);
1120         }
1121         $thiz->garbage_timeout = 0;
1122         $thiz->shm_sz = SHM_DIMS_MIN;
1123
1124         $thiz->delay_mgr = new Delay_Manager(1.5);
1125
1126         static::$sess_cur = FALSE;
1127
1128         $thiz->reload(TRUE, $ban_list, $black_list, $cloud_smasher);
1129
1130         return ($thiz);
1131     }
1132
1133     function reload($is_first, $ban_list, $black_list, $cloud_smasher)
1134     {
1135         fprintf(STDERR, "RELOAD STUFF (%d)(%d)(%d)\n",
1136                 count($ban_list), count($black_list), count($cloud_smasher));
1137
1138         if (defined('CURL_DE_SAC_VERS')) {
1139             if (brisk_cds_reload($this) == FALSE) {
1140                 exit(12);
1141             }
1142         }
1143         $this->ban_list->update($ban_list);
1144         $this->black_list->update($black_list);
1145         $this->cloud_smasher->update($cloud_smasher);
1146
1147         if (!$is_first) {
1148             $this->banned_kickoff();
1149             $this->garbage_manager(TRUE);
1150         }
1151     }
1152
1153     function banned_kickoff()
1154     {
1155         $is_ban = FALSE;
1156
1157         for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1158             $table_cur = $this->table[$table_idx];
1159             // if the table is complete and exists we check users IP
1160
1161             if ($table_cur->player_n == PLAYERS_N) {
1162                 if (isset($this->match[$table_idx]) &&
1163                     $table_cur->table_token == $bin5->table_token) {
1164                     log_main("PLAYERS == N TABLE ".$table_idx);
1165
1166                     $bin5 = $this->match[$table_idx];
1167
1168                     $is_ban |= $bin5->banned_kickoff();
1169                 }
1170             }
1171         }
1172
1173         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1174             $user_cur = $this->user[$i];
1175
1176             if ($user_cur->is_active() == FALSE)
1177                 continue;
1178
1179             // check if the IP is blacklisted
1180             if ($this->black_check($user_cur->ip) ||
1181                 $this->cloud_check($user_cur->ip)) {
1182                 $user_cur->lacc = 0;
1183                 $is_ban = TRUE;
1184                 continue;
1185             }
1186
1187             // if authorized not check if banlisted
1188             if ($user_cur->is_auth()) {
1189                 continue;
1190             }
1191
1192             if ($this->ban_check($user_cur->ip)) {
1193                 $user_cur->lacc = 0;
1194                 $is_ban = TRUE;
1195             }
1196         }
1197
1198         return $is_ban;
1199     }
1200
1201     function ban_check($ip_str)
1202     {
1203         return ($this->ban_list->check($ip_str));
1204     }
1205
1206     function black_check($ip_str)
1207     {
1208         return ($this->black_list->check($ip_str));
1209     }
1210
1211     function cloud_check($ip_str)
1212     {
1213         return ($this->cloud_smasher->check($ip_str));
1214     }
1215
1216     function users_cleanup()
1217     {
1218         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1219             $user_cur = $this->user[$i];
1220
1221             if ($user_cur->the_end) {
1222                 $user_cur->reset(); // users_cleanup, OK
1223             }
1224         }
1225     }
1226
1227   function garbage_manager($force)
1228   {
1229     GLOBAL $G_lang, $mlang_brisk, $G_base;
1230
1231     $ismod = FALSE;
1232
1233     log_rd2("garbage_manager START");
1234
1235     /* Garbage collector degli utenti in timeout */
1236     $curtime = microtime(TRUE);
1237
1238     $delta = $this->delay_mgr->delta_get($curtime);
1239
1240     if (!$force && !($this->garbage_timeout < $curtime)) {
1241         $this->delay_mgr->lastcheck_set($curtime);
1242         return ($ismod);
1243     }
1244
1245     // Before all align times with table timeout
1246     for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1247         $table_cur = $this->table[$table_idx];
1248         // if the table is complete and exists its shared mem we get the info about users lacc
1249
1250         if ($table_cur->player_n == PLAYERS_N) {
1251             log_main("PLAYERS == N TABLE ".$table_idx);
1252
1253
1254             $no_recovery = FALSE;
1255             if (isset($this->match[$table_idx])) {
1256                 $bin5 = $this->match[$table_idx];
1257
1258                 if ($table_cur->table_token != $bin5->table_token) {
1259                     log_main("ERROR: not matching table_token. Brisk: ".$table_cur->table_token."  Table: ".$bin5->table_token);
1260                     log_main("ERROR: not matching table_start. Brisk: ".$table_cur->table_start."  Table: ".$bin5->table_start);
1261                     $no_recovery = TRUE;
1262                     $bin5 = FALSE;
1263                 }
1264
1265                 if ($bin5 != FALSE) {
1266                     //
1267                     //  SPAWN: JOIN
1268                     //
1269                     log_main("garbage_manager: bri loaded successfully.");
1270                     $bin5->garbage_manager(TRUE);
1271
1272                     $bin5_table = $bin5->table[0];
1273
1274                     // is the end of the table
1275
1276                     if ($bin5->the_end == TRUE) {
1277                         /*
1278                          *  DESTROY OF FINISHED TABLE && MOVE PLAYER TO ROOM AGAIN
1279                          */
1280                         log_main("garbage_manager: INSIDE THE END.");
1281
1282                         $plist = "$table_cur->table_token|$table_cur->idx|$table_cur->player_n";
1283                         for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
1284                             $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
1285                         }
1286
1287                         for ($i = 0 ; $i < $bin5_table->player_n ; $i++) {
1288                             // stat must be "table" by definition
1289                             $user_cur = $this->user[$table_cur->player[$i]];
1290                             $bin5_user = $bin5->user[$i];
1291
1292                             $user_cur->subst      = $bin5_user->subst;
1293                             $user_cur->rd_step    = $bin5_user->rd_step;
1294                             $user_cur->step       = $bin5_user->step;
1295                             $user_cur->lacc       = $bin5_user->lacc;
1296                             $user_cur->laccwr     = $bin5_user->lacc;
1297                             $user_cur->bantime    = $bin5_user->bantime;
1298                             $user_cur->the_end    = $bin5_user->the_end;
1299                             if ($user_cur->the_end) {
1300                                 $this->ghost_sess->push($curtime, $user_cur->sess, GHOST_SESS_REAS_TTOT);
1301                             }
1302                         }
1303
1304                         log_legal($curtime, $user_cur->ip, $user_cur, "STAT:DESTROY_GAME", $plist);
1305
1306                         $this->room_join_wakeup($user_cur, FALSE, 0);
1307                         $table_cur->table_token = "";
1308                         $table_cur->wakeup_time = $curtime + WAKEUP_TIME;
1309
1310                         $this->match_del($table_idx);
1311                     }
1312                     else {
1313                         log_main("gm:: save_data");
1314
1315                         for ($i = 0 ; $i < $bin5_table->player_n ; $i++) {
1316                             $this->user[$table_cur->player[$i]]->lacc = $bin5->user[$i]->lacc;
1317                         }
1318                     }
1319                 } // if ($bin5 == FALSE
1320                 else if ($no_recovery == FALSE) {
1321                     log_crit("ERROR: table ".$table_idx." unrecoverable join");
1322
1323                     for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
1324                         $user_cur = $this->user[$table_cur->player[$i]];
1325                         $user_cur->subst = "shutdowner";
1326                         $user_cur->step_inc();
1327
1328                         $ret = sprintf('stat = "%s"; subst = "%s";',  $user_cur->stat, $user_cur->subst);
1329                         $ret .= "gst.st = ".($user_cur->step+1)."; ";
1330                         // MLANG <br>I dati del tavolo n&deg; ".$user_cur->table." sono inconsistenti, verranno resettati.<br><br>Torni in piedi.<br><br>
1331                         $prestr = sprintf($mlang_brisk['tabincon'][$G_lang], $user_cur->table);
1332                         $ret .= show_notify($prestr, 2000, $mlang_brisk['btn_close'][$G_lang], 400, 110);
1333                         $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1334                         $user_cur->step_inc();
1335                     }
1336
1337                     $plist = "$table_cur->table_token|$user_cur->table|$table_cur->player_n";
1338                     for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
1339                         $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
1340                     }
1341                     log_legal($curtime, $user_cur->ip, $user_cur, "STAT:DESTROY_GAME(RECOVERY)", $plist);
1342
1343                     $this->room_join_wakeup($user_cur, TRUE, -2);
1344                     $table_cur->table_token = "";
1345                 }
1346             }
1347         } //  if ($table_cur->player_n == PLAYERS_N) {
1348     } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1349
1350     log_rd2("out new loop.");
1351
1352     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1353         $user_cur = $this->user[$i];
1354
1355         log_rd2("User: ".$user_cur->name."  stat: ".$user_cur->stat."  subst: ".$user_cur->subst);
1356
1357         if ($user_cur->is_active() == FALSE)
1358             continue;
1359
1360         if ($user_cur->lacc + EXPIRE_TIME_RD < ($curtime - $delta)) {
1361             // Auto logout dell'utente
1362             log_rd2("AUTO LOGOUT.".($user_cur->lacc + EXPIRE_TIME_RD)." curtime - delta ".($curtime - $delta));
1363
1364             $this->ghost_sess->push($curtime, $user_cur->sess, GHOST_SESS_REAS_TOUT);
1365             $user_cur->the_end = TRUE;
1366
1367             log_rd2("AUTO LOGOUT.");
1368             if ($user_cur->stat == 'table' || $user_cur->stat == 'room') {
1369                 log_auth($user_cur->sess, "Autologout session.");
1370
1371                 if ($user_cur->subst == 'sitdown' || $user_cur->stat == 'table')
1372                     $this->room_wakeup($user_cur);
1373                 else if ($user_cur->subst == 'standup')
1374                     $this->room_outstandup($user_cur);
1375                 else
1376                     log_rd2("LOGOUT FROM WHAT ???");
1377             }
1378         }
1379
1380         if ($user_cur->laccwr + EXPIRE_TIME_SMAMMA < ($curtime - $delta)) { // lo rimettiamo in piedi
1381             if ($user_cur->stat == 'room' && $user_cur->subst == 'sitdown') {
1382                 $this->room_wakeup($user_cur);
1383                 $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
1384                 /* 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" */
1385                 $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);
1386                 $user_cur->step_inc();
1387             }
1388         }
1389     }
1390     log_rd2("GARBAGE UPDATED!");
1391
1392     $this->garbage_timeout = $curtime + GARBAGE_TIMEOUT;
1393     $ismod = TRUE;
1394
1395     $this->ghost_sess->garbage_manager($curtime);
1396
1397     $this->delay_mgr->lastcheck_set($curtime);
1398     return ($ismod);
1399   }
1400
1401   function show_room($user_step, $user)
1402   {
1403     GLOBAL $G_lang, $mlang_brisk;
1404     log_main("show_room: username: ".$user->name);
1405
1406     $ret = sprintf('gst.st = %d; ',  $user_step);
1407
1408     $prefs = Client_prefs::from_user($user);
1409     $ret .= sprintf('prefs_load(\'%s\', false, false);', json_encode($prefs));
1410
1411     if(false) {
1412         if ($user->flags & USER_FLAG_ISOLAUTH) {
1413             $ret .= 'list_set(\'isolation\', false, \''.$mlang_brisk['tit_onisol'][$G_lang].'\' ); ';
1414         }
1415         else if ($user->flags & USER_FLAG_LISTAUTH) {
1416             $ret .= 'list_set(\'auth\', false, \''.$mlang_brisk['tit_onauth'][$G_lang].'\' ); ';
1417         }
1418         else {
1419             $ret .= 'list_set(\'all\', false, \'\' ); ';
1420         }
1421     }
1422
1423     if ($user->subst == 'standup')
1424       $ret .= "tra.show(); ";
1425     else
1426       $ret .= "tra.hide(); ";
1427
1428     $ret .= sprintf('stat = "%s";',  $user->stat);
1429
1430     $ret .= root_welcome($user);
1431     if ($user->flags & USER_FLAG_DBFAILED) {
1432         $ret .= "gst.st = ".($user->step+1)."; ";
1433         $ret .= show_notify($mlang_brisk['db_failed'][$G_lang], 0, $mlang_brisk['btn_close'][$G_lang], 400, 140);
1434     }
1435
1436     $ret .= sprintf('subst = "%s";', $user->subst);
1437     $ret .= $user->myname_innerHTML();
1438
1439     for ($i = 0 ; $i < TABLES_N ; $i++) {
1440
1441       $ret .= $this->table_content($user, $i);
1442
1443       $ret .=  $this->table[$i]->act_content($user);
1444       if ($this->table[$i]->wag_own != -1)
1445         $ret .= sprintf('tra.add(%d, "%s: %s"); ', $i,  $this->user[$this->table[$i]->wag_own]->name, $this->table[$i]->wag_com);
1446       else
1447         $ret .= sprintf('tra.rem(%d); ', $i);
1448     }
1449     $ret .= $this->standup_content($user);
1450     $ret .= "setTimeout(preload_images, 0, g_preload_img_arr, g_imgct); ";
1451
1452     return ($ret);
1453   }
1454
1455   function room_wakeup($user)
1456   {
1457     $table_idx = $user->table;
1458     $table = $this->table[$table_idx];
1459
1460     log_main("WAKEUP: begin function table:".$table_idx."  stat: ".$user->stat."  subst: ".$user->subst);
1461
1462     $curtime = time();
1463
1464     $from_table = ($user->stat == "table");
1465     if ($from_table) {
1466         log_main("WAKEUP: from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
1467
1468         for ($i = 0 ; $i < $table->player_n ; $i++) {
1469             $user_cur = $this->user[$table->player[$i]];
1470             log_main("PREIMPOST: INLOOP name: ".$user_cur->name);
1471
1472             if ($user->idx_get() != $table->player[$i]) {
1473                 $user_cur->stat_set("room");
1474                 $user_cur->subst = "sitdown";
1475                 $user_cur->laccwr = $curtime;
1476             }
1477             else if ($user->is_active()) {
1478                 $user_cur->stat_set("room");
1479                 $user_cur->subst = "standup";
1480                 $user_cur->laccwr = $curtime;
1481                 $user_cur->table = -1;
1482             }
1483         }
1484     }
1485     else {
1486         $user->stat_set("room");
1487         $user->subst = "standup";
1488         $user->laccwr = $curtime;
1489     }
1490
1491     $remove_wagon = FALSE;
1492     if($table->wag_own == $user->idx_get()) {
1493         $table->wag_reset($curtime);
1494         $remove_wagon = TRUE;
1495     }
1496
1497     /* aggiorna l'array dei giocatori al tavolo. */
1498     $table->user_rem($this, $user);
1499
1500     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1501       $user_cur = $this->user[$i];
1502       if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') // is not active user or the stat isn't 'room'
1503         continue;
1504
1505       // log_main("VALORI: name: ".$user_cur->name."from_table: ".$from_table."  tab: ".$user_cur->table." taix: ".$table_idx."  ucur: ".$user_cur."  us: ".$user);
1506
1507       $ret = "gst.st = ".($user_cur->step+1)."; ".($remove_wagon ? sprintf("tra.rem(%d);",$table_idx) : "");
1508       if ($from_table && ($user_cur->table == $table_idx || $user->idx_get() == $i)) {
1509         $ret .= 'gst.st_loc++; xstm.stop(); window.onunload = null; window.onbeforeunload = null; document.location.assign("index.php");|';
1510         // $ret .= 'gst.st_loc++; document.location.assign("index.php");|';
1511         log_main("DOCUMENT.index.php: from table");
1512       }
1513       else if ($user_cur->stat == "room") {
1514         log_main("DOCUMENT.index.php: from table");
1515
1516         $ret .= $this->table_content($user_cur, $table_idx);
1517         $ret .= $this->standup_content($user_cur);
1518
1519         // $ret .= table_act_content(FALSE, 0, $table_idx, $user->table, FALSE);
1520         $ret .= $table->act_content($user);
1521
1522         if ($user->idx_get() == $i) {
1523           // set the new status
1524           $ret .=  'subst = "standup"; tra.show(); ';
1525           // clean the action buttons in other tables
1526           for ($e = 0 ; $e < TABLES_N ; $e++) {
1527             if ($this->table[$e]->player_n < PLAYERS_N) {
1528               $ret .= $this->table[$e]->act_content($user);
1529             }
1530           }
1531         }
1532         else {
1533           $ret .= $table->act_content($user_cur);
1534         }
1535       }
1536       log_wr("ROOM_WAKEUP: ".$ret);
1537       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1538       $user_cur->step_inc();
1539     }
1540   }
1541
1542   function room_join_wakeup($user, $update_lacc = FALSE, $trans_delta)
1543   {
1544     $table_idx = $user->table;
1545     $table = $this->table[$table_idx];
1546
1547     log_main("JOIN_WAKEUP: begin function table:".$table_idx."  stat: ".$user->stat."  subst: ".$user->subst);
1548
1549     $curtime = time();
1550     $user_wup = array();
1551     $user_wup_n = 0;
1552     $user_tab = array();
1553     $user_tab_n = 0;
1554     log_main("JOIN WAKEUP: from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
1555
1556     for ($i = 0 ; $i < $table->player_n ; $i++) {
1557         $user_cur = $this->user[$table->player[$i]];
1558         log_main("PREIMPOST INLOOP name: ".$user_cur->name);
1559         if ($user_cur->is_empty()) {
1560             continue;
1561         }
1562         if ($update_lacc == TRUE) {
1563             $user_cur->laccwr = $curtime;
1564         }
1565         log_main("cur: ".$user_cur->name."  subst: ".$user_cur->subst);
1566         if ($user_cur->subst == "shutdowned") {
1567             $user_cur->stat_set("room");
1568             $user_cur->subst = "sitdown";
1569         }
1570         else if ($user_cur->subst == "shutdowner") {
1571             $user_cur->stat_set("room");
1572             $user_cur->subst = "standup";
1573             $user_cur->table = -1;
1574             $user_wup[$user_wup_n++] = $user_cur;
1575
1576             $remove_wagon = FALSE;
1577             if($table->wag_own == $table->player[$i]) {
1578                 $remove_wagon = TRUE;
1579                 $table->wag_reset($curtime);
1580             }
1581         }
1582         $user_tab[$user_tab_n++] = $table->player[$i];
1583     }
1584
1585     for ($wup_idx = 0 ; $wup_idx < $user_wup_n  ; $wup_idx++)
1586       $table->user_rem($this, $user_wup[$wup_idx]);
1587
1588     /* aggiorna l'array dei giocatori al tavolo. */
1589
1590     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1591       log_main("START LOOP");
1592       $user_cur = $this->user[$i];
1593       if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') { // is not active user or the stat isn't 'room'
1594         log_main("name: ".$user_cur->name."skip   subst: ".$user_cur->subst);
1595         continue;
1596       }
1597
1598       log_main("___");
1599       log_main("VALORI name: ".$user_cur->name."  tab: ".$user_cur->table." taix: ".$table_idx);
1600
1601       $ret = "gst.st = ".($user_cur->step+1)."; ".($remove_wagon ? sprintf("tra.rem(%d);",$table_idx) : "");
1602       if ($user_cur->stat == "room") {
1603         log_main("DOCUMENT.index.php from table");
1604
1605         $ret .= $this->table_content($user_cur, $table_idx);
1606         $ret .= $this->standup_content($user_cur);
1607
1608         $ret .= $table->act_content($user_cur);
1609
1610
1611         for ($tab_idx = 0 ; $tab_idx < $user_tab_n  ; $tab_idx++)
1612             if ($user_tab[$tab_idx] == $i)
1613                 break;
1614
1615         // for users that wakeup the room will be reconstructed by index_rd.php
1616         if ($tab_idx < $user_tab_n) {
1617           log_main("PRE show_room username: ".$user_cur->name."  STEP: ".$user_cur->step);
1618
1619 //        ARRAY_POP DISABLED
1620 //           if ($trans_delta == 0)
1621 //             while (array_pop($user_cur->comm) != NULL);
1622
1623           $user_cur->trans_step = $user_cur->step + 1 + $trans_delta;
1624           $user_cur->comm[$user_cur->step % COMM_N] = "";
1625           $user_cur->step_inc();
1626           $user_cur->comm[$user_cur->step % COMM_N] = $this->show_room(($user_cur->step + 1), $user_cur);
1627           $user_cur->step_inc();
1628           log_main("POST show_room username: ".$user_cur->name."  STEP: ".$user_cur->step);
1629
1630           continue;
1631         }
1632         log_main("JOIN_WAKEUP wup_idx ".$wup_idx."  wup_n ".$user_wup_n);
1633
1634         log_main("JOIN_WAKEUP more");
1635
1636         $ret .= $table->act_content($user_cur);
1637
1638         log_main("JOIN_WAKEUP end more");
1639       }
1640       log_wr("ROOM_JOIN_WAKEUP: ".$ret);
1641       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1642       $user_cur->step_inc();
1643     }
1644   }
1645
1646   function info_show($user, $user_login, $dt)
1647   {
1648       GLOBAL $G_lang, $mlang_brisk, $G_base;
1649
1650       $mesg = "";
1651       $user_code = -1;
1652       $ret = 0;
1653
1654       do {
1655           if ($user_login == "") {
1656               $ret = 1;
1657               break;
1658           }
1659           if (($bdb = BriskDB::create()) == FALSE) {
1660               $ret = 2;
1661               break;
1662           }
1663           if (($user_item = $bdb->getitem_bylogin($user_login, $user_code)) == FALSE) {
1664               $ret = 3;
1665               break;
1666           }
1667           if ($user_login == $user->name) {
1668               $ret = 4;
1669               $mesg = sprintf($mlang_brisk['inf_self'][$G_lang]);
1670               break;
1671           }
1672           if (($guar_item = $bdb->getitem_bycode($user_item->guar_code_get())) != FALSE) {
1673               $guar_login = $guar_item->login_get();
1674           }
1675           else {
1676               $guar_login = "";
1677           }
1678           $user_tos_vers = $user_item->tos_vers_get();
1679
1680           if (versions_cmp($user_tos_vers, "1.2") < 0) {
1681               $mesg = sprintf($mlang_brisk['tos_old'][$G_lang], xcape($user_login));
1682           }
1683           else if ($guar_login == "") {
1684               $mesg = sprintf($mlang_brisk['inf_nfd'][$G_lang], xcape($user_login));
1685           }
1686       } while (0);
1687
1688       if ($ret > 0 && $mesg == "") {
1689           $mesg = sprintf($mlang_brisk['inf_err'][$G_lang], $ret);
1690       }
1691
1692       if ($ret != 0) {
1693           $jret = json_encode(array("ret" => $ret, "mesg" => $mesg));
1694       }
1695       else {
1696           $jret = json_encode(array("ret" => 0,
1697                                     "mesg" => "",
1698                                     "login" => $user_login,
1699                                     // FIXME: state internationalization
1700                                     "state" =>
1701                                     ($user_item->type & USER_FLAG_TY_APPR ? "Apprendista" :
1702                                      ($user_item->type & USER_FLAG_TY_CERT ? "Certificato" :
1703                                       ($user_item->type & (USER_FLAG_TY_NORM | USER_FLAG_TY_SUPER) ?
1704                                        "Normale" : "Stato sconosciuto"))),
1705                                     "guar" => ($user_item->type & USER_FLAG_TY_APPR ?
1706                                                "" : $guar_login),
1707                                     "match" => $user_item->match_cnt,
1708                                     "game" => $user_item->game_cnt,
1709                                     "friend" => "unknown"));
1710       }
1711
1712       return $jret;
1713   }
1714
1715   function room_outstandup($user)
1716   {
1717     $this->room_sitdown($user, -1);
1718   }
1719
1720   function table_update($user)
1721   {
1722     log_main("table_update: pre - USER: ".$user->name);
1723
1724     $table_idx = $user->table;
1725
1726     if ($table_idx > -1)
1727       $table = $this->table[$table_idx];
1728
1729     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1730       $ret = "";
1731       $user_cur = $this->user[$i];
1732       if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') // is not active user or the stat isn't 'room'
1733           continue;
1734
1735       $ret = "gst.st = ".($user_cur->step+1)."; ";
1736       if ($table_idx > -1)
1737         $ret .= $this->table_content($user_cur, $table_idx);
1738
1739       if ($user->idx_get() == $i) {
1740           $ret .= $user->myname_innerHTML();
1741       }
1742       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1743       $user_cur->step_inc();
1744     }
1745
1746     log_main("table_update: post");
1747   }
1748
1749   function room_sitdown($user, $table_idx)
1750   {
1751       log_main("room_sitdown ".($user == FALSE ? "USER: FALSE" : "USER: ".$user->name));
1752
1753       $train_app = "";
1754
1755       if ($table_idx > -1 && $table_idx < TABLES_N) {
1756           $table = $this->table[$table_idx];
1757
1758           // wagon shutdown
1759           if ($table->wag_own != -1 && $table->player_n == PLAYERS_N) {
1760               for ($i = 0 ; $i < TABLES_N ; $i++) {
1761                   if ($table->wag_own == $table->player[$i]) {
1762                       $train_app = sprintf("tra.rem(%d); ", $table_idx);
1763                       $table->wag_reset(time());
1764                       break;
1765                   }
1766               }
1767           }
1768       }
1769
1770       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1771           $ret = "";
1772           $user_cur = $this->user[$i];
1773           if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') // is not active user or the stat isn't 'room'
1774               continue;
1775
1776           $ret = "gst.st = ".($user_cur->step+1)."; ".$train_app;
1777           if ($table_idx > -1)
1778               $ret .= $this->table_content($user_cur, $table_idx);
1779           $ret .= $this->standup_content($user_cur);
1780
1781           if ($user->idx_get() == $i) {
1782               $ret .=  'subst = "sitdown"; tra.hide(); ';
1783               // clean the action buttons in other tables
1784               for ($e = 0 ; $e < TABLES_N ; $e++) {
1785                   $ret .= $this->table[$e]->act_content($user_cur);
1786               }
1787           }
1788           else if ($table_idx > -1) {
1789               if ($table->player_n == PLAYERS_N) {
1790
1791                   $ret .= $table->act_content($user_cur);
1792               }
1793           }
1794           $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1795           $user_cur->step_inc();
1796       }
1797   }
1798
1799   function kickuser($user, $out_reas)
1800   {
1801       $curtime = time();
1802
1803       fprintf(STDERR, "MOP: GHOST_SESS: %d\n", $out_reas);
1804
1805       $this->ghost_sess->push($curtime, $user->sess, $out_reas);
1806
1807       fprintf(STDERR, "MOP: status out: %s %s %d\n", $user->stat, $user->subst, $user->idx);
1808       if ($user->stat == 'table' && $user->subst != 'sitdown') {
1809           $bin5 = &$this->match[$user->table];
1810           $user_bin5 = &$bin5->user[$user->table_pos];
1811           fprintf(STDERR, "MOP: status in: %s %s %d\n", $user_bin5->stat, $user_bin5->subst, $user_bin5->idx);
1812           $bin5->table_wakeup($user_bin5);
1813           $user->the_end = TRUE;
1814           $this->room_wakeup($user);
1815           return;
1816       }
1817
1818       if ($user->stat == 'table' || $user->stat == 'room') {
1819           $user->the_end = TRUE;
1820           if ($user->subst == 'sitdown' || $user->stat == 'table') {
1821               $this->room_wakeup($user);
1822           }
1823           else if ($user->subst == 'standup') {
1824               fprintf(STDERR, "MOP: KICK here [%s]\n", btrace_line(debug_backtrace()));
1825               $this->room_outstandup($user);
1826           }
1827           else {
1828               log_rd2("LOGOUT FROM WHAT ???");
1829           }
1830       }
1831   }
1832
1833   function kickuser_by_name($name, $out_reas)
1834   {
1835       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1836           $user_out = $this->user[$i];
1837           if (strcmp($user_out->name, $name) == 0) {
1838               return ($this->kickuser($user_out, $out_reas));
1839           }
1840       }
1841       return FALSE;
1842   }
1843
1844   function kickuser_by_sess($sess, $out_reas)
1845   {
1846       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1847           $user_out = $this->user[$i];
1848           if (strcmp($user_out->sess, $sess) == 0) {
1849               return ($this->kickuser($user_out, $out_reas));
1850           }
1851       }
1852       return FALSE;
1853   }
1854
1855   function kickuser_by_idx($idx, $out_reas)
1856   {
1857       $user_out = $this->user[$idx];
1858       return ($this->kickuser($user_out, $out_reas));
1859   }
1860
1861   function chatt_send($user, $mesg)
1862   {
1863     GLOBAL $G_base, $G_alarm_passwd, $mlang_brisk, $G_lang;
1864     $only_you = FALSE;
1865
1866     fprintf(STDERR, "WE ARE HERE: [%s]\n", $mesg);
1867
1868     // common settings
1869     $msg = mb_substr($mesg, 6, 128, "UTF-8");
1870     $curtime = time();
1871     $dt = date("H:i ", $curtime);
1872     $target = "";
1873
1874     //
1875     //  Compute actions
1876     //
1877
1878     $to_user     = FALSE;
1879     $to_all      = FALSE;
1880     $to_room     = FALSE;
1881     $to_tabl     = FALSE;
1882     $is_normchat = FALSE;
1883     /* for old isolation management $is_ticker   = FALSE; */
1884     $update_room = FALSE;
1885
1886     if (strcmp($msg,  "/tav") == 0 ||
1887         strncmp($msg, "/tav ", 5) == 0) {
1888       do {
1889         if ($user->stat != 'room' || $user->subst != 'sitdown') {
1890           /* 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>" */
1891           $msg = $mlang_brisk['tickmust'][$G_lang];
1892           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1893
1894           break;
1895         }
1896
1897         $table = $this->table[$user->table];
1898
1899         if ($table->wag_own != -1) {
1900           // MLANG <br>Il messaggio di segnalazione del tavolo &egrave; gi&agrave; attivato.<br><br>
1901           $msg = $mlang_brisk['tickjust'][$G_lang];
1902           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1903
1904           break;
1905         }
1906
1907         $dtime = $curtime - $table->wag_tout;
1908         if ($dtime  < EXPIRE_TIME_WAG) {
1909           // MLANG - <br>Il messaggio di segnalazione del tavolo<br>&egrave; disattivato ancora per %d second%s.<br><br>
1910           $msg = sprintf($mlang_brisk['tickwait'][$G_lang],
1911                          EXPIRE_TIME_WAG - $dtime, (EXPIRE_TIME_WAG - $dtime == 1 ? ($G_lang == 'en' ? "" : "o") : ($G_lang == 'en' ? "s" : "i")));
1912           $to_user = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang] , 400, 100);
1913
1914           break;
1915         }
1916
1917         $msg = substr($msg, 5);
1918
1919         $table->wag_set($user->idx_get(), $msg);
1920         $to_user = sprintf('tra.add(%d, "%s");', $user->table, xcape(sprintf("%s: %s", $user->name, $msg)));
1921         $to_room = $to_user;
1922         /* for old isolation management $is_ticker = TRUE; */
1923       } while (0);
1924     } // /tav chat command
1925     // just for development use currently
1926     else if (FALSE && strncmp($msg, "/out ", 5) == 0) {
1927         fprintf(STDERR, "MOP OUT\n");
1928         $target = substr($msg, 5);
1929         $this->kickuser_by_name($target, GHOST_SESS_REAS_ANON);
1930     }
1931     else if (strncmp($msg, "/alarm ", 7) == 0) {
1932       if (strncmp($msg, "/alarm to ", 10) == 0) {
1933         $sp_pos = strpos($msg, " ", 10);
1934         $target = substr($msg, 10, $sp_pos - 10);
1935         $alarm_check = "/alarm to ".$target." ".$G_alarm_passwd." ";
1936       }
1937       else {
1938         $target = "";
1939         $alarm_check = "/alarm ".$G_alarm_passwd." ";
1940       }
1941       do {
1942         if (strncmp($msg, $alarm_check, strlen($alarm_check)) != 0) {
1943           /* MLANG: "<br>La password digitata non &egrave; corretta.<br><br>" */
1944           $msg = $mlang_brisk['alarpass'][$G_lang];
1945           $to_user = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang], 400, 100);
1946
1947           break;
1948         }
1949
1950         /* MLANG: "Alarm <b>%s</b> inviato a <b>%s</b>." */
1951         $prestr = sprintf($mlang_brisk['alarret'][$G_lang], xcape(substr($msg, strlen($alarm_check))),
1952                            ($target == "" ? $mlang_brisk['tit_all'][$G_lang] : xcape($target)) );
1953         $to_user = nickserv_msg($dt, $prestr);
1954
1955         $msg = sprintf("<br><b>%s<br><br>%s</b><br><br>",
1956                        $dt.NICKSERV, xcape(substr($msg, strlen($alarm_check))));
1957         /* MLANG: "chiudi" */
1958         $to_all = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang], 400, 120);
1959       } while (0);
1960     } // /alarm chat command
1961     else if (strncmp($msg, "/listen ", 8) == 0) {
1962       $arg = substr($msg, 8);
1963
1964       if (strcasecmp($arg, "isolation") == 0) {
1965         $flags_old = 0;
1966         if ($user->stat == 'room' && $user->subst == 'sitdown' &&
1967             $user->table >= TABLES_AUTH_N) {
1968           $to_user = nickserv_msg($dt, $mlang_brisk['listmust'][$G_lang]);
1969
1970         }
1971         else {
1972           $user->flags &= ~USER_FLAG_MAP_AUTH;
1973           $user->flags |= USER_FLAG_ISOLAUTH;
1974           $to_user = 'list_set(\'isolation\', true, \''.$mlang_brisk['tit_onisol'][$G_lang].'\'); ';
1975         }
1976       }
1977       else if (strcasecmp($arg, "auth") == 0) {
1978         $flags_old = $user->flags;
1979         $user->flags &= ~USER_FLAG_MAP_AUTH;
1980         $user->flags |= USER_FLAG_LISTAUTH;
1981         $to_user = 'list_set(\'auth\', true, \''.$mlang_brisk['tit_onauth'][$G_lang].'\'); ';
1982       }
1983       else {
1984         $flags_old = $user->flags;
1985         $user->flags &= ~USER_FLAG_MAP_AUTH;
1986         $to_user = 'list_set(\'all\', true, \'\'); ';
1987
1988       }
1989       // if from isolation redraw standup area
1990       if (($flags_old ^ $user->flags) & USER_FLAG_ISOLAUTH) {
1991         $to_user .= 'standup_data_old = null; '.$this->standup_content($user);
1992
1993       }
1994     }
1995     else if (strcmp($msg, "/authreq") == 0) {
1996         if ($user->is_cert()) {
1997             $to_user = sprintf('authbox(300,200);');
1998         }
1999         else {
2000             /* 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." */
2001             $to_user = nickserv_msg($dt, $mlang_brisk['authmust'][$G_lang]);
2002         }
2003     }
2004     else if (strncmp($msg, "/mesgtoadm", 8) == 0) {
2005         if ($user->is_auth()) {
2006         $to_user = sprintf('mesgtoadmbox(500,300);');
2007       }
2008       else {
2009         /* MLANG: "<b>Per inviare un messaggio devi essere autenticato.</b>" */
2010         $to_user = nickserv_msg($dt, $mlang_brisk['mesgmust'][$G_lang]);
2011       }
2012     }
2013     else if (FALSE && strncmp($msg, "/nick ", 6) == 0) {
2014       log_main("chatt_send BEGIN");
2015
2016       do {
2017         if (($name_new = validate_name(substr($msg, 6))) == FALSE) {
2018           $to_user = nickserv_msg($dt, $mlang_brisk['nickmust'][$G_lang]);
2019           break;
2020         }
2021
2022         $msg = "COMMAND ".$msg;
2023         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2024           $user_cur = $this->user[$i];
2025
2026           if ($user_cur->is_active() == FALSE)
2027             continue;
2028           if (strcasecmp($user_cur->name,$name_new) == 0)
2029             break;
2030           }
2031         if ($i <  MAX_PLAYERS) {
2032           $prestr = sprintf($mlang_brisk['nickdupl'][$G_lang], xcape($name_new));
2033           $to_user = nickserv_msg($dt, $prestr);
2034           break;
2035         }
2036
2037         /* 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>" */
2038         if ($user->is_auth()) {
2039           if (strcasecmp($user->name,$name_new) != 0) {
2040              if (( ($user->flags & USER_FLAG_MAP_AUTH) != USER_FLAG_ISOLAUTH) &&
2041                 ($user->subst == 'standup' ||
2042                  ($user->subst != 'standup' && $this->table[$user->table]->auth_type == TABLE_AUTH_TY_PUBL)
2043                  )
2044                 ) {
2045               $user->flags &= ~(USER_FLAG_AUTH | USER_FLAG_TY_ALL); // Remove auth if name changed
2046               for ($i = 0 ; $i < TABLES_N ; $i++) {
2047                 $to_user .= $this->table[$i]->act_content($user);
2048               }
2049             }
2050             else {
2051               $to_user = nickserv_msg($dt, $mlang_brisk['authchan'][$G_lang]);
2052               break;
2053             }
2054           }
2055         }
2056         $user->name = $name_new; // OK - nick changed
2057         /* se nome gia' in uso, segnala cosa potrebbe capitare */
2058         if ( ! $user->is_auth() ) {
2059             if (($bdb = BriskDB::create()) != FALSE) {
2060                 $bdb->users_load();
2061                 /* 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>" */
2062                 if ($bdb->login_exists($name_new)) {
2063                     $prestr = sprintf($mlang_brisk['nickjust'][$G_lang], xcape($name_new));
2064                     $to_user .= nickserv_msg($dt, $prestr);
2065                 }
2066             }
2067         }
2068
2069         log_main("chatt_send start set");
2070
2071         $update_room = TRUE;
2072       } while (0);
2073     } // nick chat command
2074     else if (strncmp($msg, "/info ", 6) == 0) {
2075         $guar_user = substr($msg, 6);
2076
2077         error_log("here [" . $guar_user."]");
2078         echo $this->info_show($user, $guar_user, $dt);
2079     }
2080     else if (strncmp($msg, "/st ", 4) == 0) {
2081       log_main("chatt_send BEGIN");
2082
2083       do {
2084         $st_str = substr($msg, 4);
2085
2086         if (strcasecmp($st_str, "normale") == 0) {
2087           $st = USER_FLAG_S_NORM;
2088         }
2089         else if (strcasecmp($st_str, "pausa") == 0) {
2090           $st = USER_FLAG_S_PAU;
2091         }
2092         else if (strcasecmp($st_str, "fuori") == 0) {
2093           $st = USER_FLAG_S_OUT;
2094         }
2095         else if (strcasecmp($st_str, "cane") == 0) {
2096           $st = USER_FLAG_S_DOG;
2097         }
2098         else if (strcasecmp($st_str, "cibo") == 0) {
2099           $st = USER_FLAG_S_EAT;
2100         }
2101         else if (strcasecmp($st_str, "lavoro") == 0) {
2102           $st = USER_FLAG_S_WRK;
2103         }
2104         else if (strcasecmp($st_str, "sigaretta") == 0) {
2105           $st = USER_FLAG_S_SMK;
2106         }
2107         else if (strcasecmp($st_str, "presente") == 0) {
2108           $st = USER_FLAG_S_EYE;
2109         }
2110         else if (strcasecmp($st_str, "coniglio") == 0) {
2111           $st = USER_FLAG_S_RABB;
2112         }
2113         else if (strcasecmp($st_str, "calcio") == 0) {
2114           $st = USER_FLAG_S_SOCC;
2115         }
2116         else if (strcasecmp($st_str, "pupo") == 0) {
2117           $st = USER_FLAG_S_BABY;
2118         }
2119         else if (strcasecmp($st_str, "pulizie") == 0) {
2120           $st = USER_FLAG_S_MOP;
2121         }
2122         else if (strcasecmp($st_str, "babbo") == 0) {
2123           $st = USER_FLAG_S_BABBO;
2124         }
2125         else if (strcasecmp($st_str, "renna") == 0) {
2126           $st = USER_FLAG_S_RENNA;
2127         }
2128         else if (strcasecmp($st_str, "pupazzo") == 0) {
2129           $st = USER_FLAG_S_PUPAZ;
2130         }
2131         else if (strcasecmp($st_str, "vischio") == 0) {
2132           $st = USER_FLAG_S_VISCH;
2133         }
2134         else {
2135           /* MLANG: "Questo stato non esiste." */
2136           $to_user = nickserv_msg($dt, $mlang_brisk['statunkn'][$G_lang]);
2137           break;
2138         }
2139
2140         log_main("chatt_send start set");
2141         if (($user->flags & USER_FLAG_S_ALL) != $st) {
2142           $update_room = TRUE;
2143           $user->flags = ($user->flags & ~USER_FLAG_S_ALL) | $st;
2144         }
2145       } while (0);
2146     } // nick chat command
2147
2148     else { // normal chat line
2149       $is_normchat = TRUE;
2150       if (CHAT_ENABLED && $curtime < ($user->chat_ban + $user->chat_dlt)) {
2151         $only_you = TRUE;
2152         $user->chat_dlt = $user->chat_dlt * 2;
2153         if ($user->chat_dlt > 120)
2154           $user->chat_dlt = 120;
2155       }
2156       else if ($user->chat_lst == $msg)
2157         $only_you = TRUE;
2158       else if (CHAT_ENABLED && $curtime - $user->chattime[($user->chat_cur + 1) % CHAT_N] < CHAT_ILL_TIME) {
2159         $user->chat_ban = $curtime;
2160         $user->chat_dlt = 5;
2161         $only_you = TRUE;
2162       }
2163       else {
2164         $user->chat_ban = 0;
2165         $user->chat_dlt = 0;
2166       }
2167
2168       if ($only_you) {
2169         $to_user = sprintf('chatt_sub("%s",[%d,"%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape("== chat ban =="));
2170       }
2171       else {
2172           // TEMPORARY DISABLED UNTIL test user option will be available
2173           // if ( TRUE && (!$user->is_auth() || $user->is_appr()) ) {
2174           if (!$user->is_auth()) {
2175               $to_user = nickserv_msg($dt, xcape("Visto l'elevato numero di molestatori che ultimamente hanno preso dimora su Brisk abbiamo deciso"));
2176               $to_user .= nickserv_msg($dt, xcape("di disattivare temporaneamente la chat in room per i non registrati, non ce ne vogliate e buone feste."));
2177               if (FALSE) {
2178                   $aug_head = array("Tanti", "Tantissimi", "Un enormità", "Un milione", "Un' esagerazione");
2179                   $aug_body = array("a tutti gli utenti", "a tutti gli uomini", "a tutte le donne", "a tutti gli utenti");
2180                   $aug_tail = array("di Brisk", "del sito", "della ciurma", "della comitiva", "del gruppo");
2181
2182                   $auguri = sprintf("%s auguri %s %s.",
2183                                     $aug_head[mt_rand(0, count($aug_head)-1)],
2184                                     $aug_body[mt_rand(0, count($aug_body)-1)],
2185                                     $aug_tail[mt_rand(0, count($aug_tail)-1)]);
2186
2187                   $to_room = sprintf('chatt_sub("%s",[%d,"%s"],"%s");', $dt, $user->flags, xcape($user->name),
2188                                      xcape($auguri));
2189               }
2190           }
2191           else {
2192               $to_user = sprintf('chatt_sub("%s",[%d,"%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape($msg));
2193               // temporary silentiation for troll (will became array check)
2194               // if (strcasecmp($user->name,'JackRokka') != 0 && $user->sess != '47ea653f602e8')
2195               $to_room = $to_user;
2196           }
2197       }
2198
2199       log_legal($curtime, $user->ip, $user,
2200                 ($user->stat == 'room' ? 'room' : 'table '.$user->table),$msg);
2201
2202       $user->chat_lst = "$msg";
2203       $user->chattime[$user->chat_cur % CHAT_N] = $curtime;
2204       $user->chat_cur++;
2205     }
2206
2207     if ($to_all) {
2208       $to_room = $to_all;
2209       $to_tabl = $to_all;
2210     }
2211
2212     //
2213     //  Output to clients
2214     //
2215
2216     if ($to_user != FALSE) {
2217       $user->comm[$user->step % COMM_N] =  "gst.st = ".($user->step+1)."; ";
2218       $user->comm[$user->step % COMM_N] .= $to_user;
2219       $user->step_inc();
2220     }
2221
2222     if ($to_room != FALSE) {
2223       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2224         $user_cur = $this->user[$i];
2225         if ($target != "" && $user_cur->name != $target)
2226           continue;
2227         if ($user_cur->is_active() == FALSE // is not active user
2228             || $user_cur->stat == 'table'   // or stat is 'table'
2229             || $user->idx_get() == $i)      // or the $user idx is equal to current var
2230           continue;
2231
2232         if ($is_normchat == TRUE) {
2233           // use MAP_AUTH to check if auth or isolation
2234           if ($user_cur->flags & USER_FLAG_MAP_AUTH) {
2235               if ( ! $user->is_auth() ) {
2236                   continue;
2237               }
2238           }
2239         }
2240         /*
2241         else if ($is_ticker) {
2242           if (($user_cur->flags & USER_FLAG_MAP_AUTH) == USER_FLAG_ISOLAUTH) {
2243             if ($user->table >= TABLES_AUTH_N)
2244               continue;
2245           }
2246         }
2247         */
2248         $user_cur->comm[$user_cur->step % COMM_N] =  "gst.st = ".($user_cur->step+1)."; ";
2249         $user_cur->comm[$user_cur->step % COMM_N] .= $to_room;
2250         $user_cur->step_inc();
2251       }
2252     }
2253
2254     if ($to_tabl) {
2255         // FIXME BRISK4: include for each kind of table
2256         require_once("${G_base}briskin5/Obj/briskin5.phh");
2257         // Before all align times with table timeout
2258         for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
2259             if (isset($this->match[$table_idx])) {
2260                 $bin5 = $this->match[$table_idx];
2261
2262                 $bin5_table = $bin5->table[0];
2263                 for ($i = 0 ; $i < $bin5_table->player_n ; $i++) {
2264                     // stat must be "table" by definition
2265                     $bin5_user = $bin5->user[$i];
2266
2267                     if ($target != "" && $bin5_user->name != $target)
2268                         continue;
2269                     log_main("writa: ".$user_mesg);
2270                     $bin5_user->comm[$bin5_user->step % COMM_N] = "gst.st = ".($bin5_user->step+1)."; ";
2271                     $bin5_user->comm[$bin5_user->step % COMM_N] .= $to_tabl;
2272                     $bin5_user->step_inc();
2273                 }
2274             } // if (isset($this->match
2275         } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
2276     } // if ($to_tabl == true ...
2277
2278     if ($update_room) {
2279       if ($user->stat == 'room' && $user->subst == 'standup') {
2280         $this->standup_update($user);
2281       }
2282       else if ($user->stat == 'room' && $user->subst == 'sitdown') {
2283         log_main("chatt_send pre table update");
2284         $this->table_update($user);
2285         log_main("chatt_send post table update");
2286       }
2287     } // if ($update_room ...
2288
2289     return;
2290   } // function chatt_send( ...
2291
2292   function get_user($sess, &$idx)
2293   {
2294       GLOBAL $PHP_SELF;
2295
2296       if (validate_sess($sess)) {
2297           for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2298               if ($this->user[$i]->is_empty())
2299                   continue;
2300               if (strcmp($sess, $this->user[$i]->sess) == 0) {
2301                   // find it
2302                   $idx = $i;
2303                   $ret = $this->user[$i];
2304                   return ($ret);
2305               }
2306           }
2307           log_main(sprintf("get_user: Wrong sess from page [%s]",$PHP_SELF));
2308           // for ($i = 0 ; $i < MAX_PLAYERS ; $i++)
2309           // log_main(sprintf("get_user: Wrong sess compared with [%s]",$this->user[$i]->sess));
2310       }
2311       else {
2312           log_main(sprintf("get_user: Wrong strlen [%s]",$sess));
2313       }
2314
2315       return (FALSE);
2316   }
2317
2318   /*
2319    * function add_user(&$brisk, &$sess, &$idx, $name, $pass, $ip, $header, $cookie)
2320    *
2321    * RETURN VALUE:
2322    *   if ($idx >  -1    && ret == FALSE)  =>  duplicated nick
2323    *   if ($idx == -2    && ret == FALSE)  =>  invalid name
2324    *   if ($idx == -3    && ret == FALSE)  =>  wrong password
2325    *   if ($idx == -1    && ret == FALSE)  =>  no space left
2326    *   if ($idx ==  0    && ret == user)   =>  SUCCESS
2327    *   if ($idx == -($idx + 1) && ret == user)   =>  SUCCESS (but the login exists in the auth db)
2328    */
2329
2330   function add_user(&$sess, &$idx, $name, $pass, $ip, $header, $cookie)
2331   {
2332     GLOBAL $G_base;
2333
2334     $idx = 0;
2335
2336     $authenticate = FALSE;
2337     $user_type    = 0;
2338     $login_exists = FALSE;
2339     $ghost = -1;
2340     $ghost_auth = FALSE;
2341     $idx = -1;
2342     $idfree = -1;
2343     $code = FALSE;
2344
2345     if (($name_new = validate_name($name)) == FALSE) {
2346       $idx = -2;
2347       return (FALSE);
2348     }
2349
2350     log_auth("XXX", sprintf("ARRIVA: [%s] pass:[%s]", $sess, ($pass == FALSE ? "FALSE" : $pass)));
2351     if (validate_sess($sess) == FALSE)
2352       $sess = "";
2353
2354     /* if pass != FALSE verify the login with pass */
2355     log_auth("XXX", "auth1");
2356
2357     if (($bdb = BriskDB::create()) != FALSE) {
2358         $bdb->users_load();
2359         if ($pass != FALSE) { // TODO: here add a method to $bdb to check if the db is available.
2360             log_auth("XXX", "auth2");
2361             $authenticate = $bdb->login_verify($name_new, $pass, $code);
2362             log_auth("XXX", "authenticate: ".($authenticate != FALSE ? "TRUE" : "FALSE"));
2363
2364             if ($authenticate != FALSE) {
2365                 $user_type = $authenticate->type_get();
2366             }
2367             else {
2368                 $idx = -3;
2369                 return (FALSE);
2370             }
2371         }
2372         else {
2373             $login_exists =  $bdb->login_exists($name_new);
2374         }
2375     }
2376     else {
2377         // if db is down, send a warning and verify only current users
2378         // no actions at this moment
2379     }
2380     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2381         /* free user ? */
2382         if ($this->user[$i]->is_empty()) {
2383             if ($idfree == -1) {
2384                 $idfree = $i;
2385             }
2386             continue;
2387         }
2388         if (strcmp($sess, $this->user[$i]->sess) == 0) {
2389             if ($idx == -1) {
2390                 $idx = $i;
2391             }
2392         }
2393         if (strcasecmp($this->user[$i]->name, $name_new) == 0) {
2394             if ($authenticate != FALSE) {
2395                 $ghost = $i;
2396                 $ghost_auth = $this->user[$i]->is_auth();
2397             }
2398             else {
2399                 $idx = $i;
2400                 break;
2401             }
2402         }
2403     }
2404     if ($idx == -1)
2405       $idx = $idfree;
2406
2407     log_auth("XXX", sprintf("TROVATO A QUESTO PUNTO [%d] sess [%s] name [%s]", $idx, $sess, $name_new));
2408
2409     /* there is another user logged with your account and you and him have authenticated => new user
2410        get the session of the old user */
2411     if ($ghost > -1 && $ghost_auth && ($authenticate != FALSE)) {
2412       /* swap session */
2413
2414       $ghost_user = $this->user[$ghost];
2415       $curtime = time();
2416       $this->ghost_sess->push($curtime, $ghost_user->sess, GHOST_SESS_REAS_ANOT);
2417       $ghost_user->comm[$ghost_user->step % COMM_N] = "";
2418       $ghost_user->step_inc();
2419       if ($sess == "") {
2420         $sess = uniqid("");
2421         $ghost_user->sess = $sess;
2422       }
2423       else {
2424         $ghost_user->sess = $sess;
2425       }
2426
2427       // If user at the table we need to update the table data too
2428       $table_idx = $ghost_user->table;
2429       if ($ghost_user->stat == "table" && $this->table[$table_idx]->player_n == PLAYERS_N) {
2430           require_once("${G_base}briskin5/Obj/briskin5.phh");
2431           if (isset($this->match[$table_idx])) {
2432               $bin5 = $this->match[$table_idx];
2433
2434               if ($bin5->the_end != TRUE) {
2435                   $bin5->user[$ghost_user->table_pos]->comm[$bin5->user[$ghost_user->table_pos]->step % COMM_N] = "";
2436                   $bin5->user[$ghost_user->table_pos]->step_inc();
2437                   $bin5->user[$ghost_user->table_pos]->sess = $sess;
2438               }
2439           }
2440       }
2441
2442       $idx = $ghost;
2443       if (defined('CURL_DE_SAC_VERS')) {
2444           brisk_cds_execute($this, $ghost, $idx, $sess, $ip, $authenticate, $header);
2445       }
2446       return ($this->user[$ghost]);
2447     }
2448     else if ($idx != -1 && $i == MAX_PLAYERS) {
2449       /* SUCCESS */
2450       $curtime = time();
2451       if ($sess == "") {
2452         $sess = uniqid("");
2453         $this->user[$idx]->sess = $sess;
2454       }
2455       else {
2456         $this->user[$idx]->sess = $sess;
2457       }
2458       $this->user[$idx]->name = $name_new; // OK - add new user
2459       $this->user[$idx]->stat_set("room");
2460       $this->user[$idx]->step_set(0);
2461       while (array_pop($this->user[$idx]->comm) != NULL);
2462       $this->user[$idx]->subst = "standup";
2463       $this->user[$idx]->lacc =   $curtime;
2464       $this->user[$idx]->laccwr = $curtime;
2465       $this->user[$idx]->bantime = 0;
2466       $this->user[$idx]->ip = $ip;
2467
2468       $this->user[$idx]->rec = $authenticate;
2469       $this->user[$idx]->flags = $user_type;
2470       $this->user[$idx]->flags |= ($authenticate != FALSE ? USER_FLAG_AUTH : 0x00);
2471       $this->user[$idx]->flags |= ( ($pass != FALSE && $bdb == FALSE) ? USER_FLAG_DBFAILED : 0x00);
2472       log_auth("XXX", sprintf("FLAGS: [%x]", $this->user[$idx]->flags));
2473
2474       if ($authenticate != FALSE) {
2475           $this->user[$idx]->code = $authenticate->code_get();
2476           if (0 == 1) {
2477               // all this part is included in the db server
2478               $this->user[$idx]->flags |= USER_FLAG_LISTAUTH;
2479
2480               if (isset($cookie['CO_list'])) {
2481                   fprintf(STDERR, "QQ: %s CO_list: [%s]\n", __FUNCTION__, $cookie['CO_list']);
2482                   if (strcmp($cookie['CO_list'], "auth") == 0) {
2483                       $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
2484                       $this->user[$idx]->flags |= USER_FLAG_LISTAUTH;
2485                   }
2486                   if (strcmp($cookie['CO_list'], "isolation") == 0) {
2487                       $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
2488                       $this->user[$idx]->flags |= USER_FLAG_ISOLAUTH;
2489                   }
2490                   else {
2491                       $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
2492                   }
2493               }
2494           }
2495           else {
2496               fprintf(STDERR, "QQ: CO_list not set flags: %x\n", __FUNCTION__, $this->user[$idx]->flags);
2497           }
2498       }
2499       fprintf(STDERR, "QQ %s: flag %x\n", __FUNCTION__, $this->user[$idx]->flags);
2500       if ($ghost > -1) {
2501         log_main("ghost: rename!");
2502         $ghost_user = $this->user[$ghost];
2503
2504         if ($ghost_auth == FALSE) {
2505           for ($sfx = 1 ; $sfx <= MAX_PLAYERS ; $sfx++) {
2506             $ghostname = 'ghost'.$sfx;
2507             for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2508               if (strcmp("", $this->user[$i]->sess) == 0)
2509                 continue;
2510
2511               if (strcasecmp($this->user[$i]->name, $ghostname) == 0) {
2512                 $ghostname = '';
2513                 break;
2514               }
2515             }
2516             if ($ghostname != '')
2517               break;
2518           }
2519
2520           $ghost_user->name = $ghostname;
2521
2522           if ($ghost_user->stat == 'room' && $ghost_user->subst == 'standup') {
2523             $this->standup_update($ghost_user);
2524           }
2525           else {
2526             log_main("chatt_send pre table update");
2527             $this->table_update($ghost_user);
2528           log_main("chatt_send post table update");
2529           }
2530         } // if ($ghost_auth == FALSE
2531         else {
2532           // FIXME: cacciare il vecchio utente room && table (if needed)
2533           $ghost_user->the_end = TRUE;
2534           $ghost_user->lacc = 0;
2535           $this->garbage_manager(TRUE);
2536         }
2537       } //  if ($ghost > -1) {
2538
2539       $real_idx = $idx;
2540       if ($login_exists)
2541         $idx = -($idx + 1);
2542       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));
2543
2544       $ret = $this->user[$real_idx];
2545       if (defined('CURL_DE_SAC_VERS')) {
2546           brisk_cds_execute($this, $ghost, $real_idx, $sess, $ip, $authenticate, $header);
2547       }
2548       return ($ret);
2549     }
2550
2551     return (FALSE);
2552   }
2553
2554   function standup_update($user)
2555   {
2556     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2557       $user_cur = $this->user[$i];
2558       if ($user_cur->is_active() == FALSE)
2559         continue;
2560
2561       log_main("STANDUP START: ".$user_cur->stat);
2562
2563       if ($user_cur->stat == 'room') {
2564         $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ".$this->standup_content($user_cur);
2565         if ($user->idx_get() == $i) {
2566           $user_cur->comm[$user_cur->step % COMM_N] .= $user->myname_innerHTML();
2567         }
2568         log_main("FROM STANDUP: NAME: ".$user_cur->name." SENDED: ".$user_cur->comm[$user_cur->step % COMM_N]);
2569
2570         $user_cur->step_inc();
2571       }
2572     }
2573   }
2574
2575   function dump_data()
2576   {
2577       $brisk_ser = serialize($this);
2578       $brisk_ser_len = mb_strlen($brisk_ser, "ASCII");
2579       if (file_put_contents($this->crystal_filename, $brisk_ser) == $brisk_ser_len) {
2580           return (TRUE);
2581       }
2582
2583       return (FALSE);
2584   }
2585
2586   function standup_content($user)
2587   {
2588     $ret = "";
2589
2590     if ($user->stat != 'room')
2591       return;
2592
2593     $content = ' j_stand_cont( [ ';
2594
2595     $user_cur_id = $user->idx_get();
2596     for ($i = 0 , $ct = 0 ; $i < MAX_PLAYERS ; $i++) {
2597         if ($this->user[$i]->is_active() == FALSE // is not active user
2598             || $this->user[$i]->stat != "room"    // or the stat isn't 'room'
2599             || $this->user[$i]->name == "")       // or the name is empty, happens when user is reset (TODO: check it)
2600         continue;
2601
2602       $flags = $this->user[$i]->flags;
2603
2604       // sql record exists AND last donate > 2013-01-01
2605       if ($this->user[$i]->is_supp_custom()) {
2606           $supp_comp_s = sprintf(', "%s"', $this->user[$i]->rec->supp_comp_get());
2607       }
2608       else {
2609           $supp_comp_s = '';
2610       }
2611
2612       if ($this->user[$i]->subst == "standup") {
2613           if ($user_cur_id == $i) {
2614               $flags |= 1;
2615           }
2616
2617           $content .= sprintf('%s[ %d, "%s"%s ]',($ct > 0 ? ', ' : ''), $flags,
2618                               xcape($this->user[$i]->name), $supp_comp_s);
2619           $ct++;
2620       }
2621     }
2622     $content .= ' ]);';
2623
2624     return ($content);
2625   }
2626
2627   function table_content($user, $table_idx)
2628   {
2629     $content = "";
2630     $ret = "";
2631     // TODO
2632     //
2633     //   Si possono usare i dati nella classe table
2634     //
2635
2636     $sess = $user->sess;
2637     $table = $this->table[$table_idx];
2638
2639     if ($user->stat != 'room')
2640       return;
2641
2642     $user_cur_id = $user->idx_get();
2643     $content = "[ ";
2644     for ($i = 0 ; $i < $table->player_n ; $i++) {
2645         $user_cur = $this->user[$table->player[$i]];
2646
2647         $flags = $user_cur->flags;
2648
2649         if ($user_cur_id == $table->player[$i])
2650             $flags |= 1;
2651
2652         log_main($user_cur->name. sprintf(" IN TABLE [%d]", $table_idx));
2653         if ($user_cur->is_supp_custom())
2654             $supp_comp_s = sprintf(', "%s"', $user_cur->rec->supp_comp_get());
2655         else
2656             $supp_comp_s = '';
2657
2658         $content .= sprintf('%s[ %d, "%s"%s ]',($i == 0 ? '' : ', '), $flags,
2659                             xcape($user_cur->name), $supp_comp_s);
2660     }
2661
2662     $content .= ' ]';
2663
2664     $ret .= sprintf('j_tab_cont(%d, %s);', $table_idx, $content);
2665
2666     return ($ret);
2667   }
2668
2669   function request_mgr(&$s_a_p, $header, &$header_out, &$new_socket, $path, $addr, $get, $post, $cookie)
2670   {
2671       GLOBAL $G_ban_list, $G_black_list, $G_cloud_smasher;
2672
2673       printf("NEW_SOCKET (root): %d PATH [%s]\n", intval($new_socket), $path);
2674
2675       fprintf(STDERR, "\n\n\n PRE_BLACK [%s]\n\n\n", $addr);
2676       if ($this->black_check($addr)) {
2677           // TODO: waiting async 5 sec before close
2678           fprintf(STDERR, "\n\n\n BLACK CHECK\n\n\n");
2679           return (FALSE);
2680       }
2681       if ($path != "" && $path != "index.php") {
2682           if ($this->cloud_check($addr)) {
2683               // TODO: waiting async 5 sec before close
2684               return (FALSE);
2685           }
2686       }
2687
2688       $enc = get_encoding($header);
2689       if (isset($header['User-Agent'])) {
2690           if (strstr($header['User-Agent'], "MSIE")) {
2691               $transp_type = "htmlfile";
2692           }
2693           else {
2694               $transp_type = "xhr";
2695           }
2696       }
2697       else {
2698           $transp_type = "iframe";
2699       }
2700       force_no_cache($header_out);
2701
2702       switch ($path) {
2703       case "":
2704       case "index.php":
2705           ob_start();
2706           index_main($this, $transp_type, $header, $header_out, $addr, $get, $post, $cookie);
2707           $content = ob_get_contents();
2708           ob_end_clean();
2709
2710           // fprintf(STDERR, "\n\nCONTENT [%s]\n\n", $content);
2711           $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
2712           return TRUE;
2713
2714           break;
2715       case "index_wr.php":
2716           //
2717           // Enhance required: in the POST case, after the header you must get content
2718           //                   from the socket, waiting if necessary
2719           //
2720
2721           ob_start();
2722           index_wr_main($this, $addr, $get, $post, $cookie);
2723           $content = ob_get_contents();
2724           ob_end_clean();
2725
2726           $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
2727           return TRUE;
2728
2729           break;
2730       case "index_rd.php":
2731           if (($transp  = gpcs_var('transp', $get, $post, $cookie)) === FALSE)
2732               $transp = "iframe";
2733           if ($transp == 'websocket')
2734               $enc = 'plain';
2735
2736           do {
2737               if (!isset($cookie['sess'])
2738                   || (($user = $this->get_user($cookie['sess'], $idx)) == FALSE)) {
2739
2740                   $content = User::stream_fini($transp, $s_a_p->rndstr, TRUE);
2741
2742                   $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
2743                   return TRUE;
2744
2745                   break;
2746               }
2747               $this->sess_cur_set($user->sess);
2748               // close a previous opened index_read_ifra socket, if exists
2749               if (($prev = $user->rd_socket_get()) != NULL) {
2750                   $s_a_p->socks_unset($user->rd_socket_get());
2751                   fclose($user->rd_socket_get());
2752                   printf("CLOSE AND OPEN AGAIN ON IFRA2\n");
2753                   $user->rd_socket_set(NULL);
2754               }
2755
2756               $content = "";
2757               $user->stream_init($s_a_p->rndstr, $enc, $header, $header_out, $content, $get, $post, $cookie);
2758               $response = headers_render($header_out, -1).$user->chunked_content($content);
2759               $response_l = mb_strlen($response, "ASCII");
2760
2761               $wret = @fwrite($new_socket, $response, $response_l);
2762               if ($wret < $response_l) {
2763                   printf("TROUBLES WITH FWRITE: %d\n", $wret);
2764                   $user->rd_cache_set(mb_substr($content, $wret, $response_l - $wret, "ASCII"));
2765               }
2766               else {
2767                   $user->rd_cache_set("");
2768               }
2769               fflush($new_socket);
2770
2771
2772               $s_a_p->socks_set($new_socket, $user, NULL);
2773               $user->rd_socket_set($new_socket);
2774               printf(" - qui ci siamo - ");
2775               return TRUE;
2776           } while (FALSE);
2777
2778           return FALSE;
2779           break;
2780       case 'test.php':
2781           if (!(BRISK_DEBUG & DBG_ENGI))
2782               return (FALSE);
2783           fprintf(STDERR, "TEST.PHP running\n");
2784           if (isset($post['data'])) {
2785               $content = $post['data'];
2786           }
2787           else {
2788               $content = "NO DATA AVAILABLE";
2789           }
2790           $header_out['Content-Type'] = 'text/plain';
2791           $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
2792           return TRUE;
2793           break;
2794       default:
2795           /* FAR TODO: move all into an array of registered sub-apps */
2796           $subs = "briskin5/";
2797           $subs_l = strlen($subs);
2798           if (!strncmp($path, $subs, $subs_l)) {
2799               $ret = Bin5::request_mgr(&$s_a_p, $header, &$header_out, &$new_socket, substr($path, $subs_l) , $addr, $get, $post, $cookie);
2800               return ($ret);
2801           }
2802           break;
2803       }
2804
2805       return (FALSE);
2806   }
2807
2808   function match_add($idx, $match)
2809   {
2810       $this->match[$idx] = $match;
2811   }
2812
2813   function match_del($idx)
2814   {
2815       unset($this->match[$idx]);
2816   }
2817
2818   function match_get($idx, $token)
2819   {
2820       if (isset($this->match[$idx])) {
2821           if (   $token == NULL
2822               || $token == $this->match[$idx]->table_token) {
2823               return ($this->match[$idx]);
2824           }
2825       }
2826       return NULL;
2827   }
2828   function sess_cur_set($sess)
2829   {
2830       static::$sess_cur = $sess;
2831   }
2832
2833   static function sess_cur_get()
2834   {
2835       return(static::$sess_cur);
2836   }
2837 } // end class Brisk
2838
2839 function make_seed()
2840 {
2841   list($usec, $sec) = explode(' ', microtime());
2842   return (float) $sec + ((float) $usec * 100000);
2843 }
2844
2845 function btrace_line($ar)
2846 {
2847     GLOBAL $G_btrace_pref_sub;
2848
2849     $ret = "";
2850     for ($i = 0 ; $i < count($ar) ; $i++) {
2851         $with_class = isset($ar[$i]['class']);
2852         $with_file  = isset($ar[$i]['file']);
2853         $ret .= sprintf("%s%s%s (%s:%d)", ($i == 0 ? "" : ", "),
2854                         ($with_class ?  $ar[$i]['class'].$ar[$i]['type'] : ""),
2855                         $ar[$i]['function'], ($with_file ? str_replace($G_btrace_pref_sub, "", $ar[$i]['file']) : ""),
2856                         ($with_file ? $ar[$i]['line'] : ""));
2857     }
2858
2859     return ($ret);
2860 }
2861
2862 function trace_ftok($id, $add)
2863 {
2864     // NOTE: without space to use sed to substitute "= @ftok("  with "= @ftok("
2865     $tok=@ftok($id, $add);
2866
2867     log_shme($tok.": ".$id." + ".$add);
2868
2869     return ($tok);
2870 }
2871
2872 function log_mop($step, $log)
2873 {
2874     GLOBAL $PHP_SELF;
2875
2876     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LMOP) == 0)
2877         return;
2878
2879     $sess = Brisk::sess_cur_get();
2880     if (isset($sess) == FALSE)
2881         $ssess = "XXXX";
2882     else
2883         $ssess = $sess;
2884
2885     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LMOP) == 0)
2886         return;
2887
2888     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2889         $btrace = btrace_line(debug_backtrace());
2890     else
2891         $btrace = "";
2892     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2893         fwrite($fp, sprintf("LMOP: [%f] [%05d] [%s] [%s]\n", gettimeofday(TRUE), $step, $log, $btrace));
2894         fclose($fp);
2895     }
2896 }
2897
2898 function log_step($log)
2899 {
2900     GLOBAL $PHP_SELF;
2901
2902     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_STEP) == 0)
2903         return;
2904
2905     $sess = Brisk::sess_cur_get();
2906     if (isset($sess) == FALSE)
2907         $ssess = "XXXX";
2908     else
2909         $ssess = $sess;
2910
2911     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_STEP) == 0)
2912         return;
2913
2914     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2915         $btrace = btrace_line(debug_backtrace());
2916     else
2917         $btrace = "";
2918     if (($fp = @fopen(LEGAL_PATH."/step.log", 'a')) != FALSE) {
2919         fwrite($fp, sprintf("STEP: [%f] [%s] [%s]\n", gettimeofday(TRUE), $log, $btrace));
2920         fclose($fp);
2921     }
2922 }
2923
2924
2925
2926 function log_cds($log)
2927 {
2928     GLOBAL $PHP_SELF;
2929
2930     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_CDS) == 0)
2931         return;
2932
2933     $sess = Brisk::sess_cur_get();
2934     if (isset($sess) == FALSE)
2935         $ssess = "XXXX";
2936     else
2937         $ssess = $sess;
2938
2939     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_CDS) == 0)
2940         return;
2941
2942     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2943         $btrace = btrace_line(debug_backtrace());
2944     else
2945         $btrace = "";
2946     if (($fp = @fopen(LEGAL_PATH."/cds.log", 'a')) != FALSE) {
2947         fwrite($fp, sprintf("CDS: [%f] [%s] [%s]\n", gettimeofday(TRUE), $log, $btrace));
2948         fclose($fp);
2949     }
2950 }
2951
2952
2953 function log_only2($log)
2954 {
2955     GLOBAL $PHP_SELF;
2956
2957     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_ONL2) == 0)
2958         return;
2959
2960     $sess = Brisk::sess_cur_get();
2961     if (isset($sess) == FALSE)
2962         $ssess = "XXXX";
2963     else
2964         $ssess = $sess;
2965
2966     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_ONL2) == 0)
2967         return;
2968
2969     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2970         $btrace = btrace_line(debug_backtrace());
2971     else
2972         $btrace = "";
2973     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2974         fwrite($fp, sprintf("ONL2: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
2975         fclose($fp);
2976     }
2977 }
2978
2979 function log_crit($log)
2980 {
2981     GLOBAL $PHP_SELF;
2982
2983     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_CRIT) == 0)
2984         return;
2985
2986     $sess = Brisk::sess_cur_get();
2987     if (isset($sess) == FALSE)
2988         $ssess = "XXXX";
2989     else
2990         $ssess = $sess;
2991
2992     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_CRIT) == 0)
2993         return;
2994
2995     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2996         $btrace = btrace_line(debug_backtrace());
2997     else
2998         $btrace = "";
2999     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3000         fwrite($fp, sprintf("CRIT: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3001         fclose($fp);
3002     }
3003 }
3004
3005 function log_only($log)
3006 {
3007     GLOBAL $PHP_SELF;
3008
3009     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_ONLY) == 0)
3010         return;
3011
3012     $sess = Brisk::sess_cur_get();
3013     if (isset($sess) == FALSE)
3014         $ssess = "XXXX";
3015     else
3016         $ssess = $sess;
3017
3018     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_ONLY) == 0)
3019         return;
3020
3021     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3022         $btrace = btrace_line(debug_backtrace());
3023     else
3024         $btrace = "";
3025     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3026         fwrite($fp, sprintf("ONLY: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3027         fclose($fp);
3028     }
3029 }
3030
3031 function log_main($log)
3032 {
3033     GLOBAL $PHP_SELF;
3034
3035     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_MAIN) == 0)
3036         return;
3037
3038     $sess = Brisk::sess_cur_get();
3039     if (isset($sess) == FALSE)
3040         $ssess = "XXXX";
3041     else
3042         $ssess = $sess;
3043
3044     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_MAIN) == 0)
3045         return;
3046
3047     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3048         $btrace = btrace_line(debug_backtrace());
3049     else
3050         $btrace = "";
3051     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3052         fwrite($fp, sprintf("MAIN: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3053         fclose($fp);
3054     }
3055 }
3056
3057 function log_rd($log)
3058 {
3059     GLOBAL $PHP_SELF;
3060
3061     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_READ) == 0)
3062         return;
3063
3064     $sess = Brisk::sess_cur_get();
3065     if (isset($sess) == FALSE)
3066         $ssess = "XXXX";
3067     else
3068         $ssess = $sess;
3069
3070     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_READ) == 0)
3071         return;
3072
3073     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3074         $btrace = btrace_line(debug_backtrace());
3075     else
3076         $btrace = "";
3077     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3078         fwrite($fp, sprintf("READ: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3079         fclose($fp);
3080     }
3081 }
3082
3083 function log_rd2($log)
3084 {
3085     GLOBAL $PHP_SELF;
3086
3087     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_REA2) == 0)
3088         return;
3089
3090     $sess = Brisk::sess_cur_get();
3091     if (isset($sess) == FALSE)
3092         $ssess = "XXXX";
3093     else
3094         $ssess = $sess;
3095
3096     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_REA2) == 0)
3097         return;
3098
3099     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3100         $btrace = btrace_line(debug_backtrace());
3101     else
3102         $btrace = "";
3103
3104     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3105         fwrite($fp, sprintf("REA2: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3106         fclose($fp);
3107     }
3108 }
3109
3110 function log_send($log)
3111 {
3112     GLOBAL $PHP_SELF;
3113
3114     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_SEND) == 0)
3115         return;
3116
3117     $sess = Brisk::sess_cur_get();
3118     if (isset($sess) == FALSE)
3119         $ssess = "XXXX";
3120     else
3121         $ssess = $sess;
3122
3123     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_SEND) == 0)
3124         return;
3125
3126     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3127         $btrace = btrace_line(debug_backtrace());
3128     else
3129         $btrace = "";
3130     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3131         fwrite($fp, sprintf("SEND: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3132         fclose($fp);
3133     }
3134 }
3135
3136 function log_lock($log)
3137 {
3138     GLOBAL $PHP_SELF;
3139
3140     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LOCK) == 0)
3141         return;
3142
3143     $sess = Brisk::sess_cur_get();
3144     if (isset($sess) == FALSE)
3145         $ssess = "XXXX";
3146     else
3147         $ssess = $sess;
3148
3149     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LOCK) == 0)
3150         return;
3151
3152     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3153         $btrace = btrace_line(debug_backtrace());
3154     else
3155         $btrace = "";
3156     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3157         fwrite($fp, sprintf("LOCK: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3158         fclose($fp);
3159     }
3160 }
3161
3162 function log_wr($log)
3163 {
3164     GLOBAL $PHP_SELF;
3165
3166     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_WRIT) == 0)
3167         return;
3168
3169     $sess = Brisk::sess_cur_get();
3170     if (isset($sess) == FALSE)
3171         $ssess = "XXXX";
3172     else
3173         $ssess = $sess;
3174
3175     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_WRIT) == 0)
3176         return;
3177
3178     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3179         $btrace = btrace_line(debug_backtrace());
3180     else
3181         $btrace = "";
3182     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3183         fwrite($fp, sprintf("WRIT: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3184         fclose($fp);
3185     }
3186 }
3187
3188 function log_load($log)
3189 {
3190     GLOBAL $PHP_SELF;
3191
3192     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LOAD) == 0)
3193         return;
3194
3195     $sess = Brisk::sess_cur_get();
3196     if (isset($sess) == FALSE)
3197         $ssess = "XXXX";
3198     else
3199         $ssess = $sess;
3200
3201     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LOAD) == 0)
3202         return;
3203
3204     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3205         $btrace = btrace_line(debug_backtrace());
3206     else
3207         $btrace = "";
3208     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3209         fwrite($fp, sprintf("LOAD: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3210         fclose($fp);
3211     }
3212 }
3213
3214 function log_auth($sess, $log)
3215 {
3216     GLOBAL $PHP_SELF;
3217
3218     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_AUTH) == 0)
3219         return;
3220
3221     if (( (BRISK_DEBUG | ($sess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_AUTH) == 0)
3222         return;
3223
3224     if ((BRISK_DEBUG | ($sess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3225         $btrace = btrace_line(debug_backtrace());
3226     else
3227         $btrace = "";
3228     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3229         fwrite($fp, sprintf("LOAD: [%s] [%d] [%s] [%s]\n", $sess, time(), $log, $btrace));
3230         fclose($fp);
3231     }
3232 }
3233
3234 function log_shme($log)
3235 {
3236     GLOBAL $PHP_SELF;
3237
3238     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_SHME) == 0)
3239         return;
3240
3241     $sess = Brisk::sess_cur_get();
3242     if (isset($sess) == FALSE)
3243         $ssess = "XXXX";
3244     else
3245         $ssess = $sess;
3246
3247     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_SHME) == 0)
3248         return;
3249
3250     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3251         $btrace = btrace_line(debug_backtrace());
3252     else
3253         $btrace = "";
3254     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3255         fwrite($fp, sprintf("SHME: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3256         fclose($fp);
3257     }
3258 }
3259
3260
3261
3262 // function log_legal($curtime, $sess, $name, $where, $mesg)
3263 function log_legal($curtime, $addr, $user, $where, $mesg)
3264 {
3265
3266   if (($fp = @fopen(LEGAL_PATH."/legal.log", 'a')) != FALSE) {
3267     /* Unix time | session | nickname | IP | where was | mesg */
3268     fwrite($fp, sprintf("%ld|%s|%s|%s|%s|%s|%s|\n", $curtime, $user->sess,
3269                         ($user->is_auth() ? 'A' : 'N'),
3270                         $user->name, $addr, $where , $mesg));
3271     fclose($fp);
3272   }
3273 }
3274
3275 function table_act_content($isstanding, $sitted, $table, $cur_table, $allowed)
3276 {
3277   $ret = "";
3278
3279   if ($isstanding) {
3280     if ($sitted < PLAYERS_N) {
3281       if ($allowed)
3282         $act = 'sit';
3283       else
3284         $act = 'reserved';
3285     }
3286   }
3287   else {
3288     if ($table == $cur_table)
3289       $act = 'wake';
3290     else
3291       $act = 'none';
3292   }
3293
3294   if ($act != '')
3295     $ret = sprintf('j_tab_act_cont(%d, \'%s\');', $table, $act);
3296
3297   return ($ret);
3298 }
3299
3300 function show_notify($text, $tout, $butt, $w, $h)
3301 {
3302   log_main("SHOW_NOTIFY: ".$text);
3303   return sprintf('var noti = new notify(gst,"%s",%d,"%s",%d,%d);', $text, $tout, $butt, $w, $h);
3304 }
3305
3306 function show_notify_ex($text, $tout, $butt, $w, $h, $is_opaque, $block_time)
3307 {
3308   log_main("SHOW_NOTIFY OPAQUE: ".$text);
3309   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);
3310 }
3311
3312 function show_notify_document($text, $tout, $butt_arr, $confirm_func, $confirm_func_args, $w, $h, $is_opaque, $block_time)
3313 {
3314   log_main("SHOW_NOTIFY OPAQUE: ".$text);
3315
3316   $butts = "";
3317   for ($i = 0 ; $i < count($butt_arr) ; $i++) {
3318       $butts .= sprintf("%s'%s'", ($i == 0 ? "" : ","), $butt_arr[$i]);
3319   }
3320
3321   return sprintf('g_nd = new notify_document(gst, "%s", %d, [ %s ], %s, %s, %d, %d, %s, %d);|',
3322                  escpush($text), $tout, $butts, ($confirm_func == NULL ? "null" : $confirm_func), (($confirm_func == NULL|| $confirm_func_args == NULL) ? "[]" : $confirm_func_args), $w, $h, ($is_opaque ? "true" : "false"), $block_time);
3323 }
3324
3325
3326 function root_welcome($user)
3327 {
3328   GLOBAL $root_wellarr, $G_lang;
3329   $ret = "";
3330
3331   $curtime = time();
3332   $dt = date("H:i ", $curtime);
3333
3334   for ($i = 0 ; $i < count($root_wellarr[$G_lang]) ; $i++)
3335       $ret .= nickserv_msg($dt, str_replace('"', '\"', $root_wellarr[$G_lang][$i]));
3336
3337   return ($ret);
3338 }
3339
3340
3341
3342 function validate_sess($sess)
3343 {
3344   if (strlen($sess) == SESS_LEN)
3345     return (TRUE);
3346   else
3347     return (FALSE);
3348 }
3349
3350 function validate_name($name)
3351 {
3352     $name_new = str_replace(' ', '_', mb_substr(trim($name),0,12, "UTF-8"));
3353
3354   for ($i = 0 ; $i < mb_strlen($name_new) ; $i++) {
3355     $c = $name_new[$i];
3356     if (($c >= "a" && $c <= "z") || ($c >= "A" && $c <= "Z") || ($c >= "0" && $c <= "9"))
3357       return ($name_new);
3358   }
3359
3360   return (FALSE);
3361 }
3362
3363 function playsound($filename)
3364 {
3365   return (sprintf('playsound("flasou", "%s");', $filename));
3366 }
3367
3368 function secstoword($secs)
3369 {
3370   GLOBAL $G_lang;
3371
3372   $ret = "";
3373
3374   $mins = floor($secs / 60);
3375   $secs = $secs % 60;
3376   if ($G_lang == 'en') {
3377     if ($mins > 0)
3378       $ret = sprintf("%d minute%s%s", $mins, ($mins > 1 ? "s" : ""), ($secs > 0 ? " and " : ""));
3379
3380     if ($secs > 0)
3381       $ret .= sprintf("%d second%s", $secs, ($secs > 1 ? "s" : ""));
3382   }
3383   else {
3384     if ($mins > 0)
3385       $ret = sprintf("%d minut%s%s", $mins, ($mins > 1 ? "i" : "o"), ($secs > 0 ? " e " : ""));
3386
3387     if ($secs > 0)
3388       $ret .= sprintf("%d second%s", $secs, ($secs > 1 ? "i" : "o"));
3389   }
3390   return ($ret);
3391 }
3392
3393 function sharedmem_sz($tok)
3394 {
3395   if (($shm_id = @shmop_open($tok, 'a', 0, 0)) == FALSE) {
3396     log_main("shmop_open failed");
3397     return (-1);
3398   }
3399   $shm_sz = shmop_size($shm_id);
3400   shmop_close($shm_id);
3401
3402   // log_main("shm_sz: ".$shm_sz."   SHM_DIMS: ".SHM_DIMS);
3403   return ($shm_sz);
3404 }
3405
3406 class Warrant {
3407     static $delta_t;
3408
3409   static function lock_data($is_exclusive)
3410   {
3411       if (($res = file_lock(FTOK_PATH."/warrant", $is_exclusive)) != FALSE) {
3412           self::$delta_t = microtime(TRUE);
3413           log_lock("LOCK   warrant      [".self::$delta_t."]");
3414
3415           return ($res);
3416       }
3417
3418       return (FALSE);
3419   }
3420
3421   static function unlock_data($res)
3422   {
3423     GLOBAL $sess;
3424
3425     log_lock("UNLOCK warrant      [".(microtime(TRUE) - (self::$delta_t))."]");
3426
3427     file_unlock($res);
3428   }
3429 }
3430
3431 class Poll {
3432     static $delta_t;
3433
3434   static function lock_data($is_exclusive)
3435   {
3436       if (($res = file_lock(FTOK_PATH."/poll", $is_exclusive)) != FALSE) {
3437           self::$delta_t = microtime(TRUE);
3438           log_lock("LOCK   poll         [".self::$delta_t."]");
3439
3440           return ($res);
3441       }
3442
3443       return (FALSE);
3444   }
3445
3446   static function unlock_data($res)
3447   {
3448     GLOBAL $sess;
3449
3450     log_lock("UNLOCK poll         [".(microtime(TRUE) - (self::$delta_t))."]");
3451
3452     file_unlock($res);
3453   }
3454 }
3455
3456 function carousel_top()
3457 {
3458     $what = rand(1,2);
3459     if ($what == 1) {
3460         $rn = rand(1, 3);
3461         return (sprintf('<a target="_blank" href="http://shop.alternativeoutput.it"><img class="nobo" style="display: inline; border: 1px solid #808080;" alt="il negozio virtuale di Brisk" title="il negozio virtuale di Brisk" src="img/briskshop%d.gif"></a>', $rn));
3462         }
3463     else {
3464         return (sprintf('<a target="_blank" href="http://www.alternativeoutput.it/briskblog"><img class="nobo" alt="il nuovo blog di Brisk" title="il nuovo blog di Brisk" style="display: inline; border: 1px solid #808080;" src="img/briskblog_bannersmall.png"></a>'));
3465     }
3466 }
3467
3468
3469 ?>