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","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","Nickname %s già in uso.");', $dt.NICKSERV, xcape($name_new));
$user->step_inc();
break;
}
}
if ($i == BRISKIN5_MAX_PLAYERS) {
$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(" %s", " %s", " %s", " %s", " %s"); ',
xcape($this->user[$table->player[($user_cur->table_pos) % BRISKIN5_PLAYERS_N]]->name),
xcape($this->user[$table->player[($user_cur->table_pos+1) % BRISKIN5_PLAYERS_N]]->name),
xcape($this->user[$table->player[($user_cur->table_pos+2) % BRISKIN5_PLAYERS_N]]->name),
(BRISKIN5_PLAYERS_N == 3 ? "" : xcape($this->user[$table->player[($user_cur->table_pos+3) % BRISKIN5_PLAYERS_N]]->name)),
(BRISKIN5_PLAYERS_N == 3 ? "" : xcape($this->user[$table->player[($user_cur->table_pos+4) % BRISKIN5_PLAYERS_N]]->name)));
if ($user_cur == $user)
$user_cur->comm[$user_cur->step % COMM_N] .= sprintf('$("myname").innerHTML = "%s";',
xcape($user->name,ENT_COMPAT,"UTF-8"));
$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","%s");',
$dt.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);
}
}
?>