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
Download Here
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
Initial Release.
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
}
