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