Diablo II Menu
 Diablo 2 News
 Contact
 Links
 Premium Diablo 2
 Scamming sites
 Link to Us
 Advertise on NewD2Event
 Firefox Browser

  Diablo 2 Topsites

Sponsors

Diablo 2 Download
 1.12a Hacks/Cheats/Bots
 FREE CD Keys
 Bots
 Hacks
 Utilities
 Diablo II Demo
 Diablo I Demo
 D2Movies
 Wallpapers

Single Player
 Editors
 Items
 Saved Games
 Mods

Methods
 Diablo II Methods
 Diablo 2 Auradin Glitch
 Forgotten Sands Exploit
 Act5 In classic
 How To Level Up
 Glitch Rush Guide
 God Mode Method
 Level 1-80 in 2 hours
 Teh Dupe 1.11b
 Dupe method 1.11b
 Merc Aura Stack Glitch
 Eth Armor Upgrade Bug
 PK in Town

MMBot
 About MMBot
 Download MMBot
 MMBot History

D2HackIt
 D2HackIt
 D2HackIt Modules
 D2HackIt Bots

RedVex and Plugins
 RedVex
 RedVex FAQ
 Adblock Plugin
 Flash Plugin
 Leader Plugin
 Macro Plugin
 MephStone Plugin
 NetStuff Plugin
 Tppk Plugin
 Magnet Plugin
 Chicken Plugin
 Keychain Plugin
 ZCommand Plugin
 TownTele Plugin
 HotPlug Plugin
 FastMod Plugin
 GameName Plugin
 Hide offline friends Plugin
 Forgotten Sands Exploit
 PreCast Plugin
 Crapstuff Plugin
 RedEye Plugin
 ChickY Plugin
 Mindigo Plugin
 FastTp Plugin
 EZBaal Plugin
 Origami Plugin
 autoHPK Plugin
 FollowBot Plugin
 OSTPPK Plugin

BlueVex and Plugins
The .NET Version of RedVex
 BlueVex
 MagicSpoof
 rPlugins
 BVSniffer
 BluePickit
 HelloWorld
 Adblock
 RuneInfo
 GoldSpoof
 Bind

botNET
 botNET
 beta v0.5.0.x
 botNET Bots
 botNET MultiKilla
 botNET Utilities
 botNET Libraries
 botNET Applications

Screenshots
 1.08 Items
 Duped Items
 Hacked-Bugged Items
 Perfect Items
 Crafted Items

Patches
 Download
 v1.11b
 v1.11
 v1.10
 v1.09D PC

Diablo 2 Info
 ALL

Fun
 Soj
 MH
 Ban
 Cube buffer dupe
 Diablo2 RIP
 Noob

Diablo 2 Items
 The Basics
 Items
 Basic Item Info
 Potions
 Rings & Amulets
 Weapons & Armors
 Socketed Items
 Gems
 Jewels
 Runes
 Rune Words
 Magic Items
 Prefixes & Suffixes
 Rare Items
 Crafted Items
 Set Items
 Unique Items
 Charms
 The Horadric Cube

Diablo 2 Quests
 Quest Index
 Quest Basic
 Quest Rewards
 Act I Quests
 Act II Quests
 Act III Quests
 Act IV Quests
 Act V Quests
 The Secret Cow Level

Diablo 2 Maps
 Act 1
 Act 2
 Act 3
 Act 4
 Act 5

Diablo 2 NPCS
 NPCs Index
 Act 1
 Act 2
 Act 3
 Act 4
 Act 5

Shrines and Wells
 Shrines and Wells

Diablo 2 Calculators
 Damage
 Speed
 Others
 More calculators

Diablo 2 Character Guides
 Faster Block Rate
 Faster Cast Rate
 Faster Hit Recovery
 Diablo 2 Hunters
 Amazon [7]
 Assassin [10]
 Barbarian [10]
 Druid [6]
 Necromancer [9]
 Paladin [20]
 Sorceress [13]

Links
 D2event Network
 Diablo and Hellfire




Content


Diablo 2 hacking (packets, d2hackit etc.) guides
Packets Guide by EvilCheese
Packets Guide by After-Death
Diablo II Packet Lists & Info
Diablo II 1.10 Skills List
D2Hackitv2 Tutorial
Battlenet Packetlist v1.11 Compilant
D2Hackit v2.00 API Reference

D2HackIt | D2HackIt Modules | D2HackIt Bots


D2Hackit v2 Module Tutorial by Lemmin

This tutorial is designed to teach you how to create a module to be used with d2h v2. This is NOT a c++ tutorial although you can very easily learn some by reading this tutorial. I'm actually still learning c++ myself, so please correct me if i say something that is completely wrong.

For this tutorial we will create a follow mod, why not?

first thing to know is that d2h modules are dynamic link libraries (dll)s. if you use visual c you can create a new project for a dll and put the include folder in the project folder. otherwise you can do it with notepad and boreland compiler. (do people need a visual c tutorial too?)

I am going to go through all the segments of code and have the whole thing posted at the bottom.
Code:
#include "includes\ClientCore.cpp"

First thing we need is the #include because we are calling definitions from d2h files. if you are using d2 v.80 (or whatever) its just "ClientCore.cpp".



Code:
CLIENTINFO
(
0,1,
"LemminMan",
"lemminman.home.comcast.net",
"Lemmin Follower",
""
)



This functuion displays the information you put into it, as well as saving the info for the help functions (i think). this will be general version information about your module. you don't need to put this function in, but its a good way to personalize it.

LemminMan = Your name!
lemminman.home.comcast.net = your website without the http protocal
Lemmin Follower = the name of your mod.

(i think the numbers are version numbers or sometihng, but i never cared about them and i dont remember what that last string is supposed to be. Some tutorial huh?)



Code:
bool on = false;
GAMEUNIT guTarget;
char chTargetName[24];
DWORD dTarget[4];



Next we declare all the variables:
1. first we have a booleen variable 'on' that is set to false if you want your mod to require a command to turn it on at start, and true if you want a command to turn it off at start.

2. And because this is a follow module, we will need a gameunit for the target that we will follow (gameunit can only be used in d2h v2 (i think)).

3. We also want an array of chars to create a string for the name of the character that we will follow. this is used for whatever reason, but in this tutorial we will have a hud showing the target.

4. And last, we need a dword for the targets id when we grab it.



Code:
BOOL PRIVATE Seton(char** argv, int argc)
{
on = true;
server->GamePrintInfo("ÿc4Lemmin Follower ÿc3:: ÿc2ON");
return true;
}
BOOL PRIVATE Setoff(char** argv, int argc)
{
on = false;
server->GamePrintInfo("ÿc4Lemmin Follower ÿc3:: ÿc1OFF");
return true;
}



These are two commands that can be executed in your module (they are implemented in the next section of code). There are on and off, which are self explainatory. whatever is put in these functions will execute whenever the respective command is typed in.



Code:
MODULECOMMANDSTRUCT ModuleCommands[]=
{
{"on", Seton, "Turn Follower On"},
{"off", Setoff, "Turn Module Off"},
};



This struct sets up the commands you want to be in your module. for now we have on and off. they corrispond to seton and setoff respectively.



Code:
VOID EXPORT OnGameJoin(THISGAMESTRUCT* thisgame)
{

server->GamePrintInfo("ÿc4Lemmin Follower ÿc3:: ÿc2Loaded!");
return;
}



This code is executed whenever you enter a game. it is also executed whenever the module is loaded (which is kind of anoying for some reasons, but there are ways around it).
Theres nothing here i want to do accept announce that its loaded.



Code:
DWORD EXPORT OnGamePacketBeforeSent(BYTE* aPacket, DWORD aLen)
{
if (aPacket[0] == 0x5d && aPacket[1] == 0x02 && aPacket[2] == 0x00)
{
memcpy(&dTarget[0], aPacket+3, 4);
guTarget.dwUnitID = dTarget[0];
server->GetUnitName(&guTarget, &chTargetName[0], 24);
if (server->VerifyUnit(&guTarget))
{
server->GameInfof("ÿc4Lemmin Follower ÿc3:: ÿc2Target setÿc5: ÿc3%s", chTargetName);
}
else
{
server->GamePrintInfo("ÿc4Lemmin Follower ÿc3:: ÿc2Target to far away to get name");
}
}
return aLen;
}



This code is executed just before a packet is sent, aPacket[] being the packet in question. lots there, lets break it down by line.



Code:
if (aPacket[0] == 0x5d && aPacket[1] == 0x02 && aPacket[2] == 0x00){}


This is unclicking the lil ear button next to a player (the squelch inverse thingy). so i am telling d2, if the packet starts with 5d and continues on with 02 and 00 (5d0200). basically, you click the ear button in the player menu twice to select the character you want to target.



Code:
memcpy(&dTarget[0], aPacket+3, 4);


memcpy is the function we will use to copy one dwords adress to another. aPacket to dTarget in this one.
i want all 4 bytes of the dTarget to be filled starting with the first one which is [0] in an array.
then i want to start from the 4th byte in aPacket and copy 4 bytes total. its plus 3 because it is starting at 1, so the 4th is plus 3 more.
and like i said, i want 4 bytes so the 4 at the end is the length.



Code:
guTarget.dwUnitID = dTarget[0];


and now those 4 bytes are in our gameunit struct and we can do all sorts of stuff with it. (im sure theres a way to memcpy straight to the struct, but i cant figure it out )



Code:
server->GetUnitName(&guTarget, &chTargetName[0], 24);


since we have a valid gameunit all set up, we can use all the neeto functions d2h gives us. lets start by finding the name of the gameunit we just got. we put it in the array of chars that we defined earlier. remember it was defined to have 24 chars, so thats what the next item is, the length.



Code:
if (server->VerifyUnit(&guTarget)){}


heres another neet function. this will return a non-zero if the gameunit is found in the game at the time it is called.



Code:
{
server->GameInfof("ÿc4Lemmin Follower ÿc3:: ÿc2Target setÿc5: ÿc3%s", chTargetName);
}
else
{
server->GamePrintInfo("ÿc4Lemmin Follower ÿc3:: ÿc2Target to far away to get name");
}



if its found we send a lil message to the game. infof can be used just as printf in c in that you use a %[letter] as the format of the variable that is being printed. %s is string.
if its not found we say its not found :p



Code:
return aLen;


everything executed? so go ahead and send that packet to the server.



Code:
DWORD EXPORT OnGamePacketBeforeReceived(BYTE* aPacket, DWORD aLen)
{
return aLen;
}



here is another useful function that is used the same as OnGamePacketBeforeSent. this is not needed for this module though.



Code:
DWORD EXPORT OnGameTimerTick(void)
{
if (on == true )
{
me->MoveToUnit(&guTarget, false);
Sleep(500);
}
return 0;
}



this next lil d2function is called errrrrtime the game loops. so you should be careful when putting code in here not to make stuff ultra spam.
anyway, if on is true, which means if you typed .mod on, than it will execute the followed code. MoveToUnit is another one of those magic d2h v2 functions that does just what its called, so we go to the target, yay! and false is to not be put in a job queue, if its true, it wont go to the next movement untill it reaches the spot from the previous MoveTo.
then so as not to spam the crap out of the d2 server with movement packets, we put about a half second pause between moving. (i dont know what the return changes, sorry )



Code:
VOID EXPORT OnDraw(CGameDC* pDC, LPCRECT lpScreenRect)
{
// Then we draw a transparent white rectangle outlines by a
// yellow frame.
pDC->SetPenColor(0xEA); // 0xA8 = yellow
pDC->SetPenWidth(1); // Frame width is 1
pDC->SetBrushColor(0x20); // 0x20 = white
pDC->SetBrushTransparency(1); // Nice-looking translucent.
RECT rect = { 325, 1, 475, 26};
pDC->Rectangle(&rect);

// Finally we draw some text at center of the rectangle, using
// a thin font.
pDC->SetFont(D2FONT_THIN);
if (server->VerifyUnit(&guTarget))
{
char chColorName[27] = "ÿc3";
strcat(&chColorName[0], &chTargetName[0]);
pDC->DrawText(chColorName, &rect, DT_CENTER | DT_VCENTER);
}
else
{
pDC->DrawText("ÿc1NO TARGET", &rect, DT_CENTER | DT_VCENTER);
}
}



And here is our hud! the drawing is confusing, so i just left the original comments by the d2h creator.
The rect coords are left, top, bottom, right.

below i will explain the code that isnt commented:



Code:
if (server->VerifyUnit(&guTarget))
{
char chColorName[27] = "ÿc3";
strcat(&chColorName[0], &chTargetName[0]);
pDC->DrawText(chColorName, &rect, DT_CENTER | DT_VCENTER);
}
else
{
pDC->DrawText("ÿc1NO TARGET", &rect, DT_CENTER | DT_VCENTER);
}



here we check to see if the unit is found in the game just like before. if it is, we do the 3 lines there.
we declare a char just like the chTargetName here, but with 3 extra chars for the d2 color code. setting it equal to "ÿc3" fills up the first 3 chars with the color code for blue.
now strcat, which is a fucntion similar to memcpy, that will append the string from chTargetName to chColorName. we dont need to use +2 or anything because it is appending, not copying.
now that we have a colorful string, we pop it into the DrawText function, put it in rect, and center it. (thats about as well as i can explain that, i didnt read up on the draw functions much.)

and if the unit isnt found, we just say no target.





And thats it!!

here is the code all together for you copy pasters:



Code:
#include "includes\ClientCore.cpp"
CLIENTINFO
(
0,1,
"LemminMan",
"lemminman.home.comcast.net",
"Lemmin Follower",
""
)

bool on = false;
GAMEUNIT guTarget;
char chTargetName[24];
DWORD dTarget[4];

BOOL PRIVATE Seton(char** argv, int argc)
{
on = true;
server->GamePrintInfo("ÿc4Lemmin Follower ÿc3:: ÿc2ON");
return true;
}
BOOL PRIVATE Setoff(char** argv, int argc)
{
on = false;
server->GamePrintInfo("ÿc4Lemmin Follower ÿc3:: ÿc1OFF");
return true;
}

MODULECOMMANDSTRUCT ModuleCommands[]=
{
{"on", Seton, ""},
{"off", Setoff, ""},
};

VOID EXPORT OnGameJoin(THISGAMESTRUCT* thisgame)
{
server->GamePrintInfo("ÿc4Lemmin Follower ÿc3:: ÿc2Loaded!");
return;
}

DWORD EXPORT OnGamePacketBeforeSent(BYTE* aPacket, DWORD aLen)
{
if (aPacket[0] == 0x5d && aPacket[1] == 0x02 && aPacket[2] == 0x00)
{
memcpy(&dTarget[0], aPacket+3, 4);
guTarget.dwUnitID = dTarget[0];
guTarget.dwUnitType = UNIT_TYPE_PLAYER;
server->GetUnitName(&guTarget, &chTargetName[0], 24);
if (server->VerifyUnit(&guTarget))
{
server->GameInfof("ÿc4Lemmin Follower ÿc3:: ÿc2Target setÿc5: ÿc3%s", chTargetName);
}
else
{
server->GamePrintInfo("ÿc4Lemmin Follower ÿc3:: ÿc2Target to far away to get name");
}
}
return aLen;
}

DWORD EXPORT OnGameTimerTick(void)
{
if (on == true )
{
me->MoveToUnit(&guTarget, false);
Sleep(1000);
}
return 0;
}

/*DWORD EXPORT OnGamePacketBeforeReceived(BYTE* aPacket, DWORD aLen)
{
return aLen;
}*/

VOID EXPORT OnDraw(CGameDC* pDC, LPCRECT lpScreenRect)
{
// Then we draw a transparent white rectangle outlines by a
// yellow frame.
pDC->SetPenColor(0xEA); // 0xA8 = yellow
pDC->SetPenWidth(1); // Frame width is 1
pDC->SetBrushColor(0x20); // 0x20 = white
pDC->SetBrushTransparency(1); // Nice-looking translucent.
RECT rect = { 325, 1, 475, 26};
pDC->Rectangle(&rect);

// Finally we draw some text at center of the rectangle, using
// a thin font.
pDC->SetFont(D2FONT_THIN);
if (server->VerifyUnit(&guTarget))
{
char chColorName[27] = "ÿc3";
strcat(&chColorName[0], &chTargetName[0]);
pDC->DrawText(chColorName, &rect, DT_CENTER | DT_VCENTER);
}
else
{
pDC->DrawText("ÿc1NO TARGET", &rect, DT_CENTER | DT_VCENTER);
}
}





hope this helped.





Diablo 2 Newsletter
Questions, ideas, problems, wishes?
Be informed whenever something new comes up
(or any important problems are fixed.).
You can unsubscribe from this newsletter at any time.
No comments yet
*Name:
Email:
Notify me about new comments on this page
Hide my email
*Text:
 

If you can't read the word, click here

Verification code:
Powered by Scriptsmill Comments Script
Diablo