VERSION 5.00 Begin VB.Form frmProcess Caption = "Thothie’s HLDS Restarter" ClientHeight = 6675 ClientLeft = 660 ClientTop = 720 ClientWidth = 8775 BeginProperty Font Name = "Arial" Size = 8.25 Charset = 0 Weight = 400 Underline = 0 'False Italic = 0 'False Strikethrough = 0 'False EndProperty Icon = "hldsrestarter.frx":0000 KeyPreview = -1 'True LinkTopic = "Form1" MaxButton = 0 'False ScaleHeight = 6675 ScaleWidth = 8775 StartUpPosition = 2 'CenterScreen Begin VB.HScrollBar command_interval Height = 255 Left = 240 Max = 60 Min = 1 TabIndex = 55 Top = 6840 Value = 1 Visible = 0 'False Width = 2775 End Begin VB.Frame method_panel Caption = "Method" Height = 735 Left = 120 TabIndex = 43 Top = 5880 Width = 8535 Begin VB.OptionButton method Caption = "Console Script Method" Height = 375 Index = 1 Left = 3000 TabIndex = 46 Top = 240 Width = 2175 End Begin VB.OptionButton method Caption = "AMX Heartbeat Method" Height = 375 Index = 2 Left = 6240 TabIndex = 45 Top = 240 Width = 2175 End Begin VB.OptionButton method Caption = "Clipboard Method" Height = 375 Index = 0 Left = 120 TabIndex = 44 Top = 240 Value = -1 'True Width = 1815 End End Begin VB.TextBox holder Height = 855 Left = 120 TabIndex = 37 Text = "Text1" Top = 8880 Visible = 0 'False Width = 855 End Begin VB.TextBox hidden Height = 855 Left = 120 TabIndex = 36 Text = "Text1" Top = 7920 Visible = 0 'False Width = 855 End Begin VB.Frame clipboard_panel Caption = "Clipboard Method Options" Height = 2055 Left = 120 TabIndex = 35 Top = 3840 Width = 3375 Begin VB.OptionButton HardTestToggle Caption = "I'm Away (Hard Crash Test Each Minute)" Height = 375 Index = 1 Left = 240 TabIndex = 42 Top = 960 Width = 2775 End Begin VB.OptionButton HardTestToggle Caption = "Im using this computer (No Hard Crash Test)" Height = 375 Index = 0 Left = 240 TabIndex = 41 Top = 360 Value = -1 'True Width = 2775 End Begin VB.CheckBox nominimize Caption = "Don't Minize Console After Paste" Height = 255 Left = 240 TabIndex = 40 Top = 1560 Width = 2895 End End Begin VB.Frame Frame2 Caption = "Tech Info" Height = 1815 Left = 120 TabIndex = 20 Top = 1920 Width = 3375 Begin VB.Timer minutetimer Enabled = 0 'False Interval = 1000 Left = 1680 Top = 480 End Begin VB.Timer onesecond Enabled = 0 'False Interval = 1000 Left = 2040 Top = 480 End Begin VB.Timer hack Enabled = 0 'False Interval = 1000 Left = 2760 Top = 480 End Begin VB.Timer wait5mins Enabled = 0 'False Interval = 1000 Left = 2400 Top = 480 End Begin VB.Label lblProcessID Height = 240 Left = 720 TabIndex = 54 Top = 120 Visible = 0 'False Width = 1560 End Begin VB.Label lastHardTestLbl Alignment = 2 'Center BackColor = &H80000016& BorderStyle = 1 'Fixed Single Caption = "Not Started" Height = 240 Left = 2040 TabIndex = 48 Top = 1200 Width = 1095 End Begin VB.Label Label5 BackColor = &H80000016& Caption = "Last Hard Crash Test" Height = 240 Left = 240 TabIndex = 47 Top = 1200 Width = 1680 End Begin VB.Label Label3 BackColor = &H80000016& Caption = "Last Soft Crash Test" Height = 240 Left = 240 TabIndex = 32 Top = 1440 Width = 1680 End Begin VB.Label lblProcess Alignment = 1 'Right Justify BackColor = &H80000016& BorderStyle = 1 'Fixed Single Height = 240 Left = 1560 TabIndex = 28 Top = 360 Width = 1575 End Begin VB.Label lblThread Alignment = 1 'Right Justify BackColor = &H80000016& BorderStyle = 1 'Fixed Single Height = 240 Left = 1560 TabIndex = 27 Top = 600 Width = 1575 End Begin VB.Label lblThreadID Alignment = 1 'Right Justify BackColor = &H80000016& BorderStyle = 1 'Fixed Single Height = 225 Left = 1560 TabIndex = 26 Top = 840 Width = 1575 End Begin VB.Label lblProcessMess BackColor = &H80000016& Caption = "Process" Height = 240 Left = 240 TabIndex = 24 Top = 360 Width = 960 End Begin VB.Label lblThreadMess BackColor = &H80000016& Caption = "Thread" Height = 240 Left = 240 TabIndex = 23 Top = 600 Width = 960 End Begin VB.Label lblThreadIDMess BackColor = &H80000016& Caption = "ThreadID" Height = 240 Left = 240 TabIndex = 22 Top = 840 Width = 960 End Begin VB.Label lblStillRunning Alignment = 2 'Center BackColor = &H80000016& BorderStyle = 1 'Fixed Single Caption = "Not Started" Height = 240 Left = 2040 TabIndex = 21 Top = 1440 Width = 1095 End End Begin VB.Frame Frame1 Caption = "Log" Height = 3975 Left = 3600 TabIndex = 17 Top = 1920 Width = 5055 Begin VB.CheckBox log_crashes_only Caption = "Log Crashes Only" Height = 255 Left = 120 TabIndex = 30 Top = 3600 Width = 1695 End Begin VB.CheckBox log_enabled Caption = "Log to File: msc_hlds_restarter.log" Height = 255 Left = 2040 TabIndex = 19 Top = 3600 Width = 2895 End Begin VB.TextBox logger Height = 3255 Left = 120 MultiLine = -1 'True ScrollBars = 2 'Vertical TabIndex = 18 Text = "hldsrestarter.frx":030A Top = 240 Width = 4815 End End Begin VB.Frame frmDestroyByProcessID Caption = "Destroy by ProcessID" Height = 735 Left = 1080 TabIndex = 11 Top = 9120 Visible = 0 'False Width = 5505 Begin VB.OptionButton Option2 Caption = "Close" Height = 240 Index = 0 Left = 1710 TabIndex = 14 Top = 315 Value = -1 'True Width = 735 End Begin VB.OptionButton Option2 Caption = "Quit" Height = 240 Index = 1 Left = 2520 TabIndex = 13 Top = 315 Width = 960 End Begin VB.CommandButton cmdDestroyByProcessID Caption = "Destroy" Enabled = 0 'False Height = 330 Left = 3735 TabIndex = 12 Top = 270 Width = 1590 End End Begin VB.Frame fraDetroyByTitle Caption = "Destroy by Title" Height = 1140 Left = 1080 TabIndex = 5 Top = 7920 Visible = 0 'False Width = 5505 Begin VB.CommandButton cmdDestroy Caption = "Destroy" Height = 330 Left = 3735 TabIndex = 10 Top = 675 Width = 1590 End Begin VB.OptionButton Option1 Caption = "Quit" Height = 240 Index = 1 Left = 2520 TabIndex = 9 Top = 720 Width = 960 End Begin VB.OptionButton Option1 Caption = "Close" Height = 240 Index = 0 Left = 1710 TabIndex = 8 Top = 720 Value = -1 'True Width = 960 End Begin VB.TextBox txtDestroy Height = 330 Left = 1710 TabIndex = 6 Top = 270 Width = 3615 End Begin VB.Label lblTitle Caption = "Program to destroy" Height = 240 Left = 135 TabIndex = 7 Top = 600 Width = 1545 End End Begin VB.Timer tmrRunning Enabled = 0 'False Interval = 1000 Left = 840 Top = 960 End Begin VB.Frame fraStart Caption = "HLDS Control" Height = 1815 Left = 120 TabIndex = 0 Top = 0 Width = 8565 Begin VB.CommandButton reloadini Caption = "Re-Load Prefs" Height = 255 Left = 2040 TabIndex = 58 Top = 720 Visible = 0 'False Width = 1215 End Begin VB.ComboBox autokill Height = 330 Left = 6960 Style = 2 'Dropdown List TabIndex = 56 Top = 720 Width = 1455 End Begin VB.CheckBox minimstart Caption = "Minimize on Launch" Height = 255 Left = 1320 TabIndex = 53 Top = 1440 Width = 1935 End Begin VB.TextBox modfolder Height = 270 Left = 1320 TabIndex = 33 Text = "msc" Top = 720 Width = 705 End Begin VB.CommandButton dev Caption = "dev" Height = 375 Left = 240 TabIndex = 31 Top = 1320 Visible = 0 'False Width = 495 End Begin VB.CommandButton cmdKill Caption = "Kill HLDS Now" Default = -1 'True Enabled = 0 'False Height = 330 Left = 4920 TabIndex = 29 Top = 1080 Width = 3495 End Begin VB.CheckBox no_restart Alignment = 1 'Right Justify Caption = "Pause AutoRestarting" Height = 255 Left = 6480 TabIndex = 25 Top = 1440 Width = 1935 End Begin VB.CommandButton cmdCreateProcess Caption = "Launch HLDS" Height = 315 Left = 1320 TabIndex = 4 Top = 1080 Width = 3495 End Begin VB.CommandButton cmdShell Caption = "Start using Shell" Height = 330 Left = 240 TabIndex = 3 Top = 120 Visible = 0 'False Width = 255 End Begin VB.TextBox txtStart Height = 330 Left = 1320 TabIndex = 1 Text = "hlds.exe -tos -insecure -game msc +maxplayers 7 -port 27017 -noipx -console +ms_pklevel 0 +exec crashed.cfg" Top = 360 Width = 7020 End Begin VB.Label Label6 Caption = "Kill Functioning Server" Height = 255 Left = 5280 TabIndex = 57 Top = 720 Width = 1695 End Begin VB.Label Label4 Alignment = 1 'Right Justify Caption = "Mod Folder:" Height = 360 Left = 240 TabIndex = 34 Top = 720 Width = 975 End Begin VB.Label lblStart Caption = "Command Line:" Height = 240 Left = 135 TabIndex = 2 Top = 405 Width = 1230 End End Begin VB.Frame script_panel Caption = "Console Script Method (No Options)." Height = 2055 Left = 120 TabIndex = 51 Top = 3840 Visible = 0 'False Width = 3375 Begin VB.Label Label8 Caption = $"hldsrestarter.frx":0310 Height = 1455 Left = 120 TabIndex = 52 Top = 360 Width = 3135 End End Begin VB.Frame amx_panel Caption = "AMX Method (No Options)" Height = 2055 Left = 120 TabIndex = 49 Top = 3840 Visible = 0 'False Width = 3375 Begin VB.Label Label7 Caption = $"hldsrestarter.frx":03F7 Height = 1335 Left = 120 TabIndex = 50 Top = 360 Width = 2895 End End Begin VB.Label lblJob BackColor = &H80000016& BeginProperty Font Name = "Arial" Size = 8.25 Charset = 0 Weight = 400 Underline = -1 'True Italic = 0 'False Strikethrough = 0 'False EndProperty Height = 240 Left = 1560 TabIndex = 39 Top = 7440 Visible = 0 'False Width = 1575 End Begin VB.Label lblProcessIDMess BackColor = &H80000016& Caption = "ProcessID" Height = 240 Left = 240 TabIndex = 38 Top = 7440 Visible = 0 'False Width = 960 End Begin VB.Label Label2 Caption = "This will destroy all windows that belong to the current ProcessID." Height = 465 Left = 5040 TabIndex = 16 Top = 9000 Visible = 0 'False Width = 2850 End Begin VB.Label Label1 Caption = "This will destroy only the window with the specified title." Height = 465 Left = 6240 TabIndex = 15 Top = 8400 Visible = 0 'False Width = 2850 End End Attribute VB_Name = "frmProcess" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False Option Explicit Dim minute_maker As Integer Dim autokill_enabled As Boolean Dim autokill_counter As Long Dim autokill_counter_goal As Long Dim minute_counter As Integer Dim second_counter As Integer Dim loadingsettings As Boolean Dim y As Integer Dim X As Variant Dim c As Variant Dim a$ Dim hack_step As Integer Dim cr$ Dim hldsrestarted As Boolean Dim old_banned_date As Variant Dim new_banned_date As Variant Dim command_interval_counter As Long Dim command_counter_goal As Long Dim lngProcess As Long Dim lngThread As Long Dim lngProcessID As Long Dim lngThreadID As Long Dim lngReply As Long Private Type STARTUPINFO cb As Long lpReserved As String lpDesktop As String lpTitle As String dwX As Long dwY As Long dwXSize As Long dwYSize As Long dwXCountChars As Long dwYCountChars As Long dwFillAttribute As Long dwFlags As Long wShowWindow As Integer cbReserved2 As Integer lpReserved2 As Byte hStdInput As Long hStdOutput As Long hStdError As Long End Type Private Type PROCESS_INFORMATION hProcess As Long hThread As Long dwProcessId As Long dwThreadId As Long End Type Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess _ As Long, ByVal uExitCode As Long) As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As _ Long) As Long Private Declare Function WaitForSingleObject Lib "kernel32" _ (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long Private Declare Function CreateProcess Lib "kernel32" Alias _ "CreateProcessA" (ByVal lpApplicationName As String, ByVal _ lpCommandLine As String, lpProcessAttributes As Any, _ lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal _ dwCreationFlags As Any, lpEnvironment As Any, ByVal _ lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, _ lpProcessInformation As PROCESS_INFORMATION) As Long Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _ (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _ ByVal lParam As Long) As Long Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _ ByVal lParam As Long) As Long Private Declare Function GetNextWindow Lib "user32" Alias _ "GetNextQueueWindow" (ByVal hWnd As Long, ByVal wFlag As Integer) _ As Long Private Declare Function GetActiveWindow Lib "user32" () As Long Private Declare Function GetWindowText Lib "user32" Alias _ "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, _ ByVal cch As Long) As Long Private Declare Function GetWindowThreadProcessId& Lib "user32" _ (ByVal hWnd As Long, lpdwProcessID As Long) Private Const GW_HWNDNEXT = 2 Private Const WM_QUIT = &H12 Private Const WM_CLOSE = &H10 Private Const SYNCHRONIZE = &H100000 Private Const NORMAL_PRIORITY_CLASS = &H20& Private pInfo As PROCESS_INFORMATION Private sInfo As STARTUPINFO Private sNull As String Public Function gethWndFromProcessID(ByVal ProcessID As Long) As Long gethWndFromProcessID = 0 Dim hWnd As Long, hWndStop As Long, hWndNext As Long, iLen As Long Dim lngAssocProcessID ' Get a handle to the active window (first in task list). hWnd = GetActiveWindow() hWndStop = hWnd ' Loop until you reach the end of the list. Do ' Get the next window handle. hWndNext = GetNextWindow(hWnd, GW_HWNDNEXT) ' Get the ProcessID the this window lngReply = GetWindowThreadProcessId(hWndNext, lngAssocProcessID) ' If this is the ProcessID I want set the return value and Exit. If lngAssocProcessID = ProcessID Then gethWndFromProcessID = hWndNext Exit Function End If hWnd = hWndNext Loop Until hWnd = hWndStop End Function Public Function gethWndFromTitle(strAppTitle As String) As Long gethWndFromTitle = 0 Dim hWnd As Long, hWndStop As Long, hWndNext As Long, iLen As Long Dim strTitle As String * 80 'Get a handle to the active window (first in task list). hWnd = GetActiveWindow() hWndStop = hWnd 'Loop until you reach the end of the list. Do 'Get the next window handle. hWndNext = GetNextWindow(hWnd, GW_HWNDNEXT) 'Get the text from the window's caption. iLen = GetWindowText(hWndNext, strTitle, Len(strTitle)) If iLen Then 'If this text is what I want see the return value to it's handle and Exit If InStr(strTitle, strAppTitle) Then gethWndFromTitle = hWndNext Exit Do End If End If hWnd = hWndNext Loop Until hWnd = hWndStop End Function Private Sub autokill_Click() If tmrRunning.Enabled = True Then autokill_counter = 0 If autokill.ListIndex = 0 Then autokill_enabled = False: appendlog ("Autokill disabled.") If Not autokill.ListIndex = 0 Then autokill_enabled = True If log_crashes_only.Value = 0 Then appendlog ("Autokill reset to: " + CStr(autokill.List(autokill.ListIndex))) End If If autokill.ListIndex = 1 Then autokill_counter_goal = 1 If autokill.ListIndex = 2 Then autokill_counter_goal = 30 If autokill.ListIndex = 3 Then autokill_counter_goal = 60 If autokill.ListIndex = 4 Then autokill_counter_goal = 120 If autokill.ListIndex = 5 Then autokill_counter_goal = 60 * 3 If autokill.ListIndex = 6 Then autokill_counter_goal = 60 * 4 If autokill.ListIndex = 7 Then autokill_counter_goal = 60 * 5 If autokill.ListIndex = 8 Then autokill_counter_goal = 60 * 6 If autokill.ListIndex = 9 Then autokill_counter_goal = 60 * 12 If autokill.ListIndex = 10 Then autokill_counter_goal = 60 * 24 End If End Sub Private Sub cmdCreateProcess_Click() If cmdKill.Enabled Then appendlog ("WARNING: Something odd has happened: restarter tried to restart HLDS before killed. Attempting Re-kill of HLDS.") cmdKill_Click For c = 1 To 10: X = DoEvents(): Next c cmdKill_Click For c = 1 To 10: X = DoEvents(): Next c End If If Left$(logger.Text, 7) = "Thothie" Then logger.Text = "": appendlog ("Launching HLDS...") disable_methods If method(1) Then If log_crashes_only.Value = 0 Then appendlog ("Verifying server.cfg") setloopscript End If If method(0) Then command_counter_goal = 60 If method(1) Then command_counter_goal = 1 If method(2) Then command_counter_goal = 1 command_interval_counter = 0 If Not hldsrestarted And Not Left$(logger.Text, 7) = "Thothie" Then appendlog ("Launching HLDS...") If hldsrestarted Then hldsrestarted = False If Len(txtStart) = 0 Then Exit Sub End If ' 'Use the CreateProcess API to start the job. This will give us 'Process,Thread,ProcessID and ThreadID handles ' sInfo.cb = Len(sInfo) lngReply = CreateProcess(sNull, txtStart, ByVal 0&, ByVal 0&, 1&, _ NORMAL_PRIORITY_CLASS, ByVal 0&, sNull, sInfo, pInfo) If lngReply = 0 Then MsgBox "Unable to start process " & txtStart.Text appendlog ("Failed ot launch HLDS!") enable_methods modfolder.Enabled = True wait5mins.Enabled = False minutetimer.Enabled = False onesecond.Enabled = False hack.Enabled = False command_interval_counter = 0 Exit Sub End If lblStillRunning.Caption = Right$(CStr(Time), 12) cmdCreateProcess.Enabled = False cmdShell.Enabled = False cmdKill.Enabled = True cmdDestroyByProcessID.Enabled = True lngProcessID = pInfo.dwProcessId lngThreadID = pInfo.dwThreadId lngProcess = pInfo.hProcess lngThread = pInfo.hThread lblProcess = lngProcess lblThread = lngThread lblThreadID = lngThreadID lblProcessID = lngProcessID lblJob = txtStart ' 'Check every second if the job is finishe1d ' 'Any job started with CreateProcess must call CloseHandle for both the 'Process and Thread handles. See tmrRunning_Timer ' tmrRunning.Interval = 1000 tmrRunning.Enabled = True command_interval_counter = 0 If method(0) Then wait5mins.Enabled = True If method(1) Or method(2) Then appendlog ("Hard Crash Tests begin 60 secs.") minutetimer.Enabled = True End If onesecond.Enabled = True 'auto killer autokill_counter = 0 If autokill.ListIndex = 0 Then autokill_enabled = False If Not autokill.ListIndex = 0 Then autokill_enabled = True If log_crashes_only.Value = 0 Then appendlog ("Autokill set to: " + CStr(autokill.List(autokill.ListIndex))) End If If autokill.ListIndex = 1 Then autokill_counter_goal = 1 If autokill.ListIndex = 2 Then autokill_counter_goal = 30 If autokill.ListIndex = 3 Then autokill_counter_goal = 60 If autokill.ListIndex = 4 Then autokill_counter_goal = 120 If autokill.ListIndex = 5 Then autokill_counter_goal = 60 * 3 If autokill.ListIndex = 6 Then autokill_counter_goal = 60 * 4 If autokill.ListIndex = 7 Then autokill_counter_goal = 60 * 5 If autokill.ListIndex = 8 Then autokill_counter_goal = 60 * 6 If autokill.ListIndex = 9 Then autokill_counter_goal = 60 * 12 If autokill.ListIndex = 10 Then autokill_counter_goal = 60 * 24 End Sub Private Sub cmdDestroy_Click() ' 'Destroys a windows program by title ' If Len(txtDestroy) = 0 Then Exit Sub End If Dim hWndNext As Long hWndNext = gethWndFromTitle(txtDestroy) 'If the process was found to be running , kill it If hWndNext <> 0 Then If Option1(0).Value = False Then lngReply = PostMessage(hWndNext, WM_QUIT, 0, 0&) Else lngReply = PostMessage(hWndNext, WM_CLOSE, 0, 0&) End If End If End Sub Private Sub cmdDestroyByProcessID_Click() If Len(lblProcessID) = 0 Then Exit Sub End If DestroyByProcessID (lngProcessID) End Sub Private Function DestroyByProcessID(ProcessID As Long) ' 'Destroys a windows program by title ' Dim hWndNext As Long ' 'Get the first window handle for this ProcessID ' hWndNext = gethWndFromProcessID(ProcessID) Do While hWndNext <> 0 'If the process was found to be running , kill it 'I am using SendMessage rather than PostMessage here as SendMessage will 'only return when the window receiving the message acknowledges it. 'This should stop me finding a window and attempting to delete it whilst 'it is still being deleted from the previous pass through the list. If Option2(0).Value = False Then lngReply = SendMessage(hWndNext, WM_QUIT, 0, 0&) Else lngReply = SendMessage(hWndNext, WM_CLOSE, 0, 0&) End If ' 'Check for any subsequent handles ' hWndNext = gethWndFromProcessID(ProcessID) Loop End Function Private Sub cmdKill_Click() enable_methods modfolder.Enabled = True wait5mins.Enabled = False minutetimer.Enabled = False onesecond.Enabled = False hack.Enabled = False command_interval_counter = 0 lngReply = TerminateProcess(lngProcess, 0&) ' 'Remove to release those handles ' lngReply = CloseHandle(lngThread) lngReply = CloseHandle(lngProcess) End Sub Private Sub cmdKill_MouseUp(Button As Integer, Shift As Integer, X As Single, y As Single) appendlog ("HLDS terminated by user via restarter.") End Sub Private Sub cmdShell_Click() ' 'Start job using the Shell command ' On Error GoTo StartError If Len(txtStart) = 0 Then Exit Sub End If lngProcessID = Shell(txtStart, vbMaximizedFocus) lblStillRunning.Caption = "" ' 'This will return a ProcessID which is of some use ' lblProcess = "Not available" lblThread = "Not available" lblThreadID = "Not available" lblProcessID = lngProcessID lblJob = txtStart Exit Sub StartError: MsgBox "An error occurred starting the job " & txtStart.Text & Chr(10) & _ Chr(10) & "Error " & Err.Number & " " & Err.Description End Sub Private Sub dev_Click() txtStart.Text = "C:\Thoth\msc_restart\sim.bat" End Sub Private Sub Form_Activate() loadsettings On Error GoTo PathError: a$ = Dir$(CStr(App.Path) + "\" + CStr(modfolder.Text) + "\banned.cfg") If a$ = "" Then Open CStr(App.Path) + "\" + CStr(modfolder.Text) + "\banned.cfg" For Output As #2 Print #2, "newfile" Close #2 End If Exit Sub PathError: X = MsgBox("WARNING: Cannot find mod folder. It is very likely you have placed this executable in the wrong folder.", , "HLDS Restart WARNING") End Sub Private Sub Form_KeyPress(KeyAscii As Integer) If UCase$(Chr$(CInt(KeyAscii))) = "`" Then dev.Visible = Not dev.Visible End Sub Private Sub Form_Load() loadingsettings = True 'prevents writing before settings load 'global presets cr$ = Chr$(13) + Chr$(10) 'init logger.Text = "Thothie's HLDS Auto Restarter 1.1 beta for MS:C" + cr$ logger.Text = logger.Text + "For when Severdoc is both too little and too much." + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "This program will check if the HLDS server can process commands by having it update a file (usually banned.cfg using the writeid console command). If the HLDS server fails to process the command (aka. is hard-locked), this program will terminate the HLDS and all its error windows, and then restart it. It allows some leeway time for the server to process the command." + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "This program will also restart the HLDS if it closes for any other reason, just as a batch based restarter would." + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "To use:" + cr$ logger.Text = logger.Text + "- Place the executable in the same folder as your HLDS.exe" + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "- Enter your hlds command line (including hlds.exe, but sans the path) as provided in the above example." + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "- You can use this for mods other than MS:C by specifying the mod's folder in the 'Mod' textbox." + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "- All your tuning preferences and command line will be saved." + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "This program has three different methods for detecting HLDS lock ups." + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "CLIPBOARD METHOD: This pastes the writeid command to the console once every minute while user is in 'Away Mode' (this is set by the option buttons in the lower left corner). This means the program brings the console into focus (ALT+Tab), pastes the command, and minimize the console again every minute - so you do not want this mode running while you are actually working on the system, as it's very annoying. Odds are also very good you may interfere with the process accidentally. Thus, there is the 'I'm working on the computer' option button. In this mode, the program will only check for SOFT crashes (ie. crashes in which the console closes but is not locked or generating error windows) but will not interfere with your work." + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "CONSOLE SCRIPT METHOD (Recommended): This starts a console script that executes the write command roughly every 30 seconds. Downside to this is that you cannot enter text at the console while this script is running. You can, however, access the server via RCON or HLSW." + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "AMX PLUGIN METHOD: This method requires the Server Heartbeat AMX plugin. You can aquire this plugin at http://www.thothie.com/ms/heartbeat.zip . While this method is superior to the others, it requires knowledge of AMX and that it be installed properly on the mod. It works by creating a file called heartbeat.txt in the mod's folder and checking for it's deletion 30 seconds later. The amx heartbeat.amx plugin checks for the file and deletes it, every 30 seconds." + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "Good luck!" + cr$ logger.Text = logger.Text + cr$ logger.Text = logger.Text + "Current Path: " + CStr(App.Path) + cr$ HardTestToggle(0).Caption = "I'm using this computer." + cr$ + "(No Hard Crash Tests)" HardTestToggle(1).Caption = "I'm away." + cr$ + "(Hard Crash Tests Each Minute)" log_enabled.Caption = "Log to File: " + Left(CStr(modfolder.Text), 3) + "_hlds_restarter.log" frmProcess.Caption = UCase$(CStr(modfolder.Text)) + " - Thothie’s HLDS Restarter" autokill.AddItem "Never" autokill.AddItem "1 Minute (Test)" autokill.AddItem "After 30 Minutes" autokill.AddItem "After an Hour" autokill.AddItem "After 2 Hours" autokill.AddItem "After 3 Hours" autokill.AddItem "After 4 Hours" autokill.AddItem "After 5 Hours" autokill.AddItem "After 6 Hours" autokill.AddItem "After 12 Hours" autokill.AddItem "After 24 Hours" autokill.ListIndex = 0 End Sub Private Sub Form_Unload(Cancel As Integer) writesettings Removewriteidscript appendlog ("Restarter Closed.") X = DoEvents() Close #1, #2 End Sub Private Sub HardTestToggle_Click(Index As Integer) If Index = 1 And tmrRunning.Enabled Then appendlog ("Hard Crash Tests Enabled - next test in 60 secs.") command_counter_goal = 60 command_interval_counter = 0 wait5mins.Enabled = True End If If Index = 0 And tmrRunning.Enabled Then appendlog ("Hard Crash Tests paused by user.") command_counter_goal = 60 command_interval_counter = 0 wait5mins.Enabled = False End If End Sub Private Sub log_enabled_Click() If log_enabled.Value = 0 And Not cmdKill.Enabled Then appendlog ("Log closed.") Close #1 End If If log_enabled.Value = 1 And Not cmdKill.Enabled Then Open CStr(App.Path) + "\" + CStr(modfolder.Text) + "_hlds_restart.log" For Append As #1 If Left$(CStr(logger.Text), 7) = "Thothie" Then logger.Text = "" appendlog ("Log started.") End If End Sub Private Sub method_Click(Index As Integer) If method(0) Then clipboard_panel.Visible = True amx_panel.Visible = False script_panel.Visible = False Removewriteidscript If HardTestToggle(1) And tmrRunning.Enabled Then wait5mins.Enabled = True End If If method(1) Then script_panel.Visible = True amx_panel.Visible = False clipboard_panel.Visible = False wait5mins.Enabled = False End If If method(2) Then amx_panel.Visible = True script_panel.Visible = False clipboard_panel.Visible = False Removewriteidscript wait5mins.Enabled = False End If End Sub Private Sub minutetimer_Timer() minute_counter = minute_counter + 1 If minute_counter = 60 Then appendlog ("Hard Crash monitoring started.") wait5mins.Enabled = True minute_counter = 0 minutetimer.Enabled = False End If End Sub Private Sub modfolder_Change() log_enabled.Caption = "Log to File: " + Left(CStr(modfolder.Text), 3) + "_hlds_restarter.log" End Sub Private Sub no_restart_Click() hack_step = 0 If no_restart.Value = 1 Then modfolder.Enabled = True If Not cmdKill.Enabled Then enable_methods appendlog ("AutoRestarting Paused.") End If If no_restart.Value = 0 And cmdKill.Enabled Then If lngReply = 258 Then appendlog ("AutoRestart Unpaused: Process Survives.") hack_step = 0 command_interval_counter = 0 If method(1) Then If log_crashes_only.Value = 0 Then appendlog ("Verifying server.cfg") setloopscript End If If method(0) Then command_counter_goal = 60 If method(1) Then command_counter_goal = 1 If method(2) Then command_counter_goal = 1 command_interval_counter = 0 If method(0) Then wait5mins.Enabled = True If method(1) Then hack.Enabled = True command_interval_counter = 0 If method(0) Then wait5mins.Enabled = True 'auto killer autokill_counter = 0 If autokill.ListIndex = 0 Then autokill_enabled = False If Not autokill.ListIndex = 0 Then autokill_enabled = True If log_crashes_only.Value = 0 Then appendlog ("Autokill reset to: " + CStr(autokill.List(autokill.ListIndex))) End If If autokill.ListIndex = 1 Then autokill_counter_goal = 1 If autokill.ListIndex = 2 Then autokill_counter_goal = 30 If autokill.ListIndex = 3 Then autokill_counter_goal = 60 If autokill.ListIndex = 4 Then autokill_counter_goal = 120 If autokill.ListIndex = 5 Then autokill_counter_goal = 60 * 3 If autokill.ListIndex = 6 Then autokill_counter_goal = 60 * 4 If autokill.ListIndex = 7 Then autokill_counter_goal = 60 * 5 If autokill.ListIndex = 8 Then autokill_counter_goal = 60 * 6 If autokill.ListIndex = 9 Then autokill_counter_goal = 60 * 12 If autokill.ListIndex = 10 Then autokill_counter_goal = 60 * 24 End If If no_restart.Value = 0 And Not cmdKill.Enabled Then If Not lblStillRunning.Caption = "Not Started" Then appendlog ("AutoRestart Unpaused: Re-launching.") cmdCreateProcess_Click End If End If End Sub Private Sub onesecond_Timer() If second_counter = 2 Then If minimstart.Value = 1 And cmdKill.Enabled Then AppActivate pInfo.dwProcessId SendKeys "% n" End If second_counter = 0 onesecond.Enabled = False End If second_counter = second_counter + 1 End Sub Private Sub reloadini_Click() loadsettings End Sub Private Sub tmrRunning_Timer() 'lblStillRunning.Visible = Not (lblStillRunning.Visible) lblStillRunning.Caption = Right$(CStr(Time), 13) lngReply = WaitForSingleObject(lngProcess, 1) ' 'If WAIT_TIMEOUT (258) was returned this means the job is still running. 'If it is not still running, release the handles ' If lngReply <> 258 Then lngReply = CloseHandle(lngProcess) lngReply = CloseHandle(lngThread) lblStillRunning.Caption = "HLDS Inactive" lblStillRunning.Visible = True tmrRunning.Enabled = False cmdCreateProcess.Enabled = True cmdShell.Enabled = True cmdKill.Enabled = False cmdDestroyByProcessID.Enabled = False lblProcess = "" lblProcessID = "" lblThread = "" lblThreadID = "" 'restart HLDS If no_restart.Value = 0 Then hldsrestarted = True appendlog ("HLDS closed. Restarting.") cmdCreateProcess_Click End If If no_restart.Value = 1 Then appendlog ("HLDS closed, but auto restart is paused.") logger.Text = logger.Text + "Uncheck 'Pause AutoRestarting' to enable HLDS restarting." + cr$ End If End If 'autokiller minute_maker = minute_maker + 1 If minute_maker = 60 Then minute_maker = 0: autokill_counter = autokill_counter + 1 If autokill_counter >= autokill_counter_goal And autokill_enabled Then appendlog ("HLDS closed by AutoKiller. (Set: " + CStr(autokill.ListIndex) + ")") cmdKill_Click End If End Sub Private Function appendlog(logentry As Variant) logentry = "[" + CStr(Date) + " " + CStr(Time) + "] " + logentry logger.Text = logger.Text + "[" + Right$(logentry, Len(logentry) - 10) + cr$ If log_enabled.Value = 1 Then If FreeFile(0) > 1 Then Print #1, logentry If FreeFile(0) < 1 Then logger.Text = logger.Text + "WTF: Freefile = " + CStr(FreeFile(0)) End If If Len(logger.Text) > 10000 Then logger.Text = "" logger.Text = "Clearning log text box to conserve memory." + cr$ If log_enabled.Value = 1 Then logger.Text = "This does not affect written log." + cr$ End If 'scroll down With logger .SelStart = Len(.Text) .SelLength = 0 End With End Function Private Sub wait5mins_Timer() command_interval_counter = command_interval_counter + 1 If command_interval_counter > command_counter_goal Then hack_step = 0 hack.Enabled = True command_interval_counter = 0 wait5mins.Enabled = False End If End Sub Private Sub hack_Timer() hack_step = hack_step + 1 If method(0) And HardTestToggle(1) Then If hack_step = 1 Then 'store file date, prepare clipboard If log_crashes_only.Value = 0 Then appendlog ("H.Crash Test: Pasteing writeid to HLDS.") old_banned_date = FileDateTime(CStr(App.Path) + "\" + CStr(modfolder.Text) + "\banned.cfg") Dim tempclip As Variant holder.Text = Clipboard.GetText() Clipboard.Clear hidden.Text = "writeid" + cr$ + "writeid" + cr$ Clipboard.SetText hidden.Text End If If hack_step = 2 Then 'send writeid command Clipboard.SetText hidden.Text X = Clipboard.GetText() If Not X = hidden.Text Then X = MsgBox("WARNING: Cannot access Clipboard! Make sure you have no clipboard managers running!", , "HLDS Restart WARNING") End If AppActivate pInfo.dwProcessId SendKeys "% ep" End If If hack_step = 3 And nominimize.Value = 0 Then 'minimize console AppActivate pInfo.dwProcessId SendKeys "% n" End If If hack_step = 4 Then 'restore clipboard Clipboard.Clear Clipboard.SetText holder.Text End If If hack_step = 15 Then lastHardTestLbl.Caption = Right$(CStr(Time), 12) CompareFileDate hack_step = 0 hack.Enabled = False End If End If If method(1) Then If hack_step = 1 Then 'check banned.cfg date If lastHardTestLbl.Caption = "Not Started" Then lastHardTestLbl.Caption = "Pending..." old_banned_date = FileDateTime(CStr(App.Path) + "\" + CStr(modfolder.Text) + "\banned.cfg") If log_crashes_only.Value = 0 Then appendlog ("H.Crash Test: Banned.cfg reads: " + Right(CStr(old_banned_date), 10)) End If If hack_step = 60 Then lastHardTestLbl.Caption = Right$(CStr(Time), 12) CompareFileDate hack_step = 0 End If End If If method(2) Then If hack_step = 1 Then If log_crashes_only.Value = 0 Then If log_crashes_only.Value = 0 Then appendlog ("H.Crash Test: Checking Heartbeat (60 secs)") End If Open CStr(App.Path) + "\" + CStr(modfolder.Text) + "\heartbeat.txt" For Output As #2 Print #2, "Testing for heartbeat" Close End If If hack_step = 60 Then lastHardTestLbl.Caption = Right$(CStr(Time), 12) a$ = Dir(CStr(App.Path) + "\" + CStr(modfolder.Text) + "\heartbeat.txt") If a$ > "" Then appendlog ("HLDS Has Locked. Terminating.") cmdKill_Click X = DoEvents() If no_restart.Value = 0 Then cmdCreateProcess_Click If no_restart.Value = 1 Then appendlog ("AutoRestarting is Paused: Cannot Restart.") If no_restart.Value = 1 Then logger.Text = logger.Text + "Uncheck Pause AutoRestart to re-enable." + cr$ End If If a$ = "" And log_crashes_only.Value = 0 Then appendlog ("H.Crash Test: Heartbeat. Server is alive.") hack_step = 0 End If End If End Sub Private Sub CompareFileDate() new_banned_date = FileDateTime(CStr(App.Path) + "\" + CStr(modfolder.Text) + "\banned.cfg") If new_banned_date = old_banned_date And no_restart.Value = 0 Then appendlog ("Banned.cfg unchanged. HLDS has locked. Terminating.") cmdKill_Click X = DoEvents() Else If log_crashes_only.Value = 0 Then If method(0) And log_crashes_only.Value = 0 Then appendlog ("H.Crash Test OK: HLDS executed command.") If method(1) And log_crashes_only.Value = 0 Then appendlog ("H.Crash Test OK: Banned.cfg was updated.") If method(2) And log_crashes_only.Value = 0 Then appendlog ("H.Crash Test OK: Heartbeat AMX still running.") End If command_interval_counter = 0 If method(0) Then wait5mins.Enabled = True End If End Sub Private Sub command_interval_Change() If command_interval.Value = 0 Then command_counter_goal = 10 End If If command_interval.Value > 0 Then command_counter_goal = command_interval.Value * 60 End If End Sub Sub writesettings() Open CStr(App.Path) + "\hlds_restart.ini" For Output As #2 '0 Print #2, "HLDS Restart INI Version 1.1" '1 Print #2, CStr(txtStart.Text) '2 Print #2, CInt(log_enabled.Value) '3 Print #2, CInt(log_crashes_only.Value) '4 Print #2, CStr(modfolder.Text) '5 Print #2, CInt(nominimize.Value) '6 Print #2, CInt(minimstart.Value) '7 For X = 0 To 2 If method(X) Then Print #2, CInt(X) End If Next X '8 For X = 0 To 1 If HardTestToggle(X) Then Print #2, CInt(X) End If Next X HardTestToggle(y).Value = True '9 Print #2, CInt(autokill.ListIndex) Close #2 End Sub Private Sub loadsettings() a$ = Dir$(CStr(App.Path) + "\hlds_restart.ini") If a$ = "" Then Exit Sub loadingsettings = True Open CStr(App.Path) + "\hlds_restart.ini" For Input As #3 '0 Line Input #3, a$ If Not a$ = "HLDS Restart INI Version 1.1" Then Close #3 Kill (CStr(App.Path) + "\hlds_restart.ini") logger.Text = logger.Text + "INI File for Previous Version - preferences lost." + cr$ Exit Sub End If '1 Line Input #3, a$ txtStart.Text = a$ '2 Line Input #3, X log_enabled.Value = X '3 Line Input #3, X log_crashes_only.Value = X '4 Line Input #3, a$ modfolder.Text = a$ '5 Line Input #3, X nominimize.Value = X '6 Line Input #3, X minimstart.Value = X '7 Input #3, y method(y).Value = True '8 Input #3, y HardTestToggle(y).Value = True '9 Input #3, y autokill.ListIndex = y Close #3 loadingsettings = False If log_enabled.Value = True Then If FreeFile(0) = 2 Then Open CStr(App.Path) + "\hlds_restart.log" For Append As #3 End If If log_enabled.Value = False Then Close #3 End If End Sub Private Sub setloopscript() a$ = Dir$(CStr(App.Path) + "\" + CStr(modfolder.Text) + "\server.cfg") If a$ = "" Then X = MsgBox("ERROR: Could not find " + CStr(modfolder.Text) + "\server.cfg - program installed in wrong folder or mod folder incorrect.", , "HLDS Restarter FATAL ERROR") End End If Open CStr(App.Path) + "\" + CStr(modfolder.Text) + "\server.cfg" For Input As #2 holder.Text = "" Dim loopscriptfound As Boolean Dim loopscriptactive As Boolean While Not EOF(2) Line Input #2, a$ If a$ = "//exec writeidloop.cfg" And Not loopscriptfound Then a$ = "exec writeidloop.cfg": loopscriptfound = True If a$ = "exec writeidloop.cfg" And Not loopscriptfound Then loopscriptactive = True: loopscriptfound = True holder.Text = holder.Text + a$ + cr$ Wend Close #2 'check if backup exists a$ = Dir$(CStr(App.Path) + "\" + CStr(modfolder.Text) + "\server.cfg.backup") If a$ = "" Then 'no backup exists, create If log_crashes_only.Value = 0 Then appendlog ("Script not found in server.cfg. Must append...") If log_crashes_only.Value = 0 Then appendlog ("Backing up server.cfg to server.cfg.backup") Dim srcfile As String Dim destfile As String srcfile = CStr(App.Path) + "\" + CStr(modfolder.Text) + "\server.cfg" destfile = CStr(App.Path) + "\" + CStr(modfolder.Text) + "\server.cfg.backup" FileCopy srcfile, destfile End If If Not loopscriptactive And loopscriptfound Then 'exec is commented, write fix If log_crashes_only.Value = 0 Then appendlog ("Uncommenting writeloop in sever.cfg") Open CStr(App.Path) + "\" + CStr(modfolder.Text) + "\server.cfg" For Output As #2 Print #2, holder.Text Close #2 loopscriptactive = True End If If Not loopscriptfound And Not loopscriptactive Then If log_crashes_only.Value = 0 Then appendlog ("Appending server.cfg...") holder.Text = holder.Text + " " + cr$ holder.Text = holder.Text + "//Execute Thothie's HLDS Restart writeid Loop Script 1.0" + cr$ holder.Text = holder.Text + "exec writeidloop.cfg" + cr$ Open CStr(App.Path) + "\" + CStr(modfolder.Text) + "\server.cfg" For Output As #2 Print #2, holder.Text Close #2 If log_crashes_only.Value = 0 Then appendlog ("Successful.") End If 'generate script If log_crashes_only.Value = 0 Then appendlog ("Creating writeidloop.cfg.") Open CStr(App.Path) + "\" + CStr(modfolder.Text) + "\writeidloop.cfg" For Output As #2 holder.Text = "//Thothie's WriteID Loop Script for HLDS Restarter 1.0" + cr$ holder.Text = holder.Text + "echo Thothies WriteID loop loaded:" + cr$ holder.Text = holder.Text + "echo -You will not be able to enter text in console." + cr$ holder.Text = holder.Text + "echo -But Rcon or HLSW can still be used." + cr$ holder.Text = holder.Text + "alias tenwait " + Chr$(34) + "wait;wait;wait;wait;wait;wait;wait;wait;wait;wait" + Chr$(34) + cr$ holder.Text = holder.Text + "alias 100wait " + Chr$(34) + "tenwait;tenwait;tenwait;tenwait;tenwait;tenwait;tenwait;tenwait;tenwait;tenwait;tenwait" + Chr$(34) + cr$ holder.Text = holder.Text + "alias 1000wait " + Chr$(34) + "100wait;100wait;100wait;100wait;100wait;100wait;100wait;100wait;100wait;100wait" + Chr$(34) + cr$ holder.Text = holder.Text + "alias writeloop " + Chr$(34) + "1000wait;writeid;writeloop" + Chr$(34) + cr$ holder.Text = holder.Text + "writeloop" + cr$ Print #2, holder.Text Close #2 End Sub Private Sub Removewriteidscript() a$ = Dir$(CStr(App.Path) + "\" + CStr(modfolder.Text) + "\server.cfg") If a$ = "" Then X = MsgBox("ERROR: Could not find" + CStr(modfolder.Text) + "\server.cfg - is this program installed in wrong folder?", , "HLDS Restarter FATAL ERROR") End End If Open CStr(App.Path) + "\" + CStr(modfolder.Text) + "\server.cfg" For Input As #2 holder.Text = "" Dim loopscriptfound As Boolean While Not EOF(2) Line Input #2, a$ If a$ = "exec writeidloop.cfg" Then a$ = "//exec writeidloop.cfg": loopscriptfound = True holder.Text = holder.Text + a$ + cr$ Wend Close #2 If loopscriptfound Then If log_crashes_only.Value = 0 Then appendlog ("Disabeling writeidloop script in server.cfg.") Open CStr(App.Path) + "\" + CStr(modfolder.Text) + "\server.cfg" For Output As #2 Print #2, holder.Text Close #2 End If End Sub Private Sub disable_methods() method_panel.Enabled = False For X = 0 To 2: method(X).Enabled = False: Next X modfolder.Enabled = False End Sub Private Sub enable_methods() method_panel.Enabled = True For X = 0 To 2: method(X).Enabled = True: Next X modfolder.Enabled = True End Sub