예제 #1
0
class PokerClientFactory(UGAMEClientFactory):
    "client factory"

    def __init__(self, *args, **kwargs):
        UGAMEClientFactory.__init__(self, *args, **kwargs)
        self.settings = kwargs["settings"]
        self.config = kwargs.get("config", None)
        #
        # Make sure the attributes exists, should an exception occur before
        # it is initialized. This is done
        # so that the caller does not have to check the existence of the
        # attribute when catching an exception.
        #
        self.crashing = False

        settings = self.settings
        self.ping_delay = settings.headerGetInt("/settings/@ping")
        self.no_display_packets = settings.headerGet("/settings/@no_display_packets")
        self.name = settings.headerGet("/settings/name")
        self.password = settings.headerGet("/settings/passwd")
        if self.config:
            chips_values = self.config.headerGet("/sequence/chips")
            if not chips_values:
                raise UserWarning, "PokerClientFactory: no /sequence/chips found in %s" % self.config.path
            self.chips_values = map(int, chips_values.split())
        else:
            self.chips_values = [1]
        self.host = "unknown"
        self.port = 0
        self.remember = settings.headerGet("/settings/remember") == "yes"
        self.chat_config = settings.headerGetProperties("/settings/chat")
        if self.chat_config:
            self.chat_config = self.chat_config[0]
            for (key, value) in self.chat_config.iteritems():
                self.chat_config[key] = int(value)
        else:
            self.chat_config = {}
        self.dirs = split(self.settings.headerGet("/settings/path"))
        self.verbose = self.settings.headerGetInt("/settings/@verbose")
        self.delays = self.settings.headerGetProperties("/settings/delays")
        if self.delays:
            self.delays = self.delays[0]
            for (key, value) in self.delays.iteritems():
                self.delays[key] = float(value)
            if self.delays.has_key("round"):
                self.delays["end_round"] = self.delays["round"]
                self.delays["begin_round"] = self.delays["round"]
                del self.delays["round"]
            if not self.delays.has_key("blind_ante_position"):
                self.delays["blind_ante_position"] = self.delays["position"]
        else:
            self.delays = {}
        if self.verbose > 2:
            self.message("PokerClient: delays %s" % self.delays)
        self.delays_enable = self.settings.headerGet("/settings/@delays") == "true"
        self.skin = PokerSkin(settings = self.settings)
        self.protocol = PokerClientProtocol
        self.games = PokerGames(dirs = self.dirs, verbose = self.verbose)
        self.file2name = {}
        self.first_time = self.settings.headerGet("/settings/name") == "username"
        self.played_time = self.settings.headerGet("/settings/played_time")

    def __del__(self):
        if hasattr(self, "games"):
            del self.games

    def buildProtocol(self, addr):
        protocol = UGAMEClientFactory.buildProtocol(self, addr)
        protocol.explain.chips_values = self.chips_values
        protocol.explain.games = self.games
        protocol.explain.setVerbose(self.verbose)
        return protocol

    def resolve(self, url):
        return reactor.resolve(url,(1,1))

    def checkNetwork(self, url):
        d = self.resolve(url)
        d.addCallback(self.hostResolved).addErrback(self.hostNotResolved)
        return d
    
    def hostNotResolved(self, d):
        self.networkNotAvailable()
        
    def hostResolved(self, d):
        self.networkAvailable()

    def networkNotAvailable(self):
        pass #pragma: no cover
    
    def networkAvailable(self):
        pass #pragma: no cover
        
    def restart(self):
        reactor.disconnectAll()
        import sys
        import os
        argv = [ sys.executable ]
        argv.extend(sys.argv)
        os.execv(sys.executable, argv)

    def quit(self):
        #
        # !!! The order MATTERS here !!! the renderer must be notified last
        # otherwise leak detection won't be happy. Inverting the two
        # is not fatal and the data will be freed eventually. However,
        # debugging is made much harder because leak detection can't
        # check as much as it could.
        #        
        self.skin.destroy()

    def getSkin(self):
        return self.skin
    
    def getUrl(self):
        return self.skin.getUrl()

    def setUrl(self,url):
        return self.skin.setUrl(url)

    def getOutfit(self):
        return self.skin.getOutfit()
    
    def setOutfit(self,outfit):
        return self.skin.setOutfit(outfit)
    
    def translateFile2Name(self, file):
        if not self.file2name.has_key(file):
            config = Config(self.dirs)
            config.load("poker.%s.xml" % file)
            name = config.headerGet("/bet/description")
            if not name:
                name = config.headerGet("/poker/variant/@name")
                if not name:
                    self.error("*CRITICAL* can't find readable name for %s" % file)
                    name = file
            self.file2name[file] = name
        return self.file2name[file]

    def saveAuthToFile(self, name, password, remember):
        settings = self.settings
        self.name = name
        self.password = password
        self.remember = remember
        if remember:
            remember = "yes"
        else:
            remember = "no"
            name = ""
            password = ""
        settings.headerSet("/settings/remember", remember)
        settings.headerSet("/settings/name", name)
        settings.headerSet("/settings/passwd", password)
        settings.save()
        settings.headerSet("/settings/name", self.name)
        settings.headerSet("/settings/passwd", self.password)

    def isOutbound(self, packet):
        return ( packet.type == PACKET_ERROR or
                 packet.type == PACKET_MESSAGE or
                 packet.type == PACKET_POKER_HAND_LIST or
                 packet.type == PACKET_POKER_PLAYER_INFO or
                 packet.type == PACKET_POKER_USER_INFO or
                 packet.type == PACKET_POKER_HAND_HISTORY or
                 packet.type == PACKET_POKER_PLAYERS_LIST or
                 packet.type == PACKET_POKER_TOURNEY_PLAYERS_LIST or
                 packet.type == PACKET_POKER_TOURNEY_UNREGISTER or
                 packet.type == PACKET_POKER_TOURNEY_REGISTER )

    def isAlwaysHandled(self, packet):
        return ( packet.type == PACKET_POKER_PLAYER_CHIPS or
                 packet.type == PACKET_POKER_CHAT )
    
    def isConnectionLess(self, packet):
        return ( packet.type == PACKET_PROTOCOL_ERROR or
                 packet.type == PACKET_QUIT )

    def getGame(self, game_id):
        return self.games.getGame(game_id)

    def getGameByNameNoCase(self, name):
        return self.games.getGameByNameNoCase(name)
    
    def getOrCreateGame(self, game_id):
        return self.games.getOrCreateGame(game_id)

    def getGameIds(self):
        return self.games.getGameIds()
    
    def deleteGame(self, game_id):
        return self.games.deleteGame(game_id)

    def packet2game(self, packet):
        if not self.isOutbound(packet):
            return self.games.packet2game(packet)
        else:
            return False

    def gameExists(self, game_id):
        return self.games.gameExists(game_id)
예제 #2
0
class PokerClientFactory(UGAMEClientFactory):
    "client factory"

    def __init__(self, *args, **kwargs):
        UGAMEClientFactory.__init__(self, *args, **kwargs)
        self.settings = kwargs["settings"]
        self.config = kwargs.get("config", None)
        #
        # Make sure the attributes exists, should an exception occur before
        # it is initialized with an instance of PokerChildren and such. This is done
        # so that the caller does not have to check the existence of the
        # attribute when catching an exception.
        #
        self.crashing = False
        self.interface = None
        self.display = None
        self.children = None

        settings = self.settings
        self.ping_delay = settings.headerGetInt("/settings/@ping")
        self.no_display_packets = settings.headerGet(
            "/settings/@no_display_packets")
        self.name = settings.headerGet("/settings/name")
        self.password = settings.headerGet("/settings/passwd")
        if self.config:
            chips_values = self.config.headerGet("/sequence/chips")
            if not chips_values:
                raise UserWarning, "PokerClientFactory: no /sequence/chips found in %s" % self.config.path
            self.chips_values = map(int, chips_values.split())
        else:
            self.chips_values = [1]
        self.host = "unknown"
        self.port = 0
        self.remember = settings.headerGet("/settings/remember") == "yes"
        self.chat_config = settings.headerGetProperties("/settings/chat")
        if self.chat_config:
            self.chat_config = self.chat_config[0]
            for (key, value) in self.chat_config.iteritems():
                self.chat_config[key] = int(value)
        else:
            self.chat_config = {}
        self.dirs = split(self.settings.headerGet("/settings/path"))
        self.verbose = self.settings.headerGetInt("/settings/@verbose")
        self.delays = self.settings.headerGetProperties("/settings/delays")
        if self.delays:
            self.delays = self.delays[0]
            for (key, value) in self.delays.iteritems():
                self.delays[key] = float(value)
            if self.delays.has_key("round"):
                self.delays["end_round"] = self.delays["round"]
                self.delays["begin_round"] = self.delays["round"]
                del self.delays["round"]
            if not self.delays.has_key("blind_ante_position"):
                self.delays["blind_ante_position"] = self.delays["position"]
        else:
            self.delays = {}
        if self.verbose > 2:
            self.message("PokerClient: delays %s" % self.delays)
        self.delays_enable = self.settings.headerGet(
            "/settings/@delays") == "true"
        self.skin = PokerSkin(settings=self.settings)
        self.protocol = PokerClientProtocol
        self.games = PokerGames(dirs=self.dirs, verbose=self.verbose)
        self.file2name = {}
        self.first_time = self.settings.headerGet(
            "/settings/name") == "username"
        self.played_time = self.settings.headerGet("/settings/played_time")

        self.children = PokerChildren(self.config, self.settings)
        self.upgrader = upgrade.Upgrader(self.config, self.settings)
        self.upgrader.registerHandler(upgrade.TICK, self.upgradeTick)
        self.upgrader.registerHandler(upgrade.CLIENT_VERSION_OK,
                                      self.clientVersionOk)
        self.upgrader.registerHandler(upgrade.NEED_UPGRADE, self.needUpgrade)
        self.upgrader.registerHandler(upgrade.UPGRADE_READY, self.upgradeReady)
        self.upgrader.registerHandler(upgrade.FAILED, self.failedUpgrade)
        self.upgrader.registerHandler(upgrade.HOST_DOES_NOT_RESPOND,
                                      self.failedUpgradeHostDoesNotRespond)
        self.upgrader.registerHandler(upgrade.NO_NETWORK,
                                      self.failedUpgradeNoNetwork)
        self.interface = None

    def __del__(self):
        if hasattr(self, "games"):
            del self.games

    def buildProtocol(self, addr):
        protocol = UGAMEClientFactory.buildProtocol(self, addr)
        protocol.explain.chips_values = self.chips_values
        protocol.explain.games = self.games
        protocol.explain.setVerbose(self.verbose)
        return protocol

    def resolve(self, url):
        return reactor.resolve(url, (1, 1))

    def checkNetwork(self, url):
        d = self.resolve(url)
        d.addCallback(self.hostResolved).addErrback(self.hostNotResolved)
        return d

    def hostNotResolved(self, d):
        self.networkNotAvailable()

    def hostResolved(self, d):
        self.networkAvailable()

    def networkNotAvailable(self):
        pass  #pragma: no cover

    def networkAvailable(self):
        pass  #pragma: no cover

    def upgradeTick(self, ratio, message):
        self.display.tickProgressBar(ratio, message)

    def restart(self):
        self.children.killall()
        reactor.disconnectAll()
        if self.display and hasattr(self.display,
                                    "underware") and self.display.underware:
            self.display.underware.Uninit()
        import sys
        import os
        if platform.system() == "Windows":
            os.execv("pok3d.exe", ["pok3d.exe", "--restart"])
        else:
            argv = [sys.executable]
            argv.extend(sys.argv)
            os.execv(sys.executable, argv)

    def quit(self):
        #
        # !!! The order MATTERS here !!! the renderer must be notified last
        # otherwise leak detection won't be happy. Inverting the two
        # is not fatal and the data will be freed eventually. However,
        # debugging is made much harder because leak detection can't
        # check as much as it could.
        #
        self.skin.destroy()
        packet = PacketQuit()
        self.display.render(packet)

    def getSkin(self):
        return self.skin

    def getUrl(self):
        return self.skin.getUrl()

    def setUrl(self, url):
        return self.skin.setUrl(url)

    def getOutfit(self):
        return self.skin.getOutfit()

    def setOutfit(self, outfit):
        return self.skin.setOutfit(outfit)

    def translateFile2Name(self, file):
        if not self.file2name.has_key(file):
            config = Config(self.dirs)
            config.load("poker.%s.xml" % file)
            name = config.headerGet("/bet/description")
            if not name:
                name = config.headerGet("/poker/variant/@name")
                if not name:
                    self.error("*CRITICAL* can't find readable name for %s" %
                               file)
                    name = file
            self.file2name[file] = name
        return self.file2name[file]

    def saveAuthToFile(self, name, password, remember):
        settings = self.settings
        self.name = name
        self.password = password
        self.remember = remember
        if remember:
            remember = "yes"
        else:
            remember = "no"
            name = ""
            password = ""
        settings.headerSet("/settings/remember", remember)
        settings.headerSet("/settings/name", name)
        settings.headerSet("/settings/passwd", password)
        settings.save()
        settings.headerSet("/settings/name", self.name)
        settings.headerSet("/settings/passwd", self.password)

    def isOutbound(self, packet):
        return (packet.type == PACKET_ERROR or packet.type == PACKET_MESSAGE
                or packet.type == PACKET_POKER_HAND_LIST
                or packet.type == PACKET_POKER_PLAYER_INFO
                or packet.type == PACKET_POKER_USER_INFO
                or packet.type == PACKET_POKER_HAND_HISTORY
                or packet.type == PACKET_POKER_PLAYERS_LIST
                or packet.type == PACKET_POKER_TOURNEY_PLAYERS_LIST
                or packet.type == PACKET_POKER_TOURNEY_UNREGISTER
                or packet.type == PACKET_POKER_TOURNEY_REGISTER)

    def isAlwaysHandled(self, packet):
        return (packet.type == PACKET_POKER_PLAYER_CHIPS
                or packet.type == PACKET_POKER_CHAT)

    def isConnectionLess(self, packet):
        return (packet.type == PACKET_PROTOCOL_ERROR
                or packet.type == PACKET_QUIT)

    def getGame(self, game_id):
        return self.games.getGame(game_id)

    def getGameByNameNoCase(self, name):
        return self.games.getGameByNameNoCase(name)

    def getOrCreateGame(self, game_id):
        return self.games.getOrCreateGame(game_id)

    def getGameIds(self):
        return self.games.getGameIds()

    def deleteGame(self, game_id):
        return self.games.deleteGame(game_id)

    def packet2game(self, packet):
        if not self.isOutbound(packet):
            return self.games.packet2game(packet)
        else:
            return False

    def gameExists(self, game_id):
        return self.games.gameExists(game_id)

    def browseWeb(self, path):
        PokerChildBrowser(self.config, self.settings, path)

    def checkClientVersion(self, version):
        self.upgrader.checkClientVersion(version)

    def clientVersionOk(self):
        pass

    def failedUpgrade(self, logs, reason):
        raise UserWarning, "upgrade failed reason:%s logs:%s" % (str(reason),
                                                                 str(logs))

    def needUpgrade(self, version):
        pass

    def upgrade(self, version, excludes):
        self.display.showProgressBar()
        self.upgrader.getUpgrade(version, excludes)

    def failedUpgradeHostDoesNotRespond(self, logs, reason):
        pass

    def failedUpgradeNoNetwork(self, logs, reason):
        pass

    def upgradeReady(self, target_dir, upgrades_dir):
        if self.verbose >= 0:
            self.message("PokerClientFactory::upgradeReady")
        self.children.killall()
        reactor.disconnectAll()
        if hasattr(self.display, "underware"):
            self.display.underware.Uninit()
        import sys
        import os
        if platform.system() == "Windows":
            os.execv(upgrades_dir + "/upgrade.exe", [
                upgrades_dir + "/upgrade.exe", '"' + target_dir + '"',
                '"' + sys.executable + '"'
            ])
        else:
            # FIXME: shouldn't this be an .in file and use @SHELL@ here?
            os.execv("/bin/sh", [
                upgrades_dir + "/upgrade", '-x', upgrades_dir + "/upgrade",
                upgrades_dir, sys.executable
            ] + sys.argv)
예제 #3
0
class PokerClientFactory(UGAMEClientFactory):
    "client factory"

    log = log.get_child('PokerClientFactory')

    def __init__(self, *args, **kwargs):
        UGAMEClientFactory.__init__(self, *args, **kwargs)
        self.settings = kwargs["settings"]
        self.config = kwargs.get("config", None)
        #
        # Make sure the attributes exists, should an exception occur before
        # it is initialized. This is done
        # so that the caller does not have to check the existence of the
        # attribute when catching an exception.
        self.crashing = False

        settings = self.settings
        self.ping_delay = settings.headerGetInt("/settings/@ping")
        self.no_display_packets = settings.headerGet(
            "/settings/@no_display_packets")
        self.name = settings.headerGet("/settings/name")
        self.password = settings.headerGet("/settings/passwd")
        if self.config:
            chips_values = self.config.headerGet("/sequence/chips")
            if not chips_values:
                raise UserWarning, "PokerClientFactory: no /sequence/chips found in %s" % self.config.path
            self.chips_values = map(int, chips_values.split())
        else:
            self.chips_values = [1]
        self.host = "unknown"
        self.port = 0
        self.remember = settings.headerGet("/settings/remember") == "yes"
        self.chat_config = settings.headerGetProperties("/settings/chat")
        if self.chat_config:
            self.chat_config = self.chat_config[0]
            for (key, value) in self.chat_config.iteritems():
                self.chat_config[key] = int(value)
        else:
            self.chat_config = {}
        self.dirs = self.settings.headerGet("/settings/path").split()
        self.delays = self.settings.headerGetProperties("/settings/delays")
        if self.delays:
            self.delays = self.delays[0]
            for (key, value) in self.delays.iteritems():
                self.delays[key] = float(value)
            if "round" in self.delays:
                self.delays["end_round"] = self.delays["round"]
                self.delays["begin_round"] = self.delays["round"]
                del self.delays["round"]
            if "blind_ante_position" not in self.delays:
                self.delays["blind_ante_position"] = self.delays["position"]
        else:
            self.delays = {}
        self.log.debug("delays %s", self.delays)
        self.delays_enable = self.settings.headerGet(
            "/settings/@delays") == "true"
        self.skin = PokerSkin(settings=self.settings)
        self.protocol = PokerClientProtocol
        self.games = PokerGames(dirs=self.dirs)
        self.file2name = {}
        self.first_time = self.settings.headerGet(
            "/settings/name") == "username"
        self.played_time = self.settings.headerGet("/settings/played_time")

    def __del__(self):
        if hasattr(self, "games"):
            del self.games

    def buildProtocol(self, addr):
        protocol = UGAMEClientFactory.buildProtocol(self, addr)
        protocol.explain.chips_values = self.chips_values
        protocol.explain.games = self.games
        return protocol

    def resolve(self, url):
        return reactor.resolve(url, (1, 1))

    def checkNetwork(self, url):
        d = self.resolve(url)
        d.addCallback(self.hostResolved).addErrback(self.hostNotResolved)
        return d

    def hostNotResolved(self, d):
        self.networkNotAvailable()

    def hostResolved(self, d):
        self.networkAvailable()

    def networkNotAvailable(self):
        pass  #pragma: no cover

    def networkAvailable(self):
        pass  #pragma: no cover

    def restart(self):
        reactor.disconnectAll()
        import sys
        import os
        argv = [sys.executable]
        argv.extend(sys.argv)
        os.execv(sys.executable, argv)

    def quit(self):
        #
        # !!! The order MATTERS here !!! the renderer must be notified last
        # otherwise leak detection won't be happy. Inverting the two
        # is not fatal and the data will be freed eventually. However,
        # debugging is made much harder because leak detection can't
        # check as much as it could.
        self.skin.destroy()

    def getSkin(self):
        return self.skin

    def getUrl(self):
        return self.skin.getUrl()

    def setUrl(self, url):
        return self.skin.setUrl(url)

    def getOutfit(self):
        return self.skin.getOutfit()

    def setOutfit(self, outfit):
        return self.skin.setOutfit(outfit)

    def translateFile2Name(self, file):
        if file not in self.file2name:
            config = Config(self.dirs)
            config.load("poker.%s.xml" % file)
            name = config.headerGet("/bet/description")
            if not name:
                name = config.headerGet("/poker/variant/@name")
                if not name:
                    self.log.crit("can't find readable name for '%s'", file)
                    name = file
            self.file2name[file] = name
        return self.file2name[file]

    def saveAuthToFile(self, name, password, remember):
        settings = self.settings
        self.name = name
        self.password = password
        self.remember = remember
        if remember:
            remember = "yes"
        else:
            remember = "no"
            name = ""
            password = ""
        settings.headerSet("/settings/remember", remember)
        settings.headerSet("/settings/name", name)
        settings.headerSet("/settings/passwd", password)
        settings.save()
        settings.headerSet("/settings/name", self.name)
        settings.headerSet("/settings/passwd", self.password)

    def isOutbound(self, packet):
        return packet.type in (PACKET_ERROR, PACKET_MESSAGE,
                               PACKET_POKER_HAND_LIST,
                               PACKET_POKER_PLAYER_INFO,
                               PACKET_POKER_USER_INFO,
                               PACKET_POKER_HAND_HISTORY,
                               PACKET_POKER_PLAYERS_LIST,
                               PACKET_POKER_TOURNEY_PLAYERS_LIST,
                               PACKET_POKER_TOURNEY_UNREGISTER,
                               PACKET_POKER_TOURNEY_REGISTER)

    def isAlwaysHandled(self, packet):
        return packet.type in (PACKET_POKER_PLAYER_CHIPS, PACKET_POKER_CHAT)

    def isConnectionLess(self, packet):
        return packet.type in (PACKET_PROTOCOL_ERROR, PACKET_QUIT)

    def getGame(self, game_id):
        return self.games.getGame(game_id)

    def getGameByNameNoCase(self, name):
        return self.games.getGameByNameNoCase(name)

    def getOrCreateGame(self, game_id):
        return self.games.getOrCreateGame(game_id)

    def getGameIds(self):
        return self.games.getGameIds()

    def deleteGame(self, game_id):
        return self.games.deleteGame(game_id)

    def packet2game(self, packet):
        if not self.isOutbound(packet):
            return self.games.packet2game(packet)
        else:
            return False

    def gameExists(self, game_id):
        return self.games.gameExists(game_id)
예제 #4
0
class PokerClientFactory(UGAMEClientFactory):
    "client factory"

    def __init__(self, *args, **kwargs):
        UGAMEClientFactory.__init__(self, *args, **kwargs)
        self.settings = kwargs["settings"]
        self.config = kwargs.get("config", None)
        #
        # Make sure the attributes exists, should an exception occur before
        # it is initialized with an instance of PokerChildren and such. This is done
        # so that the caller does not have to check the existence of the
        # attribute when catching an exception.
        #
        self.crashing = False
        self.interface = None
        self.display = None
        self.children = None

        settings = self.settings
        self.ping_delay = settings.headerGetInt("/settings/@ping")
        self.no_display_packets = settings.headerGet("/settings/@no_display_packets")
        self.name = settings.headerGet("/settings/name")
        self.password = settings.headerGet("/settings/passwd")
        if self.config:
            chips_values = self.config.headerGet("/sequence/chips")
            if not chips_values:
                raise UserWarning, "PokerClientFactory: no /sequence/chips found in %s" % self.config.path
            self.chips_values = map(int, chips_values.split())
        else:
            self.chips_values = [1]
        self.host = "unknown"
        self.port = 0
        self.remember = settings.headerGet("/settings/remember") == "yes"
        self.chat_config = settings.headerGetProperties("/settings/chat")
        if self.chat_config:
            self.chat_config = self.chat_config[0]
            for (key, value) in self.chat_config.iteritems():
                self.chat_config[key] = int(value)
        else:
            self.chat_config = {}
        self.dirs = split(self.settings.headerGet("/settings/path"))
        self.verbose = self.settings.headerGetInt("/settings/@verbose")
        self.delays = self.settings.headerGetProperties("/settings/delays")
        if self.delays:
            self.delays = self.delays[0]
            for (key, value) in self.delays.iteritems():
                self.delays[key] = float(value)
            if self.delays.has_key("round"):
                self.delays["end_round"] = self.delays["round"]
                self.delays["begin_round"] = self.delays["round"]
                del self.delays["round"]
            if not self.delays.has_key("blind_ante_position"):
                self.delays["blind_ante_position"] = self.delays["position"]
        else:
            self.delays = {}
        if self.verbose > 2:
            self.message("PokerClient: delays %s" % self.delays)
        self.delays_enable = self.settings.headerGet("/settings/@delays") == "true"
        self.skin = PokerSkin(settings = self.settings)
        self.protocol = PokerClientProtocol
        self.games = PokerGames(dirs = self.dirs, verbose = self.verbose)
        self.file2name = {}
        self.first_time = self.settings.headerGet("/settings/name") == "username"
        self.played_time = self.settings.headerGet("/settings/played_time")

        self.children = PokerChildren(self.config, self.settings)
        self.upgrader = upgrade.Upgrader(self.config, self.settings)
        self.upgrader.registerHandler(upgrade.TICK, self.upgradeTick)
        self.upgrader.registerHandler(upgrade.CLIENT_VERSION_OK, self.clientVersionOk)
        self.upgrader.registerHandler(upgrade.NEED_UPGRADE, self.needUpgrade)
        self.upgrader.registerHandler(upgrade.UPGRADE_READY, self.upgradeReady)
        self.upgrader.registerHandler(upgrade.FAILED, self.failedUpgrade)
        self.upgrader.registerHandler(upgrade.HOST_DOES_NOT_RESPOND, self.failedUpgradeHostDoesNotRespond)
        self.upgrader.registerHandler(upgrade.NO_NETWORK, self.failedUpgradeNoNetwork)
        self.interface = None

    def __del__(self):
        if hasattr(self, "games"):
            del self.games

    def buildProtocol(self, addr):
        protocol = UGAMEClientFactory.buildProtocol(self, addr)
        protocol.explain.chips_values = self.chips_values
        protocol.explain.games = self.games
        protocol.explain.setVerbose(self.verbose)
        return protocol

    def resolve(self, url):
        return reactor.resolve(url,(1,1))

    def checkNetwork(self, url):
        d = self.resolve(url)
        d.addCallback(self.hostResolved).addErrback(self.hostNotResolved)
        return d
    
    def hostNotResolved(self, d):
        self.networkNotAvailable()
        
    def hostResolved(self, d):
        self.networkAvailable()

    def networkNotAvailable(self):
        pass #pragma: no cover
    
    def networkAvailable(self):
        pass #pragma: no cover
        
    def upgradeTick(self, ratio, message):
        self.display.tickProgressBar(ratio, message)

    def restart(self):
        self.children.killall()
        reactor.disconnectAll()
        if self.display and hasattr(self.display, "underware") and self.display.underware:
            self.display.underware.Uninit()
        import sys
        import os
        if platform.system() == "Windows":
            os.execv("pok3d.exe", ["pok3d.exe", "--restart"])
        else:
            argv = [ sys.executable ]
            argv.extend(sys.argv)
            os.execv(sys.executable, argv)

    def quit(self):
        #
        # !!! The order MATTERS here !!! the renderer must be notified last
        # otherwise leak detection won't be happy. Inverting the two
        # is not fatal and the data will be freed eventually. However,
        # debugging is made much harder because leak detection can't
        # check as much as it could.
        #        
        self.skin.destroy()
        packet = PacketQuit()
        self.display.render(packet)

    def getSkin(self):
        return self.skin
    
    def getUrl(self):
        return self.skin.getUrl()

    def setUrl(self,url):
        return self.skin.setUrl(url)

    def getOutfit(self):
        return self.skin.getOutfit()
    
    def setOutfit(self,outfit):
        return self.skin.setOutfit(outfit)
    
    def translateFile2Name(self, file):
        if not self.file2name.has_key(file):
            config = Config(self.dirs)
            config.load("poker.%s.xml" % file)
            name = config.headerGet("/bet/description")
            if not name:
                name = config.headerGet("/poker/variant/@name")
                if not name:
                    self.error("*CRITICAL* can't find readable name for %s" % file)
                    name = file
            self.file2name[file] = name
        return self.file2name[file]

    def saveAuthToFile(self, name, password, remember):
        settings = self.settings
        self.name = name
        self.password = password
        self.remember = remember
        if remember:
            remember = "yes"
        else:
            remember = "no"
            name = ""
            password = ""
        settings.headerSet("/settings/remember", remember)
        settings.headerSet("/settings/name", name)
        settings.headerSet("/settings/passwd", password)
        settings.save()
        settings.headerSet("/settings/name", self.name)
        settings.headerSet("/settings/passwd", self.password)

    def isOutbound(self, packet):
        return ( packet.type == PACKET_ERROR or
                 packet.type == PACKET_MESSAGE or
                 packet.type == PACKET_POKER_HAND_LIST or
                 packet.type == PACKET_POKER_PLAYER_INFO or
                 packet.type == PACKET_POKER_USER_INFO or
                 packet.type == PACKET_POKER_HAND_HISTORY or
                 packet.type == PACKET_POKER_PLAYERS_LIST or
                 packet.type == PACKET_POKER_TOURNEY_PLAYERS_LIST or
                 packet.type == PACKET_POKER_TOURNEY_UNREGISTER or
                 packet.type == PACKET_POKER_TOURNEY_REGISTER )

    def isAlwaysHandled(self, packet):
        return ( packet.type == PACKET_POKER_PLAYER_CHIPS or
                 packet.type == PACKET_POKER_CHAT )
    
    def isConnectionLess(self, packet):
        return ( packet.type == PACKET_PROTOCOL_ERROR or
                 packet.type == PACKET_QUIT )

    def getGame(self, game_id):
        return self.games.getGame(game_id)

    def getGameByNameNoCase(self, name):
        return self.games.getGameByNameNoCase(name)
    
    def getOrCreateGame(self, game_id):
        return self.games.getOrCreateGame(game_id)

    def getGameIds(self):
        return self.games.getGameIds()
    
    def deleteGame(self, game_id):
        return self.games.deleteGame(game_id)

    def packet2game(self, packet):
        if not self.isOutbound(packet):
            return self.games.packet2game(packet)
        else:
            return False

    def gameExists(self, game_id):
        return self.games.gameExists(game_id)

    def browseWeb(self, path):
        PokerChildBrowser(self.config, self.settings, path)

    def checkClientVersion(self, version):
        self.upgrader.checkClientVersion(version)

    def clientVersionOk(self):
        pass

    def failedUpgrade(self, logs, reason):
        raise UserWarning, "upgrade failed reason:%s logs:%s" % (str(reason), str(logs))

    def needUpgrade(self, version):
        pass

    def upgrade(self, version, excludes):
        self.display.showProgressBar()
        self.upgrader.getUpgrade(version, excludes)

    def failedUpgradeHostDoesNotRespond(self, logs, reason):
        pass

    def failedUpgradeNoNetwork(self, logs, reason):
        pass

    def upgradeReady(self, target_dir, upgrades_dir):
        if self.verbose >= 0:
            self.message("PokerClientFactory::upgradeReady")
        self.children.killall()
        reactor.disconnectAll()
        if hasattr(self.display, "underware"):
            self.display.underware.Uninit()
        import sys
        import os
        if platform.system() == "Windows":
            os.execv(upgrades_dir + "/upgrade.exe", [ upgrades_dir + "/upgrade.exe", '"' + target_dir + '"', '"' + sys.executable + '"' ])
        else:
            # FIXME: shouldn't this be an .in file and use @SHELL@ here?
            os.execv("/bin/sh", [ upgrades_dir + "/upgrade", '-x', upgrades_dir + "/upgrade", upgrades_dir, sys.executable ] + sys.argv)