HALO插件编写初级教程
[font=宋体]本文献给所有热爱[/font]mini[font=宋体]的同学!感谢[/font]BB[font=宋体],感谢[/font]heart[font=宋体],感谢小[/font]4….[font=宋体],感谢广大[/font]YOYO[font=宋体],你们的支持是我前进的动力![/font][font=宋体]编写插件的要求:
[/font]1.[font=宋体]至少熟悉一门面向对象语言[/font](C++/JAVA/C#/VB.NET/DELPHI[font=宋体]等[/font])[font=宋体],由于[/font]HALO[font=宋体]是用[/font]JAVA[font=宋体]写的,所以必须用[/font]JAVA[font=宋体]写插件。如果对[/font]JAVA[font=宋体]不熟悉,可以尝试用自己熟悉的语言写,最后再一步步转到[/font]JAVA[font=宋体]上面(我就是这么干的[/font]…[font=宋体])。[/font]
2.[font=宋体]了解常用[/font]IO[font=宋体]操作和数据结构
不会可以学,挑战自己,分享知识...
请大家支持mini.支持汉化...
[/font]
[b][size=14pt]1.[/size][/b][b][font=宋体][size=14pt]搭建开发平台[/size][/font][/b]
[font=宋体] 开发[/font]JAVA[font=宋体]的工具很多,从最基本的记事本,到先进的[/font]IDE[font=宋体],这里我推荐使用[/font]eclipse,[font=宋体]一个免费的强大[/font]IDE[font=宋体],可以在官方网站下载开发[/font]JAVA[font=宋体]的版本,当然也有开发[/font]C++[font=宋体]的。[/font]eclipse de [font=宋体]强大也在于有完善的插件支持功能,从智能标记到语法识别,都是插件(这个世界软件的扩充,插件才是王道啊!),想开发[/font]python[font=宋体]么,下载个[/font]python[font=宋体]的插件就可以了:[/font]
[url=http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/20070927/eclipse-java-europa-fall-win32.zip]http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/20070927/eclipse-java-europa-fall-win32.zip[/url]
eclipse[font=宋体]是全[/font]E[font=宋体]文版的,不过使用起来难度不大。常用的快捷键:[/font]
ALT+?:[font=宋体]智能提示[/font]
CTRL+/ [font=宋体]注释[/font]
F11 [font=宋体]调试[/font]…..[font=宋体]请大家自己摸索,写[/font]2[font=宋体]个程序就会用了。对于基本的开发,并不需要配置[/font]ecplise[font=宋体]环境,如果要配置自定义功能,在[/font]Window->Preference [font=宋体]可以看到许多自定义选项[/font].General->Keys[font=宋体]可以自定义键盘绑定。[/font]General->Editors->TextEditors:[font=宋体]勾选[/font]Show Line Numbers [font=宋体]这样就可以显示代码行数,如同[/font]Editor Plus[font=宋体]里面一样。[/font]
[font=宋体]此外,建议使用一种[/font]16[font=宋体]进制查看工具,比如[/font]UE,HEX WorkShop
[font=宋体]为了开发插件,我们还需要插件开发库[/font]halolib
[url=http://forum.minisoyo.com/viewthread.php?tid=40593&extra=page%3D1%26amp%3Bfilter%3Dtype%26amp%3Btypeid%3D51]http://forum.minisoyo.com/viewth ... 26amp%3Btypeid%3D51[/url]
[[i] 本帖最后由 樱花树 于 2007-10-22 01:23 编辑 [/i]] [b][size=14pt]2.[/size][/b][b][font=宋体][size=14pt]基础知识[/size][/font][/b]
[size=12pt]
2.1[/size][font=宋体][size=12pt] 字符编码[/size][/font]
[font=宋体] 字符编码好比人类的语系,语言可以通信,计算机只有用某种字符编码才能识别诸诸如[/font]0100 0001 [font=宋体]之类的二进制符号。最早通用的字符编码是[/font]ASCII[font=宋体],规定用[/font]1[font=宋体]字节表示英文字母,数字和计算机控制符号,范围是[/font](0x00—0x7F [font=宋体]也就是[/font]0-127)[font=宋体],我们要记住的是:[/font]0x0A [font=宋体]换行[/font] 0x0D:回车,0x30-0x39 [font=宋体]数字[/font]0-9。0x41:[font=宋体]大写字母[/font]’A’ 0x61 [font=宋体]小写字母[/font]’a’ [font=宋体]这在[/font]16[font=宋体]进制编辑下特别有用[/font].
[font=宋体]可以看到,[/font]ASCII[font=宋体]字符集存在不可避免的缺点:只能表示英文字符集,对于亚太和东欧等国字符均无法支持(谁叫人家发明的计算机呢?要是计算机是中国发明的,一定首先出来汉字字符集!当然,算盘理论上也是一种人工计算器。)于是其他各各国家都发明了自己的字符集,如中国的[/font]GB2312,BIG5[font=宋体]等。显然,不同的字符集之间无法通信,犹如一个印第安人站在你面前依依呀呀一样。于是就出现了“统一编码格式”[/font]:Unicode[font=宋体],在将[/font] Unicode [font=宋体]表示的字符进行存储时,还需要一定的编码方式,比如[/font] UCS-2[font=宋体],[/font]UCS-4[font=宋体]它用两个字节或者四个字节来表示[/font] Unicode [font=宋体]编码的字符。这样子所表示的字符范围大大增加,几乎所有人类的文字都能表达(也许有一天也能表达火星语?)[/font]UTF-8 [font=宋体]是[/font] Unicode [font=宋体]字符集的另外一种编码方式,它是采用变长编码,最多[/font] 6 [font=宋体]个字节,小于[/font] 127 [font=宋体]的字符用一个字节表示,一般汉字采用[/font]3[font=宋体]字节编码。所以能和[/font]ASCII[font=宋体]做最好的兼容,又能节省空间(相对[/font]UCS-4[font=宋体])。修改版的[/font]UTF-8[font=宋体],采用长度[/font]+TEXT[font=宋体]格式,规定前[/font]2[font=宋体]个字节表示字符串长度,这在很多场合下有用。关于更多信息,可以在[/font]GOOGLE[font=宋体]中查找[/font]utf-8,Unicode[font=宋体]的编码规范。[/font]
[url=http://www.zeali.net/entry/86]http://www.zeali.net/entry/86[/url]
[url=http://www.utf.com.cn/article/s41]http://www.utf.com.cn/article/s41[/url]
[size=12pt]2.2[/size][font=宋体][size=12pt] 字节顺序[/size][/font]
[font=宋体] 计算机所唯一能识别的就是二进制,[/font]CPU[font=宋体]处理多个字节的顺序就叫字节序。好比[/font]2[font=宋体]个东西并排放前面,有的人先拿左边的,有的人先拿右边的。字节序分为:[/font]little endian ([font=宋体]小端法[/font])[font=宋体]和[/font]big endian [font=宋体](大端法),是字符处理,网络传输,[/font]CPU[font=宋体]处理的基石。我们常用的[/font]IA32[font=宋体]系列[/font]CPU[font=宋体],如[/font]Intel[font=宋体],[/font]AMD[font=宋体]的[/font]CPU[font=宋体]都是采用[/font]little endian[font=宋体]。而[/font]RISC[font=宋体]的[/font]CPU[font=宋体],很多都是[/font]big endian[font=宋体],比如[/font]MOTOROLA,PowerPC,ARM…[font=宋体]简单说来,[/font]littleendian[font=宋体]就是按照字节的“高高[/font]-[font=宋体]低低”排序,高地址放高位字节,低地址放地位字节。同样,资源文件也存在字节顺序,这直接决定了读取的方法。例如[/font]“[font=宋体]汉[/font]”[font=宋体]字的[/font]Unicode[font=宋体]编码是[/font]6C49[font=宋体]。那么写到文件里时,究竟是将[/font]6C[font=宋体]写在前面,还是将[/font]49[font=宋体]写在前面?如果将[/font]6C[font=宋体]写在前面,就是[/font]big endian[font=宋体]。还是将[/font]49[font=宋体]写在前面,就是[/font]little endian[font=宋体]。看起来和就像是倒着的。[/font]
[attach]239146[/attach]
[font=宋体]如图所示的从[/font]0000h[font=宋体]到[/font]0001h[font=宋体]的[/font]2[font=宋体]个字节:[/font] B8 06[font=宋体],当它作为一个[/font]2[font=宋体]字节的整数时,用[/font]little endian[font=宋体]解释,就是[/font]0x6B8[font=宋体]。反之就是[/font]0Xb806,[font=宋体]两者差异很大。所以在看资源文件时,首先要弄清楚它是什么字节顺序。在调用库函数时,也应该注意它是用什么顺序读写的。如果只是单字节处理或者字节编码,也就不用考虑了。[/font]
[font=宋体]查看更多:[/font]
[url=http://news.newhua.com/html/System_win/2005-5/18/16148354.shtml]http://news.newhua.com/html/System_win/2005-5/18/16148354.shtml[/url]
[size=12pt]2.3[/size][size=12pt] Java[/size][font=宋体][size=12pt]基础[/size][/font]
[font=宋体] 有一定[/font]OOP[font=宋体]基础的朋友,看看附录的[/font]DEMO[font=宋体]也就会了,插件编写不需要使用太多的[/font]JAVA[font=宋体]特征。[/font]GOOGLE[font=宋体]吧[/font]….
[size=12pt]2.4[/size][size=12pt] Handy-Games[/size][font=宋体][size=12pt]公司文本资源文件的数据结构[/size][/font]
[font=宋体] 由于本文将针对这个开发插件,所以有必要说明一下[/font].lng[font=宋体]文件的数据结构(存储方式)。简而言之,[/font]lng[font=宋体]文件是用字符串偏移来分割文本域的,有如下的格式:[/font]
[font=宋体][color=Black]文件总长度[/color][/font][color=blue][color=Black](2[/color][/color][font=宋体][color=Black]字节[/color][/font][color=blue][color=Black])|[/color][/color][font=宋体][color=Black]语言格式[/color][/font][color=blue][color=Black](1[/color][/color][font=宋体][color=Black]字节,[/color][/font][color=blue][color=Black]0[/color][/color][font=宋体][color=Black]:[/color][/font][color=blue][color=Black]1:Unicode,ASCII 2[/color][/color][font=宋体][color=Black]:[/color][/font][color=blue][color=Black]utf-8)|[/color][/color][font=宋体][color=Black]字符串总数目[/color][/font][color=blue][color=Black](2[/color][/color][font=宋体][color=Black]字节[/color][/font][color=blue][color=Black])|[/color][/color][font=宋体][color=Black]偏移表[/color][/font][color=blue][color=Black]|[/color][/color][font=宋体][color=Black]文本域[/color][/font]
[font=宋体]
首先用[/font]UE[font=宋体]打开一个英文版的[/font]lng[font=宋体]文件,我们注意到开头[/font]5[font=宋体]个字节,是文件总说明[/font]:
[attach]239147[/attach]
[font=宋体]注意[/font]UE[font=宋体]都是[/font]16[font=宋体]进制显示的。首先是[/font]2[font=宋体]字节的文件长度,[/font]0x75 09[font=宋体],可以在[/font]UE[font=宋体]的右下方看到文件总大小:[/font]2421 [font=宋体]这里是[/font]10[font=宋体]进制,用[/font]WINDOWS[font=宋体]自带的计算器可以算出就其[/font]16[font=宋体]进制表示是[/font]0x0975[font=宋体],这里整数的写入是按照前面说的[/font]little-endian[font=宋体]。所以文件最大数目是[/font]64K[font=宋体]。接着表示语言的字节是[/font]00[font=宋体],说明是[/font]ASCII[font=宋体]格式文本,要把它汉了,我们需要把它改为[/font]02.[font=宋体]接下来的[/font]11 00 [font=宋体],反过来,就是[/font]0x0011 [font=宋体]表示有[/font]17[font=宋体]句文本。我们可以用这个总数和接下来的偏移表,来确定(从文本域分割出)这[/font]17[font=宋体]句文本来。[/font]
5[font=宋体]字节以后是偏移表。偏移表的基本单位是[/font]2[font=宋体]字节,也就是说每[/font]2[font=宋体]个字节给出文本在整个文件中的地址,或称偏移量。如图[/font]:
[attach]239150[/attach]
0005h[font=宋体]到[/font]0006h[font=宋体]的[/font]2[font=宋体]个字节,给出了第一个文本的偏移量:[/font]0x0027,[font=宋体]我们定位到[/font]0x27[font=宋体]号位置,发现是[/font]73[font=宋体]而不是第一个文本的首字母[/font]’I’(49)[font=宋体],但是我们发现后[/font]2[font=宋体]个字节处就是[/font]49.[font=宋体]难道出错了?根据前面的总文本数目[/font]17[font=宋体],我们推算出偏移表的大小为[/font]17X2=34[font=宋体]字节,(一个偏移量占[/font]2[font=宋体]个字节)。用[/font]UE[font=宋体]选择从[/font]0005h[font=宋体]到[/font]0028h[font=宋体],的所有单元发现总长度是[/font]36[font=宋体],比预计的多[/font]2[font=宋体]个字节。所以,偏移量实际上要全部加上[/font]2.[font=宋体]得出公式[/font]1[font=宋体]:[/font]
[b][font=宋体][size=12pt] [size=3] 实际偏移量[/size][/size][/font][/b][size=3][b][size=12pt]= [/size][/b][b][font=宋体][size=12pt]描述偏移量[/size][/font][/b][b][size=12pt]+2 (1)[/size][/b][/size]
[b][size=12pt] [/size][/b]
[font=宋体]接下来我们来研究这多出来的[/font]2[font=宋体]个字节是什么,显然不可能中间无故多出来,只能是首尾处。我们注意到偏移表的最后[/font]2[font=宋体]个字节是:[/font]73 09 [font=宋体]说明这是最后一个文本的偏移,按照公式[/font]1[font=宋体],我们得出其实际偏移位置是[/font]0x0975[font=宋体],定位到文件末尾,发现已经是文件末了:[/font]
[attach]239148[/attach]
[font=宋体]前面我们得出文件总长度是[/font]0x975[font=宋体],说明这个偏移给出的是文件末尾。最后一个文本的位置应该是偏移表的倒数第二个位置给出:[/font]EF 08[font=宋体],切换到位置[/font]08F1[font=宋体],验证了我们的推断。[/font]
[font=宋体]接下来,通过连续[/font]2[font=宋体]个偏移可以计算处文本的长度:比如[/font]2[font=宋体]号偏移[/font]0x97-1[font=宋体]号偏移[/font]0x27=0x6A=106[font=宋体],这就是第一个文本的长度,我们选择从[/font]0029[font=宋体]到[/font]0092[font=宋体]的长度,[/font]UE[font=宋体]计算处一共有[/font]106[font=宋体]个字节。
[/font][attach]239149[/attach]
[font=宋体]于是我们得出第二个公式:[/font]
[size=3][b][font=宋体][size=12pt] 文本[/size][/font][/b][b][size=12pt]n[/size][/b][b][font=宋体][size=12pt]的长度[/size][/font][/b][b][size=12pt]= [/size][/b][b][font=宋体][size=12pt]偏移量[/size][/font][/b][b][size=12pt](n+1)-[/size][/b][b][font=宋体][size=12pt]偏移量[/size][/font][/b][b][size=12pt](n) (2)[/size][/b][/size]
[b][size=12pt] [/size][/b]
[font=宋体]这就是为什么偏移表需要[/font]n+1[font=宋体]个条目而不是[/font]n[font=宋体]个。最后一个条目用来计算最后一个文本的长度。[/font]
[font=宋体]有了这些我们就能设计出读取算法出来:[/font]
read_lngfile(File file)
{
size =readshort(file); ;[font=宋体]读取开头[/font]2[font=宋体]个字节的文件总长[/font]
lng = readbyte(file); ;[font=宋体]读取[/font]1[font=宋体]个字节的语言描述符[/font][font=宋体][/font]
count = readshort(file); ;[font=宋体]读取[/font]2[font=宋体]个字节的文本数目[/font][font=宋体][/font]
for(i=0;i<=count;i++) ;[font=宋体]读取偏移表[/font][font=宋体][/font]
{
offset_list.add(readshort(file)); ;[font=宋体]每个条目[/font]2[font=宋体]字节[/font][font=宋体][/font]
}
; [font=宋体]开始读取文本[/font]
for(int=0;i<count;i++)
{
byte buffer[ (offset_list[i+1]-offset_list)];利用公式2,计算文本i的长度,来初始 化字符缓冲区
readUTF(file,buffer); ;从file读取UTF字符串到buffer 中
……
}
}
反之,知道了文本条目数和文本,我们就能反推.lng文件。首先需要计算文件长度,我们知道,文件由5字节描述符+偏移表+文本域构成,偏移表的长度可以通过文本条目数计算:
[size=3][b] 偏移表长度= (文本数+1)*2 (3)[/b][/size]
由于每一个条目需要2个字节描述,由前面知道偏移表的实际条目数要比文本条目数多一以容纳EOF字节(End Of File)。
为了反向生成所有偏移量,我们需要知道第一个文本的偏移量。也就是前5个字节后的第一个偏移描述符。第一个偏移量知道了,后面的n个偏移量可以根据每个文本的utf-8长度推算出来:
[b] [size=3]偏移量i+1= 偏移量i+文本i的utf-8长度 (4)[/size]
[/b][font=宋体]由于偏移表后面紧跟一个文本的第一个字符,所以第一个文本的偏移量很容易计算出来:[/font]
[b][font=宋体][size=12pt]
[size=3] 第一个偏移量[/size][/size][/font][/b][size=3][b][size=12pt]= 5+[/size][/b][b][font=宋体][size=12pt]偏移表长度[/size][/font][/b][/size][b][size=12pt][size=3]-2 (5)[/size]
[/size][/b][font=宋体]减去[/font]2[font=宋体]是为了除去它本身[/font]2[font=宋体]个字节长度
[/font][font=宋体]这样,已知文本数量和文本,我们得到了构造[/font]lng[font=宋体]文件的算法:[/font]
wrie_lngfile(Strings list,Filefile);[font=宋体]已知文本列表[/font]
{
count = list.count(); ;[font=宋体]获取文本数量[/font]
[font=宋体][/font] size = 5; ;[font=宋体]初始化文件长度为[/font]5
first_offset = 5 + 2*(count+1)-2 ;[font=宋体]从公式[/font]3,5[font=宋体]计算第一个偏移量[/font]
[font=宋体][/font]
for(i=0;i<count;i++)
{
byteutfs[] = str2utf8(list[i]);[/i] ;[font=宋体]获得第[/font]i[font=宋体]个文本的[/font]utf-8[font=宋体]表示[/font]
strlist.add(utfs); ;[font=宋体]加入到[/font]utf-8[font=宋体]文本列表中以便后面使用[/font]
lenlist.add(utfs.length); ;[font=宋体]加入文本的[/font]utf-8[font=宋体]长度到长度列表中以便后面使用[/font]
size= size+utfs.length+2 ;[font=宋体]更新文件大小[/font],[font=宋体]加上文本[/font]utf[font=宋体]长度和[/font]2[font=宋体]字节的偏移描述符[/font]
}
size = size+2 ;[font=宋体]别忘记最后还有[/font]2[font=宋体]个字节的尾描述符[/font]
writeshort(file,size); ;[font=宋体]首先写[/font]2[font=宋体]字节的文件长度信息[/font]
writebyte(file,2); ;[font=宋体]语言信息汉化后默认为[/font]2
writeshort(file,count); ;[font=宋体]写入[/font]2[font=宋体]字节的文本数量信息[/font]
writeshort(file,first_offset); ;[font=宋体]写入第一个文本偏移信息[/font]
offset = first_offset
for(i=0;i<count;i++)
{
offset = offset+lenlist ;[font=宋体]利用公式[/font]4[font=宋体]计算第[/font]i+1[font=宋体]个文本偏移信息[/font]
writeshort(file,offset);
}
for(i=0;i<count;i++)
{
writebytes(file,strlist); ;[font=宋体]写入[/font]utf-8[font=宋体]文本[/font]
}
}
[font=宋体]得到了伪码,就很容易转化成某种特定语言进行编码了。[/font]
[[i] 本帖最后由 樱花树 于 2007-10-18 22:51 编辑 [/i]] [size=4][b]3.[/b][/size][b][size=14pt]HALOLib[/size][/b][b][font=宋体][size=14pt]的基本结构[/size][/font][/b]
[b][size=14pt][/size][/b]
[size=12pt]3.1 [/size][font=宋体]插件的接口描述[/font]
Jvm[font=宋体]通过[/font] ClassLoader[font=宋体]来加载插件,只要规定了接口,[/font]HALO[font=宋体]就可以在不知晓文件格式的情况下,使用接口来修改它。这就是插件存在的意义。插件需要放在[/font]/Halo/plugins/[font=宋体]目录下面。为了识别插件类,需要某种配置文件(比如[/font]Xml[font=宋体])来定义插件特征。这里[/font]HALO[font=宋体]采用[/font]MF[font=宋体]文件来定义。格式如下:[/font]
[b] Reader-Class[/b]: [font=宋体]读取类的全名称:包名[/font]+[font=宋体]类名[/font]
[b] Writer-Class[/b]: [font=宋体]写入类的全名称:包名[/font]+[font=宋体]类名[/font]
[b] Description[/b]: [font=宋体]插件的描述[/font]
[b] Name[/b]: [font=宋体]插件的唯一名称[/font]
([font=宋体]空[/font]1[font=宋体]行[/font])
([font=宋体]空[/font]2[font=宋体]行[/font])
[font=宋体][color=Yellow]友情提示[/color][/font][color=Yellow]*(MF[/color][font=宋体][color=Yellow]文件用[/color][/font][color=Yellow]EP[/color][font=宋体][color=Yellow]等[/color][/font][color=Yellow]utf-8[/color][font=宋体][color=Yellow]支持格式的文件来编写,且后面要空[/color][/font][color=Yellow]2[/color][font=宋体][color=Yellow]行[/color][/font][color=Yellow] - _-|| [/color][font=宋体][color=Yellow]不要问我为什么[/color][/font][color=Yellow])*[/color]
Halo[font=宋体]插件需要包括[/font]2[font=宋体]个类:[/font]Reader[font=宋体]和[/font]Writer[font=宋体],分别提供读取和写入服务。[/font]
Readr [font=宋体]必须实现[/font]PakReader [font=宋体]接口;[/font]Writer[font=宋体]必须实现[/font]PakWriter[font=宋体]接口。[/font]HALO[font=宋体]通过访问这[/font]2[font=宋体]个接口来实现对文件的读[/font]/[font=宋体]写操作。[/font]
public interface PakReader{
public abstract Pak readPak(String filename);
public abstract Pak readPak(InputStream in);;[font=宋体]从流中读取信息到[/font]Pak[font=宋体]中[/font]
public abstract String getName();;[font=宋体]获取插件名[/font]
public abstract String getDescription(); ;[font=宋体]获取插件描述[/font]
}
public interface PakWriter(){
public abstract void writePak(Pak pak,String filename);
public abstract void writePak(Pak pak,OutputStream out); ;[font=宋体]将信息写入到文件流中[/font]
public abstract String getName(); ;[font=宋体]获取插件名[/font]
public abstract String getDescription(); ;[font=宋体]获取插件描述[/font]
}
[size=12pt]3.2 [/size][size=12pt]Pak[/size][font=宋体][size=12pt]和[/size][/font][size=12pt]PakObject[/size][font=宋体][size=12pt]描述[/size][/font]
Pak[font=宋体]是资源的集合。读取文件时,[/font]HALO[font=宋体]通过[/font]PakReader[font=宋体]获取[/font]Pak[font=宋体],并将[/font]Pak[font=宋体]的信息显示在用户界面上以供修改。所有的修改都是基于[/font]Pak[font=宋体]对象。回写文件时,[/font]HALO[font=宋体]采用一次性提交,就是将修改后[/font]Pak[font=宋体]交给[/font]PakWriter[font=宋体]来处理,这样就做到了文件格式无关性。[/font]
[font=宋体]简而言之,[/font]Pak[font=宋体]就是[/font]PakObject[font=宋体]的容器,提供了[/font]PakObject [font=宋体]的访问机制,是[/font]HALO[font=宋体]和插件数据通信的桥梁。[/font]HALO[font=宋体]用插件读取[/font]Pak[font=宋体],利用[/font]Pak[font=宋体]修改[/font]PakObject[font=宋体],并将[/font]Pak[font=宋体]返回到插件中重写,[/font]HALO[font=宋体]充当数据消费者的角色。[/font]PakObject[font=宋体]是所有资源的接口,提供了读写资源的通用方法:[/font]
public interface PakObject{
public abstract String getName(); ;[font=宋体]获取资源名称[/font]
public abstract void setName(String str); ;[font=宋体]设置资源名称[/font]
public abstract String getDescription(); ;[font=宋体]获取资源描述[/font]
public abstract void setDescription(String str); ;[font=宋体]设置资源描述[/font]
public abstract Long getLength(); ;[font=宋体]获取资源长度[/font]
public abstract void setLength(Long len); ;[font=宋体]设置资源长度[/font]
public abstract String getType(); ;[font=宋体]获取资源类型名[/font]
public abstract voidsetType(String str); ;[font=宋体]设置资源类型名:[/font]String,Sound,Image,UnKnown
public abstract void setModify(boolean flag);;[font=宋体]设置资源是否被修改[/font]
public abstract boolean isModify(); ;[font=宋体]返回资源修改状态[/font]
}
PakString,PakImage,PakSound,PakUnKnown[font=宋体]等从[/font]PakObject[font=宋体]继承。分别表示:文本字符串,图像,声音以及未知数据。插件编写者需要了解文件的格式,并打包成对应的[/font]PakObject[font=宋体],再加入到[/font]Pak[font=宋体]容器,这样[/font]HALO[font=宋体]就能读取并修改[/font]Pak[font=宋体]了。[/font]
[[i] 本帖最后由 樱花树 于 2007-10-18 21:25 编辑 [/i]] [b][size=14pt]4.[/size][/b][b][font=宋体][size=14pt]动手写[/size][/font][/b][b][size=14pt]Handy-games plugin[/size][/b]
[font=宋体] 前面已经说了[/font]Handy games[font=宋体]文本资源文件的数据结构,现在我们开始编写插件。首先打开[/font]eclipse[font=宋体],选择[/font]File->New->Project [font=宋体]这里选择[/font]Java Project [font=宋体],点击[/font]Next[font=宋体],在[/font] Project Name[font=宋体]行内输入项目名:[/font]HandyGamesPlugin [font=宋体]其余按照默认选项,点击[/font]Next[font=宋体],这里出现项目设置,我们可以更改运行目录等,切换到[/font]Libraries[font=宋体]选项卡,选择[/font]Add External Jars[font=宋体],接着在出现的对话框中我们选择下载好的[/font]HaloPluginLib.jar[font=宋体],这样就导入了这个库文件,点击[/font]Finish[font=宋体]。在左侧的[/font]Package Explorer[font=宋体]中我们可以看到项目和被引用的插件开发包。这样,我们就进入了项目的[/font]Workspace[font=宋体]。右键点击[/font] Package Explorer[font=宋体],选择[/font]New->Class[font=宋体]使用向导新建一个类,在出现的对话框中输入类名[/font]HandyGamesReader[font=宋体]和包名[/font]xiaoyur.plugin.handygames[font=宋体],点击[/font]finish[font=宋体]。我们就创建了一个新的类。这个类必须从[/font]PakReader[font=宋体]继承,于是我们在[/font]class[font=宋体]定义后加上[/font]implements PakReader[font=宋体]。当然,先得导入包:
[/font]import com.wedomo.halo.plugin.*;[font=宋体]接下来可以实现上面描述的伪代码了。[/font]
[font=宋体]值得注意的是:[/font]JAVA[font=宋体]按找顺序[/font](big endian)[font=宋体]读取字节到缓冲区数组中,为了将它变成逆序,得使用额外的处理方法,比如反序[/font]2[font=宋体]个字节:[/font](m_data[0])|(m_data[1]<<8)[font=宋体],恩?似乎不对。忘记说了,[/font]JAVA[font=宋体]中[/font]byte[font=宋体]类型是有符号的[/font](-128-127)[font=宋体],那么又得再想办法:[/font]
([b]int[/b])(m_data[0]&0xff)|(((m_data[1]&0xff)<<8));[font=宋体]总算可以了,还真费力。我们从文件流中按照格式读出了文本(我们只需要文本),然后把它打包成[/font]PakString[font=宋体],最后放入[/font]Pak[font=宋体]中。好了,[/font]HALO[font=宋体]能读[/font]lng[font=宋体]文件了。现在[/font]Export [font=宋体]试试看。在[/font]Package Explorer[font=宋体]的项目文件树中,找到[/font]HandygamesReader.java [font=宋体],右键[/font]->Export([font=宋体]导出[/font])[font=宋体],为了发布[/font]CLASS[font=宋体]和打包[/font]JAR[font=宋体]文件,我们选择[/font]Java->JAR File[font=宋体],接下来在[/font]Jar File[font=宋体]路径框中,我们输入需要输出的[/font]JAR[font=宋体]全路径,比如[/font]D:\myplugin\HandygamesReader.jar[font=宋体],接着一路[/font]Next[font=宋体]或者直接[/font]finish[font=宋体],忽略警告。好了,一个读取器就完成了。接着我们编写写入器[/font]HandygamesWriter.jar[font=宋体]。按照上面的方法,将[/font]2[font=宋体]个[/font]JAVA[font=宋体]类多选以打包,发布成[/font]Handygamesplugin.jar[font=宋体]。完成了!哦[/font]..[font=宋体]还有一步,就是编写[/font]MF[font=宋体]文件。打开[/font]EP[font=宋体]或者[/font]UE[font=宋体],编写:[/font]
Reader-Class: xiaoyur.plugin.handygames.HandygamesReader
Writer-Class: xiaoyur.plugin.handygames.HandygamesWriter
Description: HandyGames Plugin
Name: HandyGames
[font=宋体]别忘记了最后还要打[/font]2[font=宋体]个回车键。用[/font]utf-8[font=宋体]格式保存成[/font]MANIFEST.MF[font=宋体]。回到刚才那个[/font]JAR[font=宋体]文件,用[/font]WINRAR[font=宋体]打开它,找到原来的文件[/font]MF[font=宋体],把新的直接拖拽回去覆盖掉。好了,把插件放到[/font]/halo/plugins/[font=宋体]下面。启动[/font]HALO[font=宋体],打开一个[/font]handy games [font=宋体]游戏,找到[/font]lng[font=宋体]资源文件,右键[/font]->[font=宋体]插件[/font]->[font=宋体]更多插件,选择我们刚才那个,点击[/font]OK[font=宋体],返回来在插件管理器中,就看到了我们要修改的文件了。开始汉吧。[/font][font=Wingdings]J[/font]
[font=宋体]最后完成的时候,别忘记点保存键。这样,一个插件就完成啦[/font]~[font=宋体]![/font]
[[i] 本帖最后由 樱花树 于 2007-10-18 21:27 编辑 [/i]] [b][size=14pt]5. [/size][/b][b][font=宋体][size=14pt]值得注意的问题[/size][/font][/b]
[font=宋体] 编写插件需要注意很多问题,暂时目前还不能脱离[/font]HALO[font=宋体]调试,等待[/font]BB[font=宋体]的[/font]HaloLibDebug[font=宋体]版本出来,这样成功率就提高很多。只有知道了文件格式,我们才能读取和修改,世界上像[/font]handy games[font=宋体]这样几乎所有产品用统一规范的公司很少,所以我们要不断的编写针对某一产品的插件,有时也只能用一次。其实,只要大家耐心分析,仔细调试,编写插件也不是难事!本人水平有限,正在不断学习中,所以文中有不当之处还请大家指正,在此拜谢![/font]
[align=right][i][u][font=宋体]更多信息:[/font][/u][/i][i][u][url=http://forum.minisoyo.com/]http://forum.minisoyo.com/[/url][/u][/i][i][/i][/align][align=right][i][u]By [/u][/i][i][u][font=宋体]樱花树[/font][/u][/i][i][u] (xiaoyur)2007/10/18 [/u][/i][i][u][font=宋体]初[/font][/u][/i][/align]
[[i] 本帖最后由 樱花树 于 2007-10-18 21:28 编辑 [/i]] :大笑:大笑:大笑楼下的永远占不到沙发。。
[[i] 本帖最后由 樱花树 于 2007-10-18 21:28 编辑 [/i]] :害羞 MM占位真疯狂
:002 拿下小小的沙发,MM不反对吧?
:006 据说此沙发可以延年益寿,MM见MM疯狂,姑娘见姑娘呼喊,丫头见丫头迷恋,,,and so on
PS:招商。。。 支持教程~支持佔位!:眼睛 :幸福 :流汗 编辑的真累啊 :眼睛 我来了,还算前面 支持了!很好的东西! 后排支持了 前面支持 [quote]原帖由 [i]443200530[/i] 于 2007-10-18 20:36 发表 [url=http://forum.minisoyo.com/redirect.php?goto=findpost&pid=901744&ptid=47927][img]http://forum.minisoyo.com/images/common/back.gif[/img][/url]
:害羞 MM占位真疯狂
:002 拿下小小的沙发,MM不反对吧?
:006 据说此沙发可以延年益寿,MM见MM疯狂,姑娘见姑娘呼喊,丫头见丫头迷恋,,,and so on
PS:招商。。。 [/quote]
永恒支持
不是你
你是 怎能不支持
學習中~~ 樱花,谢谢你! 来支持了 高人,先顶后看 :害羞 LZ 你一定会解决我家HALO打不开的问题:眼睛
详情请见[url=http://forum.minisoyo.com/thread-46241-1-1.html]http://forum.minisoyo.com/thread-46241-1-1.html[/url]:眼睛
[[i] 本帖最后由 杰杰不休 于 2007-10-18 23:58 编辑 [/i]] :吹吹 菜鸟路过~~
