loginLimit($params)) { $this->resetLoginLimit(); return ['status' => false, 'message' => '登录人数过多,请稍后再试']; } $account = $params['account'] ?? ''; $password = $params['password'] ?? ''; $gameId = $params['game_id'] ?? 0; $sdkVersion = $params['sdk_version']; $deviceNum = $params['unique_code'] ?? ''; $clientIp = get_client_ip(); $game = M('game', 'tab_')->where(['id' => $gameId])->find(); $result = $this->doLogin($account, $password, $game, ['client_ip' => $clientIp, 'device_num' => $deviceNum]); if (!$result['status']) { $this->resetLoginLimit(); return ['status' => false, 'message' => $result['message']]; } $user = $result['data']['user']; $noticeCount = $this->getNoticeCount($user, $game); $this->addUserPlay($user, $game, $clientIp); $this->dispatchLoginEvent([ 'game_id' => $game['id'], 'user_id' => $user['id'], 'login_time' => time(), ]); $smallList = []; $smallList[] = [ 'is_platform' => $user['is_platform'], 'user_id' => $user['id'], 'account' => $user['account'], 'user_account' => $user['account'] ]; $data = [ 'status' => 200, 'return_code' => 'success', 'return_msg' => '登录成功', 'user_id' => $user['id'], 'account' => $user['account'], 'nickname' => $user['nickname'] ? $user['nickname'] : $user['account'], 'sex' => $user['sex'] ? $user['sex'] : 0, 'is_platform' => $user['is_platform'], 'token' => $result['data']['token'], 'user_token' => $result['data']['user_token'], 'OTP_token' => think_encrypt(json_encode(array('uid' => $user['id'], 'time' => time())), 1), 'is_uc' => 0, 'is_open_small_account' => C('IS_OPEN_SMALL_ACCOUNT'), 'url' => 'http://' . str_replace(array('http://'), '', C('WEB_SITE')) . '/mobile.php', 'small_list' => $smallList, 'ios_packagename' => C('WEB_IOS_PACKAGENAME'), 'android_packagename' => C('WEB_AND_PACKAGENAME'), 'site_status' => C('SDK_SITE_STATUS'), 'head_img' => !empty($user['head_img']) ? $user['head_img'] : '', 'unread_count' => $noticeCount, 'notice_count' => $noticeCount, 'request_count' => 0, ]; $this->doUserSource($data['user_id'], $gameId, $params['promote_id'] ?? 0, $deviceNum, $sdkVersion, $clientIp); $this->resetLoginLimit(); return ['status' => true, 'message' => '登录成功', 'data' => $data]; } protected function isBan($ip, $deviceNum) { $ban = M('device_bans','tab_')->field(['id'])->where(['tag' => ['in', [$ip, $deviceNum]]])->limit(1)->find(); if (empty($ban)) { return false; } return true; } protected function doLogin($account, $password, $game, $params = []) { $clientIp = $params['client_ip'] ?? get_client_ip(); $deviceNum = $params['device_num'] ?? ''; if ($this->isBan($clientIp, $deviceNum)) { Log::write(date('Y-m-d H:i:s') . ' account:' . $account . ' clientIp:' . $clientIp . ' deviceNum:' . $deviceNum, 'INFO', '', C('LOG_PATH')."login_ban.log"); return ['status' => false, 'message' => '设备已被禁用']; } $user = M('user', 'tab_')->where(['account' => $account])->find(); /* 获取用户数据 */ if (empty($user) || $user['lock_status'] != 1 || $user['check_status'] != 1) { return ['status' => false, 'message' => '账号或密码错误']; } if ($this->password($password, UC_AUTH_KEY) !== $user['password']) { return ['status' => false, 'message' => '密码错误']; } $testingUser = M('testing_user', 'tab_')->where(['user_id' => $user['id']])->find(); if ($testingUser) { if ($testingUser['verify_status'] != 1) { return ['status' => false, 'message' => '该账号不可使用!']; } if ($testingUser['status'] == 3) { return ['status' => false, 'message' => '该账号已被禁用!']; } if ($this->isIpWarning($user, $clientIp)) { M('testing_user', 'tab_')->where(['user_id' => $user['id']])->save([ 'status' => 2, 'update_time' => time() ]); } } $result = $this->getLoginToken($user, $game, $password); if (!$result) { return ['status' => false, 'message' => '系统异常']; } [$token, $userToken] = $result; $userData = []; if (!$user['device_number']) { $userData['device_number'] = $deviceNum; } $userData['login_time'] = NOW_TIME; $userData['login_ip'] = $clientIp; $userData['last_login_ip'] = $clientIp; $userData['last_device_number'] = $deviceNum; if(!$user['fgame_id']) { $userData['fgame_id'] = $game['id']; $userData['fgame_name'] = $game['game_name']; } $userData['token'] = $token; $status = M('user', 'tab_')->where(['id' => $user['id']])->save($userData); if (!$status) { return ['status' => false, 'message' => '登录异常']; } $this->addUserLoginRecord($user, $game, $clientIp, $deviceNum); $this->addUserGameLoginRecord($user, $game, $clientIp, $deviceNum); if (!$user['device_type']) { $this->oaDeviceTypeUpdate($user, $game); } $data = [ 'user' => $user, 'token' => $token, 'user_token' => $userToken, ]; return ['status' => true, 'message' => '登录成功', 'data' => $data]; } protected function doUserSource($uid, $gameId, $promoteId, $deviceNum, $sdkVersion, $clientIp) { $find = M('user_source', 'tab_')->where([ 'user_id' => $uid, 'game_id' => $gameId, 'promote_id' => $promoteId ])->find(); if (!$find) { M('user_source', 'tab_')->add([ 'user_id' => $uid, 'game_id' => $gameId, 'promote_id' => $promoteId, 'device_num' => $deviceNum, 'sdk_version' => $sdkVersion, 'ip' => $clientIp, 'create_time' => time() ]); } } /** * @deprecated */ protected function isDeviceError($user, $testResource, $deviceNum) { if ($testResource && $user['device_number'] && $deviceNum && $user['device_number'] != $deviceNum) { return true; } return false; } /** * @deprecated */ protected function deviceErrorLog($user, $testResource, $deviceNum){ $data = []; $data['user_id'] = $user['id']; $data['user_account'] = $testResource['user_account']; $data['server_id'] = $testResource['server_id']; $data['server_name'] = $testResource['server_name']; $data['game_id'] = $testResource['game_id']; $data['game_name'] = $testResource['game_name']; $data['nickname'] = $testResource['role_name']; $data['promote_id'] = $testResource['promote_id']; $data['promote_account'] = $testResource['promote_account']; $data['type'] = 2; $data['detail'] = '登录设备号异常,本次异常设备号:' . $deviceNum . ',历史登录设备号:' . $user['device_number']; $data['create_time'] = NOW_TIME; M('protect_log','tab_')->add($data); } protected function isIpWarning($user, $clientIp) { $newResult = IPTool::getIpInfo($clientIp); $oldResult = IPTool::getIpInfo($user['login_ip']); if ( $newResult['country_id'] == $oldResult['country_id'] && $newResult['region_id'] == $oldResult['region_id'] && $newResult['city_id'] == $oldResult['city_id'] ) { return false; } return true; } /** * @deprecated */ protected function ipWarningLog($user, $testResource, $clientIp){ $data = []; $data['user_id'] = $user['id']; $data['user_account'] = $testResource['user_account']; $data['server_id'] = $testResource['server_id']; $data['server_name'] = $testResource['server_name']; $data['game_id'] = $testResource['game_id']; $data['game_name'] = $testResource['game_name']; $data['nickname'] = $testResource['role_name']; $data['promote_id'] = $testResource['promote_id']; $data['promote_account'] =$testResource['promote_account']; $data['type'] = 1; $data['detail'] = '登录IP异常,本次异常IP:' . $clientIp . ',历史登录IP:' . $user['login_ip']; $data['create_time'] = NOW_TIME; M('protect_log','tab_')->add($data); } protected function generateToken($userId, $account, $password){ $str = $userId . $account . $password . NOW_TIME . sp_random_string(7); $token = md5($str); return $token; } protected function getLoginToken($user, $game, $password) { $token = $this->generateToken($user['id'], $user['account'], $password); $userToken = $this->generateToken($user['id'], $user['account'], $password) . uniqid() . rand(1000, 9999); $record = M('user_token','tab_')->where(['user_id' => $user['id'], 'game_id' => $game['id']])->find(); if (!$record) { $status = M('user_token', 'tab_')->add([ 'user_id' => $user['id'], 'game_id' => $game['id'], 'relation_game_id' => $game['relation_game_id'], 'user_token' => $userToken, 'login_cnt' => 1, 'create_time' => time(), 'update_time' => time() ]); if (!$status) { return null; } $status = M('user_token', 'tab_')->where([ 'user_id' => $user['id'], 'relation_game_id' => $game['relation_game_id'] ])->save([ 'user_token' => $userToken, 'login_cnt' => $record['login_cnt'] + 1, 'update_time' => time() ]); } else { $status = M('user_token', 'tab_')->where([ 'user_id' => $user['id'], 'game_id|relation_game_id' => $game['relation_game_id'] ])->save([ 'user_token' => $userToken, 'login_cnt' => $record['login_cnt'] + 1, 'update_time' => time() ]); if ($status === false) { return null; } } return [$token, $userToken]; } public function oaDeviceTypeUpdate($user, $game) { $gameServer = substr($game['game_name'], -10, 9); if($gameServer == '安卓版'){ $arr['device_type'] = 'Android'; } elseif($gameServer == '苹果版') { $arr['device_type'] = 'IOS'; } $arr['time'] = time(); $arr['account'] = $user['account']; ksort($arr); reset($arr); $sign = md5(http_build_query($arr) . C('GET_INFO_KEY')); $arr['sign'] = $sign; $reData = curl_post('http://oa.76ba.com/api/wanmeng/deviceTypeUpdate', $arr); } protected function addUserLoginRecord($user, $game, $clientIp, $deviceNum){ $data = [ 'user_id' => $user['id'], 'user_account' => $user['account'], 'user_nickname' => $user['nickname'], 'game_id' => $game['id'], 'promote_id' => $user['promote_id'], 'game_name' => $game['game_name'], 'sdk_version' => $game['sdk_version'], 'type' => 1, 'server_id' => null, 'server_name' => null, 'login_time' => NOW_TIME, 'login_ip' => $clientIp, 'lpuid' => $user['puid'], ]; return M('user_login_record','tab_')->add($data); } protected function addUserGameLoginRecord($user, $game, $clientIp, $deviceNum){ $data = [ 'user_id' => $user['id'], 'user_account' => $user['account'], 'user_nickname' => $user['nickname'], 'game_id' => $game['id'], 'promote_id' => $user['promote_id'], 'game_name' => $game['game_name'], 'sdk_version' => $game['sdk_version'], 'type' => 1, 'server_id' => null, 'server_name' => null, 'login_time' => NOW_TIME, 'login_ip' => $clientIp, 'lpuid' => $user['puid'], ]; return M('user_game_login_record','tab_')->add($data); } protected function dispatchLoginEvent($params) { try { $client = new TaskClient(); $client->post('/game-event/login', $params); } catch(\Exception $e) { } } protected function addUserPlay($user, $game, $clientIp) { $map = []; $map['game_id'] = $game['id']; $map['user_id'] = $user['id']; $map['sdk_version'] = $game['sdk_version']; $userPlay = M('user_play', 'tab_')->where($map)->find(); if (empty($userPlay)) { $data = []; $data['user_id'] = $user['id']; $data['user_account'] = $user['account']; $data['user_nickname'] = $user['nickname']; $data['game_id'] = $game['id']; $data['game_appid'] = $game['game_appid']; $data['game_name'] = $game['game_name']; $data['server_id'] = 0; $data['server_name'] = ''; $data['role_id'] = 0; $data['parent_id'] = $user['parent_id']; $data['parent_name'] = $user['parent_name']; $data['role_name'] = ''; $data['role_level'] = 0; $data['bind_balance'] = 0; $data['promote_id'] = $user['promote_id']; $data['promote_account'] = $user['promote_account']; $data['play_time'] = time(); $data['play_ip'] = $clientIp; $data['sdk_version'] = $game['sdk_version']; $data['ppuid'] = $user['puid'] == '' ? 0 : $user['puid']; $data['check_time'] = time(); $data['create_time'] = time(); M('user_play', 'tab_')->add($data); } } protected function getNoticeCount($user, $game) { $noticeCount = 0; $time = time(); $noticeIds = M('notice', 'tab_') ->where('start_time < ' . $time . ' AND game_id = ' . $game['id']. ' AND (end_time = 0 OR end_time >' . $time . ')') ->getField('id',true); if(!empty($noticeIds)) { $noticeCount += count($noticeIds); $where['notice_id'] = ['in', implode(',', $noticeIds)]; $where['user_id'] = $user['id']; $where['is_read'] = 1; $noticeReadCount = M('notice_read', 'tab_')->where($where)->count(); $noticeCount -= $noticeReadCount; } return $noticeCount; } protected function loginLimit($params) { $isLoginLimit = intval(C('LOGIN_LIMIT_OPEN', null, 1)); if ($isLoginLimit == 0) { return false; } $loginLimitNum = C('LOGIN_LIMIT_NUM', null, 300); $count = Redis::incr(Redis::KEY_LOGIN_LIMIT); if ($count >= $loginLimitNum) { Log::write('login_limit:' . date('Y-m-d H:i:s') . ' ---- ' . $count, 'INFO', '', C('LOG_PATH')."login_limit.log"); return true; } return false; } protected function resetLoginLimit() { $isLoginLimit = intval(C('LOGIN_LIMIT_OPEN', null, 1)); if ($isLoginLimit != 0) { Redis::decr(Redis::KEY_LOGIN_LIMIT); } } public function password($str, $key = 'ThinkUCenter'){ return '' === $str ? '' : md5(sha1($str) . $key); } }