;======================================================= ;Smorg's Diablo II LOD Mini OOG Controller for Battlenet ;Version 1.0 ;======================================================= 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) 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 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