--- /dev/null
+<?php
+define(BRISKIN5_PLAYERS_N, 3);
+define(BRISKIN5_MAX_PLAYERS, BRISKIN5_PLAYERS_N);
+// define(BRISKIN5_SHM_MIN, (50000 * BRISKIN5_MAX_PLAYERS));
+define(BRISKIN5_SHM_MIN, 32768);
+define(BRISKIN5_SHM_MAX, (BRISKIN5_SHM_MIN + 1048576));
+define(BRISKIN5_SHM_DLT, 32768);
+
+class Briskin5 {
+ var $user;
+ var $table;
+ var $table_idx;
+ var $table_token;
+
+ var $comm; // commands for many people
+ var $step; // current step of the comm array
+ var $garbage_timeout;
+
+ var $the_end;
+
+ var $tok;
+ var $shm_sz;
+
+ function Briskin5 (&$room, $table_idx, $table_token) {
+ $this->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 <b>%s</b> 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 = "<b>%s</b>";',
+ 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.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);
+ }
+
+}
+
+
+?>