CString CSymbolEnginePokerTracker::SymbolsProvided() { CString list; for (int i=0; i<PT_DLL_GetNumberOfStats(); ++i) { CString basic_symbol_name = PT_DLL_GetBasicSymbolNameWithoutPTPrefix(i); // Add symbol for raise-chair CString new_symbol = "pt_" + basic_symbol_name + "_raischair"; list.AppendFormat(" %s", new_symbol); // Add symbol for headsup-chair... new_symbol = "pt_" + basic_symbol_name + "_headsup"; list.AppendFormat(" %s", new_symbol); // ... and all similar symbols new_symbol = "pt_" + basic_symbol_name + "_smallblind"; list.AppendFormat(" %s", new_symbol); new_symbol = "pt_" + basic_symbol_name + "_bigblind"; list.AppendFormat(" %s", new_symbol); new_symbol = "pt_" + basic_symbol_name + "_cutoff"; list.AppendFormat(" %s", new_symbol); new_symbol = "pt_" + basic_symbol_name + "_firstcaller"; list.AppendFormat(" %s", new_symbol); new_symbol = "pt_" + basic_symbol_name + "_lastcaller"; list.AppendFormat(" %s", new_symbol); new_symbol = "pt_" + basic_symbol_name + "_firstraiser"; list.AppendFormat(" %s", new_symbol); new_symbol = "pt_" + basic_symbol_name + "_dealer"; list.AppendFormat(" %s", new_symbol); new_symbol = "pt_" + basic_symbol_name + "_user"; list.AppendFormat(" %s", new_symbol); // Add symbols for all chairs, indexed by trailing numbers for (int j=0; j<kMaxNumberOfPlayers; j++) { new_symbol.Format("pt_%s%i", basic_symbol_name, j); list.AppendFormat(" %s", new_symbol); } } return list; }
UINT CPokerTrackerThread::PokertrackerThreadFunction(LPVOID pParam) { CPokerTrackerThread *pParent = static_cast<CPokerTrackerThread*>(pParam); int iteration = 0; clock_t iterStart, iterEnd; int iterDurationMS; while (::WaitForSingleObject(pParent->_m_stop_thread, 0) != WAIT_OBJECT_0) { iterStart = clock(); write_log(preferences.debug_pokertracker(), "[PokerTracker] PTthread iteration [%d] had started\n", ++iteration); if (!pParent->_connected) { pParent->Connect(); } double players = p_symbol_engine_active_dealt_playing->nopponentsplaying() + (p_symbol_engine_userchair->userchair_confirmed() ? 1 : 0); write_log(preferences.debug_pokertracker(), "[PokerTracker] Players count is [%d]\n", players); if (players < 2) { write_log(preferences.debug_pokertracker(), "[PokerTracker] Not enough players to justify iteration...\n"); write_log(preferences.debug_pokertracker(), "[PokerTracker] For beginners: possible tablemap-problem?\n"); write_log(preferences.debug_pokertracker(), "[PokerTracker] Continuing anyway...\n"); } // Avoiding division by zero and setting sleep time AdaptValueToMinMaxRange(&players, 1, k_max_number_of_players); int sleep_time = (int) ((double)(/*preferences.pt_cache_refresh() !!*/ 30 * 1000) / (double)((PT_DLL_GetNumberOfStats() + 1) * players)); write_log(preferences.debug_pokertracker(), "[PokerTracker] sleepTime set to %d\n", sleep_time); LightSleep(sleep_time, pParent); if (pParent->_connected && PQstatus(pParent->_pgconn) == CONNECTION_OK) { for (int chair = 0; chair < p_tablemap->nchairs(); ++chair) { GetStatsForChair(pParam, chair, sleep_time); /* Verify therad_stop is false */ if (LightSleep(0, pParent)) break; } } iterEnd = clock(); iterDurationMS = (int) ((double)(iterEnd - iterStart)); write_log(preferences.debug_pokertracker(), "[PokerTracker] PTthread iteration [%d] had ended, duration time in ms: [%d]\n", ++iteration, iterDurationMS); if (iterDurationMS <= 10000) { write_log(preferences.debug_pokertracker(), "[PokerTracker] sleeping [%d] ms because iteration was too quick.\n", 10000 - iterDurationMS); if (LightSleep(10000 - iterDurationMS, pParent)) break; } } // Set event write_log(preferences.debug_pokertracker(), "[PokerTracker] PokertrackerThreadFunction: outside while loop...\n"); ::SetEvent(pParent->_m_wait_thread); return 0; }
void CPokerTrackerThread::GetStatsForChair(LPVOID pParam, int chair, int sleepTime) { CPokerTrackerThread *pParent = static_cast<CPokerTrackerThread*>(pParam); int updatedCount = 0; if (pParent->CheckIfNameExistsInDB(chair) == false) { /* Note that checkname fail just when starting, doesn't necessarily mean that there's no user in that chair, but only that the scraper failed to find one. This could be due to lobby window that hides poker window behind it. We make this check once, and if we are good, the update iteration is good to go. if we are not, we assume that this seat is not taken at the moment. */ write_log(preferences.debug_pokertracker(), "[PokerTracker] GetStatsForChair[%d] had been skipped. Reason: [CheckName failed]\n", chair); return; } write_log(preferences.debug_pokertracker(), "[PokerTracker] GetStatsForChair[%d] had been started.\n", chair); /* Check if there's a complete update cycle skipping for that chair */ if (pParent->SkipUpdateForChair(chair)) { pParent->RecalcSkippedUpdates(chair); return; } if (!pParent->_connected) { pParent->Connect(); } if (pParent->_connected && PQstatus(pParent->_pgconn) == CONNECTION_OK) { if (p_autoconnector->IsConnected()) { for (int i=0; i<PT_DLL_GetNumberOfStats(); i++) { /* CheckName is necessary before each update. There's a short interval between any two updates, and it's possible that the player had stood up during the update process. But it also possible that the poker lobby was hiding our poker window, or some popup temporarily was over it, and that's why CheckName fails. Since we cannot know which one caused checkname to fail, we would continue to update, as long as we have a found name, and as long as the name did't get changed. So what we do care about, is the situation were the name got replaced by another name, in that case, we stop the update for the current chair */ if (_player_data[chair].found) { /* Verify therad_stop is false */ if (LightSleep(0, pParent)) return; /* verify that name did not get changed */ if (pParent->CheckIfNameHasChanged(i)) { /* Name got changed while we search for stats for current chair Simply return. Clearing stats happens by CSymbolEnginePokerTracker on next symbol lookup . */ write_log(preferences.debug_pokertracker(), "[PokerTracker] Name changed for chair [%d] Stopping PT-symbol-lookup. \n", chair); return; } if (pParent->SkipUpdateCondition(i, chair)) { /* Updating stat i should be skipped this time */ /* advanced/positional stats are updated every k_advanced_stat_update_every cycles */ write_log(preferences.debug_pokertracker(), "[PokerTracker] GetStatsForChair: Updating stats [%d] for chair [%d] had been skipped. Reason: [advanced/positional stats cycle [%d of %d]]\n", i, chair, pParent->GetSkippedUpdates(chair) , k_advanced_stat_update_every); } else { /* Update... */ write_log(preferences.debug_pokertracker(), "[PokerTracker] GetStatsForChair updating stats [%d] for chair [%d]...\n", i, chair); pParent->UpdateStat(chair, i); ++updatedCount; } /* Sleep between two updates (even if skipped) */ if (LightSleep(sleepTime, pParent)) return; } else { /* We couldn't find any user sitting on that chair. Give message*/ write_log(preferences.debug_pokertracker(), "[PokerTracker] GetStatsForChair for chair [%d] had been skipped. Reason: [user not found (user stood up?)]\n", chair); return; } } } } pParent->ReportUpdateComplete(updatedCount, chair); pParent->RecalcSkippedUpdates(chair); }
double CPokerTrackerThread::UpdateStat(int m_chr, int stat) { PGresult *res = NULL; double result = k_undefined; clock_t updStart, updEnd; int duration; int sym_elapsed = p_symbol_engine_time->elapsed(); //No more unnecessary queries when we don't even have a siteid to check int siteid = pt_lookup.GetSiteId(); if (siteid == k_undefined) return k_undefined; if (!_connected || PQstatus(_pgconn) != CONNECTION_OK) return k_undefined; assert(m_chr >= k_first_chair); assert(m_chr <= k_last_chair); assert(stat >= 0); assert(stat < PT_DLL_GetNumberOfStats()); // get query string for the requested statistic CString query = PT_DLL_GetQuery(stat, p_symbol_engine_isomaha->isomaha(), p_symbol_engine_istournament->istournament(), siteid, _player_data[m_chr].pt_name); // Do the query against the PT database updStart = clock(); try { // See if we can find the player name in the database write_log(preferences.debug_pokertracker(), "[PokerTracker] Querying %s for m_chr %d: %s\n", PT_DLL_GetBasicSymbolNameWithoutPTPrefix(stat), m_chr, query); res = PQexec(_pgconn, query); } catch (_com_error &e) { write_log(preferences.debug_pokertracker(), "[PokerTracker] ERROR\n"); write_log(preferences.debug_pokertracker(), _T("\tCode = %08lx\n"), e.Error()); write_log(preferences.debug_pokertracker(), _T("\tCode meaning = %s\n"), e.ErrorMessage()); _bstr_t bstrSource(e.Source()); _bstr_t bstrDescription(e.Description()); write_log(preferences.debug_pokertracker(), _T("\tSource = %s\n"), (LPCTSTR) bstrSource); write_log(preferences.debug_pokertracker(), _T("\tDescription = %s\n"), (LPCTSTR) bstrDescription); write_log(preferences.debug_pokertracker(), _T("\tQuery = [%s]\n"), query); } updEnd = clock(); duration = (int) ((double)(updEnd - updStart) / 1000); if (duration >= 3) write_log(preferences.debug_pokertracker(), "[PokerTracker] Query time in seconds: [%d]\n", duration); // Check query return code if (PQresultStatus(res) != PGRES_TUPLES_OK) { switch (PQresultStatus(res)) { case PGRES_COMMAND_OK: write_log(preferences.debug_pokertracker(), "[PokerTracker] PGRES_COMMAND_OK: %s [%s]\n", PQerrorMessage(_pgconn), query); break; case PGRES_EMPTY_QUERY: write_log(preferences.debug_pokertracker(), "[PokerTracker] PGRES_EMPTY_QUERY: %s [%s]\n", PQerrorMessage(_pgconn), query); break; case PGRES_BAD_RESPONSE: write_log(preferences.debug_pokertracker(), "[PokerTracker] PGRES_BAD_RESPONSE: %s [%s]\n", PQerrorMessage(_pgconn), query); break; case PGRES_COPY_OUT: write_log(preferences.debug_pokertracker(), "[PokerTracker] PGRES_COPY_OUT: %s [%s]\n", PQerrorMessage(_pgconn), query); break; case PGRES_COPY_IN: write_log(preferences.debug_pokertracker(), "[PokerTracker] PGRES_COPY_IN: %s [%s]\n", PQerrorMessage(_pgconn), query); break; case PGRES_NONFATAL_ERROR: write_log(preferences.debug_pokertracker(), "[PokerTracker] PGRES_NONFATAL_ERROR: %s [%s]\n", PQerrorMessage(_pgconn), query); break; case PGRES_FATAL_ERROR: write_log(preferences.debug_pokertracker(), "[PokerTracker] PGRES_FATAL_ERROR: %s [%s]\n", PQerrorMessage(_pgconn), query); break; default: write_log(preferences.debug_pokertracker(), "[PokerTracker] GENERIC ERROR: %s [%s]\n", PQerrorMessage(_pgconn), query); break; } } else { if (PQgetisnull(res,0,0) != 1) { result = atof(PQgetvalue(res,0,0)); write_log(preferences.debug_pokertracker(), "[PokerTracker] Query %s for m_chr %d success: %f\n", PT_DLL_GetBasicSymbolNameWithoutPTPrefix(stat), m_chr, result); } PQclear(res); // update cache with new values PT_DLL_SetStat(stat, m_chr, result); } return result; }