hy-farm/muchang/home/controllers/InteractionController.php
2026-05-30 20:23:54 +08:00

327 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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);
}
}