* @version : HUOSDK 8.5 */ namespace huoIdentify\controller; use huo\controller\common\CommonFunc; use huo\model\game\GameModel; use huo\model\member\MemberModel; use huoIdentify\logic\IdentifyDayDotLogic; use huoIdentify\logic\IdentifyDayIdotLogic; use huoIdentify\logic\IdentifyDayMotLogic; use huoIdentify\logic\IdentifyDotLogic; use huoIdentify\logic\IdentifyIdotLogic; use huoIdentify\logic\IdentifyMotLogic; use huoIdentify\model\IdentifyMemModel; use huolib\constant\CommonConst; use huolib\constant\GameConst; use huolib\constant\IdentifyConst; use huolib\constant\MemConst; use huolib\status\CommonStatus; use huolib\status\MemberStatus; use huolib\tool\StrUtils; use huolib\utils\IdentifyUtils; use think\Cookie; class Online { protected $app_id = 0; //当前游戏id protected $mem_id = 0; //当前玩家id protected $device_id = ''; //当前设备id protected $id_card = ''; //当前证件号 protected $return_url = ''; //要返回的url protected $identify_conf = []; //实名认证配置 protected $token = ''; //请求token public function __construct($app_id, $mem_id, $device_id) { $this->setAppId($app_id); $this->setMemId($mem_id); $this->setDeviceId($device_id); $this->setIdCard(); $this->identify_conf = (new IdentifyConf())->getConf(); } /** * 在线 * * @return string $url 实名认证地址或提示信息地址 */ public function heartOnline() { $app_id = $this->getAppId(); $_game_auth = (new GameModel())->getIsAuthById($app_id); /* 不需要实名不做任何处理 */ if (GameConst::GAME_IDENTIFY_IS_NO == $_game_auth) { return $this->return_url; } /* 统计时长 */ $this->updateOnlineTime(); /* 校验是否限制 */ $this->checkLimit(); return $this->return_url; } /*** * 实名校验和未成年校验,未通过校验的需要退出登陆 */ public function nonageCheck() { $_app_id = $this->getAppId(); $_game_auth = (new GameModel())->getIsAuthById($this->getAppId()); /* 不需要实名不做任何处理 */ if (GameConst::GAME_IDENTIFY_IS_NO == $_game_auth) { $_code = CommonStatus::NO_ERROR; return ['code' => $_code, 'msg' => CommonStatus::getMsg($_code)]; } $_id_card = $this->getIdCard(); /* 已实名 */ if (!empty($_id_card)) { $_age = IdentifyUtils::getAgeById($_id_card); // 成年玩家不限制 if ($_age >= 18) { $_code = CommonStatus::NO_ERROR; return ['code' => $_code, 'msg' => CommonStatus::getMsg($_code)]; } // 校验未成年玩家限制 $_url = $this->checkUnderageLimitOnTheHour(); $_code = MemberStatus::NO_ERROR; $_data = []; if (!empty($_url)) { $_code = MemberStatus::LOGIN_IS_OUT; $_data['url'] = $_url; } return ['code' => $_code, 'msg' => MemberStatus::getMsg($_code), 'data' => $_data]; } $_code = CommonStatus::NO_ERROR; return ['code' => $_code, 'msg' => CommonStatus::getMsg($_code)]; } /** * 获取剩余体验时长和绑定手机url */ public function getTimeLeft() { $_rdata = [ 'time_left' => CommonConst::CONST_ZERO, 'bind_url' => '' ]; $_game_auth = (new GameModel())->getIsAuthById($this->app_id); /* 不需要实名不做任何处理 */ if (GameConst::GAME_IDENTIFY_IS_NO == $_game_auth) { return $_rdata; } if (empty($this->mem_id)) { /* 未登录返回空 */ return $_rdata; } $_mem_model = new MemberModel(); $_status = $_mem_model->getStatus($this->mem_id); if (MemConst::STATUS_TRY != $_status) { /* 非试玩玩家不需要提示绑定手机 */ return $_rdata; } $_mobile = $_mem_model->getMobileById($this->mem_id); if (!empty($_mobile)) { /* 已绑定手机返回空 */ return $_rdata; } $_param = [ 'app_id' => $this->app_id, 'device_id' => $this->device_id, 'token' => $this->getToken() ]; $_rdata = [ 'time_left' => CommonConst::CONST_ZERO, 'bind_url' => IdentifyConst::getBindMobileUrl($_param) ]; $_unnamed_limit = $this->identify_conf['unnamed']['limit_time']; //后台配置未实名试玩时长 $_now_online_time = 0; $_mot_logic = new IdentifyMotLogic(); $_mot_data = $_mot_logic->getInfoByMemId($this->mem_id); $_online_time = get_val($_mot_data, 'online_duration', CommonConst::CONST_ZERO); if ($_online_time >= $_now_online_time) { $_now_online_time = $_online_time; } if (!empty($this->device_id)) { $_dot_logic = new IdentifyDotLogic(); $_dot_data = $_dot_logic->getInfoByDevice($this->device_id); $_online_time = get_val($_dot_data, 'online_duration', CommonConst::CONST_ZERO); if ($_online_time >= $_now_online_time) { $_now_online_time = $_online_time; } } $_diff_time = $_unnamed_limit - $_now_online_time; if ($_diff_time > CommonConst::CONST_ZERO) { $_rdata['time_left'] = ceil($_diff_time / CommonConst::CONST_MINUTE_SECONDS); } return $_rdata; } /** * 校验是否登陆或需要实名处理 */ public function checkLimit() { $_id_card = $this->getIdCard(); /* 已实名 */ if (!empty($_id_card)) { $_age = IdentifyUtils::getAgeById($_id_card); // 成年玩家不限制 if ($_age >= 18) { return ''; } // 校验未成年玩家限制 return $this->checkUnderageLimit(); } /* Modified by chenbingling BEGIN 2021/9/3 ISSUES:#15622 产品需求 心跳查询实名认证信息,有认证中数据不弹窗,并提交实名信息到cp*/ /* 查询游实名认证中的数据则不弹窗 */ $_identify_class = new Identify(); $_in_progress_data = $_identify_class->getInProgressDataByMemApp($this->mem_id, $this->app_id); if (!empty($_in_progress_data)) { $_real_name = get_val($_in_progress_data, 'real_name', ''); $_id_card = get_val($_in_progress_data, 'id_card', ''); $_identify_class->updateIdentify($this->mem_id, 1, $_real_name, $_id_card, $this->app_id); return ''; } /* END 2021/9/3 ISSUES:#15622 */ /* 校验未实名限制 */ // 校验设备限制 $this->checkDeviceLimit(); if (!empty($this->return_url)) { return $this->return_url; } // 校验玩家限制 $this->checkMemLimit(); if (!empty($this->return_url)) { return $this->return_url; } return $this->return_url; } /** * 校验设备限制 */ public function checkDeviceLimit() { $_app_id = $this->app_id; $_device_id = $this->device_id; $_mem_id = $this->mem_id; if (!empty($_device_id)) { $_dot_logic = new IdentifyDotLogic(); $_dot_data = $_dot_logic->getInfoByDevice($_device_id); $_now_time = time(); /* 在线时长 */ $_online_time = get_val($_dot_data, 'online_duration', CommonConst::CONST_ZERO); $_limit_day = $this->identify_conf['unnamed']['expired_day']; //后台配置下次可玩间隔15天 $_unnamed_limit = $this->identify_conf['unnamed']['limit_time']; //后台配置未实名试玩时长 if (($_online_time >= $_unnamed_limit) || ($_dot_data['next_allow_time'] > $_now_time)) { /* 达到限制时长或者在限制登陆期间返回实名验证url */ $_param = [ 'app_id' => $_app_id, 'device_id' => $_device_id, 'token' => $this->getToken() ]; $_identify_url = IdentifyConst::getIdentifyUrl($_param); if (!empty($_mem_id)) { /* 获取玩家是否已绑定手机 */ $_mem_model = new MemberModel(); $_mobile = $_mem_model->getMobileById($_mem_id); $_status = $_mem_model->getStatus($_mem_id); if (empty($_mobile) && MemConst::STATUS_TRY == $_status) { /* 试玩账号没有绑定手机才需要弹窗 */ $_identify_url = IdentifyConst::getBindMobileUrl($_param); } } $this->return_url = $_identify_url; /* 设置下次可访问时间 */ if (empty($_dot_data['next_allow_time'])) { $_dot_data['next_allow_time'] = $_now_time + ($_limit_day * CommonConst::CONST_DAY_SECONDS); $_dot_logic->updateByDevice($_dot_data, $_device_id); } /* 若调整了限制时间,则重置下次可访问时间 */ if ($_unnamed_limit > $_online_time) { $_dot_data['next_allow_time'] = CommonConst::CONST_ZERO; $_dot_logic->updateByDevice($_dot_data, $_device_id); $this->return_url = ''; } /* 若达到下次可访问时间,则重置在线时长和下次可访问时间 */ if (!empty($_dot_data['next_allow_time']) && $_dot_data['next_allow_time'] <= $_now_time) { $_dot_data['online_duration'] = CommonConst::CONST_ZERO; $_dot_data['next_allow_time'] = CommonConst::CONST_ZERO; $_dot_logic->updateByDevice($_dot_data, $_device_id); $this->return_url = ''; } } } return $this->return_url; } /** * 校验玩家限制 */ public function checkMemLimit() { $_mem_id = $this->mem_id; $_app_id = $this->app_id; $_device_id = $this->device_id; if (!empty($_mem_id)) { $_mot_logic = new IdentifyMotLogic(); $_mot_data = $_mot_logic->getInfoByMemId($_mem_id); $_now_time = time(); /* 在线时长 */ $_online_time = get_val($_mot_data, 'online_duration', CommonConst::CONST_ZERO); $_limit_day = $this->identify_conf['unnamed']['expired_day']; //后台配置下次可玩间隔15天 $_unnamed_limit = $this->identify_conf['unnamed']['limit_time']; //后台配置未实名试玩时长 if (($_online_time >= $_unnamed_limit) || ($_mot_data['next_allow_time'] > $_now_time)) { /* 达到限制时长或者在限制登陆期间返回实名验证url */ $_param = [ 'app_id' => $_app_id, 'device_id' => $_device_id, 'token' => session_id() ]; $_identify_url = IdentifyConst::getIdentifyUrl($_param); if (!empty($_mem_id)) { /* 获取玩家是否已绑定手机 */ $_mem_model = new MemberModel(); $_mobile = $_mem_model->getMobileById($_mem_id); if (empty($_mobile)) { $_identify_url = IdentifyConst::getBindMobileUrl($_param); } } $this->return_url = $_identify_url; /* 设置下次可访问时间 */ if (empty($_mot_data['next_allow_time'])) { $_mot_data['next_allow_time'] = $_now_time + ($_limit_day * CommonConst::CONST_DAY_SECONDS); $_mot_logic->updateByMemId($_mot_data, $_mem_id); } /* 若调整了限制时间,则重置下次可访问时间 */ if ($_unnamed_limit > $_online_time) { $_mot_data['next_allow_time'] = CommonConst::CONST_ZERO; $_mot_logic->updateByMemId($_mot_data, $_mem_id); $this->return_url = ''; } /* 若达到下次可访问时间,则重置在线时长和下次可访问时间 */ if (!empty($_mot_data['next_allow_time']) && $_mot_data['next_allow_time'] <= $_now_time) { $_mot_data['online_duration'] = CommonConst::CONST_ZERO; $_mot_data['next_allow_time'] = CommonConst::CONST_ZERO; $_mot_logic->updateByMemId($_mot_data, $_mem_id); $this->return_url = ''; } } } return $this->return_url; } /** * 校验未成年玩家限制--新版本 未成年用户仅限在周五、周六、周日及法定节假日每日20:00-21:00登录游戏 */ public function checkUnderageLimit() { $_now_time = time(); $_is_allow_login = (new HolidaySet())->isAllowLogin(); if (true === $_is_allow_login) { /* 允许登陆的日子,需判断是否在允许登陆的时间 每日 20:00 - 21:00 */ $_allow_start_time = $this->identify_conf['underage']['allow_start_time']; //后台配置获取,今日允许登陆开始时间 $_allow_start_time_minute = $this->identify_conf['underage']['allow_start_time_minute']; //后台配置获取,今日允许登陆开始时间 $_allow_end_time = $this->identify_conf['underage']['allow_end_time']; //后台配置获取,今日允许登陆结束时间 $_allow_end_time_minute = $this->identify_conf['underage']['allow_end_time_minute']; //后台配置获取,今日允许登陆结束时间 $_allow_start_time = mktime( $_allow_start_time, $_allow_start_time_minute, 0, date('m'), date('d'), date('Y') ); $_allow_end_time = mktime($_allow_end_time, $_allow_end_time_minute, 0, date('m'), date('d'), date('Y')); $_allow_end_time -= CommonFunc::getHeartbeatTime(); /* 减去心跳间隔时间 */ if ($_now_time > $_allow_start_time && $_now_time < $_allow_end_time) { return ''; } } $_type = IdentifyConst::UNDERAGE_ALLOW_LOGIN_LIMIT; $_param = [ 'app_id' => $this->app_id, 'token' => $this->getToken() ]; $this->return_url = IdentifyConst::getUnderageLimitMsgUrl($_type, $_param); return $this->return_url; } /** * 校验未成年玩家限制--新版本 未成年用户仅限在周五、周六、周日及法定节假日每日20:00-21:00登录游戏 */ public function checkUnderageLimitOnTheHour() { $_now_time = time(); $_is_allow_login = (new HolidaySet())->isAllowLogin(); if (true === $_is_allow_login) { /* 允许登陆的日子,需判断是否在允许登陆的时间 每日 20:00 - 21:00 */ $_allow_start_time = $this->identify_conf['underage']['allow_start_time']; //后台配置获取,今日允许登陆开始时间 $_allow_start_time_minute = $this->identify_conf['underage']['allow_start_time_minute']; //后台配置获取,今日允许登陆开始时间 $_allow_end_time = $this->identify_conf['underage']['allow_end_time']; //后台配置获取,今日允许登陆结束时间 $_allow_end_time_minute = $this->identify_conf['underage']['allow_end_time_minute']; //后台配置获取,今日允许登陆结束时间 $_allow_start_time = mktime( $_allow_start_time, $_allow_start_time_minute, 0, date('m'), date('d'), date('Y') ); $_allow_end_time = mktime($_allow_end_time, $_allow_end_time_minute, 0, date('m'), date('d'), date('Y')); if ($_now_time > $_allow_start_time && $_now_time < $_allow_end_time) { return ''; } } $_type = IdentifyConst::UNDERAGE_ALLOW_LOGIN_LIMIT; $_param = [ 'app_id' => $this->app_id, 'token' => $this->getToken() ]; $this->return_url = IdentifyConst::getUnderageLimitMsgUrl($_type, $_param); return $this->return_url; } /*** * 统计时长 */ public function updateOnlineTime() { $_app_id = $this->app_id; $_mem_id = $this->mem_id; $_id_card = $this->id_card; $_device_id = $this->device_id; $_heartbeat_time = CommonFunc::getHeartbeatTime(); //系统设置心跳间隔,一个心跳时长 $_now_time = time(); $_heart_time_cache = HeartTimeCache::ins(); $_last_heart_time = $_heart_time_cache->getLastHeartTime($_app_id, $_mem_id, $_device_id); $_heart_time_cache->setLastHeartTime($_now_time, $_app_id, $_mem_id, $_device_id); $_diff_time = $_now_time - $_last_heart_time; if ($_diff_time > ($_heartbeat_time + 10)) { /* 心跳间隔超过一个心跳时长认为是重新登陆的不增加统计时长 */ return; } /*统计实名认证信息时长*/ if (!empty($_id_card)) { (new IdentifyDayIdotLogic())->updateOnlineTimeByIdCard($_heartbeat_time, $_id_card, $_mem_id); (new IdentifyIdotLogic())->updateOnlineTimeByIdCard($_heartbeat_time, $_id_card); } /* 统计设备时长 */ if (!empty($_device_id)) { (new IdentifyDayDotLogic())->updateOnlineTimeByDevice($_heartbeat_time, $_device_id, $_mem_id); if (empty($_id_card)) { /* 只有未实名的才需要累计设备时长 */ (new IdentifyDotLogic())->updateOnlineTimeByDevice($_heartbeat_time, $_device_id); } } /* 统计玩家每日时长 */ if (!empty($_mem_id)) { (new IdentifyDayMotLogic())->updateOnlineTimeByMemId($_heartbeat_time, $_mem_id); if (empty($_id_card)) { /* 只有未实名的才需要累计玩家时长 */ (new IdentifyMotLogic())->updateOnlineTimeByMemId($_heartbeat_time, $_mem_id); } } } /** * 获取实名认证url */ public function getIdentifyUrl() { $_app_id = $this->app_id; $_id_card = $this->id_card; $_device_id = $this->device_id; if (!empty($_id_card)) { return ''; } $_mem_status = (new MemberModel())->getStatus($this->mem_id); if (MemConst::STATUS_TRY == $_mem_status) { /* 试玩用户不需要弹出实名 */ return ''; } $_param = [ 'app_id' => $_app_id, 'device_id' => $_device_id, 'token' => $this->getToken() ]; $_identify_url = IdentifyConst::getIdentifyUrl($_param); return $_identify_url; } /** * @return int */ public function getAppId() { return $this->app_id; } /** * @param int $app_id */ public function setAppId($app_id) { $this->app_id = $app_id; } /** * @return int */ public function getMemId() { return $this->mem_id; } /** * @param int $mem_id */ public function setMemId($mem_id) { $this->mem_id = $mem_id; } /** * @return string */ public function getDeviceId() { return $this->device_id; } /** * @param string $device_id */ public function setDeviceId($device_id) { if (empty($device_id)) { $device_id = $this->getHuoDeviceIdFromCookie(); } $this->device_id = $device_id; } /** * @return string */ public function getIdCard() { return $this->id_card; } /** * @param string $id_card */ public function setIdCard($id_card = '') { if (empty($id_card) && !empty($this->mem_id)) { $id_card = (new IdentifyMemModel())->getIdCardByMemId($this->mem_id); } $this->id_card = $id_card; } /** * 从cookie获取一个自定义device_id */ public function getHuoDeviceIdFromCookie() { $_device_id = $this->getSdkDeviceId(); if (empty($_device_id)) { $_device_id = StrUtils::genOrderId(0, 0, $this->mem_id, 'huoh5'); $this->setSdkDeviceId($_device_id); } return $_device_id; } /** * 设置永久标识作为 device_id * * @param string $device_id */ public function setSdkDeviceId($device_id) { /* 过期时间设为100年 */ $_expire = mktime(0, 0, 0, 1, 1, 2119); Cookie::set('HuoSdkDeviceId', $device_id, $_expire); } /** * 获取永久biaos */ public function getSdkDeviceId() { return Cookie::get('HuoSdkDeviceId'); } /** * @return string */ public function getToken() { if (empty($this->token)) { return session_id(); } return $this->token; } /** * @param string $token */ public function setToken($token) { $this->token = $token; } }