Example #1
0
 /**
  * 检查参数签名
  */
 function authSig($request)
 {
     $method = $request['m'];
     $param = $request['p'];
     if ($param['signature']) {
         $signature = $param['signature'];
         unset($param['signature']);
         $keys = array_keys($param);
         sort($keys);
         $s = '';
         foreach ($keys as $key) {
             $value = $param[$key];
             if (is_string($value) || is_numeric($value) || is_bool($value)) {
                 $s .= '&' . $key . '=' . $value;
             }
         }
         $s = substr($s, 1) . $method . P_VERSION . '~@#1xdaf,dmuopamie%%123.';
         $mysig = md5($s);
         if ($mysig != $signature) {
             glog::info("签名不对[{$mysig}]!=[{$signature}], " . json_encode($request), 'sign');
             return array('s' => StatusCode::invalid_siginature, 'msg' => 'invalid signature');
         }
         $timestamp = $param['timestamp'];
         if ($method == 'System.login') {
             // 手机设备时间和服务器时间可能有差异,所以第一次请求 System.login 时不验证时间。
             return false;
         }
         // 1. 对 timestamp 做验证 与 服务器当前时间相差太多的 认为是不合法的请求
         $now = getApp()->now;
         if (abs($now - $timestamp) > 300) {
             $ts1 = date('Y-m-d H:i:s', $now);
             $ts2 = date('Y-m-d H:i:s', $timestamp);
             glog::info("请求时间异常 server[{$ts1}], client[{$ts2}], " . json_encode($request), 'sign');
             return false;
             return array('s' => StatusCode::invalid_request_time, 'msg' => 'invalid timestamp');
         }
         // 2. 记录用户上次调用这个接口的时间戳,如果新的 timestamp <= old_timestamp 则认为是不合法的请求
         $uid = getApp()->getuid();
         $section_id = getApp()->getsec();
         if ($uid && $section_id) {
             if (model_Util::inBlacklist($uid)) {
                 //黑名单访问,禁止
                 glog::info("黑名单中玩家[{$uid}]访问分区[{$section_id}] " . json_encode($request), 'blacklist');
                 return array('s' => StatusCode::invalid_request_time, 'msg' => "uid[{$uid}] is in blacklist");
             }
             try {
                 $redis = DbConfig::getRedis('cache');
                 $timestamp_key = "sig_{$section_id}_{$uid}_{$method}";
                 $old_timestamp = $redis->get($timestamp_key);
                 if (is_numeric($old_timestamp)) {
                     // 手机端网络超时后重试,后台可能会收到两次同样时间戳的请求 所以 $timestamp == $old_timestamp 还是很有可能的
                     if ($timestamp < $old_timestamp) {
                         $ts1 = date('Y-m-d H:i:s', $old_timestamp);
                         $ts2 = date('Y-m-d H:i:s', $timestamp);
                         glog::info("请求时间异常, 上次请求[{$ts1}], 本次请求[{$ts2}], " . json_encode($request), 'sign');
                         return false;
                         return array('s' => StatusCode::outdated_siginature, 'msg' => 'outdated signature', 'debug' => "old_timestamp: {$old_timestamp}");
                     } else {
                         $redis->multi();
                         $redis->set($timestamp_key, $timestamp);
                         $redis->expire($timestamp_key, 360);
                         $redis->exec();
                         return false;
                     }
                 } else {
                     $redis->multi();
                     $redis->set($timestamp_key, $timestamp);
                     $redis->expire($timestamp_key, 360);
                     $redis->exec();
                     return false;
                 }
             } catch (Exception $ex) {
                 error_log("无法连接 cache redis ");
                 return false;
             }
         }
         return false;
     }
     glog::info("没有签名," . json_encode($request), 'sign');
     return array('s' => StatusCode::invalid_siginature, 'msg' => 'no signature');
 }
Example #2
0
 /**  
  * actionPayment
  * @author 符璨
  * @param
  *          pid
  *          uid
  *          appid
  *          sec
  *          transaction_id:订单id
  *          cashier_id:支付单id
  *          cash:支付金额
  *          status:
  *          time:支付单生成时间戳
  *          product_id:购买产品编号
  *          product_cnt
  *          sig:签名
  * @return
  *      s 状态码
  *          100:玩家数据不存在
  *          108:签名验证错误
  *          11:product_id或其他原因引起的加载支付配置错误引发的异常
  *          ok:支付成功
  * @desc
  *      提供给cashier服务器调用的支付接口
  */
 public function actionPayment()
 {
     $now = getApp()->now;
     //取出所有参数
     $pid = $_POST['pid'];
     $uid = $_POST['uid'];
     $appid = $_POST['appid'];
     $transaction_id = $_POST['transaction_id'];
     $cashier = $_POST['cashier'];
     $cash = $_POST['cash'];
     $status = $_POST['status'];
     $create_t = $_POST['create_t'];
     $product_id = $_POST['product_id'];
     $product_cnt = $_POST['product_cnt'];
     $channel = $_POST['channel'];
     $channel_id = $_POST['channel_id'];
     $sec = $_POST['sec'];
     $isrepay = $_POST['isrepay'];
     //验证签名
     $data = array('pid' => $pid, 'uid' => $uid, 'appid' => $appid, 'channel' => $channel, 'channel_id' => $channel_id, 'sec' => $sec, 'transaction_id' => $transaction_id, 'cashier' => $cashier, 'cash' => $cash, 'status' => $status, 'create_t' => $create_t, 'product_id' => $product_id, 'product_cnt' => $product_cnt, 'isrepay' => $isrepay);
     ksort($data);
     $sig = md5(http_build_query($data) . '171ca1475ffcd016fca228cd716f14b7');
     if ($sig != $_POST['sig']) {
         echo json_encode(array('s' => StatusCode::invalid_siginature));
         return;
     }
     //加锁避免重复处理
     $redis = DbConfig::getRedis('rank');
     $lock_key = "payment_{$transaction_id}";
     $lock_res = $redis->SETNX($lock_key, $now);
     if ($lock_res) {
         //60秒过期
         $redis->SETEX($lock_key, 60, $now);
     } else {
         echo json_encode(array('s' => StatusCode::can_not_do));
         return;
     }
     //判断账单是否处理避免重复处理
     $mon = getApp()->getPaymentMongoConnection();
     $order = $mon->findOne(array('transaction_id' => $transaction_id));
     if ($order) {
         echo json_encode(array('s' => StatusCode::ok));
         return;
     }
     unset($data['time']);
     unset($data['uid']);
     //$data['cashier_t'] = $cashier_t;
     $data['process_t'] = $now;
     $data['_u'] = is_numeric($uid) ? intval($uid) : $uid;
     $data['action'] = 'recharge_gem';
     $data['_sec'] = $data['sec'];
     $data['_tm'] = $data['create_t'];
     $player = new model_Player($uid, $sec);
     $user_data = $player->getFields(array('level', 'vip.lvl', 'gem'));
     $data['_lvl'] = $user_data['level'];
     $data['_vip'] = $user_data['vip']['lvl'];
     $data['ogem'] = $user_data['gem'];
     $data['order_id'] = $transaction_id;
     if ($data['channel'] == "zongle") {
         //需求使用纵乐sdk发布cps包 by zhangjun
         $data['source'] = $data['channel'] . $data['channel_id'];
     } else {
         $data['source'] = $data['channel'];
     }
     //根据pid获取uid并生成用户session
     PL_Session::$usecookie = false;
     $_REQUEST['cid'] = PL_Session::gencid($uid, $sec);
     //uid非法
     if (!$uid || $uid < 0) {
         //玩家不存在
         glog::info("异常的支付数据[uid:{$uid}][section_id:{$sec}][transaction_id:{$transaction_id}][product_id:{$product_id}]", 'payment');
         echo json_encode(array('s' => StatusCode::exception));
         return;
     }
     try {
         $player = getApp()->getPlayer();
     } catch (Exception $e) {
         //玩家不存在
         glog::info("异常的支付数据[uid:{$uid}][section_id:{$sec}][transaction_id:{$transaction_id}][product_id:{$product_id}]", 'payment');
         echo json_encode(array('s' => StatusCode::exception, 'msg' => 'error1'));
         return;
     }
     $data['cash'] = $data['cash'] / 100;
     //cash通知单位是分
     if ($channel == 'wanpay_web') {
         $this->processWanpay($data);
     }
     $ret = $player->process_payment($data, true, $data['cash']);
     $redis->DEL($lock_key);
     echo json_encode($ret);
 }
Example #3
0
 /**
  * @auther lifei@playcarb.com
  * 发放燕子坞活动 未领奖励
  */
 public static function action_award_yanziwu()
 {
     $app = getApp();
     $now = $app->now;
     //活动界面关闭后才发送奖励
     $config = $app->getActivityConfig('act_yanziwuqiangqin_20130425');
     if ($now <= $config['end_t']) {
         //self::showError("",__LINE__);
         self::showError("activity not finished!", __LINE__);
     }
     $sections = array_keys(getApp()->getSectionConfig());
     if (empty($sections)) {
         self::showError("get section config error!", __LINE__);
     }
     $start_md = date('md', $config['start_t']);
     $redis = DbConfig::getRedis('rank');
     //时间肯定超过12、21、24了不判断时间
     //所有区
     foreach ($sections as $sec) {
         echo "===============分区:{$sec}==========================\n";
         //检查各个时段的排行榜奖励
         for ($i = 1; $i <= 3; $i++) {
             $redis_key = "act_yanziwuqiangqin_" . $start_md . "_" . $sec . "_" . $i;
             //查询各个时段排行榜
             $list = self::getQiangQinRank(0, 19, $redis, $redis_key, $config, $sec);
             if (empty($list)) {
                 echo "warning:第{$i}段,分区:{$sec}的排行为空!\n";
                 continue;
             }
             echo "=============当前时段:{$i}=============";
             echo $redis_key . "\n";
             print_r($list);
             foreach ((array) $list as $v) {
                 //判断玩家是否领取过
                 $uid = $user_key = $v['id'];
                 $player = new model_Player($uid, $sec);
                 //玩家存的是带年的
                 $start_ymd = date('Ymd', $config['start_t']);
                 $player_data = $player->getFields(array('qiyu.yanziwuqiangqin_' . $start_ymd));
                 $player_pos = $player_data['qiyu']['yanziwuqiangqin_' . $start_ymd];
                 if (!empty($player_pos[$i])) {
                     //领过了
                     echo "warning:====玩家{$uid}/{$sec}领过第{$i}段奖励了!\n";
                     continue;
                 }
                 //判断奖励
                 //玩家自己的排名
                 $rank = $redis->zrevrank($redis_key, "{$user_key}");
                 echo "====玩家{$uid}/{$sec}===当前排名:{$rank}\n";
                 if ($rank === false) {
                     echo "warning:====玩家{$uid}/{$sec}排名错误为假!\n";
                     continue;
                 }
                 // 确定该玩家是否在前20,计算并列20的情况
                 $my_num = 0;
                 if ($rank >= 20) {
                     // 玩家自己的积分
                     $my_num = $redis->zscore($redis_key, $user_key);
                     // 玩家正好与第20名的积分相同
                     if ($my_num == $list[count($list) - 1]['num']) {
                         // 奖励list中最后一名相同的奖励
                         $award_config = PL_Config_Numeric::get('yanziwuaward', $list[count($list) - 1]['rank'], false);
                     }
                 } else {
                     // 如果在前20名,那么list中一定存在该玩家信息
                     foreach ($list as $val) {
                         if ($val['id'] == $uid) {
                             $my_rank = $val['rank'];
                             $my_num = $val['num'];
                         }
                     }
                     $award_config = PL_Config_Numeric::get('yanziwuaward', $my_rank, false);
                 }
                 //24点必须大于2000
                 if ($i == 3 && $my_num < 2000) {
                     continue;
                 }
                 echo "{$sec}=={$uid}开始发第{$i}段奖..\n";
                 $log['action'] = __CLASS__ . '.' . __FUNCTION__;
                 //print_r($award_config);
                 self::awardQiangQin($award_config, $i, $my_num, $player_pos, &$player, $config, &$log, $rank, $uid, $sec);
                 // 标记已经领取
                 $player_pos[$i] = 1;
                 $player->objectPut('qiyu', 'yanziwuqiangqin_' . date('Ymd', $config['start_t']), $player_pos);
                 $result = $player->commit();
                 $log['ret'] = $result;
                 glog::stat($log);
             }
             //print_r($list);
         }
     }
 }