관리 메뉴

ㄴrㅎnㅂrㄹrㄱi

Ace of Spades Server Selector (Updated for BuildAndShoot) 본문

분류없음

Ace of Spades Server Selector (Updated for BuildAndShoot)

님투 2013.01.15 17:21

http://www.autohotkey.com/board/topic/72356-ace-of-spades-server-selector-updated-for-buildandshoot/





#NoEnv

;check for portable versions
If FileExist(A_ScriptDir . "\AoS\client.exe")
    Path := """%A_ScriptDir%\AoS\client.exe"" ""%Server%"""
Else If FileExist(A_ScriptDir . "\AceOfSpades\client.exe")
    Path := """%A_ScriptDir%\AceOfSpades\client.exe"" ""%Server%"""
Else If FileExist(A_ScriptDir . "\Ace of Spades\client.exe")
    Path := """%A_ScriptDir%\Ace of Spades\client.exe"" ""%Server%"""
Else If FileExist(A_ScriptDir . "\client.exe")
    Path := """%A_ScriptDir%\client.exe"" ""%Server%"""
Else
    Path := "%Server%"

ConnectAddress := "127.0.0.1"
SortColumns := [0,0,0,0,0]

Gui, Font, s16 Bold, Arial
Gui, Add, Text, x10 y0 w780 h30 vTitle Center, Server List
Gui, Font, s8 Norm
Gui, Add, ListView, x10 y30 w780 h580 vServerList gListViewEvent, Name|Map|Mode|Players|Capacity|Ping|Address
Gui, Font, Bold
Gui, Add, Text, x10 y620 w80 h20 vServerCount
Gui, Add, Button, x620 y620 w80 h20 vIPAddress gIPAddress, &IP Address
Gui, Add, Button, x710 y620 w80 h20 vRefreshList gRefreshList Default, &Refresh
Gui, +Resize +MinSize270x150

Gosub, RefreshList

Gui, Show, Center w800 h650
Return

GuiEscape:
GuiClose:
ExitApp

GuiSize:
GuiControl, Move, Title, % "w" . (A_GuiWidth - 20)
GuiControl, Move, ServerList, % "w" . (A_GuiWidth - 20) . " h" . (A_GuiHeight - 70)
GuiControl, Move, ServerCount, % "y" . (A_GuiHeight - 30)
GuiControl, Move, IPAddress, % "x" . (A_GuiWidth - 180) . " y" . (A_GuiHeight - 30)
GuiControl, Move, RefreshList, % "x" . (A_GuiWidth - 90) . " y" . (A_GuiHeight - 30)
WinSet, Redraw
Return

IPAddress:
Gui, +OwnDialogs
Loop
{
    InputBox, Value, Connect to IP address, Enter the server IP address:,, 200, 120,,,,, 127.0.0.1
    If ErrorLevel
        Return
    If RegExMatch(Value,"S)^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})(:\d+)?$",Address)
        Break
}
ConnectAddress := Value
Server := "aos://" . (Address1 | (Address2 << 8) | (Address3 << 16) | (Address4 << 24)) . Address5
Gui, Hide
JoinServer(Server,Path,"IP Address " . ConnectAddress)
Gui, Show
Return

ListViewEvent:
If (A_GuiEvent = "ColClick")
    Gosub, SortColumns
If (A_GuiEvent != "DoubleClick")
    Return
Gosub, SelectServer
Return

SelectServer:
Row := LV_GetNext()
LV_GetText(Server,Row,7) ;retrieve the server address from the fifth column of the selected row
LV_GetText(Name,Row,1) ;retrieve the server name from the first column of the selected row
LV_GetText(Map,Row,2) ;retrieve the map from the second column of the selected row
Gui, Hide
JoinServer(Server,Path,Name . " (" . Map . ")")
Gui, Show
Return

UpdatePing:
LV_GetText(Server,CurrentIndex,7) ;retrieve the server address from the fifth column of the selected row
RegExMatch(Server,"iS)aos://\K\d+",Address)
try Ping := RoundTripTime(Address)
catch
{
    CurrentIndex ++
    If (CurrentIndex <= LV_GetCount())
        SetTimer, UpdatePing, -0
    Return
}
LV_Modify(CurrentIndex,"Col6",Ping)
CurrentIndex ++
If (CurrentIndex <= LV_GetCount())
    SetTimer, UpdatePing, -0
Return

SortColumns:
If SortColumns[A_EventInfo]
    SortColumns[A_EventInfo] := (SortColumns[A_EventInfo] & 1) + 1 ;toggle sorting types between ascending and descending
Else
    SortColumns[A_EventInfo] := (A_EventInfo = 4 || A_EventInfo = 5) ? 2 : 1 ;enable sorting for the column

For Index In SortColumns ;disable sorting on all other columns
{
    If (Index != A_EventInfo)
        SortColumns[Index] := 0
}
Return

RefreshList:
GuiControl, -Redraw, ServerList ;prevent redrawing of the ListView
LV_Delete() ;remove all listview entries

try ;request the server selection page
{
    WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1") ;create
    WebRequest.Open("GET","http://buildandshoot.com/") ;open request
    WebRequest.Send() ;send request
    ServerPage := WebRequest.ResponseText ;retrieve response
    WebRequest := "" ;free request

    ;ensure the page was downloaded correctly
    If !RegExMatch(ServerPage,"S)<th>Players</th>")
        throw

    ;retrieve the server list
    ServerPage := SubStr(ServerPage,InStr(ServerPage,"<tbody>") + 7) ;remove everything before the server list
    ServerPage := SubStr(ServerPage,1,InStr(ServerPage,"</tbody>") - 1) ;remove everything after the server list

    ;populate the ListView
    FoundPos := 1, FoundPos1 := 1
    While, FoundPos := RegExMatch(ServerPage,"iS)<tr[^>]*>[^<]*<td[^>]*>\s*(?P<Players>\d+)\s*</td>"
                                                       . "[^<]*<td[^>]*>\s*(?P<Capacity>\d+)\s*</td>"
                                                       . "[^<]*<td[^>]*>\s*<a\s+href=""(?P<Address>[^""]*)""[^>]*>(?P<Name>[^<]*)</a>\s*</td>"
                                                       . "[^<]*<td[^>]*>(?P<Mode>[^<]*)</td>"
                                                       . "[^<]*<td[^>]*>(?P<Map>[^<]*)</td>"
                                                       ,Server,FoundPos)
    {
        LV_Add("",ServerName,ServerMap,ServerMode,ServerPlayers,ServerCapacity,"?",ServerAddress)
        FoundPos += StrLen(Server), FoundPos1 := FoundPos
    }
    If FoundPos = 1 ;no matches found
        throw
}
catch Error
try ;request the pyspades server list
{
    WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1") ;create
    WebRequest.Open("GET","http://aos.mp2.dk/") ;open request
    WebRequest.Send() ;send request
    ServerPage := WebRequest.ResponseText ;retrieve response
    WebRequest := "" ;free request

    ;ensure the page was downloaded correctly
    If !RegExMatch(ServerPage,"S)<title>[^<]*Ace of Spades[^<]*</title>")
        throw

    ;retrieve the server list
    ServerPage := SubStr(ServerPage,InStr(ServerPage,"</tr>") + 6)
    ServerPage := SubStr(ServerPage,1,InStr(ServerPage,"</tbody>") - 1)

    ;populate the ListView
    FoundPos := 1, FoundPos1 := 1
    While, FoundPos := RegExMatch(ServerPage,"iS)<tr[^>]*>[^<]*<td[^>]*>[^<]*</td>"
                                         . "[^<]*<td[^>]*>\s*(?P<Players>\d+)\s*/\s*(?P<Capacity>\d+)\s*</td>"
                                         . "[^<]*<td[^>]*>[^<]*</td>"
                                         . "[^<]*<td[^>]*>(?P<Mode>[^<]*)</td>"
                                         . "[^<]*<td[^>]*>(?P<Map>[^<]*)</td>"
                                         . "[^<]*<td[^>]*>\s*<a\s+href=""(?P<Address>[^""]*)""[^>]*>(?P<Name>[^<]*)</a>\s*</td>"
                                         ,Server,FoundPos)
    {
        LV_Add("",ServerName,ServerMap,ServerMode,ServerPlayers,ServerCapacity,"?",ServerAddress)
        FoundPos += StrLen(Server), FoundPos1 := FoundPos
    }
    If FoundPos = 1 ;no matches found
        throw
}
catch Error ;could not retrieve server list
{
    WebRequest := "" ;free request
    If (Error.Extra = "Send")
        MsgBox, 16, Error, Could not request server list.
    Else If (Error.Extra = "ResponseText")
        MsgBox, 16, Error, Could not retrieve server list.
    Else
        MsgBox, 16, Error, Could not obtain server list.
    ServerPage := ""
}

;adjust column widths to suit their headers and contents
LV_ModifyCol(1,"AutoHdr") ;server name
LV_ModifyCol(2,"AutoHdr") ;map
LV_ModifyCol(3,"AutoHdr") ;game mode
LV_ModifyCol(4,"AutoHdr Integer Desc") ;players
LV_ModifyCol(5,"AutoHdr Integer Desc") ;capacity
LV_ModifyCol(6,"AutoHdr Integer") ;ping
LV_ModifyCol(7,"AutoHdr") ;server

For Index, Value In SortColumns
{
    If Value
    {
        LV_ModifyCol(Index,"Sort" . ((Value = 1) ? "" : "Desc"))
        Break
    }
}

GuiControl, +Redraw, ServerList ;allow the ListView to be redrawn

GuiControl,, ServerCount, % LV_GetCount() . " servers." ;update the server count
Gui, Show,, Ace of Spades Servers

CurrentIndex := 1
SetTimer, UpdatePing, -0
Return

JoinServer(Server,Path,Name)
{
    global AutoJoin
    AutoJoin := False
    Transform, Path, Deref, %Path%
    SetTitleMatchMode, RegEx
    Loop
    {
        ;open Ace of Spades
        Run, %Path%,, UseErrorLevel
        If ErrorLevel
        {
            MsgBox, 16, Error, Could not open Ace of Spades with command line "%Path%".
            Return, 1
        }
        WinWait, Ace of Spades|ERROR ahk_class Ace of Spades|#32770,, 5

        ;check for connection errors
        WinGetClass, WindowClass
        If (WindowClass != "Ace of Spades") ;error dialogue
        {
            WinClose
            If !AutoJoin
            {
                MsgBox, 22, Error, Could not connect to "%Name%": server is full or misconfigured.`n`nSelect "Try Again" to retry the connection`, or "Continue" to automaticially join.
                IfMsgBox, Cancel
                {
                    Gosub, StopAutoJoin
                    Break
                }
                IfMsgBox, Continue
                {
                    AutoJoin := True
                    ToolTip, Press Esc to stop automatic retrying.
                    Hotkey, Esc, StopAutoJoin, On
                }
            }
        }
        Else
        {
            If ErrorLevel ;window wait operation timed out
                Return, 1
            WinSetTitle, Ace of Spades ahk_class Ace of Spades,, Ace of Spades - %Name%
            WinWait, ERROR ahk_class #32770,, 3 ;handle the error dialog possibly showing up
            If !ErrorLevel ;server full error
            {
                WinClose ;close error dialog
                WinWaitClose, Ace of Spades ahk_class Ace of Spades
                If !AutoJoin
                {
                    MsgBox, 22, Error, Could not connect to "%Name%": server is full or misconfigured.`n`nSelect "Try Again" to retry the connection`, or "Continue" to automaticially join.
                    IfMsgBox, Cancel
                    {
                        Gosub, StopAutoJoin
                        Break
                    }
                    IfMsgBox, Continue
                    {
                        AutoJoin := True
                        ToolTip, Press Esc to stop automatic retrying.
                        Hotkey, Esc, StopAutoJoin, On
                    }
                }
            }
            Else
            {
                Gosub, StopAutoJoin
                WinWaitClose, Ace of Spades ahk_class Ace of Spades
                Break
            }
        }
    }
    Return, 0

    StopAutoJoin:
    AutoJoin := False
    ToolTip
    Hotkey, Esc, StopAutoJoin, Off
    Return
}

RoundTripTime(Address,Timeout = 1000)
{
    If DllCall("LoadLibrary","Str","icmp","UPtr") = 0 ;NULL
        throw Exception("Could not load ICMP library.")

    hPort := DllCall("icmp\IcmpCreateFile","UPtr") ;open port
    If hPort = -1 ;INVALID_HANDLE_VALUE
        throw Exception("Could not open port.")

    Length := 278 ;ICMP_ECHO_REPLY structure
    VarSetCapacity(Reply,Length)
    Count := DllCall("icmp\IcmpSendEcho","UPtr",hPort,"UInt",Address,"Str","","UShort",0,"UPtr",0,"UPtr",&Reply,"UInt",Length,"UInt",Timeout)
    If NumGet(Reply,4,"UInt") = 11001 ;IP_BUF_TOO_SMALL
    {
        Length := 278 ;ICMP_ECHO_REPLY structure
        VarSetCapacity(Reply,Length * Count)
        DllCall("icmp\IcmpSendEcho","UPtr",hPort,"UInt",Address,"Str","","UShort",0,"UPtr",0,"UPtr",&Reply,"UInt",Length * Count,"UInt",Timeout)
    }
    If NumGet(Reply,4,"UInt") != 0 ;IP_SUCCESS
        throw Exception("Could not send echo.")
    If !DllCall("icmp\IcmpCloseHandle","UInt",hPort) ;close port
        throw Exception("Could not close port.")
    Return, NumGet(Reply,8,"UInt")
}

#If ListViewFocused()

ListViewFocused()
{
    GuiControlGet, CurrentFocus, FocusV
    Return, CurrentFocus = "ServerList" && LV_GetNext()
}

Enter::Gosub, SelectServer
 

#If


0 Comments
댓글쓰기 폼