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