9368916ecfac86c78e2780e7da754fd527e655c0
[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.2.1";
157
158 /* MLANG: ALL THE INFO STRINGS IN brisk.phh */
159 $root_wellarr = array( 'it' => array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: puoi creare la tua rete di amicizie con /info, vedere cosa pensano i tuoi amici degli altri utenti e ci sono i nuovi tavoli riservati per registrati e apprendisti, corretti alcuni errori.',
160                                        'Se vuoi iscriverti alla <a target="_blank" href="mailto:ml-briscola+subscribe@milug.org">Mailing List</a>, cliccala!' ),
161                        'en' => array ( 'EN Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: puoi creare la tua rete di amicizie con /info,',
162                                        'vedere cosa pensano i tuoi amici degli altri utenti e tavoli riservati per registrati e apprendisti.',
163                                        'Se vuoi iscriverti alla <a target="_blank" href="mailto:ml-briscola+subscribe@milug.org">Mailing List</a>, cliccala!' ) );
164
165 $G_room_help = array( 'it' => '
166 <div style=\\"text-align: left; padding: 8px;\\">
167 <b>Descrizione</b><br>
168 Questa è un\'implementazione della briscola in cinque, cos&igrave; come &egrave; spiegata su
169 <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>
170 <b>Configurazione del browser.</b><br>
171 Occorre abilitare i cookies.<br>
172 <br>
173 <b>Uso del sito</b><br>
174 Potete sedervi a un tavolo o rimanere in piedi.<br>
175 Se al vostro tavolo si raggiungono i 5 giocatori inizia automaticamente la partita.<br>
176 <br>
177 <b>Partita</b><br>
178 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>
179 Chi vince l\'asta dovr&agrave; decidere il seme della carta scelta e inizier&agrave; la mano.<br>
180 Per giocare le carte dovrete trascinarle nel quadrato al centro del vostro schermo.<br><br>
181 Il vostro turno &egrave; sempre segnalato da una cornice verde lampeggiante intorno al quadrato al centro del vostro schermo.<br><br>
182 Durante la partita, se vorrete ricaricare la pagina, usate l\'apposito bottone \\"reload\\" in basso a destra.<br>
183 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.
184 <dl>
185 <dt><b>Comandi della chat</b>
186 <dd><b>/nick <i>&lt;nuovo_nickname&gt;</i></b> - cambio di nickname
187 <dd><b>/tav <i>&lt;frase di invito&gt;</i></b> - invito per gli altri giocatori al tavolo dove si &egrave; seduti
188 <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\\"
189 <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
190 <dd><b>/info <i>&lt;login&gt;</i></b> - mostra lo stato corrente dell\'utente passato come argomento e in che relazione siete
191 <dd><b>/authreq</b> - se si &egrave; autenticati permette di garantire per un utente fidato
192 <dd><b>/mesgtoadm</b> - se si &egrave; autenticati permette di lasciare un messaggio all\'amministratore del sito
193 <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)
194 </dl>
195 </div>
196 ',
197
198 'en' => '
199 <div style=\\"text-align: left; padding: 8px;\\">
200 <b>EN Descrizione</b><br>
201 EN Questa è un\'implementazione della briscola in cinque, cos&igrave; come &egrave; spiegata su
202 <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>
203 <b>Configurazione del browser.</b><br>
204 Occorre abilitare i cookies.<br>
205 <br>
206 <b>Uso del sito</b><br>
207 Potete sedervi a un tavolo o rimanere in piedi.<br>
208 Se al vostro tavolo si raggiungono i 5 giocatori inizia automaticamente la partita.<br>
209 <br>
210 <b>Partita</b><br>
211 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>
212 Chi vince l\'asta dovr&agrave; decidere il seme della carta scelta e inizier&agrave; la mano.<br>
213 Per giocare le carte dovrete trascinarle nel quadrato al centro del vostro schermo.<br><br>
214 Il vostro turno &egrave; sempre segnalato da una cornice verde lampeggiante intorno al quadrato al centro del vostro schermo.<br><br>
215 Durante la partita, se vorrete ricaricare la pagina, usate l\'apposito bottone \\"reload\\" in basso a destra.<br>
216 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.
217 <dl>
218 <dt><b>Comandi della chat</b>
219 <dd><b>/nick <i>&lt;nuovo_nickname&gt;</i></b> - cambio di nickname
220 <dd><b>/tav <i>&lt;frase di invito&gt;</i></b> - invito per gli altri giocatori al tavolo dove si &egrave; seduti
221 <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\\"
222 <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
223 <dd><b>/info <i>&lt;login&gt;</i></b> - mostra lo stato corrente dell\'utente passato come argomento e in che relazione siete
224 <dd><b>/authreq</b> - se si &egrave; autenticati permette di garantire per un utente fidato
225 <dd><b>/mesgtoadm</b> - se si &egrave; autenticati permette di lasciare un messaggio all\'amministratore del sito
226 <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)
227 </dl>
228 </div>
229 ');
230
231 //
232 $G_room_passwdhowto = array( 'it' => '<br><h2>Come registrarsi su Brisk</h2>
233 <div style=\\"text-align: left; padding: 8px;\\">
234 Attualmente ci sono due metodi per ottenere una password sul sito:<br><br>
235 <dir>
236 <li><b>Facendosi garantire da un utente di Brisk che sia certificato.</b><br><br>
237 <li><b>Auto-garantendosi utilizzando uno dei seguenti sistemi di identificazione digitale:</b><br><br>
238 <dir>
239 <li>Carta Regionale dei Servizi della Lombardia (la tessera sanitaria)
240 <li>Carta Regionale dei Servizi del Friuli Venezia Giulia (la tessera sanitaria)
241 <li>Smart card di InfoCamere
242 </dir>
243 <br>
244 <b>Per auto-garantisi occorre possedere:</b><br><br>
245 <dir>
246 <li>il codice PIN della propria carta
247 <li>il lettore di smart-card per collegare la carta al PC (acquistabile di solito presso le edicole)
248 </dir>
249 <br>
250 <b>Per effettuare la registrazione collegarsi al sito:</b> <a class=\\"flat\\"  target=\\"_blank\\" href=\\"https://brisk.mine.nu\\">https://brisk.mine.nu</a>
251 <br>
252 Se sei in possesso di una carta che permette l\'identificazione via internet che non è nell\'elenco qui sopra
253 <a class=\\"flat\\" href=\\"mailto:authadmbrisk@alternativeoutput.it\\">fai una segnalazione</a>.<br><br>
254 Le regole per ottenere la certificazione sono in via di definizione, l\' unica accettata è la conoscenza
255 diretta dell\' utente da parte dell\' amministratore.
256
257 </dir>
258 </div>
259 ',
260                              'en' => '<br><h2>EN Come registrarsi su Brisk</h2>
261 <div style=\\"text-align: left; padding: 8px;\\">
262 EN Attualmente ci sono due metodi per ottenere una password sul sito:<br><br>
263 <dir>
264 <li><b>Facendosi garantire da un utente di Brisk che gi&agrave; possidede una password</b><br><br>
265 <li><b>Auto-garantendosi utilizzando uno dei seguenti sistemi di identificazione digitale:</b><br><br>
266 <dir>
267 <li>Carta Regionale dei Servizi della Lombardia (la tessera sanitaria)
268 <li>Carta Regionale dei Servizi del Friuli Venezia Giulia (la tessera sanitaria)
269 </dir>
270 <br>
271 <b>Per auto-garantisi occorre possedere:</b><br><br>
272 <dir>
273 <li>il codice PIN della propria carta
274 <li>il lettore di smart-card per collegare la carta al PC (acquistabile di solito presso le edicole)
275 </dir>
276 <br>
277 <b>Per effettuare la registrazione collegarsi al sito:</b> <a class=\\"flat\\"  target=\\"_blank\\" href=\\"https://brisk.mine.nu\\">https://brisk.mine.nu</a>
278 <br>
279 Se sei in possesso di una carta che permette l\'identificazione via internet che non è nell\'elenco qui sopra
280 <a class=\\"flat\\" href=\\"mailto:authadmbrisk@alternativeoutput.it\\">fai una segnalazione</a>.<br><br>
281 Le regole per ottenere la certificazione sono in via di definizione, l\' unica accettata è la conoscenza
282 diretta dell\' utente da parte dell\' amministratore.
283
284
285 </dir>
286 </div>
287 ' );
288 /*
289 <dd>Seguendo la procedura di auto-garanzia all\'url: <a href="https://brisk.mine.nu">https://brisk.mine.nu</a>
290 ';
291 */
292
293 $G_room_about = array( 'it' => '<br>
294 <div id=\\"header\\" class=\\"header\\">
295   <img class=\\"nobo\\" src=\\"img/brisk_logo64.png\\">
296   briscola chiamata in salsa ajax
297 </div>
298 <br><b>version '.$G_brisk_version.'</b><br><br>
299 Copyright 2006-2012 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>',
300                       'en' => '<br>
301 <div id=\\"header\\" class=\\"header\\">
302   <img class=\\"nobo\\" src=\\"img/brisk_logo64.png\\">
303   declaration briscola in ajax sauce <b>(Beta)</b>
304 </div>
305 <br><b>version '.$G_brisk_version.'</b><br><br>
306 Copyright 2006-2012 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>');
307
308
309 $G_PG_vow = array("a", "e", "i", "o", "u", "y");
310 $G_PG_vow_n = 6;
311 $G_PG_cons = array(
312       "b", "bb", "bc", "bd", "bf", "bg", "bk", "bl", "bm", "bn", "bp",       "br", "bs", "bt", "bv", "bw",       "bz",
313       "c", "cb", "cc", "cd", "cf", "cg", "ck", "cl", "cm", "cn", "cp", "cq", "cr", "cs", "ct", "cv", "cw", "cx", "cz",
314       "d", "db", "dc", "dd", "df", "dg", "dk", "dl", "dm", "dn", "dp",       "dr", "ds", "dt", "dv", "dw", "dx", "dz",
315       "f", "fb", "fc", "fd", "ff", "fg", "fk", "fl", "fm", "fn", "fp",       "fr", "fs", "ft", "fv", "fw", "fx", "fz",
316       "g", "gb", "gc", "gd", "gf", "gg", "gk", "gl", "gm", "gn", "gp",       "gr", "gs", "gt", "gv", "gw", "gx", "gz",
317       "j", "jb", "jc", "jd", "jf", "jg", "jk", "jl", "jm", "jn", "jp", "jq", "jr", "js", "jt", "jv", "jw", "jx", "jz",
318       "k", "kb", "kc", "kd", "kf", "kg", "kk", "kl", "km", "kn", "kp",       "kr", "ks", "kt", "kv", "kw", "kx", "kz",
319       "l", "lb", "lc", "ld", "lf", "lg", "lk", "ll", "lm", "ln", "lp",       "lr", "ls", "lt", "lv", "lw", "lx", "lz",
320       "m", "mb", "mc", "md", "mf", "mg", "mk", "ml", "mm", "mn", "mp",       "mr", "ms", "mt", "mv", "mw", "mx", "mz",
321       "n", "nb", "nc", "nd", "nf", "ng", "nk", "nl", "nm", "nn", "np",       "nr", "ns", "nt", "nv", "nw", "nx", "nz",
322       "p", "pb", "pc", "pd", "pf", "pg", "pk", "pl", "pm", "pn", "pp",       "pr", "ps", "pt", "pv", "pw", "px", "pz",
323       "q", "qb", "qc", "qd", "qf", "qg", "qk", "ql", "qm", "qn", "qp", "qq", "qr", "qs", "qt", "qv", "qw", "qx", "qz",
324       "r", "rb", "rc", "rd", "rf", "rg", "rk", "rl", "rm", "rn", "rp",       "rr", "rs", "rt", "rv", "rw", "rx", "rz",
325       "s", "sb", "sc", "sd", "sf", "sg", "sk", "sl", "sm", "sn", "sp", "sq", "sr", "ss", "st", "sv", "sw", "sx", "sz",
326       "t", "tb", "tc", "td", "tf", "tg", "tk", "tl", "tm", "tn", "tp",       "tr", "ts", "tt", "tv", "tw", "tx", "tz",
327       "v", "vb", "vc", "vd", "vf", "vg", "vk", "vl", "vm", "vn", "vp",       "vr", "vs", "vt", "vv", "vw", "vx", "vz",
328       "w", "wb", "wc", "wd", "wf", "wg", "wk", "wl", "wm", "wn", "wp",       "wr", "ws", "wt", "wv", "ww", "wx", "wz",
329       "x", "xb", "xc", "xd", "xf", "xg", "xk", "xl", "xm", "xn", "xp",       "xr", "xs", "xt", "xv", "xw", "xx", "xz",
330       "z", "zb", "zc", "zd", "zf", "zg", "zk", "zl", "zm", "zn", "zp",       "zr", "zs", "zt", "zv", "zw", "zx", "zz",
331                   );
332 // $G_PG_cons_n = count($G_PG_cons);
333 // printf("N CONS: %d\n", $G_PG_cons_n);
334 $G_PG_cons_n = 345;
335     /*     printf("%d %d\n", count($voc), count($cons)); */
336     /* for ($i = 0 ; $i < 26 ; $i++) { */
337     /*     if (array_search(chr(ord('a') + $i), $voc) !== FALSE || $i == 7) */
338     /*         continue; */
339     /*     printf('      "%s", ', chr(ord('a') + $i)); */
340     /*     for ($e = 0 ; $e < 26 ; $e++) { */
341     /*         if (array_search(chr(ord('a') + $e), $voc) !== FALSE || $e == 7) */
342     /*             continue; */
343     /*         printf('"%s%s", ', chr(ord('a') + $i), chr(ord('a') + $e)); */
344     /*     } */
345     /*     printf("\n"); */
346     /* } */
347
348 function ip2int($s)
349 {
350     return (ip2long($s));
351 }
352
353 function int2ip($i)
354 {
355     return (long2ip($i));
356 }
357
358 function int2four($l)
359 {
360     if (PHP_INT_SIZE == 4)
361         return ($l);
362
363     return ( ($l & 0x80000000 ? 0xffffffff00000000 : 0x00) | $l );
364 }
365
366 function four2int($s)
367 {
368     return ($s & 0xffffffff);
369 }
370
371 function ip2four($s)
372 {
373     return int2four( ip2int($s) );
374 }
375
376 function four2ip($i)
377 {
378     return int2ip( four2int($i) );
379 }
380
381 function nickserv_msg($dt, $msg) {
382     return sprintf('chatt_sub("%s",[0x040003,"%s"],"%s");', $dt, NICKSERV, $msg);
383 }
384
385 function passwd_gen($seed = NULL)
386 {
387     GLOBAL $G_PG_vow, $G_PG_vow_n, $G_PG_cons, $G_PG_cons_n;
388
389     $pw = "";
390
391     if ($seed != NULL)
392         mt_srand($seed);
393     else
394         mt_srand();
395
396     for ($sil = 0 ; $sil < 7 ; $sil++) {
397         if (($sil % 2) == 0) {
398             // vowels
399             for ($n = 0 ; $n < mt_rand(1,2) ; $n++) {
400                 if ($n == 0) {
401                     $old = mt_rand(0, $G_PG_vow_n-1);
402                     $pw .= $G_PG_vow[$old];
403                 }
404                 else {
405                     $new = mt_rand(0, $G_PG_vow_n-1);
406                     if ($new == $old)
407                         $new = ($new + mt_rand(0, $G_PG_vow_n-2)) % $G_PG_vow_n;
408                     $pw .= $G_PG_vow[$new];
409                 }
410             }
411         }
412         else {
413             // consonants
414             $pw .= $G_PG_cons[mt_rand(0, $G_PG_cons_n-1)];
415         }
416     }
417
418     return $pw;
419 }
420
421 function cmd_return($val, $desc)
422 {
423     return array('val' => $val, 'desc' => $desc);
424 }
425
426 function cmd_serialize($attrs)
427 {
428     $ret = "";
429
430     $sep = "";
431     foreach ($attrs as $key => $value) {
432         $ret .= $sep . $key . '=' . urlencode($value);
433         $sep = "&";
434     }
435     return $ret;
436 }
437
438 function cmd_deserialize($cmd)
439 {
440     $ret = array();
441     $a = explode('&', $cmd);
442     $i = 0;
443     while ($i < count($a)) {
444         $b = split('=', $a[$i]);
445         $ret[urldecode($b[0])] = urldecode($b[1]);
446         $i++;
447     }
448
449     return $ret;
450 }
451
452 //  return values
453 // -1 v1 < v2
454 //  0 equal
455 //  1 v1 > v2
456 function versions_cmp($v1, $v2)
457 {
458     // printf("V1: [%s]\nV2: [%s]\n", $v1, $v2);
459     if ($v1 == $v2)
460         return 0;
461
462     $v1_ar = split('\.', $v1);
463     $v2_ar = split('\.', $v2);
464
465     $v2_ct = count($v2_ar);
466
467     for ($i = 0 ; $i < count($v1_ar) ; $i++) {
468         if (($v2_ct - 1) < $i) {
469             break;
470         }
471         // printf("here [%s] [%s]\n", $v1_ar[$i], $v2_ar[$i]);
472         if ($v1_ar[$i] != $v2_ar[$i]) {
473             if (strval($v1_ar[$i]) < strval($v2_ar[$i]))
474                 return -1;
475             else
476                 return  1;
477         }
478     }
479     return 0;
480 }
481
482 // return string with IPV4 address
483 function addrtoipv4($addr)
484 {
485     $ipv4addr_arr = explode(':' , $addr);
486     if (isset($ipv4addr_arr[3])) {
487         $ipv4addr = $ipv4addr_arr[3];
488     }
489     else {
490         $ipv4addr = $addr;
491     }
492     return $ipv4addr;
493 }
494
495 function mop_flush()
496 {
497     for ($i = 0; $i < ob_get_level(); $i++)
498         ob_end_flush();
499     ob_implicit_flush(1);
500     flush();
501 }
502
503 function force_no_cache(&$header_out)
504 {
505     $header_out['Pragma'] = 'no-cache, must-revalidate';
506     $header_out['Cache-Control'] = 'no-cache';
507     $header_out['Expires'] = '-1';
508 }
509
510 function file_lock($fname, $is_exclusive)
511 {
512     if (($res = @fopen($fname, "r+")) == FALSE) {
513         return (FALSE);
514     }
515
516     if (flock($res, ($is_exclusive ? LOCK_EX : LOCK_SH)) == FALSE) {
517         fclose($res);
518         return (FALSE);
519     }
520
521     return ($res);
522 }
523
524 function file_unlock($res)
525 {
526     if ($res != FALSE) {
527         flock($res, LOCK_UN);
528         fclose($res);
529     }
530 }
531
532 $escpush_from = array("\\", "\"");
533 $escpush_to   = array("\\\\", "\\\"");
534 function escpush($s)
535 {
536     GLOBAL $escpush_from, $escpush_to;
537
538     return str_replace($escpush_from, $escpush_to, $s);
539 }
540
541 $escinp_from = array( "\""     );
542 $escinp_to = array(   "&quot;" );
543
544 function escinput($s)
545 {
546     GLOBAL $escinp_from, $escinp_to;
547
548     return str_replace($escinp_from, $escinp_to, $s);
549 }
550
551 function eschtml($s)
552 {
553     return htmlentities($s, ENT_COMPAT, "UTF-8");
554 }
555
556 function esclfhtml($s)
557 {
558     return str_replace(" ", "&nbsp;", str_replace("\n", "<br>", htmlspecialchars($s)));
559 }
560
561 function langtolng($lang)
562 {
563   GLOBAL $G_lang;
564
565   return ($G_lang == 'en' ? '-en' : '');
566 }
567
568 function csplitter($in, $sep)
569 {
570   $st = 0;
571   $id = 0;
572   $out = array();
573   $out[$id] = "";
574   for ($i = 0 ; $i < strlen($in) ; $i++) {
575     $ini = substr($in, $i, 1);
576     if ($st == 0) {
577       if ($ini == '\\')
578         $st = 1;
579       else if ($ini == $sep) {
580         $id++;
581         $out[$id] = "";
582       }
583       else {
584         $out[$id] .= $ini;
585       }
586     }
587     else if ($st == 1) {
588       $out[$id] .= $ini;
589       $st = 0;
590     }
591   }
592
593   return ($out);
594 }
595
596 function xcape($s)
597 {
598   $from = array (   '\\',     '@',        '|' );
599   $to   = array ( '\\\\', '&#64;', '&brvbar;' );
600
601   return (str_replace($from, $to, htmlentities($s,ENT_COMPAT,"UTF-8")));
602 }
603
604 function xcapelt($s)
605 {
606   $from = array (   '\\',     '|',  "\t",  "\n");
607   $to   = array ( '\\\\',   '\\|', "\\t", "\\n");
608
609   return (str_replace($from, $to, $s));
610 }
611
612 function xcapemesg($s)
613 {
614   $from = array (  "\n");
615   $to   = array ( "\\n");
616
617   return (str_replace($from, $to, $s));
618 }
619
620
621 class Vect {
622     function Vect($a)
623     {
624         $this->el = $a;
625     }
626
627     function getbyid($idx)
628     {
629         return ($this->el[$idx]);
630     }
631
632     function setbyid($idx, $v)
633     {
634         $this->el[$idx] = $v;
635     }
636 }
637
638 define('TABLE_AUTH_TY_PUBL', 0);
639 define('TABLE_AUTH_TY_APPR', 1);
640 define('TABLE_AUTH_TY_AUTH', 2);
641 define('TABLE_AUTH_TY_CERT', 3);
642
643
644 class Table {
645   var $idx;
646   var $player;
647   var $player_n;
648
649   var $auth_type;     // required authorization to sit down
650
651   var $wag_own;
652   var $wag_com;
653   var $wag_tout;
654
655   var $table_token;
656   var $table_start;   // information field
657
658   var $wakeup_time;
659
660   function Table()
661   {
662   }
663
664   function create($idx)
665   {
666     if (($thiz = new Table()) == FALSE)
667       return (FALSE);
668
669     $thiz->idx       =   $idx;
670     $thiz->player    =   array();
671     $thiz->player_n  =   0;
672
673     if ($idx < TABLES_CERT_N)
674         $thiz->auth_type =   TABLE_AUTH_TY_CERT;
675     else if ($idx < TABLES_AUTH_N)
676         $thiz->auth_type =   TABLE_AUTH_TY_AUTH;
677     else if ($idx < TABLES_APPR_N)
678         $thiz->auth_type =   TABLE_AUTH_TY_APPR;
679     else
680         $thiz->auth_type =   TABLE_AUTH_TY_PUBL;
681
682     $thiz->wag_own   =  -1;
683     $thiz->wag_com   =  "";
684     $thiz->wag_tout   =  0;
685
686     $thiz->table_token  = "";
687     $thiz->table_start  = 0;
688
689     $thiz->wakeup_time = 0;
690
691     return ($thiz);
692   }
693
694   function copy($from)
695   {
696     $this->idx = $from->idx;
697     $this->player = array();
698     for ($i = 0 ; $i < $from->player_n ; $i++)
699       $this->player[$i] = $from->player[$i];
700     $this->player_n = $from->player_n;
701
702     log_main("PLAYER_N - parent::copy.".$this->player_n);
703
704     $this->auth_type =  $from->auth_type;
705
706     $this->wag_own   =  $from->wag_own;
707     $this->wag_com   =  $from->wag_com;
708     $this->wag_tout  =  $from->wag_tout;
709
710     $this->table_token  = $from->table_token;
711     $this->table_start  = $from->table_start;
712
713     $this->wakeup_time = $from->wakeup_time;
714   }
715
716   function myclone($from)
717   {
718     if (($thiz = new Table()) == FALSE)
719       return (FALSE);
720
721     $this->copy($from);
722
723     return ($thiz);
724   }
725
726   function spawn($from)
727   {
728     if (($thiz = new Table()) == FALSE)
729       return (FALSE);
730
731     $thiz->idx = $from->idx;
732     $thiz->player = array();
733     for ($i = 0 ; $i < $from->player_n ; $i++)
734       $thiz->player[$i] = $i;
735     $thiz->player_n = $from->player_n;
736
737     $thiz->auth_type =  $from->auth_type;
738
739     $thiz->wag_own = $from->wag_own;
740     $thiz->wag_com = $from->wag_com;
741     $thiz->wag_tout  =  $from->wag_tout;
742
743     $thiz->table_token  = $from->table_token;
744     $thiz->table_start  = $from->table_start;
745
746     $thiz->wakeup_time = $from->wakeup_time;
747
748     return ($thiz);
749   }
750
751   function wag_set($user_idx, $mesg)
752   {
753     log_main("WAG_SET");
754
755     $this->wag_own  =  $user_idx;
756     $this->wag_com  =  $mesg;
757     $this->wag_tout =  0;
758   }
759
760   function wag_reset($timeout)
761   {
762     log_main("WAG_RESET");
763
764     unset($this->wag_own);
765     $this->wag_own  = -1;
766     $this->wag_com  = "";
767     $this->wag_tout = $timeout;
768   }
769
770   function player_get($idx)
771   {
772     return ($this->player[$idx]);
773   }
774
775   function player_set($idx, $player)
776   {
777     $this->player[$idx] = $player;
778   }
779
780   function user_add($idx)
781   {
782     $this->player[$this->player_n] = $idx;
783     $this->player_n++;
784
785     return ($this->player_n - 1);
786   }
787
788   function user_rem($brisk, $user)
789   {
790     $tabpos = $user->table_pos;
791
792     /* verifico la consistenza dei dati */
793     if ($brisk->user[$this->player[$tabpos]] == $user) {
794
795       /* aggiorna l'array dei giocatori al tavolo. */
796       for ($i = $tabpos ; $i < $this->player_n-1 ; $i++) {
797         $this->player[$i] = $this->player[$i+1];
798         $user_cur = $brisk->user[$this->player[$i]];
799         $user_cur->table_pos = $i;
800       }
801       $this->player_n--;
802     }
803     else {
804       log_main("INCONSISTENCY ON TABLE.");
805     }
806   }
807
808   // Table->act_content - return 'id' of type of output required for table button
809   function act_content($user)
810   {
811     $ret = "";
812     $isstanding = ($user->subst == 'standup');
813     $sitted = $this->player_n;
814     $table = $this->idx;
815     $cur_table = $user->table;
816     $allowed = TRUE;
817
818     if ($isstanding) {
819       if ($sitted < PLAYERS_N) {
820           switch ($this->auth_type) {
821           case TABLE_AUTH_TY_CERT:
822               if ($user->is_cert() && !$user->is_appr())
823                   $act = "sitcert";
824               else
825                   $act = 'resercert';
826               break;
827           case TABLE_AUTH_TY_AUTH:
828               if ($user->is_auth() && !$user->is_appr())
829                   $act = "sitreser";
830               else
831                   $act = 'reserved';
832               break;
833           case TABLE_AUTH_TY_APPR:
834               if ($user->is_auth())
835                   $act = "sitappr";
836               else
837                   $act = 'reserved';
838               break;
839           default:
840               $act = 'sit';
841               break;
842           }
843       }
844       else {
845         $act = 'none';
846       }
847     }
848     else {
849       if ($table == $cur_table)
850         $act = 'wake';
851       else
852         $act = 'none';
853     }
854
855     if ($act != '')
856       $ret = sprintf('j_tab_act_cont(%d, \'%s\');', $table, $act);
857
858     return ($ret);
859   }
860 } // end class Table
861
862
863 class Delay_Manager
864 {
865     var $delta;
866     var $lastckeck;
867     var $triglevel;
868
869     function Delay_Manager($triglevel)
870     {
871         $this->triglevel = $triglevel;
872         $this->delta = array();
873         $this->lastcheck = 0;
874     }
875
876     function delta_get($curtime)
877     {
878         // clean too old delta items
879         for ($i = 0 ; $i < count($this->delta) ; $i++) {
880             if ($this->delta[$i][0] < $curtime) {
881                 array_splice($this->delta, $i, 1);
882                 $i--;
883             }
884         }
885
886         // add new delta items if delay exceeded $this->triglevel sec
887         if ($curtime > $this->lastcheck + $this->triglevel && $curtime < $this->lastcheck + 1200.0) {
888             $delta = $curtime - $this->lastcheck - $this->triglevel;
889             array_push($this->delta, array($curtime + $delta , $delta));
890             // fprintf(STDERR, "DELTA: add new delta [%f] [%f] [%f]\n", $this->triglevel, $curtime + $delta, $delta);
891         }
892
893         // extract the maximum valid delta
894         $delta_max = 0.0;
895         for ($i = 0 ; $i < count($this->delta) ; $i++) {
896             $delta_cur = $this->delta[$i][1];
897             if ($delta_max < $delta_cur)
898                 $delta_max = $delta_cur;
899         }
900
901         // fprintf(STDERR, "DELTA: status %d, delta_max: %f\n", count($this->delta), $delta_max);
902
903         return ($delta_max);
904     }
905
906     function lastcheck_set($curtime)
907     {
908         $this->lastcheck = $curtime;
909     }
910 }
911
912 class Client_prefs {
913     var $listen;
914     var $supp_comp;
915
916     function Client_prefs()
917     {
918     }
919
920     static function from_user($user)
921     {
922         $thiz = new Client_prefs();
923         $thiz->user_load($user);
924
925         return ($thiz);
926     }
927
928     static function from_json($json)
929     {
930         $thiz = new Client_prefs();
931         if ($thiz->json_load($json) == FALSE) {
932             unset($thiz);
933             return (FALSE);
934         }
935
936         return ($thiz);
937     }
938
939     function user_load($user)
940     {
941         fprintf(STDERR, "QQ %s: %x\n", __FUNCTION__, $user->flags);
942         $this->listen = ($user->flags & USER_FLAG_MAP_AUTH) >> 2;
943         if ($user->rec != FALSE) {
944             $this->supp_comp = $user->rec->supp_comp_get();
945         }
946         else {
947             $this->supp_comp = "000000000000";
948         }
949
950         fprintf(STDERR, "QQ %s: LISTEN: %d\n", __FUNCTION__, $this->listen);
951     }
952
953     function json_load($json_s)
954     {
955         $ret = FALSE;
956
957         do {
958             if (gettype($json_s) == "string") {
959                 if (($json = json_decode($json_s)) == FALSE)
960                     break;
961             }
962             else {
963                 $json = $json_s;
964             }
965             if ($this->listen < 0 || $this->listen > 2)
966                 break;
967             $this->listen = $json->listen;
968
969             if (mb_strlen($json->supp_comp, "ASCII") != 12)
970                 break;
971
972             for ($i = 0, $idx = 0 ; $i < 12 ; $i++) {
973                 if (($json->supp_comp[$i] >= '0' && $json->supp_comp[$i] <= '9') ||
974                     ($json->supp_comp[$i] >= 'a' && $json->supp_comp[$i] <= 'f'))
975                     continue;
976                 break;
977             }
978             if ($i < 12)
979                 break;
980             $this->supp_comp = $json->supp_comp;
981             $ret = TRUE;
982         } while (FALSE);
983
984         return ($ret);
985     }
986
987     function store($user, $is_save)
988     {
989         // save into DB
990         fprintf(STDERR, "QQ %s::%s PRE: %x\n", __CLASS__, __FUNCTION__,
991                 $user->flags & (~USER_FLAG_S_ALL & ~USER_FLAG_AUTH));
992         $user->flags_set(($this->listen << 2), USER_FLAG_MAP_AUTH);
993         fprintf(STDERR, "QQ %s::%s %x\n", __CLASS__, __FUNCTION__,
994                 $user->flags);
995         if ($user->is_supp_custom()) {
996             $user->rec->supp_comp_set($this->supp_comp);
997         }
998         if ($is_save)
999             $user->prefs_store();
1000     }
1001 }
1002
1003 define('GHOST_SESS_TOUT', 1800);
1004 define('GHOST_SESS_REAS_LOUT', 1); // logout
1005 define('GHOST_SESS_REAS_ANOT', 2); // another user get session
1006 define('GHOST_SESS_REAS_TOUT', 3); // room timeout
1007 define('GHOST_SESS_REAS_TTOT', 4); // table timeout
1008 define('GHOST_SESS_REAS_ANON', 5); // anonymizer access
1009 define('GHOST_SESS_REAS_PROX', 6); // proxy access
1010
1011 class GhostSessEl
1012 {
1013     var $time;
1014     var $sess;
1015     var $reas;
1016
1017     function GhostSessEl($time, $sess, $reas)
1018     {
1019         $this->time = $time + GHOST_SESS_TOUT;
1020         $this->sess = $sess;
1021         $this->reas = $reas;
1022     }
1023 }
1024
1025 class GhostSess
1026 {
1027     var $gs;
1028
1029     function GhostSess()
1030     {
1031         $this->gs = array();
1032     }
1033
1034     // push or update for this session
1035     function push($time, $sess, $reas)
1036     {
1037         foreach($this->gs as $el) {
1038             if ($el->sess == "$sess") {
1039                 $el->reas = $reas;
1040                 $el->time = $time + GHOST_SESS_TOUT;
1041                 return TRUE;
1042             }
1043         }
1044
1045         $this->gs[] = new GhostSessEl($time, $sess, $reas);
1046         return TRUE;
1047     }
1048
1049     function pop($sess)
1050     {
1051         foreach($this->gs as $key => $el) {
1052             if ($el->sess == "$sess") {
1053                 $ret = $this->gs[$key];
1054                 unset($this->gs[$key]);
1055                 return ($ret);
1056             }
1057         }
1058         return FALSE;
1059     }
1060
1061     function garbage_manager($curtime)
1062     {
1063         foreach($this->gs as $key => $el) {
1064             if ($el->time < $curtime) {
1065                 unset($this->gs[$key]);
1066             }
1067         }
1068     }
1069 }
1070
1071 class Brisk
1072 {
1073     static $delta_t;
1074
1075     var $crystal_filename;
1076     var $user;
1077     var $table;
1078     var $match;
1079     var $comm; // commands for many people
1080     var $step; // current step of the comm array
1081     var $garbage_timeout;
1082     var $shm_sz;
1083
1084     var $ban_list;       // ban list (authized allowed)
1085     var $black_list;     // black list (anti-dos, noone allowed)
1086     var $cloud_smasher;  // list of cloud ip ranges to be rejected
1087     var $ghost_sess;
1088     var $delay_mgr;
1089
1090     var $cds;
1091
1092     public static $sess_cur;
1093
1094     function Brisk()
1095     {
1096         $this->cds = NULL;
1097     }
1098
1099     // constructor
1100     static function create($crystal_filename, $ban_list, $black_list, $cloud_smasher) {
1101         if (($brisk_ser = @file_get_contents($crystal_filename)) != FALSE) {
1102             if (($brisk = unserialize($brisk_ser)) != FALSE) {
1103                 fprintf(STDERR, "ROOM FROM FILE\n");
1104                 rename($crystal_filename, $crystal_filename.".old");
1105
1106                 $brisk->reload(TRUE, $ban_list, $black_list, $cloud_smasher);
1107
1108                 return($brisk);
1109             }
1110         }
1111
1112         fprintf(STDERR, "NEW ROOM\n");
1113         $thiz = new Brisk();
1114
1115         $thiz->crystal_filename = $crystal_filename;
1116         $thiz->user  = array();
1117         $thiz->table = array();
1118         $thiz->match = array();
1119
1120         $thiz->ban_list = IpClass::create();
1121         $thiz->black_list = IpClass::create();
1122         $thiz->cloud_smasher = IpClass::create();
1123         $thiz->ghost_sess = new GhostSess();
1124
1125         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1126             $thiz->user[$i] = User::create($thiz, $i, "", "");
1127         }
1128
1129         for ($i = 0 ; $i < TABLES_N ; $i++) {
1130             $thiz->table[$i] = Table::create($i);
1131         }
1132         $thiz->garbage_timeout = 0;
1133         $thiz->shm_sz = SHM_DIMS_MIN;
1134
1135         $thiz->delay_mgr = new Delay_Manager(1.5);
1136
1137         static::$sess_cur = FALSE;
1138
1139         $thiz->reload(TRUE, $ban_list, $black_list, $cloud_smasher);
1140
1141         return ($thiz);
1142     }
1143
1144     function reload($is_first, $ban_list, $black_list, $cloud_smasher)
1145     {
1146         fprintf(STDERR, "RELOAD STUFF (%d)(%d)(%d)\n",
1147                 count($ban_list), count($black_list), count($cloud_smasher));
1148
1149         if (defined('CURL_DE_SAC_VERS')) {
1150             if (brisk_cds_reload($this) == FALSE) {
1151                 exit(12);
1152             }
1153         }
1154         $this->ban_list->update($ban_list);
1155         $this->black_list->update($black_list);
1156         $this->cloud_smasher->update($cloud_smasher);
1157
1158         if (!$is_first) {
1159             $this->banned_kickoff();
1160             $this->garbage_manager(TRUE);
1161         }
1162     }
1163
1164     function banned_kickoff()
1165     {
1166         $is_ban = FALSE;
1167
1168         for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1169             $table_cur = $this->table[$table_idx];
1170             // if the table is complete and exists we check users IP
1171
1172             if ($table_cur->player_n == PLAYERS_N) {
1173                 if (isset($this->match[$table_idx]) &&
1174                     $table_cur->table_token == $bin5->table_token) {
1175                     log_main("PLAYERS == N TABLE ".$table_idx);
1176
1177                     $bin5 = $this->match[$table_idx];
1178
1179                     $is_ban |= $bin5->banned_kickoff();
1180                 }
1181             }
1182         }
1183
1184         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1185             $user_cur = $this->user[$i];
1186
1187             if ($user_cur->is_active() == FALSE)
1188                 continue;
1189
1190             // check if the IP is blacklisted
1191             if ($this->black_check($user_cur->ip) ||
1192                 $this->cloud_check($user_cur->ip)) {
1193                 $user_cur->lacc = 0;
1194                 $is_ban = TRUE;
1195                 continue;
1196             }
1197
1198             // if authorized not check if banlisted
1199             if ($user_cur->is_auth()) {
1200                 continue;
1201             }
1202
1203             if ($this->ban_check($user_cur->ip)) {
1204                 $user_cur->lacc = 0;
1205                 $is_ban = TRUE;
1206             }
1207         }
1208
1209         return $is_ban;
1210     }
1211
1212     function ban_check($ip_str)
1213     {
1214         return ($this->ban_list->check($ip_str));
1215     }
1216
1217     function black_check($ip_str)
1218     {
1219         return ($this->black_list->check($ip_str));
1220     }
1221
1222     function cloud_check($ip_str)
1223     {
1224         return ($this->cloud_smasher->check($ip_str));
1225     }
1226
1227     function users_cleanup()
1228     {
1229         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1230             $user_cur = $this->user[$i];
1231
1232             if ($user_cur->the_end) {
1233                 $user_cur->reset(); // users_cleanup, OK
1234             }
1235         }
1236     }
1237
1238   function garbage_manager($force)
1239   {
1240     GLOBAL $G_lang, $mlang_brisk, $G_base;
1241
1242     $ismod = FALSE;
1243
1244     log_rd2("garbage_manager START");
1245
1246     /* Garbage collector degli utenti in timeout */
1247     $curtime = microtime(TRUE);
1248
1249     $delta = $this->delay_mgr->delta_get($curtime);
1250
1251     if (!$force && !($this->garbage_timeout < $curtime)) {
1252         $this->delay_mgr->lastcheck_set($curtime);
1253         return ($ismod);
1254     }
1255
1256     // Before all align times with table timeout
1257     for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1258         $table_cur = $this->table[$table_idx];
1259         // if the table is complete and exists its shared mem we get the info about users lacc
1260
1261         if ($table_cur->player_n == PLAYERS_N) {
1262             log_main("PLAYERS == N TABLE ".$table_idx);
1263
1264
1265             $no_recovery = FALSE;
1266             if (isset($this->match[$table_idx])) {
1267                 $bin5 = $this->match[$table_idx];
1268
1269                 if ($table_cur->table_token != $bin5->table_token) {
1270                     log_main("ERROR: not matching table_token. Brisk: ".$table_cur->table_token."  Table: ".$bin5->table_token);
1271                     log_main("ERROR: not matching table_start. Brisk: ".$table_cur->table_start."  Table: ".$bin5->table_start);
1272                     $no_recovery = TRUE;
1273                     $bin5 = FALSE;
1274                 }
1275
1276                 if ($bin5 != FALSE) {
1277                     //
1278                     //  SPAWN: JOIN
1279                     //
1280                     log_main("garbage_manager: bri loaded successfully.");
1281                     $bin5->garbage_manager(TRUE);
1282
1283                     $bin5_table = $bin5->table[0];
1284
1285                     // is the end of the table
1286
1287                     if ($bin5->the_end == TRUE) {
1288                         /*
1289                          *  DESTROY OF FINISHED TABLE && MOVE PLAYER TO ROOM AGAIN
1290                          */
1291                         log_main("garbage_manager: INSIDE THE END.");
1292
1293                         $plist = "$table_cur->table_token|$table_cur->idx|$table_cur->player_n";
1294                         for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
1295                             $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
1296                         }
1297
1298                         for ($i = 0 ; $i < $bin5_table->player_n ; $i++) {
1299                             // stat must be "table" by definition
1300                             $user_cur = $this->user[$table_cur->player[$i]];
1301                             $bin5_user = $bin5->user[$i];
1302
1303                             $user_cur->subst      = $bin5_user->subst;
1304                             $user_cur->rd_step    = $bin5_user->rd_step;
1305                             $user_cur->step       = $bin5_user->step;
1306                             $user_cur->lacc       = $bin5_user->lacc;
1307                             $user_cur->laccwr     = $bin5_user->lacc;
1308                             $user_cur->bantime    = $bin5_user->bantime;
1309                             $user_cur->the_end    = $bin5_user->the_end;
1310                             if ($user_cur->the_end) {
1311                                 $this->ghost_sess->push($curtime, $user_cur->sess, GHOST_SESS_REAS_TTOT);
1312                             }
1313                         }
1314
1315                         log_legal($curtime, $user_cur->ip, $user_cur, "STAT:DESTROY_GAME", $plist);
1316
1317                         $this->room_join_wakeup($user_cur, FALSE, 0);
1318                         $table_cur->table_token = "";
1319                         $table_cur->wakeup_time = $curtime + WAKEUP_TIME;
1320
1321                         $this->match_del($table_idx);
1322                     }
1323                     else {
1324                         log_main("gm:: save_data");
1325
1326                         for ($i = 0 ; $i < $bin5_table->player_n ; $i++) {
1327                             $this->user[$table_cur->player[$i]]->lacc = $bin5->user[$i]->lacc;
1328                         }
1329                     }
1330                 } // if ($bin5 == FALSE
1331                 else if ($no_recovery == FALSE) {
1332                     log_crit("ERROR: table ".$table_idx." unrecoverable join");
1333
1334                     for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
1335                         $user_cur = $this->user[$table_cur->player[$i]];
1336                         $user_cur->subst = "shutdowner";
1337                         $user_cur->step_inc();
1338
1339                         $ret = sprintf('stat = "%s"; subst = "%s";',  $user_cur->stat, $user_cur->subst);
1340                         $ret .= "gst.st = ".($user_cur->step+1)."; ";
1341                         // MLANG <br>I dati del tavolo n&deg; ".$user_cur->table." sono inconsistenti, verranno resettati.<br><br>Torni in piedi.<br><br>
1342                         $prestr = sprintf($mlang_brisk['tabincon'][$G_lang], $user_cur->table);
1343                         $ret .= show_notify($prestr, 2000, $mlang_brisk['btn_close'][$G_lang], 400, 110);
1344                         $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1345                         $user_cur->step_inc();
1346                     }
1347
1348                     $plist = "$table_cur->table_token|$user_cur->table|$table_cur->player_n";
1349                     for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
1350                         $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
1351                     }
1352                     log_legal($curtime, $user_cur->ip, $user_cur, "STAT:DESTROY_GAME(RECOVERY)", $plist);
1353
1354                     $this->room_join_wakeup($user_cur, TRUE, -2);
1355                     $table_cur->table_token = "";
1356                 }
1357             }
1358         } //  if ($table_cur->player_n == PLAYERS_N) {
1359     } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1360
1361     log_rd2("out new loop.");
1362
1363     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1364         $user_cur = $this->user[$i];
1365
1366         log_rd2("User: ".$user_cur->name."  stat: ".$user_cur->stat."  subst: ".$user_cur->subst);
1367
1368         if ($user_cur->is_active() == FALSE)
1369             continue;
1370
1371         if ($user_cur->lacc + EXPIRE_TIME_RD < ($curtime - $delta)) {
1372             // Auto logout dell'utente
1373             log_rd2("AUTO LOGOUT.".($user_cur->lacc + EXPIRE_TIME_RD)." curtime - delta ".($curtime - $delta));
1374
1375             $this->ghost_sess->push($curtime, $user_cur->sess, GHOST_SESS_REAS_TOUT);
1376             $user_cur->the_end = TRUE;
1377
1378             log_rd2("AUTO LOGOUT.");
1379             if ($user_cur->stat == 'table' || $user_cur->stat == 'room') {
1380                 log_auth($user_cur->sess, "Autologout session.");
1381
1382                 if ($user_cur->subst == 'sitdown' || $user_cur->stat == 'table')
1383                     $this->room_wakeup($user_cur);
1384                 else if ($user_cur->subst == 'standup')
1385                     $this->room_outstandup($user_cur);
1386                 else
1387                     log_rd2("LOGOUT FROM WHAT ???");
1388             }
1389         }
1390
1391         if ($user_cur->laccwr + EXPIRE_TIME_SMAMMA < ($curtime - $delta)) { // lo rimettiamo in piedi
1392             if ($user_cur->stat == 'room' && $user_cur->subst == 'sitdown') {
1393                 $this->room_wakeup($user_cur);
1394                 $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
1395                 /* 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" */
1396                 $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);
1397                 $user_cur->step_inc();
1398             }
1399         }
1400     }
1401     log_rd2("GARBAGE UPDATED!");
1402
1403     $this->garbage_timeout = $curtime + GARBAGE_TIMEOUT;
1404     $ismod = TRUE;
1405
1406     $this->ghost_sess->garbage_manager($curtime);
1407
1408     $this->delay_mgr->lastcheck_set($curtime);
1409     return ($ismod);
1410   }
1411
1412   function show_room($user_step, $user)
1413   {
1414     GLOBAL $G_lang, $mlang_brisk;
1415     log_main("show_room: username: ".$user->name);
1416
1417     $ret = sprintf('gst.st = %d; ',  $user_step);
1418
1419     if ($user->is_auth()) {
1420         $model = '{ "listen": { "__type": "radio" } }';
1421         $content = array('listen' =>  array('val' => ($user->flags & USER_FLAG_ISOLAUTH ? "2" :
1422                                                       ($user->flags & USER_FLAG_LISTAUTH ? "1" : "0")),
1423                                             'cur' => ($user->flags_cur & USER_FLAG_ISOLAUTH ? "2" :
1424                                                       ($user->flags_cur & USER_FLAG_LISTAUTH ? "1" : "0"))));
1425
1426         $ret .= sprintf('g_prefsf.fields_descr_set(JSON.parse(\'%s\'));', $model);
1427         $ret .= sprintf('g_prefsf.json2dom(JSON.parse(\'%s\'));', json_encode($content));
1428     }
1429
1430     if ($user->subst == 'standup')
1431       $ret .= "tra.show(); ";
1432     else
1433       $ret .= "tra.hide(); ";
1434
1435     $ret .= sprintf('stat = "%s";',  $user->stat);
1436
1437     $ret .= root_welcome($user);
1438     if ($user->flags & USER_FLAG_DBFAILED) {
1439         $ret .= "gst.st = ".($user->step+1)."; ";
1440         $ret .= show_notify($mlang_brisk['db_failed'][$G_lang], 0, $mlang_brisk['btn_close'][$G_lang], 400, 140);
1441     }
1442
1443     $ret .= sprintf('subst = "%s";', $user->subst);
1444     $ret .= $user->myname_innerHTML();
1445
1446     for ($i = 0 ; $i < TABLES_N ; $i++) {
1447
1448       $ret .= $this->table_content($user, $i);
1449
1450       $ret .=  $this->table[$i]->act_content($user);
1451       if ($this->table[$i]->wag_own != -1)
1452         $ret .= sprintf('tra.add(%d, "%s: %s"); ', $i,  $this->user[$this->table[$i]->wag_own]->name, $this->table[$i]->wag_com);
1453       else
1454         $ret .= sprintf('tra.rem(%d); ', $i);
1455     }
1456     $ret .= $this->standup_content($user);
1457     $ret .= "setTimeout(preload_images, 0, g_preload_img_arr, g_imgct); ";
1458
1459     return ($ret);
1460   }
1461
1462   function room_wakeup($user)
1463   {
1464     $table_idx = $user->table;
1465     $table = $this->table[$table_idx];
1466
1467     log_main("WAKEUP: begin function table:".$table_idx."  stat: ".$user->stat."  subst: ".$user->subst);
1468
1469     $curtime = time();
1470
1471     $from_table = ($user->stat == "table");
1472     if ($from_table) {
1473         log_main("WAKEUP: from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
1474
1475         for ($i = 0 ; $i < $table->player_n ; $i++) {
1476             $user_cur = $this->user[$table->player[$i]];
1477             log_main("PREIMPOST: INLOOP name: ".$user_cur->name);
1478
1479             if ($user->idx_get() != $table->player[$i]) {
1480                 $user_cur->stat_set("room");
1481                 $user_cur->subst = "sitdown";
1482                 $user_cur->laccwr = $curtime;
1483             }
1484             else if ($user->is_active()) {
1485                 $user_cur->stat_set("room");
1486                 $user_cur->subst = "standup";
1487                 $user_cur->laccwr = $curtime;
1488                 $user_cur->table = -1;
1489             }
1490         }
1491     }
1492     else {
1493         $user->stat_set("room");
1494         $user->subst = "standup";
1495         $user->laccwr = $curtime;
1496     }
1497
1498     $remove_wagon = FALSE;
1499     if($table->wag_own == $user->idx_get()) {
1500         $table->wag_reset($curtime);
1501         $remove_wagon = TRUE;
1502     }
1503
1504     /* aggiorna l'array dei giocatori al tavolo. */
1505     $table->user_rem($this, $user);
1506
1507     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1508       $user_cur = $this->user[$i];
1509       if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') // is not active user or the stat isn't 'room'
1510         continue;
1511
1512       // log_main("VALORI: name: ".$user_cur->name."from_table: ".$from_table."  tab: ".$user_cur->table." taix: ".$table_idx."  ucur: ".$user_cur."  us: ".$user);
1513
1514       $ret = "gst.st = ".($user_cur->step+1)."; ".($remove_wagon ? sprintf("tra.rem(%d);",$table_idx) : "");
1515       if ($from_table && ($user_cur->table == $table_idx || $user->idx_get() == $i)) {
1516         $ret .= 'gst.st_loc++; xstm.stop(); window.onunload = null; window.onbeforeunload = null; document.location.assign("index.php");|';
1517         // $ret .= 'gst.st_loc++; document.location.assign("index.php");|';
1518         log_main("DOCUMENT.index.php: from table");
1519       }
1520       else if ($user_cur->stat == "room") {
1521         log_main("DOCUMENT.index.php: from table");
1522
1523         $ret .= $this->table_content($user_cur, $table_idx);
1524         $ret .= $this->standup_content($user_cur);
1525
1526         // $ret .= table_act_content(FALSE, 0, $table_idx, $user->table, FALSE);
1527         $ret .= $table->act_content($user);
1528
1529         if ($user->idx_get() == $i) {
1530           // set the new status
1531           $ret .=  'subst = "standup"; tra.show(); ';
1532           // clean the action buttons in other tables
1533           for ($e = 0 ; $e < TABLES_N ; $e++) {
1534             if ($this->table[$e]->player_n < PLAYERS_N) {
1535               $ret .= $this->table[$e]->act_content($user);
1536             }
1537           }
1538         }
1539         else {
1540           $ret .= $table->act_content($user_cur);
1541         }
1542       }
1543       log_wr("ROOM_WAKEUP: ".$ret);
1544       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1545       $user_cur->step_inc();
1546     }
1547   }
1548
1549   function room_join_wakeup($user, $update_lacc = FALSE, $trans_delta)
1550   {
1551     $table_idx = $user->table;
1552     $table = $this->table[$table_idx];
1553
1554     log_main("JOIN_WAKEUP: begin function table:".$table_idx."  stat: ".$user->stat."  subst: ".$user->subst);
1555
1556     $curtime = time();
1557     $user_wup = array();
1558     $user_wup_n = 0;
1559     $user_tab = array();
1560     $user_tab_n = 0;
1561     log_main("JOIN WAKEUP: from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
1562
1563     for ($i = 0 ; $i < $table->player_n ; $i++) {
1564         $user_cur = $this->user[$table->player[$i]];
1565         log_main("PREIMPOST INLOOP name: ".$user_cur->name);
1566         if ($user_cur->is_empty()) {
1567             continue;
1568         }
1569         if ($update_lacc == TRUE) {
1570             $user_cur->laccwr = $curtime;
1571         }
1572         log_main("cur: ".$user_cur->name."  subst: ".$user_cur->subst);
1573         if ($user_cur->subst == "shutdowned") {
1574             $user_cur->stat_set("room");
1575             $user_cur->subst = "sitdown";
1576         }
1577         else if ($user_cur->subst == "shutdowner") {
1578             $user_cur->stat_set("room");
1579             $user_cur->subst = "standup";
1580             $user_cur->table = -1;
1581             $user_wup[$user_wup_n++] = $user_cur;
1582
1583             $remove_wagon = FALSE;
1584             if($table->wag_own == $table->player[$i]) {
1585                 $remove_wagon = TRUE;
1586                 $table->wag_reset($curtime);
1587             }
1588         }
1589         $user_tab[$user_tab_n++] = $table->player[$i];
1590     }
1591
1592     for ($wup_idx = 0 ; $wup_idx < $user_wup_n  ; $wup_idx++)
1593       $table->user_rem($this, $user_wup[$wup_idx]);
1594
1595     /* aggiorna l'array dei giocatori al tavolo. */
1596
1597     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1598       log_main("START LOOP");
1599       $user_cur = $this->user[$i];
1600       if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') { // is not active user or the stat isn't 'room'
1601         log_main("name: ".$user_cur->name."skip   subst: ".$user_cur->subst);
1602         continue;
1603       }
1604
1605       log_main("___");
1606       log_main("VALORI name: ".$user_cur->name."  tab: ".$user_cur->table." taix: ".$table_idx);
1607
1608       $ret = "gst.st = ".($user_cur->step+1)."; ".($remove_wagon ? sprintf("tra.rem(%d);",$table_idx) : "");
1609       if ($user_cur->stat == "room") {
1610         log_main("DOCUMENT.index.php from table");
1611
1612         $ret .= $this->table_content($user_cur, $table_idx);
1613         $ret .= $this->standup_content($user_cur);
1614
1615         $ret .= $table->act_content($user_cur);
1616
1617
1618         for ($tab_idx = 0 ; $tab_idx < $user_tab_n  ; $tab_idx++)
1619             if ($user_tab[$tab_idx] == $i)
1620                 break;
1621
1622         // for users that wakeup the room will be reconstructed by index_rd.php
1623         if ($tab_idx < $user_tab_n) {
1624           log_main("PRE show_room username: ".$user_cur->name."  STEP: ".$user_cur->step);
1625
1626 //        ARRAY_POP DISABLED
1627 //           if ($trans_delta == 0)
1628 //             while (array_pop($user_cur->comm) != NULL);
1629
1630           $user_cur->trans_step = $user_cur->step + 1 + $trans_delta;
1631           $user_cur->comm[$user_cur->step % COMM_N] = "";
1632           $user_cur->step_inc();
1633           $user_cur->comm[$user_cur->step % COMM_N] = $this->show_room(($user_cur->step + 1), $user_cur);
1634           $user_cur->step_inc();
1635           log_main("POST show_room username: ".$user_cur->name."  STEP: ".$user_cur->step);
1636
1637           continue;
1638         }
1639         log_main("JOIN_WAKEUP wup_idx ".$wup_idx."  wup_n ".$user_wup_n);
1640
1641         log_main("JOIN_WAKEUP more");
1642
1643         $ret .= $table->act_content($user_cur);
1644
1645         log_main("JOIN_WAKEUP end more");
1646       }
1647       log_wr("ROOM_JOIN_WAKEUP: ".$ret);
1648       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1649       $user_cur->step_inc();
1650     }
1651   }
1652
1653   /*
1654     function info_show($user, $target, $dt)
1655
1656     if success return assoc. array with "ret" => 0 and other fields
1657     else return an assoc. array with "ret: != 0 and "mesg" with an error description
1658   */
1659   function info_show($user, $target, $dt)
1660   {
1661       GLOBAL $G_lang, $mlang_brisk, $G_base;
1662
1663       $mesg = "";
1664       $user_code = -1;
1665       $ret = 0;
1666
1667       do {
1668           if ($target == "") {
1669               $ret = 1;
1670               break;
1671           }
1672           if (($bdb = BriskDB::create()) == FALSE) {
1673               $ret = 2;
1674               break;
1675           }
1676           if ($target == $user->name) {
1677               $ret = 3;
1678               $mesg = sprintf($mlang_brisk['inf_self'][$G_lang]);
1679               break;
1680           }
1681           if (($user_item = $bdb->getitem_bylogin($target, $user_code)) == FALSE) {
1682               $ret = 4;
1683               break;
1684           }
1685           if (($guar_item = $bdb->getitem_bycode($user_item->guar_code_get())) != FALSE) {
1686               $guar_login = $guar_item->login_get();
1687           }
1688           else {
1689               $guar_login = "";
1690           }
1691           $user_tos_vers = $user_item->tos_vers_get();
1692
1693           $partyskill = $bdb->usersnet_partyskill($user->code, $user_item->code);
1694
1695           $widefriend = $bdb->usersnet_widefriend($user->code, $user_item->code);
1696           $widefriend['skill'] = $bdb->usersnet_wideskill($user->code, $user_item->code);
1697           $narrowfriend = $bdb->usersnet_narrowfriend($user->code, $user_item->code);
1698           $narrowfriend['skill'] = $bdb->usersnet_narrowskill($user->code, $user_item->code);
1699
1700           if (($usersnet_item = $bdb->usersnet_bycode($user->code, $user_item->code,
1701                                                       $widefriend, $narrowfriend)) == FALSE) {
1702               $usersnet_item = $bdb->usersnet_default($user->code, $user_item->code,
1703                                                       $widefriend, $narrowfriend);
1704           }
1705
1706           if (versions_cmp($user_tos_vers, "1.2") < 0) {
1707               $mesg = sprintf($mlang_brisk['tos_old'][$G_lang], xcape($target));
1708           }
1709           else if ($guar_login == "") {
1710               $mesg = sprintf($mlang_brisk['inf_nfd'][$G_lang], xcape($target));
1711           }
1712       } while (0);
1713
1714       if ($ret > 0 && $mesg == "") {
1715           $mesg = sprintf($mlang_brisk['inf_err'][$G_lang], $ret);
1716       }
1717
1718       if ($ret != 0) {
1719           $jret = json_encode(array("ret" => $ret, "mesg" => $mesg));
1720       }
1721       else {
1722           $jret = json_encode(array("ret" => 0,
1723                                     "mesg" => "",
1724                                     "login" => $target,
1725                                     // FIXME: state internationalization
1726                                     "state" =>
1727                                     ($user_item->type & USER_FLAG_TY_APPR ? "Apprendista" :
1728                                      ($user_item->type & USER_FLAG_TY_CERT ? "Certificato" :
1729                                       ($user_item->type & (USER_FLAG_TY_NORM | USER_FLAG_TY_SUPER) ?
1730                                        "Normale" : "Stato sconosciuto"))),
1731                                     "guar" => ($user_item->type & USER_FLAG_TY_APPR ?
1732                                                "" : $guar_login),
1733                                     "party" => $partyskill,
1734                                     "match" => (versions_cmp($user_tos_vers, "1.4") < 0 ? "non autorizzato" : $user_item->match_cnt) ,
1735                                     "game" => (versions_cmp($user_tos_vers, "1.4") < 0 ? "non autorizzato" : $user_item->game_cnt),
1736                                     "friend" => usersnet_friend_getlabel($usersnet_item->friend),
1737                                     "skill" => $usersnet_item->skill,
1738                                     "trust"  => $usersnet_item->trust,
1739                                     "widefriend" => $usersnet_item->widefriend,
1740                                     "narrowfriend" => $usersnet_item->narrowfriend
1741                                     ));
1742       }
1743
1744       return $jret;
1745   }
1746
1747   function info_save($user, $json_s)
1748   {
1749       GLOBAL $G_lang, $mlang_brisk, $G_base;
1750
1751       $mesg = "";
1752       $user_code = -1;
1753       $ret = 0;
1754       $subret = 0;
1755
1756       do {
1757           if (($json = json_decode($json_s)) == FALSE) {
1758               $ret = 1;
1759               break;
1760           }
1761
1762           if (($bdb = BriskDB::create()) == FALSE) {
1763               $ret = 2;
1764               break;
1765           }
1766
1767           if (($subret = $bdb->usersnet_save($user->code, $json)) != 0) {
1768               $ret = 4000 + $subret;
1769               break;
1770           }
1771       } while(0);
1772
1773       return ($ret);
1774   }
1775
1776   function room_outstandup($user)
1777   {
1778     $this->room_sitdown($user, -1);
1779   }
1780
1781   function table_update($user)
1782   {
1783     log_main("table_update: pre - USER: ".$user->name);
1784
1785     $table_idx = $user->table;
1786
1787     if ($table_idx > -1)
1788       $table = $this->table[$table_idx];
1789
1790     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1791       $ret = "";
1792       $user_cur = $this->user[$i];
1793       if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') // is not active user or the stat isn't 'room'
1794           continue;
1795
1796       $ret = "gst.st = ".($user_cur->step+1)."; ";
1797       if ($table_idx > -1)
1798         $ret .= $this->table_content($user_cur, $table_idx);
1799
1800       if ($user->idx_get() == $i) {
1801           $ret .= $user->myname_innerHTML();
1802       }
1803       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1804       $user_cur->step_inc();
1805     }
1806
1807     log_main("table_update: post");
1808   }
1809
1810   function room_sitdown($user, $table_idx)
1811   {
1812       log_main("room_sitdown ".($user == FALSE ? "USER: FALSE" : "USER: ".$user->name));
1813
1814       $train_app = "";
1815
1816       if ($table_idx > -1 && $table_idx < TABLES_N) {
1817           $table = $this->table[$table_idx];
1818
1819           // wagon shutdown
1820           if ($table->wag_own != -1 && $table->player_n == PLAYERS_N) {
1821               for ($i = 0 ; $i < TABLES_N ; $i++) {
1822                   if ($table->wag_own == $table->player[$i]) {
1823                       $train_app = sprintf("tra.rem(%d); ", $table_idx);
1824                       $table->wag_reset(time());
1825                       break;
1826                   }
1827               }
1828           }
1829       }
1830
1831       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1832           $ret = "";
1833           $user_cur = $this->user[$i];
1834           if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') // is not active user or the stat isn't 'room'
1835               continue;
1836
1837           $ret = "gst.st = ".($user_cur->step+1)."; ".$train_app;
1838           if ($table_idx > -1)
1839               $ret .= $this->table_content($user_cur, $table_idx);
1840           $ret .= $this->standup_content($user_cur);
1841
1842           if ($user->idx_get() == $i) {
1843               $ret .=  'subst = "sitdown"; tra.hide(); ';
1844               // clean the action buttons in other tables
1845               for ($e = 0 ; $e < TABLES_N ; $e++) {
1846                   $ret .= $this->table[$e]->act_content($user_cur);
1847               }
1848           }
1849           else if ($table_idx > -1) {
1850               if ($table->player_n == PLAYERS_N) {
1851
1852                   $ret .= $table->act_content($user_cur);
1853               }
1854           }
1855           $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1856           $user_cur->step_inc();
1857       }
1858   }
1859
1860   function kickuser($user, $out_reas)
1861   {
1862       $curtime = time();
1863
1864       fprintf(STDERR, "MOP: GHOST_SESS: %d\n", $out_reas);
1865
1866       $this->ghost_sess->push($curtime, $user->sess, $out_reas);
1867
1868       fprintf(STDERR, "MOP: status out: %s %s %d\n", $user->stat, $user->subst, $user->idx);
1869       if ($user->stat == 'table' && $user->subst != 'sitdown') {
1870           $bin5 = &$this->match[$user->table];
1871           $user_bin5 = &$bin5->user[$user->table_pos];
1872           fprintf(STDERR, "MOP: status in: %s %s %d\n", $user_bin5->stat, $user_bin5->subst, $user_bin5->idx);
1873           $bin5->table_wakeup($user_bin5);
1874           $user->the_end = TRUE;
1875           $this->room_wakeup($user);
1876           return;
1877       }
1878
1879       if ($user->stat == 'table' || $user->stat == 'room') {
1880           $user->the_end = TRUE;
1881           if ($user->subst == 'sitdown' || $user->stat == 'table') {
1882               $this->room_wakeup($user);
1883           }
1884           else if ($user->subst == 'standup') {
1885               fprintf(STDERR, "MOP: KICK here [%s]\n", btrace_line(debug_backtrace()));
1886               $this->room_outstandup($user);
1887           }
1888           else {
1889               log_rd2("LOGOUT FROM WHAT ???");
1890           }
1891       }
1892   }
1893
1894   function kickuser_by_name($name, $out_reas)
1895   {
1896       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1897           $user_out = $this->user[$i];
1898           if (strcmp($user_out->name, $name) == 0) {
1899               return ($this->kickuser($user_out, $out_reas));
1900           }
1901       }
1902       return FALSE;
1903   }
1904
1905   function kickuser_by_sess($sess, $out_reas)
1906   {
1907       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1908           $user_out = $this->user[$i];
1909           if (strcmp($user_out->sess, $sess) == 0) {
1910               return ($this->kickuser($user_out, $out_reas));
1911           }
1912       }
1913       return FALSE;
1914   }
1915
1916   function kickuser_by_idx($idx, $out_reas)
1917   {
1918       $user_out = $this->user[$idx];
1919       return ($this->kickuser($user_out, $out_reas));
1920   }
1921
1922   function chatt_send($user, $mesg, $mlang_indwr = NULL)
1923   {
1924     GLOBAL $G_base, $G_alarm_passwd, $mlang_brisk, $G_lang;
1925     $only_you = FALSE;
1926
1927     fprintf(STDERR, "WE ARE HERE: [%s]\n", $mesg);
1928
1929     // common settings
1930     $msg = mb_substr($mesg, 6, 128, "UTF-8");
1931     $curtime = time();
1932     $dt = date("H:i ", $curtime);
1933     $target = "";
1934
1935     //
1936     //  Compute actions
1937     //
1938
1939     $to_user     = FALSE;
1940     $to_all      = FALSE;
1941     $to_room     = FALSE;
1942     $to_tabl     = FALSE;
1943     $is_normchat = FALSE;
1944     /* for old isolation management $is_ticker   = FALSE; */
1945     $update_room = FALSE;
1946
1947     if (strcmp($msg,  "/tav") == 0 ||
1948         strncmp($msg, "/tav ", 5) == 0) {
1949       do {
1950         if ($user->stat != 'room' || $user->subst != 'sitdown') {
1951           /* 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>" */
1952           $msg = $mlang_brisk['tickmust'][$G_lang];
1953           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1954
1955           break;
1956         }
1957
1958         $table = $this->table[$user->table];
1959
1960         if ($table->wag_own != -1) {
1961           // MLANG <br>Il messaggio di segnalazione del tavolo &egrave; gi&agrave; attivato.<br><br>
1962           $msg = $mlang_brisk['tickjust'][$G_lang];
1963           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1964
1965           break;
1966         }
1967
1968         $dtime = $curtime - $table->wag_tout;
1969         if ($dtime  < EXPIRE_TIME_WAG) {
1970           // MLANG - <br>Il messaggio di segnalazione del tavolo<br>&egrave; disattivato ancora per %d second%s.<br><br>
1971           $msg = sprintf($mlang_brisk['tickwait'][$G_lang],
1972                          EXPIRE_TIME_WAG - $dtime, (EXPIRE_TIME_WAG - $dtime == 1 ? ($G_lang == 'en' ? "" : "o") : ($G_lang == 'en' ? "s" : "i")));
1973           $to_user = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang] , 400, 100);
1974
1975           break;
1976         }
1977
1978         $msg = substr($msg, 5);
1979
1980         $table->wag_set($user->idx_get(), $msg);
1981         $to_user = sprintf('tra.add(%d, "%s");', $user->table, xcape(sprintf("%s: %s", $user->name, $msg)));
1982         $to_room = $to_user;
1983         /* for old isolation management $is_ticker = TRUE; */
1984       } while (0);
1985     } // /tav chat command
1986     // just for development use currently
1987     else if (FALSE && strncmp($msg, "/out ", 5) == 0) {
1988         fprintf(STDERR, "MOP OUT\n");
1989         $target = substr($msg, 5);
1990         $this->kickuser_by_name($target, GHOST_SESS_REAS_ANON);
1991     }
1992     else if (strncmp($msg, "/alarm ", 7) == 0) {
1993       if (strncmp($msg, "/alarm to ", 10) == 0) {
1994         $sp_pos = strpos($msg, " ", 10);
1995         $target = substr($msg, 10, $sp_pos - 10);
1996         $alarm_check = "/alarm to ".$target." ".$G_alarm_passwd." ";
1997       }
1998       else {
1999         $target = "";
2000         $alarm_check = "/alarm ".$G_alarm_passwd." ";
2001       }
2002       do {
2003         if (strncmp($msg, $alarm_check, strlen($alarm_check)) != 0) {
2004           /* MLANG: "<br>La password digitata non &egrave; corretta.<br><br>" */
2005           $msg = $mlang_brisk['alarpass'][$G_lang];
2006           $to_user = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang], 400, 100);
2007
2008           break;
2009         }
2010
2011         /* MLANG: "Alarm <b>%s</b> inviato a <b>%s</b>." */
2012         $prestr = sprintf($mlang_brisk['alarret'][$G_lang], xcape(substr($msg, strlen($alarm_check))),
2013                            ($target == "" ? $mlang_brisk['tit_all'][$G_lang] : xcape($target)) );
2014         $to_user = nickserv_msg($dt, $prestr);
2015
2016         $msg = sprintf("<br><b>%s<br><br>%s</b><br><br>",
2017                        $dt.NICKSERV, xcape(substr($msg, strlen($alarm_check))));
2018         /* MLANG: "chiudi" */
2019         $to_all = show_notify($msg, 0, $mlang_brisk['btn_close'][$G_lang], 400, 120);
2020       } while (0);
2021     } // /alarm chat command
2022     else if (strncmp($msg, "/listen ", 8) == 0) {
2023       $arg = substr($msg, 8);
2024
2025       if (strcasecmp($arg, "isolation") == 0) {
2026         $flags_old = 0;
2027         if ($user->stat == 'room' && $user->subst == 'sitdown' &&
2028             $user->table >= TABLES_AUTH_N) {
2029           $to_user = nickserv_msg($dt, $mlang_brisk['listmust'][$G_lang]);
2030
2031         }
2032         else {
2033           $user->flags &= ~USER_FLAG_MAP_AUTH;
2034           $user->flags |= USER_FLAG_ISOLAUTH;
2035           $to_user = 'list_set(\'isolation\', true, \''.$mlang_brisk['tit_onisol'][$G_lang].'\'); ';
2036         }
2037       }
2038       else if (strcasecmp($arg, "auth") == 0) {
2039         $flags_old = $user->flags;
2040         $user->flags &= ~USER_FLAG_MAP_AUTH;
2041         $user->flags |= USER_FLAG_LISTAUTH;
2042         $to_user = 'list_set(\'auth\', true, \''.$mlang_brisk['tit_onauth'][$G_lang].'\'); ';
2043       }
2044       else {
2045         $flags_old = $user->flags;
2046         $user->flags &= ~USER_FLAG_MAP_AUTH;
2047         $to_user = 'list_set(\'all\', true, \'\'); ';
2048
2049       }
2050       // if from isolation redraw standup area
2051       if (($flags_old ^ $user->flags) & USER_FLAG_ISOLAUTH) {
2052         $to_user .= 'standup_data_old = null; '.$this->standup_content($user);
2053
2054       }
2055     }
2056     else if (strcmp($msg, "/authreq") == 0) {
2057         if ($user->is_cert()) {
2058             $to_user = sprintf('authbox(300,200);');
2059         }
2060         else {
2061             /* 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." */
2062             $to_user = nickserv_msg($dt, $mlang_brisk['authmust'][$G_lang]);
2063         }
2064     }
2065     else if (strncmp($msg, "/mesgtoadm", 8) == 0) {
2066         if ($user->is_auth()) {
2067         $to_user = sprintf('mesgtoadmbox(500,300);');
2068       }
2069       else {
2070         /* MLANG: "<b>Per inviare un messaggio devi essere autenticato.</b>" */
2071         $to_user = nickserv_msg($dt, $mlang_brisk['mesgmust'][$G_lang]);
2072       }
2073     }
2074     else if (FALSE && strncmp($msg, "/nick ", 6) == 0) {
2075       log_main("chatt_send BEGIN");
2076
2077       do {
2078         if (($name_new = validate_name(substr($msg, 6))) == FALSE) {
2079           $to_user = nickserv_msg($dt, $mlang_brisk['nickmust'][$G_lang]);
2080           break;
2081         }
2082
2083         $msg = "COMMAND ".$msg;
2084         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2085           $user_cur = $this->user[$i];
2086
2087           if ($user_cur->is_active() == FALSE)
2088             continue;
2089           if (strcasecmp($user_cur->name,$name_new) == 0)
2090             break;
2091           }
2092         if ($i <  MAX_PLAYERS) {
2093           $prestr = sprintf($mlang_brisk['nickdupl'][$G_lang], xcape($name_new));
2094           $to_user = nickserv_msg($dt, $prestr);
2095           break;
2096         }
2097
2098         /* 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>" */
2099         if ($user->is_auth()) {
2100           if (strcasecmp($user->name,$name_new) != 0) {
2101              if (( ($user->flags & USER_FLAG_MAP_AUTH) != USER_FLAG_ISOLAUTH) &&
2102                 ($user->subst == 'standup' ||
2103                  ($user->subst != 'standup' && $this->table[$user->table]->auth_type == TABLE_AUTH_TY_PUBL)
2104                  )
2105                 ) {
2106               $user->flags &= ~(USER_FLAG_AUTH | USER_FLAG_TY_ALL); // Remove auth if name changed
2107               for ($i = 0 ; $i < TABLES_N ; $i++) {
2108                 $to_user .= $this->table[$i]->act_content($user);
2109               }
2110             }
2111             else {
2112               $to_user = nickserv_msg($dt, $mlang_brisk['authchan'][$G_lang]);
2113               break;
2114             }
2115           }
2116         }
2117         $user->name = $name_new; // OK - nick changed
2118         /* se nome gia' in uso, segnala cosa potrebbe capitare */
2119         if ( ! $user->is_auth() ) {
2120             if (($bdb = BriskDB::create()) != FALSE) {
2121                 $bdb->users_load();
2122                 /* 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>" */
2123                 if ($bdb->login_exists(strtolower($name_new))) {
2124                     $prestr = sprintf($mlang_brisk['nickjust'][$G_lang], xcape($name_new));
2125                     $to_user .= nickserv_msg($dt, $prestr);
2126                 }
2127             }
2128         }
2129
2130         log_main("chatt_send start set");
2131
2132         $update_room = TRUE;
2133       } while (0);
2134     } // nick chat command
2135     else if (strncmp($msg, "/info ", 6) == 0) {
2136         do {
2137             if (! $user->is_auth()) {
2138                 if ($mlang_indwr) {
2139                     $to_user = nickserv_msg($dt, $mlang_indwr['info_auth'][$G_lang]);
2140                 }
2141                 else {
2142                     $to_user = nickserv_msg($dt, "error");
2143                 }
2144                 break;
2145             }
2146             $info_user = substr($msg, 6);
2147
2148             echo $this->info_show($user, urldecode($info_user), $dt);
2149         } while(0);
2150     }
2151     else if (strncmp($msg, "/prefsn", 7) == 0) {
2152         do {
2153             if (! $user->is_auth()) {
2154                 if ($mlang_indwr) {
2155                     $to_user = nickserv_msg($dt, $mlang_indwr['info_auth'][$G_lang]);
2156                 }
2157                 else {
2158                     $to_user = nickserv_msg($dt, "error");
2159                 }
2160                 break;
2161             }
2162             echo $this->prefsn_show($user, $dt);
2163         } while(0);
2164     }
2165     else if (strncmp($msg, "/st ", 4) == 0) {
2166       log_main("chatt_send BEGIN");
2167
2168       do {
2169         $st_str = substr($msg, 4);
2170
2171         if (strcasecmp($st_str, "normale") == 0) {
2172           $st = USER_FLAG_S_NORM;
2173         }
2174         else if (strcasecmp($st_str, "pausa") == 0) {
2175           $st = USER_FLAG_S_PAU;
2176         }
2177         else if (strcasecmp($st_str, "fuori") == 0) {
2178           $st = USER_FLAG_S_OUT;
2179         }
2180         else if (strcasecmp($st_str, "cane") == 0) {
2181           $st = USER_FLAG_S_DOG;
2182         }
2183         else if (strcasecmp($st_str, "cibo") == 0) {
2184           $st = USER_FLAG_S_EAT;
2185         }
2186         else if (strcasecmp($st_str, "lavoro") == 0) {
2187           $st = USER_FLAG_S_WRK;
2188         }
2189         else if (strcasecmp($st_str, "sigaretta") == 0) {
2190           $st = USER_FLAG_S_SMK;
2191         }
2192         else if (strcasecmp($st_str, "presente") == 0) {
2193           $st = USER_FLAG_S_EYE;
2194         }
2195         else if (strcasecmp($st_str, "coniglio") == 0) {
2196           $st = USER_FLAG_S_RABB;
2197         }
2198         else if (strcasecmp($st_str, "calcio") == 0) {
2199           $st = USER_FLAG_S_SOCC;
2200         }
2201         else if (strcasecmp($st_str, "pupo") == 0) {
2202           $st = USER_FLAG_S_BABY;
2203         }
2204         else if (strcasecmp($st_str, "pulizie") == 0) {
2205           $st = USER_FLAG_S_MOP;
2206         }
2207         else if (strcasecmp($st_str, "babbo") == 0) {
2208           $st = USER_FLAG_S_BABBO;
2209         }
2210         else if (strcasecmp($st_str, "renna") == 0) {
2211           $st = USER_FLAG_S_RENNA;
2212         }
2213         else if (strcasecmp($st_str, "pupazzo") == 0) {
2214           $st = USER_FLAG_S_PUPAZ;
2215         }
2216         else if (strcasecmp($st_str, "vischio") == 0) {
2217           $st = USER_FLAG_S_VISCH;
2218         }
2219         else {
2220           /* MLANG: "Questo stato non esiste." */
2221           $to_user = nickserv_msg($dt, $mlang_brisk['statunkn'][$G_lang]);
2222           break;
2223         }
2224
2225         log_main("chatt_send start set");
2226         if (($user->flags & USER_FLAG_S_ALL) != $st) {
2227           $update_room = TRUE;
2228           $user->flags = ($user->flags & ~USER_FLAG_S_ALL) | $st;
2229         }
2230       } while (0);
2231     } // nick chat command
2232
2233     else { // normal chat line
2234       $is_normchat = TRUE;
2235       if (CHAT_ENABLED && $curtime < ($user->chat_ban + $user->chat_dlt)) {
2236         $only_you = TRUE;
2237         $user->chat_dlt = $user->chat_dlt * 2;
2238         if ($user->chat_dlt > 120)
2239           $user->chat_dlt = 120;
2240       }
2241       else if ($user->chat_lst == $msg)
2242         $only_you = TRUE;
2243       else if (CHAT_ENABLED && $curtime - $user->chattime[($user->chat_cur + 1) % CHAT_N] < CHAT_ILL_TIME) {
2244         $user->chat_ban = $curtime;
2245         $user->chat_dlt = 5;
2246         $only_you = TRUE;
2247       }
2248       else {
2249         $user->chat_ban = 0;
2250         $user->chat_dlt = 0;
2251       }
2252
2253       if ($only_you) {
2254         $to_user = sprintf('chatt_sub("%s",[%d,"%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape("== chat ban =="));
2255       }
2256       else {
2257           // TEMPORARY DISABLED UNTIL test user option will be available
2258           // if ( TRUE && (!$user->is_auth() || $user->is_appr()) ) {
2259           if (!$user->is_auth()) {
2260               $to_user = nickserv_msg($dt, xcape("Visto l'elevato numero di molestatori che ultimamente hanno preso dimora su Brisk abbiamo deciso"));
2261               $to_user .= nickserv_msg($dt, xcape("di disattivare temporaneamente la chat in room per i non registrati, non ce ne vogliate e buone feste."));
2262               if (FALSE) {
2263                   $aug_head = array("Tanti", "Tantissimi", "Un enormità", "Un milione", "Un' esagerazione");
2264                   $aug_body = array("a tutti gli utenti", "a tutti gli uomini", "a tutte le donne", "a tutti gli utenti");
2265                   $aug_tail = array("di Brisk", "del sito", "della ciurma", "della comitiva", "del gruppo");
2266
2267                   $auguri = sprintf("%s auguri %s %s.",
2268                                     $aug_head[mt_rand(0, count($aug_head)-1)],
2269                                     $aug_body[mt_rand(0, count($aug_body)-1)],
2270                                     $aug_tail[mt_rand(0, count($aug_tail)-1)]);
2271
2272                   $to_room = sprintf('chatt_sub("%s",[%d,"%s"],"%s");', $dt, $user->flags, xcape($user->name),
2273                                      xcape($auguri));
2274               }
2275           }
2276           else {
2277               $to_user = sprintf('chatt_sub("%s",[%d,"%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape($msg));
2278               // temporary silentiation for troll (will became array check)
2279               // if (strcasecmp($user->name,'JackRokka') != 0 && $user->sess != '47ea653f602e8')
2280               $to_room = $to_user;
2281           }
2282       }
2283
2284       log_legal($curtime, $user->ip, $user,
2285                 ($user->stat == 'room' ? 'room' : 'table '.$user->table),$msg);
2286
2287       $user->chat_lst = "$msg";
2288       $user->chattime[$user->chat_cur % CHAT_N] = $curtime;
2289       $user->chat_cur++;
2290     }
2291
2292     if ($to_all) {
2293       $to_room = $to_all;
2294       $to_tabl = $to_all;
2295     }
2296
2297     //
2298     //  Output to clients
2299     //
2300
2301     if ($to_user != FALSE) {
2302       $user->comm[$user->step % COMM_N] =  "gst.st = ".($user->step+1)."; ";
2303       $user->comm[$user->step % COMM_N] .= $to_user;
2304       $user->step_inc();
2305     }
2306
2307     if ($to_room != FALSE) {
2308       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2309         $user_cur = $this->user[$i];
2310         if ($target != "" && $user_cur->name != $target)
2311           continue;
2312         if ($user_cur->is_active() == FALSE // is not active user
2313             || $user_cur->stat == 'table'   // or stat is 'table'
2314             || $user->idx_get() == $i)      // or the $user idx is equal to current var
2315           continue;
2316
2317         if ($is_normchat == TRUE) {
2318           // use MAP_AUTH to check if auth or isolation
2319           if ($user_cur->flags & USER_FLAG_MAP_AUTH) {
2320               if ( ! $user->is_auth() ) {
2321                   continue;
2322               }
2323           }
2324         }
2325         /*
2326         else if ($is_ticker) {
2327           if (($user_cur->flags & USER_FLAG_MAP_AUTH) == USER_FLAG_ISOLAUTH) {
2328             if ($user->table >= TABLES_AUTH_N)
2329               continue;
2330           }
2331         }
2332         */
2333         $user_cur->comm[$user_cur->step % COMM_N] =  "gst.st = ".($user_cur->step+1)."; ";
2334         $user_cur->comm[$user_cur->step % COMM_N] .= $to_room;
2335         $user_cur->step_inc();
2336       }
2337     }
2338
2339     if ($to_tabl) {
2340         // FIXME BRISK4: include for each kind of table
2341         require_once("${G_base}briskin5/Obj/briskin5.phh");
2342         // Before all align times with table timeout
2343         for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
2344             if (isset($this->match[$table_idx])) {
2345                 $bin5 = $this->match[$table_idx];
2346
2347                 $bin5_table = $bin5->table[0];
2348                 for ($i = 0 ; $i < $bin5_table->player_n ; $i++) {
2349                     // stat must be "table" by definition
2350                     $bin5_user = $bin5->user[$i];
2351
2352                     if ($target != "" && $bin5_user->name != $target)
2353                         continue;
2354                     log_main("writa: ".$user_mesg);
2355                     $bin5_user->comm[$bin5_user->step % COMM_N] = "gst.st = ".($bin5_user->step+1)."; ";
2356                     $bin5_user->comm[$bin5_user->step % COMM_N] .= $to_tabl;
2357                     $bin5_user->step_inc();
2358                 }
2359             } // if (isset($this->match
2360         } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
2361     } // if ($to_tabl == true ...
2362
2363     if ($update_room) {
2364       if ($user->stat == 'room' && $user->subst == 'standup') {
2365         $this->standup_update($user);
2366       }
2367       else if ($user->stat == 'room' && $user->subst == 'sitdown') {
2368         log_main("chatt_send pre table update");
2369         $this->table_update($user);
2370         log_main("chatt_send post table update");
2371       }
2372     } // if ($update_room ...
2373
2374     return;
2375   } // function chatt_send( ...
2376
2377   function get_user($sess, &$idx)
2378   {
2379       GLOBAL $PHP_SELF;
2380
2381       if (validate_sess($sess)) {
2382           for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2383               if ($this->user[$i]->is_empty())
2384                   continue;
2385               if (strcmp($sess, $this->user[$i]->sess) == 0) {
2386                   // find it
2387                   $idx = $i;
2388                   $ret = $this->user[$i];
2389                   return ($ret);
2390               }
2391           }
2392           log_main(sprintf("get_user: Wrong sess from page [%s]",$PHP_SELF));
2393           // for ($i = 0 ; $i < MAX_PLAYERS ; $i++)
2394           // log_main(sprintf("get_user: Wrong sess compared with [%s]",$this->user[$i]->sess));
2395       }
2396       else {
2397           log_main(sprintf("get_user: Wrong strlen [%s]",$sess));
2398       }
2399
2400       return (FALSE);
2401   }
2402
2403   /*
2404    * function add_user(&$brisk, &$sess, &$idx, $name, $pass, $ip, $header, $cookie)
2405    *
2406    * RETURN VALUE:
2407    *   if ($idx >  -1    && ret == FALSE)  =>  duplicated nick
2408    *   if ($idx == -2    && ret == FALSE)  =>  invalid name
2409    *   if ($idx == -3    && ret == FALSE)  =>  wrong password
2410    *   if ($idx == -1    && ret == FALSE)  =>  no space left
2411    *   if ($idx ==  0    && ret == user)   =>  SUCCESS
2412    *   if ($idx == -($idx + 1) && ret == user)   =>  SUCCESS (but the login exists in the auth db)
2413    */
2414
2415   function add_user(&$sess, &$idx, $name, $pass, $ip, $header, $cookie)
2416   {
2417     GLOBAL $G_base;
2418
2419     $idx = 0;
2420
2421     $authenticate = FALSE;
2422     $user_type    = 0;
2423     $login_exists = FALSE;
2424     $ghost = -1;
2425     $ghost_auth = FALSE;
2426     $idx = -1;
2427     $idfree = -1;
2428     $code = FALSE;
2429
2430     if (($name_new = validate_name($name)) == FALSE) {
2431       $idx = -2;
2432       return (FALSE);
2433     }
2434
2435     log_auth("XXX", sprintf("ARRIVA: [%s] pass:[%s]", $sess, ($pass == FALSE ? "FALSE" : $pass)));
2436     if (validate_sess($sess) == FALSE)
2437       $sess = "";
2438
2439     /* if pass != FALSE verify the login with pass */
2440     log_auth("XXX", "auth1");
2441
2442     if (($bdb = BriskDB::create()) != FALSE) {
2443         $bdb->users_load();
2444         if ($pass != FALSE) { // TODO: here add a method to $bdb to check if the db is available.
2445             log_auth("XXX", "auth2");
2446             $authenticate = $bdb->login_verify($name_new, $pass, $code);
2447             log_auth("XXX", "authenticate: ".($authenticate != FALSE ? "TRUE" : "FALSE"));
2448
2449             if ($authenticate != FALSE) {
2450                 $user_type = $authenticate->type_get();
2451             }
2452             else {
2453                 $idx = -3;
2454                 return (FALSE);
2455             }
2456         }
2457         else {
2458             $login_exists =  $bdb->login_exists(strtolower($name_new));
2459         }
2460     }
2461     else {
2462         // if db is down, send a warning and verify only current users
2463         // no actions at this moment
2464     }
2465     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
2466         /* free user ? */
2467         if ($this->user[$i]->is_empty()) {
2468             if ($idfree == -1) {
2469                 $idfree = $i;
2470             }
2471             continue;
2472         }
2473         if (strcmp($sess, $this->user[$i]->sess) == 0) {
2474             if ($idx == -1) {
2475                 $idx = $i;
2476             }
2477         }
2478         if (strcasecmp($this->user[$i]->name, $name_new) == 0) {
2479             if ($authenticate != FALSE) {
2480                 $ghost = $i;
2481                 $ghost_auth = $this->user[$i]->is_auth();
2482             }
2483             else {
2484                 $idx = $i;
2485                 break;
2486             }
2487         }
2488     }
2489     if ($idx == -1)
2490       $idx = $idfree;
2491
2492     log_auth("XXX", sprintf("TROVATO A QUESTO PUNTO [%d] sess [%s] name [%s]", $idx, $sess, $name_new));
2493
2494     /* there is another user logged with your account and you and him have authenticated => new user
2495        get the session of the old user */
2496     if ($ghost > -1 && $ghost_auth && ($authenticate != FALSE)) {
2497       /* swap session */
2498
2499       $ghost_user = $this->user[$ghost];
2500       $curtime = time();
2501       $this->ghost_sess->push($curtime, $ghost_user->sess, GHOST_SESS_REAS_ANOT);
2502       $ghost_user->comm[$ghost_user->step % COMM_N] = "";
2503       $ghost_user->step_inc();
2504       if ($sess == "") {
2505         $sess = uniqid("");
2506         $ghost_user->sess = $sess;
2507       }
2508       else {
2509         $ghost_user->sess = $sess;
2510       }
2511
2512       // If user at the table we need to update the table data too
2513       $table_idx = $ghost_user->table;
2514       if ($ghost_user->stat == "table" && $this->table[$table_idx]->player_n == PLAYERS_N) {
2515           require_once("${G_base}briskin5/Obj/briskin5.phh");
2516           if (isset($this->match[$table_idx])) {
2517               $bin5 = $this->match[$table_idx];
2518
2519               if ($bin5->the_end != TRUE) {
2520                   $bin5->user[$ghost_user->table_pos]->comm[$bin5->user[$ghost_user->table_pos]->step % COMM_N] = "";
2521                   $bin5->user[$ghost_user->table_pos]->step_inc();
2522                   $bin5->user[$ghost_user->table_pos]->sess = $sess;
2523               }
2524           }
2525       }
2526
2527       $idx = $ghost;
2528       if (defined('CURL_DE_SAC_VERS')) {
2529           brisk_cds_execute($this, $ghost, $idx, $sess, $ip, $authenticate, $header);
2530       }
2531       return ($this->user[$ghost]);
2532     }
2533     else if ($idx != -1 && $i == MAX_PLAYERS) {
2534       /* SUCCESS */
2535       $curtime = time();
2536       if ($sess == "") {
2537         $sess = uniqid("");
2538         $this->user[$idx]->sess = $sess;
2539       }
2540       else {
2541         $this->user[$idx]->sess = $sess;
2542       }
2543       $this->user[$idx]->name = $name_new; // OK - add new user
2544       $this->user[$idx]->stat_set("room");
2545       $this->user[$idx]->step_set(0);
2546       while (array_pop($this->user[$idx]->comm) != NULL);
2547       $this->user[$idx]->subst = "standup";
2548       $this->user[$idx]->lacc =   $curtime;
2549       $this->user[$idx]->laccwr = $curtime;
2550       $this->user[$idx]->bantime = 0;
2551       $this->user[$idx]->ip = $ip;
2552
2553       $this->user[$idx]->rec = $authenticate;
2554       $this->user[$idx]->flags = $user_type;
2555       $this->user[$idx]->flags |= ($authenticate != FALSE ? USER_FLAG_AUTH : 0x00);
2556       $this->user[$idx]->flags |= ( ($pass != FALSE && $bdb == FALSE) ? USER_FLAG_DBFAILED : 0x00);
2557       log_auth("XXX", sprintf("FLAGS: [%x]", $this->user[$idx]->flags));
2558       $this->user[$idx]->flags_cur = $this->user[$idx]->flags;
2559       if ($authenticate != FALSE) {
2560           $this->user[$idx]->code = $authenticate->code_get();
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:
3532        name length must be less or equal than 12 chars,
3533        no more than 2 consecutive same character (or generic digits) are allowed */
3534 function login_consistency($name)
3535 {
3536     $old_c = '';
3537     if (($len = mb_strlen($name)) > 12) {
3538         return FALSE;
3539     }
3540
3541     for ($i = 0 ; $i < mb_strlen($name) ; $i++) {
3542         $c = mb_substr($name, $i, 1);
3543         if (mb_ereg_match ("[a-zA-Z0-9]", $c)) {
3544             if (mb_ereg_match ("[0-9]", $c)) {
3545                 $c = "0";
3546             }
3547             if ($old_c != $c) {
3548                 $old_c = $c;
3549                 $old_ct = 1;
3550             }
3551             else {
3552                 $old_ct++;
3553                 if ($old_ct > 2) {
3554                     return (FALSE);
3555                 }
3556             }
3557         }
3558         else {
3559             return (FALSE);
3560         }
3561     }
3562     return (TRUE);
3563 }
3564 ?>