作者:无聊的菜鸟
时间:2009年3月
声明:“知道不?其实懒惰才是人类进步的源动力!”
山口山,大家都知道的,这里就不介绍了。
先说下为什么我会写下这些。首先吧,我不会写的很详细,至少不会直接给出Patch之后的代码。因为拿来主义总让我觉得变扭;其次,不写出来吧,总觉得憋着荒……
山口上自某个补丁之后,加入了一些额外的代码,外在的表现是减少了#132错误(违规访问内存)。但是,实际效果是私服自己制作的自定义物品(就是不是暴雪开放的装备)的图标全部显示为问号(图片路径为INV_MISC_QestionMark),也无法直接在背包中右击装备,同时无法自己对自己的自定义装备进行附魔,以及左键点击拿起这些物品后图标显示为问号(图片路径同样为INV_MISC_QestionMark)。而这些问题在官方物品上是不存在的。
当然,你会说也许私服传递的数据不正确才导致这样的。这句话有道理,在补丁和检验的过程中,不同的私服服务器端传递下来的数据的正确性差异很大。但是这并不是主要的,因为这些自定义装备在那个补丁之前同样没有这些问题,而现在,即使有这这些问题,这些物品依然可以通过拖放的方法将其装备在正确的位置,并且装备在角色身上之后,在角色信息页面中图标显示的也是正确的。所以我们得出的结论是,客户端中有限制代码。
--------------------------无辜的分割线---------------------------
插件部分(Lua):
其实最开始的时候,我是去google了解决方法,结果下下来了一个插件ItemPatch,记得好像是在zgwow.cn下的,这个插件里面Hook了GetContainerItemInfo和GetActionTexture两个API,然后自行处理的这个API中出现INV_MISC_QestionMark的情况,具体往下看注释,顺带扫扫盲:
-- Item's Patch For 2.4.2 Core by W.S :P -- 由W.S为山口山2.4.2版本编写。
WOW_GetContainerItemInfo = GetContainerItemInfo; --Hook
function GetContainerItemInfo(index, id)
local texture, itemCount, locked, quality, readable; --声明本地变量
texture, itemCount, locked, quality, readable = WOW_GetContainerItemInfo(index, id);
if( texture and string.find(texture,"INV_Misc_QuestionMark") ) then
-- DEFAULT_CHAT_FRAME:AddMessage("GetContainerItemInfo Item "..itemid);
local itemlink = GetContainerItemLink(index, id);
--调用API_GetContainerItemLink获取这个显示为问号的物品的物品链接。
local itemid = 0;
if( itemlink ) then
_, _, itemid = string.find(itemlink, "Hitem:(%d+):");
--在物品链接字符串中查找物品ID。实际为"Hitem:"字符串之后的数字。
texture = string.gsub(texture,"INV_Misc_QuestionMark", My_GetItemTexture(itemid) );
--调用下一级函数
-- DEFAULT_CHAT_FRAME:AddMessage( itemlink.." - ID: "..itemid.." - Texture: "..texture );
end
end
return texture, itemCount, locked, quality, readable;
end
--说到这里,其实在后面IDA山口山的时候,我们能发现其实有直接实现的GetItemID函数,
--但是这个函数没有被导出为API……而且嘛,过程其实是一样的……
function My_GetItemTexture( itemid )
if MY_ITEM_TEXTURE[ itemid ] ~= nil and MY_ITEM_TEXTURE[ itemid ] ~= "" then
--枚举下面数组中的ID对比,典型的查表法。
return MY_ITEM_TEXTURE[ itemid ];
end
return "INV_Misc_QuestionMark";
end
MY_ITEM_TEXTURE = {};
MY_ITEM_TEXTURE =
{
-- ["物品id"] = "INV_XXX_XXX",
["1"] = "INV_Qiraj_JewelGlyphed",
["2"] = "INV_Qiraj_JewelGlyphed",
......中间省略XX千字节.....
["6051190"] = "INV_Scroll_04",
["1401019"] = "INV_Trinket_HonorHold",
}
function GetContainerItemInfo(index, id) --我们依然以这个函数为例
local texture, itemCount, locked, quality, readable = WOW_GetContainerItemInfo(index, id);
if( texture and string.find(texture,"INV_Misc_QuestionMark") ) then
local itemlink = GetContainerItemLink(index, id);
local itemid = 0;
if( itemlink ) then --如果获得的物品链接不是空串
_, _, itemid = string.find(itemlink, "Hitem:(%d+):"); --获取itemID
_, _, _, _, _, _, _, _, __, texture = GetItemInfo(itemid); --使用API_GetItemInfo来获取路径
end
end
return texture, itemCount, locked, quality, readable; --返回需要的东西
end
0093D370 49 73 49 6E 76 61 6C 69 64 4C 6F 63 61 6C 65 00 IsInvalidLocale.
00FC1D68 70 D3 93 00 p訐.@
00FC1D40 0093D3F0 鹩? ASCII "SortRealms"
00FC1D44 00476D70 pmG. WoW.00476D70
00FC1D48 0093D3DC 苡? ASCII "GetSelectedCategory"
00FC1D4C 00476E40 @nG. WoW.00476E40
00FC1D50 0093D3C0 烙? ASCII "RealmListDialogCancelled"
00FC1D54 00475E10 ^G. WoW.00475E10
00FC1D58 0093D39C 溣? ASCII "IsInvalidTournamentRealmCategory"
00FC1D5C 00476B10 kG. WoW.00476B10
00FC1D60 0093D380 €訐. ASCII "IsTournamentRealmCategory"
00FC1D64 00476BC0 纊G. WoW.00476BC0
00FC1D68 0093D370 p訐. ASCII "IsInvalidLocale" <<--这里这里
00FC1D6C 00476C40 @lG. WoW.00476C40 <<--这个就是IsInvaliLocale的实现代码的地址
00FC1D70 00930B40 @? WoW.00930B40 <<--空字符串指针,这一段表结束的标记
00FC1D74 00000000 ....
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)