TableNavigator | TableNavigatorSourceCode | TableNavChangeLog | TableNavToDoList | TableNavigatorStudio
About
This is a step-by-step guide to adding support for a new site to TableNavigator. You should be able to do this even if you don't know anything about programming or AHK whatsoever, provided you have a few hours to spare.
Step-by-Step
Table list & basic fold, call, raise... functions
If you have never written anything in AHK before, take a look at the Quick-Start Tutorial here. Read through it, but don't worry if it all means nothing to you - I'll take you through this step by step.
Next, you'll need an editor. You could use Notepad, which comes with Windows, but it's pretty, well, basic. I use Notepad2, but there are tons of different editors around. Find one you feel comfortable with.
The only other tool you'll need is Window Spy, which comes with AHK. Run any AHK script and select 'Window Spy' from the tray menu to take a look. You'll be using it to figure out the locations of buttons: Just hover over, say, the 'fold' button while the table is active, then use Shift-Alt-Tab to freeze the display so you can copy the coords.
Find the file called 'SomeCasino.ahk' in the TableNavigator folder. And copy it into the folder called 'Casinos'. Then rename it to the name of your site, say 'Prima'. Now open the file in your editor. As you can see, it's just a bunch of empty functions (don't worry if you don't know what a function is. There's some help on functions here, but for now you don't really need to know). Now, use the Replace function of your editor to replace the string '´SomeCasino' with - in our example - 'Prima'. Good. Now what we're gonna do is fill up all those functions.
Open the file for Betfair (in a second editor window). Basically, there are two types of casinos: Sites like Party and FullTilt which use buttons AHK can 'see', and sites like Stars, Absolute and Betfair, where AHK can't see the buttons. Now, if we're not able to tell AHK which button to click (because AHK can't see it...), we need to tell it where to click instead. For now, I'm only going to explain how to use this technique; I think it's the one you'll have to use for most of the smaller sites, and it's easier. Besides, this 'positional' approach also works for sites where AHK can see the buttons - although it might be a little less flexible in some cases. Anyways, we'll use the Betfair plug-in as an example here, since it's pretty typical.
Have a look at the first function, 'lobbyBetfair()':
lobbyBetfair() { SetTitleMatchMode 3 WinGet, id, id, Betfair Poker - Lobby If ( ! id ) WinGet, id, id, Classic Poker - Lobby return id }(Ignore the 'If ( ! id )..' part - just pretent those two lines aren't there). The point of this function is to get hold of the unique id of the lobby. (The id is just a number by which we can refer to a window). The first command is 'SetTitleMatchMode 1'. Please take a look here for an explanation of SetTitleMatchMode. The point is that, somehow, you have to find a way to identify the lobby out of all windows on you system - this can be tricky! Have a look at the WinGet command... you might have to specify the ahk_class of the lobby or exlude certain titles in order to id the lobby.
Once you're done writing this function, you should test it to see if it works (it probably won't - it's pretty darn rare for code to work right away, let me tell you
). What I do is to create a AHK script on my desktop called 'Test.ahk' or something. Whenever I have to test some code I just drag-and-drop the 'Test' script into a empty editor window and copy&paste whatever it is I want to test. So now you have to verify that your function actually returns the id of the lobby. Here's one way to do it: id := lobbyPrima() WinMinimize, ahk_id%id%
If you're function works, the lobby should get minimized! If it doesn't, back to the drawing board...
Okay, hopefully you're lobby function is working now. Congrats. Now take a look at the second function, 'tablesBetfair(lobby)'. Can you guess what it does? That's right - it returns a (comma-seperated) list of the ids of all the Betfair tables it can find. Note that it takes a parameter, called lobby. As you can probably guess, this is the id of the lobby. The first line specifies the TitleMatchMode again. The next line, 'WinGet, pid, PID, ahk_id%lobby%', retrieves the PID (process ID) of the lobby. The PID uniquely identifies the process the lobby belongs too, which is the reason we needed the id of the lobby in the first place: Once we know the process of the lobby, we also know the process of the tables. (The only exception I've come accross so far is Absolute, but then nothing is normal at Absolute
). So, in the next line, 'WinGet, list, list, - logged in as ahk_pid%pid%', we use the both the PID and a part of the title of a Betfair window to get us a list of all the Betfair tables. Note that in this case you definitely need both of these criteria: Using only the PID would include stuff like message-boxes and the lobby itsself; using only the sub-string '- logged in as' would include, for instance, PokerStars tables! I'm not going to explain the rest of the function. You'll only have to get the first part right, the rest will work on it's own. Whether you're function works is easy to verify: Open a few tables. Start TableNavigator, and open the Preferences Gui. Your site should now show up in the casinos drop-down list. Add it to the list and click Submit - TableNavigator should now recognise the tables.
Good, that's that. We'll ignore the next funtion (gameTypeBetfair) for now as it's not needed for basic support, and move on to 'FoldBetfair(id)'.
FoldBetfair(id) { PostLeftClick(470, 537, id) PostLeftClick(470, 570, id) }Every time you hit your fold hotkey on a Betfair table, TableNavigator calls this function, passing it the unique id of the table. As you can see, the function calls another function called 'PostLeftClick()'. Here it is:
;Juks rocks PostLeftClick(x, y, table_id, activate=1) { ; ### 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), , ahk_id%table_id% PostMessage, 0x202 , 0, ((y<<16)^x), , ahk_id%table_id% }Juk wrote this this quite a while ago, and it works perfectly. Basically, it simulates a mouse click without moving the cursor. The important thing for you is that the x and y coordinates are relative to the top left od the client are of the window. So when you find the position of the fold button with WindowSpy, you have to subtract the height of the titlebar of the table (usually 30 pixels) from the y coord, and the width of the border or frame of the window (usually 3 pixels) from the x coord.
As you can see, the fold function sends two 'clicks', one at x470 y537 and one at x470 y570. The reason is that we have no way of knowing whether we have to click the 'Fold In Turn' or the normal fold button, so we just click in both locations. If you look at the functions for 'call' and 'raise', you'll notice that they only click in one location: This is because on Betfair tables, the preselect and normal buttons overlap. If this isn't the case for your site, just click in two locations as demonstrated by the 'fold' function.
Remember to start the script with the shortcut or by running start.ahk. Do not start with tablenavigator.ahk.
That's pretty much it. I might explain the !clearBetBox() and !isTableWaiting() functions some other time, if there's interest. Once you get your plug-in to work, all you have to do is upload it to it's own wiki page and let people know it's there. To upload, just add the name of your site to the url of the main TableNavigator page. This will take you to an empty page. Then just paste in your code, in code tags (three curly brackets '{' to open, then three more '}' to close). To let people know about it, post in the 2+2 thread and also add your site to the list of plug-ins on the main TableNavigator page.
Good Luck!
Attention Queue
Pixel matching
As I mentioned above, there are two kinds of sites: Those with controls AHK can 'see' and those where it can't. Now, if AHK can't determine if a button is visible or hidden, we have to find it out by checking the color of a specific pixel. One button is always present if a table is waiting for your action, and that's the 'Fold' button. So, we'll check to see if it's there. Have a look at the 'IsTableWaitingPacific(id)' function:
IsTableWaitingPacific(id) {
local x,y,wx,wy
CoordMode, Pixel, Screen
WinGetPos, wx, wy,,, ahk_id%id%
x := wx + AQ_pixelX_Pacific
y := wy + AQ_pixelY_Pacific
If ( PixelGetColor(x, y) = AQ_pixel_Pacific )
return 1
return 0
}
On the first line, we declare some variables as local. By doing this we ensure that, to the rest of the script, these variables mean nothing, so they can't mess anything up. Also, declaring variables local automatically mean that any other variables are global - we need AQ_pixelX_Pacific etc. to be global, because we put a value into them somewhere else. (Don't worry if you didn't get any of this). In line 2, we tell the function to treat any coordinates as relative to the screen instead of the active window. Since most of the time the window we're checking won't be active, this is essential. In line 3, we get the x and y position of our target window. Now, we calculate the position our pixel is at, relative to the screen. Finally, we compare the current color of the pixel to the color the user configured (in the Preferences Gui). If they are identical, the fold button is present, so we return 1, for 'yes, table is waiting'. Else, we return 0.
Important: Pixel colors as shown by WindowSpy are in BGR format (blue-green-red), but you have to use RGB format (red-green-blue). Don't let that confuse you.
