info: error handling refactored
[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.3";
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   /*
1647     function info_show($user, $target, $dt)
1648
1649     if success return assoc. array with "ret" => 0 and other fields
1650     else return an assoc. array with "ret: != 0 and "mesg" with an error description
1651   */
1652   function info_show($user, $target, $dt)
1653   {
1654       GLOBAL $G_lang, $mlang_brisk, $G_base;
1655
1656       $mesg = "";
1657       $user_code = -1;
1658       $ret = 0;
1659
1660       do {
1661           if ($target == "") {
1662               $ret = 1;
1663               break;
1664           }
1665           if (($bdb = BriskDB::create()) == FALSE) {
1666               $ret = 2;
1667               break;
1668           }
1669           if ($target == $user->name) {
1670               $ret = 3;
1671               $mesg = sprintf($mlang_brisk['inf_self'][$G_lang]);
1672               break;
1673           }
1674           if (($user_item = $bdb->getitem_bylogin($target, $user_code)) == FALSE) {
1675               $ret = 4;
1676               break;
1677           }
1678           if (($guar_item = $bdb->getitem_bycode($user_item->guar_code_get())) != FALSE) {
1679               $guar_login = $guar_item->login_get();
1680           }
1681           else {
1682               $guar_login = "";
1683           }
1684           $user_tos_vers = $user_item->tos_vers_get();
1685
1686           if (($usersnet_item = $bdb->usersnet_bycode($user->code, $user_item->code)) == FALSE) {
1687               $usersnet_item = $bdb->usersnet_default($user->code, $user_item->code);
1688           }
1689
1690           if (versions_cmp($user_tos_vers, "1.2") < 0) {
1691               $mesg = sprintf($mlang_brisk['tos_old'][$G_lang], xcape($target));
1692           }
1693           else if ($guar_login == "") {
1694               $mesg = sprintf($mlang_brisk['inf_nfd'][$G_lang], xcape($target));
1695           }
1696       } while (0);
1697
1698       if ($ret > 0 && $mesg == "") {
1699           $mesg = sprintf($mlang_brisk['inf_err'][$G_lang], $ret);
1700       }
1701
1702       if ($ret != 0) {
1703           $jret = json_encode(array("ret" => $ret, "mesg" => $mesg));
1704       }
1705       else {
1706           $jret = json_encode(array("ret" => 0,
1707                                     "mesg" => "",
1708                                     "login" => $target,
1709                                     // FIXME: state internationalization
1710                                     "state" =>
1711                                     ($user_item->type & USER_FLAG_TY_APPR ? "Apprendista" :
1712                                      ($user_item->type & USER_FLAG_TY_CERT ? "Certificato" :
1713                                       ($user_item->type & (USER_FLAG_TY_NORM | USER_FLAG_TY_SUPER) ?
1714                                        "Normale" : "Stato sconosciuto"))),
1715                                     "guar" => ($user_item->type & USER_FLAG_TY_APPR ?
1716                                                "" : $guar_login),
1717                                     "match" => (versions_cmp($user_tos_vers, "1.4") < 0 ? "non autorizzato" : $user_item->match_cnt) ,
1718                                     "game" => (versions_cmp($user_tos_vers, "1.4") < 0 ? "non autorizzato" : $user_item->game_cnt),
1719                                     "friend" => usersnet_friend_getlabel($usersnet_item->friend),
1720                                     "skill" => $usersnet_item->skill,
1721                                     "trust"  => $usersnet_item->trust));
1722       }
1723
1724       return $jret;
1725   }
1726
1727   function info_save($user, $json_s)
1728   {
1729       GLOBAL $G_lang, $mlang_brisk, $G_base;
1730
1731       $mesg = "";
1732       $user_code = -1;
1733       $ret = 0;
1734
1735       do {
1736           if (($json = json_decode($json_s)) == FALSE) {
1737               $ret = 1;
1738               break;
1739           }
1740
1741           if (($bdb = BriskDB::create()) == FALSE) {
1742               $ret = 2;
1743               break;
1744           }
1745
1746           if (($user_item = $bdb->usersnet_save($user->code, $json)) != 0) {
1747               $ret = 4000 + $user_item;
1748               break;
1749           }
1750       } while(0);
1751
1752       return ($ret);
1753   }
1754
1755   function room_outstandup($user)
1756   {
1757     $this->room_sitdown($user, -1);
1758   }
1759
1760   function table_update($user)
1761   {
1762     log_main("table_update: pre - USER: ".$user->name);
1763
1764     $table_idx = $user->table;
1765
1766     if ($table_idx > -1)
1767       $table = $this->table[$table_idx];
1768
1769     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1770       $ret = "";
1771       $user_cur = $this->user[$i];
1772       if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') // is not active user or the stat isn't 'room'
1773           continue;
1774
1775       $ret = "gst.st = ".($user_cur->step+1)."; ";
1776       if ($table_idx > -1)
1777         $ret .= $this->table_content($user_cur, $table_idx);
1778
1779       if ($user->idx_get() == $i) {
1780           $ret .= $user->myname_innerHTML();
1781       }
1782       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1783       $user_cur->step_inc();
1784     }
1785
1786     log_main("table_update: post");
1787   }
1788
1789   function room_sitdown($user, $table_idx)
1790   {
1791       log_main("room_sitdown ".($user == FALSE ? "USER: FALSE" : "USER: ".$user->name));
1792
1793       $train_app = "";
1794
1795       if ($table_idx > -1 && $table_idx < TABLES_N) {
1796           $table = $this->table[$table_idx];
1797
1798           // wagon shutdown
1799           if ($table->wag_own != -1 && $table->player_n == PLAYERS_N) {
1800               for ($i = 0 ; $i < TABLES_N ; $i++) {
1801                   if ($table->wag_own == $table->player[$i]) {
1802                       $train_app = sprintf("tra.rem(%d); ", $table_idx);
1803                       $table->wag_reset(time());
1804                       break;
1805                   }
1806               }
1807           }
1808       }
1809
1810       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1811           $ret = "";
1812           $user_cur = $this->user[$i];
1813           if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') // is not active user or the stat isn't 'room'
1814               continue;
1815
1816           $ret = "gst.st = ".($user_cur->step+1)."; ".$train_app;
1817           if ($table_idx > -1)
1818               $ret .= $this->table_content($user_cur, $table_idx);
1819           $ret .= $this->standup_content($user_cur);
1820
1821           if ($user->idx_get() == $i) {
1822               $ret .=  'subst = "sitdown"; tra.hide(); ';
1823               // clean the action buttons in other tables
1824               for ($e = 0 ; $e < TABLES_N ; $e++) {
1825                   $ret .= $this->table[$e]->act_content($user_cur);
1826               }
1827           }
1828           else if ($table_idx > -1) {
1829               if ($table->player_n == PLAYERS_N) {
1830
1831                   $ret .= $table->act_content($user_cur);
1832               }
1833           }
1834           $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1835           $user_cur->step_inc();
1836       }
1837   }
1838
1839   function kickuser($user, $out_reas)
1840   {
1841       $curtime = time();
1842
1843       fprintf(STDERR, "MOP: GHOST_SESS: %d\n", $out_reas);
1844
1845       $this->ghost_sess->push($curtime, $user->sess, $out_reas);
1846
1847       fprintf(STDERR, "MOP: status out: %s %s %d\n", $user->stat, $user->subst, $user->idx);
1848       if ($user->stat == 'table' && $user->subst != 'sitdown') {
1849           $bin5 = &$this->match[$user->table];
1850           $user_bin5 = &$bin5->user[$user->table_pos];
1851           fprintf(STDERR, "MOP: status in: %s %s %d\n", $user_bin5->stat, $user_bin5->subst, $user_bin5->idx);
1852           $bin5->table_wakeup($user_bin5);
1853           $user->the_end = TRUE;
1854           $this->room_wakeup($user);
1855           return;
1856       }
1857
1858       if ($user->stat == 'table' || $user->stat == 'room') {
1859           $user->the_end = TRUE;
1860           if ($user->subst == 'sitdown' || $user->stat == 'table') {
1861               $this->room_wakeup($user);
1862           }
1863           else if ($user->subst == 'standup') {
1864               fprintf(STDERR, "MOP: KICK here [%s]\n", btrace_line(debug_backtrace()));
1865               $this->room_outstandup($user);
1866           }
1867           else {
1868               log_rd2("LOGOUT FROM WHAT ???");
1869           }
1870       }
1871   }
1872
1873   function kickuser_by_name($name, $out_reas)
1874   {
1875       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1876           $user_out = $this->user[$i];
1877           if (strcmp($user_out->name, $name) == 0) {
1878               return ($this->kickuser($user_out, $out_reas));
1879           }
1880       }
1881       return FALSE;
1882   }
1883
1884   function kickuser_by_sess($sess, $out_reas)
1885   {
1886       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1887           $user_out = $this->user[$i];
1888           if (strcmp($user_out->sess, $sess) == 0) {
1889               return ($this->kickuser($user_out, $out_reas));
1890           }
1891       }
1892       return FALSE;
1893   }
1894
1895   function kickuser_by_idx($idx, $out_reas)
1896   {
1897       $user_out = $this->user[$idx];
1898       return ($this->kickuser($user_out, $out_reas));
1899   }
1900
1901   function chatt_send($user, $mesg)
1902   {
1903     GLOBAL $G_base, $G_alarm_passwd, $mlang_brisk, $G_lang;
1904     $only_you = FALSE;
1905
1906     fprintf(STDERR, "WE ARE HERE: [%s]\n", $mesg);
1907
1908     // common settings
1909     $msg = mb_substr($mesg, 6, 128, "UTF-8");
1910     $curtime = time();
1911     $dt = date("H:i ", $curtime);
1912     $target = "";
1913
1914     //
1915     //  Compute actions
1916     //
1917
1918     $to_user     = FALSE;
1919     $to_all      = FALSE;
1920     $to_room     = FALSE;
1921     $to_tabl     = FALSE;
1922     $is_normchat = FALSE;
1923     /* for old isolation management $is_ticker   = FALSE; */
1924     $update_room = FALSE;
1925
1926     if (strcmp($msg,  "/tav") == 0 ||
1927         strncmp($msg, "/tav ", 5) == 0) {
1928       do {
1929         if ($user->stat != 'room' || $user->subst != 'sitdown') {
1930           /* 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>" */
1931           $msg = $mlang_brisk['tickmust'][$G_lang];
1932           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1933
1934           break;
1935         }
1936
1937         $table = $this->table[$user->table];
1938
1939         if ($table->wag_own != -1) {
1940           // MLANG <br>Il messaggio di segnalazione del tavolo &egrave; gi&agrave; attivato.<br><br>
1941           $msg = $mlang_brisk['tickjust'][$G_lang];
1942           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1943
1944           break;
1945         }
1946
1947         $dtime = $curtime - $table->wag_tout;
1948         if ($dtime  < EXPIRE_TIME_WAG) {
1949           // MLANG - <br>Il messaggio di segnalazione del tavolo<br>&egrave; disattivato ancora per %d second%s.<br><br>
1950           $msg = sprintf($mlang_brisk['tickwait'][$G_lang],
1951                          EXPIRE_TIME_WAG - $dtime, (EXPIRE_TIME_WAG - $dtime == 1 ? ($G_lang == 'en' ? "" : "o") : ($G_lang == 'en' ? "s" : "i")));
1952           $to_user = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang] , 400, 100);
1953
1954           break;
1955         }
1956
1957         $msg = substr($msg, 5);
1958
1959         $table->wag_set($user->idx_get(), $msg);
1960         $to_user = sprintf('tra.add(%d, "%s");', $user->table, xcape(sprintf("%s: %s", $user->name, $msg)));
1961         $to_room = $to_user;
1962         /* for old isolation management $is_ticker = TRUE; */
1963       } while (0);
1964     } // /tav chat command
1965     // just for development use currently
1966     else if (FALSE && strncmp($msg, "/out ", 5) == 0) {
1967         fprintf(STDERR, "MOP OUT\n");
1968         $target = substr($msg, 5);
1969         $this->kickuser_by_name($target, GHOST_SESS_REAS_ANON);
1970     }
1971     else if (strncmp($msg, "/alarm ", 7) == 0) {
1972       if (strncmp($msg, "/alarm to ", 10) == 0) {
1973         $sp_pos = strpos($msg, " ", 10);
1974         $target = substr($msg, 10, $sp_pos - 10);
1975         $alarm_check = "/alarm to ".$target." ".$G_alarm_passwd." ";
1976       }
1977       else {
1978         $target = "";
1979         $alarm_check = "/alarm ".$G_alarm_passwd." ";
1980       }
1981       do {
1982         if (strncmp($msg, $alarm_check, strlen($alarm_check)) != 0) {
1983           /* MLANG: "<br>La password digitata non &egrave; corretta.<br><br>" */
1984           $msg = $mlang_brisk['alarpass'][$G_lang];
1985           $to_user = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang], 400, 100);
1986
1987           break;
1988         }
1989
1990         /* MLANG: "Alarm <b>%s</b> inviato a <b>%s</b>." */
1991         $prestr = sprintf($mlang_brisk['alarret'][$G_lang], xcape(substr($msg, strlen($alarm_check))),
1992                            ($target == "" ? $mlang_brisk['tit_all'][$G_lang] : xcape($target)) );
1993         $to_user = nickserv_msg($dt, $prestr);
1994
1995         $msg = sprintf("<br><b>%s<br><br>%s</b><br><br>",
1996                        $dt.NICKSERV, xcape(substr($msg, strlen($alarm_check))));
1997         /* MLANG: "chiudi" */
1998         $to_all = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang], 400, 120);
1999       } while (0);
2000     } // /alarm chat command
2001     else if (strncmp($msg, "/listen ", 8) == 0) {
2002       $arg = substr($msg, 8);
2003
2004       if (strcasecmp($arg, "isolation") == 0) {
2005         $flags_old = 0;
2006         if ($user->stat == 'room' && $user->subst == 'sitdown' &&
2007             $user->table >= TABLES_AUTH_N) {
2008           $to_user = nickserv_msg($dt, $mlang_brisk['listmust'][$G_lang]);
2009
2010         }
2011         else {
2012           $user->flags &= ~USER_FLAG_MAP_AUTH;
2013           $user->flags |= USER_FLAG_ISOLAUTH;
2014           $to_user = 'list_set(\'isolation\', true, \''.$mlang_brisk['tit_onisol'][$G_lang].'\'); ';
2015         }
2016       }
2017       else if (strcasecmp($arg, "auth") == 0) {
2018         $flags_old = $user->flags;
2019         $user->flags &= ~USER_FLAG_MAP_AUTH;
2020         $user->flags |= USER_FLAG_LISTAUTH;
2021         $to_user = 'list_set(\'auth\', true, \''.$mlang_brisk['tit_onauth'][$G_lang].'\'); ';
2022       }
2023       else {
2024         $flags_old = $user->flags;
2025         $user->flags &= ~USER_FLAG_MAP_AUTH;
2026         $to_user = 'list_set(\'all\', true, \'\'); ';
2027
2028       }
2029       // if from isolation redraw standup area
2030       if (($flags_old ^ $user->flags) & USER_FLAG_ISOLAUTH) {
2031         $to_user .= 'standup_data_old = null; '.$this->standup_content($user);
2032
2033       }
2034     }
2035     else if (strcmp($msg, "/authreq") == 0) {
2036         if ($user->is_cert()) {
2037             $to_user = sprintf('authbox(300,200);');
2038         }
2039         else {
2040             /* 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." */
2041             $to_user = nickserv_msg($dt, $mlang_brisk['authmust'][$G_lang]);
2042         }
2043     }
2044     else if (strncmp($msg, "/mesgtoadm", 8) == 0) {
2045         if ($user->is_auth()) {
2046         $to_user = sprintf('mesgtoadmbox(500,300);');
2047       }
2048       else {
2049         /* MLANG: "<b>Per inviare un messaggio devi essere autenticato.</b>" */
2050         $to_user = nickserv_msg($dt, $mlang_brisk['mesgmust'][$G_lang]);
2051       }
2052     }
2053     else if (FALSE && strncmp($msg, "/nick ", 6) == 0) {
2054       log_main("chatt_send BEGIN");
2055
2056       do {
2057         if (($name_new = validate_name(substr($msg, 6))) == FALSE) {
2058           $to_user = nickserv_msg($dt, $mlang_brisk['nickmust'][$G_lang]);
2059           break;
2060         }
2061
2062         $msg = "COMMAND ".$msg;
2063         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2064           $user_cur = $this->user[$i];
2065
2066           if ($user_cur->is_active() == FALSE)
2067             continue;
2068           if (strcasecmp($user_cur->name,$name_new) == 0)
2069             break;
2070           }
2071         if ($i <  MAX_PLAYERS) {
2072           $prestr = sprintf($mlang_brisk['nickdupl'][$G_lang], xcape($name_new));
2073           $to_user = nickserv_msg($dt, $prestr);
2074           break;
2075         }
2076
2077         /* 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>" */
2078         if ($user->is_auth()) {
2079           if (strcasecmp($user->name,$name_new) != 0) {
2080              if (( ($user->flags & USER_FLAG_MAP_AUTH) != USER_FLAG_ISOLAUTH) &&
2081                 ($user->subst == 'standup' ||
2082                  ($user->subst != 'standup' && $this->table[$user->table]->auth_type == TABLE_AUTH_TY_PUBL)
2083                  )
2084                 ) {
2085               $user->flags &= ~(USER_FLAG_AUTH | USER_FLAG_TY_ALL); // Remove auth if name changed
2086               for ($i = 0 ; $i < TABLES_N ; $i++) {
2087                 $to_user .= $this->table[$i]->act_content($user);
2088               }
2089             }
2090             else {
2091               $to_user = nickserv_msg($dt, $mlang_brisk['authchan'][$G_lang]);
2092               break;
2093             }
2094           }
2095         }
2096         $user->name = $name_new; // OK - nick changed
2097         /* se nome gia' in uso, segnala cosa potrebbe capitare */
2098         if ( ! $user->is_auth() ) {
2099             if (($bdb = BriskDB::create()) != FALSE) {
2100                 $bdb->users_load();
2101                 /* 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>" */
2102                 if ($bdb->login_exists(strtolower($name_new))) {
2103                     $prestr = sprintf($mlang_brisk['nickjust'][$G_lang], xcape($name_new));
2104                     $to_user .= nickserv_msg($dt, $prestr);
2105                 }
2106             }
2107         }
2108
2109         log_main("chatt_send start set");
2110
2111         $update_room = TRUE;
2112       } while (0);
2113     } // nick chat command
2114     else if (strncmp($msg, "/info ", 6) == 0) {
2115         $info_user = substr($msg, 6);
2116
2117         echo $this->info_show($user, urldecode($info_user), $dt);
2118     }
2119     else if (strncmp($msg, "/st ", 4) == 0) {
2120       log_main("chatt_send BEGIN");
2121
2122       do {
2123         $st_str = substr($msg, 4);
2124
2125         if (strcasecmp($st_str, "normale") == 0) {
2126           $st = USER_FLAG_S_NORM;
2127         }
2128         else if (strcasecmp($st_str, "pausa") == 0) {
2129           $st = USER_FLAG_S_PAU;
2130         }
2131         else if (strcasecmp($st_str, "fuori") == 0) {
2132           $st = USER_FLAG_S_OUT;
2133         }
2134         else if (strcasecmp($st_str, "cane") == 0) {
2135           $st = USER_FLAG_S_DOG;
2136         }
2137         else if (strcasecmp($st_str, "cibo") == 0) {
2138           $st = USER_FLAG_S_EAT;
2139         }
2140         else if (strcasecmp($st_str, "lavoro") == 0) {
2141           $st = USER_FLAG_S_WRK;
2142         }
2143         else if (strcasecmp($st_str, "sigaretta") == 0) {
2144           $st = USER_FLAG_S_SMK;
2145         }
2146         else if (strcasecmp($st_str, "presente") == 0) {
2147           $st = USER_FLAG_S_EYE;
2148         }
2149         else if (strcasecmp($st_str, "coniglio") == 0) {
2150           $st = USER_FLAG_S_RABB;
2151         }
2152         else if (strcasecmp($st_str, "calcio") == 0) {
2153           $st = USER_FLAG_S_SOCC;
2154         }
2155         else if (strcasecmp($st_str, "pupo") == 0) {
2156           $st = USER_FLAG_S_BABY;
2157         }
2158         else if (strcasecmp($st_str, "pulizie") == 0) {
2159           $st = USER_FLAG_S_MOP;
2160         }
2161         else if (strcasecmp($st_str, "babbo") == 0) {
2162           $st = USER_FLAG_S_BABBO;
2163         }
2164         else if (strcasecmp($st_str, "renna") == 0) {
2165           $st = USER_FLAG_S_RENNA;
2166         }
2167         else if (strcasecmp($st_str, "pupazzo") == 0) {
2168           $st = USER_FLAG_S_PUPAZ;
2169         }
2170         else if (strcasecmp($st_str, "vischio") == 0) {
2171           $st = USER_FLAG_S_VISCH;
2172         }
2173         else {
2174           /* MLANG: "Questo stato non esiste." */
2175           $to_user = nickserv_msg($dt, $mlang_brisk['statunkn'][$G_lang]);
2176           break;
2177         }
2178
2179         log_main("chatt_send start set");
2180         if (($user->flags & USER_FLAG_S_ALL) != $st) {
2181           $update_room = TRUE;
2182           $user->flags = ($user->flags & ~USER_FLAG_S_ALL) | $st;
2183         }
2184       } while (0);
2185     } // nick chat command
2186
2187     else { // normal chat line
2188       $is_normchat = TRUE;
2189       if (CHAT_ENABLED && $curtime < ($user->chat_ban + $user->chat_dlt)) {
2190         $only_you = TRUE;
2191         $user->chat_dlt = $user->chat_dlt * 2;
2192         if ($user->chat_dlt > 120)
2193           $user->chat_dlt = 120;
2194       }
2195       else if ($user->chat_lst == $msg)
2196         $only_you = TRUE;
2197       else if (CHAT_ENABLED && $curtime - $user->chattime[($user->chat_cur + 1) % CHAT_N] < CHAT_ILL_TIME) {
2198         $user->chat_ban = $curtime;
2199         $user->chat_dlt = 5;
2200         $only_you = TRUE;
2201       }
2202       else {
2203         $user->chat_ban = 0;
2204         $user->chat_dlt = 0;
2205       }
2206
2207       if ($only_you) {
2208         $to_user = sprintf('chatt_sub("%s",[%d,"%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape("== chat ban =="));
2209       }
2210       else {
2211           // TEMPORARY DISABLED UNTIL test user option will be available
2212           // if ( TRUE && (!$user->is_auth() || $user->is_appr()) ) {
2213           if (!$user->is_auth()) {
2214               $to_user = nickserv_msg($dt, xcape("Visto l'elevato numero di molestatori che ultimamente hanno preso dimora su Brisk abbiamo deciso"));
2215               $to_user .= nickserv_msg($dt, xcape("di disattivare temporaneamente la chat in room per i non registrati, non ce ne vogliate e buone feste."));
2216               if (FALSE) {
2217                   $aug_head = array("Tanti", "Tantissimi", "Un enormità", "Un milione", "Un' esagerazione");
2218                   $aug_body = array("a tutti gli utenti", "a tutti gli uomini", "a tutte le donne", "a tutti gli utenti");
2219                   $aug_tail = array("di Brisk", "del sito", "della ciurma", "della comitiva", "del gruppo");
2220
2221                   $auguri = sprintf("%s auguri %s %s.",
2222                                     $aug_head[mt_rand(0, count($aug_head)-1)],
2223                                     $aug_body[mt_rand(0, count($aug_body)-1)],
2224                                     $aug_tail[mt_rand(0, count($aug_tail)-1)]);
2225
2226                   $to_room = sprintf('chatt_sub("%s",[%d,"%s"],"%s");', $dt, $user->flags, xcape($user->name),
2227                                      xcape($auguri));
2228               }
2229           }
2230           else {
2231               $to_user = sprintf('chatt_sub("%s",[%d,"%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape($msg));
2232               // temporary silentiation for troll (will became array check)
2233               // if (strcasecmp($user->name,'JackRokka') != 0 && $user->sess != '47ea653f602e8')
2234               $to_room = $to_user;
2235           }
2236       }
2237
2238       log_legal($curtime, $user->ip, $user,
2239                 ($user->stat == 'room' ? 'room' : 'table '.$user->table),$msg);
2240
2241       $user->chat_lst = "$msg";
2242       $user->chattime[$user->chat_cur % CHAT_N] = $curtime;
2243       $user->chat_cur++;
2244     }
2245
2246     if ($to_all) {
2247       $to_room = $to_all;
2248       $to_tabl = $to_all;
2249     }
2250
2251     //
2252     //  Output to clients
2253     //
2254
2255     if ($to_user != FALSE) {
2256       $user->comm[$user->step % COMM_N] =  "gst.st = ".($user->step+1)."; ";
2257       $user->comm[$user->step % COMM_N] .= $to_user;
2258       $user->step_inc();
2259     }
2260
2261     if ($to_room != FALSE) {
2262       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2263         $user_cur = $this->user[$i];
2264         if ($target != "" && $user_cur->name != $target)
2265           continue;
2266         if ($user_cur->is_active() == FALSE // is not active user
2267             || $user_cur->stat == 'table'   // or stat is 'table'
2268             || $user->idx_get() == $i)      // or the $user idx is equal to current var
2269           continue;
2270
2271         if ($is_normchat == TRUE) {
2272           // use MAP_AUTH to check if auth or isolation
2273           if ($user_cur->flags & USER_FLAG_MAP_AUTH) {
2274               if ( ! $user->is_auth() ) {
2275                   continue;
2276               }
2277           }
2278         }
2279         /*
2280         else if ($is_ticker) {
2281           if (($user_cur->flags & USER_FLAG_MAP_AUTH) == USER_FLAG_ISOLAUTH) {
2282             if ($user->table >= TABLES_AUTH_N)
2283               continue;
2284           }
2285         }
2286         */
2287         $user_cur->comm[$user_cur->step % COMM_N] =  "gst.st = ".($user_cur->step+1)."; ";
2288         $user_cur->comm[$user_cur->step % COMM_N] .= $to_room;
2289         $user_cur->step_inc();
2290       }
2291     }
2292
2293     if ($to_tabl) {
2294         // FIXME BRISK4: include for each kind of table
2295         require_once("${G_base}briskin5/Obj/briskin5.phh");
2296         // Before all align times with table timeout
2297         for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
2298             if (isset($this->match[$table_idx])) {
2299                 $bin5 = $this->match[$table_idx];
2300
2301                 $bin5_table = $bin5->table[0];
2302                 for ($i = 0 ; $i < $bin5_table->player_n ; $i++) {
2303                     // stat must be "table" by definition
2304                     $bin5_user = $bin5->user[$i];
2305
2306                     if ($target != "" && $bin5_user->name != $target)
2307                         continue;
2308                     log_main("writa: ".$user_mesg);
2309                     $bin5_user->comm[$bin5_user->step % COMM_N] = "gst.st = ".($bin5_user->step+1)."; ";
2310                     $bin5_user->comm[$bin5_user->step % COMM_N] .= $to_tabl;
2311                     $bin5_user->step_inc();
2312                 }
2313             } // if (isset($this->match
2314         } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
2315     } // if ($to_tabl == true ...
2316
2317     if ($update_room) {
2318       if ($user->stat == 'room' && $user->subst == 'standup') {
2319         $this->standup_update($user);
2320       }
2321       else if ($user->stat == 'room' && $user->subst == 'sitdown') {
2322         log_main("chatt_send pre table update");
2323         $this->table_update($user);
2324         log_main("chatt_send post table update");
2325       }
2326     } // if ($update_room ...
2327
2328     return;
2329   } // function chatt_send( ...
2330
2331   function get_user($sess, &$idx)
2332   {
2333       GLOBAL $PHP_SELF;
2334
2335       if (validate_sess($sess)) {
2336           for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2337               if ($this->user[$i]->is_empty())
2338                   continue;
2339               if (strcmp($sess, $this->user[$i]->sess) == 0) {
2340                   // find it
2341                   $idx = $i;
2342                   $ret = $this->user[$i];
2343                   return ($ret);
2344               }
2345           }
2346           log_main(sprintf("get_user: Wrong sess from page [%s]",$PHP_SELF));
2347           // for ($i = 0 ; $i < MAX_PLAYERS ; $i++)
2348           // log_main(sprintf("get_user: Wrong sess compared with [%s]",$this->user[$i]->sess));
2349       }
2350       else {
2351           log_main(sprintf("get_user: Wrong strlen [%s]",$sess));
2352       }
2353
2354       return (FALSE);
2355   }
2356
2357   /*
2358    * function add_user(&$brisk, &$sess, &$idx, $name, $pass, $ip, $header, $cookie)
2359    *
2360    * RETURN VALUE:
2361    *   if ($idx >  -1    && ret == FALSE)  =>  duplicated nick
2362    *   if ($idx == -2    && ret == FALSE)  =>  invalid name
2363    *   if ($idx == -3    && ret == FALSE)  =>  wrong password
2364    *   if ($idx == -1    && ret == FALSE)  =>  no space left
2365    *   if ($idx ==  0    && ret == user)   =>  SUCCESS
2366    *   if ($idx == -($idx + 1) && ret == user)   =>  SUCCESS (but the login exists in the auth db)
2367    */
2368
2369   function add_user(&$sess, &$idx, $name, $pass, $ip, $header, $cookie)
2370   {
2371     GLOBAL $G_base;
2372
2373     $idx = 0;
2374
2375     $authenticate = FALSE;
2376     $user_type    = 0;
2377     $login_exists = FALSE;
2378     $ghost = -1;
2379     $ghost_auth = FALSE;
2380     $idx = -1;
2381     $idfree = -1;
2382     $code = FALSE;
2383
2384     if (($name_new = validate_name($name)) == FALSE) {
2385       $idx = -2;
2386       return (FALSE);
2387     }
2388
2389     log_auth("XXX", sprintf("ARRIVA: [%s] pass:[%s]", $sess, ($pass == FALSE ? "FALSE" : $pass)));
2390     if (validate_sess($sess) == FALSE)
2391       $sess = "";
2392
2393     /* if pass != FALSE verify the login with pass */
2394     log_auth("XXX", "auth1");
2395
2396     if (($bdb = BriskDB::create()) != FALSE) {
2397         $bdb->users_load();
2398         if ($pass != FALSE) { // TODO: here add a method to $bdb to check if the db is available.
2399             log_auth("XXX", "auth2");
2400             $authenticate = $bdb->login_verify(strtolower($name_new), $pass, $code);
2401             log_auth("XXX", "authenticate: ".($authenticate != FALSE ? "TRUE" : "FALSE"));
2402
2403             if ($authenticate != FALSE) {
2404                 $user_type = $authenticate->type_get();
2405             }
2406             else {
2407                 $idx = -3;
2408                 return (FALSE);
2409             }
2410         }
2411         else {
2412             $login_exists =  $bdb->login_exists(strtolower($name_new));
2413         }
2414     }
2415     else {
2416         // if db is down, send a warning and verify only current users
2417         // no actions at this moment
2418     }
2419     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2420         /* free user ? */
2421         if ($this->user[$i]->is_empty()) {
2422             if ($idfree == -1) {
2423                 $idfree = $i;
2424             }
2425             continue;
2426         }
2427         if (strcmp($sess, $this->user[$i]->sess) == 0) {
2428             if ($idx == -1) {
2429                 $idx = $i;
2430             }
2431         }
2432         if (strcasecmp($this->user[$i]->name, $name_new) == 0) {
2433             if ($authenticate != FALSE) {
2434                 $ghost = $i;
2435                 $ghost_auth = $this->user[$i]->is_auth();
2436             }
2437             else {
2438                 $idx = $i;
2439                 break;
2440             }
2441         }
2442     }
2443     if ($idx == -1)
2444       $idx = $idfree;
2445
2446     log_auth("XXX", sprintf("TROVATO A QUESTO PUNTO [%d] sess [%s] name [%s]", $idx, $sess, $name_new));
2447
2448     /* there is another user logged with your account and you and him have authenticated => new user
2449        get the session of the old user */
2450     if ($ghost > -1 && $ghost_auth && ($authenticate != FALSE)) {
2451       /* swap session */
2452
2453       $ghost_user = $this->user[$ghost];
2454       $curtime = time();
2455       $this->ghost_sess->push($curtime, $ghost_user->sess, GHOST_SESS_REAS_ANOT);
2456       $ghost_user->comm[$ghost_user->step % COMM_N] = "";
2457       $ghost_user->step_inc();
2458       if ($sess == "") {
2459         $sess = uniqid("");
2460         $ghost_user->sess = $sess;
2461       }
2462       else {
2463         $ghost_user->sess = $sess;
2464       }
2465
2466       // If user at the table we need to update the table data too
2467       $table_idx = $ghost_user->table;
2468       if ($ghost_user->stat == "table" && $this->table[$table_idx]->player_n == PLAYERS_N) {
2469           require_once("${G_base}briskin5/Obj/briskin5.phh");
2470           if (isset($this->match[$table_idx])) {
2471               $bin5 = $this->match[$table_idx];
2472
2473               if ($bin5->the_end != TRUE) {
2474                   $bin5->user[$ghost_user->table_pos]->comm[$bin5->user[$ghost_user->table_pos]->step % COMM_N] = "";
2475                   $bin5->user[$ghost_user->table_pos]->step_inc();
2476                   $bin5->user[$ghost_user->table_pos]->sess = $sess;
2477               }
2478           }
2479       }
2480
2481       $idx = $ghost;
2482       if (defined('CURL_DE_SAC_VERS')) {
2483           brisk_cds_execute($this, $ghost, $idx, $sess, $ip, $authenticate, $header);
2484       }
2485       return ($this->user[$ghost]);
2486     }
2487     else if ($idx != -1 && $i == MAX_PLAYERS) {
2488       /* SUCCESS */
2489       $curtime = time();
2490       if ($sess == "") {
2491         $sess = uniqid("");
2492         $this->user[$idx]->sess = $sess;
2493       }
2494       else {
2495         $this->user[$idx]->sess = $sess;
2496       }
2497       $this->user[$idx]->name = $name_new; // OK - add new user
2498       $this->user[$idx]->stat_set("room");
2499       $this->user[$idx]->step_set(0);
2500       while (array_pop($this->user[$idx]->comm) != NULL);
2501       $this->user[$idx]->subst = "standup";
2502       $this->user[$idx]->lacc =   $curtime;
2503       $this->user[$idx]->laccwr = $curtime;
2504       $this->user[$idx]->bantime = 0;
2505       $this->user[$idx]->ip = $ip;
2506
2507       $this->user[$idx]->rec = $authenticate;
2508       $this->user[$idx]->flags = $user_type;
2509       $this->user[$idx]->flags |= ($authenticate != FALSE ? USER_FLAG_AUTH : 0x00);
2510       $this->user[$idx]->flags |= ( ($pass != FALSE && $bdb == FALSE) ? USER_FLAG_DBFAILED : 0x00);
2511       log_auth("XXX", sprintf("FLAGS: [%x]", $this->user[$idx]->flags));
2512
2513       if ($authenticate != FALSE) {
2514           $this->user[$idx]->code = $authenticate->code_get();
2515           if (0 == 1) {
2516               // all this part is included in the db server
2517               $this->user[$idx]->flags |= USER_FLAG_LISTAUTH;
2518
2519               if (isset($cookie['CO_list'])) {
2520                   fprintf(STDERR, "QQ: %s CO_list: [%s]\n", __FUNCTION__, $cookie['CO_list']);
2521                   if (strcmp($cookie['CO_list'], "auth") == 0) {
2522                       $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
2523                       $this->user[$idx]->flags |= USER_FLAG_LISTAUTH;
2524                   }
2525                   if (strcmp($cookie['CO_list'], "isolation") == 0) {
2526                       $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
2527                       $this->user[$idx]->flags |= USER_FLAG_ISOLAUTH;
2528                   }
2529                   else {
2530                       $this->user[$idx]->flags &= ~USER_FLAG_MAP_AUTH;
2531                   }
2532               }
2533           }
2534           else {
2535               fprintf(STDERR, "QQ: CO_list not set flags: %x\n", __FUNCTION__, $this->user[$idx]->flags);
2536           }
2537       }
2538       fprintf(STDERR, "QQ %s: flag %x\n", __FUNCTION__, $this->user[$idx]->flags);
2539       if ($ghost > -1) {
2540         log_main("ghost: rename!");
2541         $ghost_user = $this->user[$ghost];
2542
2543         if ($ghost_auth == FALSE) {
2544           for ($sfx = 1 ; $sfx <= MAX_PLAYERS ; $sfx++) {
2545             $ghostname = 'ghost'.$sfx;
2546             for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2547               if (strcmp("", $this->user[$i]->sess) == 0)
2548                 continue;
2549
2550               if (strcasecmp($this->user[$i]->name, $ghostname) == 0) {
2551                 $ghostname = '';
2552                 break;
2553               }
2554             }
2555             if ($ghostname != '')
2556               break;
2557           }
2558
2559           $ghost_user->name = $ghostname;
2560
2561           if ($ghost_user->stat == 'room' && $ghost_user->subst == 'standup') {
2562             $this->standup_update($ghost_user);
2563           }
2564           else {
2565             log_main("chatt_send pre table update");
2566             $this->table_update($ghost_user);
2567           log_main("chatt_send post table update");
2568           }
2569         } // if ($ghost_auth == FALSE
2570         else {
2571           // FIXME: cacciare il vecchio utente room && table (if needed)
2572           $ghost_user->the_end = TRUE;
2573           $ghost_user->lacc = 0;
2574           $this->garbage_manager(TRUE);
2575         }
2576       } //  if ($ghost > -1) {
2577
2578       $real_idx = $idx;
2579       if ($login_exists)
2580         $idx = -($idx + 1);
2581       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));
2582
2583       $ret = $this->user[$real_idx];
2584       if (defined('CURL_DE_SAC_VERS')) {
2585           brisk_cds_execute($this, $ghost, $real_idx, $sess, $ip, $authenticate, $header);
2586       }
2587       return ($ret);
2588     }
2589
2590     return (FALSE);
2591   }
2592
2593   function standup_update($user)
2594   {
2595     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2596       $user_cur = $this->user[$i];
2597       if ($user_cur->is_active() == FALSE)
2598         continue;
2599
2600       log_main("STANDUP START: ".$user_cur->stat);
2601
2602       if ($user_cur->stat == 'room') {
2603         $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ".$this->standup_content($user_cur);
2604         if ($user->idx_get() == $i) {
2605           $user_cur->comm[$user_cur->step % COMM_N] .= $user->myname_innerHTML();
2606         }
2607         log_main("FROM STANDUP: NAME: ".$user_cur->name." SENDED: ".$user_cur->comm[$user_cur->step % COMM_N]);
2608
2609         $user_cur->step_inc();
2610       }
2611     }
2612   }
2613
2614   function dump_data()
2615   {
2616       $brisk_ser = serialize($this);
2617       $brisk_ser_len = mb_strlen($brisk_ser, "ASCII");
2618       if (file_put_contents($this->crystal_filename, $brisk_ser) == $brisk_ser_len) {
2619           return (TRUE);
2620       }
2621
2622       return (FALSE);
2623   }
2624
2625   function standup_content($user)
2626   {
2627     $ret = "";
2628
2629     if ($user->stat != 'room')
2630       return;
2631
2632     $content = ' j_stand_cont( [ ';
2633
2634     $user_cur_id = $user->idx_get();
2635     for ($i = 0 , $ct = 0 ; $i < MAX_PLAYERS ; $i++) {
2636         if ($this->user[$i]->is_active() == FALSE // is not active user
2637             || $this->user[$i]->stat != "room"    // or the stat isn't 'room'
2638             || $this->user[$i]->name == "")       // or the name is empty, happens when user is reset (TODO: check it)
2639         continue;
2640
2641       $flags = $this->user[$i]->flags;
2642
2643       // sql record exists AND last donate > 2013-01-01
2644       if ($this->user[$i]->is_supp_custom()) {
2645           $supp_comp_s = sprintf(', "%s"', $this->user[$i]->rec->supp_comp_get());
2646       }
2647       else {
2648           $supp_comp_s = '';
2649       }
2650
2651       if ($this->user[$i]->subst == "standup") {
2652           if ($user_cur_id == $i) {
2653               $flags |= 1;
2654           }
2655
2656           $content .= sprintf('%s[ %d, "%s"%s ]',($ct > 0 ? ', ' : ''), $flags,
2657                               xcape($this->user[$i]->name), $supp_comp_s);
2658           $ct++;
2659       }
2660     }
2661     $content .= ' ]);';
2662
2663     return ($content);
2664   }
2665
2666   function table_content($user, $table_idx)
2667   {
2668     $content = "";
2669     $ret = "";
2670     // TODO
2671     //
2672     //   Si possono usare i dati nella classe table
2673     //
2674
2675     $sess = $user->sess;
2676     $table = $this->table[$table_idx];
2677
2678     if ($user->stat != 'room')
2679       return;
2680
2681     $user_cur_id = $user->idx_get();
2682     $content = "[ ";
2683     for ($i = 0 ; $i < $table->player_n ; $i++) {
2684         $user_cur = $this->user[$table->player[$i]];
2685
2686         $flags = $user_cur->flags;
2687
2688         if ($user_cur_id == $table->player[$i])
2689             $flags |= 1;
2690
2691         log_main($user_cur->name. sprintf(" IN TABLE [%d]", $table_idx));
2692         if ($user_cur->is_supp_custom())
2693             $supp_comp_s = sprintf(', "%s"', $user_cur->rec->supp_comp_get());
2694         else
2695             $supp_comp_s = '';
2696
2697         $content .= sprintf('%s[ %d, "%s"%s ]',($i == 0 ? '' : ', '), $flags,
2698                             xcape($user_cur->name), $supp_comp_s);
2699     }
2700
2701     $content .= ' ]';
2702
2703     $ret .= sprintf('j_tab_cont(%d, %s);', $table_idx, $content);
2704
2705     return ($ret);
2706   }
2707
2708   function request_mgr(&$s_a_p, $header, &$header_out, &$new_socket, $path, $addr, $get, $post, $cookie)
2709   {
2710       GLOBAL $G_ban_list, $G_black_list, $G_cloud_smasher;
2711
2712       printf("NEW_SOCKET (root): %d PATH [%s]\n", intval($new_socket), $path);
2713
2714       fprintf(STDERR, "\n\n\n PRE_BLACK [%s]\n\n\n", $addr);
2715       if ($this->black_check($addr)) {
2716           // TODO: waiting async 5 sec before close
2717           fprintf(STDERR, "\n\n\n BLACK CHECK\n\n\n");
2718           return (FALSE);
2719       }
2720       if ($path != "" && $path != "index.php") {
2721           if ($this->cloud_check($addr)) {
2722               // TODO: waiting async 5 sec before close
2723               return (FALSE);
2724           }
2725       }
2726
2727       $enc = get_encoding($header);
2728       if (isset($header['User-Agent'])) {
2729           if (strstr($header['User-Agent'], "MSIE")) {
2730               $transp_type = "htmlfile";
2731           }
2732           else {
2733               $transp_type = "xhr";
2734           }
2735       }
2736       else {
2737           $transp_type = "iframe";
2738       }
2739       force_no_cache($header_out);
2740
2741       switch ($path) {
2742       case "":
2743       case "index.php":
2744           ob_start();
2745           index_main($this, $transp_type, $header, $header_out, $addr, $get, $post, $cookie);
2746           $content = ob_get_contents();
2747           ob_end_clean();
2748
2749           // fprintf(STDERR, "\n\nCONTENT [%s]\n\n", $content);
2750           $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
2751           return TRUE;
2752
2753           break;
2754       case "index_wr.php":
2755           //
2756           // Enhance required: in the POST case, after the header you must get content
2757           //                   from the socket, waiting if necessary
2758           //
2759
2760           ob_start();
2761           index_wr_main($this, $addr, $get, $post, $cookie);
2762           $content = ob_get_contents();
2763           ob_end_clean();
2764
2765           $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
2766           return TRUE;
2767
2768           break;
2769       case "index_rd.php":
2770           if (($transp  = gpcs_var('transp', $get, $post, $cookie)) === FALSE)
2771               $transp = "iframe";
2772           if ($transp == 'websocket')
2773               $enc = 'plain';
2774
2775           do {
2776               if (!isset($cookie['sess'])
2777                   || (($user = $this->get_user($cookie['sess'], $idx)) == FALSE)) {
2778
2779                   $content = User::stream_fini($transp, $s_a_p->rndstr, TRUE);
2780
2781                   $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
2782                   return TRUE;
2783
2784                   break;
2785               }
2786               $this->sess_cur_set($user->sess);
2787               // close a previous opened index_read_ifra socket, if exists
2788               if (($prev = $user->rd_socket_get()) != NULL) {
2789                   $s_a_p->socks_unset($user->rd_socket_get());
2790                   fclose($user->rd_socket_get());
2791                   printf("CLOSE AND OPEN AGAIN ON IFRA2\n");
2792                   $user->rd_socket_set(NULL);
2793               }
2794
2795               $content = "";
2796               $user->stream_init($s_a_p->rndstr, $enc, $header, $header_out, $content, $get, $post, $cookie);
2797               $response = headers_render($header_out, -1).$user->chunked_content($content);
2798               $response_l = mb_strlen($response, "ASCII");
2799
2800               $wret = @fwrite($new_socket, $response, $response_l);
2801               if ($wret < $response_l) {
2802                   printf("TROUBLES WITH FWRITE: %d\n", $wret);
2803                   $user->rd_cache_set(mb_substr($content, $wret, $response_l - $wret, "ASCII"));
2804               }
2805               else {
2806                   $user->rd_cache_set("");
2807               }
2808               fflush($new_socket);
2809
2810
2811               $s_a_p->socks_set($new_socket, $user, NULL);
2812               $user->rd_socket_set($new_socket);
2813               printf(" - qui ci siamo - ");
2814               return TRUE;
2815           } while (FALSE);
2816
2817           return FALSE;
2818           break;
2819       case 'test.php':
2820           if (!(BRISK_DEBUG & DBG_ENGI))
2821               return (FALSE);
2822           fprintf(STDERR, "TEST.PHP running\n");
2823           if (isset($post['data'])) {
2824               $content = $post['data'];
2825           }
2826           else {
2827               $content = "NO DATA AVAILABLE";
2828           }
2829           $header_out['Content-Type'] = 'text/plain';
2830           $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
2831           return TRUE;
2832           break;
2833       default:
2834           /* FAR TODO: move all into an array of registered sub-apps */
2835           $subs = "briskin5/";
2836           $subs_l = strlen($subs);
2837           if (!strncmp($path, $subs, $subs_l)) {
2838               $ret = Bin5::request_mgr(&$s_a_p, $header, &$header_out, &$new_socket, substr($path, $subs_l) , $addr, $get, $post, $cookie);
2839               return ($ret);
2840           }
2841           break;
2842       }
2843
2844       return (FALSE);
2845   }
2846
2847   function match_add($idx, $match)
2848   {
2849       $this->match[$idx] = $match;
2850   }
2851
2852   function match_del($idx)
2853   {
2854       unset($this->match[$idx]);
2855   }
2856
2857   function match_get($idx, $token)
2858   {
2859       if (isset($this->match[$idx])) {
2860           if (   $token == NULL
2861               || $token == $this->match[$idx]->table_token) {
2862               return ($this->match[$idx]);
2863           }
2864       }
2865       return NULL;
2866   }
2867   function sess_cur_set($sess)
2868   {
2869       static::$sess_cur = $sess;
2870   }
2871
2872   static function sess_cur_get()
2873   {
2874       return(static::$sess_cur);
2875   }
2876 } // end class Brisk
2877
2878 function make_seed()
2879 {
2880   list($usec, $sec) = explode(' ', microtime());
2881   return (float) $sec + ((float) $usec * 100000);
2882 }
2883
2884 function btrace_line($ar)
2885 {
2886     GLOBAL $G_btrace_pref_sub;
2887
2888     $ret = "";
2889     for ($i = 0 ; $i < count($ar) ; $i++) {
2890         $with_class = isset($ar[$i]['class']);
2891         $with_file  = isset($ar[$i]['file']);
2892         $ret .= sprintf("%s%s%s (%s:%d)", ($i == 0 ? "" : ", "),
2893                         ($with_class ?  $ar[$i]['class'].$ar[$i]['type'] : ""),
2894                         $ar[$i]['function'], ($with_file ? str_replace($G_btrace_pref_sub, "", $ar[$i]['file']) : ""),
2895                         ($with_file ? $ar[$i]['line'] : ""));
2896     }
2897
2898     return ($ret);
2899 }
2900
2901 function trace_ftok($id, $add)
2902 {
2903     // NOTE: without space to use sed to substitute "= @ftok("  with "= @ftok("
2904     $tok=@ftok($id, $add);
2905
2906     log_shme($tok.": ".$id." + ".$add);
2907
2908     return ($tok);
2909 }
2910
2911 function log_mop($step, $log)
2912 {
2913     GLOBAL $PHP_SELF;
2914
2915     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LMOP) == 0)
2916         return;
2917
2918     $sess = Brisk::sess_cur_get();
2919     if (isset($sess) == FALSE)
2920         $ssess = "XXXX";
2921     else
2922         $ssess = $sess;
2923
2924     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LMOP) == 0)
2925         return;
2926
2927     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2928         $btrace = btrace_line(debug_backtrace());
2929     else
2930         $btrace = "";
2931     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2932         fwrite($fp, sprintf("LMOP: [%f] [%05d] [%s] [%s]\n", gettimeofday(TRUE), $step, $log, $btrace));
2933         fclose($fp);
2934     }
2935 }
2936
2937 function log_step($log)
2938 {
2939     GLOBAL $PHP_SELF;
2940
2941     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_STEP) == 0)
2942         return;
2943
2944     $sess = Brisk::sess_cur_get();
2945     if (isset($sess) == FALSE)
2946         $ssess = "XXXX";
2947     else
2948         $ssess = $sess;
2949
2950     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_STEP) == 0)
2951         return;
2952
2953     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2954         $btrace = btrace_line(debug_backtrace());
2955     else
2956         $btrace = "";
2957     if (($fp = @fopen(LEGAL_PATH."/step.log", 'a')) != FALSE) {
2958         fwrite($fp, sprintf("STEP: [%f] [%s] [%s]\n", gettimeofday(TRUE), $log, $btrace));
2959         fclose($fp);
2960     }
2961 }
2962
2963
2964
2965 function log_cds($log)
2966 {
2967     GLOBAL $PHP_SELF;
2968
2969     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_CDS) == 0)
2970         return;
2971
2972     $sess = Brisk::sess_cur_get();
2973     if (isset($sess) == FALSE)
2974         $ssess = "XXXX";
2975     else
2976         $ssess = $sess;
2977
2978     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_CDS) == 0)
2979         return;
2980
2981     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
2982         $btrace = btrace_line(debug_backtrace());
2983     else
2984         $btrace = "";
2985     if (($fp = @fopen(LEGAL_PATH."/cds.log", 'a')) != FALSE) {
2986         fwrite($fp, sprintf("CDS: [%f] [%s] [%s]\n", gettimeofday(TRUE), $log, $btrace));
2987         fclose($fp);
2988     }
2989 }
2990
2991
2992 function log_only2($log)
2993 {
2994     GLOBAL $PHP_SELF;
2995
2996     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_ONL2) == 0)
2997         return;
2998
2999     $sess = Brisk::sess_cur_get();
3000     if (isset($sess) == FALSE)
3001         $ssess = "XXXX";
3002     else
3003         $ssess = $sess;
3004
3005     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_ONL2) == 0)
3006         return;
3007
3008     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3009         $btrace = btrace_line(debug_backtrace());
3010     else
3011         $btrace = "";
3012     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3013         fwrite($fp, sprintf("ONL2: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3014         fclose($fp);
3015     }
3016 }
3017
3018 function log_crit($log)
3019 {
3020     GLOBAL $PHP_SELF;
3021
3022     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_CRIT) == 0)
3023         return;
3024
3025     $sess = Brisk::sess_cur_get();
3026     if (isset($sess) == FALSE)
3027         $ssess = "XXXX";
3028     else
3029         $ssess = $sess;
3030
3031     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_CRIT) == 0)
3032         return;
3033
3034     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3035         $btrace = btrace_line(debug_backtrace());
3036     else
3037         $btrace = "";
3038     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3039         fwrite($fp, sprintf("CRIT: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3040         fclose($fp);
3041     }
3042 }
3043
3044 function log_only($log)
3045 {
3046     GLOBAL $PHP_SELF;
3047
3048     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_ONLY) == 0)
3049         return;
3050
3051     $sess = Brisk::sess_cur_get();
3052     if (isset($sess) == FALSE)
3053         $ssess = "XXXX";
3054     else
3055         $ssess = $sess;
3056
3057     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_ONLY) == 0)
3058         return;
3059
3060     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3061         $btrace = btrace_line(debug_backtrace());
3062     else
3063         $btrace = "";
3064     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3065         fwrite($fp, sprintf("ONLY: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3066         fclose($fp);
3067     }
3068 }
3069
3070 function log_main($log)
3071 {
3072     GLOBAL $PHP_SELF;
3073
3074     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_MAIN) == 0)
3075         return;
3076
3077     $sess = Brisk::sess_cur_get();
3078     if (isset($sess) == FALSE)
3079         $ssess = "XXXX";
3080     else
3081         $ssess = $sess;
3082
3083     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_MAIN) == 0)
3084         return;
3085
3086     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3087         $btrace = btrace_line(debug_backtrace());
3088     else
3089         $btrace = "";
3090     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3091         fwrite($fp, sprintf("MAIN: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3092         fclose($fp);
3093     }
3094 }
3095
3096 function log_rd($log)
3097 {
3098     GLOBAL $PHP_SELF;
3099
3100     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_READ) == 0)
3101         return;
3102
3103     $sess = Brisk::sess_cur_get();
3104     if (isset($sess) == FALSE)
3105         $ssess = "XXXX";
3106     else
3107         $ssess = $sess;
3108
3109     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_READ) == 0)
3110         return;
3111
3112     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3113         $btrace = btrace_line(debug_backtrace());
3114     else
3115         $btrace = "";
3116     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3117         fwrite($fp, sprintf("READ: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3118         fclose($fp);
3119     }
3120 }
3121
3122 function log_rd2($log)
3123 {
3124     GLOBAL $PHP_SELF;
3125
3126     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_REA2) == 0)
3127         return;
3128
3129     $sess = Brisk::sess_cur_get();
3130     if (isset($sess) == FALSE)
3131         $ssess = "XXXX";
3132     else
3133         $ssess = $sess;
3134
3135     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_REA2) == 0)
3136         return;
3137
3138     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3139         $btrace = btrace_line(debug_backtrace());
3140     else
3141         $btrace = "";
3142
3143     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3144         fwrite($fp, sprintf("REA2: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3145         fclose($fp);
3146     }
3147 }
3148
3149 function log_send($log)
3150 {
3151     GLOBAL $PHP_SELF;
3152
3153     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_SEND) == 0)
3154         return;
3155
3156     $sess = Brisk::sess_cur_get();
3157     if (isset($sess) == FALSE)
3158         $ssess = "XXXX";
3159     else
3160         $ssess = $sess;
3161
3162     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_SEND) == 0)
3163         return;
3164
3165     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3166         $btrace = btrace_line(debug_backtrace());
3167     else
3168         $btrace = "";
3169     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3170         fwrite($fp, sprintf("SEND: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3171         fclose($fp);
3172     }
3173 }
3174
3175 function log_lock($log)
3176 {
3177     GLOBAL $PHP_SELF;
3178
3179     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LOCK) == 0)
3180         return;
3181
3182     $sess = Brisk::sess_cur_get();
3183     if (isset($sess) == FALSE)
3184         $ssess = "XXXX";
3185     else
3186         $ssess = $sess;
3187
3188     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LOCK) == 0)
3189         return;
3190
3191     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3192         $btrace = btrace_line(debug_backtrace());
3193     else
3194         $btrace = "";
3195     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3196         fwrite($fp, sprintf("LOCK: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3197         fclose($fp);
3198     }
3199 }
3200
3201 function log_wr($log)
3202 {
3203     GLOBAL $PHP_SELF;
3204
3205     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_WRIT) == 0)
3206         return;
3207
3208     $sess = Brisk::sess_cur_get();
3209     if (isset($sess) == FALSE)
3210         $ssess = "XXXX";
3211     else
3212         $ssess = $sess;
3213
3214     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_WRIT) == 0)
3215         return;
3216
3217     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3218         $btrace = btrace_line(debug_backtrace());
3219     else
3220         $btrace = "";
3221     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3222         fwrite($fp, sprintf("WRIT: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3223         fclose($fp);
3224     }
3225 }
3226
3227 function log_load($log)
3228 {
3229     GLOBAL $PHP_SELF;
3230
3231     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LOAD) == 0)
3232         return;
3233
3234     $sess = Brisk::sess_cur_get();
3235     if (isset($sess) == FALSE)
3236         $ssess = "XXXX";
3237     else
3238         $ssess = $sess;
3239
3240     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LOAD) == 0)
3241         return;
3242
3243     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3244         $btrace = btrace_line(debug_backtrace());
3245     else
3246         $btrace = "";
3247     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3248         fwrite($fp, sprintf("LOAD: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3249         fclose($fp);
3250     }
3251 }
3252
3253 function log_auth($sess, $log)
3254 {
3255     GLOBAL $PHP_SELF;
3256
3257     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_AUTH) == 0)
3258         return;
3259
3260     if (( (BRISK_DEBUG | ($sess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_AUTH) == 0)
3261         return;
3262
3263     if ((BRISK_DEBUG | ($sess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3264         $btrace = btrace_line(debug_backtrace());
3265     else
3266         $btrace = "";
3267     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3268         fwrite($fp, sprintf("LOAD: [%s] [%d] [%s] [%s]\n", $sess, time(), $log, $btrace));
3269         fclose($fp);
3270     }
3271 }
3272
3273 function log_shme($log)
3274 {
3275     GLOBAL $PHP_SELF;
3276
3277     if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_SHME) == 0)
3278         return;
3279
3280     $sess = Brisk::sess_cur_get();
3281     if (isset($sess) == FALSE)
3282         $ssess = "XXXX";
3283     else
3284         $ssess = $sess;
3285
3286     if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_SHME) == 0)
3287         return;
3288
3289     if ((BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_TRAC)
3290         $btrace = btrace_line(debug_backtrace());
3291     else
3292         $btrace = "";
3293     if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
3294         fwrite($fp, sprintf("SHME: [%s] [%s] [%s]\n", $ssess, $log, $btrace));
3295         fclose($fp);
3296     }
3297 }
3298
3299
3300
3301 // function log_legal($curtime, $sess, $name, $where, $mesg)
3302 function log_legal($curtime, $addr, $user, $where, $mesg)
3303 {
3304
3305   if (($fp = @fopen(LEGAL_PATH."/legal.log", 'a')) != FALSE) {
3306     /* Unix time | session | nickname | IP | where was | mesg */
3307     fwrite($fp, sprintf("%ld|%s|%s|%s|%s|%s|%s|\n", $curtime, $user->sess,
3308                         ($user->is_auth() ? 'A' : 'N'),
3309                         $user->name, $addr, $where , $mesg));
3310     fclose($fp);
3311   }
3312 }
3313
3314 function table_act_content($isstanding, $sitted, $table, $cur_table, $allowed)
3315 {
3316   $ret = "";
3317
3318   if ($isstanding) {
3319     if ($sitted < PLAYERS_N) {
3320       if ($allowed)
3321         $act = 'sit';
3322       else
3323         $act = 'reserved';
3324     }
3325   }
3326   else {
3327     if ($table == $cur_table)
3328       $act = 'wake';
3329     else
3330       $act = 'none';
3331   }
3332
3333   if ($act != '')
3334     $ret = sprintf('j_tab_act_cont(%d, \'%s\');', $table, $act);
3335
3336   return ($ret);
3337 }
3338
3339 function show_notify($text, $tout, $butt, $w, $h)
3340 {
3341   log_main("SHOW_NOTIFY: ".$text);
3342   return sprintf('var noti = new notify(gst,"%s",%d,"%s",%d,%d);', $text, $tout, $butt, $w, $h);
3343 }
3344
3345 function show_notify_ex($text, $tout, $butt, $w, $h, $is_opaque, $block_time)
3346 {
3347   log_main("SHOW_NOTIFY OPAQUE: ".$text);
3348   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);
3349 }
3350
3351 function show_notify_document($text, $tout, $butt_arr, $confirm_func, $confirm_func_args, $w, $h, $is_opaque, $block_time)
3352 {
3353   log_main("SHOW_NOTIFY OPAQUE: ".$text);
3354
3355   $butts = "";
3356   for ($i = 0 ; $i < count($butt_arr) ; $i++) {
3357       $butts .= sprintf("%s'%s'", ($i == 0 ? "" : ","), $butt_arr[$i]);
3358   }
3359
3360   return sprintf('g_nd = new notify_document(gst, "%s", %d, [ %s ], %s, %s, %d, %d, %s, %d);|',
3361                  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);
3362 }
3363
3364
3365 function root_welcome($user)
3366 {
3367   GLOBAL $root_wellarr, $G_lang;
3368   $ret = "";
3369
3370   $curtime = time();
3371   $dt = date("H:i ", $curtime);
3372
3373   for ($i = 0 ; $i < count($root_wellarr[$G_lang]) ; $i++)
3374       $ret .= nickserv_msg($dt, str_replace('"', '\"', $root_wellarr[$G_lang][$i]));
3375
3376   return ($ret);
3377 }
3378
3379
3380
3381 function validate_sess($sess)
3382 {
3383   if (strlen($sess) == SESS_LEN)
3384     return (TRUE);
3385   else
3386     return (FALSE);
3387 }
3388
3389 function validate_name($name)
3390 {
3391     $name_new = str_replace(' ', '_', mb_substr(trim($name),0,12, "UTF-8"));
3392
3393   for ($i = 0 ; $i < mb_strlen($name_new) ; $i++) {
3394     $c = $name_new[$i];
3395     if (($c >= "a" && $c <= "z") || ($c >= "A" && $c <= "Z") || ($c >= "0" && $c <= "9"))
3396       return ($name_new);
3397   }
3398
3399   return (FALSE);
3400 }
3401
3402 function playsound($filename)
3403 {
3404   return (sprintf('playsound("flasou", "%s");', $filename));
3405 }
3406
3407 function secstoword($secs)
3408 {
3409   GLOBAL $G_lang;
3410
3411   $ret = "";
3412
3413   $mins = floor($secs / 60);
3414   $secs = $secs % 60;
3415   if ($G_lang == 'en') {
3416     if ($mins > 0)
3417       $ret = sprintf("%d minute%s%s", $mins, ($mins > 1 ? "s" : ""), ($secs > 0 ? " and " : ""));
3418
3419     if ($secs > 0)
3420       $ret .= sprintf("%d second%s", $secs, ($secs > 1 ? "s" : ""));
3421   }
3422   else {
3423     if ($mins > 0)
3424       $ret = sprintf("%d minut%s%s", $mins, ($mins > 1 ? "i" : "o"), ($secs > 0 ? " e " : ""));
3425
3426     if ($secs > 0)
3427       $ret .= sprintf("%d second%s", $secs, ($secs > 1 ? "i" : "o"));
3428   }
3429   return ($ret);
3430 }
3431
3432 function sharedmem_sz($tok)
3433 {
3434   if (($shm_id = @shmop_open($tok, 'a', 0, 0)) == FALSE) {
3435     log_main("shmop_open failed");
3436     return (-1);
3437   }
3438   $shm_sz = shmop_size($shm_id);
3439   shmop_close($shm_id);
3440
3441   // log_main("shm_sz: ".$shm_sz."   SHM_DIMS: ".SHM_DIMS);
3442   return ($shm_sz);
3443 }
3444
3445 class Warrant {
3446     static $delta_t;
3447
3448   static function lock_data($is_exclusive)
3449   {
3450       if (($res = file_lock(FTOK_PATH."/warrant", $is_exclusive)) != FALSE) {
3451           self::$delta_t = microtime(TRUE);
3452           log_lock("LOCK   warrant      [".self::$delta_t."]");
3453
3454           return ($res);
3455       }
3456
3457       return (FALSE);
3458   }
3459
3460   static function unlock_data($res)
3461   {
3462     GLOBAL $sess;
3463
3464     log_lock("UNLOCK warrant      [".(microtime(TRUE) - (self::$delta_t))."]");
3465
3466     file_unlock($res);
3467   }
3468 }
3469
3470 class Poll {
3471     static $delta_t;
3472
3473   static function lock_data($is_exclusive)
3474   {
3475       if (($res = file_lock(FTOK_PATH."/poll", $is_exclusive)) != FALSE) {
3476           self::$delta_t = microtime(TRUE);
3477           log_lock("LOCK   poll         [".self::$delta_t."]");
3478
3479           return ($res);
3480       }
3481
3482       return (FALSE);
3483   }
3484
3485   static function unlock_data($res)
3486   {
3487     GLOBAL $sess;
3488
3489     log_lock("UNLOCK poll         [".(microtime(TRUE) - (self::$delta_t))."]");
3490
3491     file_unlock($res);
3492   }
3493 }
3494
3495 function carousel_top()
3496 {
3497     $what = rand(1,2);
3498     if ($what == 1) {
3499         $rn = rand(1, 3);
3500         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));
3501         }
3502     else {
3503         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>'));
3504     }
3505 }
3506
3507
3508 ?>