• 欢迎来到THBWiki!如果您是第一次来到这里,请点击右上角注册一个帐户
  • 有任何意见、建议、求助、反馈都可以在 讨论板 提出
  • THBWiki以专业性和准确性为目标,如果你发现了任何确定的错误或疏漏,可在登录后直接进行改正

帮助:成就扩展

来自THBWiki
跳到导航 跳到搜索

成就扩展Github)是一个提供用户成就及用户头衔的Mediawiki插件,可以设置多种成就触发条件,不过某几种条件需要手动修改一下MediaWiki/其他扩展代码才能正常运作。推荐同时安装SocialProfileEcho

安装

  1. 你需要最新版本(0.4.0)的Achievements.zip
  2. 解压到extensions目录下。
  3. LocalSettings.php一处加上require_once( "$IP/extensions/Achievements/Achievements.php" );1
  4. 如要使用某几种类型,需要修改几个地方
  5. 在SQL数据库执行本扩展目录下的manual_import.sql2
  6. 安装完成。
  7. 按需要设定管理成就对应的“manageachievements”权限。
  8. 按需要设定cron
  9. 按需要设定成就

配置

  • $wgAchievementsIconStaged,分阶段成就的默认图标,默认为Wiki LOGO
  • $wgAchievementsIconNormal,普通成就的默认图标,默认为Wiki LOGO
  • $wgAchievementsTokenLength成就兑换码的长度,更改此值时需要修改对应的说明Message,默认为“10”。
  • $wgAchievementsScoring,是否启用成就计分及等级功能,默认为“false”。
  • $wgAchievementsConfigs,设定成就的关联数组,详见设定成就

成就类型

static
静态成就,需通过兑换码来获取。
editcount
编辑计数,可指定只计算某页面的子页面、某分类或某名字空间下的编辑次数。
edittop
编辑计数排名,可指定只计算某页面的子页面、某分类或某名字空间下的编辑次数。
friendcount
好友计数,好友系统是SocialProfile的一个功能,使用此类型需要修改部分SocialProfile代码
friendtop
好友计数排名,好友系统是SocialProfile的一个功能,使用此类型需要修改部分SocialProfile代码
foecount
仇敌计数,好友系统是SocialProfile的一个功能,使用此类型需要修改部分SocialProfile代码
foetop
仇敌计数排名,好友系统是SocialProfile的一个功能,使用此类型需要修改部分SocialProfile代码
frienduser
与指定用户成为好友,好友系统是SocialProfile的一个功能,使用此类型需要修改部分SocialProfile代码
watch
页面监视计数,可指定只计算某页面的子页面、某分类或某名字空间下的页面监视次数,使用此类型需要修改部分MediaWiki代码
usergroup
用户组计数,可指定用户组属于特定用户组时触发。
userprop
用户设定计数,可指定用户设定某种内容时触发。
useravatar
用户头像计数,头像系统是SocialProfile的一个功能。
useremail
用户验证邮件计数。
registerday
注册日数,使用此类型需要设定cron执行日更脚本。
viewcount
用户浏览计数,可以设定计数几率降低服务器写入负担。
viewtop
用户浏览计数排名,可以设定计数几率降低服务器写入负担。
random
随机计数,原理为在现在和指定时间后之间随机选个时间,那个时间后第一个浏览的用户便会获得计数。

设定cron

Cron是Linux系统中用于设置周期性被执行的指令,在这里用于定时更新计数器(例:registerday)及刷新并处理设定了定时更新的成就。进行上述操作的PHP脚本位于MW根目录下(/extensions/Achievements/scripts/reset.php),需要指定参数--i刷新对应时间更新的成就。

例如执行/extensions/Achievements/scripts/reset.php --i m便会刷新所有每月更新的成就,根据设定不同可能会收发对应成就、清空计数器或增加计数。所有可用的间隔为“d”(每日)、“w”(每周)和“m”(每月),你也可以通过Cron设置更多时间间隔并将成就设定成使用该间隔。

以下是设置Cron的范例:

0 22 * * * PHP路径 MW根目录/extensions/Achievements/scripts/reset.php --i d > /dev/null 2>&1
会在 每日 06:00 更新
0 23 * * 0 PHP路径 MW根目录/extensions/Achievements/scripts/reset.php --i w > /dev/null 2>&1
会在 每周一 07:00 更新
0 0 1 * * PHP路径 MW根目录/extensions/Achievements/scripts/reset.php --i m > /dev/null 2>&1
会在 每月一号 08:00 更新

具体在每天每周每月哪个时间点更新是无所谓的,不过注意更新操作可能需要一点时间,对于本站规模的用户量和成就量大概需要一分钟,为了能更准时更新建议把更新时间错开。

另外也可以自行添加更多间隔种类,例如“q”表示每季:

0 0 1 1,4,7,10 * PHP路径 MW根目录/extensions/Achievements/scripts/reset.php --i q > /dev/null 2>&1

如果使用了不同于以上设置的更新时间,就需要更改与更新间隔相关的几个Message:

如果添加了更多间隔种类,就需要用以下格式增加几个Message:

设定成就

大致可以参考本扩展目录下的Achievements.settings.example.php。所有成就可以设定的基本项目都是一样的,只是用了不同的type的成就counter里面的参数会有点差异,默认值也可能不一样,具体可以参考放在class/counters下的计数器Class。

所有成就通用的基本项目:

  • type,文本,成就计数器类型,默认为“static”(静态)。
  • image,文本或null,设定成就图标,会在各种地方随着成就显示,适当尺寸为60px×60px,默认为默认图标
  • counter,数组,计数器的设定,不同成就类型会需要不同的参数。
  • reset,文本或false,设定更新间隔,初始可用“d”、“w”、“m”,默认为“false”。
  • threshold,数字或数组,用数字设定单阶段成就,只有一个阶段,用户达到了就会触发;用数组设定分多个阶段的成就,用户进度达到一个阶段值就会获得对应成就,默认为“1”。
  • scoremul,数字,设定成就分数乘数,会在自动计算的分数上再乘以此数得出此成就的分数,默认为“1”。
  • exclude,文本或数组或false,设定一个或多个跟此成就互斥的成就,只要用户已经拥有列表中其中一个成就此成就将无法触发,默认为“false”。
  • multiple,布尔值,设定成就可重复颁发,设为“true”时用户再次满足成就要求时会再次颁发此成就,仅对设定了reset参数的成就有效,默认为“false”。
  • removable,布尔值,设定成就可移除,设为“true”时用户不满足此成就条件时会失去此成就,默认为“false”。
  • awardable,布尔值,设定成就可颁发,设为“true”时此成就便可以由管理员颁发,默认为“false”。
  • hidden,布尔值,设定是否隐藏成就,设为“true”时此成就就不会自动在用户成就列表中出现,只有拥有此成就的用户才能看到,默认为“false”。
  • active,布尔值,设定是否活跃成就,设为“true”时便是活跃成就,默认为“true”。
  • activerange,数组或false,设定限时成就的时限,设为“['开始UTC时间戳', '结束UTC时间戳']”(例:“['20180317160000', '20180318160000']”表示东8区2018年3月18日0时到2018年3月19日0时)时此成就将仅在以上期间内有效,默认为“false”。

编写设定时创建并写到Achievements.settings.php里就可以了。

添加新成就后需要为该新成就执行初始化脚本,“计数器初始值为0”及“只能手动颁发”的成就可以省略此步骤。

脚本

reset.php

用于定时更新的脚本,设定cron自动执行,切勿手动执行。
可用参数:

  • --i,指定间隔代号。
  • --nohook,防止执行RegularJobs::间隔代号Hook。

initAchievementCounter.php

用于初始化成就,于数据库写入计数器初始值,给已经达成成就条件的用户颁发成就。对于“计数器初始值为current”的成就,重复初始化不但不会造成bug,而且可以修正计数器长时间累计可能造成的误差,成就条件更改后也可以通过再初始化重新颁发及消去成就。
可用参数:

  • --achiev,指定需要初始化的成就ID。
  • --counter,指定需要初始化的成就计数器类型,这种方法可以一次过刷新多个同类成就。
  • --all,初始化所有成就。
  • --alluser,设定初始化范围包含所有用户,默认初始化只会包含有编辑的用户,适用于初始化编辑数类成就时节省无谓的开销,而一些跟编辑数无关的成就例如好友数就需要设定此参数确保所有用户都有机会获得成就。
  • --reset,设定初始化范围包含设定了周期更新的成就,默认初始化不会包含设定了周期更新的成就,避免长时间累积的计数被重设成0。
  • --suppress,防止发出获得及失去成就Echo通知。

特殊页面

管理成就

  • 需要“manageachievements”权限,用于选择执行所有管理操作。

兑换成就

  • 用于兑换成就,兑换码可在管理成就由有足够权限的用户生成。

成就计分

系统会自动根据成绩的类型、设定及估计难度计算合适的成就分数,管理员亦可以设定scoremul参数改变成就的分数。具体计算函数参见AchievementClass.php 中的 getStageScore 函数

等级计算

每个等级都有对应的分数,用户有足够分数时便会升至该等级。等级所需分数公式如下:

所需分数=等级×(等级+2)×10

前10级所需分数简表:

等级 所需分数
1 30
2 80
3 150
4 240
5 350
6 480
7 630
8 800
9 990
10 1200

功能展望

以下列表中提及的功能均尚未实现,亦不保证以后必定会有,仅供参考。

  • 更好的特殊:管理成就界面,增加各个模式之间的链接。
  • 更改头衔文本样式的方法,例如更改字体颜色大小。
  • 增加设定获取成就的基本门槛的功能,即用户需要满足一定条件才可以开始获得成就,防止自动颁发过多成就(例如注册日数成就)给不活跃的账户增加数据库负担。
  • 更多预设成就图标。
  • 更多类型的计数器。

修改地方

如果你不使用需要修改的那几个类型,不修改是不会出BUG的。

MediaWiki

/includes/specials/SpecialEditWatchlist.php

private function SpecialEditWatchlist::clearWatchlist内增加在清空监视列表时触发Hook的功能。

$dbw = wfGetDB( DB_MASTER );
$dbw->delete(
	'watchlist',
	[ 'wl_user' => $this->getUser()->getId() ],
	__METHOD__
);
改成
$dbw = wfGetDB( DB_MASTER );
$dbw->delete(
	'watchlist',
	[ 'wl_user' => $this->getUser()->getId() ],
	__METHOD__
);
Hooks::run( 'WatchArticleClearComplete', [ $this->getUser() ] );

SocialProfile

/UserRelationship/UserRelationshipClass.php

public function UserRelationship::addRelationship内把输入Hook的用户名称改成更容易识别的用户ID。

if ( $ur_type == 1 ) {
	Hooks::run( 'NewFriendAccepted', array( $ur_user_name_from, $this->user_name ) );
} else {
	Hooks::run( 'NewFoeAccepted', array( $ur_user_name_from, $this->user_name ) );
}
改成
if ( $ur_type == 1 ) {
	Hooks::run( 'NewFriendAccepted', array( $ur_user_id_from, $this->user_id ) );
} else {
	Hooks::run( 'NewFoeAccepted', array( $ur_user_id_from, $this->user_id ) );
}

public function UserRelationship::removeRelationshipByUserID内增加把取消关系类型信息也加进Hook里的功能。

$dbw = wfGetDB( DB_MASTER );

$dbw->delete(
	'user_relationship',
	array( 'r_user_id' => $user1, 'r_user_id_relation' => $user2 ),
	__METHOD__
);
改成
$dbw = wfGetDB( DB_MASTER );
$rel_type = (int)($dbw->selectField(
	'user_relationship',
	'r_type',
	array( 'r_user_id' => $user1, 'r_user_id_relation' => $user2 ),
	__METHOD__
));
$dbw->delete(
	'user_relationship',
	array( 'r_user_id' => $user1, 'r_user_id_relation' => $user2 ),
	__METHOD__
);

以及

Hooks::run( 'RelationshipRemovedByUserID', array( $user1, $user2 ) );
改成
Hooks::run( 'RelationshipRemovedByUserID', array( $user1, $user2, $rel_type ) );

注释

  1. 本扩展目前不支持使用extension.json加载
  2. 因为执行mw-config很麻烦所以只做了手动创建数据表的代码