user = array(); $this->table = array(); $this->the_end = FALSE; $this->shm_sz = BRISKIN5_SHM_MIN; if (($this->tok = @ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) { echo "FTOK FAILED"; exit; } $user =& $room->user; $table =& $room->table[$table_idx]; log_wr("Briskin5 constructor"); for ($i = 0 ; $i < $table->player_n ; $i++) { $user[$table->player[$i]]->table_token = $table_token; $this->user[$i] =& User::spawn(&$user[$table->player[$i]], 0, $i); } $this->table[0] =& Table::spawn(&$table); $this->table_idx = $table_idx; $this->table_token = $table_token; $this->garbage_timeout = 0; log_wr("Briskin5 constructor end"); } function &get_user($sess, &$idx) { GLOBAL $PHP_SELF, $G_false; if (validate_sess($sess)) { for ($i = 0 ; $i < BRISKIN5_MAX_PLAYERS ; $i++) { if (strcmp($sess, $this->user[$i]->sess) == 0) { // find it $idx = $i; $ret = &$this->user[$i]; return ($ret); } } log_main(sprintf("get_user: Wrong sess from page [%s]",$PHP_SELF)); // for ($i = 0 ; $i < BRISKIN5_MAX_PLAYERS ; $i++) // log_main(sprintf("get_user: Wrong sess compared with [%s]",$this->user[$i]->sess)); } else { log_main(sprintf("get_user: Wrong strlen [%s]",$sess)); } return ($G_false); } function garbage_manager($force) { /* Garbage collector degli utenti in timeout */ $ismod = FALSE; $curtime = time(); if ($force || $this->garbage_timeout < $curtime) { for ($i = 0 ; $i < BRISKIN5_MAX_PLAYERS ; $i++) { $user_cur = &$this->user[$i]; if ($user_cur->sess == "" || ($user_cur->stat == 'table' && ($user_cur->subst == 'shutdowned' || $user_cur->subst == 'shutdowner'))) continue; if ($user_cur->lacc + EXPIRE_TIME_RD < $curtime) { // Auto logout dell'utente log_rd2($user_cur->sess." bin5 AUTO LOGOUT."); if ($user_cur->stat == 'table') { log_auth($user_cur->sess," bin5 Autologout session."); /* SI DELEGA AL garbage_manager principale LA RIMOZIONE DELL'UTENTE $tmp_sess = $user_cur->sess; $user_cur->sess = ""; step_unproxy($tmp_sess); $user_cur->name = ""; $user_cur->the_end = FALSE; */ $this->table_wakeup(&$user_cur); } } } log_rd2($user_cur->sess." GARBAGE UPDATED!"); $this->garbage_timeout = $curtime + GARBAGE_TIMEOUT; $ismod = TRUE; } return ($ismod); } // // static functions // function &load_data($table_idx, $table_token = "") { GLOBAL $G_false, $sess; $doexit = FALSE; $shm = FALSE; log_wr("TABLE_IDX ".FTOK_PATH."/table".$table_idx); do { if (($tok = @ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) { log_main("ftok failed"); $doexit = TRUE; break; } if (($shm_sz = sharedmem_sz($tok)) == -1) { log_main("shmop_open failed"); break; } if (($shm = shm_attach($tok, $shm_sz)) == FALSE) break; if (($bri = @shm_get_var($shm, $tok)) == FALSE) break; if ($table_token != "" && $bri->table_token != $table_token) { log_wr("bri->table_token: ".$bri->table_token."table_token: ".$table_token); break; } $bri->tok = $tok; shm_detach($shm); $ret = &$bri; return ($ret); } while (FALSE); if ($shm != FALSE) shm_detach($shm); log_wr("briskin5 load_data failed"); if ($doexit) exit(); return ($G_false); } function save_data(&$bri) { GLOBAL $sess; $ret = FALSE; $shm = FALSE; log_main("SAVE BRISKIN5 DATA"); if (!isset($bri->tok)) return (FALSE); while ($bri->shm_sz < BRISKIN5_SHM_MAX) { if (($shm = shm_attach($bri->tok, $bri->shm_sz)) == FALSE) break; if (@shm_put_var($shm, $bri->tok, $bri) != FALSE) { shm_detach($shm); return (TRUE); } if (shm_remove($shm) === FALSE) { log_only("REMOVE FALLITA"); break; } shm_detach($shm); $bri->shm_sz += BRISKIN5_SHM_DLT; } log_crit("save data failed!"); if ($shm) shm_detach($shm); return ($ret); } function destroy_data($table_idx) { GLOBAL $sess; $ret = FALSE; $shm = FALSE; log_main("DESTROY BRISKIN5 DATA"); do { log_main("DESTROY2 BRISKIN5 DATA"); if (($tok = @ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) break; if (($shm = @shmop_open($tok, 'a', 0, 0)) == FALSE) break; if (shmop_delete($shm) == 0) { log_only("REMOVE FALLITA "); break; } $shm = FALSE; log_main("DESTROY2 BRISKIN5 DATA SUCCESS"); // log_main("QUI CI ARRIVA [".$bri->user[0]->name."]"); $ret = TRUE; } while (0); if ($shm) shm_detach($shm); return ($ret); } function lock_data($table_idx) { GLOBAL $sess; log_wr("LOCK_DATA ".FTOK_PATH."/table".$table_idx); // echo "LOCK: ".FTOK_PATH."/main"; // exit; // WARNING monitor this step if (($tok = @ftok(FTOK_PATH."/table".$table_idx, "B")) == -1) { echo "FTOK FAILED"; exit; } // WARNING monitor this step if (($res = @sem_get($tok)) == FALSE) { echo "SEM_GET FAILED"; exit; } if (sem_acquire($res)) { log_lock("LOCK table ".$table_idx."[res: ".$res."]"); return ($res); } else { log_lock("LOCK table ".$table_idx.":FAILED"); return (FALSE); } } function unlock_data($res) { GLOBAL $sess; log_lock("UNLOCK table [res: ".$res."]"); return (sem_release($res)); } function chatt_send(&$user, $mesg) { if ($user->stat == 'table') { $table = &$this->table[$user->table]; } $user_mesg = substr($mesg,6); $curtime = time(); $dt = date("H:i ", $curtime); if (strncmp($user_mesg, "/nick ", 6) == 0) { log_main($user->sess." chatt_send BEGIN"); if (($name_new = validate_name(substr($user_mesg, 6))) == FALSE) { $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; "; $user->comm[$user->step % COMM_N] .= sprintf('chatt_sub("%s", [2, "%s"],"Il nickname deve contenere almeno una lettera dell\'alfabeto o una cifra.");', $dt, NICKSERV); $user->step_inc(); return; } $user_mesg = "COMMAND ".$user_mesg; // Search dup name // change // update local graph // update remote graphs for ($i = 0 ; $i < BRISKIN5_MAX_PLAYERS ; $i++) { $user_cur = &$this->user[$i]; // if ($user_cur->sess == '' || $user_cur->stat != 'room') if ($user_cur->sess == '') continue; if ($user_cur->name == $name_new) { $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; "; $user->comm[$user->step % COMM_N] .= sprintf('chatt_sub("%s", [2, "%s"],"Nickname %s già in uso.%d");', $dt, NICKSERV, xcape($name_new), $this->table[$user->table]->auth_only == TRUE); $user->step_inc(); break; } } if ($i == BRISKIN5_MAX_PLAYERS) { if ($user->flags & USER_FLAG_AUTH && strcasecmp($user->name,$name_new) != 0) { if ($this->table[$user->table]->auth_only == TRUE) { $user->comm[$user->step % COMM_N] = "gst.st = ".($user->step+1)."; "; $user->comm[$user->step % COMM_N] .= sprintf('chatt_sub("%s", [2, "%s"],"Non puoi cambiare nick a un tavolo per soli autenticati.");', $dt, NICKSERV); $user->step_inc(); return; } else { $user->flags &= ~USER_FLAG_AUTH; // Remove auth if name changed } } $user->name = $name_new; log_main($user->sess." chatt_send start set"); for ($i = 0 ; $i < BRISKIN5_MAX_PLAYERS ; $i++) { log_main($user->sess." chatt_send set loop"); $user_cur = &$this->user[$i]; if ($user_cur->sess == '') continue; if ($user_cur->stat == 'room') { if ($user->stat == 'room' && $user->subst == 'standup') { $this->standup_update(&$user); } else if ($user->stat == 'room' && $user->subst == 'sitdown' || $user->stat == 'table') { log_main($user->sess." chatt_send pre table update"); $this->table_update(&$user); log_main($user->sess." chatt_send post table update"); } } else if ($user_cur->stat == 'table' && $user_cur->table == $user->table) { $table = &$this->table[$user->table]; $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; "; $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('set_names([%d, "%s"], [%d, "%s"], [%d, "%s"], [%d, "%s"], [%d, "%s"]); ', $this->user[$table->player[($user_cur->table_pos) % BRISKIN5_PLAYERS_N]]->flags, xcape($this->user[$table->player[($user_cur->table_pos) % BRISKIN5_PLAYERS_N]]->name), $this->user[$table->player[($user_cur->table_pos+1) % BRISKIN5_PLAYERS_N]]->flags, xcape($this->user[$table->player[($user_cur->table_pos+1) % BRISKIN5_PLAYERS_N]]->name), $this->user[$table->player[($user_cur->table_pos+2) % BRISKIN5_PLAYERS_N]]->flags, xcape($this->user[$table->player[($user_cur->table_pos+2) % BRISKIN5_PLAYERS_N]]->name), (BRISKIN5_PLAYERS_N == 3 ? 0: $this->user[$table->player[($user_cur->table_pos+3) % BRISKIN5_PLAYERS_N]]->flags), (BRISKIN5_PLAYERS_N == 3 ? "" : xcape($this->user[$table->player[($user_cur->table_pos+3) % BRISKIN5_PLAYERS_N]]->name)), (BRISKIN5_PLAYERS_N == 3 ? 0: $this->user[$table->player[($user_cur->table_pos+4) % BRISKIN5_PLAYERS_N]]->flags), (BRISKIN5_PLAYERS_N == 3 ? "" : xcape($this->user[$table->player[($user_cur->table_pos+4) % BRISKIN5_PLAYERS_N]]->name))); if ($user_cur == $user) { $itin = ($user->flags & USER_FLAG_AUTH ? "" : ""); $itou = ($user->flags & USER_FLAG_AUTH ? "" : ""); $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('$("myname").innerHTML = "%s%s%s";', $itin, xcape($user->name,ENT_COMPAT,"UTF-8"), $itou); } $user_cur->step_inc(); } } } } else { for ($i = 0 ; $i < ($user->stat == 'room' ? BRISKIN5_MAX_PLAYERS : BRISKIN5_PLAYERS_N) ; $i++) { if ($user->stat == 'room') { $user_cur = &$this->user[$i]; if ($user_cur->sess == '' || $user_cur->stat != 'room') continue; } else { $user_cur = &$this->user[$table->player[$i]]; } $user_cur->comm[$user_cur->step % COMM_N] = "gst.st = ".($user_cur->step+1)."; "; $user_cur->comm[$user_cur->step % COMM_N] .= sprintf('chatt_sub("%s", [%d, "%s"],"%s");', $dt, $user->flags, xcape($user->name), xcape($user_mesg)); $user_cur->step_inc(); } log_legal($curtime, $user->sess, $user->name, ($user->stat == 'room' ? 'room' : 'table '.$user->table),$user_mesg); } } function table_wakeup(&$user) { $table = &$this->table[0]; log_main("BRISKIN5_WAKEUP begin function table stat: ".$user->stat." subst: ".$user->subst); $curtime = time(); log_main("BRISKIN5_WAKEUP from table [".$user->table."] nplayers_n: ".$this->table[$user->table]->player_n); for ($i = 0 ; $i < $table->player_n ; $i++) { $user_cur = &$this->user[$i]; log_main("PREIMPOST INLOOP name: ".$user_cur->name); if ($user_cur == $user) $user_cur->subst = "shutdowner"; else $user_cur->subst = "shutdowned"; $user_cur->laccwr = $curtime; $ret = "gst.st = ".($user_cur->step+1)."; "; $ret .= 'gst.st_loc++; the_end=true; window.onbeforeunload = null; window.onunload = null; document.location.assign("../index.php");|'; log_wr($user_cur->sess." BRISKIN5_WAKEUP: ".$ret); $user_cur->comm[$user_cur->step % COMM_N] = $ret; $user_cur->step_inc(); } $this->the_end = TRUE; } /* * If all players are freezed the room garbage_manager clean up table and users. */ function is_abandoned() { $is_ab = TRUE; $curtime = time(); $table = &$this->table[0]; for ($i = 0 ; $i < $table->player_n ; $i++) { $user_cur = &$this->user[$i]; if ($user_cur->lacc + (EXPIRE_TIME_RD * 2) >= $curtime) { $is_ab = FALSE; break; } } return ($is_ab); } } // end class Briskin5 function locshm_exists($tok) { // return (TRUE); if (($id = @shmop_open($tok,"a", 0, 0)) == FALSE) { log_main($tok." SHM NOT exists"); return (FALSE); } else { shmop_close($id); log_main($tok." SHM exists"); return (TRUE); } } ?>