MS的KB更新还真挺慢的
今天同事问我问题,于是我想到了一年前写的文章:
CMD Prompt Can be Full Screen Again in Windows 7?! – An Explanation of Why Windows 7 Doesn’t Support CMD Prompt Full-Screen Mode and an Issue Analysis.
然后他找到了MS的KB:
http://support.microsoft.com/kb/926657
领先了半年啊~lol
Patch MsvpPasswordValidate still works on Win8
Win8弱爆了,这个还能用。
CA之行-1
Week 1
keywords: hotel, Niagara, jet lag, work, car rental
据说前台mm帮忙订机票酒店时总是考虑很周到,果然如此。机票订的是靠走道的座位,而且去时旁边没人,一个人很舒服。
以前好像没坐过Boeing 777. Air Canada给AC-087/AC-088配的都是777-300ER机型。YY一下什么时候能去体验A380和787,协和已经没机会了。由于是自西向东飞,所以其实一直能看到太阳。为了调节时差,全程是不允许打开遮光板的。空乘中有华裔的,不知道是从国航招的,还是在CA当地招的华人,英语没有中国口音,汉语有点但又不是台湾腔,空少空姐都30来岁的样子;也有空”姨”,年纪蛮大了,还在做空乘,身上香水味很重。接近14个小时的航程是够长的,所以看了有4部电影,包括猩球崛起这种新片,还有就是看地图,从实时GPS可以看出,直飞飞得并不”直”,绕到北极圈去了,经过了西伯利亚,白令海峡,阿拉斯加这些地方。最高海拔和飞行速度不记得了。飞机座位右前方有的男的挺惹眼的,又是拖鞋颈枕又看书,然后经常跑到前边一个mm旁边搭讪,开始以为是留学的,后来到了公司才发现原来是自己同事,哈哈。看看飞机上的人,猜着他们的职业与身份,也挺有意思。有的一看就是国内某机关去考察的;有的是去探亲,给移民的子女照看小孩子;有的人一句英语也不会说,去旅游的;也有手拿蓝本本的美国籍中国老太太。
大约是晚上7点抵达的YYZ(Pearson International Airport)。落地后两个感觉,一是冷,10月中旬,气温已经降到了6-7°,据说11月初就会下雪了;二是人少,虽然同时也有几个航班降落,但机场并不拥挤。清洁厕所的黑大叔,聚在一起聊天的黑哥们保安,拉着警犬巡视的女警。整体感觉上和浦东、虹桥还是很不相同,一种说不出的感觉,大约就是那种”成熟的发达国家+萧条+老龄化+人少”的集合体。犹豫了一下,没有直接租车,毕竟晚上了,又不熟悉交通,还是等白天吧。取了行李就打车去酒店了。
出租司机是个印度个哥们,问了目的地,设定好GPS,就朝着Markham出发了。一路闲聊着,也就很平常的问问哪里来,第几次来,来做啥之类的。是辆SUV,听说经常能打到林肯这种豪华车,后来和同事又去了一次机场,就坐了一回林肯。加国的涉及人工服务的收费都很高,比如出租车就是,大约30km的路,不算tips花掉,很贵的。怪不得老外到了中国都使劲叫车,实在便宜啊。给小费的时候土了,给了100他找我20,我自己算错了所以又看看他,于是他又给我5块,我才反应过来其实80就OK了,但这时候也不好把5块再还给他了,于是赶忙说谢谢,然后要了receipt,下车自己把箱子扛下来。后面吃饭给小费的时候就好多了,算多了就不大容易算错了。
Check-in,入住。后来回国之后同事和我说,入住的时候可以办一张VIP卡,算积分,回国后很多地方能用,比如航线里程,4星级送一晚之类的。当时前台小哥没和我提这事,也许他给自己积分了。。。之所以订这家酒店,一方面因为离公司近,步行5分钟就到,还有一个重要原因是有早餐,而且每周有3天也有晚餐的,所以基本上出差的同事都会订这家。
和航班座位一样,酒店房间的位置也很恰当, 4/5F,离电梯比较近。房间挺大的,感觉有20平米,大床房。还有厨房,设施很全,电炉灶,冰箱,微波炉,洗碗机,咖啡机,以及各种餐具,有食材基本完全可以自己做饭吃了。第二天还有活动,所以联系一下家里报个平安,就洗洗睡了。
第二天约好了,老爸的一个前几年移民到这里的同学带我去看瀑布,所以很早就起来了。下楼吃完早餐,正好人也来了,于是出发去瀑布。从小就很有方向感,从不迷路,所以一路都很清楚我们是在朝哪个方向行进。基本就是沿着Lake Ontario边缘开,大部分时间都会在QEW(The Queen Elizabeth Way)上,一条还挺有历史的路。有一段我们没有在桥上开,而是在乡间小路上,看了看普通民居,也进了家卖建材的超市逛逛。
然后就到了Niagara Falls。前几天刚下过雨,于是水发土黄色,而不是原有的白色。时隔一周再去,颜色就好看多了。我们把车停在靠近上游的一个公园内(43°04’06.71″ N 79°04’02.98″ W),就开始步行向瀑布进发了。在拍照片的同时,感受着大自然的力量。虽然是世界七大奇迹之一景观,却没有拥挤的赶脚。不像某地,一到节假日,甚至双休日也是,感觉就是去看人的。除了各国的游客,还有不少当地居民,来散步的,来锻炼的,牵着各式狗狗,在大自然的怀抱中尽情享受。当时真有一种马上来这里定居的冲动。在一块石头边静静的坐了一会儿,呼吸着这里的空气,看着巨大的水流,听着轰轰的水声,什么都不去想,真的是非常放松的10分钟。游客也各有特点。比如感觉是从欧美来的,夫妻两人带着2-3个孩子;从中亚,南亚来的,上下3代一大家子;老太太旅游团,看长相就知道是日本或者韩国的;各种喧哗的,一看就知道是国内来的。单从相机上也能看出诸多不同:亚洲面孔的装备基本都比较高级,长枪短炮各种单反;欧美的,还在用傻瓜机,甚至以前的老式摄像机。
Niagara Falls由3部分组成,Horseshoe Falls(43°04’40.50″ N 79°04’32.08″ W), American Falls(43°05’05.17″ N 79°04’10.61″ W), Bridal Veil Falls(43°05’00.71″ N 79°04’15.51″ W).加国这一侧比美国那边具有更好的欣赏角度。
逛完瀑布,拍了足够多的照片,就又去旁边的小镇(43°05’27.66″ N 79°04’32.51″ W)上看看。一个以旅游为主的小镇,摩天轮,鬼屋,游乐场什么的,还有Skylon Tower, 适合从高空俯视瀑布全景,一家IMAX剧院,播放瀑布相关的影片。在镇里绕了一圈回来,等到晚上瀑布开灯,又拍了一点照片。可惜没带三脚架,不然能拍出很美的瀑布夜景。
夜景看差不多,就打道回府了。等我到酒店,已经晚上11点了。来去的路上,还去参观了一下他一个亲戚家的房子,去了一些公园看看,以及一家华人超市-大统华(T&T),去买了点水果和吃的。赶快洗洗睡啊,第二天还要上班。。。
第一周工作,以熟悉环境、认识人、以及修bug为主。没办法,谁让快递从台湾到北美只要3天,而到大陆可能要3周呢,所以台湾同时宁肯把客户平台寄到北美让我修bug,我来是做项目的啊本来。。。周一早上开会,给Markham的同事分了一下我带来的小吃。担心他们有人不吃花生,所以就从来伊份买了各种蜜饯话梅。想了半天,怎么翻译呢,preserved plums吧,好在都能理解。公司里华裔面孔挺多的,当然有些人只会广东话。也能看到大胡子爷爷,像爱因斯坦一般,以及年纪很大了仍在做工程师的老外。
作为出差员工,有一点挺好的,那就是没有没完没了的会议!每周只需要参加一次他们的sync-up meeting,也没有人各种人来问问题,其他时间都能安心干活,于是挺有效率的。前一周多,搞定10多个issue。据老大说,那个月team的统计数据,我帮了很大忙。。。
刚下飞机的第二天就去了瀑布,还没什么时差的感觉。而工作的这周可是累坏了,每天下午3点开始就巨困无比,晚上回去就要睡了,半夜12点再醒,然后醒醒睡睡折腾一晚上。这样的状况等第一周快结束了才好转,时差总算倒过来了。大概是年纪大了。。。
还有个大事就是要租车。没车,真不行,靠步行只能在方圆2km活动,再远就走不动了。而且这里公交不方便,是极其不方便,具体的后面再说。刚下飞机没租是考虑晚上不方便开,要规律上班了,可真得租个车,后面还有一个月呢。先去酒店附近的Time Square,有家Thrifty。本来都搞定了,结果我把信用卡拿出来他们说不行,说这是debit card,不是major credit card不收,怎么解释都没用,于是作罢。再让国内一起来的同事载我去附近一家Herz,当天也不能租,说这里车少,一定要提前预约才可以,又作罢。一直折腾到周四,有个同事要回国了。因为机场租金比较便宜,而且有GPS,于是就和他一起做taxi到机场(林肯), 我送好他,然后租了车再从机场开回来。租车那里也是个印度哥们,已经提前在网上预约,办好手续很快就搞定了,Nissan Sentra开始不会用GPS,完全凭感觉开,开了很久觉得怎么还没到啊,于是开下高速,好好研究了一把GPS,找对方向,又继续开了回来。好在没开错方向。终于有车了,接下来的行动就自由多了。
来简单说说吃饭,主要是早餐。整体的饮食最后再总结吧。
酒店有早餐,所以不用担心早餐。说起来,我吃得真是多啊。。。
每天吃的有,注意是每天:
果汁/水
牛奶泡脆谷乐/粥
面包+果酱/黄油
薯角若干,水炒蛋,一片培根,一块烤牛肉
水果,酸奶
很能吃有木有…
在家里,基本就是一杯牛奶两片面包的水平,周末的话吃个煎饼什么的,绝对不碰油的东西。。。
午饭晚饭都在外面解决的,几乎都吃中餐。胃似乎还不适应每天西餐,而且也贵啊。。。而且去T&T买过几个盒饭,万一懒得出去也可以自己在房间里凑合。
总得来说,第一周就是调整的一周,各种方面的适应吧。睡不好觉真是痛苦。
几张照片:
CA之行-0
回来之后一直忙,忙到连安心听一会儿音乐的时间也没有。正好趁休假,事情也忙差不多了,抽出时间写掉。
在此之前没出过国,港澳台新马泰也包括在内。所以借出差的机会,补补经历也挺好的。
最早大概是5月份知道要出差的,然后就去把护照先办好。接下来就各种折腾吧,计划不断改变,时间不断调整,等最终确定是Q4都已经是8月份的事情了。然后就抓紧去签证了。公务签证比较快,印象中2-3周就好了(当时没记,于是具体时间都不记得了。。。)。然后签证的时候也挺折腾的,主要是准备不足。先是证件照,为了符合标准,就在photo booth里拍的,结果不收100的纸币。。。然后跑出去把钱换开,回来再拍。材料交上去,付钱,靠,差100,现金没带足。。。于是又跑出去银行取现。签证过程,没什么过程,交完材料就结束了。应该不是因为公务原因所以容易吧,大概是看我长得不像坏人,恩。大楼里有很多国家的签证中心,英国比利时什么的。CA这里基本没人,但隔壁好像是南非还是哪里,人很多。。
签证好之后,让前台小mm帮忙订酒店,订机票什么的,行程安排算是确定下来了。由于预算的原因还延期了一周,这样来回机票能省2000多。也不知道到底是大老板精打细算呢,还是代理商坑爹,总之就是又多折腾了一下,否则还能赶上Thanksgiving,趁机休个假。
自己也没准备什么,淘宝了一个26′的外交官,然后把本本上用的软件折腾好,skype充值,换外币,信用卡提上限,各种材料复印,翻译驾照,列购物清单之类的。
Dungeon Siege 3 *.OAF 格式分析 续
上次讲到了OAF的文件格式,经过后来进一步的分析与研究,发现有点问题,在此修正一下,并更新新的研究成果。
仍然还是四部分组成,file header, zlib stream offset table, zlib stream, file name and tree structure table,结构上没有问题。
1). File header. 文件头。
文件头到0×14这里结束了。0×1开始8的4个byte应该算作是表项的开始。
2). Zlib stream offset table. zlib数据流偏移表。
这部分的起点应该从0×18开始,而不是上次分析的从0x1C开始。
每一项的组成.hash在最前,而不是上次说的数据起始偏移在最前。
0×0: 4 bytes. 文件名hash值。这一部分的算法也是最近的反编译研究成果。
0×4: 4 bytes. zlib压缩包起始偏移。
0×8: 4 bytes. 是否压缩。0×10000000表示压缩过。
0xC: 4 bytes. Raw data size. 未压缩数据的大小。
0×10: 4 bytes. Packed data size. 压缩后数据的大小。如果为0则说明这一表项指向的数据没用压缩。
其余两部分没有变化。
接下来要说一下文件名的hash算法。
DS3中对字符串都会做hash计算,主要用于对OAF包中的数据进行校验,以判断是否非法。当然,一旦知道了校验方法,那么就可以随便替换了…
分析过程就不写了,挺长一段汇编计算,耐心就好。我用C重写如下。传入参数seed始终为0x2A.
注意两点:
1)反斜杠back slash要转化成斜杠slash
2)文件名都是小写的.但不要强制都转化为小写,因为DS3中其他大写字符串也用到了同样的hash算法。
最后顺便求教,有人知道这种算法有什么具体名字么?对hash算法不熟…
DWORD hash(const char * string, unsigned int length, DWORD seed)
{
char str[MAX_PATH] = {0};
char *pstr = str;
strcpy_s(pstr,MAX_PATH,string);
unsigned int lengtToHandle = length;
DWORD x = 0;
DWORD y = 0;
DWORD z = 0;
x = length + seed – 0×21524111;
y = length + seed – 0×21524111;
z = length + seed – 0×21524111;
while (*pstr != ”)
{
if (*pstr == ‘\\’)
*pstr = ‘/’;
pstr++;
}
pstr = str;
while(lengtToHandle > 0xC)
{
x += *pstr << 0×18;
x += *(pstr + 0×1) << 0×10;
x += *(pstr + 0×2) << 0×8;
x += *(pstr + 0×3);
y += *(pstr + 0×4) << 0×18;
y += *(pstr + 0×5) << 0×10;
y += *(pstr + 0×6) << 0×8;
y += *(pstr + 0×7);
z += *(pstr + 0×8) << 0×18;
z += *(pstr + 0×9) << 0×10;
z += *(pstr + 0xA) << 0×8;
z += *(pstr + 0xB);
x -= z;
x = ((z << 0×4) | (z >> 0x1C)) ^ x;
z += y;
y -= x;
y = ((x << 0×6) | (x >> 0x1A)) ^ y;
x += z;
z -= y;
z = ((y << 0×8) | (y >> 0×18)) ^ z;
y += x;
x -= z;
x = ((z << 0×10) | (z >> 0×10)) ^ x;
z += y;
y -= x;
y = ((x << 0×13) | (x >> 0xD)) ^ y;
x += z;
z -= y;
z = ((y << 0×4) | (y >> 0x1C)) ^ z;
y += x;
lengtToHandle -= 0xC;
pstr += 0xC;
}
switch(lengtToHandle)
{
case 0xC:
z += *(pstr + 0xB);
case 0xB:
z += *(pstr + 0xA) << 0×8;
case 0xA:
z += *(pstr + 0×9) << 0×10;
case 0×9:
z += *(pstr + 0×8) << 0×18;
case 0×8:
y += *(pstr + 0×7);
case 0×7:
y += *(pstr + 0×6) << 0×8;
case 0×6:
y += *(pstr + 0×5) << 0×10;
case 0×5:
y += *(pstr + 0×4) << 0×18;
case 0×4:
x += *(pstr + 0×3);
case 0×3:
x += *(pstr + 0×2) << 8;
case 0×2:
x += *(pstr + 0×1) << 0×10;
case 0×1:
x += *pstr << 0×18;
}
z = z ^ y;
z = z – ((y << 0xE) | (y >> 0×12));
x = x ^ z;
x = x – ((z << 0xB) | (z >> 0×15));
y = y ^ x;
y = y – ((x << 0×19) | (x >> 0×7));
z = z ^ y;
z = z – ((y << 0×10) | (y >> 0×10));
x = x ^ z;
x = x – ((z << 0×4) | (z >> 0x1C));
y = y ^ x;
y = y – ((x << 0xE) | (x >> 0×12));
z = z ^ y;
z = z – ((y << 0×18) | (y >> 0×8));
return z;
}
Dungeon Siege 3 OAF Packer 0.1 released
Initial version of DS3 OAF file packer.
Usage: OAFPacker <template OAF file> <directory to pack> <output file>
Example:
OAFPacker D:\data_localized_en.oaf D:\Data D:\patched.oaf
http://www.rayfile.com/zh-cn/files/b26ff354-a0db-11e0-8e78-0015c55db73d/
Future work:
Add Zlib compression support.
Add checksum calculation.
Dungeon Siege 3 汉化技术分析
Dungeon Siege 3 汉化技术分析
作者:Colin Xu
日期:2011/06/20
声明:本文内容出于对技术的兴趣和个人爱好撰写,请勿将本文用于任何商业目的。
链接:http://colinxu.wordpress.com/2011/06/21/dungeon-siege-3-%E6%B1%89%E5%8C%96%E6%8A%80%E6%9C%AF%E5%88%86%E6%9E%90/
转载请保持完整并注明出处。
有心情做这个,绝对是出于对前作的情节。不过鉴于本作与前作有较大差别,所以我还是建议用”基于前作故事背景的新游戏”这样的态度来看待,这样就能够享受每一代游戏不同的乐趣,而不用去纠结是不是正统。
先来看看游戏目录的整体架构。
比较显眼、让人觉得有文章的就是:
Dungeon Siege III.exe,可执行文件
一堆*.oaf文件,看上去很大的样子,显然游戏的主要资源都在这些OAF文件里了。
data文件夹,里面看到movies,恩,*.bik视频文件,不用说这就是所有过场动画了。如果你有Gabest分离器RadGtSplitter.ax和bink video的动态库binkw32.dll,用kmplayer就能直接看所有动画了。
这次的目标是探索如何汉化,并且理解DS3的资源,因此感兴趣的是那一堆*.oaf文件。
关于OAF文件的细节,参加上一篇博文:
http://colinxu.wordpress.com/2011/06/17/dungeon-siege-3-oaf-%E6%A0%BC%E5%BC%8F%E5%88%86%E6%9E%90/
这里要补充两点:
1.OAF文件的分析离不开Raptor的解包工具dungeon siege 3 OAF files extractor。站在前人的肩膀上继续研究,省去了从头开始的重复工作,所以要感谢Raptor的贡献。不过也要说明的是,Raptor的解包工具也有一些问题,比如会把未选择的文件也解包出来,在打包的时候会占用不必要的空间,等等。
2.OAF作为压缩包,其效果和解压至游戏目录的data\下是一样的。比如把语言文件data_localized_en.oaf用extractor解压到data目录下,形成这样的结构:
\data\global\loot_system\*.*
\data\global\strings\*.*
然后把data_localized_en.oaf删掉,那么游戏一样可以运行,游戏的所有字符一样可以显示。这样就很大程度上方便了修改,而不用每次修改都去打包。当然作为发布,自然还是单一文档更有优势,游戏运行前都会解压到内存中,就免去了许多小文件的读写造成的效率低下。
OAF文件的分工:
可以从名字中猜测,也可以解包查看,结果如下:
base_item_init.oaf,基本名称的定义,这里只有定义和命名,没有具体的资源。
data_archive.oaf,最大的文件,包含所有的图形和素材资源、脚本等等。
data_localized_en.oaf,这是英文版的,根据语言不同文件也不同。包含游戏中出现的所有字符串。汉化主要就是汉化这里的字符串资源。
engine.oaf,engine咯,Onyx Engine用来render的主要部分,这个应该是不需要我们去碰的。
从易到难,就先来看看字符串的汉化,也就是大量的文本翻译工作。都在data_localized_en.oaf文件中了。如果选其他语言版本当然也是可以,每条字符串所在的文件名都是一样的,字符串ID也是一样的,主要是根据语言不同而显示不同。这一步很简单,把文件解包了,翻译好,然后选择打包或者就放在\data\下,就可以了。
改好之后可以很快看到效果,但如果你改的是中文字,用日语版改的人中文有些字符不能显示,而用其他语言版改的人中文完全不能显示。现在这个年代写的代码,除非特别不注意的,基本都不会是不能处理单字节字符造成的,所以基本都是找不到合适的字体来显示非西语字符。否则日文版为什么可以显示呢?
漏掉一件事。看看\data\目录下,是否有个game.oeisku文件,这个文件是用来选择语言和语音的。如果没这个文件,那就打开data_archive.oaf解压一份放到\data\目录下吧。然后修改一下game.oeisku,就可以自由选择语言版本了。我建议把汉化后的字符串资源命名为data_localized_chs.oaf,并在game.oeisku中进行相应修改,这样即不会影响其他语言,又能在各种语言之间自由切换。
已经说了,字符串文本的翻译只是大量体力劳动,没有很多技术门槛。关键难点还在于,如何让中文字符能正常显示。接下来就重点说这个。
如果你有日文版文本data_localized_en.oaf,那么解压出localized_fonts.gfx。如果没有,也没关系,素材包data_archive.oaf中同样有这个文件。
顺便提一下,data_archive.oaf中与字体有关的文件有4个:
localized_fonts.gfx,高分辨率用的字体库
localized_fonts_stddef.gfx,标准分辨率用的字体库
localized_fonts.scn,对上述的描述
gfxfontlib.gfx,其他字体库
我在有的版本的localized_fonts.scn里面,还看到了localized_fonts_ch.gfx并且被定义为manual load,感觉像是预留了中文版。
其实只要关注localized_fonts.gfx即可,其他文件有兴趣的自行研究吧,方法相同。
找个十六进制编辑器,打开localized_fonts.gfx,注意到前三个byte是
0×43 0×46 0×58
即字符CFX
这样的GFX文件,是Scaleform GFX格式的。如果签名是CFX,则表示该文件是压缩的SWF(flash格式);如果签名是GFX,则表示该文件是未压缩的SWF。
对于CFX,把它编辑成CWS;对于GFX,把它编辑成FWS。然后把文件扩展名改成SWF,如果能正常打开,就表示正常。
对于localized_fonts.gfx,把它修改成CWS就可以正常打开了。
这里提一下Scaleform GFX格式。这种格式其本质就是一个SWF(flash),但其中加了Scaleform自己的Tag,如果你不用它提供的工具进行编辑,或者不懂它的格式,修改后的文件是无法正常作为Scaleform GFX正常使用的。
改完文件签名后继续看一下这个文件。
既然是SWF,那么其第4个byte就表示编译发布时使用的flash版本。
紧随其后的四个字节表示SWF的大小,也包含文件头。如果是压缩的,那么这个大小表示压缩前的大小;如果是未压缩的,那么就等于当前文件大小。
这前面的八个字节是SWF的文件头。
由于是压缩的SWf,接下来的数据是由zlib压缩的数据流,必须先解压缩才能继续编辑。可以使用zlib压缩工具做单纯的解压缩,也可以找一款flash的decompile工具直接反编译这个swf,根据个人需要。我是直接当做zlib的压缩流来解的,然后拼在文件头后,组成完整的未压缩SWF。如果直接反编译会漏掉很重要的一部分,也是Scaleform GFX特有的一段Tag。
文件头:
43 57 53 09 F4 F7 00 00
; CWS,压缩的SWF,flash版本9,文件大小0xF7F4
解压后的zlib流:
78 00 05 5F 00 00 0F A0 00
; 帧的大小是Xmin=0,Ymin=0,Xmax=550,Ymax=400。为什么这么算,请自己读SWF的文档吧。
00 0C 01 00
; 帧率12,帧数1
1F FA 6F 03 02 00 00 00 0E 00 00 0F 6C 6F 63 61
6C 69 7A 65 64 5F 66 6F 6E 74 73 01 00 1E 00 00
00
这一段很有看头,Tag type是1000, tag length是31。标准SWF中并没有定义这一段,这一段就是Scaleform GFX自己的特殊tag。如果处理完SWF少了这一段,一定要手动加上,否则修改后的文件无法被识别。
往后都是SWF标准的tag了。
得到正常的SWF文件,就可以反编译进行修改了。可以用Sothink SWF Decompiler配合Adobe Flash,或者直接用Sothink SWF Quicker进行修改。
看它的ActionScript文件,可以知道,字体是这样使用的:
如果定义了dt1,dt2,…,dt6,这些文本框,则把它们作为font放入字体集合。看上去有6个命名,其实只有3个文本框。
当要拿get_mapped_font_name时,把字符串表示的变量作为字体名返回给调用者。
当要拿get_localized_font_name时,把字符自己的字体返回给调用者。
由于我们改的是localized字符串,因此就要改dt1,dt2,…,dt6这些文本框中字符串的字体。比如我改的是幼圆。记得要把文本中的字符都嵌入。
然后重新发布为flash。这里还是要选未压缩的SWF。因为发布时不论是Adobe Flash还是Sothink SWF Quicker,都会抛弃不认识的tag,然后压缩。这样我们就没办法把Scaleform GFX自己的特殊tag一起压缩进去了。
发布为SWF后,记得要手工把那段tag type=1000的东西放在第一个tag段,并且修改文件表示为GFX(因为现在是未压缩SWF),修改文件大小(4-8个字节),然后重新命名为localized_fonts.gfx。
好了基本完成,可以测试一下效果:把该文件放到\data\gui\localized_fonts.gfx,配合改好的中文文本,这下汉字可以正常显示了吧~
最后还有一步,如果我们希望把文本和字体一起发布为单独的语言包,完全可以把这些做成一个文件。由于Raptor的工具还有点问题,我用的是自己的工具,通用性不太强,等如果有心情写个好的打包工具再放出吧。要向自己改的话,只要照我上一篇中说的文件结构改就可以了。
技术工作告一段落~我要真正开始玩DS3啦~~
Dungeon Siege 3 *.OAF 格式分析
探索未知事物,比玩游戏本身要有趣的多。
上一篇提到,有一些现成的工具可以用来提取、压缩OAF文件,不过还是想对文件结构能有更精确的了解。经过一番分析,有了以下结果,不过仍有部分未知,有待继续研究。
DS3的OAF文件基本可以分为四部分:file header, zlib stream offset table, zlib stream, file name and tree structure table
1). File header. 文件头。
0×0: 3 bytes. 即被称为magic number或者signature的部分,’OAF’
0×3: 9 bytes. 未知。当然这一部分也可能是文件签名的一部分。
0xC: 4 bytes. File name table entry offset. 保存文件名表的入口偏移。
0×10: 4 bytes. 未知。
0×14: 4 bytes. Entry number,表项数目。zlib数据流包含的压缩包数目应该与文件名数目相等,否则无法匹配。
0×18: 4 bytes. 未知。感觉像是某种校验。
2). Zlib stream offset table. zlib数据流偏移表。
每个表项都指向文件中具体一个压缩包的未知,表项长度为0×14个byte。容易算出来,这部分的长度应该是 0×14 bytes * 表项数,出于对齐的考虑,这部分结束后可能有若干字节补零。
每个表项的结构如下:
0×0: 4 bytes. zlib压缩包起始偏移。
0×4: 4 bytes. 未知。感觉上可能是与压缩算法有关的参数。
0×8: 4 bytes. Raw data size. 未压缩数据的大小。
0xC: 4 bytes. Packed data size. 压缩后数据的大小。如果为0则说明这一表项指向的数据没用压缩。
0×10: 4 bytes. 未知。感觉有可能是未压缩数据的某种校验。
3). Zlib stream. zlib数据流。
这一部分的起始地址应该是0×10 byte对齐的,即”起始地址 & 0xF = 0″。
根据第二部分的每一个表项,都可以在这部分中找到对应的、压缩后的数据流。
4). File name and tree structure. 文件名和目录结构。
该部分的偏移在文件头中有描述。
这部分是若干个字符串,每个字符串都有标准结尾”0×0″. 文件名和第二、三部分按照相同的次序排列,一一对应。
有了以上这些信息,接下来准备做一个提取用的工具,顺便也玩一下zlib。另外,未知的部分也要想办法研究一下。
Dungeon Siege 3 初体验及相关工具
从DS1的喜欢,到DS2的迷恋,到3代出来,真的好久了。
DS最先吸引住人的应该是其背景音乐,宏大的场面,昂扬的斗志,以及世界的奇幻,每个人都能在一遍又一遍重复的音乐中找到那种感觉。
其次就是其扩展性极强的mod系统,给游戏带来了更多变化和乐趣。当时自己痴迷其中,也制作/修改了几个mod相关的工具。
等3代的推出等了好久,现在出来了,玩了一把,却有少许失望。
音乐并没有很引人入胜,没有感觉。
虽是Obsidian制作,不过没有了前2代那种感觉,更多的融入了黑曜石自己历代作品的想法。也可能是Square Enix发行的关系,觉得欧美的感觉不正统,而是带上了日式欧美的影子。
不知道是否支持Mod,只看到一定会有DLC,但系统来看mod是不太可能支持了。
画面还是不错的,华丽了很多。不过本人玩游戏对画面并不太重视。
说一说相关工具。大概是沿袭了2代的体会,第一时间就去找相关工具,找到的相关资源如下。不难找所以就不放链接了。
DungeonSiege3Extractor – Raptor的解包工具 DungeonSiege3Translator – Raptor的翻译工具 offzip – Luigi Auriemma的通用解包工具,适用于从偏移提取压缩文件 packzip – Luigi Auriemma的注入工具,与offzip配套使用
使用说明: Extractor可以打开*.oaf的压缩档并提取内容。 比如data_localized_vo_en.oaf,可以发现是英文的全称语音,ogg格式。 比如data_localized_en.oaf,游戏中用到的字符串,比如gui.std和oei_shared_gui.std基本就是所有界面相关的字符串了,呵呵。不过只是这样简单改一下是不能汉化的,还有code page的问题,想办法研究一下。 Translator,方便解析std文件进行字符串修改。 offzip,从指定offset提取有效zip压缩包的工具。用-s参数查看oaf的偏移,可以得到和extractor相同的结果。 packzip,把修改过的文件inject到oaf中,也就是patch。
不管怎么说,总还是很喜欢的作品,耐心打完再谈体会吧。
M50创意园
其实我不懂艺术的。我和艺术唯一沾边的大概就是听听古典音乐了吧。
沿着莫干山路尽头的涂鸦巷一路走进去,除了各种涂鸦风格的不同之外,感觉也是随之变化的,从城市角落的破马路,到硬朗的厂房,再到残破的待拆小楼,最后到一个很具现代气息的创意园入口。颇有意思的是,残破小楼周围有着广场上那种广播,看着,听着,非常有五、六十年代的那种感觉。其实那声音来自对面的垃圾房,里面放着的广播产生了极好的共鸣。不太协调的是对面住宅小区外有很多中档车,略破坏气氛。
阴天,小雨,这种天气还挺适合逛艺术之地的。
改造后的厂房,只有留下的管道和墙上的铭牌告诉我们这里曾经是什么,除此之外,就是各种装饰风格的工作室、展览室。颜色和线条都很简单,不同的作品让你感觉到,主人有不同的风格。当然还有一点是共同的:玻璃门上贴着的银联标记。
两个多小时,大概看了1/4不到的地方吧。油画、摄影、雕塑,还有其他艺术品,都看了一些。想不出很多词汇来描述,作者用各种熟悉的手段,来表现自己内心追求的一种想法,或者一种意识形态。其实并不难明白有些作品表达的意思,作品中的元素有时候是很简单的。只是很难明白,他们选择用这样一种方式表达一些东西的过程。大概这就是我们和搞艺术的人的区别吧:思维方式。
很多门没敢去推开。。。因为里面没有人,怕一眼就看出来自己不懂进去瞎逛。听说这是摩羯男爱面子!= =!
偶尔也装一回文青,体会些东西。














Recent Comments