Example #1
0
    def update(self, dic):
        self.name = dic["name"]
        self.played = dic["played"]
        self.description = dic["description"]
        self.version = dic["version"]
        self.author = dic["author"]
        self.downloads = dic["downloads"]
        self.likes = dic["likes"]
        self.comments = dic["comments"]
        self.bugreports = dic["bugreports"]
        self.date = QtCore.QDateTime.fromTime_t(dic['date']).toString("yyyy-MM-dd")
        self.isuimod = dic["ui"]
        self.isbigmod = dic["big"]
        self.issmallmod = dic["small"]
        self.link = dic["link"] #Direct link to the zip file.
        self.thumbstr = dic["thumbnail"]# direct url to the thumbnail file.
        self.uploadedbyuser = (self.author == self.parent.client.login)

        self.thumbnail = None
        if self.thumbstr == "":
            self.setIcon(util.icon("games/unknown_map.png"))
        else:
            img = getIcon(os.path.basename(urllib2.unquote(self.thumbstr)))
            if img:
                self.setIcon(util.icon(img, False))
            else:
                self.parent.client.downloader.downloadModPreview(self.thumbstr, self)
        self.updateVisibility()
    def __init__(self, client, *args, **kwargs):

        BaseClass.__init__(self, *args, **kwargs)

        self.setupUi(self)

        self.client = client
        self.client.gamesTab.layout().addWidget(self)

        #Dictionary containing our actual games.
        self.games = {}

        #Ranked search UI
        self.rankedAeon.setIcon(util.icon("games/automatch/aeon.png"))
        self.rankedCybran.setIcon(util.icon("games/automatch/cybran.png"))
        self.rankedSeraphim.setIcon(util.icon("games/automatch/seraphim.png"))
        self.rankedUEF.setIcon(util.icon("games/automatch/uef.png"))
        self.rankedRandom.setIcon(util.icon("games/automatch/random.png"))


        self.connectRankedToggles()
        self.rankedTimer = QtCore.QTimer()
        self.rankedTimer.timeout.connect(self.expandSearchRanked)
        self.searchProgress.hide()

        # Ranked search state variables
        self.searching = False
        self.radius = 0
        self.race = None
        self.ispassworded = False
        self.canChooseMap = True

        self.client.modInfo.connect(self.processModInfo)
        self.client.gameInfo.connect(self.processGameInfo)

        self.client.rankedGameAeon.connect(self.togglingAeon)
        self.client.rankedGameCybran.connect(self.togglingCybran)
        self.client.rankedGameSeraphim.connect(self.togglingSeraphim)
        self.client.rankedGameUEF.connect(self.togglingUEF)
        self.client.rankedGameRandom.connect(self.togglingRandom)


        self.client.gameEnter.connect(self.stopSearchRanked)
        self.client.viewingReplay.connect(self.stopSearchRanked)

        self.gameList.setItemDelegate(GameItemDelegate(self))
        self.gameList.itemDoubleClicked.connect(self.gameDoubleClicked)

        self.modList.itemDoubleClicked.connect(self.hostGameClicked)

        try:
            self.mapSelectButton.clicked.connect(self.mapSelectClicked)
        except:
            QtGui.QMessageBox.warning(None, "Skin outdated.", "The theme you are using is outdated. Please remove it or the lobby will malfunction.")

        #Load game name from settings (yay, it's persistent!)
        self.loadGameName()
        self.loadGameMap()
        self.loadPassword()
        self.options = []
Example #3
0
def preview(mapname, pixmap=False):
    try:
        # Try to load directly from cache
        for extension in iconExtensions:
            img = os.path.join(util.CACHE_DIR, mapname + "." + extension)
            if os.path.isfile(img):
                logger.debug("Using cached preview image for: " + mapname)
                return util.icon(img, False, pixmap)

        # Try to find in local map folder
        img = __exportPreviewFromMap(mapname)

        if img and 'cache' in img and img['cache'] and os.path.isfile(
                img['cache']):
            logger.debug("Using fresh preview image for: " + mapname)
            return util.icon(img['cache'], False, pixmap)
        else:
            # Try to download from web
            img = __downloadPreviewFromWeb(mapname)
            if img and os.path.isfile(img):
                logger.debug("Using web preview image for: " + mapname)
                return util.icon(img, False, pixmap)

        return None
    except:
        logger.error("Error raised in maps.preview(...) for " + mapname)
        logger.error("Map Preview Exception", exc_info=sys.exc_info())
Example #4
0
    def update(self, dic):
        self.name = dic["name"]
        self.played = dic["played"]
        self.description = dic["description"]
        self.version = dic["version"]
        self.author = dic["author"]
        self.downloads = dic["downloads"]
        self.likes = dic["likes"]
        self.comments = dic["comments"]
        self.bugreports = dic["bugreports"]
        self.date = QtCore.QDateTime.fromTime_t(
            dic['date']).toString("yyyy-MM-dd")
        self.isuimod = dic["ui"]
        self.isbigmod = dic["big"]
        self.issmallmod = dic["small"]
        self.link = dic["link"]  #Direct link to the zip file.
        self.thumbstr = dic["thumbnail"]  # direct url to the thumbnail file.
        self.uploadedbyuser = (self.author == self.parent.client.login)

        self.thumbnail = None
        if self.thumbstr == "":
            self.setIcon(util.icon("games/unknown_map.png"))
        else:
            img = getIcon(os.path.basename(urllib2.unquote(self.thumbstr)))
            if img:
                self.setIcon(util.icon(img, False))
            else:
                self.parent.client.downloader.downloadModPreview(
                    self.thumbstr, self)
        self.updateVisibility()
Example #5
0
def preview(mapname, pixmap = False, force=False):
    try:
        # Try to load directly from cache
        for extension in iconExtensions:
            img = os.path.join(util.CACHE_DIR, mapname + "." + extension)
            if os.path.isfile(img):
                logger.debug("Using cached preview image for: " + mapname)
                return util.icon(img, False, pixmap)
        if force :
        # Try to download from web
            img = __downloadPreviewFromWeb(mapname)
            if img and os.path.isfile(img):
                logger.debug("Using web preview image for: " + mapname)
                return util.icon(img, False, pixmap)
    
        # Try to find in local map folder    
        img = __exportPreviewFromMap(mapname)["cache"]
        if img and os.path.isfile(img):
            logger.debug("Using fresh preview image for: " + mapname)
            return util.icon(img, False, pixmap)
        
        return None
    except:
        logger.error("Error raised in maps.preview(...) for " + mapname)
        logger.error("Map Preview Exception", exc_info=sys.exc_info())
Example #6
0
    def __init__(self, client, *args, **kwargs):
        BaseClass.__init__(self, *args, **kwargs)

        self.setupUi(self)

        self.client = client
        self.client.gamesTab.layout().addWidget(self)

        self.mods = {}

        # Dictionary containing our actual games.
        self.games = {}

        self.canChooseMap = True

        #Ranked search UI
        self._ranked_icons = {
            Factions.AEON: self.rankedAeon,
            Factions.CYBRAN: self.rankedCybran,
            Factions.SERAPHIM: self.rankedSeraphim,
            Factions.UEF: self.rankedUEF,
            Factions.RANDOM: self.rankedRandom
        }
        self.rankedAeon.setIcon(util.icon("games/automatch/aeon.png"))
        self.rankedCybran.setIcon(util.icon("games/automatch/cybran.png"))
        self.rankedSeraphim.setIcon(util.icon("games/automatch/seraphim.png"))
        self.rankedUEF.setIcon(util.icon("games/automatch/uef.png"))
        self.rankedRandom.setIcon(util.icon("games/automatch/random.png"))

        for faction, icon in self._ranked_icons.items():
            icon.clicked.connect(partial(self.toggle_search, faction=faction))

        self.searchProgress.hide()

        # Ranked search state variables
        self.searching = False
        self.race = None
        self.ispassworded = False

        self.client.modInfo.connect(self.processModInfo)
        self.client.gameInfo.connect(self.processGameInfo)
        self.client.disconnected.connect(self.clear_games)

        self.client.gameEnter.connect(self.stopSearchRanked)
        self.client.viewingReplay.connect(self.stopSearchRanked)

        self.gameList.setItemDelegate(GameItemDelegate(self))
        self.gameList.itemDoubleClicked.connect(self.gameDoubleClicked)
        self.gameList.sortBy = 0  # Default Sorting is By Players count

        self.sortGamesComboBox.addItems(
            ['By Players', 'By Game Quality', 'By avg. Player Rating'])
        self.sortGamesComboBox.currentIndexChanged.connect(
            self.sortGamesComboChanged)

        self.hideGamesWithPw.stateChanged.connect(self.togglePrivateGames)

        self.modList.itemDoubleClicked.connect(self.hostGameClicked)
Example #7
0
    def __init__(self, client, *args, **kwargs):
        BaseClass.__init__(self, *args, **kwargs)

        self.setupUi(self)

        self.client = client
        self.client.gamesTab.layout().addWidget(self)

        self.mods = {}

        # Dictionary containing our actual games.
        self.games = {}

        self.canChooseMap = True

        #Ranked search UI
        self._ranked_icons = {
            Factions.AEON: self.rankedAeon,
            Factions.CYBRAN: self.rankedCybran,
            Factions.SERAPHIM: self.rankedSeraphim,
            Factions.UEF: self.rankedUEF,
            Factions.RANDOM: self.rankedRandom
        }
        self.rankedAeon.setIcon(util.icon("games/automatch/aeon.png"))
        self.rankedCybran.setIcon(util.icon("games/automatch/cybran.png"))
        self.rankedSeraphim.setIcon(util.icon("games/automatch/seraphim.png"))
        self.rankedUEF.setIcon(util.icon("games/automatch/uef.png"))
        self.rankedRandom.setIcon(util.icon("games/automatch/random.png"))

        for faction, icon in self._ranked_icons.items():
            icon.clicked.connect(partial(self.toggle_search, faction=faction))

        self.searchProgress.hide()

        # Ranked search state variables
        self.searching = False
        self.race = None
        self.ispassworded = False

        self.client.modInfo.connect(self.processModInfo)
        self.client.gameInfo.connect(self.processGameInfo)
        self.client.disconnected.connect(self.clear_games)

        self.client.gameEnter.connect(self.stopSearchRanked)
        self.client.viewingReplay.connect(self.stopSearchRanked)

        self.gameList.setItemDelegate(GameItemDelegate(self))
        self.gameList.itemDoubleClicked.connect(self.gameDoubleClicked)
        self.gameList.sortBy = 0  # Default Sorting is By Players count

        self.sortGamesComboBox.addItems(['By Players', 'By Game Quality', 'By avg. Player Rating'])
        self.sortGamesComboBox.currentIndexChanged.connect(self.sortGamesComboChanged)

        self.hideGamesWithPw.stateChanged.connect(self.togglePrivateGames)

        self.modList.itemDoubleClicked.connect(self.hostGameClicked)
Example #8
0
def categories():
#	util.add_dir(__addon__.getLocalizedString(30001),{'top':BASE_URL+'/videozebricky/poslednich-50-videi'},util.icon('new.png'))
	util.add_dir('Top 200',{'top':furl('/videozebricky/top-100')},util.icon('top.png'))
	util.add_local_dir(__language__(30037),__addon__.getSetting('downloads'),util.icon('download.png'))
	data = util.request(BASE_URL)
	data = util.substr(data,'<ul id=\"headerMenu2\">','</ul>')
	pattern = '<a href=\"(?P<url>[^\"]+)(.+?)>(?P<name>[^<]+)'
	for m in re.finditer(pattern, data, re.IGNORECASE | re.DOTALL ):
		if m.group('url') == '/':
			continue
		util.add_dir(m.group('name'),{'cat':furl(m.group('url'))})
Example #9
0
    def __init__(self, message, *args, **kwargs):
        QtGui.QListWidgetItem.__init__(self, *args, **kwargs)

        self.mod  = message["name"]
        self.name = message["fullname"]
        self.options = message["options"]
        #Load Icon and Tooltip

        tip = message["desc"]      
        self.setToolTip(tip)
        
        if message["icon"] == None :
            icon = util.icon("games/mods/faf.png")        
            self.setIcon(icon)
        else :
            # TODO : download the icon from the remote path.
            pass
        
        
        if  self.mod in mod_crucial:
            color = client.instance.getColor("self")
        else:
            color = client.instance.getColor("player")
            
        self.setTextColor(QtGui.QColor(color))
        self.setText(self.name)
Example #10
0
def categories():
	#search.item()
	util.add_local_dir(__language__(30037),__addon__.getSetting('downloads'),util.icon('download.png'))
	util.add_dir('VÅ¡echny',{'list-all':''})
	for index,letter in enumerate(letters):
		util.add_dir(letter,{'list':str(index)})
	xbmcplugin.endOfDirectory(int(sys.argv[1]))
Example #11
0
    def update(self, message, client):
        '''
        Updates this item from the message dictionary supplied
        '''

        self.client = client
        self.tutorial = message['tutorial']
        self.description = message['description']
        self.url = "http://content.faforever.com/faf/tutorials/" + message[
            'url']

        # Map preview code
        if self.mapname != message['mapname']:
            self.mapname = message['mapname']
            self.mapdisplayname = maps.getDisplayName(self.mapname)

            icon = maps.preview(self.mapname)
            if not icon:
                icon = util.icon("games/unknown_map.png")
                self.client.downloader.downloadMap(self.mapname, self)

            self.setIcon(icon)

        self.setText(
            self.FORMATTER_TUTORIAL.format(mapdisplayname=self.mapdisplayname,
                                           title=self.tutorial,
                                           description=self.description))
Example #12
0
    def __init__(self, message, *args, **kwargs):
        QtGui.QListWidgetItem.__init__(self, *args, **kwargs)

        self.mod = message["name"]
        self.name = message["fullname"]
        self.options = message["options"]
        #Load Icon and Tooltip

        tip = message["desc"]
        self.setToolTip(tip)

        if message["icon"] == None:
            icon = util.icon("games/mods/faf.png")
            self.setIcon(icon)
        else:
            # TODO : download the icon from the remote path.
            pass

        if self.mod in mod_crucial:
            color = client.instance.getColor("self")
        else:
            color = client.instance.getColor("player")

        self.setTextColor(QtGui.QColor(color))
        self.setText(self.name)
Example #13
0
 def mapChanged(self, index):
     self.parent.gamemap = self.mapList.itemData(index)
     icon = maps.preview(self.parent.gamemap, True)
     if not icon:
         icon = util.icon("games/unknown_map.png", False, True)
     #self.mapPreview.setPixmap(icon)
     self.message['mapname'] = self.parent.gamemap
     self.game.update(self.message, self.parent.client)
Example #14
0
 def mapChanged(self, index):
     self.parent.gamemap = self.mapList.itemData(index)
     icon = maps.preview(self.parent.gamemap, True)
     if not icon:
         icon = util.icon("games/unknown_map.png", False, True)
     #self.mapPreview.setPixmap(icon)
     self.message['mapname'] = self.parent.gamemap
     self.game.update(self.message, self.parent.client)
Example #15
0
    def __init__(self, client, *args, **kwargs):
        BaseClass.__init__(self, *args, **kwargs)

        self.setupUi(self)
        self.client = client

        self.labelIcon.setPixmap(util.icon("client/tray_icon.png", pix=True).scaled(32, 32))
        self.standardIcon = util.icon("client/comment.png", pix=True)

        screen = QtGui.QDesktopWidget().screenGeometry()
        dialog_size = self.geometry()

        # TODO: more positions
        # bottom right
        self.move(screen.width() - dialog_size.width(), screen.height() - dialog_size.height())

        # Frameless, always on top, steal no focus & no entry at the taskbar
        self.setWindowFlags(QtCore.Qt.ToolTip)
Example #16
0
def search_plugin(plugin, url, action):
    info = scrapper.get_info(url)
    titles = info["search-title"]
    params = {}
    if __addon__.getSetting("search-integration-update-history") == "false":
        params["search-no-history"] = ""
    for title in info["search-title"]:
        params[action] = title
        add_plugin_call(__language__(30008) + ": " + title, plugin, params, util.icon("search.png"))
    xbmcplugin.endOfDirectory(int(sys.argv[1]))
Example #17
0
    def __init__(self, client, *args, **kwargs):
        BaseClass.__init__(self, *args, **kwargs)

        self.setupUi(self)
        self.client = client

        self.labelIcon.setPixmap(
            util.icon("client/tray_icon.png", pix=True).scaled(32, 32))
        self.standardIcon = util.icon("client/comment.png", pix=True)

        screen = QtGui.QDesktopWidget().screenGeometry()
        dialog_size = self.geometry()

        # TODO: more positions
        # bottom right
        self.move(screen.width() - dialog_size.width(),
                  screen.height() - dialog_size.height())

        # Frameless, always on top, steal no focus & no entry at the taskbar
        self.setWindowFlags(QtCore.Qt.ToolTip)
Example #18
0
    def __init__(self, client):
        self.client = client

        self.dialog = NotificationDialog(self.client)
        self.events = []
        self.disabledStartup = True
        self.lock = Lock()

        self.settings = NsSettingsDialog(self.client)

        self.user = util.icon("client/user.png", pix=True)
Example #19
0
    def __init__(self, client):
        self.client = client

        self.dialog = NotficationDialog(self.client)
        self.events = []
        self.disabledStartup = True
        self.lock = Lock()

        self.settings = NsSettingsDialog(self.client)

        self.user = util.icon("client/user.png", pix=True)
Example #20
0
    def update(self):
        """
        Updates the appearance of this chatter in the nicklist
         according to its lobby and irc states
        """
        # Color handling
        self.set_color()

        player = self.lobby.client.players[self.id]
        if not player and not self.id == -1:  # We should have a player object for this
            player = self.lobby.client.players[self.name]
            print("Looked up {} to {}".format(self.id, player))

        # Weed out IRC users and those we don't know about early.
        if self.id == -1 or player is None:
            self.rankItem.setIcon(util.icon("chat/rank/civilian.png"))
            self.rankItem.setToolTip("IRC User")
            return

        country = player.country
        if country is not None:
            self.setIcon(util.icon("chat/countries/%s.png" % country.lower()))
            self.setToolTip(country)

        if player.avatar != self.avatar:
            self.avatar = player.avatar
            self.updateAvatar()

        self.rating = player.rating_estimate()

        self.clan = player.clan
        if self.clan is not None:
            self.setText("[%s]%s" % (self.clan,self.name))

        rating = self.rating

        # Status icon handling
        if self.name in client.instance.urls:
            url = client.instance.urls[self.name]
            if url:
                if url.scheme() == "fafgame":
                    self.statusItem.setIcon(util.icon("chat/status/lobby.png"))
                    self.statusItem.setToolTip("In Game Lobby<br/>"+url.toString())
                elif url.scheme() == "faflive":
                    self.statusItem.setIcon(util.icon("chat/status/playing.png"))
                    self.statusItem.setToolTip("Playing Game<br/>"+url.toString())
        else:
            self.statusItem.setIcon(QtGui.QIcon())
            self.statusItem.setToolTip("Idle")

        #Rating icon choice
        #TODO: These are very basic and primitive
        self.rankItem.setToolTip("Global Rating: " + str(int(rating)))

        league = player.league
        if league is not None:
            self.rankItem.setToolTip("Division : " + league["division"]+ "\nGlobal Rating: " + str(int(rating)))
            self.rankItem.setIcon(util.icon("chat/rank/%s.png" % league["league"]))
        else:
            self.rankItem.setIcon(util.icon("chat/rank/newplayer.png"))
Example #21
0
    def __init__(self, message, *args, **kwargs):
        QtGui.QListWidgetItem.__init__(self, *args, **kwargs)

        self.mod  = message["name"]
        self.order = message.get("order", 0)
        self.name = message["fullname"]
        #Load Icon and Tooltip

        tip = message["desc"]      
        self.setToolTip(tip)

        icon = util.icon(os.path.join("games/mods/", self.mod + ".png"))
        if icon.isNull():
            icon = util.icon("games/mods/default.png")
        self.setIcon(icon)

        if self.mod in mod_crucial:
            color = client.instance.getColor("self")
        else:
            color = client.instance.getColor("player")
            
        self.setTextColor(QtGui.QColor(color))
        self.setText(self.name)
Example #22
0
    def finishedDownload(self, reply):
        ''' finishing downloads '''
        urlstring = reply.url().toString()
        reqlist = []
        if urlstring in self.mapRequests: reqlist = self.mapRequests[urlstring]
        if urlstring in self.modRequests: reqlist = self.modRequests[urlstring]
        if reqlist:
            #save the map from cache
            name = os.path.basename(reply.url().toString())
            pathimg = os.path.join(util.CACHE_DIR, name)
            img = QtCore.QFile(pathimg)
            img.open(QtCore.QIODevice.WriteOnly)
            img.write(reply.readAll())
            img.close()
            if os.path.exists(pathimg):
                #Create alpha-mapped preview image
                try:
                    pass  # the server already sends 100x100 pic
#                    img = QtGui.QImage(pathimg).scaled(100,100)
#                    img.save(pathimg)
                except:
                    pathimg = "games/unknown_map.png"
                    logger.info("Failed to resize " + name)
            else:
                pathimg = "games/unknown_map.png"
                logger.debug("Web Preview failed for: " + name)
            logger.debug("Web Preview used for: " + name)
            for requester in reqlist:
                if requester:
                    if requester in self.mapRequestsItem:
                        requester.setIcon(0, util.icon(pathimg, False))
                        self.mapRequestsItem.remove(requester)
                    else:
                        requester.setIcon(util.icon(pathimg, False))
            if urlstring in self.mapRequests: del self.mapRequests[urlstring]
            if urlstring in self.modRequests: del self.modRequests[urlstring]
Example #23
0
    def finishedDownload(self,reply):
        ''' finishing downloads '''
        urlstring = reply.url().toString()
        reqlist = []
        if urlstring in self.mapRequests: reqlist = self.mapRequests[urlstring]
        if urlstring in self.modRequests: reqlist = self.modRequests[urlstring]
        if reqlist:
            #save the map from cache
            name = os.path.basename(reply.url().toString())
            pathimg = os.path.join(util.CACHE_DIR, name)
            img = QtCore.QFile(pathimg)
            img.open(QtCore.QIODevice.WriteOnly)
            img.write(reply.readAll())
            img.close()
            if os.path.exists(pathimg):
                #Create alpha-mapped preview image
                try:
                    pass # the server already sends 100x100 pic
#                    img = QtGui.QImage(pathimg).scaled(100,100)
#                    img.save(pathimg)
                except:
                    pathimg = "games/unknown_map.png"
                    logger.info("Failed to resize " + name)
            else :
                pathimg = "games/unknown_map.png"
                logger.debug("Web Preview failed for: " + name)
            logger.debug("Web Preview used for: " + name)
            for requester in reqlist:
                if requester:
                    if requester in self.mapRequestsItem:
                        requester.setIcon(0, util.icon(pathimg, False))
                        self.mapRequestsItem.remove(requester)
                    else:
                        requester.setIcon(util.icon(pathimg, False))
            if urlstring in self.mapRequests: del self.mapRequests[urlstring]
            if urlstring in self.modRequests: del self.modRequests[urlstring]
Example #24
0
    def update(self, message):
        self.uid = message["idmap"]
        self.mapname = maps.link2name(message['maprealname'])
        # Map preview code

        self.mapdisplayname = maps.getDisplayName(self.mapname)
        icon = maps.preview(self.mapname)
        if not icon:
            self.parent.downloader.downloadMap(self.mapname, self)
            icon = util.icon("games/unknown_map.png")

        self.selected = message["selected"]

        self.setIcon(icon)
        text = "<font valign=center><b>%s</b></font>" % self.mapdisplayname
        self.setText(text)
    def loadPixmap(self):
        self.pix = QtGui.QPixmap(40+16 + self.indent, 20)
        self.pix.fill(QtCore.Qt.transparent)
        painter = QtGui.QPainter(self.pix)

        self.avatar =  self.group.client.getUserAvatar(self.username)
        if  self.avatar:
            avatarPix = util.respix(self.avatar['url'])
            if avatarPix:
                painter.drawPixmap(0, 0, avatarPix)
                self.avatarNotLoaded = False
            else:
                self.avatarNotLoaded = True

        if self.country != None:
            painter.drawPixmap(40 + self.indent, 2, util.icon("chat/countries/%s.png" % self.country.lower(), pix=True))
        painter.end()
Example #26
0
    def update(self, message, client):
        '''
        Updates this item from the message dictionary supplied
        '''

        self.client = client

        self.name = message["name"]
        self.mapname = message["map"]
        self.duration = time.strftime('%H:%M:%S',
                                      time.gmtime(message["duration"]))
        self.startHour = time.strftime("%H:%M",
                                       time.localtime(message['start']))
        self.startDate = time.strftime("%Y-%m-%d",
                                       time.localtime(message['start']))
        self.mod = message["mod"]

        # Map preview code
        self.mapdisplayname = maps.getDisplayName(self.mapname)

        self.icon = maps.preview(self.mapname)
        if not self.icon:
            self.client.downloader.downloadMap(self.mapname, self, True)
            self.icon = util.icon("games/unknown_map.png")
        #self.setIcon(0, self.icon)

        self.moddisplayname = self.mod
        self.modoptions = []

        if self.mod in mods:
            self.moddisplayname = mods[self.mod].name

#        self.title      = message['title']
#        self.host       = message['host']
#        self.teams      = message['teams']
#        self.access     = message.get('access', 'public')
#        self.mod        = message['featured_mod']
#        self.options    = message.get('options', [])
#        self.numplayers = message.get('num_players', 0)
#        self.slots      = message.get('max_players',12)

        self.viewtext = (self.FORMATTER_REPLAY.format(time=self.startHour,
                                                      name=self.name,
                                                      map=self.mapdisplayname,
                                                      duration=self.duration,
                                                      mod=self.moddisplayname))
Example #27
0
    def update(self, message):  
        self.uid = message["idmap"]
        self.mapname = maps.link2name(message['maprealname'])  
        # Map preview code

        self.mapdisplayname = maps.getDisplayName(self.mapname)
        icon = maps.preview(self.mapname)
        if not icon:
            self.parent.downloader.downloadMap(self.mapname, self)
            icon = util.icon("games/unknown_map.png")


        self.selected = message["selected"]  
            

        self.setIcon(icon)
        text = "<font valign=center><b>%s</b></font>" % self.mapdisplayname
        self.setText(text)
Example #28
0
def parse_page(page,url):
	data = util.substr(page,'<div class=\"vypis','<div class=\"right')
	pattern = '<div class=\"tale_char_div\"(.+?)<img(.+?)src=\"(?P<img>[^\"]+)(.+?)<a(.+?)href=\"(?P<url>[^\"]+)[^>]+>(?P<name>[^<]+)<(.+?)<p[^>]*>(?P<plot>[^<]+)'
	for m in re.finditer(pattern, data, re.IGNORECASE | re.DOTALL):
		util.add_video(
			m.group('name'),
			{'play':furl(m.group('url'))},
			m.group('img'),
			infoLabels={'Plot':m.group('plot')},
			menuItems={xbmc.getLocalizedString(33003):{'name':m.group('name'),'download':furl(m.group('url'))}}
		)
	data = util.substr(page,'<p class=\"p_wrapper','</p>')
	index =  url.find('?')
	if index > 0:
		url = url[:index]
	n = re.search('<a(.+?)href=\"(?P<url>[^\"]+)\"[^>]*>&gt;<',data)
	if n:
		util.add_dir(__language__(30012),{'tale':furl(url+n.group('url'))},util.icon('next.png'))
	xbmcplugin.endOfDirectory(int(sys.argv[1]))
Example #29
0
    def update(self, message, client):
        '''
        Updates this item from the message dictionary supplied
        '''
        
        
        self.client  = client
        
        self.name       = message["name"]
        self.mapname    = message["map"]
        self.duration   = time.strftime('%H:%M:%S', time.gmtime(message["duration"]))
        self.startHour  = time.strftime("%H:%M", time.localtime(message['start']))
        self.startDate  = time.strftime("%Y-%m-%d", time.localtime(message['start']))
        self.mod        = message["mod"]
         
        # Map preview code
        self.mapdisplayname = maps.getDisplayName(self.mapname)
      
        self.icon = maps.preview(self.mapname)
        if not self.icon:
            self.client.downloader.downloadMap(self.mapname, self, True)
            self.icon = util.icon("games/unknown_map.png")        
        #self.setIcon(0, self.icon)
        
        self.moddisplayname = self.mod
        self.modoptions = []

        if self.mod in mods :
            self.moddisplayname = mods[self.mod].name 

#        self.title      = message['title']
#        self.host       = message['host']
#        self.teams      = message['teams']
#        self.access     = message.get('access', 'public')
#        self.mod        = message['featured_mod']
#        self.options    = message.get('options', [])
#        self.numplayers = message.get('num_players', 0) 
#        self.slots      = message.get('max_players',12)

        self.viewtext = (self.FORMATTER_REPLAY.format(time=self.startHour, name=self.name, map = self.mapdisplayname, duration = self.duration, mod = self.moddisplayname))
Example #30
0
    def update(self, message, client):
        '''
        Updates this item from the message dictionary supplied
        '''
        
        
        self.client = client
        self.tutorial      = message['tutorial']
        self.description   = message['description']
        self.url           = "http://content.faforever.com/faf/tutorials/" + message['url']

        # Map preview code
        if self.mapname != message['mapname']:
            self.mapname = message['mapname']
            self.mapdisplayname = maps.getDisplayName(self.mapname)

            icon = maps.preview(self.mapname)
            if not icon:
                icon = util.icon("games/unknown_map.png")
                self.client.downloader.downloadMap(self.mapname, self)
                                        
            self.setIcon(icon)

        self.setText(self.FORMATTER_TUTORIAL.format(mapdisplayname=self.mapdisplayname, title=self.tutorial, description=self.description))
Example #31
0
 def updateOnlineTree(self):
     self.replayInfos.clear()
     self.onlineTree.clear()
     buckets = {}
     for uid in self.onlineReplays :
         bucket = buckets.setdefault(self.onlineReplays[uid].startDate, [])
         bucket.append(self.onlineReplays[uid])
         
     for bucket in buckets.keys():
         bucket_item = QtGui.QTreeWidgetItem()
         self.onlineTree.addTopLevelItem(bucket_item)
         
         bucket_item.setIcon(0, util.icon("replays/bucket.png"))                                
         bucket_item.setText(0, "<font color='white'>" + bucket+"</font>")
         bucket_item.setText(1,"<font color='white'>" + str(len(buckets[bucket])) + " replays</font>")
         
         
         
         for replay in buckets[bucket]:
             bucket_item.addChild(replay)
             replay.setFirstColumnSpanned(True)
             replay.setIcon(0, replay.icon)
             
         bucket_item.setExpanded(True)
Example #32
0
    def updateOnlineTree(self):
        self.replayInfos.clear()
        self.onlineTree.clear()
        buckets = {}
        for uid in self.onlineReplays:
            bucket = buckets.setdefault(self.onlineReplays[uid].startDate, [])
            bucket.append(self.onlineReplays[uid])

        for bucket in buckets.keys():
            bucket_item = QtGui.QTreeWidgetItem()
            self.onlineTree.addTopLevelItem(bucket_item)

            bucket_item.setIcon(0, util.icon("replays/bucket.png"))
            bucket_item.setText(0, "<font color='white'>" + bucket + "</font>")
            bucket_item.setText(
                1, "<font color='white'>" + str(len(buckets[bucket])) +
                " replays</font>")

            for replay in buckets[bucket]:
                bucket_item.addChild(replay)
                replay.setFirstColumnSpanned(True)
                replay.setIcon(0, replay.icon)

            bucket_item.setExpanded(True)
Example #33
0
    def update(self):
        '''
        updates the appearance of this chatter in the nicklist according to its lobby and irc states 
        '''

        country = self.lobby.client.getUserCountry(self.name)

        if country != None:
            self.setIcon(util.icon("chat/countries/%s.png" % country.lower()))
            self.setToolTip(country)

        if self.lobby.client.getUserAvatar(self.name) != self.avatar:
            self.avatar = self.lobby.client.getUserAvatar(self.name)
            self.updateAvatar()

        self.rating = self.lobby.client.getUserRanking(self.name)

        self.clan = self.lobby.client.getUserClan(self.name)
        if self.clan != "":
            self.setText("[%s]%s" % (self.clan, self.name))

        # Color handling
        if self.elevation in self.lobby.OPERATOR_COLORS:
            self.setTextColor(
                QtGui.QColor(self.lobby.OPERATOR_COLORS[self.elevation]))
        else:
            if self.name in self.lobby.client.colors:
                self.setTextColor(
                    QtGui.QColor(self.lobby.client.getColor(self.name)))
            else:
                self.setTextColor(
                    QtGui.QColor(self.lobby.client.getUserColor(self.name)))

        rating = self.rating

        # Status icon handling
        if self.name in client.instance.urls:
            url = client.instance.urls[self.name]
            if url:
                if url.scheme() == "fafgame":
                    self.statusItem.setIcon(util.icon("chat/status/lobby.png"))
                    self.statusItem.setToolTip("In Game Lobby<br/>" +
                                               url.toString())
                elif url.scheme() == "faflive":
                    self.statusItem.setIcon(
                        util.icon("chat/status/playing.png"))
                    self.statusItem.setToolTip("Playing Game<br/>" +
                                               url.toString())
        else:
            self.statusItem.setIcon(QtGui.QIcon())
            self.statusItem.setToolTip("Idle")

        #Rating icon choice
        #TODO: These are very basic and primitive
        if rating != None:
            league = self.lobby.client.getUserLeague(self.name)

            self.rankItem.setToolTip("Global Rating: " + str(int(rating)))

            if league != None:
                self.rankItem.setToolTip("Division : " + league["division"] +
                                         "\nGlobal Rating: " +
                                         str(int(rating)))
                if league["league"] == 1:
                    self.league = "chat/rank/Aeon_Scout.png"
                    self.rankItem.setIcon(
                        util.icon("chat/rank/Aeon_Scout.png"))
                elif league["league"] == 2:
                    self.league = "chat/rank/Aeon_T1.png"
                    self.rankItem.setIcon(util.icon("chat/rank/Aeon_T1.png"))
                elif league["league"] == 3:
                    self.league = "chat/rank/Aeon_T2.png"
                    self.rankItem.setIcon(util.icon("chat/rank/Aeon_T2.png"))
                elif league["league"] == 4:
                    self.league = "chat/rank/Aeon_T3.png"
                    self.rankItem.setIcon(util.icon("chat/rank/Aeon_T3.png"))
                elif league["league"] == 5:
                    self.league = "chat/rank/Aeon_XP.png"
                    self.rankItem.setIcon(util.icon("chat/rank/Aeon_XP.png"))
            else:
                self.league = "chat/rank/newplayer.png"
                self.rankItem.setIcon(util.icon("chat/rank/newplayer.png"))

        else:
            self.rankItem.setIcon(util.icon("chat/rank/civilian.png"))
            self.rankItem.setToolTip("IRC User")
Example #34
0
    def processGameInfo(self, info):
        if info['state'] == "playing":
            if info['uid'] in self.games:
                # Updating an existing item
                item = self.games[info['uid']]

                item.takeChildren(
                )  #Clear the children of this item before we're updating it
            else:
                # Creating a fresh item
                item = QtGui.QTreeWidgetItem()
                self.games[info['uid']] = item

                self.liveTree.insertTopLevelItem(0, item)

                if time.time() - info["game_time"] < LIVEREPLAY_DELAY_TIME:
                    item.setHidden(True)
                    QtCore.QTimer.singleShot(
                        LIVEREPLAY_DELAY_QTIMER, self.displayReplay
                    )  #The delay is there because we have a delay in the livereplay server

            # For debugging purposes, format our tooltip for the top level items
            # so it contains a human-readable representation of the info dictionary
            item.info = info
            tip = ""
            for key in info.keys():
                tip += "'" + unicode(key) + "' : '" + unicode(
                    info[key]) + "'<br/>"

            item.setToolTip(1, tip)

            icon = fa.maps.preview(info['mapname'])
            item.setToolTip(0, fa.maps.getDisplayName(info['mapname']))
            if not icon:
                self.client.downloader.downloadMap(item.info['mapname'], item,
                                                   True)
                icon = util.icon("games/unknown_map.png")

            item.setText(
                0,
                time.strftime("%H:%M", time.localtime(item.info['game_time'])))
            item.setTextColor(
                0, QtGui.QColor(client.instance.getColor("default")))

            item.setIcon(0, icon)
            item.setText(1, info['title'])
            item.setTextColor(1,
                              QtGui.QColor(client.instance.getColor("player")))

            item.setText(2, info['featured_mod'])
            item.setTextAlignment(2, QtCore.Qt.AlignCenter)

            if not info['teams']:
                item.setDisabled(True)

            # This game is the game the player is currently in
            mygame = False

            # Create player entries for all the live players in a match
            for team in info['teams']:
                if team == "-1":  #skip observers, they don't seem to stream livereplays
                    continue

                for player in info['teams'][team]:
                    playeritem = QtGui.QTreeWidgetItem()
                    playeritem.setText(0, player)

                    url = QtCore.QUrl()
                    url.setScheme("faflive")
                    url.setHost("lobby.faforever.com")
                    url.setPath(
                        str(info["uid"]) + "/" + player + ".SCFAreplay")
                    url.addQueryItem("map", info["mapname"])
                    url.addQueryItem("mod", info["featured_mod"])

                    playeritem.url = url
                    if client.instance.login == player:
                        mygame = True
                        item.setTextColor(
                            1, QtGui.QColor(client.instance.getColor("self")))
                        playeritem.setTextColor(
                            0, QtGui.QColor(client.instance.getColor("self")))
                        playeritem.setToolTip(0, url.toString())
                        playeritem.setIcon(0, util.icon("replays/replay.png"))
                    elif client.instance.isFriend(player):
                        if not mygame:
                            item.setTextColor(
                                1,
                                QtGui.QColor(
                                    client.instance.getColor("friend")))
                        playeritem.setTextColor(
                            0,
                            QtGui.QColor(client.instance.getColor("friend")))
                        playeritem.setToolTip(0, url.toString())
                        playeritem.setIcon(0, util.icon("replays/replay.png"))
                    elif client.instance.isPlayer(player):
                        playeritem.setTextColor(
                            0,
                            QtGui.QColor(client.instance.getColor("player")))
                        playeritem.setToolTip(0, url.toString())
                        playeritem.setIcon(0, util.icon("replays/replay.png"))
                    else:
                        playeritem.setTextColor(
                            0,
                            QtGui.QColor(client.instance.getColor("default")))
                        playeritem.setDisabled(True)

                    item.addChild(playeritem)
                    self.liveTree.setFirstItemColumnSpanned(playeritem, True)
        elif info['state'] == "closed":
            if info['uid'] in self.games:
                self.liveTree.takeTopLevelItem(
                    self.liveTree.indexOfTopLevelItem(self.games[info['uid']]))
Example #35
0
    def updatemyTree(self):
        self.myTree.clear()

        # We put the replays into buckets by day first, then we add them to the treewidget.
        buckets = {}

        # Iterate
        for infile in os.listdir(util.REPLAY_DIR):
            if infile.endswith(".scfareplay"):
                bucket = buckets.setdefault("legacy", [])

                item = QtGui.QTreeWidgetItem()
                item.setText(1, infile)
                item.filename = os.path.join(util.REPLAY_DIR, infile)
                item.setIcon(0, util.icon("replays/replay.png"))
                item.setTextColor(
                    0, QtGui.QColor(client.instance.getColor("default")))

                bucket.append(item)

            elif infile.endswith(".fafreplay"):
                item = QtGui.QTreeWidgetItem()
                try:
                    item.filename = os.path.join(util.REPLAY_DIR, infile)
                    item.info = json.loads(
                        open(item.filename, "rt").readline())

                    # Parse replayinfo into data
                    if item.info.get('complete', False):
                        game_date = time.strftime(
                            "%Y-%m-%d", time.localtime(item.info['game_time']))
                        game_hour = time.strftime(
                            "%H:%M", time.localtime(item.info['game_time']))

                        bucket = buckets.setdefault(game_date, [])

                        icon = fa.maps.preview(item.info['mapname'])
                        if icon:
                            item.setIcon(0, icon)
                        else:
                            self.client.downloader.downloadMap(
                                item.info['mapname'], item, True)
                            item.setIcon(0, util.icon("games/unknown_map.png"))
                        item.setToolTip(
                            0, fa.maps.getDisplayName(item.info['mapname']))
                        item.setText(0, game_hour)
                        item.setTextColor(
                            0,
                            QtGui.QColor(client.instance.getColor("default")))

                        item.setText(1, item.info['title'])
                        item.setToolTip(1, infile)

                        # Hacky way to quickly assemble a list of all the players, but including the observers
                        playerlist = []
                        for _, players in item.info['teams'].items():
                            playerlist.extend(players)
                        item.setText(2, ", ".join(playerlist))
                        item.setToolTip(2, ", ".join(playerlist))

                        # Add additional info
                        item.setText(3, item.info['featured_mod'])
                        item.setTextAlignment(3, QtCore.Qt.AlignCenter)
                        item.setTextColor(
                            1,
                            QtGui.QColor(
                                client.instance.getUserColor(
                                    item.info.get('recorder', ""))))
                    else:
                        bucket = buckets.setdefault("incomplete", [])
                        item.setIcon(0, util.icon("replays/replay.png"))
                        item.setText(1, infile)
                        item.setText(
                            2, "(replay doesn't have complete metadata)")
                        item.setTextColor(1, QtGui.QColor(
                            "yellow"))  #FIXME: Needs to come from theme

                except:
                    bucket = buckets.setdefault("broken", [])
                    item.setIcon(0, util.icon("replays/broken.png"))
                    item.setText(1, infile)
                    item.setTextColor(
                        1,
                        QtGui.QColor("red"))  #FIXME: Needs to come from theme
                    item.setText(2, "(replay parse error)")
                    item.setTextColor(
                        2,
                        QtGui.QColor("gray"))  #FIXME: Needs to come from theme
                    logger.error("Replay parse error for " + infile)

                bucket.append(item)

        # Now, create a top level treewidgetitem for every bucket, and put the bucket's contents into them
        for bucket in buckets.keys():
            bucket_item = QtGui.QTreeWidgetItem()

            if bucket == "broken":
                bucket_item.setTextColor(
                    0, QtGui.QColor("red"))  #FIXME: Needs to come from theme
                bucket_item.setText(1, "(not watchable)")
                bucket_item.setTextColor(
                    1, QtGui.QColor(client.instance.getColor("default")))
            elif bucket == "incomplete":
                bucket_item.setTextColor(
                    0,
                    QtGui.QColor("yellow"))  #FIXME: Needs to come from theme
                bucket_item.setText(1, "(watchable)")
                bucket_item.setTextColor(
                    1, QtGui.QColor(client.instance.getColor("default")))
            elif bucket == "legacy":
                bucket_item.setTextColor(
                    0, QtGui.QColor(client.instance.getColor("default")))
                bucket_item.setTextColor(
                    1, QtGui.QColor(client.instance.getColor("default")))
                bucket_item.setText(1, "(old replay system)")
            else:
                bucket_item.setTextColor(
                    0, QtGui.QColor(client.instance.getColor("player")))

            bucket_item.setIcon(0, util.icon("replays/bucket.png"))
            bucket_item.setText(0, bucket)
            bucket_item.setText(3, str(len(buckets[bucket])) + " replays")
            bucket_item.setTextColor(
                3, QtGui.QColor(client.instance.getColor("default")))

            self.myTree.addTopLevelItem(bucket_item)
            #self.myTree.setFirstItemColumnSpanned(bucket_item, True)

            for replay in buckets[bucket]:
                bucket_item.addChild(replay)
Example #36
0
    def update(self):
        '''
        updates the appearance of this chatter in the nicklist according to its lobby and irc states 
        '''        

        country = self.lobby.client.getUserCountry(self.name)

        if  country != None :
            self.setIcon(util.icon("chat/countries/%s.png" % country.lower()))
            self.setToolTip(country)
            
        
        if self.lobby.client.getUserAvatar(self.name) != self.avatar:            
            self.avatar = self.lobby.client.getUserAvatar(self.name)
            self.updateAvatar()

        self.rating = self.lobby.client.getUserRanking(self.name)

        self.clan = self.lobby.client.getUserClan(self.name)
        if self.clan != "":
            self.setText("[%s]%s" % (self.clan,self.name))

        # Color handling
        if self.elevation in self.lobby.OPERATOR_COLORS:            
            self.setTextColor(QtGui.QColor(self.lobby.OPERATOR_COLORS[self.elevation]))
        else:
            if self.name in self.lobby.client.colors :
                self.setTextColor(QtGui.QColor(self.lobby.client.getColor(self.name)))
            else :
                self.setTextColor(QtGui.QColor(self.lobby.client.getUserColor(self.name)))

        rating = self.rating

        # Status icon handling
        if self.name in client.instance.urls:
            url = client.instance.urls[self.name]
            if url:
                if url.scheme() == "fafgame":
                    self.statusItem.setIcon(util.icon("chat/status/lobby.png"))
                    self.statusItem.setToolTip("In Game Lobby<br/>"+url.toString())
                elif url.scheme() == "faflive":
                    self.statusItem.setIcon(util.icon("chat/status/playing.png"))
                    self.statusItem.setToolTip("Playing Game<br/>"+url.toString())
        else:
                self.statusItem.setIcon(QtGui.QIcon())
                self.statusItem.setToolTip("Idle")
            

        #Rating icon choice
        #TODO: These are very basic and primitive
        if rating != None:            
                league = self.lobby.client.getUserLeague(self.name)
                
                self.rankItem.setToolTip("Global Rating: " + str(int(rating)))  
                
                if league != None :        
                    self.rankItem.setToolTip("Division : " + league["division"]+ "\nGlobal Rating: " + str(int(rating)))
                    if league["league"] == 1 :
                        self.league = "chat/rank/Aeon_Scout.png"
                        self.rankItem.setIcon(util.icon("chat/rank/Aeon_Scout.png"))
                    elif league["league"] == 2 :
                        self.league = "chat/rank/Aeon_T1.png"
                        self.rankItem.setIcon(util.icon("chat/rank/Aeon_T1.png"))
                    elif league["league"] == 3 :
                        self.league = "chat/rank/Aeon_T2.png"
                        self.rankItem.setIcon(util.icon("chat/rank/Aeon_T2.png"))
                    elif league["league"] == 4 :
                        self.league = "chat/rank/Aeon_T3.png"
                        self.rankItem.setIcon(util.icon("chat/rank/Aeon_T3.png"))
                    elif league["league"] == 5 :                
                        self.league = "chat/rank/Aeon_XP.png"        
                        self.rankItem.setIcon(util.icon("chat/rank/Aeon_XP.png"))
                else :
                    self.league = "chat/rank/newplayer.png"
                    self.rankItem.setIcon(util.icon("chat/rank/newplayer.png"))
                    
        else:
                self.rankItem.setIcon(util.icon("chat/rank/civilian.png"))
                self.rankItem.setToolTip("IRC User")
Example #37
0
    def update(self, message, client):
        '''
        Updates this item from the message dictionary supplied
        '''

        foo = message
        message = copy.deepcopy(foo)
        
        self.client  = client

        self.title      = message['title']
        self.host       = message['host']
        self.teams      = dict.copy(message['teams'])
        self.access     = message.get('access', 'public')
        self.mod        = message['featured_mod']
        self.modVersion = message.get('featured_mod_versions', [])
        self.mods       = message.get('sim_mods',{})
        self.options    = message.get('options', [])
        self.numplayers = message.get('num_players', 0) 
        self.slots      = message.get('max_players',12)
        
        oldstate = self.state
        self.state  = message['state']
      

        # Assemble a players & teams lists
        self.teamlist = []
        self.observerlist = []
        self.realPlayers = []
        self.teamsTrueskill = []
        self.gamequality = 0
        self.invalidTS = False
        self.nTeams = 0

        #HACK: Visibility field not supported yet.
        self.private = self.title.lower().find("private") != -1        
        self.setHidden((self.state != 'open') or (self.mod in mod_invisible))        


        # Clear the status for all involved players (url may change, or players may have left, or game closed)        
        for player in self.players:
            if player in client.urls:
                del client.urls[player]


        # Just jump out if we've left the game, but tell the client that all players need their states updated
        if self.state == "closed":
            client.usersUpdated.emit(self.players)
            return
            
        self.players = []
        for team in self.teams:
            self.players.extend(self.teams[team])


        # Map preview code
        if self.mapname != message['mapname']:
            self.mapname = message['mapname']
            self.mapdisplayname = maps.getDisplayName(self.mapname)
            refresh_icon = True
        else:
            refresh_icon = False
                    
        #Resolve pretty display name
        self.moddisplayname = self.mod
        self.modoptions = []
        
        if self.mod in mods :
            self.moddisplayname = mods[self.mod].name 
            self.modoptions = mods[self.mod].options
        

        #Checking if the mod has options

        #Alternate icon: If private game, use game_locked icon. Otherwise, use preview icon from map library.
        if refresh_icon:
            if self.access == "password" or self.private:
                icon = util.icon("games/private_game.png")
            else:            
                icon = maps.preview(self.mapname)
                if not icon:
                    self.client.downloader.downloadMap(self.mapname, self)
                    icon = util.icon("games/unknown_map.png")
                             
            self.setIcon(icon)
        

        # Used to differentiate between newly added / removed and previously present players            
        oldplayers = set(self.players)
        
       
        self.playerIncluded = False
        
        
        if self.state == "open" :
            if "1" in self.teams and "2" in self.teams and self.client.login != None and self.client.login not in self.teams["1"] and self.client.login not in self.teams["2"] :
                if len(self.teams["1"]) < len(self.teams["2"]) :
                    self.teams["1"].append(self.client.login)
                    self.playerIncluded = True

                elif len(self.teams["1"]) > len(self.teams["2"]) :
                    self.teams["2"].append(self.client.login)
                    self.playerIncluded = True

        if self.state == "open" and  "1" in self.teams and "2" in self.teams :
            for team in self.teams:
                if team != "-1" :
                    self.realPlayers.extend(self.teams[team])
                    if team == 0 :
                        for player in self.teams[team] :
                            curTeam = Team()
                            if player in self.client.players :
                                mean = self.client.players[player]["rating_mean"]
                                dev = self.client.players[player]["rating_deviation"]
                                curTeam.addPlayer(player, Rating(mean, dev))
                            else :
                                self.invalidTS = True
                            self.teamsTrueskill.append(curTeam)
                    else :
                        curTeam = Team()

                        if team == "1" and (len(self.teams["1"]) < len(self.teams["2"])) and self.playerIncluded == True :
                            if self.client.login in self.client.players :
                                curTeam.addPlayer(self.client.login, Rating(self.client.players[self.client.login]["rating_mean"], self.client.players[self.client.login]["rating_deviation"]))
                        
                        if team == "2" and (len(self.teams["1"]) > len(self.teams["2"])) and self.playerIncluded == True :
                            if self.client.login in self.client.players :
                                curTeam.addPlayer(self.client.login, Rating(self.client.players[self.client.login]["rating_mean"], self.client.players[self.client.login]["rating_deviation"]))


                        for player in self.teams[team] :          
                            if player in self.client.players :
                                if self.client.isFoe(player) :
                                    self.hasFoe = True
                                mean = self.client.players[player]["rating_mean"]
                                dev = self.client.players[player]["rating_deviation"]
                                curTeam.addPlayer(player, Rating(mean, dev))
                            else :
                                self.invalidTS = True
                                

                        self.teamsTrueskill.append(curTeam)
                    
                # computing game quality :
                if len(self.teamsTrueskill) > 1 and self.invalidTS == False :
                    self.nTeams = 0
                    for t in self.teams :
                        if int(t) != -1 :
                            self.nTeams += 1

                    realPlayers = len(self.realPlayers)

                    if realPlayers % self.nTeams == 0 :

                        gameInfo = GameInfo()
                        calculator = FactorGraphTrueSkillCalculator()
                        gamequality = calculator.calculateMatchQuality(gameInfo, self.teamsTrueskill)
                        if gamequality < 1 :
                            self.gamequality = round((gamequality * 100), 2)

        strQuality = ""
        
        if self.gamequality == 0 :
            strQuality = "? %"
        else :
            strQuality = str(self.gamequality)+" %"


        if len(self.players) == 1:
            playerstring = "player"
        else:
            playerstring = "players"
        
        
        self.numplayers = len(self.players)
        
        self.playerIncludedTxt = ""
        if self.playerIncluded :
            self.playerIncludedTxt = "(with you)"
            
        color = client.getUserColor(self.host)
        
        for player in self.players :
            if self.client.isFoe(player) :
                color = client.getUserColor(player)

        self.editTooltip()
        
        

        if self.mod == "faf" or self.mod == "balancetesting" and not self.mods:
            self.setText(self.FORMATTER_FAF.format(color=color, mapslots = self.slots, mapdisplayname=self.mapdisplayname, title=self.title, host=self.host, players=self.numplayers, playerstring=playerstring, gamequality = strQuality, playerincluded = self.playerIncludedTxt))
        else:
            if not self.mods:
                modstr = self.mod
            else:
                if self.mod == 'faf': modstr = ", ".join(self.mods.values())
                else: modstr = self.mod + " & " + ", ".join(self.mods.values())
                if len(modstr) > 20: modstr = modstr[:15] + "..."
            self.setText(self.FORMATTER_MOD.format(color=color, mapslots = self.slots, mapdisplayname=self.mapdisplayname, title=self.title, host=self.host, players=self.numplayers, playerstring=playerstring, gamequality = strQuality, playerincluded = self.playerIncludedTxt, mod=modstr))
        
        if self.uid == 0:
            return
                
        #Spawn announcers: IF we had a gamestate change, show replay and hosting announcements 
        if (oldstate != self.state):            
            if (self.state == "playing"):
                QtCore.QTimer.singleShot(5*60000, self.announceReplay) #The delay is there because we have a 5 minutes delay in the livereplay server
            elif (self.state == "open"):
                QtCore.QTimer.singleShot(35000, self.announceHosting)   #The delay is there because we currently the host needs time to choose a map

        # Update player URLs
        for player in self.players:
            client.urls[player] = self.url(player)

        # Determine which players are affected by this game's state change            
        newplayers = set(self.players)            
        affectedplayers = oldplayers | newplayers
        client.usersUpdated.emit(list(affectedplayers))
Example #38
0
    faf_client.show()

    # Main update loop
    QtGui.QApplication.exec_()


if __name__ == '__main__':
    import logging
    logger = logging.getLogger(__name__)

    logger.info(">>> --------------------------- Application Launch")

    app = QtGui.QApplication(sys.argv)
    # Set application icon to nicely stack in the system task bar
    app.setWindowIcon(util.icon("window_icon.png", True))

    # We can now set our excepthook since the app has been initialized
    sys.excepthook = excepthook

    if platform.system() == "Windows":
        import ctypes
        if getattr(ctypes.windll.shell32,
                   "SetCurrentProcessExplicitAppUserModelID",
                   None) is not None:
            myappid = 'com.faforever.lobby'
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(
                myappid)

    if len(sys.argv) == 1:
        #Do the magic
Example #39
0
    def __init__(self, client, *args, **kwargs):

        BaseClass.__init__(self, *args, **kwargs)

        self.setupUi(self)

        self.client = client
        self.client.gamesTab.layout().addWidget(self)

        #Dictionary containing our actual games.
        self.games = {}

        #Ranked search UI
        self.rankedAeon.setIcon(util.icon("games/automatch/aeon.png"))
        self.rankedCybran.setIcon(util.icon("games/automatch/cybran.png"))
        self.rankedSeraphim.setIcon(util.icon("games/automatch/seraphim.png"))
        self.rankedUEF.setIcon(util.icon("games/automatch/uef.png"))
        self.rankedRandom.setIcon(util.icon("games/automatch/random.png"))

        self.connectRankedToggles()
        self.rankedTimer = QtCore.QTimer()
        self.rankedTimer.timeout.connect(self.expandSearchRanked)
        self.searchProgress.hide()

        # Ranked search state variables
        self.searching = False
        self.radius = 0
        self.race = None
        self.ispassworded = False
        self.canChooseMap = True


        self.teamFrame.setVisible(False)
        # Team search UI
        # self.teamAeon.setIcon(util.icon("games/automatch/aeon.png"))
        # self.teamCybran.setIcon(util.icon("games/automatch/cybran.png"))
        # self.teamSeraphim.setIcon(util.icon("games/automatch/seraphim.png"))
        # self.teamUEF.setIcon(util.icon("games/automatch/uef.png"))
        # self.teamRandom.setIcon(util.icon("games/automatch/random.png"))

        #self.teamRandom.setChecked(True)

        # self.connectTeamFactionToggles()

        # self.teamSearchButton={}
        # self.teamSearchButton[2] = self.players2
        # self.teamSearchButton[3] = self.players3
        # self.teamSearchButton[4] = self.players4
        # self.teamSearchButton[5] = self.players5
        # self.teamSearchButton[6] = self.players6

        # self.teamSearchFnc = {}

        # self.connectTeamSearchToggles()

        # self.teamTimer = QtCore.QTimer()
        # self.teamTimer.timeout.connect(self.expandSearchTeamRanked)
        # self.teamSearchProgress.hide()

        # self.client.matchmakerInfo.connect(self.handleMatchmakerInfo)

        # # Team search state variables
        # self.teamSearching = False

        # self.teamInvitations = {}

        self.client.modInfo.connect(self.processModInfo)
        self.client.gameInfo.connect(self.processGameInfo)

        self.client.rankedGameAeon.connect(self.togglingAeon)
        self.client.rankedGameCybran.connect(self.togglingCybran)
        self.client.rankedGameSeraphim.connect(self.togglingSeraphim)
        self.client.rankedGameUEF.connect(self.togglingUEF)
        self.client.rankedGameRandom.connect(self.togglingRandom)


        self.client.teamInvitation.connect(self.handleInvitations)
        self.client.teamInfo.connect(self.handleTeamInfo)


        self.client.gameEnter.connect(self.stopSearchRanked)
        self.client.viewingReplay.connect(self.stopSearchRanked)

        self.gameList.setItemDelegate(GameItemDelegate(self))
        self.gameList.itemDoubleClicked.connect(self.gameDoubleClicked)

        self.modList.itemDoubleClicked.connect(self.hostGameClicked)

        self.mapSelectButton.clicked.connect(self.mapSelectClicked)

        #self.TeamMapSelectButton.setVisible(False)

        # try:            
        #     self.teamInvitationsListWidget.itemDoubleClicked.connect(self.teamInvitationClicked)
        #     self.leaveTeamButton.clicked.connect(self.quitTeam)    
        #     self.leaveTeamButton.setVisible(False)
        # except:
        #     QtGui.QMessageBox.warning(None, "Skin outdated.", "The theme you are using is outdated. Please remove it or the lobby will malfunction.")

        #Load game name from settings (yay, it's persistent!)
        self.loadGameName()
        self.loadGameMap()
        self.loadPassword()
        self.options = []
Example #40
0
                QtGui.QApplication.exec_()

    


#Actual "main" method 
if __name__ == '__main__':                
    #Set up logging framework
    import logging
    logger = logging.getLogger("faf.main")
    logger.propagate = True
 
    #init application framework    
    logger.info(">>> --------------------------- Application Launch")    
    app = QtGui.QApplication(sys.argv)
    app.setWindowIcon(util.icon("window_icon.png", True))
    #Set application icon to nicely stack in the system task bar    
    import ctypes    
    if getattr(ctypes.windll.shell32, "SetCurrentProcessExplicitAppUserModelID", None) is not None: 
        myappid = 'com.faforever.lobby'
        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)

    if len(sys.argv) == 1:
        #Do the magic   
        sys.path += ['.'] 
        runFAF()
    else:  
        #Try to interpret the argument as a replay.
        if sys.argv[1].lower().endswith(".fafreplay") or sys.argv[1].lower().endswith(".scfareplay"):
            import fa
            fa.exe.replay(sys.argv[1], True) #Launch as detached process
Example #41
0
    def __init__(self, parent, item, *args, **kwargs):
        BaseClass.__init__(self, *args, **kwargs)

        self.setupUi(self)
        self.parent = parent

        self.parent.options = []

        if len(item.options) == 0:
            self.optionGroup.setVisible(False)
        else:
            group_layout = QtGui.QVBoxLayout()
            self.optionGroup.setLayout(group_layout)

            for option in item.options:
                checkBox = QtGui.QCheckBox(self)
                checkBox.setText(option)
                checkBox.setChecked(True)
                group_layout.addWidget(checkBox)
                self.parent.options.append(checkBox)

        self.setStyleSheet(self.parent.client.styleSheet())

        self.setWindowTitle("Hosting Game : " + item.name)
        self.titleEdit.setText(self.parent.gamename)
        self.passEdit.setText(self.parent.gamepassword)
        self.game = GameItem(0)
        self.gamePreview.setItemDelegate(GameItemDelegate(self))
        self.gamePreview.addItem(self.game)

        self.message = {}
        self.message['title'] = self.parent.gamename
        self.message['host'] = self.parent.client.login
        self.message['teams'] = {1: [self.parent.client.login]}
        #        self.message.get('access', 'public')
        self.message['featured_mod'] = "faf"
        self.message['mapname'] = self.parent.gamemap
        self.message['state'] = "open"

        self.game.update(self.message, self.parent.client)

        i = 0
        index = 0
        if self.parent.canChooseMap == True:
            allmaps = dict()
            for map in maps.maps.keys() + maps.getUserMaps():
                allmaps[map] = maps.getDisplayName(map)
            for (map, name) in sorted(allmaps.iteritems(), key=lambda x: x[1]):
                if map == self.parent.gamemap:
                    index = i
                self.mapList.addItem(name, map)
                i = i + 1
            self.mapList.setCurrentIndex(index)
        else:
            self.mapList.hide()

        icon = maps.preview(self.parent.gamemap, True)

        if not icon:
            icon = util.icon("games/unknown_map.png", False, True)

        self.mods = {}
        #this makes it so you can select every non-ui_only mod
        for mod in modvault.getInstalledMods():
            if mod.ui_only:
                continue
            self.mods[mod.totalname] = mod
            self.modList.addItem(mod.totalname)

        names = [mod.totalname for mod in modvault.getActiveMods(uimods=False)]
        logger.debug("Active Mods detected: %s" % str(names))
        for name in names:
            l = self.modList.findItems(name, QtCore.Qt.MatchExactly)
            logger.debug("found item: %s" % l[0].text())
            if l: l[0].setSelected(True)

        #self.mapPreview.setPixmap(icon)

        self.mapList.currentIndexChanged.connect(self.mapChanged)
        self.hostButton.released.connect(self.hosting)
        self.titleEdit.textChanged.connect(self.updateText)
        self.modList.itemClicked.connect(self.modclicked)
Example #42
0
    def update(self):
        """
        Updates the appearance of this chatter in the nicklist
         according to its lobby and irc states
        """
        # Color handling
        self.set_color()

        player = self.lobby.client.players[self.id]
        if not player and not self.id == -1:  # We should have a player object for this
            player = self.lobby.client.players[self.name]
            print("Looked up {} to {}".format(self.id, player))

        # Weed out IRC users and those we don't know about early.
        if self.id == -1 or player is None:
            self.rankItem.setIcon(util.icon("chat/rank/civilian.png"))
            self.rankItem.setToolTip("IRC User")
            return

        country = player.country
        if country is not None:
            self.setIcon(util.icon("chat/countries/%s.png" % country.lower()))
            self.setToolTip(country)

        if player.avatar != self.avatar:
            self.avatar = player.avatar
            self.updateAvatar()

        self.rating = player.rating_estimate()

        self.clan = player.clan
        if self.clan is not None:
            self.setText("[%s]%s" % (self.clan, self.name))

        rating = self.rating

        # Status icon handling
        if self.name in client.instance.urls:
            url = client.instance.urls[self.name]
            if url:
                if url.scheme() == "fafgame":
                    self.statusItem.setIcon(util.icon("chat/status/lobby.png"))
                    self.statusItem.setToolTip("In Game Lobby<br/>" +
                                               url.toString())
                elif url.scheme() == "faflive":
                    self.statusItem.setIcon(
                        util.icon("chat/status/playing.png"))
                    self.statusItem.setToolTip("Playing Game<br/>" +
                                               url.toString())
        else:
            self.statusItem.setIcon(QtGui.QIcon())
            self.statusItem.setToolTip("Idle")

        #Rating icon choice
        #TODO: These are very basic and primitive
        self.rankItem.setToolTip("Global Rating: " + str(int(rating)))

        league = player.league
        if league is not None:
            self.rankItem.setToolTip("Division : " + league["division"] +
                                     "\nGlobal Rating: " + str(int(rating)))
            self.rankItem.setIcon(
                util.icon("chat/rank/%s.png" % league["league"]))
        else:
            self.rankItem.setIcon(util.icon("chat/rank/newplayer.png"))
Example #43
0
    def update(self, message, client):
        '''
        Updates this item from the message dictionary supplied
        '''

        foo = message
        message = copy.deepcopy(foo)

        self.client = client

        self.title = message['title']
        self.host = message['host']
        self.teams = dict.copy(message['teams'])
        self.access = message.get('access', 'public')
        self.mod = message['featured_mod']
        self.modVersion = message.get('featured_mod_versions', [])
        self.mods = message.get('sim_mods', {})
        self.options = message.get('options', [])
        self.numplayers = message.get('num_players', 0)
        self.slots = message.get('max_players', 12)

        oldstate = self.state
        self.state = message['state']

        # Assemble a players & teams lists
        self.teamlist = []
        self.observerlist = []
        self.realPlayers = []
        self.teamsTrueskill = []
        self.gamequality = 0
        self.invalidTS = False
        self.nTeams = 0

        #HACK: Visibility field not supported yet.
        self.private = self.title.lower().find("private") != -1
        self.setHidden((self.state != 'open') or (self.mod in mod_invisible))

        # Clear the status for all involved players (url may change, or players may have left, or game closed)
        for player in self.players:
            if player in client.urls:
                del client.urls[player]

        # Just jump out if we've left the game, but tell the client that all players need their states updated
        if self.state == "closed":
            client.usersUpdated.emit(self.players)
            return

        self.players = []
        for team in self.teams:
            self.players.extend(self.teams[team])

        # Map preview code
        if self.mapname != message['mapname']:
            self.mapname = message['mapname']
            self.mapdisplayname = maps.getDisplayName(self.mapname)
            refresh_icon = True
        else:
            refresh_icon = False

        #Resolve pretty display name
        self.moddisplayname = self.mod
        self.modoptions = []

        if self.mod in mods:
            self.moddisplayname = mods[self.mod].name
            self.modoptions = mods[self.mod].options

        #Checking if the mod has options

        #Alternate icon: If private game, use game_locked icon. Otherwise, use preview icon from map library.
        if refresh_icon:
            if self.access == "password" or self.private:
                icon = util.icon("games/private_game.png")
            else:
                icon = maps.preview(self.mapname)
                if not icon:
                    self.client.downloader.downloadMap(self.mapname, self)
                    icon = util.icon("games/unknown_map.png")

            self.setIcon(icon)

        # Used to differentiate between newly added / removed and previously present players
        oldplayers = set(self.players)

        self.playerIncluded = False

        if self.state == "open":
            if "1" in self.teams and "2" in self.teams and self.client.login != None and self.client.login not in self.teams[
                    "1"] and self.client.login not in self.teams["2"]:
                if len(self.teams["1"]) < len(self.teams["2"]):
                    self.teams["1"].append(self.client.login)
                    self.playerIncluded = True

                elif len(self.teams["1"]) > len(self.teams["2"]):
                    self.teams["2"].append(self.client.login)
                    self.playerIncluded = True

        if self.state == "open" and "1" in self.teams and "2" in self.teams:
            for team in self.teams:
                if team != "-1":
                    self.realPlayers.extend(self.teams[team])
                    if team == 0:
                        for player in self.teams[team]:
                            curTeam = Team()
                            if player in self.client.players:
                                mean = self.client.players[player][
                                    "rating_mean"]
                                dev = self.client.players[player][
                                    "rating_deviation"]
                                curTeam.addPlayer(player, Rating(mean, dev))
                            else:
                                self.invalidTS = True
                            self.teamsTrueskill.append(curTeam)
                    else:
                        curTeam = Team()

                        if team == "1" and (len(self.teams["1"]) < len(
                                self.teams["2"])
                                            ) and self.playerIncluded == True:
                            if self.client.login in self.client.players:
                                curTeam.addPlayer(
                                    self.client.login,
                                    Rating(
                                        self.client.players[
                                            self.client.login]["rating_mean"],
                                        self.client.players[self.client.login]
                                        ["rating_deviation"]))

                        if team == "2" and (len(self.teams["1"]) > len(
                                self.teams["2"])
                                            ) and self.playerIncluded == True:
                            if self.client.login in self.client.players:
                                curTeam.addPlayer(
                                    self.client.login,
                                    Rating(
                                        self.client.players[
                                            self.client.login]["rating_mean"],
                                        self.client.players[self.client.login]
                                        ["rating_deviation"]))

                        for player in self.teams[team]:
                            if player in self.client.players:
                                if self.client.isFoe(player):
                                    self.hasFoe = True
                                mean = self.client.players[player][
                                    "rating_mean"]
                                dev = self.client.players[player][
                                    "rating_deviation"]
                                curTeam.addPlayer(player, Rating(mean, dev))
                            else:
                                self.invalidTS = True

                        self.teamsTrueskill.append(curTeam)

                # computing game quality :
                if len(self.teamsTrueskill) > 1 and self.invalidTS == False:
                    self.nTeams = 0
                    for t in self.teams:
                        if int(t) != -1:
                            self.nTeams += 1

                    realPlayers = len(self.realPlayers)

                    if realPlayers % self.nTeams == 0:

                        gameInfo = GameInfo()
                        calculator = FactorGraphTrueSkillCalculator()
                        gamequality = calculator.calculateMatchQuality(
                            gameInfo, self.teamsTrueskill)
                        if gamequality < 1:
                            self.gamequality = round((gamequality * 100), 2)

        strQuality = ""

        if self.gamequality == 0:
            strQuality = "? %"
        else:
            strQuality = str(self.gamequality) + " %"

        if len(self.players) == 1:
            playerstring = "player"
        else:
            playerstring = "players"

        self.numplayers = len(self.players)

        self.playerIncludedTxt = ""
        if self.playerIncluded:
            self.playerIncludedTxt = "(with you)"

        color = client.getUserColor(self.host)

        for player in self.players:
            if self.client.isFoe(player):
                color = client.getUserColor(player)

        self.editTooltip()

        if self.mod == "faf" or self.mod == "balancetesting" and not self.mods:
            self.setText(
                self.FORMATTER_FAF.format(
                    color=color,
                    mapslots=self.slots,
                    mapdisplayname=self.mapdisplayname,
                    title=self.title,
                    host=self.host,
                    players=self.numplayers,
                    playerstring=playerstring,
                    gamequality=strQuality,
                    playerincluded=self.playerIncludedTxt))
        else:
            if not self.mods:
                modstr = self.mod
            else:
                if self.mod == 'faf': modstr = ", ".join(self.mods.values())
                else: modstr = self.mod + " & " + ", ".join(self.mods.values())
                if len(modstr) > 20: modstr = modstr[:15] + "..."
            self.setText(
                self.FORMATTER_MOD.format(
                    color=color,
                    mapslots=self.slots,
                    mapdisplayname=self.mapdisplayname,
                    title=self.title,
                    host=self.host,
                    players=self.numplayers,
                    playerstring=playerstring,
                    gamequality=strQuality,
                    playerincluded=self.playerIncludedTxt,
                    mod=modstr))

        if self.uid == 0:
            return

        #Spawn announcers: IF we had a gamestate change, show replay and hosting announcements
        if (oldstate != self.state):
            if (self.state == "playing"):
                QtCore.QTimer.singleShot(
                    5 * 60000, self.announceReplay
                )  #The delay is there because we have a 5 minutes delay in the livereplay server
            elif (self.state == "open"):
                QtCore.QTimer.singleShot(
                    35000, self.announceHosting
                )  #The delay is there because we currently the host needs time to choose a map

        # Update player URLs
        for player in self.players:
            client.urls[player] = self.url(player)

        # Determine which players are affected by this game's state change
        newplayers = set(self.players)
        affectedplayers = oldplayers | newplayers
        client.usersUpdated.emit(list(affectedplayers))
Example #44
0
    def update(self, message, client):
        '''
        Updates this item from the message dictionary supplied
        '''
        self.client  = client

        self.title = message['title']
        self.host = message['host']

        # Maps integral team numbers (from 2, with 1 "none") to lists of names.
        teams_map = dict.copy(message['teams'])
        self.password_protected = message.get('password_protected', False)
        self.mod = message['featured_mod']
        self.modVersion = message.get('featured_mod_versions', [])
        self.mods = message.get('sim_mods', {})
        self.options = message.get('options', [])
        num_players = message.get('num_players', 0)
        self.slots = message.get('max_players', 12)
        
        oldstate = self.state
        self.state  = message['state']

        # Assemble a players & teams lists
        self.teamlist = []
        self.observerlist = []

        self.setHidden((self.state != 'open') or (self.mod in mod_invisible))        

        # Clear the status for all involved players (url may change, or players may have left, or game closed)        
        for player in self.players:
            if player.login in client.urls:
                del client.urls[player.login]

        # Just jump out if we've left the game, but tell the client that all players need their states updated
        if self.state == "closed":
            client.usersUpdated.emit(self.players)
            return

        # Used to differentiate between newly added / removed and previously present players
        oldplayers = set(map(lambda p: p.login, self.players))

        # Following the convention used by the game, a team value of 1 represents "No team". Let's
        # desugar those into "real" teams now (and convert the dict to a list)
        # Also, turn the lists of names into lists of players, and build a player name list.
        self.players = []
        teams = []
        for team_index, team in teams_map.iteritems():
            if team_index == 1:
                for ffa_player in team:
                    if ffa_player in self.client.players:
                        self.players.append(self.client.players[ffa_player])
                        teams.append([self.client.players[ffa_player]])
            else:
                real_team = []
                for name in team:
                    if name in self.client.players:
                        self.players.append(self.client.players[name])
                        real_team.append(self.client.players[name])
                teams.append(real_team)

        # Tuples for feeding into trueskill.
        rating_tuples = []
        for team in teams:
            ratings_for_team = map(lambda player: Rating(player.rating_mean, player.rating_deviation), team)
            rating_tuples.append(tuple(ratings_for_team))

        try:
            self.gamequality = 100*round(trueskill.quality(rating_tuples), 2)
        except ValueError:
            self.gamequality = 0
        self.nTeams = len(teams)

        # Map preview code
        if self.mapname != message['mapname']:
            self.mapname = message['mapname']
            self.mapdisplayname = maps.getDisplayName(self.mapname)
            refresh_icon = True
        else:
            refresh_icon = False

        #Alternate icon: If private game, use game_locked icon. Otherwise, use preview icon from map library.
        if refresh_icon:
            if self.password_protected:
                icon = util.icon("games/private_game.png")
            else:            
                icon = maps.preview(self.mapname)
                if not icon:
                    self.client.downloader.downloadMap(self.mapname, self)
                    icon = util.icon("games/unknown_map.png")
                             
            self.setIcon(icon)

        strQuality = ""
        
        if self.gamequality == 0 :
            strQuality = "? %"
        else :
            strQuality = str(self.gamequality)+" %"

        if num_players == 1:
            playerstring = "player"
        else:
            playerstring = "players"

        color = client.players.getUserColor(self.host)

        self.editTooltip(teams)

        self.setText(self.FORMATTER_FAF.format(color=color, mapslots = self.slots, mapdisplayname=self.mapdisplayname, title=self.title, host=self.host, players=num_players, playerstring=playerstring, gamequality = strQuality))

        #Spawn announcers: IF we had a gamestate change, show replay and hosting announcements 
        if (oldstate != self.state):            
            if (self.state == "playing"):
                QtCore.QTimer.singleShot(5*60000, self.announceReplay) #The delay is there because we have a 5 minutes delay in the livereplay server
            elif (self.state == "open"):
                QtCore.QTimer.singleShot(35000, self.announceHosting)   #The delay is there because we currently the host needs time to choose a map

        # Update player URLs
        for player in self.players:
            client.urls[player.login] = self.url(player.id)

        # Determine which players are affected by this game's state change            
        newplayers = set(map(lambda p: p.login, self.players))
        affectedplayers = oldplayers | newplayers
        client.usersUpdated.emit(list(affectedplayers))
Example #45
0
    def __init__(self, parent=None):
        super(selectFactionPage, self).__init__(parent)

        self.parent = parent
        self.client = parent.client

        self.setTitle("Faction selection")

        layout = QtGui.QVBoxLayout()
        label = QtGui.QLabel(
            "Hi commander. <br><br>The war is raging through the galaxy.<br>You have to pick a side !"
        )

        layoutFactions = QtGui.QHBoxLayout()

        Aeon = QtGui.QPushButton()
        Cybran = QtGui.QPushButton()
        Seraphim = QtGui.QPushButton()
        UEF = QtGui.QPushButton()

        Aeon.setIconSize(QtCore.QSize(60, 60))
        Cybran.setIconSize(QtCore.QSize(60, 60))
        Seraphim.setIconSize(QtCore.QSize(60, 60))
        UEF.setIconSize(QtCore.QSize(60, 60))

        UEF.setMaximumSize(100, 100)
        Aeon.setMaximumSize(100, 100)
        Seraphim.setMaximumSize(100, 100)
        Cybran.setMaximumSize(100, 100)

        UEF.setMinimumSize(100, 100)
        Aeon.setMinimumSize(100, 100)
        Seraphim.setMinimumSize(100, 100)
        Cybran.setMinimumSize(100, 100)

        Aeon.setFlat(1)
        Cybran.setFlat(1)
        Seraphim.setFlat(1)
        UEF.setFlat(1)

        Aeon.setIcon(util.icon("games/automatch/aeon.png"))
        Cybran.setIcon(util.icon("games/automatch/cybran.png"))
        Seraphim.setIcon(util.icon("games/automatch/seraphim.png"))
        UEF.setIcon(util.icon("games/automatch/uef.png"))

        layoutFactions.addWidget(UEF)
        layoutFactions.addWidget(Aeon)
        layoutFactions.addWidget(Cybran)
        layoutFactions.addWidget(Seraphim)

        UEF.pressed.connect(self.uef)
        Aeon.pressed.connect(self.aeon)
        Cybran.pressed.connect(self.cybran)
        Seraphim.pressed.connect(self.seraphim)

        label2 = QtGui.QLabel(
            "Be careful ! Once you have confirmed your allegiance to a faction, you won't be able to change it !"
        )
        label2.setWordWrap(True)

        layout.addWidget(label)
        layout.addLayout(layoutFactions)
        layout.addWidget(label2)
        self.setLayout(layout)
Example #46
0
    def __init__(self, parent=None):
        super(selectFactionPage, self).__init__(parent)
        
        self.parent = parent
        self.client = parent.client

        self.setTitle("Faction selection")
        
        layout = QtGui.QVBoxLayout()
        label = QtGui.QLabel("Hi commander. <br><br>The war is raging through the galaxy.<br>You have to pick a side !")
        
        
        layoutFactions = QtGui.QHBoxLayout()
        
        Aeon = QtGui.QPushButton()
        Cybran = QtGui.QPushButton()
        Seraphim = QtGui.QPushButton()
        UEF = QtGui.QPushButton()

        Aeon.setIconSize(QtCore.QSize(60,60))
        Cybran.setIconSize(QtCore.QSize(60,60))
        Seraphim.setIconSize(QtCore.QSize(60,60))
        UEF.setIconSize(QtCore.QSize(60,60))

        UEF.setMaximumSize(100, 100)
        Aeon.setMaximumSize(100, 100)
        Seraphim.setMaximumSize(100, 100)
        Cybran.setMaximumSize(100, 100)
        
        UEF.setMinimumSize(100, 100)
        Aeon.setMinimumSize(100, 100)
        Seraphim.setMinimumSize(100, 100)
        Cybran.setMinimumSize(100, 100)
        
        Aeon.setFlat(1)
        Cybran.setFlat(1)
        Seraphim.setFlat(1)
        UEF.setFlat(1)
        
        Aeon.setIcon(util.icon("games/automatch/aeon.png"))
        Cybran.setIcon(util.icon("games/automatch/cybran.png"))
        Seraphim.setIcon(util.icon("games/automatch/seraphim.png"))
        UEF.setIcon(util.icon("games/automatch/uef.png"))
            
        layoutFactions.addWidget(UEF)
        layoutFactions.addWidget(Aeon)
        layoutFactions.addWidget(Cybran)        
        layoutFactions.addWidget(Seraphim)
        
        UEF.pressed.connect(self.uef)
        Aeon.pressed.connect(self.aeon)
        Cybran.pressed.connect(self.cybran)
        Seraphim.pressed.connect(self.seraphim)

        label2 = QtGui.QLabel("Be careful ! Once you have confirmed your allegiance to a faction, you won't be able to change it !")
        label2.setWordWrap(True)

        layout.addWidget(label)
        layout.addLayout(layoutFactions)
        layout.addWidget(label2)
        self.setLayout(layout)
Example #47
0
    def processGameInfo(self, info):
        if info['state'] == "playing":
            if info['uid'] in self.games:
                # Updating an existing item
                item = self.games[info['uid']]
                
                item.takeChildren()  #Clear the children of this item before we're updating it
            else:
                # Creating a fresh item
                item = QtGui.QTreeWidgetItem()
                self.games[info['uid']] = item
                
                self.liveTree.insertTopLevelItem(0, item)
                
                if time.time() - info.get('launched_at', time.time()) < LIVEREPLAY_DELAY_TIME:
                    item.setHidden(True)
                    QtCore.QTimer.singleShot(LIVEREPLAY_DELAY_QTIMER, self.displayReplay) #The delay is there because we have a delay in the livereplay server

            # For debugging purposes, format our tooltip for the top level items
            # so it contains a human-readable representation of the info dictionary
            item.info = info
            tip = ""            
            for key in info.keys():
                tip += "'" + unicode(key) + "' : '" + unicode(info[key]) + "'<br/>"
                             
            item.setToolTip(1, tip)
            
            icon = fa.maps.preview(info['mapname'])
            item.setToolTip(0, fa.maps.getDisplayName(info['mapname']))
            if not icon:           
                self.client.downloader.downloadMap(item.info['mapname'], item, True)
                icon = util.icon("games/unknown_map.png")

            item.setText(0,time.strftime("%H:%M", time.localtime(item.info.get('launched_at', time.time()))))
            item.setTextColor(0, QtGui.QColor(client.instance.getColor("default")))
                                    

            item.setIcon(0, icon)
            item.setText(1, info['title'])
            item.setTextColor(1, QtGui.QColor(client.instance.getColor("player")))
            
            item.setText(2, info['featured_mod'])
            item.setTextAlignment(2, QtCore.Qt.AlignCenter)

            if not info['teams']:
                item.setDisabled(True)

            # This game is the game the player is currently in
            mygame = False            

            # Create player entries for all the live players in a match
            for team in info['teams']:
                if team == "-1": #skip observers, they don't seem to stream livereplays
                    continue
                
                for player in info['teams'][team]:
                    playeritem = QtGui.QTreeWidgetItem()
                    playeritem.setText(0, player)  

                    url = QtCore.QUrl()
                    url.setScheme("faflive")
                    url.setHost("lobby.faforever.com")
                    url.setPath(str(info["uid"]) + "/" + player + ".SCFAreplay")
                    url.addQueryItem("map", info["mapname"])
                    url.addQueryItem("mod", info["featured_mod"])
                    
                    playeritem.url = url
                    if client.instance.login == player:
                        mygame = True
                        item.setTextColor(1, QtGui.QColor(client.instance.getColor("self")))
                        playeritem.setTextColor(0, QtGui.QColor(client.instance.getColor("self")))
                        playeritem.setToolTip(0, url.toString())
                        playeritem.setIcon(0, util.icon("replays/replay.png"))                        
                    elif client.instance.players.isFriend(player):
                        if not mygame:
                            item.setTextColor(1, QtGui.QColor(client.instance.getColor("friend")))
                        playeritem.setTextColor(0, QtGui.QColor(client.instance.getColor("friend")))
                        playeritem.setToolTip(0, url.toString())
                        playeritem.setIcon(0, util.icon("replays/replay.png"))                        
                    elif client.instance.players.isPlayer(player):
                        playeritem.setTextColor(0, QtGui.QColor(client.instance.getColor("player")))                        
                        playeritem.setToolTip(0, url.toString())
                        playeritem.setIcon(0, util.icon("replays/replay.png"))                        
                    else:
                        playeritem.setTextColor(0, QtGui.QColor(client.instance.getColor("default")))
                        playeritem.setDisabled(True)

                    item.addChild(playeritem)
                    self.liveTree.setFirstItemColumnSpanned(playeritem, True)
        elif info['state'] == "closed":
            if info['uid'] in self.games:
                self.liveTree.takeTopLevelItem(self.liveTree.indexOfTopLevelItem(self.games[info['uid']]))
Example #48
0
 def get_icon_path(self, size=16, use_theme=True):
     return util.icon(self.icon, size, use_theme)
Example #49
0
    def __init__(self, client, *args, **kwargs):

        BaseClass.__init__(self, *args, **kwargs)

        self.setupUi(self)

        self.client = client
        self.client.gamesTab.layout().addWidget(self)

        #Dictionary containing our actual games.
        self.games = {}

        #Ranked search UI
        self.rankedAeon.setIcon(util.icon("games/automatch/aeon.png"))
        self.rankedCybran.setIcon(util.icon("games/automatch/cybran.png"))
        self.rankedSeraphim.setIcon(util.icon("games/automatch/seraphim.png"))
        self.rankedUEF.setIcon(util.icon("games/automatch/uef.png"))
        self.rankedRandom.setIcon(util.icon("games/automatch/random.png"))

        self.connectRankedToggles()
        self.rankedTimer = QtCore.QTimer()
        self.rankedTimer.timeout.connect(self.expandSearchRanked)
        self.searchProgress.hide()

        # Ranked search state variables
        self.searching = False
        self.radius = 0
        self.race = None
        self.ispassworded = False
        self.canChooseMap = True

        self.teamFrame.setVisible(False)
        # Team search UI
        # self.teamAeon.setIcon(util.icon("games/automatch/aeon.png"))
        # self.teamCybran.setIcon(util.icon("games/automatch/cybran.png"))
        # self.teamSeraphim.setIcon(util.icon("games/automatch/seraphim.png"))
        # self.teamUEF.setIcon(util.icon("games/automatch/uef.png"))
        # self.teamRandom.setIcon(util.icon("games/automatch/random.png"))

        #self.teamRandom.setChecked(True)

        # self.connectTeamFactionToggles()

        # self.teamSearchButton={}
        # self.teamSearchButton[2] = self.players2
        # self.teamSearchButton[3] = self.players3
        # self.teamSearchButton[4] = self.players4
        # self.teamSearchButton[5] = self.players5
        # self.teamSearchButton[6] = self.players6

        # self.teamSearchFnc = {}

        # self.connectTeamSearchToggles()

        # self.teamTimer = QtCore.QTimer()
        # self.teamTimer.timeout.connect(self.expandSearchTeamRanked)
        # self.teamSearchProgress.hide()

        # self.client.matchmakerInfo.connect(self.handleMatchmakerInfo)

        # # Team search state variables
        # self.teamSearching = False

        # self.teamInvitations = {}

        self.client.modInfo.connect(self.processModInfo)
        self.client.gameInfo.connect(self.processGameInfo)

        self.client.rankedGameAeon.connect(self.togglingAeon)
        self.client.rankedGameCybran.connect(self.togglingCybran)
        self.client.rankedGameSeraphim.connect(self.togglingSeraphim)
        self.client.rankedGameUEF.connect(self.togglingUEF)
        self.client.rankedGameRandom.connect(self.togglingRandom)

        self.client.teamInvitation.connect(self.handleInvitations)
        self.client.teamInfo.connect(self.handleTeamInfo)

        self.client.gameEnter.connect(self.stopSearchRanked)
        self.client.viewingReplay.connect(self.stopSearchRanked)

        self.gameList.setItemDelegate(GameItemDelegate(self))
        self.gameList.itemDoubleClicked.connect(self.gameDoubleClicked)
        self.gameList.sortBy = 0  # Default Sorting is By Players count

        self.sortGamesComboBox.addItems(
            ['By Players', 'By Game Quality', 'By avg. Player Rating'])
        self.sortGamesComboBox.currentIndexChanged.connect(
            self.sortGamesComboChanged)

        self.hideGamesWithPw.stateChanged.connect(self.togglePrivateGames)

        self.modList.itemDoubleClicked.connect(self.hostGameClicked)

        self.mapSelectButton.clicked.connect(self.mapSelectClicked)

        #self.TeamMapSelectButton.setVisible(False)

        # try:
        #     self.teamInvitationsListWidget.itemDoubleClicked.connect(self.teamInvitationClicked)
        #     self.leaveTeamButton.clicked.connect(self.quitTeam)
        #     self.leaveTeamButton.setVisible(False)
        # except:
        #     QtGui.QMessageBox.warning(None, "Skin outdated.", "The theme you are using is outdated. Please remove it or the lobby will malfunction.")

        #Load game name from settings (yay, it's persistent!)
        self.loadGameName()
        self.loadGameMap()
        self.loadPassword()
        self.options = []
Example #50
0
    def __init__(self, parent, item, *args, **kwargs):
        BaseClass.__init__(self, *args, **kwargs)

        self.setupUi(self)
        self.parent = parent
        
        self.parent.options = []

        if len(item.options) == 0 :   
            self.optionGroup.setVisible(False)
        else :
            group_layout = QtGui.QVBoxLayout()
            self.optionGroup.setLayout(group_layout)
            
            for option in item.options :
                checkBox = QtGui.QCheckBox(self)
                checkBox.setText(option)
                checkBox.setChecked(True)
                group_layout.addWidget(checkBox)
                self.parent.options.append(checkBox)
        
        self.setStyleSheet(self.parent.client.styleSheet())
        
        self.setWindowTitle ( "Hosting Game : " + item.name )
        self.titleEdit.setText ( self.parent.gamename )
        self.passEdit.setText ( self.parent.gamepassword )
        self.game = GameItem(0)
        self.gamePreview.setItemDelegate(GameItemDelegate(self));
        self.gamePreview.addItem(self.game)
        
        self.message = {}
        self.message['title'] = self.parent.gamename
        self.message['host'] = self.parent.client.login
        self.message['teams'] = {1:[self.parent.client.login]}
#        self.message.get('access', 'public')
        self.message['featured_mod'] = "faf"
        self.message['mapname'] = self.parent.gamemap
        self.message['state'] = "open"
        
        self.game.update(self.message, self.parent.client)
        
        i = 0
        index = 0
        if self.parent.canChooseMap == True:
            allmaps = dict()
            for map in maps.maps.keys() + maps.getUserMaps():
                allmaps[map] = maps.getDisplayName(map)
            for (map, name) in sorted(allmaps.iteritems(), key=lambda x: x[1]):
                if map == self.parent.gamemap :
                    index = i
                self.mapList.addItem(name, map)
                i = i + 1
            self.mapList.setCurrentIndex(index)
        else:
            self.mapList.hide()
            
        icon = maps.preview(self.parent.gamemap, True)

        if not icon:
            icon = util.icon("games/unknown_map.png", False, True)
                

        self.mods = {}
        #this makes it so you can select every non-ui_only mod
        for mod in modvault.getInstalledMods():
            if mod.ui_only:
                continue
            self.mods[mod.totalname] = mod
            self.modList.addItem(mod.totalname)

        names = [mod.totalname for mod in modvault.getActiveMods(uimods=False)]
        logger.debug("Active Mods detected: %s" % str(names))
        for name in names:
            l = self.modList.findItems(name, QtCore.Qt.MatchExactly)
            logger.debug("found item: %s" % l[0].text())
            if l: l[0].setSelected(True)
            
        #self.mapPreview.setPixmap(icon)
        
        self.mapList.currentIndexChanged.connect(self.mapChanged)
        self.hostButton.released.connect(self.hosting)
        self.titleEdit.textChanged.connect(self.updateText)
        self.modList.itemClicked.connect(self.modclicked)
Example #51
0
    def update(self, message, client):
        '''
        Updates this item from the message dictionary supplied
        '''
        self.client = client

        self.title = message['title']
        self.host = message['host']

        # Maps integral team numbers (from 2, with 1 "none") to lists of names.
        teams_map = dict.copy(message['teams'])
        self.password_protected = message.get('password_protected', False)
        self.mod = message['featured_mod']
        self.modVersion = message.get('featured_mod_versions', [])
        self.mods = message.get('sim_mods', {})
        self.options = message.get('options', [])
        num_players = message.get('num_players', 0)
        self.slots = message.get('max_players', 12)

        oldstate = self.state
        self.state = message['state']

        # Assemble a players & teams lists
        self.teamlist = []
        self.observerlist = []

        self.setHidden((self.state != 'open') or (self.mod in mod_invisible))

        # Clear the status for all involved players (url may change, or players may have left, or game closed)
        for player in self.players:
            if player.login in client.urls:
                del client.urls[player.login]

        # Just jump out if we've left the game, but tell the client that all players need their states updated
        if self.state == "closed":
            client.usersUpdated.emit(self.players)
            return

        # Used to differentiate between newly added / removed and previously present players
        oldplayers = set(map(lambda p: p.login, self.players))

        # Following the convention used by the game, a team value of 1 represents "No team". Let's
        # desugar those into "real" teams now (and convert the dict to a list)
        # Also, turn the lists of names into lists of players, and build a player name list.
        self.players = []
        teams = []
        for team_index, team in teams_map.iteritems():
            if team_index == 1:
                for ffa_player in team:
                    if ffa_player in self.client.players:
                        self.players.append(self.client.players[ffa_player])
                        teams.append([self.client.players[ffa_player]])
            else:
                real_team = []
                for name in team:
                    if name in self.client.players:
                        self.players.append(self.client.players[name])
                        real_team.append(self.client.players[name])
                teams.append(real_team)

        # Tuples for feeding into trueskill.
        rating_tuples = []
        for team in teams:
            ratings_for_team = map(
                lambda player: Rating(player.rating_mean, player.
                                      rating_deviation), team)
            rating_tuples.append(tuple(ratings_for_team))

        try:
            self.gamequality = 100 * round(trueskill.quality(rating_tuples), 2)
        except ValueError:
            self.gamequality = 0
        self.nTeams = len(teams)

        # Map preview code
        if self.mapname != message['mapname']:
            self.mapname = message['mapname']
            self.mapdisplayname = maps.getDisplayName(self.mapname)
            refresh_icon = True
        else:
            refresh_icon = False

        #Alternate icon: If private game, use game_locked icon. Otherwise, use preview icon from map library.
        if refresh_icon:
            if self.password_protected:
                icon = util.icon("games/private_game.png")
            else:
                icon = maps.preview(self.mapname)
                if not icon:
                    self.client.downloader.downloadMap(self.mapname, self)
                    icon = util.icon("games/unknown_map.png")

            self.setIcon(icon)

        strQuality = ""

        if self.gamequality == 0:
            strQuality = "? %"
        else:
            strQuality = str(self.gamequality) + " %"

        if num_players == 1:
            playerstring = "player"
        else:
            playerstring = "players"

        color = client.players.getUserColor(self.host)

        self.editTooltip(teams)

        self.setText(
            self.FORMATTER_FAF.format(color=color,
                                      mapslots=self.slots,
                                      mapdisplayname=self.mapdisplayname,
                                      title=self.title,
                                      host=self.host,
                                      players=num_players,
                                      playerstring=playerstring,
                                      gamequality=strQuality))

        #Spawn announcers: IF we had a gamestate change, show replay and hosting announcements
        if (oldstate != self.state):
            if (self.state == "playing"):
                QtCore.QTimer.singleShot(
                    5 * 60000, self.announceReplay
                )  #The delay is there because we have a 5 minutes delay in the livereplay server
            elif (self.state == "open"):
                QtCore.QTimer.singleShot(
                    35000, self.announceHosting
                )  #The delay is there because we currently the host needs time to choose a map

        # Update player URLs
        for player in self.players:
            client.urls[player.login] = self.url(player.id)

        # Determine which players are affected by this game's state change
        newplayers = set(map(lambda p: p.login, self.players))
        affectedplayers = oldplayers | newplayers
        client.usersUpdated.emit(list(affectedplayers))
Example #52
0
 def get_icon_path(self, size=16, use_theme=True):
   return util.icon(self.icon, size, use_theme)
Example #53
0
    def updatemyTree(self):
        self.myTree.clear()
        
        # We put the replays into buckets by day first, then we add them to the treewidget.
        buckets = {}

        cache = self.loadLocalCache()
        cache_add = {}
        cache_hit = {}
        # Iterate
        for infile in os.listdir(util.REPLAY_DIR):            
            if infile.endswith(".scfareplay"):
                bucket = buckets.setdefault("legacy", [])
                
                item = QtGui.QTreeWidgetItem()
                item.setText(1, infile)
                item.filename = os.path.join(util.REPLAY_DIR, infile)
                item.setIcon(0, util.icon("replays/replay.png"))
                item.setTextColor(0, QtGui.QColor(client.instance.getColor("default")))
                                
                bucket.append(item)
                
            elif infile.endswith(".fafreplay"):
                item = QtGui.QTreeWidgetItem()
                try:
                    item.filename = os.path.join(util.REPLAY_DIR, infile)
                    basename = os.path.basename(item.filename)
                    if basename in cache:
                        oneline = cache[basename]
                        cache_hit[basename] = oneline
                    else:
                        with open(item.filename, "rt") as fh:
                            oneline = fh.readline()
                            cache_add[basename] = oneline

                    item.info = json.loads(oneline)

                    # Parse replayinfo into data
                    if item.info.get('complete', False):
                        t = time.localtime(item.info.get('launched_at', item.info.get('game_time', time.time())))
                        game_date = time.strftime("%Y-%m-%d", t)
                        game_hour = time.strftime("%H:%M", t)
                        
                        bucket = buckets.setdefault(game_date, [])                    
                        
                        icon = fa.maps.preview(item.info['mapname'])
                        if icon:
                            item.setIcon(0, icon)
                        else:
                            self.client.downloader.downloadMap(item.info['mapname'], item, True)
                            item.setIcon(0,util.icon("games/unknown_map.png"))                                                      
                        item.setToolTip(0, fa.maps.getDisplayName(item.info['mapname']))
                        item.setText(0, game_hour)
                        item.setTextColor(0, QtGui.QColor(client.instance.getColor("default")))
                        
                        item.setText(1, item.info['title'])
                        item.setToolTip(1, infile)
    
                        # Hacky way to quickly assemble a list of all the players, but including the observers
                        playerlist = []
                        for _, players in item.info['teams'].items():
                            playerlist.extend(players)
                        item.setText(2, ", ".join(playerlist))
                        item.setToolTip(2, ", ".join(playerlist))
                        
                        # Add additional info
                        item.setText(3, item.info['featured_mod'])
                        item.setTextAlignment(3, QtCore.Qt.AlignCenter)
                        item.setTextColor(1, QtGui.QColor(client.instance.players.getUserColor(item.info.get('recorder', ""))))
                    else:
                        bucket = buckets.setdefault("incomplete", [])                    
                        item.setIcon(0, util.icon("replays/replay.png"))
                        item.setText(1, infile)
                        item.setText(2, "(replay doesn't have complete metadata)")
                        item.setTextColor(1, QtGui.QColor("yellow")) #FIXME: Needs to come from theme

                except Exception as ex:
                    bucket = buckets.setdefault("broken", [])                    
                    item.setIcon(0, util.icon("replays/broken.png"))
                    item.setText(1, infile)
                    item.setTextColor(1, QtGui.QColor("red"))   #FIXME: Needs to come from theme
                    item.setText(2, "(replay parse error)")
                    item.setTextColor(2, QtGui.QColor("gray"))  #FIXME: Needs to come from theme
                    logger.exception("Exception parsing replay {}: {}".format(infile, ex))

                bucket.append(item)

        if len(cache_add) > 10 or len(cache) - len(cache_hit) > 10:
            self.saveLocalCache(cache_hit, cache_add)
        # Now, create a top level treewidgetitem for every bucket, and put the bucket's contents into them         
        for bucket in buckets.keys():
            bucket_item = QtGui.QTreeWidgetItem()
            
            if bucket == "broken":
                bucket_item.setTextColor(0, QtGui.QColor("red")) #FIXME: Needs to come from theme
                bucket_item.setText(1, "(not watchable)")
                bucket_item.setTextColor(1, QtGui.QColor(client.instance.getColor("default")))
            elif bucket == "incomplete":
                bucket_item.setTextColor(0, QtGui.QColor("yellow")) #FIXME: Needs to come from theme
                bucket_item.setText(1, "(watchable)")
                bucket_item.setTextColor(1, QtGui.QColor(client.instance.getColor("default")))
            elif bucket == "legacy":
                bucket_item.setTextColor(0, QtGui.QColor(client.instance.getColor("default")))
                bucket_item.setTextColor(1, QtGui.QColor(client.instance.getColor("default")))
                bucket_item.setText(1, "(old replay system)")
            else:
                bucket_item.setTextColor(0, QtGui.QColor(client.instance.getColor("player")))
                
            bucket_item.setIcon(0, util.icon("replays/bucket.png"))                                
            bucket_item.setText(0, bucket)
            bucket_item.setText(3, str(len(buckets[bucket])) + " replays")
            bucket_item.setTextColor(3, QtGui.QColor(client.instance.getColor("default")))
                
            self.myTree.addTopLevelItem(bucket_item)
            #self.myTree.setFirstItemColumnSpanned(bucket_item, True)
                
            for replay in buckets[bucket]:
                bucket_item.addChild(replay)