Personally, I've been interested into this topic, since long time ago.
| Introduction Video | |
|
|
|
Expendables, what are expendables? Expendables are the items which are expendable
My main purpose was creating/defining a new type of them, not just a basic gold scroll..
How can we achieve that... One of the easiest things is following the packet sent after using your expendable item, 0x704C | 0xB04C | AGENT_INVENTORY_ITEM_USE.
Following them is an easy thing to do, just a constant search, and some breakpoints and you'd end up there, at the function that handles item usage, 0x00510980.
The function is a part of a well-known class, CGObjPC. It has a single argument, which is the client item usage message/packet | 0x704C.
So, the function should be parsing the packet and doing instructions, so we should find out the structure of the item usage packets.
Here's a correct structure for both client/server packets:
Code:
//Success Example [C -> S][704C] 18 ................ //Inventory Slot EC 08 ................ //TID [S -> C][B04C] 01 ................ //Result (1 = Success | 2 = Fail) 18 ................ //Inventory Slot 0F 27 ................ //Quantity EC 08 ................ //TID //Fail Example [C -> S][704C] 19 ................ //Inventory Slot ED 4E ................ //TID //(if TID == skin changer scroll's TID) 77 07 00 00 ................ //New skin's ObjID 22 ................ //New skin's scale [S -> C][B04C] 02 ................ //Result (1 = Success | 2 = Fail) 92 18 ................ //ErrorCode
before too.How about error code? Error code is a number which indicates if an error is occurred or not. If error code is 1, then everything is alright and your item will be consumed as an expendable, otherwise then its not ok and your item won't be consumed. Error code is also used indicate the error type and showing a proper message for it. (for example, an error code of skin changer scroll, the code with value 6290 indicates this message "UIIT_MSG_CHAR_SKIN_ERR_ARMOR")
Code:
TID = CashItem + (TypeID1 * 4) + (TypeID2 * 32) + (TypeID3 * 128) + (TypeID4 * 2048)
So, now we know the packet structures, we followed the game server parse too. I guess, let's create our fancy scroll before we get deeper,
RefObjCommon:
Code:
1 41798 ITEM_MALL_GOLD_SCROLL ????? xxx SN_ITEM_MALL_GOLD_SCROLL SN_ITEM_MALL_GOLD_SCROLL_TT_DESC 1 0 3 3 13 24 180000 3 0 1 1 1 255 0 1 0 0 1 0 0 0 0 0 0 0 -1 0 -1 0 -1 0 -1 0 -1 0 0 0 0 0 0 0 100 0 0 0 xxx item\etc\drop_mall_scroll.bsr item\etc\e090930_super_scroll.ddj xxx xxx 21333
Code:
21333 1 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 666 9000 -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx 0 0 0
If you try to use the scroll, also with a packet debugging, the scroll won't be affected if you right click on it, but if you look at your packets log, you'll find something like:
Code:
[C -> S][704C] 0D ................ //Inventory Slot ED C6 ................ //TID [S -> C][B04C] 02 ................ //Result 02 ................ //ErrorCode
After an hour of following game server's, I found the function that returns the error code and rejects our new expendable! (I am not sure if they're divided as groups by first 2 item type ids or not, but I am good bruh :v)
So, after doing a proper hook with our new item TID exception, finally everything seems to work fine!
Let's do a little last touch, we need to create settings for our fancy scroll!
So, how about customizing a new param too?
If you re-look at RefObjItem line above, I created a new custom param with ID "666", which refers to a "gold reward", and Desc1 contains the amount of gold. Had to parse GS's object data too and check if Param1 contains the gold reward param ID (666) or not.
You can do the check for the whole 20 params if you'd like too. I did it as for the first one only. Sorry, I am lazy.
Client Side: (all files below are a part of this path: Media\server_dep\silkroad\textdata\)
item_grouping.txt:
Code:
보호석 3 3 13 24 SN_ITEM_TOOLTIP_GROUPING_127
Code:
1 SN_ITEM_TOOLTIP_GROUPING_127 ???? (??) 0 0 0 0 0 Gold Scroll Gold Scroll 0 0 0 0 0 0 1 SN_ITEM_MALL_GOLD_SCROLL Gold Obtain Scroll 1 SN_ITEM_MALL_GOLD_SCROLL_TT_DESC This scroll will give you a specific amount of gold.
Code:
1 41798 ITEM_MALL_GOLD_SCROLL ????? xxx SN_ITEM_MALL_GOLD_SCROLL SN_ITEM_MALL_GOLD_SCROLL_TT_DESC 1 0 3 3 13 24 180000 3 0 1 1 1 255 0 1 0 0 1 0 0 0 0 0 0 0 -1 0 -1 0 -1 0 -1 0 -1 0 0 0 0 0 0 0 100 0 0 0 xxx item\etc\drop_mall_scroll.bsr item\etc\e090930_super_scroll.ddj xxx xxx 1 2 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 666 9000 -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx -1 xxx 0 0
An extra thing which some people may need/wonder about,
All that research above is to use a very very basic expendable item, like hp or mp... How about something like skin changer scroll, which you click on it, it opens a window to customize your new skin settings and it gets consumed.
At this situation, we'll need to do a client part too. We're basically gonna hook the place where item usage function is called, handle it well like with a new window too, customizing our new data then sending the item usage packet with the main data, slot and TID and your extra ones. (Remember that item usage packet should be encrypted!)
Also handling the packet extra data from the server side. Server side is required in both situations...
Conclusion: This maybe was one of the most interesting things I've worked on. So, hope you guys make a good use of it
Download: Attached below. You may not need the sro_client part, unless you want to add extra data to the usual item usage packet structure.
Note: Any addresses given above were found on VSRO 1.88 game server and sro_client, so they are most likely different on any other version.
Note: Structures found in the files are for VC80 libs, back when strings were 28 bytes.
Note: Always compile on Release!
Special thanks to: florian0






Great
