aggiunto smammamorti
[brisk.git] / web / brisk.phh
1 <?php
2 /*
3  *  brisk - brisk.phh
4  *
5  *  Copyright (C) 2006 matteo.nastasi@milug.org
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details. You should have received a
16  * copy of the GNU General Public License along with this program; if
17  * not, write to the Free Software Foundation, Inc, 59 Temple Place -
18  * Suite 330, Boston, MA 02111-1307, USA.
19  *
20  */
21
22 define( FTOK_PATH, "/var/lib/brisk");
23 define(TABLES_N, 8);
24 define(PLAYERS_N, 3);
25 define(MAX_POINTS, 5);
26 define(MAX_PLAYERS, (PLAYERS_N * TABLES_N));
27 define(COMM_N, 12);
28 define(COMM_GEN_N, 50);
29 define(SESS_LEN, 13);
30 define(STREAM_TIMEOUT, 20);
31 define(EXPIRE_TIME_RD, 180);
32 define(EXPIRE_TIME_SMAMMA, 300); 
33 define(GARBAGE_TIMEOUT, 10);
34 define(NICKSERV, "<i>SERVER</i>");
35 define(BRISK_DEBUG, FALSE);
36 // define(DEBUGGING, "local");
37
38 $G_brisk_version = "0.4.4";
39
40 $root_wellarr = Array ( 'Benvenuto in brisk (Ver. '.$G_brisk_version.').',
41                         'Se vuoi iscriverti alla <a target="_blank" href="http://www.milug.org/cgi-bin/mailman/listinfo/ml-briscola">Mailing List</a>, cliccala!' );
42 $table_wellarr = Array ( 'Benvenuto al tavolo.');
43
44
45 $G_room_help= '
46 <div style=\\"text-align: left; padding: 8px;\\">
47 <b>Descrizione</b><br>
48 Questa &egrave; un\'implementazione della briscola in cinque, cos&igrave; come &egrave; spiegata su
49 <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>
50 <b>Uso del sito</b><br>
51 Potete sedervi a un tavolo o rimanere in piedi.<br>
52 Se al vostro tavolo si raggiungono i 5 giocatori inizia automaticamente la partita.<br>
53 <br>
54 <b>Partita</b><br>
55 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>
56 Chi vince l\'asta dovr&agrave; decidere il seme della carta scelta e inizier&agrave; la mano.<br>
57 Per giocare le carte dovrete trascinarle nel quadrato al centro del vostro schermo.<br><br>
58 Il vostro turno &egrave; sempre segnalato da una cornice verde lampeggiante intorno quadrato al centro del vostro schermo.<br><br>
59 Durante la partita, se vorrete ricaricare la pagina, usate l\'apposito bottone \\"reload\\" in basso a destra.<br>
60 <dl>
61 <dt><b>Comandi della chat</b>
62 <dd><b>/nick <i>&lt;nuovo_nickname&gt;</i></b> - cambio di nickname
63 <dd>.. to be continue ..
64 </dl>
65 </div>
66 ';
67
68 $G_room_about= '<br>
69 <div id=\\"header\\" class=\\"header\\">
70   <img class=\\"nobo\\" src=\\"img/brisk_logo64.png\\">
71   briscola chiamata in salsa ajax
72 </div>
73 <br><b>version '.$G_brisk_version.'</b><br><br>
74 Copyright 2006-2007 <a href=\\"mailto:brisk@alternativeoutput.it\\">Matteo Nastasi</a> (aka mop)<br><br>';
75
76
77 function xcape($s)
78 {
79   $from = array (   '\\',     '@',        '|' );
80   $to   = array ( '\\\\', '&#64;', '&brvbar;' );
81
82   return (str_replace($from, $to, htmlentities($s,ENT_COMPAT,"UTF-8")));
83 }
84
85
86 class Card {
87   var $value; /* 0 - 39 card value */
88   var $stat;  /* 'bunch', 'hand', 'table', 'take' */
89   var $owner; /* (table position 0-4) */
90   // var $pos;   /* Pos in hand. */
91   var $x;     /* When played the X position on the table of the owner. */
92   var $y;     /* When played the Y position on the table of the owner. */
93
94   function Card($value, $stat, $owner)
95   {
96     $this->value = $value;
97     $this->stat  = $stat;
98     $this->owner = $owner;
99   }
100
101   function assign($stat,$owner)
102   {
103     $this->stat  = $stat;
104     $this->owner = $owner;
105   }
106
107   function setpos($pos)
108   {
109     $this->pos   = $pos;
110   }
111
112   function play($x,$y)
113   {
114     $this->stat = 'table';
115     $this->x = $x;
116     $this->y = $y;
117   }
118
119   function take($newown)
120   {
121     $this->stat = 'take';
122     $this->owner = $newown;
123   }
124 }
125
126 class Table {
127   var $player;
128   var $player_n;
129   var $card;
130   var $mazzo;
131   var $gstart;
132   var $turn;
133
134   var $asta_pla;
135   var $asta_pla_n;
136   var $asta_card;
137   var $asta_pnt;
138   
139   var $mult;
140   var $points;    // points array
141   var $points_n;  // number of row of points
142   var $total;
143
144   var $asta_win;
145   var $briscola;
146   var $friend;
147   
148   var $old_asta_pnt;
149   var $old_pnt;
150   var $old_win;
151   var $old_friend;
152
153   function Table() 
154   {
155     $this->player    =   array();
156     $this->player_n  =   0;
157     $this->card      =  &$this->bunch_create();
158     $this->asta_pla  =   array(); // TRUE: in auction, FALSE: out of the auction
159     $this->asta_pla_n=  -1;
160     $this->asta_card =  -1;
161     $this->asta_pnt  =  -1;
162     $this->mult      =   1;
163     $this->points    =   array( );
164     $this->points_n  =   0;
165     $this->total     =   array( 0, 0, 0, 0, 0);
166     $this->asta_win  =  -1;
167     $this->briscola  =  -1;
168     $this->friend    =  -1;
169     $this->turn      =   0;
170     $this->old_asta_pnt = -1;
171     $this->old_pnt      = -1;
172     $this->old_win   =  -1;
173     $this->old_friend=  -1;
174
175   }
176
177   function &bunch_create()
178   {
179     $ret = array();
180
181     for ($i = 0 ; $i < 40 ; $i++) {
182       $ret[$i] = new Card($i, 'bunch', 'no_owner');
183     }
184
185     return ($ret);
186   }
187
188   function bunch_make()
189   {
190     $ct = array(0,0,0,0,0);
191     
192     mt_srand(make_seed());
193     
194     for ($i = 39 ; $i >= 0 ; $i--) 
195       $rest[$i] = $i;
196
197     for ($i = 39 ; $i >= 0 ; $i--) {
198       $rn = rand(0, $i);
199
200       if ($rn == 0)
201         log_main("RND ZERO", "");
202       
203       $id = $rest[$rn];
204
205       $owner = $i % 5;
206       $this->card[$id]->assign('hand', $owner);
207
208       $rest[$rn] = $rest[$i];
209       $pubbpos[$rn2] = $pubbpos[$i];
210     }
211   }
212
213   function init()
214   {
215     $this->mazzo    = rand(0,PLAYERS_N-1);
216     $this->points_n = 0;
217     $this->mult     = 1;
218     $this->old_win  =-1;
219     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
220       $this->total[$i] = 0;
221     }
222
223     log_main("table::init","ci siamo");
224   }
225
226   function game_init(&$bri)
227   {
228     log_rd2($sess,"GSTART 4");
229
230     $this->gstart = ($this->mazzo+1) % PLAYERS_N;
231     $this->bunch_make();
232     
233     
234     $this->asta_pla_n = PLAYERS_N;
235     $this->asta_card = -1;
236     $this->asta_pnt  = 60;
237     $this->asta_win  = -1;
238     $this->briscola  = -1;
239     $this->friend    = -1;
240     $this->turn      =  0;
241     
242     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
243       $this->asta_pla[$i] = TRUE;
244       $user_cur = &$bri->user[$this->player[$i]];
245       $user_cur->subst = 'asta';
246       $user_cur->asta_card = -2;
247       $user_cur->asta_pnt  = -1;
248     }
249   }
250
251   function game_next()
252   {
253     $this->mazzo  = ($this->mazzo + 1) % PLAYERS_N;
254   }
255
256   function getPlayer($idx)
257   {
258     return ($this->player[$idx]);
259   }
260
261   function setPlayer($idx, $player)
262   {
263     $this->player[$idx] = $player;
264   }
265
266   function user_add($idx)
267   {
268     $this->player[$this->player_n] = $idx;
269     $this->player_n++;
270     
271     return ($this->player_n - 1);
272   }
273   
274   function user_rem(&$bri, &$user)
275   {
276     $tabpos = $user->table_pos;
277     
278     /* verifico la consistenza dei dati */
279     if ($bri->user[$this->player[$tabpos]] == $user) {
280       
281       /* aggiorna l'array dei giocatori al tavolo. */
282       for ($i = $tabpos ; $i < $this->player_n-1 ; $i++) {
283         $this->player[$i] = $this->player[$i+1];
284         $user_cur = &$bri->user[$this->player[$i]];
285         $user_cur->table_pos = $i;
286       }
287       $this->player_n--;
288     }
289     else {
290       log_main($user->sess, "INCONSISTENCY ON TABLE.");
291     }
292   }
293
294 } // End class Table
295   
296 class User {
297   var $name;       // name of the user
298   var $sess;       // session of the user
299   var $lacc;       // last access (for the cleanup)
300   var $laccwr;     // last access (for the cleanup)
301   var $stat;       // status (outdoor, room, table, game, ...)
302   var $subst;      // substatus for each status   
303   var $step;       // step of the current status
304   var $trans_step; // step to enable transition between pages (disable == -1)
305   var $comm;       // commands array
306   var $asta_card;  // 
307   var $asta_pnt;   //
308
309   var $table;      // id of the current table (if in table state)
310   var $table_pos;  // idx on the table
311
312   function User($name, $sess, $stat = "", $subst = "", $table = -1) {
313     $this->name  = $name;
314     $this->sess  = $sess;
315     $this->lacc   = time();
316     $this->laccwr = time();
317     $this->stat  = $stat;
318     $this->subst  = $subst;
319     $this->step  = 1;
320     $this->trans_step  = -1;
321     $this->comm  = array();
322     $this->asta_card = -2;
323     $this->asta_pnt  = -1;
324
325     $this->table = $table;
326   }
327 }
328
329 class brisco {
330   var $user;
331   var $table;
332   var $comm; // commands for many people
333   var $step; // current step of the comm array
334   var $garbage_timeout;
335
336   function brisco () {
337     $this->user = array();
338
339     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
340       $this->user[$i] = new User("", "");
341     }
342     for ($i = 0 ; $i < TABLES_N ; $i++) 
343       $this->table[$i] = new Table();
344     $this->garbage_timeout = 0;
345   }
346
347   function garbage_manager($force)
348   {
349     
350     /* Garbage collector degli utenti in timeout */
351     $curtime = time();
352     if ($force || $this->garbage_timeout < $curtime) {
353       
354       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
355         $user_cur = &$this->user[$i];
356         if ($user_cur->sess == "")
357           continue;
358         
359         if ($user_cur->lacc + EXPIRE_TIME_RD < $curtime) { // Auto logout dell'utente
360           log_rd2($user_cur->sess, "AUTO LOGOUT.");
361
362           if ($user_cur->stat == 'table' || $user_cur->stat == 'room') {
363             log_auth($user_cur->sess, "Autologout session.");
364             
365             $user_cur->sess = "";
366             $user_cur->name = "";
367             $user_cur->the_end = FALSE;
368             
369             log_rd2($user_cur->sess, "AUTO LOGOUT.");
370             if ($user_cur->subst == 'sitdown' || $user_cur->stat == 'table')
371               $this->room_wakeup(&$user_cur);
372             else if ($user_cur->subst == 'standup')
373               $this->room_outstandup(&$user_cur);
374             else
375               log_rd2($sess, "LOGOUT FROM WHAT ???");
376           }
377           //    } // if (0 == 1) 
378           
379         }
380
381         if ($user_cur->laccwr + EXPIRE_TIME_SMAMMA < $curtime) { // lo rimettiamo in piedi
382           if ($user_cur->stat == 'room' && $user_cur->subst == 'sitdown') {
383             $this->room_wakeup(&$user_cur);
384             $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
385             $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);
386             $user_cur->step++;
387           }
388         }
389       }
390       log_rd2($user_cur->sess, "GARBAGE UPDATED!");
391       
392       $this->garbage_timeout = time() + GARBAGE_TIMEOUT;
393     }
394   }
395
396
397   function room_wakeup(&$user)
398   {
399     $table_idx = $user->table;
400     $table = &$this->table[$table_idx];
401
402     log_main("WAKEUP", "begin function table:".$table_idx."  stat: ".$user->stat."  subst: ".$user->subst);
403
404     $from_table = ($user->stat == "table");
405     if ($from_table) {
406       log_main("WAKEUP", "from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
407       for ($i = 0 ; $i < $table->player_n ; $i++) {
408         $user_cur = &$this->user[$table->player[$i]];
409         log_main("PREIMPOST", "INLOOP name: ".$user_cur->name);
410
411         if ($user_cur != $user) {
412           $user_cur->stat = "room";
413           $user_cur->subst = "sitdown";
414         }
415         else if ($user->sess != "") {
416           $user_cur->stat = "room";
417           $user_cur->subst = "standup";
418           $user_cur->table = -1;
419         }
420       }
421     }
422     else {
423       $user->stat = "room";
424       $user->subst = "standup";
425     }
426     /* aggiorna l'array dei giocatori al tavolo. */
427     $table->user_rem(&$this, &$user);
428
429     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
430       $user_cur = &$this->user[$i];
431       if ($user_cur->sess == '' || $user_cur->stat != 'room')
432         continue;
433       
434       log_main("VALORI", "name: ".$user_cur->name."from_table: ".$from_table."  tab: ".$user_cur->table." taix: ".$table_idx."  ucur: ".$user_cur."  us: ".$user);
435
436       $ret = "gst.st = ".($user_cur->step+1)."; ";
437       if ($from_table && ($user_cur->table == $table_idx || $user_cur == $user)) {
438         $ret .= 'gst.st_loc++; the_end=true; window.onunload = null; document.location.assign("index.php");|';
439         // $ret .= 'gst.st_loc++; document.location.assign("index.php");|';
440         log_main("DOCUMENT.index.php", "from table");
441       }
442       else if ($user_cur->stat == "room") {
443         log_main("DOCUMENT.index.php", "from table");
444
445         $ret .= table_content($this, $user_cur, $table_idx);
446         $ret .= standup_content($this, $user_cur);
447         
448         $act_content = table_act_content(FALSE, 0, $e, $user->table);
449         $ret .= sprintf('$("table_act%d").innerHTML = "%s";', $table_idx, $act_content);
450         
451         
452         if ($user_cur == $user) {
453           // set the new status 
454           $ret .=  'subst = "standup"; ';
455           // clean the action buttons in other tables
456           for ($e = 0 ; $e < TABLES_N ; $e++) {
457             if ($this->table[$e]->player_n < PLAYERS_N)
458               $ret .= sprintf('$("table_act%d").innerHTML = "%s";', $e, table_act_content(TRUE, 0, $e, $user->table));
459           }
460         }
461         else {
462           $act_content = table_act_content(($user_cur->subst == 'standup'), $table->player_n, $table_idx, $user_cur->table);
463           $ret .= sprintf('$("table_act%d").innerHTML = "%s";', $table_idx, $act_content);
464         }
465       }
466       log_wr($user_cur->sess, "ROOM_WAKEUP: ".$ret);
467       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
468       $user_cur->step++;
469     }
470   }
471   
472
473
474
475   function room_outstandup(&$user)
476   {
477     $this->room_sitdown(&$user, -1);
478   }
479   
480   function table_update(&$user)
481   {
482     log_main("table_update", "pre - USER: ".$user->name);
483
484     $table_idx = $user->table;
485
486     if ($table_idx > -1) 
487       $table = &$this->table[$table_idx];
488     
489     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
490       $ret = "";
491       $user_cur = &$this->user[$i];
492       if ($user_cur->sess == '' || $user_cur->stat != 'room')
493       continue;
494       
495       $ret = "gst.st = ".($user_cur->step+1)."; ";
496       if ($table_idx > -1)
497         $ret .= table_content($this, $user_cur, $table_idx);
498       
499       if ($user_cur == $user) {
500         $ret .= sprintf('$("myname").innerHTML = "<b>%s</b>: ";',  xcape($user->name));
501       }
502       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
503       $user_cur->step++;
504     }
505
506     log_main("table_update", "post");
507   }
508
509   function room_sitdown(&$user, $table_idx)
510   {
511     log_main("room_sitdown", ($user == FALSE ? "USER: FALSE" : "USER: ".$user->name));
512
513     if ($table_idx > -1) 
514       $table = &$this->table[$table_idx];
515     
516     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
517       $ret = "";
518       $user_cur = &$this->user[$i];
519       if ($user_cur->sess == '' || $user_cur->stat != 'room')
520       continue;
521       
522       $ret = "gst.st = ".($user_cur->step+1)."; ";
523       if ($table_idx > -1)
524       $ret .= table_content($this, $user_cur, $table_idx);
525       $ret .= standup_content($this, $user_cur);
526       
527       if ($user_cur == $user) {
528         $ret .=  'subst = "sitdown"; ';
529         // clean the action buttons in other tables
530         for ($e = 0 ; $e < TABLES_N ; $e++) {
531           $act_content = table_act_content(FALSE, 0, $e, $user_cur->table);
532           $ret .= sprintf('$("table_act%d").innerHTML = "%s";', $e, $act_content);
533         }
534       }
535       else if ($table_idx > -1) {
536         if ($table->player_n == PLAYERS_N) {
537           $act_content = table_act_content(($user_cur->subst == 'standup'), PLAYERS_N, $table_idx, $user_cur->table);
538           $ret .= sprintf('$("table_act%d").innerHTML = "%s";', $table_idx, $act_content);
539         }
540       }
541       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
542       $user_cur->step++;
543     }
544   }
545
546   function chatt_send(&$user, $mesg)
547   {
548     if ($user->stat == 'table') {
549       $table = &$this->table[$user->table];
550     }
551     
552     $user_mesg = substr($mesg,6);
553     
554     $dt = date("H:i ",time());
555     if (strncmp($user_mesg, "/nick ", 6) == 0) {
556       log_main($user->sess, "chatt_send BEGIN");
557
558       $name_new = str_replace(' ', '_', substr(trim(substr($user_mesg, 6)),0,12));
559       $user_mesg = "COMMAND ".$user_mesg;
560       // Search dup name
561       // change
562       // update local graph
563       // update remote graphs
564       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
565         $user_cur = &$this->user[$i];
566         //      if ($user_cur->sess == '' || $user_cur->stat != 'room')
567         if ($user_cur->sess == '')
568           continue;
569         if ($user_cur->name == $name_new) {
570           $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; ";
571           $user->comm[$user->step % COMM_N] .= sprintf('chatt_sub("%s","Nickname <b>%s</b> gi&agrave; in uso.");', $dt.NICKSERV, xcape($name_new));
572           $user->step++;
573           break;
574         }
575       }
576       if ($i == MAX_PLAYERS) {
577         $user->name = $name_new;
578
579       log_main($user->sess, "chatt_send start set");
580         
581
582         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
583           log_main($user->sess, "chatt_send set loop");
584           
585           $user_cur = &$this->user[$i];
586           if ($user_cur->sess == '')
587             continue;
588           if ($user_cur->stat == 'room') {
589             if ($user->stat == 'room' && $user->subst == 'standup') {
590               $this->standup_update(&$user);
591             }
592             else if ($user->stat == 'room' && $user->subst == 'sitdown' ||
593                      $user->stat == 'table') {
594               log_main($user->sess, "chatt_send pre table update");
595
596               $this->table_update(&$user);
597
598               log_main($user->sess, "chatt_send post table update");
599             }
600           }
601           else if ($user_cur->stat == 'table' && $user_cur->table == $user->table) {
602             $table = &$this->table[$user->table];
603             
604             $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
605             $user_cur->comm[$user_cur->step % COMM_N] = sprintf('set_names(" %s", " %s", " %s", " %s", " %s"); ',
606                 xcape($this->user[$table->player[($user_cur->table_pos)%PLAYERS_N]]->name),
607                 xcape($this->user[$table->player[($user_cur->table_pos+1)%PLAYERS_N]]->name),
608                 xcape($this->user[$table->player[($user_cur->table_pos+2)%PLAYERS_N]]->name),
609                 (PLAYERS_N == 3 ? "" :  xcape($this->user[$table->player[($user_cur->table_pos+3)%PLAYERS_N]]->name)),
610                 (PLAYERS_N == 3 ? "" :  xcape($this->user[$table->player[($user_cur->table_pos+4)%PLAYERS_N]]->name)));
611             if ($user_cur == $user)
612               $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('$("myname").innerHTML = "<b>%s</b>";', 
613                                                                    xcape($user->name,ENT_COMPAT,"UTF-8"));
614             $user_cur->step++;
615           }
616         }
617       }
618     }
619     else {
620       for ($i = 0 ; $i < ($user->stat == 'room' ? MAX_PLAYERS : PLAYERS_N) ; $i++) {
621         if ($user->stat == 'room') {
622           $user_cur = &$this->user[$i];
623           if ($user_cur->sess == '' || $user_cur->stat != 'room')
624             continue;
625         }
626         else {
627           $user_cur = &$this->user[$table->player[$i]];
628         }
629         
630         $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
631         $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('chatt_sub("%s","%s");',
632                                                              $dt.xcape($user->name), xcape($user_mesg));
633         $user_cur->step++;
634       }
635     }
636   }
637
638   function &get_user($sess, &$idx)
639   {
640     GLOBAL $PHP_SELF;
641     
642     if (strlen($sess) == SESS_LEN) {
643       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
644         if (strcmp($sess, $this->user[$i]->sess) == 0) {
645           // find it
646           $idx = $i;
647           return ($this->user[$i]);
648         }
649       }
650       log_main($sess, sprintf("get_user: Wrong sess from page [%s]",$PHP_SELF));
651       // for ($i = 0 ; $i < MAX_PLAYERS ; $i++) 
652       // log_main($sess, sprintf("get_user: Wrong sess compared with [%s]",$this->user[$i]->sess));
653     }
654     else {
655       log_main($sess, sprintf("get_user: Wrong strlen [%s]",$sess));
656     }
657     return (FALSE);
658   }
659
660   /*
661    * function &add_user(&$bri, &$sess, &$idx, $name)
662    *
663    * RETURN VALUE:
664    *   if ($idx != -1 && ret == FALSE)  =>  duplicated nick
665    *   if ($idx == -1 && ret == FALSE)  =>  no space left
666    *   if (ret == TRUE)                 =>  SUCCESS
667    */
668   function &add_user(&$sess, &$idx, $name)
669   {
670     $idx = -1;
671     $idfree = -1;
672     
673     log_auth("XXX", sprintf("ARRIVA: [%s]", $sess));
674     if (validate_sess($sess) == FALSE) 
675       $sess = "";
676
677     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
678       /* free user ? */
679       if (strcmp($sess, $this->user[$i]->sess) == 0) {
680         if ($idx == -1)
681           $idx = $i;
682       }
683       if ($idfree == -1 && strcmp("", $this->user[$i]->sess) == 0) {
684         $idfree = $i;
685       }
686       if (strcmp($this->user[$i]->name, $name) == 0) {
687         $idx = $i;
688         break;
689       }
690     }
691     if ($idx == -1)
692       $idx = $idfree;
693
694     log_auth("XXX", sprintf("TROVATO A QUESTO PUNTO [%d] sess [%s] name [%s]", $idx, $sess, $name));
695
696     if ($idx != -1 && $i == MAX_PLAYERS) {
697       /* SUCCESS */
698       if ($sess == "") {
699         $this->user[$idx]->sess = uniqid("");
700         $sess = $this->user[$idx]->sess;
701         
702       }
703       else {
704         $this->user[$idx]->sess = $sess;
705       }
706       $this->user[$idx]->name = $name;
707       $this->user[$idx]->stat = "room";
708       $this->user[$idx]->subst = "standup";
709       
710       log_main("XXX", sprintf("TROVATO LIBERO A [%d] sess [%s] name [%s]", $idx, $sess, $name));
711       
712       return ($this->user[$idx]);
713     }
714
715     return (FALSE);
716   }
717   
718   function standup_update(&$user)
719   {
720     for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
721       $user_cur = &$this->user[$i];
722       if ($user_cur->sess == '')
723         continue;
724
725       log_main("STANDUP START", $user_cur->stat);
726       
727       if ($user_cur->stat == 'room') {
728         $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ".standup_content($this, $user_cur);
729         if ($user_cur == $user)
730           $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('$("myname").innerHTML = "<b>%s</b>: ";',  xcape($user->name));
731         
732         log_main("FROM STANDUP", "NAME: ".$user_cur->name." SENDED: ".$user_cur->comm[$user_cur->step % COMM_N]);
733         
734         $user_cur->step++;
735       }
736     }
737   }
738
739
740 } // end class brisco
741
742 function make_seed()
743 {
744   list($usec, $sec) = explode(' ', microtime());
745   return (float) $sec + ((float) $usec * 100000);
746 }
747
748 function log_main($sess, $log) {
749   if (BRISK_DEBUG != TRUE)
750     return;
751
752   $fp = fopen("/tmp/brisk_main.log", 'a');
753   fwrite($fp, sprintf("SESS: [%s] [%s]\n", $sess, $log));
754   fclose($fp);
755 }
756
757 function log_rd($sess, $log) {
758   if (BRISK_DEBUG != TRUE)
759     return;
760
761   $fp = fopen("/tmp/brisk_rd.log", 'a');
762   fwrite($fp, sprintf("SESS: [%s] [%s]\n", $sess, $log));
763   fclose($fp);
764 }
765
766 function log_rd2($sess, $log) {
767   if (BRISK_DEBUG != TRUE)
768     return;
769
770   $fp = fopen("/tmp/brisk_rd2.log", 'a');
771   fwrite($fp, sprintf("SESS: [%s] [%s]\n", $sess, $log));
772   fclose($fp);
773 }
774
775 function log_send($sess, $log) {
776   if (BRISK_DEBUG != TRUE)
777     return;
778
779   $fp = fopen("/tmp/brisk_send.log", 'a');
780   fwrite($fp, sprintf("SESS: [%s] [%s]\n", $sess, $log));
781   fclose($fp);
782 }
783
784 function log_auth($sess, $log) {
785   if (BRISK_DEBUG != TRUE)
786     return;
787
788   $fp = fopen("/tmp/brisk_auth.log", 'a');
789   fwrite($fp, sprintf("SESS: [%d] [%s] [%s]\n", time(), $sess, $log));
790   fclose($fp);
791 }
792
793 function log_wr($sess, $log) {
794   if (BRISK_DEBUG != TRUE)
795     return;
796
797   $fp = fopen("/tmp/brisk_wr.log", 'a');
798   fwrite($fp, sprintf("SESS: [%s] [%s]\n", $sess, $log));
799   fclose($fp);
800 }
801
802 function log_load($sess, $log) {
803   if (BRISK_DEBUG != TRUE)
804     return;
805
806   $fp = fopen("/tmp/brisk_load.log", 'a');
807   fwrite($fp, sprintf("SESS: [%s] [%s]\n", $sess, $log));
808   fclose($fp);
809 }
810
811 function init_data()
812 {
813   $brisco = new brisco();
814
815   return $brisco;
816 }
817
818 function lock_data()
819 {
820         //  echo "LOCK: ".FTOK_PATH."/main";
821         //  exit;
822   if (($tok = ftok(FTOK_PATH."/main", "B")) == -1) {
823     echo "FTOK FAILED";
824     exit;
825   }
826   // echo "FTOK ".$tok."<br>";
827   if (($res = sem_get($tok)) == FALSE) {
828     echo "SEM_GET FAILED";
829     exit;
830   }
831   if (sem_acquire($res)) 
832     return ($res);
833   else
834     return (false);
835 }
836
837 function unlock_data($res)
838 {
839   return (sem_release($res));
840 }
841
842
843 function &load_data() 
844 {
845   if (($tok = ftok(FTOK_PATH."/main", "B")) == -1) {
846     echo "FTOK FAILED";
847     exit;
848   }
849
850   if ($shm = shm_attach($tok,100000 * TABLES_N)) {
851     if(($bri = @shm_get_var($shm, $tok)) == false) {
852       log_main("XXX", "INIT MAIN DATA");
853
854       $bri = init_data();
855       shm_put_var($shm, $tok, $bri);
856     }
857     
858     shm_detach($shm);
859
860     return ($bri);
861   }
862
863   return (NULL);
864 }
865
866
867 function save_data(&$bri) 
868 {
869   $ret =   FALSE;
870   $shm =   FALSE;
871   $isacq = FALSE;
872
873   // var_dump($bri);
874
875   if (($tok = ftok(FTOK_PATH."/main", "B")) == -1) 
876     return (FALSE);
877
878   do {
879     $isacq = TRUE;
880     
881     if (($shm = shm_attach($tok,100000 * TABLES_N)) == FALSE)
882       break;
883     
884     if (shm_put_var($shm, $tok, $bri) == FALSE)
885       break;
886     // log_main("XXX", "QUI CI ARRIVA [".$bri->user[0]->name."]");
887     $ret = TRUE;
888   } while (0);
889   
890   if ($shm)
891     shm_detach($shm);
892      
893   return ($ret);
894 }
895
896 function table_act_content($isstanding, $sitted, $table, $cur_table)
897 {
898   $ret = "";
899
900   if ($isstanding) {
901     if ($sitted < PLAYERS_N) {
902       $ret = sprintf('<input type=\\"button\\" class=\\"button\\" name=\\"xhenter%d\\"  value=\\"Mi siedo.\\" onclick=\\"act_sitdown(%d);\\">', $table, $table);
903     }
904   }
905   else {
906     if ($table == $cur_table)
907       $ret = sprintf('<input type=\\"button\\" class=\\"button\\" name=\\"xwakeup\\"  value=\\"Mi alzo.\\" onclick=\\"act_wakeup();\\">');
908     else
909       $ret = "";
910   }
911   return ($ret);
912 }
913
914 function table_content($bri, $user, $table_idx)
915 {
916   $content = "";
917
918   // TODO
919   //
920   //   Si possono usare i dati nella classe table
921   //
922
923   $sess = $user->sess;
924   $table = &$bri->table[$table_idx];
925
926   if ($user->stat != 'room')
927     return;
928
929   for ($i = 0 ; $i < $table->player_n ; $i++) {
930     $user_cur = &$bri->user[$table->player[$i]];
931
932     if ($user_cur == $user) 
933         { $hilion = "<b>"; $hilioff = "</b>"; }
934       else
935         { $hilion = ""; $hilioff = ""; }
936
937     log_main($bri->user[$e]->name, sprintf("IN TABLE [%d]", $table_idx));
938     
939     $content .= sprintf("%s%s%s<br>",$hilion, xcape($user_cur->name), $hilioff);
940   }
941   /*
942   for ( ; $i < PLAYERS_N ; $i++)
943     $content .= "<br>";
944   */
945
946   $ret .= sprintf('$("table%d").innerHTML = "%s";', $table_idx, $content);
947   
948   return ($ret);
949 }
950
951 function standup_content(&$bri, $user)
952 {
953   $ret = "";
954   $content = "";
955
956   if ($user->stat != 'room')
957     return;
958
959   for ($e = 0 , $ct = 0 ; $ct < 4 && $e < MAX_PLAYERS ; $e++) {
960     if ($bri->user[$e]->sess == "" || $bri->user[$e]->stat != "room" || $bri->user[$e]->name == "")
961       continue;
962     $ct++;
963   }
964
965   $content .= sprintf('<table cols=\\"%d\\" class=\\"table_standup\\">', $ct);
966
967   for ($e = 0 , $ct = 0 ; $e < MAX_PLAYERS ; $e++) {
968     if ($bri->user[$e]->sess == "" || $bri->user[$e]->stat != "room" || $bri->user[$e]->name == "")
969       continue;
970
971
972     if ($bri->user[$e]->subst == "standup") {
973       if (($ct % 4) == 0) {
974         $content .= '<tr>';
975       }
976       if ($bri->user[$e] == $user) 
977         { $hilion = "<b>"; $hilioff = "</b>"; }
978       else
979         { $hilion = ""; $hilioff = ""; }
980
981       $content .= sprintf('<td class=\\"room_standup\\">%s%s%s</td>',$hilion, xcape($bri->user[$e]->name), $hilioff);
982       if (($ct % 4) == 3) {
983         $content .= '</tr>';
984       }
985       $ct++;
986     }
987   }
988   $content .= '</table>';
989         
990   $content2 = '<input class=\\"button\\" name=\\"logout\\" value=\\"Esco.\\" onclick=\\"window.onunload = null; act_logout();\\" type=\\"button\\">';
991   $ret .= sprintf('$("standup").innerHTML = "%s";  $("esco").innerHTML = "%s";', 
992                   $content, $content2);
993
994   return ($ret);
995 }
996
997
998 function show_notify($text, $tout, $butt, $w, $h)
999 {
1000   log_main("SHOW_NOTIFY", $text);
1001   return sprintf('var noti = new notify(gst,"%s",%d,"%s",%d,%d);', $text, $tout, $butt, $w, $h);
1002 }
1003
1004 function briscola_show($bri, $table, $user)
1005 {
1006   $ptnadd = "";
1007   $ret = "";
1008
1009   if ($table->asta_card == 9) 
1010     $ptnadd = sprintf("<br>con %d punti", $table->asta_pnt);
1011   
1012   /* text of caller cell */
1013   if ($user->table_pos == $table->asta_win) 
1014     $ret .= sprintf('$("callerinfo").innerHTML = "Chiami%s:";', $ptnadd);
1015   else 
1016     $ret .= sprintf('$("callerinfo").innerHTML = "Chiama %s%s:";', 
1017                     xcape($bri->user[$table->player[$table->asta_win]]->name), $ptnadd);
1018
1019   $ret .= sprintf('$("caller").style.backgroundImage = \'url("img/brisk_caller_sand%d.png")\';',
1020                   $table->asta_win);
1021   $ret .= sprintf('$("callerimg").src = "img/%02d.png";', $table->briscola);
1022   $ret .= sprintf('$("caller").style.visibility = "visible";');
1023   $ret .= sprintf('$("chooseed").style.visibility = "hidden";');
1024   $ret .= sprintf('$("asta").style.visibility = "hidden";');
1025   $ret .= sprintf('show_astat(-2,-2,-2,-2,-2);');
1026   
1027   return ($ret);
1028 }
1029
1030
1031 function game_result($asta_pnt, $pnt)
1032 {
1033   if ($asta_pnt == 61) {
1034     if ($pnt > 60)
1035       return (1);
1036     else if ($pnt == 60)
1037       return (0);
1038     else
1039       return (-1);
1040   }
1041   else {
1042     if ($pnt >= $asta_pnt)
1043       return (1);
1044     else
1045       return (-1);
1046   }
1047 }
1048
1049 function multoval($mult)
1050 {
1051   if ($mult == 2)
1052     return ("doppio");
1053   else if ($mult == 4)
1054     return ("quadruplo");
1055   else
1056     return (sprintf("%d-plo", $mult));
1057 }
1058
1059 function show_table_info(&$bri, &$table, $table_pos)
1060 {
1061   $user = &$bri->user[$table->player[$table_pos]];
1062
1063   $pnt_min = $table->points_n - MAX_POINTS < 0 ? 0 : $table->points_n - MAX_POINTS;
1064   $noty = sprintf('<table class=\"points\"><tr><th></th>');
1065   
1066   // Names.
1067   for ($i = 0 ; $i < PLAYERS_N ; $i++) 
1068     $noty .= sprintf('<th class=\"td_points\">%s</th>', xcape($bri->user[$table->player[$i]]->name));
1069   $noty .= sprintf("</tr>");
1070
1071   // Points.
1072   log_main("show_table_info", "pnt_min: ".$pnt_min."   Points_n: ".$table->points_n);
1073
1074   for ($i = $pnt_min ; $i < $table->points_n ; $i++) {
1075     $noty .= sprintf('<tr><th class=\"td_points\">%d</th>', $i+1);
1076     for ($e = 0 ; $e < PLAYERS_N ; $e++) 
1077       $noty .= sprintf('<td class=\"td_points\">%d</td>', $table->points[$i % MAX_POINTS][$e]);
1078     $noty .= "</tr>";
1079   }
1080
1081   // Total points.
1082   $noty .= '<tr><th class=\"td_points\">Tot.</th>';
1083   for ($e = 0 ; $e < PLAYERS_N ; $e++) 
1084     $noty .= sprintf('<td class=\"td_points\">%d</td>', $table->total[$e]);
1085   $noty .= "</tr></table>";
1086
1087   if ($table->old_win != -1) {
1088     $win = $table->player[$table->old_win];
1089     $fri = $table->player[$table->old_friend];
1090
1091     $wol = game_result($table->old_asta_pnt, $table->old_pnt);
1092
1093     if ($win != $fri) {
1094       $noty .= sprintf("<hr>Nell'ultima mano ha chiamato <b>%s</b>, il socio era <b>%s</b>,<br>", 
1095                        xcape($bri->user[$win]->name),
1096                        xcape($bri->user[$fri]->name));
1097       if ($table->old_pnt == 120) {
1098         $noty .= sprintf("hanno fatto <b>cappotto</b> EBBRAVI!.<hr>");
1099       }
1100       else {
1101         $noty .= sprintf("dovevano fare <b>%s</b> punti e ne hanno fatti <b>%d</b>: hanno <b>%s</b>.<hr>",
1102                          ($table->old_asta_pnt > 61 ? "almeno ".$table->old_asta_pnt :
1103                           'pi&ugrave; di 60'), $table->old_pnt,
1104                          ($wol == 1 ? "vinto" : ($wol == 0 ? "pareggiato" : "perso")));
1105       }
1106     }
1107     else {
1108       $noty .= sprintf("<hr>Nell'ultima mano <b>%s</b> si &egrave; chiamato in mano,<br>", 
1109                        xcape($bri->user[$win]->name));
1110       if ($table->old_pnt == 120) {
1111         $noty .= sprintf("ha fatto <b>cappotto</b> EBBRAVO!.<hr>");
1112       }
1113       else {
1114         $noty .= sprintf("doveva fare <b>%s</b> punti e ne ha fatti <b>%d</b>: ha <b>%s</b>.<hr>",
1115                          ($table->old_asta_pnt > 61 ? "almeno ".$table->old_asta_pnt :
1116                           'pi&ugrave; di 60'), $table->old_pnt,
1117                          ($wol == 1 ? "vinto" : ($wol == 0 ? "pareggiato" : "perso")));
1118       }
1119     }
1120   }
1121   if ($table->mazzo == $table_pos) 
1122     $noty .= "Fai <b>tu</b> il mazzo,";
1123   else {
1124     $unam = xcape($bri->user[$table->player[$table->mazzo]]->name);
1125     $noty .= "Il mazzo a <b>$unam</b>,";
1126   }
1127
1128   if ($user->subst == 'asta') {
1129     if ($table->asta_win == -1)  // auction case
1130       $curplayer = $table->gstart % PLAYERS_N;
1131     else 
1132       $curplayer = $table->asta_win;
1133   }
1134   else if ($user->subst == 'game') {
1135     $curplayer = ($table->gstart + $table->turn) % PLAYERS_N;
1136   }
1137
1138
1139   if ($curplayer == $table_pos) {
1140     $noty .= " tocca a <b>te</b> giocare.";
1141   }
1142   else {
1143     $unam = xcape($bri->user[$table->player[$curplayer]]->name);
1144     $noty .= " tocca a <b>$unam</b> giocare.";
1145   }
1146
1147   if ($table->mult > 1) {
1148     $noty .= sprintf(" La partita vale <b>%s</b>.", multoval($table->mult));
1149   }
1150   $noty .= "<hr><br>";
1151
1152   $ret .= show_notify($noty, 3000, "torna alla partita", 500, 400);
1153   
1154   return ($ret);
1155 }
1156
1157 function root_wellcome($user)
1158 {
1159   GLOBAL $root_wellarr;
1160
1161   for ($i = 0 ; $i < count($root_wellarr) ; $i++)
1162     $ret .= sprintf('chatt_sub("ChanServ: ","%s");', str_replace('"', '\"', $root_wellarr[$i]));
1163
1164   return ($ret);
1165 }
1166
1167 function table_wellcome($user)
1168 {
1169   GLOBAL $table_wellarr;
1170
1171   for ($i = 0 ; $i < count($table_wellarr) ; $i++)
1172     $ret .= sprintf('chatt_sub("ChanServ: ","%s");', str_replace('"', '\"', $table_wellarr[$i]));
1173
1174   return ($ret);
1175 }
1176
1177 function show_room(&$bri, &$user)
1178 {
1179   $ret .= sprintf('gst.st = %d;',  $user->step);
1180   $ret .= sprintf('stat = "%s";',  $user->stat);
1181
1182   $ret .= root_wellcome($user);
1183   $ret .= sprintf('subst = "%s";', $user->subst);
1184   $ret .= sprintf('$("myname").innerHTML = "<b>%s</b>";', xcape($user->name,ENT_COMPAT,"UTF-8"));
1185   for ($i = 0 ; $i < TABLES_N ; $i++) {
1186     $ret .= table_content($bri, $user, $i);
1187     $act_content = table_act_content(($user->subst == 'standup'), 
1188                                      $bri->table[$i]->player_n, $i, $user->table);
1189     $ret .= sprintf('$("table_act%d").innerHTML = "%s";', $i, $act_content);
1190   }
1191   $ret .= standup_content($bri, $user);
1192   
1193   return ($ret);
1194 }
1195
1196
1197
1198 /* show table 
1199 is_transition (is from room to table ?)
1200 is_again      (is another game)
1201
1202 Examles of $is_transition, $is_again:
1203   from reload of the page:              FALSE, FALSE
1204   from sitdown in room:                 TRUE, FALSE
1205   from table: asta cmd e tutti passano: TRUE, TRUE
1206   from table: fine partita:             TRUE, TRUE
1207  */
1208 function show_table(&$bri, &$user, $sendstep, $is_transition, $is_again)
1209 {
1210   $table_idx = $user->table;
1211   $table = &$bri->table[$table_idx];
1212
1213   /****************
1214    FOR RELOAD:
1215      DONE - user names
1216      handed cards
1217      tabled cards
1218      taked  cards
1219      remark on/off
1220      cards dnd (and gameable card if its turn)
1221      who call and what
1222   ****************/
1223  
1224
1225   $ret = "table_init();";
1226   
1227   if (!$is_again) {
1228     /* GENERAL STATUS */
1229     $ret .= sprintf( 'gst.st = %d; stat = "%s"; subst = "%s"; table_pos = %d;',
1230                      $sendstep, $user->stat, $user->subst, $user->table_pos);
1231     /* BACKGROUND */
1232     $ret .= "background_set();";
1233     
1234     /* USERS INFO */
1235     $ret .= sprintf('$("myname").innerHTML = "<b>%s</b>";', xcape($user->name,ENT_COMPAT,"UTF-8"));
1236     $ret .= sprintf('set_names(" %s", " %s", " %s", " %s", " %s"); ',
1237                     xcape($bri->user[$table->player[($user->table_pos)%PLAYERS_N]]->name),
1238                     xcape($bri->user[$table->player[($user->table_pos+1)%PLAYERS_N]]->name),
1239                     xcape($bri->user[$table->player[($user->table_pos+2)%PLAYERS_N]]->name),
1240                     (PLAYERS_N == 3 ? "" :  xcape($bri->user[$table->player[($user->table_pos+3)%PLAYERS_N]]->name)),
1241                     (PLAYERS_N == 3 ? "" :  xcape($bri->user[$table->player[($user->table_pos+4)%PLAYERS_N]]->name)));
1242   }
1243   /* NOTIFY FOR THE CARD MAKER */
1244   if ($is_transition) { //  && $user->subst ==  "asta" superfluo
1245     $ret .= show_table_info(&$bri, &$table, $user->table_pos);
1246   }
1247   if (!$is_again) 
1248     $ret .= table_wellcome($user);
1249
1250   /* CARDS */
1251   if ($is_transition) { //  && $user->subst ==  "asta" superfluo
1252     $ret .= "|";
1253     
1254     for ($i = 0 ; $i < 8 ; $i++) {
1255       for ($e = 0 ; $e < PLAYERS_N ; $e++) {
1256         $ct = 0;
1257         for ($o = 0 ; $o < 40 && $ct < $i+1 ; $o++) {
1258           if ($table->card[$o]->owner == (($e + $table->gstart) % PLAYERS_N)) {
1259             $ct++;
1260             if ($ct == $i+1)
1261               break;
1262           }
1263         }
1264         log_rd($sess, "O ".$o." VAL ".$table->card[$o]->value." Owner: ".$table->card[$o]->owner);
1265         
1266         $ret .= sprintf( ' card_send(%d,%d,%d,%8.2f,%d);|', ($table->gstart + $e) % PLAYERS_N, 
1267                          $i, ((($e + PLAYERS_N - $user->table_pos + $table->gstart) % PLAYERS_N) == 0 ?
1268                               $table->card[$o]->value : -1), 
1269                          ($i == 7 && $e == (PLAYERS_N - 1) ? 1 : 0.5),$i+1);
1270       }
1271     }    
1272   }
1273   else {
1274     $taked  = array(0,0,0,0,0);
1275     $inhand = array(0,0,0,0,0);
1276     $ontabl  = array(-1,-1,-1,-1,-1);
1277     $cards  = array();
1278
1279     for ($i = 0 ; $i < 40 ; $i++) {
1280       if ($table->card[$i]->stat == 'hand') {
1281         if ($table->card[$i]->owner == $user->table_pos) {
1282           $cards[$inhand[$table->card[$i]->owner]] = $table->card[$i]->value;
1283         }
1284         $inhand[$table->card[$i]->owner]++;
1285       }
1286       else if ($table->card[$i]->stat == 'take') {
1287         log_main("Card taked:", $table->card[$i]->value."OWN: ".$table->card[$i]->owner);
1288         $taked[$table->card[$i]->owner]++;
1289       }
1290       else if ($table->card[$i]->stat == 'table') {
1291         $ontabl[$table->card[$i]->owner] = $i;
1292       }
1293     }
1294     $logg = "\n";
1295     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
1296       $logg .= sprintf("INHAND: %d   IN TABLE %d   TAKED %d\n", $inhand[$i], $ontabl[$i], $taked[$i]);
1297     }
1298     log_main("Stat table:", $logg);
1299
1300     /* Set ours cards. */
1301     $oursarg = "";
1302     for ($i = 0 ; $i < $inhand[$user->table_pos] ; $i++) 
1303       $oursarg .= ($i == 0 ? "" : ", ").$cards[$i];
1304     for ($i = $inhand[$user->table_pos] ; $i < 8 ; $i++) 
1305       $oursarg .= ($i == 0 ? "" : ", ")."-1";
1306     $ret .= sprintf('card_setours(%s);', $oursarg);
1307
1308     /* Dispose all cards */
1309     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
1310       /* Qui sotto al posto di + 1 c'era + ->gstart ... credo in modo errato */
1311       $ret .= sprintf('cards_dispose(%d,%d,%d);', $i,
1312                       $inhand[$i], $taked[$i]);
1313
1314       if ($ontabl[$i] != -1) {
1315         $ret .= sprintf('card_place(%d,%d,%d,%d,%d);',$i, $inhand[$i], 
1316                         $table->card[$ontabl[$i]]->value, 
1317                         $table->card[$ontabl[$i]]->x, $table->card[$ontabl[$i]]->y);
1318       }
1319     }
1320   }
1321
1322   /* Show auction */
1323   if ($user->subst == 'asta') {
1324
1325     /* show users auction status */
1326     $showst = "";
1327     for ($i = 0 ; $i < PLAYERS_N ; $i++) {
1328       $user_cur = &$bri->user[$table->player[$i]];
1329       $showst .= sprintf("%s%d", ($i == 0 ? "" : ", "), 
1330                          ($user_cur->asta_card < 9 ? $user_cur->asta_card : $user_cur->asta_pnt));
1331     }
1332     if (PLAYERS_N == 3)
1333         $showst .= ",-2,-2";
1334     $ret .= sprintf('show_astat(%s);', $showst);
1335
1336     if ($table->asta_win != -1 && $table->asta_win == $user->table_pos) {
1337       /* show card chooser */
1338       $ret .= sprintf('choose_seed(%s); $("asta").style.visibility = "hidden";',
1339                       $table->asta_card);
1340     }
1341     else {
1342       /* show auction */
1343       if ($user->table_pos == ($table->gstart % PLAYERS_N) &&
1344           $table->asta_win == -1) 
1345         $ret .= sprintf('dispose_asta(%d,%d);', 
1346                         $table->asta_card + 1, $table->asta_pnt+1);
1347       else
1348         $ret .= sprintf('dispose_asta(%d,%d);',
1349                         $table->asta_card + 1, -($table->asta_pnt+1));
1350     }
1351
1352     /* Remark */
1353     if ($table->asta_win == -1) { // auction case
1354       if ($user->table_pos == ($table->gstart % PLAYERS_N)) 
1355         $ret .= "remark_on();";
1356       else
1357         $ret .= "remark_off();";
1358     }
1359     else { // chooseed case
1360       if ($user->table_pos == $table->asta_win) 
1361         $ret .= "remark_on();";
1362       else
1363         $ret .= "remark_off();";
1364     }
1365   }
1366   else if ($user->subst == 'game') {
1367     /* HIGHLIGHT */
1368     if (($table->gstart + $table->turn) % PLAYERS_N == $user->table_pos) 
1369       $ret .= "is_my_time = true; remark_on();";
1370     else
1371       $ret .= "remark_off();";
1372     
1373     /* WHO CALL AND WATH */
1374     $ret .= briscola_show($bri, $table, $user);
1375     
1376   }
1377   return ($ret);
1378   }
1379
1380 function calculate_winner(&$table)
1381 {
1382   $briontab = FALSE;
1383   $ontab = array();
1384   $ontid = array();
1385   $cur_win  =  -1;
1386   $cur_val  = 100;
1387   $cur_seed = $table->briscola - ($table->briscola % 10);
1388
1389   for ($i = 0 ; $i < 40 ; $i++) {
1390     if ($table->card[$i]->stat != "table")
1391       continue;
1392
1393     log_wr($sess, sprintf("Card On table: [%d]", $i));
1394
1395     $v = $table->card[$i]->value; 
1396     $ontab[$table->card[$i]->owner] = $v;
1397     $ontid[$table->card[$i]->owner] = $i;
1398     /* se briscola setto il flag */
1399     if (($v - ($v % 10)) == $cur_seed)
1400       $briontab = TRUE;
1401   }
1402
1403   if ($briontab == FALSE) {
1404     $cur_win  = $table->gstart;
1405     $cur_val  = $ontab[$cur_win];
1406     $cur_seed = $cur_val - ($cur_val % 10);
1407   }
1408
1409   for ($i = 0 ; $i < PLAYERS_N ; $i++) {
1410     if (($ontab[$i] - ($ontab[$i] % 10)) == $cur_seed) {
1411       if ($ontab[$i] < $cur_val) {
1412         $cur_val = $ontab[$i];
1413         $cur_win = $i;
1414       }
1415     }
1416   }
1417
1418   for ($i = 0 ; $i < PLAYERS_N ; $i++) {
1419     $table->card[$ontid[$i]]->owner = $cur_win;
1420     $table->card[$ontid[$i]]->stat =  "take";
1421   }
1422   return ($cur_win);
1423 }
1424
1425 function calculate_points(&$table)
1426 {
1427   $all_points = array( 11,10,4,3,2, 0,0,0,0,0 );
1428
1429   $pro = 0;
1430
1431   if ($table->asta_pnt == 60)
1432     $table->asta_pnt = 61;
1433
1434   $table->old_win = $table->asta_win;
1435   $table->old_friend = $table->friend;
1436   $table->old_asta_pnt = $table->asta_pnt;
1437
1438   for ($i = 0 ; $i < 40 ; $i++) {
1439     $ctt = $table->card[$i]->value % 10;
1440     $own = $table->card[$i]->owner;
1441     if ($own == $table->asta_win || $own == $table->friend) 
1442       $pro += $all_points[$ctt];
1443   }
1444
1445   log_wr("XXX", sprintf("PRO: [%d]", $pro));
1446
1447   
1448   if ($table->asta_pnt == 61 && $pro == 60) { // PATTA !
1449     $table->points[$table->points_n % MAX_POINTS] = array();
1450     for ($i = 0 ; $i < PLAYERS_N ; $i++) 
1451       $table->points[$table->points_n % MAX_POINTS][$i] = 0;
1452     $table->points_n++;
1453     $table->old_pnt = $pro;
1454     $table->mult *= 2;
1455
1456     return;
1457   }
1458
1459   if ($pro >= $table->asta_pnt) 
1460     $sig = 1;
1461   else
1462     $sig = -1;
1463
1464   $table->points[$table->points_n % MAX_POINTS] = array();
1465   for ($i = 0 ; $i < 5 ; $i++) {
1466     if ($i == $table->asta_win) 
1467       $pt = ($i == $table->friend ? 4 : 2);
1468     else if ($i == $table->friend) 
1469       $pt = 1;
1470     else
1471       $pt = -1;
1472
1473     log_wr("XXX", sprintf("PRO: pt[%d][%d] = %d", $table->points_n % MAX_POINTS, $i, $pt));
1474
1475     $pt = $pt * $sig * $table->mult * ($pro == 120 ? 2 : 1);
1476
1477     log_wr("XXX", sprintf("PRO:[%d][%d][%d]", $sig, $table->mult, ($pro == 120 ? 2 : 1)));
1478     
1479     $table->points[$table->points_n % MAX_POINTS][$i] = $pt;
1480     $table->total[$i] += $pt;
1481   }
1482   $table->points_n++;
1483   $table->old_pnt = $pro;
1484   $table->mult = 1;
1485 }
1486
1487 function validate_sess($sess) {
1488   if (strlen($sess) == SESS_LEN) 
1489     return (TRUE);
1490   else
1491     return (FALSE);
1492 }
1493 ?>