123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632 |
- <?php
- defined( 'IN_WEB') or die( 'Include Error!');
- /**
- * 钻石相关
- */
- class ModelDiamond
- {
- CONST COINNOTENOUGH = 4; //金币不足pid
- CONST SPINNOTENOUGH = 5; //体力不足pid
- /**
- * 钻石商品gpid映射的groupid
- * @return array
- */
- public function getGroupWithGpid() {
- return [ 1 => 220, 2 => 221, 3 => 222, 4 => 223, 5 => 224, 6 => 225, ];
- }
- /**
- * 钻石积分获取兑换商城分组列表
- * @param int $groupId
- * @return array
- */
- public function getGroupsByScore($score) {
- //积分分组
- $scores = [
- 220 => [
- [0, 100],
- [101, 10000],
- ],
- 221 => [
- [0, 100],
- [10000, 9999999999],
- ],
- 222 => [
- [0, 100],
- [101, 10000],
- ],
- 223 => [
- [10000, 9999999999],
- ],
- 224 => [
- [101, 10000],
- ],
- 225 => [
- [10000, 9999999999],
- ]
- ];
- $arr = [];
- foreach($scores as $k => $v){
- foreach($v as $vv){
- if($score >= $vv[0] && $score <= $vv[1]){
- $arr[] = $k;
- break;
- }
- }
- }
- return $arr;
- }
- /**
- * 获取钻石商城兑换信息
- */
- public function getShopDiamondWithClient($uid) {
- $version = oo::commonOprModel('user')->getUserVersion($uid);
- if(oo::compareVersion($version,'1.7.7')){
- $shop = $this->getNewShopDiamond();
- $uExchanged = $this->getNewUserExchangeInfo($uid);
- }else{
- $shop = $this->getShopDiamond();
- $uExchanged = $this->getUserExchangeInfo($uid);
- }
- if(!oo::compareVersion($version,'1.8.4')){
- unset($shop[2237]);
- unset($shop[2238]);
- unset($shop[2239]);
- }
- $pStages = $arr = [];
- foreach($shop as $k => $v){
- if(!isset($pStages[$v['pid']])){
- $pStages[$v['pid']] = 0;
- }else{
- $pStages[$v['pid']] += 1;
- }
- $pInfo = empty($uExchanged[$v['pid']]) ? [] : $uExchanged[$v['pid']];
- if(oo::compareVersion($version,'1.7.7') && isset($pInfo[$pStages[$v['pid']]])){
- $pInfo = isset($pInfo[$pStages[$v['pid']]]) ? $pInfo[$pStages[$v['pid']]] : [];
- }
- if(!isset($arr[$v['pid']])){
- $expire = isset($pInfo['expire']) ? $pInfo['expire'] : 0;
- $stage = empty($pInfo['stage']) ? 0 : $pInfo['stage'];
- $buyTimes = empty($pInfo['buyTimes']) ? 0 : $pInfo['buyTimes'];
- if($expire && $expire < time()){ //cd过期了
- $expire = $stage = $buyTimes = 0;
- }
- //每次都有cd,客户端只有最后一次展示cd
- if(oo::compareVersion($version,'1.7.7')){
- $expire = $buyTimes < $v['times'] ? 0 : $expire;
- }else{
- if($expire && !$this->checkIfLast($v['pid'], $pInfo, $version)){
- $expire = 0;
- }
- }
- $arr[$v['pid']] = [
- 'gid' => $v['pid'],
- 'list' => [],
- ];
- if(!oo::compareVersion($version,'1.7.7')){
- $arr[$v['pid']]['stage'] = $stage;
- $arr[$v['pid']]['buyTimes'] = $buyTimes;
- $arr[$v['pid']]['expire'] = $expire;
- }
- }
- if(isset($v['gbaseReward']['props'])){
- $v['propId'] = $v['gbaseReward']['props'];
- $v['num'] = 1;
- }else{
- $v['gbaseReward'] = $this->getReward($uid, $v['gbaseReward']);
- $key = key($v['gbaseReward']);
- $key = $key == 'money' ? 'coins' : $key;
- $v['propId'] = $key;
- $v['num'] = current($v['gbaseReward']);
- }
- if(oo::compareVersion($version,'1.7.7')){
- if((!isset($pInfo['expire']) || $pInfo['expire'] < time())){
- $v['expire'] = $v['buyTimes'] = 0;
- }else{
- $v['expire'] = $pInfo['expire'];
- $v['buyTimes'] = isset($pInfo['buyTimes']) ? $pInfo['buyTimes'] : 0;
- }
- $v['stage'] = $pStages[$v['pid']];
- }else{
- $v['expire'] = $v['gExpire'];
- }
- unset($v['gbaseReward'], $v['gExpire'], $v['stages']);
- $arr[$v['pid']]['list'][] = $v;
- }
- return array_values($arr);
- }
- /**
- * 获取玩家阶次兑换信息
- * @param int $uid
- * @param int $pid
- */
- public function getExchangedWithClient($uid, $pid, $stage, $version = '') {
- if(empty($version)){
- $version = oo::commonOprModel('user')->getUserVersion($uid);
- }
- if(oo::compareVersion($version,'1.7.7')){
- $info = $this->getNewUserExchangeInfo($uid, $pid);
- if(isset($info[$stage])){
- $info = $info[$stage];
- }else{
- $info = [];
- }
- }else{
- $info = $this->getUserExchangeInfo($uid, $pid);
- }
- if(empty($info)){
- $info = ['stage' => 0, 'buyTimes' => 0, 'expire' => 0];
- }
- if(oo::compareVersion($version,'1.7.7')){
- $shopArr = $this->getShopDiamondByPid($pid, $version);
- $gInfo = isset($shopArr[$stage]) ? $shopArr[$stage] : [];
- if(empty($gInfo) || $gInfo['times'] > $info['buyTimes']){
- $info['expire'] = 0;
- }
- $info['stage'] = $stage;
- $info['expire'] = (isset($info['expire']) && $info['expire'] > time()) ? $info['expire'] : 0;
- }else{
- if(empty($info['expire']) || !$this->checkIfLast($pid, $info, $version)){
- $info['expire'] = 0;
- }
- }
- return $info;
- }
- public function getShopDiamondByPid($pid = 0, $version = '1.7.3') {
- if(oo::compareVersion($version,'1.7.7')){
- $tmp = $this->getNewShopDiamond();
- }else{
- $tmp = $this->getShopDiamond();
- }
- $arr = [];
- foreach($tmp as $k => $v){
- if(!isset($arr[$v['pid']])){
- $arr[$v['pid']] = [];
- }
- $arr[$v['pid']][] = $v;
- }
- return isset($arr[$pid]) ? $arr[$pid] : [];
- }
- /**
- * 新版钻石兑换分3行显示
- * @param int $gid
- * @return array
- */
- public function getNewShopDiamond($gid = 0) {
- $arr = $this->getShopDiamond();
- $pid3Arr = $data = [];
- $end = end($arr);
- $stages3 = $end['stages'];
- $stages2 = 0;
- foreach($arr as $k => $v){
- if($v['pid'] == 3){ //pid3的结构有变更
- $v['pid'] = 2;
- $v['stages'] += $stages2;
- $pid3Arr[$k] = $v;
- continue;
- }
- if($v['pid'] == 2){
- empty($stages2) && $stages2 = $v['stages'];
- $v['stages'] = $v['stages'] + $stages3;
- }
- $data[$k] = $v;
- }
- $data = $data + $pid3Arr;
- if($gid){
- return !isset($data[$gid]) ? [] : $data[$gid];
- }
- return $data;
- }
- public function getShopDiamond($gid = 0) {
- $arr = oo::commonOprRedis("common")->hGetAll(okeys::shopDiamond());
- ksort($arr);
- $stages = [];
- if(empty($arr)){
- $tb = otable::diamondCrazy();
- $sql = "SELECT * FROM {$tb} WHERE pid IN(1, 2, 3,6)";
- $rs = oo::commonOprDb('common')->getAll($sql,1);
- $arr = [];
- foreach($rs as $k => $v){
- $v['gbaseReward'] = json_decode($v['gbaseReward'], true);
- $arr[$v['gid']] = $v;
- $stages[$v['pid']] = isset($stages[$v['pid']]) ? $stages[$v['pid']]+1 : 1;
- }
- //存redis
- foreach($arr as $k => $v){
- $v['stages'] = isset($stages[$v['pid']]) ? $stages[$v['pid']] : 0;
- $arr[$k] = $v;
- oo::commonOprRedis("common")->hSet(okeys::shopDiamond(), $k, json_encode($v));
- }
- }
- foreach($arr as $k => $v){
- $arr[$k] = is_array($v) ? $v : (array)json_decode($v, true);
- }
- if($gid){
- return !isset($arr[$gid]) ? [] : $arr[$gid];
- }
- return $arr;
- }
- /**
- * 获取下一次过期时间戳
- */
- public function getExpire() {
- $expire = strtotime(date('Y-m-d', strtotime('+1 days')));
- if(defined('IS_DEBUF') && IS_DEBUF){
- $h = date('H');
- if($h < 8){ //世界时间前一天
- $expire = strtotime(date('Y-m-d', time()))+8*3600;
- }else{
- $expire = strtotime(date('Y-m-d', strtotime('+1 days')))+8*3600;
- }
- }
- return $expire;
- }
- /**
- * 新版玩家钻石兑换记录
- * @param int $uid
- * @param int $pid
- * @return array
- */
- public function getNewUserExchangeInfo($uid, $pid = 0) {
- $arr = oo::commonOprRedis("user")->hGetAll(okeys::userDdiamond($uid));
- //最大过期时间,第二天0点
- $maxExpire = $this->getExpire();
- if($pid){
- $info = !empty($arr[$pid]) ? (array)json_decode($arr[$pid], true) : [];
- foreach($info as $k => $v){
- if($info[$k] && !isset($info[$k]['buyTimes'])){ //第一次直接重置
- //$info[$k]['expire'] = time()-8*3600-1; //世界时间
- oo::commonOprRedis("user")->delete(okeys::userDdiamond($uid));
- return [];
- }
- if(!empty($info[$k]['expire']) && $info[$k]['expire'] > $maxExpire){
- $info[$k]['expire'] = $maxExpire;
- }
- if($info[$k]['expire'] < time()){
- $info[$k]['expire'] = $info[$k]['buyTimes'] = 0;
- }
- }
- return $info;
- }
- foreach($arr as $k => $v){
- $arr[$k] = (array)json_decode($v, true);
- //老版本的数据直接清除
- if($arr[$k] && (isset($arr[$k]['buyTimes']) || isset($arr[$k]['expire']))){
- oo::commonOprRedis("user")->delete(okeys::userDdiamond($uid));
- return [];
- }
- foreach($arr[$k] as $kk => $vv){
- if(!empty($arr[$k][$kk]['expire']) && $arr[$k][$kk]['expire'] > $maxExpire){
- $arr[$k][$kk]['expire'] = $maxExpire;
- }
- if($arr[$k][$kk]['expire'] < time()){
- $arr[$k][$kk]['buyTimes'] = $arr[$k][$kk]['expire'] = 0;
- }
- }
- }
- return $arr;
- }
- /**
- * 获取玩家当前商品钻石兑换阶次
- * @param int $uid
- * @param int $pid 钻石商品组id [1, 2, 3]
- * @return array
- */
- public function getUserExchangeInfo($uid, $pid = 0) {
- $arr = oo::commonOprRedis("user")->hGetAll(okeys::userDdiamond($uid));
- //最大过期时间,第二天0点
- $maxExpire = $this->getExpire();
- if($pid){
- $info = !empty($arr[$pid]) ? (array)json_decode($arr[$pid], true) : [];
- if($info && !isset($info['expire'])){
- $info['expire'] = 0; //世界时间
- oo::commonOprRedis("user")->hSet(okeys::userDdiamond($uid), $pid, json_encode($info));
- }
- if(!empty($info['expire']) && $info['expire'] > $maxExpire){
- $info['expire'] = $maxExpire;
- }
- return $info;
- }
- foreach($arr as $k => $v){
- $arr[$k] = (array)json_decode($v, true);
- //兼容前期redis没有设置expire问题
- if($arr[$k] && !isset($arr[$k]['expire'])){
- $arr[$k]['expire'] = 0; //世界时间
- oo::commonOprRedis("user")->hSet(okeys::userDdiamond($uid), $k, json_encode($arr[$k]));
- }
- if(!empty($arr[$k]['expire']) && $arr[$k]['expire'] > $maxExpire){
- $arr[$k]['expire'] = $maxExpire;
- }
- }
- return $arr;
- }
- public function getGroupIdByGid($gid) {
- $arr = $this->getShopDiamond($gid);
- if(empty($arr['pid'])){
- return 0;
- }
- return $arr['pid'];
- }
- /**
- * 判断玩家当前是否到了最后一次兑换
- * @param int $pid
- * @param array $info
- * @return bool
- */
- public function checkIfLast($pid, $info, $version = '1.7.3') {
- if(empty($info['stage'])){
- return false;
- }
- $shopArr = $this->getShopDiamondByPid($pid, $version);
- if($info['stage'] < count($shopArr) - 1){
- return false;
- }
- $shopInfo = $shopArr[$info['stage']];
- if($info['buyTimes'] >= $shopInfo['buyTimes']){
- return true;
- }
- return false;
- }
- /**
- * 判断当前玩家当前是否可用宝石兑换物品
- */
- public function canExchange($uid, $pid, $stage, $version = '1.7.3') {
- if(oo::compareVersion($version,'1.7.7')){
- $tmp = $this->getNewUserExchangeInfo($uid, $pid);
- if(isset($tmp[$stage])){
- $info = $tmp[$stage];
- }else{
- $info = [];
- }
- }else{
- $info = $this->getUserExchangeInfo($uid, $pid);
- if(empty($info)){
- $info = ['stage' => 0, 'buyTimes' => 0];
- }
- }
- $shopInfoArr = $this->getShopDiamondByPid($pid, $version);
- if(!isset($shopInfoArr[$stage])){
- return false;
- }
- $shopInfo = $shopInfoArr[$stage];
- $curShopInfo = [];
- if(!oo::compareVersion($version,'1.7.7')){
- $curShopInfo = $shopInfoArr[$info['stage']];
- }
- if(empty($stage)){ //0阶
- //已过cd时间
- if(!empty($info['expire']) && $info['expire'] < time()){
- return true;
- }
- if(!oo::compareVersion($version,'1.7.7')){
- //还未到最后一阶
- if($info['stage'] && $info['stage'] < $shopInfo['stages'] - 1){
- return false;
- }
- //最后一阶次数未完
- if($info['stage'] >= $shopInfo['stages'] - 1 && $info['buyTimes'] < $curShopInfo['times']){
- return false;
- }
- //cd中
- if($info['stage'] && !empty($info['expire']) && $info['expire'] > time()){
- return false;
- }
- //当前阶次数买完了
- if(empty($info['stage']) && $info['buyTimes'] >= $curShopInfo['times']){
- return false;
- }
- }
- if(isset($info['buyTimes']) && $info['buyTimes'] >= $shopInfo['times']){
- return false;
- }
- }else{
- //已过cd时间
- if(!empty($info['expire']) && $info['expire'] < time()){
- return true;
- }
- if(!oo::compareVersion($version,'1.7.7')){
- if($info['stage'] > $stage){ //请求阶错误
- return false;
- }
- if($info['stage'] + 1 < $stage){ //跨阶了
- return false;
- }
- //当前阶次数未买完
- if($info['stage'] + 1 == $stage && $info['buyTimes'] < $curShopInfo['times']){
- return false;
- }
- //当前阶已买完
- if($info['stage'] == $stage && $info['buyTimes'] >= $curShopInfo['times']){
- return false;
- }
- }
- if(isset($info['buyTimes']) && $info['buyTimes'] >= $shopInfo['times']){
- return false;
- }
- }
- $assetsInfo = oo::commonOprModel('member')->getUserAssetsInfo($uid);
- //钻石不足
- if($shopInfo['price'] > (int)$assetsInfo['diamond']){
- return false;
- }
- return true;
- }
- /**
- * 使用钻石兑换物品
- * @param int $uid
- * @param int $pid
- */
- public function diamondExchange($uid, $pid, $stage, $version = '1.7.3') {
- $shopInfoArr = $this->getShopDiamondByPid($pid, $version);
- if(!isset($shopInfoArr[$stage])){
- return false;
- }
- if(oo::compareVersion($version, '1.7.7')){
- $info = $this->getNewUserExchangeInfo($uid, $pid);
- }else{
- $info = $this->getUserExchangeInfo($uid, $pid);
- }
- $shopInfo = $shopInfoArr[$stage];
- //扣除钻石
- $ret = oo::commonOprModel('member')->optProperty(
- $uid,['diamond' => $shopInfo['price']],'-',12,'钻石兑换,消耗钻石:'.$pid.':'.$stage
- );
- if(!$ret){
- oo::logs()->debug(['uid'=> $uid,'data'=>$shopInfo['price']],'getDiamond.log', date('Ymd').'/');
- return false;
- }
- if(oo::compareVersion($version,'1.7.7')){
- $upArr = $info;
- if(!isset($upArr[$stage])){
- $upArr[$stage] = ['buyTimes' => 1];
- }else{
- $upArr[$stage]['buyTimes'] += 1;
- }
- }else{
- $upArr = ['stage' => (int)$stage];
- if($stage != $info['stage']){ //跨阶或重新开始买
- $upArr['buyTimes'] = 1;//重置次数
- }else{
- $times = $info['buyTimes']+1 >= $shopInfo['times'] ? $shopInfo['times'] : $info['buyTimes']+1;
- $upArr['buyTimes'] = (int)$times;
- }
- }
- //最后一阶了,更新倒计时,世界时间第二天0点
- $expire = $this->getExpire();
- if(oo::compareVersion($version,'1.7.7')){
- $upArr[$stage]['expire'] = (isset($upArr[$stage]['expire']) && $upArr[$stage]['expire'] > time()) ? $upArr[$stage]['expire'] : $expire;
- }else{
- $upArr['expire'] = $expire;
- }
- //更新兑换信息
- $ret = oo::commonOprRedis("user")->hSet(okeys::userDdiamond($uid), $pid, json_encode($upArr));
- if(!$ret){
- $log = json_encode(['act' => 'up user diamond exchange stage fail','value' => $stage+1]);
- oo::logs()->debug(['uid'=> $uid, 'data'=>$log],'getDiamond.log', date('Ymd').'/');
- return false;
- }
- $reward = $this->getReward($uid, $shopInfo['gbaseReward']);
- if(isset($shopInfo['gbaseReward']['crazyPassExp'])){
- $ret = oo::commonOprModel('member')->sendReward($uid, 38, $shopInfo['gbaseReward']['crazyPassExp'],13,'钻石兑换,增加物品:'.$pid.':'.$stage);
- }else{
- $ret = oo::commonOprModel('member')->optProperty($uid,$reward,'+',13,'钻石兑换,增加物品:'.$pid.':'.$stage);
- }
-
- if(!$ret){
- $log = json_encode(['act'=>'diamond exchange attr fail,stage:'.((int)$stage+1),'value'=>$shopInfo['gbaseReward']]);
- oo::logs()->debug(['uid'=> $uid,'data'=>$log],'getDiamond.log', date('Ymd').'/');
- }
- return $ret;
- }
- public function getReward($uid, $gbaseReward) {
- if(is_array($gbaseReward) && isset($gbaseReward['coins'])){
- $gbaseReward['money'] = oo::commonOprModel('goods')->getGoodCoins($uid, $gbaseReward['coins']);
- $num = isset($gbaseReward['num']) ? (int)$gbaseReward['num'] : 1;
- if($num < 0){
- $num = 1;
- }
- $gbaseReward['money'] = $gbaseReward['money'] * $num;
- unset($gbaseReward['coins'], $gbaseReward['num']);
- }
- return $gbaseReward;
- }
- /**
- * 金币/体力不足直接钻石兑换列表
- * @param $gid int
- * @return array
- */
- public function getNotEnoughDiamond($uid, $gid = 0) {
- $arr = oo::commonOprRedis("common")->hGetAll(okeys::notEnouthDiamond());
- ksort($arr);
- if(empty($arr)){
- $tb = otable::diamondCrazy();
- $pids = self::COINNOTENOUGH . ',' . self::SPINNOTENOUGH;
- $sql = "SELECT * FROM {$tb} WHERE pid IN({$pids})";
- $rs = oo::commonOprDb('common')->getAll($sql,1);
- $arr = [];
- foreach($rs as $k => $v){
- $v['gbaseReward'] = json_decode($v['gbaseReward'], true);
- $arr[$v['gid']] = $v;
- }
- unset($v['gExpire'], $v['times']);
- //存redis
- foreach($arr as $k => $v){
- $arr[$k] = $v;
- oo::commonOprRedis("common")->hSet(okeys::notEnouthDiamond(), $k, json_encode($v));
- }
- }
- foreach($arr as $k => $v){
- $v = is_array($v) ? $v : (array)json_decode($v, true);
- if(!is_array($v) || empty($v)){
- continue;
- }
- unset($v['gExpire'], $v['times']);
- if(isset($v['gbaseReward']['props'])){
- $v['propId'] = $v['gbaseReward']['props'];
- $v['num'] = 1;
- }else{
- $v['gbaseReward'] = $this->getReward($uid, $v['gbaseReward']);
- }
- $arr[$k] = is_array($v) ? $v : (array)json_decode($v, true);
- }
- if($gid){
- return !isset($arr[$gid]) ? [] : $arr[$gid];
- }
- return $arr;
- }
- /**
- * 返回给客户端的结构
- */
- public function notEnoughWithClient($uid) {
- $tmp = $this->getNotEnoughDiamond($uid);
- $data = [
- 'diamondCoin' => [],
- 'diamondSpin' => [],
- ];
- foreach($tmp as $v) {
- $v['id'] = $v['gid'];
- $v['addRatio'] = empty($v['gaddRatio']) ? '0' : $v['gaddRatio'];
- unset($v['gaddRatio']);
- if($v['pid'] == self::SPINNOTENOUGH){
- $v['num'] = $v['gbaseReward']['spins'];
- unset($v['gbaseReward']);
- $data['diamondSpin'][] = $v;
- }else{
- $v['num'] = $v['gbaseReward']['money'];
- unset($v['gbaseReward']);
- $data['diamondCoin'][] = $v;
- }
- }
- return $data;
- }
- }
|