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