' * ' * Copyright (C) 2015 il, Lance ' * ' * This program is free software; you can redistribute it and/or ' * modify it under the terms of the GNU General Public License ' * as published by the Free Software Foundation; either version 2 ' * of the License, or (at your option) any later version. ' * ' * This program is distributed in the hope that it will be useful, ' * but WITHOUT ANY WARRANTY; without even the implied warranty of ' * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ' * GNU General Public License for more details. ' * ' * You should have received a copy of the GNU General Public License ' * along with this program; if not, write to the Free Software ' * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 'il '1.0 '&il_GameCreator:il 'Modified heavily by Lance, hell this might as well be a complete re-write from scratch. Nothing of iL's code even remains. ' ******** BEGIN CONFIGURATION SETTINGS, You can and SHOULD change these values. -Lance GameBotName = "efgb" GameBotPw = "ddd" HostBotName = "efhb" HostBotOwner = "{Lance}" GameBotChannel = "HostBotTestingGrounds" 'Channel that GameBotName should stay in HostBotChannel = "HostBotTestingGrounds" 'Channel that HostBotName should stay in 'GameBotChannel = "War2BNE" 'Channel that GameBotName should stay in 'HostBotChannel = "War2BNE" 'Channel that HostBotName should stay in AutoHostGameInterval = 5 'This is in MINUTES. Every 15 minutes the bot will try to host a game itself. Setting this to 0 will cause the bot to not autohost anything. -Lance UseTeamviewer = "Yes" ' Set to NO if you do not use Teamviewer. I use it, so it's here. This removes the Nag Screen from the remote server when you disconnect from it and then re-maximizes War2. -Lance AutoRebootWar2Interval = 0 'Reboot War2 if it's missing for X amount of time. Set to 0 to disable MaxAutoStartTime = 10 'Max time a bot will stay in a game before autostarting it. This limits players to asking for games to stay open for to long. MaxGameTimeInterval = 15 'This is the max time the bot is allowed to be in the "in game" status. Make sure this is LOWER than MaxAutoStartTime by at least 5 mins or so or games could get killed by a reboot and that would be sad ;) 0 = Infinate, but I dont recommend this as your bot could get stuck in a game. -Lance MaintMode = "off" 'This stops anyone from using the bot OTHER than GameBotName, HostBotName, and HostBotOwner, values:on off MaintMsg = "Hostbot currently in maint mode." ' ******** END CONFIGURATION SETTINGS, You should not touch anything else unless you are a programmer. -Lance ' Define some globals -Lance Public GameBotStatus, RebootCounter, AutoHostGameCounter, MaxGameTimeCounter, Username, GameOwner, MapName, MapSpeed, GameType, StartTime, GameTeams, MapResources, OnePeon, MapFixedOrder, GamePassword, ForceStart, CPUs 'Max Map Navigation keys. This should be plenty, if its not enough, push more keys per element or increase the size of the array here -Lance Dim MapNavigation(256) 'Used for presets, 256 should be plenty. Dim preset_cmd_array(256) 'Create a Tick event that we can use sort of like a Cronjob or to simulate Realtime statuses such as where the bot is, etc. -Lance CreateObj "LongTimer", "Tick_Event" Tick_Event.Interval = 1 Tick_Event.Enabled = True ' Load Autoit COM Object. This is required to control the mouse! If mouse movements/clicks dont work, then you need to install AUTOIT from here: https://www.autoitscript.com/cgi-bin/getfile.pl?autoit3/autoit-v3-setup.exe -Lance Set Shell = CreateObject("wscript.shell") Set oAutoIt = CreateObject("AutoItX3.Control") oAutoIt.AutoItSetOption WinTitleMatchMode, 2 'Attempt to Join HostBot's channel. -Lance AddQ "/join " & HostBotChannel 'Initialize some counters that are used in the Ticks events. -Lance GameBotCounter = 0 InGameCounter = 0 TeamViewerNagScreenCounter = 0 AutoHostGameInterval = AutoHostGameInterval * 60 MaxGameTimeInterval = MaxGameTimeInterval * 60 AutoRebootWar2Interval = AutoRebootWar2Interval * 60 If AutoHostGameInterval > 0 Then AutoHostGameCounter = AutoHostGameInterval If MaxGameTimeInterval > 0 Then MaxGameTimeCounter = MaxGameTimeInterval 'Autoit.WinActivate can sometimes fuck up the screen if it's run while War2 is in the Chat screen. So we fix it by minimizing/maximizing from a Game Lobby. -Lance Sub FixScreen() 'Open Create Game screen SendKeysToWar2 "{ALTDOWN}c{ALTUP}" SetGameName "dontenter" SetGamePassword "123" SendKeysToWar2 "{ENTER}" 'This will fix a bug that causes War2 to maximize incorrectly. We're only able to fix it in the Game Lobby chat or In game itself. -Lance oAutoIt.WinSetState "Warcraft II", "", 6 Sleep(1) ActivateWar2 Sleep(2) SendKeysToWar2 "{ALTDOWN}c{ALTUP}" End Sub '---------------------------------------------------------- BEGIN Stealthbot Hooks system is called "Events". All "Events" (AKA Hooks) begin with Event_NameOfEvent -Lance ' ----------------- user whispers command --------------------- Sub Event_WhisperFromUser(Username, Flags, Message, Ping) cmd_found = 0 map_start_time = 2 If (MaintMode = "on" AND (NOT Username = HostBotName AND NOT Username = GameBotName AND NOT Username = HostBotOwner)) Then Msg Username, MaintMsg Exit Sub End If If (Message = "test") Then 'test = GetURL("http://server.war2.ru/status/server.php", 0) 'Set eatme = ParseJson(test, "decode") 'MsgBox eatme("timestamp") End If 'Autoit.WinActivate can sometimes fuck up the screen if it's run while War2 is in the Chat screen. So we fix it by minimizing/maximizing from a Game Lobby. -Lance If (Message = "fixscreen") Then If (Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner) Then FixScreen End If Exit Sub End If 'Minimize War2, helps get control of screen back if autoit.WinActivate has fucked up the screen. Only useful when working on the bot really. -Lance If (Message = "min") Then If (Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner) Then oAutoIt.WinSetState "Warcraft II", "", 6 End If Exit Sub End If 'Minimize War2, helps get control of screen back if autoit.WinActivate has fucked up the screen. Only useful when working on the bot really. -Lance If (Message = "ac") Then If (Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner) Then ActivateWar2 End If Exit Sub End If 'This only temporarily disables autohosting. To re-enable it, duh, run enable autohosting -Lance If (Message = "disable autohosting") Then If (Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner) Then AutoHostGameInterval = 0 AutoHostGameCounter = 0 Msg Username, "AutoHosting has been temporarily disabled." End If Exit Sub End If 'This only temporarily disables autorebootwar2. To re-enable it, duh, run enable autorebootwar2 -Lance If (Message = "disable autorebootwar2") Then If (Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner) Then AutoRebootWar2Interval = 0 Msg Username, "AutoRebootWar2 has been temporarily disabled." End If Exit Sub End If 'Put all SINGLE word commands here. Multi-word commands are handled below. If (Message = "start") Then If (GameBotStatus = "in game") Then 'Allow anyone to start the game when HostBotName is the owner. If (GameOwner = HostBotName OR GameOwner = GameBotName) Then ForceStart = 1 End If Select Case Username Case GameOwner AddQ "/w " & Username & " starting game now" ForceStart = 1 Case GameBotName AddQ "/w " & Username & " starting game now" ForceStart = 1 Case HostBotName AddQ "/w " & Username & " starting game now" ForceStart = 1 Case HostBotOwner AddQ "/w " & Username & " starting game now" ForceStart = 1 Case Else AddQ "/w " & Username & " you are not game owner to start it" End Select Else AddQ "/w " & Username & " There is no game currently running." End If Exit Sub End If 'Restart the Stealthbot script. Useful for updating stealthbot without actually minimizing War2 screen. Dont do this unless the bot has NO errors in it. Otherwise you'll have to manually reload the SB anyway. -Lance If (Message = "sb_reload") Then If (GameBotStatus = "in game") Then Msg Username, GameBotName & " is in a game. Consider using Reboot instead since this would cause the Gamebot to get stuck in the game." Exit Sub End If 'GameBot was not in a game, so its safe to restart the stealthbot script -Lance SB_Reload Username Exit Sub End If 'For some reason the original reset that iL developed used nncron rather than VBScript to do the loading and killing of war2. This method doesnt require the war2 icon to be in a specific location on the Desktop -Lance If (Message = "reboot") Then RebootWar2 Username Exit Sub End If if (Message = "help") Then Msg Username, "Commands are in [] symbols:" Msg Username, "[gow ef 4] Start game in 4 minutes" Msg Username, "[Kick 2] Kick player in slot 2, change number to desired slot." Msg Username, "[Ban 2] Ban player in slot 2, DONT use this please, its rude. Only use to ban annoying players, not newbies!!!!" Msg Username, "[reboot] If Gamebot is stuck in a game or not in chat, use this to reboot it. Abuse will result in banning of bot usage, all reboot commands are logged." Msg Username, "[start] When in a game lobby, this starts the game" Msg Username, "END OF COMMAND LIST" Exit Sub End If ' ******** ALL Multi-Argument commands must go after this Split call. -Lance cmd_array = Split(trim(Message)) If (arrLength(cmd_array) > 0) Then Select Case cmd_array(0) Case "gow" Game_Gow cmd_array, Username Exit Sub Case "gowbne" Game_Gowbne cmd_array, Username Exit Sub End Select 'This is an example of a Preset that uses the cmd_array to setup the game. If (arrLength(cmd_array)) => 1 AND cmd_array(0) = "gowcomps" Then 'Allow user to override the default of 4 CPUs before we setup the game. If (arrLength(cmd_array) <= 1) Then CPUs = 4 Else CPUs = cmd_array(1) End If 'Now overwrite the cmd_array with correct game values -Lance preset_cmd_array(0) = "gowbne" preset_cmd_array(1) = "ef" preset_cmd_array(2) = 5 preset_cmd_array(3) = "Melee" preset_cmd_array(4) = CPUs Game_Gowbne preset_cmd_array, Username Exit Sub End If If (arrLength(cmd_array)) = 3 Then If (cmd_array(0) = "enable" AND cmd_array(1) = "autohosting" AND IsNumeric(cmd_array(2))) Then If (Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner) Then Msg Username, "AutoHosting has been re-enabled and will run every " & cmd_array(2) & " minutes." AutoHostGameInterval = CInt(cmd_array(2)) * 60 End If Exit Sub End If End If If (arrLength(cmd_array)) = 3 Then If (cmd_array(0) = "enable" AND cmd_array(1) = "autorebootwar2" AND IsNumeric(cmd_array(2))) Then If (Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner) Then Msg Username, "AutoRebootWar2 has been re-enabled and will check for the Gamebot every " & cmd_array(2) & " minutes." AutoRebootWar2Interval = CInt(cmd_array(2)) * 60 End If Exit Sub End If End If If (arrLength(cmd_array)) = 2 Then If (cmd_array(0) = "kick" And (GameOwner = Username OR Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner)) Then kick CInt(cmd_array(1)) Exit Sub End If End If If (arrLength(cmd_array)) = 2 Then If (cmd_array(0) = "ban" And (GameOwner = Username OR Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner)) Then ban CInt(cmd_array(1)) Exit Sub End If End If If (arrLength(cmd_array)) = 2 Then If (cmd_array(0) = "ban" And (GameOwner = Username OR Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner)) Then ban CInt(cmd_array(1)) Exit Sub End If End If End If 'Print a simple help screen if no command was found. Displaying this to the HostBotName user would result in an infinite loop so we dont allow that. -Lance If Username <> HostBotName Then AddQ "/w " & Username & " Please type '/msg " & HostBotName & " help for a list of available commands." End If End Sub Sub Tick_Event_Timer() 'Every 1 second check to see if the gamebot is logged in and if X amount of time passes and no bot, then reboot it. -Lance If GameBotStatus = "unknown" AND AutoRebootWar2Interval > 0 Then 'Couldnt find Bot for 1m30s so lets try to restart it RebootCounter = RebootCounter + 1 If RebootCounter > AutoRebootWar2Interval AND AutoRebootWar2Interval > 0 Then RebootCounter = 0 RebootWar2 HostBotName End If End If 'Check the Gamebots status every 5 seconds GameBotCounter = GameBotCounter + 1 If GameBotCounter = 5 Then AddQ "/whois " & GameBotName GameBotCounter = 0 End If If UseTeamviewer = "Yes" Then TeamViewerNagScreenCounter = TeamViewerNagScreenCounter + 1 If TeamViewerNagScreenCounter > 5 Then TeamViewerNagScreenCounter = 0 If oAutoIt.WinGetState("Sponsored session") > 0 Then oAutoIt.WinActivate "Sponsored session" Sleep(1) oAutoIt.Send "{ENTER}" Sleep(2) ActivateWar2 End If TeamViewerNagScreenCounter = 0 End If End If If AutoHostGameInterval > 0 Then AutoHostGameCounter = AutoHostGameCounter - 1 If AutoHostGameCounter <= 0 Then dim rand randomize rand = int(rnd*2) + 1 Select Case rand Case 1 Msg HostBotName, "gow ef 5" Case 2 Msg HostBotName, "gowcomps" End Select AutoHostGameCounter = AutoHostGameInterval End If End If End Sub Sub Event_ServerInfo(Message) If InStr(Message, GameBotName & " is using") Then If InStr(Message, "private game") Then GameBotStatus = "in game" RebootCounter = 0 InGameCounter = InGameCounter + 1 Exit Sub End If If InStr(Message, "in game") Then 'Yes that is 2 spaces between in game, there is a typo in the PVPGN server. -Lance GameBotStatus = "in game" RebootCounter = 0 InGameCounter = InGameCounter + 1 Exit Sub End If If InStr(Message, "in channel") Then GameBotStatus = "in channel" RebootCounter = 0 InGameCounter = 0 Exit Sub End If End If If InStr(Message, "User was last seen on") Then GameBotStatus = "unknown" End If End Sub '------------------------------------------------------------END EVENTS/Hooks Section -Lance '------------------------------------- Begin Game functions for creating games, these are used by the event_whisper command interface -Lance Sub Game_Gow(cmd_array, Username) 'MAP DEFAULTS Go Here, if a user doesnt specify enough arguments, then these defaults will be used. MapSpeed = "ef" StartTime = 5 GameType = "Melee" MapResources = "High" MapFixedOrder = "No" OnePeon = "Yes" GamePassword = "" GameTeams = "2s" 'Not yet used. CPUs = 0 'Map Navigation is AFTER the map browser has been brought up. Enter the keys to navigate to your map here, nice and simple :) -Lance MapNavigation(0) = "{HOME}" MapNavigation(1) = "{HOME}" MapNavigation(2) = "c{ENTER}" MapNavigation(3) = "g{ENTER}" CreateGame Username, MapName, MapSpeed, GameType, StartTime, GameTeams, MapResources, OnePeon, MapFixedOrder, GamePassword, cmd_array, MapNavigation, CPUs End Sub Sub Game_Gowbne(cmd_array, Username) 'MAP DEFAULTS Go Here, if a user doesnt specify enough arguments, then these defaults will be used. MapSpeed = "f" StartTime = 5 GameType = "Melee" MapResources = "High" MapFixedOrder = "No" OnePeon = "Yes" GamePassword = "" GameTeams = "2s" 'Not yet used. CPUs = 0 'Map Navigation is AFTER the map browser has been brought up. Enter the keys to navigate to your map here, nice and simple :) -Lance MapNavigation(0) = "{HOME}" MapNavigation(1) = "{HOME}" MapNavigation(2) = "l{ENTER}" MapNavigation(3) = "g{ENTER}" CreateGame Username, MapName, MapSpeed, GameType, StartTime, GameTeams, MapResources, OnePeon, MapFixedOrder, GamePassword, cmd_array, MapNavigation, CPUs End Sub '-------------------------------------- ENF Game Functions -Lance ' ------------------------------------ BEGIN UTILITY FUNCTIONS -Lance 'Reload the StealthBot Script itself. This is not the War2 window, this is the SB (AKA HostBotName) Sub SB_Reload(Username) Log("StealthBot Reloaded by " & Username) AddQ "StealthBot Reloaded by " & Username oAutoIt.ControlSend "StealthBot", "", "", "{RCTRL Down}r{RCTRL up}" End Sub 'Generic Create game function. Map names, creation mouse/click locations are defined elsewhere. -Lance Sub CreateGame(GameOwner, MapName, MapSpeed, GameType, StartTime, GameTeams, MapResources, OnePeon, MapFixedOrder, GamePassword, cmd_array, MapNavigation, CPUs) If NOT GameBotStatus = "in channel" Then AddQ "/w " & GameOwner & " please, wait for " & GameBotName &" to join a channel." & GameBotStatus Exit Sub End If 'Allow Player to override the Defaults. This code allows the player to override the defaults. This is not user friendly, but its not possible to make it user friendly anyway with all the settings. However, it does allow you to make PRESETS very easily. -Lance MapName = trim(cmd_array(0)) If (arrLength(cmd_array) >= 2 ) Then MapSpeed = trim(cmd_array(1)) End If If (arrLength(cmd_array) >= 3 ) Then StartTime = CInt(cmd_array(2)) End If If (arrLength(cmd_array) >= 4 ) Then GameType = cmd_array(3) End If If (arrLength(cmd_array) >= 5 ) Then CPUs = CInt(cmd_array(4)) End If If (arrLength(cmd_array) >= 6 ) Then MapResources = cmd_array(5) End If If (arrLength(cmd_array) >= 7 ) Then MapFixedOrder = cmd_array(6) End If If (arrLength(cmd_array) >= 8 ) Then OnePeon = cmd_array(7) End If If (arrLength(cmd_array) >= 9 ) Then GamePassword = cmd_array(8) End If 'Duh, max CPUs is 4 and nothing less than 0. If (CPUs > 0 AND CPUs > 4) Then CPUs = 4 If (CPUs < 0) Then CPUs = 0 If (CPUs > 0 AND NOT GameType = "Melee") Then Msg GameOwner, "CPUs can only be used on Melee, please use that gametype for CPU games." Exit Sub End If If (IsNumeric(StartTime) = False) Then AddQ "/w " & Username & " Invalid start delay time, please try again." Exit Sub End If If (CInt(StartTime) > MaxAutoStartTime) Then StartTime = MaxAutoStartTime End If If (StartTime < 1) Then StartTime = 1 End If 'Send out the notifications to players about the game. -Lance If (CPUs > 0) Then AddQ GameOwner & " requested CompStomp on " & MapName & " " & MapSpeed & ", game will autostart in " & StartTime & " minutes." Else AddQ GameOwner & " requested " & MapName & " " & MapSpeed & ", game will autostart in " & StartTime & " minutes." End If AddQ "/w " & GameOwner & " please, type '/msg " & HostBotName & " start' to start the game early or the game will autostart in " & map_start_time & " minutes." 'Open Create Game screen SendKeysToWar2 "{ALTDOWN}c{ALTUP}" GamePassword = "" If (CPUs > 0) Then SetGameName "Comps " & MapName & MapSpeed & ": " & GameOwner Else SetGameName MapName & MapSpeed & " By: " & GameOwner End If SetGamePassword GamePassword SetMap MapNavigation SetMapSpeed MapSpeed SetGameType GameType SetMapResources MapResources SetOnePeon OnePeon SetMapFixedOrder MapFixedOrder SendKeysToWar2 "{ENTER}" StartTimer = StartTime * 60 StartCounter = 0 GameBotStatus = "in game" 'Add any CPUs to the game -Lance Do While (CPUs > 0) AddCPU(CPUs + 4) CPUs = CPUs - 1 Loop Do While StartTimer > 0 If ForceStart = 1 Then Exit Do End If 'If the Gamebot somehow left the game without trying to start, we can cancel the loop here so that it's not spamming chat with the Notice msgs. -Lance If (NOT GameBotStatus = "in game") Then ResetGameVariables Exit Sub End If StartTimer = StartTimer - 1 StartCounter = StartCounter + 1 If StartCounter = 30 Then 'Msg users every 30 secs the status of the timer SendKeysToWar2 " Autostart in " & StartTimer / 60 & " minutes.{ENTER}" If (GameOwner = HostBotName OR GameOwner = GameBotName) Then SendKeysToWar2 "To start the game now Type: /msg " & HostBotName & " start{ENTER}" End If StartCounter = 0 End If Sleep(1) Loop SendKeysToWar2 "Starting....{ENTER}" ' Let'r Rip! -Lance StartGame 'Reset all the variables -Lance ResetGameVariables End Sub 'We only allow CPUs in 7 of the slots. Sub AddCPU(Slot) If (Slot = 2) Then SlotClick 65, 65, 65, 107 End If If (Slot = 3) Then SlotClick 65, 90, 65, 132 End If If (Slot = 4) Then SlotClick 65, 115, 65, 157 End If If (Slot = 5) Then SlotClick 65, 140, 65, 182 End If If (Slot = 6) Then SlotClick 65, 165, 65, 207 End If If (Slot = 7) Then SlotClick 65, 190, 65, 232 End If If (Slot = 8) Then SlotClick 65, 215, 65, 257 End If End Sub Sub ResetGameVariables() ForceStart = 0 StartCounter = 0 StartTimer = 0 GameOwner = "" MapName = "" MapSpeed = "" GameType = "" StartTime = 0 GameTeams = "" MapResources = "" OnePeon = "" MapFixedOrder = "" GamePassword = "" CPUs = 0 End Sub Sub SetMapFixedOrder(MapFixedOrder) If MapFixedOrder = "Yes" Then SendKeysToWar2 "{ALTDOWN}f{ALTUP}" End Sub Sub SetOnePeon(OnePeon) If OnePeon = "No" Then SendKeysToWar2 "{ALTDOWN}o{ALTUP}" End Sub Sub SetGameName(GameName) SendKeysToWar2 "{ALTDOWN}n{ALTUP}" SendKeysToWar2 GameName End Sub Sub SetGamePassword(GamePassword) SendKeysToWar2 "{ALTDOWN}p{ALTUP}" SendKeysToWar2 GamePassword End Sub Sub SetGameType(GameType) 'Highlight the GameType selector -Lance SendKeysToWar2 "{ALTDOWN}t{ALTUP}" SendKeysToWar2 "{DOWN}" 'Move the slider all the way to the Top (TvB) -Lance SendKeysToWar2 "{UP}{UP}{UP}{UP}{UP}{UP}" Select Case GameType Case "TvB" SendKeysToWar2 "{ENTER}" Case "Melee" SendKeysToWar2 "{DOWN}{ENTER}" Case "CPUs" 'CPUs can only be selected via Melee, so we set it to the melee type. SendKeysToWar2 "{DOWN}{ENTER}" Case "FFA" SendKeysToWar2 "{DOWN}{DOWN}{ENTER}" 'Case "1v1" ' SendKeysToWar2 "{DOWN}{DOWN}{DOWN}{ENTER}" Case "UseMapSettings" SendKeysToWar2 "{DOWN}{DOWN}{DOWN}{DOWN}{ENTER}" Case Else SendKeysToWar2 "{DOWN}{ENTER}" 'Default to Melee End Select End Sub ' Each map is located in a different place so this function takes directions and selects the proper map. If maps are different on your machine, you can fix the navigation in that map's function above. -Lance Sub SetMap(MapNavigation) 'Bring up the Map browser SendKeysToWar2 "{ALTDOWN}b{ALTUP}" Dim Key For Each Key In MapNavigation If (NOT Key = "") Then SendKeysToWar2 Key End If Next End Sub Sub SetMapSpeed(MapSpeed) 'Highlight the Speed selector -Lance SendKeysToWar2 "{ALTDOWN}s{ALTUP}" 'Move the slider all the way to the Left (SLOWEST SPEED) -Lance SendKeysToWar2 "{LEFT}{LEFT}{LEFT}{LEFT}{LEFT}{LEFT}{LEFT}{LEFT}" Select Case MapSpeed Case "ef" SendKeysToWar2 "{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}" Case "f" SendKeysToWar2 "{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}" Case Else SendKeysToWar2 "{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}{RIGHT}" ' Default to EF End Select End Sub Sub SetGameTeams(GameTeams) Select Case GameTeams Case "1v1" Case "2v2" Case "3v3" Case Else End Select End Sub Sub SetMapResources(MapResources) 'Highlight the Resources Selector -Lance SendKeysToWar2 "{ALTDOWN}r{ALTUP}" SendKeysToWar2 "{DOWN}" 'Move resources all the way to Top -Lance SendKeysToWar2 "{UP}{UP}{UP}{UP}" Select Case MapResources Case "High" SendKeysToWar2 "{DOWN}{DOWN}{DOWN}{DOWN}{ENTER}" Case "Medium" SendKeysToWar2 "{DOWN}{DOWN}{DOWN}{ENTER}" Case "Low" SendKeysToWar2 "{DOWN}{DOWN}{ENTER}" Case "Random" SendKeysToWar2 "{DOWN}{ENTER}" Case "Default" SendKeysToWar2 "{ENTER}" Case Else SendKeysToWar2 "{DOWN}{DOWN}{DOWN}{DOWN}{ENTER}" ' Default to High End Select End Sub ' -------------- All Maps Subs should go here, Naming convention is up to you but I recommend using the mapnames like I have for GoW -Lance ' Because VBs is one of the stupidest languages in the scripting world, there is no Sleep() function that can be used in StealthBot. So, fuck you VBS, I am SCHMARTER THAN YOU. We use ping to simulate a Sleep function. -Lance Sub Sleep(seconds) Shell.Run "%COMSPEC% /c ping localhost -n " _ & seconds+1, 0, True End Sub 'Duh, Start a game :D -Lance Sub StartGame() 'Slap the OK button in War2 -Lance SendKeysToWar2 "{ALTDOWN}o{ALTUP}" 'If there are no opponents a msg will pop up that requires us to click OK. To get around this, we do the following. We dont need to cancel the game as we take care of that in the QuitGame function -Lance SendKeysToWar2 "{ENTER}" 'Wait 15 seconds to Quit the game. Sleep(15) QuitGame End Sub Sub QuitGame() 'In case there were no players when we tried to start, this will exit the game. -Lance SendKeysToWar2 "{ALTDOWN}c{ALTUP}" SendClickToWar2 "primary", 10, 10, "Click" SendKeysToWar2 "e" 'Delete the "e" that could possibly be in the chat window due to a canceled game. -Lance SendKeysToWar2 "{BACKSPACE}" 'I dont use eqq because that does not always work. If the bot takes a long time, it might change to ess (surrender vs Quit for draw). So we use clicks instead. SendClickToWar2 "primary", 300, 190, "Click" SendClickToWar2 "primary", 300, 220, "Click" Sleep(10) 'This should Exit the Draw screen. -Lance SendKeysToWar2 "{ENTER}" Sleep(2) RejoinBnet End Sub ' Utility function to Send the GameBotPw to the War2 Login Screen. I use primary instead of 'left' in case of left handed users. -Lance Sub SendGameBotLoginPassword() SendClickToWar2 "primary", 220, 284, "DoubleClick" SendKeysToWar2 GameBotPw End Sub ' Utility function to Send the GameBotName to the War2 Login screen. -Lance Sub SendGameBotLoginName() SendClickToWar2 "Left", 260, 220, "DoubleClick" SendKeysToWar2 GameBotName End Sub 'Utility function to send mouse clicks to War2 via Autoit -Lance Sub SendClickToWar2(Button, Horizontal, Vertical, Position) 'Since ControlClick does NOT work with War2, we're forced to use this crap. Moving the mouse with ControlClick works, but actually doing the click does not because it's a Full Screen game and not a real window. -Lance If oAutoIt.WinGetState("Warcraft II") <> 3 AND oAutoIt.WinGetState("Warcraft II") <> 15 Then ActivateWar2 Sleep(3) End If oAutoIt.MouseMove Horizontal, Vertical If Position = "Click" Then oAutoIt.MouseClick Button End If If Position = "DoubleClick" Then oAutoIt.MouseClick Button oAutoIt.MouseClick Button End If If Position = "Down" Then oAutoIt.MouseDown Button End If If Position = "Up" Then oAutoIt.MouseUp Button End If 'oAutoIt.Sleep(500) Sleep(1) End Sub Sub ActivateWar2() 'oAutoIt.WinSetState "Warcraft II", "", 4 'Minimize and then maximize in an attempt to fix the bug that causes war2 to maximize incorrectly. -Lance oAutoIt.WinActivate "Warcraft II" End Sub 'There is a weird bug that causes War2 to Maximize incorrectly when it's in a Non-War2 Game screen such as BNE Chat, Login screen, etc. You cant minimize anything with mouse or keys, so this fixes that bug. This forces War2 into minimized state. It will eventually fix itself when games are started, etc. -Lance Sub MinimizeWar2() oAutoIt.WinSetState "Warcraft II", "", 6 End Sub 'Utility function to sent keys to War2 window via Autoit -Lance Sub SendKeysToWar2(Keys) 'Activate isnt really necessary but I put it here just in case. -Lance If oAutoIt.WinGetState("Warcraft II") <> 3 AND oAutoIt.WinGetState("Warcraft II") <> 15 Then ActivateWar2 Sleep(7) End If oAutoIt.ControlSend "Warcraft II", "", "", Keys 'oAutoIt.Sleep(500) Sleep(1) End Sub ' Utility function to msg a user -Lance Sub Msg(Username,Message) AddQ("/w " & Username & " " & Message) End Sub 'Bans a user from the specified game slot -Lance Sub Ban (Slot) If (GameType = "Melee" OR GameType = "FFA") Then If (Slot = 2) Then SlotClick 65, 65, 65, 140 End If If (Slot = 3) Then SlotClick 65, 90, 65, 165 End If If (Slot = 4) Then SlotClick 65, 115, 65, 190 End If If (Slot = 5) Then SlotClick 65, 140, 65, 215 End If If (Slot = 6) Then SlotClick 65, 165, 65, 240 End If If (Slot = 7) Then SlotClick 65, 190, 65, 265 End If If (Slot = 8) Then SlotClick 65, 215, 65, 290 End If End If If (GameType = "TvB") Then If (Slot = 2) Then SlotClick 65, 90, 65, 165 End If If (Slot = 3) Then SlotClick 65, 115, 65, 190 End If If (Slot = 4) Then SlotClick 65, 140, 65, 215 End If If (Slot = 5) Then SlotClick 65, 190, 65, 240 End If If (Slot = 6) Then SlotClick 65, 215, 65, 265 End If If (Slot = 7) Then SlotClick 65, 240, 65, 300 End If If (Slot = 8) Then SlotClick 65, 265, 65, 325 End If End If SendKeysToWar2 "{ENTER}" End Sub Sub SlotClick(DownHorizontal, DownVertical, UpHorizontal, UpVertical) SendClickToWar2 "Left", 0, 0, "Up" 'Clear any possible up/down clicks SendClickToWar2 "Left", DownHorizontal, DownVertical, "Down" SendClickToWar2 "Left", UpHorizontal, UpVertical, "Up" 'SendKeysToWar2 "{ENTER}" End Sub 'Duh, kicks a user from the specified game slot -Lance Sub Kick (Slot) If (GameType = "Melee" OR GameType = "FFA") Then If (Slot = 2) Then SlotClick 65, 65, 65, 90 End If If (Slot = 3) Then SlotClick 65, 90, 65, 115 End If If (Slot = 4) Then SlotClick 65, 115, 65, 140 End If If (Slot = 5) Then SlotClick 65, 140, 65, 165 End If If (Slot = 6) Then SlotClick 65, 165, 65, 190 End If If (Slot = 7) Then SlotClick 65, 190, 65, 215 End If If (Slot = 8) Then SlotClick 65, 215, 65, 240 End If End If If (GameType = "TvB") Then If (Slot = 2) Then SlotClick 65, 90, 65, 115 End If If (Slot = 3) Then SlotClick 65, 115, 65, 140 End If If (Slot = 4) Then SlotClick 65, 140, 65, 165 End If If (Slot = 5) Then SlotClick 65, 190, 65, 215 End If If (Slot = 6) Then SlotClick 65, 215, 65, 240 End If If (Slot = 7) Then SlotClick 65, 240, 65, 265 End If If (Slot = 8) Then SlotClick 65, 265, 65, 290 End If End If SendKeysToWar2 "{ENTER}" End Sub 'This will kill any running War2 Process and attempt to re-login the GameBotName -Lance Sub RebootWar2(Username) If RebootInProgress = 1 Then Msg Username, "A reboot is already in progress." Exit Sub End If If (Username = GameBotName OR Username = HostBotName OR Username = HostBotOwner) Then ForceReboot = 1 End If If (MaxGameTimeInterval >= InGameCounter AND ForceReboot < 1) Then Msg Username, GameBotName & " is currently in an active game. Wait until its finished or wait at least " & MaxGameTimeInterval & " minutes before attempting another reboot." Exit Sub End If RebootInProgress = 1 ' Log all calls to Reboot -Lance Log "Rebooted by " & Username 'Not sure why, but the CWD needs to be changed since the CWD field does not work in the Autoit.Run function when executed througb VBScript -Lance OriginalCWD = Shell.CurrentDirectory Shell.CurrentDirectory = "c:\war2combat" 'Use Autoit to try to kill War2 and then give it 2 seconds to close. -Lance oAutoIt.WinKill "Warcraft II" Sleep(3) 'WinKill is UNRELIABLE. IE: If war2 is at the login screen, WinKill will fail for some reason. IDK Why, so I replace it with a real kill command if the window is still open. -Lance state = oAutoIt.WinGetState("Warcraft II") If state > 0 Then Shell.Run "CMD /k taskkill /f /fi ""WINDOWTITLE eq Warcraft II"" & exit" End If 'Run War2 via Autoit -Lance oAutoIt.Run "War2PLoader.exe" 'Set the CWD back to Stealthbot or bad things WILL happen lmao -Lance Shell.CurrentDirectory = OriginalCWD 'Give war2 about 15 secs to load -Lance 'oAutoIt.WinWaitActive "", "Warcraft II", 15 Sleep(15) 'Connect to RU server -Lance SendKeysToWar2 "-{Delay 100}m{Delay 100}e{Delay 100}c" 'Wait for connection to RU to complete (3 secs) -Lance Sleep(5) 'Click the username box, delete any usernames there, and then type our GameBotName -Lance SendGameBotLoginName 'Click the password box, delete any passwords there, and then type our GameBotPw -Lance SendGameBotLoginPassword 'Hit enter to actually login. -Lance SendKeysToWar2 "{ENTER}" 'Give bot 3 secs to login and then set the away msg -Lance Sleep(5) SendKeysToWar2 "/away To get a list of commands to use me type /msg " & HostBotName & " help{ENTER}" SendKeysToWar2 "/join " & GameBotChannel & "{ENTER}" AddQ("EF_GameBot has been rebooted by: " & Username) RebootInProgress = 0 'Also take the opportunity to reload the StealthBot script as well. 'SB_Reload Username End Sub Sub RejoinBnet() SendKeysToWar2 "{ALTDOWN}q{ALTUP}" 'Connect to RU server -Lance SendKeysToWar2 "-{Delay 100}m{Delay 100}e{Delay 100}c" 'Wait for connection to RU to complete (3 secs) -Lance Sleep(5) 'Click the username box, delete any usernames there, and then type our GameBotName -Lance SendGameBotLoginName 'Click the password box, delete any passwords there, and then type our GameBotPw -Lance SendGameBotLoginPassword 'Hit enter to actually login. -Lance SendKeysToWar2 "{ENTER}" 'Give bot 3 secs to login and then set the away msg -Lance Sleep(5) SendKeysToWar2 "/away To get a list of commands to use me type /msg " & HostBotName & " help{ENTER}" SendKeysToWar2 "/join " & GameBotChannel & "{ENTER}" End Sub Function arrLength(vArray) ItemCount = 0 For ItemIndex = 0 To UBound(vArray) If Not(vArray(ItemIndex)) = Empty Then ItemCount = ItemCount + 1 End If Next arrLength = ItemCount End Function Function GetURL(URL, UseCache) If (UseCache = 1) Then sSource = URL Else 'MS crap sux ass so we have to feed it fake URLs in order for it to stop it's caching -Lance sSource = URL & "?n45ty45yjneg856yjinergtuh45ty4rth9067oiil34tujgjmtime=" & Now() End If set oHTTP = CreateObject("Microsoft.XMLHTTP") oHTTP.open "GET", sSource, False oHTTP.send body = oHTTP.responseBody set oHTTP = nothing For i = 1 to UBound(body) + 1 sOut = sOut & chr(ascb(midb(body,i,1))) Next 'Return the results -Lance GetURL = sOut End Function ' ------------------------------------ END Utility Functions -Lance Class VbsJson 'Author: Demon 'Date: 2012/5/3 'Website: http://demon.tw Private Whitespace, NumberRegex, StringChunk Private b, f, r, n, t Private Sub Class_Initialize Whitespace = " " & vbTab & vbCr & vbLf b = ChrW(8) f = vbFormFeed r = vbCr n = vbLf t = vbTab Set NumberRegex = New RegExp NumberRegex.Pattern = "(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?" NumberRegex.Global = False NumberRegex.MultiLine = True NumberRegex.IgnoreCase = True Set StringChunk = New RegExp StringChunk.Pattern = "([\s\S]*?)([""\\\x00-\x1f])" StringChunk.Global = False StringChunk.MultiLine = True StringChunk.IgnoreCase = True End Sub 'Return a JSON string representation of a VBScript data structure 'Supports the following objects and types '+-------------------+---------------+ '| VBScript | JSON | '+===================+===============+ '| Dictionary | object | '+-------------------+---------------+ '| Array | array | '+-------------------+---------------+ '| String | string | '+-------------------+---------------+ '| Number | number | '+-------------------+---------------+ '| True | true | '+-------------------+---------------+ '| False | false | '+-------------------+---------------+ '| Null | null | '+-------------------+---------------+ Public Function Encode(ByRef obj) Dim buf, i, c, g Set buf = CreateObject("Scripting.Dictionary") Select Case VarType(obj) Case vbNull buf.Add buf.Count, "null" Case vbBoolean If obj Then buf.Add buf.Count, "true" Else buf.Add buf.Count, "false" End If Case vbInteger, vbLong, vbSingle, vbDouble buf.Add buf.Count, obj Case vbString buf.Add buf.Count, """" For i = 1 To Len(obj) c = Mid(obj, i, 1) Select Case c Case """" buf.Add buf.Count, "\""" Case "\" buf.Add buf.Count, "\\" Case "/" buf.Add buf.Count, "/" Case b buf.Add buf.Count, "\b" Case f buf.Add buf.Count, "\f" Case r buf.Add buf.Count, "\r" Case n buf.Add buf.Count, "\n" Case t buf.Add buf.Count, "\t" Case Else If AscW(c) >= 0 And AscW(c) <= 31 Then c = Right("0" & Hex(AscW(c)), 2) buf.Add buf.Count, "\u00" & c Else buf.Add buf.Count, c End If End Select Next buf.Add buf.Count, """" Case vbArray + vbVariant g = True buf.Add buf.Count, "[" For Each i In obj If g Then g = False Else buf.Add buf.Count, "," buf.Add buf.Count, Encode(i) Next buf.Add buf.Count, "]" Case vbObject If TypeName(obj) = "Dictionary" Then g = True buf.Add buf.Count, "{" For Each i In obj If g Then g = False Else buf.Add buf.Count, "," buf.Add buf.Count, """" & i & """" & ":" & Encode(obj(i)) Next buf.Add buf.Count, "}" Else Err.Raise 8732,,"None dictionary object" End If Case Else buf.Add buf.Count, """" & CStr(obj) & """" End Select Encode = Join(buf.Items, "") End Function 'Return the VBScript representation of ``str(`` 'Performs the following translations in decoding '+---------------+-------------------+ '| JSON | VBScript | '+===============+===================+ '| object | Dictionary | '+---------------+-------------------+ '| array | Array | '+---------------+-------------------+ '| string | String | '+---------------+-------------------+ '| number | Double | '+---------------+-------------------+ '| true | True | '+---------------+-------------------+ '| false | False | '+---------------+-------------------+ '| null | Null | '+---------------+-------------------+ Public Function Decode(ByRef str) Dim idx idx = SkipWhitespace(str, 1) If Mid(str, idx, 1) = "{" Then Set Decode = ScanOnce(str, 1) Else Decode = ScanOnce(str, 1) End If End Function Private Function ScanOnce(ByRef str, ByRef idx) Dim c, ms idx = SkipWhitespace(str, idx) c = Mid(str, idx, 1) If c = "{" Then idx = idx + 1 Set ScanOnce = ParseObject(str, idx) Exit Function ElseIf c = "[" Then idx = idx + 1 ScanOnce = ParseArray(str, idx) Exit Function ElseIf c = """" Then idx = idx + 1 ScanOnce = ParseString(str, idx) Exit Function ElseIf c = "n" And StrComp("null", Mid(str, idx, 4)) = 0 Then idx = idx + 4 ScanOnce = Null Exit Function ElseIf c = "t" And StrComp("true", Mid(str, idx, 4)) = 0 Then idx = idx + 4 ScanOnce = True Exit Function ElseIf c = "f" And StrComp("false", Mid(str, idx, 5)) = 0 Then idx = idx + 5 ScanOnce = False Exit Function End If Set ms = NumberRegex.Execute(Mid(str, idx)) If ms.Count = 1 Then idx = idx + ms(0).Length ScanOnce = CDbl(ms(0)) Exit Function End If Err.Raise 8732,,"No JSON object could be ScanOnced" End Function Private Function ParseObject(ByRef str, ByRef idx) Dim c, key, value Set ParseObject = CreateObject("Scripting.Dictionary") idx = SkipWhitespace(str, idx) c = Mid(str, idx, 1) If c = "}" Then Exit Function ElseIf c <> """" Then Err.Raise 8732,,"Expecting property name" End If idx = idx + 1 Do key = ParseString(str, idx) idx = SkipWhitespace(str, idx) If Mid(str, idx, 1) <> ":" Then Err.Raise 8732,,"Expecting : delimiter" End If idx = SkipWhitespace(str, idx + 1) If Mid(str, idx, 1) = "{" Then Set value = ScanOnce(str, idx) Else value = ScanOnce(str, idx) End If ParseObject.Add key, value idx = SkipWhitespace(str, idx) c = Mid(str, idx, 1) If c = "}" Then Exit Do ElseIf c <> "," Then Err.Raise 8732,,"Expecting , delimiter" End If idx = SkipWhitespace(str, idx + 1) c = Mid(str, idx, 1) If c <> """" Then Err.Raise 8732,,"Expecting property name" End If idx = idx + 1 Loop idx = idx + 1 End Function Private Function ParseArray(ByRef str, ByRef idx) Dim c, values, value Set values = CreateObject("Scripting.Dictionary") idx = SkipWhitespace(str, idx) c = Mid(str, idx, 1) If c = "]" Then ParseArray = values.Items Exit Function End If Do idx = SkipWhitespace(str, idx) If Mid(str, idx, 1) = "{" Then Set value = ScanOnce(str, idx) Else value = ScanOnce(str, idx) End If values.Add values.Count, value idx = SkipWhitespace(str, idx) c = Mid(str, idx, 1) If c = "]" Then Exit Do ElseIf c <> "," Then Err.Raise 8732,,"Expecting , delimiter" End If idx = idx + 1 Loop idx = idx + 1 ParseArray = values.Items End Function Private Function ParseString(ByRef str, ByRef idx) Dim chunks, content, terminator, ms, esc, char Set chunks = CreateObject("Scripting.Dictionary") Do Set ms = StringChunk.Execute(Mid(str, idx)) If ms.Count = 0 Then Err.Raise 8732,,"Unterminated string starting" End If content = ms(0).Submatches(0) terminator = ms(0).Submatches(1) If Len(content) > 0 Then chunks.Add chunks.Count, content End If idx = idx + ms(0).Length If terminator = """" Then Exit Do ElseIf terminator <> "\" Then Err.Raise 8732,,"Invalid control character" End If esc = Mid(str, idx, 1) If esc <> "u" Then Select Case esc Case """" char = """" Case "\" char = "\" Case "/" char = "/" Case "b" char = b Case "f" char = f Case "n" char = n Case "r" char = r Case "t" char = t Case Else Err.Raise 8732,,"Invalid escape" End Select idx = idx + 1 Else char = ChrW("&H" & Mid(str, idx + 1, 4)) idx = idx + 5 End If chunks.Add chunks.Count, char Loop ParseString = Join(chunks.Items, "") End Function Private Function SkipWhitespace(ByRef str, ByVal idx) Do While idx <= Len(str) And _ InStr(Whitespace, Mid(str, idx, 1)) > 0 idx = idx + 1 Loop SkipWhitespace = idx End Function End Class 'I shamelessly style the VbsJson code from some website and then made this el-quicko wrapper function. You use it like this: -Lance 'test = GetURL(someUrlThatSpitsBackJsonCode) 'Set eatme = ParseJson(test, "decode") 'MsgBox eatme("timestamp") 'Element named "timestamp" in the json. Embeded elements are like timestamp_type = eatme("timestamp")("type") where the element name "type" might contain a string called "unix" It's stupid, but hey it works! Function ParseJson(strJson, enctype) Dim fso, json, str, O, i Set json = New VbsJson If enctype = "encode" Then Set ParseJson = json.Encode(strJson) End If If enctype = "decode" Then Set ParseJson = json.Decode(strJson) End If End Function ' -------------- Functions to depreciate -Lance ' Send Keys to the Gamebot. For hostbot use AddQ instead -Lance Sub SendKeys(Keys) Shell.sendkeys Keys End Sub ' ----------------- Create file ------------------------------- Sub CreateFile(Filename) Set fso = CreateObject("Scripting.FileSystemObject") Set file = fso.OpenTextFile(Filename,2,True) file.close End Sub ' ----------------- Delete file ------------------------------- Sub DeleteFile(Filename) Set fso = CreateObject("Scripting.FileSystemObject") Set file = fso.DeleteFile(Filename) file.close End Sub ' ----------------- Write to file ----------------------------- Sub WriteToFile(Filename,Message) Set fso = CreateObject("Scripting.FileSystemObject") Set file = fso.OpenTextFile(Filename, 2, True) file.WriteLine Message file.Close End Sub ' ----------------- log --------------------------------------- Sub Log(Message) AddQ "/w " & HostBotOwner & " " & Message End Sub