currRankSeasonMeta = mt\RankSeason::getCurrentSeason(); if (!$this->currRankSeasonMeta) { $this->_rspErr(10, 'server internal error'); die(); } $this->propertyChgService = new services\PropertyChgService(); $this->awardService = new services\AwardService(); $this->userInfo = $this->_safeGetOrmUserInfo(); $this->seasonDb = Season::find($this->currRankSeasonMeta['id']); if (!$this->seasonDb) { Season::add($this->currRankSeasonMeta['id']); $this->seasonDb = Season::find($this->currRankSeasonMeta['id']); } if (!$this->seasonDb) { $this->_rspErr(10, 'server internal error'); die(); } $this->missionService = new services\MissionService(); $this->missionService->init($this->userInfo, $this->seasonDb); } public function info() { $rankMeta = mt\Rank::get($this->userInfo['rank']); $this->_rspData(array( 'info' => array( 'season_id' => $this->currSeasonMeta['id'], 'rank' => $this->userInfo['rank'], 'score' => $this->userInfo['score'], 'max_score' => $rankMeta ? $rankMeta['max_score'] : 0, 'noshow_score_bar' => $rankMeta ? $rankMeta['noshow_score_bar'] : 1, 'mission' => $this->getMissionInfo() ) )); } public function infoNew() { // $r = $this->_getRedis($this->TopXunid.'4'); // $TopX_List = $this->readRankingList($r,$this->TopXunid.'5'); // $XX = $TopX_List ? $TopX_List[0]["rank_sort"]:10001; // print_r($XX); // die; $rankMeta = mt\Rank::getRankById($this->userInfo['rank']); $nextRankMeta = mt\Rank::getNextRankById($this->userInfo['rank']); if (!$nextRankMeta){ $nextRankMeta = mt\Rank::getMaxRank(); } $info = array( 'season_name' => $this->currRankSeasonMeta['name'], 'rank' => $this->userInfo['rank'], 'rank_name' => $rankMeta['rank_name'], 'score' => $this->userInfo['score'], 'next_score' => $nextRankMeta['rank_score'], 'season_end_time' => strtotime($this->currRankSeasonMeta['end_time']), 'season_reward' => Season::seasonReward($rankMeta) ); $r = $this->_getRedis($this->rankingUnid); $rankList = $this->readRankingList($r,$this->rankingUnid); $list = array(); if (!$rankList){ $rankList = $this->checkRankingList(); $this->saveRankingList($r,$this->rankingUnid,$rankList); } foreach ($rankList as $v){ if ($this->userInfo['rank'] == $v['rank'] && count($list) < 20){ array_push($list,$v); } } $info['season_rank'] = $rankList; $this->_rspData(['info'=>$info]); } public function getRankingInfo(){ $rank_param = getReqVal('rank',0); if (!$rank_param){ $this->_rspErr(1, 'params rank error'); die(); } $r = $this->_getRedis($this->rankingUnid); $rankList = $this->readRankingList($r,$this->rankingUnid); $list = array(); if (!$rankList){ $rankList = $this->checkRankingList(); $this->saveRankingList($r,$this->rankingUnid,$rankList); } foreach ($rankList as $v){ if ($rank_param == $v['rank'] && count($list) < 20){ array_push($list,$v); } } $this->_rspData(['info'=>$list]); } public function getDataInfo(){ $seasonDb = Season::find($this->currRankSeasonMeta['id']); $currRankSeasonHistory = array(); if ($seasonDb){ $battleData = json_decode($seasonDb['battle_data'], true); $seasonBattleData = isset($battleData) ? getXVal($battleData, 'season_data', array()) : array(); $gameTimes = getXVal($seasonBattleData, 'total_battle_times', 0); $winTimes = getXVal($seasonBattleData, 'total_win_times', 0); $topTenTimes = getXVal($seasonBattleData, 'total_top_ten_times', 0); $totalKills = getXVal($seasonBattleData, 'total_kills_times', 0); $currRankSeasonHistory= array( 'season_id' => $seasonDb['season_id'], // 'total_kills' => $totalKills, 'game_times' => $gameTimes, 'win_times' => $winTimes, 'top_ten_times' => $topTenTimes, 'kill_killed' => round($totalKills/($gameTimes-$winTimes),2), ); } if (!$currRankSeasonHistory){ $currRankSeasonHistory = array( 'season_id' => $this->currRankSeasonMeta['id'], // 'total_kills' => $totalKills, 'game_times' => 0, 'win_times' => 0, 'top_ten_times' => 0, 'kill_killed' => 0, ); } $this->_rspData(['info'=>$currRankSeasonHistory]); } public function getHeroInfo(){ $seasonDb = Season::find($this->currRankSeasonMeta['id']); $currHeroSeasonHistory = array(); if ($seasonDb) { $battleData = json_decode($seasonDb['battle_data'], true); $seasonBattleData = isset($battleData) ? getXVal($battleData, 'season_data', array()) : array(); $seasonHeroInfo = isset($seasonBattleData) ? getXVal($seasonBattleData, 'hero_info', array()) : array(); $heroSort = array(); foreach ($seasonHeroInfo as $key=>$heroInfo){ $heroSort[$key]['use_times'] = isset($heroInfo['use_times']) ? $heroInfo['use_times'] : 0; $heroSort[$key]['weapon'] = isset($heroInfo['weapon']) ? $heroInfo['weapon'] : array(); $heroSort[$key]['win_times'] = isset($heroInfo['win_times']) ? $heroInfo['win_times'] : 0; $heroSort[$key]['top_ten_times'] = isset($heroInfo['top_ten_times']) ? $heroInfo['top_ten_times'] : 0; $heroSort[$key]['hero'] = $key; arsort($heroSort[$key]['weapon']); $heroSort[$key]['weapon'] = array_keys($heroSort[$key]['weapon']); $heroSort[$key]['weapon'] = implode('|',array_slice($heroSort[$key]['weapon'],0,2)); } arsort($heroSort); $heroSort = array_slice($heroSort,0,3); foreach ($heroSort as &$value){ $value['season_id'] = $seasonDb['season_id']; $value['win_rate'] = round($value['win_times']/$value['use_times'],2); $value['top_ten_rate'] = round($value['top_ten_times']/$value['use_times'],2); } $currHeroSeasonHistory = $heroSort; } // if (!$currHeroSeasonHistory){ // array_push($currHeroSeasonHistory, // array( // 'season_id' => $this->currRankSeasonMeta['id'], // 'use_times' => 0, // 'weapon' => 0, // 'win_times' => 0, // 'top_ten_times' => 0, // 'hero_id' => 0, // 'win_rate' => 0, // 'top_ten_rate' => 0, // )); // } $this->_rspData(['info'=>$currHeroSeasonHistory]); } public function getMissionReward() { $mission = $this->getMissionInfo(); if (!$mission || $mission['state'] != Mission::RECEIVEABLE_STATE) { $this->_rspErr(1, 'Can not receive'); return; } $missionMeta = mt\Task::get($this->currSeasonMeta['task_id']); $missionId = $this->currSeasonMeta['task_id']; if (!$missionMeta) { $this->_rspErr(10, 'server internal error'); return; } $dropMeta = mt\Drop::get($missionMeta['reward']); if (!$dropMeta) { $this->_rspErr(10, 'server internal error'); return; } $this->_scatterDrop('mission:' . $missionId, $dropMeta, $this->awardService, $this->propertyChgService); Mission::add($missionId); $missionDb = Mission::find($missionId); $missionDto = $this->missionService->getMissionDto( $this->userInfo, $this->seasonDb, $missionDb, $missionMeta); $this->_rspData(array( 'award' => $this->awardService->toDto(), 'property_chg' => $this->propertyChgService->toDto(), )); } private function getMissionInfo() { $info = array( 'state' => Mission::NOT_FINISHED_STATE, 'current' => 0, 'target' => 0, 'target_rank' => 0 ); $missionMeta = mt\Task::get($this->currSeasonMeta['task_id']); if ($missionMeta) { $info['target_rank'] = $missionMeta['param1']; $info['target'] = $missionMeta['target']; $missionDb = Mission::find($missionMeta['id']); $missionDto = $this->missionService->getMissionDto( $this->userInfo, $this->seasonDb, $missionDb, $missionMeta); if ($missionDto) { $info['state'] = $missionDto['state']; $info['current'] = $missionDto['current']; $info['target'] = $missionDto['target']; } } return $info; } private function checkRankingList(){ $rankList = array(); $users = User::orderBy(User::allUser()); $rewardParamMeta = \mt\Parameter::getByName('rank_ring_reward'); $rewardParamMetaValue = $rewardParamMeta ? $rewardParamMeta['param_value'] : ''; $rewardList = explode('|',$rewardParamMetaValue); if (count($users)>0){ $KingCount = 0; foreach ($users as $k=>$user){ $userDto = User::getUserByRankMess($user); $userDto['rank_sort'] = $k+1; if ($userDto['score'] >= $this->starshine){ $KingCount += 1; $userDto['echelonTopX'] = $this->echelonTopX($userDto['rank_sort']); $r = $this->_getRedis($this->TopXunid.$userDto['echelonTopX']); $TopX_List = $this->readRankingList($r,$this->TopXunid.$userDto['echelonTopX']); array_push($TopX_List,$userDto); $this->saveRankingList($r,$this->TopXunid.$userDto['echelonTopX'],$TopX_List); } switch ($userDto['rank_sort']){ case 1:$userDto['ring_item_id'] = $rewardList[0];break; case 2:$userDto['ring_item_id'] = $rewardList[1];break; case 3:$userDto['ring_item_id'] = $rewardList[2];break; default : $userDto['ring_item_id'] = 0; } array_push($rankList,$userDto); } //当月排位赛最大分配金额 $maxSum = $this->calcCECMaxSum(); //排位赛参与分配人数 // $PeopleCapita = $this->calcPeopleCapita($KingCount); //排位赛人数% // $PeopleCapitaPer = $this->calcPeopleCapitaPer($KingCount); //排位赛预计分配额 $expected_CEC_Sum = 0; foreach ($rankList as $k=>$value){ $r = $this->_getRedis($this->TopXunid.($value['echelonTopX']+1)); $TopX_List = $this->readRankingList($r,$this->TopXunid.($value['echelonTopX']+1)); $XX = $TopX_List ? $TopX_List[0]["rank_sort"]:10001; $rankList[$k]['standardTopX'] = $this->standardTopX($value['rank_sort'],$XX); $expected_CEC_Sum += $this->calcCECTopXSum($value['rank_sort'],$KingCount,$XX); } //排位赛金额% $rankAmountPre = min($maxSum/($expected_CEC_Sum+1),1); //MIN(当月排位赛最大分配额/(排位赛预计分配额+1),1) foreach ($rankList as $k=>$value){ // $rankList[$k]['rewardCEC'] = $value['standardTopX']*$rankAmountPre; if ($value['score'] >= $this->starshine){ $rankList[$k]['rewardCEC'] = $value['standardTopX']*$rankAmountPre; }else{ $rankList[$k]['rewardCEC'] = 0; } } } return $rankList; } //排位赛最大分配金额 private function calcCECMaxSum(){ //当月排位赛最大分配金额=ROUND(40000000/(12*(1+0.7^1+0.7^2+0.7^3+0.7^4+0.7^5+0.7^6+0.7^7))*0.7^(CEILING(月份数/12-0.01,1)-1),0)*70% $month = date('m',$this->_getNowTime()); return round(40000000/(12*(1+pow(0.7,1)+pow(0.7,2)+pow(0.7,3)+pow(0.7,4) +pow(0.7,5)+pow(0.7,6)+pow(0.7,7)))*pow(0.7,ceil($month/12-0.01)-1),0)*0.7; } //排位赛参与分配人数 private function calcPeopleCapita($kingCount){ //MIN(当月王者及以上用户数,ROUND(LOG10(当月王者及以上用户数+2)^3*1.5,1)*100) return min($kingCount,round(pow(log10($kingCount+2),3)*1.5,1)*100); } //排位赛人数% private function calcPeopleCapitaPer($kingCount){ //MIN(ROUND(0.31*MIN(当月王者及以上用户数,ROUND(LOG10(当月王者及以上用户数+1)^3*1.5,2)*100)^0.226,2),2) return min(round(0.31*pow(min($kingCount,round(pow(log10($kingCount+1),3)*1.5,2)*100),0.226),2),2); } //TopX梯队 private function echelonTopX($top){ //TopX梯队=SIGN(TopX<=3)*1+SIGN(TopX>3)*SIGN(TopX<=10)*2+SIGN(TopX>10)*SIGN(TopX<=50)*3 //+SIGN(TopX>50)*SIGN(TopX<=100)*4+SIGN(TopX>100)*SIGN(TopX<=500)*5+SIGN(TopX>500)*SIGN(TopX<=1000)*6 //+SIGN(TopX>1000)*SIGN(TopX<=2000)*7+SIGN(TopX>2000)*SIGN(TopX<=5000)*8 //+SIGN(TopX>5000)*SIGN(TopX<=10000)*9+SIGN(TopX>10000)*10 return ($top<=3?1:0)*1+($top>3?1:0)*($top<=10?1:0)*2+($top>10?1:0)*($top<=50?1:0)*3 +($top>50?1:0)*($top<=100?1:0)*4+($top>100?1:0)*($top<=500?1:0)*5+($top>500?1:0)*($top<=1000?1:0)*6 +($top>1000?1:0)*($top<=2000?1:0)*7+($top>2000?1:0)*($top<=5000?1:0)*8 +($top>5000?1:0)*($top<=10000?1:0)*9+($top>10000?1:0)*10; } //TopX开始值 private function startTopX($top){ //TopX开始值=SIGN(TopX梯队=1)*1+SIGN(TopX梯队=2)*4+SIGN(TopX梯队=3)*11+SIGN(TopX梯队=4)*51 //+SIGN(TopX梯队=5)*101+SIGN(TopX梯队=6)*501+SIGN(TopX梯队=7)*1001 //+SIGN(TopX梯队=8)*2001+SIGN(TopX梯队=9)*5001+SIGN(TopX梯队=10)*10001 return ($this->echelonTopX($top)==1?1:0)*1+($this->echelonTopX($top)==2?1:0)*4+($this->echelonTopX($top)==3?1:0)*11+($this->echelonTopX($top)==4?1:0)*51 +($this->echelonTopX($top)==5?1:0)*101+($this->echelonTopX($top)==6?1:0)*501+($this->echelonTopX($top)==7?1:0)*1001 +($this->echelonTopX($top)==8?1:0)*2001+($this->echelonTopX($top)==9?1:0)*5001+($this->echelonTopX($top)==10?1:0)*10001; } //TopX梯队最高值 private function maxTopX($top){ //TopX梯队最高值=ROUND(2000*0.6^(TopX梯队-1)*0.9^(TopX梯队-1),0) return round(2000*pow(0.6,$this->echelonTopX($top)-1)*pow(0.9,$this->echelonTopX($top)-1),0); } //TopX梯队最低值 private function minTopX($top){ //TopX梯队最低值=ROUND(2000*0.6^(TopX梯队)*0.9^(TopX梯队-1),0) return round(2000*pow(0.6,$this->echelonTopX($top))*pow(0.9,$this->echelonTopX($top)-1),0); } //TopX排位赛标准分配额 private function standardTopX($top,$XX){ //TopX排位赛标准分配额=MAX(ROUND(TopX梯队最高值-(TopX梯队最高值-TopX梯队最低值)/(TopX梯队开始值(TopX梯队+1)-TopX梯队开始值-1)*(TopX-TopX梯队开始值),2),TopX梯队最低值) return max(round($this->maxTopX($top)-($this->maxTopX($top)-$this->minTopX($top))/($XX-$this->startTopX($top)-1)*($top-$this->startTopX($top)),2),$this->minTopX($top)); } //TopX排位赛预计分配额 private function calcCECTopXSum($top,$kingCount,$XX){ //TopX排位赛标准分配额*排位赛人数% return $this->standardTopX($top,$XX)*$this->calcPeopleCapitaPer($kingCount); } //排位赛金额% private function rankAmountPre(){ //MIN(当月排位赛最大分配额/(排位赛预计分配额+1),1) } private function readRankingList($r,$rankUnid) { $list = $r->get(RANKING_KEY.$rankUnid); if (empty($list)) { return array(); } $list = json_decode($list, true); return $list; } private function saveRankingList($r,$rankUnid ,$list) { $r->set(RANKING_KEY.$rankUnid , json_encode($list)); $r->pexpire(RANKING_KEY.$rankUnid , 6*60*60*1000); } }