rushnotes: initial commit (for testing and eval only)
This commit is contained in:
parent
744e5292ef
commit
36e2ef3f35
216
pyfpdb/RushNotesAux.py
Normal file
216
pyfpdb/RushNotesAux.py
Normal file
|
@ -0,0 +1,216 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""RushNotesAux.py
|
||||||
|
|
||||||
|
EXPERIMENTAL - USE WITH CARE
|
||||||
|
|
||||||
|
Auxilliary process to push HUD data into the FullTilt player notes XML
|
||||||
|
This will allow a rudimentary "HUD" in rush games
|
||||||
|
|
||||||
|
The existing notes file will be altered by this function
|
||||||
|
"""
|
||||||
|
# Copyright 2010, "Gimick" of the FPDB project fpdb.sourceforge.net
|
||||||
|
#
|
||||||
|
#This program is free software: you can redistribute it and/or modify
|
||||||
|
#it under the terms of the GNU Affero General Public License as published by
|
||||||
|
#the Free Software Foundation, version 3 of the License.
|
||||||
|
#
|
||||||
|
#This program is distributed in the hope that it will be useful,
|
||||||
|
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
#GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
#You should have received a copy of the GNU Affero General Public License
|
||||||
|
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#In the "official" distribution you can find the license in agpl-3.0.txt.
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
##########for each hand processed, attempts to update hero.xml player notes for FullTilt
|
||||||
|
##########based upon the AW howto notes written by Ray E. Barker (nutomatic) at fpdb.sourceforge.net
|
||||||
|
|
||||||
|
#to do
|
||||||
|
### think about seeding
|
||||||
|
### multiple huds firing at the same xml
|
||||||
|
### same player / two levels / only one xml
|
||||||
|
### http://www.faqs.org/docs/diveintopython/kgp_search.html
|
||||||
|
|
||||||
|
#debugmode will write logfiles for the __init__ and update_data methods
|
||||||
|
debugmode = False
|
||||||
|
|
||||||
|
# Standard Library modules
|
||||||
|
import os
|
||||||
|
from xml.dom import minidom
|
||||||
|
from datetime import datetime
|
||||||
|
from time import *
|
||||||
|
|
||||||
|
# FreePokerDatabase modules
|
||||||
|
from Mucked import Aux_Window
|
||||||
|
from Mucked import Seat_Window
|
||||||
|
from Mucked import Aux_Seats
|
||||||
|
import Stats
|
||||||
|
|
||||||
|
class RushNotes(Aux_Window):
|
||||||
|
|
||||||
|
def __init__(self, hud, config, params):
|
||||||
|
|
||||||
|
self.hud = hud
|
||||||
|
self.config = config
|
||||||
|
|
||||||
|
#
|
||||||
|
# following line makes all the site params magically available (thanks Ray!)
|
||||||
|
#
|
||||||
|
site_params_dict = self.hud.config.get_site_parameters(self.hud.site)
|
||||||
|
|
||||||
|
heroname = site_params_dict['screen_name']
|
||||||
|
sitename = site_params_dict['site_name']
|
||||||
|
notepath = site_params_dict['site_path'] # this is a temporary hijack of site-path
|
||||||
|
notepath = r"/home/steve/.wine/drive_c/Program Files/Full Tilt Poker/"
|
||||||
|
self.heroid = self.hud.db_connection.get_player_id(self.config, sitename, heroname)
|
||||||
|
self.notefile = notepath + "/" + heroname + ".xml"
|
||||||
|
|
||||||
|
#
|
||||||
|
# read in existing notefile and backup with date/time in name
|
||||||
|
# todo change to not use dom
|
||||||
|
#
|
||||||
|
now = datetime.now()
|
||||||
|
notefilebackup = self.notefile + ".backup." + now.strftime("%Y%m%d%H%M%S")
|
||||||
|
xmlnotefile = minidom.parse(self.notefile)
|
||||||
|
outputfile = open(notefilebackup, 'w')
|
||||||
|
xmlnotefile.writexml(outputfile)
|
||||||
|
outputfile.close()
|
||||||
|
xmlnotefile.unlink
|
||||||
|
|
||||||
|
# Create a fresh queue file with skeleton XML
|
||||||
|
#
|
||||||
|
self.queuefile = self.notefile + ".queue"
|
||||||
|
queuedom = minidom.Document()
|
||||||
|
# Create the minidom document
|
||||||
|
|
||||||
|
# Create the <wml> base element
|
||||||
|
pld=queuedom.createElement("PLAYERDATA")
|
||||||
|
queuedom.appendChild(pld)
|
||||||
|
|
||||||
|
nts=queuedom.createElement("NOTES")
|
||||||
|
pld.appendChild(nts)
|
||||||
|
|
||||||
|
nte = queuedom.createElement("NOTE")
|
||||||
|
nte = queuedom.createTextNode("\n")
|
||||||
|
nts.insertBefore(nte,None)
|
||||||
|
|
||||||
|
outputfile = open(self.queuefile, 'w')
|
||||||
|
queuedom.writexml(outputfile)
|
||||||
|
outputfile.close()
|
||||||
|
queuedom.unlink
|
||||||
|
|
||||||
|
if (debugmode):
|
||||||
|
#initialise logfiles
|
||||||
|
debugfile=open("~Rushdebug.init", "w")
|
||||||
|
debugfile.write("conf="+str(config)+"\n")
|
||||||
|
debugfile.write("spdi="+str(site_params_dict)+"\n")
|
||||||
|
debugfile.write("para="+str(params)+"\n")
|
||||||
|
debugfile.write("hero="+heroname+" "+str(self.heroid)+"\n")
|
||||||
|
debugfile.write("back="+notefilebackup+"\n")
|
||||||
|
debugfile.write("queu="+self.queuefile+"\n")
|
||||||
|
debugfile.close()
|
||||||
|
|
||||||
|
open("~Rushdebug.data", "w").close()
|
||||||
|
|
||||||
|
|
||||||
|
def update_data(self, new_hand_id, db_connection):
|
||||||
|
#this method called once for every hand processed
|
||||||
|
# self.hud.stat_dict contains the stats information for this hand
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (debugmode):
|
||||||
|
debugfile=open("~Rushdebug.data", "a")
|
||||||
|
debugfile.write(new_hand_id+"\n")
|
||||||
|
now = datetime.now()
|
||||||
|
debugfile.write(now.strftime("%Y%m%d%H%M%S")+ " update_data begins"+ "\n")
|
||||||
|
debugfile.write("hero="+str(self.heroid)+"\n")
|
||||||
|
#debugfile.write(str(self.hud.stat_dict)+"\n")
|
||||||
|
debugfile.write(self.hud.table.name+"\n")
|
||||||
|
debugfile.write(str(self.hud.stat_dict.keys())+"\n")
|
||||||
|
|
||||||
|
if self.hud.table.name not in {"Mach 10", "Lightning", "Celerity", "Flash", "Zoom"}
|
||||||
|
return
|
||||||
|
#
|
||||||
|
# Grab a list of player id's
|
||||||
|
#
|
||||||
|
handplayers = self.hud.stat_dict.keys()
|
||||||
|
|
||||||
|
#
|
||||||
|
# build a dictionary of stats text for each player in the hand (excluding the hero)
|
||||||
|
# xmlqueuedict contains {playername : stats text}
|
||||||
|
#
|
||||||
|
xmlqueuedict = {}
|
||||||
|
for playerid in handplayers:
|
||||||
|
# ignore hero, no notes available for hero at Full Tilt
|
||||||
|
if playerid == self.heroid: continue
|
||||||
|
|
||||||
|
playername=unicode(str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'playername')[1]))
|
||||||
|
# Use index[3] which is a short description
|
||||||
|
n=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'n')[3] + " ")
|
||||||
|
vpip=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'vpip')[3] + " ")
|
||||||
|
pfr=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'pfr')[3] + " ")
|
||||||
|
three_B=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'three_B')[3] + " ")
|
||||||
|
cbet=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'cbet')[3] + " ")
|
||||||
|
steal=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'steal')[3] + " ")
|
||||||
|
ffreq1=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'ffreq1')[3] + " ")
|
||||||
|
agg_freq=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'agg_freq')[3] + " ")
|
||||||
|
BBper100=str(Stats.do_stat(self.hud.stat_dict, player = playerid, stat = 'BBper100')[3] + " ")
|
||||||
|
|
||||||
|
xmlqueuedict[playername] = "~fpdb~" + n + vpip + pfr + three_B + cbet + steal + ffreq1 + agg_freq + BBper100 + "~ends~"
|
||||||
|
|
||||||
|
if (debugmode):
|
||||||
|
now = datetime.now()
|
||||||
|
debugfile.write(now.strftime("%Y%m%d%H%M%S")+" villain data has been processed" + "\n")
|
||||||
|
debugfile.write(str(xmlqueuedict)+"\n")
|
||||||
|
|
||||||
|
#
|
||||||
|
# delaying processing of xml until now. Grab current queuefile contents and
|
||||||
|
# read each existing NOTE element in turn, if matched to a player in xmlqueuedict
|
||||||
|
# update their text in the xml and delete the dictionary item
|
||||||
|
#
|
||||||
|
xmlnotefile = minidom.parse(self.queuefile)
|
||||||
|
notelist = xmlnotefile.getElementsByTagName('NOTE')
|
||||||
|
|
||||||
|
for noteentry in notelist: #for each note in turn
|
||||||
|
noteplayer = noteentry.getAttribute("PlayerId") #extract the playername from xml
|
||||||
|
if noteplayer in xmlqueuedict: # does that player exist in the queue?
|
||||||
|
noteentry.setAttribute("Text",xmlqueuedict[noteplayer])
|
||||||
|
del xmlqueuedict[noteplayer] #remove from list, does not need to be added later on
|
||||||
|
|
||||||
|
#
|
||||||
|
#create entries for new players (those remaining in the dictionary)
|
||||||
|
#
|
||||||
|
if len(xmlqueuedict) > 0:
|
||||||
|
playerdata=xmlnotefile.lastChild #move to the PLAYERDATA node (assume last one in the list)
|
||||||
|
notesnode=playerdata.childNodes[0] #Find NOTES node
|
||||||
|
|
||||||
|
for newplayer in xmlqueuedict:
|
||||||
|
newentry = xmlnotefile.createElement("NOTE")
|
||||||
|
newentry.setAttribute("PlayerId", newplayer)
|
||||||
|
newentry.setAttribute("Text", xmlqueuedict[newplayer])
|
||||||
|
notesnode.insertBefore(newentry,None)
|
||||||
|
newentry = xmlnotefile.createTextNode("\n")
|
||||||
|
notesnode.insertBefore(newentry,None)
|
||||||
|
|
||||||
|
if (debugmode):
|
||||||
|
now = datetime.now()
|
||||||
|
debugfile.write(now.strftime("%Y%m%d%H%M%S")+" xml pre-processing complete"+ "\n")
|
||||||
|
|
||||||
|
#
|
||||||
|
# OverWrite existing xml file with updated DOM and cleanup
|
||||||
|
#
|
||||||
|
updatednotes = open(self.queuefile, 'w')
|
||||||
|
xmlnotefile.writexml(updatednotes)
|
||||||
|
updatednotes.close()
|
||||||
|
|
||||||
|
xmlnotefile.unlink
|
||||||
|
|
||||||
|
if (debugmode):
|
||||||
|
now = datetime.now()
|
||||||
|
debugfile.write(now.strftime("%Y%m%d%H%M%S")+" dom written, process finished"+ "\n")
|
||||||
|
debugfile.close()
|
122
pyfpdb/RushNotesMerge.py
Executable file
122
pyfpdb/RushNotesMerge.py
Executable file
|
@ -0,0 +1,122 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""RushNotesMerge.py
|
||||||
|
|
||||||
|
EXPERIMENTAL - USE WITH CARE
|
||||||
|
|
||||||
|
Merge .queue file with hero's note to generate fresh .merge file
|
||||||
|
|
||||||
|
normal usage
|
||||||
|
$> ./pyfpdb/RushNotesMerge.py "/home/steve/.wine/drive_c/Program Files/Full Tilt Poker/heroname.xml"
|
||||||
|
|
||||||
|
The generated file can then replace heroname.xml (if all is well).
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
# Copyright 2010, "Gimick" of the FPDB project fpdb.sourceforge.net
|
||||||
|
#
|
||||||
|
#This program is free software: you can redistribute it and/or modify
|
||||||
|
#it under the terms of the GNU Affero General Public License as published by
|
||||||
|
#the Free Software Foundation, version 3 of the License.
|
||||||
|
#
|
||||||
|
#This program is distributed in the hope that it will be useful,
|
||||||
|
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
#GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
#You should have received a copy of the GNU Affero General Public License
|
||||||
|
#along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#In the "official" distribution you can find the license in agpl-3.0.txt.
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# Standard Library modules
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from xml.dom import minidom
|
||||||
|
|
||||||
|
statqueue=0
|
||||||
|
statupdated=0
|
||||||
|
statadded=0
|
||||||
|
|
||||||
|
def cleannote(textin):
|
||||||
|
if textin.find("~fpdb~") == -1: return textin
|
||||||
|
if textin.find("~ends~") == -1: return textin
|
||||||
|
if textin.find("~fpdb~") > textin.find("~ends~"): return textin
|
||||||
|
return textin[0:textin.find("~fpdb~")] + textin[textin.find("~ends~")+6:]
|
||||||
|
# get out now if parameter not passed
|
||||||
|
try:
|
||||||
|
sys.argv[1] <> ""
|
||||||
|
except:
|
||||||
|
print "A parameter is required, quitting now"
|
||||||
|
quit()
|
||||||
|
|
||||||
|
if not os.path.isfile(sys.argv[1]):
|
||||||
|
print "Hero notes file not found, quitting"
|
||||||
|
quit()
|
||||||
|
|
||||||
|
if not os.path.isfile((sys.argv[1]+".queue")):
|
||||||
|
print "Nothing queued, quitting"
|
||||||
|
quit()
|
||||||
|
|
||||||
|
print "reading from: ", sys.argv[1]
|
||||||
|
print "merging with: ", sys.argv[1]+".queue"
|
||||||
|
|
||||||
|
#read queue and turn into a dict
|
||||||
|
queuedict = {}
|
||||||
|
xmlqueue = minidom.parse(sys.argv[1]+".queue")
|
||||||
|
notelist = xmlqueue.getElementsByTagName('NOTE')
|
||||||
|
|
||||||
|
for noteentry in notelist:
|
||||||
|
noteplayer = noteentry.getAttribute("PlayerId")
|
||||||
|
notetext = noteentry.getAttribute("Text")
|
||||||
|
queuedict[noteplayer] = notetext
|
||||||
|
statqueue = statqueue + 1
|
||||||
|
|
||||||
|
#read existing player note file
|
||||||
|
|
||||||
|
xmlnotefile = minidom.parse(sys.argv[1])
|
||||||
|
notelist = xmlnotefile.getElementsByTagName('NOTE')
|
||||||
|
|
||||||
|
#
|
||||||
|
#for existing players, empty out existing fpdbtext and refill
|
||||||
|
#
|
||||||
|
for noteentry in notelist:
|
||||||
|
noteplayer = noteentry.getAttribute("PlayerId")
|
||||||
|
if noteplayer in queuedict:
|
||||||
|
existingnote = noteentry.getAttribute("Text")
|
||||||
|
newnote=cleannote(existingnote)
|
||||||
|
newnote = newnote + queuedict[noteplayer]
|
||||||
|
noteentry.setAttribute("Text",newnote)
|
||||||
|
statupdated = statupdated + 1
|
||||||
|
del queuedict[noteplayer]
|
||||||
|
|
||||||
|
#
|
||||||
|
#create entries for new players (those remaining in the dictionary)
|
||||||
|
#
|
||||||
|
if len(queuedict) > 0:
|
||||||
|
playerdata=xmlnotefile.lastChild #move to the PLAYERDATA node (assume last one in the list)
|
||||||
|
notesnode=playerdata.childNodes[1] #Find NOTES node
|
||||||
|
|
||||||
|
for newplayer in queuedict:
|
||||||
|
newentry = xmlnotefile.createElement("NOTE")
|
||||||
|
newentry.setAttribute("PlayerId", newplayer)
|
||||||
|
newentry.setAttribute("Text", queuedict[newplayer])
|
||||||
|
notesnode.insertBefore(newentry,None)
|
||||||
|
newentry = xmlnotefile.createTextNode("\n")
|
||||||
|
notesnode.insertBefore(newentry,None)
|
||||||
|
statadded=statadded+1
|
||||||
|
|
||||||
|
#print xmlnotefile.toprettyxml()
|
||||||
|
|
||||||
|
mergednotes = open(sys.argv[1]+".merged", 'w')
|
||||||
|
xmlnotefile.writexml(mergednotes)
|
||||||
|
mergednotes.close()
|
||||||
|
|
||||||
|
xmlnotefile.unlink
|
||||||
|
|
||||||
|
print "new file has been written to: ", sys.argv[1]+".merged"
|
||||||
|
print "number in queue: ", statqueue
|
||||||
|
print "existing players updated: ", statupdated
|
||||||
|
print "new players added: ", statadded
|
166
pyfpdb/RushNotesReadMe.txt
Normal file
166
pyfpdb/RushNotesReadMe.txt
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
aux to write fpdb data to player notes on Full Tilt
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
by Gimick 30th Dec 2010
|
||||||
|
|
||||||
|
RushNotesAux - auxillary processed attached to the full tilt hud
|
||||||
|
builds up fpdb notes "queue" for each villain met while the autoimport is running
|
||||||
|
uses HUD aggregation stats to do this
|
||||||
|
|
||||||
|
RushNotesMerge - stand alone process to merge the existing ftp notes, together with queue
|
||||||
|
produced by Aux.
|
||||||
|
the output file can then be renamed to become the new ftp notes file
|
||||||
|
|
||||||
|
Important info:
|
||||||
|
The Merge process can only be run when ftp client is shutdown - otherwise ftp overwrites the xml on exit.
|
||||||
|
|
||||||
|
Restarting the autoimport will empty the notes"queue" so avoid restarting autoimport until the previous
|
||||||
|
notes "queue" has been merged.
|
||||||
|
|
||||||
|
Existing ftp notes _SHOULD_ be preserved, but this isn't guaranteed, you have been warned
|
||||||
|
Existing colour codings should be preserved, this process should not change colourcodings.
|
||||||
|
|
||||||
|
Copies of the live ftp notes file are preserved everytime RushNotesAux is started, just in case.
|
||||||
|
|
||||||
|
The AW is hard-coded with just the table names of Micro Rush Poker, and should ignore all other hands.
|
||||||
|
|
||||||
|
Getting started:
|
||||||
|
---------------
|
||||||
|
|
||||||
|
1. Set the Hero aggregation to alltime. hero_stat_range="A"
|
||||||
|
This overcomes a sqlite "bug" which has nothing to do with auxillary windows - not doing this
|
||||||
|
will slow processing down to about 1 hand per minute.
|
||||||
|
|
||||||
|
2. Set the site_path to be the folder containing the FTP notes xml file
|
||||||
|
(on wine this is normally site_path="/home/blah/.wine/Program Files/Full Tilt Poker/")
|
||||||
|
|
||||||
|
|
||||||
|
Wire-up the aux process:
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
<aw class="RushNotes" module="RushNotesAux" name="Rush1"> </aw>
|
||||||
|
<game aux="Rush1" cols="3" db="fpdb" game_name="holdem" rows="3">
|
||||||
|
|
||||||
|
or whatever works for you.
|
||||||
|
|
||||||
|
Start Autoimport, and rearrange the on-screen stats out of the way
|
||||||
|
(killing the HUD kills the AW updates)
|
||||||
|
|
||||||
|
Play some poker
|
||||||
|
|
||||||
|
Stop the autoimport
|
||||||
|
Exit the Full tilt poker client (ensure it has fully stopped with ps -A)
|
||||||
|
|
||||||
|
execute the following:
|
||||||
|
|
||||||
|
./pyfpdb/RushNotesMerge.py "/home/foo/.wine/drive_c/Program Files/Full Tilt Poker/myname.xml"
|
||||||
|
|
||||||
|
A revised notes file (blah.merge) should automagically appear in the full tilt root directory.
|
||||||
|
If you are happy with it, replace the existing (myname.xml file)
|
||||||
|
|
||||||
|
|
||||||
|
Summary
|
||||||
|
------
|
||||||
|
|
||||||
|
This is very rough and ready, but it does what I set-out to achieve.
|
||||||
|
|
||||||
|
All feedback welcome, and if this is useful as a basis for general notes processing, then thats great.
|
||||||
|
|
||||||
|
As I find bugs and make improvements, I will push to the git branch.
|
||||||
|
|
||||||
|
|
||||||
|
Much more information below:
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Background
|
||||||
|
----------
|
||||||
|
|
||||||
|
When playing rush poker, some sort of rudimentary HUD would answer simple questions
|
||||||
|
like "is this allin overbet being made by a nit, or a maniac". Although some
|
||||||
|
notes may have been made previously, some statistics would help to backup the decision.
|
||||||
|
|
||||||
|
Currently fpdb cannot support rush because the HUD is always 1 hand or more
|
||||||
|
behind the current action.
|
||||||
|
|
||||||
|
The only way to do this at the moment is to switch to GuiPlayerStats and make a quick
|
||||||
|
enquiry by player name. However, this effectively times you out of all other
|
||||||
|
action if multitabling.
|
||||||
|
|
||||||
|
Full Tilt situation
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Full Tilt notes are stored in xml format ("hero.xml"). Previously these could
|
||||||
|
be updated while the game was in progress, however, FullTilt now cache the
|
||||||
|
notes and write them out when the application exits. This makes it impossible
|
||||||
|
to use the notes as a real-time HUD, and therefore real-time huds are now
|
||||||
|
forced to screen-scrape or poke around in the client memory.
|
||||||
|
|
||||||
|
Accepting this a limitation, this implementation updates the notes only once
|
||||||
|
the FullTilt client has been closed. Obviously, the villain HUD stats are only
|
||||||
|
as at the end of the last session, however, it is hoped this is significantly
|
||||||
|
better than having nothing at all. As the hero's hand history increases, the
|
||||||
|
notes should progressively mature in accuracy.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
--------
|
||||||
|
|
||||||
|
Note that this implementation was written purely to be "good enough" to work
|
||||||
|
for the author, and is not intended as package or production quality. It
|
||||||
|
is contributed as a starting point for others, or for experimental use.
|
||||||
|
|
||||||
|
Thanks to Ray Barker who gave a great deal of help throughout.
|
||||||
|
|
||||||
|
|
||||||
|
The implementation
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
RushNotesAux is an fpdb auxilliary process, and is called for every hand
|
||||||
|
processed by autoimport. Each villain has a note prepared based on the current
|
||||||
|
fpdb data, and this note (in XML format) is stored in a queue file.
|
||||||
|
|
||||||
|
Auxilliary windows were chosen because
|
||||||
|
a) the author has limited fpdb and programming skill
|
||||||
|
b) the auxillary windows handler is well documented and supported
|
||||||
|
c) any code created has access to the full range of stats with little or no extra work
|
||||||
|
d) runs within the HUD, so the aggregation parameters are already available
|
||||||
|
|
||||||
|
|
||||||
|
Limitations
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The notes are only regenerated if a hand is played against the villain. The
|
||||||
|
process does not "bulk load" notes based upon all the player stats in FPDB.
|
||||||
|
|
||||||
|
It is hoped that due to the relatively large hand volume and relatively small
|
||||||
|
player pools, this limitation will be largely overcome after a few sessions
|
||||||
|
although there will obviously be a number of players with no fpdb note.
|
||||||
|
|
||||||
|
The aggregation parameters used for the notes are based upon the HUD parameters.
|
||||||
|
|
||||||
|
Stopping and starting the HUD will erase the previously created notes holding file.
|
||||||
|
|
||||||
|
The HUD must run, so the individual player popups need to be manually relocated.
|
||||||
|
|
||||||
|
Although hard-coded for micro RUSH tablenames, the auxilliary window will
|
||||||
|
probably happily update notes of all cash and tournament players.
|
||||||
|
|
||||||
|
Process overview
|
||||||
|
----------------
|
||||||
|
|
||||||
|
1/ The HUD process is started.
|
||||||
|
1.1/ when the first hand is received, h fresh holding file is created, and
|
||||||
|
a copy of the current live xml note file is created as a security backup.
|
||||||
|
2/ For every hand played, the auxillary window is called
|
||||||
|
3/ Based upon the players in the hand, fpdb will be interrogated
|
||||||
|
and key stats are formatted in xml-style and written out to a holding file.
|
||||||
|
4/ At the end of the session, the HUD is stopped and the poker client closed
|
||||||
|
|
||||||
|
5/ The user can then review the contents of the holding file.
|
||||||
|
6/ A process is begun to "merge" the holding file into the existing player notes
|
||||||
|
7/ A new "merged" file is created. The process attempts to preserve any
|
||||||
|
existing notes, but this cannot be guaranteed.
|
||||||
|
8/ The user can review this merged file, and if they are happy,
|
||||||
|
they replace the existing note file.
|
||||||
|
9/ Note that this process never updates the live notes file in situ, but
|
||||||
|
there is a risk that something goes wrong, and that existing notes could be destroyed.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user