;=======================================================
;Smorg's Diablo II LOD Mini OOG Controller for Battlenet
;Version 1.0 Modifed to work with sjsp by sheppard..
;=======================================================
opt("PixelCoordMode", 2)
opt("MouseCoordMode", 2)
opt("RunErrorsFatal", 0)
opt("SendKeyDelay", 200)
$RunLoop = 0
$CurrentCDkey = 1
#Include "IniRead.au3"
#Include "Checksums.au3"
SetNextCDkey()
If WinExists($D2WinName) Then
MsgBox(0, "", "Looks like a d2 window is already open! Close it before launching the bot.")
Exit
EndIf
;AdLibEnable("ShowSum", 200) ;for debugging... replace the checksum in ShowSum() to adjust what to look for
If LaunchD2() = 0 Then
MsgBox(0, "", "Oh noes! we failed to log in! Better check the error log to find out why...")
Exit
Else
LogEvent(0, "Launched Diablo II and successfully logged in to the Lobby.")
EndIf
;===============================
;Main Loop: Your code goes here!
;===============================
While 1
For $RunCount = 1 To 9999
$RunLoop = $RunLoop + 1
If CreateGame() = 1 Then
;MsgBox(0, "blub", "Looks like we've made it in-game okay... but You've gotta write some code if you want me to do something! O_o")
Send("{ENTER}")
Sleep(200)
Send(".start")
Sleep(200)
Send("{ENTER}")
$begin__ = TimerInit()
while ScreenCheck("Lobby") = 0
Sleep(1000)
If (TimerDiff($begin__) > 90000) Then
ExitLoop
EndIf
wend
If $RunLoop > 9 Then
Sleep(1000)
Else
Sleep(5000)
EndIf
;$RunLoop = $RunLoop + 1
Else
$RunLoop = 0
LogEvent(0, "Restarting D2 - New keys!!")
opt("SendKeyDelay", 5)
D2Kill()
SetNextCDkey()
for $loopage = 1 to 50
If LaunchD2() = 0 Then
LogEvent(0, "Failed to login #" & $loopage)
D2Kill()
Sleep(300000)
Else
ExitLoop
EndIf
Next
opt("SendKeyDelay", 200)
EndIf
If $RunLoop > 9 Then
$RunLoop = 0
LogEvent(0, "Restarting D2 - New keys!!")
opt("SendKeyDelay", 5)
D2Kill()
SetNextCDkey()
for $loopage = 1 to 50
If LaunchD2() = 0 Then
LogEvent(0, "Failed to login #" & $loopage)
D2Kill()
Sleep(300000)
Else
ExitLoop
EndIf
Next
opt("SendKeyDelay", 200)
EndIf
;Chicken()
;Exit
Next
WEnd
;===============================
Func SetNextCDkey()
$ClaKey_M = "\data\global\sfx\cursor\wavindx.wav"
$ExpKey_M = "\data\global\chars\am\cof\amblxbow.cof"
If (FileCopy(@ScriptDir & "\CDkeys\" & $CurrentCDkey & "\wavindx.wav", @ScriptDir & $ClaKey_M,9) = 1) AND (FileCopy(@ScriptDir & "\CDkeys\" & $CurrentCDkey & "\amblxbow.cof", @ScriptDir & $ExpKey_M,9) = 1) Then
LogEvent(0, "CDkey was injected successfully ~#" & $CurrentCDkey)
Else
LogEvent(0, "CDkey was NOT injected successfully ~#" & $CurrentCDkey)
EndIf
$CurrentCDkey = $CurrentCDkey + 1
if ($CDkeyCount < $CurrentCDkey) THEN
$CurrentCDkey = 1
endif
EndFunc
;Launches D2, logs in, and gets you to the lobby. Returns 0 if failed, 1 if success.
Func LaunchD2()
LogEvent(0, "Smorg's Mini OOG controller is launching Diablo II LOD for Battlenet...")
If Run($D2PathName & " " & $Paramaters) = 0 Then
LogEvent(1, "Failed to launch Diablo at " & $D2PathName & " Check your D2PathName key in Config.ini")
Return 0
Else
LogEvent(0, "D2 Loaded successfully!")
EndIf
WinWaitActive($D2WinName)
Sleep(1000)
WinMove($D2WinName, "", 0, 0)
MouseClick("Left", 100, 100, 1, $MenuMouseSpeed)
If ScreenWait("TitleScreen", 5000) = 0 Then Return 0
MouseClick("Left", 394, 353, 1, $MenuMouseSpeed)
If ScreenWait("LoginScreen", 10000) = 0 Then Return 0
MouseClickDrag("Left", 477, 336, 300, 336, $MenuMouseSpeed)
Sleep($MenuStaticDelay)
Send($Account)
Sleep($MenuStaticDelay)
Send("{TAB}")
Sleep($MenuStaticDelay)
Send($Password)
Sleep($MenuStaticDelay)
MouseClick("Left", 395, 470, 1, $MenuMouseSpeed)
If ScreenWait("CharacterSelect", 10000) = 0 Then Return 0
MouseClick("Left", 173 + (IsInt($CharSlot/2) * 277), 130 + (93 * (($CharSlot/2) - 1)), 1, $MenuMouseSpeed)
Sleep($MenuStaticDelay)
MouseClick("Left", 692, 557, 1, $MenuMouseSpeed)
Sleep(1000)
Run("HardLoad.exe") ; to inject, sjsp stuffs... :E
Sleep(2000) ; give time, to inject... :C
If ScreenWait("Lobby", 10000) = 0 Then Return 0
Return 1
EndFunc
;Create a game with dynamic waits & retries. Returns 0 if failed, 1 if success.
Func CreateGame()
For $Retry = 0 to 4
; If (IniRead(IniRead(@ScriptDir & "\Config.ini", "Settings", "RedvexIni", "0"), "Intercom", "WasDeadStatus", "1")) = 1 Then
; LogEvent(0, "Bot Died. Stopping due to that...")
; EXIT(0)
;EndIf
;// Above commented out, cause not used with sheppards bot...
LogEvent(0, "Attempting to create the game " & $GameName & $RunCount & " This is attempt number " & $Retry)
MouseClick("Left", 590, 462, 1, $MenuMouseSpeed)
If ScreenWait("CreateButton", 5000) = 0 Then
MouseClick("Left", 712, 461, 1, $MenuMouseSpeed)
Sleep(2000)
ContinueLoop
EndIf
If (IniRead(IniRead(@ScriptDir & "\Config.ini", "Settings", "RedvexIni", "0"), "Intercom", "WasHostiled", "1")) = 1 Then
$RunCount = Random(1, 5000, 1)
EndIf
$RunCount = $RunCount+$Retry
Send($GameName & $RunCount)
Sleep(200)
If ($GamePassLength > 0) Then
Send("{TAB}")
For $LOLx = 1 to $GamePassLength
Send(Random(0, 9, 1))
Next
EndIf
MouseClick("Left", 676, 418, 1, $MenuMouseSpeed)
If ScreenWait("GameJoin", 5000) = 0 Then
LogEvent(1, "Game create screen not detected after 5 seconds... will retry the game join.")
MouseClick("Left", 711, 461, 1, $MenuMouseSpeed)
ContinueLoop
EndIf
Local $Timeout = TimerInit()
While ScreenCheck("GameJoin") = 1
If TimerDiff($Timeout) > 30000 Then
LogEvent(1, "Looks like we got stuck on the game create screen for over 30 seconds...")
Return 0
EndIf
Sleep(500)
WEnd
If ScreenCheck("Lobby") = 1 Then
LogEvent(1, "Failed to Join! Bnet needs to fix their damn servers!!! Lets just retry...")
ContinueLoop
ElseIf ScreenCheck("GUIBar") = 1 Then
LogEvent(0, "Successfully joined the game after " & Round((TimerDiff($Timeout)/1000), 2) & " seconds.")
Return 1
Else
LogEvent(1, "Hmm, looks like we got lost somewhere while attempting to create a game...")
Return 0
EndIf
Next
LogEvent(1, "Failed to create a game after 5 retries.")
Return 0
EndFunc
;Dynamic wait for a screen. Feed a screen to wait for from Checksums.au3, or define your own. Also supply a timeout. Returns 0 if failed, 1 if success
Func ScreenWait($ScreenName, $Timeout)
Local $Checksum[5]
Local $Sum
$Checksum = Eval($ScreenName)
$Time = TimerInit()
Do
Sleep(200)
$Sum = PixelChecksum($Checksum[1], $Checksum[2], $Checksum[3], $Checksum[4])
If $Sum = $Checksum[0] Then Return 1
Until TimerDiff($Time) > $Timeout
LogEvent(1, $Sum & " does not match the expected the checksum of " & $Checksum[0] & " for the menu " & $ScreenName & " at coordinates (" & $Checksum[1] & " ," & $Checksum[2] & " ," & $Checksum[3] & " ," & $Checksum[4] & ") and timed out after " & $TimeOut & " milliseconds.")
Return 0
EndFunc
;Simple screen detection, so you don't have to type out the pixelchecksum every time. Returns 1 if the screen matches, 0 if failed.
Func ScreenCheck($ScreenName)
Local $Checksum[5]
$Checksum = Eval($ScreenName)
;LogEvent(1, PixelChecksum($Checksum[1], $Checksum[2], $Checksum[3], $Checksum[4]) & " is checksum for: " & $ScreenName)
If PixelChecksum($Checksum[1], $Checksum[2], $Checksum[3], $Checksum[4]) = $Checksum[0] Then
Return 1
Else
Return 0
EndIf
EndFunc
;Quit D2. will try to chicken first if you are in-game.
Func D2Kill()
For $Retry = 0 To 9
Send("{ESC}")
If Not WinExists($D2WinName) Then ExitLoop
Sleep(500)
Next
WinClose($D2WinName)
WinKill($D2WinName)
EndFunc
;Do a quick & effective game exit. Suitable for both emergency chickens, and standard save & exits.
Func Chicken()
For $Retries = 1 To $ChickenRetries
Send($KEY_ClearScreen)
MouseUp("Right")
MouseUp("Left")
Send("{ESC}")
$Timeout = TimerInit()
While 1
If (PixelGetColor(481, 535) <> 5406092) AND (PixelGetColor(320, 537) <> 6521492) Then
ExitLoop
ElseIf TimerDiff($Timeout) > 500 Then
LogEvent("Failed to open the main menu, will retry... Retry # " & $Retries)
ContinueLoop 2
EndIf
Sleep(100)
WEnd
MouseClick("Left", 400, 280, 1, 0)
$Timeout = TimerInit()
While TimerDiff($Timeout) < $ChickenTimeout
If (PixelGetColor(600, 575) <> 6512995) AND (PixelGetColor(5, 575) <> 2697257) Then ExitLoop 2
Sleep(100)
WEnd
If $Retries >= $ChickenRetries Then
LogEvent("Max Retries exceeded, Will terminate the Game.exe process")
ProcessClose("Game.exe")
Else
LogEvent("Failed to chicken, Will retry the chicken...")
EndIf
Next
LogEvent("Chicken was a success! ^^")
EndFunc
;Returns 0 if either a menu is open or we aren't in game, and returns 1 if the minipanel is in its expected position. (this requires it to be open)
Func IsMenuOpen()
If PixelGetColor(325, 559) <> 5274764 Then
If PixelGetColor(462, 559) <> 8429760 Then
Return 0
EndIf
EndIf
Return 1
EndFunc
;Simple logging function
Func LogEvent($Code, $String)
$LogFile = FileOpen(@ScriptDir & "\Logs\Events.txt", 1)
Select
Case $Code = 0
FileWriteLine($LogFile, @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & " [I]> " & $String)
Case $Code = 1
FileWriteLine($LogFile, @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & " [E]> " & $String)
EndSelect
FileClose($LogFile)
EndFunc
;Debug function... replace the search pattern with whatever you need.
Func ShowSum()
ToolTip(PixelCheckSum($GameJoin[1], $GameJoin[2], $GameJoin[3], $GameJoin[4]), 0, 0)
EndFunc