def grabHand(self): #NOTE: we could be faced with an arbitrary windowat this point or an inavlid handle if Tc2Win32.windowGetTextLength( self._hwndEdit) > Tc2Config.MaxHandHistoryText: #TODO: have to find a better way to give feedback on what hapens on hand grabbing Tc2Config.globalObject.feedbackMessage.emit( self.parent(), 'Hand text too long') return data = Tc2Win32.windowGetText(self._hwndEdit, maxSize=Tc2Config.MaxHandHistoryText) if data and data != self._data: self._data = data handData = '' hand = Tc2HandTypes.PokerHand() #TODO: very sloppy test to minimize risk we are grabbing 'show summary only' in instant hand history if not ('*** HOLE CARDS ***' in data or '*** 3rd STREET ***' in data or '*** DEALING HANDS ***' in data): pass else: #NOTE: we are let Tc2Config handle errors because we are maybe working with arbitrary data # from an unknown window try: hand = self._handParser.parse(data) except: Tc2Config.handleException('\n' + data) else: handData = self._handFormatter.dump(hand) self.siteHandler.handGrabbed.emit(hand, handData)
def hotkeysEnabled(self): point = Tc2Win32.mouseGetPos() hwndUnderMouse = Tc2Win32.windowFromPoint(point) className = Tc2Win32.windowGetClassName(hwndUnderMouse) if className in (self.ClassChat, self.ClassNoteEditor, self.ClassChatEditor, self.ClassNoteEditorBox, self.ClassInfoBox): return False return True
def handleCreated(self): if Tc2Config.globalObject.settingsPokerStars.autoCloseTableMessageBoxes(): buttons = Tc2Win32.windowGetButtons(self.hwnd) if len(buttons) != 1: return if not 'OK' in buttons: return Tc2Win32.windowClickButton(buttons['OK']) Tc2Config.globalObject.feedbackMessage.emit('Closed Table Message Box')
def readData(self): data = {} text = Tc2Win32.windowGetText(self.hwnd, maxSize=Tc2Config.MaxWindowText) if not text: return data match = self.PatAmountSB.match(text) if match is None: raise ValueError('could not determine smallBlind: %r' % text) data['smallBlind'] = float(match.group(1)) match = self.PatAmountBB.match(text) if match is None: raise ValueError('could not determine smallBlind: %r' % text) data['bigBlind'] = float(match.group(1)) hwndBetBox = Tc2Win32.windowFindChild(self.hwnd, self.ClassTableBetBox) data['hwndBetBox'] = hwndBetBox data['betBoxIsVisible'] = Tc2Win32.windowIsVisible( hwndBetBox) if hwndBetBox else False data['bet'] = None if data['hwndBetBox']: p = Tc2Win32.windowGetText( hwndBetBox, maxSize=Tc2Config.MaxPokerStarsBetBoxText) try: data['bet'] = float(p) except ValueError: pass return data
def matchesHwnd(klass, hwnd): if Tc2Win32.windowGetClassName(hwnd) != self.WindowClassName: return False if not Tc2Win32.windowGetText(hwnd, maxSize=len( klass.WindowTitle)).startswith(klass.WindowTitle): return False if not PokerStarsWindow.matchesHwnd(hwnd): return False return True
def handleCreated(self): if Tc2Config.globalObject.settingsPokerStars.autoCloseLogin(): buttons = Tc2Win32.windowGetButtons(self.hwnd) if sorted(buttons) == ['', 'Cancel', 'Create New Account...', 'Forgot User ID / Password...', 'OK']: if Tc2Win32.windowCheckboxIsChecked(buttons['']): if Tc2Win32.windowIsEnabled(buttons['OK']): Tc2Win32.windowClickButton(buttons['OK']) Tc2Config.globalObject.feedbackMessage.emit('Closed Log In Box')
def matchesHwnd(klass, hwnd): if Tc2Win32.windowGetClassName(hwnd) != klass.WindowClassName: return False if Tc2Win32.windowGetText(hwnd, maxSize=len( klass.WindowTitle)) != klass.WindowTitle: return False hwndParent = Tc2Win32.windowGetParent(hwnd) if not Table.matchesHwnd(hwndParent): return False return True
def setVisible(self, flag): QtGui.QWidget.setVisible(self, flag) if not self._isInited: self._isInited = True hwnd = self.effectiveWinId() if hwnd is None: raise RuntimeError('main window has no valid hwnd') hwnd = int(hwnd) Tc2Win32.windowSetTopmost(hwnd)
def handleCreated(self): if Tc2Config.globalObject.settingsPokerStars.autoCloseTableMessageBoxes( ): buttons = Tc2Win32.windowGetButtons(self.hwnd) if len(buttons) != 1: return if not 'OK' in buttons: return Tc2Win32.windowClickButton(buttons['OK']) Tc2Config.globalObject.feedbackMessage.emit( 'Closed Table Message Box')
def clickRestoreFocus(self, point, template): #NOTE: we always double click. not realy necessary here si = Tc2Win32.SendInput() si.leftClickDouble(point, hwnd=self.hwnd) si.send(restoreCursor=False) # replayer gains focus, so we have to wait a bit and send another click to reactivate the table. si = Tc2Win32.SendInput() si.leftClickDouble(template.points['EmptySpace'], hwnd=self.hwnd) si.send(restoreCursor=Tc2Config.globalObject.settingsGlobal. restoreMousePosition())
def _windowInfo(self, hwnd, level=0): if Tc2Win32.windowGetTextLength(hwnd) > Tc2Config.MaxWindowText: title = 'Window title too long' else: title = Tc2Win32.windowGetText(hwnd, maxSize=Tc2Config.MaxWindowText).replace('\r', '') if '\n' in title: title = title.split('\n', 1)[0] className = Tc2Win32.windowGetClassName(hwnd) buttons = sorted( Tc2Win32.windowGetButtons(hwnd).keys() ) size = Tc2Win32.windowGetRect(hwnd).size() pos = Tc2Win32.windowGetPos(hwnd) clientSize = Tc2Win32.windowGetClientRect(hwnd).size() if not buttons: buttons = '' elif len(buttons) == 1: buttons = "'%s'" % buttons[0] else: buttons = "'%s'" % ', '.join(["'%s'" % i for i in buttons] ) isVisible = Tc2Win32.windowIsVisible(hwnd) isEnabled = Tc2Win32.windowIsEnabled(hwnd) indent = '\x20\x20\x20\x20' *level p = '%s%s\n' % (indent, '/'*level) p += '%sTitle: %s\n' % (indent, title) p += '%sClassName: %s\n' % (indent, className) p += '%sPos: %s,%s\n' % (indent, pos.x(), pos.y() ) p += '%sSize: %sx%s\n' % (indent, size.width(), size.height() ) p += '%sClientSize: %sx%s\n' % (indent, clientSize.width(), clientSize.height() ) p += '%sButtons: %s\n' % (indent, buttons) p += '%sVisible: %s\n' % (indent, isVisible) p += '%sEnabled: %s\n' % (indent, isEnabled) p += '%sHwnd: %s\n' % (indent, hwnd) return p
def handleBetPot(self, hotkey, template, inputEvent): data = self.readData() if not data: return if not data['hwndBetBox']: return if not data['betBoxIsVisible']: return pointTopLeft = template.points['PotTopLeft'] pointBottomRight = template.points['PotBottomRight'] if pointTopLeft == Tc2Config.PointNone: Tc2Config.globalObject.feedbackMessage.emit('%s: -- Point Pot Top Left Not Set -' % template.name() ) return if pointBottomRight == Tc2Config.PointNone: Tc2Config.globalObject.feedbackMessage.emit('%s: -- Point Pot Bottom Right Not Set -' % template.name() ) return # grab pot rect pixmap = QtGui.QPixmap.grabWindow(self.hwnd, pointTopLeft.x(), pointTopLeft.y(), pointBottomRight.x() - pointTopLeft.x(), pointBottomRight.y() - pointTopLeft.y(), ) pgmImage = gocr.ImagePGM.fromQPixmap(pixmap) # scan pot num, err = gocr.scanImage( pgmImage=pgmImage, chars='0-9,.', dustSize=0, outputType=gocr.OutputTypeFloat, outputPattern=self.PatPot, ) if num is None: # try again with inverted image num, err = gocr.scanImage( pgmImage=pgmImage, flagInvertImage=True, chars='0-9,.', dustSize=0, outputType=gocr.OutputTypeFloat, outputPattern=self.PatPot, ) if num is None: try: raise ValueError('Could not scan pot\n<image>%s</image>' % base64.b64encode(pgmImage.toString())) except: Tc2Config.handleException() Tc2Config.globalObject.feedbackMessage.emit('%s: Error - Could not scan pot' % hotkey.action() ) return newBet = hotkey.applyAction(inputEvent, blinds=(data['smallBlind'], data['bigBlind']), bet=num) if newBet is None: return Tc2Win32.windowSetText(data['hwndBetBox'], text=newBet, isUnicode=False) Tc2Config.globalObject.feedbackMessage.emit('%s - %s -- %s' % (template.name() , hotkey.action(), newBet) )
def handleMultiplyBet(self, hotkey, template, inputEvent): data = self.readData() if not data: return if not data['hwndBetBox']: return if not data['betBoxIsVisible']: return if data['bet'] is None: return newBet = hotkey.applyAction(inputEvent, blinds=(data['smallBlind'], data['bigBlind']), bet=data['bet']) if newBet is None: return #NOTE: the box gets mesed up when unicode is thrown at it Tc2Win32.windowSetText(data['hwndBetBox'], text=newBet, isUnicode=False) Tc2Config.globalObject.feedbackMessage.emit('%s - %s -- %s' % (template.name() , hotkey.action(), newBet))
def handleCreated(self): if Tc2Config.globalObject.settingsPokerStars.autoCloseLogin(): buttons = Tc2Win32.windowGetButtons(self.hwnd) if sorted(buttons) == [ '', 'Cancel', 'Create New Account...', 'Forgot User ID / Password...', 'OK' ]: if Tc2Win32.windowCheckboxIsChecked(buttons['']): if Tc2Win32.windowIsEnabled(buttons['OK']): Tc2Win32.windowClickButton(buttons['OK']) Tc2Config.globalObject.feedbackMessage.emit( 'Closed Log In Box')
def clickButton(self, point, template, hotkey, modifiers=None): #NOTE: # 1) checkboxes behave like tri state boxes when we send input. not when clicking them (weird) # 2) PostMessage(WM_LBUTTONDOWN,...) works for buttons but is not working for checkboxes # 3) SendInput() throws messages anonymously into the eent queue so we can not # be shure the current foreground window is receiving the messages (race condition) # 4) there is no way we can check if our input triggered the desired effect # 5) we dont know when PS schows us buttons or checkboxes. bet box being # visible gives us an indicator at times, but is useless for example if s.o. is all-in #TODO: have to rewrite InputEvent() to accept mouse and keyboard events modifiers = () if modifiers is None else modifiers si = Tc2Win32.SendInput() for vk in modifiers: si.keyDown(vk) si.leftClick(point, hwnd=self.hwnd) for vk in modifiers: si.keyUp(vk) si.send(restoreCursor=Tc2Config.globalObject.settingsGlobal. restoreMousePosition()) # workaround to send double clicks. this handles checkboxes as expected but may trigger # accidental clicks on unrelated tables. we add an abitrary timeout to check if PS has thrown another # table to the foreground. no way to get this fail save, we have a race condition ##time.sleep( min(0.05, Tc2Win32.mouseDoubleClickTime()) ) ##hwnd2 = Tc2Win32.windowForeground() ##if hwnd == hwnd2: ## si.leftClick(point, hwnd=hwnd).send(restoreCursor=self.settingsGlobal.Tc2Config.globalObject.settingsGlobal.()) Tc2Config.globalObject.feedbackMessage.emit( '%s: %s' % (template.name(), hotkey.action())) return
def template(self): rect = Tc2Win32.windowGetClientRect(self.hwnd) for template in Tc2Config.globalObject.templateManager: if not template.isEnabled(): continue if template.id() != Tc2ConfigTemplates.TemplatePokerStarsTable.id(): continue if template.size != rect.size(): continue return template return None
def handleMultiplyBlind(self, hotkey, template, inputEvent): data = self.readData() if not data: return if not data['hwndBetBox']: return if not data['betBoxIsVisible']: return if data['bet'] is None: return newBet = hotkey.applyAction(inputEvent, blinds=(data['smallBlind'], data['bigBlind'])) if newBet is None: return #NOTE: the box gets mesed up when unicode is thrown at it Tc2Win32.windowSetText(data['hwndBetBox'], text=newBet, isUnicode=False) Tc2Config.globalObject.feedbackMessage.emit( '%s - %s -- %s' % (template.name(), hotkey.action(), newBet))
def template(self): rect = Tc2Win32.windowGetClientRect(self.hwnd) for template in Tc2Config.globalObject.templateManager: if not template.isEnabled(): continue if template.id() != Tc2ConfigTemplates.TemplatePokerStarsTable.id( ): continue if template.size != rect.size(): continue return template return None
def onInputEvent(self, inputEvent): hwnd = self.effectiveWinId() if hwnd is None: return hwnd = int(hwnd) if hwnd == Tc2Win32.windowForeground(): for hotkey in Tc2Config.globalObject.hotkeyManager: if not hotkey.key() or hotkey.key() != inputEvent.key: continue if hotkey.id() == Tc2ConfigHotkeys.HotkeyCardProtector.id(): self.handleInputEvent(hwnd, hotkey, inputEvent) break
def gatherWindowInfo(self, hwnd): self._lastScreenshotInfo = '' self._lastScreenshotInfo += '-----------------------------------------------------------------\n' self._lastScreenshotInfo += 'Current Window\n' self._lastScreenshotInfo += '-----------------------------------------------------------------\n' self._lastScreenshotInfo += self._windowInfo(hwnd) self._lastScreenshotInfo += '-----------------------------------------------------------------\n' self._lastScreenshotInfo += 'Window Hirarchy\n' self._lastScreenshotInfo += '-----------------------------------------------------------------\n' level = 0 hwndParent = hwnd while hwndParent: self._lastScreenshotInfo += self._windowInfo(hwndParent, level=level) hwndParent = Tc2Win32.windowGetParent(hwndParent) level += 1 self._lastScreenshotInfo += '-----------------------------------------------------------------\n' self._lastScreenshotInfo += 'Window Details\n' self._lastScreenshotInfo += '-----------------------------------------------------------------\n' for level, hwnd in Tc2Win32.windowWalkChildren(hwnd, report=True): self._lastScreenshotInfo += self._windowInfo(hwnd, level=level)
def handleHilightBet(self, hotkey, template, inputEvent): data = self.readData() if not data: return hwndBetBox = data['hwndBetBox'] if not hwndBetBox: return if not data['betBoxIsVisible']: return point = QtCore.QPoint(2, 2) si = Tc2Win32.SendInput() si.leftClickDouble(point, hwnd=hwndBetBox) si.send(restoreCursor=Tc2Config.globalObject.settingsGlobal. restoreMousePosition()) Tc2Config.globalObject.feedbackMessage.emit( '%s: %s' % (template.name(), hotkey.action()))
def __init__(self, *args, **kws): PokerStarsWindow.__init__(self, *args, **kws) self._timer = QtCore.QTimer(self.siteHandler) self._timer.setInterval(Tc2Config.HandGrabberTimeout * 1000) self._timer.timeout.connect(self.grabHand) #self._timer.setSingleShot(True) self._handParser = Tc2SitePokerStarsHandGrabber.HandParser() self._handFormatter = Tc2Config.handFormatter('HtmlTabular') self._data = '' self._hwndEdit = None for hwnd in Tc2Win32.windowChildren(self.hwnd): if Tc2Win32.windowGetClassName(hwnd) == self.WidgetClassName: self._hwndEdit = hwnd break if self._hwndEdit is None: try: raise ValueError('Instant hand history edit box not found') except: Tc2Config.handleException() else: self._timer.start()
def readData(self): data = {} text = Tc2Win32.windowGetText(self.hwnd, maxSize=Tc2Config.MaxWindowText ) if not text: return data match = self.PatAmountSB.match(text) if match is None: raise ValueError('could not determine smallBlind: %r' % text) data['smallBlind'] = float(match.group(1)) match = self.PatAmountBB.match(text) if match is None: raise ValueError('could not determine smallBlind: %r' % text) data['bigBlind'] = float(match.group(1)) hwndBetBox = Tc2Win32.windowFindChild(self.hwnd, self.ClassTableBetBox) data['hwndBetBox'] = hwndBetBox data['betBoxIsVisible'] = Tc2Win32.windowIsVisible(hwndBetBox) if hwndBetBox else False data['bet'] = None if data['hwndBetBox']: p = Tc2Win32.windowGetText(hwndBetBox, maxSize=Tc2Config.MaxPokerStarsBetBoxText) try: data['bet'] = float(p) except ValueError: pass return data
def handleAll_In(self, hotkey, template, inputEvent): data = self.readData() if not data: return if not data['hwndBetBox']: return if not data['betBoxIsVisible']: return point = self.point('BetSliderEnd', template) if point is None: return si = Tc2Win32.SendInput() si.leftClick( point, hwnd=self.hwnd).send(restoreCursor=Tc2Config.globalObject. settingsGlobal.restoreMousePosition()) Tc2Config.globalObject.feedbackMessage.emit( '%s: %s' % (template.name(), hotkey.action()))
def handleInputEvent(self, hwnd, hotkey, inputEvent): if Tc2Win32.windowIsSameProcess(hwnd, self._hwndMain): return True if hotkey.id() == Tc2ConfigHotkeys.HotkeyScreenshot.id(): if inputEvent.keyIsDown: Tc2Config.widgetScreenshot(hwnd) Tc2Config.globalObject.feedbackMessage.emit(hotkey.action() ) inputEvent.accept = True return True #TODO: implement hide card protector if card protector has focus. we'd have # to translate Qt keyboard events to input events to do so. too much trouble for now. elif hotkey.id() == Tc2ConfigHotkeys.HotkeyCardProtector.id(): self._widgetCardProtector.handleInputEvent(hwnd, hotkey, inputEvent) return True
def __init__(self): QtCore.QObject.__init__(self) self.mainWindow = self.objectCreatedMainWindow.connect( lambda obj, self=self: setattr(self, 'mainWindow', obj)) self.windowHook = Tc2Win32.WindowHook(parent=self, timeout=WindowHookTimeout) self.mouseHook = Tc2Win32.MouseHook(parent=self) self.keyboardHook = Tc2Win32.KeyboardHook(parent=self) self.hotkeyManager = self.objectCreatedHotkeyManager.connect( lambda obj, self=self: setattr(self, 'hotkeyManager', obj)) templateManager = self.objectCreatedTemplateManager.connect( lambda obj, self=self: setattr(self, 'templateManager', obj)) self.settingsGlobal = self.objectCreatedSettingsGlobal.connect( lambda obj, self=self: setattr(self, 'settingsGlobal', obj)) self.settingsNetwork = self.objectCreatedSettingsNetwork.connect( lambda obj, self=self: setattr(self, 'settingsNetwork', obj)) self.settingsPokerStars = self.objectCreatedSettingsPokerStars.connect( lambda obj, self=self: setattr(self, 'settingsPokerStars', obj)) self.settingsHandViewer = self.objectCreatedSettingsHandViewer.connect( lambda obj, self=self: setattr(self, 'settingsHandViewer', obj)) self.settingsPHandViewerStyleSheet = self.objectCreatedSettingsHandViewerStyleSheet.connect( lambda obj, self=self: setattr( self, 'settingsHandViewerStyleSheet', obj)) self.settingsNashCalculationsStyleSheet = self.objectCreatedSettingsNashCalculationsStyleSheet.connect( lambda obj, self=self: setattr( self, 'settingsNashCalculationsStyleSheet', obj)) self.settingsICMTaxStyleSheet = self.objectCreatedSettingsICMTaxStyleSheet.connect( lambda obj, self=self: setattr(self, 'settingsICMTaxStyleSheet', obj)) self.settingsClock = self.objectCreatedSettingsClock.connect( lambda obj, self=self: setattr(self, 'settingsClock', obj)) self.settingsCardProtector = self.objectCreatedSettingsCardProtector.connect( lambda obj, self=self: setattr(self, 'settingsCardProtector', obj)) self.siteManager = self.objectCreatedSiteManager.connect( lambda obj, self=self: setattr(self, 'siteManager', obj)) self.siteHandlerPokerStars = self.objectCreatedSiteHandlerPokerStars.connect( lambda obj, self=self: setattr(self, 'siteHandlerPokerStars', obj))
def grabHand(self): #NOTE: we could be faced with an arbitrary windowat this point or an inavlid handle if Tc2Win32.windowGetTextLength(self._hwndEdit) > Tc2Config.MaxHandHistoryText: #TODO: have to find a better way to give feedback on what hapens on hand grabbing Tc2Config.globalObject.feedbackMessage.emit(self.parent(), 'Hand text too long') return data = Tc2Win32.windowGetText(self._hwndEdit, maxSize=Tc2Config.MaxHandHistoryText) if data and data != self._data: self._data = data handData = '' hand = Tc2HandTypes.PokerHand() #TODO: very sloppy test to minimize risk we are grabbing 'show summary only' in instant hand history if not ('*** HOLE CARDS ***' in data or '*** 3rd STREET ***' in data or '*** DEALING HANDS ***' in data): pass else: #NOTE: we are let Tc2Config handle errors because we are maybe working with arbitrary data # from an unknown window try: hand = self._handParser.parse(data) except: Tc2Config.handleException('\n' + data) else: handData = self._handFormatter.dump(hand) self.siteHandler.handGrabbed.emit(hand, handData)
def onInputEvent(self, inputEvent): if Tc2Config.globalObject.hotkeyManager is None or Tc2Config.globalObject.templateManager is None: return hwnd = Tc2Win32.windowForeground() if hwnd: for hotkey in Tc2Config.globalObject.hotkeyManager: if not hotkey.key() or hotkey.key() != inputEvent.key: continue #NOTE: have to stop hooks here so we do not get recursive Tc2Config.globalObject.keyboardHook.setEnabled(False) Tc2Config.globalObject.mouseHook.setEnabled(False) try: for handler in self._siteHandlers: if handler.handleInputEvent(hwnd, hotkey, inputEvent): break finally: Tc2Config.globalObject.keyboardHook.setEnabled(True) Tc2Config.globalObject.mouseHook.setEnabled(True)
def handleGainedForeground(self): template = self.template() if template is not None: Tc2Config.globalObject.feedbackMessage.emit(template.name() ) if Tc2Config.globalObject.settingsPokerStars.moveMouseToActiveTable(): if not Tc2Win32.mouseButtonsDown(): point = Tc2Win32.mouseGetPos() rect = Tc2Win32.windowGetRect(self.hwnd) if not rect.contains(point): point = template.points['EmptySpace'] point = Tc2Win32.windowClientPointToScreenPoint(self.hwnd, point) Tc2Win32.mouseSetPos(point) return True return False
def handleGainedForeground(self): template = self.template() if template is not None: Tc2Config.globalObject.feedbackMessage.emit(template.name()) if Tc2Config.globalObject.settingsPokerStars.moveMouseToActiveTable( ): if not Tc2Win32.mouseButtonsDown(): point = Tc2Win32.mouseGetPos() rect = Tc2Win32.windowGetRect(self.hwnd) if not rect.contains(point): point = template.points['EmptySpace'] point = Tc2Win32.windowClientPointToScreenPoint( self.hwnd, point) Tc2Win32.mouseSetPos(point) return True return False
def handleInputEvent(self, hotkey, inputEvent): if not self.hotkeysEnabled(): return hotkeyID = hotkey.id() if hotkeyID == Tc2ConfigHotkeys.HotkeyTableSizeNext.id(): if inputEvent.keyIsDown: # find next table template that is not of current tables size size = Tc2Win32.windowGetClientRect(self.hwnd).size() templates = [] indexCurrent = None i = 0 for template in Tc2Config.globalObject.templateManager: if template.id() != Tc2ConfigTemplates.TemplatePokerStarsTable.id(): continue if not template.isEnabled(): continue if template.size == Tc2Config.SizeNone: continue if template.size == size: indexCurrent = i templates.append(template) i += 1 if templates: if indexCurrent is None: indexCurrent = len(templates) -1 indexNext = indexCurrent +1 if indexNext >= len(templates): indexNext = 0 template = templates[indexNext] #NOTE: on wine tables do not get redrawn on resize [ http://bugs.winehq.org/show_bug.cgi?id=5941 ]. # for some reson sending F5 via KeyboardInput has no effect whatsoever, so we tell Tc2Win32 # to wrap resizing into enter- exitsizemove messages. tested on winXP as well - works nicely Tc2Win32.windowSetClientSize(self.hwnd, template.size, sendSizeMove=True) Tc2Config.globalObject.feedbackMessage.emit('%s: %s' % (hotkey.menuName(), template.name() ) ) inputEvent.accept = True return True # template = self.template() if template is None: return False handler = None if hotkeyID == Tc2ConfigHotkeys.HotkeyCheck.id(): handler = self.handleCheck elif hotkeyID == Tc2ConfigHotkeys.HotkeyFold.id(): handler = self.handleFold elif hotkeyID == Tc2ConfigHotkeys.HotkeyFoldAndStay.id(): handler = self.handleFoldAndStay elif hotkeyID == Tc2ConfigHotkeys.HotkeyRaise.id(): handler = self.handleRaise elif hotkeyID == Tc2ConfigHotkeys.HotkeyAll_In.id(): handler = self.handleAll_In elif hotkeyID == Tc2ConfigHotkeys.HotkeyHilightBet.id(): handler = self.handleHilightBet elif hotkeyID == Tc2ConfigHotkeys.HotkeyMultiplyBlind.id(): handler = self.handleMultiplyBlind elif hotkeyID == Tc2ConfigHotkeys.HotkeyAddToBet.id(): handler = self.handleAddToBet elif hotkeyID == Tc2ConfigHotkeys.HotkeySubtractFromBet.id(): handler = self.handleSubtractFromBet elif hotkeyID == Tc2ConfigHotkeys.HotkeyMultiplyBet.id(): handler = self.handleMultiplyBet elif hotkeyID == Tc2ConfigHotkeys.HotkeyBetPot.id(): handler = self.handleBetPot elif hotkeyID == Tc2ConfigHotkeys.HotkeyReplayer.id(): handler = self.handleReplayer elif hotkeyID == Tc2ConfigHotkeys.HotkeyInstantHandHistory.id(): handler = self.handleInstantHandHistory elif hotkeyID in ( Tc2ConfigHotkeys.HotkeyClick1.id(), Tc2ConfigHotkeys.HotkeyClick2.id(), Tc2ConfigHotkeys.HotkeyClick3.id(), Tc2ConfigHotkeys.HotkeyClick4.id(), Tc2ConfigHotkeys.HotkeyClick5.id(), ): handler = self.handleHotkeyClick if handler is not None: if inputEvent.keyIsDown: handler(hotkey, template, inputEvent) inputEvent.accept = True
def __init__(self): scope = Tc2Config.settingsValue( Tc2Config.SettingsKeySingleApplicationScope, '').toString() if scope not in Tc2Win32.SingleApplication.Scopes: scope = Tc2Config.SingleApplicationScopeDefault self.singleApplication = Tc2Win32.SingleApplication( Tc2Config.SingleApplicationMagicString, scope=scope, parent=None) try: self.singleApplication.start() except self.singleApplication.ErrorOtherInstanceRunning: raise RuntimeError('%s is already running' % Tc2Config.ApplicationName) QtGui.QMainWindow.__init__(self) #NOTE: have to use our own timer to not have messages cover our clock self._statusMessageTimer = QtCore.QTimer(self) self._statusMessageTimer.setSingleShot(True) self._statusMessageTimer.timeout.connect(self.onStatusBarTimer) self.setWindowTitle(Tc2Config.ReleaseName) self.setWindowIcon(QtGui.QIcon(Tc2Config.Pixmaps.tableCrab())) self.restoreGeometry( Tc2Config.settingsValue(self.SettingsKeyGeometry, QtCore.QByteArray()).toByteArray()) self._siteManager = Tc2SiteManager.SiteManager(parent=self) # need to store some state data for the statusBar so we can restore on tab changes # error messages are displayed as longs as there is no new feedback from the current tab self._feedbackMessages = { # widget/tab --> feedbackData None: '', # reserved for lastError } # setup status labels self._labelClock = Tc2GuiToolsClock.ClockLabel(parent=self) self._labelStatus = ClickableLabel('Ready: ', self) self._labelStatus.setTextFormat(QtCore.Qt.RichText) self._labelStatus.doubleClicked.connect( self.onLabelFeedbackDoubleClicked) self.labelFeedback = QtGui.QLabel('', self) # setup StatusBar statusBar = self.statusBar() #BUG: QTBUG-5566 sizegrip is broken on windows statusBar.setSizeGripEnabled(False) statusBar.addWidget(self._labelClock, 0) statusBar.addWidget(self._labelStatus, 0) statusBar.addWidget(self.labelFeedback, 99) # setup tabs self._tabWidget = QtGui.QTabWidget(self) self.setCentralWidget(self._tabWidget) self._tabSetup = self._addTab(Tc2GuiSetup.FrameSetup, 'Se&tup') self._tabHotkeys = self._addTab(Tc2GuiHotkeys.FrameHotkeys, 'Hot&keys') self._tabHand = self._addTab(Tc2GuiHandViewer.FrameHandViewer, 'H&and') self._tabTools = self._addTab(Tc2GuiTools.FrameTools, 'Too&ls') self._tabSettings = self._addTab(Tc2GuiSettings.FrameSettings, 'Settin&gs') self._tabHelp = self._addTab(Tc2GuiHelp.FrameHelp, '&Help') self._tabWidget.currentChanged.connect(self.onTabCurrentChanged) # connect global signals g = Tc2Config.globalObject g.initSettingsFinished.connect(self.onGlobalObjectInitSettingsFinished) g.feedback.connect(self.onFeedback) g.feedbackException.connect(self.onFeedbackException) g.clearException.connect(self.onClearException) g.feedbackMessage.connect(self.onFeedbackMessage)
def handleWindowLostForeground(self, hwnd): if Tc2Win32.windowIsSameProcess(hwnd, self._hwndMain): return True return False
def hasPokerStarsWidgets(klass, hwnd): for hwnd in Tc2Win32.windowChildren(hwnd): if Tc2Win32.windowGetClassName(hwnd).startswith('PokerStars'): return True return False
def matchesHwnd(klass, hwnd): if not Tc2Win32.windowGetClassName(hwnd) == klass.WindowClassName: return False return True
def handleWindowDestroyed(self, hwnd): if Tc2Win32.windowIsSameProcess(hwnd, self._hwndMain): return True return False
def matchesHwnd(klass, hwnd): if Tc2Win32.windowGetClassName(hwnd) != klass.WindowClassName: return False if Tc2Win32.windowGetText(hwnd, maxSize=len(klass.WindowTitle)) != klass.WindowTitle: return False hwndParent = Tc2Win32.windowGetParent(hwnd) if not Table.matchesHwnd(hwndParent): return False return True
def matchesHwnd(klass, hwnd): while hwnd: if klass.hasPokerStarsWidgets(hwnd): return True hwnd = Tc2Win32.windowGetParent(hwnd) return False
def handleCreated(self): if Tc2Config.globalObject.settingsPokerStars.autoClosePopupNews(): Tc2Win32.windowClose(self.hwnd) Tc2Config.globalObject.feedbackMessage.emit('Closed Popup News')
def matchesHwnd(klass, hwnd): if Tc2Win32.windowGetClassName(hwnd) != self.WindowClassName: return False if not Tc2Win32.windowGetText(hwnd, maxSize=len(klass.WindowTitle)).startswith(klass.WindowTitle): return False if not PokerStarsWindow.matchesHwnd(hwnd): return False return True
def handleBetPot(self, hotkey, template, inputEvent): data = self.readData() if not data: return if not data['hwndBetBox']: return if not data['betBoxIsVisible']: return pointTopLeft = template.points['PotTopLeft'] pointBottomRight = template.points['PotBottomRight'] if pointTopLeft == Tc2Config.PointNone: Tc2Config.globalObject.feedbackMessage.emit( '%s: -- Point Pot Top Left Not Set -' % template.name()) return if pointBottomRight == Tc2Config.PointNone: Tc2Config.globalObject.feedbackMessage.emit( '%s: -- Point Pot Bottom Right Not Set -' % template.name()) return # grab pot rect pixmap = QtGui.QPixmap.grabWindow( self.hwnd, pointTopLeft.x(), pointTopLeft.y(), pointBottomRight.x() - pointTopLeft.x(), pointBottomRight.y() - pointTopLeft.y(), ) pgmImage = gocr.ImagePGM.fromQPixmap(pixmap) # scan pot num, err = gocr.scanImage( pgmImage=pgmImage, chars='0-9,.', dustSize=0, outputType=gocr.OutputTypeFloat, outputPattern=self.PatPot, ) if num is None: # try again with inverted image num, err = gocr.scanImage( pgmImage=pgmImage, flagInvertImage=True, chars='0-9,.', dustSize=0, outputType=gocr.OutputTypeFloat, outputPattern=self.PatPot, ) if num is None: try: raise ValueError('Could not scan pot\n<image>%s</image>' % base64.b64encode(pgmImage.toString())) except: Tc2Config.handleException() Tc2Config.globalObject.feedbackMessage.emit( '%s: Error - Could not scan pot' % hotkey.action()) return newBet = hotkey.applyAction(inputEvent, blinds=(data['smallBlind'], data['bigBlind']), bet=num) if newBet is None: return Tc2Win32.windowSetText(data['hwndBetBox'], text=newBet, isUnicode=False) Tc2Config.globalObject.feedbackMessage.emit( '%s - %s -- %s' % (template.name(), hotkey.action(), newBet))