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