2026-05-29 19:54:56 +08:00

317 lines
11 KiB
PHP

<?php
/**
* Created by PhpStorm.
* User: zn
* Date: 2017/8/9
* Time: 11:51
*/
namespace common\modules\arena;
use common\models\User;
use common\modules\achievement\AchievementUtil;
use common\modules\arena\vo\Arena;
use common\modules\dailytask\DailyTaskUtil;
use common\modules\pet\vo\Pet;
use common\modules\safe\SafeUtil;
use common\modules\systemlog\SystemLogUtil;
use common\modules\vip\vo\Vip;
use common\services\ClientMessageServices;
use common\services\GameConfigServices;
use common\services\ResultStatusServices;
use common\services\StatusException;
use common\utils\CommUtil;
use common\utils\MoneyUtil;
use common\utils\RedisKeyUtil;
use Yii;
/**
* 竞技场
* Class
*/
class ArenaUtil
{
const GIFT_NOT_GET = 0;//未领取奖励
const GIFT_GET = 1;//已领取奖励
const GIFT_GET_LIST = [
self::GIFT_NOT_GET,
self::GIFT_GET,
];
const BATTLE_SUCCESS = 0;//战斗胜利
const BATTLE_FAIL = 1;//战斗失败
const BATTLE_RESULT_LIST = [
self::BATTLE_SUCCESS,
self::BATTLE_FAIL,
];
/**
* 获取前几名玩家
* @param int $count
* @return array
*/
public static function getRankList($count = 5)
{
return Arena::findRankList($count);
}
/**
* 获取玩家竞技场数据
* @param $userID
* @param bool $create
* @return Arena|null
* @throws StatusException
*/
public static function getArena($userID, $create = true)
{
$change = false;
$arena = Arena::findByUserID($userID);
if (empty($arena) && $create) {
$arena = new Arena();
$arena->user_id = $userID;
$user = User::findById($userID);
if (empty($user)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$arena->nickname = $user->nickname;
$arena->avatar = $user->avatar;
$pet = Pet::findEnterWarPetByUserID($userID);
if (empty($pet)) throw new StatusException(ResultStatusServices::RS_BATTLE_PET_NOT_ENTER_BATTLE);
$arena->pet_id = $pet->id;
$arena->fighting_capacity = $pet->fighting_capacity;
$arena->last_week_index = rand(10000, 20000);
$change = true;
}
if (!empty($arena)) {
if (CommUtil::dayStr(time()) != CommUtil::dayStr($arena->last_challenge_time)) {
$vip = Vip::findByUserID($userID);
$vipConfig = GameConfigServices::getParamByPath('vip_list.' . $vip->level);
$vipCount = 0;
if (!empty($vipConfig)) $vipCount = (int)$vipConfig['arena'];
$arena->remaining_challenges_count = GameConfigServices::getCommonNumByID(GameConfigServices::COMMON_ENTER_ARENA_COUNT) + $vipCount;
$change = true;
}
if ($arena->is_get_gift == ArenaUtil::GIFT_GET && CommUtil::getWeekTime(time() - 3600 * 24 * 7) != CommUtil::getWeekTime($arena->last_get_gift_time)) {
$arena->is_get_gift = ArenaUtil::GIFT_NOT_GET;
$change = true;
}
if ($change && !$arena->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR, $arena->getErrors());
}
return $arena;
}
public static function weekGiftList($weekTime, $create = false)
{
$str = Yii::$app->redis->get(RedisKeyUtil::weekGiftList($weekTime));
$allList = null;
if (!empty($str)) $allList = json_decode($str, true);
if (empty($allList) || $create) {
$allList = [];
$configList = GameConfigServices::getParamByPath('arena');
foreach ($configList as $config) {
$itemObj = [];
$itemObj['ranking_min_id'] = intval($config['ranking_min_id']);
$itemObj['ranking_mzx_id'] = intval($config['ranking_mzx_id']);
$itemObj['fixed_id'] = $config['fixed_id'];
$itemObj['fixed_id2'] = $config['fixed_id2'];
//随机奖励
if (isset($config['random_id'])) {
$itemStr = $config['random_id'];
$list = explode(',', $itemStr);
if (count($list) == 0) return null;
$oddList = [];
foreach ($list as $str) {
list($itemID, $count, $odds) = explode(':', $str);
if (empty($itemID) || empty($odds) || empty($count)) continue;
array_push($oddList, ['itemID' => $itemID, 'odds' => $odds, 'count' => $count]);
}
$item = CommUtil::oddsOne($oddList, "odds");
if (empty($item)) return null;
$str = sprintf('%s:%d', $item['itemID'], $item['count']);
$itemObj['random_id'] = $str;
} else {
$itemObj['random_id'] = '';
}
array_push($allList, $itemObj);
}
$jsonStr = json_encode($allList);
Yii::$app->redis->set(RedisKeyUtil::weekGiftList($weekTime), $jsonStr, 3600 * 24 * 7 * 2);
}
Yii::warning($allList);
return $allList;
}
/**
* 获取挑战对手列表
* @param $userID
* @return array|null
* @throws StatusException
*/
public static function getChallengeList($userID)
{
$arena = self::getArena($userID);
return Arena::findAllByFightingCapacity($userID, $arena->fighting_capacity,$arena->score);
}
/**
* 挑战结果
* @param $fromUserID
* @param $beUserID
* @param $type
*/
public static function challenge($fromUserID, $beUserID, $type)
{
SafeUtil::dbOperate(function ($fromUserID, $beUserID, $type) {
if ($fromUserID == $beUserID) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
if (!in_array($type, self::BATTLE_RESULT_LIST)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$fromArena = self::getArena($fromUserID);
if (empty($fromArena)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
if ($fromArena->remaining_challenges_count == 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$disTime = GameConfigServices::getCommonNumByID(GameConfigServices::COMMON_ARENA_TIME_DIS);
if (time() < $fromArena->last_challenge_time + $disTime) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$pet = Pet::findByPetID($fromArena->pet_id);
if (empty($pet)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
if ($pet->end_brooding_time > time()) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$petConfig = GameConfigServices::getParamByPath('pet.' . $pet->pet_config_id);
if (empty($petConfig)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$hunger = intval($petConfig['hunger']);
if ($hunger < 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$pet->feed -= $hunger;
if ($pet->feed < 0) $pet->feed = 0;
if (!$pet->save(true, ['feed', 'updated_at'])) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
$fromArena->remaining_challenges_count -= 1;
$fromArena->last_challenge_time = time();
if ($type == self::BATTLE_SUCCESS) {
DailyTaskUtil::addTaskCount($fromUserID, DailyTaskUtil::TYPE_ENTER_GYMKHANA_SUCCESS, null, 1);
AchievementUtil::addCount($fromUserID, AchievementUtil::ID_GYMKHANA_SUCCESS, 1);
}
DailyTaskUtil::addTaskCount($fromUserID, DailyTaskUtil::TYPE_ENTER_GYMKHANA, null, 1);
AchievementUtil::addCount($fromUserID, AchievementUtil::ID_ENTER_GYMKHANA, 1);
if ($type != self::BATTLE_SUCCESS) {
$fromArena->fail_count++;
if (!$fromArena->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
return;
}
$beArena = self::getArena($beUserID);
$fromArena->score = $beArena->score + 1;
$fromArena->win_count++;
if (!$fromArena->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
}, [$fromUserID, $beUserID, $type]);
}
/**
* 获取奖励
* @param $userID
* @return array
*/
public static function getGift($userID)
{
$getItemList = SafeUtil::dbOperate(function ($userID) {
return SafeUtil::redisLockOperate(function ($userID) {
$week = CommUtil::getWeekTime(time() - 3600 * 24 * 7);
$arena = Arena::findByUserID($userID);
if (empty($arena)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
if ($arena->is_get_gift != self::GIFT_NOT_GET) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
$getItemList = [];
$configList = self::weekGiftList($week);
foreach ($configList as $config) {
$min = $config['ranking_min_id'];
$max = $config['ranking_mzx_id'];
if ($arena->last_week_index >= $min && $arena->last_week_index <= $max) {
$getItem = MoneyUtil::parseItem($config['fixed_id'], 1, false, $userID, SystemLogUtil::FROM_TYPE_GET_ARENA_GIFT, ['config' => $config]);
if (!empty($getItem)) array_push($getItemList, $getItem);
$getItem = MoneyUtil::parseItem($config['fixed_id2'], 1, false, $userID, SystemLogUtil::FROM_TYPE_GET_ARENA_GIFT, ['config' => $config]);
if (!empty($getItem)) array_push($getItemList, $getItem);
$getItem = MoneyUtil::parseItem($config['random_id'], 1, false, $userID, SystemLogUtil::FROM_TYPE_GET_ARENA_GIFT, ['config' => $config]);
if (!empty($getItem)) array_push($getItemList, $getItem);
}
}
$arena->is_get_gift = self::GIFT_GET;
$arena->last_get_gift_time = time() - 3600 * 24 * 7;
if (!$arena->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
return $getItemList;
}, [$userID], RedisKeyUtil::lockArena($userID));
}, [$userID]);
return ClientMessageServices::sendMessage(ResultStatusServices::RS_OPERATION_SUCCESS, $getItemList);
}
public static function updatePet($userID, Pet $pet)
{
$arena = self::getArena($userID, false);
if (!empty($arena)) {
$arena->pet_id = $pet->id;
$arena->fighting_capacity = $pet->fighting_capacity;
if (!$arena->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
}
$user = User::findById($userID);
$user->fighting_capacity = $pet->fighting_capacity;
if (!$user->save(true, ['fighting_capacity', 'updated_at'])) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
}
public static function nowWeekGiftList()
{
return self::weekGiftList(CommUtil::getWeekTime(time()));
}
}