Merge branch 'master' of https://git.isekai.cn/Isekai-Project/mediawiki-extension-IsekaiUserPoints
commit
839eae0239
@ -0,0 +1,2 @@
|
|||||||
|
<?php
|
||||||
|
$specialPageAliases = [];
|
@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"name": "IsekaiUserPointsQuests",
|
||||||
|
"namemsg": "isekai-userpoints-quests",
|
||||||
|
"author": "Hyperzlib",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"url": "https://git.isekai.cn/Isekai-Project/mediawiki-extension-IsekaiUserPoints",
|
||||||
|
"descriptionmsg": "isekai-userpoints-quests-desc",
|
||||||
|
"license-name": "MIT",
|
||||||
|
"type": "api",
|
||||||
|
"requires": {
|
||||||
|
"MediaWiki": ">= 1.39.0"
|
||||||
|
},
|
||||||
|
"MessagesDirs": {
|
||||||
|
"IsekaiUserPointsQuests": [
|
||||||
|
"i18n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ExtensionMessagesFiles": {
|
||||||
|
"IsekaiUserPointsQuestsAlias": "IsekaiUserPointsQuests.alias.php"
|
||||||
|
},
|
||||||
|
"AutoloadNamespaces": {
|
||||||
|
"Isekai\\UserPoints\\Quests\\": "includes"
|
||||||
|
},
|
||||||
|
"Hooks": {
|
||||||
|
"LoadExtensionSchemaUpdates": "Isekai\\UserPoints\\Quests\\Hooks::onLoadExtensionSchemaUpdates",
|
||||||
|
"PageSaveComplete": "Isekai\\UserPoints\\Quests\\Hooks::onPageSaveComplete",
|
||||||
|
"BeforePageDisplay": "Isekai\\UserPoints\\Quests\\Hooks::onBeforePageDisplay"
|
||||||
|
},
|
||||||
|
"ResourceModules": {
|
||||||
|
"ext.isekai.userpoints.quests.notification": {
|
||||||
|
"scripts": ["ext.isekai.userpoints.quests.notification.js"],
|
||||||
|
"messages": [
|
||||||
|
"comma-separator",
|
||||||
|
"isekai-userpoints-point-name-num",
|
||||||
|
"isekai-quests-complete-notification-title",
|
||||||
|
"isekai-quests-complete-notification-message",
|
||||||
|
"isekai-quests-daily-count",
|
||||||
|
"isekai-quests-weekly-count",
|
||||||
|
"isekai-quests-monthly-count",
|
||||||
|
"isekai-quests-type-edit-notification",
|
||||||
|
"isekai-quests-type-create-notification"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ResourceFileModulePaths": {
|
||||||
|
"localBasePath": "modules",
|
||||||
|
"remoteExtPath": "IsekaiUserPoints/Quests/modules"
|
||||||
|
},
|
||||||
|
"APIModules": {
|
||||||
|
"userquestsgetnotification": "Isekai\\UserPoints\\Quests\\Api\\ApiUserQuestsGetNotification"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"IsekaiQuestsConfig": {
|
||||||
|
"value": {
|
||||||
|
"new": {
|
||||||
|
"periodQuestNumber": 1,
|
||||||
|
"periodType": "daily",
|
||||||
|
"points": {
|
||||||
|
"exp": {
|
||||||
|
"points": [60]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"periodQuestNumber": 2,
|
||||||
|
"periodType": "daily",
|
||||||
|
"points": {
|
||||||
|
"exp": {
|
||||||
|
"points": [40, 40]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"IsekaiQuestsTaskConfig": {
|
||||||
|
"value": {
|
||||||
|
"edit": {
|
||||||
|
"unitPoints": {
|
||||||
|
"exp": 10
|
||||||
|
},
|
||||||
|
"maxPoints": {
|
||||||
|
"exp": 400
|
||||||
|
},
|
||||||
|
"unitWords": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"manifest_version": 2
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
namespace Isekai\UserPoints\Quests\Api;
|
||||||
|
|
||||||
|
use ApiBase;
|
||||||
|
use Isekai\UserPoints\Quests\QuestsUtils;
|
||||||
|
use MediaWiki\Session\SessionManager;
|
||||||
|
|
||||||
|
class ApiUserQuestsGetNotification extends ApiBase {
|
||||||
|
public function __construct( $main, $method ) {
|
||||||
|
parent::__construct( $main->getMain(), $method );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function execute() {
|
||||||
|
$user = $this->getUser();
|
||||||
|
|
||||||
|
if (!$user->isRegistered()) {
|
||||||
|
$this->dieWithError('apierror-mustbeloggedin-generic', 'login-required');
|
||||||
|
}
|
||||||
|
|
||||||
|
$sesssionManager = SessionManager::getGlobalSession();
|
||||||
|
if ($sesssionManager->exists(QuestsUtils::SESSION_KEY_QUEST_COMPLETE_NOTIFICATION)) {
|
||||||
|
$notificationData = $sesssionManager->get(QuestsUtils::SESSION_KEY_QUEST_COMPLETE_NOTIFICATION);
|
||||||
|
$this->getResult()->addValue(['userquestsgetnotification'], 'notification', $notificationData);
|
||||||
|
} else {
|
||||||
|
$this->getResult()->addValue(['userquestsgetnotification'], 'notification', null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isInternal() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Isekai\UserPoints\Quests;
|
||||||
|
|
||||||
|
use MediaWiki\MediaWikiServices;
|
||||||
|
use MediaWiki\Session\SessionManager;
|
||||||
|
use OutputPage;
|
||||||
|
|
||||||
|
class Hooks {
|
||||||
|
/**
|
||||||
|
* Implements LoadExtensionSchemaUpdates hook.
|
||||||
|
*
|
||||||
|
* @param \DatabaseUpdater $updater
|
||||||
|
*/
|
||||||
|
public static function onLoadExtensionSchemaUpdates($updater) {
|
||||||
|
$dir = dirname(__DIR__) . '/sql/';
|
||||||
|
$type = $updater->getDB()->getType();
|
||||||
|
$updater->addExtensionTable('isekai_user_quests_record', $dir . $type . '/isekai_user_quests_record.sql');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \WikiPage $wikiPage
|
||||||
|
* @param \MediaWiki\User\UserIdentity $user
|
||||||
|
* @param string $summary
|
||||||
|
* @param int $flags
|
||||||
|
* @param \MediaWiki\Revision\RevisionRecord $revisionRecord
|
||||||
|
* @param \MediaWiki\Storage\EditResult $editResult
|
||||||
|
*/
|
||||||
|
public static function onPageSaveComplete($wikiPage, $user, $summary, $flags, $revisionRecord, $editResult) {
|
||||||
|
wfDebugLog('IsekaiQuests', 'onPageSaveComplete');
|
||||||
|
$services = MediaWikiServices::getInstance();
|
||||||
|
$config = $services->getMainConfig();
|
||||||
|
|
||||||
|
$questsConfig = $config->get('IsekaiQuestsConfig');
|
||||||
|
|
||||||
|
$allowedNamespaces = [NS_MAIN, NS_CATEGORY, NS_TEMPLATE, NS_HELP];
|
||||||
|
|
||||||
|
if (in_array($wikiPage->getNamespace(), $allowedNamespaces)) {
|
||||||
|
if ($flags & EDIT_NEW && isset($questsConfig['new'])) {
|
||||||
|
// 新建页面
|
||||||
|
$questConfig = $questsConfig['new'];
|
||||||
|
|
||||||
|
$questRes = QuestsUtils::onQuestComplete($user, 'new', $questConfig);
|
||||||
|
wfDebugLog('IsekaiQuests', 'quest finished: ', var_export($questRes, true));
|
||||||
|
if ($questRes) {
|
||||||
|
QuestsUtils::setQuestCompleteNotification('new', $questRes['deltaPoints'], $questRes['completeNum'], $questConfig);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果新建页面的任务次数已满,则作为编辑页面处理
|
||||||
|
if ($flags & EDIT_UPDATE && isset($questsConfig['edit'])) {
|
||||||
|
// 编辑页面
|
||||||
|
$questConfig = $questsConfig['edit'];
|
||||||
|
|
||||||
|
$questRes = QuestsUtils::onQuestComplete($user, 'edit', $questConfig);
|
||||||
|
wfDebugLog('IsekaiQuests', 'quest finished: ', var_export($questRes, true));
|
||||||
|
if ($questRes) {
|
||||||
|
QuestsUtils::setQuestCompleteNotification('edit', $questRes['deltaPoints'], $questRes['completeNum'], $questConfig);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function onBeforePageDisplay(OutputPage $out, $skin) {
|
||||||
|
$out->addModules(['ext.isekai.userpoints.quests.notification']);
|
||||||
|
|
||||||
|
$sessionManager = SessionManager::getGlobalSession();
|
||||||
|
if ($sessionManager->exists(QuestsUtils::SESSION_KEY_QUEST_COMPLETE_NOTIFICATION)) {
|
||||||
|
$out->addJsConfigVars([
|
||||||
|
'wgIsekaiQuestsCompleteNotification' => $sessionManager->get(QuestsUtils::SESSION_KEY_QUEST_COMPLETE_NOTIFICATION),
|
||||||
|
]);
|
||||||
|
$sessionManager->remove(QuestsUtils::SESSION_KEY_QUEST_COMPLETE_NOTIFICATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,152 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Isekai\UserPoints\Quests;
|
||||||
|
|
||||||
|
use MediaWiki\MediaWikiServices;
|
||||||
|
use 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);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
CREATE TABLE /*_*/isekai_user_quests_record (
|
||||||
|
`id` INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
`user_id` INT UNSIGNED NOT NULL,
|
||||||
|
`quest_type` VARCHAR(60) NOT NULL,
|
||||||
|
`period_time` VARCHAR(50) NOT NULL,
|
||||||
|
`quest_complete_num` INT UNSIGNED NOT NULL DEFAULT '0'
|
||||||
|
) /*$wgDBTableOptions*/;
|
||||||
|
ALTER TABLE /*_*/isekai_user_quests_record ADD INDEX (`user_id`, `quest_type`);
|
||||||
|
ALTER TABLE /*_*/isekai_user_quests_record ADD INDEX (`user_id`);
|
@ -0,0 +1,9 @@
|
|||||||
|
CREATE TABLE isekai_user_quests_record (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user_id INT NOT NULL,
|
||||||
|
quest_type VARCHAR(60) NOT NULL,
|
||||||
|
period_time VARCHAR(50) NOT NULL,
|
||||||
|
quest_complete_num INT NOT NULL DEFAULT 0
|
||||||
|
);
|
||||||
|
ALTER TABLE isekai_user_points_log ADD INDEX (user_id, quest_type);
|
||||||
|
ALTER TABLE isekai_user_points_log ADD INDEX (user_id);
|
@ -1,105 +1,106 @@
|
|||||||
{
|
{
|
||||||
"name": "Isekai User Points",
|
"name": "IsekaiUserPoints",
|
||||||
"namemsg": "isekai-userpoints",
|
"namemsg": "isekai-userpoints",
|
||||||
"author": "Hyperzlib",
|
"author": "Hyperzlib",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"url": "https://git.isekai.cn/Isekai-Project/mediawiki-extension-IsekaiUserPoints",
|
"url": "https://git.isekai.cn/Isekai-Project/mediawiki-extension-IsekaiUserPoints",
|
||||||
"descriptionmsg": "isekai-userpoints-desc",
|
"descriptionmsg": "isekai-userpoints-desc",
|
||||||
"license-name": "GPL-2.0-or-later",
|
"license-name": "MIT",
|
||||||
"type": "api",
|
"type": "api",
|
||||||
"requires": {
|
"requires": {
|
||||||
"MediaWiki": ">= 1.35.0"
|
"MediaWiki": ">= 1.39.0"
|
||||||
},
|
},
|
||||||
"MessagesDirs": {
|
"MessagesDirs": {
|
||||||
"IsekaiUserPoints": [
|
"IsekaiUserPoints": [
|
||||||
"i18n"
|
"i18n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ExtensionMessagesFiles": {
|
"ExtensionMessagesFiles": {
|
||||||
"IsekaiUserPointsAlias": "IsekaiUserPoints.alias.php"
|
"IsekaiUserPointsAlias": "IsekaiUserPoints.alias.php"
|
||||||
},
|
},
|
||||||
"AutoloadNamespaces": {
|
"AutoloadNamespaces": {
|
||||||
"Isekai\\UserPoints\\": "includes"
|
"Isekai\\UserPoints\\": "includes"
|
||||||
},
|
},
|
||||||
"Hooks": {
|
"Hooks": {
|
||||||
"LoadExtensionSchemaUpdates": "Isekai\\UserPoints\\Hooks::onLoadExtensionSchemaUpdates",
|
"LoadExtensionSchemaUpdates": "Isekai\\UserPoints\\Hooks::onLoadExtensionSchemaUpdates",
|
||||||
"BeforePageDisplay": "Isekai\\UserPoints\\Hooks::onBeforePageDisplay",
|
"BeforePageDisplay": "Isekai\\UserPoints\\Hooks::onBeforePageDisplay",
|
||||||
"GetPreferences": "Isekai\\UserPoints\\Hooks::onGetPreferences"
|
"GetPreferences": "Isekai\\UserPoints\\Hooks::onGetPreferences",
|
||||||
},
|
"ResourceLoaderGetConfigVars": "Isekai\\UserPoints\\Hooks::onResourceLoaderGetConfigVars"
|
||||||
"APIModules": {
|
},
|
||||||
"userdailysign": "Isekai\\UserPoints\\Api\\ApiUserDailySign"
|
"APIModules": {
|
||||||
},
|
"userdailysign": "Isekai\\UserPoints\\Api\\ApiUserDailySign"
|
||||||
"APIPropModules": {
|
},
|
||||||
"userpoints": "Isekai\\UserPoints\\Api\\ApiQueryUserPoints",
|
"APIPropModules": {
|
||||||
"pointinfo": "Isekai\\UserPoints\\Api\\ApiQueryPointInfo"
|
"userpoints": "Isekai\\UserPoints\\Api\\ApiQueryUserPoints",
|
||||||
},
|
"pointinfo": "Isekai\\UserPoints\\Api\\ApiQueryPointInfo"
|
||||||
"APIListModules": {
|
},
|
||||||
"userspoints": "Isekai\\UserPoints\\Api\\ApiQueryUsersPoints"
|
"APIListModules": {
|
||||||
},
|
"userspoints": "Isekai\\UserPoints\\Api\\ApiQueryUsersPoints"
|
||||||
"ServiceWiringFiles": [
|
},
|
||||||
"IsekaiUserPoints.services.php"
|
"ServiceWiringFiles": [
|
||||||
],
|
"IsekaiUserPoints.services.php"
|
||||||
"GroupPermissions": {
|
],
|
||||||
"bureaucrat": {
|
"GroupPermissions": {
|
||||||
"queryuserpoints": true,
|
"bureaucrat": {
|
||||||
"edituserpoints": true
|
"queryuserpoints": true,
|
||||||
},
|
"edituserpoints": true
|
||||||
"suppress": {
|
},
|
||||||
"queryuserpoints": true,
|
"suppress": {
|
||||||
"edituserpoints": true
|
"queryuserpoints": true,
|
||||||
},
|
"edituserpoints": true
|
||||||
"sysop": {
|
},
|
||||||
"queryuserpoints": true,
|
"sysop": {
|
||||||
"edituserpoints": true
|
"queryuserpoints": true,
|
||||||
}
|
"edituserpoints": true
|
||||||
},
|
}
|
||||||
"GrantPermissions": {
|
},
|
||||||
"userpointsmanager": {
|
"GrantPermissions": {
|
||||||
"queryuserpoints": true,
|
"userpointsmanager": {
|
||||||
"edituserpoints": true
|
"queryuserpoints": true,
|
||||||
}
|
"edituserpoints": true
|
||||||
},
|
}
|
||||||
"ResourceModules": {
|
},
|
||||||
"ext.isekai.userpoints.base": {
|
"ResourceModules": {
|
||||||
"styles": ["ext.isekai.userpoints.base.less"]
|
"ext.isekai.userpoints.base": {
|
||||||
},
|
"styles": ["ext.isekai.userpoints.base.less"]
|
||||||
"ext.isekai.userpoints.dailysign": {
|
},
|
||||||
"scripts": ["ext.isekai.userpoints.dailysign.js"],
|
"ext.isekai.userpoints.dailysign": {
|
||||||
"messages": [
|
"scripts": ["ext.isekai.userpoints.dailysign.js"],
|
||||||
"comma-separator",
|
"messages": [
|
||||||
"isekai-userpoints-point-name-num",
|
"comma-separator",
|
||||||
"isekai-userpoints-dailysign-notify-title",
|
"isekai-userpoints-point-name-num",
|
||||||
"isekai-userpoints-dailysign-notify-success"
|
"isekai-userpoints-dailysign-notify-title",
|
||||||
]
|
"isekai-userpoints-dailysign-notify-success"
|
||||||
}
|
]
|
||||||
},
|
}
|
||||||
"ResourceFileModulePaths": {
|
},
|
||||||
"localBasePath": "modules",
|
"ResourceFileModulePaths": {
|
||||||
"remoteExtPath": "IsekaiUserPoints/modules"
|
"localBasePath": "modules",
|
||||||
},
|
"remoteExtPath": "IsekaiUserPoints/modules"
|
||||||
"config": {
|
},
|
||||||
"IsekaiUserPointConfig": {
|
"config": {
|
||||||
"value": {
|
"IsekaiUserPointConfig": {
|
||||||
"exp": {
|
"value": {
|
||||||
"name": "Exp.",
|
"exp": {
|
||||||
"namemsg": "isekai-userpoints-point-name-exp",
|
"name": "Exp.",
|
||||||
"icon": {
|
"namemsg": "isekai-userpoints-point-name-exp",
|
||||||
"normal": {
|
"icon": {
|
||||||
"image": "https://static.isekai.dev/isekaiwiki/isekaiwiki-exp.png"
|
"normal": {
|
||||||
},
|
"image": "https://static.isekai.dev/isekaiwiki/isekaiwiki-exp.png"
|
||||||
"invert": {
|
},
|
||||||
"image": "https://static.isekai.dev/isekaiwiki/isekaiwiki-exp-invert.png"
|
"invert": {
|
||||||
}
|
"image": "https://static.isekai.dev/isekaiwiki/isekaiwiki-exp-invert.png"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
"IsekaiUserPointShowOnUserPerferences": {
|
},
|
||||||
"value": true
|
"IsekaiUserPointShowOnUserPerferences": {
|
||||||
},
|
"value": true
|
||||||
"IsekaiUserDailySignConfig": {
|
},
|
||||||
"value": null
|
"IsekaiUserDailySignConfig": {
|
||||||
}
|
"value": null
|
||||||
},
|
}
|
||||||
"manifest_version": 2
|
},
|
||||||
|
"manifest_version": 2
|
||||||
}
|
}
|
@ -1,43 +1,64 @@
|
|||||||
$(function() {
|
$(function() {
|
||||||
const storeKey = 'isekai-userpoints-dailysign-lastSignDate';
|
if (!mw.user.isAnon()) {
|
||||||
const lastSignDate = localStorage.getItem(storeKey);
|
var storeKey = 'isekai-userpoints-dailysign-lastSignDate';
|
||||||
const today = new Date().toLocaleDateString();
|
var lastSignDate = localStorage.getItem(storeKey);
|
||||||
if (lastSignDate !== today) {
|
|
||||||
let mwApi = new mw.Api();
|
|
||||||
mwApi.postWithToken('csrf', {
|
|
||||||
action: 'userdailysign',
|
|
||||||
}).done(function(data) {
|
|
||||||
if (data.userdailysign && data.userdailysign.success) {
|
|
||||||
if (Array.isArray(data.userdailysign.point_delta)) {
|
|
||||||
const pointDelta = data.userdailysign.point_delta;
|
|
||||||
let pointMsgList = [];
|
|
||||||
pointDelta.forEach(function (pointDeltaInfo) {
|
|
||||||
let msg = mw.msg('isekai-userpoints-point-name-num', pointDeltaInfo.name, pointDeltaInfo.icon, pointDeltaInfo.points);
|
|
||||||
pointMsgList.push(msg);
|
|
||||||
});
|
|
||||||
let separator = mw.msg('comma-separator');
|
|
||||||
let pointMsg = pointMsgList.join(separator);
|
|
||||||
|
|
||||||
let notificationMsg = mw.msg('isekai-userpoints-dailysign-notify-success', pointMsg);
|
function getDateWithTimezone(deltaMinutes) {
|
||||||
mw.notify('', {
|
var date = new Date();
|
||||||
title: mw.msg('isekai-userpoints-dailysign-notify-title'),
|
var offset = date.getTimezoneOffset();
|
||||||
tag: 'isekai-userpoints-dailysign',
|
var offsetMilliSeconds = offset * 60 * 1000;
|
||||||
id: 'isekai-userpoints-dailysign-notify',
|
var deltaMilliSeconds = deltaMinutes * 60 * 1000;
|
||||||
});
|
var newDate = new Date(date.getTime() + offsetMilliSeconds + deltaMilliSeconds);
|
||||||
|
return newDate;
|
||||||
|
}
|
||||||
|
|
||||||
function changeNotifyContent() {
|
function getDateString(dateObj) {
|
||||||
let notifyDom = document.querySelector('#isekai-userpoints-dailysign-notify');
|
var year = dateObj.getFullYear();
|
||||||
if (notifyDom) {
|
var month = dateObj.getMonth() + 1;
|
||||||
notifyDom.querySelector('.mw-notification-content').innerHTML = notificationMsg;
|
var date = dateObj.getDate();
|
||||||
} else {
|
return year + '-' + month + '-' + date;
|
||||||
requestAnimationFrame(changeNotifyContent);
|
}
|
||||||
|
|
||||||
|
var timezoneOffset = mw.config.get('wgTimezoneOffsetMinutes');
|
||||||
|
var today = getDateString(getDateWithTimezone(timezoneOffset));
|
||||||
|
|
||||||
|
if (lastSignDate !== today) {
|
||||||
|
var mwApi = new mw.Api();
|
||||||
|
mwApi.postWithToken('csrf', {
|
||||||
|
action: 'userdailysign',
|
||||||
|
}).done(function(data) {
|
||||||
|
if (data.userdailysign && data.userdailysign.success) {
|
||||||
|
if (Array.isArray(data.userdailysign.point_delta)) {
|
||||||
|
var pointDelta = data.userdailysign.point_delta;
|
||||||
|
var pointMsgList = [];
|
||||||
|
pointDelta.forEach(function (pointDeltaInfo) {
|
||||||
|
var msg = mw.msg('isekai-userpoints-point-name-num', pointDeltaInfo.name, pointDeltaInfo.icon, pointDeltaInfo.points);
|
||||||
|
pointMsgList.push(msg);
|
||||||
|
});
|
||||||
|
var separator = mw.msg('comma-separator');
|
||||||
|
var pointMsg = pointMsgList.join(separator);
|
||||||
|
|
||||||
|
var notificationMsg = mw.msg('isekai-userpoints-dailysign-notify-success', pointMsg);
|
||||||
|
mw.notify('', {
|
||||||
|
title: mw.msg('isekai-userpoints-dailysign-notify-title'),
|
||||||
|
tag: 'isekai-userpoints-dailysign',
|
||||||
|
id: 'isekai-userpoints-dailysign-notify',
|
||||||
|
});
|
||||||
|
|
||||||
|
function changeNotifyContent() {
|
||||||
|
var notifyDom = document.querySelector('#isekai-userpoints-dailysign-notify');
|
||||||
|
if (notifyDom) {
|
||||||
|
notifyDom.querySelector('.mw-notification-content').innerHTML = notificationMsg;
|
||||||
|
} else {
|
||||||
|
requestAnimationFrame(changeNotifyContent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
changeNotifyContent();
|
changeNotifyContent();
|
||||||
|
}
|
||||||
|
localStorage.setItem(storeKey, today);
|
||||||
}
|
}
|
||||||
localStorage.setItem(storeKey, today);
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
Loading…
Reference in New Issue