game token, table recovery, clean of table data
[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     $curtime = time();
73     if ($force || $this->garbage_timeout < $curtime) {
74       
75       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
76         $user_cur = &$this->user[$i];
77         if ($user_cur->sess == "")
78           continue;
79         
80         if ($user_cur->lacc + EXPIRE_TIME_RD < $curtime) { // Auto logout dell'utente
81           log_rd2($user_cur->sess, "AUTO LOGOUT.");
82
83           if ($user_cur->stat == 'table' || $user_cur->stat == 'room') {
84             log_auth($user_cur->sess, "Autologout session.");
85             
86             $tmp_sess = $user_cur->sess;
87             $user_cur->sess = "";
88             step_unproxy($tmp_sess);
89             $user_cur->name = "";
90             $user_cur->the_end = FALSE;
91             
92             log_rd2($user_cur->sess, "AUTO LOGOUT.");
93             if ($user_cur->subst == 'sitdown' || $user_cur->stat == 'table')
94               $this->room_wakeup(&$user_cur);
95             else if ($user_cur->subst == 'standup')
96               $this->room_outstandup(&$user_cur);
97             else
98               log_rd2($sess, "LOGOUT FROM WHAT ???");
99           }
100         }
101
102         if ($user_cur->laccwr + EXPIRE_TIME_SMAMMA < $curtime) { // lo rimettiamo in piedi
103           if ($user_cur->stat == 'room' && $user_cur->subst == 'sitdown') {
104             $this->room_wakeup(&$user_cur);
105             $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
106             $user_cur->comm[$user_cur->step % COMM_N] .=  show_notify("<br>Sei stato inattivo per ".(EXPIRE_TIME_SMAMMA/60.0)." minuti. <br><br>Quindi ritorni tra i <b>Giocatori in piedi</b>.", 0, "torna ai tavoli", 400, 100);
107             $user_cur->step_inc();
108           }
109         }
110       }
111       log_rd2($user_cur->sess, "GARBAGE UPDATED!");
112       
113       $this->garbage_timeout = time() + GARBAGE_TIMEOUT;
114     }
115
116     // BAN_IP_CLEAN
117
118   }
119
120
121
122
123   //
124   //  static functions
125   //
126   function &load_data($table_idx,$table_token) 
127   {
128     GLOBAL $G_false, $sess;
129     $shm = FALSE;
130
131     log_wr($sess, "TABLE_IDX ".FTOK_PATH."/table".$table_idx);
132     if (($tok = ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) {
133       echo "FTOK FAILED";
134       exit;
135     }
136     
137     do {
138       if (($shm = shm_attach($tok, SHM_DIMS)) == FALSE)
139         break;
140
141       if (($bri = @shm_get_var($shm, $tok)) == FALSE) 
142         break;
143
144       if ($bri->table_token != $table_token) {
145         log_wr($sess, "bri->table_token: ".$bri->table_token."table_token: ".$table_token);
146         
147         break;
148       }
149       $bri->tok = $tok;
150
151       shm_detach($shm);
152         
153       $ret = &$bri;
154       return ($ret); 
155     } while (FALSE);
156
157     if ($shm != FALSE)
158       shm_detach($shm);
159
160     log_wr($sess, "briskin5 load_data failed");
161     
162     return ($G_false);
163   }
164   
165
166   function save_data(&$bri) 
167   {
168     GLOBAL $sess;
169     
170     $ret =   FALSE;
171     $shm =   FALSE;
172     $isacq = FALSE;
173     
174     log_main("XXX", "SAVE BRISKIN5 DATA");
175     // var_dump($bri);
176     
177     if (!isset($bri->tok))
178       return (FALSE);
179     
180     do {
181       $isacq = TRUE;
182       
183       if (($shm = shm_attach($bri->tok, SHM_DIMS)) == FALSE)
184         break;
185       
186       // log_only($sess, "PUT_VAR DI ".strlen(serialize($bri)));
187       if (shm_put_var($shm, $bri->tok, $bri) == FALSE) {
188         log_only($sess, "PUT_VAR FALLITA ".strlen(serialize($bri)));
189         log_only($sess, serialize($bri));
190         break;
191       }
192       // log_main("XXX", "QUI CI ARRIVA [".$bri->user[0]->name."]");
193       $ret = TRUE;
194     } while (0);
195     
196     if ($shm)
197       shm_detach($shm);
198     
199     return ($ret);
200   }
201
202   function destroy_data(&$bri) 
203   {
204     GLOBAL $sess;
205     
206     $ret =   FALSE;
207     $shm =   FALSE;
208     $isacq = FALSE;
209     
210     // var_dump($bri);
211     
212     log_main("XXX", "DESTROY BRISKIN5 DATA");
213
214     if (!isset($bri->tok))
215       return (FALSE);
216     
217     do {
218       $isacq = TRUE;
219       
220       log_main("XXX", "DESTROY2 BRISKIN5 DATA");
221       if (($shm = shm_attach($bri->tok, SHM_DIMS)) === FALSE)
222         break;
223       
224       if (shm_remove($shm) === FALSE) {
225         log_only($sess, "REMOVE FALLITA ".strlen(serialize($bri)));
226         log_only($sess, serialize($bri));
227         break;
228       }
229       else {
230         $shm = FALSE;
231         log_main("XXX", "DESTROY2 BRISKIN5 DATA SUCCESS");
232       }
233       // log_main("XXX", "QUI CI ARRIVA [".$bri->user[0]->name."]");
234       $ret = TRUE;
235     } while (0);
236     
237     if ($shm)
238       shm_detach($shm);
239     
240     return ($ret);
241   }
242
243   function lock_data($table_idx)
244   {
245     GLOBAL $sess; 
246     
247     log_wr($sess, "LOCK_DATA ".FTOK_PATH."/table".$table_idx);
248     //  echo "LOCK: ".FTOK_PATH."/main";
249     //  exit;
250     if (($tok = ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) {
251       echo "FTOK FAILED";
252       exit;
253     }
254     // echo "FTOK ".$tok."<br>";
255     if (($res = sem_get($tok)) == FALSE) {
256       echo "SEM_GET FAILED";
257       exit;
258     }
259     if (sem_acquire($res)) {   
260       log_only($sess, "LOCK");
261       return ($res);
262     }
263     else
264       return (FALSE);
265   }
266   
267   function unlock_data($res)
268   {
269     GLOBAL $sess; 
270     
271     log_only($sess, "UNLOCK");
272
273     return (sem_release($res));
274   }
275
276
277   function chatt_send(&$user, $mesg)
278   {
279     if ($user->stat == 'table') {
280       $table = &$this->table[$user->table];
281     }
282     
283     $user_mesg = substr($mesg,6);
284     
285     $timecur = time();
286     
287     $dt = date("H:i ", $timecur);
288     if (strncmp($user_mesg, "/nick ", 6) == 0) {
289       log_main($user->sess, "chatt_send BEGIN");
290
291       if (($name_new = validate_name(substr($user_mesg, 6))) == FALSE) {
292           $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; ";
293           $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));
294           $user->step_inc();
295
296           return;
297       }
298       $user_mesg = "COMMAND ".$user_mesg;
299       // Search dup name
300       // change
301       // update local graph
302       // update remote graphs
303       for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
304         $user_cur = &$this->user[$i];
305         //      if ($user_cur->sess == '' || $user_cur->stat != 'room')
306         if ($user_cur->sess == '')
307           continue;
308         if ($user_cur->name == $name_new) {
309           $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; ";
310           $user->comm[$user->step % COMM_N] .= sprintf('chatt_sub("%s","Nickname <b>%s</b> gi&agrave; in uso.");', $dt.NICKSERV, xcape($name_new));
311           $user->step_inc();
312           break;
313         }
314       }
315       if ($i == MAX_PLAYERS) {
316         $user->name = $name_new;
317
318       log_main($user->sess, "chatt_send start set");
319         
320
321         for ($i = 0 ; $i < MAX_PLAYERS ; $i++) {
322           log_main($user->sess, "chatt_send set loop");
323           
324           $user_cur = &$this->user[$i];
325           if ($user_cur->sess == '')
326             continue;
327           if ($user_cur->stat == 'room') {
328             if ($user->stat == 'room' && $user->subst == 'standup') {
329               $this->standup_update(&$user);
330             }
331             else if ($user->stat == 'room' && $user->subst == 'sitdown' ||
332                      $user->stat == 'table') {
333               log_main($user->sess, "chatt_send pre table update");
334
335               $this->table_update(&$user);
336
337               log_main($user->sess, "chatt_send post table update");
338             }
339           }
340           else if ($user_cur->stat == 'table' && $user_cur->table == $user->table) {
341             $table = &$this->table[$user->table];
342             
343             $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
344             $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('set_names(" %s", " %s", " %s", " %s", " %s"); ',
345                 xcape($this->user[$table->player[($user_cur->table_pos)%PLAYERS_N]]->name),
346                 xcape($this->user[$table->player[($user_cur->table_pos+1)%PLAYERS_N]]->name),
347                 xcape($this->user[$table->player[($user_cur->table_pos+2)%PLAYERS_N]]->name),
348                 (PLAYERS_N == 3 ? "" :  xcape($this->user[$table->player[($user_cur->table_pos+3)%PLAYERS_N]]->name)),
349                 (PLAYERS_N == 3 ? "" :  xcape($this->user[$table->player[($user_cur->table_pos+4)%PLAYERS_N]]->name)));
350             if ($user_cur == $user)
351               $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('$("myname").innerHTML = "<b>%s</b>";', 
352                                                                    xcape($user->name,ENT_COMPAT,"UTF-8"));
353             $user_cur->step_inc();
354           }
355         }
356       }
357     }
358     else {
359       for ($i = 0 ; $i < ($user->stat == 'room' ? MAX_PLAYERS : PLAYERS_N) ; $i++) {
360         if ($user->stat == 'room') {
361           $user_cur = &$this->user[$i];
362           if ($user_cur->sess == '' || $user_cur->stat != 'room')
363             continue;
364         }
365         else {
366           $user_cur = &$this->user[$table->player[$i]];
367         }
368         
369         $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; ";
370         $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('chatt_sub("%s","%s");',
371                                                              $dt.xcape($user->name), xcape($user_mesg));
372         $user_cur->step_inc();
373       }
374       log_legal($timecur, $user->sess, $user->name, 
375                 ($user->stat == 'room' ? 'room' : 'table '.$user->table),$user_mesg);
376     }
377   }
378
379   function table_wakeup(&$user)
380   {
381     $table = &$this->table[0];
382
383     log_main("BRISKIN5_WAKEUP", "begin function table  stat: ".$user->stat."  subst: ".$user->subst);
384
385     $curtime = time();
386
387     log_main("BRISKIN5_WAKEUP", "from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n);
388     
389     for ($i = 0 ; $i < $table->player_n ; $i++) {
390       $user_cur = &$this->user[$i];
391       log_main("PREIMPOST", "INLOOP name: ".$user_cur->name);
392       
393       if ($user_cur == $user)
394         $user_cur->subst = "shutdowner";
395       else
396         $user_cur->subst = "shutdowned";
397       $user_cur->laccwr = $curtime;
398
399       $ret = "gst.st = ".($user_cur->step+1)."; ";
400       $ret .= 'gst.st_loc++; the_end=true; window.onunload = null; document.location.assign("../index.php");|';
401
402       log_wr($user_cur->sess, "BRISKIN5_WAKEUP: ".$ret);
403       $user_cur->comm[$user_cur->step % COMM_N] = $ret;
404       $user_cur->step_inc();
405     }
406   }
407
408
409 } // end of class Briskin5
410
411 ?>