Merge branch 'master' of git://git.assembla.com/fpdboz

This commit is contained in:
Ray 2009-06-19 16:10:44 -04:00
commit a998a6dc6e
8 changed files with 38 additions and 240 deletions

View File

@ -32,60 +32,20 @@ import string
# pyGTK modules # pyGTK modules
# FreePokerTools modules # FreePokerTools modules
import fpdb_db
import Configuration import Configuration
import SQL import SQL
import Card import Card
class Database: class Database:
def __init__(self, c, db_name, game): def __init__(self, c, db_name, game):
self.fdb = fpdb_db.fpdb_db() # sets self.fdb.db self.fdb.cursor and self.fdb.sql
self.fdb.do_connect(c)
self.connection = self.fdb.db
db_params = c.get_db_parameters() db_params = c.get_db_parameters()
if (string.lower(db_params['db-server']) == 'postgresql' or
string.lower(db_params['db-server']) == 'postgres'):
import psycopg2 # posgres via DB-API
import psycopg2.extensions
psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
try:
if db_params['db-host'] == 'localhost' or db_params['db-host'] == '127.0.0.1':
self.connection = psycopg2.connect(database = db_params['db-databaseName'])
else:
self.connection = psycopg2.connect(host = db_params['db-host'],
user = db_params['db-user'],
password = db_params['db-password'],
database = db_params['db-databaseName'])
except:
print "Error opening database connection %s. See error log file." % (file)
traceback.print_exc(file=sys.stderr)
print "press enter to continue"
sys.stdin.readline()
sys.exit()
elif string.lower(db_params['db-server']) == 'mysql':
import MySQLdb # mysql bindings
try:
self.connection = MySQLdb.connect(host = db_params['db-host'],
user = db_params['db-user'],
passwd = db_params['db-password'],
db = db_params['db-databaseName'])
cur_iso = self.connection.cursor()
cur_iso.execute('SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED')
cur_iso.close()
except:
print "Error opening database connection %s. See error log file." % (file)
traceback.print_exc(file=sys.stderr)
print "press enter to continue"
sys.stdin.readline()
sys.exit()
else:
print "Database = %s not recognized." % (c.supported_databases[db_name].db_server)
sys.stderr.write("Database not recognized, exiting.\n")
print "press enter to continue"
sys.exit()
self.type = db_params['db-type'] self.type = db_params['db-type']
self.sql = SQL.Sql(game = game, type = self.type) self.sql = SQL.Sql(game = game, type = self.type, db_server = db_params['db-server'])
self.connection.rollback() self.connection.rollback()
# To add to config: # To add to config:
@ -199,7 +159,7 @@ class Database:
def get_action_from_hand(self, hand_no): def get_action_from_hand(self, hand_no):
action = [ [], [], [], [], [] ] action = [ [], [], [], [], [] ]
c = self.connection.cursor() c = self.connection.cursor()
c.execute(self.sql.query['get_action_from_hand'], (hand_no, )) c.execute(self.sql.query['get_action_from_hand'], (hand_no,))
for row in c.fetchall(): for row in c.fetchall():
street = row[0] street = row[0]
act = row[1:] act = row[1:]
@ -210,7 +170,7 @@ class Database:
"""Returns a hash of winners:amount won, given a hand number.""" """Returns a hash of winners:amount won, given a hand number."""
winners = {} winners = {}
c = self.connection.cursor() c = self.connection.cursor()
c.execute(self.sql.query['get_winners_from_hand'], (hand, )) c.execute(self.sql.query['get_winners_from_hand'], (hand,))
for row in c.fetchall(): for row in c.fetchall():
winners[row[0]] = row[1] winners[row[0]] = row[1]
return winners return winners
@ -321,10 +281,10 @@ if __name__=="__main__":
for p in stat_dict.keys(): for p in stat_dict.keys():
print p, " ", stat_dict[p] print p, " ", stat_dict[p]
# print "nutOmatics stats:" #print "nutOmatics stats:"
# stat_dict = db_connection.get_stats_from_hand(h, hero) #stat_dict = db_connection.get_stats_from_hand(h, hero)
# for p in stat_dict.keys(): #for p in stat_dict.keys():
# print p, " ", stat_dict[p] # print p, " ", stat_dict[p]
print "cards =", db_connection.get_cards(u'1') print "cards =", db_connection.get_cards(u'1')
db_connection.close_connection db_connection.close_connection

View File

@ -1,161 +0,0 @@
# pokerstars_cash.py
# -*- coding: iso-8859-15
#
# PokerStats, an online poker statistics tracking software for Linux
# Copyright (C) 2007-2008 Mika Boström <bostik@iki.fi>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3 of the License.
#
# Modified for use in fpdb by Carl Gherardi
import re
# These are PokerStars specific;
# More importantly, they are currently valid for cash game only.
#####
# XXX: There was a weird problem with saved hand histories in PokerStars
# client 2.491; if a user was present on the table (and thus anywhere in
# the hand history), with non-standard characters in their username, the
# client would prepend a literal Ctrl-P (ASCII 16, 0x10) character to
# the hand history title line. Hence, to allow these strangely saved
# hands to be parsed and imported, there is a conditional "one extra
# character" allowed at the start of the new hand regex.
class FpdbRegex:
def __init__(self):
self.__GAME_INFO_REGEX=''
self.__SPLIT_HAND_REGEX='\n\n\n'
self.__NEW_HAND_REGEX='^.?PokerStars Game #\d+:\s+Hold\'em'
self.__HAND_INFO_REGEX='^.*#(\d+):\s+(\S+)\s([\s\S]+)\s\(\$?([.0-9]+)/\$?([.0-9]+)\)\s-\s(\S+)\s-?\s?(\S+)\s\(?(\w+)\)?'
self.__TABLE_INFO_REGEX='^\S+\s+\'.*\'\s+(\d+)-max\s+Seat\s#(\d+)'
self.__PLAYER_INFO_REGEX='^Seat\s(\d+):\s(.*)\s\(\$?([.\d]+)\s'
self.__POST_SB_REGEX='^(.*):\sposts small blind'
self.__POST_BB_REGEX='^(.*):\sposts big blind'
self.__POST_BOTH_REGEX='^(.*):\sposts small & big blinds'
self.__HAND_STAGE_REGEX='^\*{3}\s(.*)\s\*{3}'
self.__HOLE_CARD_REGEX='^\*{3}\sHOLE CARDS'
self.__FLOP_CARD_REGEX='^\*{3}\sFLOP\s\*{3}\s\[(\S{2})\s(\S{2})\s(\S{2})\]'
self.__TURN_CARD_REGEX='^\*{3}\sTURN\s\*{3}\s\[\S{2}\s\S{2}\s\S{2}\]\s\[(\S{2})\]'
self.__RIVER_CARD_REGEX='^\*{3}\sRIVER\s\*{3}\s\[\S{2}\s\S{2}\s\S{2}\s\S{2}\]\s\[(\S{2})\]'
self.__SHOWDOWN_REGEX='^\*{3}\sSHOW DOWN'
self.__SUMMARY_REGEX='^\*{3}\sSUMMARY'
self.__UNCALLED_BET_REGEX='^Uncalled bet \(\$([.\d]+)\) returned to (.*)'
self.__POT_AND_RAKE_REGEX='^Total\spot\s\$([.\d]+).*\|\sRake\s\$([.\d]+)'
self.__COLLECT_POT_REGEX='^(.*)\scollected\s\$([.\d]+)\sfrom\s((main|side)\s)?pot'
self.__HERO_CARDS_REGEX='^Dealt\sto\s(.*)\s\[(\S{2})\s(\S{2})\]'
self.__SHOWN_CARDS_REGEX='^(.*):\sshows\s\[(\S{2})\s(\S{2})\]'
self.__ACTION_STEP_REGEX='^(.*):\s(bets|checks|raises|calls|folds)((\s\$([.\d]+))?(\sto\s\$([.\d]+))?)?'
self.__SHOWDOWN_ACTION_REGEX='^(.*):\s(shows|mucks)'
self.__SUMMARY_CARDS_REGEX='^Seat\s\d+:\s(.*)\s(showed|mucked)\s\[(\S{2})\s(\S{2})\]'
self.__SUMMARY_CARDS_EXTRA_REGEX='^Seat\s\d+:\s(.*)\s(\(.*\)\s)(showed|mucked)\s\[(\S{2})\s(\S{2})\]'
def compileRegexes(self):
### Compile the regexes
self.game_info_re = re.compile(self.__GAME_INFO_REGEX)
self.split_hand_re = re.compile(self.__SPLIT_HAND_REGEX)
self.hand_start_re = re.compile(self.__NEW_HAND_REGEX)
self.hand_info_re = re.compile(self.__HAND_INFO_REGEX)
self.table_info_re = re.compile(self.__TABLE_INFO_REGEX)
self.player_info_re = re.compile(self.__PLAYER_INFO_REGEX)
self.small_blind_re = re.compile(self.__POST_SB_REGEX)
self.big_blind_re = re.compile(self.__POST_BB_REGEX)
self.both_blinds_re = re.compile(self.__POST_BOTH_REGEX)
self.hand_stage_re = re.compile(self.__HAND_STAGE_REGEX)
self.hole_cards_re = re.compile(self.__HOLE_CARD_REGEX)
self.flop_cards_re = re.compile(self.__FLOP_CARD_REGEX)
self.turn_card_re = re.compile(self.__TURN_CARD_REGEX)
self.river_card_re = re.compile(self.__RIVER_CARD_REGEX)
self.showdown_re = re.compile(self.__SHOWDOWN_REGEX)
self.summary_re = re.compile(self.__SUMMARY_REGEX)
self.uncalled_bet_re = re.compile(self.__UNCALLED_BET_REGEX)
self.collect_pot_re = re.compile(self.__COLLECT_POT_REGEX)
self.hero_cards_re = re.compile(self.__HERO_CARDS_REGEX)
self.cards_shown_re = re.compile(self.__SHOWN_CARDS_REGEX)
self.summary_cards_re = re.compile(self.__SUMMARY_CARDS_REGEX)
self.summary_cards_extra_re = re.compile(self.__SUMMARY_CARDS_EXTRA_REGEX)
self.action_re = re.compile(self.__ACTION_STEP_REGEX)
self.rake_re = re.compile(self.__POT_AND_RAKE_REGEX)
self.showdown_action_re = re.compile(self.__SHOWDOWN_ACTION_REGEX)
# Set methods for plugins to override
def setGameInfoRegex(self, string):
self.__GAME_INFO_REGEX = string
def setSplitHandRegex(self, string):
self.__SPLIT_HAND_REGEX = string
def setNewHandRegex(self, string):
self.__NEW_HAND_REGEX = string
def setHandInfoRegex(self, string):
self.__HAND_INFO_REGEX = string
def setTableInfoRegex(self, string):
self.__TABLE_INFO_REGEX = string
def setPlayerInfoRegex(self, string):
self.__PLAYER_INFO_REGEX = string
def setPostSbRegex(self, string):
self.__POST_SB_REGEX = string
def setPostBbRegex(self, string):
self.__POST_BB_REGEX = string
def setPostBothRegex(self, string):
self.__POST_BOTH_REGEX = string
def setHandStageRegex(self, string):
self.__HAND_STAGE_REGEX = string
def setHoleCardRegex(self, string):
self.__HOLE_CARD_REGEX = string
def setFlopCardRegex(self, string):
self.__FLOP_CARD_REGEX = string
def setTurnCardRegex(self, string):
self.__TURN_CARD_REGEX = string
def setRiverCardRegex(self, string):
self.__RIVER_CARD_REGEX = string
def setShowdownRegex(self, string):
self.__SHOWDOWN_REGEX = string
def setSummaryRegex(self, string):
self.__SUMMARY_REGEX = string
def setUncalledBetRegex(self, string):
self.__UNCALLED_BET_REGEX = string
def setCollectPotRegex(self, string):
self.__COLLECT_POT_REGEX = string
def setHeroCardsRegex(self, string):
self.__HERO_CARDS_REGEX = string
def setShownCardsRegex(self, string):
self.__SHOWN_CARDS_REGEX = string
def setSummaryCardsRegex(self, string):
self.__SUMMARY_CARDS_REGEX = string
def setSummaryCardsExtraRegex(self, string):
self.__SUMMARY_CARDS_EXTRA_REGEX = string
def setActionStepRegex(self, string):
self.__ACTION_STEP_REGEX = string
def setPotAndRakeRegex(self, string):
self.__POT_AND_RAKE_REGEX = string
def setShowdownActionRegex(self, string):
self.__SHOWDOWN_ACTION_REGEX = string

View File

@ -231,7 +231,12 @@ def discover_nt_by_name(c, tablename):
titles = {} titles = {}
win32gui.EnumWindows(win_enum_handler, titles) win32gui.EnumWindows(win_enum_handler, titles)
for hwnd in titles: for hwnd in titles:
print "Tbales.py: tablename =", tablename, "title =", titles[hwnd]
try:
# this can blow up in XP on some windows, eg firefox displaying http://docs.python.org/tutorial/classes.html
if not tablename in titles[hwnd]: continue if not tablename in titles[hwnd]: continue
except:
continue
if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window if 'History for table:' in titles[hwnd]: continue # Everleaf Network HH viewer window
if 'HUD:' in titles[hwnd]: continue # FPDB HUD window if 'HUD:' in titles[hwnd]: continue # FPDB HUD window
if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows if 'Chat:' in titles[hwnd]: continue # Some sites (FTP? PS? Others?) have seperable or seperately constructed chat windows

View File

@ -578,7 +578,7 @@ class fpdb_db:
self.cursor.execute( "lock tables Hands write" ) self.cursor.execute( "lock tables Hands write" )
except: except:
# Table 'fpdb.hands' doesn't exist # Table 'fpdb.hands' doesn't exist
if str(sys.exc_value).find(".hands' doesn't exist") >= 0: if str(sys.exc_value).find(".Hands' doesn't exist") >= 0:
return(2) return(2)
print "Error! failed to obtain global lock. Close all programs accessing " \ print "Error! failed to obtain global lock. Close all programs accessing " \
+ "database (including fpdb) and try again (%s)." \ + "database (including fpdb) and try again (%s)." \

View File

@ -394,7 +394,7 @@ class Importer:
self.hand=hand self.hand=hand
try: try:
handsId = fpdb_parse_logic.mainParser(self.settings, self.fdb.db handsId = fpdb_parse_logic.mainParser(self.settings['db-backend'], self.fdb.db
,self.fdb.cursor, self.siteIds[site], category, hand, self.config) ,self.fdb.cursor, self.siteIds[site], category, hand, self.config)
self.fdb.db.commit() self.fdb.db.commit()

View File

@ -35,6 +35,7 @@ def mainParser(settings, db, cursor, siteID, category, hand, config):
#part 1: read hand no and check for duplicate #part 1: read hand no and check for duplicate
siteHandNo = fpdb_simple.parseSiteHandNo(hand[0]) siteHandNo = fpdb_simple.parseSiteHandNo(hand[0])
#print "siteHandNo =", siteHandNo
handStartTime = fpdb_simple.parseHandStartTime(hand[0]) handStartTime = fpdb_simple.parseHandStartTime(hand[0])
isTourney = fpdb_simple.isTourney(hand[0]) isTourney = fpdb_simple.isTourney(hand[0])
@ -127,6 +128,7 @@ def mainParser(settings, db, cursor, siteID, category, hand, config):
totalWinnings = sum(winnings) totalWinnings = sum(winnings)
# if hold'em, use positions and not antes, if stud do not use positions, use antes # if hold'em, use positions and not antes, if stud do not use positions, use antes
# this is used for handsplayers inserts, so still needed even if hudcache update is being skipped
if base == "hold": if base == "hold":
hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes hudImportData = fpdb_simple.generateHudCacheData(playerIDs, base, category, actionTypes
, allIns, actionTypeByNo, winnings, totalWinnings, positions , allIns, actionTypeByNo, winnings, totalWinnings, positions

View File

@ -34,12 +34,11 @@ saveActions = True # set this to False to avoid storing action data
# variance not available on stats page # variance not available on stats page
# : No graphs # : No graphs
#stores a stud/razz hand into the database #stores a stud/razz hand into the database
def ring_stud(config, settings, db, cursor, base, category, site_hand_no, gametype_id, hand_start_time def ring_stud(config, backend, db, cursor, base, category, site_hand_no, gametype_id, hand_start_time
,names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes ,names, player_ids, start_cashes, antes, card_values, card_suits, winnings, rakes
,action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName ,action_types, allIns, action_amounts, actionNos, hudImportData, maxSeats, tableName
,seatNos): ,seatNos):
backend = settings['db-backend']
import_options = config.get_import_parameters() import_options = config.get_import_parameters()
saveActions = False if import_options['saveActions'] == False else True saveActions = False if import_options['saveActions'] == False else True
@ -55,7 +54,6 @@ def ring_stud(config, settings, db, cursor, base, category, site_hand_no, gamety
,start_cashes, antes, card_values ,start_cashes, antes, card_values
,card_suits, winnings, rakes, seatNos) ,card_suits, winnings, rakes, seatNos)
if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop':
fpdb_simple.storeHudCache(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) fpdb_simple.storeHudCache(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
if saveActions: if saveActions:
@ -64,13 +62,12 @@ def ring_stud(config, settings, db, cursor, base, category, site_hand_no, gamety
return hands_id return hands_id
#end def ring_stud #end def ring_stud
def ring_holdem_omaha(config, settings, db, cursor, base, category, site_hand_no, gametype_id def ring_holdem_omaha(config, backend, db, cursor, base, category, site_hand_no, gametype_id
,hand_start_time, names, player_ids, start_cashes, positions, card_values ,hand_start_time, names, player_ids, start_cashes, positions, card_values
,card_suits, board_values, board_suits, winnings, rakes, action_types, allIns ,card_suits, board_values, board_suits, winnings, rakes, action_types, allIns
,action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos): ,action_amounts, actionNos, hudImportData, maxSeats, tableName, seatNos):
"""stores a holdem/omaha hand into the database""" """stores a holdem/omaha hand into the database"""
backend = settings['db-backend']
import_options = config.get_import_parameters() import_options = config.get_import_parameters()
saveActions = False if import_options['saveActions'] == False else True saveActions = False if import_options['saveActions'] == False else True
fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False
@ -93,7 +90,6 @@ def ring_holdem_omaha(config, settings, db, cursor, base, category, site_hand_no
, positions, card_values, card_suits, winnings, rakes, seatNos, hudImportData) , positions, card_values, card_suits, winnings, rakes, seatNos, hudImportData)
t4 = time() t4 = time()
#print "ring holdem, backend=%d" % backend #print "ring holdem, backend=%d" % backend
if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop':
if fastStoreHudCache: if fastStoreHudCache:
fpdb_simple.storeHudCache2(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) fpdb_simple.storeHudCache2(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
else: else:
@ -108,7 +104,7 @@ def ring_holdem_omaha(config, settings, db, cursor, base, category, site_hand_no
return hands_id return hands_id
#end def ring_holdem_omaha #end def ring_holdem_omaha
def tourney_holdem_omaha(config, settings, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout def tourney_holdem_omaha(config, backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout
,entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId ,entries, prizepool, tourney_start, payin_amounts, ranks, tourneyTypeId
,siteId #end of tourney specific params ,siteId #end of tourney specific params
,site_hand_no, gametype_id, hand_start_time, names, player_ids ,site_hand_no, gametype_id, hand_start_time, names, player_ids
@ -117,7 +113,6 @@ def tourney_holdem_omaha(config, settings, db, cursor, base, category, siteTourn
,actionNos, hudImportData, maxSeats, tableName, seatNos): ,actionNos, hudImportData, maxSeats, tableName, seatNos):
"""stores a tourney holdem/omaha hand into the database""" """stores a tourney holdem/omaha hand into the database"""
backend = settings['db-backend']
import_options = config.get_import_parameters() import_options = config.get_import_parameters()
saveActions = True if import_options['saveActions'] == True else False saveActions = True if import_options['saveActions'] == True else False
fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False
@ -136,7 +131,6 @@ def tourney_holdem_omaha(config, settings, db, cursor, base, category, siteTourn
, card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids) , card_values, card_suits, winnings, rakes, seatNos, tourneys_players_ids)
#print "tourney holdem, backend=%d" % backend #print "tourney holdem, backend=%d" % backend
if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop':
if fastStoreHudCache: if fastStoreHudCache:
fpdb_simple.storeHudCache2(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData) fpdb_simple.storeHudCache2(backend, cursor, base, category, gametype_id, hand_start_time, player_ids, hudImportData)
else: else:
@ -149,14 +143,13 @@ def tourney_holdem_omaha(config, settings, db, cursor, base, category, siteTourn
return hands_id return hands_id
#end def tourney_holdem_omaha #end def tourney_holdem_omaha
def tourney_stud(config, settings, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries def tourney_stud(config, backend, db, cursor, base, category, siteTourneyNo, buyin, fee, knockout, entries
,prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId ,prizepool, tourneyStartTime, payin_amounts, ranks, tourneyTypeId, siteId
,siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes ,siteHandNo, gametypeId, handStartTime, names, playerIds, startCashes, antes
,cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts ,cardValues, cardSuits, winnings, rakes, actionTypes, allIns, actionAmounts
,actionNos, hudImportData, maxSeats, tableName, seatNos): ,actionNos, hudImportData, maxSeats, tableName, seatNos):
#stores a tourney stud/razz hand into the database #stores a tourney stud/razz hand into the database
backend = settings['db-backend']
import_options = config.get_import_parameters() import_options = config.get_import_parameters()
saveActions = True if import_options['saveActions'] == True else False saveActions = True if import_options['saveActions'] == True else False
fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False fastStoreHudCache = True if import_options['fastStoreHudCache'] == True else False
@ -173,7 +166,6 @@ def tourney_stud(config, settings, db, cursor, base, category, siteTourneyNo, bu
, playerIds, startCashes, antes, cardValues, cardSuits , playerIds, startCashes, antes, cardValues, cardSuits
, winnings, rakes, seatNos, tourneys_players_ids) , winnings, rakes, seatNos, tourneys_players_ids)
if 'updateHudCache' not in settings or settings['updateHudCache'] != 'drop':
fpdb_simple.storeHudCache(backend, cursor, base, category, gametypeId, hand_start_time, playerIds, hudImportData) fpdb_simple.storeHudCache(backend, cursor, base, category, gametypeId, hand_start_time, playerIds, hudImportData)
if saveActions: if saveActions:

View File

@ -2393,7 +2393,7 @@ def storeHudCache2(backend, cursor, base, category, gametypeId, hand_start_time,
# Try to do the update first: # Try to do the update first:
num = cursor.execute("""UPDATE HudCache num = cursor.execute("""UPDATE HudCache
SET HDs=HDs+%s, street0VPI=street0VPI+%s, street0Aggr=street0Aggr+%s, SET HDs=HDs+%s, street0VPI=street0VPI+%s, street0Aggr=street0Aggr+%s,
street0_3B4BChance=street0_3B4BChance+%s, street0_3B4BDone=street0_3B4BDone+%s, street0_3BChance=street0_3BChance+%s, street0_3BDone=street0_3BDone+%s,
street1Seen=street1Seen+%s, street2Seen=street2Seen+%s, street3Seen=street3Seen+%s, street1Seen=street1Seen+%s, street2Seen=street2Seen+%s, street3Seen=street3Seen+%s,
street4Seen=street4Seen+%s, sawShowdown=sawShowdown+%s, street4Seen=street4Seen+%s, sawShowdown=sawShowdown+%s,
street1Aggr=street1Aggr+%s, street2Aggr=street2Aggr+%s, street3Aggr=street3Aggr+%s, street1Aggr=street1Aggr+%s, street2Aggr=street2Aggr+%s, street3Aggr=street3Aggr+%s,