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