A3 Server Monitor

Socius Decennalis
Decennium
Joined
Jan 26, 2012
Messages
75
Reaction score
74
It is a monitoring program that I have used in order to simplify server startup and kill.

There is a monitoring function if there is an abnormality in one of the servers, it is possible to restart from killing all servers.
There is a schedule function, it is possible to shut down or restart the server to the required time.

monitor - A3 Server Monitor - RaGEZONE Forums

View attachment A3 Monitor.zip


Is created using the AutoHotkey, is a Korean environment. Please use by modifying the source if needed.

The source code includes a scheduling function of the ZS for event. In my memory, perhaps this feature was not tested.


A3 Monitor.ahk
Code:
#SingleInstance Force
#NoTrayIcon
#NoEnv

FormatTime, _sDays, A_Now, yyyyMMdd
FormatTime, _eDays, A_Now, yyyyMMdd
_sHour := ""
_eHour := ""
_sMin := ""
_eMin := ""
_eStart := ""
_eEnd := ""
_PID := ""

;gui start
Gui, Font,, Segoe UI
Gui, Add, GroupBox, x5 y5 w340 h55 cBlack, Server Scheduler
Gui, Font, s11 Bold
Gui, Add, Edit, xp+5 yp+20 h28 w48 Number vSetHour0
Gui, Add, UpDown, vSetHour Wrap Range0-23, 0
Gui, Font, s19
Gui, Add, Text, x+5 yp-7, :
Gui, Font, s11
Gui, Add, Edit, x+5 yp+7 h28 w48 Number vSetMin0
Gui, Add, UpDown, vSetMin Wrap Range0-59, 0
Gui, Font, s9 Normal
Gui, Add, CheckBox, x+20 yp-6 vsOp1 gOper, 서버종료
Gui, Add, CheckBox, xp y+4 vsOp2 gOper, 서버재시작
Gui, Font, s20 Normal
Gui, Add, Text, x+40 yp-22 vScheInfo cBLUE, OFF

Gui, Font, s9 Normal
Gui, Add, GroupBox, x5 y+10 w340 h85 cBlack, Event ZS Scheduler
Gui, Font, s9 Normal
Gui, Add, CheckBox, xp+5 yp+18 vsOp3 geOper, 시작
Gui, Font, s11 Bold
Gui, Add, Edit, xp y+2 h28 w48 Number vSetESHour0
Gui, Add, UpDown, vSetESHour Wrap Range0-23, 0
Gui, Font, s19
Gui, Add, Text, x+5 yp-7, :
Gui, Font, s11
Gui, Add, Edit, x+5 yp+7 h28 w48 Number vSetESMin0
Gui, Add, UpDown, vSetESMin Wrap Range0-59, 0

Gui, Font, s9 Normal
Gui, Add, CheckBox, x+15 yp-17 vsOp4 geOper, 종료
Gui, Font, s11 Bold
Gui, Add, Edit, xp y+2 h28 w48 Number vSetEEHour0
Gui, Add, UpDown, vSetEEHour Wrap Range0-23, 0
Gui, Font, s19
Gui, Add, Text, x+5 yp-7, :
Gui, Font, s11
Gui, Add, Edit, x+5 yp+7 h28 w48 Number vSetEEMin0
Gui, Add, UpDown, vSetEEMin Wrap Range0-59, 0

Gui, Font, s9 Normal
Gui, Add, CheckBox, x+20 yp-17 vsOp5 geOper, 반복
Gui, Font, s11 Bold
Gui, Add, Edit, xp y+2 h28 w48 Number vSetRepeat
Gui, Font, s16 normal
Gui, Add, Text, x+2 yp-2, h
Gui, Font, s9 Normal
Gui, Add, Text, xs+5 y+3 w125 vNextStart cBLUE
Gui, Add, Text, x+3 yp w125 vNextEnd cRed
Gui, Add, Text, x+3 yp w75 vzsPID cBlack

GuiControl, Disable, sOp4
GuiControl, Disable, sOp5

;Gui, Font, s20 Normal
;Gui, Add, Text, x+40 yp-22 veScheInfo cBLUE, OFF

Gui, Font, s9 Normal
Gui, Add, GroupBox, x5 y+10 w340 h100 cBlack, Serverlist
Gui, Font, s8
Gui, Add, Edit, xs+5 yp+20 w329 h73 vSvrlist ReadOnly -Wrap
Gui, Add, Text, x5 y+18 vInfo w265 cRED Center
Gui, Add, Button, x+5 yp-5 w70 h30 gKillServer, 서버 종료
Gui, Add, Button, xp y+5 w70 h30 gStartServer, 서버 시작
Gui, Add, Button, xp y+5 w70 h30 vBT_M gTG_Monitor, 감시 시작
Gui, Add, Edit, x5 yp-44 w265 h73 vSvrLog ReadOnly
Gui, Add, GroupBox, x5 y+10 w340 h48 cBlack, Update Server
Gui, Add, Button, xp+5 yp+18 w330 h24 vBT_U gTG_Update
Gui, Show, w350, A3 Monitor ⓒ 2013 by prologos

;ini read
IniRead, UpdatePath, SvrInfo.ini, UpdateInfo, UpdatePath
If (!UpdatePath OR UpdatePath = "ERROR")
{
	GuiControl,, BT_U, 설정파일에 설정값 없음
	GuiControl, -g, BT_U
}
else
{
	IfExist, %UpdatePath%
	{
		GuiControl,, BT_U, [ ON ] 업데이트 가능
		Update_Tg := True
	}
	else IfExist, %UpdatePath%_off
	{
		GuiControl,, BT_U, [ OFF ] 업데이트 불가능
		Update_Tg := False
	}
	else
	{
		GuiControl,, BT_U, 업데이트 폴더 지정이 잘못됨
		GuiControl, -g, BT_U
	}
}

IniRead, ServerMax, SvrInfo.ini, SvrInfo, ServerMax
If (!ServerMax OR ServerMax = "ERROR")
	ServerMax := 0
IniRead, WinWaitSec, SvrInfo.ini, SvrInfo, WinWaitSec, 30
IniRead, Interval, SvrInfo.ini, SvrInfo, Interval, 60
Interval := Interval * 1000 ;sec을 ms로 변환

Svrlist := ""
Loop, % ServerMax + 1
{
    IDX := A_Index - 1
	IniRead, SvrPath%IDX%, SvrInfo.ini, SvrInfo, SvrPath%IDX%
	If (!SvrPath%IDX% OR SvrPath%IDX% = "ERROR")
		SvrPath%IDX% := ""
	Else
	{
		StringSplit, tmp, SvrPath%IDX%, `,
		Loop, 5 ;서버 Path를 제외하고 나머지 변수들은 공백제거
		{
			If (A_Index > 1)
				StringReplace, tmp%A_Index%, tmp%A_Index%, %A_SPACE%,, All
		}
		SvrPath%IDX% := tmp1
		WinSize%IDX% := tmp2
		WinX%IDX% := tmp3
		WinY%IDX% := tmp4
		WinClick%IDX% := tmp5

		tmp := ""
		Loop, % 2 - StrLen(IDX)
			tmp .= "0"
		Svrlist .= "[" . tmp . IDX . "] " . SvrPath%IDX% . "`n"
        ;풀 패스(SvrPath%IDX%)를 디렉토리(SvrDir%IDX%)와 파일명(SvrName%IDX%)으로 분리
		SplitPath, SvrPath%IDX%, SvrName%IDX%, SvrDir%IDX%
	}
}
StringReplace, Svrlist, Svrlist, [00], [eZS]
GuiControl,, Svrlist, % SubStr(Svrlist, 1, StrLen(Svrlist)-1)
Return

;이벤트서버
eOper:
    Gui, Submit, NoHide

    if (A_GuiControl = "sOp3")
    {
      if (sOp3 = 1)
      {
        ;시작시간 셋팅
        FormatTime, _sDays, A_Now, yyyyMMdd
        SetESHour := "0" . SetESHour
        StringRight, _sHour, SetESHour, 2
        SetESMin := "0" . SetESMin
        StringRight, _sMin, SetESMin, 2
        FormatTime, _eStart, % _sDays . _sHour . _sMin, yyyyMMddHHmm

        GuiControl, Enable, sOp4
        GuiControl,, NextStart, % "다음시작: " . Substr(_eStart, 5, 2) . "-" . Substr(_eStart, 7, 2) . " " . Substr(_eStart, 9, 2) . ":" . Substr(_eStart, 11, 2)

        GuiControl, +ReadOnly, SetESHour0
        GuiControl, +ReadOnly, SetESMin0
        GuiControl, Disable, SetESHour
        GuiControl, Disable, SetESMin

        ;ZS시작 타이머 시작: 1분마다 체크
        SetTimer, EventZS_Start, 60000
      }
      else
      {
        GuiControl,, sOp4, 0
        GuiControl,, sOp5, 0
        GuiControl, Disable, sOp4
        GuiControl, Disable, sOp5

        ;시작 컨트롤 원복
        GuiControl,, NextStart
        GuiControl, -ReadOnly, SetESHour0
        GuiControl, -ReadOnly, SetESMin0
        GuiControl, Enable, SetESHour
        GuiControl, Enable, SetESMin
        ;타이머 끄기
        SetTimer, EventZS_Start, Off

        ;종료 컨트롤 원복
        GuiControl,, NextEnd
        GuiControl, -ReadOnly, SetEEHour0
        GuiControl, -ReadOnly, SetEEMin0
        GuiControl, Enable, SetEEHour
        GuiControl, Enable, SetEEMin

        ;반복 컨트롤 원복
        GuiControl, -ReadOnly, SetRepeat
      }
    }
    else if (A_GuiControl = "sOp4")
    {
      if (sOp4 = 1)
      {
        ;종료시간 셋팅
        FormatTime, _eDays, A_Now, yyyyMMdd
        SetEEHour := "0" . SetEEHour
        StringRight, _eHour, SetEEHour, 2
        SetEEMin := "0" . SetEEMin
        StringRight, _eMin, SetEEMin, 2
        FormatTime, _eEnd, % _eDays . _eHour . _eMin, yyyyMMddHHmm
        
        ;종료 시간이 시작 시간보다 작은경우는 다음날로 간주
        if (_eStart >= _eEnd)
        {
          EnvAdd, _eEnd, 24, hours
          FormatTime, _eEnd, %_eEnd%, yyyyMMddHHmm
        }

        GuiControl, Enable, sOp5
        GuiControl,, NextEnd, % "다음종료: " . Substr(_eEnd, 5, 2) . "-" . Substr(_eEnd, 7, 2) . " " . Substr(_eEnd, 9, 2) . ":" . Substr(_eEnd, 11, 2)

        GuiControl, +ReadOnly, SetEEHour0
        GuiControl, +ReadOnly, SetEEMin0
        GuiControl, Disable, SetEEHour
        GuiControl, Disable, SetEEMin

        ;ZS시작 타이머 시작: 1분마다 체크
        SetTimer, EventZS_End, 60000
      }
      else
      {
        GuiControl,, sOp5, 0
        GuiControl, Disable, sOp5

        GuiControl,, NextEnd

        GuiControl, -ReadOnly, SetEEHour0
        GuiControl, -ReadOnly, SetEEMin0
        GuiControl, Enable, SetEEHour
        GuiControl, Enable, SetEEMin

        ;타이머 끄기
        SetTimer, EventZS_End, Off
      }
    }
    else if (A_GuiControl = "sOp5")
    {
      if (sOp5 = 1)
      {
        GuiControl, +ReadOnly, SetRepeat
      }
      else
      {
        GuiControl, -ReadOnly, SetRepeat
      }
    }

Return
;이벤트 ZS 종료
EventZS_End:
    Gui, Submit, NoHide

    FormatTime, CurrentTime, %A_Now%, yyyyMMddHHmm
    if (CurrentTime = _eEnd)
    {
      ;eZS종료 코드 넣을곳
      RunWait, %ComSpec% /C TASKKILL /F /PID %_PID%,, Hide
      GuiControl,, zsPID

      if (sOp5 = 1)
      {
        ;반복 체크되어 있을때 다음 시작 시간 계산
        EnvAdd, _eEnd, SetRepeat, hours
        FormatTime, _eEnd, %_eEnd%, yyyyMMddHHmm
        GuiControl,, NextEnd, % "다음종료: " . Substr(_eEnd, 5, 2) . "-" . Substr(_eEnd, 7, 2) . " " . Substr(_eEnd, 9, 2) . ":" . Substr(_eEnd, 11, 2)
      }
      else
      {
        GuiControl,, NextEnd
        ;타이머 끄기
        SetTimer, EventZS_End, Off
      }
    }
Return

;이벤트 ZS 시작
EventZS_Start:
    Gui, Submit, NoHide

    FormatTime, CurrentTime, %A_Now%, yyyyMMddHHmm
    if (CurrentTime = _eStart)
    {
      ;eZS시작 코드 넣을곳 pid: zsPID
	  Run, "%SvrPath0%", %SvrDir0%, UseErrorLevel, _PID
      WinWait, ahk_pid %_PID%,, %WinWaitSec%
	  If ErrorLevel
	    Goto TimedOut
	  Sleep 200
      ;이벤트용 ZS의 PID표시
      GuiControl,, zsPID, %_PID%

      ;반복 체크되어 있을때 다음 시작 시간 계산
      if (sOp5 = 1)
      {
        EnvAdd, _eStart, SetRepeat, hours
        FormatTime, _eStart, %_eStart%, yyyyMMddHHmm
        GuiControl,, NextStart, % "다음시작: " . Substr(_eStart, 5, 2) . "-" . Substr(_eStart, 7, 2) . " " . Substr(_eStart, 9, 2) . ":" . Substr(_eStart, 11, 2)
      }
      else
      {
        GuiControl,, NextStart
        ;타이머 끄기
        SetTimer, EventZS_Start, Off
      }
    }
Return


;예약작업
Oper:
    Gui, Submit, NoHide

    if (A_GuiControl = "sOp1")
    {
      GuiControl,, sOp2, 0
      if (sOp1 = 1)
        GuiControl, Disable, sOp2
      else
        GuiControl, Enable, sOp2
    }
    else if (A_GuiControl = "sOp2")
    {
      GuiControl,, sOp1, 0
      if (sOp2 = 1)
        GuiControl, Disable, sOp1
      else
        GuiControl, Enable, sOp1
    }

    if (sOp1 = 1 or sOp2 = 1)
    {
      GuiControl,, ScheInfo, ON
      GuiControl, +ReadOnly, SetHour0
      GuiControl, +ReadOnly, SetMin0
      GuiControl, Disable, SetHour
      GuiControl, Disable, SetMin

      if (sOp1 = 1)
        SetTimer, ScheKill, 60000
      else if (sOp2 = 1)
        SetTimer, ScheRestart, 60000
    }
    else
    {
      GuiControl,, ScheInfo, OFF
      GuiControl, -ReadOnly, SetHour0
      GuiControl, -ReadOnly, SetMin0
      GuiControl, Enable, SetHour
      GuiControl, Enable, SetMin

      SetTimer, ScheKill, Off
      SetTimer, ScheRestart, Off
    }
    ;msgbox, %A_GuiControl% - %SetHour%:%SetMin% %sOp1% - %sOp2%
Return

;스케줄 - 서버종료
ScheKill:
    Gui, Submit, NoHide
    if (SetHour = A_Hour and SetMin = A_Min)
    {
	  GuiControl,, sOp1, 0
      GuiControl,, sOp2, 0
      GuiControl, Enable, sOp1
      GuiControl, Enable, sOp2
      GoSub Oper
      ;모니터링 상태이면 모니터링 끄기
      if (Monitoring_Tg)
        GoSub TG_Monitor
      ;업데이트 가능상태이면 불가능으로 만들기
      if (Update_Tg)
      {
        GoSub TG_Update
        ;FileMove, %UpdatePath%vn.ini, %UpdatePath%vn_off.ini, 1
        ;GuiControl,, BT_U, [ OFF ] 업데이트 불가능
        ;Update_Tg := Not Update_Tg
      }
      Step := "Schedule"
      Step := "KILL " . A_YYYY . "-" . A_MM . "-" . A_DD . " " . A_Hour . ":" . A_Min . ":" . A_Sec . " / Cause [" . Step . "]"
	  Err(Step)
      GoSub KillServer
    }
Return

;스케줄 - 서버 재시작
ScheRestart:
    Gui, Submit, NoHide
    if (SetHour = A_Hour and SetMin = A_Min)
    {
      ;업데이트 서버 중단
      if (Update_Tg)
      {
        GoSub TG_Update
      }

	  GuiControl,, sOp1, 0
      GuiControl,, sOp2, 0
      GuiControl, Enable, sOp1
      GuiControl, Enable, sOp2
      GoSub Oper
      Step := "Schedule"
      ;모니터링 상태이면 모니터링 끄기고 작업후 다시 켜기
      if (Monitoring_Tg)
      {
        GoSub TG_Monitor
        GoSub ServerRestart
        GoSub TG_Monitor
      }
      else
        GoSub ServerRestart

      ;업데이트 서버 재개
      if (!Update_Tg)
      {
        GoSub TG_Update
      }
    }
Return

;업데이트 서버 설정부분
TG_Update:
	Update_Tg := Not Update_Tg
	if (Update_Tg)
	{
		FileMoveDir, %UpdatePath%_off, %UpdatePath%, R
		GuiControl,, BT_U, [ ON ] 업데이트 가능
	}
	else
	{
		FileMoveDir, %UpdatePath%, %UpdatePath%_off, R
		GuiControl,, BT_U, [ OFF ] 업데이트 불가능
	}
Return

KillServer:
	;GuiControl,, Info, 서버 종료중...
	Loop, %ServerMax%
	{
		Num := ServerMax + 1 - A_Index
		SvrName := SvrName%Num%

		If (SvrName)
		{
			tmp := ""
			Loop, % 2 - StrLen(Num)
				tmp .= "0"
			GuiControl,, Info, [%tmp%%Num%] 서버 종료중...
			RunWait, %ComSpec% /C TASKKILL /F /IM %SvrName%,, Hide
		}
	}
	GuiControl,, Info, 서버 종료 완료
Return

StartServer:
	GuiControl,, Info, 서버 시작하는중...
	;BlockInput, MouseMove

	Loop, %ServerMax%
	{
		Step := A_Index
		SvrPath := SvrPath%A_Index%
		SvrDir := SvrDir%A_Index%
		If (SvrPath)
		{
			Run, "%SvrPath%", %SvrDir%, UseErrorLevel, PID
			WinWait, ahk_pid %PID%,, %WinWaitSec%
			If ErrorLevel
				Goto TimedOut
			Sleep 200

			;설정에따라 클릭이 필요하면 처리함
			If (WinClick%A_Index%)
			{
				If (WinClick%A_Index% = 3) ;GM Shouts by ChrissDeGrece의 경우
				{
					CountWhile := 0
					While 1
					{
						ControlGetFocus, TBcheck, ahk_pid %PID%
						if (TBcheck = "ListBox1")
							ControlClick, Button4, ahk_pid %PID%,, LEFT, 1
						else if (TBcheck = "Button1")
							ControlClick, Button1, ahk_pid %PID%,, LEFT, 1
						else if (TBcheck = "Button4")
							Break

						CountWhile++
						If (CountWhile > 50)
							Goto TimedOut
					}
				}
				else if (WinClick%A_Index% = 2) ;GM Shouts by prologos의 경우
				{
					TBcheck := 1
					CountWhile := 0
					While (TBcheck)
					{
						ControlGet, TBcheck, Enabled,, Button4, ahk_pid %PID%
						ControlClick, Button4, ahk_pid %PID%,, LEFT, 2
						CountWhile++
						If (CountWhile > 50)
							Goto TimedOut
					}
				}
				else ;ODBC 설정의 경우
				{
					TBname1 := "TButton4"
					TBname2 := "TButton5"
					TBname3 := "TButton2"
					Loop, 3
					{
						TBname := TBname%A_Index%
						TBcheck := 1
						CountWhile := 0
						While (TBcheck)
						{
							ControlGet, TBcheck, Enabled,, %TBname%, ahk_pid %PID%
							ControlClick, %TBname%, ahk_pid %PID%,, LEFT, 2
							CountWhile++
							If (CountWhile > 50)
								Goto TimedOut
						}
					}
					While (!TBcheck) ;리스트박스에 "[OK] Listening" 메시지 뜰때까지 대기
					{
						ControlGet, TBcheck, List,, TColorListBox1, ahk_pid %PID%
					}
				}
			}

			;설정에따라 창을 최소화하거나 지정된 위치로 이동시킴
			If (!WinSize%A_Index%)
				WinMinimize, ahk_pid %PID%
			else
				WinMove, ahk_pid %PID%,, WinX%A_Index%, WinY%A_Index%

			Sleep 500 ;서버하나 실행후 잠시 텀두기
		}
	}

	;BlockInput, MouseMoveOff
	GuiControl,, Info, 서버 시작 완료
Return

TimedOut:
	;BlockInput, MouseMoveOff
	GuiControl,, Info, 서버 시작 오류
	Loop, % 2 - StrLen(Step)
		Step := "0" . Step
	Step := "[" . Step . "] / " . A_YYYY . "-" . A_MM . "-" . A_DD . " " . A_Hour . ":" . A_Min . ":" . A_Sec
	Err("TIMEOUT " . Step)
Return


TG_Monitor:
	Monitoring_Tg := Not Monitoring_Tg
	MonitorInfo(Monitoring_Tg)

	If (Monitoring_Tg)
		SetTimer, Monitoring, %Interval%
	Else
		SetTimer, Monitoring, Off
Return

Monitoring:
	MonitorInfo(Monitoring_Tg)
	If (Monitoring_Tg)
	{
		Loop, %ServerMax%
		{
			SvrName := SvrName%A_Index%
			If (SvrName)
			{
				Step := A_Index
				Process, Exist, %SvrName%
				If (ErrorLevel = 0)
					Goto ServerRestart
			}
		}
	}
	Else
		SetTimer, Monitoring, Off
Return

ServerRestart:
	Loop, % 2 - StrLen(Step)
		Step := "0" . Step
	Step := "RESTART " . A_YYYY . "-" . A_MM . "-" . A_DD . " " . A_Hour . ":" . A_Min . ":" . A_Sec . " / Cause [" . Step . "]"
	Err(Step)

    ;업데이트서버 상태 반전
    GoSub TG_Update

	;서버 재시작
    GoSub KillServer
	GoSub StartServer

    ;업데이트서버 상태 원복
    GoSub TG_Update
Return

GuiClose:
GuiEscape:
ExitApp

Err(msg) {
	GuiControlGet, tmp,, SvrLog
	tmp := msg . "`n" . tmp
	GuiControl,, SvrLog, %tmp%
}

MonitorInfo(Toggle) {
	If (Toggle)
	{
		GuiControl,, Info, 모니터링중...
		GuiControl,, BT_M, 감시 종료
	}
	else
	{
		GuiControl,, Info, 모니터링 종료
		GuiControl,, BT_M, 감시 시작
	}
}


SvrInfo.ini
Code:
*************************************************************************************************
* ServerMax : SvrPath의 마지막 번호								*
* SvrPath? :  Full Path										*
*             0-Minimize | 1-WinMove								*
*             X좌표(WinMove일경우)								*
*             Y좌표										*
*             0-클릭없음 | 1-ODBC | 2-GM Shouts by prologos | 3-GM Shouts by ChrissDeGrece	*
* SvrPath0 : 이벤트용 존서버									*
* Interval : 서버 모니터링 인터벌(초)								*
* WinWaitSec : 서버 실행시 창의 활성화시까지 대기시간(초)					*
* UpdatePath : 업데이트 파일들이 있는 폴더. 마지막 "\"는 적지않기				*
* 서버 프로그램은 낮은 번호순으로 실행되고 종료시는 높은 번호 순으로 종료됨			*
*************************************************************************************************

[UpdateInfo]
UpdatePath=D:\inetpub\wwwroot\A3_update

[SvrInfo]
WinWaitSec=60
Interval=180
ServerMax=14
SvrPath0=D:\A3Server\E.ZoneServer\ZoneServer.exe,0,,,0
SvrPath1=D:\a3server\7770\asd_mw_v1.3.21a.exe,0,,,1
SvrPath2=D:\a3server\8880\asd_mw_v1.3.21a.exe,0,,,1
SvrPath3=D:\a3server\9990\asd_mw_v1.3.21a.exe,0,,,1
SvrPath4=D:\a3server\LoginServer\newLoginServer.exe,0,,,0
SvrPath5=D:\a3server\Loginagent\enLoginAgentr.exe,0,,,0
SvrPath6=D:\a3server\ZoneAgent\EnZa_v2.0.16a.exe,1,610,30,0
SvrPath7=D:\a3server\mainserver\MainServer.exe,0,,,0
SvrPath8=D:\a3server\A3_Util\FDB2Txt.exe,0,,,0
SvrPath9=D:\a3server\A3_Util\MWCLDB.exe,0,,,0
SvrPath10=D:\a3server\accountserver\AccountServer.exe,1,50,30,0
SvrPath11=D:\a3server\Zoneserver\ZoneServer.exe,0,,,0
SvrPath12=D:\a3server\BattleServer\BattleServer.exe,0,,,0
SvrPath13=D:\a3server\new\CenterServer.exe,0,,,0
SvrPath14=D:\a3server\Zoneserver\gmshouts.exe,0,,,2
SvrPath15=
 
Thanks prologos for the share
As this was in korean i tried to convert it in English (based on google)
Here is the script and exe file i have attached
hope it works..
Code:
#SingleInstance Force
#NoTrayIcon
#NoEnv

FormatTime, _sDays, A_Now, yyyyMMdd
FormatTime, _eDays, A_Now, yyyyMMdd
_sHour := ""
_eHour := ""
_sMin := ""
_eMin := ""
_eStart := ""
_eEnd := ""
_PID := ""

;gui start
Gui, Font,, Segoe UI
Gui, Add, GroupBox, x5 y5 w340 h55 cBlack, Server Scheduler
Gui, Font, s11 Bold
Gui, Add, Edit, xp+5 yp+20 h28 w48 Number vSetHour0
Gui, Add, UpDown, vSetHour Wrap Range0-23, 0
Gui, Font, s19
Gui, Add, Text, x+5 yp-7, :
Gui, Font, s11
Gui, Add, Edit, x+5 yp+7 h28 w48 Number vSetMin0
Gui, Add, UpDown, vSetMin Wrap Range0-59, 0
Gui, Font, s9 Normal
Gui, Add, CheckBox, x+20 yp-6 vsOp1 gOper, Server shutdown
Gui, Add, CheckBox, xp y+4 vsOp2 gOper, Server Restart
Gui, Font, s20 Normal
Gui, Add, Text, x+40 yp-22 vScheInfo cBLUE, OFF

Gui, Font, s9 Normal
Gui, Add, GroupBox, x5 y+10 w340 h85 cBlack, Event ZS Scheduler
Gui, Font, s9 Normal
Gui, Add, CheckBox, xp+5 yp+18 vsOp3 geOper, Start
Gui, Font, s11 Bold
Gui, Add, Edit, xp y+2 h28 w48 Number vSetESHour0
Gui, Add, UpDown, vSetESHour Wrap Range0-23, 0
Gui, Font, s19
Gui, Add, Text, x+5 yp-7, :
Gui, Font, s11
Gui, Add, Edit, x+5 yp+7 h28 w48 Number vSetESMin0
Gui, Add, UpDown, vSetESMin Wrap Range0-59, 0

Gui, Font, s9 Normal
Gui, Add, CheckBox, x+15 yp-17 vsOp4 geOper, Termination
Gui, Font, s11 Bold
Gui, Add, Edit, xp y+2 h28 w48 Number vSetEEHour0
Gui, Add, UpDown, vSetEEHour Wrap Range0-23, 0
Gui, Font, s19
Gui, Add, Text, x+5 yp-7, :
Gui, Font, s11
Gui, Add, Edit, x+5 yp+7 h28 w48 Number vSetEEMin0
Gui, Add, UpDown, vSetEEMin Wrap Range0-59, 0

Gui, Font, s9 Normal
Gui, Add, CheckBox, x+20 yp-17 vsOp5 geOper, Repeat
Gui, Font, s11 Bold
Gui, Add, Edit, xp y+2 h28 w48 Number vSetRepeat
Gui, Font, s16 normal
Gui, Add, Text, x+2 yp-2, h
Gui, Font, s9 Normal
Gui, Add, Text, xs+5 y+3 w125 vNextStart cBLUE
Gui, Add, Text, x+3 yp w125 vNextEnd cRed
Gui, Add, Text, x+3 yp w75 vzsPID cBlack

GuiControl, Disable, sOp4
GuiControl, Disable, sOp5

;Gui, Font, s20 Normal
;Gui, Add, Text, x+40 yp-22 veScheInfo cBLUE, OFF

Gui, Font, s9 Normal
Gui, Add, GroupBox, x5 y+10 w340 h100 cBlack, Serverlist
Gui, Font, s8
Gui, Add, Edit, xs+5 yp+20 w329 h73 vSvrlist ReadOnly -Wrap
Gui, Add, Text, x5 y+18 vInfo w265 cRED Center
Gui, Add, Button, x+5 yp-5 w70 h30 gKillServer, Server shutdown
Gui, Add, Button, xp y+5 w70 h30 gStartServer, Starting the server
Gui, Add, Button, xp y+5 w70 h30 vBT_M gTG_Monitor, Start monitoring
Gui, Add, Edit, x5 yp-44 w265 h73 vSvrLog ReadOnly
Gui, Add, GroupBox, x5 y+10 w340 h48 cBlack, Update Server
Gui, Add, Button, xp+5 yp+18 w330 h24 vBT_U gTG_Update
Gui, Show, w350, A3 Monitor ⓒ 2013 by prologos

;ini read
IniRead, UpdatePath, SvrInfo.ini, UpdateInfo, UpdatePath
If (!UpdatePath OR UpdatePath = "ERROR")
{
	GuiControl,, BT_U, No value set in the configuration file
	GuiControl, -g, BT_U
}
else
{
	IfExist, %UpdatePath%
	{
		GuiControl,, BT_U, [ ON ] Update Available
		Update_Tg := True
	}
	else IfExist, %UpdatePath%_off
	{
		GuiControl,, BT_U, [ OFF ] Updates impossible
		Update_Tg := False
	}
	else
	{
		GuiControl,, BT_U, Update folder specified is incorrect
		GuiControl, -g, BT_U
	}
}

IniRead, ServerMax, SvrInfo.ini, SvrInfo, ServerMax
If (!ServerMax OR ServerMax = "ERROR")
	ServerMax := 0
IniRead, WinWaitSec, SvrInfo.ini, SvrInfo, WinWaitSec, 30
IniRead, Interval, SvrInfo.ini, SvrInfo, Interval, 60
Interval := Interval * 1000 ;secBy msBy.. By....

Svrlist := ""
Loop, % ServerMax + 1
{
    IDX := A_Index - 1
	IniRead, SvrPath%IDX%, SvrInfo.ini, SvrInfo, SvrPath%IDX%
	If (!SvrPath%IDX% OR SvrPath%IDX% = "ERROR")
		SvrPath%IDX% := ""
	Else
	{
		StringSplit, tmp, SvrPath%IDX%, `,
		Loop, 5 ;Server PathThe Except for removing the remaining variables are blank
		{
			If (A_Index > 1)
				StringReplace, tmp%A_Index%, tmp%A_Index%, %A_SPACE%,, All
		}
		SvrPath%IDX% := tmp1
		WinSize%IDX% := tmp2
		WinX%IDX% := tmp3
		WinY%IDX% := tmp4
		WinClick%IDX% := tmp5

		tmp := ""
		Loop, % 2 - StrLen(IDX)
			tmp .= "0"
		Svrlist .= "[" . tmp . IDX . "] " . SvrPath%IDX% . "`n"
        ;Remove the full path (SvrPath% IDX%) in the directory (SvrDir% IDX%) and filename (SvrName% IDX%)
		SplitPath, SvrPath%IDX%, SvrName%IDX%, SvrDir%IDX%
	}
}
StringReplace, Svrlist, Svrlist, [00], [eZS]
GuiControl,, Svrlist, % SubStr(Svrlist, 1, StrLen(Svrlist)-1)
Return

;Event Server
eOper:
    Gui, Submit, NoHide

    if (A_GuiControl = "sOp3")
    {
      if (sOp3 = 1)
      {
        ;Set start time
        FormatTime, _sDays, A_Now, yyyyMMdd
        SetESHour := "0" . SetESHour
        StringRight, _sHour, SetESHour, 2
        SetESMin := "0" . SetESMin
        StringRight, _sMin, SetESMin, 2
        FormatTime, _eStart, % _sDays . _sHour . _sMin, yyyyMMddHHmm

        GuiControl, Enable, sOp4
        GuiControl,, NextStart, % "Next start: " . Substr(_eStart, 5, 2) . "-" . Substr(_eStart, 7, 2) . " " . Substr(_eStart, 9, 2) . ":" . Substr(_eStart, 11, 2)

        GuiControl, +ReadOnly, SetESHour0
        GuiControl, +ReadOnly, SetESMin0
        GuiControl, Disable, SetESHour
        GuiControl, Disable, SetESMin

        ;ZS start timer start: check every minute
        SetTimer, EventZS_Start, 60000
      }
      else
      {
        GuiControl,, sOp4, 0
        GuiControl,, sOp5, 0
        GuiControl, Disable, sOp4
        GuiControl, Disable, sOp5

        ;Start Control wonbok
        GuiControl,, NextStart
        GuiControl, -ReadOnly, SetESHour0
        GuiControl, -ReadOnly, SetESMin0
        GuiControl, Enable, SetESHour
        GuiControl, Enable, SetESMin
        ;Timer off
        SetTimer, EventZS_Start, Off

        ;End control wonbok
        GuiControl,, NextEnd
        GuiControl, -ReadOnly, SetEEHour0
        GuiControl, -ReadOnly, SetEEMin0
        GuiControl, Enable, SetEEHour
        GuiControl, Enable, SetEEMin

        ;Repeat control wonbok
        GuiControl, -ReadOnly, SetRepeat
      }
    }
    else if (A_GuiControl = "sOp4")
    {
      if (sOp4 = 1)
      {
        ;Set End Time
        FormatTime, _eDays, A_Now, yyyyMMdd
        SetEEHour := "0" . SetEEHour
        StringRight, _eHour, SetEEHour, 2
        SetEEMin := "0" . SetEEMin
        StringRight, _eMin, SetEEMin, 2
        FormatTime, _eEnd, % _eDays . _eHour . _eMin, yyyyMMddHHmm
        
        ;If the end time is smaller than the start time is assumed to be the next day
        if (_eStart >= _eEnd)
        {
          EnvAdd, _eEnd, 24, hours
          FormatTime, _eEnd, %_eEnd%, yyyyMMddHHmm
        }

        GuiControl, Enable, sOp5
        GuiControl,, NextEnd, % "Following termination: " . Substr(_eEnd, 5, 2) . "-" . Substr(_eEnd, 7, 2) . " " . Substr(_eEnd, 9, 2) . ":" . Substr(_eEnd, 11, 2)

        GuiControl, +ReadOnly, SetEEHour0
        GuiControl, +ReadOnly, SetEEMin0
        GuiControl, Disable, SetEEHour
        GuiControl, Disable, SetEEMin

        ;ZS start timer start: check every minute
        SetTimer, EventZS_End, 60000
      }
      else
      {
        GuiControl,, sOp5, 0
        GuiControl, Disable, sOp5

        GuiControl,, NextEnd

        GuiControl, -ReadOnly, SetEEHour0
        GuiControl, -ReadOnly, SetEEMin0
        GuiControl, Enable, SetEEHour
        GuiControl, Enable, SetEEMin

        ;Timer off
        SetTimer, EventZS_End, Off
      }
    }
    else if (A_GuiControl = "sOp5")
    {
      if (sOp5 = 1)
      {
        GuiControl, +ReadOnly, SetRepeat
      }
      else
      {
        GuiControl, -ReadOnly, SetRepeat
      }
    }

Return
;Events ZS end
EventZS_End:
    Gui, Submit, NoHide

    FormatTime, CurrentTime, %A_Now%, yyyyMMddHHmm
    if (CurrentTime = _eEnd)
    {
      ;ZS exit code to put where
      RunWait, %ComSpec% /C TASKKILL /F /PID %_PID%,, Hide
      GuiControl,, zsPID

      if (sOp5 = 1)
      {
        ;Check calculation is repeated when the next start time
        EnvAdd, _eEnd, SetRepeat, hours
        FormatTime, _eEnd, %_eEnd%, yyyyMMddHHmm
        GuiControl,, NextEnd, % "Following termination: " . Substr(_eEnd, 5, 2) . "-" . Substr(_eEnd, 7, 2) . " " . Substr(_eEnd, 9, 2) . ":" . Substr(_eEnd, 11, 2)
      }
      else
      {
        GuiControl,, NextEnd
        ;Timer off
        SetTimer, EventZS_End, Off
      }
    }
Return

;Events ZS start
EventZS_Start:
    Gui, Submit, NoHide

    FormatTime, CurrentTime, %A_Now%, yyyyMMddHHmm
    if (CurrentTime = _eStart)
    {
      ;ePlace to put startup code ZS pid: zsPID
	  Run, "%SvrPath0%", %SvrDir0%, UseErrorLevel, _PID
      WinWait, ahk_pid %_PID%,, %WinWaitSec%
	  If ErrorLevel
	    Goto TimedOut
	  Sleep 200
      ;PID display of ZS for events
      GuiControl,, zsPID, %_PID%

      ;Check calculation is repeated when the next start time
      if (sOp5 = 1)
      {
        EnvAdd, _eStart, SetRepeat, hours
        FormatTime, _eStart, %_eStart%, yyyyMMddHHmm
        GuiControl,, NextStart, % "Next start: " . Substr(_eStart, 5, 2) . "-" . Substr(_eStart, 7, 2) . " " . Substr(_eStart, 9, 2) . ":" . Substr(_eStart, 11, 2)
      }
      else
      {
        GuiControl,, NextStart
        ;Timer off
        SetTimer, EventZS_Start, Off
      }
    }
Return


;Scheduled Tasks
Oper:
    Gui, Submit, NoHide

    if (A_GuiControl = "sOp1")
    {
      GuiControl,, sOp2, 0
      if (sOp1 = 1)
        GuiControl, Disable, sOp2
      else
        GuiControl, Enable, sOp2
    }
    else if (A_GuiControl = "sOp2")
    {
      GuiControl,, sOp1, 0
      if (sOp2 = 1)
        GuiControl, Disable, sOp1
      else
        GuiControl, Enable, sOp1
    }

    if (sOp1 = 1 or sOp2 = 1)
    {
      GuiControl,, ScheInfo, ON
      GuiControl, +ReadOnly, SetHour0
      GuiControl, +ReadOnly, SetMin0
      GuiControl, Disable, SetHour
      GuiControl, Disable, SetMin

      if (sOp1 = 1)
        SetTimer, ScheKill, 60000
      else if (sOp2 = 1)
        SetTimer, ScheRestart, 60000
    }
    else
    {
      GuiControl,, ScheInfo, OFF
      GuiControl, -ReadOnly, SetHour0
      GuiControl, -ReadOnly, SetMin0
      GuiControl, Enable, SetHour
      GuiControl, Enable, SetMin

      SetTimer, ScheKill, Off
      SetTimer, ScheRestart, Off
    }
    ;msgbox, %A_GuiControl% - %SetHour%:%SetMin% %sOp1% - %sOp2%
Return

;Schedule - server shutdown
ScheKill:
    Gui, Submit, NoHide
    if (SetHour = A_Hour and SetMin = A_Min)
    {
	  GuiControl,, sOp1, 0
      GuiControl,, sOp2, 0
      GuiControl, Enable, sOp1
      GuiControl, Enable, sOp2
      GoSub Oper
      ;If the monitoring status monitored Off
      if (Monitoring_Tg)
        GoSub TG_Monitor
      ;When making updates to the disable state
      if (Update_Tg)
      {
        GoSub TG_Update
        ;FileMove, %UpdatePath%vn.ini, %UpdatePath%vn_off.ini, 1
        ;GuiControl,, BT_U, [ OFF ] Updates impossible
        ;Update_Tg := Not Update_Tg
      }
      Step := "Schedule"
      Step := "KILL " . A_YYYY . "-" . A_MM . "-" . A_DD . " " . A_Hour . ":" . A_Min . ":" . A_Sec . " / Cause [" . Step . "]"
	  Err(Step)
      GoSub KillServer
    }
Return

;Schedule-server restart
ScheRestart:
    Gui, Submit, NoHide
    if (SetHour = A_Hour and SetMin = A_Min)
    {
      ;Update server is down
      if (Update_Tg)
      {
        GoSub TG_Update
      }

	  GuiControl,, sOp1, 0
      GuiControl,, sOp2, 0
      GuiControl, Enable, sOp1
      GuiControl, Enable, sOp2
      GoSub Oper
      Step := "Schedule"
      ;If the monitor off and turn on again after the operation status monitoring
      if (Monitoring_Tg)
      {
        GoSub TG_Monitor
        GoSub ServerRestart
        GoSub TG_Monitor
      }
      else
        GoSub ServerRestart

      ;Update server resume
      if (!Update_Tg)
      {
        GoSub TG_Update
      }
    }
Return

;Update Server Settings section
TG_Update:
	Update_Tg := Not Update_Tg
	if (Update_Tg)
	{
		FileMoveDir, %UpdatePath%_off, %UpdatePath%, R
		GuiControl,, BT_U, [ ON ] Update Available
	}
	else
	{
		FileMoveDir, %UpdatePath%, %UpdatePath%_off, R
		GuiControl,, BT_U, [ OFF ] Updates impossible
	}
Return

KillServer:
	;GuiControl,, Info, During server shutdown ...
	Loop, %ServerMax%
	{
		Num := ServerMax + 1 - A_Index
		SvrName := SvrName%Num%

		If (SvrName)
		{
			tmp := ""
			Loop, % 2 - StrLen(Num)
				tmp .= "0"
			GuiControl,, Info, [%tmp%%Num%] During server shutdown ...
			RunWait, %ComSpec% /C TASKKILL /F /IM %SvrName%,, Hide
		}
	}
	GuiControl,, Info, Complete server shutdown
Return

StartServer:
	GuiControl,, Info, Starting server ...
	;BlockInput, MouseMove

	Loop, %ServerMax%
	{
		Step := A_Index
		SvrPath := SvrPath%A_Index%
		SvrDir := SvrDir%A_Index%
		If (SvrPath)
		{
			Run, "%SvrPath%", %SvrDir%, UseErrorLevel, PID
			WinWait, ahk_pid %PID%,, %WinWaitSec%
			If ErrorLevel
				Goto TimedOut
			Sleep 200

			;Click this box if you need treatment, depending on the settings
			If (WinClick%A_Index%)
			{
				If (WinClick%A_Index% = 3) ;GM Shouts by ChrissDeGrece의 경우
				{
					CountWhile := 0
					While 1
					{
						ControlGetFocus, TBcheck, ahk_pid %PID%
						if (TBcheck = "ListBox1")
							ControlClick, Button4, ahk_pid %PID%,, LEFT, 1
						else if (TBcheck = "Button1")
							ControlClick, Button1, ahk_pid %PID%,, LEFT, 1
						else if (TBcheck = "Button4")
							Break

						CountWhile++
						If (CountWhile > 50)
							Goto TimedOut
					}
				}
				else if (WinClick%A_Index% = 2) ;GM Shouts by prologos의 경우
				{
					TBcheck := 1
					CountWhile := 0
					While (TBcheck)
					{
						ControlGet, TBcheck, Enabled,, Button4, ahk_pid %PID%
						ControlClick, Button4, ahk_pid %PID%,, LEFT, 2
						CountWhile++
						If (CountWhile > 50)
							Goto TimedOut
					}
				}
				else ;ODBC For a set
				{
					TBname1 := "TButton4"
					TBname2 := "TButton5"
					TBname3 := "TButton2"
					Loop, 3
					{
						TBname := TBname%A_Index%
						TBcheck := 1
						CountWhile := 0
						While (TBcheck)
						{
							ControlGet, TBcheck, Enabled,, %TBname%, ahk_pid %PID%
							ControlClick, %TBname%, ahk_pid %PID%,, LEFT, 2
							CountWhile++
							If (CountWhile > 50)
								Goto TimedOut
						}
					}
					While (!TBcheck) ;n the list box "[OK] Listening" message waiting for sunrise
					{
						ControlGet, TBcheck, List,, TColorListBox1, ahk_pid %PID%
					}
				}
			}

			;Depending on the setting minimize the window or to move to a specified location Sikkim
			If (!WinSize%A_Index%)
				WinMinimize, ahk_pid %PID%
			else
				WinMove, ahk_pid %PID%,, WinX%A_Index%, WinY%A_Index%

			Sleep 500 ;Putting one term after a while the server is running
		}
	}

	;BlockInput, MouseMoveOff
	GuiControl,, Info, Complete server startup
Return

TimedOut:
	;BlockInput, MouseMoveOff
	GuiControl,, Info, Server start error
	Loop, % 2 - StrLen(Step)
		Step := "0" . Step
	Step := "[" . Step . "] / " . A_YYYY . "-" . A_MM . "-" . A_DD . " " . A_Hour . ":" . A_Min . ":" . A_Sec
	Err("TIMEOUT " . Step)
Return


TG_Monitor:
	Monitoring_Tg := Not Monitoring_Tg
	MonitorInfo(Monitoring_Tg)

	If (Monitoring_Tg)
		SetTimer, Monitoring, %Interval%
	Else
		SetTimer, Monitoring, Off
Return

Monitoring:
	MonitorInfo(Monitoring_Tg)
	If (Monitoring_Tg)
	{
		Loop, %ServerMax%
		{
			SvrName := SvrName%A_Index%
			If (SvrName)
			{
				Step := A_Index
				Process, Exist, %SvrName%
				If (ErrorLevel = 0)
					Goto ServerRestart
			}
		}
	}
	Else
		SetTimer, Monitoring, Off
Return

ServerRestart:
	Loop, % 2 - StrLen(Step)
		Step := "0" . Step
	Step := "RESTART " . A_YYYY . "-" . A_MM . "-" . A_DD . " " . A_Hour . ":" . A_Min . ":" . A_Sec . " / Cause [" . Step . "]"
	Err(Step)

    ;Update server status reversal
    GoSub TG_Update

	;Server Restart
    GoSub KillServer
	GoSub StartServer

    ;Server status update wonbok
    GoSub TG_Update
Return

GuiClose:
GuiEscape:
ExitApp

Err(msg) {
	GuiControlGet, tmp,, SvrLog
	tmp := msg . "`n" . tmp
	GuiControl,, SvrLog, %tmp%
}

MonitorInfo(Toggle) {
	If (Toggle)
	{
		GuiControl,, Info, Of the monitoring ...
		GuiControl,, BT_M, End monitoring
	}
	else
	{
		GuiControl,, Info, Monitoring end
		GuiControl,, BT_M, Start monitoring
	}
}
 

Attachments

  • a.rar
    a.rar
    200.9 KB · Views: 127
Back