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 = []
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())
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 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())
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)
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)
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'))})
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)
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]))
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))
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)
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)
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)
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]))
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)
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)
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)
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"))
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)
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]
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]
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()
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))
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>[^\"]+)\"[^>]*>><',data) if n: util.add_dir(__language__(30012),{'tale':furl(url+n.group('url'))},util.icon('next.png')) xbmcplugin.endOfDirectory(int(sys.argv[1]))
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))
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))
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)
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)
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")
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']]))
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)
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")
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))
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
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 = []
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
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)
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"))
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))
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))
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)
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)
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']]))
def get_icon_path(self, size=16, use_theme=True): return util.icon(self.icon, size, use_theme)
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 = []
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)
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))
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)