PokerStars SNG Table Opener

By _dave_ at 2+2 forums. The corresponding thread on 2+2 is here.

Currently broken due to Stars updates - Feel free to contribute fixes

This script is based on original work by Mark1978, including contributions from Roland and JukofYork. Many thanks to all of the AHK peoples in the 2p2 software forum.

This script automatically registers for a specified number of SNG tournaments at a specified buyin on PokerStars.com.

There may be errors, problems etc. with this script - Please let me know about them so I may fix them - I can't fix a problem I do not know about :)

I suggest the use of both BetPot script and StarsPlanner in addition to this script to assist in the ease of multi-tabling on PokerStars.com.

Enjoy!

dave.

Note: Updates for Stars periodic updates are being developed by Frozinite. For more information, PM Frozinite on 2+2.

P.S. Updates have restarted. An update coming soon, continue checking 2+2 for v0.03.

Screenshot

sngopeneryg1

Download Here

Stars_SNG_Opener-v0.01a.zip

Instructions

You will need to download the zip file attachment above, and extract it to a folder ("Right Click -> Extract All" for Windows XP).

You will also need to set up your PokerStars lobby so that the desired level of SNGs are visible while they are open for registration.

If you like, edit the script in notepad. There are a few global variables (settings) right at the start of the script - these may need changes if / when PokerStars re-compiles their software - namely the class_id for the table list control.

Version History

0.01

Code - Version 0.01

; PokerStars SNG opener, by _dave_at twoplustwo.com forums
; Original idea / hard work by Matt1978, contributions by Roland 

; Automatically opens specified number of SNGs (and kills the lobbies)
; Keeps them opening until you turn it off, either continuosly or in sets.
; Kills a few pop-up boxes also


lobby_class := "Afx:400000:28:10013:0:025"


#NoEnv
#SingleInstance, Force
SendMode Input
SetTitleMatchMode, 2
SysGet, border, 32
SysGet, caption, 4
CoordMode, Pixel, Screen
CoordMode, Mouse, Screen


;MsgBox, %border% %caption%

debug := 0
Reg_Title := "Tournament Registration"

lobby_id := ""
SetTimer, FindSuitable, 5000
SetTimer, FindSuitable, Off

Gui, Add, Checkbox, vOpenTables gOpenTables x10 y10 c, Table Opener ON
Gui, Add, DropDownList, vTourneyType gTourneyType x10 y30 w190
Gui, Add, ListBox, 8 vBuyin gBuyin x10 y60 w190 h80
Gui, Add, Text, x220 y15 , Number of Tables to Open
Gui, Add, Edit,  x380 y10 w50 r1 Limit3 Number
Gui, Add, UpDown, vhowmany Range1-48,4
Gui, Add, Text, x220 y15 , Number of Tables to Open
Gui, Add, Text, x220 y40 , Stagger Starting Time (Mins.)
Gui, Add, Edit,  x380 y35 w50 r1 Limit3 Number
Gui, Add, UpDown, vstagger Range0-10,0
Gui, Add, Checkbox, vContinuous gContinuous x220 y65, Continuous
Gui, Add, Checkbox, vSetPlay x330 y65, Play in Sets
GuiControl, Disable, SetPlay
Gui, Add, Text, vCurrentlyOpen x220 y90 w100, Currently Open: 0
Gui, Add, Text, vCurrentlyRegistered x330 y90 w100, Registered: 0
Gui, Add, Text, vSession x220 y110 w120, Session Total: 0

Gui, Show, x%gx% y%gy% h140 w440, Stars SNG Opener v0.01 ( by _dave_ )

FolderList := ""
BuyinList := ""
Loop, LobbyPics\Game_Types\*.*, , 1
{
  StringTrimLeft, tmp, A_LoopFileFullPath, InStr(A_LoopFileFullPath, "\")
  StringTrimLeft, tmp, tmp, InStr(tmp, "\")
  if (InStr(tmp, "\"))
  {
    StringTrimRight, tmp1, tmp, Strlen(tmp) - InStr(tmp, "\")+1
    ;StringTrimLeft, tmp, tmp, InStr(tmp, "\")
    StringTrimRight, tmp, tmp, Strlen(tmp) - InStr(tmp, "\", true, 0)+1
    
    FolderList := FolderList . tmp1 . "|"
    BuyinList := BuyinList . tmp . "|"
  }
  ;MsgBox %A_LoopField%
}
Sort, folderlist, D| U
Sort, buyinlist, D| U
;MsgBox, %folderlist%`n`n%BuyinList%
;StringReplace, folderlist, `n, |, All
GuiControl, , TourneyType, %folderlist%

registered_table_list := ""
tables_needed := 1
sessiontotal := 0
opened_one := 0
SetTimer, RefreshInterface, 2000

return

GUIClose:
  ExitApp
return

RefreshInterface:
NumTables()
return

OpenTables:
Gui, Submit, NoHide

if (!tourneytype || !buyin)
{
  GuiControl, , OpenTables, 0
  return
}

if (OpenTables)
{
  GuiControl, Disable, TourneyType
  GuiControl, Disable, Buyin
  GuiControl, Disable, howmany
  GuiControl, Disable, continuous
  GuiControl, Disable, setplay
  opened_one := 0
  SetTimer, FindSuitable, On
  
}
else
{
  SetTimer, FindSuitable, Off
  GuiControl, Enable, TourneyType
  GuiControl, Enable, Buyin
  GuiControl, Enable, howmany
  GuiControl, Enable, continuous
  GuiControl, Enable, setplay
}
return

Continuous:
Gui, Submit, NoHide
if (continuous)
{
  GuiControl, Enable, SetPlay,
}
else
{
  GuiControl, , SetPlay, 0
  GuiControl, Disable, SetPlay,
}
return

TourneyType:
Gui, Submit, NoHide
bl := ""
;GuiControl, , Buyin, %bl%
Loop, Parse, buyinlist, |
{
  if (InStr(A_LoopField, TourneyType))
  {
    StringTrimLeft, tmp, A_LoopField, InStr(A_LoopField, "\")
    bl := bl . tmp . "|"
  }
}
Sort, bl, D| N
GuiControl, , Buyin, |%bl%

return

Buyin:
Gui, Submit, NoHide
return

debug_gui(id, x1, y1, x2, y2, delay=500)
{
  Gui, 2: +Alwaysontop +Lastfound +Owner
  Gui, 2: Color, ff0000
  WinSet, Transparent, 200
  Gui, 2: -Caption
  w1 := x2 - x1
  h1 := y2 - y1
  Gui, 2: Show, w%w1% h%h1% x%x1% y%y1% NoActivate
  Sleep, %delay%
  Gui,2: Destroy
}


NumTables()
{
  global registered_table_list
  global currentlyopen
  global currentlyregistered
  global sessiontotal
  
  open_table_list := ""
  WinGet, ps_pid, pid, PokerStars Lobby
  WinGet, list, list, ahk_pid%ps_pid% $ Tournament, ,Lobby
  Loop, %list%
  {
    id := list%A_Index%
    WinGetTitle, title, ahk_id%id%
    StringTrimLeft, title, title, 11
    StringTrimRight, title, title, StrLen(title) - InStr(title, A_Space) +1
    ;Msgbox, %title%
    ;registered_table_list := RemoveFromList(registered_table_list,title)
    StringReplace, registered_table_list, registered_table_list, %title%, ,All
    registered_table_list := CleanList(registered_table_list)
    
    tourney_lobby_id := ""
    tourney_lobby_title := "Tournament " . title . " Lobby"
    WinGet, tourney_lobby_id, id, %tourney_lobby_title%
    if (tourney_lobby_id)
    {
      WinClose, ahk_id%tourney_lobby_id%
    }
  }
  ot := 0
  Loop, Parse, registered_table_list, `,
  {
    ot := A_Index
  }
  GuiControl, , currentlyopen, Currently Open: %list%
  GuiControl, , currentlyregistered, Registered: %ot%
  GuiControl, , session, Session Total: %sessiontotal%
  ot := ot + list
  return %ot% 
}

FindSuitable:
  Gui, Submit, NoHide
  WinGet, lobby_id, id, PokerStars Lobby

  hm := NumTables()
  ;Msgbox, %howmany%`n`n%hm%
  ;------------------------
  ;return
  ;------------------------
  if (setplay)
  {
    if (hm = 0 && continuous)
    {
      tables_needed := 1
      opened_one := 0
    }
    else if (!opened_one)
    {
      tables_needed := 1
    }
    else if ( hm >= howmany)
    {
      tables_needed := 0
    }
  }
  else
  {
    if (hm < howmany && continuous)
    {
      tables_needed := 1
    }
    else if ( hm >= howmany)
    {
      tables_needed := 0
    }
  }
  
  if (hm = 0 && opened_one )
  {
    GuiControl, , OpenTables, 0
    GoSub OpenTables
    return
  }
  
  if (tables_needed)
  {
    SetTimer, FindSuitable, Off
    Loop, Parse, buyin, |
    {
      reg_id := open_tourney(A_LoopField)
      if (reg_id)
      {
        registered_table_list := AddToList(registered_table_list,reg_id)
        sessiontotal := sessiontotal + 1
        opened_one := 1
        ot := 0
        Loop, Parse, registered_table_list, `,
        {
          ot := A_Index
        }
        GuiControl, , currentlyregistered, Registered: %ot%
        if (stagger >= 1)
        {
          delaytime := stagger * 1000 * 60
          Sleep, %delaytime%
        }
    break
      }
    }
    if (opentables)
    {
      SetTimer, FindSuitable, On
    }
  }
  GuiControl, , session, Session Total: %sessiontotal%
return


open_tourney(buyin)
{
  global debug
  global lobby_id
  global reg_title
  global lobby_class
  global tourneytype
  global border
  global caption
  
  CoordMode, Pixel, Screen
  WinGetPos, x, y, w, h, ahk_id%lobby_id%
  x2 := x + w - border - 420
  y2 := y + h - border - 120
  x1 := x + border + 65
  y1 := y2 - 221 
  ;Msgbox, %x% %y% %w% %h%
  
  x1a := x1
  y1a := y1
  x2a := x2
  y2a := y1 + 13
  
  Loop, 17
  {
  
    WinActivate, ahk_id%lobby_id%
    if (debug)
    {
      debug_gui(lobby_id, x1a, y1a, x2a, y2a, 500)
    }
    folder := "LobbyPics\Game_Types\" . TourneyType . "\" . Buyin . "\"
    
    
    Loop, 3
    {
      x3 := 0
      y3 := 0
      picfile := folder . A_Index . ".bmp"
      ;Msgbox, %picfile%
      WinActivate, ahk_id%lobby_id%
      ImageSearch, x3, y3, x1a, y1a, x2a, y2a, %picfile%
      if (debug)
      {
        TrayTip, SNG Opener, %ErrorLevel% ,10,17
      }
      if (!ErrorLevel)
      {
        x3 := x3 - x
        y3 := y3 - y
        
        x3 := x3 - border
        y3 := y3 - (border + caption) + 5
        ;y3 := y3
        ;x3 := x3 - 12
        y3 := y3 - 210
        if (debug)
        {
          TrayTip, SNG Opener, %x3% %y3% ,10,17
        }
        PostLeftClick(x3, y3, lobby_id, 1, lobby_class)
        Sleep, 100
        id_num := DigitSearch((x1a-50),y1a,x1a,y2a,lobby_id,"LobbyPics\numbers","",1) 
        if (StrLen(id_num) != 8)
        {
          return 0
        }
        
        if (debug)
        {
          TrayTip, SNG Opener, %id_num%
        }
        Sleep, 200
        x4 := x + w - 180
        y4 := y + h - 80
        x5 := x4 + 120
        y5 := y4 + 80
        if (debug)
        {
          debug_gui(lobby_id, x4, y4, x5, y5, 500)
        }
        
        
        registerpic := "LobbyPics\register.bmp"
        ImageSearch, , , x4, y4, x5, y5, *70 %registerpic% 
                if (!ErrorLevel)
        {       
          PostLeftClick(680, 500, lobby_id)
          WinWait, %Reg_Title%
          WinGet, reg_id, id
          
          buyin_check := "$" . buyin . " Total."
          ControlGetText, buyin_test, Button1, ahk_id%reg_id%
          if(buyin_test == buyin_check)
          {
                loop, 50
                {
                        ControlGet, c, Checked, , Button1, ahk_id%reg_id%
                        if(!c)
                        {
                                ControlFocus, Button1, ahk_id%reg_id%
                ControlClick, Button1, ahk_id%reg_id%
                                sleep, 200
                        }
                        else
                        {
                                break
                        }
                }
          
                loop, 50
                {
                        ControlGet, v, Visible, , Button4, ahk_id%reg_id%
                        if(v)
                        {
                                ControlFocus, Button4, ahk_id%reg_id%
                ControlClick, Button4, ahk_id%reg_id%
                                sleep, 200
                        }
          
                }
          
                WinWait, PokerStars, Regist
                WinGet, reg_confirmed, id
            WinGetText, t, ahk_id%reg_confirmed%
          
                loop, 50
                {
                        
                        ControlGet, v, Visible, , Button1, ahk_id%reg_confirmed%
                        if(v)
                        {
                                ControlFocus, Button1, ahk_id%reg_confirmed%
                ControlClick, Button1, ahk_id%reg_confirmed%
                                sleep, 200
                        }
          
                }
                        
                if(InStr(t, "Registered"))
                {
                        ; Registration success
                        return %id_num%
                }
                else
                {
                        ; Registration failure
                        return 0
                }
          
          }
          else
          {
                ; buyin check failed
            ControlFocus, Button5, ahk_id%reg_id%
            ControlClick, Button5, ahk_id%reg_id% ; Click cancel
            return 0
          }

          ;WinWaitClose, ahk_id%reg_id%
        }
        else
        {
          if (debug)
          {
            TrayTip, SNG Opener, Register Pic not found
          }
        }
        break
      }
    }
  y1a := y1a + 13
  y2a := y2a + 13
  
  }
  return 0
}


;---------------------------------------------------------------------------
;
; Below Code from RolandsFunctions.ahk (overcards.com)
;
; Slightly modified
;
;---------------------------------------------------------------------------



;Juks rocks
PostLeftClick(x, y, table_id, activate=1, control_class="") {
; ### JUK: Send the down left click, then the mouse-up messages.
; NOTE: This is relative to the top left of the client area and NOT the top left of the
;       window (ie: It *doesn't* include the title-bar like AHK's MouseClick does!!!).
If activate
 WinActivate, ahk_id%table_id%
PostMessage, 0x201, 0x0001, ((y<<16)^x), %control_class%, ahk_id%table_id%
PostMessage, 0x202 , 0, ((y<<16)^x), %control_class%, ahk_id%table_id%
}




DigitSearch(startX,startY,endX,endY,win,dir,ex="",shades=1) {

global debug

If ex =
 ex = bmp
batchlines = %A_BatchLines%
SetBatchLines -1
;WinGetPos,Xwin,Ywin,,,ahk_id%win%
;WinGetPos,Xwin,Ywin,w,h,ahk_id%win%

;Msgbox, %startX%,%startY%`n%endX% %endY%


CoordMode, Pixel, Screen
Loop, 11 {
  i = %a_index%
  If i = 10
    i = 0
  else if i = 11
    i = -1
  lastXpos := startX
  Loop {
    x1 := lastXpos + 1
    y1 := startY
    x2 :=  endX
    y2 := endY
    
    if (debug)
    {
      debug_gui(id, x1, y1, x2, y2, 50)
    }
    
    ImageSearch, lastXpos,, x1, y1, x2, y2, *%shades% %dir%\%i%.%ex%
    
    
    If ( errorLevel )
    {
      break
    }
    p++
    p%p% = %lastXpos%
    If i = -1
      t = .
    else
      t = %i%
    StringReplace, xpos, lastXpos, -, _
    c%xpos% = %t%
   }
 }

Loop, %p%
 p_all := p_all "," p%a_index%

Sort, p_all, N D, U
;Msgbox %p_all%
Loop, Parse, p_all, `,
{
 StringReplace, xpos, a_loopfield, -, _
    
 amount := amount "" c%xpos%
 ;Msgbox,%amount%
} 
;CoordMode, Pixel, Relative
SetBatchLines %batchlines%
return amount
}

;###########################################
;################# Lists ####################
;###########################################

;adds said item to the end of said list
AddToList(list,item,del=""){
del := IIf(del="",",",del)
If list =
 return item
return list . del . item
}

;return item at said position in said list
ExFromList(list,pos=1,del="") {
del := IIf(del,del,",")
StringSplit, item, list, %del%
return item%pos%
}

;removes said item from said list
RemoveFromList(list,item=1,del="") {
del := IIf(del,del,",")
;Msgbox, %list%
If InStr(list, item . del)
 return StrRep(list, item . del, "", 0)
else if InStr(list, del . item, "", 0)
 return StrRep(list, del . item, "", 0)
else if (item = list)
 return
else
 return list
}

;removes the nth item from said list
RemoveItemNFromList(list,n,del="") {
del := IIf(del,del,",")
return RemoveFromList(list, ExFromList(list,n,del))
}

;returns the position of said item in said list
;(0 if not in list)
GetItemPos(list,item,del="") {
del := IIf(del,del,",")
StringSplit, array, list, %del%
Loop %array0% {
        If array%a_index% = %item%
                return a_index
 }
return 0
}

;inserts said item at said position in said list
InsertItem(list,item,pos,del="") {
del := IIf(del="",",",del)
StringSplit,array,list,%del%
Loop % IIf( ( pos < array0 ), array0, pos ) {
        thisItem := array%a_index%
        If ( a_index != pos )
                newList = %newList%%del%%thisItem%
        else
                newList = %newList%%del%%item%%del%%thisItem%
 }
If ( InStr(newList, ",",0,0) = StrLen(newList) )
 StringTrimRight, newList, newList, 1
StringTrimLeft, newList, newList, 1
return newList
}

;removes empty items (and trailing delimiters)
CleanList(list, del="") {
If del =
 del = `,
Loop {
  StringReplace, list, list, %del%%del%, %del%, UseErrorLevel
  If ! ErrorLevel
   break
 }
If InStr(list, del) = 1
 StringTrimLeft, list, list, 1
If InStr(list, del,0,0) = StrLen(list)
 StringTrimRight, list, list, 1
return list
}

List_longest(list, del="") {
del := IIf( del="", ",", del)
longest = 0
Loop, Parse, list, %del%
 {
        If (longest < StrLen(a_loopfield))
                longest := StrLen(a_loopfield)
 }
return longest
}


IIf(_boolExpr, _exprTrue, _exprFalse) {
If _boolExpr
 Return _exprTrue
else
 return _exprFalse
}

StrRep(str,char,rep_char="",all=1) {
StringReplace,str,str,%char%,%rep_char%,%all%
return str
}

CategoryAutoHotKey

StarsSNGOpener (last edited 2008-05-06 18:47:18 by MogobuTheFool)