pass by reference fixed [4]
[brisk.git] / web / briskin5 / Obj / briskin5.phh
1 <?php
2 /*
3  *  brisk - briskin5.phh
4  *
5  *  Copyright (C) 2006-2013 Matteo Nastasi
6  *                          mailto: nastasi@alternativeoutput.it
7  *                                  matteo.nastasi@milug.org
8  *                          web: http://www.alternativeoutput.it
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details. You should have received a
19  * copy of the GNU General Public License along with this program; if
20  * not, write to the Free Software Foundation, Inc, 59 Temple Place -
21  * Suite 330, Boston, MA 02111-1307, USA.
22  *
23  */
24 define('BIN5_PLAYERS_N', 3);
25 define('BIN5_CARD_HAND', 3); // normal value 8
26 define('BIN5_MAX_PLAYERS', BIN5_PLAYERS_N);
27 // define(BIN5_SHM_MIN', (50000 * BIN5_MAX_PLAYERS));
28 define('BIN5_SHM_MIN', 32768);
29 define('BIN5_SHM_MAX', (BIN5_SHM_MIN + 1048576));
30 define('BIN5_SHM_DLT', 32768);
31 define('BIN5_PROXY_PATH', PROXY_PATH."/bin5");
32
33 require_once('rules.phh');
34
35 define('BIN5_TOURNAMENT_CURRENT', BIN5_TOURNAMENT_NO_DRAW);
36
37 $mlang_bin5_bin5 = array(
38                          // br, hr, b, /b, win, fri
39                          'info_last' => array( 'it' => '%3$sultima mano%4$s',
40                                                'en' => '%3$slast hand%4$s'),
41                          'info_curr' => array( 'it' => '%3$smano corrente%4$s',
42                                                'en' => '%3$scurrent hand%4$s'),
43                          'info_yshuf'=> array( 'it' => 'Fai <b>tu</b> il mazzo, ',
44                                                'en' => 'It\'s <b>your</b> shuffled the cards, '),
45                          'info_shuf' => array( 'it' => 'Il mazzo a <b>%s</b>, ',
46                                                'en' => '<b>%s</b> shuffled the cards, '),
47                          'info_yturn'=> array( 'it' => ' tocca a <b>te</b> giocare.',
48                                                'en' => ' it\'s <b>your</b> turn.'),
49                          'info_turn' => array( 'it' => 'tocca a <b>%s</b> giocare.',
50                                                'en' => 'it\'s the <b>%s</b>\'s turn.'),
51                          'info_mult' => array( 'it' => ' La partita vale <b>%s</b>.',
52                                                'en' => ' The game worth <b>%s</b>.' ),
53                          'info_match'=> array( 'it' => 'Il codice della partita รจ <b>%d</b>.',
54                                                'en' => 'Match code is <b>%d</b>.'),
55
56                          'btn_bkgame'=> array( 'it' => 'torna alla partita',
57                                                'en' => 'back to the game'),
58                          'call_wptn' => array( 'it' => '<br>con %d punti',
59                                                'en' => '<br>with %d points'),
60                          'call_ycall'=> array( 'it' => 'Chiami%s:',
61                                                'en' => 'Call%s:'),
62                          'call_call' => array( 'it' => 'Chiama %s%s:',
63                                                'en' => 'The declarer is %s%s:')
64                           );
65
66 // MLANG
67 $table_wellarr = Array( 'it' => Array ( 'Benvenuto al tavolo. Se almeno tre giocatori non sbloccano l\'uscita cliccando il lucchetto, chi esce non pu&ograve; risedersi a un qualunque tavolo per '.floor(BAN_TIME/60).' minuti.'),
68                         'en' => Array ( 'EN Benvenuto al tavolo. Se almeno tre giocatori non sbloccano l\'uscita cliccando il lucchetto, chi esce non pu&ograve; risedersi a un qualunque tavolo per '.floor(BAN_TIME/60).' minuti.') );
69
70 function multoval($mult)
71 {
72     GLOBAL $G_lang;
73
74     if ($mult == 2)
75         return ($G_lang == 'en' ? 'double' : 'doppio');
76     if ($mult == 3)
77         return ($G_lang == 'en' ? 'triple' : 'triplo');
78     else if ($mult == 4)
79         return ($G_lang == 'en' ? 'quadruple' : 'quadruplo');
80     else
81         return (sprintf(($G_lang == 'en' ? "%d-ple" : "%d-plo"), $mult));
82 }
83
84 function dom_select_rules()
85 {
86     GLOBAL $G_lang;
87
88     $ret = "<select id='select_rules'>\n";
89     foreach (rules_keys() as $key) {
90         $value = rules_id2descr($key, $G_lang);
91         $ret .= sprintf("<option value='%d'>%s</option>\n", $key, $value);
92     }
93     $ret .= "</select>\n";
94
95     echo "$ret";
96 }
97
98 class Card {
99     var $value; /* 0 - 39 card value */
100     var $stat;  /* 'bunch', 'hand', 'table', 'take' */
101     var $owner; /* (table position 0-4) */
102     // var $pos;   /* Pos in hand. */
103     var $x;     /* When played the X position on the table of the owner. */
104     var $y;     /* When played the Y position on the table of the owner. */
105
106     function Card($value, $stat, $owner)
107     {
108         $this->value = $value;
109         $this->stat  = $stat; // Card stat
110         $this->owner = $owner;
111     }
112
113     function assign($stat,$owner)
114     {
115         $this->stat  = $stat; // Card stat
116         $this->owner = $owner;
117     }
118
119     function setpos($pos)
120     {
121         $this->pos   = $pos;
122     }
123
124     function play($x,$y)
125     {
126         $this->stat = 'table'; // Card stat
127         $this->x = $x;
128         $this->y = $y;
129     }
130
131     function take($newown)
132     {
133         $this->stat = 'take'; // Card stat
134         $this->owner = $newown;
135     }
136 } // end class Card
137
138 class Bin5_table extends Table {
139     var $card;              // il mazzo di carte
140     var $mazzo;             // chi e' di mazzo
141     var $gstart;            // first player of the current game
142     var $turn;              // turn in the game (absolute, not modularized)
143
144     var $asta_pla;          // array(); TRUE: in auction, FALSE: out of the auction
145     var $asta_pla_n;        // number of players in auction
146     var $asta_card;         // current card for auction
147     var $asta_pnt;          // current point for auction
148
149     var $mult;
150     var $points;            // points array
151     var $points_n;          // number of row of points
152     var $total;
153
154     var $asta_win;          // the caller idx position at table
155     var $briscola;
156     var $tourn_pts;         // points in the caller hand
157     var $friend;            // the callee idx position at table
158
159     var $match_id;          // the id of the match on the database (-1 == just not saved)
160
161     var $old_act;           // last action that trigs the end of the game
162     var $old_mazzo;
163     var $old_reason;
164     var $old_asta_pnt;
165     var $old_mult;
166     var $old_pnt;           // points made by caller and callee
167     var $old_asta_win;      // the old caller idx position at table
168     var $old_friend;        // the old callee idx position at table
169
170     var $old_tourn_pts;     // the old tournment computed points in the hand of caller
171     var $rules;
172
173     function Bin5_table()
174     {
175     }
176
177
178     /* CREATE() NOT USED
179        function create($idx)
180        {
181        if (($thiz =& new Bin5_table()) == FALSE)
182        return (FALSE);
183
184        $thiz->create($idx);
185
186        $thiz->card      =   FALSE;
187        $thiz->asta_pla  =   array(); // TRUE: in auction, FALSE: out of the auction
188        $thiz->asta_pla_n=  -1;
189        $thiz->asta_card =  -1;
190        $thiz->asta_pnt  =  -1;
191        $thiz->mult      =   0;
192
193        $thiz->points    =   array( );
194        $thiz->points_n  =   0;
195        $thiz->total     =   array( 0, 0, 0, 0, 0);
196        $thiz->asta_win  =  -1;
197        $thiz->briscola  =  -1;
198        $thiz->tourn_pts =  -1;
199        $thiz->friend    =  -1;
200        $thiz->turn      =   0;
201
202        $thiz->match_id     = -1;
203
204        $thiz->old_act      = -1;
205        $thiz->old_mazzo    = -1;
206        $thiz->old_reason   = "";
207        $thiz->old_asta_pnt = -1;
208        $thiz->old_mult     = -1;
209        $thiz->old_pnt      = -1;
210        $thiz->old_asta_win = -1;
211        $thiz->old_friend   = -1;
212
213        return ($thiz);
214        }
215     */
216
217     /* CLONE() NOT USED
218        function myclone(&$from)
219        {
220        if (($thiz =& new Bin5_table()) == FALSE)
221        return (FALSE);
222
223        parent::copy($from);
224
225        $thiz->card         = $from->card;
226        $thiz->mazzo        = $from->mazzo; // REVIEW
227        $thiz->gstart       = $from->gstart;
228        $thiz->turn         = $from->turn;
229
230        $thiz->asta_pla     = $from->asta_pla;
231        $thiz->asta_pla_n   = $from->asta_pla_n;
232        $thiz->asta_card    = $from->asta_card;
233        $thiz->asta_pnt     = $from->asta_pnt;
234
235        $thiz->mult         = $from->mult;
236        $thiz->points       = $from->points;
237        $thiz->points_n     = $from->points_n;
238        $thiz->total        = $from->total;
239
240        $thiz->asta_win     = $from->asta_win;
241        $thiz->briscola     = $from->briscola;
242        $thiz->tourn_pts    = $from->tourn_pts;
243        $thiz->friend       = $from->friend;
244
245        $thiz->match_id     = $from->match_id;
246
247        $thiz->old_act      = $from->old_act;
248        $thiz->old_mazzo    = $from->old_mazzo;
249        $thiz->old_reason   = $from->old_reason;
250        $thiz->old_asta_pnt = $from->old_asta_pnt;
251        $thiz->old_mult     = $from->mult;
252        $thiz->old_pnt      = $from->old_pnt;
253        $thiz->old_asta_win = $from->old_asta_win;
254        $thiz->old_friend   = $from->old_friend;
255
256        return ($thiz);
257        }
258     */
259
260     function parentcopy(&$from)
261     {
262         parent::copy($from);
263     }
264
265     function spawn(&$from)
266     {
267         GLOBAL $G_lang;
268         if (($thiz =& new Bin5_table()) == FALSE)
269             return (FALSE);
270
271         $thiz->parentcopy($from);
272
273         log_main("PLAYER_N - spawn.".$thiz->player_n);
274
275         $thiz->card = array();
276         $thiz->bunch_create();
277         $thiz->mazzo  = rand(0,PLAYERS_N-1);
278         $thiz->points = array();
279         $thiz->total  = array();
280         $thiz->points_n = 0;
281         $thiz->mult     = 0;
282
283         $thiz->match_id     = -1;
284
285         $thiz->old_asta_win = -1;
286         $thiz->old_reason = "";
287
288         $rules_name = rules_id2name(BIN5_TOURNAMENT_CURRENT);
289         $thiz->rules = new $rules_name($thiz);
290         // players are rearranged in an dedicated array
291         $thiz->player = array();
292         for ($i = 0 ; $i < $from->player_n ; $i++)
293             $thiz->player[$i] = $i;
294
295         log_main("TABLE_OLD_WIN - spawn:".$thiz->old_asta_win);
296
297         return ($thiz);
298     }
299
300
301     //   function bunch_create_old() function AND
302     //   {
303     //     $ret = array();
304     //
305     //     for ($i = 0 ; $i < (BIN5_CARD_HAND * BIN5_PLAYERS_N) ; $i++) {
306     //       // for ($i = 0 ; $i < (BIN5_CARD_HAND * BIN5_PLAYERS_N) ; $i++) {
307     //       $ret[$i] =& new Card($i, 'bunch', 'no_owner');
308     //     }
309     //
310     //     $oret = &$ret;
311     //     return ($oret);
312     //   }
313
314     function bunch_create()
315     {
316         $ret = array();
317
318         for ($i = 0 ; $i < (BIN5_CARD_HAND * BIN5_PLAYERS_N) ; $i++) {
319             $this->card[$i] = new Card($i, 'bunch', 'no_owner');
320         }
321     }
322
323     function bunch_make()
324     {
325         log_main("bunch_make start");
326         $ct = array(0,0,0,0,0);
327
328         mt_srand(make_seed());
329
330         for ($i = (BIN5_CARD_HAND * BIN5_PLAYERS_N) - 1 ; $i >= 0 ; $i--)
331             $rest[$i] = $i;
332
333         for ($i = (BIN5_CARD_HAND * BIN5_PLAYERS_N) - 1 ; $i >= 0 ; $i--) {
334             $rn = rand(0, $i);
335
336             if ($rn == 0)
337                 log_main("RND ZERO");
338
339             $id = $rest[$rn];
340
341             $owner = $i % BIN5_PLAYERS_N;
342             $this->card[$id]->assign('hand', $owner);
343
344             $rest[$rn] = $rest[$i];
345             // $pubbpos[$rn2] = $pubbpos[$i];
346         }
347         log_main("bunch_make end");
348     }
349
350     function init($userarr)
351     {
352         /* MOVED INTO SPAWN
353            $this->mazzo    =  rand(0,PLAYERS_N-1);
354            $this->points_n =  0;
355            $this->mult     =  0;
356            $this->old_asta_win  = -1;
357            $this->old_reason = "";
358         */
359         for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
360             $this->total[$i] = 0;
361             $user_cur = $userarr[$this->player[$i]];
362             $user_cur->stat_set('table');
363             $user_cur->exitislock = TRUE;
364         }
365
366         log_main("table::init: ci siamo");
367     }
368
369     function game_init($userarr)
370     {
371         log_rd2("GSTART 4");
372
373         $this->gstart = ($this->mazzo+1) % BIN5_PLAYERS_N;
374         $this->bunch_make();
375
376         $this->asta_pla_n = BIN5_PLAYERS_N;
377         $this->asta_card = -1;
378         $this->asta_pnt  = 60;
379         $this->asta_win  = -1;
380         $this->briscola  = -1;
381         $this->tourn_pts = -1;
382         $this->friend    = -1;
383         $this->turn      =  0;
384
385         for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
386             $this->asta_pla[$i] = TRUE;
387             $user_cur = $userarr[$this->player[$i]];
388             $user_cur->subst = 'asta';
389             $user_cur->asta_card = -2;
390             $user_cur->asta_pnt  = -1;
391             $user_cur->handpt = $this->hand_points($i);
392             $this->rules->tourn_points($user_cur, $i);
393         }
394         log_rd2("GEND 4");
395     }
396
397     function game_next($delta)
398     {
399         $this->old_mazzo = $this->mazzo;
400         $this->mazzo  = ($this->mazzo + $delta) % BIN5_PLAYERS_N;
401     }
402
403     function mult_inc($val)
404     {
405         $this->old_mult = $this->mult;
406         $this->mult += $val;
407     }
408
409     function mult_set($val)
410     {
411         $this->old_mult = $this->mult;
412         $this->mult = $val;
413     }
414
415     function hand_points($idx)
416     {
417         GLOBAL $G_all_points;
418
419         $tot = 0;
420
421         for ($i = 0 ; $i < (BIN5_CARD_HAND * BIN5_PLAYERS_N) ; $i++) {
422             // for ($i = 0 ; $i < 40 ; $i++) {
423             if ($this->card[$i]->owner != $idx)
424                 continue;
425
426             $ctt = $this->card[$i]->value % 10;
427             $tot += $G_all_points[$ctt];
428         }
429
430         return ($tot);
431     }
432
433
434     function exitlock_show($userarr, $table_pos)
435     {
436         $ct = $this->exitlock_calc($userarr, $table_pos);
437
438         $ret = sprintf('exitlock_show(%d, %s);', $ct,
439                        ($userarr[$this->player[$table_pos]]->exitislock ? 'true' : 'false'));
440         return ($ret);
441     }
442
443     function exitlock_calc(&$userarr, $table_pos)
444     {
445         $ct = 0;
446
447         for ($i = 0 , $ct = 0 ; $i < PLAYERS_N ; $i++) {
448             if ($userarr[$this->player[$i]]->exitislock == FALSE)
449                 $ct++;
450         }
451
452         return ($ct);
453     }
454
455     function match_continue(&$bri, $user, $match_id_s)
456     {
457         //
458         //  Rules: update version following loaded tcode
459         //
460         $ret = FALSE;
461         $curtime = time();
462
463         do {
464             if ($this->match_id != -1) {
465                 $msg = sprintf("Stai giร  giocando la partita con codice %d.", $this->match_id);
466                 break;
467             }
468
469             /* - verify if match_id and user are both valid to accept
470                the match_continue request - */
471             $match_id = (int)$match_id_s;
472             if ($match_id <= 0) {
473                 $msg = "questa partita non esiste";
474                 break;
475             }
476
477             if ($user->continue_get() == $match_id) {
478                 $msg = "Hai giร  richiesto di continuare questa partita.";
479                 break;
480             }
481             // retrieves users list for this match
482             $match_data = array();
483             if (($bdb = BriskDB::create()) != FALSE) {
484                 // match_order_get return FALSE for old matches
485                 $ucodes = $bdb->match_order_get($match_data, $match_id, BIN5_PLAYERS_N);
486                 unset($bdb);
487             }
488             if ($ucodes == FALSE) {
489                 $msg = "questa partita non รจ stata memorizzata correttamente";
490                 break;
491             }
492
493             // if current user code must be in the users list
494             if (array_search($user->code, $ucodes) === FALSE) {
495                 $msg = sprintf("Questo utente non compare nella partita che si vuole continuare [%d].", $user->code);
496                 break;
497             }
498
499             /* - the user is in the list, add the match_id to his profile
500                and check if he is the N'th to require continue - */
501
502             $continue_tot = 0;
503             for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
504                 $user_cur = &$bri->user[$this->player[$i]];
505
506                 if ($user == $user_cur) {
507                     $continue_tot += 1;
508                     continue;
509                 }
510
511                 if ($user_cur->continue_get() == BIN5_USER_CONTINUE_INIT)
512                     continue;
513
514                 if ($user_cur->continue_get() != $match_id)
515                     break;
516                 $continue_tot += 1;
517             }
518             if ($i < BIN5_PLAYERS_N) {
519                 $msg = sprintf("<b>L'utente <i>%s</i> voleva giร  continuare la partita nยฐ %d.</b>",
520                                xcape($user_cur->name), $user_cur->continue_get());
521                 break;
522             }
523
524             // set the match_id for the current user
525             $user->continue_set($match_id);
526
527             $ret = TRUE;
528             // not all players set the continue match than we exit
529             if ($continue_tot < BIN5_PLAYERS_N) {
530                 $msg = sprintf("<b>L'utente <i>%s</i> vorrebbe continuare la partita nยฐ %d.</b>",
531                                xcape($user->name), $match_id);
532                 break;
533             }
534
535             /* - all users decide to continue the same match, update all infos and rearrange users
536                to the right positions on the table - */
537
538             /*  reset users table order */
539             for ($i = 0 ; $i < BIN5_PLAYERS_N - 1 ; $i++) {
540                 if ($bri->user[$this->player[$i]]->code == $ucodes[$i]) {
541                     continue;
542                 }
543                 for ($e = $i + 1 ; $e < BIN5_PLAYERS_N ; $e++) {
544                     if ($bri->user[$this->player[$e]]->code == $ucodes[$i]) {
545                         $swap = $this->player[$i];
546                         $this->player[$i] = $this->player[$e];
547                         $this->player[$e] = $swap;
548                         $bri->user[$this->player[$i]]->table_pos = $i;
549                         $bri->user[$this->player[$e]]->table_pos = $e;
550                     }
551                 }
552             }
553             for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
554                 fprintf(STDERR, "USERZ: [%s]\n", $bri->user[$this->player[$i]]->name);
555             }
556
557             // update database info to be aligned with current table (ttok and table_idx
558             if (($bdb = BriskDB::create()) != FALSE) {
559                 if ($bdb->match_continue($match_id, $this, $user->table_orig) == FALSE) {
560                     unset($bdb);
561                     $msg = "aggiornamento dei dati della partita fallito";
562                     break;
563                 }
564                 unset($bdb);
565             }
566
567             /* update rules engine */
568             $rules_name = rules_id2name($match_data['tcode']);
569             $this->rules = new $rules_name($this);
570
571             /* bunch and multiplier status set */
572             $this->mazzo = $match_data['mazzo_next'];
573             $this->mult  = $match_data['mult_next'];
574             $this->match_id = $match_id;
575             $this->game_init($bri->user);
576
577             /* reload of the page with the new layout */
578             for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
579                 $user_cur = &$bri->user[$this->player[$i]];
580
581                 $user_cur->trans_step = $user_cur->step + 1;
582                 $user_cur->comm[$user_cur->step % COMM_N] = sprintf('gst.st_loc++; gst.st=%d; xstm.stop(); window.onunload = null ; window.onbeforeunload = null ; document.location.assign("index.php");|', $user_cur->step+1);
583                 $user_cur->step_inc();
584
585                 // a void command force xynt-streamer to flush all data to client
586                 $user_cur->trans_step = $user_cur->step + 1;
587                 $user_cur->comm[$user_cur->step % COMM_N] = "";
588                 $user_cur->step_inc();
589
590                 $user_cur->comm[$user_cur->step % COMM_N] = show_table($bri, $user_cur, $user_cur->step+1, TRUE, FALSE);
591                 $user_cur->step_inc();
592             }
593             return (TRUE);
594         } while (FALSE);
595
596         $dt = date("H:i ", $curtime);
597         for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
598             if ($ret == FALSE && $this->player[$i] != $user->idx)
599                 continue;
600             $user_cur = &$bri->user[$this->player[$i]];
601             $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
602             $user_cur->comm[$user_cur->step % COMM_N] .= nickserv_msg($dt, $msg);
603             $user_cur->step_inc();
604         }
605     }
606
607     function rules_change(&$bri, $user, $rules_id_s)
608     {
609         GLOBAL $G_lang;
610
611         //
612         //  Rules: update version following loaded tcode
613         //
614         $ret = FALSE;
615         $curtime = time();
616
617         do {
618             if ($this->match_id != -1) {
619                 // FIXME_LANG
620                 $msg = sprintf("Stai giร  giocando la partita con codice %d.", $this->match_id);
621                 break;
622             }
623
624             if ($this->asta_card != -1 || $this->asta_pla_n < BIN5_PLAYERS_N) {
625                 // FIXME_LANG
626                 $msg = sprintf("La partita รจ giร  stata avviata.");
627                 break;
628             }
629
630             $rules_id = (int)$rules_id_s;
631             if (! in_array($rules_id, rules_keys())) {
632                 // FIXME_LANG
633                 $msg = "queste regole non esistono o non sono attive";
634                 break;
635             }
636
637             if ($user->rules_get() == $rules_id) {
638                 // FIXME_LANG
639                 $msg = "hai giร  richiesto di usare queste regole";
640                 break;
641             }
642
643             /* - the user is in the list, add the match_id to his profile
644                and check if he is the N'th to require continue - */
645
646             $rules_tot = 0;
647             for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
648                 $user_cur = &$bri->user[$this->player[$i]];
649
650                 if ($user == $user_cur) {
651                     $rules_tot += 1;
652                     continue;
653                 }
654
655                 if ($user_cur->rules_get() == BIN5_USER_CONTINUE_INIT)
656                     continue;
657
658                 if ($user_cur->rules_get() != $rules_id)
659                     break;
660                 $rules_tot += 1;
661             }
662             if ($i < BIN5_PLAYERS_N) {
663                 // FIXME_LANG
664                 $msg = sprintf("<b>L'utente <i>%s</i> voleva giร  usare le %s.</b>",
665                                xcape($user_cur->name), xcape(rules_id2descr($user_cur->rules_get(), $G_lang)));
666                 break;
667             }
668
669             // set the match_id for the current user
670             $user->rules_set($rules_id);
671
672             $ret = TRUE;
673             // not all players set the continue match than we exit
674             if ($rules_tot < BIN5_PLAYERS_N) {
675                 // FIXME_LANG
676                 $msg = sprintf("<b>L'utente <i>%s</i> vorrebbe usare le %s.</b>",
677                                xcape($user->name), xcape(rules_id2descr($rules_id, $G_lang)));
678                 break;
679             }
680
681             /* - all users decide to continue the same match, update all infos and rearrange users
682                to the right positions on the table - */
683
684             /* update rules engine */
685             $rules_name = rules_id2name($rules_id);
686             $this->rules = new $rules_name($this);
687
688             // $this->game_init(&$bri->user);
689
690             /* reload of the page with the new layout */
691             for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
692                 $user_cur = &$bri->user[$this->player[$i]];
693                 $this->rules->tourn_points($user_cur, $i);
694
695                 $user_cur->rules_set(BIN5_USER_CONTINUE_INIT);
696                 $user_cur->trans_step = $user_cur->step + 1;
697                 $user_cur->comm[$user_cur->step % COMM_N] = sprintf('gst.st_loc++; gst.st=%d; xstm.stop(); window.onunload = null ; window.onbeforeunload = null ; document.location.assign("index.php");|', $user_cur->step+1);
698                 $user_cur->step_inc();
699
700                 // a void command force xynt-streamer to flush all data to client
701                 $user_cur->trans_step = $user_cur->step + 1;
702                 $user_cur->comm[$user_cur->step % COMM_N] = "";
703                 $user_cur->step_inc();
704
705                 $user_cur->comm[$user_cur->step % COMM_N] = show_table(&$bri, &$user_cur, $user_cur->step+1, TRUE, FALSE);
706                 $user_cur->step_inc();
707             }
708             return (TRUE);
709         } while (FALSE);
710
711         $dt = date("H:i ", $curtime);
712         if ($ret == TRUE) {
713             for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
714                 $user_cur = &$bri->user[$this->player[$i]];
715                 $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
716                 $user_cur->comm[$user_cur->step % COMM_N] .= nickserv_msg($dt, $msg);
717                 $user_cur->step_inc();
718             }
719         }
720         else {
721             $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; ";
722             $user->comm[$user->step % COMM_N] = xcape(sprintf("rules_set(%d);",
723                                                               $this->rules->id));
724             $user->comm[$user->step % COMM_N] .= nickserv_msg($dt, $msg);
725             $user->step_inc();
726         }
727     } // end function rules_change
728 } // end class Bin5_table
729
730
731
732
733 define('BIN5_USER_FLAG_RING_ENDAUCT', 0x01);
734 define('BIN5_USER_CONTINUE_INIT', -1);
735
736 define('BIN5_USER_RULES_INIT', -1);
737 class Bin5_user extends User {
738     var $asta_card;  //
739     var $asta_pnt;   //
740     var $handpt;     // Total card points at the beginning of the current hand.
741     var $exitislock; // Player can exit from the table ?
742     var $privflags;  // Flags for briskin5 only
743
744     var $continue;   // Id of the match that the user would continue
745     var $rules;      // Id of rules required by user
746
747     var $asta_tourn_pts;    // array with tournment points for each suit
748
749     const BASE = "../";
750
751     function User() {
752     }
753
754     /* CREATE NOT USED
755        function create($name, $sess, $stat = "", $subst = "", $table = -1, $ip="0.0.0.0") {
756        if (($thiz =& new User()) == FALSE)
757        return (FALSE);
758
759        $thiz->asta_card = -2;
760        $thiz->asta_pnt  = -1;
761        $thiz->handpt = -1;
762        $thiz->exitislock = TRUE;
763        $thiz->privflags = 0;
764        $thiz->continue = BIN5_USER_CONTINUE_INIT;
765        $thiz->rules = BIN5_USER_RULES_INIT;
766
767        return ($thiz);
768        }
769     */
770
771     function parentcopy(&$from)
772     {
773         parent::copy($from);
774     }
775
776     function copy(&$from)
777     {
778         $this->parentcopy($from);
779
780         $this->asta_card  = $from->asta_card;
781         $this->asta_pnt   = $from->asta_pnt;
782         $this->handpt     = $from->handpt;
783         $this->exitislock = $from->exitislock;
784         $this->privflags  = $from->privflags;
785         $this->continue   = $from->continue;
786         $this->rules      = $from->rules;
787     }
788
789     /* CLONE NOT USED
790        function myclone(&$from)
791        {
792        if (($thiz =& new User()) == FALSE)
793        return (FALSE);
794
795        $thiz->copy($from);
796
797        return ($thiz);
798        }
799     */
800
801     static function spawn($from, &$bri, $table, $table_pos, $get, $post, $cookie)
802     {
803         if (($thiz = new Bin5_user()) == FALSE)
804             return (FALSE);
805
806         if (($CO_bin5_pref_ring_endauct = gpcs_var("CO_bin5_pref_ring_endauct", $get, $post, $cookie)) === FALSE) {
807             $CO_bin5_pref_ring_endauct = "";
808         }
809
810         $thiz->parentcopy($from);
811
812         /* NOTE: at this moment idx and table_pos fields have the same value
813            but diffentent functions, we keep them separated for a while */
814         $thiz->room       = $bri;
815         $thiz->idx        = $table_pos; // it is the position in the mini-room,
816                                         // not related to table pos (see below)
817         $thiz->asta_card  = -2;
818         $thiz->asta_pnt   = -1;
819         $thiz->handpt     = -1;
820         $thiz->exitislock = TRUE;
821         $thiz->continue   = BIN5_USER_CONTINUE_INIT;
822         $thiz->rules      = BIN5_USER_RULES_INIT;
823
824         log_wr("Bin5 constructor");
825
826         $thiz->privflags  = ($CO_bin5_pref_ring_endauct == "true" ? BIN5_USER_FLAG_RING_ENDAUCT : 0) | 0;
827
828         $thiz->table_orig = $table;
829         $thiz->table      = 0;
830         $thiz->table_pos  = $table_pos;
831
832         $thiz->step_inc();
833
834         return ($thiz);
835     }
836
837     function step_set($step)
838     {
839         $this->step = $step & 0x7fffffff;
840
841         return TRUE;
842     }
843
844     function step_inc($delta = 1) {
845         $this->step += $delta;
846         /* modularization because unpack() not manage unsigned 32bit int correctly */
847         $this->step &= 0x7fffffff;
848
849         return (TRUE);
850     }
851
852     static function load_step($tab_id, $sess)
853     {
854         $fp = FALSE;
855         do {
856             if (validate_sess($sess) == FALSE)
857                 break;
858
859             if (file_exists(BIN5_PROXY_PATH."/table".$tab_id) == FALSE)
860                 mkdir(BIN5_PROXY_PATH."/table".$tab_id, 0775, TRUE);
861             if (($fp = @fopen(BIN5_PROXY_PATH."/table".$tab_id."/".$sess.".step", 'rb')) == FALSE)
862                 break;
863             if (($s = fread($fp, 8)) == FALSE)
864                 break;
865             if (mb_strlen($s, "ASCII") != 8)
866                 break;
867             $arr = unpack('Ls/Li', $s);
868             fclose($fp);
869
870             // log_rd2("A0: ".$arr[0]."  A1: ".$arr[1]);
871             return ($arr);
872         } while (0);
873
874         if ($fp != FALSE)
875             fclose($fp);
876
877         log_rd2("STEP_GET [".$sess."]: return false ");
878
879         return (FALSE);
880     }
881
882     function save_step()
883     {
884         do {
885             if (validate_sess($this->sess) == FALSE)
886                 break;
887             if (file_exists(BIN5_PROXY_PATH."/table".$this->table_orig) == FALSE)
888                 mkdir(BIN5_PROXY_PATH."/table".$this->table_orig, 0775, TRUE);
889             if (($fp = @fopen(BIN5_PROXY_PATH."/table".$this->table_orig."/".$this->sess.".step", 'w')) == FALSE)
890                 break;
891             fwrite($fp, pack("LL",$this->step, $this->idx));
892             fclose($fp);
893
894             log_main("step_set [".$this->sess. "] [".$this->step."]");
895
896             return (TRUE);
897         } while (0);
898
899         return (FALSE);
900     }
901
902     static function unproxy_step($tab_id, $sess)
903     {
904         log_rd2("UNPROXY: ".BIN5_PROXY_PATH."/table".$tab_id."/".$sess.".step");
905         if (file_exists(BIN5_PROXY_PATH."/table".$tab_id) == FALSE)
906             return;
907
908         @unlink(BIN5_PROXY_PATH."/table".$tab_id."/".$sess.".step");
909     }
910
911     function destroy_data($tab_id)
912     {
913         do {
914             if (($tok = @ftok(FTOK_PATH."/bin5/table".$tab_id."/user".$this->table_pos, "B")) == -1) {
915                 log_crit("BIN5 USER DATA REMOVE FAILED 1 [".FTOK_PATH."/bin5/table".$tab_id."/user".$this->table_pos."]");
916                 break;
917             }
918
919             if (($shm = @shmop_open($tok, 'a', 0, 0)) == FALSE) {
920                 log_crit("BIN5 USER DATA REMOVE FAILED 2");
921                 break;
922             }
923             if (shmop_delete($shm) == 0) {
924                 log_crit("BIN5 USER DATA REMOVE FAILED 3");
925                 break;
926             }
927             $shm = FALSE;
928
929             log_main("BIN5 USER DATA DESTROY SUCCESS");
930
931             // log_main("QUI CI ARRIVA [".$bri->user[0]->name."]");
932             $ret = TRUE;
933         } while (0);
934
935         if ($shm)
936             shm_detach($shm);
937
938         return ($ret);
939     }
940
941     static function blocking_error($is_unrecoverable)
942     {
943         log_crit("BLOCKING_ERROR UNREC: ".($is_unrecoverable ? "TRUE" : "FALSE"));
944         return (sprintf(($is_unrecoverable ? 'xstm.stop(); ' : '').'window.onbeforeunload = null; window.onunload = null; document.location.assign("../index.php");'));
945     }
946
947     protected function page_sync($sess, $page)
948     {
949         log_rd2("PAGE_SYNC");
950         printf("xXx BIN5_USER::PAGE_SYNC\n");
951         return (sprintf('xstm.stop(); window.onbeforeunload = null; window.onunload = null; document.location.assign("%s");', $page));
952     }
953
954     protected function maincheck($get, $post, $cookie)
955     {
956         GLOBAL $G_lang;
957         GLOBAL $G_with_splash, $G_splash_content, $G_splash_interval, $G_splash_idx;
958         GLOBAL $G_splash_w, $G_splash_h, $G_splash_timeout;
959
960         GLOBAL $S_load_stat;
961
962         log_rd("maincheck begin");
963
964         $ret = FALSE;
965         $curtime = time();
966
967       /* Nothing changed, return. */
968       if ($this->rd_step == $this->step)
969           return (FALSE);
970
971       log_rd2("do other cur_stat[".$this->rd_stat."] user->stat[".$this->stat."] cur_step[".$this->rd_step."] user_step[".$this->step."]");
972
973       if ($this->rd_step == -1) {
974           /*
975            *  if $this->rd_step == -1 load the current state from the main struct
976            */
977
978           $S_load_stat['wR_minusone']++;
979
980           // if ($this->the_end == TRUE) {
981           // log_rd2("main_check: the end".var_export(debug_backtrace()));
982           // }
983
984           if ($this->trans_step != -1) {
985               log_rd2("TRANS USATO ".$this->trans_step);
986               $this->rd_step = $this->trans_step;
987               $this->trans_step = -1;
988           }
989           else {
990               log_rd2("TRANS NON ATTIVATO");
991           }
992       }
993
994
995       /* this part I suppose is read only on $this->room structure */
996       if ($this->rd_step == -1) {
997           log_rd2("PRE-NEWSTAT");
998
999           /***************
1000            *             *
1001            *    TABLE    *
1002            *             *
1003            ***************/
1004           if ($this->stat == 'table') {
1005               log_load("RESYNC");
1006               /* NOTE: $this->room is associated with the current $bri object */
1007               printf("xXx CLASS NAME [%s]\n", get_class($this->room));
1008               $ret = show_table($this->room, $this, $this->step, FALSE, FALSE);
1009           }
1010           log_rd2("NEWSTAT: ".$this->stat);
1011
1012           $this->rd_stat  = $this->stat;
1013           $this->rd_subst = $this->subst;
1014           $this->rd_step  = $this->step;
1015       } /* if ($this->rd_step == -1) { */
1016       else {
1017           $S_load_stat['rU_heavy']++;
1018
1019           if ($this->rd_step < $this->step) {
1020               do {
1021                   if ($this->rd_step + COMM_N < $this->step) {
1022                       if ($this->rd_stat != $this->stat) {
1023                           $to_stat = $this->stat;
1024                           log_load("RESYNC");
1025                           printf("xXx BIN5_USER::MAINCHECK\n");
1026                           return ($this->page_sync($this->sess, ($to_stat == "table" ? "index.php" : "../index.php"), $this->table, $this->table_token));
1027                       }
1028                       log_rd2("lost history, refresh from scratch");
1029                       printf("xXx LOST HISTORY!\n");
1030                       $this->rd_step = -1;
1031                       break;
1032                   }
1033                   for ($i = $this->rd_step ; $i < $this->step ; $i++) {
1034                       $ii = $i % COMM_N;
1035                       if ($this->comm[$ii] == "") {
1036                           if ($i == $this->rd_step)
1037                               continue;
1038                           else
1039                               break;
1040                       }
1041                       log_rd2("ADDED TO THE STREAM: ".$this->comm[$ii]);
1042                       $ret .= $this->comm[$ii];
1043                   }
1044                   $this->rd_stat  = $this->stat;
1045                   $this->rd_subst = $this->subst;
1046                   $this->rd_step  = $this->step;
1047               } while (0);
1048
1049               log_rd2($this->step, 'index_rd.php: after ret set');
1050
1051               // if ($this->the_end == TRUE) { management is moved
1052               // in the spush scope
1053           } /* if ($this->rd_step < $this->step) { */
1054       }  /* else of if ($this->rd_step == -1) { */
1055
1056
1057       return ($ret);
1058     }  //   function maincheck(...
1059
1060     function continue_set($match_code)
1061     {
1062         $this->continue = $match_code;
1063     }
1064
1065     function continue_get() {
1066         return ($this->continue);
1067     }
1068
1069     function rules_set($rules_id)
1070     {
1071         $this->rules = $rules_id;
1072     }
1073
1074     function rules_get() {
1075         return ($this->rules);
1076     }
1077
1078 } // end class Bin5_user
1079
1080
1081 class Bin5 {
1082     static $delta_t = array();
1083     var $brisk;// room object reference
1084
1085     var $user;
1086     var $table;
1087     var $comm; // commands for many people
1088     var $step; // current step of the comm array
1089     var $garbage_timeout;
1090     var $shm_sz;
1091
1092     var $table_idx;
1093     var $table_token;
1094
1095     var $the_end;
1096     var $tok;
1097
1098     var $delay_mgr;
1099
1100     function Bin5($brisk, $table_idx, $table_token, $get, $post, $cookie) {
1101         $this->user = array();
1102         $this->table = array();
1103
1104         $this->the_end = FALSE;
1105         $this->shm_sz = BIN5_SHM_MIN;
1106         if (($this->tok = @ftok(FTOK_PATH."/bin5/table".$table_idx."/table", "B")) == -1) {
1107             echo "FTOK FAILED";
1108             exit;
1109         }
1110
1111         $this->brisk = $brisk;
1112         $user  = $brisk->user;
1113         $table = $brisk->table[$table_idx];
1114         log_wr("Bin5 constructor");
1115
1116         for ($i = 0 ; $i < $table->player_n ; $i++) {
1117             $user[$table->player[$i]]->table_token = $table_token;
1118             $this->user[$i] = Bin5_user::spawn($user[$table->player[$i]], $this, $table_idx, $i, $get, $post, $cookie);
1119         }
1120         $this->table[0] = Bin5_table::spawn($table);
1121
1122         log_main("TABLE_OLD_WIN - Bin5:".$this->table[0]->old_asta_win);
1123
1124         $this->table_idx = $table_idx;
1125         $this->table_token = $table_token;
1126         $this->garbage_timeout = 0;
1127
1128         $this->delay_mgr = new Delay_Manager((GARBAGE_TIMEOUT *3.0) / 2.0);
1129
1130         log_wr("Bin5 constructor end");
1131     }
1132
1133
1134     function get_user($sess, &$idx)
1135     {
1136         GLOBAL $PHP_SELF;
1137
1138         if (validate_sess($sess)) {
1139             for ($i = 0 ; $i < BIN5_MAX_PLAYERS ; $i++) {
1140                 if ($this->user[$i]->is_empty())
1141                     continue;
1142                 if (strcmp($sess, $this->user[$i]->sess) == 0) {
1143                     // find it
1144                     $idx = $i;
1145                     $ret = &$this->user[$i];
1146                     return ($ret);
1147                 }
1148             }
1149             log_main(sprintf("get_user: Wrong sess from page [%s]",$PHP_SELF));
1150             // for ($i = 0 ; $i < BIN5_MAX_PLAYERS ; $i++)
1151             // log_main(sprintf("get_user: Wrong sess compared with [%s]",$this->user[$i]->sess));
1152         }
1153         else {
1154             log_main(sprintf("get_user: Wrong strlen [%s]",$sess));
1155         }
1156
1157         return (FALSE);
1158     }
1159     function banned_kickoff()
1160     {
1161         $is_ban = FALSE;
1162
1163         for ($i = 0 ; $i < BIN5_MAX_PLAYERS ; $i++) {
1164             $user_cur = $this->user[$i];
1165
1166             // check if the IP is blacklisted
1167             if ($this->brisk->black_check($user_cur->ip)) {
1168                 $user_cur->lacc = 0;
1169                 $is_ban = TRUE;
1170                 continue;
1171             }
1172
1173             // if authorized not check if banlisted
1174             if ($user_cur->is_auth()) {
1175                 continue;
1176             }
1177
1178             if ($this->brisk->ban_check($user_cur->ip)) {
1179                 $user_cur->lacc = 0;
1180                 $is_ban = TRUE;
1181             }
1182         }
1183         return ($is_ban);
1184     }
1185
1186     function garbage_manager($force)
1187     {
1188         GLOBAL $G_base;
1189
1190         /* Garbage collector degli utenti in timeout */
1191         $ismod = FALSE;
1192         $curtime = time();
1193
1194         $delta = $this->delay_mgr->delta_get($curtime);
1195
1196         if ($force || $this->garbage_timeout < $curtime) {
1197             for ($i = 0 ; $i < BIN5_MAX_PLAYERS ; $i++) {
1198                 $user_cur = $this->user[$i];
1199                 if ($user_cur->is_active() == FALSE || // is not active user or
1200                     ($user_cur->stat == 'table' && ($user_cur->subst == 'shutdowned' || $user_cur->subst == 'shutdowner')))
1201                     continue;
1202
1203                 if ($user_cur->lacc + EXPIRE_TIME_RD < ($curtime - $delta)) { // Auto logout dell'utente
1204                     log_rd2($user_cur->sess." bin5 AUTO LOGOUT.");
1205
1206                     if ($user_cur->stat == 'table') {
1207                         log_auth($user_cur->sess," bin5 Autologout session.");
1208
1209                         /* main garbage_manager is delegate as autologout management */
1210                         $user_cur->the_end = TRUE;
1211
1212                         /* se gli altri utenti non erano d'accordo questo utente viene bannato */
1213                         $remcalc = $this->table[0]->exitlock_calc($this->user, $user_cur->table_pos);
1214                         if ($remcalc < 3) {
1215                             require_once("${G_base}Obj/hardban.phh");
1216                             Hardbans::add(($user_cur->is_auth() ? $user_cur->name : FALSE),
1217                                           $user_cur->ip, $user_cur->sess, $user_cur->laccwr + BAN_TIME);
1218                         }
1219                         //      $user->bantime = $user->laccwr + BAN_TIME;
1220
1221                         $this->table_wakeup($user_cur);
1222                     }
1223                 }
1224             }
1225             log_rd2($user_cur->sess." GARBAGE UPDATED!");
1226
1227             $this->garbage_timeout = $curtime + GARBAGE_TIMEOUT;
1228
1229             $ismod = TRUE;
1230         }
1231
1232         $this->delay_mgr->lastcheck_set($curtime);
1233         return ($ismod);
1234     }
1235
1236
1237     function destroy_data()
1238     {
1239         GLOBAL $sess;
1240
1241         $ret =   FALSE;
1242         $shm =   FALSE;
1243         log_main("DESTROY BRISKIN5 DATA");
1244
1245         do {
1246             log_main("DESTROY2 BRISKIN5 DATA [".$this->table_idx."]");
1247             for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
1248                 $this->user[$i]->destroy_data($this->table_idx);
1249                 Bin5_user::unproxy_step($this->table_idx, $this->user[$i]->sess);
1250             }
1251             if (($tok = @ftok(FTOK_PATH."/bin5/table".$this->table_idx."/table", "B")) == -1)
1252                 break;
1253
1254             if (($shm = @shmop_open($tok, 'a', 0, 0)) == FALSE)
1255                 break;
1256
1257             if (shmop_delete($shm) == 0) {
1258                 log_only("REMOVE FALLITA ");
1259                 break;
1260             }
1261
1262             $shm = FALSE;
1263             log_main("DESTROY2 BRISKIN5 DATA SUCCESS");
1264
1265             // log_main("QUI CI ARRIVA [".$bri->user[0]->name."]");
1266             $ret = TRUE;
1267         } while (0);
1268
1269         if ($shm)
1270             shm_detach($shm);
1271
1272         return ($ret);
1273     }
1274
1275     static function lock_data($is_exclusive, $table_idx)
1276     {
1277         if (($res = file_lock(FTOK_PATH."/bin5/table".$table_idx."/table", $is_exclusive)) != FALSE) {
1278             self::$delta_t = microtime(TRUE);
1279             log_lock("LOCK   table [".$table_idx."]         [".self::$delta_t[$table_idx]."]");
1280
1281             return (new Vect(array('res' => $res, 'tab' => $table_idx)));
1282         }
1283
1284         return (FALSE);
1285     }
1286
1287
1288     static function unlock_data($res_vect)
1289     {
1290         GLOBAL $sess;
1291
1292         $res = $res_vect->getbyid('res');
1293         $tab = $res_vect->getbyid('tab');
1294
1295         log_lock("UNLOCK table [".$tab."]         [".(microtime(TRUE) - (self::$delta_t[$tab]))."]");
1296
1297         file_unlock($res);
1298     }
1299
1300
1301     function chatt_send($user, $mesg, $mlang_indwr = NULL)
1302     {
1303         GLOBAL $mlang_brisk, $G_lang;
1304
1305         if ($user->stat != 'table') {
1306             return;
1307         }
1308         $curtime = time();
1309
1310         $table = &$this->table[$user->table];
1311         $user_mesg = substr($mesg,6);
1312
1313         $ret = FALSE;
1314         $mesg = "";
1315
1316         $dt = date("H:i ", $curtime);
1317         if (strncmp($user_mesg, "/cont ", 6) == 0) {
1318             log_main($user->sess." chatt_send BEGIN");
1319
1320             $match_id = substr($user_mesg, 6);
1321             $table->match_continue($this, $user, $match_id);
1322         }
1323         else if (strncmp($user_mesg, "/rules ", 7) == 0) {
1324             log_main($user->sess." chatt_send BEGIN");
1325
1326             $rules_id = substr($user_mesg, 7);
1327             $table->rules_change($this, $user, $rules_id);
1328         }
1329         else {
1330             for ($i = 0 ; $i < ($user->stat == 'room' ? BIN5_MAX_PLAYERS : BIN5_PLAYERS_N) ; $i++) {
1331                 if ($user->stat == 'room') {
1332                     $user_cur = &$this->user[$i];
1333                     if ($user_cur->is_active() == FALSE || $user_cur->stat != 'room') // is not active user or stat isn't 'room'
1334                         continue;
1335                 }
1336                 else {
1337                     $user_cur = &$this->user[$table->player[$i]];
1338                 }
1339
1340                 $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
1341                 $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('chatt_sub("%s", [%d, "%s"],"%s");',
1342                                                                      $dt, $user->flags, xcape($user->name), xcape($user_mesg));
1343                 $user_cur->step_inc();
1344             }
1345             log_legal($curtime, $user->ip, $user, ($user->stat == 'room' ? 'room' : 'table '.$user->table_orig),$user_mesg);
1346         }
1347     }
1348
1349     function table_wakeup($user)
1350     {
1351         $table = &$this->table[0];
1352
1353         log_main("BIN5_WAKEUP begin function table  stat: ".$user->stat."  subst: ".$user->subst);
1354
1355         $curtime = time();
1356
1357         log_main("BIN5_WAKEUP from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
1358
1359         for ($i = 0 ; $i < $table->player_n ; $i++) {
1360             $user_cur = &$this->user[$i];
1361             log_main("PREIMPOST INLOOP name: ".$user_cur->name);
1362
1363             if ($user_cur == $user)
1364                 $user_cur->subst = "shutdowner";
1365             else
1366                 $user_cur->subst = "shutdowned";
1367             $user_cur->laccwr = $curtime;
1368
1369             $ret = "gst.st = ".($user_cur->step+1)."; ";
1370             $ret .= 'gst.st_loc++; xstm.stop(); window.onbeforeunload = null; window.onunload = null; document.location.assign("../index.php");|';
1371
1372             log_wr($user_cur->sess." BIN5_WAKEUP: ".$ret);
1373             $user_cur->comm[$user_cur->step % COMM_N] = $ret;
1374             $user_cur->step_inc();
1375         }
1376
1377         $this->the_end = TRUE;
1378     }
1379
1380     /*
1381      *  If all players are freezed the room garbage_manager clean up table and users.
1382      */
1383     function is_abandoned()
1384     {
1385         $is_ab = TRUE;
1386         $curtime = time();
1387
1388         $table = &$this->table[0];
1389
1390         for ($i = 0 ; $i < $table->player_n ; $i++) {
1391             $user_cur = &$this->user[$i];
1392
1393             if ($user_cur->lacc + (EXPIRE_TIME_RD * 2) >= $curtime) {
1394                 $is_ab = FALSE;
1395                 break;
1396             }
1397         }
1398
1399         return ($is_ab);
1400     }
1401
1402     static function request_mgr(&$s_a_p, $header, &$header_out, &$new_socket, $path, $addr, $get, $post, $cookie)
1403     {
1404         GLOBAL $G_ban_list, $G_black_list;
1405
1406         printf("NEW_SOCKET (root): %d\n", intval($new_socket));
1407
1408         $enc = get_encoding($header);
1409         if (isset($header['User-Agent'])) {
1410             if (strstr($header['User-Agent'], "MSIE")) {
1411                 $transp_type = "htmlfile";
1412             }
1413             else {
1414                 $transp_type = "xhr";
1415             }
1416         }
1417         else {
1418             $transp_type = "iframe";
1419         }
1420         force_no_cache($header_out);
1421
1422         if (($table_idx = gpcs_var('table_idx', $get, $post, $cookie)) === FALSE)
1423             unset($table_idx);
1424
1425         if (($table_token = gpcs_var('table_token', $get, $post, $cookie)) === FALSE)
1426             unset($table_token);
1427
1428
1429         switch ($path) {
1430         case "":
1431         case "index.php":
1432             ob_start();
1433             bin5_index_main($transp_type, $header, $header_out, $addr, $get, $post, $cookie);
1434             $content = ob_get_contents();
1435             ob_end_clean();
1436
1437             $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
1438             return TRUE;
1439
1440         break;
1441         case "index_wr.php":
1442             if (isset($table_idx) && isset($table_token)) {
1443                 if (($bri = $s_a_p->app->match_get($table_idx, $table_token)) != FALSE) {
1444                     ob_start();
1445                     bin5_index_wr_main($bri, $addr, $get, $post, $cookie);
1446                     $content = ob_get_contents();
1447                     ob_end_clean();
1448                 }
1449                 else {
1450                     $content = "Bin5 Load data error";
1451                 }
1452             }
1453             else {
1454                 $content = "Bin5 Load data error";
1455             }
1456             $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
1457             return TRUE;
1458
1459             break;
1460         case "index_rd.php":
1461         case "index_rd_wss.php":
1462             if (($transp  = gpcs_var('transp', $get, $post, $cookie)) === FALSE)
1463                 $transp = "iframe";
1464             if ($transp == 'websocket' || $transp == 'websocketsec')
1465                 $enc = 'plain';
1466
1467             do {
1468                 if (!isset($table_idx)
1469                     || !isset($table_token)
1470                     || !isset($cookie['sess'])
1471                     || ($bri = $s_a_p->app->match_get($table_idx, $table_token)) == NULL
1472                     || (($user = $bri->get_user($cookie['sess'], $idx)) == FALSE)) {
1473
1474                     $content = Bin5_user::stream_fini($transp_type, $s_a_p->rndstr, TRUE);
1475                     $s_a_p->pendpage_try_addflush($new_socket, 20, $enc, $header_out, $content);
1476
1477                     return TRUE;
1478                     break;
1479                 }
1480                 $bri->brisk->sess_cur_set($user->sess);
1481
1482                 // close a previous opened index_read_ifra socket, if exists
1483                 if (($prev = $user->rd_socket_get()) != NULL) {
1484                     $s_a_p->socks_unset($user->rd_socket_get());
1485                     fclose($user->rd_socket_get());
1486                     printf("CLOSE AND OPEN AGAIN ON IFRA2\n");
1487                     $user->rd_socket_set(NULL);
1488                 }
1489
1490                 $content = "";
1491                 $user->stream_init($s_a_p->rndstr, $enc, $header, $header_out, $content, $get, $post, $cookie);
1492
1493                 $response = headers_render($header_out, -1).$user->chunked_content($content);
1494                 $response_l = mb_strlen($response, "ASCII");
1495
1496                 $wret = @fwrite($new_socket, $response, $response_l);
1497                 if ($wret < $response_l) {
1498                     printf("TROUBLES WITH FWRITE: %d\n", $wret);
1499                     $user->rd_cache_set(mb_substr($content, $wret, $response_l - $wret, "ASCII"));
1500                 }
1501                 else {
1502                     $user->rd_cache_set("");
1503                 }
1504                 fflush($new_socket);
1505
1506
1507                 $s_a_p->socks_set($new_socket, $user, NULL);
1508                 $user->rd_socket_set($new_socket);
1509                 printf(" - qui ci siamo - ");
1510                 return TRUE;
1511             } while (FALSE);
1512
1513             return FALSE;
1514             break;
1515
1516         default:
1517             return FALSE;
1518             break;
1519       }
1520
1521       return (FALSE);
1522   }
1523
1524
1525
1526 } // end class Bin5
1527
1528 function locshm_exists($tok)
1529 {
1530     // return (TRUE);
1531
1532     if (($id = @shmop_open($tok,"a", 0, 0)) == FALSE) {
1533         log_main($tok." SHM NOT exists");
1534
1535         return (FALSE);
1536     }
1537     else {
1538         shmop_close($id);
1539         log_main($tok." SHM exists");
1540
1541         return (TRUE);
1542     }
1543
1544 }
1545
1546
1547 /* show table
1548    is_transition (is from room to table ?)
1549    is_again      (is another game)
1550
1551    Examples                    of $is_transition, $is_again:
1552    from reload of the page:              FALSE, FALSE
1553    from sitdown in room:                  TRUE, FALSE
1554    from table: asta cmd e tutti passano:  TRUE, TRUE
1555    from table: fine partita:              TRUE, TRUE
1556 */
1557 function show_table(&$bri, &$user, $sendstep, $is_transition, $is_again)
1558 {
1559     $table_idx = $user->table;
1560     $table     = $bri->table[$table_idx];
1561     $table_pos = $user->table_pos;
1562
1563     $ret = "table_init();";
1564     $ret .= $table->exitlock_show($bri->user, $table_pos);
1565     if (!$is_again) {
1566         /* GENERAL STATUS */
1567         $user_rules = $user->rules_get();
1568         $ret .= sprintf('gst.st = %d; stat = "%s"; subst = "%s"; table_pos = %d; rules_set(%d);',
1569                         $sendstep, $user->stat, $user->subst, $table_pos,
1570                         ($user_rules == BIN5_USER_CONTINUE_INIT ? $table->rules->id_get() : $user_rules));
1571
1572         log_rd(sprintf( 'SHOW_TABLE: gst.st = %d; stat = "%s"; subst = "%s"; table_pos = %d;', $sendstep, $user->stat, $user->subst, $table_pos));
1573
1574         /* BACKGROUND */
1575         $ret .= "background_set();";
1576
1577         /* USERS INFO */
1578         $ret .= $user->myname_innerHTML();
1579         $ret .= sprintf('set_names([%d, "%s"], [%d, "%s"], [%d, "%s"], [%d, "%s"], [%d, "%s"]); ',
1580                         $bri->user[$table->player[($table_pos) % BIN5_PLAYERS_N]]->flags,
1581                         xcape($bri->user[$table->player[($table_pos) % BIN5_PLAYERS_N]]->name),
1582
1583                         $bri->user[$table->player[($table_pos+1) % BIN5_PLAYERS_N]]->flags,
1584                         xcape($bri->user[$table->player[($table_pos+1) % BIN5_PLAYERS_N]]->name),
1585
1586                         $bri->user[$table->player[($table_pos+2) % BIN5_PLAYERS_N]]->flags,
1587                         xcape($bri->user[$table->player[($table_pos+2) % BIN5_PLAYERS_N]]->name),
1588
1589                         (BIN5_PLAYERS_N == 3 ? 0 : $bri->user[$table->player[($table_pos+3) % BIN5_PLAYERS_N]]->flags),
1590                         (BIN5_PLAYERS_N == 3 ? "" :  xcape($bri->user[$table->player[($table_pos+3) % BIN5_PLAYERS_N]]->name)),
1591
1592                         (BIN5_PLAYERS_N == 3 ? 0 : $bri->user[$table->player[($table_pos+4) % BIN5_PLAYERS_N]]->flags),
1593                         (BIN5_PLAYERS_N == 3 ? "" :  xcape($bri->user[$table->player[($table_pos+4) % BIN5_PLAYERS_N]]->name)));
1594     }
1595     /* NOTIFY FOR THE CARD MAKER */
1596     if ($is_transition) { //  && $user->subst ==  "asta" superfluo
1597         $ret .= show_table_info($bri, $table, $table_pos);
1598         $ret .= "setTimeout(preload_images, 500, g_preload_img_arr, g_imgct);";
1599     }
1600     else {
1601         $ret .= "\$('imgct').innerHTML = \$('imgct').innerHTML = mlang_commons['imgload_a'][g_lang]+\"100%.\";";
1602     }
1603     if (!$is_again)
1604         $ret .= table_welcome($user);
1605
1606     if ($is_transition && !$is_again) { // just sit, play cow
1607         $ret .= playsound("cow.mp3");
1608     }
1609
1610
1611     /* CARDS */
1612     if ($is_transition) { //  && $user->subst ==  "asta" superfluo
1613         $ret .= "|";
1614
1615         for ($i = 0 ; $i < BIN5_CARD_HAND ; $i++) {
1616             for ($e = 0 ; $e < BIN5_PLAYERS_N ; $e++) {
1617                 $ct = 0;
1618                 for ($o = 0 ; $o < (BIN5_CARD_HAND * BIN5_PLAYERS_N) && $ct < $i+1 ; $o++) {
1619                     // for ($o = 0 ; $o < 40 && $ct < $i+1 ; $o++) {
1620                     if ($table->card[$o]->owner == (($e + $table->gstart) % BIN5_PLAYERS_N)) {
1621                         $ct++;
1622                         if ($ct == $i+1)
1623                             break;
1624                     }
1625                 }
1626                 log_rd("O ".$o." VAL ".$table->card[$o]->value." Owner: ".$table->card[$o]->owner);
1627
1628                 $ret .= sprintf( ' card_send(%d,%d,%d,%8.2f,%d);|', ($table->gstart + $e) % BIN5_PLAYERS_N,
1629                                  $i, ((($e + BIN5_PLAYERS_N - $table_pos + $table->gstart) % BIN5_PLAYERS_N) == 0 ?
1630                                       $table->card[$o]->value : -1),
1631                                  ($i == 7 && $e == (BIN5_PLAYERS_N - 1) ? 1 : 0.5),$i+1);
1632             }
1633         }
1634     }
1635     else {
1636         $taked  = array(0,0,0,0,0);
1637         $inhand = array(0,0,0,0,0);
1638         $ontabl  = array(-1,-1,-1,-1,-1);
1639         $cards  = array();
1640
1641         for ($i = 0 ; $i < (BIN5_CARD_HAND * BIN5_PLAYERS_N) ; $i++) {
1642             // for ($i = 0 ; $i < 40 ; $i++) {
1643             if ($table->card[$i]->stat == 'hand') {
1644                 if ($table->card[$i]->owner == $table_pos) {
1645                     $cards[$inhand[$table->card[$i]->owner]] = $table->card[$i]->value;
1646                 }
1647                 $inhand[$table->card[$i]->owner]++;
1648             }
1649             else if ($table->card[$i]->stat == 'take') {
1650                 log_main("Card taked: ".$table->card[$i]->value."OWN: ".$table->card[$i]->owner);
1651                 $taked[$table->card[$i]->owner]++;
1652             }
1653             else if ($table->card[$i]->stat == 'table') {
1654                 $ontabl[$table->card[$i]->owner] = $i;
1655             }
1656         }
1657         $logg = "\n";
1658         for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
1659             $logg .= sprintf("INHAND: %d   IN TABLE %d   TAKED %d\n", $inhand[$i], $ontabl[$i], $taked[$i]);
1660         }
1661         log_main("Stat table: ".$logg);
1662
1663         /* Set ours cards. */
1664         $oursarg = "";
1665         for ($i = 0 ; $i < $inhand[$table_pos] ; $i++)
1666             $oursarg .= ($i == 0 ? "" : ", ").$cards[$i];
1667         for ($i = $inhand[$table_pos] ; $i < BIN5_CARD_HAND ; $i++)
1668             $oursarg .= ($i == 0 ? "" : ", ")."-1";
1669         $ret .= sprintf('card_setours(%s);', $oursarg);
1670
1671         /* Dispose all cards */
1672         for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
1673             /* Qui sotto al posto di + 1 c'era + ->gstart ... credo in modo errato */
1674             $ret .= sprintf('cards_dispose(%d,%d,%d);', $i,
1675                             ($inhand[$i] <= BIN5_CARD_HAND ? $inhand[$i] : BIN5_CARD_HAND), $taked[$i]);
1676
1677             if ($ontabl[$i] != -1) {
1678                 $ret .= sprintf('card_place(%d,%d,%d,%d,%d);',$i, $inhand[$i],
1679                                 $table->card[$ontabl[$i]]->value,
1680                                 $table->card[$ontabl[$i]]->x, $table->card[$ontabl[$i]]->y);
1681             }
1682         }
1683     }
1684
1685     /* Show auction */
1686     if ($user->subst == 'asta') {
1687
1688         /* show users auction status */
1689         $showst = "";
1690         for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
1691             $user_cur = &$bri->user[$table->player[$i]];
1692             $showst .= sprintf("%s%d", ($i == 0 ? "" : ", "),
1693                                ($user_cur->asta_card < 9 ? $user_cur->asta_card : $user_cur->asta_pnt));
1694         }
1695         if (BIN5_PLAYERS_N == 3)
1696             $showst .= ",-2,-2";
1697         $ret .= sprintf('document.title = "Brisk - Tavolo %d (asta)";', $user->table_orig);
1698         $ret .= sprintf('show_astat(%s);', $showst);
1699
1700         if ($table->asta_win != -1 && $table->asta_win == $table_pos) {
1701             /* show card chooser */
1702             $ret .= sprintf('choose_seed(%s); $("astalascio").style.visibility = ""; $("asta").style.visibility = "hidden";',
1703                             $table->asta_card);
1704         }
1705         else {
1706             // FIXME - RULES to be able to abandon table
1707             /* show auction */
1708             if ($table_pos == ($table->gstart % BIN5_PLAYERS_N) &&
1709                 $table->asta_win == -1)
1710                 $ret .= sprintf('dispose_asta(%d,%d, %s);',
1711                                 $table->asta_card + 1, $table->asta_pnt+1, ($user->handpt <= 2 ? "true" : "false"));
1712             else
1713                 $ret .= sprintf('dispose_asta(%d,%d, %s);',
1714                                 $table->asta_card + 1, -($table->asta_pnt+1), ($user->handpt <= 2 ?  "true" : "false"));
1715         }
1716
1717         /* Remark */
1718         if ($table->asta_win == -1) { // auction case
1719             if ($table_pos == ($table->gstart % BIN5_PLAYERS_N))
1720                 $ret .= "remark_on();";
1721             else
1722                 $ret .= "remark_off();";
1723         }
1724         else { // chooseed case
1725             if ($table_pos == $table->asta_win)
1726                 $ret .= "remark_on();";
1727             else
1728                 $ret .= "remark_off();";
1729         }
1730     }
1731     else if ($user->subst == 'game') {
1732         /* HIGHLIGHT */
1733         if (($table->gstart + $table->turn) % BIN5_PLAYERS_N == $table_pos)
1734             $ret .= "is_my_time = true; remark_on();";
1735         else
1736             $ret .= "remark_off();";
1737
1738         /* WHO CALL AND WHAT */
1739         $ret .= briscola_show($bri, $table, $user);
1740
1741     }
1742     return ($ret);
1743 } // end function show_table(...
1744
1745 function calculate_winner(&$table)
1746 {
1747     $briontab = FALSE;
1748     $ontab = array();
1749     $ontid = array();
1750     $cur_win  =  -1;
1751     $cur_val  = 100;
1752     $cur_seed = $table->briscola - ($table->briscola % 10);
1753
1754     for ($i = 0 ; $i < (BIN5_CARD_HAND * BIN5_PLAYERS_N) ; $i++) {
1755         // for ($i = 0 ; $i < 40 ; $i++) {
1756         if ($table->card[$i]->stat != "table")
1757             continue;
1758
1759         log_wr(sprintf("Card On table: [%d]", $i));
1760
1761         $v = $table->card[$i]->value;
1762         $ontab[$table->card[$i]->owner] = $v;
1763         $ontid[$table->card[$i]->owner] = $i;
1764         /* se briscola setto il flag */
1765         if (($v - ($v % 10)) == $cur_seed)
1766             $briontab = TRUE;
1767     }
1768
1769     if ($briontab == FALSE) {
1770         $cur_win  = $table->gstart;
1771         $cur_val  = $ontab[$cur_win];
1772         $cur_seed = $cur_val - ($cur_val % 10);
1773     }
1774
1775     for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
1776         if (($ontab[$i] - ($ontab[$i] % 10)) == $cur_seed) {
1777             if ($ontab[$i] < $cur_val) {
1778                 $cur_val = $ontab[$i];
1779                 $cur_win = $i;
1780             }
1781         }
1782     }
1783
1784     for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++) {
1785         $table->card[$ontid[$i]]->owner = $cur_win;
1786         $table->card[$ontid[$i]]->stat =  "take"; // Card stat
1787     }
1788     return ($cur_win);
1789 }
1790
1791 function show_table_info(&$bri, &$table, $table_pos)
1792 {
1793     GLOBAL $G_lang, $mlang_bin5_bin5;
1794
1795     $tg_br = "<br>";
1796     $tg_hr = "<hr>";
1797     $tg_bo = "<b>";
1798     $tg_bc = "</b>";
1799
1800     $ret = "";
1801     $user = $bri->user[$table->player[$table_pos]];
1802
1803     // TAG: POINTS_MANAGEMENT
1804     $pnt_min = $table->points_n - MAX_POINTS < 0 ? 0 : $table->points_n - MAX_POINTS;
1805     $noty = sprintf('<p>%s.</p>\n', xcape(ucfirst(rules_id2descr($table->rules->id_get(), $G_lang))));
1806     $noty .= sprintf('<table class=\"points\"><tr><th></th>');
1807
1808     // Names.
1809     for ($i = 0 ; $i < BIN5_PLAYERS_N ; $i++)
1810         $noty .= sprintf('<th class=\"td_points\">%s</th>', xcape($bri->user[$table->player[$i]]->name));
1811     $noty .= sprintf("</tr>");
1812
1813     // Points.
1814     log_main("show_table_info: pnt_min: ".$pnt_min."   Points_n: ".$table->points_n);
1815
1816     for ($i = $pnt_min ; $i < $table->points_n ; $i++) {
1817         $noty .= sprintf('<tr><th class=\"td_points\">%d</th>', $i+1);
1818         for ($e = 0 ; $e < BIN5_PLAYERS_N ; $e++)
1819             $noty .= sprintf('<td class=\"td_points\">%d</td>', $table->points[$i % MAX_POINTS][$e]);
1820         $noty .= "</tr>";
1821     }
1822
1823     // Total points.
1824     $noty .= '<tr><th class=\"td_points\">Tot.</th>';
1825     for ($e = 0 ; $e < BIN5_PLAYERS_N ; $e++)
1826         $noty .= sprintf('<td class=\"td_points\">%d</td>', $table->total[$e]);
1827     $noty .= "</tr></table>";
1828     $noty .= "<hr>";
1829     if ($table->old_reason != "") {
1830         $noty .= sprintf($mlang_bin5_bin5['info_last'][$G_lang],
1831                          $tg_br, $tg_hr, $tg_bo, $tg_bc);
1832         $noty .= '<br>';
1833         $noty .= $table->old_reason;
1834     }
1835
1836     $noty .= sprintf($mlang_bin5_bin5['info_curr'][$G_lang],
1837                      $tg_br, $tg_hr, $tg_bo, $tg_bc);
1838     $noty .= '<br>';
1839     /* MLANG: "Fai <b>tu</b> il mazzo,", "Il mazzo a <b>$unam</b>," */
1840     if ($table->mazzo == $table_pos)
1841         $noty .= $mlang_bin5_bin5['info_yshuf'][$G_lang];
1842     else {
1843         $unam = xcape($bri->user[$table->player[$table->mazzo]]->name);
1844         $noty .= sprintf($mlang_bin5_bin5['info_shuf'][$G_lang], $unam);
1845     }
1846
1847     if ($user->subst == 'asta') {
1848         if ($table->asta_win == -1)  // auction case
1849             $curplayer = $table->gstart % BIN5_PLAYERS_N;
1850         else
1851             $curplayer = $table->asta_win;
1852     }
1853     else if ($user->subst == 'game') {
1854         $curplayer = ($table->gstart + $table->turn) % BIN5_PLAYERS_N;
1855     }
1856
1857     /* MLANG: " tocca a <b>te</b> giocare.", " tocca a <b>$unam</b> giocare.", " La partita vale <b>%s</b>.", "torna alla partita" */
1858     if ($curplayer == $table_pos) {
1859         $noty .= $mlang_bin5_bin5['info_yturn'][$G_lang];
1860     }
1861     else {
1862         $unam = xcape($bri->user[$table->player[$curplayer]]->name);
1863         $noty .= sprintf($mlang_bin5_bin5['info_turn'][$G_lang], $unam);
1864     }
1865
1866     $multer = $table->rules->multer(TRUE);
1867     if ($multer > 1) {
1868         $noty .= sprintf($mlang_bin5_bin5['info_mult'][$G_lang], multoval($multer) );
1869     }
1870     $noty .= "<hr>";
1871     if ($table->match_id != -1) {
1872         $noty .= sprintf($mlang_bin5_bin5['info_match'][$G_lang], $table->match_id);
1873         $noty .= "<hr>";
1874     }
1875     $ret .= show_notify($noty, 3000, $mlang_bin5_bin5['btn_bkgame'][$G_lang], 500, 400);
1876     /* NOTE: show_notify($noty, 3000, "torna alla partita", 500,
1877      *                   130 + ($table->points_n > 0 ? 50 : 0) +
1878      *                   (120 * ($table->points_n / MAX_POINTS)));
1879      *       will be used when we refact notify js function following
1880      *       photoo class logic
1881      */
1882
1883     return ($ret);
1884 }
1885
1886 function table_welcome($user)
1887 {
1888     GLOBAL $table_wellarr, $G_lang;
1889     $ret = "";
1890
1891     for ($i = 0 ; $i < count($table_wellarr[$G_lang]) ; $i++)
1892         $ret .= sprintf('chatt_sub("%s", [2, "ChanServ: "],"%s");', "", str_replace('"', '\"', $table_wellarr[$G_lang][$i]));
1893
1894     return ($ret);
1895 }
1896
1897
1898 function briscola_show($bri, $table, $user)
1899 {
1900     GLOBAL $G_lang, $mlang_bin5_bin5;
1901     $ptnadd = "";
1902     $ret = "";
1903
1904     if ($table->asta_card == 9)
1905         $ptnadd = sprintf($mlang_bin5_bin5['call_wptn'][$G_lang], $table->asta_pnt);
1906
1907     /* text of caller cell */
1908     if ($user->table_pos == $table->asta_win) {
1909         $prestr = sprintf('$("callerinfo").innerHTML = "%s";', $mlang_bin5_bin5['call_ycall'][$G_lang]);
1910         $ret .= sprintf($prestr, $ptnadd);
1911     }
1912     else {
1913         $prestr = sprintf('$("callerinfo").innerHTML = "%s";', $mlang_bin5_bin5['call_call'][$G_lang]);
1914         $ret .= sprintf($prestr,
1915                         xcape($bri->user[$table->player[$table->asta_win]]->name), $ptnadd);
1916     }
1917     $ret .= sprintf('set_iscalling(%d);', ($table->asta_win - $user->table_pos + BIN5_PLAYERS_N) % BIN5_PLAYERS_N);
1918
1919     $ret .= sprintf('$("caller").style.backgroundImage = \'url("img/brisk_caller_sand%d.png")\';',
1920                     $table->asta_win);
1921     $ret .= sprintf('$("callerimg").src = "img/%02d.png";', $table->briscola);
1922     $ret .= sprintf('$("caller").style.visibility = "visible";');
1923     $ret .= sprintf('$("chooseed").style.visibility = "hidden";');
1924     $ret .= sprintf('$("astalascio").style.visibility = "";');
1925     $ret .= sprintf('$("asta").style.visibility = "hidden";');
1926     $ret .= sprintf('show_astat(-2,-2,-2,-2,-2);');
1927
1928     return ($ret);
1929 }
1930
1931 function log_points($remote_addr, $curtime, $user, $where, $mesg)
1932 {
1933     if (($fp = @fopen(LEGAL_PATH."/points.log", 'a')) != FALSE) {
1934         /* Unix time | session | nickname | IP | where was | mesg */
1935         fwrite($fp, sprintf("%ld|%s|%s|%s|%s|%s|%s|\n", $curtime, $user->sess,
1936                             ($user->is_auth() ? 'A' : 'N'),
1937                             $user->name, $remote_addr, $where , $mesg));
1938         fclose($fp);
1939     }
1940 }
1941
1942
1943 ?>