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
PHP
153 lines
5.1 KiB
PHP
<?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);
|
|
}
|
|
}
|