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