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