true, 'time'=>true, 'userID'=>true, 'userName'=>true, 'userGrade'=>true, 'writeClosed'=>true ]; const GAME_KEY_DATE = '_g_loginDate'; const GAME_KEY_GENERAL_ID = '_g_no'; const GAME_KEY_GENERAL_NAME = '_g_name'; const GAME_KEY_EXPECTED_DEADTIME = '_g_deadtime'; private $writeClosed = false; /** * @return \sammo\Session */ public static function Instance(){ static $inst = null; if($inst === null){ $inst = new Session(); } return $inst; } /** * @return \sammo\Session */ public static function requireLogin($movePath = ROOT){ $session = Session::Instance(); if($session->isLoggedIn()){ return $session; } $session->setReadOnly(); if(is_string($path)){ header('Location:'.$path); die(); } Json::die([ 'result'=>false, 'reason'=>'로그인이 필요합니다.' ]); } public function __construct() { //session_cache_limiter('nocache, must_revalidate'); // 세션 변수의 등록 if (session_id() == ""){ session_start(); } //첫 등장 if(!Util::array_get($_SESSION['ip'])) { $_SESSION['ip'] = Util::get_client_ip(true); $_SESSION['time'] = time(); } } /** * @return \sammo\Session */ public function setReadOnly(){ if(!$this->writeClosed){ session_write_close(); $this->writeClosed = true; } return $this; } public function __set(string $name, $value){ if(key_exists($key, $this->PROTECED_NAMES)){ trigger_error("{$name}은 외부에서 쓰기 금지된 Session 변수입니다.", E_USER_NOTICE); return; } $this->set($name, $value); } private function set(string $name, $value){ if($value === null){ unset($_SESSION[$name]); } else{ $_SESSION[$name] = $value; } } public function __get(string $name){ return $this->get($name); } private function get(string $name){ return Util::array_get($_SESSION[$name]); } public function login(int $userID, string $userName, int $grade) { $this->set('userID', $userID); $this->set('userName', $userName); $this->set('ip', Util::get_client_ip(true)); $this->set('time', time()); $this->set('userGrade', $grade); $this->set('access_token', null); return $this; } public function logout() { $this->logoutGame(); $this->set('userID', null); $this->set('userName', null); $this->set('userGrade', null); $this->set('time', time()); return $this; } public function loginGame(&$result = null){ $userID = $this->userID; if(!$userID){ if($result !== null){ $result = false; } return $this; } if(!class_exists('\\sammo\\DB')){ if($result !== null){ $result = false; } return $this; } $prefix = DB::prefix(); $db = DB::db(); $loginDate = $this->get($prefix.static::GAME_KEY_DATE); $generalID = $this->get($prefix.static::GAME_KEY_GENERAL_ID); $generalName = $this->get($prefix.static::GAME_KEY_GENERAL_NAME); $deadTime = $this->get($prefix.static::GAME_KEY_EXPECTED_DEADTIME); $now = time(); if( $generalID && $generalName && $loginDate && $deateTime && $loginDate + 600 > $now && $deadTime > $now ){ //로그인 정보는 5분간 유지한다. if($result !== null){ $result = true; } return $this; } if($generalID || $generalName || $loginDate || $deadTime){ $this->logoutGame(); } $general = $db->queryFirstRow( 'SELECT `no`, `name`, `killturn`, `turntime` from general where `owner` = %i', $userID ); if(!$general){ if($result !== null){ $result = false; } return $this; } $turnterm = $db->queryFirstField('SELECT turnterm from game limit 1'); $generalID = $general['no']; $generalName = $general['name']; } public function logoutGame(){ $prefix = DB::prefix(); $this->set($prefix.static::GAME_KEY_DATE, null); $this->set($prefix.static::GAME_KEY_GENERAL_ID, null); $this->set($prefix.static::GAME_KEY_GENERAL_NAME, null); $this->set($prefix.static::GAME_KEY_EXPECTED_DEADTIME, null); return $this; } /** * 로그인 유저의 전역 grade를 받아옴 * @return int|null */ public static function getUserGrade(bool $requireLogin = false, string $exitPath = ROOT){ if($requireLogin){ $obj = self::requireLogin($exitPath); } else{ $obj = self::Instance(); } return $obj->userGrade; } /** * 로그인한 유저의 전역 id(숫자)를 받아옴 * * @return int|null */ public static function getUserID(bool $requireLogin = false, string $exitPath = ROOT){ if($requireLogin){ $obj = self::requireLogin($exitPath); } else{ $obj = self::Instance(); } return $obj->userID; } public function isLoggedIn() { if($this->userID){ return true; } else{ return false; } } public function __destruct() { } }