本帖最后由 andersgong 于 2020-8-4 08:54 编辑
今天为大家带来《OD陪你玩暗黑2》这个系列的第三篇文章---主流1.13C版本突破极限达到255孔的mod教程。
特别声明:本人是该功能的原创作者,这个功能目前在全球范围内应该还没有第二家(目前只有1.10版有人实现了15孔而已)。
为了暗黑2的回忆,我特意将修改方法整理成文档教程,分享给大家,希望大家喜欢和支持。
为了避免不必要的麻烦,本文不会提供任何逆向成品和太过具体的汇编地址。
下面,先看一下成品的效果吧:
底材---

底材.png (102.52 KB, 下载次数: 4)
下载附件
2020-8-4 08:42 上传
镶嵌物品---

s001.png (175.47 KB, 下载次数: 2)
下载附件
2020-8-4 08:42 上传
8孔效果---

8孔s001.png (215.02 KB, 下载次数: 3)
下载附件
2020-8-4 08:42 上传
开255孔---

开孔后.png (493.28 KB, 下载次数: 5)
下载附件
2020-8-4 08:35 上传
镶嵌255个物品---

255孔s001.png (878.46 KB, 下载次数: 4)
下载附件
2020-8-4 08:36 上传
言归正传,开始正文内容。
要支持多孔,就需要解决原版的几个问题:
1、itemstatcost.txt里,item_numsockets的Send bits和Save bits默认为4,也就是2^4=16(0-15),最多支持15孔的存档
2、itemtyps.txt里各种物品的MaxSock1/MaxSock25/MaxSock40对应三个难度,也限制了该类物品的最大孔数
3、dll里对孔数和镶嵌物的判断和堆栈处理都是硬编码,需要找到位置修改,这里主要依赖OD
4、dll对孔数和镶嵌物的存档操作需要修改
5、孔数和镶嵌物的显示需要重写
下面的讲解,均假设你已经把itemstatcost.txt里的item_numsockets修改到了8,也就是2^8=256(0-255),并且也对itemtyps.txt进行了修改,还做了开255孔的cube公式,因为本文的开孔仅针对cube进行讲解。
一、cube开孔(物品生成和任务打孔的原理是一样的,找到地址稍作修改即可,我已经全部搞定)
开孔相对来说比较简单,只需要修改几处比较和跳转即可。这里需要修改d2common.dll几处硬编码,至于patch地址,完全可以参照1.10自行找到,如下图:

图片1.png (95.23 KB, 下载次数: 3)
下载附件
2020-8-4 08:38 上传
第一处是直接比较不能超过6孔,第二处是跟底材的格子数进行比较,超过格子就按格子来,也就是下面的jg指令。
大家可以将这里的两个06改为你需要的数值,比如0xFF就是255,然后把下面的jg改为直接jmp即可。

图片2.png (95.99 KB, 下载次数: 3)
下载附件
2020-8-4 08:38 上传
同上。
如果想要孔数能够突破物品的格子数,那么还需要对下面的代码进行patch:

图片3.png (34.12 KB, 下载次数: 3)
下载附件
2020-8-4 08:39 上传
这个jl指令就是判断格子数小于开孔数的,直接nop掉即可。
二、镶嵌
镶嵌这里,看过1.10 8s那篇文章的朋友都知道,首先要解决堆栈问题,15s只需要简单的改一下压栈的立即数即可,完全可以参照那篇文章自行修改。但是我们要255孔的话,这个函数的栈空间是不够的,我这里采取的办法是直接jmp出来压栈后再jmp回去即可解决。如下图:

图片4.png (32.56 KB, 下载次数: 3)
下载附件
2020-8-4 08:40 上传
三、存档
接下来是对存档的读写操作。
镶嵌物多于7个的时候,原来fog.dll里的3bit已经无法存放了(2^3=8只能存7个镶嵌物)。
因此,我在这里想了个办法,因为镶嵌物这3个bit前面的内存里是4个字节的底材code,而底材的code都是可见字符,也就是说ASCII码<0x80,最大也就是0x7F,最高bit永远是0,可以借用。
那么我们就可以利用4个字节code中每个字节借用一个bit,加上原来的3bit,一共就是7bit,2^7=128,可以支持到127个镶嵌物读写。
如果还不够,接下来的步骤就非常重要了,原版code实际都是三个字节,最后一个字节固定是0x20,二进制是0010,实际上有两个bit可用。
因此,我们可以在这里再借用一个bit,一共就是8个bit了,2^8=256,也就是可以存放255个镶嵌物。
当然,以上骚操作的前提有两个,大家一定要注意:
1、物品code的4字节ASCII码不能超过0x80
2、如果mod物品的code达到了4个字节,那么最后一个字节的ASCII码不要超过0x3F(孔数不超过127的话可以无视这条)
当然,这两者之间可以做个权衡,如果确实需要更为广阔的物品code,那么可以通过减小孔数上限来达到平衡。
所以这里我们需要直接将读写物品存档的代码hook出来进行处理,如下图:

图片5.png (30.75 KB, 下载次数: 3)
下载附件
2020-8-4 08:40 上传

图片6.png (31.05 KB, 下载次数: 3)
下载附件
2020-8-4 08:40 上传
自己重新对镶嵌物数量进行编码和存取。
四、显示
最后是显示的问题,当孔数超过物品格子的时候,原版dll是无法正常显示的,因此我们在这里也要hook一下,我自己用C语言重写了显示的函数,如下图:

图片7.png (33.54 KB, 下载次数: 3)
下载附件
2020-8-4 08:41 上传

图片8.png (89.35 KB, 下载次数: 3)
下载附件
2020-8-4 08:41 上传
五、最后其实如果有需要的话,孔数还可以增加,理解了方法,剩下的就是体力活了。
最后的最后,祝大家玩得愉快!
附上全过程的视频,可在线观摩,感谢大家支持!
https://v.youku.com/v_show/id_XNDc0MDUyNzg0OA==.html
免费评分
参与人数 31威望 +1
吾爱币 +46
热心值 +29
理由

°何人能及
+ 1
+ 1
啊这

wzh527
+ 1
+ 1
谢谢@Thanks!

伤不起的小马
+ 1
+ 1
真大佬,暗黑这么久了还能整出这种大活,牛逼,期待下一期

Donghui891227
+ 1
+ 1
谢谢@Thanks!

jcy7368591
+ 3
+ 1
直呼牛逼!!!

Hmily
+ 1
+ 20
+ 1
感谢发布原创作品,吾爱破解论坛因你更精彩!

ihusr
+ 1
谢谢@Thanks!

shiwoha
+ 1
+ 1
我很赞同!

z297171662
+ 1
佩服4楼的评论,太搞笑了哈哈

爆山大爷
+ 1
+ 1
感谢发布原创作品,吾爱破解论坛因你更精彩!

mincai
+ 1
+ 1
66666

iefydi
+ 1
用心讨论,共获提升!

忧人孤卧寒窗
+ 1
+ 1
我陪暗黑玩OD

loo1221ool
+ 1
+ 1
热心回复!

huyu01
+ 1
用心讨论,共获提升!

vethenc
+ 1
+ 1
牛逼克拉斯!

YYL7535
+ 1
+ 1
谢谢@Thanks!

西门吹牛
+ 1
+ 1
弄一个圆盾,打255个孔,装红宝石,改名成蜂窝煤!

zq5202002
+ 1
+ 1
修改后玩两小时,不修改能玩两年。

Oo凌轩oO
+ 1
已经处理,感谢您对吾爱破解论坛的支持!

xkwkl
+ 1
+ 1
谢谢@Thanks!

windypro
+ 1
+ 1
谢谢@Thanks!

zixijian
+ 1
+ 1
感谢发布原创作品,吾爱破解论坛因你更精彩!

Nekohai
+ 1
用心讨论,共获提升!

jinne0
+ 1
+ 1
谢谢@Thanks!

焰澈
+ 1
我很赞同!

xiaoze1993
+ 1
+ 1
谢谢@Thanks!

lengyanhuo
+ 1
+ 1
热心回复!

howmoney
+ 1
+ 1
楼主厉害!

明月相照
+ 1
+ 1
感谢发布原创作品,吾爱破解论坛因你更精彩!

就叫柠檬吧
+ 1
OD陪我玩暗黑×
查看全部评分