* @version : HUOSDK 8.0 */ namespace huo\controller\pay; use huo\controller\common\Base; use huo\controller\game\Game; use huo\controller\game\GamePaySwitchCache; use huo\controller\member\MemCache; use huo\controller\request\Channel; use huo\controller\request\Device; use huo\controller\request\Game as GameRq; use huo\controller\request\Mem; use huo\controller\request\Order as OrderRq; use huo\controller\request\Role; use huo\logic\order\OrderLogic; use huo\model\game\GameServerSwitchModel; use huo\model\game\PsMemWhiteModel; use huo\model\member\MgRoleModel; use huolib\constant\GameConst; use huolib\constant\OrderConst; use huolib\tool\Ip; class PaySwitch extends Base { /** * 判断支付切换 * * @param OrderRq $order * @param Role $role * @param Mem $mem * @param GameRq $game_rq * @param Channel $channel * @param Device $device * * @return int PAY_SWITCH_YES 1 切换 PAY_SWITCH_NO 2 不切换 */ public function getPaySwitch(OrderRq $order, Role $role, Mem $mem, GameRq $game_rq, Channel $channel, Device $device ) { $_from = $device->getFrom(); $_vb_id = $game_rq->getVbId(); if (GameConst::GAME_IOS_SWITCH != $_from && GameConst::GAME_MP != $_from && empty($_vb_id)) { return OrderConst::PAY_SWITCH_NO; } /* 查询游戏是否是切换 */ $_app_id = $game_rq->getHAppId(); $_switch_rule_app_id = $_app_id; $_game_class = new Game(); /* 使用马甲包的规则 */ if (!empty($_vb_id)) { $_switch_rule_app_id = $_vb_id; } $_pay_switch = $_game_class->getPaySwitchStatus($_switch_rule_app_id); if (OrderConst::PAY_SWITCH_NO == $_pay_switch) { return OrderConst::PAY_SWITCH_NO; } /* 获取切换规则 */ $_switch_rule = GamePaySwitchCache::ins()->getInfoByAppId($_switch_rule_app_id); if (empty($_switch_rule)) { /* 规则为空时直接返回切换状态 */ return $_pay_switch; } /* 判断玩家是否在白名单 */ $_rs = $this->inMemWhite($_switch_rule_app_id, $mem->getMemId()); if (true == $_rs) { /* IP白名单内的直接返回切换状态 */ return $_pay_switch; } /* 判断IP是否在白名单 */ $_rs = $this->inIpWhite($device->getIp(), $_switch_rule['ip_white']); if (true == $_rs) { /* IP白名单内的直接返回切换状态 */ return $_pay_switch; } /* 判断城市是否切换 */ $_rs = $this->inArea($device->getIp(), $_switch_rule['area']); if (OrderConst::PAY_SWITCH_NO == $_rs) { $_mem_ext_info = MemCache::ins()->getMeInfoById($mem->getMemId()); /* 已充值6元以上的用户不受地区切换限制 */ if (empty($_mem_ext_info['sum_money']) || 6 >= $_mem_ext_info['sum_money']) { return OrderConst::PAY_SWITCH_NO; } } $_client_id = $game_rq->getHVer(); /* 判断版本是否切换 */ $_rs = $this->switchVersion($_client_id, $_switch_rule['no_switch_version']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } /* 根据时间判断是否是否切换 */ $_rs = $this->switchTime($_switch_rule['start_time'], $_switch_rule['end_time']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } /* 根据IP段判断是否切换 */ $_rs = $this->switchIp($device->getIp(), $_switch_rule['is_domestic'], $_switch_rule['is_overseas']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } /* Modified by chenbingling BEGIN 2020/12/30 ISSUES:#13939 产品需求 IOS不判断首充 */ $_os = $device->getOs(); if (false !== strpos(strtolower($_os), 'android')) { /* 根据首充是否切换 */ $_rs = $this->switchFirst($mem->getMemId(), $_app_id, $_switch_rule['is_first']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } } /* END 2020/12/30 ISSUES:#13939 */ /* 根据金额是否切换 */ $_rs = $this->switchMoney($order->getProductRealPrice(), $_switch_rule['price']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } /* 判断版本是否切换 */ $_rs = $this->switchOs($_os, $_switch_rule['system']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } /* 判断区服是否切换 */ $_rs = $this->switchSever($_app_id, $role->getServerId()); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } /* 判断战力是否切换 */ if (empty($_switch_rule['combat_num_mini']) && empty($_switch_rule['combat_num_max'])) { /* 未填写表示不启用功能,返回切换 */ return OrderConst::PAY_SWITCH_YES; } $_combat_num = $role->getCombatNum(); if (empty($_combat_num)) { $_data = (new MgRoleModel())->getDetailByMemGameServerRole( $mem->getMgMemId(), $_app_id, $role->getServerId(), $role->getRoleId() ); $_combat_num = empty($_data['combat_num']) ? 0 : $_data['combat_num']; } $_rs = $this->switchCombat($_combat_num, $_switch_rule['combat_num_mini'], $_switch_rule['combat_num_max']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } return OrderConst::PAY_SWITCH_YES; } /** * 判断切换 * * @param GameRq $game_rq * @param Device $device * * @return int PAY_SWITCH_YES 1 切换 PAY_SWITCH_NO 2 不切换 */ public function getSwitch(GameRq $game_rq, Device $device) { /* 查询游戏是否是切换 */ $_app_id = $game_rq->getHAppId(); $_pay_switch = (new Game())->getPaySwitchStatus($_app_id); if (OrderConst::PAY_SWITCH_NO == $_pay_switch) { return OrderConst::PAY_SWITCH_NO; } /* 获取切换规则 */ $_switch_rule = GamePaySwitchCache::ins()->getInfoByAppId($_app_id); if (empty($_switch_rule)) { /* 规则为空时直接返回切换状态 */ return $_pay_switch; } /* 判断IP是否在白名单 */ $_rs = $this->inIpWhite($device->getIp(), $_switch_rule['ip_white']); if (true == $_rs) { /* IP白名单内的直接返回切换状态 */ return $_pay_switch; } /* 判断城市是否切换 */ $_rs = $this->inArea($device->getIp(), $_switch_rule['area']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } $_client_id = $game_rq->getHVer(); /* 判断版本是否切换 */ $_rs = $this->switchVersion($_client_id, $_switch_rule['no_switch_version']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } /* 根据时间判断是否是否切换 */ $_rs = $this->switchTime($_switch_rule['start_time'], $_switch_rule['end_time']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } /* 根据IP段判断是否切换 */ $_rs = $this->switchIp($device->getIp(), $_switch_rule['is_domestic'], $_switch_rule['is_overseas']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } $_os = $device->getOs(); /* 判断版本是否切换 */ $_rs = $this->switchOs($_os, $_switch_rule['system']); if (OrderConst::PAY_SWITCH_NO == $_rs) { return OrderConst::PAY_SWITCH_NO; } return OrderConst::PAY_SWITCH_YES; } /** * 判断是否在IP白名单 * * @param string $ip 当前ip * @param string $area 不切换的城市名 * * @return int */ public function inArea($ip, $area) { if (empty($area)) { /* 没城市则返回切换 */ return OrderConst::PAY_SWITCH_YES; } $_area_array = explode('|', $area); if (empty($_area_array)) { return OrderConst::PAY_SWITCH_YES; } $_ip_arr = Ip::find($ip); if (empty($_ip_arr)) { /* 未知IP不切换 */ return OrderConst::PAY_SWITCH_NO; } if (in_array($_ip_arr[2], $_area_array)) { /* 如果城市名在不切换城市 */ return OrderConst::PAY_SWITCH_NO; } return OrderConst::PAY_SWITCH_YES; } /** * 判断是否在玩家白名单 * * @param int $app_id 游戏id * @param int $mem_id 当前mem_id * * @return bool */ public function inMemWhite($app_id, $mem_id) { $_data = (new PsMemWhiteModel())->getInfo($app_id, $mem_id); if (!empty($_data)) { return true; } return false; } /** * 判断是否在IP白名单 * * @param string $ip 当前ip * @param string $ip_white ip白名单字符串 * * @return bool */ public function inIpWhite($ip, $ip_white) { if (empty($ip_white)) { /* 没白名单则返回跳过 */ return false; } $_ip_array = explode('|', $ip_white); if (empty($_ip_array)) { return false; } if (in_array($ip, $_ip_array)) { return true; } return false; } /** * 判断战力是否切换 * * @param int $combat_num 角色战力 * @param int $combat_num_mini 战力区间小值 * @param int $combat_num_max 战力区间大值 * * @return int */ public function switchCombat($combat_num, $combat_num_mini, $combat_num_max) { if (empty($combat_num)) { /* 没有战力表示 不切换 */ return OrderConst::PAY_SWITCH_NO; } if ($combat_num_mini < $combat_num && $combat_num < $combat_num_max) { /* 战力区间内表示切换*/ return OrderConst::PAY_SWITCH_YES; } return OrderConst::PAY_SWITCH_NO; } /** * 判断区服是否切换 * * @param int $app_id 游戏id * @param int $sever_id 区服id * * @return int */ public function switchSever($app_id, $sever_id) { /* 传入空值则全部切换 */ if (empty($app_id) || empty($sever_id)) { return OrderConst::PAY_SWITCH_YES; } $_data = (new GameServerSwitchModel())->getInfo($app_id, $sever_id); if (empty($_data)) { /* 不存在区服信息则不切换 */ return OrderConst::PAY_SWITCH_YES; } return $_data['is_switch']; } /** * 判断版本号是否切换 * * @param int $client_id 版本ID * @param string $rule_clients 不切换的版本 * * @return int PAY_SWITCH_YES 1 切换 PAY_SWITCH_NO 2 不切换 */ public function switchVersion($client_id = 0, $rule_clients = '') { if (empty($rule_clients) || empty($client_id)) { /* 没有设置不切换版本 全部切换 */ return OrderConst::PAY_SWITCH_YES; } $_rule_clients = trim($rule_clients, ','); if ($client_id == $_rule_clients) { /* 当前版本等于不切换版本 不切换 */ return OrderConst::PAY_SWITCH_NO; } if (false == strpos($rule_clients, ',')) { $_rule_clients_arr = explode(',', $_rule_clients); if (is_array($_rule_clients_arr) && in_array($client_id, $_rule_clients_arr)) { /* 当前版本在不切换版本内 不切换 */ return OrderConst::PAY_SWITCH_NO; } } return OrderConst::PAY_SWITCH_YES; } /** * 判断操作系统是否切换 * * @param string $os 操作系统 * @param string $rule_os 切换的操作系统 * * @return int PAY_SWITCH_YES 1 切换 PAY_SWITCH_NO 2 不切换 PAY_SWITCH_IOS_NO 3 IOS不切换关闭 */ public function switchOs($os = '', $rule_os = '') { if (empty($rule_os) || empty($os)) { /* 没有设置不切换版本 全部切换 */ return OrderConst::PAY_SWITCH_YES; } if (false !== strpos(strtolower($os), 'ios') && false !== strpos($rule_os, strval(GameConst::GAME_IOS))) { /* 设置切换IOS */ return OrderConst::PAY_SWITCH_YES; } elseif (false !== strpos(strtolower($os), 'android') && false !== strpos($rule_os, strval(GameConst::GAME_ANDROID))) { /* 设置切换安卓 */ return OrderConst::PAY_SWITCH_YES; } /* IOS 不切换 关闭支付 米大师目前不支持IOS支付,故关闭,后续开发需删除当前代码 chenbingling 20181207 _start*/ if (false !== strpos(strtolower($os), 'ios')) { return OrderConst::PAY_SWITCH_IOS_NO; } /* IOS 不切换 关闭支付 米大师目前不支持IOS支付,故关闭,后续开发需删除当前代码 chenbingling 20181207 _end*/ return OrderConst::PAY_SWITCH_NO; } /** * 判断是否在时间范围内 * * @param String $start_time * @param INT $end_time * * @return int PAY_SWITCH_YES 1 切换 PAY_SWITCH_NO 2 不切换 */ public function switchTime($start_time, $end_time) { if (empty($start_time)) { $start_time = '00:00:00'; } if (empty($end_time)) { $end_time = '23:59:59'; } if ($end_time == '00:00:00') { $end_time = '23:59:59'; } if ($start_time == $end_time) { $start_time = '00:00:00'; $end_time = '23:59:59'; } $_time = time(); $_start_time = strtotime(date('Y-m-d').' '.$start_time); $_end_time = strtotime(date('Y-m-d').' '.$end_time); if ($_time < $_start_time || $_time > $_end_time) { return OrderConst::PAY_SWITCH_NO; } return OrderConst::PAY_SWITCH_YES; } /** * 判断IP是否是国内IP * * @param string $ip IP地址 * @param int $is_domestic 国内是否切换 1切换 2不切换 * @param int $is_overseas 国外是否切换 1切换 2不切换 * * @return int PAY_SWITCH_YES 1 切换 PAY_SWITCH_NO 2 不切换 */ public function switchIp($ip, $is_domestic, $is_overseas) { if (empty($is_domestic) && empty($is_overseas)) { return OrderConst::PAY_SWITCH_YES; } if (OrderConst::PAY_SWITCH_YES == $is_domestic && OrderConst::PAY_SWITCH_YES == $is_overseas) { return OrderConst::PAY_SWITCH_YES; } $_ip_arr = Ip::find($ip); if (empty($_ip_arr)) { /* 未知IP不切换 */ return OrderConst::PAY_SWITCH_NO; } /* 根据统计需要,港澳台地区放入海外处理 */ $_domestic_except = array('台湾', '香港', '澳门'); $_ip_is_domestic = false; if (is_array($_ip_arr) && '中国' == $_ip_arr[0]) { $_ip_is_domestic = true; if (!empty($_ip_arr[1]) && in_array($_ip_arr[1], $_domestic_except)) { $_ip_is_domestic = false; } } if (true == $_ip_is_domestic && OrderConst::PAY_SWITCH_NO == $is_domestic) { return OrderConst::PAY_SWITCH_NO; } if (false == $_ip_is_domestic && OrderConst::PAY_SWITCH_NO == $is_overseas) { return OrderConst::PAY_SWITCH_NO; } return OrderConst::PAY_SWITCH_YES; } /** * 判断首充是否切换 * * @param INT $mem_id 玩家ID * @param INT $app_id 游戏ID * @param INT $is_first 是否首冲不切换 1切换 2不切换 * * @return int PAY_SWITCH_YES 1 切换 PAY_SWITCH_NO 2 不切换 */ public function switchFirst($mem_id, $app_id, $is_first) { if (OrderConst::PAY_IS_FIRST != $is_first) { return OrderConst::PAY_SWITCH_YES; } $_map = [ 'app_id' => $app_id, 'mem_id' => $mem_id, 'status' => OrderConst::PAY_STATUS_SUC ]; $_rs = (new OrderLogic())->isFirstCharge($_map); if (true == $_rs) { /* 首充 不切换 */ return OrderConst::PAY_SWITCH_NO; } return OrderConst::PAY_SWITCH_YES; } /** * 判断首充是否切换 * * @param float $amount 订单金额 * @param float $rule_money 规则金额 * * @return int PAY_SWITCH_YES 1 切换 PAY_SWITCH_NO 2 不切换 */ public function switchMoney($amount, $rule_money = 0.00) { if (empty($rule_money)) { /* 没有设置金额 全部切换 */ return OrderConst::PAY_SWITCH_YES; } if ($amount < $rule_money) { /* 金额小于设置金额 不切换 */ return OrderConst::PAY_SWITCH_NO; } return OrderConst::PAY_SWITCH_YES; } public function checkShowPay($pay_check, Device $device_rq) { $_pay_check = $pay_check; if (OrderConst::PAY_SWITCH_NO == $_pay_check) { //IOS 不切换 关闭支付 米大师目前不支持IOS支付,故关闭,后续开发需删除当前代码 chenbingling 20181207 _start $_os = $device_rq->getOs(); if (false !== strpos(strtolower($_os), 'ios')) { $_pay_check = OrderConst::PAY_SWITCH_IOS_NO; } } return $_pay_check; } }