You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
5.1 KiB
PHTML

<?php
namespace Isekai\UserPoints\Quests;
use MediaWiki\MediaWikiServices;
use MediaWiki\User\User;
use Isekai\UserPoints\Service\IsekaiUserPointsFactory;
use Isekai\UserPoints\Utils;
use MediaWiki\Session\SessionManager;
class QuestsUtils {
public const SESSION_KEY_QUEST_COMPLETE_NOTIFICATION = 'IsekaiQuests::questCompleteNotification';
public static function getUserQuestCompleteNum(User $user, string $questType, string $periodTime) {
$dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection(DB_REPLICA);
$res = $dbr->newSelectQueryBuilder()
->from('isekai_user_quests_record')
->where([
'user_id' => $user->getId(),
'quest_type' => $questType,
'period_time' => $periodTime,
])->field('quest_complete_num')
->fetchField();
if ($res === false) {
return 0;
}
return intval($res);
}
public static function setUserQuestCompleteNum(User $user, string $questType, string $periodTime, int $num) {
$dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection(DB_REPLICA);
$dbw = MediaWikiServices::getInstance()->getDBLoadBalancer()->getConnection(DB_PRIMARY);
$res = $dbr->selectField('isekai_user_quests_record', 'id', [
'user_id' => $user->getId(),
'quest_type' => $questType,
'period_time' => $periodTime,
], __METHOD__);
if ($res === false) {
$dbw->insert('isekai_user_quests_record', [
'user_id' => $user->getId(),
'quest_type' => $questType,
'period_time' => $periodTime,
'quest_complete_num' => $num,
], __METHOD__);
} else {
$dbw->update('isekai_user_quests_record', [
'quest_complete_num' => $num,
], [
'id' => $res,
], __METHOD__);
}
}
public static function onQuestComplete(User $user, string $questType, array $questConfig) {
$services = MediaWikiServices::getInstance();
$periodQuestNumber = $questConfig['periodQuestNumber'];
$periodType = $questConfig['periodType'];
$pointsConfig = $questConfig['points'];
$periodTime = QuestsUtils::getPeriodTime($periodType);
$completeNum = QuestsUtils::getUserQuestCompleteNum($user, $questType, $periodTime);
if ($completeNum > $periodQuestNumber) {
return false;
}
$deltaPoints = [];
/** @var IsekaiUserPointsFactory */
$userPointsFactory = $services->getService('IsekaiUserPoints');
foreach ($pointsConfig as $pointType => $pointConfig) {
$userPoints = $userPointsFactory->newFromUser($user, $pointType);
if ($userPoints) {
$expireTime = $pointConfig['expireTime'] ?? -1;
$pointsAddConfig = $pointConfig['points'];
if (count($pointsAddConfig) > 0) {
// 获取当前任务完成次数对应的积分数量
$periodIndex = $completeNum % count($pointsAddConfig);
$pointsAdd = $pointsAddConfig[$periodIndex];
$userPoints->addPoints($pointsAdd, $expireTime, 'quests', $questType);
$deltaPoints[$pointType] = $pointsAdd;
}
}
}
$completeNum ++;
QuestsUtils::setUserQuestCompleteNum($user, $questType, $periodTime, $completeNum);
return [
'completeNum' => $completeNum,
'deltaPoints' => $deltaPoints,
];
}
/**
* Get period time string from period type
* @param string $periodType
* @return string
*/
public static function getPeriodTime($periodType = 'daily') {
switch ($periodType) {
case 'daily':
return date('Y-m-d');
case 'weekly':
return date('Y-W') . 'week';
case 'monthly':
return date('Y-m');
}
}
public static function setQuestCompleteNotification(string $questType, array $deltaPoints, $completeNum = null, ?array $questConfig = null) {
$sesssionManager = SessionManager::getGlobalSession();
$resultPointDelta = [];
foreach ($deltaPoints as $pointType => $delta) {
$pointName = Utils::getPointName($pointType);
$pointIcon = Utils::getPointIcon($pointType);
$resultPointDelta[] = [
'point_type' => $pointType,
'name' => $pointName,
'icon' => $pointIcon,
'points' => $delta,
];
}
$notificationData = [
'questType' => $questType,
'deltaPoints' => $resultPointDelta,
];
if ($questConfig) {
$notificationData['completeNum'] = $completeNum;
$notificationData['periodQuestNumber'] = $questConfig['periodQuestNumber'];
$notificationData['periodType'] = $questConfig['periodType'];
}
$sesssionManager->set(self::SESSION_KEY_QUEST_COMPLETE_NOTIFICATION, $notificationData);
}
}