Warranty form management added, server_request() enhanced, states management added
[brisk.git] / web / Obj / brisk.phh
1 <?php
2 /*
3  *  brisk - brisk.phh
4  *
5  *  Copyright (C) 2006-2008 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, 32);
31 define(PLAYERS_N, 3);
32 define(MAX_POINTS, 5);
33 define(MAX_PLAYERS, (20 + (PLAYERS_N * TABLES_N)));
34 define(SHM_DIMS_MIN, (50000 + 10000 * TABLES_N + 15000 * MAX_PLAYERS));
35 define(SHM_DIMS_MAX, SHM_DIMS_MIN + 1048576);
36 define(SHM_DIMS_DLT, 65536);
37  
38 define(COMM_N, 18);
39 define(COMM_GEN_N, 50);
40
41 define(CHAT_N, 3);
42 define(CHAT_ILL_TIME, 6);
43
44 define(SESS_LEN, 13);
45 define(STREAM_TIMEOUT, 20);
46 define(EXPIRE_TIME_RD, 180);
47 define(EXPIRE_TIME_SMAMMA, 360); 
48 define(EXPIRE_TIME_WAG, 10);
49 define(WAKEUP_TIME, 12); 
50 // BAN_TIME da allineare anche in commons.js
51 define(BAN_TIME, 3600); 
52 define(GARBAGE_TIMEOUT, 10);
53 define(NICKSERV, "<i>BriskServ</i>");
54
55 define(DBG_ONL2, 0x0001);
56 define(DBG_ONLY, 0x0002);
57 define(DBG_MAIN, 0x0004);
58 define(DBG_READ, 0x0008);
59 define(DBG_REA2, 0x0010);
60 define(DBG_SEND, 0x0020);
61 define(DBG_LOCK, 0x0040);
62 define(DBG_WRIT, 0x0080);
63 define(DBG_LOAD, 0x0100);
64 define(DBG_AUTH, 0x0200);
65 define(DBG_CRIT, 0x0400);
66
67 define(BRISK_DEBUG, 0);
68
69 define(BRISK_SINGLE_DEBUG,0);
70 define(BRISK_SINGLE_SESS, "");
71 // define(DEBUGGING, "local");
72
73 require_once("$DOCUMENT_ROOT/Etc/".BRISK_CONF);
74
75 $G_false = FALSE;
76
77 $G_all_points = array( 11,10,4,3,2, 0,0,0,0,0 );
78 $G_brisk_version = "2.1.3 - trusty";
79
80 $root_wellarr = Array ( 'Brisk (Ver. '.$G_brisk_version.'), <b>NOVITA\'</b>: Garanzia dal sito e stato degli utenti (guarda l\'help).',
81                         'Se vuoi iscriverti alla <a target="_blank" href="http://www.milug.org/cgi-bin/mailman/listinfo/ml-briscola">Mailing List</a>, cliccala!' );
82 $table_wellarr = Array ( 'Benvenuto al tavolo. Se almeno tre giocatori non sbloccano l\'uscita cliccando il lucchetto, chi esce non pu&ograve; risedersi a un qualunque tavolo per '.floor(BAN_TIME/60).' minuti.');
83
84
85 $G_room_help= '
86 <div style=\\"text-align: left; padding: 8px;\\">
87 <b>Descrizione</b><br>
88 Questa รจ un\'implementazione della briscola in cinque, cos&igrave; come &egrave; spiegata su
89 <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>
90 <b>Configurazione del browser.</b><br>
91 Occorre abilitare i cookies.<br>
92 <br>
93 <b>Uso del sito</b><br>
94 Potete sedervi a un tavolo o rimanere in piedi.<br>
95 Se al vostro tavolo si raggiungono i 5 giocatori inizia automaticamente la partita.<br>
96 <br>
97 <b>Partita</b><br>
98 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>
99 Chi vince l\'asta dovr&agrave; decidere il seme della carta scelta e inizier&agrave; la mano.<br>
100 Per giocare le carte dovrete trascinarle nel quadrato al centro del vostro schermo.<br><br>
101 Il vostro turno &egrave; sempre segnalato da una cornice verde lampeggiante intorno al quadrato al centro del vostro schermo.<br><br>
102 Durante la partita, se vorrete ricaricare la pagina, usate l\'apposito bottone \\"reload\\" in basso a destra.<br>
103 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.
104 <dl>
105 <dt><b>Comandi della chat</b>
106 <dd><b>/nick <i>&lt;nuovo_nickname&gt;</i></b> - cambio di nickname
107 <dd><b>/tav <i>&lt;frase di invito&gt;</i></b> - invito per gli altri giocatori al tavolo dove si &egrave; seduti 
108 <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\\" oppure \\"sigaretta\\"
109 <dd><b>/garante</b> - se si &egrave; autenticati permette di garantire per un utente fidato
110 </dl>
111 </div>
112 ';
113
114 //  
115
116 $G_room_about= '<br>
117 <div id=\\"header\\" class=\\"header\\">
118   <img class=\\"nobo\\" src=\\"img/brisk_logo64.png\\">
119   briscola chiamata in salsa ajax
120 </div>
121 <br><b>version '.$G_brisk_version.'</b><br><br>
122 Copyright 2006-2008 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>';
123
124
125 function xcape($s)
126 {
127   $from = array (   '\\',     '@',        '|' );
128   $to   = array ( '\\\\', '&#64;', '&brvbar;' );
129
130   return (str_replace($from, $to, htmlentities($s,ENT_COMPAT,"UTF-8")));
131 }
132
133 function xcapelt($s)
134 {
135   $from = array (   '\\',     '|' );
136   $to   = array ( '\\\\',   '\\|' );
137
138   return (str_replace($from, $to, $s));
139 }
140
141 class Card {
142   var $value; /* 0 - 39 card value */
143   var $stat;  /* 'bunch', 'hand', 'table', 'take' */
144   var $owner; /* (table position 0-4) */
145   // var $pos;   /* Pos in hand. */
146   var $x;     /* When played the X position on the table of the owner. */
147   var $y;     /* When played the Y position on the table of the owner. */
148
149   function Card($value, $stat, $owner)
150   {
151     $this->value = $value;
152     $this->stat  = $stat; // Card stat
153     $this->owner = $owner;
154   }
155
156   function assign($stat,$owner)
157   {
158     $this->stat  = $stat; // Card stat
159     $this->owner = $owner;
160   }
161
162   function setpos($pos)
163   {
164     $this->pos   = $pos;
165   }
166
167   function play($x,$y)
168   {
169     $this->stat = 'table'; // Card stat
170     $this->x = $x;
171     $this->y = $y;
172   }
173
174   function take($newown)
175   {
176     $this->stat = 'take'; // Card stat
177     $this->owner = $newown;
178   }
179 } // end class Card
180
181 class Table {
182   var $idx;
183   var $player;
184   var $player_n;
185   var $card;
186   var $mazzo;
187   var $gstart;
188   var $turn;
189   var $auth_only;
190
191   var $wag_own;
192   var $wag_com;
193   var $wag_tout;
194
195   var $asta_pla;
196   var $asta_pla_n;
197   var $asta_card;
198   var $asta_pnt;
199   
200   var $mult;
201   var $points;    // points array
202   var $points_n;  // number of row of points
203   var $total;
204
205   var $asta_win;
206   var $briscola;
207   var $friend;
208   
209   var $old_reason;
210   var $old_asta_pnt;
211   var $old_pnt;
212   var $old_win;
213   var $old_friend;
214
215   var $table_token;
216   var $table_start;
217
218   var $wakeup_time;
219
220   function Table() 
221   {
222   }
223   
224   function &create($idx) 
225   {
226     GLOBAL $G_false;
227
228     if (($thiz =& new Table()) == FALSE)
229       return ($G_false);
230
231     $thiz->idx       =   $idx;
232     $thiz->player    =   array();
233     $thiz->player_n  =   0;
234     $thiz->card      =   FALSE;
235     $thiz->asta_pla  =   array(); // TRUE: in auction, FALSE: out of the auction
236     $thiz->asta_pla_n=  -1;
237     $thiz->asta_card =  -1;
238     $thiz->asta_pnt  =  -1;
239     $thiz->mult      =   1;
240     
241     $thiz->auth_only =   FALSE;
242
243     $thiz->points    =   array( );
244     $thiz->points_n  =   0;
245     $thiz->total     =   array( 0, 0, 0, 0, 0);
246     $thiz->asta_win  =  -1;
247     $thiz->briscola  =  -1;
248     $thiz->friend    =  -1;
249     $thiz->turn      =   0;
250
251     $thiz->wag_own   =  NULL;
252     $thiz->wag_com   =  "";
253     $thiz->wag_tout   =  0;
254
255     $thiz->old_reason   = "";
256     $thiz->old_asta_pnt = -1;
257     $thiz->old_pnt      = -1;
258     $thiz->old_win      = -1;
259     $thiz->old_friend   = -1;
260
261     $thiz->table_token  = "";
262     $thiz->table_start  = 0;
263     
264     $thiz->wakeup_time = 0;
265
266     return ($thiz);
267   }
268
269   function &clone(&$from)
270   {
271     GLOBAL $G_false;
272     
273     if (($thiz =& new Table()) == FALSE)
274       return ($G_false);
275     
276     $thiz->idx = $from->idx;
277     $thiz->player = array();
278     for ($i = 0 ; $i < $from->player_n ; $i++)
279       $thiz->player[$i] = $from->player[$i];
280     $thiz->player_n = $from->player_n;
281     $thiz->card = $from->card;
282     $thiz->mazzo = $from->mazzo; // REVIEW
283     $thiz->gstart = $from->gstart;
284     $thiz->turn = $from->turn;
285
286     $thiz->auth_only =  $from->auth_only;
287
288     $thiz->wag_own   =  $from->wag_own;
289     $thiz->wag_com   =  $from->wag_com;
290     $thiz->wag_tout  =  $from->wag_taut;
291
292     $thiz->asta_pla = $from->asta_pla;
293     $thiz->asta_pla_n = $from->asta_pla_n;
294     $thiz->asta_card = $from->asta_card;
295     $thiz->asta_pnt = $from->asta_pnt;
296     
297     $thiz->mult = $from->mult;
298     $thiz->points = $from->points;
299     $thiz->points_n = $from->points_n;
300     $thiz->total = $from->total;
301     
302     $thiz->asta_win = $from->asta_win;
303     $thiz->briscola = $from->briscola;
304     $thiz->friend = $from->friend;
305     
306     $thiz->old_reason = $from->old_reason;
307     $thiz->old_asta_pnt = $from->old_asta_pnt;
308     $thiz->old_pnt = $from->old_pnt;
309     $thiz->old_win = $from->old_win;
310     $thiz->old_friend = $from->old_friend;
311
312     $thiz->table_token  = $from->table_token;
313     $thiz->table_start  = $from->table_start;
314
315     $thiz->wakeup_time = $from->wakeup_time;
316
317     return ($thiz);
318   }
319   
320   function &spawn(&$from)
321   {
322     GLOBAL $G_false;
323     
324     if (($thiz =& new Table()) == FALSE)
325       return ($G_false);
326     
327     $thiz->idx = $from->idx;
328     $thiz->player_n = $from->player_n;
329     $thiz->card = &$thiz->bunch_create();
330     $thiz->mazzo = $from->mazzo;
331     $thiz->gstart = $from->gstart;
332     $thiz->turn = $from->turn;
333
334     $thiz->auth_only =  $from->auth_only;
335
336     $thiz->wag_own = $from->wag_own;
337     $thiz->wag_com = $from->wag_com;
338     $thiz->wag_tout  =  $from->wag_taut;
339
340     $thiz->asta_pla = $from->asta_pla;
341     $thiz->asta_pla_n = $from->asta_pla_n;
342     $thiz->asta_card = $from->asta_card;
343     $thiz->asta_pnt = $from->asta_pnt;
344     
345     $thiz->mult = $from->mult;
346     $thiz->points = $from->points;
347     $thiz->points_n = $from->points_n;
348     $thiz->total = $from->total;
349     
350     $thiz->asta_win = $from->asta_win;
351     $thiz->briscola = $from->briscola;
352     $thiz->friend = $from->friend;
353     
354     $thiz->old_reason = $from->old_reason;
355     $thiz->old_asta_pnt = $from->old_asta_pnt;
356     $thiz->old_pnt = $from->old_pnt;
357     $thiz->old_win = $from->old_win;
358     $thiz->old_friend = $from->old_friend;
359
360     // players are rearranged in an dedicated array
361     $thiz->player = array();
362     for ($i = 0 ; $i < $from->player_n ; $i++)
363       $thiz->player[$i] = $i;
364
365     $thiz->table_token  = $from->table_token;
366     $thiz->table_start  = $from->table_start;
367
368     $thiz->wakeup_time = $from->wakeup_time;
369
370     return ($thiz);
371   }
372   
373   function &bunch_create()
374   {
375     $ret = array();
376
377     for ($i = 0 ; $i < 40 ; $i++) {
378       $ret[$i] =& new Card($i, 'bunch', 'no_owner');
379     }
380
381     $oret = &$ret;
382     return ($oret);
383   }
384
385   function wag_set(&$user, $mesg)
386   {
387     log_main("WAG_SET");
388
389     $this->wag_own  = &$user;
390     $this->wag_com  =  $mesg;
391     $this->wag_tout =  0;
392   }
393
394   function wag_reset($timeout)
395   {
396     log_main("WAG_RESET");
397
398     unset($this->wag_own);
399     $this->wag_own = NULL;
400     $this->wag_com  = "";
401     $this->wag_tout = $timeout;
402   }
403
404   function bunch_make()
405   {
406     $ct = array(0,0,0,0,0);
407     
408     mt_srand(make_seed());
409     
410     for ($i = 39 ; $i >= 0 ; $i--) 
411       $rest[$i] = $i;
412
413     for ($i = 39 ; $i >= 0 ; $i--) {
414       $rn = rand(0, $i);
415       
416       if ($rn == 0)
417         log_main("RND ZERO");
418       
419       $id = $rest[$rn];
420
421       $owner = $i % 5;
422       $this->card[$id]->assign('hand', $owner);
423
424       $rest[$rn] = $rest[$i];
425       // $pubbpos[$rn2] = $pubbpos[$i];
426     }
427   }
428
429   function init(&$userarr)
430   {
431     $this->mazzo    = rand(0,PLAYERS_N-1);
432     $this->points_n = 0;
433     $this->mult     = 1;
434     $this->old_win  =-1;
435     $this->old_reason = "";
436     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
437       $this->total[$i] = 0;
438       $user_cur = &$userarr[$this->player[$i]];
439       $user_cur->exitislock = TRUE;
440     }
441
442     log_main("table::init: ci siamo");
443   }
444
445   function game_init(&$userarr)
446   {
447     log_rd2("GSTART 4");
448
449     $this->gstart = ($this->mazzo+1) % PLAYERS_N;
450     $this->bunch_make();
451     
452     
453     $this->asta_pla_n = PLAYERS_N;
454     $this->asta_card = -1;
455     $this->asta_pnt  = 60;
456     $this->asta_win  = -1;
457     $this->briscola  = -1;
458     $this->friend    = -1;
459     $this->turn      =  0;
460     
461     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
462       $this->asta_pla[$i] = TRUE;
463       $user_cur = &$userarr[$this->player[$i]];
464       $user_cur->subst = 'asta';
465       $user_cur->asta_card = -2;
466       $user_cur->asta_pnt  = -1;
467       $user_cur->handpt = $this->hand_points($i);
468       // SEE function calculate_points(&$table)
469     }
470   }
471
472   function game_next()
473   {
474     $this->mazzo  = ($this->mazzo + 1) % PLAYERS_N;
475   }
476
477   function getPlayer($idx)
478   {
479     return ($this->player[$idx]);
480   }
481
482   function setPlayer($idx, $player)
483   {
484     $this->player[$idx] = $player;
485   }
486
487   function user_add($idx)
488   {
489     $this->player[$this->player_n] = $idx;
490     $this->player_n++;
491     
492     return ($this->player_n - 1);
493   }
494   
495   function user_rem(&$room, &$user)
496   {
497     $tabpos = $user->table_pos;
498     
499     /* verifico la consistenza dei dati */
500     if ($room->user[$this->player[$tabpos]] == $user) {
501       
502       /* aggiorna l'array dei giocatori al tavolo. */
503       for ($i = $tabpos ; $i < $this->player_n-1 ; $i++) {
504         $this->player[$i] = $this->player[$i+1];
505         $user_cur = &$room->user[$this->player[$i]];
506         $user_cur->table_pos = $i;
507       }
508       $this->player_n--;
509     }
510     else {
511       log_main("INCONSISTENCY ON TABLE.");
512     }
513   }
514
515   function hand_points($idx)
516   {
517     GLOBAL $G_all_points; 
518     
519     $tot = 0;
520     
521     for ($i = 0 ; $i < 40 ; $i++) {
522       if ($this->card[$i]->owner != $idx)
523         continue;
524
525       $ctt = $this->card[$i]->value % 10;
526       $tot += $G_all_points[$ctt];
527     }
528
529     return ($tot);
530   }
531
532   function exitlock_show(&$userarr, $table_pos)
533   {
534     $ct = $this->exitlock_calc(&$userarr, $table_pos);
535
536     $ret = sprintf('exitlock_show(%d, %s);', $ct, 
537                    ($userarr[$this->player[$table_pos]]->exitislock ? 'true' : 'false'));
538     return ($ret);
539   }
540
541   function exitlock_calc(&$userarr, $table_pos)
542   {
543     $ct = 0;
544
545     for ($i = 0 , $ct = 0 ; $i < PLAYERS_N ; $i++) {    
546       if ($userarr[$this->player[$i]]->exitislock == FALSE)
547         $ct++;
548     }
549
550     return ($ct);
551   }
552
553
554
555
556   //      $ret .= table_act_content(($user->subst == 'standup'), $this->table[$i]->player_n, $i, $user->table, 
557   //                              ($this->table[$i]->auth_only == FALSE ? TRUE : $user->flags & USER_FLAG_AUTH));
558
559   // function act_content($isstanding, $sitted, $table, $cur_table, $allowed)
560   function act_content(&$user)
561   {
562     $ret = "";
563     $isstanding = ($user->subst == 'standup');
564     $sitted = $this->player_n;
565     $table = $this->idx;
566     $cur_table = $user->table;
567     $allowed = TRUE;
568
569     if ($isstanding) {
570       if ($sitted < PLAYERS_N) {
571         if ($this->auth_only) {
572           if ($user->flags & USER_FLAG_AUTH) 
573             $act = "sitreser";
574           else
575             $act = 'reserved';
576         }
577         else {
578           $act = 'sit';
579         }
580       }
581       else {
582         $act = 'none';
583       }
584     }
585     else {
586       if ($table == $cur_table)
587         $act = 'wake';
588       else
589         $act = 'none';
590     }
591     
592     if ($act != '')
593       $ret = sprintf('j_tab_act_cont(%d, \'%s\');', $table, $act);
594     
595     return ($ret);
596   }
597
598
599 } // end class Table
600   
601
602 // User flags
603 define(USER_FLAG_AUTH, 0x02);
604
605 //   user status
606 define(USER_FLAG_S_NORM,  0x000); // done
607 define(USER_FLAG_S_PAU,   0x100); // done
608 define(USER_FLAG_S_OUT,   0x200); // done
609 define(USER_FLAG_S_DOG,   0x300); // done
610 define(USER_FLAG_S_EAT,   0x400); // done
611 define(USER_FLAG_S_WRK,   0x500); // done
612 define(USER_FLAG_S_SMK,   0x600); // done
613
614 define(USER_FLAG_S_ALL,   0xf00); // done
615
616 class User {
617   var $name;       // name of the user
618   var $sess;       // session of the user
619   var $ip;         // ip of the user
620   var $lacc;       // last access (for the cleanup)
621   var $laccwr;     // last access (for the cleanup)
622   var $bantime;    // timeout to temporary ban
623   var $stat;       // status (outdoor, room, table, game, ...)
624   var $subst;      // substatus for each status   
625   var $step;       // step of the current status
626   var $trans_step; // step to enable transition between pages (disable == -1)
627   var $comm;       // commands array
628   var $asta_card;  // 
629   var $asta_pnt;   //
630   var $handpt;     // Total card points at the beginning of the current hand.
631   var $exitislock; // Player can exit from the table ?
632   var $table;      // id of the current table (if in table state)
633   var $table_pos;  // idx on the table
634   var $table_token;// token that identify a game on a table
635   var $flags;      // Bitfield with: AUTHENTICATE: 0x02 
636   var $the_end;    // Flag to change the end of the session
637
638   var $chat_lst;      // Last chat line
639   var $chattime;      // Array of chat times
640   var $chat_cur;      // Current chat line number
641   var $chat_ban;      // Time for ban chat
642   var $chat_dlt;      // Delta t for ban
643   function User() {
644   }
645
646   function &create($name, $sess, $stat = "", $subst = "", $table = -1, $ip="0.0.0.0") {
647     GLOBAL $G_false;
648
649     if (($thiz =& new User()) == FALSE)
650       return ($G_false);
651
652     $thiz->name  = $name;
653     $thiz->sess  = $sess;
654     $thiz->ip    = $ip;
655     $thiz->lacc   = time();
656     $thiz->laccwr = time();
657     $thiz->bantime = 0;
658     $thiz->stat  = $stat;
659     $thiz->subst  = $subst;
660     $thiz->step  = 1;
661     $thiz->trans_step  = -1;
662     $thiz->comm  = array();
663     $thiz->asta_card = -2;
664     $thiz->asta_pnt  = -1;
665     $thiz->handpt = -1;
666     $thiz->exitislock = TRUE;
667
668     $thiz->flags = 0x00;
669     
670     $thiz->chattime = array_fill(0, CHAT_N, 0);
671     $thiz->chat_cur = 0;
672     $thiz->chat_lst = "";
673     $thiz->chat_ban = 0;
674     $thiz->chat_dlt = 0;
675
676     $thiz->table = $table;
677     $thiz->table_pos = -1;
678     $thiz->table_token = "";
679
680     return ($thiz);
681   }
682
683   function &clone(&$from)
684   {
685     GLOBAL $G_false;
686     
687     if (($thiz =& new User()) == FALSE)
688       return ($G_false);
689     
690     $thiz->name       = $from->name;
691     $thiz->sess       = $from->sess;
692     $thiz->ip         = $from->ip;
693     $thiz->lacc       = $from->lacc;
694     $thiz->laccwr     = $from->laccwr;
695     $thiz->bantime    = $from->bantime;
696     $thiz->stat       = $from->stat;
697     $thiz->subst      = $from->subst;
698     $thiz->step       = $from->step;
699     $thiz->trans_step = $from->trans_step;
700     $thiz->comm       = array();
701
702     $i_start = (1 > ($from->step - COMM_N) ? 1 : ($from->step - COMM_N)); 
703     for ($i = $i_start ; $i < $from->step ; $i++) {
704       $ii = $i % COMM_N;
705       $thiz->comm[$ii] = $from->comm[$ii];
706     }
707     $thiz->asta_card  = $from->asta_card;
708     $thiz->asta_pnt   = $from->asta_pnt;
709     $thiz->handpt     = $from->handpt;
710     $thiz->exitislock = $from->exitislock;
711
712     $thiz->flags = $from->flags;
713
714     $thiz->chattime = array();
715     for ($i = 0 ; $i < CHAT_N ; $i++)
716       $thiz->chattime[$i] = $from->chattime[$i];
717     $thiz->chat_cur = $from->chat_cur;
718     $thiz->chat_lst = $from->chat_lst;
719     $thiz->chat_ban = $from->chat_ban;
720     $thiz->chat_dlt = $from->chat_dlt;
721
722     $thiz->table      = $from->table;
723     $thiz->table_pos  = $from->table_pos;
724     $thiz->table_token = $from->table_token;
725     $thiz->the_end    = $from->the_end;
726
727     return ($thiz);
728   }
729   
730   function &spawn(&$from, $table, $table_pos)
731   {
732     GLOBAL $G_false;
733     
734     if (($thiz =& new User()) == FALSE)
735       return ($G_false);
736     
737     $thiz->name       = $from->name;
738     $thiz->sess       = $from->sess;
739     $thiz->ip         = $from->ip;
740     $thiz->lacc       = $from->lacc;
741     $thiz->laccwr     = $from->laccwr;
742     $thiz->bantime    = $from->bantime;
743     $thiz->stat       = $from->stat;
744     $thiz->subst      = $from->subst;
745     $thiz->step       = $from->step;
746     $thiz->trans_step = $from->trans_step;
747     $thiz->comm       = array();
748
749     /*
750     $i_start = (1 > ($from->step - COMM_N) ? 1 : ($from->step - COMM_N)); 
751     for ($i = $i_start ; $i < $from->step ; $i++) {
752       log_wr("TRY PUSH:".$i);
753       $ii = $i % COMM_N;
754       $thiz->comm[$ii]   = $from->comm[$ii];
755     }
756     */
757     $thiz->asta_card  = $from->asta_card;
758     $thiz->asta_pnt   = $from->asta_pnt;
759     $thiz->handpt     = $from->handpt;
760     $thiz->exitislock = $from->exitislock;
761     $thiz->the_end    = $from->the_end;
762
763     $thiz->flags      = $from->flags;
764
765     $thiz->chattime   = array_fill(0, CHAT_N, 0);
766     $thiz->chat_cur   = 0;
767     $thiz->chat_lst   = "";
768     $thiz->chat_ban   = 0;
769     $thiz->chat_dlt   = 0;
770
771
772     $thiz->table      = $table;
773     $thiz->table_pos  = $table_pos;
774     $thiz->table_token = $from->table_token;
775
776     return ($thiz);
777   }
778   
779   function stat_set($stat) {
780     log_main("sess: [".$this->sess. "] NEW STAT: [".$stat."]"); 
781     $this->stat = "$stat";
782     
783     /*
784     if (validate_sess($this->sess)) {
785       if (file_exists(PROXY_PATH) == FALSE)
786         mkdir(PROXY_PATH);
787       $fp = fopen(PROXY_PATH."/".$this->sess.".stat", 'w');
788       fwrite($fp, sprintf("%s\n",$this->stat));
789       fclose($fp);
790     }
791     */
792   }
793
794   function step_set($step) {
795     $this->step = $step;
796     
797     do {
798       if (validate_sess($this->sess) == FALSE)
799         break;
800       if (file_exists(PROXY_PATH) == FALSE)
801         mkdir(PROXY_PATH);
802       if (($fp = @fopen(PROXY_PATH."/".$this->sess.".step", 'w')) == FALSE)
803         break;
804       fwrite($fp, pack("l",$this->step), 4);
805       fclose($fp);
806
807       return (TRUE);
808     } while (0);
809
810     return (FALSE);
811   }
812
813   function step_inc($delta = 1) {
814     $this->step += $delta;
815     
816     if (validate_sess($this->sess)) {
817       if (file_exists(PROXY_PATH) == FALSE)
818         mkdir(PROXY_PATH);
819       $fp = fopen(PROXY_PATH."/".$this->sess.".step", 'w');
820       fwrite($fp, pack("l",$this->step), 4);
821       fclose($fp);
822
823       return (TRUE);
824     }
825     
826     return (FALSE);
827   }
828
829   function reset() {
830     $curtime = time();
831     log_legal($curtime, $this->sess, $this->name, "STAT:LOGOUT", '');
832
833     $tmp_sess = $this->sess;
834     $this->sess = "";
835     step_unproxy($tmp_sess);
836     $this->name = "";  // OK here
837     while (array_pop($this->comm) != NULL);
838     $this->step = 0;
839     $this->chattime = array_fill(0, CHAT_N, 0);
840     $this->chat_cur = 0;
841     $this->chat_lst = "";
842     $this->chat_ban = 0;
843     $this->chat_dlt = 0;
844     $this->the_end = FALSE;
845   }
846 } // end class User
847
848
849 function step_get($sess) {
850   $fp = FALSE;
851   do {
852     if (validate_sess($sess) == FALSE)
853       break;
854
855     if (file_exists(PROXY_PATH) == FALSE)
856       mkdir(PROXY_PATH);
857     if (($fp = @fopen(PROXY_PATH."/".$sess.".step", 'rb')) == FALSE)
858       break;
859     if (($s = fread($fp, 4)) == FALSE)
860       break;
861     if (strlen($s) != 4)
862       break;
863     $arr = unpack('l', $s);
864     fclose($fp);
865
866     // log_rd2("A0: ".$arr[0]."  A1: ".$arr[1]);
867     return ($arr[1]);
868   } while (0);
869
870   if ($fp != FALSE)
871     fclose($fp);
872
873   log_rd2("STEP_GET: return false ");
874
875   return (FALSE);
876 }
877
878 function step_unproxy($sess) {
879   log_rd2("UNPROXY: ".PROXY_PATH."/".$sess.".step");
880   if (file_exists(PROXY_PATH) == FALSE)
881     mkdir(PROXY_PATH);
882   @unlink(PROXY_PATH."/".$sess.".step");
883 }
884
885
886 class Room {
887   var $user;
888   var $table;
889   var $comm; // commands for many people
890   var $step; // current step of the comm array
891   var $garbage_timeout;
892   var $shm_sz;
893
894   function Room () {
895     $this->user = array();
896     $this->table = array();
897
898     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
899       $this->user[$i] =& User::create("", "");
900     }
901
902     for ($i = 0 ; $i < TABLES_N ; $i++) {
903       $this->table[$i] =& Table::create($i);
904       if ($i < 12) {
905         $row = ( (((int)($i / 4)) % 2) == 0 );
906         $col = ($i % 2 == 0);
907         $this->table[$i]->auth_only = (($row && $col) || (!$row && !$col));
908       }
909       else {
910         $this->table[$i]->auth_only = FALSE;
911       }
912     }
913     $this->garbage_timeout = 0;
914   }
915
916   function garbage_manager($force)
917   {
918     $ismod = FALSE;
919
920     log_rd2("garbage_manager START");
921
922     /* Garbage collector degli utenti in timeout */
923     $curtime = time();
924     if ($force || $this->garbage_timeout < $curtime) {
925       
926       // Before all align times with table timeout
927       for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
928         $table_cur =& $this->table[$table_idx];
929         // if the table is complete and exists its shared mem we get the info about users lacc
930
931         if ($table_cur->player_n == PLAYERS_N) {
932           log_main("PLAYERS == N TABLE ".$table_idx);
933           
934           if (($sem = Briskin5::lock_data($table_idx)) != FALSE) { 
935             log_main("bin5 lock data success");
936             
937             $no_recovery = FALSE;
938             if (($bri = &Briskin5::load_data($table_idx)) != FALSE) {
939               if ($table_cur->table_token != $bri->table_token) {
940                 log_main("ERROR: not matching table_token. Room: ".$table_cur->table_token."  Table: ".$bri->table_token);
941                 log_main("ERROR: not matching table_start. Room: ".$table_cur->table_start."  Table: ".$bri->table_start);
942                 $no_recovery = TRUE;
943                 $bri = FALSE;
944               }
945             }
946             
947             if ($bri != FALSE) {
948               //
949               //  SPAWN: JOIN
950               //
951               log_main("garbage_manager: bri loaded successfully.");
952               $bri->garbage_manager(TRUE);
953               
954               $bri_table = &$bri->table[0];
955
956               // is the end of the table
957               if ($bri->the_end == TRUE) {
958                 /*
959                  *  DESTROY OF FINISHED TABLE && MOVE PLAYER TO ROOM AGAIN
960                  */
961                 log_main("garbage_manager: INSIDE THE END.");
962
963                 $plist = "$table_cur->table_token|$user_cur->table|$table_cur->player_n";
964                 for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
965                   $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
966                 }
967
968                 for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
969                   // stat must be "table" by definition
970                   $user_cur =& $this->user[$table_cur->player[$i]];
971                   $bri_user =& $bri->user[$i];
972                   
973                   $user_cur->subst      = $bri_user->subst;
974                   $user_cur->step       = $bri_user->step;
975                   $user_cur->lacc       = $bri_user->lacc;
976                   $user_cur->laccwr     = $bri_user->lacc;
977                   $user_cur->bantime    = $bri_user->bantime;
978                 }
979
980                 log_legal($curtime, $user_cur->sess, $user_cur->name, "STAT:DESTROY_GAME", $plist);
981
982                 $this->room_join_wakeup(&$user_cur, FALSE, 0); 
983                 $table_cur->table_token = "";
984                 $table_cur->wakeup_time = $curtime + WAKEUP_TIME;
985                 Briskin5::destroy_data($table_idx);
986               }
987               else {
988                 log_main("gm:: save_data");
989
990                 for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
991                   $this->user[$table_cur->player[$i]]->lacc = $bri->user[$i]->lacc;
992                 }
993               
994                 Briskin5::save_data(&$bri);
995               }
996             } // else if (($bri = &Briskin5::load_data($table_idx)) != FALSE) {
997             else if ($no_recovery == FALSE) {
998               log_crit("ERROR: table ".$table_idx." unrecoverable join");
999
1000               for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
1001                 $user_cur = &$this->user[$table_cur->player[$i]];
1002                 $user_cur->subst = "shutdowner";
1003                 $user_cur->step_inc();
1004                 
1005                 $ret = sprintf('stat = "%s"; subst = "%s";',  $user_cur->stat, $user_cur->subst);
1006                 $ret .= "gst.st = ".($user_cur->step+1)."; ";
1007                 $ret .= show_notify("<br>I dati del tavolo n&deg; ".$user_cur->table." sono inconsistenti, verranno resettati.<br><br>Torni in piedi.<br><br>", 2000, "Chiudi.", 400, 110);
1008                 $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1009                 $user_cur->step_inc();
1010               }
1011
1012               $plist = "$table_cur->table_token|$user_cur->table|$table_cur->player_n";
1013               for ($i = 0 ; $i < $table_cur->player_n ; $i++) {
1014                 $plist .= '|'.$this->user[$table_cur->player[$i]]->sess;
1015               }
1016               log_legal($curtime, $user_cur->sess, $user_cur->name, "STAT:DESTROY_GAME(RECOVERY)", $plist);
1017               
1018               $this->room_join_wakeup(&$user_cur, TRUE, -2); 
1019               $table_cur->table_token = "";
1020             }
1021
1022             Briskin5::unlock_data($sem);
1023           } // bri::lock_data
1024         } //  if ($table_cur->player_n == PLAYERS_N) {
1025       } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1026     
1027       log_rd2("out new loop.");
1028                 
1029       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1030         $user_cur = &$this->user[$i];
1031         
1032         log_rd2("User: ".$user_cur->name."  stat: ".$user_cur->stat."  subst: ".$user_cur->subst);
1033           
1034         if ($user_cur->sess == "") 
1035           continue;
1036         
1037         if ($user_cur->lacc + EXPIRE_TIME_RD < $curtime) {
1038           // Auto logout dell'utente
1039           log_rd2("AUTO LOGOUT.".($user_cur->lacc + EXPIRE_TIME_RD)." curtime ".$curtime);
1040           
1041           if ($user_cur->stat == 'table' || $user_cur->stat == 'room') {
1042             log_auth($user_cur->sess, "Autologout session.");
1043             
1044             $user_cur->reset();
1045             
1046             log_rd2("AUTO LOGOUT.");
1047             if ($user_cur->subst == 'sitdown' || $user_cur->stat == 'table')
1048               $this->room_wakeup(&$user_cur);
1049             else if ($user_cur->subst == 'standup')
1050               $this->room_outstandup(&$user_cur);
1051             else
1052               log_rd2("LOGOUT FROM WHAT ???");
1053           }
1054         }
1055
1056         if ($user_cur->laccwr + EXPIRE_TIME_SMAMMA < $curtime) { // lo rimettiamo in piedi
1057           if ($user_cur->stat == 'room' && $user_cur->subst == 'sitdown') {
1058             $this->room_wakeup(&$user_cur);
1059             $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
1060             $user_cur->comm[$user_cur->step % COMM_N] .=  show_notify("<br>Sei stato inattivo per ".(EXPIRE_TIME_SMAMMA/60.0)." minuti. <br><br>Quindi ritorni tra i <b>Giocatori in piedi</b>.", 0, "torna ai tavoli", 400, 100);
1061             $user_cur->step_inc();
1062           }
1063         }
1064       }
1065       log_rd2("GARBAGE UPDATED!");
1066       
1067       $this->garbage_timeout = time() + GARBAGE_TIMEOUT;
1068       $ismod = TRUE;
1069     }
1070
1071     return ($ismod);
1072   }
1073
1074   function show_room($user_step, &$user)
1075   {
1076     log_main("show_room: username: ".$user->name);
1077     
1078     
1079     $ret = sprintf('gst.st = %d; ',  $user_step);
1080     if ($user->subst == 'standup')
1081       $ret .= "tra.show(); ";
1082     else
1083       $ret .= "tra.hide(); ";
1084
1085     $ret .= sprintf('stat = "%s";',  $user->stat);
1086     
1087     $ret .= root_wellcome($user);
1088     $ret .= sprintf('subst = "%s";', $user->subst);
1089     $itin = ($user->flags & USER_FLAG_AUTH ? "<i>" : "");
1090     $itou = ($user->flags & USER_FLAG_AUTH ? "</i>" : "");
1091     $ret .= sprintf('$("myname").innerHTML = "<b>%s%s%s</b>";', $itin, xcape($user->name), $itou);
1092     for ($i = 0 ; $i < TABLES_N ; $i++) {
1093       $ret .= $this->table_content($user, $i);
1094       // $ret .= table_act_content(($user->subst == 'standup'), $this->table[$i]->player_n, $i, $user->table, 
1095       //                          ($this->table[$i]->auth_only == FALSE ? TRUE : $user->flags & USER_FLAG_AUTH));
1096       $ret .=  $this->table[$i]->act_content($user);
1097       if ($this->table[$i]->wag_own != NULL) 
1098         $ret .= sprintf('tra.add(%d, "%s: %s"); ', $i,  $this->table[$i]->wag_own->name, $this->table[$i]->wag_com);
1099       else 
1100         $ret .= sprintf('tra.rem(%d); ', $i);
1101     }
1102     $ret .= $this->standup_content($user);
1103     
1104     return ($ret);
1105   }
1106   
1107
1108   function room_wakeup(&$user)
1109   {
1110     $table_idx = $user->table;
1111     $table = &$this->table[$table_idx];
1112
1113     log_main("WAKEUP: begin function table:".$table_idx."  stat: ".$user->stat."  subst: ".$user->subst);
1114
1115     $curtime = time();
1116
1117     $from_table = ($user->stat == "table");
1118     if ($from_table) {
1119       log_main("WAKEUP: from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
1120
1121       for ($i = 0 ; $i < $table->player_n ; $i++) {
1122         $user_cur = &$this->user[$table->player[$i]];
1123         log_main("PREIMPOST: INLOOP name: ".$user_cur->name);
1124
1125         if ($user_cur != $user) {
1126           $user_cur->stat_set("room");
1127           $user_cur->subst = "sitdown";
1128           $user_cur->laccwr = $curtime;
1129         }
1130         else if ($user->sess != "") {
1131           $user_cur->stat_set("room");
1132           $user_cur->subst = "standup";
1133           $user_cur->laccwr = $curtime;
1134           $user_cur->table = -1;
1135         }
1136       }
1137     }
1138     else {
1139       $user->stat_set("room");
1140       $user->subst = "standup";
1141       $user->laccwr = $curtime;
1142     }
1143     
1144     $remove_wagon = false;
1145     if($table->wag_own == $user) {
1146       $remove_wagon = true;
1147       $table->wag_reset($curtime);
1148       
1149     }
1150     
1151
1152     /* aggiorna l'array dei giocatori al tavolo. */
1153     $table->user_rem(&$this, &$user);
1154
1155     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1156       $user_cur = &$this->user[$i];
1157       if ($user_cur->sess == '' || $user_cur->stat != 'room')
1158         continue;
1159       
1160       log_main("VALORI: name: ".$user_cur->name."from_table: ".$from_table."  tab: ".$user_cur->table." taix: ".$table_idx."  ucur: ".$user_cur."  us: ".$user);
1161
1162       $ret = "gst.st = ".($user_cur->step+1)."; ".($remove_wagon ? sprintf("tra.rem(%d);",$table_idx) : "");
1163       if ($from_table && ($user_cur->table == $table_idx || $user_cur == $user)) {
1164         $ret .= 'gst.st_loc++; the_end=true; window.onunload = null; window.onbeforeunload = null; document.location.assign("index.php");|';
1165         // $ret .= 'gst.st_loc++; document.location.assign("index.php");|';
1166         log_main("DOCUMENT.index.php: from table");
1167       }
1168       else if ($user_cur->stat == "room") {
1169         log_main("DOCUMENT.index.php: from table");
1170
1171         $ret .= $this->table_content($user_cur, $table_idx);
1172         $ret .= $this->standup_content($user_cur);
1173         
1174         // $ret .= table_act_content(FALSE, 0, $table_idx, $user->table, FALSE);
1175         $ret .= $table->act_content($user);
1176
1177         if ($user_cur == $user) {
1178           // set the new status 
1179           $ret .=  'subst = "standup"; tra.show(); ';
1180           // clean the action buttons in other tables
1181           for ($e = 0 ; $e < TABLES_N ; $e++) {
1182             if ($this->table[$e]->player_n < PLAYERS_N) {
1183               // $ret .= table_act_content(TRUE, 0, $e, $user->table, 
1184               //                           ($this->table[$e]->auth_only == FALSE ? TRUE : $user->flags & USER_FLAG_AUTH));
1185               $ret .= $this->table[$e]->act_content($user);
1186             }
1187           }
1188         }
1189         else {
1190           // $ret .= table_act_content(($user_cur->subst == 'standup'), $table->player_n, $table_idx, $user_cur->table,
1191           //                           ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
1192           $ret .= $table->act_content($user_cur);
1193         }
1194       }
1195       log_wr("ROOM_WAKEUP: ".$ret);
1196       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1197       $user_cur->step_inc();
1198     }
1199   }
1200
1201   function room_join_wakeup(&$user, $update_lacc = FALSE, $trans_delta)
1202   {
1203     $table_idx = $user->table;
1204     $table = &$this->table[$table_idx];
1205     
1206     log_main("JOIN_WAKEUP: begin function table:".$table_idx."  stat: ".$user->stat."  subst: ".$user->subst);
1207
1208     $curtime = time();
1209     $user_wup = array();
1210     $user_wup_n = 0;
1211     $user_tab = array();
1212     $user_tab_n = 0;
1213     log_main("JOIN WAKEUP: from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
1214     
1215     for ($i = 0 ; $i < $table->player_n ; $i++) {
1216       $user_cur = &$this->user[$table->player[$i]];
1217       log_main("PREIMPOST INLOOP name: ".$user_cur->name);
1218       if ($user_cur->sess != "") {
1219         if ($update_lacc == TRUE) {
1220           $user_cur->laccwr = $curtime;
1221         }
1222         log_main("cur: ".$user_cur->name."  subst: ".$user_cur->subst);
1223         if ($user_cur->subst == "shutdowned") {
1224           $user_cur->stat_set("room");
1225           $user_cur->subst = "sitdown";
1226         }
1227         else if ($user_cur->subst == "shutdowner") {
1228           $user_cur->stat_set("room");
1229           $user_cur->subst = "standup";
1230           $user_cur->table = -1;
1231           $user_wup[$user_wup_n++] = &$user_cur;
1232           
1233           $remove_wagon = false;
1234           if($table->wag_own == $user_cur) {
1235             $remove_wagon = true;
1236             $table->wag_reset($curtime);
1237           }
1238         }
1239         $user_tab[$user_tab_n++] = &$user_cur;
1240       }
1241     }
1242
1243     for ($wup_idx = 0 ; $wup_idx < $user_wup_n  ; $wup_idx++)
1244       $table->user_rem(&$this, &$user_wup[$wup_idx]);
1245
1246     /* aggiorna l'array dei giocatori al tavolo. */
1247
1248     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1249       log_main("START LOOP");
1250       $user_cur = &$this->user[$i];
1251       if ($user_cur->sess == '' || $user_cur->stat != 'room') {
1252         log_main("name: ".$user_cur->name."skip   subst: ".$user_cur->subst);
1253         continue;
1254       }
1255
1256       log_main("___");
1257       log_main("VALORI name: ".$user_cur->name."  tab: ".$user_cur->table." taix: ".$table_idx."  ucur: ".$user_cur."  us: ".$user);
1258
1259       $ret = "gst.st = ".($user_cur->step+1)."; ".($remove_wagon ? sprintf("tra.rem(%d);",$table_idx) : "");
1260       if ($user_cur->stat == "room") {
1261         log_main("DOCUMENT.index.php from table");
1262
1263         $ret .= $this->table_content($user_cur, $table_idx);
1264         $ret .= $this->standup_content($user_cur);
1265         
1266         // $ret .= table_act_content(FALSE, 0, $table_idx, $user_cur->table,
1267         //                           ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
1268         $ret .= $table->act_content($user_cur);
1269
1270
1271         for ($tab_idx = 0 ; $tab_idx < $user_tab_n  ; $tab_idx++)
1272           if ($user_cur == $user_tab[$tab_idx]) 
1273             break;
1274
1275         // for users that wakeup the room will be reconstructed by index_rd.php
1276         if ($tab_idx < $user_tab_n) {
1277           log_main("PRE show_room username: ".$user_cur->name."  STEP: ".$user_cur->step);
1278
1279 //        ARRAY_POP DISABLED
1280 //        if ($trans_delta == 0)
1281 //          while (array_pop($user_cur->comm) != NULL);
1282
1283           $user_cur->trans_step = $user_cur->step + 1 + $trans_delta;
1284           $user_cur->comm[$user_cur->step % COMM_N] = "";
1285           $user_cur->step_inc();
1286           $user_cur->comm[$user_cur->step % COMM_N] = $this->show_room(($user_cur->step + 1), &$user_cur);
1287           $user_cur->step_inc();
1288           log_main("POST show_room username: ".$user_cur->name."  STEP: ".$user_cur->step);
1289
1290           continue;
1291         }
1292         log_main("JOIN_WAKEUP wup_idx ".$wup_idx."  wup_n ".$user_wup_n);
1293
1294         log_main("JOIN_WAKEUP more");
1295         // $ret .= table_act_content(($user_cur->subst == 'standup'), $table->player_n, $table_idx, $user_cur->table,
1296         //                           ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
1297         $ret .= $table->act_content($user_cur);
1298
1299         log_main("JOIN_WAKEUP end more");
1300       }
1301       log_wr("ROOM_JOIN_WAKEUP: ".$ret);
1302       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1303       $user_cur->step_inc();
1304     }
1305   }
1306
1307   function room_outstandup(&$user)
1308   {
1309     $this->room_sitdown(&$user, -1);
1310   }
1311   
1312   function table_update(&$user)
1313   {
1314     log_main("table_update: pre - USER: ".$user->name);
1315
1316     $table_idx = $user->table;
1317
1318     if ($table_idx > -1) 
1319       $table = &$this->table[$table_idx];
1320     
1321     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1322       $ret = "";
1323       $user_cur = &$this->user[$i];
1324       if ($user_cur->sess == '' || $user_cur->stat != 'room')
1325       continue;
1326       
1327       $ret = "gst.st = ".($user_cur->step+1)."; ";
1328       if ($table_idx > -1)
1329         $ret .= $this->table_content($user_cur, $table_idx);
1330       
1331       if ($user_cur == $user) {
1332         $itin = ($user->flags & USER_FLAG_AUTH ? "<i>" : "");
1333         $itou = ($user->flags & USER_FLAG_AUTH ? "</i>" : "");
1334         $ret .= sprintf('$("myname").innerHTML = "<b>%s%s%s</b>: ";', $itin, xcape($user->name), $itou);
1335       }
1336       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1337       $user_cur->step_inc();
1338     }
1339
1340     log_main("table_update: post");
1341   }
1342
1343   function room_sitdown(&$user, $table_idx)
1344   {
1345     log_main("room_sitdown ".($user == FALSE ? "USER: FALSE" : "USER: ".$user->name));
1346
1347     $train_app = "";
1348
1349     if ($table_idx > -1 && $table_idx < TABLES_N) { 
1350       $table = &$this->table[$table_idx];
1351
1352       // wagon shutdown 
1353       if ($table->wag_own != NULL && $table->player_n == PLAYERS_N) {        
1354         for ($i = 0 ; $i < TABLES_N ; $i++) {
1355           $user_cur =& $this->user[$table->player[$i]];
1356           if ($user_cur == $table->wag_own) {
1357             $train_app = sprintf("tra.rem(%d); ", $table_idx); 
1358             $table->wag_reset(time());
1359             break;
1360           }
1361         }
1362       }
1363     }
1364
1365     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1366       $ret = "";
1367       $user_cur = &$this->user[$i];
1368       if ($user_cur->sess == '' || $user_cur->stat != 'room')
1369       continue;
1370       
1371       $ret = "gst.st = ".($user_cur->step+1)."; ".$train_app;
1372       if ($table_idx > -1)
1373       $ret .= $this->table_content($user_cur, $table_idx);
1374       $ret .= $this->standup_content($user_cur);
1375       
1376       if ($user_cur == $user) {
1377         $ret .=  'subst = "sitdown"; tra.hide(); ';
1378         // clean the action buttons in other tables
1379         for ($e = 0 ; $e < TABLES_N ; $e++) {
1380           // $ret .= table_act_content(FALSE, 0, $e, $user_cur->table, FALSE);
1381           $ret .= $this->table[$e]->act_content($user_cur);
1382         }
1383       }
1384       else if ($table_idx > -1) {
1385         if ($table->player_n == PLAYERS_N) {
1386           // $ret .= table_act_content(($user_cur->subst == 'standup'), PLAYERS_N, $table_idx, $user_cur->table,
1387           ///                      ($table->auth_only == FALSE ? TRUE : $user_cur->flags & USER_FLAG_AUTH));
1388           $ret .= $table->act_content($user_cur);
1389         }
1390       }
1391       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1392       $user_cur->step_inc();
1393     }
1394   }
1395
1396   function chatt_send(&$user, $mesg)
1397   {
1398     GLOBAL $G_alarm_passwd;
1399     $only_you = FALSE;
1400     
1401     // common settings
1402     $msg = substr($mesg, 6, 128);
1403     $curtime = time();
1404     $dt = date("H:i ", $curtime);
1405
1406     //
1407     //  Compute actions
1408     //
1409
1410     $to_user     = FALSE;
1411     $to_all      = FALSE;
1412     $to_room     = FALSE;
1413     $to_tabl     = FALSE;
1414     $update_room = FALSE;
1415
1416     if (strcmp($msg,  "/tav") == 0 || 
1417         strncmp($msg, "/tav ", 5) == 0) {
1418       do {
1419         if ($user->stat != 'room' || $user->subst != 'sitdown') {
1420           $msg = "<br>Per attivare il messaggio di segnalazione del tavolo occorre essere seduti.<br><br>";
1421           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1422
1423           break;
1424         }
1425
1426         $table = &$this->table[$user->table];
1427         
1428         if ($table->wag_own != NULL) {
1429           $msg = "<br>Il messaggio di segnalazione del tavolo &egrave; gi&agrave; attivato.<br><br>";
1430           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1431
1432           break;
1433         }
1434
1435         $dtime = $curtime - $table->wag_tout;
1436         if ($dtime  < EXPIRE_TIME_WAG) {
1437           $msg = sprintf("<br>Il messaggio di segnalazione del tavolo<br>&egrave; disattivato ancora per %d second%s.<br><br>",
1438                          EXPIRE_TIME_WAG - $dtime, (EXPIRE_TIME_WAG - $dtime == 1 ? "o" : "i"));
1439           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1440
1441           break;
1442         }
1443         
1444         $msg = substr($msg, 5);
1445         
1446         $table->wag_set($user, $msg);
1447         $to_user = sprintf('tra.add(%d, "%s");', $user->table, xcape(sprintf("%s: %s", $user->name, $msg)));
1448         $to_room = $to_user;
1449         
1450       } while (0);
1451     } // /tav chat command
1452
1453     else if (strncmp($msg, "/alarm ", 7) == 0) {
1454       if (strncmp($msg, "/alarm to ", 10) == 0) {
1455         $sp_pos = strpos($msg, " ", 10);
1456         $target = substr($msg, 10, $sp_pos - 10);
1457         $alarm_check = "/alarm to ".$target." ".$G_alarm_passwd." ";
1458       }
1459       else {
1460         $target = "";
1461         $alarm_check = "/alarm ".$G_alarm_passwd." ";
1462       }
1463       do {
1464         if (strncmp($msg, $alarm_check, strlen($alarm_check)) != 0) {
1465           $msg = "<br>La password digitata non &egrave; corretta.<br><br>";
1466           $to_user = show_notify($msg, 0, "chiudi", 400, 100);
1467
1468           break;
1469         }
1470
1471         $to_user = sprintf('chatt_sub("%s", [2, "%s"],"Alarm <b>%s</b> inviato a <b>%s</b>.");', 
1472                            $dt, NICKSERV, xcape(substr($msg, strlen($alarm_check))), 
1473                            ($target == "" ? "tutti" : xcape($target)) );
1474
1475         $msg = sprintf("<br><b>%s<br><br>%s</b><br><br>",
1476                        $dt.NICKSERV, xcape(substr($msg, strlen($alarm_check))));
1477         $to_all = show_notify($msg, 0, "chiudi", 400, 120);
1478       } while (0);
1479     } // /alarm chat command
1480     else if (strncmp($msg, "/garante", 8) == 0) {
1481       if ($user->flags & USER_FLAG_AUTH) {
1482         $to_user = sprintf('authbox(300,200);');
1483       }
1484       else {
1485         $to_user = sprintf('chatt_sub("%s", [2, "%s"],"<b>Per autenticare qualcuno devi a tua volta essere autenticato.</b>");', $dt, NICKSERV);
1486       }
1487     }
1488     else if (strncmp($msg, "/nick ", 6) == 0) {
1489       log_main("chatt_send BEGIN");
1490
1491       do {
1492         if (($name_new = validate_name(substr($msg, 6))) == FALSE) {
1493           $to_user = sprintf('chatt_sub("%s", [2,"%s"],"Il nickname deve contenere almeno una lettera dell\'alfabeto o una cifra.");', $dt, NICKSERV);
1494           break;
1495         }
1496
1497         $msg = "COMMAND ".$msg;
1498         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1499           $user_cur = &$this->user[$i];
1500
1501           if ($user_cur->sess == '')
1502             continue;
1503           if ($user_cur->name == $name_new)
1504             break;
1505           }
1506         if ($i <  MAX_PLAYERS) {
1507           $to_user = sprintf('chatt_sub("%s", [2, "%s"],"Nickname <b>%s</b> gi&agrave; in uso.");', $dt, NICKSERV, xcape($name_new));
1508           break;
1509         }
1510         
1511         if ($user->flags & USER_FLAG_AUTH) {
1512           if (strcasecmp($user->name,$name_new) != 0) {
1513             if ($user->subst == 'standup' || ($user->subst != 'standup' && $this->table[$user->table]->auth_only == FALSE)) {
1514               $user->flags &= ~USER_FLAG_AUTH; // Remove auth if name changed
1515               for ($i = 0 ; $i < TABLES_N ; $i++) {
1516                 $to_user .= $this->table[$i]->act_content($user);
1517               }
1518             }
1519             else {
1520               $to_user = sprintf('chatt_sub("%s", [2, "%s"],"<b>Non puoi cambiare nick a un tavolo per soli autenticati.</b>");', $dt, NICKSERV);
1521               break;
1522             }
1523           }
1524         }
1525         $user->name = $name_new; // OK - nick changed
1526         
1527         /* se nome gia' in uso, segnala cosa potrebbe capitare */
1528         if (($user->flags & USER_FLAG_AUTH) == 0) {
1529           $userdb = new LoginDB();
1530           if ($userdb->login_exists($name_new)) {
1531             $to_user .= sprintf('chatt_sub("%s", [2, "%s"],"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>");', $dt, NICKSERV, xcape($name_new));
1532           }
1533         }
1534
1535         log_main("chatt_send start set");
1536
1537         $update_room = TRUE;
1538       } while (0);
1539     } // nick chat command
1540
1541     else if (strncmp($msg, "/st ", 4) == 0) {
1542       log_main("chatt_send BEGIN");
1543
1544       do {
1545         $st_str = substr($msg, 4);
1546         
1547         if (strcasecmp($st_str, "normale") == 0) {
1548           $st = USER_FLAG_S_NORM;
1549         }
1550         else if (strcasecmp($st_str, "pausa") == 0) {
1551           $st = USER_FLAG_S_PAU;
1552         }
1553         else if (strcasecmp($st_str, "fuori") == 0) {
1554           $st = USER_FLAG_S_OUT;
1555         }
1556         else if (strcasecmp($st_str, "cane") == 0) {
1557           $st = USER_FLAG_S_DOG;
1558         }
1559         else if (strcasecmp($st_str, "cibo") == 0) {
1560           $st = USER_FLAG_S_EAT;
1561         }
1562         else if (strcasecmp($st_str, "lavoro") == 0) {
1563           $st = USER_FLAG_S_WRK;
1564         }
1565         else if (strcasecmp($st_str, "sigaretta") == 0) {
1566           $st = USER_FLAG_S_SMK;
1567         }
1568         else {
1569           $to_user = sprintf('chatt_sub("%s", [2,"%s"],"Questo stato non esiste.");', $dt, NICKSERV);
1570           break;
1571         }
1572
1573         log_main("chatt_send start set");
1574         if (($user->flags & USER_FLAG_S_ALL) != $st) {
1575           $update_room = TRUE;
1576           $user->flags = ($user->flags & ~USER_FLAG_S_ALL) | $st;
1577         }
1578       } while (0);
1579     } // nick chat command
1580
1581     else { // normal chat line
1582       if ($curtime < ($user->chat_ban + $user->chat_dlt)) {
1583         $only_you = TRUE;
1584         $user->chat_dlt = $user->chat_dlt * 2; 
1585         if ($user->chat_dlt > 120)
1586           $user->chat_dlt = 120; 
1587       }
1588       else if ($user->chat_lst == $msg)
1589         $only_you = TRUE;
1590       else if ($curtime - $user->chattime[($user->chat_cur + 1) % CHAT_N] < CHAT_ILL_TIME) {
1591         $user->chat_ban = $curtime;
1592         $user->chat_dlt = 5;
1593         $only_you = TRUE;
1594       }
1595       else {
1596         $user->chat_ban = 0;
1597         $user->chat_dlt = 0;
1598       }
1599
1600       if ($only_you) {
1601         $to_user = sprintf('chatt_sub("%s", [%d, "%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape("== chat ban =="));
1602       }
1603       else {
1604         $to_user = sprintf('chatt_sub("%s", [%d, "%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape($msg));
1605         // temporary silentiation for troll (will became array check)
1606         if (strcasecmp($user->name,'JackRokka') != 0 && $user->sess != '47ea653f602e8')
1607           $to_room = $to_user;
1608       }
1609
1610       log_legal($curtime, $user->sess, $user->name, 
1611                 ($user->stat == 'room' ? 'room' : 'table '.$user->table),$msg);
1612       
1613       $user->chat_lst = "$msg";
1614       $user->chattime[$user->chat_cur % CHAT_N] = $curtime;
1615       $user->chat_cur++;
1616     }
1617
1618     if ($to_all) {
1619       $to_room = $to_all;
1620       $to_tabl = $to_all;
1621     }
1622
1623     //
1624     //  Output to clients
1625     //
1626
1627     if ($to_user != FALSE) {
1628       $user->comm[$user->step % COMM_N] =  "gst.st = ".($user->step+1)."; ";
1629       $user->comm[$user->step % COMM_N] .= $to_user;
1630       $user->step_inc();
1631     }
1632
1633     if ($to_room != FALSE) {
1634       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1635         $user_cur = &$this->user[$i];
1636         if ($target != "" && $user_cur->name != $target)
1637           continue;
1638         //      if ($user_cur->sess == '' || $user_cur->stat != 'room')
1639         if ($user_cur->sess == '' || $user_cur->stat == 'table' || $user_cur == $user)
1640           continue;
1641         
1642         $user_cur->comm[$user_cur->step % COMM_N] =  "gst.st = ".($user_cur->step+1)."; ";
1643         $user_cur->comm[$user_cur->step % COMM_N] .= $to_room; 
1644         $user_cur->step_inc();
1645       }
1646     }
1647     
1648     if ($to_tabl) {
1649       // Before all align times with table timeout
1650       for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1651         $table_cur =& $this->table[$table_idx];
1652         // if the table is complete and exists its shared mem we get the info about users lacc
1653         
1654         if ($table_cur->player_n == PLAYERS_N) {
1655           log_main("PLAYERS == N TABLE ".$table_idx);
1656         
1657           if (($sem = Briskin5::lock_data($table_idx)) != FALSE) { 
1658             log_main("bin5 lock data success");
1659             
1660             $no_recovery = FALSE;
1661             if (($bri = &Briskin5::load_data($table_idx)) != FALSE) {
1662               if ($table_cur->table_token != $bri->table_token) {
1663                 log_main("ERROR: not matching table_token. Room: ".$table_cur->table_token."  Table: ".$bri->table_token);
1664                 $bri = FALSE;
1665               }
1666             }
1667             
1668             if ($bri != FALSE) {
1669               $bri_table = &$bri->table[0];
1670               for ($i = 0 ; $i < $bri_table->player_n ; $i++) {
1671                 // stat must be "table" by definition
1672                 $bri_user =& $bri->user[$i];
1673               
1674                 if ($target != "" && $bri_user->name != $target)
1675                   continue;
1676                 log_main("writa: ".$user_mesg);
1677                 $bri_user->comm[$bri_user->step % COMM_N] = "gst.st = ".($bri_user->step+1)."; ";
1678                 $bri_user->comm[$bri_user->step % COMM_N] .= $to_tabl;
1679                 $bri_user->step_inc();
1680               }
1681               Briskin5::save_data(&$bri);
1682             }
1683             Briskin5::unlock_data($sem);
1684           } // bri::lock_data
1685         } //  if ($table_cur->player_n == PLAYERS_N) {
1686       } //  for ($table_idx = 0 ; $table_idx < TABLES_N ; $table_idx++) {
1687     } // if ($to_tabl == true ...
1688
1689     if ($update_room) {
1690       if ($user->stat == 'room' && $user->subst == 'standup') {
1691         $this->standup_update(&$user);
1692       }
1693       else if ($user->stat == 'room' && $user->subst == 'sitdown') {
1694         log_main("chatt_send pre table update");
1695         $this->table_update(&$user);
1696         log_main("chatt_send post table update");
1697       }
1698     } // if ($update_room ...
1699
1700     return;
1701   } // function chatt_send( ...
1702
1703   function &get_user($sess, &$idx)
1704   {
1705     GLOBAL $PHP_SELF, $G_false;
1706
1707     if (validate_sess($sess)) {
1708       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1709         if (strcmp($sess, $this->user[$i]->sess) == 0) {
1710           // find it
1711           $idx = $i;
1712           $ret = &$this->user[$i];
1713           return ($ret);
1714         }
1715       }
1716       log_main(sprintf("get_user: Wrong sess from page [%s]",$PHP_SELF));
1717       // for ($i = 0 ; $i < MAX_PLAYERS ; $i++) 
1718       // log_main(sprintf("get_user: Wrong sess compared with [%s]",$this->user[$i]->sess));
1719     }
1720     else {
1721       log_main(sprintf("get_user: Wrong strlen [%s]",$sess));
1722     }
1723
1724     return ($G_false);
1725   }
1726
1727   
1728
1729   /*
1730    * function &add_user(&$room, &$sess, &$idx, $name, $pass, $ip)
1731    *
1732    * RETURN VALUE:
1733    *   if ($idx >  -1    && ret == FALSE)  =>  duplicated nick
1734    *   if ($idx == -2    && ret == FALSE)  =>  invalid name
1735    *   if ($idx == -3    && ret == FALSE)  =>  wrong password
1736    *   if ($idx == -1    && ret == FALSE)  =>  no space left
1737    *   if ($idx ==  0    && ret == user)   =>  SUCCESS
1738    *   if ($idx == -$idx && ret == user)   =>  SUCCESS (but the login exists in the auth db 
1739    */
1740
1741
1742
1743   function &add_user(&$sess, &$idx, $name, $pass, $ip)
1744   {
1745     GLOBAL $G_false;
1746
1747     $idx = 0;
1748
1749     $authenticate = FALSE;
1750     $login_exists = FALSE;
1751     $ghost = -1;
1752     $ghost_auth = FALSE;
1753     $idx = -1;
1754     $idfree = -1;
1755     
1756     if (($name_new = validate_name($name)) == FALSE) {
1757       $idx = -2;
1758       return ($G_false);
1759     }
1760
1761     log_auth("XXX", sprintf("ARRIVA: [%s] pass:[%s]", $sess, ($pass == FALSE ? "FALSE" : $pass)));
1762     if (validate_sess($sess) == FALSE) 
1763       $sess = "";
1764
1765     /* if pass != FALSE verify the login with pass */
1766     log_auth("XXX", "auth1");
1767     $userdb = new LoginDB();
1768     if ($pass != FALSE) {
1769       log_auth("XXX", "auth2");
1770       $authenticate = $userdb->login_verify($name_new, $pass);
1771       log_auth("XXX", "authenticate: ".($authenticate == TRUE ? "TRUE" : "FALSE"));
1772       
1773       if ($authenticate == FALSE) {
1774         $idx = -3;
1775         return ($G_false);
1776       }
1777     }
1778     else {
1779       $login_exists =  $userdb->login_exists($name_new);
1780     }
1781     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1782       /* free user ? */
1783       if (strcmp($sess, $this->user[$i]->sess) == 0) {
1784         if ($idx == -1)
1785           $idx = $i;
1786       }
1787       if ($idfree == -1 && strcmp("", $this->user[$i]->sess) == 0) {
1788         $idfree = $i;
1789         continue; // NOTE: CHECK IT !!
1790       }
1791       if (strcasecmp($this->user[$i]->name, $name_new) == 0) {
1792         if ($authenticate == FALSE) {
1793           $idx = $i;
1794           break;
1795         }
1796         else {
1797           $ghost = $i;
1798           $ghost_auth = ($this->user[$i]->flags & USER_FLAG_AUTH);
1799         }
1800       }
1801     }
1802     if ($idx == -1)
1803       $idx = $idfree;
1804
1805     log_auth("XXX", sprintf("TROVATO A QUESTO PUNTO [%d] sess [%s] name [%s]", $idx, $sess, $name_new));
1806
1807     if ($ghost > -1 && $authenticate) {
1808       /* swap session */
1809
1810       $ghost_user =& $this->user[$ghost];
1811       $curtime = time();
1812       $ghost_user->step_inc();
1813       if ($sess == "") {
1814         $sess = uniqid(""); 
1815         $ghost_user->sess = $sess;
1816       }
1817       else {
1818         $ghost_user->sess = $sess;
1819       }
1820       
1821       // If user at the table we need to update the table data too
1822       $table_idx = $ghost_user->table;
1823       if ($ghost_user->stat == "table" && $this->table[$table_idx]->player_n == PLAYERS_N) {
1824         if (($brisem = Briskin5::lock_data($table_idx)) != FALSE) { 
1825           if (($bri = &Briskin5::load_data($table_idx)) != FALSE) {
1826             if ($bri->the_end != TRUE) {
1827               $bri->user[$ghost_user->table_pos]->step_inc();
1828               $bri->user[$ghost_user->table_pos]->sess = $sess;
1829               Briskin5::save_data(&$bri);
1830             }
1831           }
1832           Briskin5::unlock_data($brisem);
1833         }
1834       }
1835
1836       $idx = $ghost;
1837       return ($this->user[$ghost]);
1838     }
1839     else if ($idx != -1 && $i == MAX_PLAYERS) {
1840       /* SUCCESS */
1841       $curtime = time();
1842       if ($sess == "") {
1843         $sess = uniqid("");
1844         $this->user[$idx]->sess = $sess;
1845       }
1846       else {
1847         $this->user[$idx]->sess = $sess;
1848       }
1849       $this->user[$idx]->name = $name_new; // OK - add new user
1850       $this->user[$idx]->stat_set("room");
1851       $this->user[$idx]->step_set(0);
1852       while (array_pop($this->user[$idx]->comm) != NULL);
1853       $this->user[$idx]->subst = "standup";
1854       $this->user[$idx]->lacc =   $curtime;
1855       $this->user[$idx]->laccwr = $curtime;
1856       $this->user[$idx]->bantime = 0;
1857       $this->user[$idx]->ip = $ip;
1858
1859       $this->user[$idx]->flags = ($authenticate ? USER_FLAG_AUTH : 0x00);
1860
1861       if ($ghost > -1) {
1862         log_main("ghost: rename!");
1863         $ghost_user =& $this->user[$ghost];
1864
1865         if ($ghost_auth == FALSE) {
1866           for ($sfx = 1 ; $sfx <= MAX_PLAYERS ; $sfx++) {
1867             $ghostname = 'ghost'.$sfx;
1868             for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1869               if (strcmp("", $this->user[$i]->sess) == 0) 
1870                 continue;
1871               
1872               if (strcmp($this->user[$i]->name, $ghostname) == 0) {
1873                 $ghostname = '';
1874                 break;
1875               }
1876             }
1877             if ($ghostname != '')
1878               break;
1879           }
1880           
1881           $ghost_user->name = $ghostname;
1882           
1883           if ($ghost_user->stat == 'room' && $ghost_user->subst == 'standup') {
1884             $this->standup_update(&$ghost_user);
1885           }
1886           else {
1887             log_main("chatt_send pre table update");
1888             $this->table_update(&$ghost_user);
1889           log_main("chatt_send post table update");
1890           }
1891         } // if ($ghost_auth == FALSE
1892         else {
1893           // FIXME: cacciare il vecchio utente room && table (if needed)
1894           $ghost_user->the_end = TRUE;
1895           $ghost_user->lacc = 0;
1896           $this->garbage_manager(TRUE);
1897         }
1898       } //  if ($ghost > -1) {
1899
1900       log_main(sprintf("TROVATO LIBERO A [%d] sess [%s] name [%s]", $idx, $sess, $name_new));
1901       $real_idx = $idx;
1902       if ($login_exists)
1903         $idx = -($idx + 1);
1904       return ($this->user[$real_idx]);
1905     }
1906
1907     return ($G_false);
1908   }
1909   
1910   function standup_update(&$user)
1911   {
1912     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
1913       $user_cur = &$this->user[$i];
1914       if ($user_cur->sess == '')
1915         continue;
1916
1917       log_main("STANDUP START: ".$user_cur->stat);
1918       
1919       if ($user_cur->stat == 'room') {
1920         $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ".$this->standup_content($user_cur);
1921         if ($user_cur == $user) {
1922           $itin = ($user->flags & USER_FLAG_AUTH ? "<i>" : "");
1923           $itou = ($user->flags & USER_FLAG_AUTH ? "</i>" : "");
1924
1925           $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('$("myname").innerHTML = "<b>%s%s%s</b>: ";', 
1926                                                                $itin, xcape($user->name), $itou);
1927         }
1928         log_main("FROM STANDUP: NAME: ".$user_cur->name." SENDED: ".$user_cur->comm[$user_cur->step % COMM_N]);
1929         
1930         $user_cur->step_inc();
1931       }
1932     }
1933   }
1934
1935   // Static functions
1936   function &init_data()
1937   {
1938     $room =& new Room();
1939     
1940     return $room;
1941   }
1942   
1943
1944   function &load_data() 
1945   {
1946     GLOBAL $G_false, $sess;
1947     $doexit = FALSE;
1948     do {
1949       if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) {
1950         log_main("ftok failed");
1951         $doexit = TRUE;
1952         break;
1953       }
1954     
1955       if (($shm_sz = sharedmem_sz($tok)) == -1) {
1956         log_main("shmop_open failed");
1957       }
1958         
1959       if ($shm_sz == -1)
1960         $shm_sz = SHM_DIMS_MIN;
1961
1962       if ($shm = shm_attach($tok, $shm_sz)) {
1963         $room = @shm_get_var($shm, $tok);
1964         
1965         log_only("bri ==  ".($room == FALSE ?   "FALSE" : "TRUE")."  bri ===  ".($room === FALSE ? "FALSE" : "TRUE")."  bri isset ".(isset($room) ?   "TRUE" : "FALSE"));
1966         if (isset($room)) 
1967           log_only("bri count ".count($room));
1968         
1969         if ($room == FALSE) {
1970           log_only("INIT MAIN DATA");
1971           
1972           $room =& Room::init_data();
1973           if (@shm_put_var($shm, $tok, $room) == FALSE) {
1974             log_only("PUT_VAR FALLITA ".strlen(serialize($room)));
1975             log_only(serialize($room));
1976           }
1977         }
1978         $room->shm_sz = $shm_sz;
1979         
1980         shm_detach($shm);
1981       }
1982       $ret = &$room;
1983       return ($ret);
1984     } while (0);
1985     
1986     if ($doexit)
1987       exit();
1988     
1989     return ($G_false);
1990   }
1991   
1992
1993   function save_data(&$room) 
1994   {
1995     GLOBAL $sess;
1996     
1997     $shm =   FALSE;
1998     
1999     // var_dump($room);
2000     
2001     if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) 
2002       return (FALSE);
2003     
2004     while ($room->shm_sz < SHM_DIMS_MAX) {
2005       if (($shm = shm_attach($tok, $room->shm_sz)) == FALSE)
2006         break;
2007       
2008       // log_only("PUT_VAR DI ".strlen(serialize($room)));
2009       if (shm_put_var($shm, $tok, $room) != FALSE) {
2010         shm_detach($shm);
2011         return (TRUE);
2012       }
2013       if (shm_remove($shm) === FALSE) {
2014         log_only("REMOVE FALLITA");
2015         break;
2016       }
2017       shm_detach($shm);
2018       $room->shm_sz += SHM_DIMS_DLT;
2019     } 
2020
2021     if ($shm)
2022       shm_detach($shm);
2023     
2024     return (FALSE);
2025   }
2026
2027   function lock_data()
2028   {
2029     GLOBAL $sess; 
2030     
2031     //  echo "LOCK: ".FTOK_PATH."/main";
2032     //  exit;
2033     if (($tok = @ftok(FTOK_PATH."/main", "B")) == -1) {
2034       echo "FTOK FAILED";
2035       exit;
2036     }
2037     // echo "FTOK ".$tok."<br>";
2038     if (($res = sem_get($tok)) == FALSE) {
2039       echo "SEM_GET FAILED";
2040       exit;
2041     }
2042     if (sem_acquire($res)) {   
2043       log_lock("LOCK room");
2044       return ($res);
2045     }
2046     else
2047       return (FALSE);
2048   }
2049   
2050   function unlock_data($res)
2051   {
2052     GLOBAL $sess; 
2053     
2054     log_lock("UNLOCK room");
2055
2056     return (sem_release($res));
2057   }
2058
2059
2060   function standup_content($user)
2061   {
2062     $ret = "";
2063     $content = "";
2064     
2065     if ($user->stat != 'room')
2066       return;
2067     
2068     for ($e = 0 , $ct = 0 ; $ct < 4 && $e < MAX_PLAYERS ; $e++) {
2069       if ($this->user[$e]->sess == "" || $this->user[$e]->stat != "room" || $this->user[$e]->name == "")
2070         continue;
2071       $ct++;
2072     }
2073     
2074     // $content .= sprintf('<table cols=\\"%d\\" class=\\"table_standup\\">', $ct);
2075     
2076     $content = ' j_stand_cont( [ ';
2077
2078     for ($e = 0 , $ct = 0 ; $e < MAX_PLAYERS ; $e++) {
2079       if ($this->user[$e]->sess == "" || $this->user[$e]->stat != "room" || $this->user[$e]->name == "")
2080         continue;
2081       
2082       $flags = $this->user[$e]->flags;
2083       
2084       if ($this->user[$e]->subst == "standup") {
2085         if ($this->user[$e] == $user) 
2086           { 
2087             $flags |= 1;
2088           }
2089         
2090         $content .= sprintf('%s[ %d, "%s" ]',($ct > 0 ? ', ' : ''), $flags, xcape($this->user[$e]->name));
2091         $ct++;
2092       }
2093     }
2094     $content .= ' ]);';
2095     
2096     return ($content);
2097   }
2098   
2099   function table_content_old($user, $table_idx)
2100   {
2101     $content = "";
2102     $ret = "";
2103     // TODO
2104     //
2105     //   Si possono usare i dati nella classe table
2106     //
2107     
2108     $sess = $user->sess;
2109     $table = &$this->table[$table_idx];
2110     
2111     if ($user->stat != 'room')
2112       return;
2113     
2114     for ($i = 0 ; $i < $table->player_n ; $i++) {
2115       $user_cur = &$this->user[$table->player[$i]];
2116       
2117       if ($user_cur == $user) 
2118         { $hilion = "<b>"; $hilioff = "</b>"; }
2119       else
2120         { $hilion = ""; $hilioff = ""; }
2121       
2122       log_main($user_cur->name. sprintf(" IN TABLE [%d]", $table_idx));
2123       
2124       $content .= sprintf("%s%s%s<br>",$hilion, xcape($user_cur->name), $hilioff);
2125     }
2126     /*
2127   for ( ; $i < PLAYERS_N ; $i++)
2128     $content .= "<br>";
2129     */
2130     
2131     $ret .= sprintf('$("table%d").innerHTML = "%s";', $table_idx, $content);
2132     
2133     return ($ret);
2134   }
2135
2136
2137   function table_content($user, $table_idx)
2138   {
2139     $content = "";
2140     $ret = "";
2141     // TODO
2142     //
2143     //   Si possono usare i dati nella classe table
2144     //
2145     
2146     $sess = $user->sess;
2147     $table = &$this->table[$table_idx];
2148     
2149     if ($user->stat != 'room')
2150       return;
2151     
2152     $content = "[ ";
2153     for ($i = 0 ; $i < $table->player_n ; $i++) {
2154       $user_cur = &$this->user[$table->player[$i]];
2155
2156       $flags = $user_cur->flags;
2157
2158       if ($user_cur == $user) 
2159         $flags |= 1;
2160       
2161       log_main($user_cur->name. sprintf(" IN TABLE [%d]", $table_idx));
2162       
2163       $content .= sprintf('%s[ %d, "%s" ]',($i == 0 ? '' : ', '), $flags, xcape($user_cur->name));
2164     }
2165
2166     $content .= ' ]';
2167
2168     $ret .= sprintf('j_tab_cont(%d, %s);', $table_idx, $content);
2169     
2170     return ($ret);
2171   }
2172
2173 } // end class Room
2174
2175 function make_seed()
2176 {
2177   list($usec, $sec) = explode(' ', microtime());
2178   return (float) $sec + ((float) $usec * 100000);
2179 }
2180
2181
2182 function log_only2($log) {
2183   GLOBAL $sess;
2184
2185   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_ONL2) == 0)
2186     return;
2187
2188   if (isset($sess) == FALSE)
2189     $ssess = "XXXX";
2190   else
2191     $ssess = $sess;
2192
2193   if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_ONL2) == 0)
2194     return;
2195
2196   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2197     fwrite($fp, sprintf("ONL2: [%s] [%s]\n", $ssess, $log));
2198     fclose($fp);
2199   }
2200 }
2201
2202 function log_crit($log) {
2203   GLOBAL $sess;
2204
2205   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_CRIT) == 0)
2206     return;
2207
2208   if (isset($sess) == FALSE)
2209     $ssess = "XXXX";
2210   else
2211     $ssess = $sess;
2212
2213   if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_CRIT) == 0)
2214     return;
2215
2216   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2217     fwrite($fp, sprintf("CRIT: [%s] [%s]\n", $ssess, $log));
2218     fclose($fp);
2219   }
2220 }
2221
2222 function log_only($log) {
2223   GLOBAL $sess;
2224
2225   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_ONLY) == 0)
2226     return;
2227
2228   if (isset($sess) == FALSE)
2229     $ssess = "XXXX";
2230   else
2231     $ssess = $sess;
2232
2233   if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_ONLY) == 0)
2234     return;
2235
2236   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2237     fwrite($fp, sprintf("ONLY: [%s] [%s]\n", $ssess, $log));
2238     fclose($fp);
2239   }
2240 }
2241
2242 function log_main($log) {
2243   GLOBAL $sess;
2244
2245   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_MAIN) == 0)
2246     return;
2247
2248   if (isset($sess) == FALSE)
2249     $ssess = "XXXX";
2250   else
2251     $ssess = $sess;
2252
2253   if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_MAIN) == 0)
2254     return;
2255
2256   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2257     fwrite($fp, sprintf("MAIN: [%s] [%s]\n", $ssess, $log));
2258     fclose($fp);
2259   }
2260 }
2261
2262 function log_rd($log) {
2263   GLOBAL $sess;
2264
2265   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_READ) == 0)
2266     return;
2267
2268   if (isset($sess) == FALSE)
2269     $ssess = "XXXX";
2270   else
2271     $ssess = $sess;
2272
2273   if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_READ) == 0)
2274     return;
2275
2276   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2277     fwrite($fp, sprintf("READ: [%s] [%s]\n", $ssess, $log));
2278     fclose($fp);
2279   }
2280 }
2281
2282 function log_rd2($log) {
2283   GLOBAL $sess;
2284
2285   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_REA2) == 0)
2286     return;
2287
2288   if (isset($sess) == FALSE)
2289     $ssess = "XXXX";
2290   else
2291     $ssess = $sess;
2292       
2293   if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_REA2) == 0)
2294     return;
2295
2296   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2297     fwrite($fp, sprintf("REA2: [%s] [%s]\n", $ssess, $log));
2298     fclose($fp);
2299   }
2300 }
2301
2302 function log_send($log) {
2303   GLOBAL $sess;
2304
2305   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_SEND) == 0)
2306     return;
2307
2308   if (isset($sess) == FALSE)
2309     $ssess = "XXXX";
2310   else
2311     $ssess = $sess;
2312       
2313   if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_SEND) == 0)
2314     return;
2315
2316   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2317     fwrite($fp, sprintf("SEND: [%s] [%s]\n", $ssess, $log));
2318     fclose($fp);
2319   }
2320 }
2321
2322 function log_lock($log) {
2323   GLOBAL $sess;
2324
2325   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LOCK) == 0)
2326     return;
2327
2328   if (isset($sess) == FALSE)
2329     $ssess = "XXXX";
2330   else
2331     $ssess = $sess;
2332
2333   if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LOCK) == 0)
2334     return;
2335
2336   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2337     fwrite($fp, sprintf("LOCK: [%s] [%s]\n", $ssess, $log));
2338     fclose($fp);
2339   }
2340 }
2341
2342 function log_wr($log) {
2343   GLOBAL $sess;
2344
2345   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_WRIT) == 0)
2346     return;
2347
2348   if (isset($sess) == FALSE)
2349     $ssess = "XXXX";
2350   else
2351     $ssess = $sess;
2352       
2353   if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_WRIT) == 0)
2354     return;
2355
2356   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2357     fwrite($fp, sprintf("WRIT: [%s] [%s]\n", $ssess, $log));
2358     fclose($fp);
2359   }
2360 }
2361
2362 function log_load($log) {
2363   GLOBAL $sess;
2364
2365   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_LOAD) == 0)
2366     return;
2367
2368   if (isset($sess) == FALSE)
2369     $ssess = "XXXX";
2370   else
2371     $ssess = $sess;
2372
2373   if (( (BRISK_DEBUG | ($ssess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_LOAD) == 0)
2374     return;
2375       
2376   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2377     fwrite($fp, sprintf("LOAD: [%s] [%s]\n", $ssess, $log));
2378     fclose($fp);
2379   }
2380 }
2381
2382 function log_auth($sess, $log) {
2383   if (BRISK_SINGLE_SESS == "" && (BRISK_DEBUG & DBG_AUTH) == 0)
2384     return;
2385
2386   if (( (BRISK_DEBUG | ($sess == BRISK_SINGLE_SESS ? BRISK_SINGLE_DEBUG : 0) ) & DBG_AUTH) == 0)
2387     return;
2388
2389   if (($fp = @fopen(LEGAL_PATH."/brisk.log", 'a')) != FALSE) {
2390     fwrite($fp, sprintf("AUTH: [%s] [%d] [%s]\n", $sess, time(), $log));
2391     fclose($fp);
2392   }
2393 }
2394
2395
2396 function log_legal($curtime, $sess, $name, $where, $mesg) 
2397 {
2398   GLOBAL $_SERVER;
2399
2400   if (($fp = @fopen(LEGAL_PATH."/legal.log", 'a')) != FALSE) {
2401     /* Unix time | session | nickname | IP | where was | mesg */
2402     fwrite($fp, sprintf("%ld|%s|%s|%s|%s|%s|\n", $curtime, $sess, $name, $_SERVER['REMOTE_ADDR'], $where , $mesg));
2403     fclose($fp);
2404   }
2405 }
2406
2407
2408
2409
2410 function lock_banlist()
2411 {
2412   if (($tok = @ftok(FTOK_PATH."/main", "L")) == -1) {
2413     echo "FTOK FAILED";
2414     exit;
2415   }
2416   if (($res = sem_get($tok)) == FALSE) {
2417     echo "SEM_GET FAILED";
2418     exit;
2419   }
2420   if (sem_acquire($res)) 
2421     return ($res);
2422   else
2423     return (FALSE);
2424 }
2425
2426 function unlock_banlist($res)
2427 {
2428   return (sem_release($res));
2429 }
2430
2431 function table_act_content_old($isstanding, $sitted, $table, $cur_table)
2432 {
2433   $ret = "";
2434
2435   if ($isstanding) {
2436     if ($sitted < PLAYERS_N) {
2437       $ret = sprintf('<input type=\\"button\\" class=\\"button\\" name=\\"xhenter%d\\"  value=\\"Mi siedo.\\" onclick=\\"act_sitdown(%d);\\">', $table, $table);
2438     }
2439   }
2440   else {
2441     if ($table == $cur_table)
2442       $ret = sprintf('<input type=\\"button\\" class=\\"button\\" name=\\"xwakeup\\"  value=\\"Mi alzo.\\" onclick=\\"act_wakeup();\\">');
2443     else
2444       $ret = "";
2445   }
2446   return ($ret);
2447 }
2448
2449 function table_act_content($isstanding, $sitted, $table, $cur_table, $allowed)
2450 {
2451   $ret = "";
2452
2453   if ($isstanding) {
2454     if ($sitted < PLAYERS_N) {
2455       if ($allowed)
2456         $act = 'sit';
2457       else
2458         $act = 'reserved';
2459     }
2460   }
2461   else {
2462     if ($table == $cur_table)
2463       $act = 'wake';
2464     else
2465       $act = 'none';
2466   }
2467
2468   if ($act != '')
2469     $ret = sprintf('j_tab_act_cont(%d, \'%s\');', $table, $act);
2470
2471   return ($ret);
2472 }
2473
2474 function show_notify($text, $tout, $butt, $w, $h)
2475 {
2476   log_main("SHOW_NOTIFY: ".$text);
2477   return sprintf('var noti = new notify(gst,"%s",%d,"%s",%d,%d);', $text, $tout, $butt, $w, $h);
2478 }
2479
2480 function briscola_show($room, $table, $user)
2481 {
2482   $ptnadd = "";
2483   $ret = "";
2484
2485   if ($table->asta_card == 9) 
2486     $ptnadd = sprintf("<br>con %d punti", $table->asta_pnt);
2487   
2488   /* text of caller cell */
2489   if ($user->table_pos == $table->asta_win) 
2490     $ret .= sprintf('$("callerinfo").innerHTML = "Chiami%s:";', $ptnadd);
2491   else 
2492     $ret .= sprintf('$("callerinfo").innerHTML = "Chiama %s%s:";', 
2493                     xcape($room->user[$table->player[$table->asta_win]]->name), $ptnadd);
2494
2495   $ret .= sprintf('$("caller").style.backgroundImage = \'url("img/brisk_caller_sand%d.png")\';',
2496                   $table->asta_win);
2497   $ret .= sprintf('$("callerimg").src = "img/%02d.png";', $table->briscola);
2498   $ret .= sprintf('$("caller").style.visibility = "visible";');
2499   $ret .= sprintf('$("chooseed").style.visibility = "hidden";');
2500   $ret .= sprintf('$("astalascio").style.visibility = "";');
2501   $ret .= sprintf('$("asta").style.visibility = "hidden";');
2502   $ret .= sprintf('show_astat(-2,-2,-2,-2,-2);');
2503   
2504   return ($ret);
2505 }
2506
2507
2508 function game_result($asta_pnt, $pnt)
2509 {
2510   if ($asta_pnt == 61) {
2511     if ($pnt > 60)
2512       return (1);
2513     else if ($pnt == 60)
2514       return (0);
2515     else
2516       return (-1);
2517   }
2518   else {
2519     if ($pnt >= $asta_pnt)
2520       return (1);
2521     else
2522       return (-1);
2523   }
2524 }
2525
2526 function multoval($mult)
2527 {
2528   if ($mult == 2)
2529     return ("doppio");
2530   else if ($mult == 4)
2531     return ("quadruplo");
2532   else
2533     return (sprintf("%d-plo", $mult));
2534 }
2535
2536 function show_table_info(&$room, &$table, $table_pos)
2537 {
2538   $ret = "";
2539   $user = &$room->user[$table->player[$table_pos]];
2540
2541   $pnt_min = $table->points_n - MAX_POINTS < 0 ? 0 : $table->points_n - MAX_POINTS;
2542   $noty = sprintf('<table class=\"points\"><tr><th></th>');
2543   
2544   // Names.
2545   for ($i = 0 ; $i < PLAYERS_N ; $i++) 
2546     $noty .= sprintf('<th class=\"td_points\">%s</th>', xcape($room->user[$table->player[$i]]->name));
2547   $noty .= sprintf("</tr>");
2548
2549   // Points.
2550   log_main("show_table_info: pnt_min: ".$pnt_min."   Points_n: ".$table->points_n);
2551
2552   for ($i = $pnt_min ; $i < $table->points_n ; $i++) {
2553     $noty .= sprintf('<tr><th class=\"td_points\">%d</th>', $i+1);
2554     for ($e = 0 ; $e < PLAYERS_N ; $e++) 
2555       $noty .= sprintf('<td class=\"td_points\">%d</td>', $table->points[$i % MAX_POINTS][$e]);
2556     $noty .= "</tr>";
2557   }
2558
2559   // Total points.
2560   $noty .= '<tr><th class=\"td_points\">Tot.</th>';
2561   for ($e = 0 ; $e < PLAYERS_N ; $e++) 
2562     $noty .= sprintf('<td class=\"td_points\">%d</td>', $table->total[$e]);
2563   $noty .= "</tr></table>";
2564
2565   if ($table->old_reason != "") {
2566     $noty .= sprintf("<hr><b>%s</b><br>", xcape($table->old_reason));
2567   }
2568
2569   if ($table->old_win != -1) {
2570     $win = $table->player[$table->old_win];
2571     $fri = $table->player[$table->old_friend];
2572
2573     $wol = game_result($table->old_asta_pnt, $table->old_pnt);
2574
2575     if ($win != $fri) {
2576       $noty .= sprintf("<hr>Nell'ultima mano ha chiamato <b>%s</b>, il socio era <b>%s</b>,<br>", 
2577                        xcape($room->user[$win]->name),
2578                        xcape($room->user[$fri]->name));
2579       if ($table->old_pnt == 120) {
2580         $noty .= sprintf("hanno fatto <b>cappotto</b> EBBRAVI!.<hr>");
2581       }
2582       else {
2583         $noty .= sprintf("dovevano fare <b>%s</b> punti e ne hanno fatti <b>%d</b>: hanno <b>%s</b>.<hr>",
2584                          ($table->old_asta_pnt > 61 ? "almeno ".$table->old_asta_pnt :
2585                           'pi&ugrave; di 60'), $table->old_pnt,
2586                          ($wol == 1 ? "vinto" : ($wol == 0 ? "pareggiato" : "perso")));
2587       }
2588     }
2589     else {
2590       $noty .= sprintf("<hr>Nell'ultima mano <b>%s</b> si &egrave; chiamato in mano,<br>", 
2591                        xcape($room->user[$win]->name));
2592       if ($table->old_pnt == 120) {
2593         $noty .= sprintf("ha fatto <b>cappotto</b> EBBRAVO!.<hr>");
2594       }
2595       else {
2596         $noty .= sprintf("doveva fare <b>%s</b> punti e ne ha fatti <b>%d</b>: ha <b>%s</b>.<hr>",
2597                          ($table->old_asta_pnt > 61 ? "almeno ".$table->old_asta_pnt :
2598                           'pi&ugrave; di 60'), $table->old_pnt,
2599                          ($wol == 1 ? "vinto" : ($wol == 0 ? "pareggiato" : "perso")));
2600       }
2601     }
2602   }
2603   if ($table->mazzo == $table_pos) 
2604     $noty .= "Fai <b>tu</b> il mazzo,";
2605   else {
2606     $unam = xcape($room->user[$table->player[$table->mazzo]]->name);
2607     $noty .= "Il mazzo a <b>$unam</b>,";
2608   }
2609
2610   if ($user->subst == 'asta') {
2611     if ($table->asta_win == -1)  // auction case
2612       $curplayer = $table->gstart % PLAYERS_N;
2613     else 
2614       $curplayer = $table->asta_win;
2615   }
2616   else if ($user->subst == 'game') {
2617     $curplayer = ($table->gstart + $table->turn) % PLAYERS_N;
2618   }
2619
2620
2621   if ($curplayer == $table_pos) {
2622     $noty .= " tocca a <b>te</b> giocare.";
2623   }
2624   else {
2625     $unam = xcape($room->user[$table->player[$curplayer]]->name);
2626     $noty .= " tocca a <b>$unam</b> giocare.";
2627   }
2628   
2629   if ($table->mult > 1) {
2630     $noty .= sprintf(" La partita vale <b>%s</b>.", multoval($table->mult));
2631   }
2632   $noty .= "<hr><br>";
2633   $ret .= show_notify($noty, 3000, "torna alla partita", 500, 400);
2634   /* NOTE: show_notify($noty, 3000, "torna alla partita", 500, 
2635    *                   130 + ($table->points_n > 0 ? 50 : 0) + 
2636    *                   (120 * ($table->points_n / MAX_POINTS)));
2637    *       will be used when we refact notify js function following 
2638    *       photoo class logic 
2639    */ 
2640   
2641   return ($ret);
2642 }
2643
2644 function root_wellcome($user)
2645 {
2646   GLOBAL $root_wellarr;
2647   $ret = "";
2648
2649   $curtime = time();
2650   $dt = date("H:i ", $curtime);
2651     
2652   for ($i = 0 ; $i < count($root_wellarr) ; $i++)
2653     $ret .= sprintf('chatt_sub("%s", [2, "%s"],"%s");', $dt, NICKSERV, str_replace('"', '\"', $root_wellarr[$i]));
2654
2655   return ($ret);
2656 }
2657
2658 function table_wellcome($user)
2659 {
2660   GLOBAL $table_wellarr;
2661   $ret = "";
2662
2663   for ($i = 0 ; $i < count($table_wellarr) ; $i++)
2664     $ret .= sprintf('chatt_sub("%s", [2, "ChanServ: "],"%s");', "", str_replace('"', '\"', $table_wellarr[$i]));
2665
2666   return ($ret);
2667 }
2668
2669
2670
2671 /* show table 
2672 is_transition (is from room to table ?)
2673 is_again      (is another game)
2674
2675 Examples                    of $is_transition, $is_again:
2676   from reload of the page:              FALSE, FALSE
2677   from sitdown in room:                  TRUE, FALSE
2678   from table: asta cmd e tutti passano:  TRUE, TRUE
2679   from table: fine partita:              TRUE, TRUE
2680  */
2681 function show_table(&$room, &$user, $sendstep, $is_transition, $is_again)
2682 {
2683   $table_idx = $user->table;
2684   $table = &$room->table[$table_idx];
2685   $table_pos = $user->table_pos;
2686
2687   $ret = "table_init();";
2688   $ret .= $table->exitlock_show(&$room->user, $table_pos);
2689   if (!$is_again) {
2690     /* GENERAL STATUS */
2691     $ret .= sprintf( 'gst.st = %d; stat = "%s"; subst = "%s"; table_pos = %d;',
2692                      $sendstep, $user->stat, $user->subst, $table_pos);
2693
2694     log_rd(sprintf( 'SHOW_TABLE: gst.st = %d; stat = "%s"; subst = "%s"; table_pos = %d;',
2695                      $sendstep, $user->stat, $user->subst, $table_pos));
2696
2697     /* BACKGROUND */
2698     $ret .= "background_set();";
2699     
2700     /* USERS INFO */
2701     $itin = ($user->flags & USER_FLAG_AUTH ? "<i>" : "");
2702     $itou = ($user->flags & USER_FLAG_AUTH ? "</i>" : "");
2703
2704     $ret .= sprintf('$("myname").innerHTML = "<b>%s%s%s</b>";', $itin, xcape($user->name), $itou);
2705     $ret .= sprintf('set_names([%d, "%s"], [%d, "%s"], [%d, "%s"], [%d, "%s"], [%d, "%s"]); ',
2706                     $room->user[$table->player[($table_pos)%PLAYERS_N]]->flags,
2707                     xcape($room->user[$table->player[($table_pos)%PLAYERS_N]]->name),
2708
2709                     $room->user[$table->player[($table_pos+1)%PLAYERS_N]]->flags,
2710                     xcape($room->user[$table->player[($table_pos+1)%PLAYERS_N]]->name),
2711
2712                     $room->user[$table->player[($table_pos+2)%PLAYERS_N]]->flags,
2713                     xcape($room->user[$table->player[($table_pos+2)%PLAYERS_N]]->name),
2714
2715                     (PLAYERS_N == 3 ? 0 : $room->user[$table->player[($table_pos+3)%PLAYERS_N]]->flags),
2716                     (PLAYERS_N == 3 ? "" :  xcape($room->user[$table->player[($table_pos+3)%PLAYERS_N]]->name)),
2717
2718                     (PLAYERS_N == 3 ? 0 : $room->user[$table->player[($table_pos+4)%PLAYERS_N]]->flags),
2719                     (PLAYERS_N == 3 ? "" :  xcape($room->user[$table->player[($table_pos+4)%PLAYERS_N]]->name)));
2720   }
2721   /* NOTIFY FOR THE CARD MAKER */
2722   if ($is_transition) { //  && $user->subst ==  "asta" superfluo
2723     $ret .= show_table_info(&$room, &$table, $table_pos);
2724   }
2725   if (!$is_again) 
2726     $ret .= table_wellcome($user);
2727
2728   if ($is_transition && !$is_again) { // appena seduti al tavolo, play della mucca
2729     $ret .= playsound("cow.mp3");
2730   }
2731
2732
2733   /* CARDS */
2734   if ($is_transition) { //  && $user->subst ==  "asta" superfluo
2735     $ret .= "|";
2736     
2737     for ($i = 0 ; $i < 8 ; $i++) {
2738       for ($e = 0 ; $e < PLAYERS_N ; $e++) {
2739         $ct = 0;
2740         for ($o = 0 ; $o < 40 && $ct < $i+1 ; $o++) {
2741           if ($table->card[$o]->owner == (($e + $table->gstart) % PLAYERS_N)) {
2742             $ct++;
2743             if ($ct == $i+1)
2744               break;
2745           }
2746         }
2747         log_rd("O ".$o." VAL ".$table->card[$o]->value." Owner: ".$table->card[$o]->owner);
2748         
2749         $ret .= sprintf( ' card_send(%d,%d,%d,%8.2f,%d);|', ($table->gstart + $e) % PLAYERS_N, 
2750                          $i, ((($e + PLAYERS_N - $table_pos + $table->gstart) % PLAYERS_N) == 0 ?
2751                               $table->card[$o]->value : -1), 
2752                          ($i == 7 && $e == (PLAYERS_N - 1) ? 1 : 0.5),$i+1);
2753       }
2754     }    
2755   }
2756   else {
2757     $taked  = array(0,0,0,0,0);
2758     $inhand = array(0,0,0,0,0);
2759     $ontabl  = array(-1,-1,-1,-1,-1);
2760     $cards  = array();
2761
2762     for ($i = 0 ; $i < 40 ; $i++) {
2763       if ($table->card[$i]->stat == 'hand') {
2764         if ($table->card[$i]->owner == $table_pos) {
2765           $cards[$inhand[$table->card[$i]->owner]] = $table->card[$i]->value;
2766         }
2767         $inhand[$table->card[$i]->owner]++;
2768       }
2769       else if ($table->card[$i]->stat == 'take') {
2770         log_main("Card taked: ".$table->card[$i]->value."OWN: ".$table->card[$i]->owner);
2771         $taked[$table->card[$i]->owner]++;
2772       }
2773       else if ($table->card[$i]->stat == 'table') {
2774         $ontabl[$table->card[$i]->owner] = $i;
2775       }
2776     }
2777     $logg = "\n";
2778     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
2779       $logg .= sprintf("INHAND: %d   IN TABLE %d   TAKED %d\n", $inhand[$i], $ontabl[$i], $taked[$i]);
2780     }
2781     log_main("Stat table: ".$logg);
2782
2783     /* Set ours cards. */
2784     $oursarg = "";
2785     for ($i = 0 ; $i < $inhand[$table_pos] ; $i++) 
2786       $oursarg .= ($i == 0 ? "" : ", ").$cards[$i];
2787     for ($i = $inhand[$table_pos] ; $i < 8 ; $i++) 
2788       $oursarg .= ($i == 0 ? "" : ", ")."-1";
2789     $ret .= sprintf('card_setours(%s);', $oursarg);
2790
2791     /* Dispose all cards */
2792     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
2793       /* Qui sotto al posto di + 1 c'era + ->gstart ... credo in modo errato */
2794       $ret .= sprintf('cards_dispose(%d,%d,%d);', $i,
2795                       $inhand[$i], $taked[$i]);
2796
2797       if ($ontabl[$i] != -1) {
2798         $ret .= sprintf('card_place(%d,%d,%d,%d,%d);',$i, $inhand[$i], 
2799                         $table->card[$ontabl[$i]]->value, 
2800                         $table->card[$ontabl[$i]]->x, $table->card[$ontabl[$i]]->y);
2801       }
2802     }
2803   }
2804
2805   /* Show auction */
2806   if ($user->subst == 'asta') {
2807
2808     /* show users auction status */
2809     $showst = "";
2810     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
2811       $user_cur = &$room->user[$table->player[$i]];
2812       $showst .= sprintf("%s%d", ($i == 0 ? "" : ", "), 
2813                          ($user_cur->asta_card < 9 ? $user_cur->asta_card : $user_cur->asta_pnt));
2814     }
2815     if (PLAYERS_N == 3)
2816         $showst .= ",-2,-2";
2817     $ret .= sprintf('show_astat(%s);', $showst);
2818
2819     if ($table->asta_win != -1 && $table->asta_win == $table_pos) {
2820       /* show card chooser */
2821       $ret .= sprintf('choose_seed(%s); $("astalascio").style.visibility = ""; $("asta").style.visibility = "hidden";',
2822                       $table->asta_card);
2823     }
2824     else {
2825       /* show auction */
2826       if ($table_pos == ($table->gstart % PLAYERS_N) &&
2827           $table->asta_win == -1) 
2828         $ret .= sprintf('dispose_asta(%d,%d, %s);', 
2829                         $table->asta_card + 1, $table->asta_pnt+1, ($user->handpt <= 2 ? "true" : "false"));
2830       else
2831         $ret .= sprintf('dispose_asta(%d,%d, %s);',
2832                         $table->asta_card + 1, -($table->asta_pnt+1), ($user->handpt <= 2 ?  "true" : "false"));
2833     }
2834
2835     /* Remark */
2836     if ($table->asta_win == -1) { // auction case
2837       if ($table_pos == ($table->gstart % PLAYERS_N)) 
2838         $ret .= "remark_on();";
2839       else
2840         $ret .= "remark_off();";
2841     }
2842     else { // chooseed case
2843       if ($table_pos == $table->asta_win) 
2844         $ret .= "remark_on();";
2845       else
2846         $ret .= "remark_off();";
2847     }
2848   }
2849   else if ($user->subst == 'game') {
2850     /* HIGHLIGHT */
2851     if (($table->gstart + $table->turn) % PLAYERS_N == $table_pos) 
2852       $ret .= "is_my_time = true; remark_on();";
2853     else
2854       $ret .= "remark_off();";
2855     
2856     /* WHO CALL AND WATH */
2857     $ret .= briscola_show($room, $table, $user);
2858     
2859   }
2860   return ($ret);
2861 } // end function show_table(...
2862
2863 function calculate_winner(&$table)
2864 {
2865   $briontab = FALSE;
2866   $ontab = array();
2867   $ontid = array();
2868   $cur_win  =  -1;
2869   $cur_val  = 100;
2870   $cur_seed = $table->briscola - ($table->briscola % 10);
2871
2872   for ($i = 0 ; $i < 40 ; $i++) {
2873     if ($table->card[$i]->stat != "table")
2874       continue;
2875
2876     log_wr(sprintf("Card On table: [%d]", $i));
2877
2878     $v = $table->card[$i]->value; 
2879     $ontab[$table->card[$i]->owner] = $v;
2880     $ontid[$table->card[$i]->owner] = $i;
2881     /* se briscola setto il flag */
2882     if (($v - ($v % 10)) == $cur_seed)
2883       $briontab = TRUE;
2884   }
2885
2886   if ($briontab == FALSE) {
2887     $cur_win  = $table->gstart;
2888     $cur_val  = $ontab[$cur_win];
2889     $cur_seed = $cur_val - ($cur_val % 10);
2890   }
2891
2892   for ($i = 0 ; $i < PLAYERS_N ; $i++) {
2893     if (($ontab[$i] - ($ontab[$i] % 10)) == $cur_seed) {
2894       if ($ontab[$i] < $cur_val) {
2895         $cur_val = $ontab[$i];
2896         $cur_win = $i;
2897       }
2898     }
2899   }
2900
2901   for ($i = 0 ; $i < PLAYERS_N ; $i++) {
2902     $table->card[$ontid[$i]]->owner = $cur_win;
2903     $table->card[$ontid[$i]]->stat =  "take"; // Card stat
2904   }
2905   return ($cur_win);
2906 }
2907
2908 function calculate_points(&$table)
2909 {
2910   GLOBAL $G_all_points; 
2911
2912   $pro = 0;
2913
2914   if ($table->asta_pnt == 60)
2915     $table->asta_pnt = 61;
2916
2917   $table->old_reason = "";
2918   $table->old_win = $table->asta_win;
2919   $table->old_friend = $table->friend;
2920   $table->old_asta_pnt = $table->asta_pnt;
2921
2922   for ($i = 0 ; $i < 40 ; $i++) {
2923     $ctt = $table->card[$i]->value % 10;
2924     $own = $table->card[$i]->owner;
2925     if ($own == $table->asta_win || $own == $table->friend) 
2926       $pro += $G_all_points[$ctt];
2927   }
2928
2929   log_wr(sprintf("PRO: [%d]", $pro));
2930
2931   
2932   if ($table->asta_pnt == 61 && $pro == 60) { // PATTA !
2933     $table->points[$table->points_n % MAX_POINTS] = array();
2934     for ($i = 0 ; $i < PLAYERS_N ; $i++) 
2935       $table->points[$table->points_n % MAX_POINTS][$i] = 0;
2936     $table->points_n++;
2937     $table->old_pnt = $pro;
2938     $table->mult *= 2;
2939
2940     return;
2941   }
2942
2943   if ($pro >= $table->asta_pnt) 
2944     $sig = 1;
2945   else
2946     $sig = -1;
2947
2948   $table->points[$table->points_n % MAX_POINTS] = array();
2949   for ($i = 0 ; $i < 5 ; $i++) {
2950     if ($i == $table->asta_win) 
2951       $pt = ($i == $table->friend ? 4 : 2);
2952     else if ($i == $table->friend) 
2953       $pt = 1;
2954     else
2955       $pt = -1;
2956
2957     log_wr(sprintf("PRO: pt[%d][%d] = %d", $table->points_n % MAX_POINTS, $i, $pt));
2958
2959     $pt = $pt * $sig * $table->mult * ($pro == 120 ? 2 : 1);
2960
2961     log_wr(sprintf("PRO:[%d][%d][%d]", $sig, $table->mult, ($pro == 120 ? 2 : 1)));
2962     
2963     $table->points[$table->points_n % MAX_POINTS][$i] = $pt;
2964     $table->total[$i] += $pt;
2965   }
2966   $table->points_n++;
2967   $table->old_pnt = $pro;
2968   $table->mult = 1;
2969 }
2970
2971 function validate_sess($sess) 
2972 {
2973   if (strlen($sess) == SESS_LEN) 
2974     return (TRUE);
2975   else
2976     return (FALSE);
2977 }
2978
2979 function validate_name($name) 
2980 {
2981   $name_new = str_replace(' ', '_', substr(trim($name),0,12));
2982
2983   for ($i = 0 ; $i < strlen($name_new) ; $i++) {
2984     $c = $name_new[$i];
2985     if (($c >= "a" && $c <= "z") || ($c >= "A" && $c <= "Z") || ($c >= "0" && $c <= "9"))
2986       return ($name_new);
2987   }
2988
2989   return (FALSE);
2990 }
2991
2992 function playsound($filename)
2993 {
2994   return (sprintf('playsound("flasou", "%s");', $filename));
2995 }
2996
2997 function secstoword($secs)
2998 {
2999   $mins = floor($secs / 60);
3000   $secs = $secs % 60;
3001   if ($mins > 0) 
3002     $ret = sprintf("%d minut%s%s", $mins, ($mins > 1 ? "i" : "o"), ($secs > 0 ? " e " : ""));
3003   
3004   if ($secs > 0)
3005     $ret .= sprintf("%d second%s", $secs, ($secs > 1 ? "i" : "o"));
3006   
3007   return ($ret);
3008 }
3009
3010 function sharedmem_sz($tok)
3011 {
3012   if (($shm_id = @shmop_open($tok, 'a', 0, 0)) == FALSE) {
3013     log_main("shmop_open failed");
3014     return (-1);
3015   }
3016   $shm_sz = shmop_size($shm_id);
3017   shmop_close($shm_id);
3018   
3019   log_main("shm_sz: ".$shm_sz."   SHM_DIMS: ".SHM_DIMS);
3020   return ($shm_sz);
3021 }    
3022
3023 class Warrant {
3024   function lock_data()
3025   {
3026     GLOBAL $sess; 
3027     
3028     if (($tok = @ftok(FTOK_PATH."/warrant", "B")) == -1) {
3029       echo "FTOK FAILED";
3030       exit;
3031     }
3032     // echo "FTOK ".$tok."<br>";
3033     if (($res = sem_get($tok)) == FALSE) {
3034       echo "SEM_GET FAILED";
3035       exit;
3036     }
3037     if (sem_acquire($res)) {   
3038       log_lock("LOCK room");
3039       return ($res);
3040     }
3041     else
3042       return (FALSE);
3043   }
3044   
3045   function unlock_data($res)
3046   {
3047     GLOBAL $sess; 
3048     
3049     log_lock("UNLOCK room");
3050     
3051     return (sem_release($res));
3052   }
3053
3054   
3055 }
3056 ?>