第9章 插件解析
插件其实就是一堆文件的集合。这些文件被放在客户端,并在客户端被加载运行。现在可用的魔兽世界自定义插件已经非常丰富,这一章重点介绍插件是如何组成的,并对各部分进行解释。
9.1 开发属于您自己的插件文件夹
想要让游戏加载和应用一个插件,你需要把它放在魔兽世界指定的文件夹中,如果您已经运行过魔兽世界,那在魔兽世界游戏的目录下面就会有一个interface文件夹,这个文件夹里还有一个AddOns文件夹,而插件就要放在AddOns文件夹里。
9.1.1 暴雪的插件
在默认情况下,暴雪就使用了许多的插件来完成用户界面的设计,这些插件只在客户端有需求时才会加载。
每个暴雪插件在它的目录里都有一个以.pub为扩展名的文件。它是游戏标识插件可信度的一种方案。暴雪插件被认为是安全插件,第17章会详细介绍相关知识。
1.9.2 自定义插件
自定义插件与暴雪的插件都放在AddOns文件夹下面,不过它们遵循不同的插件组织形式,有不同种类的文件和不同的命名方式。
9.2 插件组件和文件
每个插件包含的文件都有不同的地方,但每个插件总有一些部分是相同的,下面将介绍插件可能包含的各种文件。
9.2.1 内容表格文件(.toc)
TOC文件是每个插件必须包含的文件,它们必须以插件的文件夹命名。例如文件夹的名字是MyAddOns,它的TOC文件名就是MyAddOns.toc。TOC文件主要提供一些重要信息(如标题、描述以及作者信息等等)来帮助加载特定的插件文件。下面是一个示例:
##Interface:20300
##Title:My Addon Name
##Notes:This is mysample addon
MyAddon.xml
MyAddon.lua
在toc文档有许多以##开头的标签,每个标签占用一行。冒号之前是标签的名称,冒号之后是标签的值。在标签之后是插件将要加载文件的一个列表
1.##Interface:
这个标签为用户在插件选择窗口提供了一个版本号,以便魔兽世界客户端识别你的插件是否与之兼容。如果不兼容会显示以下两种错误:
l 插件过期——这是由于你的##Interface版本与游戏客户端版本不同导致。这仅仅是一个警告,你可以通过选择“加载过期插件”来解决这个问题,通常插件加载后就会正常工作。
l 不兼容——这是由于游戏客户端的API有了较大的改变,这个插件已经不能加载。为了能够正确运行,需要修改你的插件。
插件被列为“过期”并不意味着有显著的错误,可能只是.toc文件中的Interface标签没有更新到最新的界面号。这种情况提醒了您需要把插件更新到最新的版本。它可以帮助您得到最新的bug修复和功能。最新的版本可以得到插件作者更好的技术支持。
Interface后面的版本号一般是由魔兽世界客户端的版本号确立的,例如,2.3.0的Interface版本号就是20300,这个号码可以通过查询其他可用插件的.toc文件获得(默然说话:个人觉得这是最简单的方式了。)
在魔兽世界游戏的角色选择窗口的左下角你可以看到一个“插件管理”的按钮,点击此按钮会弹出一个插件管理的对话框,你就可以看到上面所说到的“过期”或“不兼容”的提示了。
2.##Title
这是你在魔兽世界里看到的插件的名称。通常这个名称会与插件的文件夹名称相同,当然,如果你不想让玩家轻易认出你的插件所存放的位置,你也可以取一个与插件文件夹名称毫无关系的名称。
这个名称是可以本地化的,你只需要在##Title的后面加上国家地区码就可以了。例如:
## Title-zhCN: 治疗助手 Grid
这就是简体中文里会显示的插件名称。又如:
## Title-zhTW: 治療助手 Grid
这就是繁体中文里会显示的插件名称。
3.##Notes
这是一个对插件进行详细介绍的标签。你可以在这里提供给玩家更多关于插件的有用的帮助信息,它也可以如Title标签一样进行本地化(在后面加国家地区码,以显示对应国家所使用的语言),例如:
## Notes: A modular,lightweight and screen-estate saving grid of party/raid unit frames
## Notes-zhCN: 小巧的轻量级模块化队伍框架
## Notes-zhTW: 精簡的團隊框架功能
4.##Dependencies和##RequiredDeps
两个所实现的效果相同,它们都是说明插件必须依赖的别的插件的列表,如果此列表中的插件被禁用,或者因为某种原因无法加载,那么它本身也无法加载。在插件管理器中会看到“依赖插件被禁用”的提示字样。写法如下:
## RequiredDeps:DBM-Core
上面是我们常用的“首领预警”中一个插件的TOC代码,首领预警是一个由多个插件组成的插件组,而几乎所有的分插件都依赖于DBM-Core这个核心插件。所以,你可以在所有分插件的TOC文件中找到上面的这句标签。
这个标签还能带来一个附加的功能:决定插件的加载顺序(默然说话:被依赖的插件一定会先被加载,所以如果你的插件加载有一些冲突问题与他们的加载顺序有关,你可以主动修它们的TOC给它们加上依赖关系)。
5.##OptionalDeps
OptionalDeps标签一般为可供某些插件调用的扩展函数库或插件。当扩展函数库存在时,插件所调用的功能即可实现;但即使扩展函数库不存在,插件也应能正常工作。这些插件亦需提供不依赖上述函数库而实现主要功能的方法,以保证插件的正常工作。
6.##LoadOnDemand
从1.7版本开始,插件可以在需要时,而不是在玩家第一次进入游戏时加载。若此项被启用,该插件只能在稍后由其他插件加载。此项标签可避免在进入游戏时加载某些特殊功能的插件,从而有效地节约内存。
该标签的值只能是1或0。1表示按需要加载。
7.##LoadsWith
自1.9版本后,结合LoadOnDemand标签,此项标签可在某一插件(通常为Blizzard的UI模块,如Blizzard_AuctionUI)加载后再自动加载您的插件。
8.##DefaultState
DefaultState标签用于确定插件在安装时默认是否被启用。若该值被设为disabled,则玩家需在人物选择界面手动启用该插件。若此标签未设置则默认值为enabled。
9.##SavedVariables
从插件版本2150开始,SavedVariables已成为目前进程之间保存数据的最佳方式。插件要保存信息只能通过定义一个Lua变量,并在TOC文件的##SavedVariables标签中列出变量的名字。当关闭游戏的时候,系统就会将变量的内容存储到一个外面的文件中。当游戏重启时,又会读取该变量。变量类型可以是字符串、数字或者表格。
10.##SavedVariablesPerCharacter
SavedVariablesPerCharacter标签的工作方式与SavedVariables基本相同,区别在于前者所保存的变量仅在某一人物角色名下。此标签原仅使用人物姓名以区分不同角色,但现在可使用服务器名加人物名以区分(现在版本下(3.2.2),该标签所保存的变量文件位于World of Warcraft\WTF\Account\用户ID\服务器名\人物名\下)。
9.2.2 Lua脚本文件
TOC文件可以列出每个Lua文件(包括子目录中的文件)。这些文件都按照TOC文件中列出的次序由游戏客户端进行加载、解析和执行。
Lua文件通常都用于定义插件的行为,当然也可以使用它来动态地创建窗口(16章)
9.2.3 XML文件
在单个插件之内(或在FrameXML 之内),文件载入是按照 .toc 文件中定义的顺序线性进行的。toc 中定义的第一个文件最先被解析执行,之后是第二个,然后是第三个,依此类推。对于 XML 文件,每当执行到其中包含的 元素,就会去解析和执行引用的文件 X,处理完后才会接着处理后面的元素。
9.2.4 媒体文件
游戏客户端插件也可以包含自定义的图形、声音和字体等,从而为您提供不同的视听风格。这些文件包含在插件自己的文件夹里,在使用时必须使用完整的路径名来标明地址。
1.音乐
魔兽世界客户端可以识别MP3和WAV的文件。
如果你有一个声音文件叫mysound.mp3,并且它放在了Interface\Addons\MySound\mysound.mp3下,那你可以在游戏中运行如下命令来播放这个音频文件:
/run PlaySoundFile(“Interface\\Addons\\MySound\\mysound.mp3”)
2.图形
魔兽世界支持两种不同的图形格式——BLP和TGA,另外它们还要满足以下要求:
l 文件的高度和宽度要大于等于2像素,同时小于512像素。
l 文件的高度和宽度要是2的整数倍,但宽度和高度可以不一样(即图形可以是正方形的,也可以是长方形的)
20章将重点介绍如何创建自定义图形文件。
9.3 本地化您的插件
9.3.1 可用的本地语言
表9-2可用的客户端本地语言
本地语言代码 |
对应的语言 |
deDE |
德语 |
enUS |
美国英语 |
enGB |
英国英语 |
esES |
西班牙语 |
frFR |
法语 |
koKR |
朝鲜语 |
zhCN |
简体中文 |
zhTW |
繁体中文 |
9.3.2 本地化的原因
当玩家玩游戏的时候,如果自定义插件的语言和他自己的语言相同,则他会很容易做出瞬间的反应。如果不是他自己的语言,即使玩家的阅读能力很高也很难在短时间做出语言的转换。
另外,大多数的玩家都愿意并有能力帮助作者进行本地化。如果插件的设计好,那么插件的本地化更新也会变得很容易。
9.3.3 鼓励玩家建议
玩家常常会向作者提出一些本地化文件的方案,下面是一些让作者更便于本地化的方法:
l 提供一个常数集,或者一个便于查找翻译的列表,而不要仅使用字符串。
l 把插件的本地化信息写入readme.txt文件中,或者写在自己的官方网站上。
l 提供一些注释标明相关信息的含义以便用户能够方便地进行翻译。
9.3.4 实现本地化
这里介绍一种推荐的执行方案,它可以方便您更新本地化文件。
1.为每个地方语言添加一个文件
为您翻译的地方语言添加一个新的本地化文件。若没有什么翻译,就在您开发的插件中为基本的地方语言创建一个文件。例如Localization.zhCN.lua,并把这个文件添加到.toc文件中文件列表部分的第一行,以保证它能在第一时间被加载。
2.创建一个包含所有输出字符串的全局表
如果我们创建的插件叫MyAddOns,那么我们就在Localization.zhCN.lua中创建一个叫MyAddOnsLocalization的全局表。
MyAddOnsLocalization={};
MyAddOnsLocalization[“Frames_Locked”]=”框架已经锁定”
MyAddOnsLocalization[“Frames_UnLocked”]=”框架已经解锁”
3.添加新的地方语言
您可以再创建一个新的文件(例如Localization.enUS.lua)来添加新的语言。这些文件应该出现在.toc文件的文件表中,紧跟Localization.zhCN.lua文件的后面。
if GetLocale()==”enUS”then
if not MyAddonLocalization then
MyAddonLocalization={}
end
MyAddOnsLocalization[“Frames_Locked”]=”Frameshave been locked”
MyAddOnsLocalization[“Frames_UnLocked”]=”Frames have been unlocked”
end
第一个if用来保证只有用户的地方语言是英语时才重新填写所有的输出字符串为英文,第二个if用来保证即使在出现意外的情况下仍然能创建出全局表。
现在,在一个美国的客户端上显示的信息将会是英语而不是简体中文。
9.4 创建插件框架
第10~11章将介绍一系列使用XML的例子,为了后面的两章,这里教大家一个基本的插件框架,从而不必为每个例子都重复做一些事情。
9.4.1 为插件命名(创建目录)
请创建一个名为WowXMLExample的文件夹,它的位置应该位于你的魔兽世界的文件夹中的如下目录:
Worldof Warcraft\Interface\AddOns\WowXMLExample
接下来的两章会教您创建所有的新东西。
9.4.2 创建.toc文件
若没有一个TOC文件,插件将不起作用,因此先使用下面的代码创建一个TOC文件(文件名:WowXMLExample.toc):
##Interface:30200
##Title:WowXMLExample
##Title-zhCN:XML示例插件
##Description:Exampleaddon for World of Warcraft Programming
WowXMLExample.xml
默然说话:上面的版本号已经被我改为最新的版本号了,不过不保证以后《大灾变》等版本出来还可以用。
9.4.3 创建.xml文件
使用下面的代码在插件的目录中创建WowXMLExample.xml文件:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd"> 上面的代码一个符号都不能敲错(区分大小写。另外注意回车的位置),请认真核对。后面我们将在 9.5 使用外部库 推荐大家先学习如何使用魔兽世界API以及XML来写一些基本的插件。附录E包含了一个列表,列出了主要的库和框架,以及它们的详细信息。(默然说话:你也可以在http://www.wowwiki.com/World_of_Warcraft_API找到详细的说明,只是看上去好象这些资料有些过时,不过它们绝大部分都还可用) 9.6 小结 本章介绍了包含在一个插件中的基本组件,包括内容文件表格、XML定义以及Lua脚本。此外,插件还可以包含并使用特定类型的媒体文件。