327 lines
14 KiB
PHP
327 lines
14 KiB
PHP
<?php
|
||
/**
|
||
* Created by PhpStorm.
|
||
* User: zn
|
||
* Date: 2017/5/31
|
||
* Time: 15:46
|
||
*/
|
||
|
||
namespace app\controllers;
|
||
|
||
|
||
use common\models\Farm;
|
||
use common\models\Interaction;
|
||
use common\models\Land;
|
||
use common\models\User;
|
||
use common\modules\achievement\AchievementUtil;
|
||
use common\modules\dailytask\DailyTaskUtil;
|
||
use common\modules\systemlog\SystemLogUtil;
|
||
use common\services\ClientMessageServices;
|
||
use common\services\GameConfigServices;
|
||
use common\services\ItemServices;
|
||
use common\services\LandService;
|
||
use common\services\PetBattleService;
|
||
use common\services\ResultStatusServices;
|
||
use common\services\StaminaService;
|
||
use common\services\UserLogService;
|
||
use common\utils\EnumUtil;
|
||
use common\utils\RedisKeyUtil;
|
||
use RedisLock\RedisLock;
|
||
use Yii;
|
||
use yii\rest\Controller;
|
||
|
||
/**
|
||
* 玩家之间的互动
|
||
* Class InteractionController
|
||
* @package app\controllers
|
||
*/
|
||
class InteractionController extends Controller
|
||
{
|
||
/**
|
||
* 获取其他用户信息
|
||
*/
|
||
public function actionGetOtherUserInfo()
|
||
{
|
||
$userID = Yii::$app->request->get('user_id');
|
||
$beUserID = Yii::$app->request->get('be_user_id');
|
||
|
||
if (!$userID) return ClientMessageServices::sendMessage(ResultStatusServices::RS_USER_NOT_LOGIN);//验证登录
|
||
|
||
if (!$beUserID) return ClientMessageServices::sendMessage(ResultStatusServices::RS_PARAM_ERROR);
|
||
|
||
//获取其他用户数据
|
||
$userDbData = User::findById($beUserID);
|
||
if (!$userDbData)
|
||
return ClientMessageServices::sendMessage(ResultStatusServices::RS_USER_DISABLE_OR_NOT_FIND);
|
||
|
||
$farmDbData = Farm::findRedis($beUserID);
|
||
|
||
$returnData = $userDbData->genClientData();
|
||
foreach ($returnData['landList'] as $key => $landData) {
|
||
$landDbData = Land::findRedis($farmDbData->id, $landData['position']);
|
||
$typeList = LandService::getLandInteractionType($userID, $beUserID, $landDbData);
|
||
$returnData['landList'][$key]['interaction_type_list'] = $typeList;
|
||
}
|
||
|
||
return ClientMessageServices::sendMessage(ResultStatusServices::RS_OPERATION_SUCCESS, $returnData);
|
||
}
|
||
|
||
/**
|
||
* 偷菜等交互操作
|
||
*/
|
||
public function actionInteraction()
|
||
{
|
||
$userID = Yii::$app->request->get('user_id');
|
||
$type = Yii::$app->request->get('type');//交互操作类型
|
||
$beUserID = Yii::$app->request->get('be_user_id');//被操作用户ID
|
||
$position = Yii::$app->request->get('position');//要操作的农田位置
|
||
|
||
if (!$userID) return ClientMessageServices::sendMessage(ResultStatusServices::RS_USER_NOT_LOGIN);//验证登录
|
||
|
||
//验证操作类型
|
||
if (!in_array($type, EnumUtil::INTERACTION_TYPE_LIST) ||
|
||
!$beUserID || $beUserID == $userID ||
|
||
$position === null || $position < 0 || $position > EnumUtil::LAND_MAX_POSITION
|
||
)
|
||
return ClientMessageServices::sendMessage(ResultStatusServices::RS_PARAM_ERROR);
|
||
|
||
//验证要操作的用户
|
||
$beUserDbData = User::findById($beUserID);
|
||
if (!$beUserDbData)
|
||
return ClientMessageServices::sendMessage(ResultStatusServices::RS_NOT_FIND_USER);
|
||
|
||
$farmDbData = Farm::findOne(['user_id' => $beUserID]);
|
||
|
||
//更新农田状态
|
||
$rs = LandService::updateCropStatus($beUserID, $farmDbData->id, $position, $farmDbData->level);
|
||
if ($rs != ResultStatusServices::RS_OPERATION_SUCCESS)
|
||
return ClientMessageServices::sendMessage($rs);
|
||
|
||
$lock = new RedisLock(Yii::$app->redis, RedisKeyUtil::lockLandInteraction($userID, $beUserID, $position), RedisLock::FLAG_CATCH_EXCEPTIONS);
|
||
if (!$lock->acquire(10)) return ResultStatusServices::RS_SAME_TIME_OPERATION;
|
||
|
||
//更新操作状态
|
||
$stealCount = 0;//偷到的果实数量
|
||
$deductGold = 0;//旧抓捕兼容字段,宠物战斗制度下固定为0
|
||
$staminaData = null;//体力同步数据
|
||
$petBattleData = null;//宠物战斗同步数据
|
||
|
||
try {
|
||
|
||
//检查操作状态是否正确
|
||
$landDbData = Land::findRedis($farmDbData->id, $position);
|
||
$canTypeList = LandService::getLandInteractionType($userID, $beUserID, $landDbData);
|
||
|
||
if (!in_array($type, $canTypeList)) {
|
||
return ClientMessageServices::sendMessage(EnumUtil::INTERACTION_OPERATE_TYPE_ERROR_TO_RS_LIST[$type]);
|
||
}
|
||
|
||
if ($type == EnumUtil::INTERACTION_TYPE_STEAL) {
|
||
$stealGate = StaminaService::withStaminaLock($userID, function ($lockedUserID) use ($beUserID) {
|
||
$staminaCheck = StaminaService::checkStealUnlocked($lockedUserID);
|
||
if (empty($staminaCheck['ok'])) {
|
||
return [
|
||
'ok' => false,
|
||
'status' => $staminaCheck['status'],
|
||
'data' => ['stamina' => $staminaCheck['data']],
|
||
];
|
||
}
|
||
|
||
$battleResult = PetBattleService::resolveSteal($lockedUserID, $beUserID);
|
||
if (empty($battleResult['ok'])) {
|
||
return [
|
||
'ok' => false,
|
||
'status' => $battleResult['status'],
|
||
'data' => [
|
||
'stamina' => $staminaCheck['data'],
|
||
'pet_battle' => $battleResult['data'],
|
||
],
|
||
];
|
||
}
|
||
|
||
$staminaResult = StaminaService::consumeStealUnlocked($lockedUserID);
|
||
if (empty($staminaResult['ok'])) {
|
||
return [
|
||
'ok' => false,
|
||
'status' => $staminaResult['status'],
|
||
'data' => [
|
||
'stamina' => $staminaResult['data'],
|
||
'pet_battle' => $battleResult['data'],
|
||
],
|
||
];
|
||
}
|
||
|
||
return [
|
||
'ok' => true,
|
||
'status' => ResultStatusServices::RS_OPERATION_SUCCESS,
|
||
'data' => [
|
||
'stamina' => $staminaResult['data'],
|
||
'pet_battle' => $battleResult['data'],
|
||
],
|
||
];
|
||
});
|
||
|
||
if (empty($stealGate['ok'])) {
|
||
return ClientMessageServices::sendMessage($stealGate['status'], $stealGate['data']);
|
||
}
|
||
|
||
$staminaData = $stealGate['data']['stamina'];
|
||
$petBattleData = $stealGate['data']['pet_battle'];
|
||
if (!empty($petBattleData) && empty($petBattleData['allow_steal'])) {
|
||
$returnData = [
|
||
'position' => $position,
|
||
'type' => $type,
|
||
'steal_count' => $stealCount,
|
||
'deduct_gold' => $deductGold,
|
||
'stamina' => $staminaData,
|
||
'pet_battle' => $petBattleData,
|
||
'land' => $landDbData->genClientData(),
|
||
];
|
||
return ClientMessageServices::sendMessage(ResultStatusServices::RS_OPERATION_SUCCESS, $returnData);
|
||
}
|
||
}
|
||
|
||
$success = false;
|
||
$change = false;
|
||
$dbTrans = Yii::$app->db->beginTransaction();
|
||
try {
|
||
if ($type == EnumUtil::INTERACTION_TYPE_STEAL) {
|
||
//偷菜
|
||
|
||
//偷取农田
|
||
$rs = LandService::steal($farmDbData->id, $position, $stealCount, $userID, $beUserID);
|
||
if ($rs != ResultStatusServices::RS_OPERATION_SUCCESS)
|
||
return ClientMessageServices::sendMessage($rs);
|
||
|
||
//修改仓库数量
|
||
$cropConfig = GameConfigServices::getParamByPath('crop_list.' . $landDbData->crop_id);
|
||
$itemID = $cropConfig['item_id'];
|
||
$log = SystemLogUtil::get($userID, SystemLogUtil::TYPE_ITEM, $itemID, $stealCount, SystemLogUtil::FROM_TYPE_STEAL_GET, []);
|
||
$rs = ItemServices::checkAndModifyNum($userID, $itemID, true, $stealCount, $log);
|
||
if ($rs != ResultStatusServices::RS_OPERATION_SUCCESS)
|
||
return ClientMessageServices::sendMessage($rs);
|
||
|
||
//记录日志
|
||
UserLogService::addUserLog($userID, EnumUtil::USER_LOG_TYPE_STEAL, $itemID, $stealCount, $beUserID);
|
||
UserLogService::addUserLog($beUserID, EnumUtil::USER_LOG_TYPE_BE_STEAL, $itemID, $stealCount, $userID);
|
||
|
||
//任务记录
|
||
DailyTaskUtil::addTaskCount($userID, DailyTaskUtil::TYPE_STEAL_SUCCESS, null, 1);
|
||
|
||
//成就
|
||
AchievementUtil::addCount($userID, AchievementUtil::ID_STEAL, 1);
|
||
AchievementUtil::addCount($userID, AchievementUtil::ID_STEAL_SUCCESS, 1);
|
||
|
||
$change = true;
|
||
}
|
||
|
||
//放虫
|
||
if ($type == EnumUtil::INTERACTION_TYPE_BUG) {
|
||
$landDbData->has_bug = true;
|
||
if (!$landDbData->save(true, ['has_bug', 'updated_at']))
|
||
return ClientMessageServices::sendMessage(ResultStatusServices::RS_SAVE_DB_ERROR);
|
||
|
||
//记录日志
|
||
UserLogService::addUserLog($userID, EnumUtil::USER_LOG_TYPE_BUG, 0, 0, $beUserID);
|
||
UserLogService::addUserLog($beUserID, EnumUtil::USER_LOG_TYPE_BE_BUG, 0, 0, $userID);
|
||
|
||
$change = true;
|
||
}
|
||
|
||
//放草
|
||
if ($type == EnumUtil::INTERACTION_TYPE_GRASS) {
|
||
$landDbData->has_grass = 1;
|
||
if (!$landDbData->save(true, ['has_grass', 'updated_at']))
|
||
return ClientMessageServices::sendMessage(ResultStatusServices::RS_SAVE_DB_ERROR);
|
||
|
||
//记录日志
|
||
UserLogService::addUserLog($userID, EnumUtil::USER_LOG_TYPE_GRASS, 0, 0, $beUserID);
|
||
UserLogService::addUserLog($beUserID, EnumUtil::USER_LOG_TYPE_BE_GRASS, 0, 0, $userID);
|
||
|
||
$change = true;
|
||
}
|
||
|
||
// //浇水
|
||
// if ($type == EnumUtil::INTERACTION_TYPE_WATERING) {
|
||
// $landDbData->has_dry = false;
|
||
// if (!$landDbData->save(true, ['has_dry', 'updated_at']))
|
||
// return ClientMessageServices::sendMessage(ResultStatusServices::RS_SAVE_DB_ERROR);
|
||
//
|
||
// //记录日志
|
||
// UserLogService::addLog($userID, EnumUtil::USER_LOG_TYPE_WATERING, 0, 0, $beUserID);
|
||
// UserLogService::addLog($beUserID, EnumUtil::USER_LOG_TYPE_BE_WATERING, 0, 0, $userID);
|
||
//
|
||
// $change = true;
|
||
// }
|
||
//
|
||
// //除虫
|
||
// if ($type == EnumUtil::INTERACTION_TYPE_DISINSECTION) {
|
||
// $landDbData->has_bug = false;
|
||
// if (!$landDbData->save(true, ['has_bug', 'updated_at']))
|
||
// return ClientMessageServices::sendMessage(ResultStatusServices::RS_SAVE_DB_ERROR);
|
||
//
|
||
// //记录日志
|
||
// UserLogService::addLog($userID, EnumUtil::USER_LOG_TYPE_DISINSECTION, 0, 0, $beUserID);
|
||
// UserLogService::addLog($beUserID, EnumUtil::USER_LOG_TYPE_BE_DISINSECTION, 0, 0, $userID);
|
||
//
|
||
// $change = true;
|
||
// }
|
||
//
|
||
// //除草
|
||
// if ($type == EnumUtil::INTERACTION_TYPE_WEEDING) {
|
||
// $landDbData->has_grass = false;
|
||
// if (!$landDbData->save(true, ['has_grass', 'updated_at']))
|
||
// return ClientMessageServices::sendMessage(ResultStatusServices::RS_SAVE_DB_ERROR);
|
||
//
|
||
// //记录日志
|
||
// UserLogService::addLog($userID, EnumUtil::USER_LOG_TYPE_WEEDING, 0, 0, $beUserID);
|
||
// UserLogService::addLog($beUserID, EnumUtil::USER_LOG_TYPE_BE_WEEDING, 0, 0, $userID);
|
||
//
|
||
// $change = true;
|
||
// }
|
||
|
||
if ($change) {
|
||
//记录交互
|
||
$interactionDbData = new Interaction();
|
||
$interactionDbData->from_user_id = $userID;
|
||
$interactionDbData->be_user_id = $beUserID;
|
||
$interactionDbData->land_create_time = $landDbData->crop_start_time;
|
||
$interactionDbData->position = $landDbData->position;
|
||
$interactionDbData->type = $type;
|
||
$interactionDbData->num = $stealCount;
|
||
if (!$interactionDbData->save())
|
||
return ClientMessageServices::sendMessage(ResultStatusServices::RS_SAVE_DB_ERROR, $interactionDbData->getErrors());
|
||
}
|
||
|
||
$success = true;
|
||
} finally {
|
||
if ($success)
|
||
$dbTrans->commit();
|
||
else {
|
||
$dbTrans->rollBack();
|
||
Yii::$app->redis->clearDirtyKey();//清除脏缓存数据
|
||
}
|
||
}
|
||
} finally {
|
||
$lock->release();
|
||
}
|
||
|
||
//返回数据
|
||
$returnData['position'] = $position;
|
||
$returnData['type'] = $type;
|
||
$returnData['steal_count'] = $stealCount;
|
||
$returnData['deduct_gold'] = $deductGold;
|
||
if ($staminaData !== null) {
|
||
$returnData['stamina'] = $staminaData;
|
||
}
|
||
if ($petBattleData !== null) {
|
||
$returnData['pet_battle'] = $petBattleData;
|
||
}
|
||
|
||
$landDbData = Land::findRedis($farmDbData->id, $position);
|
||
$returnData['land'] = $landDbData->genClientData();
|
||
//ClientMessageServices::sendDebugInfo($landDbData->genClientData());
|
||
return ClientMessageServices::sendMessage(ResultStatusServices::RS_OPERATION_SUCCESS, $returnData);
|
||
}
|
||
}
|