Merge branch 'hotfix/queue_login' of wmtx/sdk into master

添加登录限制队列/角色上传异步
master
廖金灵 5 years ago committed by Gogs
commit 62ad2104fb

@ -0,0 +1,382 @@
<?php
namespace Base\Service;
/**
*
* @todo 未完成
*/
class UserService
{
public function isBan($ip, $deviceNum)
{
$ban = M('device_bans','tab_')->select(['id'])->where(['tag' => ['in', [$ip, $deviceNum]]])->limit(1)->find();
if (empty($ban)) {
return false;
}
return true;
}
public function login()
{
#获取SDK上POST方式传过来的数据 然后base64解密 然后将json字符串转化成数组
$user = json_decode(base64_decode(file_get_contents("php://input")), true);
#判断数据是否为空
if (empty($user)) {
$this -> set_message(1001, "fail", "登录数据不能为空");
}
$account = $params['account'];
$password = $params['password'];
$gameId = $params['game_id'];
$sdkVersion = $params['sdk_version'];
$deviceNum = $params['unique_code'];
$ip = get_client_ip();
if ($this->isBan($ip, $user['unique_code'])) {
$this->set_message(1004, "fail", "设备已被禁用");
}
$game = M('game', 'tab_')->where(['game_id' => $gameId])->find();
$user = M('user', 'tab_')->where(['account' => $account])->find();
if (empty($user)) {
$this->set_message(1005, "fail", "账号或密码错误");
}
$userApi = new MemberApi();
$result = $userApi->login_sdk($account, $password, 1, $gameId, $game['game_name'], $sdkVersion, $deviceNum);
$res_msg = array();
switch ($result) {
case - 1:
// $log['remarks'] = '扶持号被禁用';
// log_action($log);
$this -> set_message(1005, "fail", "密码错误");
break;
case - 2:
// $log['remarks'] = '密码错误';
// log_action($log);
$this -> set_message(1005, "fail", "密码错误");
break;
default:
if (is_array($result)) {
$user["user_id"] = $result['user_id'];
$user['puid'] = 0;
$this -> add_user_play($user);
$platform = $this -> get_platform($user['user_id']);
$small_list = $this -> small_list($user['user_id'], $user['game_id']);
$small_list[] = array('is_platform' => $platform, 'user_id' => $user['user_id'], 'account' => $user['account'], 'user_account' => $user['account']);
$user_res = M('User', 'tab_') -> where(['account' => $user['account']]) -> find();
$unread_count = 0;
$time = time();
$notice = M('notice', 'tab_')->where('start_time < ' . $time . ' AND game_id = ' . $user['game_id']. ' AND (end_time = 0 OR end_time >' . $time . ')')->getField('id',true);
if(!empty($notice))
{
$unread_count += count($notice);
$where['notice_id'] = ['in', implode(',', $notice)];
$where['user_id'] = $user['user_id'];
$where['is_read'] = 1;
$notice_read_count = M('notice_read', 'tab_')->where($where)->count();
$unread_count -= $notice_read_count;
}
$unread_count += M('share_record', 'tab_') -> where(['invite_id' => $user['user_id'], 'award_coin' => ['gt', 0], 'read' => 0]) -> count();
$unread_count += M('point_record', 'tab_') -> where(['type_id' => 6, 'user_id' => $user['user_id'], 'point' => ['gt', 0], 'read' => 0]) -> count();
$notice_count = $unread_count;
$buddies_request = get_buddies_unagree_count($user['user_id']);
$unread_count += $buddies_request;
$userToken = $result['user_token'];
$res_msg = array(
"status" => 200,
"return_code" => "success",
"return_msg" => "登录成功",
"user_id" => $user["user_id"],
"account" => $user["account"],
"nickname" => $user_res["nickname"] ? $user_res["nickname"] : $user["account"],
"sex" => $user_res["sex"] ? $user_res["sex"] : 0,
"is_platform" => $platform,
"token" => $result['token'],
"user_token" => $userToken,
"OTP_token" => think_encrypt(json_encode(array('uid' => $user["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' => $small_list,
'ios_packagename' => C('WEB_IOS_PACKAGENAME'),
'android_packagename' => C('WEB_AND_PACKAGENAME'),
'site_status' => C('SDK_SITE_STATUS'),
'head_img' => !empty($user_res['head_img']) ? $user_res['head_img'] : '',
'unread_count' => $unread_count,
'notice_count' => $notice_count,
'request_count' => $buddies_request,
);
// 通知后台 TASK_URLhttp://47.111.118.107:9501
$url = C('TASK_URL')."/game-event/login";
try {
post_async($url, [
'form_params' => [
'game_id' => $user["game_id"],
'user_id' => $user["user_id"],
'login_time' => time()
]
]);
} catch(\Exception $e) {
}
} else {
// $log['remarks'] = '未知错误';
// log_action($log);
$this -> set_message(1028, "fail", "未知错误");
}
break;
}
$log['uid'] = $user['user_id'];
// log_action($log);
echo base64_encode(json_encode($res_msg));
}
protected function doLogin($user, $game, $clientIp, $deviceNum)
{
/* 获取用户数据 */
if (empty($user) || $user['lock_status'] != 1 && $user['check_status'] != 1) {
return null;
}
if (think_ucenter_md5($password, UC_AUTH_KEY) === $user['password']) {
return null;
}
$userData = [];
if (!$user['device_number']) {
$userData['device_number'] = $deviceNum;
}
$testResource = M('test_resource','tab_')->select(['device_number'])->where("user_id=%s and apply_status=2", $user['id'])->find(); //测试资源(扶持号)
if ($testResource) {
if ($this->isDeviceError($user, $testResource, $deviceNum)) {
$userData['last_device_number'] = $deviceNum;
$userData['lock_status'] = 0 ;
$this->deviceErrorLog($user, $testResource, $deviceNum);
return null;
}
if ($this->isIpWarning($user, $testResource, $deviceNum)) {
$this->ipWarningLog($user, $testResource, $deviceNum);
}
}
$userData["id"] = $uid;
$userData["login_time"] = NOW_TIME;
$userData["login_ip"] = $clientIp;
$userData["last_login_ip"] = $clientIp;
$userData["last_device_number"] = $deviceNum;
$userData["token"] = $this->generateToken($uid,$account,$password);
$userToken = 0;
if($testResource) { //扶持号
if($user['device_number'] && $unique_code && $user['device_number'] != $unique_code){ //#当前登录设备信息与历史登录设备信息不一致,触发账户冻结
$this->sdklogin_device_error($user,$test_resource,$unique_code);
$this->sdklogin_ip_error($user,$test_resource,get_client_ip());
return -1;//扶持号被禁用
}else{
$token = $this->sdklogin_update($user,$account,$password,$user['fgame_id'],$game_id,$game_name,$unique_code,$userToken); //更新用户登录信息
$this->user_login_record2($user,$type,$game_id,$game_name,$sdk_version);
$this->sdklogin_ip_error($user,$test_resource,get_client_ip());
return array("user_id"=>$user['id'],"token"=>$token, "user_token" => $userToken); //登录成功返回用户ID
}
}else{
$token = $this->sdklogin_update($user,$account,$password,$user['fgame_id'],$game_id,$game_name,$unique_code,$userToken); //更新用户登录信息
$this->user_login_record2($user,$type,$game_id,$game_name,$sdk_version);
return array("user_id"=>$user['id'],"token"=>$token, "user_token" => $userToken); //登录成功返回用户ID
}
}
protected function isDeviceError($user, $testResource, $deviceNum)
{
if ($testResource && $user['device_number'] && $deviceNum && $user['device_number'] != $deviceNum) {
return true;
}
return false;
}
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, $testResource, $deviceNum)
{
$newResult = file_get_contents("http://ip.taobao.com/service/getIpInfo.php?ip=".$clientIp);
$oldResult = file_get_contents("http://ip.taobao.com/service/getIpInfo.php?ip=".$user['login_ip']);
$newResult = json_decode($newResult, true);
$oldResult = json_decode($oldResult, true);
if($newResult['data']['city'] != $oldResult['data']['city']) {
return true;
}
return false;
}
// 扶持号登录IP异常
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 sdklogin_update($user, $account, $password, $user_fgame_id, $game_id, $game_name, $unique_code='', &$userToken=''){
$model = M('User','tab_');
$uid = $user['id'];
$data["id"] = $uid;
$data["login_time"] = NOW_TIME;
$data["login_ip"] = get_client_ip();
// $data["device_number"] = $unique_code;
$data["last_login_ip"] = $user['login_ip'];
$data["last_device_number"] = $user['device_number'] ? $user['device_number'] : '';
$data["token"] = $this->generateToken($uid,$account,$password);
M('user_token','tab_')->startTrans();
$userToken = $this->generateToken($uid,$account,$password).uniqid().rand(1000, 9999);
$relationGameId = M('game', 'tab_')->where([
'id' => $game_id
])->getField('relation_game_id');
$userTokens = M('user_token','tab_')->where([
'user_id' => $uid,
'game_id' => $game_id
])->find();
if (!$userTokens) {
$r = M('user_token', 'tab_')->add([
'user_id' => $uid,
'game_id' => $game_id,
'relation_game_id' => $relationGameId,
'user_token' => $userToken,
'login_cnt' => 1,
'create_time' => time(),
'update_time' => time()
]);
if (!$r) {
M('user_token','tab_')->rollback();
$msg = array(
"status" => 5,
"return_code" => 5,
"return_msg" => "数据出错",
"msg" => '1'
);
echo base64_encode(json_encode($msg));
exit();
}
$r = M('user_token', 'tab_')->where([
'user_id' => $uid,
'relation_game_id' => $relationGameId
])->save([
'user_token' => $userToken,
'login_cnt' => $userTokens['login_cnt'] + 1,
'update_time' => time()
]);
if ($r === false) {
M('user_token','tab_')->rollback();
$msg = array(
"status" => 5,
"return_code" => 5,
"return_msg" => "数据出错2",
"msg" => '1'
);
echo base64_encode(json_encode($msg));
exit();
}
} else {
$r = M('user_token', 'tab_')->where([
'user_id' => $uid,
'game_id|relation_game_id' => $relationGameId
])->save([
'user_token' => $userToken,
'login_cnt' => $userTokens['login_cnt'] + 1,
'update_time' => time()
]);
if ($r === false) {
M('user_token','tab_')->rollback();
exit();
}
}
M('user_token','tab_')->commit();
if($user_fgame_id){
$model->save($data);
}else{
$data['fgame_id']=$game_id;
$data['fgame_name']=$game_name;
$model->save($data);
$device_type = M('User','tab_')->where(['id' => $user['id']])->getField('device_type');
if(empty($device_type)){
$gameServer = substr($game_name, -10, 9);
if($gameServer == '安卓版'){
$arr['device_type'] = 'Android';
} elseif($gameServer == '苹果版') {
$arr['device_type'] = 'IOS';
}
$arr['time'] = time();
$arr['account'] = $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);
}
}
return $data["token"];
}
public function saveUserGameLoginRecord($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);
}
}

@ -0,0 +1,40 @@
<?php
namespace Base\Tool;
use Redis as Handler;
class Redis
{
const KEY_LOGIN_LIMIT = 'sdk.login_limit';
private static $handler;
public static function getHandler()
{
if(self::$handler == null) {
self::$handler = self::createHandler();
}
return self::$handler;
}
private static function createHandler()
{
$host = C('REDIS_HOST', null, '127.0.0.1');
$port = C('REDIS_PORT', null, 6379);
$timeout = C('REDIS_TIMEOUT', null, 300);
$auth = C('REDIS_AUTH');
$handler = new Handler();
$handler->connect($host, $port, $timeout);
if($auth !== null) {
$handler->auth($auth);
}
return $handler;
}
public static function __callStatic($method, $arguments)
{
return call_user_func_array([self::getHandler(), $method], $arguments);
}
}

@ -0,0 +1,30 @@
<?php
namespace Base\Tool;
use GuzzleHttp\Client;
class TaskClient
{
const SUCCESS = '0000';
protected $client;
public function __construct()
{
$this->client = new Client([
'base_uri' => C('TASK_URL'),
'timeout' => 5.0,
]);
}
public function post($uri, $data)
{
$response = $this->client->post($uri, [
'verify' => false,
'form_params' => $data
]);
$result = (string)$response->getBody();
return json_decode($result, true);
}
}

@ -12,20 +12,37 @@ use App\Model\PointShopRecordModel;
use Qiniu\json_decode;
use Think\Log;
use Sdk\Model\SmsLogModel;
use Base\Tool\TaskClient;
use Base\Tool\Redis;
class UserController extends BaseController
{
public 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;
}
/**
*SDK用户登录
*/
public function user_login()
{
$count = Redis::incr(Redis::KEY_LOGIN_LIMIT);
if ($count >= 300) {
Redis::decr(Redis::KEY_LOGIN_LIMIT);
$this->set_message(1001, "fail", "登录人数过多,请稍后再试!");
}
#获取SDK上POST方式传过来的数据 然后base64解密 然后将json字符串转化成数组
$user = json_decode(base64_decode(file_get_contents("php://input")), true);
#判断数据是否为空
if (empty($user)) {
Redis::decr(Redis::KEY_LOGIN_LIMIT);
$this -> set_message(1001, "fail", "登录数据不能为空");
}
@ -35,11 +52,8 @@ class UserController extends BaseController
$log['action'] = json_encode($user); // 请求参数 */
$ip = get_client_ip();
$device_bans_ip = M('device_bans','tab_')->where(['tag' => $ip,'type' => 2])->find();
$device_bans_num = M('device_bans','tab_')->where(['tag' => $user['unique_code'],'type' => 1])->find();
if(!empty($device_bans_ip) || !empty($device_bans_num)){
/* $log['remarks'] = '设备已被禁用';
log_action($log); */
if ($this->isBan($ip, $user['unique_code'])) {
Redis::decr(Redis::KEY_LOGIN_LIMIT);
$this->set_message(1004, "fail", "设备已被禁用");
}
@ -60,11 +74,13 @@ class UserController extends BaseController
case - 1:
// $log['remarks'] = '用户不存在或被禁用';
// log_action($log);
Redis::decr(Redis::KEY_LOGIN_LIMIT);
$this -> set_message(1004, "fail", "用户不存在或被禁用");
break;
case - 2:
// $log['remarks'] = '密码错误';
// log_action($log);
Redis::decr(Redis::KEY_LOGIN_LIMIT);
$this -> set_message(1005, "fail", "密码错误");
break;
default:
@ -107,11 +123,13 @@ class UserController extends BaseController
} else {
// $log['remarks'] = '未知错误';
// log_action($log);
Redis::decr(Redis::KEY_LOGIN_LIMIT);
$this -> set_message(1028, "fail", "未知错误");
}
break;
}
// log_action($log);
Redis::decr(Redis::KEY_LOGIN_LIMIT);
echo base64_encode(json_encode($res_msg));
die;
@ -297,6 +315,7 @@ class UserController extends BaseController
//登录失败
}
}
#实例化用户接口
$userApi = new MemberApi();
$result = $userApi -> login_sdk($user["account"], $user['password'], 1, $user["game_id"], get_game_name($user["game_id"]), $user['sdk_version'],$user['unique_code']);#调用登录
@ -306,11 +325,13 @@ class UserController extends BaseController
case - 1:
// $log['remarks'] = '扶持号被禁用';
// log_action($log);
Redis::decr(Redis::KEY_LOGIN_LIMIT);
$this -> set_message(1005, "fail", "密码错误");
break;
case - 2:
// $log['remarks'] = '密码错误';
// log_action($log);
Redis::decr(Redis::KEY_LOGIN_LIMIT);
$this -> set_message(1005, "fail", "密码错误");
break;
default:
@ -441,12 +462,15 @@ class UserController extends BaseController
} else {
// $log['remarks'] = '未知错误';
// log_action($log);
Redis::decr(Redis::KEY_LOGIN_LIMIT);
$this -> set_message(1028, "fail", "未知错误");
}
break;
}
Redis::decr(Redis::KEY_LOGIN_LIMIT);
$log['uid'] = $user['user_id'];
// log_action($log);
echo base64_encode(json_encode($res_msg));
@ -1374,13 +1398,41 @@ class UserController extends BaseController
}
public function save_user_play_info()
{
$request = json_decode(base64_decode(file_get_contents("php://input")), true);
if (empty($request)) {
$this->set_message(1001, "fail", "操作数据不能为空");
}
$params = [
'user_id' => $request['user_id'],
'game_id' => $request['game_id'],
'server_id' => $request['server_id'],
'game_player_id' => $request['game_player_id'],
'server_name' => $request['server_name'],
'game_player_name' => $$request['game_player_name'],
'role_level' => $request['role_level'],
'sdk_version' => $request['sdk_version'],
'time' => time(),
'client_ip' => get_client_ip()
];
try {
$taskClient = new TaskClient();
$taskClient->post('/game-event/save-role', $params);
} catch (\Exception $e) {
$this->set_message(1001, "fail", "上报数据异常");
}
$this->set_message(200, "success", "成功");
}
/**
* 添加游戏角色数据
*
* @param $request
*/
public function save_user_play_info()
public function save_user_play_info_old()
{
$request = json_decode(base64_decode(file_get_contents("php://input")), true);

Loading…
Cancel
Save