from briskin5.php to index.php
[brisk.git] / web / briskin5 / Obj / briskin5.phh
1 <?php
2 define(MAX_BRISKIN5_PLAYERS, 3);
3
4 class Briskin5 {
5   var $user;
6   var $table;
7   var $table_idx;
8   var $table_token;
9
10   var $comm; // commands for many people
11   var $step; // current step of the comm array
12   var $garbage_timeout;
13
14   var $the_end;
15
16   var $tok;
17
18   function Briskin5 (&$room, $table_idx, $table_token) {
19     $this->user = array();
20     $this->table = array();
21
22     $this->the_end = FALSE;
23
24     if (($this->tok = ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) {
25       echo "FTOK FAILED";
26       exit;
27     }
28
29     $user  =& $room->user;
30     $table =& $room->table[$table_idx];
31
32     log_wr("Briskin5 constructor");
33
34     for ($i = 0 ; $i < $table->player_n ; $i++) {
35       $user[$table->player[$i]]->table_token = $table_token;
36       $this->user[$i] =& User::spawn(&$user[$table->player[$i]], 0, $i);
37     }
38     $this->table[0] =& Table::spawn(&$table);
39     $this->table_idx = $table_idx;
40     $this->table_token = $table_token;
41     $this->garbage_timeout = 0;
42     
43     log_wr("Briskin5 constructor end");
44   }
45
46
47   function &get_user($sess, &$idx)
48   {
49     GLOBAL $PHP_SELF, $G_false;
50
51     if (validate_sess($sess)) {
52       for ($i = 0 ; $i < MAX_BRISKIN5_PLAYERS ; $i++) {
53         if (strcmp($sess, $this->user[$i]->sess) == 0) {
54           // find it
55           $idx = $i;
56           $ret = &$this->user[$i];
57           return ($ret);
58         }
59       }
60       log_main(sprintf("get_user: Wrong sess from page [%s]",$PHP_SELF));
61       // for ($i = 0 ; $i < MAX_PLAYERS ; $i++) 
62       // log_main(sprintf("get_user: Wrong sess compared with [%s]",$this->user[$i]->sess));
63     }
64     else {
65       log_main(sprintf("get_user: Wrong strlen [%s]",$sess));
66     }
67
68     return ($G_false);
69   }
70
71
72   function garbage_manager($force)
73   {
74     
75     /* Garbage collector degli utenti in timeout */
76     $ismod = FALSE;
77     $curtime = time();
78     if ($force || $this->garbage_timeout < $curtime) {
79       
80       for ($i = 0 ; $i < MAX_BRISKIN5_PLAYERS ; $i++) {
81         $user_cur = &$this->user[$i];
82         if ($user_cur->sess == "" || 
83             ($user_cur->stat == 'table' && ($user_cur->subst == 'shutdowned' || $user_cur->subst == 'shutdowner')))
84           continue;
85         
86         if ($user_cur->lacc + EXPIRE_TIME_RD < $curtime) { // Auto logout dell'utente
87           log_rd2($user_cur->sess." bin5 AUTO LOGOUT.");
88
89           if ($user_cur->stat == 'table') {
90             log_auth($user_cur->sess," bin5 Autologout session.");
91
92             /* SI DELEGA AL garbage_manager principale LA RIMOZIONE DELL'UTENTE 
93
94             $tmp_sess = $user_cur->sess;
95             $user_cur->sess = "";
96             step_unproxy($tmp_sess);
97             $user_cur->name = "";
98             $user_cur->the_end = FALSE;
99             
100             */
101
102             $this->table_wakeup(&$user_cur);
103           }
104         }
105       }
106       log_rd2($user_cur->sess." GARBAGE UPDATED!");
107       
108       $this->garbage_timeout = $curtime + GARBAGE_TIMEOUT;
109       $ismod = TRUE;
110     }
111
112     return ($ismod);
113   }
114
115
116
117
118   //
119   //  static functions
120   //
121   function &load_data($table_idx, $table_token = "") 
122   {
123     GLOBAL $G_false, $sess;
124     $shm = FALSE;
125
126     log_wr("TABLE_IDX ".FTOK_PATH."/table".$table_idx);
127     if (($tok = ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) {
128       echo "FTOK FAILED";
129       exit;
130     }
131     
132     do {
133       //      if (shmchk_exists($tok) == FALSE)
134       if (locshm_exists($tok) == FALSE)
135         break;
136
137       if (($shm = shm_attach($tok, SHM_DIMS)) == FALSE)
138         break;
139
140       if (($bri = @shm_get_var($shm, $tok)) == FALSE) 
141         break;
142
143       if ($table_token != "" && $bri->table_token != $table_token) {
144         log_wr("bri->table_token: ".$bri->table_token."table_token: ".$table_token);
145         
146         break;
147       }
148       $bri->tok = $tok;
149
150       shm_detach($shm);
151         
152       $ret = &$bri;
153       return ($ret); 
154     } while (FALSE);
155
156     if ($shm != FALSE)
157       shm_detach($shm);
158
159     log_wr("briskin5 load_data failed");
160     
161     return ($G_false);
162   }
163   
164
165   function save_data(&$bri) 
166   {
167     GLOBAL $sess;
168     
169     $ret =   FALSE;
170     $shm =   FALSE;
171     $isacq = FALSE;
172     
173     log_main("SAVE BRISKIN5 DATA");
174     // var_dump($bri);
175     
176     if (!isset($bri->tok))
177       return (FALSE);
178     
179     do {
180       $isacq = TRUE;
181       
182       if (($shm = shm_attach($bri->tok, SHM_DIMS)) == FALSE)
183         break;
184       
185       // log_only("PUT_VAR DI ".strlen(serialize($bri)));
186       if (shm_put_var($shm, $bri->tok, $bri) == FALSE) {
187         log_only("PUT_VAR FALLITA ".strlen(serialize($bri)));
188         log_only(serialize($bri));
189         break;
190       }
191       // log_main("QUI CI ARRIVA [".$bri->user[0]->name."]");
192       $ret = TRUE;
193     } while (0);
194     
195     if ($shm)
196       shm_detach($shm);
197     
198     return ($ret);
199   }
200
201   function destroy_data($table_idx) 
202   {
203     GLOBAL $sess;
204
205     $ret =   FALSE;
206     $shm =   FALSE;
207     $isacq = FALSE;
208
209     log_main("DESTROY BRISKIN5 DATA");
210
211     
212     do {
213       $isacq = TRUE;
214       
215       log_main("DESTROY2 BRISKIN5 DATA");
216
217       if (($tok = ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) 
218         break;
219
220       if (($shm = shm_attach($tok, SHM_DIMS)) === FALSE)
221         break;
222       
223       if (shm_remove($shm) === FALSE) {
224         log_only("REMOVE FALLITA ".strlen(serialize($bri)));
225         log_only(serialize($bri));
226         break;
227       }
228    
229       $shm = FALSE;
230       log_main("DESTROY2 BRISKIN5 DATA SUCCESS");
231       
232       // log_main("QUI CI ARRIVA [".$bri->user[0]->name."]");
233       $ret = TRUE;
234     } while (0);
235     
236     if ($shm)
237       shm_detach($shm);
238     
239     return ($ret);
240   }
241
242   function lock_data($table_idx)
243   {
244     GLOBAL $sess; 
245     
246     log_wr("LOCK_DATA ".FTOK_PATH."/table".$table_idx);
247     //  echo "LOCK: ".FTOK_PATH."/main";
248     //  exit;
249     if (($tok = ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) {
250       echo "FTOK FAILED";
251       exit;
252     }
253     // echo "FTOK ".$tok."<br>";
254     if (($res = sem_get($tok)) == FALSE) {
255       echo "SEM_GET FAILED";
256       exit;
257     }
258     if (sem_acquire($res)) {   
259       log_lock("LOCK table ".$table_idx."[res: ".$res."]");
260       return ($res);
261     }
262     else {
263       log_lock("LOCK table ".$table_idx.":FAILED");
264       return (FALSE);
265     }
266   }
267   
268   function unlock_data($res)
269   {
270     GLOBAL $sess; 
271     
272     log_lock("UNLOCK table [res: ".$res."]");
273
274     return (sem_release($res));
275   }
276
277
278   function chatt_send(&$user, $mesg)
279   {
280     if ($user->stat == 'table') {
281       $table = &$this->table[$user->table];
282     }
283     
284     $user_mesg = substr($mesg,6);
285     
286     $timecur = time();
287     
288     $dt = date("H:i ", $timecur);
289     if (strncmp($user_mesg, "/nick ", 6) == 0) {
290       log_main($user->sess." chatt_send BEGIN");
291
292       if (($name_new = validate_name(substr($user_mesg, 6))) == FALSE) {
293           $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; ";
294           $user->comm[$user->step % COMM_N] .= sprintf('chatt_sub("%s","Il nickname deve contenere almeno una lettera o una cifra.");', $dt.NICKSERV, xcape($name_new));
295           $user->step_inc();
296
297           return;
298       }
299       $user_mesg = "COMMAND ".$user_mesg;
300       // Search dup name
301       // change
302       // update local graph
303       // update remote graphs
304       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
305         $user_cur = &$this->user[$i];
306         //      if ($user_cur->sess == '' || $user_cur->stat != 'room')
307         if ($user_cur->sess == '')
308           continue;
309         if ($user_cur->name == $name_new) {
310           $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; ";
311           $user->comm[$user->step % COMM_N] .= sprintf('chatt_sub("%s","Nickname <b>%s</b> gi&agrave; in uso.");', $dt.NICKSERV, xcape($name_new));
312           $user->step_inc();
313           break;
314         }
315       }
316       if ($i == MAX_PLAYERS) {
317         $user->name = $name_new;
318
319       log_main($user->sess." chatt_send start set");
320         
321
322         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
323           log_main($user->sess." chatt_send set loop");
324           
325           $user_cur = &$this->user[$i];
326           if ($user_cur->sess == '')
327             continue;
328           if ($user_cur->stat == 'room') {
329             if ($user->stat == 'room' && $user->subst == 'standup') {
330               $this->standup_update(&$user);
331             }
332             else if ($user->stat == 'room' && $user->subst == 'sitdown' ||
333                      $user->stat == 'table') {
334               log_main($user->sess." chatt_send pre table update");
335
336               $this->table_update(&$user);
337
338               log_main($user->sess." chatt_send post table update");
339             }
340           }
341           else if ($user_cur->stat == 'table' && $user_cur->table == $user->table) {
342             $table = &$this->table[$user->table];
343             
344             $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
345             $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('set_names(" %s", " %s", " %s", " %s", " %s"); ',
346                 xcape($this->user[$table->player[($user_cur->table_pos)%PLAYERS_N]]->name),
347                 xcape($this->user[$table->player[($user_cur->table_pos+1)%PLAYERS_N]]->name),
348                 xcape($this->user[$table->player[($user_cur->table_pos+2)%PLAYERS_N]]->name),
349                 (PLAYERS_N == 3 ? "" :  xcape($this->user[$table->player[($user_cur->table_pos+3)%PLAYERS_N]]->name)),
350                 (PLAYERS_N == 3 ? "" :  xcape($this->user[$table->player[($user_cur->table_pos+4)%PLAYERS_N]]->name)));
351             if ($user_cur == $user)
352               $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('$("myname").innerHTML = "<b>%s</b>";', 
353                                                                    xcape($user->name,ENT_COMPAT,"UTF-8"));
354             $user_cur->step_inc();
355           }
356         }
357       }
358     }
359     else {
360       for ($i = 0 ; $i < ($user->stat == 'room' ? MAX_PLAYERS : PLAYERS_N) ; $i++) {
361         if ($user->stat == 'room') {
362           $user_cur = &$this->user[$i];
363           if ($user_cur->sess == '' || $user_cur->stat != 'room')
364             continue;
365         }
366         else {
367           $user_cur = &$this->user[$table->player[$i]];
368         }
369         
370         $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
371         $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('chatt_sub("%s","%s");',
372                                                              $dt.xcape($user->name), xcape($user_mesg));
373         $user_cur->step_inc();
374       }
375       log_legal($timecur, $user->sess, $user->name, 
376                 ($user->stat == 'room' ? 'room' : 'table '.$user->table),$user_mesg);
377     }
378   }
379
380   function table_wakeup(&$user)
381   {
382     $table = &$this->table[0];
383
384     log_main("BRISKIN5_WAKEUP begin function table  stat: ".$user->stat."  subst: ".$user->subst);
385
386     $curtime = time();
387
388     log_main("BRISKIN5_WAKEUP from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
389     
390     for ($i = 0 ; $i < $table->player_n ; $i++) {
391       $user_cur = &$this->user[$i];
392       log_main("PREIMPOST INLOOP name: ".$user_cur->name);
393       
394       if ($user_cur == $user)
395         $user_cur->subst = "shutdowner";
396       else
397         $user_cur->subst = "shutdowned";
398       $user_cur->laccwr = $curtime;
399
400       $ret = "gst.st = ".($user_cur->step+1)."; ";
401       $ret .= 'gst.st_loc++; the_end=true; window.onunload = null; document.location.assign("../index.php");|';
402
403       log_wr($user_cur->sess." BRISKIN5_WAKEUP: ".$ret);
404       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
405       $user_cur->step_inc();
406     }
407
408     $this->the_end = TRUE;
409   }
410   
411   /*
412    *  If all players are freezed the room garbage_manager clean up table and users.
413    */ 
414   function is_abandoned() 
415   {
416     $is_ab = TRUE;
417     $curtime = time();
418
419     $table = &$this->table[0];
420
421     for ($i = 0 ; $i < $table->player_n ; $i++) {
422       $user_cur = &$this->user[$i];
423
424       if ($user_cur->lacc + (EXPIRE_TIME_RD * 2) >= $curtime) { 
425         $is_ab = FALSE;
426         break;
427       }
428     }
429
430     return ($is_ab);
431   }
432 } // end class Briskin5
433
434 function locshm_exists($tok)
435 {
436   // return (TRUE);
437
438   if (($id = shmop_open($tok,"a", 0, 0)) == FALSE) {
439     log_main($tok." SHM NOT exists");
440
441     return (FALSE);
442   }
443   else {
444     shmop_close($id);
445     log_main($tok." SHM exists");
446
447     return (TRUE);
448   }
449     
450 }
451
452
453 ?>