魔兽世界插件开发入门教程——1

昨晚折腾网站折腾得太晚
到今天中午才睡觉
此刻果然全无睡意
刚好趁此时间整理下东西
借以排遣此般漫漫长夜

前言

记得当初我开始查找编写WoW的插件的资料时,在google里直接进行中文搜索,得到的资料极为稀少且多为重复内容,偶然间发现CWDG社区(CWoW Developer Group),那是我当时为数不多的中文资料来源。

若你要编写WoW的插件,请做好英语上的准备,因为大部分的资料都是来自于国外。你可以不在意四六级成绩,这种应试的英语考试也没什么用,但是至少英文的读写能力要能基本合格。

本文以我自己编写的QuestRepeat这个插件为例讲解

[查看插件功能及其基本介绍]

你可以在上面的链接,大概了解下整个插件的功能及界面,本插件是为了解决那些可以上缴物品的烦人重复任务开发的,有个印象之后,我们开始来讲解。

 

准备工作

首先编写插件的核心代码需要用到Lua语言

这里推荐一本叫《Programming in Lua》的电子书,中文名叫《Lua程序设计》,作者是Roberto Ierusalimschy,你可以在网上搜索到中文译本,看完前10章就可以,后面的高级特性可以暂时先不用了解

现在Lua的版本是5.2,记得几个月前我去投简历的时候,面试官问我写的插件lua用的是什么版本,当时就晕了自己只记得是5.X,平时不够高端很少留意这个,毕竟WoW对lua的版本要求并不多,而且5.2的版本也刚更新不久。不过这对我们编写插件并没太多影响,WoW给的官方API的变动才是影响最大的地方。

请偶尔多留意下这种细节,不要像我一样丢人现眼的被人误解作品不是自己所写,=.=!。

传言lua每更新版本都会伤筋动骨的大改,不过5.1转5.2的这个时候,我已不再关注WoW的插件开发,我也并不知道有多少影响,在此不多评价。

学程序是需要练习的,你可以在lua.org下载到Lua在windows平台下的整个开发环境的安装包,这个请自行查阅资料去使用。

然后你需要了解点XML相关的知识

不需要太多,http://www.w3school.com.cn/xml/index.asp这里你可以挑选着看点,大概知道一些规定就可以,毕竟XML在我们这只是用来描述界面结构,我们并不去开发网页

最后,开始编写插件

你只需要用windows自带的记事本就可以了,当然你若喜欢用Vim或者Emacs这类文本编辑器,你一定高端到不用我来废话。

请看完以下内容,并自己写一个toc文件,但是你还无法验证对错
先准备着,等第二节教程看完学会了下一节的东西,再一起验证。
如何使用记事本创建一个非txt扩展名的文件,这样的基本操作知识如果不会,请自行google。

技术讲解

插件整体结构

  • 插件工程 —— 其实就是插件的目录,用来存放以下三种文件。要调试或使用插件时,目录的存放位置: {你的魔兽安装目录}\Interface\Addons\{你的插件名}\
  • 工程描述 —— 后缀名为Toc的文件。描述插件工程的必要信息,也是项目载入时的总入口。
  • 屏幕布局 —— 布局描述使用XML文件。使用各种标签代表特定对象,并描述相互位置及各种特征属性,通俗的说,你的插件的图形界面就是用这个文件来描述的。
  • 功能脚本 —— 脚本文件使用LUA语言。使用WoW提供的API函数编写代码实现各种具体操作,插件的功能实现核心。

如下图所示,我自己编写的QuestRepeat插件就放在了”D:\Game\World of Warcraft\Interface\AddOns\QuestRepeat”

下面我们来看看其中的文件,如图所示,包含了上面讲到的3种文件,你可以使用windows自带的记事本打开编辑他们,我使用的是gVim,会有代码高亮等优点,你可以自己下载一个折腾看看。

值得一提的是,XML文件并不是必须的,因为早些时候的WoW版本,你的插件界面只能靠XML文件来描述,但是到了后面,又有了可以用lua动态创建窗口等资源的API,所以你可以完全抛弃XML全部使用lua+toc文件就可以写出一个插件。另外假如你的插件不需要界面,那XML文件自然是可以省略,不要怪我罗嗦,只是为了个初学者提个醒。插件只实现某种功能,比如过滤垃圾文字,可以不写界面。

Toc文件的结构

以我的插件为例
QuestRepeat.toc内容如下

## Interface: 30300
## Title: QuestRepeat
## Author: Tyreal Han
## Version: 2.3.2
## Notes: Enables quicker repeating of quests.
## Notes-zhCN: QuestRepeat 让一些可以重复完成的任务快速完成,比如交声望的任务。
## Notes-zhTW: QuestRepeat 讓一些可以重複完成的任務快速完成,比如交聲望的任務。
## DefaultState: Enabled
## SavedVariables: QR_VerControl, QR_RepDB

localisation.lua
QuestRepeat.lua
InfoFrame.lua
CalHonorFrame.lua
CalRepFrame.lua
QuestRepeat.xml
    • Interface ——插件适用的WoW的版本号

比如3.1.3的国服版本,就是30100,那些奋斗在wlk的3.3的国外版本,就是30300,以此类推。 还记得每次更新WoW之后在人物登录界面的那个插件列表看到一堆插件过期的显示么,就是靠这个来检测的,其实很多插件都是一直可以用的,你只需要用记事本打开这个toc文件,修改这里的数字就可以了。

    • Title —— 插件的名称,会显示在我们人物登录界面的那个插件列表里
    • Author —— 插件作者的名字,仅仅只是陈述下,但是不会显示出来
    • Version —— 插件版本号

不会界面中的列表显示出来,有时候我们安装了某些插件看到插件后面带了版本号,其实是作者在Title那边一起写的,这里其实只是给开发人员一个提示作用,所以版本号的格式,自己规定的而已,你可以从来都写1.0之类的一个版本,不改变,不过这样就是丑陋了点。

    • Notes/Notes-zhCN/Notes-zhTW —— 分别对应英文版/大陆版/台湾版客户端运行下的插件说明,可以只有一个Notes的英文版说明即可
    • DefaultState —— 默认状态,我一直填写Enabled

这个参数我没去详查,一直没什么影响,若你好奇,查得结果,请留言赐教

    • SavedVariables ——插件储存、读取变量设置

很有用的一个参数设定,我们使用插件的时候,插件经常有各种不同的设置,或者有些插件,比如QuestRepeat会保存任务获取的一些信息,那这些配置乃至任务信息要怎么存储到硬盘上呢,就是靠这个参数设定的这几个变量。
名称自己设定, 比如QR_RepDB,这是我用来保存任务信息的一个table,不知道table是何物的请回去重读《Programming in Lua》,游戏运行时候,当上缴完任务之后,QuestRepeat截获的一些任务奖励信息,会保存到QR_RepDB这个table变量中,然后等游戏重新加载,或者退出游戏的时候,这些变量的内容会被WoW的客户端写入

{你的WoW安装目录}\WTF\Account\{你的游戏帐号名称}\SavedVariables\{插件名称}.lua

当游戏下次运行的时候,插件会根据SavedVariables后面的的设定,并从中刚才的那个文件中读取出对应需要的数据。

由于WoW保存变量的时间是在游戏退出或者重新加载插件的时候,所以有些记录DKP的插件,若你的WoW异常出错被强制关闭,你本次活动的过程中又没有自己手动重新加载全部插件或者中途重启过游戏,那记录的所有信息将丢失,这也就是有些玩家抱怨说游戏出错后当时活动的DKP数据都不见的原因。你可以在聊天框输入

/console reloadui

这样就可以让数据写入硬盘了,不需要重启游戏,我们等会写插件也会经常用到这个命令来查看插件修改的结果,另外还有一些别的宏命令也一样可以实现同样功能,请自行google。

    • 最后,那些一行行的文件名称列表,是告诉WoW客户端加载你编写插件的文件的顺序

请根据你程序结构注意好顺序,变量的生命周期是有影响的。不过一般我们自己编写的插件只要不要太大型,自己应该都知道怎么安排顺序,这个造成混乱的机会不多。
若你想了解更多内幕,请猛击这里的资料:CWDG WiKi-UI代码的载入顺序

PS:localisation.lua是插件本地化文件需要的东西,比如我们要把一个英文版的插件翻译成中文版,修改这个文件就是。当然还有一些别的实现方法,这个是比较普通常见的一种。

总结一下

由上面的资料我们可以知道,编写一个插件需要为它建立一个文件夹,然后给文件夹也就是插件取个名字,在文件夹下面建立一个同名的.toc文件,按照规定填入那些规定的字段,整体描述下你的插件,SavedVariables以及最后面的文件列表,我们可以一边编写,一边添加,放空暂留个位置就可以。

当然,弄完toc文件你的插件还是无法在游戏中运行的,因为还没有写最关键的lua脚本代码,没事,先有个整体的了解,下一次我们会先讲下插件的界面描述XML文件,然后在那些界面的基础上开发插件的功能。

实际上我们设计的时候,是先设想要什么功能,然后根据功能定夺需要什么样的界面,但是实现它的时候,界面往往会先写出来,因为毕竟插件编写不是像平常写C++一样有个IDE可以先进行各种单元测试,插件需要先在游戏中看得到界面才能进行一些交互操作开发,我也是按照这种顺序来开发的,看起来很原始很低端又不那么高效,且在前期不好验证功能的可行性,假如你有更好的方法,希望能互相交流下。

下次见~

Tagged , ,

追逐梦的放肆

终于下定决心买了域名跟空间
折腾了一晚上才弄好
其实在DreamHost注册的最后,我忘记添推荐码了,买的这第一年的空间还是要119美金……
无奈执着于注册的域名跟自己的gmail邮箱
忍痛付费下去
浪费云麟的推荐码
浪费自己以为可以节省800块的窃喜

之前写博客,向来都不轻易转载
网上复制来复制去的已经够多了,不需要再多我一个
日后若要更新,定会自己亲自操刀,更新可能并不勤快,不过至少是自己的心得之物
自知自己的愚见也不会有怎样的水准
不求无过
但求在自己漫长的学术追逐之中帮自己找准定位
也让有志踏上同一征途之人能避免我的曲折与错误

 

曾经自己在自学计算机的时候
一度不知道如何下手
偶尔问过些前辈
给的意见都过于抽象与概括
并非他们所讲不好
现在回头来看,他们的意见都算中肯
这是当时茫然不知方向的时候
这样的指导越搞得我越加混乱
这多半受限于我当时的眼界
但是事情往往就是这么矛盾
当你跳脱出新手的行列
开始自己悟道、对整个框架越加清楚的时候
别人如同以前的你一样问你同样的那些问题
你的回答也常常效仿那些前辈一样
处处拿捏分寸、生怕指导错别人
不知不觉,你的回答也变得不怎么具体

而此刻,我该如何记录并留下点值得一看的东西
我不想再对新手说一些大局观的介绍,何况我并没这样的实力
若是我做过的东西,我会记录下如何去做的线索
若你感兴趣,按照线索去学,学下去,不要过多计较得失
很多时候在什么都不懂的情况下就直接入手去做
远比等了解完一切才入手要更有效率
鉴于当年自己的痛苦
我会尽可能的详细说明各种入手线索
至少会具体到有方向可以循

我并不是什么高手
我也刚上路
此后的数年之中
我也深知自己无法留下什么经得起岁月摧残的东西
纵使所写之物有所谬误
若还能给你带来点启发
亦是我的荣幸
若你看到我的不足
能留言赐教
本人亦深为感激

若此生之中
能一直享受此般追逐自我成长之快感
那该是何等放肆的回忆

文末附上自己很喜欢的一阕词
在这越发浮躁的大环境下
与君共勉

《定风波》——苏轼
三月七日沙湖道中遇雨。雨具先去,同行皆狼狈,余独不觉。已而遂晴,故作此。

莫听穿林打叶声,何妨吟啸且徐行。
竹杖芒鞋轻胜马,谁怕?
一蓑烟雨任平生。
料峭春风吹酒醒,微冷,山头斜照却相迎。
回首向来萧瑟处,归去,也无风雨也无晴。