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