Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

A3 Server Monitor

Newbie Spellweaver
Joined
Jan 26, 2012
Messages
75
Reaction score
73
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=
 

Attachments

You must be registered for see attachments list
Junior Spellweaver
Joined
Nov 16, 2012
Messages
101
Reaction score
21
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

You must be registered for see attachments list
Back
Top